comparison src/iflow.sml @ 1216:09caa8c780e5

Some serious debugging of the new Cc
author Adam Chlipala <adamc@hcoop.net>
date Thu, 08 Apr 2010 14:20:46 -0400
parents 360f1ed0a969
children 4d206e603300
comparison
equal deleted inserted replaced
1215:360f1ed0a969 1216:09caa8c780e5
544 | NONE => 544 | NONE =>
545 let 545 let
546 val r' = ref (Node {Rep = ref NONE, 546 val r' = ref (Node {Rep = ref NONE,
547 Cons = ref SM.empty, 547 Cons = ref SM.empty,
548 Variety = Dt1 (f, r), 548 Variety = Dt1 (f, r),
549 Known = ref false}) 549 Known = #Known (unNode r)})
550 in 550 in
551 #Cons (unNode r) := SM.insert (!(#Cons (unNode r)), f, r'); 551 #Cons (unNode r) := SM.insert (!(#Cons (unNode r)), f, r');
552 r' 552 r'
553 end 553 end
554 end 554 end
566 let 566 let
567 val cons = ref SM.empty 567 val cons = ref SM.empty
568 val r' = ref (Node {Rep = ref NONE, 568 val r' = ref (Node {Rep = ref NONE,
569 Cons = cons, 569 Cons = cons,
570 Variety = Nothing, 570 Variety = Nothing,
571 Known = ref false}) 571 Known = #Known (unNode r)})
572 572
573 val r'' = ref (Node {Rep = ref NONE, 573 val r'' = ref (Node {Rep = ref NONE,
574 Cons = #Cons (unNode r), 574 Cons = #Cons (unNode r),
575 Variety = Dt1 (f, r'), 575 Variety = Dt1 (f, r'),
576 Known = #Known (unNode r)}) 576 Known = #Known (unNode r)})
632 in 632 in
633 case #Variety (unNode r) of 633 case #Variety (unNode r) of
634 Recrd xes => 634 Recrd xes =>
635 (case SM.find (!xes, f) of 635 (case SM.find (!xes, f) of
636 SOME r => repOf r 636 SOME r => repOf r
637 | NONE =>let 637 | NONE => let
638 val r = ref (Node {Rep = ref NONE, 638 val r = ref (Node {Rep = ref NONE,
639 Cons = ref SM.empty, 639 Cons = ref SM.empty,
640 Variety = Nothing, 640 Variety = Nothing,
641 Known = ref false}) 641 Known = #Known (unNode r)})
642 in 642 in
643 xes := SM.insert (!xes, f, r); 643 xes := SM.insert (!xes, f, r);
644 r 644 r
645 end) 645 end)
646 | Nothing => 646 | Nothing =>
647 let 647 let
648 val r' = ref (Node {Rep = ref NONE, 648 val r' = ref (Node {Rep = ref NONE,
649 Cons = ref SM.empty, 649 Cons = ref SM.empty,
650 Variety = Nothing, 650 Variety = Nothing,
651 Known = ref false}) 651 Known = #Known (unNode r)})
652 652
653 val r'' = ref (Node {Rep = ref NONE, 653 val r'' = ref (Node {Rep = ref NONE,
654 Cons = #Cons (unNode r), 654 Cons = #Cons (unNode r),
655 Variety = Recrd (ref (SM.insert (SM.empty, f, r'))), 655 Variety = Recrd (ref (SM.insert (SM.empty, f, r'))),
656 Known = #Known (unNode r)}) 656 Known = #Known (unNode r)})
836 decomp 836 decomp
837 end 837 end
838 838
839 fun imply (p1, p2) = 839 fun imply (p1, p2) =
840 (reset (); 840 (reset ();
841 (*Print.prefaces "Bigger go" [("p1", p_prop p1),
842 ("p2", p_prop p2)];*)
841 decomp true (fn (e1, e2) => e1 andalso e2 ()) p1 843 decomp true (fn (e1, e2) => e1 andalso e2 ()) p1
842 (fn hyps => 844 (fn hyps =>
843 decomp false (fn (e1, e2) => e1 orelse e2 ()) p2 845 decomp false (fn (e1, e2) => e1 orelse e2 ()) p2
844 (fn goals => 846 (fn goals =>
845 let 847 let
859 ("hyps", Print.p_list p_atom hyps), 861 ("hyps", Print.p_list p_atom hyps),
860 ("db", Cc.p_database cc)];*) 862 ("db", Cc.p_database cc)];*)
861 false)) acc 863 false)) acc
862 orelse onFail ()) 864 orelse onFail ())
863 handle Cc.Contradiction => onFail () 865 handle Cc.Contradiction => onFail ()
864 end handle Cc.Undetermined => onFail ()) 866 end handle Cc.Undetermined => ((*print "Undetermined\n";*) onFail ()))
865 | AReln (Sql gf, [ge]) :: goals => 867 | (g as AReln (Sql gf, [ge])) :: goals =>
866 let 868 let
867 fun hps hyps = 869 fun hps hyps =
868 case hyps of 870 case hyps of
869 [] => onFail () 871 [] => gls goals onFail (g :: acc)
870 | AReln (Sql hf, [he]) :: hyps => 872 | AReln (Sql hf, [he]) :: hyps =>
871 if gf = hf then 873 if gf = hf then
872 let 874 let
873 val saved = save () 875 val saved = save ()
874 in 876 in
891 in 893 in
892 hps hyps 894 hps hyps
893 end 895 end
894 | g :: goals => gls goals onFail (g :: acc) 896 | g :: goals => gls goals onFail (g :: acc)
895 in 897 in
898 (*Print.prefaces "Big go" [("hyps", Print.p_list p_atom hyps),
899 ("goals", Print.p_list p_atom goals)];*)
896 gls goals (fn () => false) [] 900 gls goals (fn () => false) []
897 end handle Cc.Contradiction => true))) 901 end handle Cc.Contradiction => true)))
898 902
899 fun patCon pc = 903 fun patCon pc =
900 case pc of 904 case pc of
1203 1207
1204 datatype queryMode = 1208 datatype queryMode =
1205 SomeCol of exp 1209 SomeCol of exp
1206 | AllCols of exp 1210 | AllCols of exp
1207 1211
1212 exception Default
1213
1208 fun queryProp env rvN rv oe e = 1214 fun queryProp env rvN rv oe e =
1209 case parse query e of 1215 let
1210 NONE => (print ("Warning: Information flow checker can't parse SQL query at " 1216 fun default () = (print ("Warning: Information flow checker can't parse SQL query at "
1211 ^ ErrorMsg.spanToString (#2 e) ^ "\n"); 1217 ^ ErrorMsg.spanToString (#2 e) ^ "\n");
1212 (rvN, Var 0, Unknown, [])) 1218 (rvN, Unknown, []))
1213 | SOME r => 1219 in
1214 let 1220 case parse query e of
1215 val (rvN, count) = rv rvN 1221 NONE => default ()
1216 1222 | SOME r =>
1217 val (rvs, rvN) = ListUtil.foldlMap (fn ((_, v), rvN) => 1223 let
1218 let 1224 val (rvs, rvN) = ListUtil.foldlMap (fn ((_, v), rvN) =>
1219 val (rvN, e) = rv rvN 1225 let
1220 in 1226 val (rvN, e) = rv rvN
1221 ((v, e), rvN) 1227 in
1222 end) rvN (#From r) 1228 ((v, e), rvN)
1223 1229 end) rvN (#From r)
1224 fun rvOf v = 1230
1225 case List.find (fn (v', _) => v' = v) rvs of 1231 fun rvOf v =
1226 NONE => raise Fail "Iflow.queryProp: Bad table variable" 1232 case List.find (fn (v', _) => v' = v) rvs of
1227 | SOME (_, e) => e 1233 NONE => raise Fail "Iflow.queryProp: Bad table variable"
1228 1234 | SOME (_, e) => e
1229 fun usedFields e = 1235
1230 case e of 1236 fun usedFields e =
1231 SqConst _ => [] 1237 case e of
1232 | Field (v, f) => [(v, f)] 1238 SqConst _ => []
1233 | Binop (_, e1, e2) => removeDups (usedFields e1 @ usedFields e2) 1239 | Field (v, f) => [(v, f)]
1234 | SqKnown _ => [] 1240 | Binop (_, e1, e2) => removeDups (usedFields e1 @ usedFields e2)
1235 | Inj _ => [] 1241 | SqKnown _ => []
1236 | SqFunc (_, e) => usedFields e 1242 | Inj _ => []
1237 | Count => [] 1243 | SqFunc (_, e) => usedFields e
1238 1244 | Count => []
1239 val p = 1245
1240 foldl (fn ((t, v), p) => And (p, Reln (Sql t, [rvOf v]))) True (#From r) 1246 val p =
1241 1247 foldl (fn ((t, v), p) => And (p, Reln (Sql t, [rvOf v]))) True (#From r)
1242 fun expIn e = 1248
1243 case e of 1249 fun expIn e =
1244 SqConst p => inl (Const p) 1250 case e of
1245 | Field (v, f) => inl (Proj (rvOf v, f)) 1251 SqConst p => inl (Const p)
1246 | Binop (bo, e1, e2) => 1252 | Field (v, f) => inl (Proj (rvOf v, f))
1247 inr (case (bo, expIn e1, expIn e2) of 1253 | Binop (bo, e1, e2) =>
1248 (Exps f, inl e1, inl e2) => f (e1, e2) 1254 inr (case (bo, expIn e1, expIn e2) of
1249 | (Props f, inr p1, inr p2) => f (p1, p2) 1255 (Exps f, inl e1, inl e2) => f (e1, e2)
1250 | _ => Unknown) 1256 | (Props f, inr p1, inr p2) => f (p1, p2)
1251 | SqKnown e => 1257 | _ => Unknown)
1252 inr (case expIn e of 1258 | SqKnown e =>
1253 inl e => Reln (Known, [e]) 1259 inr (case expIn e of
1254 | _ => Unknown) 1260 inl e => Reln (Known, [e])
1255 | Inj e => 1261 | _ => Unknown)
1256 let 1262 | Inj e =>
1257 fun deinj (e, _) = 1263 let
1258 case e of 1264 fun deinj (e, _) =
1259 ERel n => List.nth (env, n) 1265 case e of
1260 | EField (e, f) => Proj (deinj e, f) 1266 ERel n => List.nth (env, n)
1261 | _ => raise Fail "Iflow: non-variable injected into query" 1267 | EField (e, f) => Proj (deinj e, f)
1262 in 1268 | _ => raise Fail "Iflow: non-variable injected into query"
1263 inl (deinj e) 1269 in
1264 end 1270 inl (deinj e)
1265 | SqFunc (f, e) => 1271 end
1266 inl (case expIn e of 1272 | SqFunc (f, e) =>
1267 inl e => Func (Other f, [e]) 1273 inl (case expIn e of
1268 | _ => raise Fail ("Iflow: non-expresion passed to function " ^ f)) 1274 inl e => Func (Other f, [e])
1269 | Count => inl count 1275 | _ => raise Fail ("Iflow: non-expresion passed to function " ^ f))
1270 1276 | Count => raise Default
1271 val p = case #Where r of 1277
1272 NONE => p 1278 val p = case #Where r of
1273 | SOME e => 1279 NONE => p
1274 case expIn e of 1280 | SOME e =>
1275 inr p' => And (p, p') 1281 case expIn e of
1276 | _ => p 1282 inr p' => And (p, p')
1277 in 1283 | _ => p
1278 (rvN, 1284
1279 count, 1285 fun normal () =
1280 And (p, case oe of 1286 (rvN,
1281 SomeCol oe => 1287 And (p, case oe of
1282 foldl (fn (si, p) => 1288 SomeCol oe =>
1283 let 1289 foldl (fn (si, p) =>
1284 val p' = case si of 1290 let
1285 SqField (v, f) => Reln (Eq, [oe, Proj (rvOf v, f)]) 1291 val p' = case si of
1286 | SqExp (e, f) => 1292 SqField (v, f) => Reln (Eq, [oe, Proj (rvOf v, f)])
1287 case expIn e of 1293 | SqExp (e, f) =>
1288 inr _ => Unknown 1294 case expIn e of
1289 | inl e => Reln (Eq, [oe, e]) 1295 inr _ => Unknown
1290 in 1296 | inl e => Reln (Eq, [oe, e])
1291 Or (p, p') 1297 in
1292 end) 1298 Or (p, p')
1293 False (#Select r) 1299 end)
1294 | AllCols oe => 1300 False (#Select r)
1295 foldl (fn (si, p) => 1301 | AllCols oe =>
1296 let 1302 foldl (fn (si, p) =>
1297 val p' = case si of 1303 let
1298 SqField (v, f) => Reln (Eq, [Proj (Proj (oe, v), f), 1304 val p' = case si of
1299 Proj (rvOf v, f)]) 1305 SqField (v, f) => Reln (Eq, [Proj (Proj (oe, v), f),
1300 | SqExp (e, f) => 1306 Proj (rvOf v, f)])
1301 case expIn e of 1307 | SqExp (e, f) =>
1302 inr p => Cond (Proj (oe, f), p) 1308 case expIn e of
1303 | inl e => Reln (Eq, [Proj (oe, f), e]) 1309 inr p => Cond (Proj (oe, f), p)
1304 in 1310 | inl e => Reln (Eq, [Proj (oe, f), e])
1305 And (p, p') 1311 in
1306 end) 1312 And (p, p')
1307 True (#Select r)), 1313 end)
1308 1314 True (#Select r)),
1309 case #Where r of 1315 case #Where r of
1310 NONE => [] 1316 NONE => []
1311 | SOME e => map (fn (v, f) => Proj (rvOf v, f)) (usedFields e)) 1317 | SOME e => map (fn (v, f) => Proj (rvOf v, f)) (usedFields e))
1312 end 1318 in
1319 case #Select r of
1320 [SqExp (Binop (Exps bo, Count, SqConst (Prim.Int 0)), f)] =>
1321 (case bo (Const (Prim.Int 1), Const (Prim.Int 2)) of
1322 Reln (Gt, [Const (Prim.Int 1), Const (Prim.Int 2)]) =>
1323 let
1324 val oe = case oe of
1325 SomeCol oe => oe
1326 | AllCols oe => Proj (oe, f)
1327 in
1328 (rvN,
1329 Or (Reln (Eq, [oe, Func (DtCon0 "Basis.bool.False", [])]),
1330 And (Reln (Eq, [oe, Func (DtCon0 "Basis.bool.True", [])]),
1331 p)),
1332 [])
1333 end
1334 | _ => normal ())
1335 | _ => normal ()
1336 end
1337 handle Default => default ()
1338 end
1313 1339
1314 fun evalPat env e (pt, _) = 1340 fun evalPat env e (pt, _) =
1315 case pt of 1341 case pt of
1316 PWild => (env, True) 1342 PWild => (env, True)
1317 | PVar _ => (e :: env, True) 1343 | PVar _ => (e :: env, True)
1461 1487
1462 val st = foldl (fn ((pt, pe), st) => 1488 val st = foldl (fn ((pt, pe), st) =>
1463 let 1489 let
1464 val (env, pp) = evalPat env e pt 1490 val (env, pp) = evalPat env e pt
1465 val (pe, st') = evalExp env (pe, (#1 st, And (orig, pp), #3 st)) 1491 val (pe, st') = evalExp env (pe, (#1 st, And (orig, pp), #3 st))
1492 (*val () = Print.prefaces "Case" [("loc", Print.PD.string
1493 (ErrorMsg.spanToString (#2 pt))),
1494 ("env", Print.p_list p_exp env),
1495 ("sent", Print.p_list_sep Print.PD.newline
1496 (fn (loc, e, p) =>
1497 Print.box [Print.PD.string
1498 (ErrorMsg.spanToString loc),
1499 Print.PD.string ":",
1500 Print.space,
1501 p_exp e,
1502 Print.space,
1503 Print.PD.string "in",
1504 Print.space,
1505 p_prop p])
1506 (List.take (#3 st', length (#3 st')
1507 - length (#3 st))))]*)
1466 1508
1467 val this = And (removeRedundant orig (#2 st'), Reln (Eq, [Var r, pe])) 1509 val this = And (removeRedundant orig (#2 st'), Reln (Eq, [Var r, pe]))
1468 in 1510 in
1469 (#1 st', Or (#2 st, this), #3 st') 1511 (#1 st', Or (#2 st, this), #3 st')
1470 end) (#1 st, False, #3 st) pes 1512 end) (#1 st, False, #3 st) pes
1526 val acc = #1 st + 1 1568 val acc = #1 st + 1
1527 val st' = (#1 st + 2, #2 st, #3 st) 1569 val st' = (#1 st + 2, #2 st, #3 st)
1528 1570
1529 val (b, st') = evalExp (Var acc :: Var r :: env) (b, st') 1571 val (b, st') = evalExp (Var acc :: Var r :: env) (b, st')
1530 1572
1531 val (rvN, count, qp, used) = 1573 val (rvN, qp, used) =
1532 queryProp env 1574 queryProp env
1533 (#1 st') (fn rvN => (rvN + 1, Var rvN)) 1575 (#1 st') (fn rvN => (rvN + 1, Var rvN))
1534 (AllCols (Var r)) q 1576 (AllCols (Var r)) q
1535 1577
1536 val p' = And (qp, #2 st') 1578 val p' = And (qp, #2 st')
1541 let 1583 let
1542 val out = rvN 1584 val out = rvN
1543 1585
1544 val p = Or (Reln (Eq, [Var out, i]), 1586 val p = Or (Reln (Eq, [Var out, i]),
1545 And (Reln (Eq, [Var out, b]), 1587 And (Reln (Eq, [Var out, b]),
1546 And (Reln (Gt, [count, 1588 p'))
1547 Const (Prim.Int 0)]),
1548 p')))
1549 in 1589 in
1550 (out + 1, p, Var out) 1590 (out + 1, p, Var out)
1551 end 1591 end
1552 1592
1553 val sent = map (fn (loc, e, p) => (loc, e, And (qp, p))) (#3 st') 1593 val sent = map (fn (loc, e, p) => (loc, e, And (qp, p))) (#3 st')
1577 let 1617 let
1578 val file = MonoReduce.reduce file 1618 val file = MonoReduce.reduce file
1579 val file = MonoOpt.optimize file 1619 val file = MonoOpt.optimize file
1580 val file = Fuse.fuse file 1620 val file = Fuse.fuse file
1581 val file = MonoOpt.optimize file 1621 val file = MonoOpt.optimize file
1622 val file = MonoShake.shake file
1582 (*val () = Print.preface ("File", MonoPrint.p_file MonoEnv.empty file)*) 1623 (*val () = Print.preface ("File", MonoPrint.p_file MonoEnv.empty file)*)
1583 1624
1584 val exptd = foldl (fn ((d, _), exptd) => 1625 val exptd = foldl (fn ((d, _), exptd) =>
1585 case d of 1626 case d of
1586 DExport (_, _, n, _, _, _) => IS.add (exptd, n) 1627 DExport (_, _, n, _, _, _) => IS.add (exptd, n)
1606 val (e, (_, p, sent)) = evalExp env (e, (nv, p, [])) 1647 val (e, (_, p, sent)) = evalExp env (e, (nv, p, []))
1607 in 1648 in
1608 (sent @ vals, pols) 1649 (sent @ vals, pols)
1609 end 1650 end
1610 1651
1611 | DPolicy (PolClient e) => (vals, #3 (queryProp [] 0 (fn rvN => (rvN + 1, Lvar rvN)) 1652 | DPolicy (PolClient e) => (vals, #2 (queryProp [] 0 (fn rvN => (rvN + 1, Lvar rvN))
1612 (SomeCol (Var 0)) e) :: pols) 1653 (SomeCol (Var 0)) e) :: pols)
1613 1654
1614 | _ => (vals, pols) 1655 | _ => (vals, pols)
1615 1656
1616 val () = reset () 1657 val () = reset ()
1634 else 1675 else
1635 false) pols then 1676 false) pols then
1636 () 1677 ()
1637 else 1678 else
1638 (ErrorMsg.errorAt loc "The information flow policy may be violated here."; 1679 (ErrorMsg.errorAt loc "The information flow policy may be violated here.";
1639 Print.preface ("The state satisifes this predicate:", p_prop p)) 1680 Print.preface ("The state satisifies this predicate:", p_prop p))
1640 end 1681 end
1641 1682
1642 fun doAll e = 1683 fun doAll e =
1643 case e of 1684 case e of
1644 Const _ => () 1685 Const _ => ()
1645 | Var _ => doOne e 1686 | Var _ => doOne e
1646 | Lvar _ => raise Fail "Iflow.doAll: Lvar" 1687 | Lvar _ => raise Fail "Iflow.doAll: Lvar"
1647 | Func (UnCon _, [e]) => doOne e 1688 | Func (UnCon _, [_]) => doOne e
1648 | Func (_, es) => app doAll es 1689 | Func (_, es) => app doAll es
1649 | Recd xes => app (doAll o #2) xes 1690 | Recd xes => app (doAll o #2) xes
1650 | Proj _ => doOne e 1691 | Proj _ => doOne e
1651 | Finish => () 1692 | Finish => ()
1652 in 1693 in