comparison src/iflow.sml @ 1244:1eedc9086e6c

Use key information in more places, and catch cases where one key completion depends on another having happened already
author Adam Chlipala <adamc@hcoop.net>
date Sun, 18 Apr 2010 13:00:36 -0400
parents e754dc92c47c
children 5c2555dfce8f
comparison
equal deleted inserted replaced
1243:e754dc92c47c 1244:1eedc9086e6c
246 val builtFrom : database * {UseKnown : bool, 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 local
252 val count = ref 0
253 in
254 fun nodeId () =
255 let
256 val n = !count
257 in
258 count := n + 1;
259 n
260 end
261 end
262
251 exception Contradiction 263 exception Contradiction
252 exception Undetermined 264 exception Undetermined
253 265
254 structure CM = BinaryMapFn(struct 266 structure CM = BinaryMapFn(struct
255 type ord_key = Prim.t 267 type ord_key = Prim.t
256 val compare = Prim.compare 268 val compare = Prim.compare
257 end) 269 end)
258 270
259 datatype node = Node of {Rep : node ref option ref, 271 datatype node = Node of {Id : int,
272 Rep : node ref option ref,
260 Cons : node ref SM.map ref, 273 Cons : node ref SM.map ref,
261 Variety : variety, 274 Variety : variety,
262 Known : bool ref} 275 Known : bool ref}
263 276
264 and variety = 277 and variety =
298 311
299 fun p_rep n = 312 fun p_rep n =
300 case !(#Rep (unNode n)) of 313 case !(#Rep (unNode n)) of
301 SOME n => p_rep n 314 SOME n => p_rep n
302 | NONE => 315 | NONE =>
303 box [(*string (Int.toString (Unsafe.cast n) ^ ":"), 316 box [string (Int.toString (#Id (unNode n)) ^ ":"),
304 space,*) 317 space,
305 case #Variety (unNode n) of 318 case #Variety (unNode n) of
306 Nothing => string "?" 319 Nothing => string "?"
307 | Dt0 s => string ("Dt0(" ^ s ^ ")") 320 | Dt0 s => string ("Dt0(" ^ s ^ ")")
308 | Dt1 (s, n) => box[string ("Dt1(" ^ s ^ ","), 321 | Dt1 (s, n) => box[string ("Dt1(" ^ s ^ ","),
309 space, 322 space,
370 case e of 383 case e of
371 Const p => (case CM.find (!(#Consts db), p) of 384 Const p => (case CM.find (!(#Consts db), p) of
372 SOME r => repOf r 385 SOME r => repOf r
373 | NONE => 386 | NONE =>
374 let 387 let
375 val r = ref (Node {Rep = ref NONE, 388 val r = ref (Node {Id = nodeId (),
389 Rep = ref NONE,
376 Cons = ref SM.empty, 390 Cons = ref SM.empty,
377 Variety = Prim p, 391 Variety = Prim p,
378 Known = ref true}) 392 Known = ref true})
379 in 393 in
380 #Consts db := CM.insert (!(#Consts db), p, r); 394 #Consts db := CM.insert (!(#Consts db), p, r);
382 end) 396 end)
383 | Var n => (case IM.find (!(#Vars db), n) of 397 | Var n => (case IM.find (!(#Vars db), n) of
384 SOME r => repOf r 398 SOME r => repOf r
385 | NONE => 399 | NONE =>
386 let 400 let
387 val r = ref (Node {Rep = ref NONE, 401 val r = ref (Node {Id = nodeId (),
402 Rep = ref NONE,
388 Cons = ref SM.empty, 403 Cons = ref SM.empty,
389 Variety = Nothing, 404 Variety = Nothing,
390 Known = ref false}) 405 Known = ref false})
391 in 406 in
392 #Vars db := IM.insert (!(#Vars db), n, r); 407 #Vars db := IM.insert (!(#Vars db), n, r);
395 | Lvar _ => raise Undetermined 410 | Lvar _ => raise Undetermined
396 | Func (DtCon0 f, []) => (case SM.find (!(#Con0s db), f) of 411 | Func (DtCon0 f, []) => (case SM.find (!(#Con0s db), f) of
397 SOME r => repOf r 412 SOME r => repOf r
398 | NONE => 413 | NONE =>
399 let 414 let
400 val r = ref (Node {Rep = ref NONE, 415 val r = ref (Node {Id = nodeId (),
416 Rep = ref NONE,
401 Cons = ref SM.empty, 417 Cons = ref SM.empty,
402 Variety = Dt0 f, 418 Variety = Dt0 f,
403 Known = ref true}) 419 Known = ref true})
404 in 420 in
405 #Con0s db := SM.insert (!(#Con0s db), f, r); 421 #Con0s db := SM.insert (!(#Con0s db), f, r);
412 in 428 in
413 case SM.find (!(#Cons (unNode r)), f) of 429 case SM.find (!(#Cons (unNode r)), f) of
414 SOME r => repOf r 430 SOME r => repOf r
415 | NONE => 431 | NONE =>
416 let 432 let
417 val r' = ref (Node {Rep = ref NONE, 433 val r' = ref (Node {Id = nodeId (),
434 Rep = ref NONE,
418 Cons = ref SM.empty, 435 Cons = ref SM.empty,
419 Variety = Dt1 (f, r), 436 Variety = Dt1 (f, r),
420 Known = ref (!(#Known (unNode r)))}) 437 Known = ref (!(#Known (unNode r)))})
421 in 438 in
422 #Cons (unNode r) := SM.insert (!(#Cons (unNode r)), f, r'); 439 #Cons (unNode r) := SM.insert (!(#Cons (unNode r)), f, r');
434 else 451 else
435 raise Contradiction 452 raise Contradiction
436 | Nothing => 453 | Nothing =>
437 let 454 let
438 val cons = ref SM.empty 455 val cons = ref SM.empty
439 val r' = ref (Node {Rep = ref NONE, 456 val r' = ref (Node {Id = nodeId (),
457 Rep = ref NONE,
440 Cons = cons, 458 Cons = cons,
441 Variety = Nothing, 459 Variety = Nothing,
442 Known = ref (!(#Known (unNode r)))}) 460 Known = ref (!(#Known (unNode r)))})
443 461
444 val r'' = ref (Node {Rep = ref NONE, 462 val r'' = ref (Node {Id = nodeId (),
463 Rep = ref NONE,
445 Cons = #Cons (unNode r), 464 Cons = #Cons (unNode r),
446 Variety = Dt1 (f, r'), 465 Variety = Dt1 (f, r'),
447 Known = #Known (unNode r)}) 466 Known = #Known (unNode r)})
448 in 467 in
449 cons := SM.insert (!cons, f, r''); 468 cons := SM.insert (!cons, f, r'');
458 val rs = map rep es 477 val rs = map rep es
459 in 478 in
460 case List.find (fn (x : string * representative list, _) => x = (f, rs)) (!(#Funcs db)) of 479 case List.find (fn (x : string * representative list, _) => x = (f, rs)) (!(#Funcs db)) of
461 NONE => 480 NONE =>
462 let 481 let
463 val r = ref (Node {Rep = ref NONE, 482 val r = ref (Node {Id = nodeId (),
483 Rep = ref NONE,
464 Cons = ref SM.empty, 484 Cons = ref SM.empty,
465 Variety = Nothing, 485 Variety = Nothing,
466 Known = ref false}) 486 Known = ref false})
467 in 487 in
468 #Funcs db := ((f, rs), r) :: (!(#Funcs db)); 488 #Funcs db := ((f, rs), r) :: (!(#Funcs db));
485 SOME (_, r) => repOf r 505 SOME (_, r) => repOf r
486 | NONE => 506 | NONE =>
487 let 507 let
488 val xes = foldl SM.insert' SM.empty xes 508 val xes = foldl SM.insert' SM.empty xes
489 509
490 val r' = ref (Node {Rep = ref NONE, 510 val r' = ref (Node {Id = nodeId (),
511 Rep = ref NONE,
491 Cons = ref SM.empty, 512 Cons = ref SM.empty,
492 Variety = Recrd (ref xes, true), 513 Variety = Recrd (ref xes, true),
493 Known = ref false}) 514 Known = ref false})
494 in 515 in
495 #Records db := (xes, r') :: (!(#Records db)); 516 #Records db := (xes, r') :: (!(#Records db));
503 case #Variety (unNode r) of 524 case #Variety (unNode r) of
504 Recrd (xes, _) => 525 Recrd (xes, _) =>
505 (case SM.find (!xes, f) of 526 (case SM.find (!xes, f) of
506 SOME r => repOf r 527 SOME r => repOf r
507 | NONE => let 528 | NONE => let
508 val r = ref (Node {Rep = ref NONE, 529 val r = ref (Node {Id = nodeId (),
530 Rep = ref NONE,
509 Cons = ref SM.empty, 531 Cons = ref SM.empty,
510 Variety = Nothing, 532 Variety = Nothing,
511 Known = ref (!(#Known (unNode r)))}) 533 Known = ref (!(#Known (unNode r)))})
512 in 534 in
513 xes := SM.insert (!xes, f, r); 535 xes := SM.insert (!xes, f, r);
514 r 536 r
515 end) 537 end)
516 | Nothing => 538 | Nothing =>
517 let 539 let
518 val r' = ref (Node {Rep = ref NONE, 540 val r' = ref (Node {Id = nodeId (),
541 Rep = ref NONE,
519 Cons = ref SM.empty, 542 Cons = ref SM.empty,
520 Variety = Nothing, 543 Variety = Nothing,
521 Known = ref (!(#Known (unNode r)))}) 544 Known = ref (!(#Known (unNode r)))})
522 545
523 val r'' = ref (Node {Rep = ref NONE, 546 val r'' = ref (Node {Id = nodeId (),
547 Rep = ref NONE,
524 Cons = #Cons (unNode r), 548 Cons = #Cons (unNode r),
525 Variety = Recrd (ref (SM.insert (SM.empty, f, r')), false), 549 Variety = Recrd (ref (SM.insert (SM.empty, f, r')), false),
526 Known = #Known (unNode r)}) 550 Known = #Known (unNode r)})
527 in 551 in
528 #Rep (unNode r) := SOME r''; 552 #Rep (unNode r) := SOME r'';
633 | Nothing => 657 | Nothing =>
634 (case SM.find (!(#Con0s db), f) of 658 (case SM.find (!(#Con0s db), f) of
635 SOME r' => markEq (r, r') 659 SOME r' => markEq (r, r')
636 | NONE => 660 | NONE =>
637 let 661 let
638 val r' = ref (Node {Rep = ref NONE, 662 val r' = ref (Node {Id = nodeId (),
663 Rep = ref NONE,
639 Cons = ref SM.empty, 664 Cons = ref SM.empty,
640 Variety = Dt0 f, 665 Variety = Dt0 f,
641 Known = ref false}) 666 Known = ref false})
642 in 667 in
643 #Rep (unNode r) := SOME r'; 668 #Rep (unNode r) := SOME r';
654 () 679 ()
655 else 680 else
656 raise Contradiction 681 raise Contradiction
657 | Nothing => 682 | Nothing =>
658 let 683 let
659 val r'' = ref (Node {Rep = ref NONE, 684 val r'' = ref (Node {Id = nodeId (),
685 Rep = ref NONE,
660 Cons = ref SM.empty, 686 Cons = ref SM.empty,
661 Variety = Nothing, 687 Variety = Nothing,
662 Known = ref (!(#Known (unNode r)))}) 688 Known = ref (!(#Known (unNode r)))})
663 689
664 val r' = ref (Node {Rep = ref NONE, 690 val r' = ref (Node {Id = nodeId (),
691 Rep = ref NONE,
665 Cons = ref SM.empty, 692 Cons = ref SM.empty,
666 Variety = Dt1 (f, r''), 693 Variety = Dt1 (f, r''),
667 Known = #Known (unNode r)}) 694 Known = #Known (unNode r)})
668 in 695 in
669 #Rep (unNode r) := SOME r' 696 #Rep (unNode r) := SOME r'
741 end 768 end
742 769
743 end 770 end
744 771
745 val tabs = ref (SM.empty : (string list * string list list) SM.map) 772 val tabs = ref (SM.empty : (string list * string list list) SM.map)
746
747 fun ccOf hyps =
748 let
749 val cc = Cc.database ()
750 val () = app (fn a => Cc.assert (cc, a)) hyps
751
752 (* Take advantage of table key information *)
753 fun findKeys hyps =
754 case hyps of
755 [] => ()
756 | AReln (Sql tab, [r1]) :: hyps =>
757 (case SM.find (!tabs, tab) of
758 NONE => findKeys hyps
759 | SOME (_, []) => findKeys hyps
760 | SOME (_, ks) =>
761 let
762 fun finder hyps =
763 case hyps of
764 [] => ()
765 | AReln (Sql tab', [r2]) :: hyps =>
766 (if tab' = tab andalso
767 List.exists (List.all (fn f =>
768 let
769 val r =
770 Cc.check (cc,
771 AReln (Eq, [Proj (r1, f),
772 Proj (r2, f)]))
773 in
774 (*Print.prefaces "Fs"
775 [("tab",
776 Print.PD.string tab),
777 ("r1",
778 p_exp (Proj (r1, f))),
779 ("r2",
780 p_exp (Proj (r2, f))),
781 ("r",
782 Print.PD.string
783 (Bool.toString r))];*)
784 r
785 end)) ks then
786 ((*Print.prefaces "Key match" [("tab", Print.PD.string tab),
787 ("r1", p_exp r1),
788 ("r2", p_exp r2),
789 ("rp1", Cc.p_repOf cc r1),
790 ("rp2", Cc.p_repOf cc r2)];*)
791 Cc.assert (cc, AReln (Eq, [r1, r2])))
792 else
793 ();
794 finder hyps)
795 | _ :: hyps => finder hyps
796 in
797 finder hyps;
798 findKeys hyps
799 end)
800 | _ :: hyps => findKeys hyps
801 in
802 findKeys hyps;
803 cc
804 end
805 773
806 fun patCon pc = 774 fun patCon pc =
807 case pc of 775 case pc of
808 PConVar n => "C" ^ Int.toString n 776 PConVar n => "C" ^ Int.toString n
809 | PConFfi {mod = m, datatyp = d, con = c, ...} => m ^ "." ^ d ^ "." ^ c 777 | PConFfi {mod = m, datatyp = d, con = c, ...} => m ^ "." ^ d ^ "." ^ c
1210 val debug : unit -> unit 1178 val debug : unit -> unit
1211 end = struct 1179 end = struct
1212 1180
1213 val hnames = ref 1 1181 val hnames = ref 1
1214 1182
1215 type hyps = int * atom list 1183 type hyps = int * atom list * bool ref
1216 1184
1217 val db = Cc.database () 1185 val db = Cc.database ()
1218 val path = ref ([] : (hyps * check) option ref list) 1186 val path = ref ([] : ((int * atom list) * check) option ref list)
1219 val hyps = ref (0, [] : atom list) 1187 val hyps = ref (0, [] : atom list, ref false)
1220 val nvar = ref 0 1188 val nvar = ref 0
1221 1189
1222 fun setHyps (h as (n', hs)) = 1190 fun setHyps (n', hs) =
1223 let 1191 let
1224 val (n, _) = !hyps 1192 val (n, _, _) = !hyps
1225 in 1193 in
1226 if n' = n then 1194 if n' = n then
1227 () 1195 ()
1228 else 1196 else
1229 (hyps := h; 1197 (hyps := (n', hs, ref false);
1230 Cc.clear db; 1198 Cc.clear db;
1231 app (fn a => Cc.assert (db, a)) hs) 1199 app (fn a => Cc.assert (db, a)) hs)
1232 end 1200 end
1233 1201
1234 type stashed = int * (hyps * check) option ref list * (int * atom list) 1202 fun useKeys () =
1235 fun stash () = (!nvar, !path, !hyps) 1203 let
1204 val changed = ref false
1205
1206 fun findKeys (hyps, acc) =
1207 case hyps of
1208 [] => acc
1209 | (a as AReln (Sql tab, [r1])) :: hyps =>
1210 (case SM.find (!tabs, tab) of
1211 NONE => findKeys (hyps, a :: acc)
1212 | SOME (_, []) => findKeys (hyps, a :: acc)
1213 | SOME (_, ks) =>
1214 let
1215 fun finder (hyps, acc) =
1216 case hyps of
1217 [] => acc
1218 | (a as AReln (Sql tab', [r2])) :: hyps =>
1219 if tab' = tab andalso
1220 List.exists (List.all (fn f =>
1221 let
1222 val r =
1223 Cc.check (db,
1224 AReln (Eq, [Proj (r1, f),
1225 Proj (r2, f)]))
1226 in
1227 (*Print.prefaces "Fs"
1228 [("tab",
1229 Print.PD.string tab),
1230 ("r1",
1231 p_exp (Proj (r1, f))),
1232 ("r2",
1233 p_exp (Proj (r2, f))),
1234 ("r",
1235 Print.PD.string
1236 (Bool.toString r))];*)
1237 r
1238 end)) ks then
1239 (changed := true;
1240 Cc.assert (db, AReln (Eq, [r1, r2]));
1241 finder (hyps, acc))
1242 else
1243 finder (hyps, a :: acc)
1244 | a :: hyps => finder (hyps, a :: acc)
1245
1246 val hyps = finder (hyps, [])
1247 in
1248 findKeys (hyps, acc)
1249 end)
1250 | a :: hyps => findKeys (hyps, a :: acc)
1251
1252 fun loop hs =
1253 let
1254 val hs = findKeys (hs, [])
1255 in
1256 if !changed then
1257 (changed := false;
1258 loop hs)
1259 else
1260 ()
1261 end
1262
1263 val (_, hs, _) = !hyps
1264 in
1265 (*print "findKeys\n";*)
1266 loop hs
1267 end
1268
1269 fun complete () =
1270 let
1271 val (_, _, bf) = !hyps
1272 in
1273 if !bf then
1274 ()
1275 else
1276 (bf := true;
1277 useKeys ())
1278 end
1279
1280 type stashed = int * ((int * atom list) * check) option ref list * (int * atom list)
1281 fun stash () = (!nvar, !path, (#1 (!hyps), #2 (!hyps)))
1236 fun reinstate (nv, p, h) = 1282 fun reinstate (nv, p, h) =
1237 (nvar := nv; 1283 (nvar := nv;
1238 path := p; 1284 path := p;
1239 setHyps h) 1285 setHyps h)
1240 1286
1247 end 1293 end
1248 1294
1249 fun assert ats = 1295 fun assert ats =
1250 let 1296 let
1251 val n = !hnames 1297 val n = !hnames
1252 val (_, hs) = !hyps 1298 val (_, hs, _) = !hyps
1253 in 1299 in
1254 hnames := n + 1; 1300 hnames := n + 1;
1255 hyps := (n, ats @ hs); 1301 hyps := (n, ats @ hs, ref false);
1256 app (fn a => Cc.assert (db, a)) ats 1302 app (fn a => Cc.assert (db, a)) ats
1257 end 1303 end
1258 1304
1259 fun addPath c = path := ref (SOME (!hyps, c)) :: !path 1305 fun addPath c = path := ref (SOME ((#1 (!hyps), #2 (!hyps)), c)) :: !path
1260 1306
1261 val sendable = ref ([] : (atom list * exp list) list) 1307 val sendable = ref ([] : (atom list * exp list) list)
1262 1308
1263 fun checkGoals goals k = 1309 fun checkGoals goals k =
1264 let 1310 let
1266 case goals of 1312 case goals of
1267 [] => k unifs 1313 [] => k unifs
1268 | AReln (Sql tab, [Lvar lv]) :: goals => 1314 | AReln (Sql tab, [Lvar lv]) :: goals =>
1269 let 1315 let
1270 val saved = stash () 1316 val saved = stash ()
1271 val (_, hyps) = !hyps 1317 val (_, hyps, _) = !hyps
1272 1318
1273 fun tryAll unifs hyps = 1319 fun tryAll unifs hyps =
1274 case hyps of 1320 case hyps of
1275 [] => false 1321 [] => false
1276 | AReln (Sql tab', [e]) :: hyps => 1322 | AReln (Sql tab', [e]) :: hyps =>
1280 | _ :: hyps => tryAll unifs hyps 1326 | _ :: hyps => tryAll unifs hyps
1281 in 1327 in
1282 tryAll unifs hyps 1328 tryAll unifs hyps
1283 end 1329 end
1284 | (g as AReln (r, es)) :: goals => 1330 | (g as AReln (r, es)) :: goals =>
1285 Cc.check (db, AReln (r, map (simplify unifs) es)) 1331 (complete ();
1286 andalso checkGoals goals unifs 1332 Cc.check (db, AReln (r, map (simplify unifs) es))
1333 andalso checkGoals goals unifs)
1287 | ACond _ :: _ => false 1334 | ACond _ :: _ => false
1288 in 1335 in
1289 checkGoals goals IM.empty 1336 checkGoals goals IM.empty
1290 end
1291
1292 fun useKeys () =
1293 let
1294 fun findKeys hyps =
1295 case hyps of
1296 [] => ()
1297 | AReln (Sql tab, [r1]) :: hyps =>
1298 (case SM.find (!tabs, tab) of
1299 NONE => findKeys hyps
1300 | SOME (_, []) => findKeys hyps
1301 | SOME (_, ks) =>
1302 let
1303 fun finder hyps =
1304 case hyps of
1305 [] => ()
1306 | AReln (Sql tab', [r2]) :: hyps =>
1307 (if tab' = tab andalso
1308 List.exists (List.all (fn f =>
1309 let
1310 val r =
1311 Cc.check (db,
1312 AReln (Eq, [Proj (r1, f),
1313 Proj (r2, f)]))
1314 in
1315 (*Print.prefaces "Fs"
1316 [("tab",
1317 Print.PD.string tab),
1318 ("r1",
1319 p_exp (Proj (r1, f))),
1320 ("r2",
1321 p_exp (Proj (r2, f))),
1322 ("r",
1323 Print.PD.string
1324 (Bool.toString r))];*)
1325 r
1326 end)) ks then
1327 ((*Print.prefaces "Key match" [("tab", Print.PD.string tab),
1328 ("r1", p_exp r1),
1329 ("r2", p_exp r2),
1330 ("rp1", Cc.p_repOf cc r1),
1331 ("rp2", Cc.p_repOf cc r2)];*)
1332 Cc.assert (db, AReln (Eq, [r1, r2])))
1333 else
1334 ();
1335 finder hyps)
1336 | _ :: hyps => finder hyps
1337 in
1338 finder hyps;
1339 findKeys hyps
1340 end)
1341 | _ :: hyps => findKeys hyps
1342
1343 val (_, hs) = !hyps
1344 in
1345 (*print "findKeys\n";*)
1346 findKeys hs
1347 end 1337 end
1348 1338
1349 fun buildable uk (e, loc) = 1339 fun buildable uk (e, loc) =
1350 let 1340 let
1351 fun doPols pols acc = 1341 fun doPols pols acc =
1356 Cc.builtFrom (db, {UseKnown = uk, Base = acc, Derived = e})) 1346 Cc.builtFrom (db, {UseKnown = uk, Base = acc, Derived = e}))
1357 | (goals, es) :: pols => 1347 | (goals, es) :: pols =>
1358 checkGoals goals (fn unifs => doPols pols (map (simplify unifs) es @ acc)) 1348 checkGoals goals (fn unifs => doPols pols (map (simplify unifs) es @ acc))
1359 orelse doPols pols acc 1349 orelse doPols pols acc
1360 in 1350 in
1361 useKeys ();
1362 if doPols (!sendable) [] then 1351 if doPols (!sendable) [] then
1363 () 1352 ()
1364 else 1353 else
1365 let 1354 let
1366 val (_, hs) = !hyps 1355 val (_, hs, _) = !hyps
1367 in 1356 in
1368 ErrorMsg.errorAt loc "The information flow policy may be violated here."; 1357 ErrorMsg.errorAt loc "The information flow policy may be violated here.";
1369 Print.prefaces "Situation" [("Hypotheses", Print.p_list p_atom hs), 1358 Print.prefaces "Situation" [("Hypotheses", Print.p_list p_atom hs),
1370 ("User learns", p_exp e), 1359 ("User learns", p_exp e)(*,
1371 ("E-graph", Cc.p_database db)] 1360 ("E-graph", Cc.p_database db)*)]
1372 end 1361 end
1373 end 1362 end
1374 1363
1375 fun checkPaths () = 1364 fun checkPaths () =
1376 let 1365 let
1377 val hs = !hyps 1366 val (n, hs, _) = !hyps
1367 val hs = (n, hs)
1378 in 1368 in
1379 app (fn r => 1369 app (fn r =>
1380 case !r of 1370 case !r of
1381 NONE => () 1371 NONE => ()
1382 | SOME (hs, e) => 1372 | SOME (hs, e) =>
1389 fun allowSend v = ((*Print.prefaces "Allow" [("goals", Print.p_list p_atom (#1 v)), 1379 fun allowSend v = ((*Print.prefaces "Allow" [("goals", Print.p_list p_atom (#1 v)),
1390 ("exps", Print.p_list p_exp (#2 v))];*) 1380 ("exps", Print.p_list p_exp (#2 v))];*)
1391 sendable := v :: !sendable) 1381 sendable := v :: !sendable)
1392 1382
1393 fun send uk (e, loc) = ((*Print.preface ("Send", p_exp e);*) 1383 fun send uk (e, loc) = ((*Print.preface ("Send", p_exp e);*)
1384 complete ();
1394 checkPaths (); 1385 checkPaths ();
1395 if isKnown e then 1386 if isKnown e then
1396 () 1387 ()
1397 else 1388 else
1398 buildable uk (e, loc)) 1389 buildable uk (e, loc))
1399 1390
1400 fun doable pols (loc : ErrorMsg.span) = 1391 fun doable pols (loc : ErrorMsg.span) =
1401 let 1392 let
1402 val pols = !pols 1393 val pols = !pols
1403 in 1394 in
1395 complete ();
1404 if List.exists (fn goals => 1396 if List.exists (fn goals =>
1405 if checkGoals goals (fn _ => true) then 1397 if checkGoals goals (fn _ => true) then
1406 ((*Print.prefaces "Match" [("goals", Print.p_list p_atom goals), 1398 ((*Print.prefaces "Match" [("goals", Print.p_list p_atom goals),
1407 ("hyps", Print.p_list p_atom (#2 (!hyps)))];*) 1399 ("hyps", Print.p_list p_atom (#2 (!hyps)))];*)
1408 true) 1400 true)
1411 ("hyps", Print.p_list p_atom (#2 (!hyps)))];*) 1403 ("hyps", Print.p_list p_atom (#2 (!hyps)))];*)
1412 false)) pols then 1404 false)) pols then
1413 () 1405 ()
1414 else 1406 else
1415 let 1407 let
1416 val (_, hs) = !hyps 1408 val (_, hs, _) = !hyps
1417 in 1409 in
1418 ErrorMsg.errorAt loc "The database update policy may be violated here."; 1410 ErrorMsg.errorAt loc "The database update policy may be violated here.";
1419 Print.preface ("Hypotheses", Print.p_list p_atom hs) 1411 Print.preface ("Hypotheses", Print.p_list p_atom hs)
1420 end 1412 end
1421 end 1413 end
1432 fun allowDelete v = deletable := v :: !deletable 1424 fun allowDelete v = deletable := v :: !deletable
1433 val delete = doable deletable 1425 val delete = doable deletable
1434 1426
1435 fun reset () = (Cc.clear db; 1427 fun reset () = (Cc.clear db;
1436 path := []; 1428 path := [];
1437 hyps := (0, []); 1429 hyps := (0, [], ref false);
1438 nvar := 0; 1430 nvar := 0;
1439 sendable := []; 1431 sendable := [];
1440 insertable := []; 1432 insertable := [];
1441 updatable := []; 1433 updatable := [];
1442 deletable := []) 1434 deletable := [])
1443 1435
1444 fun havocReln r = 1436 fun havocReln r =
1445 let 1437 let
1446 val n = !hnames 1438 val n = !hnames
1447 val (_, hs) = !hyps 1439 val (_, hs, _) = !hyps
1448 in 1440 in
1449 hnames := n + 1; 1441 hnames := n + 1;
1450 hyps := (n, List.filter (fn AReln (r', _) => r' <> r | _ => true) hs) 1442 hyps := (n, List.filter (fn AReln (r', _) => r' <> r | _ => true) hs, ref false)
1451 end 1443 end
1452 1444
1453 fun debug () = 1445 fun debug () =
1454 let 1446 let
1455 val (_, hs) = !hyps 1447 val (_, hs, _) = !hyps
1456 in 1448 in
1457 Print.preface ("Hyps", Print.p_list p_atom hs) 1449 Print.preface ("Hyps", Print.p_list p_atom hs)
1458 end 1450 end
1459 1451
1460 end 1452 end