Mercurial > urweb
comparison src/iflow.sml @ 1238:d6938ab3b5ae
Get refurbished Iflow working with calendar
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Wed, 14 Apr 2010 09:18:16 -0400 |
parents | a9c200f73f24 |
children | 30f789d5e2ad |
comparison
equal
deleted
inserted
replaced
1237:a9c200f73f24 | 1238:d6938ab3b5ae |
---|---|
241 val assert : database * atom -> unit | 241 val assert : database * atom -> unit |
242 val check : database * atom -> bool | 242 val check : database * atom -> bool |
243 | 243 |
244 val p_database : database Print.printer | 244 val p_database : database Print.printer |
245 | 245 |
246 val builtFrom : database * {Base : exp list, Derived : exp} -> bool | 246 val builtFrom : database * {UseKnown : bool, Base : exp list, Derived : exp} -> bool |
247 | 247 |
248 val p_repOf : database -> exp Print.printer | 248 val p_repOf : database -> exp Print.printer |
249 end = struct | 249 end = struct |
250 | 250 |
251 exception Contradiction | 251 exception Contradiction |
708 in | 708 in |
709 repOf r1 = repOf r2 | 709 repOf r1 = repOf r2 |
710 end | 710 end |
711 | _ => false | 711 | _ => false |
712 | 712 |
713 fun builtFrom (db, {Base = bs, Derived = d}) = | 713 fun builtFrom (db, {UseKnown = uk, Base = bs, Derived = d}) = |
714 let | 714 let |
715 val bs = map (fn b => representative (db, b)) bs | 715 val bs = map (fn b => representative (db, b)) bs |
716 | 716 |
717 fun loop d = | 717 fun loop d = |
718 let | 718 let |
719 val d = repOf d | 719 val d = repOf d |
720 in | 720 in |
721 List.exists (fn b => repOf b = d) bs | 721 (uk andalso !(#Known (unNode d))) |
722 orelse List.exists (fn b => repOf b = d) bs | |
722 orelse case #Variety (unNode d) of | 723 orelse case #Variety (unNode d) of |
723 Dt0 _ => true | 724 Dt0 _ => true |
724 | Dt1 (_, d) => loop d | 725 | Dt1 (_, d) => loop d |
725 | Prim _ => true | 726 | Prim _ => true |
726 | Recrd (xes, _) => List.all loop (SM.listItems (!xes)) | 727 | Recrd (xes, _) => List.all loop (SM.listItems (!xes)) |
727 | Nothing => false | 728 | Nothing => false |
728 end | 729 end |
730 | |
731 fun decomp e = | |
732 case e of | |
733 Func (Other _, es) => List.all decomp es | |
734 | _ => loop (representative (db, e)) | |
729 in | 735 in |
730 loop (representative (db, d)) | 736 decomp d |
731 end | 737 end |
732 | 738 |
733 end | 739 end |
734 | 740 |
735 val tabs = ref (SM.empty : (string list * string list list) SM.map) | 741 val tabs = ref (SM.empty : (string list * string list list) SM.map) |
1160 val assert : atom list -> unit | 1166 val assert : atom list -> unit |
1161 | 1167 |
1162 val addPath : check -> unit | 1168 val addPath : check -> unit |
1163 | 1169 |
1164 val allowSend : atom list * exp list -> unit | 1170 val allowSend : atom list * exp list -> unit |
1165 val send : check -> unit | 1171 val send : bool -> check -> unit |
1166 | 1172 |
1167 val allowInsert : atom list -> unit | 1173 val allowInsert : atom list -> unit |
1168 val insert : ErrorMsg.span -> unit | 1174 val insert : ErrorMsg.span -> unit |
1169 | 1175 |
1170 val allowDelete : atom list -> unit | 1176 val allowDelete : atom list -> unit |
1172 | 1178 |
1173 val allowUpdate : atom list -> unit | 1179 val allowUpdate : atom list -> unit |
1174 val update : ErrorMsg.span -> unit | 1180 val update : ErrorMsg.span -> unit |
1175 | 1181 |
1176 val havocReln : reln -> unit | 1182 val havocReln : reln -> unit |
1183 | |
1184 val debug : unit -> unit | |
1177 end = struct | 1185 end = struct |
1178 | 1186 |
1179 val hnames = ref 1 | 1187 val hnames = ref 1 |
1180 | 1188 |
1181 type hyps = int * atom list | 1189 type hyps = int * atom list |
1182 | 1190 |
1183 val db = Cc.database () | 1191 val db = Cc.database () |
1184 val path = ref ([] : (hyps * check) option ref list) | 1192 val path = ref ([] : (hyps * check) option ref list) |
1185 val hyps = ref (0, [] : atom list) | 1193 val hyps = ref (0, [] : atom list) |
1186 val nvar = ref 0 | 1194 val nvar = ref 0 |
1187 | |
1188 fun reset () = (Cc.clear db; | |
1189 path := []; | |
1190 hyps := (0, []); | |
1191 nvar := 0) | |
1192 | 1195 |
1193 fun setHyps (h as (n', hs)) = | 1196 fun setHyps (h as (n', hs)) = |
1194 let | 1197 let |
1195 val (n, _) = !hyps | 1198 val (n, _) = !hyps |
1196 in | 1199 in |
1229 | 1232 |
1230 fun addPath c = path := ref (SOME (!hyps, c)) :: !path | 1233 fun addPath c = path := ref (SOME (!hyps, c)) :: !path |
1231 | 1234 |
1232 val sendable = ref ([] : (atom list * exp list) list) | 1235 val sendable = ref ([] : (atom list * exp list) list) |
1233 | 1236 |
1234 fun checkGoals goals unifs succ fail = | 1237 fun checkGoals goals k = |
1235 case goals of | |
1236 [] => succ (unifs, []) | |
1237 | AReln (Sql tab, [Lvar lv]) :: goals => | |
1238 let | |
1239 val saved = stash () | |
1240 val (_, hyps) = !hyps | |
1241 | |
1242 fun tryAll unifs hyps = | |
1243 case hyps of | |
1244 [] => fail () | |
1245 | AReln (Sql tab', [e]) :: hyps => | |
1246 if tab' = tab then | |
1247 checkGoals goals (IM.insert (unifs, lv, e)) succ | |
1248 (fn () => tryAll unifs hyps) | |
1249 else | |
1250 tryAll unifs hyps | |
1251 | _ :: hyps => tryAll unifs hyps | |
1252 in | |
1253 tryAll unifs hyps | |
1254 end | |
1255 | AReln (r, es) :: goals => checkGoals goals unifs | |
1256 (fn (unifs, ls) => succ (unifs, AReln (r, map (simplify unifs) es) :: ls)) | |
1257 fail | |
1258 | ACond _ :: _ => fail () | |
1259 | |
1260 fun buildable (e, loc) = | |
1261 let | 1238 let |
1262 fun doPols pols acc fail = | 1239 fun checkGoals goals unifs = |
1240 case goals of | |
1241 [] => k unifs | |
1242 | AReln (Sql tab, [Lvar lv]) :: goals => | |
1243 let | |
1244 val saved = stash () | |
1245 val (_, hyps) = !hyps | |
1246 | |
1247 fun tryAll unifs hyps = | |
1248 case hyps of | |
1249 [] => false | |
1250 | AReln (Sql tab', [e]) :: hyps => | |
1251 (tab' = tab andalso | |
1252 checkGoals goals (IM.insert (unifs, lv, e))) | |
1253 orelse tryAll unifs hyps | |
1254 | _ :: hyps => tryAll unifs hyps | |
1255 in | |
1256 tryAll unifs hyps | |
1257 end | |
1258 | AReln (r, es) :: goals => | |
1259 Cc.check (db, AReln (r, map (simplify unifs) es)) | |
1260 andalso checkGoals goals unifs | |
1261 | ACond _ :: _ => false | |
1262 in | |
1263 checkGoals goals IM.empty | |
1264 end | |
1265 | |
1266 fun useKeys () = | |
1267 let | |
1268 fun findKeys hyps = | |
1269 case hyps of | |
1270 [] => () | |
1271 | AReln (Sql tab, [r1]) :: hyps => | |
1272 (case SM.find (!tabs, tab) of | |
1273 NONE => findKeys hyps | |
1274 | SOME (_, []) => findKeys hyps | |
1275 | SOME (_, ks) => | |
1276 let | |
1277 fun finder hyps = | |
1278 case hyps of | |
1279 [] => () | |
1280 | AReln (Sql tab', [r2]) :: hyps => | |
1281 (if tab' = tab andalso | |
1282 List.exists (List.all (fn f => | |
1283 let | |
1284 val r = | |
1285 Cc.check (db, | |
1286 AReln (Eq, [Proj (r1, f), | |
1287 Proj (r2, f)])) | |
1288 in | |
1289 (*Print.prefaces "Fs" | |
1290 [("tab", | |
1291 Print.PD.string tab), | |
1292 ("r1", | |
1293 p_exp (Proj (r1, f))), | |
1294 ("r2", | |
1295 p_exp (Proj (r2, f))), | |
1296 ("r", | |
1297 Print.PD.string | |
1298 (Bool.toString r))];*) | |
1299 r | |
1300 end)) ks then | |
1301 ((*Print.prefaces "Key match" [("tab", Print.PD.string tab), | |
1302 ("r1", p_exp r1), | |
1303 ("r2", p_exp r2), | |
1304 ("rp1", Cc.p_repOf cc r1), | |
1305 ("rp2", Cc.p_repOf cc r2)];*) | |
1306 Cc.assert (db, AReln (Eq, [r1, r2]))) | |
1307 else | |
1308 (); | |
1309 finder hyps) | |
1310 | _ :: hyps => finder hyps | |
1311 in | |
1312 finder hyps; | |
1313 findKeys hyps | |
1314 end) | |
1315 | _ :: hyps => findKeys hyps | |
1316 | |
1317 val (_, hs) = !hyps | |
1318 in | |
1319 (*print "findKeys\n";*) | |
1320 findKeys hs | |
1321 end | |
1322 | |
1323 fun buildable uk (e, loc) = | |
1324 let | |
1325 fun doPols pols acc = | |
1263 case pols of | 1326 case pols of |
1264 [] => ((*Print.prefaces "buildable" [("Base", Print.p_list p_exp acc), | 1327 [] => ((*Print.prefaces "buildable" [("Base", Print.p_list p_exp acc), |
1265 ("Derived", p_exp e), | 1328 ("Derived", p_exp e), |
1266 ("Hyps", Print.p_list p_atom (#2 (!hyps)))];*) | 1329 ("Hyps", Print.p_list p_atom (#2 (!hyps)))];*) |
1267 if Cc.builtFrom (db, {Base = acc, Derived = e}) then | 1330 Cc.builtFrom (db, {UseKnown = uk, Base = acc, Derived = e})) |
1268 () | |
1269 else | |
1270 fail ()) | |
1271 | (goals, es) :: pols => | 1331 | (goals, es) :: pols => |
1272 checkGoals goals IM.empty | 1332 checkGoals goals (fn unifs => doPols pols (map (simplify unifs) es @ acc)) |
1273 (fn (unifs, goals) => | 1333 orelse doPols pols acc |
1274 if List.all (fn a => Cc.check (db, a)) goals then | |
1275 doPols pols (map (simplify unifs) es @ acc) fail | |
1276 else | |
1277 doPols pols acc fail) | |
1278 (fn () => doPols pols acc fail) | |
1279 in | 1334 in |
1280 doPols (!sendable) [] | 1335 useKeys (); |
1281 (fn () => let | 1336 if doPols (!sendable) [] then |
1282 val (_, hs) = !hyps | 1337 () |
1283 in | 1338 else |
1284 ErrorMsg.errorAt loc "The information flow policy may be violated here."; | 1339 let |
1285 Print.prefaces "Situation" [("Hypotheses", Print.p_list p_atom hs), | 1340 val (_, hs) = !hyps |
1286 ("User learns", p_exp e)] | 1341 in |
1287 end) | 1342 ErrorMsg.errorAt loc "The information flow policy may be violated here."; |
1343 Print.prefaces "Situation" [("Hypotheses", Print.p_list p_atom hs), | |
1344 ("User learns", p_exp e)] | |
1345 end | |
1288 end | 1346 end |
1289 | 1347 |
1290 fun checkPaths () = | 1348 fun checkPaths () = |
1291 let | 1349 let |
1292 val hs = !hyps | 1350 val hs = !hyps |
1295 case !r of | 1353 case !r of |
1296 NONE => () | 1354 NONE => () |
1297 | SOME (hs, e) => | 1355 | SOME (hs, e) => |
1298 (r := NONE; | 1356 (r := NONE; |
1299 setHyps hs; | 1357 setHyps hs; |
1300 buildable e)) (!path); | 1358 buildable true e)) (!path); |
1301 setHyps hs | 1359 setHyps hs |
1302 end | 1360 end |
1303 | 1361 |
1304 fun allowSend v = sendable := v :: !sendable | 1362 fun allowSend v = ((*Print.prefaces "Allow" [("goals", Print.p_list p_atom (#1 v)), |
1305 | 1363 ("exps", Print.p_list p_exp (#2 v))];*) |
1306 fun send (e, loc) = ((*Print.preface ("Send", p_exp e);*) | 1364 sendable := v :: !sendable) |
1307 checkPaths (); | 1365 |
1308 if isKnown e then | 1366 fun send uk (e, loc) = ((*Print.preface ("Send", p_exp e);*) |
1309 () | 1367 checkPaths (); |
1310 else | 1368 if isKnown e then |
1311 buildable (e, loc)) | 1369 () |
1370 else | |
1371 buildable uk (e, loc)) | |
1312 | 1372 |
1313 fun doable pols (loc : ErrorMsg.span) = | 1373 fun doable pols (loc : ErrorMsg.span) = |
1314 let | 1374 let |
1315 val pols = !pols | 1375 val pols = !pols |
1316 in | 1376 in |
1317 if List.exists (fn goals => | 1377 if List.exists (fn goals => |
1318 checkGoals goals IM.empty | 1378 if checkGoals goals (fn _ => true) then |
1319 (fn (_, goals) => List.all (fn a => Cc.check (db, a)) goals) | 1379 ((*Print.prefaces "Match" [("goals", Print.p_list p_atom goals), |
1320 (fn () => false)) pols then | 1380 ("hyps", Print.p_list p_atom (#2 (!hyps)))];*) |
1381 true) | |
1382 else | |
1383 ((*Print.prefaces "No match" [("goals", Print.p_list p_atom goals), | |
1384 ("hyps", Print.p_list p_atom (#2 (!hyps)))];*) | |
1385 false)) pols then | |
1321 () | 1386 () |
1322 else | 1387 else |
1323 let | 1388 let |
1324 val (_, hs) = !hyps | 1389 val (_, hs) = !hyps |
1325 in | 1390 in |
1338 | 1403 |
1339 val deletable = ref ([] : atom list list) | 1404 val deletable = ref ([] : atom list list) |
1340 fun allowDelete v = deletable := v :: !deletable | 1405 fun allowDelete v = deletable := v :: !deletable |
1341 val delete = doable deletable | 1406 val delete = doable deletable |
1342 | 1407 |
1408 fun reset () = (Cc.clear db; | |
1409 path := []; | |
1410 hyps := (0, []); | |
1411 nvar := 0; | |
1412 sendable := []; | |
1413 insertable := []; | |
1414 updatable := []; | |
1415 deletable := []) | |
1416 | |
1343 fun havocReln r = | 1417 fun havocReln r = |
1344 let | 1418 let |
1345 val n = !hnames | 1419 val n = !hnames |
1346 val (_, hs) = !hyps | 1420 val (_, hs) = !hyps |
1347 in | 1421 in |
1348 hnames := n + 1; | 1422 hnames := n + 1; |
1349 hyps := (n, List.filter (fn AReln (r', _) => r' <> r | _ => true) hs) | 1423 hyps := (n, List.filter (fn AReln (r', _) => r' <> r | _ => true) hs) |
1424 end | |
1425 | |
1426 fun debug () = | |
1427 let | |
1428 val (_, hs) = !hyps | |
1429 in | |
1430 Print.preface ("Hyps", Print.p_list p_atom hs) | |
1350 end | 1431 end |
1351 | 1432 |
1352 end | 1433 end |
1353 | 1434 |
1354 | 1435 |
1411 | 1492 |
1412 fun decomp {Save = save, Restore = restore, Add = add} = | 1493 fun decomp {Save = save, Restore = restore, Add = add} = |
1413 let | 1494 let |
1414 fun go p k = | 1495 fun go p k = |
1415 case p of | 1496 case p of |
1416 True => k () | 1497 True => (k () handle Cc.Contradiction => ()) |
1417 | False => () | 1498 | False => () |
1418 | Unknown => () | 1499 | Unknown => () |
1419 | And (p1, p2) => go p1 (fn () => go p2 k) | 1500 | And (p1, p2) => go p1 (fn () => go p2 k) |
1420 | Or (p1, p2) => | 1501 | Or (p1, p2) => |
1421 let | 1502 let |
1430 in | 1511 in |
1431 go | 1512 go |
1432 end | 1513 end |
1433 | 1514 |
1434 datatype queryMode = | 1515 datatype queryMode = |
1435 SomeCol of exp list -> unit | 1516 SomeCol of {New : (string * exp) option, Old : (string * exp) option, Outs : exp list} -> unit |
1436 | AllCols of exp -> unit | 1517 | AllCols of exp -> unit |
1437 | 1518 |
1438 type 'a doQuery = { | 1519 type 'a doQuery = { |
1439 Env : exp list, | 1520 Env : exp list, |
1440 NextVar : unit -> exp, | 1521 NextVar : unit -> exp, |
1456 let | 1537 let |
1457 fun doQuery q = | 1538 fun doQuery q = |
1458 case q of | 1539 case q of |
1459 Query1 r => | 1540 Query1 r => |
1460 let | 1541 let |
1461 val rvs = map (fn (_, v) => (v, #NextVar arg ())) (#From r) | 1542 val new = ref NONE |
1543 val old = ref NONE | |
1544 | |
1545 val rvs = map (fn (tab, v) => | |
1546 let | |
1547 val nv = #NextVar arg () | |
1548 in | |
1549 case v of | |
1550 "New" => new := SOME (tab, nv) | |
1551 | "Old" => old := SOME (tab, nv) | |
1552 | _ => (); | |
1553 (v, nv) | |
1554 end) (#From r) | |
1462 | 1555 |
1463 fun rvOf v = | 1556 fun rvOf v = |
1464 case List.find (fn (v', _) => v' = v) rvs of | 1557 case List.find (fn (v', _) => v' = v) rvs of |
1465 NONE => raise Fail "Iflow.queryProp: Bad table variable" | 1558 NONE => raise Fail "Iflow.queryProp: Bad table variable" |
1466 | SOME (_, e) => e | 1559 | SOME (_, e) => e |
1498 | SqExp (e, f) => | 1591 | SqExp (e, f) => |
1499 case expIn e of | 1592 case expIn e of |
1500 inr _ => #NextVar arg () | 1593 inr _ => #NextVar arg () |
1501 | inl e => e) (#Select r) | 1594 | inl e => e) (#Select r) |
1502 in | 1595 in |
1503 k sis | 1596 k {New = !new, Old = !old, Outs = sis} |
1504 end | 1597 end |
1505 | AllCols k => | 1598 | AllCols k => |
1506 let | 1599 let |
1507 val (ts, es) = | 1600 val (ts, es) = |
1508 foldl (fn (si, (ts, es)) => | 1601 foldl (fn (si, (ts, es)) => |
1556 SomeCol _ => () | 1649 SomeCol _ => () |
1557 | AllCols k => | 1650 | AllCols k => |
1558 let | 1651 let |
1559 fun answer e = k (Recd [(f, e)]) | 1652 fun answer e = k (Recd [(f, e)]) |
1560 | 1653 |
1561 val () = answer (Func (DtCon0 "Basis.bool.False", [])) | |
1562 val saved = #Save arg () | 1654 val saved = #Save arg () |
1655 val () = (answer (Func (DtCon0 "Basis.bool.False", []))) | |
1656 handle Cc.Contradiction => () | |
1563 in | 1657 in |
1658 #Restore arg saved; | |
1659 (*print "True time!\n";*) | |
1564 doWhere (fn () => answer (Func (DtCon0 "Basis.bool.True", []))); | 1660 doWhere (fn () => answer (Func (DtCon0 "Basis.bool.True", []))); |
1565 #Restore arg saved | 1661 #Restore arg saved |
1566 end) | 1662 end) |
1567 | _ => normal ()) | 1663 | _ => normal ()) |
1568 | _ => normal ()) | 1664 | _ => normal ()) |
1606 env | 1702 env |
1607 end | 1703 end |
1608 | 1704 |
1609 fun evalExp env (e as (_, loc)) k = | 1705 fun evalExp env (e as (_, loc)) k = |
1610 let | 1706 let |
1707 (*val () = St.debug ()*) | |
1611 (*val () = Print.preface ("evalExp", MonoPrint.p_exp MonoEnv.empty e)*) | 1708 (*val () = Print.preface ("evalExp", MonoPrint.p_exp MonoEnv.empty e)*) |
1612 | 1709 |
1613 fun default () = k (Var (St.nextVar ())) | 1710 fun default () = k (Var (St.nextVar ())) |
1614 | 1711 |
1615 fun doFfi (m, s, es) = | 1712 fun doFfi (m, s, es) = |
1617 let | 1714 let |
1618 fun doArgs es = | 1715 fun doArgs es = |
1619 case es of | 1716 case es of |
1620 [] => k (Recd []) | 1717 [] => k (Recd []) |
1621 | e :: es => | 1718 | e :: es => |
1622 evalExp env e (fn e => (St.send (e, loc); doArgs es)) | 1719 evalExp env e (fn e => (St.send true (e, loc); doArgs es)) |
1623 in | 1720 in |
1624 doArgs es | 1721 doArgs es |
1625 end | 1722 end |
1626 else if Settings.isEffectful (m, s) andalso not (Settings.isBenignEffectful (m, s)) then | 1723 else if Settings.isEffectful (m, s) andalso not (Settings.isBenignEffectful (m, s)) then |
1627 default () | 1724 default () |
1671 val () = St.addPath (e, loc) | 1768 val () = St.addPath (e, loc) |
1672 in | 1769 in |
1673 app (fn (p, pe) => | 1770 app (fn (p, pe) => |
1674 let | 1771 let |
1675 val saved = St.stash () | 1772 val saved = St.stash () |
1676 | |
1677 val env = evalPat env e p | |
1678 in | 1773 in |
1679 evalExp env pe k; | 1774 let |
1680 St.reinstate saved | 1775 val env = evalPat env e p |
1776 in | |
1777 evalExp env pe k; | |
1778 St.reinstate saved | |
1779 end | |
1780 handle Cc.Contradiction => St.reinstate saved | |
1681 end) pes | 1781 end) pes |
1682 end handle Cc.Contradiction => ()) | 1782 end) |
1683 | EStrcat (e1, e2) => | 1783 | EStrcat (e1, e2) => |
1684 evalExp env e1 (fn e1 => | 1784 evalExp env e1 (fn e1 => |
1685 evalExp env e2 (fn e2 => | 1785 evalExp env e2 (fn e2 => |
1686 k (Func (Other "cat", [e1, e2])))) | 1786 k (Func (Other "cat", [e1, e2])))) |
1687 | EError (e, _) => evalExp env e (fn e => St.send (e, loc)) | 1787 | EError (e, _) => evalExp env e (fn e => St.send true (e, loc)) |
1688 | EReturnBlob {blob = b, mimeType = m, ...} => | 1788 | EReturnBlob {blob = b, mimeType = m, ...} => |
1689 evalExp env b (fn b => | 1789 evalExp env b (fn b => |
1690 (St.send (b, loc); | 1790 (St.send true (b, loc); |
1691 evalExp env m | 1791 evalExp env m |
1692 (fn m => St.send (m, loc)))) | 1792 (fn m => St.send true (m, loc)))) |
1693 | ERedirect (e, _) => | 1793 | ERedirect (e, _) => |
1694 evalExp env e (fn e => St.send (e, loc)) | 1794 evalExp env e (fn e => St.send true (e, loc)) |
1695 | EWrite e => | 1795 | EWrite e => |
1696 evalExp env e (fn e => (St.send (e, loc); | 1796 evalExp env e (fn e => (St.send true (e, loc); |
1697 k (Recd []))) | 1797 k (Recd []))) |
1698 | ESeq (e1, e2) => | 1798 | ESeq (e1, e2) => |
1699 evalExp env e1 (fn _ => evalExp env e2 k) | 1799 evalExp env e1 (fn _ => evalExp env e2 k) |
1700 | ELet (_, _, e1, e2) => | 1800 | ELet (_, _, e1, e2) => |
1701 evalExp env e1 (fn e1 => evalExp (e1 :: env) e2 k) | 1801 evalExp env e1 (fn e1 => evalExp (e1 :: env) e2 k) |
1709 in | 1809 in |
1710 doArgs (es, []) | 1810 doArgs (es, []) |
1711 end | 1811 end |
1712 | 1812 |
1713 | EQuery {query = q, body = b, initial = i, state = state, ...} => | 1813 | EQuery {query = q, body = b, initial = i, state = state, ...} => |
1714 evalExp env q (fn _ => | 1814 evalExp env i (fn i => |
1715 evalExp env i (fn i => | 1815 let |
1716 let | 1816 val saved = St.stash () |
1717 val saved = St.stash () | 1817 |
1718 | 1818 val () = (k i) |
1719 val r = Var (St.nextVar ()) | 1819 handle Cc.Contradiction => () |
1720 val acc = Var (St.nextVar ()) | 1820 val () = St.reinstate saved |
1721 in | 1821 |
1722 if MonoUtil.Exp.existsB {typ = fn _ => false, | 1822 val r = Var (St.nextVar ()) |
1723 exp = fn (n, e) => | 1823 val acc = Var (St.nextVar ()) |
1724 case e of | 1824 in |
1725 ERel n' => n' = n | 1825 if MonoUtil.Exp.existsB {typ = fn _ => false, |
1726 | _ => false, | 1826 exp = fn (n, e) => |
1727 bind = fn (n, b) => | 1827 case e of |
1728 case b of | 1828 ERel n' => n' = n |
1729 MonoUtil.Exp.RelE _ => n + 1 | 1829 | _ => false, |
1730 | _ => n} | 1830 bind = fn (n, b) => |
1731 0 b then | 1831 case b of |
1732 doQuery {Env = env, | 1832 MonoUtil.Exp.RelE _ => n + 1 |
1733 NextVar = Var o St.nextVar, | 1833 | _ => n} |
1734 Add = fn a => St.assert [a], | 1834 0 b then |
1735 Save = St.stash, | 1835 doQuery {Env = env, |
1736 Restore = St.reinstate, | 1836 NextVar = Var o St.nextVar, |
1737 UsedExp = fn e => St.send (e, loc), | 1837 Add = fn a => St.assert [a], |
1738 Cont = AllCols (fn _ => (St.reinstate saved; | 1838 Save = St.stash, |
1739 evalExp | 1839 Restore = St.reinstate, |
1740 (acc :: r :: env) | 1840 UsedExp = fn e => St.send false (e, loc), |
1741 b (fn _ => default ())))} q | 1841 Cont = AllCols (fn _ => evalExp |
1742 else | 1842 (acc :: r :: env) |
1743 doQuery {Env = env, | 1843 b (fn _ => default ()))} q |
1744 NextVar = Var o St.nextVar, | 1844 else |
1745 Add = fn a => St.assert [a], | 1845 doQuery {Env = env, |
1746 Save = St.stash, | 1846 NextVar = Var o St.nextVar, |
1747 Restore = St.reinstate, | 1847 Add = fn a => St.assert [a], |
1748 UsedExp = fn e => St.send (e, loc), | 1848 Save = St.stash, |
1749 Cont = AllCols (fn x => | 1849 Restore = St.reinstate, |
1750 (St.assert [AReln (Eq, [r, x])]; | 1850 UsedExp = fn e => St.send false (e, loc), |
1751 evalExp (acc :: r :: env) b k))} q | 1851 Cont = AllCols (fn x => |
1752 end)) | 1852 (St.assert [AReln (Eq, [r, x])]; |
1853 evalExp (acc :: r :: env) b k))} q | |
1854 end) | |
1753 | EDml e => | 1855 | EDml e => |
1754 (case parse dml e of | 1856 (case parse dml e of |
1755 NONE => (print ("Warning: Information flow checker can't parse DML command at " | 1857 NONE => (print ("Warning: Information flow checker can't parse DML command at " |
1756 ^ ErrorMsg.spanToString loc ^ "\n"); | 1858 ^ ErrorMsg.spanToString loc ^ "\n"); |
1757 default ()) | 1859 default ()) |
1789 inl e => raise Fail "Iflow.evalExp: DELETE with non-boolean" | 1891 inl e => raise Fail "Iflow.evalExp: DELETE with non-boolean" |
1790 | inr p => p | 1892 | inr p => p |
1791 | 1893 |
1792 val saved = St.stash () | 1894 val saved = St.stash () |
1793 in | 1895 in |
1794 St.assert [AReln (Sql "$Old", [Var old]), | 1896 St.assert [AReln (Sql (tab ^ "$Old"), [Var old])]; |
1795 AReln (Sql tab, [Var old])]; | |
1796 decomp {Save = St.stash, | 1897 decomp {Save = St.stash, |
1797 Restore = St.reinstate, | 1898 Restore = St.reinstate, |
1798 Add = fn a => St.assert [a]} p | 1899 Add = fn a => St.assert [a]} p |
1799 (fn () => (St.delete loc; | 1900 (fn () => (St.delete loc; |
1800 St.reinstate saved; | 1901 St.reinstate saved; |
1834 inl e => raise Fail "Iflow.evalExp: UPDATE with non-boolean" | 1935 inl e => raise Fail "Iflow.evalExp: UPDATE with non-boolean" |
1835 | inr p => p | 1936 | inr p => p |
1836 val saved = St.stash () | 1937 val saved = St.stash () |
1837 in | 1938 in |
1838 St.assert [AReln (Sql (tab ^ "$New"), [Recd fs]), | 1939 St.assert [AReln (Sql (tab ^ "$New"), [Recd fs]), |
1839 AReln (Sql "$Old", [Var old]), | 1940 AReln (Sql (tab ^ "$Old"), [Var old])]; |
1840 AReln (Sql tab, [Var old])]; | |
1841 decomp {Save = St.stash, | 1941 decomp {Save = St.stash, |
1842 Restore = St.reinstate, | 1942 Restore = St.reinstate, |
1843 Add = fn a => St.assert [a]} p | 1943 Add = fn a => St.assert [a]} p |
1844 (fn () => (St.update loc; | 1944 (fn () => (St.update loc; |
1845 St.reinstate saved; | 1945 St.reinstate saved; |
1856 k (Var nv) | 1956 k (Var nv) |
1857 end | 1957 end |
1858 | ENextval _ => default () | 1958 | ENextval _ => default () |
1859 | ESetval _ => default () | 1959 | ESetval _ => default () |
1860 | 1960 |
1861 | EUnurlify ((EFfiApp ("Basis", "get_cookie", _), _), _, _) => | 1961 | EUnurlify ((EFfiApp ("Basis", "get_cookie", [(EPrim (Prim.String cname), _)]), _), _, _) => |
1862 let | 1962 let |
1863 val nv = St.nextVar () | 1963 val e = Var (St.nextVar ()) |
1864 in | 1964 in |
1865 St.assert [AReln (Known, [Var nv])]; | 1965 St.assert [AReln (Known, [e])]; |
1866 k (Var nv) | 1966 k e |
1867 end | 1967 end |
1868 | 1968 |
1869 | EUnurlify _ => default () | 1969 | EUnurlify _ => default () |
1870 | EJavaScript _ => default () | 1970 | EJavaScript _ => default () |
1871 | ESignalReturn _ => default () | 1971 | ESignalReturn _ => default () |
1911 map (map (fn s => str (Char.toUpper (String.sub (s, 3))) | 2011 map (map (fn s => str (Char.toUpper (String.sub (s, 3))) |
1912 ^ String.extract (s, 4, NONE))) ks)) | 2012 ^ String.extract (s, 4, NONE))) ks)) |
1913 else | 2013 else |
1914 raise Fail "Table name does not begin with uw_" | 2014 raise Fail "Table name does not begin with uw_" |
1915 end | 2015 end |
1916 | DVal (_, n, _, e, _) => | 2016 | DVal (x, n, _, e, _) => |
1917 let | 2017 let |
2018 (*val () = print ("\n=== " ^ x ^ " ===\n\n");*) | |
2019 | |
1918 val isExptd = IS.member (exptd, n) | 2020 val isExptd = IS.member (exptd, n) |
1919 | 2021 |
1920 val saved = St.stash () | 2022 val saved = St.stash () |
1921 | 2023 |
1922 fun deAbs (e, env, ps) = | 2024 fun deAbs (e, env, ps) = |
1956 NextVar = rv, | 2058 NextVar = rv, |
1957 Add = fn a => atoms := a :: !atoms, | 2059 Add = fn a => atoms := a :: !atoms, |
1958 Save = fn () => !atoms, | 2060 Save = fn () => !atoms, |
1959 Restore = fn ls => atoms := ls, | 2061 Restore = fn ls => atoms := ls, |
1960 UsedExp = fn _ => (), | 2062 UsedExp = fn _ => (), |
1961 Cont = SomeCol (fn es => k (!atoms, es))} | 2063 Cont = SomeCol (fn r => k (rev (!atoms), r))} |
2064 | |
2065 fun untab tab = List.filter (fn AReln (Sql tab', _) => tab' <> tab | |
2066 | _ => true) | |
1962 in | 2067 in |
1963 case pol of | 2068 case pol of |
1964 PolClient e => | 2069 PolClient e => |
1965 doQ (fn (ats, es) => St.allowSend (ats, es)) e | 2070 doQ (fn (ats, {Outs = es, ...}) => St.allowSend (ats, es)) e |
1966 | PolInsert e => | 2071 | PolInsert e => |
1967 doQ (fn (ats, _) => St.allowInsert ats) e | 2072 doQ (fn (ats, {New = SOME (tab, new), ...}) => |
2073 St.allowInsert (AReln (Sql (tab ^ "$New"), [new]) :: untab tab ats) | |
2074 | _ => raise Fail "Iflow: No New in mayInsert policy") e | |
1968 | PolDelete e => | 2075 | PolDelete e => |
1969 doQ (fn (ats, _) => St.allowDelete ats) e | 2076 doQ (fn (ats, {Old = SOME (tab, old), ...}) => |
2077 St.allowDelete (AReln (Sql (tab ^ "$Old"), [old]) :: untab tab ats) | |
2078 | _ => raise Fail "Iflow: No Old in mayDelete policy") e | |
1970 | PolUpdate e => | 2079 | PolUpdate e => |
1971 doQ (fn (ats, _) => St.allowUpdate ats) e | 2080 doQ (fn (ats, {New = SOME (tab, new), Old = SOME (_, old), ...}) => |
2081 St.allowUpdate (AReln (Sql (tab ^ "$Old"), [old]) | |
2082 :: AReln (Sql (tab ^ "$New"), [new]) | |
2083 :: untab tab ats) | |
2084 | _ => raise Fail "Iflow: No New or Old in mayUpdate policy") e | |
1972 | PolSequence e => | 2085 | PolSequence e => |
1973 (case #1 e of | 2086 (case #1 e of |
1974 EPrim (Prim.String seq) => | 2087 EPrim (Prim.String seq) => |
1975 let | 2088 let |
1976 val p = AReln (Sql (String.extract (seq, 3, NONE)), [Lvar 0]) | 2089 val p = AReln (Sql (String.extract (seq, 3, NONE)), [Lvar 0]) |