86 |
86 |
87 fun lookth th_pairs fth = |
87 fun lookth th_pairs fth = |
88 the (AList.lookup (uncurry Metis_Thm.equal) th_pairs fth) |
88 the (AList.lookup (uncurry Metis_Thm.equal) th_pairs fth) |
89 handle Option.Option => raise Fail ("Failed to find Metis theorem " ^ Metis_Thm.toString fth) |
89 handle Option.Option => raise Fail ("Failed to find Metis theorem " ^ Metis_Thm.toString fth) |
90 |
90 |
91 fun cterm_incr_types thy idx = cterm_of thy o (map_types (Logic.incr_tvar idx)) |
91 fun cterm_incr_types thy idx = Thm.cterm_of thy o map_types (Logic.incr_tvar idx) |
92 |
92 |
93 (* INFERENCE RULE: AXIOM *) |
93 (* INFERENCE RULE: AXIOM *) |
94 |
94 |
95 (* This causes variables to have an index of 1 by default. See also |
95 (* This causes variables to have an index of 1 by default. See also |
96 "term_of_atp" in "ATP_Proof_Reconstruct". *) |
96 "term_of_atp" in "ATP_Proof_Reconstruct". *) |
101 val EXCLUDED_MIDDLE = @{lemma "P ==> ~ P ==> False" by (rule notE)} |
101 val EXCLUDED_MIDDLE = @{lemma "P ==> ~ P ==> False" by (rule notE)} |
102 |
102 |
103 fun inst_excluded_middle thy i_atom = |
103 fun inst_excluded_middle thy i_atom = |
104 let |
104 let |
105 val th = EXCLUDED_MIDDLE |
105 val th = EXCLUDED_MIDDLE |
106 val [vx] = Term.add_vars (prop_of th) [] |
106 val [vx] = Term.add_vars (Thm.prop_of th) [] |
107 val substs = [(cterm_of thy (Var vx), cterm_of thy i_atom)] |
107 val substs = [(Thm.cterm_of thy (Var vx), Thm.cterm_of thy i_atom)] |
108 in |
108 in |
109 cterm_instantiate substs th |
109 cterm_instantiate substs th |
110 end |
110 end |
111 |
111 |
112 fun assume_inference ctxt type_enc concealed sym_tab atom = |
112 fun assume_inference ctxt type_enc concealed sym_tab atom = |
120 |
120 |
121 fun inst_inference ctxt type_enc concealed sym_tab th_pairs fsubst th = |
121 fun inst_inference ctxt type_enc concealed sym_tab th_pairs fsubst th = |
122 let |
122 let |
123 val thy = Proof_Context.theory_of ctxt |
123 val thy = Proof_Context.theory_of ctxt |
124 val i_th = lookth th_pairs th |
124 val i_th = lookth th_pairs th |
125 val i_th_vars = Term.add_vars (prop_of i_th) [] |
125 val i_th_vars = Term.add_vars (Thm.prop_of i_th) [] |
126 |
126 |
127 fun find_var x = the (List.find (fn ((a,_),_) => a=x) i_th_vars) |
127 fun find_var x = the (List.find (fn ((a,_),_) => a=x) i_th_vars) |
128 fun subst_translation (x,y) = |
128 fun subst_translation (x,y) = |
129 let |
129 let |
130 val v = find_var x |
130 val v = find_var x |
131 (* We call "polish_hol_terms" below. *) |
131 (* We call "polish_hol_terms" below. *) |
132 val t = hol_term_of_metis ctxt type_enc sym_tab y |
132 val t = hol_term_of_metis ctxt type_enc sym_tab y |
133 in |
133 in |
134 SOME (cterm_of thy (Var v), t) |
134 SOME (Thm.cterm_of thy (Var v), t) |
135 end |
135 end |
136 handle Option.Option => |
136 handle Option.Option => |
137 (trace_msg ctxt (fn () => |
137 (trace_msg ctxt (fn () => |
138 "\"find_var\" failed for " ^ x ^ " in " ^ Display.string_of_thm ctxt i_th); |
138 "\"find_var\" failed for " ^ x ^ " in " ^ Display.string_of_thm ctxt i_th); |
139 NONE) |
139 NONE) |
158 val ctm_of = cterm_incr_types thy (1 + Thm.maxidx_of i_th) |
158 val ctm_of = cterm_incr_types thy (1 + Thm.maxidx_of i_th) |
159 val substs' = ListPair.zip (vars, map ctm_of tms) |
159 val substs' = ListPair.zip (vars, map ctm_of tms) |
160 val _ = trace_msg ctxt (fn () => |
160 val _ = trace_msg ctxt (fn () => |
161 cat_lines ("subst_translations:" :: |
161 cat_lines ("subst_translations:" :: |
162 (substs' |> map (fn (x, y) => |
162 (substs' |> map (fn (x, y) => |
163 Syntax.string_of_term ctxt (term_of x) ^ " |-> " ^ |
163 Syntax.string_of_term ctxt (Thm.term_of x) ^ " |-> " ^ |
164 Syntax.string_of_term ctxt (term_of y))))) |
164 Syntax.string_of_term ctxt (Thm.term_of y))))) |
165 in |
165 in |
166 cterm_instantiate substs' i_th |
166 cterm_instantiate substs' i_th |
167 end |
167 end |
168 handle THM (msg, _, _) => raise METIS_RECONSTRUCT ("inst_inference", msg) |
168 handle THM (msg, _, _) => raise METIS_RECONSTRUCT ("inst_inference", msg) |
169 | ERROR msg => raise METIS_RECONSTRUCT ("inst_inference", msg) |
169 | ERROR msg => raise METIS_RECONSTRUCT ("inst_inference", msg) |
173 (*Increment the indexes of only the type variables*) |
173 (*Increment the indexes of only the type variables*) |
174 fun incr_type_indexes inc th = |
174 fun incr_type_indexes inc th = |
175 let |
175 let |
176 val tvs = Term.add_tvars (Thm.full_prop_of th) [] |
176 val tvs = Term.add_tvars (Thm.full_prop_of th) [] |
177 val thy = Thm.theory_of_thm th |
177 val thy = Thm.theory_of_thm th |
178 fun inc_tvar ((a, i), s) = apply2 (ctyp_of thy) (TVar ((a, i), s), TVar ((a, i + inc), s)) |
178 fun inc_tvar ((a, i), s) = apply2 (Thm.ctyp_of thy) (TVar ((a, i), s), TVar ((a, i + inc), s)) |
179 in |
179 in |
180 Thm.instantiate (map inc_tvar tvs, []) th |
180 Thm.instantiate (map inc_tvar tvs, []) th |
181 end |
181 end |
182 |
182 |
183 (* Like RSN, but we rename apart only the type variables. Vars here typically |
183 (* Like RSN, but we rename apart only the type variables. Vars here typically |
186 fun resolve_inc_tyvars ctxt tha i thb = |
186 fun resolve_inc_tyvars ctxt tha i thb = |
187 let |
187 let |
188 val tha = incr_type_indexes (1 + Thm.maxidx_of thb) tha |
188 val tha = incr_type_indexes (1 + Thm.maxidx_of thb) tha |
189 fun res (tha, thb) = |
189 fun res (tha, thb) = |
190 (case Thm.bicompose (SOME ctxt) {flatten = true, match = false, incremented = true} |
190 (case Thm.bicompose (SOME ctxt) {flatten = true, match = false, incremented = true} |
191 (false, tha, nprems_of tha) i thb |
191 (false, tha, Thm.nprems_of tha) i thb |
192 |> Seq.list_of |> distinct Thm.eq_thm of |
192 |> Seq.list_of |> distinct Thm.eq_thm of |
193 [th] => th |
193 [th] => th |
194 | _ => |
194 | _ => |
195 let |
195 let |
196 val thaa'bb' as [(tha', _), (thb', _)] = |
196 val thaa'bb' as [(tha', _), (thb', _)] = |
205 res (tha, thb) |
205 res (tha, thb) |
206 handle TERM z => |
206 handle TERM z => |
207 let |
207 let |
208 val thy = Proof_Context.theory_of ctxt |
208 val thy = Proof_Context.theory_of ctxt |
209 val ps = [] |
209 val ps = [] |
210 |> fold (Term.add_vars o prop_of) [tha, thb] |
210 |> fold (Term.add_vars o Thm.prop_of) [tha, thb] |
211 |> AList.group (op =) |
211 |> AList.group (op =) |
212 |> maps (fn ((s, _), T :: Ts) => map (fn T' => (Free (s, T), Free (s, T'))) Ts) |
212 |> maps (fn ((s, _), T :: Ts) => map (fn T' => (Free (s, T), Free (s, T'))) Ts) |
213 |> rpair (Envir.empty ~1) |
213 |> rpair (Envir.empty ~1) |
214 |-> fold (Pattern.unify (Context.Proof ctxt)) |
214 |-> fold (Pattern.unify (Context.Proof ctxt)) |
215 |> Envir.type_env |> Vartab.dest |
215 |> Envir.type_env |> Vartab.dest |
216 |> map (fn (x, (S, T)) => apply2 (ctyp_of thy) (TVar (x, S), T)) |
216 |> map (fn (x, (S, T)) => apply2 (Thm.ctyp_of thy) (TVar (x, S), T)) |
217 in |
217 in |
218 (* The unifier, which is invoked from "Thm.bicompose", will sometimes refuse to unify |
218 (* The unifier, which is invoked from "Thm.bicompose", will sometimes refuse to unify |
219 "?a::?'a" with "?a::?'b" or "?a::nat" and throw a "TERM" exception (with "add_ffpair" as |
219 "?a::?'a" with "?a::?'b" or "?a::nat" and throw a "TERM" exception (with "add_ffpair" as |
220 first argument). We then perform unification of the types of variables by hand and try |
220 first argument). We then perform unification of the types of variables by hand and try |
221 again. We could do this the first time around but this error occurs seldom and we don't |
221 again. We could do this the first time around but this error occurs seldom and we don't |
246 | j => j) + 1 |
246 | j => j) + 1 |
247 end |
247 end |
248 |
248 |
249 (* Permute a rule's premises to move the i-th premise to the last position. *) |
249 (* Permute a rule's premises to move the i-th premise to the last position. *) |
250 fun make_last i th = |
250 fun make_last i th = |
251 let val n = nprems_of th in |
251 let val n = Thm.nprems_of th in |
252 if i >= 1 andalso i <= n then Thm.permute_prems (i - 1) 1 th |
252 if i >= 1 andalso i <= n then Thm.permute_prems (i - 1) 1 th |
253 else raise THM ("select_literal", i, [th]) |
253 else raise THM ("select_literal", i, [th]) |
254 end |
254 end |
255 |
255 |
256 (* Maps a rule that ends "... ==> P ==> False" to "... ==> ~ P" while avoiding |
256 (* Maps a rule that ends "... ==> P ==> False" to "... ==> ~ P" while avoiding |
257 to create double negations. The "select" wrapper is a trick to ensure that |
257 to create double negations. The "select" wrapper is a trick to ensure that |
258 "P ==> ~ False ==> False" is rewritten to "P ==> False", not to "~ P". We |
258 "P ==> ~ False ==> False" is rewritten to "P ==> False", not to "~ P". We |
259 don't use this trick in general because it makes the proof object uglier than |
259 don't use this trick in general because it makes the proof object uglier than |
260 necessary. FIXME. *) |
260 necessary. FIXME. *) |
261 fun negate_head ctxt th = |
261 fun negate_head ctxt th = |
262 if exists (fn t => t aconv @{prop "~ False"}) (prems_of th) then |
262 if exists (fn t => t aconv @{prop "~ False"}) (Thm.prems_of th) then |
263 (th RS @{thm select_FalseI}) |
263 (th RS @{thm select_FalseI}) |
264 |> fold (rewrite_rule ctxt o single) @{thms not_atomize_select atomize_not_select} |
264 |> fold (rewrite_rule ctxt o single) @{thms not_atomize_select atomize_not_select} |
265 else |
265 else |
266 th |> fold (rewrite_rule ctxt o single) @{thms not_atomize atomize_not} |
266 th |> fold (rewrite_rule ctxt o single) @{thms not_atomize atomize_not} |
267 |
267 |
284 let |
284 let |
285 val i_atom = |
285 val i_atom = |
286 singleton (hol_terms_of_metis ctxt type_enc concealed sym_tab) (Metis_Term.Fn atom) |
286 singleton (hol_terms_of_metis ctxt type_enc concealed sym_tab) (Metis_Term.Fn atom) |
287 val _ = trace_msg ctxt (fn () => " atom: " ^ Syntax.string_of_term ctxt i_atom) |
287 val _ = trace_msg ctxt (fn () => " atom: " ^ Syntax.string_of_term ctxt i_atom) |
288 in |
288 in |
289 (case index_of_literal (s_not i_atom) (prems_of i_th1) of |
289 (case index_of_literal (s_not i_atom) (Thm.prems_of i_th1) of |
290 0 => (trace_msg ctxt (fn () => "Failed to find literal in \"th1\""); i_th1) |
290 0 => (trace_msg ctxt (fn () => "Failed to find literal in \"th1\""); i_th1) |
291 | j1 => |
291 | j1 => |
292 (trace_msg ctxt (fn () => " index th1: " ^ string_of_int j1); |
292 (trace_msg ctxt (fn () => " index th1: " ^ string_of_int j1); |
293 (case index_of_literal i_atom (prems_of i_th2) of |
293 (case index_of_literal i_atom (Thm.prems_of i_th2) of |
294 0 => (trace_msg ctxt (fn () => "Failed to find literal in \"th2\""); i_th2) |
294 0 => (trace_msg ctxt (fn () => "Failed to find literal in \"th2\""); i_th2) |
295 | j2 => |
295 | j2 => |
296 (trace_msg ctxt (fn () => " index th2: " ^ string_of_int j2); |
296 (trace_msg ctxt (fn () => " index th2: " ^ string_of_int j2); |
297 resolve_inc_tyvars ctxt (select_literal ctxt j1 i_th1) j2 i_th2 |
297 resolve_inc_tyvars ctxt (select_literal ctxt j1 i_th1) j2 i_th2 |
298 handle TERM (s, _) => raise METIS_RECONSTRUCT ("resolve_inference", s))))) |
298 handle TERM (s, _) => raise METIS_RECONSTRUCT ("resolve_inference", s))))) |
301 |
301 |
302 (* INFERENCE RULE: REFL *) |
302 (* INFERENCE RULE: REFL *) |
303 |
303 |
304 val REFL_THM = Thm.incr_indexes 2 @{lemma "t ~= t ==> False" by simp} |
304 val REFL_THM = Thm.incr_indexes 2 @{lemma "t ~= t ==> False" by simp} |
305 |
305 |
306 val refl_x = cterm_of @{theory} (Var (hd (Term.add_vars (prop_of REFL_THM) []))); |
306 val refl_x = Thm.cterm_of @{theory} (Var (hd (Term.add_vars (Thm.prop_of REFL_THM) []))); |
307 val refl_idx = 1 + Thm.maxidx_of REFL_THM; |
307 val refl_idx = 1 + Thm.maxidx_of REFL_THM; |
308 |
308 |
309 fun refl_inference ctxt type_enc concealed sym_tab t = |
309 fun refl_inference ctxt type_enc concealed sym_tab t = |
310 let |
310 let |
311 val thy = Proof_Context.theory_of ctxt |
311 val thy = Proof_Context.theory_of ctxt |
372 val _ = trace_msg ctxt (fn () => "i_tm: " ^ Syntax.string_of_term ctxt i_tm) |
372 val _ = trace_msg ctxt (fn () => "i_tm: " ^ Syntax.string_of_term ctxt i_tm) |
373 val _ = trace_msg ctxt (fn () => "located term: " ^ Syntax.string_of_term ctxt tm_subst) |
373 val _ = trace_msg ctxt (fn () => "located term: " ^ Syntax.string_of_term ctxt tm_subst) |
374 val imax = maxidx_of_term (i_tm $ tm_abs $ tm_subst) (*ill-typed but gives right max*) |
374 val imax = maxidx_of_term (i_tm $ tm_abs $ tm_subst) (*ill-typed but gives right max*) |
375 val subst' = Thm.incr_indexes (imax+1) (if pos then subst_em else ssubst_em) |
375 val subst' = Thm.incr_indexes (imax+1) (if pos then subst_em else ssubst_em) |
376 val _ = trace_msg ctxt (fn () => "subst' " ^ Display.string_of_thm ctxt subst') |
376 val _ = trace_msg ctxt (fn () => "subst' " ^ Display.string_of_thm ctxt subst') |
377 val eq_terms = map (apply2 (cterm_of thy)) |
377 val eq_terms = map (apply2 (Thm.cterm_of thy)) |
378 (ListPair.zip (Misc_Legacy.term_vars (prop_of subst'), [tm_abs, tm_subst, i_tm])) |
378 (ListPair.zip (Misc_Legacy.term_vars (Thm.prop_of subst'), [tm_abs, tm_subst, i_tm])) |
379 in |
379 in |
380 cterm_instantiate eq_terms subst' |
380 cterm_instantiate eq_terms subst' |
381 end |
381 end |
382 |
382 |
383 val factor = Seq.hd o distinct_subgoals_tac |
383 val factor = Seq.hd o distinct_subgoals_tac |
397 fun flexflex_first_order th = |
397 fun flexflex_first_order th = |
398 (case Thm.tpairs_of th of |
398 (case Thm.tpairs_of th of |
399 [] => th |
399 [] => th |
400 | pairs => |
400 | pairs => |
401 let |
401 let |
402 val thy = theory_of_thm th |
402 val thy = Thm.theory_of_thm th |
403 val cert = cterm_of thy |
403 val cert = Thm.cterm_of thy |
404 val certT = ctyp_of thy |
404 val certT = Thm.ctyp_of thy |
405 val (tyenv, tenv) = fold (Pattern.first_order_match thy) pairs (Vartab.empty, Vartab.empty) |
405 val (tyenv, tenv) = fold (Pattern.first_order_match thy) pairs (Vartab.empty, Vartab.empty) |
406 |
406 |
407 fun mkT (v, (S, T)) = (certT (TVar (v, S)), certT T) |
407 fun mkT (v, (S, T)) = (certT (TVar (v, S)), certT T) |
408 fun mk (v, (T, t)) = (cert (Var (v, Envir.subst_type tyenv T)), cert t) |
408 fun mk (v, (T, t)) = (cert (Var (v, Envir.subst_type tyenv T)), cert t) |
409 |
409 |
427 unifiable) types. *) |
427 unifiable) types. *) |
428 fun resynchronize ctxt fol_th th = |
428 fun resynchronize ctxt fol_th th = |
429 let |
429 let |
430 val num_metis_lits = |
430 val num_metis_lits = |
431 count is_metis_literal_genuine (Metis_LiteralSet.toList (Metis_Thm.clause fol_th)) |
431 count is_metis_literal_genuine (Metis_LiteralSet.toList (Metis_Thm.clause fol_th)) |
432 val num_isabelle_lits = count is_isabelle_literal_genuine (prems_of th) |
432 val num_isabelle_lits = count is_isabelle_literal_genuine (Thm.prems_of th) |
433 in |
433 in |
434 if num_metis_lits >= num_isabelle_lits then |
434 if num_metis_lits >= num_isabelle_lits then |
435 th |
435 th |
436 else |
436 else |
437 let |
437 let |
438 val (prems0, concl) = th |> prop_of |> Logic.strip_horn |
438 val (prems0, concl) = th |> Thm.prop_of |> Logic.strip_horn |
439 val prems = prems0 |> map normalize_literal |> distinct Term.aconv_untyped |
439 val prems = prems0 |> map normalize_literal |> distinct Term.aconv_untyped |
440 val goal = Logic.list_implies (prems, concl) |
440 val goal = Logic.list_implies (prems, concl) |
441 val ctxt' = fold Thm.declare_hyps (#hyps (Thm.crep_thm th)) ctxt |
441 val ctxt' = fold Thm.declare_hyps (#hyps (Thm.crep_thm th)) ctxt |
442 val tac = |
442 val tac = |
443 cut_tac th 1 THEN |
443 cut_tac th 1 THEN |
452 end |
452 end |
453 end |
453 end |
454 |
454 |
455 fun replay_one_inference ctxt type_enc concealed sym_tab (fol_th, inf) |
455 fun replay_one_inference ctxt type_enc concealed sym_tab (fol_th, inf) |
456 th_pairs = |
456 th_pairs = |
457 if not (null th_pairs) andalso prop_of (snd (hd th_pairs)) aconv @{prop False} then |
457 if not (null th_pairs) andalso Thm.prop_of (snd (hd th_pairs)) aconv @{prop False} then |
458 (* Isabelle sometimes identifies literals (premises) that are distinct in |
458 (* Isabelle sometimes identifies literals (premises) that are distinct in |
459 Metis (e.g., because of type variables). We give the Isabelle proof the |
459 Metis (e.g., because of type variables). We give the Isabelle proof the |
460 benefice of the doubt. *) |
460 benefice of the doubt. *) |
461 th_pairs |
461 th_pairs |
462 else |
462 else |
479 variables before applying "assume_tac". Typical constraints are of the form |
479 variables before applying "assume_tac". Typical constraints are of the form |
480 ?SK_a_b_c_x SK_d_e_f_y ... SK_a_b_c_x ... SK_g_h_i_z =?= SK_a_b_c_x, |
480 ?SK_a_b_c_x SK_d_e_f_y ... SK_a_b_c_x ... SK_g_h_i_z =?= SK_a_b_c_x, |
481 where the nonvariables are goal parameters. *) |
481 where the nonvariables are goal parameters. *) |
482 fun unify_first_prem_with_concl thy i th = |
482 fun unify_first_prem_with_concl thy i th = |
483 let |
483 let |
484 val goal = Logic.get_goal (prop_of th) i |> Envir.beta_eta_contract |
484 val goal = Logic.get_goal (Thm.prop_of th) i |> Envir.beta_eta_contract |
485 val prem = goal |> Logic.strip_assums_hyp |> hd |
485 val prem = goal |> Logic.strip_assums_hyp |> hd |
486 val concl = goal |> Logic.strip_assums_concl |
486 val concl = goal |> Logic.strip_assums_concl |
487 |
487 |
488 fun pair_untyped_aconv (t1, t2) (u1, u2) = |
488 fun pair_untyped_aconv (t1, t2) (u1, u2) = |
489 Term.aconv_untyped (t1, u1) andalso Term.aconv_untyped (t2, u2) |
489 Term.aconv_untyped (t1, u1) andalso Term.aconv_untyped (t2, u2) |
520 | (Var _, _) => add_terms (t, u) |
520 | (Var _, _) => add_terms (t, u) |
521 | (_, Var _) => add_terms (u, t) |
521 | (_, Var _) => add_terms (u, t) |
522 | _ => I) |
522 | _ => I) |
523 |
523 |
524 val t_inst = |
524 val t_inst = |
525 [] |> try (unify_terms (prem, concl) #> map (apply2 (cterm_of thy))) |
525 [] |> try (unify_terms (prem, concl) #> map (apply2 (Thm.cterm_of thy))) |
526 |> the_default [] (* FIXME *) |
526 |> the_default [] (* FIXME *) |
527 in |
527 in |
528 cterm_instantiate t_inst th |
528 cterm_instantiate t_inst th |
529 end |
529 end |
530 |
530 |
541 |
541 |
542 fun instantiate_forall_tac ctxt t i st = |
542 fun instantiate_forall_tac ctxt t i st = |
543 let |
543 let |
544 val thy = Proof_Context.theory_of ctxt |
544 val thy = Proof_Context.theory_of ctxt |
545 |
545 |
546 val params = Logic.strip_params (Logic.get_goal (prop_of st) i) |> rev |
546 val params = Logic.strip_params (Logic.get_goal (Thm.prop_of st) i) |> rev |
547 |
547 |
548 fun repair (t as (Var ((s, _), _))) = |
548 fun repair (t as (Var ((s, _), _))) = |
549 (case find_index (fn (s', _) => s' = s) params of |
549 (case find_index (fn (s', _) => s' = s) params of |
550 ~1 => t |
550 ~1 => t |
551 | j => Bound j) |
551 | j => Bound j) |
574 var_body_T :: var_binder_Ts) |
574 var_body_T :: var_binder_Ts) |
575 val env = |
575 val env = |
576 Envir.Envir {maxidx = Vartab.fold (Integer.max o snd o fst) tyenv 0, |
576 Envir.Envir {maxidx = Vartab.fold (Integer.max o snd o fst) tyenv 0, |
577 tenv = Vartab.empty, tyenv = tyenv} |
577 tenv = Vartab.empty, tyenv = tyenv} |
578 val ty_inst = |
578 val ty_inst = |
579 Vartab.fold (fn (x, (S, T)) => cons (apply2 (ctyp_of thy) (TVar (x, S), T))) tyenv [] |
579 Vartab.fold (fn (x, (S, T)) => cons (apply2 (Thm.ctyp_of thy) (TVar (x, S), T))) |
580 val t_inst = [apply2 (cterm_of thy o Envir.norm_term env) (Var var, t')] |
580 tyenv [] |
|
581 val t_inst = [apply2 (Thm.cterm_of thy o Envir.norm_term env) (Var var, t')] |
581 in |
582 in |
582 Drule.instantiate_normalize (ty_inst, t_inst) th |
583 Drule.instantiate_normalize (ty_inst, t_inst) th |
583 end |
584 end |
584 | _ => raise Fail "expected a single non-zapped, non-Metis Var") |
585 | _ => raise Fail "expected a single non-zapped, non-Metis Var") |
585 in |
586 in |
637 (* Attempts to derive the theorem "False" from a theorem of the form |
638 (* Attempts to derive the theorem "False" from a theorem of the form |
638 "P1 ==> ... ==> Pn ==> False", where the "Pi"s are to be discharged using the |
639 "P1 ==> ... ==> Pn ==> False", where the "Pi"s are to be discharged using the |
639 specified axioms. The axioms have leading "All" and "Ex" quantifiers, which |
640 specified axioms. The axioms have leading "All" and "Ex" quantifiers, which |
640 must be eliminated first. *) |
641 must be eliminated first. *) |
641 fun discharge_skolem_premises ctxt axioms prems_imp_false = |
642 fun discharge_skolem_premises ctxt axioms prems_imp_false = |
642 if prop_of prems_imp_false aconv @{prop False} then |
643 if Thm.prop_of prems_imp_false aconv @{prop False} then |
643 prems_imp_false |
644 prems_imp_false |
644 else |
645 else |
645 let |
646 let |
646 val thy = Proof_Context.theory_of ctxt |
647 val thy = Proof_Context.theory_of ctxt |
647 |
648 |
683 | [(ax_no, cluster_no)] => |
684 | [(ax_no, cluster_no)] => |
684 SOME ((ax_no, cluster_no), |
685 SOME ((ax_no, cluster_no), |
685 clusters_in_term true t |> cluster_no > 1 ? cons (ax_no, cluster_no - 1)) |
686 clusters_in_term true t |> cluster_no > 1 ? cons (ax_no, cluster_no - 1)) |
686 | _ => raise TERM ("discharge_skolem_premises: Expected Var", [var])) |
687 | _ => raise TERM ("discharge_skolem_premises: Expected Var", [var])) |
687 |
688 |
688 val prems = Logic.strip_imp_prems (prop_of prems_imp_false) |
689 val prems = Logic.strip_imp_prems (Thm.prop_of prems_imp_false) |
689 val substs = prems |> map2 subst_info_of_prem (1 upto length prems) |
690 val substs = prems |> map2 subst_info_of_prem (1 upto length prems) |
690 |> sort (int_ord o apply2 fst) |
691 |> sort (int_ord o apply2 fst) |
691 val depss = maps (map_filter deps_of_term_subst o snd o snd o snd) substs |
692 val depss = maps (map_filter deps_of_term_subst o snd o snd o snd) substs |
692 val clusters = maps (op ::) depss |
693 val clusters = maps (op ::) depss |
693 val ordered_clusters = |
694 val ordered_clusters = |