Mercurial > urweb
comparison src/iflow.sml @ 1220:526575a9537a
Insert policies
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Sun, 11 Apr 2010 10:57:52 -0400 |
parents | 3224faec752d |
children | 00e628854005 |
comparison
equal
deleted
inserted
replaced
1219:3224faec752d | 1220:526575a9537a |
---|---|
882 [("a", p_atom a), | 882 [("a", p_atom a), |
883 ("hyps", Print.p_list p_atom hyps), | 883 ("hyps", Print.p_list p_atom hyps), |
884 ("db", Cc.p_database cc)];*) | 884 ("db", Cc.p_database cc)];*) |
885 false)) acc | 885 false)) acc |
886 (*andalso (Print.preface ("Finding", Cc.p_database cc); true)*) | 886 (*andalso (Print.preface ("Finding", Cc.p_database cc); true)*) |
887 andalso Cc.builtFrom (cc, {Derived = Var 0, | 887 andalso (case outs of |
888 Base = outs})) | 888 NONE => true |
889 | SOME outs => Cc.builtFrom (cc, {Derived = Var 0, | |
890 Base = outs}))) | |
889 handle Cc.Contradiction => false | 891 handle Cc.Contradiction => false |
890 end handle Cc.Undetermined => false) | 892 end handle Cc.Undetermined => false) |
891 orelse onFail () | 893 orelse onFail () |
892 | (g as AReln (Sql gf, [ge])) :: goals => | 894 | (g as AReln (Sql gf, [ge])) :: goals => |
893 let | 895 let |
1216 | 1218 |
1217 val query = log "query" | 1219 val query = log "query" |
1218 (wrap (follow (follow select from) (opt wher)) | 1220 (wrap (follow (follow select from) (opt wher)) |
1219 (fn ((fs, ts), wher) => {Select = fs, From = ts, Where = wher})) | 1221 (fn ((fs, ts), wher) => {Select = fs, From = ts, Where = wher})) |
1220 | 1222 |
1223 datatype dml = | |
1224 Insert of string * (string * sqexp) list | |
1225 | |
1226 val insert = log "insert" | |
1227 (wrapP (follow (const "INSERT INTO ") | |
1228 (follow uw_ident | |
1229 (follow (const " (") | |
1230 (follow (list uw_ident) | |
1231 (follow (const ") VALUES (") | |
1232 (follow (list sqexp) | |
1233 (const ")"))))))) | |
1234 (fn ((), (tab, ((), (fs, ((), (es, ())))))) => | |
1235 (SOME (Insert (tab, ListPair.zipEq (fs, es)))) | |
1236 handle ListPair.UnequalLengths => NONE)) | |
1237 | |
1238 val dml = log "dml" | |
1239 insert | |
1240 | |
1221 fun removeDups (ls : (string * string) list) = | 1241 fun removeDups (ls : (string * string) list) = |
1222 case ls of | 1242 case ls of |
1223 [] => [] | 1243 [] => [] |
1224 | x :: ls => | 1244 | x :: ls => |
1225 let | 1245 let |
1233 | 1253 |
1234 datatype queryMode = | 1254 datatype queryMode = |
1235 SomeCol | 1255 SomeCol |
1236 | AllCols of exp | 1256 | AllCols of exp |
1237 | 1257 |
1238 exception Default | 1258 fun expIn rv env rvOf = |
1259 let | |
1260 fun expIn (e, rvN) = | |
1261 let | |
1262 fun default () = | |
1263 let | |
1264 val (rvN, e) = rv rvN | |
1265 in | |
1266 (inl e, rvN) | |
1267 end | |
1268 in | |
1269 case e of | |
1270 SqConst p => (inl (Const p), rvN) | |
1271 | Field (v, f) => (inl (Proj (rvOf v, f)), rvN) | |
1272 | Binop (bo, e1, e2) => | |
1273 let | |
1274 val (e1, rvN) = expIn (e1, rvN) | |
1275 val (e2, rvN) = expIn (e2, rvN) | |
1276 in | |
1277 (inr (case (bo, e1, e2) of | |
1278 (Exps f, inl e1, inl e2) => f (e1, e2) | |
1279 | (Props f, inr p1, inr p2) => f (p1, p2) | |
1280 | _ => Unknown), rvN) | |
1281 end | |
1282 | SqKnown e => | |
1283 (case expIn (e, rvN) of | |
1284 (inl e, rvN) => (inr (Reln (Known, [e])), rvN) | |
1285 | _ => (inr Unknown, rvN)) | |
1286 | Inj e => | |
1287 let | |
1288 fun deinj e = | |
1289 case #1 e of | |
1290 ERel n => (List.nth (env, n), rvN) | |
1291 | EField (e, f) => | |
1292 let | |
1293 val (e, rvN) = deinj e | |
1294 in | |
1295 (Proj (e, f), rvN) | |
1296 end | |
1297 | _ => | |
1298 let | |
1299 val (rvN, e) = rv rvN | |
1300 in | |
1301 (e, rvN) | |
1302 end | |
1303 | |
1304 val (e, rvN) = deinj e | |
1305 in | |
1306 (inl e, rvN) | |
1307 end | |
1308 | SqFunc (f, e) => | |
1309 (case expIn (e, rvN) of | |
1310 (inl e, rvN) => (inl (Func (Other f, [e])), rvN) | |
1311 | _ => default ()) | |
1312 | |
1313 | Count => default () | |
1314 end | |
1315 in | |
1316 expIn | |
1317 end | |
1239 | 1318 |
1240 fun queryProp env rvN rv oe e = | 1319 fun queryProp env rvN rv oe e = |
1241 let | 1320 let |
1242 fun default () = (print ("Warning: Information flow checker can't parse SQL query at " | 1321 fun default () = (print ("Warning: Information flow checker can't parse SQL query at " |
1243 ^ ErrorMsg.spanToString (#2 e) ^ "\n"); | 1322 ^ ErrorMsg.spanToString (#2 e) ^ "\n"); |
1270 | Count => [] | 1349 | Count => [] |
1271 | 1350 |
1272 val p = | 1351 val p = |
1273 foldl (fn ((t, v), p) => And (p, Reln (Sql t, [rvOf v]))) True (#From r) | 1352 foldl (fn ((t, v), p) => And (p, Reln (Sql t, [rvOf v]))) True (#From r) |
1274 | 1353 |
1275 fun expIn e = | 1354 val expIn = expIn rv env rvOf |
1276 case e of | 1355 |
1277 SqConst p => inl (Const p) | 1356 val (p, rvN) = case #Where r of |
1278 | Field (v, f) => inl (Proj (rvOf v, f)) | 1357 NONE => (p, rvN) |
1279 | Binop (bo, e1, e2) => | 1358 | SOME e => |
1280 inr (case (bo, expIn e1, expIn e2) of | 1359 case expIn (e, rvN) of |
1281 (Exps f, inl e1, inl e2) => f (e1, e2) | 1360 (inr p', rvN) => (And (p, p'), rvN) |
1282 | (Props f, inr p1, inr p2) => f (p1, p2) | 1361 | _ => (p, rvN) |
1283 | _ => Unknown) | |
1284 | SqKnown e => | |
1285 inr (case expIn e of | |
1286 inl e => Reln (Known, [e]) | |
1287 | _ => Unknown) | |
1288 | Inj e => | |
1289 let | |
1290 fun deinj (e, _) = | |
1291 case e of | |
1292 ERel n => List.nth (env, n) | |
1293 | EField (e, f) => Proj (deinj e, f) | |
1294 | _ => raise Fail "Iflow: non-variable injected into query" | |
1295 in | |
1296 inl (deinj e) | |
1297 end | |
1298 | SqFunc (f, e) => | |
1299 inl (case expIn e of | |
1300 inl e => Func (Other f, [e]) | |
1301 | _ => raise Fail ("Iflow: non-expresion passed to function " ^ f)) | |
1302 | Count => raise Default | |
1303 | |
1304 val p = case #Where r of | |
1305 NONE => p | |
1306 | SOME e => | |
1307 case expIn e of | |
1308 inr p' => And (p, p') | |
1309 | _ => p | |
1310 | 1362 |
1311 fun normal () = | 1363 fun normal () = |
1312 case oe of | 1364 case oe of |
1313 SomeCol => | 1365 SomeCol => |
1314 (rvN, p, True, | 1366 let |
1315 List.mapPartial (fn si => | 1367 val (sis, rvN) = |
1316 case si of | 1368 ListUtil.foldlMap |
1317 SqField (v, f) => SOME (Proj (rvOf v, f)) | 1369 (fn (si, rvN) => |
1318 | SqExp (e, f) => | 1370 case si of |
1319 case expIn e of | 1371 SqField (v, f) => (Proj (rvOf v, f), rvN) |
1320 inr _ => NONE | 1372 | SqExp (e, f) => |
1321 | inl e => SOME e) (#Select r)) | 1373 case expIn (e, rvN) of |
1374 (inr _, _) => | |
1375 let | |
1376 val (rvN, e) = rv rvN | |
1377 in | |
1378 (e, rvN) | |
1379 end | |
1380 | (inl e, rvN) => (e, rvN)) rvN (#Select r) | |
1381 in | |
1382 (rvN, p, True, sis) | |
1383 end | |
1322 | AllCols oe => | 1384 | AllCols oe => |
1323 (rvN, And (p, foldl (fn (si, p) => | 1385 let |
1324 let | 1386 val (p', rvN) = |
1325 val p' = case si of | 1387 foldl (fn (si, (p, rvN)) => |
1326 SqField (v, f) => Reln (Eq, [Proj (Proj (oe, v), f), | 1388 let |
1327 Proj (rvOf v, f)]) | 1389 val (p', rvN) = |
1328 | SqExp (e, f) => | 1390 case si of |
1329 case expIn e of | 1391 SqField (v, f) => (Reln (Eq, [Proj (Proj (oe, v), f), |
1330 inr p => Cond (Proj (oe, f), p) | 1392 Proj (rvOf v, f)]), rvN) |
1331 | inl e => Reln (Eq, [Proj (oe, f), e]) | 1393 | SqExp (e, f) => |
1332 in | 1394 case expIn (e, rvN) of |
1333 And (p, p') | 1395 (inr p, rvN) => (Cond (Proj (oe, f), p), rvN) |
1334 end) | 1396 | (inl e, rvN) => (Reln (Eq, [Proj (oe, f), e]), rvN) |
1335 True (#Select r)), | 1397 in |
1336 True, []) | 1398 (And (p, p'), rvN) |
1399 end) | |
1400 (True, rvN) (#Select r) | |
1401 in | |
1402 (rvN, And (p, p'), True, []) | |
1403 end | |
1337 | 1404 |
1338 val (rvN, p, wp, outs) = | 1405 val (rvN, p, wp, outs) = |
1339 case #Select r of | 1406 case #Select r of |
1340 [SqExp (Binop (Exps bo, Count, SqConst (Prim.Int 0)), f)] => | 1407 [SqExp (Binop (Exps bo, Count, SqConst (Prim.Int 0)), f)] => |
1341 (case bo (Const (Prim.Int 1), Const (Prim.Int 2)) of | 1408 (case bo (Const (Prim.Int 1), Const (Prim.Int 2)) of |
1368 in | 1435 in |
1369 (rvN, p, wp, case #Where r of | 1436 (rvN, p, wp, case #Where r of |
1370 NONE => [] | 1437 NONE => [] |
1371 | SOME e => map (fn (v, f) => Proj (rvOf v, f)) (usedFields e), outs) | 1438 | SOME e => map (fn (v, f) => Proj (rvOf v, f)) (usedFields e), outs) |
1372 end | 1439 end |
1373 handle Default => default () | 1440 end |
1441 | |
1442 fun insertProp rvN rv e = | |
1443 let | |
1444 fun default () = (print ("Warning: Information flow checker can't parse SQL query at " | |
1445 ^ ErrorMsg.spanToString (#2 e) ^ "\n"); | |
1446 Unknown) | |
1447 in | |
1448 case parse query e of | |
1449 NONE => default () | |
1450 | SOME r => | |
1451 let | |
1452 val (rvs, rvN) = ListUtil.foldlMap (fn ((_, v), rvN) => | |
1453 let | |
1454 val (rvN, e) = rv rvN | |
1455 in | |
1456 ((v, e), rvN) | |
1457 end) rvN (#From r) | |
1458 | |
1459 fun rvOf v = | |
1460 case List.find (fn (v', _) => v' = v) rvs of | |
1461 NONE => raise Fail "Iflow.insertProp: Bad table variable" | |
1462 | SOME (_, e) => e | |
1463 | |
1464 val p = | |
1465 foldl (fn ((t, v), p) => | |
1466 let | |
1467 val t = | |
1468 case v of | |
1469 "New" => "$New" | |
1470 | _ => t | |
1471 in | |
1472 And (p, Reln (Sql t, [rvOf v])) | |
1473 end) True (#From r) | |
1474 | |
1475 val expIn = expIn rv [] rvOf | |
1476 in | |
1477 case #Where r of | |
1478 NONE => p | |
1479 | SOME e => | |
1480 case expIn (e, rvN) of | |
1481 (inr p', _) => And (p, p') | |
1482 | _ => p | |
1483 end | |
1374 end | 1484 end |
1375 | 1485 |
1376 fun evalPat env e (pt, _) = | 1486 fun evalPat env e (pt, _) = |
1377 case pt of | 1487 case pt of |
1378 PWild => (env, True) | 1488 PWild => (env, True) |
1426 end | 1536 end |
1427 | 1537 |
1428 datatype cflow = Case | Where | 1538 datatype cflow = Case | Where |
1429 datatype flow = Data | Control of cflow | 1539 datatype flow = Data | Control of cflow |
1430 type check = ErrorMsg.span * exp * prop | 1540 type check = ErrorMsg.span * exp * prop |
1541 type insert = ErrorMsg.span * prop | |
1431 | 1542 |
1432 structure St :> sig | 1543 structure St :> sig |
1433 type t | 1544 type t |
1434 val create : {Var : int, | 1545 val create : {Var : int, |
1435 Ambient : prop} -> t | 1546 Ambient : prop} -> t |
1447 val setPaths : t * (check * cflow) list -> t | 1558 val setPaths : t * (check * cflow) list -> t |
1448 | 1559 |
1449 val sent : t -> (check * flow) list | 1560 val sent : t -> (check * flow) list |
1450 val addSent : t * (check * flow) -> t | 1561 val addSent : t * (check * flow) -> t |
1451 val setSent : t * (check * flow) list -> t | 1562 val setSent : t * (check * flow) list -> t |
1563 | |
1564 val inserted : t -> insert list | |
1565 val addInsert : t * insert -> t | |
1452 end = struct | 1566 end = struct |
1453 | 1567 |
1454 type t = {Var : int, | 1568 type t = {Var : int, |
1455 Ambient : prop, | 1569 Ambient : prop, |
1456 Path : (check * cflow) list, | 1570 Path : (check * cflow) list, |
1457 Sent : (check * flow) list} | 1571 Sent : (check * flow) list, |
1572 Insert : insert list} | |
1458 | 1573 |
1459 fun create {Var = v, Ambient = p} = {Var = v, | 1574 fun create {Var = v, Ambient = p} = {Var = v, |
1460 Ambient = p, | 1575 Ambient = p, |
1461 Path = [], | 1576 Path = [], |
1462 Sent = []} | 1577 Sent = [], |
1578 Insert = []} | |
1463 | 1579 |
1464 fun curVar (t : t) = #Var t | 1580 fun curVar (t : t) = #Var t |
1465 fun nextVar (t : t) = ({Var = #Var t + 1, | 1581 fun nextVar (t : t) = ({Var = #Var t + 1, |
1466 Ambient = #Ambient t, | 1582 Ambient = #Ambient t, |
1467 Path = #Path t, | 1583 Path = #Path t, |
1468 Sent = #Sent t}, #Var t) | 1584 Sent = #Sent t, |
1585 Insert = #Insert t}, #Var t) | |
1469 | 1586 |
1470 fun ambient (t : t) = #Ambient t | 1587 fun ambient (t : t) = #Ambient t |
1471 fun setAmbient (t : t, p) = {Var = #Var t, | 1588 fun setAmbient (t : t, p) = {Var = #Var t, |
1472 Ambient = p, | 1589 Ambient = p, |
1473 Path = #Path t, | 1590 Path = #Path t, |
1474 Sent = #Sent t} | 1591 Sent = #Sent t, |
1592 Insert = #Insert t} | |
1475 | 1593 |
1476 fun paths (t : t) = #Path t | 1594 fun paths (t : t) = #Path t |
1477 fun addPath (t : t, c) = {Var = #Var t, | 1595 fun addPath (t : t, c) = {Var = #Var t, |
1478 Ambient = #Ambient t, | 1596 Ambient = #Ambient t, |
1479 Path = c :: #Path t, | 1597 Path = c :: #Path t, |
1480 Sent = #Sent t} | 1598 Sent = #Sent t, |
1599 Insert = #Insert t} | |
1481 fun addPaths (t : t, cs) = {Var = #Var t, | 1600 fun addPaths (t : t, cs) = {Var = #Var t, |
1482 Ambient = #Ambient t, | 1601 Ambient = #Ambient t, |
1483 Path = cs @ #Path t, | 1602 Path = cs @ #Path t, |
1484 Sent = #Sent t} | 1603 Sent = #Sent t, |
1604 Insert = #Insert t} | |
1485 fun clearPaths (t : t) = {Var = #Var t, | 1605 fun clearPaths (t : t) = {Var = #Var t, |
1486 Ambient = #Ambient t, | 1606 Ambient = #Ambient t, |
1487 Path = [], | 1607 Path = [], |
1488 Sent = #Sent t} | 1608 Sent = #Sent t, |
1609 Insert = #Insert t} | |
1489 fun setPaths (t : t, cs) = {Var = #Var t, | 1610 fun setPaths (t : t, cs) = {Var = #Var t, |
1490 Ambient = #Ambient t, | 1611 Ambient = #Ambient t, |
1491 Path = cs, | 1612 Path = cs, |
1492 Sent = #Sent t} | 1613 Sent = #Sent t, |
1614 Insert = #Insert t} | |
1493 | 1615 |
1494 fun sent (t : t) = #Sent t | 1616 fun sent (t : t) = #Sent t |
1495 fun addSent (t : t, c) = {Var = #Var t, | 1617 fun addSent (t : t, c) = {Var = #Var t, |
1496 Ambient = #Ambient t, | 1618 Ambient = #Ambient t, |
1497 Path = #Path t, | 1619 Path = #Path t, |
1498 Sent = c :: #Sent t} | 1620 Sent = c :: #Sent t, |
1621 Insert = #Insert t} | |
1499 fun setSent (t : t, cs) = {Var = #Var t, | 1622 fun setSent (t : t, cs) = {Var = #Var t, |
1500 Ambient = #Ambient t, | 1623 Ambient = #Ambient t, |
1501 Path = #Path t, | 1624 Path = #Path t, |
1502 Sent = cs} | 1625 Sent = cs, |
1626 Insert = #Insert t} | |
1627 | |
1628 fun inserted (t : t) = #Insert t | |
1629 fun addInsert (t : t, c) = {Var = #Var t, | |
1630 Ambient = #Ambient t, | |
1631 Path = #Path t, | |
1632 Sent = #Sent t, | |
1633 Insert = c :: #Insert t} | |
1503 | 1634 |
1504 end | 1635 end |
1505 | 1636 |
1506 fun evalExp env (e as (_, loc), st) = | 1637 fun evalExp env (e as (_, loc), st) = |
1507 let | 1638 let |
1718 val p' = And (p', qwp) | 1849 val p' = And (p', qwp) |
1719 val paths = map (fn e => ((loc, e, p'), Where)) used | 1850 val paths = map (fn e => ((loc, e, p'), Where)) used |
1720 in | 1851 in |
1721 (res, St.addPaths (St.setSent (st, sent), paths)) | 1852 (res, St.addPaths (St.setSent (st, sent), paths)) |
1722 end | 1853 end |
1723 | EDml _ => default () | 1854 | EDml e => |
1855 (case parse dml e of | |
1856 NONE => (print ("Warning: Information flow checker can't parse DML command at " | |
1857 ^ ErrorMsg.spanToString loc ^ "\n"); | |
1858 default ()) | |
1859 | SOME d => | |
1860 case d of | |
1861 Insert (tab, es) => | |
1862 let | |
1863 val (st, new) = St.nextVar st | |
1864 | |
1865 fun rv st = | |
1866 let | |
1867 val (st, n) = St.nextVar st | |
1868 in | |
1869 (st, Var n) | |
1870 end | |
1871 | |
1872 val expIn = expIn rv env (fn "New" => Var new | |
1873 | _ => raise Fail "Iflow.evalExp: Bad field expression in EDml") | |
1874 | |
1875 val (es, st) = ListUtil.foldlMap | |
1876 (fn ((x, e), st) => | |
1877 let | |
1878 val (e, st) = case expIn (e, st) of | |
1879 (inl e, st) => (e, st) | |
1880 | (inr _, _) => raise Fail | |
1881 ("Iflow.evalExp: Selecting " | |
1882 ^ "boolean expression") | |
1883 in | |
1884 ((x, e), st) | |
1885 end) | |
1886 st es | |
1887 in | |
1888 (Recd [], St.addInsert (st, (loc, And (St.ambient st, | |
1889 Reln (Sql "$New", [Recd es]))))) | |
1890 end) | |
1891 | |
1724 | ENextval _ => default () | 1892 | ENextval _ => default () |
1725 | ESetval _ => default () | 1893 | ESetval _ => default () |
1726 | 1894 |
1727 | EUnurlify ((EFfiApp ("Basis", "get_cookie", _), _), _, _) => | 1895 | EUnurlify ((EFfiApp ("Basis", "get_cookie", _), _), _, _) => |
1728 let | 1896 let |
1754 val exptd = foldl (fn ((d, _), exptd) => | 1922 val exptd = foldl (fn ((d, _), exptd) => |
1755 case d of | 1923 case d of |
1756 DExport (_, _, n, _, _, _) => IS.add (exptd, n) | 1924 DExport (_, _, n, _, _, _) => IS.add (exptd, n) |
1757 | _ => exptd) IS.empty file | 1925 | _ => exptd) IS.empty file |
1758 | 1926 |
1759 fun decl ((d, _), (vals, pols)) = | 1927 fun decl ((d, _), (vals, inserts, client, insert)) = |
1760 case d of | 1928 case d of |
1761 DVal (_, n, _, e, _) => | 1929 DVal (_, n, _, e, _) => |
1762 let | 1930 let |
1763 val isExptd = IS.member (exptd, n) | 1931 val isExptd = IS.member (exptd, n) |
1764 | 1932 |
1774 val (e, env, nv, p) = deAbs (e, [], 1, True) | 1942 val (e, env, nv, p) = deAbs (e, [], 1, True) |
1775 | 1943 |
1776 val (_, st) = evalExp env (e, St.create {Var = nv, | 1944 val (_, st) = evalExp env (e, St.create {Var = nv, |
1777 Ambient = p}) | 1945 Ambient = p}) |
1778 in | 1946 in |
1779 (St.sent st @ vals, pols) | 1947 (St.sent st @ vals, St.inserted st @ inserts, client, insert) |
1780 end | 1948 end |
1781 | 1949 |
1782 | DPolicy (PolClient e) => | 1950 | DPolicy pol => |
1783 let | 1951 let |
1784 val (_, p, _, _, outs) = queryProp [] 0 (fn rvN => (rvN + 1, Lvar rvN)) SomeCol e | 1952 fun rv rvN = (rvN + 1, Lvar rvN) |
1785 in | 1953 in |
1786 (vals, (p, outs) :: pols) | 1954 case pol of |
1955 PolClient e => | |
1956 let | |
1957 val (_, p, _, _, outs) = queryProp [] 0 rv SomeCol e | |
1958 in | |
1959 (vals, inserts, (p, outs) :: client, insert) | |
1960 end | |
1961 | PolInsert e => | |
1962 let | |
1963 val p = insertProp 0 rv e | |
1964 in | |
1965 (vals, inserts,client, p :: insert) | |
1966 end | |
1787 end | 1967 end |
1788 | 1968 |
1789 | _ => (vals, pols) | 1969 | _ => (vals, inserts, client, insert) |
1790 | 1970 |
1791 val () = reset () | 1971 val () = reset () |
1792 | 1972 |
1793 val (vals, pols) = foldl decl ([], []) file | 1973 val (vals, inserts, client, insert) = foldl decl ([], [], [], []) file |
1974 | |
1975 val decompH = decomp true (fn (e1, e2) => e1 andalso e2 ()) | |
1976 val decompG = decomp false (fn (e1, e2) => e1 orelse e2 ()) | |
1794 in | 1977 in |
1795 app (fn ((loc, e, p), fl) => | 1978 app (fn ((loc, e, p), fl) => |
1796 let | 1979 let |
1797 fun doOne e = | 1980 fun doOne e = |
1798 let | 1981 let |
1799 val p = And (p, Reln (Eq, [Var 0, e])) | 1982 val p = And (p, Reln (Eq, [Var 0, e])) |
1800 in | 1983 in |
1801 if decomp true (fn (e1, e2) => e1 andalso e2 ()) p | 1984 if decompH p |
1802 (fn hyps => | 1985 (fn hyps => |
1803 (fl <> Control Where | 1986 (fl <> Control Where |
1804 andalso imply (hyps, [AReln (Known, [Var 0])], [Var 0])) | 1987 andalso imply (hyps, [AReln (Known, [Var 0])], SOME [Var 0])) |
1805 orelse List.exists (fn (p', outs) => | 1988 orelse List.exists (fn (p', outs) => |
1806 decomp false (fn (e1, e2) => e1 orelse e2 ()) p' | 1989 decompG p' |
1807 (fn goals => imply (hyps, goals, outs))) | 1990 (fn goals => imply (hyps, goals, SOME outs))) |
1808 pols) then | 1991 client) then |
1809 () | 1992 () |
1810 else | 1993 else |
1811 (ErrorMsg.errorAt loc "The information flow policy may be violated here."; | 1994 (ErrorMsg.errorAt loc "The information flow policy may be violated here."; |
1812 Print.preface ("The state satisifies this predicate:", p_prop p)) | 1995 Print.preface ("The state satisifies this predicate:", p_prop p)) |
1813 end | 1996 end |
1822 | Recd xes => app (doAll o #2) xes | 2005 | Recd xes => app (doAll o #2) xes |
1823 | Proj _ => doOne e | 2006 | Proj _ => doOne e |
1824 | Finish => () | 2007 | Finish => () |
1825 in | 2008 in |
1826 doAll e | 2009 doAll e |
1827 end) vals | 2010 end) vals; |
2011 | |
2012 app (fn (loc, p) => | |
2013 if decompH p | |
2014 (fn hyps => | |
2015 List.exists (fn p' => | |
2016 decompG p' | |
2017 (fn goals => imply (hyps, goals, NONE))) | |
2018 insert) then | |
2019 () | |
2020 else | |
2021 (ErrorMsg.errorAt loc "The information flow policy may be violated here."; | |
2022 Print.preface ("The state satisifies this predicate:", p_prop p))) inserts | |
1828 end | 2023 end |
1829 | 2024 |
1830 val check = fn file => | 2025 val check = fn file => |
1831 let | 2026 let |
1832 val oldInline = Settings.getMonoInline () | 2027 val oldInline = Settings.getMonoInline () |