src/HOL/Tools/Sledgehammer/sledgehammer_atp_translate.ML
changeset 41134 de9e0adc21da
parent 41091 0afdf5cde874
child 41136 30bedf58b177
equal deleted inserted replaced
41133:6c7c135a3270 41134:de9e0adc21da
     8 
     8 
     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 
       
    14   datatype type_system =
       
    15     Tags of bool |
       
    16     Preds of bool |
       
    17     Const_Args |
       
    18     Overload_Args |
       
    19     No_Types
    13 
    20 
    14   val fact_prefix : string
    21   val fact_prefix : string
    15   val conjecture_prefix : string
    22   val conjecture_prefix : string
    16   val translate_atp_fact :
    23   val translate_atp_fact :
    17     Proof.context -> (string * 'a) * thm
    24     Proof.context -> (string * 'a) * thm
    18     -> translated_formula option * ((string * 'a) * thm)
    25     -> translated_formula option * ((string * 'a) * thm)
    19   val prepare_atp_problem :
    26   val prepare_atp_problem :
    20     Proof.context -> bool -> bool -> bool -> bool -> term list -> term
    27     Proof.context -> bool -> bool -> type_system -> bool -> term list -> term
    21     -> (translated_formula option * ((string * 'a) * thm)) list
    28     -> (translated_formula option * ((string * 'a) * thm)) list
    22     -> string problem * string Symtab.table * int * (string * 'a) list vector
    29     -> string problem * string Symtab.table * int * (string * 'a) list vector
    23 end;
    30 end;
    24 
    31 
    25 structure Sledgehammer_ATP_Translate : SLEDGEHAMMER_ATP_TRANSLATE =
    32 structure Sledgehammer_ATP_Translate : SLEDGEHAMMER_ATP_TRANSLATE =
    42 type translated_formula =
    49 type translated_formula =
    43   {name: string,
    50   {name: string,
    44    kind: kind,
    51    kind: kind,
    45    combformula: (name, combterm) formula,
    52    combformula: (name, combterm) formula,
    46    ctypes_sorts: typ list}
    53    ctypes_sorts: typ list}
       
    54 
       
    55 datatype type_system =
       
    56   Tags of bool |
       
    57   Preds of bool |
       
    58   Const_Args |
       
    59   Overload_Args |
       
    60   No_Types
       
    61 
       
    62 fun is_fully_typed (Tags full_types) = full_types
       
    63   | is_fully_typed (Preds full_types) = full_types
       
    64   | is_fully_typed _ = false
    47 
    65 
    48 fun mk_anot phi = AConn (ANot, [phi])
    66 fun mk_anot phi = AConn (ANot, [phi])
    49 fun mk_aconn c phi1 phi2 = AConn (c, [phi1, phi2])
    67 fun mk_aconn c phi1 phi2 = AConn (c, [phi1, phi2])
    50 fun mk_ahorn [] phi = phi
    68 fun mk_ahorn [] phi = phi
    51   | mk_ahorn (phi :: phis) psi =
    69   | mk_ahorn (phi :: phis) psi =
   221   [(["c_COMBI"], @{thms Meson.COMBI_def}),
   239   [(["c_COMBI"], @{thms Meson.COMBI_def}),
   222    (["c_COMBK"], @{thms Meson.COMBK_def}),
   240    (["c_COMBK"], @{thms Meson.COMBK_def}),
   223    (["c_COMBB"], @{thms Meson.COMBB_def}),
   241    (["c_COMBB"], @{thms Meson.COMBB_def}),
   224    (["c_COMBC"], @{thms Meson.COMBC_def}),
   242    (["c_COMBC"], @{thms Meson.COMBC_def}),
   225    (["c_COMBS"], @{thms Meson.COMBS_def})]
   243    (["c_COMBS"], @{thms Meson.COMBS_def})]
   226 val optional_typed_helpers =
   244 val optional_fully_typed_helpers =
   227   [(["c_True", "c_False", "c_If"], @{thms True_or_False}),
   245   [(["c_True", "c_False", "c_If"], @{thms True_or_False}),
   228    (["c_If"], @{thms if_True if_False})]
   246    (["c_If"], @{thms if_True if_False})]
   229 val mandatory_helpers = @{thms Metis.fequal_def}
   247 val mandatory_helpers = @{thms Metis.fequal_def}
   230 
   248 
   231 val init_counters =
   249 val init_counters =
   232   [optional_helpers, optional_typed_helpers] |> maps (maps fst)
   250   [optional_helpers, optional_fully_typed_helpers] |> maps (maps fst)
   233   |> sort_distinct string_ord |> map (rpair 0) |> Symtab.make
   251   |> sort_distinct string_ord |> map (rpair 0) |> Symtab.make
   234 
   252 
   235 fun get_helper_facts ctxt is_FO full_types conjectures facts =
   253 fun get_helper_facts ctxt is_FO type_sys conjectures facts =
   236   let
   254   let
   237     val ct =
   255     val ct =
   238       fold (fold count_translated_formula) [conjectures, facts] init_counters
   256       fold (fold count_translated_formula) [conjectures, facts] init_counters
   239     fun is_needed c = the (Symtab.lookup ct c) > 0
   257     fun is_needed c = the (Symtab.lookup ct c) > 0
   240     fun baptize th = ((Thm.get_name_hint th, false), th)
   258     fun baptize th = ((Thm.get_name_hint th, false), th)
   241   in
   259   in
   242     (optional_helpers
   260     (optional_helpers
   243      |> full_types ? append optional_typed_helpers
   261      |> is_fully_typed type_sys ? append optional_fully_typed_helpers
   244      |> maps (fn (ss, ths) =>
   262      |> maps (fn (ss, ths) =>
   245                  if exists is_needed ss then map baptize ths else [])) @
   263                  if exists is_needed ss then map baptize ths else [])) @
   246     (if is_FO then [] else map baptize mandatory_helpers)
   264     (if is_FO then [] else map baptize mandatory_helpers)
   247     |> map_filter (make_fact ctxt false)
   265     |> map_filter (make_fact ctxt false)
   248   end
   266   end
   249 
   267 
   250 fun translate_atp_fact ctxt = `(make_fact ctxt true)
   268 fun translate_atp_fact ctxt = `(make_fact ctxt true)
   251 
   269 
   252 fun translate_formulas ctxt full_types hyp_ts concl_t rich_facts =
   270 fun translate_formulas ctxt type_sys hyp_ts concl_t rich_facts =
   253   let
   271   let
   254     val thy = ProofContext.theory_of ctxt
   272     val thy = ProofContext.theory_of ctxt
   255     val fact_ts = map (prop_of o snd o snd) rich_facts
   273     val fact_ts = map (prop_of o snd o snd) rich_facts
   256     val (facts, fact_names) =
   274     val (facts, fact_names) =
   257       rich_facts
   275       rich_facts
   266     val subs = tfree_classes_of_terms [goal_t]
   284     val subs = tfree_classes_of_terms [goal_t]
   267     val supers = tvar_classes_of_terms fact_ts
   285     val supers = tvar_classes_of_terms fact_ts
   268     val tycons = type_consts_of_terms thy (goal_t :: fact_ts)
   286     val tycons = type_consts_of_terms thy (goal_t :: fact_ts)
   269     (* TFrees in the conjecture; TVars in the facts *)
   287     (* TFrees in the conjecture; TVars in the facts *)
   270     val conjectures = make_conjecture ctxt (hyp_ts @ [concl_t])
   288     val conjectures = make_conjecture ctxt (hyp_ts @ [concl_t])
   271     val helper_facts = get_helper_facts ctxt is_FO full_types conjectures facts
   289     val helper_facts = get_helper_facts ctxt is_FO type_sys conjectures facts
   272     val (supers', arity_clauses) = make_arity_clauses thy tycons supers
   290     val (supers', arity_clauses) = make_arity_clauses thy tycons supers
   273     val class_rel_clauses = make_class_rel_clauses thy subs supers'
   291     val class_rel_clauses = make_class_rel_clauses thy subs supers'
   274   in
   292   in
   275     (fact_names |> map single |> Vector.fromList,
   293     (fact_names |> map single |> Vector.fromList,
   276      (conjectures, facts, helper_facts, class_rel_clauses, arity_clauses))
   294      (conjectures, facts, helper_facts, class_rel_clauses, arity_clauses))
   288   | fo_literal_for_type_literal (TyLitFree (class, name)) =
   306   | fo_literal_for_type_literal (TyLitFree (class, name)) =
   289     (true, ATerm (class, [ATerm (name, [])]))
   307     (true, ATerm (class, [ATerm (name, [])]))
   290 
   308 
   291 fun formula_for_fo_literal (pos, t) = AAtom t |> not pos ? mk_anot
   309 fun formula_for_fo_literal (pos, t) = AAtom t |> not pos ? mk_anot
   292 
   310 
   293 fun fo_term_for_combterm full_types =
   311 fun fo_term_for_combterm type_sys =
   294   let
   312   let
   295     fun aux top_level u =
   313     fun aux top_level u =
   296       let
   314       let
   297         val (head, args) = strip_combterm_comb u
   315         val (head, args) = strip_combterm_comb u
   298         val (x, ty_args) =
   316         val (x, ty_args) =
   299           case head of
   317           case head of
   300             CombConst (name as (s, s'), _, ty_args) =>
   318             CombConst (name as (s, s'), _, ty_args) =>
   301             let val ty_args = if full_types then [] else ty_args in
   319             let val ty_args = if is_fully_typed type_sys then [] else ty_args in
   302               if s = "equal" then
   320               if s = "equal" then
   303                 if top_level andalso length args = 2 then (name, [])
   321                 if top_level andalso length args = 2 then (name, [])
   304                 else (("c_fequal", @{const_name Metis.fequal}), ty_args)
   322                 else (("c_fequal", @{const_name Metis.fequal}), ty_args)
   305               else if top_level then
   323               else if top_level then
   306                 case s of
   324                 case s of
   313           | CombVar (name, _) => (name, [])
   331           | CombVar (name, _) => (name, [])
   314           | CombApp _ => raise Fail "impossible \"CombApp\""
   332           | CombApp _ => raise Fail "impossible \"CombApp\""
   315         val t = ATerm (x, map fo_term_for_combtyp ty_args @
   333         val t = ATerm (x, map fo_term_for_combtyp ty_args @
   316                           map (aux false) args)
   334                           map (aux false) args)
   317     in
   335     in
   318       if full_types then wrap_type (fo_term_for_combtyp (combtyp_of u)) t else t
   336       t |> (if type_sys = Tags true then
       
   337               wrap_type (fo_term_for_combtyp (combtyp_of u))
       
   338             else
       
   339               I)
   319     end
   340     end
   320   in aux true end
   341   in aux true end
   321 
   342 
   322 fun formula_for_combformula full_types =
   343 fun formula_for_combformula type_sys =
   323   let
   344   let
   324     fun aux (AQuant (q, xs, phi)) = AQuant (q, xs, aux phi)
   345     fun aux (AQuant (q, xs, phi)) = AQuant (q, xs, aux phi)
   325       | aux (AConn (c, phis)) = AConn (c, map aux phis)
   346       | aux (AConn (c, phis)) = AConn (c, map aux phis)
   326       | aux (AAtom tm) = AAtom (fo_term_for_combterm full_types tm)
   347       | aux (AAtom tm) = AAtom (fo_term_for_combterm type_sys tm)
   327   in aux end
   348   in aux end
   328 
   349 
   329 fun formula_for_fact full_types
   350 fun formula_for_fact type_sys
   330                      ({combformula, ctypes_sorts, ...} : translated_formula) =
   351                      ({combformula, ctypes_sorts, ...} : translated_formula) =
   331   mk_ahorn (map (formula_for_fo_literal o fo_literal_for_type_literal)
   352   mk_ahorn (map (formula_for_fo_literal o fo_literal_for_type_literal)
   332                 (type_literals_for_types ctypes_sorts))
   353                 (type_literals_for_types ctypes_sorts))
   333            (formula_for_combformula full_types combformula)
   354            (formula_for_combformula type_sys combformula)
   334 
   355 
   335 fun problem_line_for_fact prefix full_types (formula as {name, kind, ...}) =
   356 fun problem_line_for_fact prefix type_sys (formula as {name, kind, ...}) =
   336   Fof (prefix ^ ascii_of name, kind, formula_for_fact full_types formula)
   357   Fof (prefix ^ ascii_of name, kind, formula_for_fact type_sys formula)
   337 
   358 
   338 fun problem_line_for_class_rel_clause (ClassRelClause {name, subclass,
   359 fun problem_line_for_class_rel_clause (ClassRelClause {name, subclass,
   339                                                        superclass, ...}) =
   360                                                        superclass, ...}) =
   340   let val ty_arg = ATerm (("T", "T"), []) in
   361   let val ty_arg = ATerm (("T", "T"), []) in
   341     Fof (class_rel_clause_prefix ^ ascii_of name, Axiom,
   362     Fof (class_rel_clause_prefix ^ ascii_of name, Axiom,
   354        mk_ahorn (map (formula_for_fo_literal o apfst not
   375        mk_ahorn (map (formula_for_fo_literal o apfst not
   355                       o fo_literal_for_arity_literal) premLits)
   376                       o fo_literal_for_arity_literal) premLits)
   356                 (formula_for_fo_literal
   377                 (formula_for_fo_literal
   357                      (fo_literal_for_arity_literal conclLit)))
   378                      (fo_literal_for_arity_literal conclLit)))
   358 
   379 
   359 fun problem_line_for_conjecture full_types
   380 fun problem_line_for_conjecture type_sys
   360         ({name, kind, combformula, ...} : translated_formula) =
   381         ({name, kind, combformula, ...} : translated_formula) =
   361   Fof (conjecture_prefix ^ name, kind,
   382   Fof (conjecture_prefix ^ name, kind,
   362        formula_for_combformula full_types combformula)
   383        formula_for_combformula type_sys combformula)
   363 
   384 
   364 fun free_type_literals_for_conjecture
   385 fun free_type_literals_for_conjecture
   365         ({ctypes_sorts, ...} : translated_formula) =
   386         ({ctypes_sorts, ...} : translated_formula) =
   366   map fo_literal_for_type_literal (type_literals_for_types ctypes_sorts)
   387   map fo_literal_for_type_literal (type_literals_for_types ctypes_sorts)
   367 
   388 
   399 
   420 
   400 fun const_table_for_problem explicit_apply problem =
   421 fun const_table_for_problem explicit_apply problem =
   401   if explicit_apply then NONE
   422   if explicit_apply then NONE
   402   else SOME (Symtab.empty |> consider_problem problem)
   423   else SOME (Symtab.empty |> consider_problem problem)
   403 
   424 
   404 fun min_arity_of thy full_types NONE s =
   425 fun min_arity_of thy type_sys NONE s =
   405     (if s = "equal" orelse s = type_wrapper_name orelse
   426     (if s = "equal" orelse s = type_wrapper_name orelse
   406         String.isPrefix type_const_prefix s orelse
   427         String.isPrefix type_const_prefix s orelse
   407         String.isPrefix class_prefix s then
   428         String.isPrefix class_prefix s then
   408        16383 (* large number *)
   429        16383 (* large number *)
   409      else if full_types then
   430      else if is_fully_typed type_sys then
   410        0
   431        0
   411      else case strip_prefix_and_unascii const_prefix s of
   432      else case strip_prefix_and_unascii const_prefix s of
   412        SOME s' => num_type_args thy (invert_const s')
   433        SOME s' => num_type_args thy (invert_const s')
   413      | NONE => 0)
   434      | NONE => 0)
   414   | min_arity_of _ _ (SOME the_const_tab) s =
   435   | min_arity_of _ _ (SOME the_const_tab) s =
   427     let val ty' = ATerm (`make_fixed_type_const @{type_name fun},
   448     let val ty' = ATerm (`make_fixed_type_const @{type_name fun},
   428                          [full_type_of t2, ty]) in
   449                          [full_type_of t2, ty]) in
   429       ATerm (`I "hAPP", [wrap_type ty' (list_hAPP_rev (SOME ty') t1 ts2), t2])
   450       ATerm (`I "hAPP", [wrap_type ty' (list_hAPP_rev (SOME ty') t1 ts2), t2])
   430     end
   451     end
   431 
   452 
   432 fun repair_applications_in_term thy full_types const_tab =
   453 fun repair_applications_in_term thy type_sys const_tab =
   433   let
   454   let
   434     fun aux opt_ty (ATerm (name as (s, _), ts)) =
   455     fun aux opt_ty (ATerm (name as (s, _), ts)) =
   435       if s = type_wrapper_name then
   456       if s = type_wrapper_name then
   436         case ts of
   457         case ts of
   437           [t1, t2] => ATerm (name, [aux NONE t1, aux (SOME t1) t2])
   458           [t1, t2] => ATerm (name, [aux NONE t1, aux (SOME t1) t2])
   438         | _ => raise Fail "malformed type wrapper"
   459         | _ => raise Fail "malformed type wrapper"
   439       else
   460       else
   440         let
   461         let
   441           val ts = map (aux NONE) ts
   462           val ts = map (aux NONE) ts
   442           val (ts1, ts2) = chop (min_arity_of thy full_types const_tab s) ts
   463           val (ts1, ts2) = chop (min_arity_of thy type_sys const_tab s) ts
   443         in list_hAPP_rev opt_ty (ATerm (name, ts1)) (rev ts2) end
   464         in list_hAPP_rev opt_ty (ATerm (name, ts1)) (rev ts2) end
   444   in aux NONE end
   465   in aux NONE end
   445 
   466 
   446 fun boolify t = ATerm (`I "hBOOL", [t])
   467 fun boolify t = ATerm (`I "hBOOL", [t])
   447 
   468 
   479       | formula_vars bounds (AAtom tm) = term_vars bounds tm
   500       | formula_vars bounds (AAtom tm) = term_vars bounds tm
   480   in
   501   in
   481     case formula_vars [] phi [] of [] => phi | xs => AQuant (AForall, xs, phi)
   502     case formula_vars [] phi [] of [] => phi | xs => AQuant (AForall, xs, phi)
   482   end
   503   end
   483 
   504 
   484 fun repair_formula thy explicit_forall full_types const_tab =
   505 fun repair_formula thy explicit_forall type_sys const_tab =
   485   let
   506   let
   486     fun aux (AQuant (q, xs, phi)) = AQuant (q, xs, aux phi)
   507     fun aux (AQuant (q, xs, phi)) = AQuant (q, xs, aux phi)
   487       | aux (AConn (c, phis)) = AConn (c, map aux phis)
   508       | aux (AConn (c, phis)) = AConn (c, map aux phis)
   488       | aux (AAtom tm) =
   509       | aux (AAtom tm) =
   489         AAtom (tm |> repair_applications_in_term thy full_types const_tab
   510         AAtom (tm |> repair_applications_in_term thy type_sys const_tab
   490                   |> repair_predicates_in_term const_tab)
   511                   |> repair_predicates_in_term const_tab)
   491   in aux #> explicit_forall ? close_universally end
   512   in aux #> explicit_forall ? close_universally end
   492 
   513 
   493 fun repair_problem_line thy explicit_forall full_types const_tab
   514 fun repair_problem_line thy explicit_forall type_sys const_tab
   494                         (Fof (ident, kind, phi)) =
   515                         (Fof (ident, kind, phi)) =
   495   Fof (ident, kind, repair_formula thy explicit_forall full_types const_tab phi)
   516   Fof (ident, kind, repair_formula thy explicit_forall type_sys const_tab phi)
   496 fun repair_problem_with_const_table thy =
   517 fun repair_problem_with_const_table thy =
   497   map o apsnd o map ooo repair_problem_line thy
   518   map o apsnd o map ooo repair_problem_line thy
   498 
   519 
   499 fun repair_problem thy explicit_forall full_types explicit_apply problem =
   520 fun repair_problem thy explicit_forall type_sys explicit_apply problem =
   500   repair_problem_with_const_table thy explicit_forall full_types
   521   repair_problem_with_const_table thy explicit_forall type_sys
   501       (const_table_for_problem explicit_apply problem) problem
   522       (const_table_for_problem explicit_apply problem) problem
   502 
   523 
   503 fun prepare_atp_problem ctxt readable_names explicit_forall full_types
   524 fun prepare_atp_problem ctxt readable_names explicit_forall type_sys
   504                         explicit_apply hyp_ts concl_t facts =
   525                         explicit_apply hyp_ts concl_t facts =
   505   let
   526   let
   506     val thy = ProofContext.theory_of ctxt
   527     val thy = ProofContext.theory_of ctxt
   507     val (fact_names, (conjectures, facts, helper_facts, class_rel_clauses,
   528     val (fact_names, (conjectures, facts, helper_facts, class_rel_clauses,
   508                       arity_clauses)) =
   529                       arity_clauses)) =
   509       translate_formulas ctxt full_types hyp_ts concl_t facts
   530       translate_formulas ctxt type_sys hyp_ts concl_t facts
   510     val fact_lines = map (problem_line_for_fact fact_prefix full_types) facts
   531     val fact_lines = map (problem_line_for_fact fact_prefix type_sys) facts
   511     val helper_lines =
   532     val helper_lines =
   512       map (problem_line_for_fact helper_prefix full_types) helper_facts
   533       map (problem_line_for_fact helper_prefix type_sys) helper_facts
   513     val conjecture_lines =
   534     val conjecture_lines =
   514       map (problem_line_for_conjecture full_types) conjectures
   535       map (problem_line_for_conjecture type_sys) conjectures
   515     val tfree_lines = problem_lines_for_free_types conjectures
   536     val tfree_lines = problem_lines_for_free_types conjectures
   516     val class_rel_lines =
   537     val class_rel_lines =
   517       map problem_line_for_class_rel_clause class_rel_clauses
   538       map problem_line_for_class_rel_clause class_rel_clauses
   518     val arity_lines = map problem_line_for_arity_clause arity_clauses
   539     val arity_lines = map problem_line_for_arity_clause arity_clauses
   519     (* Reordering these might or might not confuse the proof reconstruction
   540     (* Reordering these might or might not confuse the proof reconstruction
   523        ("Class relationships", class_rel_lines),
   544        ("Class relationships", class_rel_lines),
   524        ("Arity declarations", arity_lines),
   545        ("Arity declarations", arity_lines),
   525        ("Helper facts", helper_lines),
   546        ("Helper facts", helper_lines),
   526        ("Conjectures", conjecture_lines),
   547        ("Conjectures", conjecture_lines),
   527        ("Type variables", tfree_lines)]
   548        ("Type variables", tfree_lines)]
   528       |> repair_problem thy explicit_forall full_types explicit_apply
   549       |> repair_problem thy explicit_forall type_sys explicit_apply
   529     val (problem, pool) = nice_atp_problem readable_names problem
   550     val (problem, pool) = nice_atp_problem readable_names problem
   530     val conjecture_offset =
   551     val conjecture_offset =
   531       length fact_lines + length class_rel_lines + length arity_lines
   552       length fact_lines + length class_rel_lines + length arity_lines
   532       + length helper_lines
   553       + length helper_lines
   533   in
   554   in