comparison src/iflow.sml @ 1226:df5bd4115267

Use functional dependency information
author Adam Chlipala <adamc@hcoop.net>
date Sun, 11 Apr 2010 15:05:51 -0400
parents 3950cf1f5736
children 1d8fba74e7f5
comparison
equal deleted inserted replaced
1225:950d1e540df6 1226:df5bd4115267
390 val check : database * atom -> bool 390 val check : database * atom -> bool
391 391
392 val p_database : database Print.printer 392 val p_database : database Print.printer
393 393
394 val builtFrom : database * {Base : exp list, Derived : exp} -> bool 394 val builtFrom : database * {Base : exp list, Derived : exp} -> bool
395
396 val p_repOf : database -> exp Print.printer
395 end = struct 397 end = struct
396 398
397 exception Contradiction 399 exception Contradiction
398 exception Undetermined 400 exception Undetermined
399 401
410 and variety = 412 and variety =
411 Dt0 of string 413 Dt0 of string
412 | Dt1 of string * node ref 414 | Dt1 of string * node ref
413 | Prim of Prim.t 415 | Prim of Prim.t
414 | Recrd of node ref SM.map ref * bool 416 | Recrd of node ref SM.map ref * bool
415 | VFinish
416 | Nothing 417 | Nothing
417 418
418 type representative = node ref 419 type representative = node ref
419
420 val finish = ref (Node {Rep = ref NONE,
421 Cons = ref SM.empty,
422 Variety = VFinish,
423 Known = ref true})
424 420
425 type database = {Vars : representative IM.map ref, 421 type database = {Vars : representative IM.map ref,
426 Consts : representative CM.map ref, 422 Consts : representative CM.map ref,
427 Con0s : representative SM.map ref, 423 Con0s : representative SM.map ref,
428 Records : (representative SM.map * representative) list ref, 424 Records : (representative SM.map * representative) list ref,
465 string "}", 461 string "}",
466 if b then 462 if b then
467 box [space, 463 box [space,
468 string "(complete)"] 464 string "(complete)"]
469 else 465 else
470 box []] 466 box []]]
471 | VFinish => string "FINISH"]
472 467
473 fun p_database (db : database) = 468 fun p_database (db : database) =
474 box [string "Vars:", 469 box [string "Vars:",
475 newline, 470 newline,
476 p_list_sep newline (fn (i, n) => box [string ("x" ^ Int.toString i), 471 p_list_sep newline (fn (i, n) => box [string ("x" ^ Int.toString i),
598 in 593 in
599 cons := SM.insert (!cons, f, r''); 594 cons := SM.insert (!cons, f, r'');
600 #Rep (unNode r) := SOME r''; 595 #Rep (unNode r) := SOME r'';
601 r' 596 r'
602 end 597 end
603 | VFinish => r
604 | _ => raise Contradiction 598 | _ => raise Contradiction
605 end 599 end
606 | Func (UnCon _, _) => raise Fail "Iflow.rep: UnCon" 600 | Func (UnCon _, _) => raise Fail "Iflow.rep: UnCon"
607 | Func (Other f, es) => 601 | Func (Other f, es) =>
608 let 602 let
677 Known = #Known (unNode r)}) 671 Known = #Known (unNode r)})
678 in 672 in
679 #Rep (unNode r) := SOME r''; 673 #Rep (unNode r) := SOME r'';
680 r' 674 r'
681 end 675 end
682 | VFinish => r
683 | _ => raise Contradiction 676 | _ => raise Contradiction
684 end 677 end
685 | Finish => finish 678 | Finish => raise Contradiction
686 in 679 in
687 rep e 680 rep e
688 end 681 end
682
683 fun p_repOf db e = p_rep (representative (db, e))
689 684
690 fun assert (db, a) = 685 fun assert (db, a) =
691 case a of 686 case a of
692 ACond _ => () 687 ACond _ => ()
693 | AReln x => 688 | AReln x =>
744 | _ => raise Contradiction 739 | _ => raise Contradiction
745 end 740 end
746 | (Eq, [e1, e2]) => 741 | (Eq, [e1, e2]) =>
747 let 742 let
748 fun markEq (r1, r2) = 743 fun markEq (r1, r2) =
749 if r1 = r2 then 744 let
750 () 745 val r1 = repOf r1
751 else case (#Variety (unNode r1), #Variety (unNode r2)) of 746 val r2 = repOf r2
752 (Prim p1, Prim p2) => if Prim.equal (p1, p2) then 747 in
753 () 748 if r1 = r2 then
754 else 749 ()
755 raise Contradiction 750 else case (#Variety (unNode r1), #Variety (unNode r2)) of
756 | (Dt0 f1, Dt0 f2) => if f1 = f2 then 751 (Prim p1, Prim p2) => if Prim.equal (p1, p2) then
757 () 752 ()
758 else 753 else
759 raise Contradiction 754 raise Contradiction
760 | (Dt1 (f1, r1), Dt1 (f2, r2)) => if f1 = f2 then 755 | (Dt0 f1, Dt0 f2) => if f1 = f2 then
761 markEq (r1, r2) 756 ()
762 else 757 else
763 raise Contradiction 758 raise Contradiction
764 | (Recrd (xes1, _), Recrd (xes2, _)) => 759 | (Dt1 (f1, r1), Dt1 (f2, r2)) => if f1 = f2 then
765 let 760 markEq (r1, r2)
766 fun unif (xes1, xes2) = 761 else
767 SM.appi (fn (x, r1) => 762 raise Contradiction
768 case SM.find (xes2, x) of 763 | (Recrd (xes1, _), Recrd (xes2, _)) =>
769 NONE => () 764 let
770 | SOME r2 => markEq (r1, r2)) xes1 765 fun unif (xes1, xes2) =
771 in 766 SM.appi (fn (x, r1) =>
772 unif (!xes1, !xes2); 767 case SM.find (!xes2, x) of
773 unif (!xes2, !xes1) 768 NONE => xes2 := SM.insert (!xes2, x, r1)
774 end 769 | SOME r2 => markEq (r1, r2)) (!xes1)
775 | (VFinish, VFinish) => () 770 in
776 | (Nothing, _) => mergeNodes (r1, r2) 771 unif (xes1, xes2);
777 | (_, Nothing) => mergeNodes (r2, r1) 772 unif (xes2, xes1)
778 | _ => raise Contradiction 773 end
774 | (Nothing, _) => mergeNodes (r1, r2)
775 | (_, Nothing) => mergeNodes (r2, r1)
776 | _ => raise Contradiction
777 end
779 778
780 and mergeNodes (r1, r2) = 779 and mergeNodes (r1, r2) =
781 (#Rep (unNode r1) := SOME r2; 780 (#Rep (unNode r1) := SOME r2;
782 if !(#Known (unNode r1)) then 781 if !(#Known (unNode r1)) then
783 markKnown r2 782 markKnown r2
868 orelse case #Variety (unNode d) of 867 orelse case #Variety (unNode d) of
869 Dt0 _ => true 868 Dt0 _ => true
870 | Dt1 (_, d) => loop d 869 | Dt1 (_, d) => loop d
871 | Prim _ => true 870 | Prim _ => true
872 | Recrd (xes, _) => List.all loop (SM.listItems (!xes)) 871 | Recrd (xes, _) => List.all loop (SM.listItems (!xes))
873 | VFinish => true
874 | Nothing => false 872 | Nothing => false
875 end 873 end
876 in 874 in
877 loop (representative (db, d)) 875 loop (representative (db, d))
878 end 876 end
896 | Cond x => k [ACond x] 894 | Cond x => k [ACond x]
897 in 895 in
898 decomp 896 decomp
899 end 897 end
900 898
899 val tabs = ref (SM.empty : (string list * string list list) SM.map)
900
901 fun imply (hyps, goals, outs) = 901 fun imply (hyps, goals, outs) =
902 let 902 let
903 fun gls goals onFail acc = 903 fun gls goals onFail acc =
904 case goals of 904 case goals of
905 [] => 905 [] =>
906 (let 906 (let
907 val cc = Cc.database () 907 val cc = Cc.database ()
908 val () = app (fn a => Cc.assert (cc, a)) hyps 908 val () = app (fn a => Cc.assert (cc, a)) hyps
909
910 (* Take advantage of table key information *)
911 fun findKeys hyps =
912 case hyps of
913 [] => ()
914 | AReln (Sql tab, [r1]) :: hyps =>
915 (case SM.find (!tabs, tab) of
916 NONE => findKeys hyps
917 | SOME (_, []) => findKeys hyps
918 | SOME (_, ks) =>
919 let
920 fun finder hyps =
921 case hyps of
922 [] => ()
923 | AReln (Sql tab', [r2]) :: hyps =>
924 (if tab' = tab andalso
925 List.exists (List.all (fn f =>
926 let
927 val r =
928 Cc.check (cc,
929 AReln (Eq, [Proj (r1, f),
930 Proj (r2, f)]))
931 in
932 (*Print.prefaces "Fs"
933 [("tab",
934 Print.PD.string tab),
935 ("r1",
936 p_exp (Proj (r1, f))),
937 ("r2",
938 p_exp (Proj (r2, f))),
939 ("r",
940 Print.PD.string
941 (Bool.toString r))];*)
942 r
943 end)) ks then
944 ((*Print.prefaces "Key match" [("tab", Print.PD.string tab),
945 ("r1", p_exp r1),
946 ("r2", p_exp r2),
947 ("rp1", Cc.p_repOf cc r1),
948 ("rp2", Cc.p_repOf cc r2)];*)
949 Cc.assert (cc, AReln (Eq, [r1, r2])))
950 else
951 ();
952 finder hyps)
953 | _ :: hyps => finder hyps
954 in
955 finder hyps;
956 findKeys hyps
957 end)
958 | _ :: hyps => findKeys hyps
909 in 959 in
960 findKeys hyps;
961
910 (*Print.preface ("db", Cc.p_database cc);*) 962 (*Print.preface ("db", Cc.p_database cc);*)
911 (List.all (fn a => 963 (List.all (fn a =>
912 if Cc.check (cc, a) then 964 if Cc.check (cc, a) then
913 true 965 true
914 else 966 else
1832 Delete = #Delete t, 1884 Delete = #Delete t,
1833 Update = c :: #Update t} 1885 Update = c :: #Update t}
1834 1886
1835 end 1887 end
1836 1888
1837 val tabs = ref (SM.empty : string list SM.map)
1838
1839 fun evalExp env (e as (_, loc), st) = 1889 fun evalExp env (e as (_, loc), st) =
1840 let 1890 let
1841 fun default () = 1891 fun default () =
1842 let 1892 let
1843 val (st, nv) = St.nextVar st 1893 val (st, nv) = St.nextVar st
2139 in 2189 in
2140 ((x, e), st) 2190 ((x, e), st)
2141 end) 2191 end)
2142 st fs 2192 st fs
2143 2193
2144 val fs' = case SM.find (!tabs, "uw_" ^ tab) of 2194 val fs' = case SM.find (!tabs, tab) of
2145 NONE => raise Fail "Iflow.evalExp: Updating unknown table" 2195 NONE => raise Fail "Iflow.evalExp: Updating unknown table"
2146 | SOME fs' => fs' 2196 | SOME (fs', _) => fs'
2147 2197
2148 val fs = foldl (fn (f, fs) => 2198 val fs = foldl (fn (f, fs) =>
2149 if List.exists (fn (f', _) => f' = f) fs then 2199 if List.exists (fn (f', _) => f' = f) fs then
2150 fs 2200 fs
2151 else 2201 else
2198 DExport (_, _, n, _, _, _) => IS.add (exptd, n) 2248 DExport (_, _, n, _, _, _) => IS.add (exptd, n)
2199 | _ => exptd) IS.empty file 2249 | _ => exptd) IS.empty file
2200 2250
2201 fun decl ((d, _), (vals, inserts, deletes, updates, client, insert, delete, update)) = 2251 fun decl ((d, _), (vals, inserts, deletes, updates, client, insert, delete, update)) =
2202 case d of 2252 case d of
2203 DTable (tab, fs, _, _) => 2253 DTable (tab, fs, pk, _) =>
2204 (tabs := SM.insert (!tabs, tab, map #1 fs); 2254 let
2205 (vals, inserts, deletes, updates, client, insert, delete, update)) 2255 val ks =
2256 case #1 pk of
2257 EPrim (Prim.String s) =>
2258 (case String.tokens (fn ch => ch = #"," orelse ch = #" ") s of
2259 [] => []
2260 | pk => [pk])
2261 | _ => []
2262 in
2263 if size tab >= 3 then
2264 (tabs := SM.insert (!tabs, String.extract (tab, 3, NONE),
2265 (map #1 fs,
2266 map (map (fn s => str (Char.toUpper (String.sub (s, 3)))
2267 ^ String.extract (s, 4, NONE))) ks));
2268 (vals, inserts, deletes, updates, client, insert, delete, update))
2269 else
2270 raise Fail "Table name does not begin with uw_"
2271 end
2206 | DVal (_, n, _, e, _) => 2272 | DVal (_, n, _, e, _) =>
2207 let 2273 let
2208 val isExptd = IS.member (exptd, n) 2274 val isExptd = IS.member (exptd, n)
2209 2275
2210 fun deAbs (e, env, nv, p) = 2276 fun deAbs (e, env, nv, p) =