51 |
51 |
52 (*preprocessing, performed on a representation of subgoals as list of premises:*) |
52 (*preprocessing, performed on a representation of subgoals as list of premises:*) |
53 val pre_decomp: Proof.context -> typ list * term list -> (typ list * term list) list |
53 val pre_decomp: Proof.context -> typ list * term list -> (typ list * term list) list |
54 |
54 |
55 (*preprocessing, performed on the goal -- must do the same as 'pre_decomp':*) |
55 (*preprocessing, performed on the goal -- must do the same as 'pre_decomp':*) |
56 val pre_tac: simpset -> int -> tactic |
56 val pre_tac: Proof.context -> int -> tactic |
57 |
57 |
58 (*the limit on the number of ~= allowed; because each ~= is split |
58 (*the limit on the number of ~= allowed; because each ~= is split |
59 into two cases, this can lead to an explosion*) |
59 into two cases, this can lead to an explosion*) |
60 val neq_limit: int Config.T |
60 val neq_limit: int Config.T |
61 |
61 |
77 be modified by pre_decomp (pre_tac, resp.) in a corresponding way. See |
77 be modified by pre_decomp (pre_tac, resp.) in a corresponding way. See |
78 the comment for split_items below. (This is even necessary for eta- and |
78 the comment for split_items below. (This is even necessary for eta- and |
79 beta-equivalent modifications, as some of the lin. arith. code is not |
79 beta-equivalent modifications, as some of the lin. arith. code is not |
80 insensitive to them.) |
80 insensitive to them.) |
81 |
81 |
82 ss must reduce contradictory <= to False. |
82 Simpset must reduce contradictory <= to False. |
83 It should also cancel common summands to keep <= reduced; |
83 It should also cancel common summands to keep <= reduced; |
84 otherwise <= can grow to massive proportions. |
84 otherwise <= can grow to massive proportions. |
85 *) |
85 *) |
86 |
86 |
87 signature FAST_LIN_ARITH = |
87 signature FAST_LIN_ARITH = |
88 sig |
88 sig |
89 val prems_lin_arith_tac: simpset -> int -> tactic |
89 val prems_lin_arith_tac: Proof.context -> int -> tactic |
90 val lin_arith_tac: Proof.context -> bool -> int -> tactic |
90 val lin_arith_tac: Proof.context -> bool -> int -> tactic |
91 val lin_arith_simproc: simpset -> term -> thm option |
91 val lin_arith_simproc: Proof.context -> term -> thm option |
92 val map_data: |
92 val map_data: |
93 ({add_mono_thms: thm list, mult_mono_thms: thm list, inj_thms: thm list, |
93 ({add_mono_thms: thm list, mult_mono_thms: thm list, inj_thms: thm list, |
94 lessD: thm list, neqE: thm list, simpset: Simplifier.simpset, |
94 lessD: thm list, neqE: thm list, simpset: simpset, |
95 number_of: (theory -> typ -> int -> cterm) option} -> |
95 number_of: (theory -> typ -> int -> cterm) option} -> |
96 {add_mono_thms: thm list, mult_mono_thms: thm list, inj_thms: thm list, |
96 {add_mono_thms: thm list, mult_mono_thms: thm list, inj_thms: thm list, |
97 lessD: thm list, neqE: thm list, simpset: Simplifier.simpset, |
97 lessD: thm list, neqE: thm list, simpset: simpset, |
98 number_of: (theory -> typ -> int -> cterm) option}) -> |
98 number_of: (theory -> typ -> int -> cterm) option}) -> |
99 Context.generic -> Context.generic |
99 Context.generic -> Context.generic |
100 val add_inj_thms: thm list -> Context.generic -> Context.generic |
100 val add_inj_thms: thm list -> Context.generic -> Context.generic |
101 val add_lessD: thm -> Context.generic -> Context.generic |
101 val add_lessD: thm -> Context.generic -> Context.generic |
102 val add_simps: thm list -> Context.generic -> Context.generic |
102 val add_simps: thm list -> Context.generic -> Context.generic |
117 {add_mono_thms: thm list, |
117 {add_mono_thms: thm list, |
118 mult_mono_thms: thm list, |
118 mult_mono_thms: thm list, |
119 inj_thms: thm list, |
119 inj_thms: thm list, |
120 lessD: thm list, |
120 lessD: thm list, |
121 neqE: thm list, |
121 neqE: thm list, |
122 simpset: Simplifier.simpset, |
122 simpset: simpset, |
123 number_of: (theory -> typ -> int -> cterm) option}; |
123 number_of: (theory -> typ -> int -> cterm) option}; |
124 |
124 |
125 val empty : T = |
125 val empty : T = |
126 {add_mono_thms = [], mult_mono_thms = [], inj_thms = [], |
126 {add_mono_thms = [], mult_mono_thms = [], inj_thms = [], |
127 lessD = [], neqE = [], simpset = Simplifier.empty_ss, |
127 lessD = [], neqE = [], simpset = empty_ss, |
128 number_of = NONE}; |
128 number_of = NONE}; |
129 val extend = I; |
129 val extend = I; |
130 fun merge |
130 fun merge |
131 ({add_mono_thms = add_mono_thms1, mult_mono_thms = mult_mono_thms1, inj_thms = inj_thms1, |
131 ({add_mono_thms = add_mono_thms1, mult_mono_thms = mult_mono_thms1, inj_thms = inj_thms1, |
132 lessD = lessD1, neqE = neqE1, simpset = simpset1, number_of = number_of1}, |
132 lessD = lessD1, neqE = neqE1, simpset = simpset1, number_of = number_of1}, |
135 {add_mono_thms = Thm.merge_thms (add_mono_thms1, add_mono_thms2), |
135 {add_mono_thms = Thm.merge_thms (add_mono_thms1, add_mono_thms2), |
136 mult_mono_thms = Thm.merge_thms (mult_mono_thms1, mult_mono_thms2), |
136 mult_mono_thms = Thm.merge_thms (mult_mono_thms1, mult_mono_thms2), |
137 inj_thms = Thm.merge_thms (inj_thms1, inj_thms2), |
137 inj_thms = Thm.merge_thms (inj_thms1, inj_thms2), |
138 lessD = Thm.merge_thms (lessD1, lessD2), |
138 lessD = Thm.merge_thms (lessD1, lessD2), |
139 neqE = Thm.merge_thms (neqE1, neqE2), |
139 neqE = Thm.merge_thms (neqE1, neqE2), |
140 simpset = Simplifier.merge_ss (simpset1, simpset2), |
140 simpset = merge_ss (simpset1, simpset2), |
141 number_of = merge_options (number_of1, number_of2)}; |
141 number_of = merge_options (number_of1, number_of2)}; |
142 ); |
142 ); |
143 |
143 |
144 val map_data = Data.map; |
144 val map_data = Data.map; |
145 val get_data = Data.get o Context.Proof; |
145 val get_data = Data.get o Context.Proof; |
150 |
150 |
151 fun map_lessD f {add_mono_thms, mult_mono_thms, inj_thms, lessD, neqE, simpset, number_of} = |
151 fun map_lessD f {add_mono_thms, mult_mono_thms, inj_thms, lessD, neqE, simpset, number_of} = |
152 {add_mono_thms = add_mono_thms, mult_mono_thms = mult_mono_thms, inj_thms = inj_thms, |
152 {add_mono_thms = add_mono_thms, mult_mono_thms = mult_mono_thms, inj_thms = inj_thms, |
153 lessD = f lessD, neqE = neqE, simpset = simpset, number_of = number_of}; |
153 lessD = f lessD, neqE = neqE, simpset = simpset, number_of = number_of}; |
154 |
154 |
155 fun map_simpset f {add_mono_thms, mult_mono_thms, inj_thms, lessD, neqE, simpset, number_of} = |
155 fun map_simpset f context = |
156 {add_mono_thms = add_mono_thms, mult_mono_thms = mult_mono_thms, inj_thms = inj_thms, |
156 map_data (fn {add_mono_thms, mult_mono_thms, inj_thms, lessD, neqE, simpset, number_of} => |
157 lessD = lessD, neqE = neqE, simpset = f simpset, number_of = number_of}; |
157 {add_mono_thms = add_mono_thms, mult_mono_thms = mult_mono_thms, inj_thms = inj_thms, |
|
158 lessD = lessD, neqE = neqE, simpset = simpset_map (Context.proof_of context) f simpset, |
|
159 number_of = number_of}) context; |
158 |
160 |
159 fun add_inj_thms thms = map_data (map_inj_thms (append thms)); |
161 fun add_inj_thms thms = map_data (map_inj_thms (append thms)); |
160 fun add_lessD thm = map_data (map_lessD (fn thms => thms @ [thm])); |
162 fun add_lessD thm = map_data (map_lessD (fn thms => thms @ [thm])); |
161 fun add_simps thms = map_data (map_simpset (fn simpset => simpset addsimps thms)); |
163 fun add_simps thms = map_simpset (fn ctxt => ctxt addsimps thms); |
162 fun add_simprocs procs = map_data (map_simpset (fn simpset => simpset addsimprocs procs)); |
164 fun add_simprocs procs = map_simpset (fn ctxt => ctxt addsimprocs procs); |
163 |
165 |
164 fun set_number_of f = |
166 fun set_number_of f = |
165 map_data (fn {add_mono_thms, mult_mono_thms, inj_thms, lessD, neqE, simpset, ...} => |
167 map_data (fn {add_mono_thms, mult_mono_thms, inj_thms, lessD, neqE, simpset, ...} => |
166 {add_mono_thms = add_mono_thms, mult_mono_thms = mult_mono_thms, inj_thms = inj_thms, |
168 {add_mono_thms = add_mono_thms, mult_mono_thms = mult_mono_thms, inj_thms = inj_thms, |
167 lessD = lessD, neqE = neqE, simpset = simpset, number_of = SOME f}); |
169 lessD = lessD, neqE = neqE, simpset = simpset, number_of = SOME f}); |
471 *) |
473 *) |
472 local |
474 local |
473 exception FalseE of thm |
475 exception FalseE of thm |
474 in |
476 in |
475 |
477 |
476 fun mkthm ss asms (just: injust) = |
478 fun mkthm ctxt asms (just: injust) = |
477 let |
479 let |
478 val ctxt = Simplifier.the_context ss; |
|
479 val thy = Proof_Context.theory_of ctxt; |
480 val thy = Proof_Context.theory_of ctxt; |
480 val {add_mono_thms, mult_mono_thms, inj_thms, lessD, simpset, ...} = get_data ctxt; |
481 val {add_mono_thms, mult_mono_thms, inj_thms, lessD, simpset, ...} = get_data ctxt; |
481 val number_of = number_of ctxt; |
482 val number_of = number_of ctxt; |
482 val simpset' = Simplifier.inherit_context ss simpset; |
483 val simpset_ctxt = put_simpset simpset ctxt; |
483 fun only_concl f thm = |
484 fun only_concl f thm = |
484 if Thm.no_prems thm then f (Thm.concl_of thm) else NONE; |
485 if Thm.no_prems thm then f (Thm.concl_of thm) else NONE; |
485 val atoms = atoms_of (map_filter (only_concl (LA_Data.decomp ctxt)) asms); |
486 val atoms = atoms_of (map_filter (only_concl (LA_Data.decomp ctxt)) asms); |
486 |
487 |
487 fun use_first rules thm = |
488 fun use_first rules thm = |
505 |
506 |
506 fun mult_by_add n thm = |
507 fun mult_by_add n thm = |
507 let fun mul i th = if i = 1 then th else mul (i - 1) (add_thms thm th) |
508 let fun mul i th = if i = 1 then th else mul (i - 1) (add_thms thm th) |
508 in mul n thm end; |
509 in mul n thm end; |
509 |
510 |
510 val rewr = Simplifier.rewrite simpset'; |
511 val rewr = Simplifier.rewrite simpset_ctxt; |
511 val rewrite_concl = Conv.fconv_rule (Conv.concl_conv ~1 (Conv.arg_conv |
512 val rewrite_concl = Conv.fconv_rule (Conv.concl_conv ~1 (Conv.arg_conv |
512 (Conv.binop_conv rewr))); |
513 (Conv.binop_conv rewr))); |
513 fun discharge_prem thm = if Thm.nprems_of thm = 0 then thm else |
514 fun discharge_prem thm = if Thm.nprems_of thm = 0 then thm else |
514 let val cv = Conv.arg1_conv (Conv.arg_conv rewr) |
515 let val cv = Conv.arg1_conv (Conv.arg_conv rewr) |
515 in Thm.implies_elim (Conv.fconv_rule cv thm) LA_Logic.trueI end |
516 in Thm.implies_elim (Conv.fconv_rule cv thm) LA_Logic.trueI end |
535 if n = ~1 then thm RS LA_Logic.sym |
536 if n = ~1 then thm RS LA_Logic.sym |
536 else if n < 0 then mult (~n) thm RS LA_Logic.sym |
537 else if n < 0 then mult (~n) thm RS LA_Logic.sym |
537 else mult n thm; |
538 else mult n thm; |
538 |
539 |
539 fun simp thm = |
540 fun simp thm = |
540 let val thm' = trace_thm ctxt ["Simplified:"] (full_simplify simpset' thm) |
541 let val thm' = trace_thm ctxt ["Simplified:"] (full_simplify simpset_ctxt thm) |
541 in if LA_Logic.is_False thm' then raise FalseE thm' else thm' end; |
542 in if LA_Logic.is_False thm' then raise FalseE thm' else thm' end; |
542 |
543 |
543 fun mk (Asm i) = trace_thm ctxt ["Asm " ^ string_of_int i] (nth asms i) |
544 fun mk (Asm i) = trace_thm ctxt ["Asm " ^ string_of_int i] (nth asms i) |
544 | mk (Nat i) = trace_thm ctxt ["Nat " ^ string_of_int i] (LA_Logic.mk_nat_thm thy (nth atoms i)) |
545 | mk (Nat i) = trace_thm ctxt ["Nat " ^ string_of_int i] (LA_Logic.mk_nat_thm thy (nth atoms i)) |
545 | mk (LessD j) = trace_thm ctxt ["L"] (hd ([mk j] RL lessD)) |
546 | mk (LessD j) = trace_thm ctxt ["L"] (hd ([mk j] RL lessD)) |
797 (* dropping the conclusion doesn't work either, because even *) |
798 (* dropping the conclusion doesn't work either, because even *) |
798 (* 'False' does not imply arbitrary 'concl::prop') *) |
799 (* 'False' does not imply arbitrary 'concl::prop') *) |
799 (trace_msg ctxt "prove failed (cannot negate conclusion)."; |
800 (trace_msg ctxt "prove failed (cannot negate conclusion)."; |
800 (false, NONE)); |
801 (false, NONE)); |
801 |
802 |
802 fun refute_tac ss (i, split_neq, justs) = |
803 fun refute_tac ctxt (i, split_neq, justs) = |
803 fn state => |
804 fn state => |
804 let |
805 let |
805 val ctxt = Simplifier.the_context ss; |
|
806 val _ = trace_thm ctxt |
806 val _ = trace_thm ctxt |
807 ["refute_tac (on subgoal " ^ string_of_int i ^ ", with " ^ |
807 ["refute_tac (on subgoal " ^ string_of_int i ^ ", with " ^ |
808 string_of_int (length justs) ^ " justification(s)):"] state |
808 string_of_int (length justs) ^ " justification(s)):"] state |
809 val {neqE, ...} = get_data ctxt; |
809 val {neqE, ...} = get_data ctxt; |
810 fun just1 j = |
810 fun just1 j = |
813 REPEAT_DETERM (eresolve_tac neqE i) |
813 REPEAT_DETERM (eresolve_tac neqE i) |
814 else |
814 else |
815 all_tac) THEN |
815 all_tac) THEN |
816 PRIMITIVE (trace_thm ctxt ["State after neqE:"]) THEN |
816 PRIMITIVE (trace_thm ctxt ["State after neqE:"]) THEN |
817 (* use theorems generated from the actual justifications *) |
817 (* use theorems generated from the actual justifications *) |
818 Subgoal.FOCUS (fn {prems, ...} => rtac (mkthm ss prems j) 1) ctxt i |
818 Subgoal.FOCUS (fn {prems, ...} => rtac (mkthm ctxt prems j) 1) ctxt i |
819 in |
819 in |
820 (* rewrite "[| A1; ...; An |] ==> B" to "[| A1; ...; An; ~B |] ==> False" *) |
820 (* rewrite "[| A1; ...; An |] ==> B" to "[| A1; ...; An; ~B |] ==> False" *) |
821 DETERM (resolve_tac [LA_Logic.notI, LA_Logic.ccontr] i) THEN |
821 DETERM (resolve_tac [LA_Logic.notI, LA_Logic.ccontr] i) THEN |
822 (* user-defined preprocessing of the subgoal *) |
822 (* user-defined preprocessing of the subgoal *) |
823 DETERM (LA_Data.pre_tac ss i) THEN |
823 DETERM (LA_Data.pre_tac ctxt i) THEN |
824 PRIMITIVE (trace_thm ctxt ["State after pre_tac:"]) THEN |
824 PRIMITIVE (trace_thm ctxt ["State after pre_tac:"]) THEN |
825 (* prove every resulting subgoal, using its justification *) |
825 (* prove every resulting subgoal, using its justification *) |
826 EVERY (map just1 justs) |
826 EVERY (map just1 justs) |
827 end state; |
827 end state; |
828 |
828 |
829 (* |
829 (* |
830 Fast but very incomplete decider. Only premises and conclusions |
830 Fast but very incomplete decider. Only premises and conclusions |
831 that are already (negated) (in)equations are taken into account. |
831 that are already (negated) (in)equations are taken into account. |
832 *) |
832 *) |
833 fun simpset_lin_arith_tac ss show_ex = SUBGOAL (fn (A, i) => |
833 fun simpset_lin_arith_tac ctxt show_ex = SUBGOAL (fn (A, i) => |
834 let |
834 let |
835 val ctxt = Simplifier.the_context ss |
|
836 val params = rev (Logic.strip_params A) |
835 val params = rev (Logic.strip_params A) |
837 val Hs = Logic.strip_assums_hyp A |
836 val Hs = Logic.strip_assums_hyp A |
838 val concl = Logic.strip_assums_concl A |
837 val concl = Logic.strip_assums_concl A |
839 val _ = trace_term ctxt ["Trying to refute subgoal " ^ string_of_int i] A |
838 val _ = trace_term ctxt ["Trying to refute subgoal " ^ string_of_int i] A |
840 in |
839 in |
841 case prove ctxt params show_ex true Hs concl of |
840 case prove ctxt params show_ex true Hs concl of |
842 (_, NONE) => (trace_msg ctxt "Refutation failed."; no_tac) |
841 (_, NONE) => (trace_msg ctxt "Refutation failed."; no_tac) |
843 | (split_neq, SOME js) => (trace_msg ctxt "Refutation succeeded."; |
842 | (split_neq, SOME js) => (trace_msg ctxt "Refutation succeeded."; |
844 refute_tac ss (i, split_neq, js)) |
843 refute_tac ctxt (i, split_neq, js)) |
845 end); |
844 end); |
846 |
845 |
847 fun prems_lin_arith_tac ss = |
846 fun prems_lin_arith_tac ctxt = |
848 Method.insert_tac (Simplifier.prems_of ss) THEN' |
847 Method.insert_tac (Simplifier.prems_of ctxt) THEN' |
849 simpset_lin_arith_tac ss false; |
848 simpset_lin_arith_tac ctxt false; |
850 |
849 |
851 fun lin_arith_tac ctxt = |
850 fun lin_arith_tac ctxt = |
852 simpset_lin_arith_tac (Simplifier.context ctxt Simplifier.empty_ss); |
851 simpset_lin_arith_tac (empty_simpset ctxt); |
853 |
852 |
854 |
853 |
855 |
854 |
856 (** Forward proof from theorems **) |
855 (** Forward proof from theorems **) |
857 |
856 |
890 ct2, elim_neq neqs (asms', asms@[thm2])) |
889 ct2, elim_neq neqs (asms', asms@[thm2])) |
891 end |
890 end |
892 | NONE => elim_neq neqs (asm::asms', asms)) |
891 | NONE => elim_neq neqs (asm::asms', asms)) |
893 in elim_neq neqE ([], asms) end; |
892 in elim_neq neqE ([], asms) end; |
894 |
893 |
895 fun fwdproof ss (Tip asms : splittree) (j::js : injust list) = (mkthm ss asms j, js) |
894 fun fwdproof ctxt (Tip asms : splittree) (j::js : injust list) = (mkthm ctxt asms j, js) |
896 | fwdproof ss (Spl (thm, ct1, tree1, ct2, tree2)) js = |
895 | fwdproof ctxt (Spl (thm, ct1, tree1, ct2, tree2)) js = |
897 let |
896 let |
898 val (thm1, js1) = fwdproof ss tree1 js |
897 val (thm1, js1) = fwdproof ctxt tree1 js |
899 val (thm2, js2) = fwdproof ss tree2 js1 |
898 val (thm2, js2) = fwdproof ctxt tree2 js1 |
900 val thm1' = Thm.implies_intr ct1 thm1 |
899 val thm1' = Thm.implies_intr ct1 thm1 |
901 val thm2' = Thm.implies_intr ct2 thm2 |
900 val thm2' = Thm.implies_intr ct2 thm2 |
902 in (thm2' COMP (thm1' COMP thm), js2) end; |
901 in (thm2' COMP (thm1' COMP thm), js2) end; |
903 (* FIXME needs handle THM _ => NONE ? *) |
902 (* FIXME needs handle THM _ => NONE ? *) |
904 |
903 |
905 fun prover ss thms Tconcl (js : injust list) split_neq pos : thm option = |
904 fun prover ctxt thms Tconcl (js : injust list) split_neq pos : thm option = |
906 let |
905 let |
907 val ctxt = Simplifier.the_context ss |
|
908 val thy = Proof_Context.theory_of ctxt |
906 val thy = Proof_Context.theory_of ctxt |
909 val nTconcl = LA_Logic.neg_prop Tconcl |
907 val nTconcl = LA_Logic.neg_prop Tconcl |
910 val cnTconcl = cterm_of thy nTconcl |
908 val cnTconcl = cterm_of thy nTconcl |
911 val nTconclthm = Thm.assume cnTconcl |
909 val nTconclthm = Thm.assume cnTconcl |
912 val tree = (if split_neq then splitasms ctxt else Tip) (thms @ [nTconclthm]) |
910 val tree = (if split_neq then splitasms ctxt else Tip) (thms @ [nTconclthm]) |
913 val (Falsethm, _) = fwdproof ss tree js |
911 val (Falsethm, _) = fwdproof ctxt tree js |
914 val contr = if pos then LA_Logic.ccontr else LA_Logic.notI |
912 val contr = if pos then LA_Logic.ccontr else LA_Logic.notI |
915 val concl = Thm.implies_intr cnTconcl Falsethm COMP contr |
913 val concl = Thm.implies_intr cnTconcl Falsethm COMP contr |
916 in SOME (trace_thm ctxt ["Proved by lin. arith. prover:"] (LA_Logic.mk_Eq concl)) end |
914 in SOME (trace_thm ctxt ["Proved by lin. arith. prover:"] (LA_Logic.mk_Eq concl)) end |
917 (*in case concl contains ?-var, which makes assume fail:*) (* FIXME Variable.import_terms *) |
915 (*in case concl contains ?-var, which makes assume fail:*) (* FIXME Variable.import_terms *) |
918 handle THM _ => NONE; |
916 handle THM _ => NONE; |
921 This assumption is OK because |
919 This assumption is OK because |
922 1. lin_arith_simproc tries both to prove and disprove concl and |
920 1. lin_arith_simproc tries both to prove and disprove concl and |
923 2. lin_arith_simproc is applied by the Simplifier which |
921 2. lin_arith_simproc is applied by the Simplifier which |
924 dives into terms and will thus try the non-negated concl anyway. |
922 dives into terms and will thus try the non-negated concl anyway. |
925 *) |
923 *) |
926 fun lin_arith_simproc ss concl = |
924 fun lin_arith_simproc ctxt concl = |
927 let |
925 let |
928 val ctxt = Simplifier.the_context ss |
926 val thms = maps LA_Logic.atomize (Simplifier.prems_of ctxt) |
929 val thms = maps LA_Logic.atomize (Simplifier.prems_of ss) |
|
930 val Hs = map Thm.prop_of thms |
927 val Hs = map Thm.prop_of thms |
931 val Tconcl = LA_Logic.mk_Trueprop concl |
928 val Tconcl = LA_Logic.mk_Trueprop concl |
932 in |
929 in |
933 case prove ctxt [] false false Hs Tconcl of (* concl provable? *) |
930 case prove ctxt [] false false Hs Tconcl of (* concl provable? *) |
934 (split_neq, SOME js) => prover ss thms Tconcl js split_neq true |
931 (split_neq, SOME js) => prover ctxt thms Tconcl js split_neq true |
935 | (_, NONE) => |
932 | (_, NONE) => |
936 let val nTconcl = LA_Logic.neg_prop Tconcl in |
933 let val nTconcl = LA_Logic.neg_prop Tconcl in |
937 case prove ctxt [] false false Hs nTconcl of (* ~concl provable? *) |
934 case prove ctxt [] false false Hs nTconcl of (* ~concl provable? *) |
938 (split_neq, SOME js) => prover ss thms nTconcl js split_neq false |
935 (split_neq, SOME js) => prover ctxt thms nTconcl js split_neq false |
939 | (_, NONE) => NONE |
936 | (_, NONE) => NONE |
940 end |
937 end |
941 end; |
938 end; |
942 |
939 |
943 end; |
940 end; |