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