89 assumptions. *) |
89 assumptions. *) |
90 exception Contr of proof; |
90 exception Contr of proof; |
91 (* Internal exception, raised if contradiction ( x < x ) was derived *) |
91 (* Internal exception, raised if contradiction ( x < x ) was derived *) |
92 |
92 |
93 fun prove asms = |
93 fun prove asms = |
94 let fun pr (Asm i) = nth_elem (i, asms) |
94 let fun pr (Asm i) = List.nth (asms, i) |
95 | pr (Thm (prfs, thm)) = (map pr prfs) MRS thm |
95 | pr (Thm (prfs, thm)) = (map pr prfs) MRS thm |
96 in pr end; |
96 in pr end; |
97 |
97 |
98 (* Internal datatype for inequalities *) |
98 (* Internal datatype for inequalities *) |
99 datatype less |
99 datatype less |
435 end |
435 end |
436 | assemble nil _ = nil |
436 | assemble nil _ = nil |
437 |
437 |
438 (* Compute, for each adjacency list, the list with reversed edges, |
438 (* Compute, for each adjacency list, the list with reversed edges, |
439 and concatenate these lists. *) |
439 and concatenate these lists. *) |
440 val flipped = foldr (op @) ((map flip g),nil) |
440 val flipped = Library.foldr (op @) ((map flip g),nil) |
441 |
441 |
442 in assemble g flipped end |
442 in assemble g flipped end |
443 |
443 |
444 (* *********************************************************************** *) |
444 (* *********************************************************************** *) |
445 (* *) |
445 (* *) |
473 (* Returns the nodes in the DFS tree rooted at u in g *) |
473 (* Returns the nodes in the DFS tree rooted at u in g *) |
474 fun dfs_visit g u : term list = |
474 fun dfs_visit g u : term list = |
475 let |
475 let |
476 val _ = visited := u :: !visited |
476 val _ = visited := u :: !visited |
477 val descendents = |
477 val descendents = |
478 foldr (fn ((v,l),ds) => if been_visited v then ds |
478 Library.foldr (fn ((v,l),ds) => if been_visited v then ds |
479 else v :: dfs_visit g v @ ds) |
479 else v :: dfs_visit g v @ ds) |
480 ((adjacent (op aconv) g u) ,nil) |
480 ((adjacent (op aconv) g u) ,nil) |
481 in |
481 in |
482 finish := u :: !finish; |
482 finish := u :: !finish; |
483 descendents |
483 descendents |
497 |
497 |
498 (* DFS on the transpose. The vertices returned by |
498 (* DFS on the transpose. The vertices returned by |
499 dfs_visit along with u form a connected component. We |
499 dfs_visit along with u form a connected component. We |
500 collect all the connected components together in a |
500 collect all the connected components together in a |
501 list, which is what is returned. *) |
501 list, which is what is returned. *) |
502 foldl (fn (comps,u) => |
502 Library.foldl (fn (comps,u) => |
503 if been_visited u then comps |
503 if been_visited u then comps |
504 else ((u :: dfs_visit (transpose (op aconv) G) u) :: comps)) (nil,(!finish)) |
504 else ((u :: dfs_visit (transpose (op aconv) G) u) :: comps)) (nil,(!finish)) |
505 end; |
505 end; |
506 |
506 |
507 |
507 |
523 |
523 |
524 fun dfs_visit g u : int list = |
524 fun dfs_visit g u : int list = |
525 let |
525 let |
526 val _ = visited := u :: !visited |
526 val _ = visited := u :: !visited |
527 val descendents = |
527 val descendents = |
528 foldr (fn ((v,l),ds) => if been_visited v then ds |
528 Library.foldr (fn ((v,l),ds) => if been_visited v then ds |
529 else v :: dfs_visit g v @ ds) |
529 else v :: dfs_visit g v @ ds) |
530 ( ((adjacent (op =) g u)) ,nil) |
530 ( ((adjacent (op =) g u)) ,nil) |
531 in descendents end |
531 in descendents end |
532 |
532 |
533 in u :: dfs_visit g u end; |
533 in u :: dfs_visit g u end; |
535 |
535 |
536 fun indexComps components = |
536 fun indexComps components = |
537 ListPair.map (fn (a,b) => (a,b)) (0 upto (length components -1), components); |
537 ListPair.map (fn (a,b) => (a,b)) (0 upto (length components -1), components); |
538 |
538 |
539 fun indexNodes IndexComp = |
539 fun indexNodes IndexComp = |
540 flat (map (fn (index, comp) => (map (fn v => (v,index)) comp)) IndexComp); |
540 List.concat (map (fn (index, comp) => (map (fn v => (v,index)) comp)) IndexComp); |
541 |
541 |
542 fun getIndex v [] = ~1 |
542 fun getIndex v [] = ~1 |
543 | getIndex v ((v',k)::vs) = if v aconv v' then k else getIndex v vs; |
543 | getIndex v ((v',k)::vs) = if v aconv v' then k else getIndex v vs; |
544 |
544 |
545 |
545 |
649 let val edge = lookup (getIndex y' ntc) predlist |
649 let val edge = lookup (getIndex y' ntc) predlist |
650 val u = lower edge |
650 val u = lower edge |
651 val v = upper edge |
651 val v = upper edge |
652 in |
652 in |
653 if (getIndex u ntc) = xi then |
653 if (getIndex u ntc) = xi then |
654 (completeTermPath x u (nth_elem(xi, sccSubgraphs)) )@[edge] |
654 (completeTermPath x u (List.nth(sccSubgraphs, xi)) )@[edge] |
655 @(completeTermPath v y' (nth_elem((getIndex y' ntc),sccSubgraphs)) ) |
655 @(completeTermPath v y' (List.nth(sccSubgraphs, getIndex y' ntc)) ) |
656 else (rev_completeComponentPath u)@[edge] |
656 else (rev_completeComponentPath u)@[edge] |
657 @(completeTermPath v y' (nth_elem((getIndex y' ntc),sccSubgraphs)) ) |
657 @(completeTermPath v y' (List.nth(sccSubgraphs, getIndex y' ntc)) ) |
658 end |
658 end |
659 in |
659 in |
660 if x aconv y then |
660 if x aconv y then |
661 [(Le (x, y, (Thm ([], Less.le_refl))))] |
661 [(Le (x, y, (Thm ([], Less.le_refl))))] |
662 else ( if xi = yi then completeTermPath x y (nth_elem(xi, sccSubgraphs)) |
662 else ( if xi = yi then completeTermPath x y (List.nth(sccSubgraphs, xi)) |
663 else rev_completeComponentPath y ) |
663 else rev_completeComponentPath y ) |
664 end; |
664 end; |
665 |
665 |
666 (* ******************************************************************* *) |
666 (* ******************************************************************* *) |
667 (* findLess e x y xi yi xreachable yreachable *) |
667 (* findLess e x y xi yi xreachable yreachable *) |
818 ) |
818 ) |
819 ) |
819 ) |
820 (* if SCC_x is linked to SCC_y via edge e *) |
820 (* if SCC_x is linked to SCC_y via edge e *) |
821 else if ui = xi andalso vi = yi then ( |
821 else if ui = xi andalso vi = yi then ( |
822 case e of (Less (_, _,_)) => ( |
822 case e of (Less (_, _,_)) => ( |
823 let val xypath = (completeTermPath x u (nth_elem(ui, sccSubgraphs)) ) @ [e] @ (completeTermPath v y (nth_elem(vi, sccSubgraphs)) ) |
823 let val xypath = (completeTermPath x u (List.nth(sccSubgraphs, ui)) ) @ [e] @ (completeTermPath v y (List.nth(sccSubgraphs, vi)) ) |
824 val xyLesss = transPath (tl xypath, hd xypath) |
824 val xyLesss = transPath (tl xypath, hd xypath) |
825 in (Thm ([getprf xyLesss], Less.less_imp_neq)) end) |
825 in (Thm ([getprf xyLesss], Less.less_imp_neq)) end) |
826 | _ => ( |
826 | _ => ( |
827 let |
827 let |
828 val xupath = completeTermPath x u (nth_elem(ui, sccSubgraphs)) |
828 val xupath = completeTermPath x u (List.nth(sccSubgraphs, ui)) |
829 val uxpath = completeTermPath u x (nth_elem(ui, sccSubgraphs)) |
829 val uxpath = completeTermPath u x (List.nth(sccSubgraphs, ui)) |
830 val vypath = completeTermPath v y (nth_elem(vi, sccSubgraphs)) |
830 val vypath = completeTermPath v y (List.nth(sccSubgraphs, vi)) |
831 val yvpath = completeTermPath y v (nth_elem(vi, sccSubgraphs)) |
831 val yvpath = completeTermPath y v (List.nth(sccSubgraphs, vi)) |
832 val xuLesss = transPath (tl xupath, hd xupath) |
832 val xuLesss = transPath (tl xupath, hd xupath) |
833 val uxLesss = transPath (tl uxpath, hd uxpath) |
833 val uxLesss = transPath (tl uxpath, hd uxpath) |
834 val vyLesss = transPath (tl vypath, hd vypath) |
834 val vyLesss = transPath (tl vypath, hd vypath) |
835 val yvLesss = transPath (tl yvpath, hd yvpath) |
835 val yvLesss = transPath (tl yvpath, hd yvpath) |
836 val x_eq_u = (Thm ([(getprf xuLesss),(getprf uxLesss)], Less.eqI)) |
836 val x_eq_u = (Thm ([(getprf xuLesss),(getprf uxLesss)], Less.eqI)) |
839 (Thm ([x_eq_u , (getprf e), v_eq_y ], Less.eq_neq_eq_imp_neq)) |
839 (Thm ([x_eq_u , (getprf e), v_eq_y ], Less.eq_neq_eq_imp_neq)) |
840 end |
840 end |
841 ) |
841 ) |
842 ) else if ui = yi andalso vi = xi then ( |
842 ) else if ui = yi andalso vi = xi then ( |
843 case e of (Less (_, _,_)) => ( |
843 case e of (Less (_, _,_)) => ( |
844 let val xypath = (completeTermPath y u (nth_elem(ui, sccSubgraphs)) ) @ [e] @ (completeTermPath v x (nth_elem(vi, sccSubgraphs)) ) |
844 let val xypath = (completeTermPath y u (List.nth(sccSubgraphs, ui)) ) @ [e] @ (completeTermPath v x (List.nth(sccSubgraphs, vi)) ) |
845 val xyLesss = transPath (tl xypath, hd xypath) |
845 val xyLesss = transPath (tl xypath, hd xypath) |
846 in (Thm ([(Thm ([getprf xyLesss], Less.less_imp_neq))] , thm "not_sym")) end ) |
846 in (Thm ([(Thm ([getprf xyLesss], Less.less_imp_neq))] , thm "not_sym")) end ) |
847 | _ => ( |
847 | _ => ( |
848 |
848 |
849 let val yupath = completeTermPath y u (nth_elem(ui, sccSubgraphs)) |
849 let val yupath = completeTermPath y u (List.nth(sccSubgraphs, ui)) |
850 val uypath = completeTermPath u y (nth_elem(ui, sccSubgraphs)) |
850 val uypath = completeTermPath u y (List.nth(sccSubgraphs, ui)) |
851 val vxpath = completeTermPath v x (nth_elem(vi, sccSubgraphs)) |
851 val vxpath = completeTermPath v x (List.nth(sccSubgraphs, vi)) |
852 val xvpath = completeTermPath x v (nth_elem(vi, sccSubgraphs)) |
852 val xvpath = completeTermPath x v (List.nth(sccSubgraphs, vi)) |
853 val yuLesss = transPath (tl yupath, hd yupath) |
853 val yuLesss = transPath (tl yupath, hd yupath) |
854 val uyLesss = transPath (tl uypath, hd uypath) |
854 val uyLesss = transPath (tl uypath, hd uypath) |
855 val vxLesss = transPath (tl vxpath, hd vxpath) |
855 val vxLesss = transPath (tl vxpath, hd vxpath) |
856 val xvLesss = transPath (tl xvpath, hd xvpath) |
856 val xvLesss = transPath (tl xvpath, hd xvpath) |
857 val y_eq_u = (Thm ([(getprf yuLesss),(getprf uyLesss)], Less.eqI)) |
857 val y_eq_u = (Thm ([(getprf yuLesss),(getprf uyLesss)], Less.eqI)) |
942 (* k is index of the actual component *) |
942 (* k is index of the actual component *) |
943 |
943 |
944 fun processComponent (k, comp) = |
944 fun processComponent (k, comp) = |
945 let |
945 let |
946 (* all edges with weight <= of the actual component *) |
946 (* all edges with weight <= of the actual component *) |
947 val leqEdges = flat (map (adjacent (op aconv) leqG) comp); |
947 val leqEdges = List.concat (map (adjacent (op aconv) leqG) comp); |
948 (* all edges with weight ~= of the actual component *) |
948 (* all edges with weight ~= of the actual component *) |
949 val neqEdges = map snd (flat (map (adjacent (op aconv) neqG) comp)); |
949 val neqEdges = map snd (List.concat (map (adjacent (op aconv) neqG) comp)); |
950 |
950 |
951 (* find an edge leading to a contradiction *) |
951 (* find an edge leading to a contradiction *) |
952 fun findContr [] = NONE |
952 fun findContr [] = NONE |
953 | findContr (e::es) = |
953 | findContr (e::es) = |
954 let val ui = (getIndex (lower e) ntc) |
954 let val ui = (getIndex (lower e) ntc) |
1062 val partial_tac = SUBGOAL (fn (A, n, sign) => |
1062 val partial_tac = SUBGOAL (fn (A, n, sign) => |
1063 let |
1063 let |
1064 val rfrees = map Free (rename_wrt_term A (Logic.strip_params A)) |
1064 val rfrees = map Free (rename_wrt_term A (Logic.strip_params A)) |
1065 val Hs = map (fn H => subst_bounds (rfrees, H)) (Logic.strip_assums_hyp A) |
1065 val Hs = map (fn H => subst_bounds (rfrees, H)) (Logic.strip_assums_hyp A) |
1066 val C = subst_bounds (rfrees, Logic.strip_assums_concl A) |
1066 val C = subst_bounds (rfrees, Logic.strip_assums_concl A) |
1067 val lesss = flat (ListPair.map (mkasm_partial sign) (Hs, 0 upto (length Hs - 1))) |
1067 val lesss = List.concat (ListPair.map (mkasm_partial sign) (Hs, 0 upto (length Hs - 1))) |
1068 val prfs = solvePartialOrder sign (lesss, C); |
1068 val prfs = solvePartialOrder sign (lesss, C); |
1069 val (subgoals, prf) = mkconcl_partial sign C; |
1069 val (subgoals, prf) = mkconcl_partial sign C; |
1070 in |
1070 in |
1071 METAHYPS (fn asms => |
1071 METAHYPS (fn asms => |
1072 let val thms = map (prove asms) prfs |
1072 let val thms = map (prove asms) prfs |
1080 val linear_tac = SUBGOAL (fn (A, n, sign) => |
1080 val linear_tac = SUBGOAL (fn (A, n, sign) => |
1081 let |
1081 let |
1082 val rfrees = map Free (rename_wrt_term A (Logic.strip_params A)) |
1082 val rfrees = map Free (rename_wrt_term A (Logic.strip_params A)) |
1083 val Hs = map (fn H => subst_bounds (rfrees, H)) (Logic.strip_assums_hyp A) |
1083 val Hs = map (fn H => subst_bounds (rfrees, H)) (Logic.strip_assums_hyp A) |
1084 val C = subst_bounds (rfrees, Logic.strip_assums_concl A) |
1084 val C = subst_bounds (rfrees, Logic.strip_assums_concl A) |
1085 val lesss = flat (ListPair.map (mkasm_linear sign) (Hs, 0 upto (length Hs - 1))) |
1085 val lesss = List.concat (ListPair.map (mkasm_linear sign) (Hs, 0 upto (length Hs - 1))) |
1086 val prfs = solveTotalOrder sign (lesss, C); |
1086 val prfs = solveTotalOrder sign (lesss, C); |
1087 val (subgoals, prf) = mkconcl_linear sign C; |
1087 val (subgoals, prf) = mkconcl_linear sign C; |
1088 in |
1088 in |
1089 METAHYPS (fn asms => |
1089 METAHYPS (fn asms => |
1090 let val thms = map (prove asms) prfs |
1090 let val thms = map (prove asms) prfs |