14 val trace : bool Config.T |
14 val trace : bool Config.T |
15 val trace_msg : Proof.context -> (unit -> string) -> unit |
15 val trace_msg : Proof.context -> (unit -> string) -> unit |
16 val lookth : (Metis_Thm.thm * 'a) list -> Metis_Thm.thm -> 'a |
16 val lookth : (Metis_Thm.thm * 'a) list -> Metis_Thm.thm -> 'a |
17 val untyped_aconv : term -> term -> bool |
17 val untyped_aconv : term -> term -> bool |
18 val replay_one_inference : |
18 val replay_one_inference : |
19 Proof.context -> mode -> (string * term) list |
19 Proof.context -> mode -> (string * term) list * int Unsynchronized.ref |
20 -> Metis_Thm.thm * Metis_Proof.inference -> (Metis_Thm.thm * thm) list |
20 -> Metis_Thm.thm * Metis_Proof.inference -> (Metis_Thm.thm * thm) list |
21 -> (Metis_Thm.thm * thm) list |
21 -> (Metis_Thm.thm * thm) list |
22 val discharge_skolem_premises : |
22 val discharge_skolem_premises : |
23 Proof.context -> (thm * term) option list -> thm -> thm |
23 Proof.context -> (thm * term) option list -> thm -> thm |
24 val setup : theory -> theory |
24 val setup : theory -> theory |
91 case strip_prefix_and_unascii tfree_prefix x of |
91 case strip_prefix_and_unascii tfree_prefix x of |
92 SOME tf => mk_tfree ctxt tf |
92 SOME tf => mk_tfree ctxt tf |
93 | NONE => raise Fail ("hol_type_from_metis_term: " ^ x)); |
93 | NONE => raise Fail ("hol_type_from_metis_term: " ^ x)); |
94 |
94 |
95 (*Maps metis terms to isabelle terms*) |
95 (*Maps metis terms to isabelle terms*) |
96 fun hol_term_from_metis_PT ctxt fol_tm = |
96 fun hol_term_from_metis_PT ctxt new_skolem_var_count fol_tm = |
97 let val thy = ProofContext.theory_of ctxt |
97 let val thy = ProofContext.theory_of ctxt |
98 val _ = trace_msg ctxt (fn () => "hol_term_from_metis_PT: " ^ |
98 val _ = trace_msg ctxt (fn () => "hol_term_from_metis_PT: " ^ |
99 Metis_Term.toString fol_tm) |
99 Metis_Term.toString fol_tm) |
100 fun tm_to_tt (Metis_Term.Var v) = |
100 fun tm_to_tt (Metis_Term.Var v) = |
101 (case strip_prefix_and_unascii tvar_prefix v of |
101 (case strip_prefix_and_unascii tvar_prefix v of |
124 val c = smart_invert_const b |
124 val c = smart_invert_const b |
125 val ntypes = num_type_args thy c |
125 val ntypes = num_type_args thy c |
126 val nterms = length ts - ntypes |
126 val nterms = length ts - ntypes |
127 val tts = map tm_to_tt ts |
127 val tts = map tm_to_tt ts |
128 val tys = types_of (List.take(tts,ntypes)) |
128 val tys = types_of (List.take(tts,ntypes)) |
|
129 val j = !new_skolem_var_count + 1 |
|
130 val _ = new_skolem_var_count := j |
129 val t = |
131 val t = |
130 if String.isPrefix new_skolem_const_prefix c then |
132 if String.isPrefix new_skolem_const_prefix c then |
131 Var (new_skolem_var_from_const c, |
133 Var ((new_skolem_var_name_from_const c, j), |
132 Type_Infer.paramify_vars (tl tys ---> hd tys)) |
134 Type_Infer.paramify_vars (tl tys ---> hd tys)) |
133 else |
135 else |
134 Const (c, dummyT) |
136 Const (c, dummyT) |
135 in if length tys = ntypes then |
137 in if length tys = ntypes then |
136 apply_list t nterms (List.drop(tts,ntypes)) |
138 apply_list t nterms (List.drop(tts,ntypes)) |
160 SomeTerm t => t |
162 SomeTerm t => t |
161 | SomeType T => raise TYPE ("fol_tm_to_tt: Term expected", [T], []) |
163 | SomeType T => raise TYPE ("fol_tm_to_tt: Term expected", [T], []) |
162 end |
164 end |
163 |
165 |
164 (*Maps fully-typed metis terms to isabelle terms*) |
166 (*Maps fully-typed metis terms to isabelle terms*) |
165 fun hol_term_from_metis_FT ctxt fol_tm = |
167 fun hol_term_from_metis_FT ctxt new_skolem_var_count fol_tm = |
166 let val _ = trace_msg ctxt (fn () => "hol_term_from_metis_FT: " ^ |
168 let val _ = trace_msg ctxt (fn () => "hol_term_from_metis_FT: " ^ |
167 Metis_Term.toString fol_tm) |
169 Metis_Term.toString fol_tm) |
168 fun cvt (Metis_Term.Fn ("ti", [Metis_Term.Var v, _])) = |
170 fun cvt (Metis_Term.Fn ("ti", [Metis_Term.Var v, _])) = |
169 (case strip_prefix_and_unascii schematic_var_prefix v of |
171 (case strip_prefix_and_unascii schematic_var_prefix v of |
170 SOME w => mk_var(w, dummyT) |
172 SOME w => mk_var(w, dummyT) |
191 | NONE => (*Not a constant. Is it a fixed variable??*) |
193 | NONE => (*Not a constant. Is it a fixed variable??*) |
192 case strip_prefix_and_unascii fixed_var_prefix x of |
194 case strip_prefix_and_unascii fixed_var_prefix x of |
193 SOME v => Free (v, dummyT) |
195 SOME v => Free (v, dummyT) |
194 | NONE => (trace_msg ctxt (fn () => |
196 | NONE => (trace_msg ctxt (fn () => |
195 "hol_term_from_metis_FT bad const: " ^ x); |
197 "hol_term_from_metis_FT bad const: " ^ x); |
196 hol_term_from_metis_PT ctxt t)) |
198 hol_term_from_metis_PT ctxt new_skolem_var_count t)) |
197 | cvt t = (trace_msg ctxt (fn () => |
199 | cvt t = (trace_msg ctxt (fn () => |
198 "hol_term_from_metis_FT bad term: " ^ Metis_Term.toString t); |
200 "hol_term_from_metis_FT bad term: " ^ Metis_Term.toString t); |
199 hol_term_from_metis_PT ctxt t) |
201 hol_term_from_metis_PT ctxt new_skolem_var_count t) |
200 in fol_tm |> cvt end |
202 in fol_tm |> cvt end |
201 |
203 |
202 fun hol_term_from_metis FT = hol_term_from_metis_FT |
204 fun hol_term_from_metis FT = hol_term_from_metis_FT |
203 | hol_term_from_metis _ = hol_term_from_metis_PT |
205 | hol_term_from_metis _ = hol_term_from_metis_PT |
204 |
206 |
205 fun hol_terms_from_fol ctxt mode old_skolems fol_tms = |
207 fun hol_terms_from_metis ctxt mode (old_skolems, new_skolem_var_count) fol_tms = |
206 let val ts = map (hol_term_from_metis mode ctxt) fol_tms |
208 let val ts = map (hol_term_from_metis mode ctxt new_skolem_var_count) fol_tms |
207 val _ = trace_msg ctxt (fn () => " calling type inference:") |
209 val _ = trace_msg ctxt (fn () => " calling type inference:") |
208 val _ = app (fn t => trace_msg ctxt |
210 val _ = app (fn t => trace_msg ctxt |
209 (fn () => Syntax.string_of_term ctxt t)) ts |
211 (fn () => Syntax.string_of_term ctxt t)) ts |
210 val ts' = ts |> map (reveal_old_skolem_terms old_skolems) |
212 val ts' = ts |> map (reveal_old_skolem_terms old_skolems) |
211 |> infer_types ctxt |
213 |> infer_types ctxt |
247 let val th = EXCLUDED_MIDDLE |
249 let val th = EXCLUDED_MIDDLE |
248 val [vx] = Term.add_vars (prop_of th) [] |
250 val [vx] = Term.add_vars (prop_of th) [] |
249 val substs = [(cterm_of thy (Var vx), cterm_of thy i_atm)] |
251 val substs = [(cterm_of thy (Var vx), cterm_of thy i_atm)] |
250 in cterm_instantiate substs th end; |
252 in cterm_instantiate substs th end; |
251 |
253 |
252 fun assume_inf ctxt mode old_skolems atm = |
254 fun assume_inf ctxt mode skolem_params atm = |
253 inst_excluded_middle |
255 inst_excluded_middle |
254 (ProofContext.theory_of ctxt) |
256 (ProofContext.theory_of ctxt) |
255 (singleton (hol_terms_from_fol ctxt mode old_skolems) (Metis_Term.Fn atm)) |
257 (singleton (hol_terms_from_metis ctxt mode skolem_params) |
|
258 (Metis_Term.Fn atm)) |
256 |
259 |
257 (* INFERENCE RULE: INSTANTIATE (SUBST). Type instantiations are ignored. Trying |
260 (* INFERENCE RULE: INSTANTIATE (SUBST). Type instantiations are ignored. Trying |
258 to reconstruct them admits new possibilities of errors, e.g. concerning |
261 to reconstruct them admits new possibilities of errors, e.g. concerning |
259 sorts. Instead we try to arrange that new TVars are distinct and that types |
262 sorts. Instead we try to arrange that new TVars are distinct and that types |
260 can be inferred from terms. *) |
263 can be inferred from terms. *) |
261 |
264 |
262 fun inst_inf ctxt mode old_skolems thpairs fsubst th = |
265 fun inst_inf ctxt mode (old_skolems, new_skolem_var_count) thpairs fsubst th = |
263 let val thy = ProofContext.theory_of ctxt |
266 let val thy = ProofContext.theory_of ctxt |
264 val i_th = lookth thpairs th |
267 val i_th = lookth thpairs th |
265 val i_th_vars = Term.add_vars (prop_of i_th) [] |
268 val i_th_vars = Term.add_vars (prop_of i_th) [] |
266 fun find_var x = the (List.find (fn ((a,_),_) => a=x) i_th_vars) |
269 fun find_var x = the (List.find (fn ((a,_),_) => a=x) i_th_vars) |
267 fun subst_translation (x,y) = |
270 fun subst_translation (x,y) = |
268 let val v = find_var x |
271 let val v = find_var x |
269 (* We call "reveal_old_skolem_terms" and "infer_types" below. *) |
272 (* We call "reveal_old_skolem_terms" and "infer_types" below. *) |
270 val t = hol_term_from_metis mode ctxt y |
273 val t = hol_term_from_metis mode ctxt new_skolem_var_count y |
271 in SOME (cterm_of thy (Var v), t) end |
274 in SOME (cterm_of thy (Var v), t) end |
272 handle Option.Option => |
275 handle Option.Option => |
273 (trace_msg ctxt (fn () => "\"find_var\" failed for " ^ x ^ |
276 (trace_msg ctxt (fn () => "\"find_var\" failed for " ^ x ^ |
274 " in " ^ Display.string_of_thm ctxt i_th); |
277 " in " ^ Display.string_of_thm ctxt i_th); |
275 NONE) |
278 NONE) |
373 val negate_head = rewrite_rule [@{thm atomize_not}, not_not RS eq_reflection] |
376 val negate_head = rewrite_rule [@{thm atomize_not}, not_not RS eq_reflection] |
374 |
377 |
375 (* Maps the clause [P1,...Pn]==>False to [P1,...,P(i-1),P(i+1),...Pn] ==> ~P *) |
378 (* Maps the clause [P1,...Pn]==>False to [P1,...,P(i-1),P(i+1),...Pn] ==> ~P *) |
376 val select_literal = negate_head oo make_last |
379 val select_literal = negate_head oo make_last |
377 |
380 |
378 fun resolve_inf ctxt mode old_skolems thpairs atm th1 th2 = |
381 fun resolve_inf ctxt mode skolem_params thpairs atm th1 th2 = |
379 let |
382 let |
380 val thy = ProofContext.theory_of ctxt |
383 val thy = ProofContext.theory_of ctxt |
381 val i_th1 = lookth thpairs th1 and i_th2 = lookth thpairs th2 |
384 val i_th1 = lookth thpairs th1 and i_th2 = lookth thpairs th2 |
382 val _ = trace_msg ctxt (fn () => " isa th1 (pos): " ^ Display.string_of_thm ctxt i_th1) |
385 val _ = trace_msg ctxt (fn () => " isa th1 (pos): " ^ Display.string_of_thm ctxt i_th1) |
383 val _ = trace_msg ctxt (fn () => " isa th2 (neg): " ^ Display.string_of_thm ctxt i_th2) |
386 val _ = trace_msg ctxt (fn () => " isa th2 (neg): " ^ Display.string_of_thm ctxt i_th2) |
413 val REFL_THM = Thm.incr_indexes 2 @{lemma "t ~= t ==> False" by simp} |
416 val REFL_THM = Thm.incr_indexes 2 @{lemma "t ~= t ==> False" by simp} |
414 |
417 |
415 val refl_x = cterm_of @{theory} (Var (hd (Term.add_vars (prop_of REFL_THM) []))); |
418 val refl_x = cterm_of @{theory} (Var (hd (Term.add_vars (prop_of REFL_THM) []))); |
416 val refl_idx = 1 + Thm.maxidx_of REFL_THM; |
419 val refl_idx = 1 + Thm.maxidx_of REFL_THM; |
417 |
420 |
418 fun refl_inf ctxt mode old_skolems t = |
421 fun refl_inf ctxt mode skolem_params t = |
419 let val thy = ProofContext.theory_of ctxt |
422 let val thy = ProofContext.theory_of ctxt |
420 val i_t = singleton (hol_terms_from_fol ctxt mode old_skolems) t |
423 val i_t = singleton (hol_terms_from_metis ctxt mode skolem_params) t |
421 val _ = trace_msg ctxt (fn () => " term: " ^ Syntax.string_of_term ctxt i_t) |
424 val _ = trace_msg ctxt (fn () => " term: " ^ Syntax.string_of_term ctxt i_t) |
422 val c_t = cterm_incr_types thy refl_idx i_t |
425 val c_t = cterm_incr_types thy refl_idx i_t |
423 in cterm_instantiate [(refl_x, c_t)] REFL_THM end; |
426 in cterm_instantiate [(refl_x, c_t)] REFL_THM end; |
424 |
427 |
425 (* INFERENCE RULE: EQUALITY *) |
428 (* INFERENCE RULE: EQUALITY *) |
431 |
434 |
432 fun get_ty_arg_size _ (Const (@{const_name HOL.eq}, _)) = 0 (*equality has no type arguments*) |
435 fun get_ty_arg_size _ (Const (@{const_name HOL.eq}, _)) = 0 (*equality has no type arguments*) |
433 | get_ty_arg_size thy (Const (c, _)) = (num_type_args thy c handle TYPE _ => 0) |
436 | get_ty_arg_size thy (Const (c, _)) = (num_type_args thy c handle TYPE _ => 0) |
434 | get_ty_arg_size _ _ = 0; |
437 | get_ty_arg_size _ _ = 0; |
435 |
438 |
436 fun equality_inf ctxt mode old_skolems (pos, atm) fp fr = |
439 fun equality_inf ctxt mode skolem_params (pos, atm) fp fr = |
437 let val thy = ProofContext.theory_of ctxt |
440 let val thy = ProofContext.theory_of ctxt |
438 val m_tm = Metis_Term.Fn atm |
441 val m_tm = Metis_Term.Fn atm |
439 val [i_atm,i_tm] = hol_terms_from_fol ctxt mode old_skolems [m_tm, fr] |
442 val [i_atm,i_tm] = hol_terms_from_metis ctxt mode skolem_params [m_tm, fr] |
440 val _ = trace_msg ctxt (fn () => "sign of the literal: " ^ Bool.toString pos) |
443 val _ = trace_msg ctxt (fn () => "sign of the literal: " ^ Bool.toString pos) |
441 fun replace_item_list lx 0 (_::ls) = lx::ls |
444 fun replace_item_list lx 0 (_::ls) = lx::ls |
442 | replace_item_list lx i (l::ls) = l :: replace_item_list lx (i-1) ls |
445 | replace_item_list lx i (l::ls) = l :: replace_item_list lx (i-1) ls |
443 fun path_finder_FO tm [] = (tm, Bound 0) |
446 fun path_finder_FO tm [] = (tm, Bound 0) |
444 | path_finder_FO tm (p::ps) = |
447 | path_finder_FO tm (p::ps) = |
513 (ListPair.zip (OldTerm.term_vars (prop_of subst'), [tm_abs, tm_subst, i_tm])) |
516 (ListPair.zip (OldTerm.term_vars (prop_of subst'), [tm_abs, tm_subst, i_tm])) |
514 in cterm_instantiate eq_terms subst' end; |
517 in cterm_instantiate eq_terms subst' end; |
515 |
518 |
516 val factor = Seq.hd o distinct_subgoals_tac; |
519 val factor = Seq.hd o distinct_subgoals_tac; |
517 |
520 |
518 fun step ctxt mode old_skolems thpairs p = |
521 fun step ctxt mode skolem_params thpairs p = |
519 case p of |
522 case p of |
520 (fol_th, Metis_Proof.Axiom _) => factor (axiom_inf thpairs fol_th) |
523 (fol_th, Metis_Proof.Axiom _) => factor (axiom_inf thpairs fol_th) |
521 | (_, Metis_Proof.Assume f_atm) => assume_inf ctxt mode old_skolems f_atm |
524 | (_, Metis_Proof.Assume f_atm) => assume_inf ctxt mode skolem_params f_atm |
522 | (_, Metis_Proof.Metis_Subst (f_subst, f_th1)) => |
525 | (_, Metis_Proof.Metis_Subst (f_subst, f_th1)) => |
523 factor (inst_inf ctxt mode old_skolems thpairs f_subst f_th1) |
526 factor (inst_inf ctxt mode skolem_params thpairs f_subst f_th1) |
524 | (_, Metis_Proof.Resolve(f_atm, f_th1, f_th2)) => |
527 | (_, Metis_Proof.Resolve(f_atm, f_th1, f_th2)) => |
525 factor (resolve_inf ctxt mode old_skolems thpairs f_atm f_th1 f_th2) |
528 factor (resolve_inf ctxt mode skolem_params thpairs f_atm f_th1 f_th2) |
526 | (_, Metis_Proof.Refl f_tm) => refl_inf ctxt mode old_skolems f_tm |
529 | (_, Metis_Proof.Refl f_tm) => refl_inf ctxt mode skolem_params f_tm |
527 | (_, Metis_Proof.Equality (f_lit, f_p, f_r)) => |
530 | (_, Metis_Proof.Equality (f_lit, f_p, f_r)) => |
528 equality_inf ctxt mode old_skolems f_lit f_p f_r |
531 equality_inf ctxt mode skolem_params f_lit f_p f_r |
529 |
532 |
530 fun flexflex_first_order th = |
533 fun flexflex_first_order th = |
531 case Thm.tpairs_of th of |
534 case Thm.tpairs_of th of |
532 [] => th |
535 [] => th |
533 | pairs => |
536 | pairs => |
543 fun is_isabelle_literal_genuine t = |
546 fun is_isabelle_literal_genuine t = |
544 case t of _ $ (Const (@{const_name Meson.skolem}, _) $ _) => false | _ => true |
547 case t of _ $ (Const (@{const_name Meson.skolem}, _) $ _) => false | _ => true |
545 |
548 |
546 fun count p xs = fold (fn x => if p x then Integer.add 1 else I) xs 0 |
549 fun count p xs = fold (fn x => if p x then Integer.add 1 else I) xs 0 |
547 |
550 |
548 fun replay_one_inference ctxt mode old_skolems (fol_th, inf) thpairs = |
551 fun replay_one_inference ctxt mode skolem_params (fol_th, inf) thpairs = |
549 let |
552 let |
550 val _ = trace_msg ctxt (fn () => "=============================================") |
553 val _ = trace_msg ctxt (fn () => "=============================================") |
551 val _ = trace_msg ctxt (fn () => "METIS THM: " ^ Metis_Thm.toString fol_th) |
554 val _ = trace_msg ctxt (fn () => "METIS THM: " ^ Metis_Thm.toString fol_th) |
552 val _ = trace_msg ctxt (fn () => "INFERENCE: " ^ Metis_Proof.inferenceToString inf) |
555 val _ = trace_msg ctxt (fn () => "INFERENCE: " ^ Metis_Proof.inferenceToString inf) |
553 val th = step ctxt mode old_skolems thpairs (fol_th, inf) |
556 val th = step ctxt mode skolem_params thpairs (fol_th, inf) |
554 |> flexflex_first_order |
557 |> flexflex_first_order |
555 val _ = trace_msg ctxt (fn () => "ISABELLE THM: " ^ Display.string_of_thm ctxt th) |
558 val _ = trace_msg ctxt (fn () => "ISABELLE THM: " ^ Display.string_of_thm ctxt th) |
556 val _ = trace_msg ctxt (fn () => "=============================================") |
559 val _ = trace_msg ctxt (fn () => "=============================================") |
557 val num_metis_lits = |
560 val num_metis_lits = |
558 fol_th |> Metis_Thm.clause |> Metis_LiteralSet.toList |
561 fol_th |> Metis_Thm.clause |> Metis_LiteralSet.toList |