6 *) |
6 *) |
7 |
7 |
8 signature ATP_PROBLEM_IMPORT = |
8 signature ATP_PROBLEM_IMPORT = |
9 sig |
9 sig |
10 val read_tptp_file : theory -> (string * term -> 'a) -> string -> |
10 val read_tptp_file : theory -> (string * term -> 'a) -> string -> |
11 'a list * ('a list * 'a list) * Proof.context |
11 'a list * ('a list * 'a list) * local_theory |
12 val nitpick_tptp_file : theory -> int -> string -> unit |
12 val nitpick_tptp_file : theory -> int -> string -> unit |
13 val refute_tptp_file : theory -> int -> string -> unit |
13 val refute_tptp_file : theory -> int -> string -> unit |
14 val can_tac : Proof.context -> (Proof.context -> tactic) -> term -> bool |
14 val can_tac : Proof.context -> (Proof.context -> tactic) -> term -> bool |
15 val SOLVE_TIMEOUT : int -> string -> tactic -> tactic |
15 val SOLVE_TIMEOUT : int -> string -> tactic -> tactic |
16 val atp_tac : Proof.context -> int -> (string * string) list -> int -> term list -> string -> |
16 val atp_tac : local_theory -> int -> (string * string) list -> int -> term list -> string -> |
17 int -> tactic |
17 int -> tactic |
18 val smt_solver_tac : string -> Proof.context -> int -> tactic |
18 val smt_solver_tac : string -> local_theory -> int -> tactic |
19 val freeze_problem_consts : theory -> term -> term |
|
20 val make_conj : term list * term list -> term list -> term |
19 val make_conj : term list * term list -> term list -> term |
21 val sledgehammer_tptp_file : theory -> int -> string -> unit |
20 val sledgehammer_tptp_file : theory -> int -> string -> unit |
22 val isabelle_tptp_file : theory -> int -> string -> unit |
21 val isabelle_tptp_file : theory -> int -> string -> unit |
23 val isabelle_hot_tptp_file : theory -> int -> string -> unit |
22 val isabelle_hot_tptp_file : theory -> int -> string -> unit |
24 val translate_tptp_file : theory -> string -> string -> unit |
23 val translate_tptp_file : theory -> string -> string -> unit |
71 (is_Const t orelse is_Free t) andalso not (exists_subterm (curry (op =) t) u) |
70 (is_Const t orelse is_Free t) andalso not (exists_subterm (curry (op =) t) u) |
72 | is_legitimate_tptp_def _ = false |
71 | is_legitimate_tptp_def _ = false |
73 |
72 |
74 fun nitpick_tptp_file thy timeout file_name = |
73 fun nitpick_tptp_file thy timeout file_name = |
75 let |
74 let |
76 val (conjs, (defs, nondefs), ctxt) = read_tptp_file thy snd file_name |
75 val (conjs, (defs, nondefs), lthy) = read_tptp_file thy snd file_name |
77 val thy = Proof_Context.theory_of ctxt |
76 val thy = Proof_Context.theory_of lthy |
78 val (defs, pseudo_defs) = defs |
77 val (defs, pseudo_defs) = defs |
79 |> map (ATP_Util.abs_extensionalize_term ctxt #> aptrueprop (hol_open_form I)) |
78 |> map (ATP_Util.abs_extensionalize_term lthy #> aptrueprop (hol_open_form I)) |
80 |> List.partition (is_legitimate_tptp_def o perhaps (try HOLogic.dest_Trueprop) |
79 |> List.partition (is_legitimate_tptp_def o perhaps (try HOLogic.dest_Trueprop) |
81 o ATP_Util.unextensionalize_def) |
80 o ATP_Util.unextensionalize_def) |
82 val nondefs = pseudo_defs @ nondefs |
81 val nondefs = pseudo_defs @ nondefs |
83 val state = Proof.init ctxt |
82 val state = Proof.init lthy |
84 val params = |
83 val params = |
85 [("card", "1-100"), |
84 [("card", "1-100"), |
86 ("box", "false"), |
85 ("box", "false"), |
87 ("max_threads", "1"), |
86 ("max_threads", "1"), |
88 ("batch_size", "5"), |
87 ("batch_size", "5"), |
116 (if s = "genuine" then |
115 (if s = "genuine" then |
117 if falsify then "CounterSatisfiable" else "Satisfiable" |
116 if falsify then "CounterSatisfiable" else "Satisfiable" |
118 else |
117 else |
119 "GaveUp") |
118 "GaveUp") |
120 |> writeln |
119 |> writeln |
121 val (conjs, (defs, nondefs), ctxt) = read_tptp_file thy snd file_name |
120 val (conjs, (defs, nondefs), lthy) = read_tptp_file thy snd file_name |
122 val params = |
121 val params = |
123 [("maxtime", string_of_int timeout), |
122 [("maxtime", string_of_int timeout), |
124 ("maxvars", "100000")] |
123 ("maxvars", "100000")] |
125 in |
124 in |
126 Refute.refute_term ctxt params (defs @ nondefs) |
125 Refute.refute_term lthy params (defs @ nondefs) |
127 (case conjs of conj :: _ => conj | [] => \<^prop>\<open>True\<close>) |
126 (case conjs of conj :: _ => conj | [] => \<^prop>\<open>True\<close>) |
128 |> print_szs_of_outcome (not (null conjs)) |
127 |> print_szs_of_outcome (not (null conjs)) |
129 end |
128 end |
130 |
129 |
131 |
130 |
144 (case result of |
143 (case result of |
145 NONE => (writeln ("FAILURE: " ^ name); Seq.empty) |
144 NONE => (writeln ("FAILURE: " ^ name); Seq.empty) |
146 | SOME st' => (writeln ("SUCCESS: " ^ name); Seq.single st')) |
145 | SOME st' => (writeln ("SUCCESS: " ^ name); Seq.single st')) |
147 end |
146 end |
148 |
147 |
149 fun nitpick_finite_oracle_tac ctxt timeout i th = |
148 fun nitpick_finite_oracle_tac lthy timeout i th = |
150 let |
149 let |
151 fun is_safe (Type (\<^type_name>\<open>fun\<close>, Ts)) = forall is_safe Ts |
150 fun is_safe (Type (\<^type_name>\<open>fun\<close>, Ts)) = forall is_safe Ts |
152 | is_safe \<^typ>\<open>prop\<close> = true |
151 | is_safe \<^typ>\<open>prop\<close> = true |
153 | is_safe \<^typ>\<open>bool\<close> = true |
152 | is_safe \<^typ>\<open>bool\<close> = true |
154 | is_safe _ = false |
153 | is_safe _ = false |
157 in |
156 in |
158 if exists_type (not o is_safe) conj then |
157 if exists_type (not o is_safe) conj then |
159 Seq.empty |
158 Seq.empty |
160 else |
159 else |
161 let |
160 let |
162 val thy = Proof_Context.theory_of ctxt |
161 val thy = Proof_Context.theory_of lthy |
163 val state = Proof.init ctxt |
162 val state = Proof.init lthy |
164 val params = |
163 val params = |
165 [("box", "false"), |
164 [("box", "false"), |
166 ("max_threads", "1"), |
165 ("max_threads", "1"), |
167 ("verbose", "true"), |
166 ("verbose", "true"), |
168 ("debug", if debug then "true" else "false"), |
167 ("debug", if debug then "true" else "false"), |
175 val step = 0 |
174 val step = 0 |
176 val subst = [] |
175 val subst = [] |
177 val (outcome, _) = |
176 val (outcome, _) = |
178 Nitpick.pick_nits_in_term state params Nitpick.Normal i n step subst [] [] conj |
177 Nitpick.pick_nits_in_term state params Nitpick.Normal i n step subst [] [] conj |
179 in |
178 in |
180 if outcome = "none" then ALLGOALS (Skip_Proof.cheat_tac ctxt) th else Seq.empty |
179 if outcome = "none" then ALLGOALS (Skip_Proof.cheat_tac lthy) th else Seq.empty |
181 end |
180 end |
182 end |
181 end |
183 |
182 |
184 fun atp_tac ctxt completeness override_params timeout assms prover = |
183 fun atp_tac lthy completeness override_params timeout assms prover = |
185 let |
184 let |
186 val thy = Proof_Context.theory_of ctxt |
185 val thy = Proof_Context.theory_of lthy |
187 val assm_ths0 = map (Skip_Proof.make_thm thy) assms |
186 val assm_ths0 = map (Skip_Proof.make_thm thy) assms |
188 val ((assm_name, _), ctxt) = ctxt |
187 val ((assm_name, _), lthy) = lthy |
189 |> Config.put Sledgehammer_Prover_ATP.atp_completish (if completeness > 0 then 3 else 0) |
188 |> Config.put Sledgehammer_Prover_ATP.atp_completish (if completeness > 0 then 3 else 0) |
190 |> Local_Theory.note ((\<^binding>\<open>thms\<close>, []), assm_ths0) |
189 |> Local_Theory.note ((\<^binding>\<open>thms\<close>, []), assm_ths0) |
191 |
190 |
192 fun ref_of th = (Facts.named (Thm.derivation_name th), []) |
191 fun ref_of th = (Facts.named (Thm.derivation_name th), []) |
193 val ref_of_assms = (Facts.named assm_name, []) |
192 val ref_of_assms = (Facts.named assm_name, []) |
194 in |
193 in |
195 Sledgehammer_Tactics.sledgehammer_as_oracle_tac ctxt |
194 Sledgehammer_Tactics.sledgehammer_as_oracle_tac lthy |
196 ([("debug", if debug then "true" else "false"), |
195 ([("debug", if debug then "true" else "false"), |
197 ("overlord", if overlord then "true" else "false"), |
196 ("overlord", if overlord then "true" else "false"), |
198 ("provers", prover), |
197 ("provers", prover), |
199 ("timeout", string_of_int timeout)] @ |
198 ("timeout", string_of_int timeout)] @ |
200 (if completeness > 0 then |
199 (if completeness > 0 then |
203 []) @ |
202 []) @ |
204 override_params) |
203 override_params) |
205 {add = ref_of_assms :: map ref_of [ext, @{thm someI}], del = [], only = true} [] |
204 {add = ref_of_assms :: map ref_of [ext, @{thm someI}], del = [], only = true} [] |
206 end |
205 end |
207 |
206 |
208 fun sledgehammer_tac demo ctxt timeout assms i = |
207 fun sledgehammer_tac demo lthy timeout assms i = |
209 let |
208 let |
210 val frac = if demo then 16 else 12 |
209 val frac = if demo then 16 else 12 |
211 fun slice mult completeness prover = |
210 fun slice mult completeness prover = |
212 SOLVE_TIMEOUT (mult * timeout div frac) |
211 SOLVE_TIMEOUT (mult * timeout div frac) |
213 (prover ^ (if completeness > 0 then "(" ^ string_of_int completeness ^ ")" else "")) |
212 (prover ^ (if completeness > 0 then "(" ^ string_of_int completeness ^ ")" else "")) |
214 (atp_tac ctxt completeness [] (mult * timeout div frac) assms prover i) |
213 (atp_tac lthy completeness [] (mult * timeout div frac) assms prover i) |
215 in |
214 in |
216 slice 2 0 ATP_Proof.spassN |
215 slice 2 0 ATP_Proof.spassN |
217 ORELSE slice 2 0 ATP_Proof.vampireN |
216 ORELSE slice 2 0 ATP_Proof.vampireN |
218 ORELSE slice 2 0 ATP_Proof.eN |
217 ORELSE slice 2 0 ATP_Proof.eN |
219 ORELSE slice 2 0 ATP_Proof.z3_tptpN |
218 ORELSE slice 2 0 ATP_Proof.z3_tptpN |
227 ORELSE slice 2 0 ATP_Proof.leo2N |
226 ORELSE slice 2 0 ATP_Proof.leo2N |
228 else |
227 else |
229 no_tac) |
228 no_tac) |
230 end |
229 end |
231 |
230 |
232 fun smt_solver_tac solver ctxt = |
231 fun smt_solver_tac solver lthy = |
233 let |
232 let |
234 val ctxt = ctxt |> Context.proof_map (SMT_Config.select_solver solver) |
233 val lthy = lthy |> Context.proof_map (SMT_Config.select_solver solver) |
235 in SMT_Solver.smt_tac ctxt [] end |
234 in SMT_Solver.smt_tac lthy [] end |
236 |
235 |
237 fun auto_etc_tac ctxt timeout assms i = |
236 fun auto_etc_tac lthy timeout assms i = |
238 SOLVE_TIMEOUT (timeout div 20) "nitpick" (nitpick_finite_oracle_tac ctxt (timeout div 20) i) |
237 SOLVE_TIMEOUT (timeout div 20) "nitpick" (nitpick_finite_oracle_tac lthy (timeout div 20) i) |
239 ORELSE SOLVE_TIMEOUT (timeout div 10) "simp" (asm_full_simp_tac ctxt i) |
238 ORELSE SOLVE_TIMEOUT (timeout div 10) "simp" (asm_full_simp_tac lthy i) |
240 ORELSE SOLVE_TIMEOUT (timeout div 10) "blast" (blast_tac ctxt i) |
239 ORELSE SOLVE_TIMEOUT (timeout div 10) "blast" (blast_tac lthy i) |
241 ORELSE SOLVE_TIMEOUT (timeout div 5) "auto+spass" |
240 ORELSE SOLVE_TIMEOUT (timeout div 5) "auto+spass" |
242 (auto_tac ctxt THEN ALLGOALS (atp_tac ctxt 0 [] (timeout div 5) assms ATP_Proof.spassN)) |
241 (auto_tac lthy THEN ALLGOALS (atp_tac lthy 0 [] (timeout div 5) assms ATP_Proof.spassN)) |
243 ORELSE SOLVE_TIMEOUT (timeout div 10) "fast" (fast_tac ctxt i) |
242 ORELSE SOLVE_TIMEOUT (timeout div 10) "fast" (fast_tac lthy i) |
244 ORELSE SOLVE_TIMEOUT (timeout div 20) "z3" (smt_solver_tac "z3" ctxt i) |
243 ORELSE SOLVE_TIMEOUT (timeout div 20) "z3" (smt_solver_tac "z3" lthy i) |
245 ORELSE SOLVE_TIMEOUT (timeout div 20) "cvc4" (smt_solver_tac "cvc4" ctxt i) |
244 ORELSE SOLVE_TIMEOUT (timeout div 20) "cvc4" (smt_solver_tac "cvc4" lthy i) |
246 ORELSE SOLVE_TIMEOUT (timeout div 20) "best" (best_tac ctxt i) |
245 ORELSE SOLVE_TIMEOUT (timeout div 20) "best" (best_tac lthy i) |
247 ORELSE SOLVE_TIMEOUT (timeout div 10) "force" (force_tac ctxt i) |
246 ORELSE SOLVE_TIMEOUT (timeout div 10) "force" (force_tac lthy i) |
248 ORELSE SOLVE_TIMEOUT (timeout div 10) "meson" (Meson.meson_tac ctxt [] i) |
247 ORELSE SOLVE_TIMEOUT (timeout div 10) "meson" (Meson.meson_tac lthy [] i) |
249 ORELSE SOLVE_TIMEOUT (timeout div 10) "fastforce" (fast_force_tac ctxt i) |
248 ORELSE SOLVE_TIMEOUT (timeout div 10) "fastforce" (fast_force_tac lthy i) |
250 |
249 |
251 fun problem_const_prefix thy = Context.theory_name thy ^ Long_Name.separator |
250 fun problem_const_prefix thy = Context.theory_name thy ^ Long_Name.separator |
252 |
|
253 (* Isabelle's standard automatic tactics ("auto", etc.) are more eager to |
|
254 unfold "definitions" of free variables than of constants (cf. PUZ107^5). *) |
|
255 fun freeze_problem_consts thy = |
|
256 let val is_problem_const = String.isPrefix (problem_const_prefix thy) in |
|
257 map_aterms |
|
258 (fn t as Const (s, T) => if is_problem_const s then Free (Long_Name.base_name s, T) else t |
|
259 | t => t) |
|
260 end |
|
261 |
251 |
262 fun make_conj (defs, nondefs) conjs = |
252 fun make_conj (defs, nondefs) conjs = |
263 Logic.list_implies (rev defs @ rev nondefs, case conjs of conj :: _ => conj | [] => \<^prop>\<open>False\<close>) |
253 Logic.list_implies (rev defs @ rev nondefs, case conjs of conj :: _ => conj | [] => \<^prop>\<open>False\<close>) |
264 |
254 |
265 fun print_szs_of_success conjs success = |
255 fun print_szs_of_success conjs success = |
269 else |
259 else |
270 "GaveUp")) |
260 "GaveUp")) |
271 |
261 |
272 fun sledgehammer_tptp_file thy timeout file_name = |
262 fun sledgehammer_tptp_file thy timeout file_name = |
273 let |
263 let |
274 val (conjs, assms, ctxt) = read_tptp_file thy (freeze_problem_consts thy o snd) file_name |
264 val (conjs, assms, lthy) = read_tptp_file thy snd file_name |
275 val conj = make_conj ([], []) conjs |
265 val conj = make_conj ([], []) conjs |
276 val assms = op @ assms |
266 val assms = op @ assms |
277 in |
267 in |
278 can_tac ctxt (fn ctxt => sledgehammer_tac true ctxt timeout assms 1) conj |
268 can_tac lthy (fn lthy => sledgehammer_tac true lthy timeout assms 1) conj |
279 |> print_szs_of_success conjs |
269 |> print_szs_of_success conjs |
280 end |
270 end |
281 |
271 |
282 fun generic_isabelle_tptp_file demo thy timeout file_name = |
272 fun generic_isabelle_tptp_file demo thy timeout file_name = |
283 let |
273 let |
284 val (conjs, assms, ctxt) = read_tptp_file thy (freeze_problem_consts thy o snd) file_name |
274 val (conjs, assms, lthy) = read_tptp_file thy snd file_name |
285 val conj = make_conj ([], []) conjs |
275 val conj = make_conj ([], []) conjs |
286 val full_conj = make_conj assms conjs |
276 val full_conj = make_conj assms conjs |
287 val assms = op @ assms |
277 val assms = op @ assms |
288 val (last_hope_atp, last_hope_completeness) = |
278 val (last_hope_atp, last_hope_completeness) = |
289 if demo then (ATP_Proof.satallaxN, 0) else (ATP_Proof.vampireN, 2) |
279 if demo then (ATP_Proof.satallaxN, 0) else (ATP_Proof.vampireN, 2) |
290 in |
280 in |
291 (can_tac ctxt (fn ctxt => auto_etc_tac ctxt (timeout div 2) assms 1) full_conj orelse |
281 (can_tac lthy (fn lthy => auto_etc_tac lthy (timeout div 2) assms 1) full_conj orelse |
292 can_tac ctxt (fn ctxt => sledgehammer_tac demo ctxt (timeout div 2) assms 1) conj orelse |
282 can_tac lthy (fn lthy => sledgehammer_tac demo lthy (timeout div 2) assms 1) conj orelse |
293 can_tac ctxt (fn ctxt => SOLVE_TIMEOUT timeout (last_hope_atp ^ "(*)") |
283 can_tac lthy (fn lthy => SOLVE_TIMEOUT timeout (last_hope_atp ^ "(*)") |
294 (atp_tac ctxt last_hope_completeness [] timeout assms last_hope_atp 1)) full_conj) |
284 (atp_tac lthy last_hope_completeness [] timeout assms last_hope_atp 1)) full_conj) |
295 |> print_szs_of_success conjs |
285 |> print_szs_of_success conjs |
296 end |
286 end |
297 |
287 |
298 val isabelle_tptp_file = generic_isabelle_tptp_file false |
288 val isabelle_tptp_file = generic_isabelle_tptp_file false |
299 val isabelle_hot_tptp_file = generic_isabelle_tptp_file true |
289 val isabelle_hot_tptp_file = generic_isabelle_tptp_file true |
301 |
291 |
302 (** Translator between TPTP(-like) file formats **) |
292 (** Translator between TPTP(-like) file formats **) |
303 |
293 |
304 fun translate_tptp_file thy format_str file_name = |
294 fun translate_tptp_file thy format_str file_name = |
305 let |
295 let |
306 val (conjs, (defs, nondefs), ctxt) = read_tptp_file thy I file_name |
296 val (conjs, (defs, nondefs), lthy) = read_tptp_file thy I file_name |
307 val conj = make_conj ([], []) (map snd conjs) |
297 val conj = make_conj ([], []) (map snd conjs) |
308 |
298 |
309 val (format, type_enc, lam_trans) = |
299 val (format, type_enc, lam_trans) = |
310 (case format_str of |
300 (case format_str of |
311 "FOF" => (FOF, "mono_guards??", liftingN) |
301 "FOF" => (FOF, "mono_guards??", liftingN) |
320 val presimp = true |
310 val presimp = true |
321 val facts = |
311 val facts = |
322 map (apfst (rpair (Global, Non_Rec_Def))) defs @ |
312 map (apfst (rpair (Global, Non_Rec_Def))) defs @ |
323 map (apfst (rpair (Global, General))) nondefs |
313 map (apfst (rpair (Global, General))) nondefs |
324 val (atp_problem, _, _, _) = |
314 val (atp_problem, _, _, _) = |
325 generate_atp_problem ctxt generate_info format Hypothesis (type_enc_of_string Strict type_enc) |
315 generate_atp_problem lthy generate_info format Hypothesis (type_enc_of_string Strict type_enc) |
326 Translator |
316 Translator |
327 lam_trans uncurried_aliases readable_names presimp [] conj facts |
317 lam_trans uncurried_aliases readable_names presimp [] conj facts |
328 |
318 |
329 val ord = effective_term_order ctxt spassN |
319 val ord = effective_term_order lthy spassN |
330 val ord_info = K [] |
320 val ord_info = K [] |
331 val lines = lines_of_atp_problem format ord ord_info atp_problem |
321 val lines = lines_of_atp_problem format ord ord_info atp_problem |
332 in |
322 in |
333 List.app Output.physical_stdout lines |
323 List.app Output.physical_stdout lines |
334 end |
324 end |