src/HOL/Tools/Sledgehammer/sledgehammer_atp_translate.ML
changeset 40204 da97d75e20e6
parent 40145 04a05b2a7a36
child 41088 54eb8e7c7f9b
equal deleted inserted replaced
40203:aff7d1471b62 40204:da97d75e20e6
     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
    27 
    27 
    28 open ATP_Problem
    28 open ATP_Problem
    29 open Metis_Translate
    29 open Metis_Translate
    30 open Sledgehammer_Util
    30 open Sledgehammer_Util
    31 
    31 
    32 val axiom_prefix = "ax_"
    32 val fact_prefix = "fact_"
    33 val conjecture_prefix = "conj_"
    33 val conjecture_prefix = "conj_"
    34 val helper_prefix = "help_"
    34 val helper_prefix = "help_"
    35 val class_rel_clause_prefix = "clrel_";
    35 val class_rel_clause_prefix = "clrel_";
    36 val arity_clause_prefix = "arity_"
    36 val arity_clause_prefix = "arity_"
    37 val tfree_prefix = "tfree_"
    37 val tfree_prefix = "tfree_"
   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;