Mercurial > urweb
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 |