47 In Isabelle, type tags are stripped away, so we are left with "t = t" or |
47 In Isabelle, type tags are stripped away, so we are left with "t = t" or |
48 "t => t". Type tag idempotence is also handled this way. *) |
48 "t => t". Type tag idempotence is also handled this way. *) |
49 fun reflexive_or_trivial_of_metis ctxt type_enc sym_tab concealed mth = |
49 fun reflexive_or_trivial_of_metis ctxt type_enc sym_tab concealed mth = |
50 (case hol_clause_of_metis ctxt type_enc sym_tab concealed mth of |
50 (case hol_clause_of_metis ctxt type_enc sym_tab concealed mth of |
51 Const (\<^const_name>\<open>HOL.eq\<close>, _) $ _ $ t => |
51 Const (\<^const_name>\<open>HOL.eq\<close>, _) $ _ $ t => |
52 let |
52 let |
53 val ct = Thm.cterm_of ctxt t |
53 val ct = Thm.cterm_of ctxt t |
54 val cT = Thm.ctyp_of_cterm ct |
54 val cT = Thm.ctyp_of_cterm ct |
55 in refl |> Thm.instantiate' [SOME cT] [SOME ct] end |
55 in refl |> Thm.instantiate' [SOME cT] [SOME ct] end |
56 | Const (\<^const_name>\<open>disj\<close>, _) $ t1 $ t2 => |
56 | Const (\<^const_name>\<open>disj\<close>, _) $ t1 $ t2 => |
57 (if can HOLogic.dest_not t1 then t2 else t1) |
57 (if can HOLogic.dest_not t1 then t2 else t1) |
58 |> HOLogic.mk_Trueprop |> Thm.cterm_of ctxt |> Thm.trivial |
58 |> HOLogic.mk_Trueprop |> Thm.cterm_of ctxt |> Thm.trivial |
59 | _ => raise Fail "expected reflexive or trivial clause") |
59 | _ => raise Fail "expected reflexive or trivial clause") |
60 |> Meson.make_meta_clause ctxt |
60 |> Meson.make_meta_clause ctxt |
61 |
61 |
62 fun lam_lifted_of_metis ctxt type_enc sym_tab concealed mth = |
62 fun lam_lifted_of_metis ctxt type_enc sym_tab concealed mth = |
63 let |
63 let |
64 val tac = rewrite_goals_tac ctxt @{thms lambda_def [abs_def]} THEN resolve_tac ctxt [refl] 1 |
64 val tac = rewrite_goals_tac ctxt @{thms lambda_def [abs_def]} THEN resolve_tac ctxt [refl] 1 |
65 val t = hol_clause_of_metis ctxt type_enc sym_tab concealed mth |
65 val t = hol_clause_of_metis ctxt type_enc sym_tab concealed mth |
66 val ct = Thm.cterm_of ctxt (HOLogic.mk_Trueprop t) |
66 val ct = Thm.cterm_of ctxt (HOLogic.mk_Trueprop t) |
67 in Goal.prove_internal ctxt [] ct (K tac) |> Meson.make_meta_clause ctxt end |
67 in |
|
68 Goal.prove_internal ctxt [] ct (K tac) |
|
69 |> Meson.make_meta_clause ctxt |
|
70 end |
68 |
71 |
69 fun add_vars_and_frees (t $ u) = fold (add_vars_and_frees) [t, u] |
72 fun add_vars_and_frees (t $ u) = fold (add_vars_and_frees) [t, u] |
70 | add_vars_and_frees (Abs (_, _, t)) = add_vars_and_frees t |
73 | add_vars_and_frees (Abs (_, _, t)) = add_vars_and_frees t |
71 | add_vars_and_frees (t as Var _) = insert (op =) t |
74 | add_vars_and_frees (t as Var _) = insert (op =) t |
72 | add_vars_and_frees (t as Free _) = insert (op =) t |
75 | add_vars_and_frees (t as Free _) = insert (op =) t |
73 | add_vars_and_frees _ = I |
76 | add_vars_and_frees _ = I |
74 |
77 |
75 fun introduce_lam_wrappers ctxt th = |
78 fun introduce_lam_wrappers ctxt th = |
76 if Meson_Clausify.is_quasi_lambda_free (Thm.prop_of th) then |
79 if Meson_Clausify.is_quasi_lambda_free (Thm.prop_of th) then th |
77 th |
|
78 else |
80 else |
79 let |
81 let |
80 fun conv first ctxt ct = |
82 fun conv first ctxt ct = |
81 if Meson_Clausify.is_quasi_lambda_free (Thm.term_of ct) then |
83 if Meson_Clausify.is_quasi_lambda_free (Thm.term_of ct) then Thm.reflexive ct |
82 Thm.reflexive ct |
|
83 else |
84 else |
84 (case Thm.term_of ct of |
85 (case Thm.term_of ct of |
85 Abs (_, _, u) => |
86 Abs (_, _, u) => |
86 if first then |
87 if first then |
87 (case add_vars_and_frees u [] of |
88 (case add_vars_and_frees u [] of |
88 [] => |
89 [] => |
89 Conv.abs_conv (conv false o snd) ctxt ct |
90 Conv.abs_conv (conv false o snd) ctxt ct |
90 |> (fn th => Meson.first_order_resolve ctxt th @{thm Metis.eq_lambdaI}) |
91 |> (fn th => Meson.first_order_resolve ctxt th @{thm Metis.eq_lambdaI}) |
91 | v :: _ => |
92 | v :: _ => |
92 Abs (Name.uu, fastype_of v, abstract_over (v, Thm.term_of ct)) $ v |
93 Abs (Name.uu, fastype_of v, abstract_over (v, Thm.term_of ct)) $ v |
93 |> Thm.cterm_of ctxt |
94 |> Thm.cterm_of ctxt |
94 |> Conv.comb_conv (conv true ctxt)) |
95 |> Conv.comb_conv (conv true ctxt)) |
95 else |
96 else Conv.abs_conv (conv false o snd) ctxt ct |
96 Conv.abs_conv (conv false o snd) ctxt ct |
|
97 | Const (\<^const_name>\<open>Meson.skolem\<close>, _) $ _ => Thm.reflexive ct |
97 | Const (\<^const_name>\<open>Meson.skolem\<close>, _) $ _ => Thm.reflexive ct |
98 | _ => Conv.comb_conv (conv true ctxt) ct) |
98 | _ => Conv.comb_conv (conv true ctxt) ct) |
99 val eq_th = conv true ctxt (Thm.cprop_of th) |
99 val eq_th = conv true ctxt (Thm.cprop_of th) |
100 (* We replace the equation's left-hand side with a beta-equivalent term |
100 (* We replace the equation's left-hand side with a beta-equivalent term |
101 so that "Thm.equal_elim" works below. *) |
101 so that "Thm.equal_elim" works below. *) |
143 |
143 |
144 exception METIS_UNPROVABLE of unit |
144 exception METIS_UNPROVABLE of unit |
145 |
145 |
146 (* Main function to start Metis proof and reconstruction *) |
146 (* Main function to start Metis proof and reconstruction *) |
147 fun FOL_SOLVE unused type_encs lam_trans ctxt cls ths0 = |
147 fun FOL_SOLVE unused type_encs lam_trans ctxt cls ths0 = |
148 let val thy = Proof_Context.theory_of ctxt |
148 let |
149 val type_enc :: fallback_type_encs = type_encs |
149 val thy = Proof_Context.theory_of ctxt |
150 val new_skolem = |
150 |
151 Config.get ctxt new_skolem orelse null (Meson.choice_theorems thy) |
151 val new_skolem = Config.get ctxt new_skolem orelse null (Meson.choice_theorems thy) |
152 val do_lams = |
152 val do_lams = |
153 (lam_trans = liftingN orelse lam_trans = lam_liftingN) |
153 (lam_trans = liftingN orelse lam_trans = lam_liftingN) ? introduce_lam_wrappers ctxt |
154 ? introduce_lam_wrappers ctxt |
154 val th_cls_pairs = |
155 val th_cls_pairs = |
155 map2 (fn j => fn th => |
156 map2 (fn j => fn th => |
156 (Thm.get_name_hint th, |
157 (Thm.get_name_hint th, |
157 th |
158 th |> Drule.eta_contraction_rule |
158 |> Drule.eta_contraction_rule |
159 |> Meson_Clausify.cnf_axiom ctxt new_skolem (lam_trans = combsN) j |
159 |> Meson_Clausify.cnf_axiom ctxt new_skolem (lam_trans = combsN) j |
160 ||> map do_lams)) |
160 ||> map do_lams)) |
161 (0 upto length ths0 - 1) ths0 |
161 (0 upto length ths0 - 1) ths0 |
162 val ths = maps (snd o snd) th_cls_pairs |
162 val ths = maps (snd o snd) th_cls_pairs |
163 val dischargers = map (fst o snd) th_cls_pairs |
163 val dischargers = map (fst o snd) th_cls_pairs |
164 val cls = cls |> map (Drule.eta_contraction_rule #> do_lams) |
164 val cls = cls |> map (Drule.eta_contraction_rule #> do_lams) |
165 val _ = trace_msg ctxt (K "FOL_SOLVE: CONJECTURE CLAUSES") |
165 val _ = trace_msg ctxt (K "FOL_SOLVE: CONJECTURE CLAUSES") |
166 val _ = List.app (fn th => trace_msg ctxt (fn () => Thm.string_of_thm ctxt th)) cls |
166 val _ = List.app (fn th => trace_msg ctxt (fn () => Thm.string_of_thm ctxt th)) cls |
167 val _ = trace_msg ctxt (fn () => "type_enc = " ^ type_enc) |
167 |
168 val type_enc = type_enc_of_string Strict type_enc |
168 val type_enc :: fallback_type_encs = type_encs |
169 val (sym_tab, axioms, ord_info, concealed) = |
169 val _ = trace_msg ctxt (fn () => "type_enc = " ^ type_enc) |
170 generate_metis_problem ctxt type_enc lam_trans cls ths |
170 val type_enc = type_enc_of_string Strict type_enc |
171 fun get_isa_thm mth Isa_Reflexive_or_Trivial = |
171 |
|
172 val (sym_tab, axioms, ord_info, concealed) = |
|
173 generate_metis_problem ctxt type_enc lam_trans cls ths |
|
174 fun get_isa_thm mth Isa_Reflexive_or_Trivial = |
172 reflexive_or_trivial_of_metis ctxt type_enc sym_tab concealed mth |
175 reflexive_or_trivial_of_metis ctxt type_enc sym_tab concealed mth |
173 | get_isa_thm mth Isa_Lambda_Lifted = |
176 | get_isa_thm mth Isa_Lambda_Lifted = |
174 lam_lifted_of_metis ctxt type_enc sym_tab concealed mth |
177 lam_lifted_of_metis ctxt type_enc sym_tab concealed mth |
175 | get_isa_thm _ (Isa_Raw ith) = ith |
178 | get_isa_thm _ (Isa_Raw ith) = ith |
176 val axioms = axioms |> map (fn (mth, ith) => (mth, get_isa_thm mth ith)) |
179 val axioms = axioms |> map (fn (mth, ith) => (mth, get_isa_thm mth ith)) |
177 val _ = trace_msg ctxt (K "ISABELLE CLAUSES") |
180 val _ = trace_msg ctxt (K "ISABELLE CLAUSES") |
178 val _ = List.app (fn (_, ith) => trace_msg ctxt (fn () => Thm.string_of_thm ctxt ith)) axioms |
181 val _ = List.app (fn (_, ith) => trace_msg ctxt (fn () => Thm.string_of_thm ctxt ith)) axioms |
179 val _ = trace_msg ctxt (K "METIS CLAUSES") |
182 val _ = trace_msg ctxt (K "METIS CLAUSES") |
180 val _ = List.app (fn (mth, _) => trace_msg ctxt (fn () => Metis_Thm.toString mth)) axioms |
183 val _ = List.app (fn (mth, _) => trace_msg ctxt (fn () => Metis_Thm.toString mth)) axioms |
181 val _ = trace_msg ctxt (K "START METIS PROVE PROCESS") |
184 |
182 val ordering = |
185 val _ = trace_msg ctxt (K "START METIS PROVE PROCESS") |
183 if Config.get ctxt advisory_simp then |
186 val ordering = |
184 kbo_advisory_simp_ordering (ord_info ()) |
187 if Config.get ctxt advisory_simp |
185 else |
188 then kbo_advisory_simp_ordering (ord_info ()) |
186 Metis_KnuthBendixOrder.default |
189 else Metis_KnuthBendixOrder.default |
|
190 |
187 fun fall_back () = |
191 fun fall_back () = |
188 (verbose_warning ctxt |
192 (verbose_warning ctxt |
189 ("Falling back on " ^ quote (metis_call (hd fallback_type_encs) lam_trans) ^ "..."); |
193 ("Falling back on " ^ quote (metis_call (hd fallback_type_encs) lam_trans) ^ "..."); |
190 FOL_SOLVE unused fallback_type_encs lam_trans ctxt cls ths0) |
194 FOL_SOLVE unused fallback_type_encs lam_trans ctxt cls ths0) |
191 in |
195 in |
192 (case filter (fn t => Thm.prop_of t aconv \<^prop>\<open>False\<close>) cls of |
196 (case filter (fn t => Thm.prop_of t aconv \<^prop>\<open>False\<close>) cls of |
193 false_th :: _ => [false_th RS @{thm FalseE}] |
197 false_th :: _ => [false_th RS @{thm FalseE}] |
194 | [] => |
198 | [] => |
195 (case Metis_Resolution.loop (Metis_Resolution.new (resolution_params ordering) |
199 (case Metis_Resolution.loop (Metis_Resolution.new (resolution_params ordering) |
196 {axioms = axioms |> map fst, conjecture = []}) of |
200 {axioms = axioms |> map fst, conjecture = []}) of |
197 Metis_Resolution.Contradiction mth => |
201 Metis_Resolution.Contradiction mth => |
198 let |
202 let |
199 val _ = trace_msg ctxt (fn () => "METIS RECONSTRUCTION START: " ^ Metis_Thm.toString mth) |
203 val _ = trace_msg ctxt (fn () => "METIS RECONSTRUCTION START: " ^ Metis_Thm.toString mth) |
200 val ctxt' = fold Variable.declare_constraints (map Thm.prop_of cls) ctxt |
204 val ctxt' = fold Variable.declare_constraints (map Thm.prop_of cls) ctxt |
201 (*add constraints arising from converting goal to clause form*) |
205 (*add constraints arising from converting goal to clause form*) |
202 val proof = Metis_Proof.proof mth |
206 val proof = Metis_Proof.proof mth |
203 val result = fold (replay_one_inference ctxt' type_enc concealed sym_tab) proof axioms |
207 val result = fold (replay_one_inference ctxt' type_enc concealed sym_tab) proof axioms |
204 val used = map_filter (used_axioms axioms) proof |
208 val used = map_filter (used_axioms axioms) proof |
205 val _ = trace_msg ctxt (K "METIS COMPLETED; clauses actually used:") |
209 val _ = trace_msg ctxt (K "METIS COMPLETED; clauses actually used:") |
206 val _ = List.app (fn th => trace_msg ctxt (fn () => Thm.string_of_thm ctxt th)) used |
210 val _ = List.app (fn th => trace_msg ctxt (fn () => Thm.string_of_thm ctxt th)) used |
207 val (used_th_cls_pairs, unused_th_cls_pairs) = |
211 val (used_th_cls_pairs, unused_th_cls_pairs) = |
208 List.partition (have_common_thm ctxt used o snd o snd) th_cls_pairs |
212 List.partition (have_common_thm ctxt used o snd o snd) th_cls_pairs |
209 val unused_ths = maps (snd o snd) unused_th_cls_pairs |
213 val unused_ths = maps (snd o snd) unused_th_cls_pairs |
210 val unused_names = map fst unused_th_cls_pairs |
214 val unused_names = map fst unused_th_cls_pairs |
211 in |
215 |
212 unused := unused_ths; |
216 val _ = unused := unused_ths; |
213 if not (null unused_names) then |
217 val _ = |
214 verbose_warning ctxt ("Unused theorems: " ^ commas_quote unused_names) |
218 if not (null unused_names) then |
215 else |
219 verbose_warning ctxt ("Unused theorems: " ^ commas_quote unused_names) |
216 (); |
220 else (); |
217 if not (null cls) andalso not (have_common_thm ctxt used cls) then |
221 val _ = |
218 verbose_warning ctxt "The assumptions are inconsistent" |
222 if not (null cls) andalso not (have_common_thm ctxt used cls) then |
219 else |
223 verbose_warning ctxt "The assumptions are inconsistent" |
220 (); |
224 else (); |
221 (case result of |
225 in |
222 (_, ith) :: _ => |
226 (case result of |
223 (trace_msg ctxt (fn () => "Success: " ^ Thm.string_of_thm ctxt ith); |
227 (_, ith) :: _ => |
224 [discharge_skolem_premises ctxt dischargers ith]) |
228 (trace_msg ctxt (fn () => "Success: " ^ Thm.string_of_thm ctxt ith); |
225 | _ => (trace_msg ctxt (K "Metis: No result"); [])) |
229 [discharge_skolem_premises ctxt dischargers ith]) |
226 end |
230 | _ => (trace_msg ctxt (K "Metis: No result"); [])) |
227 | Metis_Resolution.Satisfiable _ => |
231 end |
228 (trace_msg ctxt (K "Metis: No first-order proof with the supplied lemmas"); |
232 | Metis_Resolution.Satisfiable _ => |
229 raise METIS_UNPROVABLE ())) |
233 (trace_msg ctxt (K "Metis: No first-order proof with the supplied lemmas"); |
230 handle METIS_UNPROVABLE () => if null fallback_type_encs then [] else fall_back () |
234 raise METIS_UNPROVABLE ())) |
231 | METIS_RECONSTRUCT (loc, msg) => |
235 handle METIS_UNPROVABLE () => if null fallback_type_encs then [] else fall_back () |
232 if null fallback_type_encs then |
236 | METIS_RECONSTRUCT (loc, msg) => |
233 (verbose_warning ctxt ("Failed to replay Metis proof\n" ^ loc ^ ": " ^ msg); []) |
237 if null fallback_type_encs then |
234 else |
238 (verbose_warning ctxt ("Failed to replay Metis proof\n" ^ loc ^ ": " ^ msg); []) |
235 fall_back ()) |
239 else fall_back ()) |
236 end |
240 end |
237 |
241 |
238 fun neg_clausify ctxt combinators = |
242 fun neg_clausify ctxt combinators = |
239 single |
243 single |
240 #> Meson.make_clauses_unsorted ctxt |
244 #> Meson.make_clauses_unsorted ctxt |