14 val default_unsound_type_sys : string |
14 val default_unsound_type_sys : string |
15 val default_sound_type_sys : string |
15 val default_sound_type_sys : string |
16 val trace : bool Config.T |
16 val trace : bool Config.T |
17 val verbose : bool Config.T |
17 val verbose : bool Config.T |
18 val new_skolemizer : bool Config.T |
18 val new_skolemizer : bool Config.T |
19 val old_metis_tac : Proof.context -> thm list -> int -> tactic |
19 val metis_tac : string list -> Proof.context -> thm list -> int -> tactic |
20 val old_metisF_tac : Proof.context -> thm list -> int -> tactic |
20 val metisFT_tac : Proof.context -> thm list -> int -> tactic |
21 val old_metisFT_tac : Proof.context -> thm list -> int -> tactic |
|
22 val new_metis_tac : string list -> Proof.context -> thm list -> int -> tactic |
|
23 val new_metisFT_tac : Proof.context -> thm list -> int -> tactic |
|
24 val setup : theory -> theory |
21 val setup : theory -> theory |
25 end |
22 end |
26 |
23 |
27 structure Metis_Tactics : METIS_TACTICS = |
24 structure Metis_Tactics : METIS_TACTICS = |
28 struct |
25 struct |
36 val full_typesN = "full_types" |
33 val full_typesN = "full_types" |
37 |
34 |
38 val default_unsound_type_sys = "poly_args" |
35 val default_unsound_type_sys = "poly_args" |
39 val default_sound_type_sys = "poly_preds_heavy_query" |
36 val default_sound_type_sys = "poly_preds_heavy_query" |
40 |
37 |
41 fun method_call_for_mode HO = (@{binding old_metis}, "") |
38 fun method_call_for_type_sys type_sys = |
42 | method_call_for_mode FO = (@{binding metisF}, "") |
39 if type_sys = default_sound_type_sys then |
43 | method_call_for_mode FT = (@{binding old_metisFT}, "") |
40 (@{binding metisFT}, "") |
44 | method_call_for_mode (Type_Sys type_sys) = |
41 else |
45 if type_sys = default_sound_type_sys then |
42 (@{binding metis}, |
46 (@{binding metisFT}, "") |
43 if type_sys = default_unsound_type_sys then "" else type_sys) |
47 else |
|
48 (@{binding metis}, |
|
49 if type_sys = default_unsound_type_sys then "" else type_sys) |
|
50 |
44 |
51 val new_skolemizer = |
45 val new_skolemizer = |
52 Attrib.setup_config_bool @{binding metis_new_skolemizer} (K false) |
46 Attrib.setup_config_bool @{binding metis_new_skolemizer} (K false) |
53 |
47 |
54 (* Designed to work also with monomorphic instances of polymorphic theorems. *) |
48 (* Designed to work also with monomorphic instances of polymorphic theorems. *) |
110 val dischargers = map (fst o snd) th_cls_pairs |
99 val dischargers = map (fst o snd) th_cls_pairs |
111 val _ = trace_msg ctxt (fn () => "FOL_SOLVE: CONJECTURE CLAUSES") |
100 val _ = trace_msg ctxt (fn () => "FOL_SOLVE: CONJECTURE CLAUSES") |
112 val _ = app (fn th => trace_msg ctxt (fn () => Display.string_of_thm ctxt th)) cls |
101 val _ = app (fn th => trace_msg ctxt (fn () => Display.string_of_thm ctxt th)) cls |
113 val _ = trace_msg ctxt (fn () => "THEOREM CLAUSES") |
102 val _ = trace_msg ctxt (fn () => "THEOREM CLAUSES") |
114 val _ = app (fn th => trace_msg ctxt (fn () => Display.string_of_thm ctxt th)) ths |
103 val _ = app (fn th => trace_msg ctxt (fn () => Display.string_of_thm ctxt th)) ths |
115 val (mode, sym_tab, {axioms, old_skolems, ...}) = |
104 val (sym_tab, axioms, old_skolems) = |
116 prepare_metis_problem ctxt mode cls ths |
105 prepare_metis_problem ctxt type_sys cls ths |
117 fun get_isa_thm mth Isa_Reflexive_or_Trivial = |
106 fun get_isa_thm mth Isa_Reflexive_or_Trivial = |
118 reflexive_or_trivial_from_metis ctxt sym_tab old_skolems mth |
107 reflexive_or_trivial_from_metis ctxt sym_tab old_skolems mth |
119 | get_isa_thm _ (Isa_Raw ith) = ith |
108 | get_isa_thm _ (Isa_Raw ith) = ith |
120 val axioms = axioms |> map (fn (mth, ith) => (mth, get_isa_thm mth ith)) |
109 val axioms = axioms |> map (fn (mth, ith) => (mth, get_isa_thm mth ith)) |
121 val _ = trace_msg ctxt (fn () => "CLAUSES GIVEN TO METIS") |
110 val _ = trace_msg ctxt (fn () => "CLAUSES GIVEN TO METIS") |
122 val thms = axioms |> map fst |
111 val thms = axioms |> map fst |
123 val _ = app (fn th => trace_msg ctxt (fn () => Metis_Thm.toString th)) thms |
112 val _ = app (fn th => trace_msg ctxt (fn () => Metis_Thm.toString th)) thms |
124 val _ = trace_msg ctxt (fn () => "mode = " ^ string_of_mode mode) |
113 val _ = trace_msg ctxt (fn () => "type_sys = " ^ type_sys) |
125 val _ = trace_msg ctxt (fn () => "START METIS PROVE PROCESS") |
114 val _ = trace_msg ctxt (fn () => "START METIS PROVE PROCESS") |
126 in |
115 in |
127 case filter (fn t => prop_of t aconv @{prop False}) cls of |
116 case filter (fn t => prop_of t aconv @{prop False}) cls of |
128 false_th :: _ => [false_th RS @{thm FalseE}] |
117 false_th :: _ => [false_th RS @{thm FalseE}] |
129 | [] => |
118 | [] => |
134 Metis_Thm.toString mth) |
123 Metis_Thm.toString mth) |
135 val ctxt' = fold Variable.declare_constraints (map prop_of cls) ctxt |
124 val ctxt' = fold Variable.declare_constraints (map prop_of cls) ctxt |
136 (*add constraints arising from converting goal to clause form*) |
125 (*add constraints arising from converting goal to clause form*) |
137 val proof = Metis_Proof.proof mth |
126 val proof = Metis_Proof.proof mth |
138 val result = |
127 val result = |
139 fold (replay_one_inference ctxt' mode old_skolems sym_tab) |
128 axioms |
140 proof axioms |
129 |> fold (replay_one_inference ctxt' old_skolems sym_tab) proof |
141 val used = map_filter (used_axioms axioms) proof |
130 val used = map_filter (used_axioms axioms) proof |
142 val _ = trace_msg ctxt (fn () => "METIS COMPLETED...clauses actually used:") |
131 val _ = trace_msg ctxt (fn () => "METIS COMPLETED...clauses actually used:") |
143 val _ = app (fn th => trace_msg ctxt (fn () => Display.string_of_thm ctxt th)) used |
132 val _ = app (fn th => trace_msg ctxt (fn () => Display.string_of_thm ctxt th)) used |
144 val names = th_cls_pairs |> map fst |
133 val names = th_cls_pairs |> map fst |
145 val used_names = |
134 val used_names = |
164 [discharge_skolem_premises ctxt dischargers ith]) |
153 [discharge_skolem_premises ctxt dischargers ith]) |
165 | _ => (trace_msg ctxt (fn () => "Metis: No result"); []) |
154 | _ => (trace_msg ctxt (fn () => "Metis: No result"); []) |
166 end |
155 end |
167 | Metis_Resolution.Satisfiable _ => |
156 | Metis_Resolution.Satisfiable _ => |
168 (trace_msg ctxt (fn () => "Metis: No first-order proof with the lemmas supplied"); |
157 (trace_msg ctxt (fn () => "Metis: No first-order proof with the lemmas supplied"); |
169 if null fallback_modes then |
158 if null fallback_type_syss then |
170 () |
159 () |
171 else |
160 else |
172 raise METIS ("FOL_SOLVE", |
161 raise METIS ("FOL_SOLVE", |
173 "No first-order proof with the lemmas supplied"); |
162 "No first-order proof with the lemmas supplied"); |
174 []) |
163 []) |
175 end |
164 end |
176 handle METIS (loc, msg) => |
165 handle METIS (loc, msg) => |
177 case fallback_modes of |
166 case fallback_type_syss of |
178 [] => error ("Failed to replay Metis proof in Isabelle." ^ |
167 [] => error ("Failed to replay Metis proof in Isabelle." ^ |
179 (if Config.get ctxt verbose then "\n" ^ loc ^ ": " ^ msg |
168 (if Config.get ctxt verbose then "\n" ^ loc ^ ": " ^ msg |
180 else "")) |
169 else "")) |
181 | mode :: _ => |
170 | type_sys :: _ => |
182 let val (binding, arg) = method_call_for_mode mode in |
171 let val (binding, arg) = method_call_for_type_sys type_sys in |
183 (verbose_warning ctxt |
172 (verbose_warning ctxt |
184 ("Falling back on " ^ |
173 ("Falling back on " ^ |
185 quote (Binding.qualified_name_of binding ^ |
174 quote (Binding.qualified_name_of binding ^ |
186 (arg |> arg <> "" ? enclose " (" ")")) ^ "..."); |
175 (arg |> arg <> "" ? enclose " (" ")")) ^ "..."); |
187 FOL_SOLVE fallback_modes ctxt cls ths0) |
176 FOL_SOLVE fallback_type_syss ctxt cls ths0) |
188 end |
177 end |
189 |
178 |
190 val neg_clausify = |
179 val neg_clausify = |
191 single |
180 single |
192 #> Meson.make_clauses_unsorted |
181 #> Meson.make_clauses_unsorted |
202 all_tac) st0 |
191 all_tac) st0 |
203 |
192 |
204 val type_has_top_sort = |
193 val type_has_top_sort = |
205 exists_subtype (fn TFree (_, []) => true | TVar (_, []) => true | _ => false) |
194 exists_subtype (fn TFree (_, []) => true | TVar (_, []) => true | _ => false) |
206 |
195 |
207 fun generic_metis_tac modes ctxt ths i st0 = |
196 fun generic_metis_tac type_syss ctxt ths i st0 = |
208 let |
197 let |
209 val _ = trace_msg ctxt (fn () => |
198 val _ = trace_msg ctxt (fn () => |
210 "Metis called with theorems\n" ^ |
199 "Metis called with theorems\n" ^ |
211 cat_lines (map (Display.string_of_thm ctxt) ths)) |
200 cat_lines (map (Display.string_of_thm ctxt) ths)) |
212 fun tac clause = resolve_tac (FOL_SOLVE modes ctxt clause ths) 1 |
201 fun tac clause = resolve_tac (FOL_SOLVE type_syss ctxt clause ths) 1 |
213 in |
202 in |
214 if exists_type type_has_top_sort (prop_of st0) then |
203 if exists_type type_has_top_sort (prop_of st0) then |
215 (verbose_warning ctxt "Proof state contains the universal sort {}"; |
204 (verbose_warning ctxt "Proof state contains the universal sort {}"; |
216 Seq.empty) |
205 Seq.empty) |
217 else |
206 else |
218 Meson.MESON (preskolem_tac ctxt) (maps neg_clausify) tac ctxt i st0 |
207 Meson.MESON (preskolem_tac ctxt) (maps neg_clausify) tac ctxt i st0 |
219 end |
208 end |
220 |
209 |
221 val old_metis_modes = [HO, FT] |
210 val metis_default_type_syss = [default_unsound_type_sys, default_sound_type_sys] |
222 val old_metisF_modes = [FO, FT] |
211 val metisFT_type_syss = [default_sound_type_sys] |
223 val old_metisFT_modes = [FT] |
212 |
224 val new_metis_default_modes = |
213 fun metis_tac [] = generic_metis_tac metis_default_type_syss |
225 map Type_Sys [default_unsound_type_sys, default_sound_type_sys] |
214 | metis_tac type_syss = generic_metis_tac type_syss |
226 val new_metisFT_modes = [Type_Sys default_sound_type_sys] |
215 val metisFT_tac = generic_metis_tac metisFT_type_syss |
227 |
|
228 val old_metis_tac = generic_metis_tac old_metis_modes |
|
229 val old_metisF_tac = generic_metis_tac old_metisF_modes |
|
230 val old_metisFT_tac = generic_metis_tac old_metisFT_modes |
|
231 fun new_metis_tac [] = generic_metis_tac new_metis_default_modes |
|
232 | new_metis_tac type_syss = generic_metis_tac (map Type_Sys type_syss) |
|
233 val new_metisFT_tac = generic_metis_tac new_metisFT_modes |
|
234 |
216 |
235 (* Whenever "X" has schematic type variables, we treat "using X by metis" as |
217 (* Whenever "X" has schematic type variables, we treat "using X by metis" as |
236 "by (metis X)" to prevent "Subgoal.FOCUS" from freezing the type variables. |
218 "by (metis X)" to prevent "Subgoal.FOCUS" from freezing the type variables. |
237 We don't do it for nonschematic facts "X" because this breaks a few proofs |
219 We don't do it for nonschematic facts "X" because this breaks a few proofs |
238 (in the rare and subtle case where a proof relied on extensionality not being |
220 (in the rare and subtle case where a proof relied on extensionality not being |
239 applied) and brings few benefits. *) |
221 applied) and brings few benefits. *) |
240 val has_tvar = |
222 val has_tvar = |
241 exists_type (exists_subtype (fn TVar _ => true | _ => false)) o prop_of |
223 exists_type (exists_subtype (fn TVar _ => true | _ => false)) o prop_of |
242 |
224 |
243 fun method modes (type_sys, ths) ctxt facts = |
225 fun method type_syss (type_sys, ths) ctxt facts = |
244 let |
226 let |
245 val (schem_facts, nonschem_facts) = List.partition has_tvar facts |
227 val (schem_facts, nonschem_facts) = List.partition has_tvar facts |
246 val modes = type_sys |> Option.map (single o Type_Sys) |> the_default modes |
228 val type_syss = type_sys |> Option.map single |> the_default type_syss |
247 in |
229 in |
248 HEADGOAL (Method.insert_tac nonschem_facts THEN' |
230 HEADGOAL (Method.insert_tac nonschem_facts THEN' |
249 CHANGED_PROP o generic_metis_tac modes ctxt (schem_facts @ ths)) |
231 CHANGED_PROP |
250 end |
232 o generic_metis_tac type_syss ctxt (schem_facts @ ths)) |
251 |
233 end |
252 fun setup_method (modes as mode :: _) = |
234 |
253 (if modes = new_metis_default_modes then |
235 fun setup_method (type_syss as type_sys :: _) = |
|
236 (if type_syss = metis_default_type_syss then |
254 (Args.parens Parse.short_ident |
237 (Args.parens Parse.short_ident |
255 >> (fn s => if s = full_typesN then default_sound_type_sys else s)) |
238 >> (fn s => if s = full_typesN then default_sound_type_sys else s)) |
256 |> Scan.option |> Scan.lift |
239 |> Scan.option |> Scan.lift |
257 else |
240 else |
258 Scan.succeed NONE) |
241 Scan.succeed NONE) |
259 -- Attrib.thms >> (METHOD oo method modes) |
242 -- Attrib.thms >> (METHOD oo method type_syss) |
260 |> Method.setup (fst (method_call_for_mode mode)) |
243 |> Method.setup (fst (method_call_for_type_sys type_sys)) |
261 |
244 |
262 val setup = |
245 val setup = |
263 [(old_metis_modes, "Metis for FOL and HOL problems"), |
246 [(metis_default_type_syss, "Metis for FOL and HOL problems"), |
264 (old_metisF_modes, "Metis for FOL problems (legacy)"), |
247 (metisFT_type_syss, |
265 (old_metisFT_modes, |
248 "Metis for FOL/HOL problems with fully-typed translation")] |
266 "Metis for FOL/HOL problems with fully-typed translation"), |
|
267 (new_metis_default_modes, "Metis for FOL and HOL problems (experimental)"), |
|
268 (new_metisFT_modes, |
|
269 "Metis for FOL/HOL problems with fully-typed translation (experimental)")] |
|
270 |> fold (uncurry setup_method) |
249 |> fold (uncurry setup_method) |
271 |
250 |
272 end; |
251 end; |