9 signature SLEDGEHAMMER_ATP_TRANSLATE = |
9 signature SLEDGEHAMMER_ATP_TRANSLATE = |
10 sig |
10 sig |
11 type 'a problem = 'a ATP_Problem.problem |
11 type 'a problem = 'a ATP_Problem.problem |
12 type translated_formula |
12 type translated_formula |
13 |
13 |
14 val axiom_prefix : string |
14 val fact_prefix : string |
15 val conjecture_prefix : string |
15 val conjecture_prefix : string |
16 val translate_axiom : |
16 val translate_fact : |
17 Proof.context -> (string * 'a) * thm |
17 Proof.context -> (string * 'a) * thm |
18 -> term * ((string * 'a) * translated_formula) option |
18 -> term * ((string * 'a) * translated_formula) option |
19 val prepare_atp_problem : |
19 val prepare_atp_problem : |
20 Proof.context -> bool -> bool -> bool -> bool -> term list -> term |
20 Proof.context -> bool -> bool -> bool -> bool -> term list -> term |
21 -> (term * ((string * 'a) * translated_formula) option) list |
21 -> (term * ((string * 'a) * translated_formula) option) list |
172 | aux (Const (@{const_name "=="}, Type (_, [T, _])) $ t1 $ t2) = |
172 | aux (Const (@{const_name "=="}, Type (_, [T, _])) $ t1 $ t2) = |
173 HOLogic.eq_const T $ t1 $ t2 |
173 HOLogic.eq_const T $ t1 $ t2 |
174 | aux _ = raise Fail "aux" |
174 | aux _ = raise Fail "aux" |
175 in perhaps (try aux) end |
175 in perhaps (try aux) end |
176 |
176 |
177 (* making axiom and conjecture formulas *) |
177 (* making fact and conjecture formulas *) |
178 fun make_formula ctxt presimp name kind t = |
178 fun make_formula ctxt presimp name kind t = |
179 let |
179 let |
180 val thy = ProofContext.theory_of ctxt |
180 val thy = ProofContext.theory_of ctxt |
181 val t = t |> Envir.beta_eta_contract |
181 val t = t |> Envir.beta_eta_contract |
182 |> transform_elim_term |
182 |> transform_elim_term |
192 in |
192 in |
193 {name = name, combformula = combformula, kind = kind, |
193 {name = name, combformula = combformula, kind = kind, |
194 ctypes_sorts = ctypes_sorts} |
194 ctypes_sorts = ctypes_sorts} |
195 end |
195 end |
196 |
196 |
197 fun make_axiom ctxt presimp ((name, loc), th) = |
197 fun make_fact ctxt presimp ((name, loc), th) = |
198 case make_formula ctxt presimp name Axiom (prop_of th) of |
198 case make_formula ctxt presimp name Axiom (prop_of th) of |
199 {combformula = AAtom (CombConst (("c_True", _), _, _)), ...} => NONE |
199 {combformula = AAtom (CombConst (("c_True", _), _, _)), ...} => NONE |
200 | formula => SOME ((name, loc), formula) |
200 | formula => SOME ((name, loc), formula) |
201 fun make_conjecture ctxt ts = |
201 fun make_conjecture ctxt ts = |
202 let val last = length ts - 1 in |
202 let val last = length ts - 1 in |
230 |
230 |
231 val init_counters = |
231 val init_counters = |
232 [optional_helpers, optional_typed_helpers] |> maps (maps fst) |
232 [optional_helpers, optional_typed_helpers] |> maps (maps fst) |
233 |> sort_distinct string_ord |> map (rpair 0) |> Symtab.make |
233 |> sort_distinct string_ord |> map (rpair 0) |> Symtab.make |
234 |
234 |
235 fun get_helper_facts ctxt is_FO full_types conjectures axioms = |
235 fun get_helper_facts ctxt is_FO full_types conjectures facts = |
236 let |
236 let |
237 val ct = |
237 val ct = |
238 fold (fold count_translated_formula) [conjectures, axioms] init_counters |
238 fold (fold count_translated_formula) [conjectures, facts] init_counters |
239 fun is_needed c = the (Symtab.lookup ct c) > 0 |
239 fun is_needed c = the (Symtab.lookup ct c) > 0 |
240 fun baptize th = ((Thm.get_name_hint th, false), th) |
240 fun baptize th = ((Thm.get_name_hint th, false), th) |
241 in |
241 in |
242 (optional_helpers |
242 (optional_helpers |
243 |> full_types ? append optional_typed_helpers |
243 |> full_types ? append optional_typed_helpers |
244 |> maps (fn (ss, ths) => |
244 |> maps (fn (ss, ths) => |
245 if exists is_needed ss then map baptize ths else [])) @ |
245 if exists is_needed ss then map baptize ths else [])) @ |
246 (if is_FO then [] else map baptize mandatory_helpers) |
246 (if is_FO then [] else map baptize mandatory_helpers) |
247 |> map_filter (Option.map snd o make_axiom ctxt false) |
247 |> map_filter (Option.map snd o make_fact ctxt false) |
248 end |
248 end |
249 |
249 |
250 fun translate_axiom ctxt (ax as (_, th)) = (prop_of th, make_axiom ctxt true ax) |
250 fun translate_fact ctxt (ax as (_, th)) = (prop_of th, make_fact ctxt true ax) |
251 |
251 |
252 fun translate_formulas ctxt full_types hyp_ts concl_t axioms = |
252 fun translate_formulas ctxt full_types hyp_ts concl_t facts = |
253 let |
253 let |
254 val thy = ProofContext.theory_of ctxt |
254 val thy = ProofContext.theory_of ctxt |
255 val (axiom_ts, translated_axioms) = ListPair.unzip axioms |
255 val (fact_ts, translated_facts) = ListPair.unzip facts |
256 (* Remove existing axioms from the conjecture, as this can dramatically |
256 (* Remove existing facts from the conjecture, as this can dramatically |
257 boost an ATP's performance (for some reason). *) |
257 boost an ATP's performance (for some reason). *) |
258 val hyp_ts = hyp_ts |> filter_out (member (op aconv) axiom_ts) |
258 val hyp_ts = hyp_ts |> filter_out (member (op aconv) fact_ts) |
259 val goal_t = Logic.list_implies (hyp_ts, concl_t) |
259 val goal_t = Logic.list_implies (hyp_ts, concl_t) |
260 val is_FO = Meson.is_fol_term thy goal_t |
260 val is_FO = Meson.is_fol_term thy goal_t |
261 val subs = tfree_classes_of_terms [goal_t] |
261 val subs = tfree_classes_of_terms [goal_t] |
262 val supers = tvar_classes_of_terms axiom_ts |
262 val supers = tvar_classes_of_terms fact_ts |
263 val tycons = type_consts_of_terms thy (goal_t :: axiom_ts) |
263 val tycons = type_consts_of_terms thy (goal_t :: fact_ts) |
264 (* TFrees in the conjecture; TVars in the axioms *) |
264 (* TFrees in the conjecture; TVars in the facts *) |
265 val conjectures = make_conjecture ctxt (hyp_ts @ [concl_t]) |
265 val conjectures = make_conjecture ctxt (hyp_ts @ [concl_t]) |
266 val (axiom_names, axioms) = ListPair.unzip (map_filter I translated_axioms) |
266 val (fact_names, facts) = ListPair.unzip (map_filter I translated_facts) |
267 val helper_facts = get_helper_facts ctxt is_FO full_types conjectures axioms |
267 val helper_facts = get_helper_facts ctxt is_FO full_types conjectures facts |
268 val (supers', arity_clauses) = make_arity_clauses thy tycons supers |
268 val (supers', arity_clauses) = make_arity_clauses thy tycons supers |
269 val class_rel_clauses = make_class_rel_clauses thy subs supers' |
269 val class_rel_clauses = make_class_rel_clauses thy subs supers' |
270 in |
270 in |
271 (axiom_names |> map single |> Vector.fromList, |
271 (fact_names |> map single |> Vector.fromList, |
272 (conjectures, axioms, helper_facts, class_rel_clauses, arity_clauses)) |
272 (conjectures, facts, helper_facts, class_rel_clauses, arity_clauses)) |
273 end |
273 end |
274 |
274 |
275 fun wrap_type ty t = ATerm ((type_wrapper_name, type_wrapper_name), [ty, t]) |
275 fun wrap_type ty t = ATerm ((type_wrapper_name, type_wrapper_name), [ty, t]) |
276 |
276 |
277 fun fo_term_for_combtyp (CombTVar name) = ATerm (name, []) |
277 fun fo_term_for_combtyp (CombTVar name) = ATerm (name, []) |
320 fun aux (AQuant (q, xs, phi)) = AQuant (q, xs, aux phi) |
320 fun aux (AQuant (q, xs, phi)) = AQuant (q, xs, aux phi) |
321 | aux (AConn (c, phis)) = AConn (c, map aux phis) |
321 | aux (AConn (c, phis)) = AConn (c, map aux phis) |
322 | aux (AAtom tm) = AAtom (fo_term_for_combterm full_types tm) |
322 | aux (AAtom tm) = AAtom (fo_term_for_combterm full_types tm) |
323 in aux end |
323 in aux end |
324 |
324 |
325 fun formula_for_axiom full_types |
325 fun formula_for_fact full_types |
326 ({combformula, ctypes_sorts, ...} : translated_formula) = |
326 ({combformula, ctypes_sorts, ...} : translated_formula) = |
327 mk_ahorn (map (formula_for_fo_literal o fo_literal_for_type_literal) |
327 mk_ahorn (map (formula_for_fo_literal o fo_literal_for_type_literal) |
328 (type_literals_for_types ctypes_sorts)) |
328 (type_literals_for_types ctypes_sorts)) |
329 (formula_for_combformula full_types combformula) |
329 (formula_for_combformula full_types combformula) |
330 |
330 |
331 fun problem_line_for_fact prefix full_types (formula as {name, kind, ...}) = |
331 fun problem_line_for_fact prefix full_types (formula as {name, kind, ...}) = |
332 Fof (prefix ^ ascii_of name, kind, formula_for_axiom full_types formula) |
332 Fof (prefix ^ ascii_of name, kind, formula_for_fact full_types formula) |
333 |
333 |
334 fun problem_line_for_class_rel_clause (ClassRelClause {name, subclass, |
334 fun problem_line_for_class_rel_clause (ClassRelClause {name, subclass, |
335 superclass, ...}) = |
335 superclass, ...}) = |
336 let val ty_arg = ATerm (("T", "T"), []) in |
336 let val ty_arg = ATerm (("T", "T"), []) in |
337 Fof (class_rel_clause_prefix ^ ascii_of name, Axiom, |
337 Fof (class_rel_clause_prefix ^ ascii_of name, Axiom, |
495 fun repair_problem thy explicit_forall full_types explicit_apply problem = |
495 fun repair_problem thy explicit_forall full_types explicit_apply problem = |
496 repair_problem_with_const_table thy explicit_forall full_types |
496 repair_problem_with_const_table thy explicit_forall full_types |
497 (const_table_for_problem explicit_apply problem) problem |
497 (const_table_for_problem explicit_apply problem) problem |
498 |
498 |
499 fun prepare_atp_problem ctxt readable_names explicit_forall full_types |
499 fun prepare_atp_problem ctxt readable_names explicit_forall full_types |
500 explicit_apply hyp_ts concl_t axioms = |
500 explicit_apply hyp_ts concl_t facts = |
501 let |
501 let |
502 val thy = ProofContext.theory_of ctxt |
502 val thy = ProofContext.theory_of ctxt |
503 val (axiom_names, (conjectures, axioms, helper_facts, class_rel_clauses, |
503 val (fact_names, (conjectures, facts, helper_facts, class_rel_clauses, |
504 arity_clauses)) = |
504 arity_clauses)) = |
505 translate_formulas ctxt full_types hyp_ts concl_t axioms |
505 translate_formulas ctxt full_types hyp_ts concl_t facts |
506 val axiom_lines = map (problem_line_for_fact axiom_prefix full_types) axioms |
506 val fact_lines = map (problem_line_for_fact fact_prefix full_types) facts |
507 val helper_lines = |
507 val helper_lines = |
508 map (problem_line_for_fact helper_prefix full_types) helper_facts |
508 map (problem_line_for_fact helper_prefix full_types) helper_facts |
509 val conjecture_lines = |
509 val conjecture_lines = |
510 map (problem_line_for_conjecture full_types) conjectures |
510 map (problem_line_for_conjecture full_types) conjectures |
511 val tfree_lines = problem_lines_for_free_types conjectures |
511 val tfree_lines = problem_lines_for_free_types conjectures |
513 map problem_line_for_class_rel_clause class_rel_clauses |
513 map problem_line_for_class_rel_clause class_rel_clauses |
514 val arity_lines = map problem_line_for_arity_clause arity_clauses |
514 val arity_lines = map problem_line_for_arity_clause arity_clauses |
515 (* Reordering these might or might not confuse the proof reconstruction |
515 (* Reordering these might or might not confuse the proof reconstruction |
516 code or the SPASS Flotter hack. *) |
516 code or the SPASS Flotter hack. *) |
517 val problem = |
517 val problem = |
518 [("Relevant facts", axiom_lines), |
518 [("Relevant facts", fact_lines), |
519 ("Class relationships", class_rel_lines), |
519 ("Class relationships", class_rel_lines), |
520 ("Arity declarations", arity_lines), |
520 ("Arity declarations", arity_lines), |
521 ("Helper facts", helper_lines), |
521 ("Helper facts", helper_lines), |
522 ("Conjectures", conjecture_lines), |
522 ("Conjectures", conjecture_lines), |
523 ("Type variables", tfree_lines)] |
523 ("Type variables", tfree_lines)] |
524 |> repair_problem thy explicit_forall full_types explicit_apply |
524 |> repair_problem thy explicit_forall full_types explicit_apply |
525 val (problem, pool) = nice_atp_problem readable_names problem |
525 val (problem, pool) = nice_atp_problem readable_names problem |
526 val conjecture_offset = |
526 val conjecture_offset = |
527 length axiom_lines + length class_rel_lines + length arity_lines |
527 length fact_lines + length class_rel_lines + length arity_lines |
528 + length helper_lines |
528 + length helper_lines |
529 in |
529 in |
530 (problem, |
530 (problem, |
531 case pool of SOME the_pool => snd the_pool | NONE => Symtab.empty, |
531 case pool of SOME the_pool => snd the_pool | NONE => Symtab.empty, |
532 conjecture_offset, axiom_names) |
532 conjecture_offset, fact_names) |
533 end |
533 end |
534 |
534 |
535 end; |
535 end; |