Mercurial > urweb
comparison src/iflow.sml @ 1247:0c643f51fbc0
Fix innappropriate removal of duplicate tables from DML policies
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Sun, 18 Apr 2010 15:54:37 -0400 |
parents | fd4028a594a9 |
children | cf9a636f9b15 |
comparison
equal
deleted
inserted
replaced
1246:fd4028a594a9 | 1247:0c643f51fbc0 |
---|---|
231 (* Congruence closure *) | 231 (* Congruence closure *) |
232 structure Cc :> sig | 232 structure Cc :> sig |
233 type database | 233 type database |
234 | 234 |
235 exception Contradiction | 235 exception Contradiction |
236 exception Undetermined | |
237 | 236 |
238 val database : unit -> database | 237 val database : unit -> database |
239 val clear : database -> unit | 238 val clear : database -> unit |
240 | 239 |
241 val assert : database * atom -> unit | 240 val assert : database * atom -> unit |
736 case !(#Ge (unNode (repOf r1))) of | 735 case !(#Ge (unNode (repOf r1))) of |
737 NONE => #Ge (unNode (repOf r1)) := SOME n2 | 736 NONE => #Ge (unNode (repOf r1)) := SOME n2 |
738 | SOME n1 => #Ge (unNode (repOf r1)) := SOME (Int64.max (n1, n2)) | 737 | SOME n1 => #Ge (unNode (repOf r1)) := SOME (Int64.max (n1, n2)) |
739 end | 738 end |
740 | _ => () | 739 | _ => () |
741 end | 740 end handle Undetermined => () |
742 | 741 |
743 fun check (db, a) = | 742 fun check (db, a) = |
744 case a of | 743 (case a of |
745 ACond _ => false | 744 ACond _ => false |
746 | AReln x => | 745 | AReln x => |
747 case x of | 746 case x of |
748 (Known, [e]) => | 747 (Known, [e]) => |
749 let | 748 let |
750 fun isKnown r = | 749 fun isKnown r = |
751 let | 750 let |
752 val r = repOf r | 751 val r = repOf r |
753 in | 752 in |
754 !(#Known (unNode r)) | 753 !(#Known (unNode r)) |
755 orelse case #Variety (unNode r) of | 754 orelse case #Variety (unNode r) of |
756 Dt1 (_, r) => isKnown r | 755 Dt1 (_, r) => isKnown r |
757 | Recrd (xes, true) => List.all isKnown (SM.listItems (!xes)) | 756 | Recrd (xes, true) => List.all isKnown (SM.listItems (!xes)) |
758 | _ => false | 757 | _ => false |
759 end | 758 end |
760 | 759 |
761 val r = representative (db, e) | 760 val r = representative (db, e) |
762 in | 761 in |
763 isKnown r | 762 isKnown r |
764 end | 763 end |
765 | (PCon0 f, [e]) => | 764 | (PCon0 f, [e]) => |
766 (case #Variety (unNode (representative (db, e))) of | 765 (case #Variety (unNode (representative (db, e))) of |
767 Dt0 f' => f' = f | 766 Dt0 f' => f' = f |
768 | _ => false) | 767 | _ => false) |
769 | (PCon1 f, [e]) => | 768 | (PCon1 f, [e]) => |
770 (case #Variety (unNode (representative (db, e))) of | 769 (case #Variety (unNode (representative (db, e))) of |
771 Dt1 (f', _) => f' = f | 770 Dt1 (f', _) => f' = f |
772 | _ => false) | 771 | _ => false) |
773 | (Eq, [e1, e2]) => | 772 | (Eq, [e1, e2]) => |
774 let | 773 let |
775 val r1 = representative (db, e1) | 774 val r1 = representative (db, e1) |
776 val r2 = representative (db, e2) | 775 val r2 = representative (db, e2) |
777 in | 776 in |
778 repOf r1 = repOf r2 | 777 repOf r1 = repOf r2 |
779 end | 778 end |
780 | (Ge, [e1, e2]) => | 779 | (Ge, [e1, e2]) => |
781 let | 780 let |
782 val r1 = representative (db, e1) | 781 val r1 = representative (db, e1) |
783 val r2 = representative (db, e2) | 782 val r2 = representative (db, e2) |
784 in | 783 in |
785 case (!(#Ge (unNode (repOf r1))), #Variety (unNode (repOf r2))) of | 784 case (!(#Ge (unNode (repOf r1))), #Variety (unNode (repOf r2))) of |
786 (SOME n1, Prim (Prim.Int n2)) => Int64.>= (n1, n2) | 785 (SOME n1, Prim (Prim.Int n2)) => Int64.>= (n1, n2) |
787 | _ => false | 786 | _ => false |
788 end | 787 end |
789 | _ => false | 788 | _ => false) |
789 handle Undetermined => false | |
790 | 790 |
791 fun builtFrom (db, {UseKnown = uk, Base = bs, Derived = d}) = | 791 fun builtFrom (db, {UseKnown = uk, Base = bs, Derived = d}) = |
792 let | 792 let |
793 val bs = map (fn b => representative (db, b)) bs | 793 val bs = map (fn b => representative (db, b)) bs |
794 | 794 |
810 case e of | 810 case e of |
811 Func (Other _, es) => List.all decomp es | 811 Func (Other _, es) => List.all decomp es |
812 | _ => loop (representative (db, e)) | 812 | _ => loop (representative (db, e)) |
813 in | 813 in |
814 decomp d | 814 decomp d |
815 end | 815 end handle Undetermined => false |
816 | 816 |
817 end | 817 end |
818 | 818 |
819 val tabs = ref (SM.empty : (string list * string list list) SM.map) | 819 val tabs = ref (SM.empty : (string list * string list list) SM.map) |
820 | 820 |
1254 let | 1254 let |
1255 val changed = ref false | 1255 val changed = ref false |
1256 | 1256 |
1257 fun findKeys (hyps, acc) = | 1257 fun findKeys (hyps, acc) = |
1258 case hyps of | 1258 case hyps of |
1259 [] => acc | 1259 [] => rev acc |
1260 | (a as AReln (Sql tab, [r1])) :: hyps => | 1260 | (a as AReln (Sql tab, [r1])) :: hyps => |
1261 (case SM.find (!tabs, tab) of | 1261 (case SM.find (!tabs, tab) of |
1262 NONE => findKeys (hyps, a :: acc) | 1262 NONE => findKeys (hyps, a :: acc) |
1263 | SOME (_, []) => findKeys (hyps, a :: acc) | 1263 | SOME (_, []) => findKeys (hyps, a :: acc) |
1264 | SOME (_, ks) => | 1264 | SOME (_, ks) => |
1265 let | 1265 let |
1266 fun finder (hyps, acc) = | 1266 fun finder (hyps, acc) = |
1267 case hyps of | 1267 case hyps of |
1268 [] => acc | 1268 [] => rev acc |
1269 | (a as AReln (Sql tab', [r2])) :: hyps => | 1269 | (a as AReln (Sql tab', [r2])) :: hyps => |
1270 if tab' = tab andalso | 1270 if tab' = tab andalso |
1271 List.exists (List.all (fn f => | 1271 List.exists (List.all (fn f => |
1272 let | 1272 let |
1273 val r = | 1273 val r = |
1409 let | 1409 let |
1410 val (_, hs, _) = !hyps | 1410 val (_, hs, _) = !hyps |
1411 in | 1411 in |
1412 ErrorMsg.errorAt loc "The information flow policy may be violated here."; | 1412 ErrorMsg.errorAt loc "The information flow policy may be violated here."; |
1413 Print.prefaces "Situation" [("User learns", p_exp e), | 1413 Print.prefaces "Situation" [("User learns", p_exp e), |
1414 ("Hypotheses", Print.p_list p_atom hs), | 1414 ("Hypotheses", Print.p_list p_atom hs)(*, |
1415 ("E-graph", Cc.p_database db)] | 1415 ("E-graph", Cc.p_database db)*)] |
1416 end | 1416 end |
1417 end | 1417 end |
1418 | 1418 |
1419 fun checkPaths () = | 1419 fun checkPaths () = |
1420 let | 1420 let |
1461 else | 1461 else |
1462 let | 1462 let |
1463 val (_, hs, _) = !hyps | 1463 val (_, hs, _) = !hyps |
1464 in | 1464 in |
1465 ErrorMsg.errorAt loc "The database update policy may be violated here."; | 1465 ErrorMsg.errorAt loc "The database update policy may be violated here."; |
1466 Print.prefaces "Situation" [("Hypotheses", Print.p_list p_atom hs)(*, | 1466 Print.prefaces "Situation" [("Hypotheses", Print.p_list p_atom hs), |
1467 ("E-graph", Cc.p_database db)*)] | 1467 ("E-graph", Cc.p_database db)] |
1468 end | 1468 end |
1469 end | 1469 end |
1470 | 1470 |
1471 val insertable = ref ([] : atom list list) | 1471 val insertable = ref ([] : atom list list) |
1472 fun allowInsert v = insertable := v :: !insertable | 1472 fun allowInsert v = insertable := v :: !insertable |
2175 Save = fn () => !atoms, | 2175 Save = fn () => !atoms, |
2176 Restore = fn ls => atoms := ls, | 2176 Restore = fn ls => atoms := ls, |
2177 UsedExp = fn _ => (), | 2177 UsedExp = fn _ => (), |
2178 Cont = SomeCol (fn r => k (rev (!atoms), r))} | 2178 Cont = SomeCol (fn r => k (rev (!atoms), r))} |
2179 | 2179 |
2180 fun untab tab = List.filter (fn AReln (Sql tab', _) => tab' <> tab | 2180 fun untab (tab, nams) = List.filter (fn AReln (Sql tab', [Lvar lv]) => |
2181 | _ => true) | 2181 tab' <> tab |
2182 orelse List.all (fn Lvar lv' => lv' <> lv | |
2183 | _ => false) nams | |
2184 | _ => true) | |
2182 in | 2185 in |
2183 case pol of | 2186 case pol of |
2184 PolClient e => | 2187 PolClient e => |
2185 doQ (fn (ats, {Outs = es, ...}) => St.allowSend (ats, es)) e | 2188 doQ (fn (ats, {Outs = es, ...}) => St.allowSend (ats, es)) e |
2186 | PolInsert e => | 2189 | PolInsert e => |
2187 doQ (fn (ats, {New = SOME (tab, new), ...}) => | 2190 doQ (fn (ats, {New = SOME (tab, new), ...}) => |
2188 St.allowInsert (AReln (Sql (tab ^ "$New"), [new]) :: untab tab ats) | 2191 St.allowInsert (AReln (Sql (tab ^ "$New"), [new]) :: untab (tab, [new]) ats) |
2189 | _ => raise Fail "Iflow: No New in mayInsert policy") e | 2192 | _ => raise Fail "Iflow: No New in mayInsert policy") e |
2190 | PolDelete e => | 2193 | PolDelete e => |
2191 doQ (fn (ats, {Old = SOME (tab, old), ...}) => | 2194 doQ (fn (ats, {Old = SOME (tab, old), ...}) => |
2192 St.allowDelete (AReln (Sql (tab ^ "$Old"), [old]) :: untab tab ats) | 2195 St.allowDelete (AReln (Sql (tab ^ "$Old"), [old]) :: untab (tab, [old]) ats) |
2193 | _ => raise Fail "Iflow: No Old in mayDelete policy") e | 2196 | _ => raise Fail "Iflow: No Old in mayDelete policy") e |
2194 | PolUpdate e => | 2197 | PolUpdate e => |
2195 doQ (fn (ats, {New = SOME (tab, new), Old = SOME (_, old), ...}) => | 2198 doQ (fn (ats, {New = SOME (tab, new), Old = SOME (_, old), ...}) => |
2196 St.allowUpdate (AReln (Sql (tab ^ "$Old"), [old]) | 2199 St.allowUpdate (AReln (Sql (tab ^ "$Old"), [old]) |
2197 :: AReln (Sql (tab ^ "$New"), [new]) | 2200 :: AReln (Sql (tab ^ "$New"), [new]) |
2198 :: untab tab ats) | 2201 :: untab (tab, [new, old]) ats) |
2199 | _ => raise Fail "Iflow: No New or Old in mayUpdate policy") e | 2202 | _ => raise Fail "Iflow: No New or Old in mayUpdate policy") e |
2200 | PolSequence e => | 2203 | PolSequence e => |
2201 (case #1 e of | 2204 (case #1 e of |
2202 EPrim (Prim.String seq) => | 2205 EPrim (Prim.String seq) => |
2203 let | 2206 let |