src/HOL/Tools/Sledgehammer/sledgehammer_atp_translate.ML
changeset 42579 2552c09b1a72
parent 42577 78414ec6fa4e
child 42585 723b9d1e8ba5
equal deleted inserted replaced
42578:1eaf4d437d4c 42579:2552c09b1a72
     8 
     8 
     9 signature SLEDGEHAMMER_ATP_TRANSLATE =
     9 signature SLEDGEHAMMER_ATP_TRANSLATE =
    10 sig
    10 sig
    11   type 'a fo_term = 'a ATP_Problem.fo_term
    11   type 'a fo_term = 'a ATP_Problem.fo_term
    12   type 'a problem = 'a ATP_Problem.problem
    12   type 'a problem = 'a ATP_Problem.problem
       
    13   type type_system = ATP_Systems.type_system
    13   type translated_formula
    14   type translated_formula
    14 
       
    15   datatype type_system =
       
    16     Many_Typed |
       
    17     Mangled of bool |
       
    18     Args of bool |
       
    19     Tags of bool |
       
    20     No_Types
       
    21 
    15 
    22   val readable_names : bool Unsynchronized.ref
    16   val readable_names : bool Unsynchronized.ref
    23   val fact_prefix : string
    17   val fact_prefix : string
    24   val conjecture_prefix : string
    18   val conjecture_prefix : string
    25   val predicator_base : string
    19   val predicator_base : string
    26   val explicit_app_base : string
    20   val explicit_app_base : string
    27   val type_pred_base : string
    21   val type_pred_base : string
    28   val tff_type_prefix : string
    22   val tff_type_prefix : string
    29   val is_type_system_sound : type_system -> bool
       
    30   val type_system_types_dangerous_types : type_system -> bool
       
    31   val num_atp_type_args : theory -> type_system -> string -> int
    23   val num_atp_type_args : theory -> type_system -> string -> int
    32   val unmangled_const : string -> string * string fo_term list
    24   val unmangled_const : string -> string * string fo_term list
    33   val translate_atp_fact :
    25   val translate_atp_fact :
    34     Proof.context -> bool -> (string * 'a) * thm
    26     Proof.context -> bool -> (string * 'a) * thm
    35     -> translated_formula option * ((string * 'a) * thm)
    27     -> translated_formula option * ((string * 'a) * thm)
    43 
    35 
    44 structure Sledgehammer_ATP_Translate : SLEDGEHAMMER_ATP_TRANSLATE =
    36 structure Sledgehammer_ATP_Translate : SLEDGEHAMMER_ATP_TRANSLATE =
    45 struct
    37 struct
    46 
    38 
    47 open ATP_Problem
    39 open ATP_Problem
       
    40 open ATP_Systems
    48 open Metis_Translate
    41 open Metis_Translate
    49 open Sledgehammer_Util
    42 open Sledgehammer_Util
    50 
    43 
    51 (* Readable names are often much shorter, especially if types are mangled in
    44 (* Readable names are often much shorter, especially if types are mangled in
    52    names. For that reason, they are on by default. *)
    45    names. For that reason, they are on by default. *)
    96   {name = name, kind = kind, combformula = f combformula,
    89   {name = name, kind = kind, combformula = f combformula,
    97    atomic_types = atomic_types} : translated_formula
    90    atomic_types = atomic_types} : translated_formula
    98 
    91 
    99 fun fact_lift f ({combformula, ...} : translated_formula) = f combformula
    92 fun fact_lift f ({combformula, ...} : translated_formula) = f combformula
   100 
    93 
   101 datatype type_system =
    94 fun type_sys_declares_sym_types Many_Typed = true
   102   Many_Typed |
    95   | type_sys_declares_sym_types (Mangled level) = level <> Unsound
   103   Mangled of bool |
    96   | type_sys_declares_sym_types (Args (_, level)) = level <> Unsound
   104   Args of bool |
    97   | type_sys_declares_sym_types _ = false
   105   Tags of bool |
       
   106   No_Types
       
   107 
       
   108 fun is_type_system_sound Many_Typed = true
       
   109   | is_type_system_sound (Mangled full_types) = full_types
       
   110   | is_type_system_sound (Args full_types) = full_types
       
   111   | is_type_system_sound (Tags full_types) = full_types
       
   112   | is_type_system_sound No_Types = false
       
   113 
       
   114 fun type_system_types_dangerous_types (Tags _) = true
       
   115   | type_system_types_dangerous_types type_sys = is_type_system_sound type_sys
       
   116 
       
   117 fun type_system_introduces_type_preds (Mangled true) = true
       
   118   | type_system_introduces_type_preds (Args true) = true
       
   119   | type_system_introduces_type_preds _ = false
       
   120 
       
   121 fun type_system_declares_sym_types Many_Typed = true
       
   122   | type_system_declares_sym_types type_sys =
       
   123     type_system_introduces_type_preds type_sys
       
   124 
    98 
   125 val boring_consts = [explicit_app_base, @{const_name Metis.fequal}]
    99 val boring_consts = [explicit_app_base, @{const_name Metis.fequal}]
   126 
   100 
   127 fun should_omit_type_args type_sys s =
   101 fun should_omit_type_args type_sys s =
   128   s <> type_pred_base andalso
   102   s <> type_pred_base andalso
   129   (s = @{const_name HOL.eq} orelse
   103   (s = @{const_name HOL.eq} orelse
   130    case type_sys of
   104    case type_sys of
   131      Many_Typed => false
   105      Many_Typed => false
   132    | Mangled _ => false
   106    | Mangled _ => false
       
   107    | Tags (_, Sound) => true
   133    | No_Types => true
   108    | No_Types => true
   134    | Tags true => true
       
   135    | _ => member (op =) boring_consts s)
   109    | _ => member (op =) boring_consts s)
   136 
   110 
   137 datatype type_arg_policy = No_Type_Args | Mangled_Types | Explicit_Type_Args
   111 datatype type_arg_policy = No_Type_Args | Mangled_Types | Explicit_Type_Args
   138 
   112 
   139 fun general_type_arg_policy Many_Typed = Mangled_Types
   113 fun general_type_arg_policy Many_Typed = Mangled_Types
   140   | general_type_arg_policy (Mangled _) = Mangled_Types
   114   | general_type_arg_policy (Mangled _) = Mangled_Types
       
   115   | general_type_arg_policy No_Types = No_Type_Args
   141   | general_type_arg_policy _ = Explicit_Type_Args
   116   | general_type_arg_policy _ = Explicit_Type_Args
   142 
   117 
   143 fun type_arg_policy type_sys s =
   118 fun type_arg_policy type_sys s =
   144   if should_omit_type_args type_sys s then No_Type_Args
   119   if should_omit_type_args type_sys s then No_Type_Args
   145   else general_type_arg_policy type_sys
   120   else general_type_arg_policy type_sys
   540   case strip_prefix_and_unascii const_prefix s of
   515   case strip_prefix_and_unascii const_prefix s of
   541     SOME mangled_s =>
   516     SOME mangled_s =>
   542     let
   517     let
   543       val thy = Proof_Context.theory_of ctxt
   518       val thy = Proof_Context.theory_of ctxt
   544       val unmangled_s = mangled_s |> unmangled_const_name
   519       val unmangled_s = mangled_s |> unmangled_const_name
   545       fun dub_and_inst c needs_full_types (th, j) =
   520       fun dub_and_inst c needs_some_types (th, j) =
   546         ((c ^ "_" ^ string_of_int j ^ (if needs_full_types then "ft" else ""),
   521         ((c ^ "_" ^ string_of_int j ^ (if needs_some_types then "T" else ""),
   547           false),
   522           false),
   548          let val t = th |> prop_of in
   523          let val t = th |> prop_of in
   549            t |> (general_type_arg_policy type_sys = Mangled_Types andalso
   524            t |> (general_type_arg_policy type_sys = Mangled_Types andalso
   550                  not (null (Term.hidden_polymorphism t)))
   525                  not (null (Term.hidden_polymorphism t)))
   551                 ? (case typ of
   526                 ? (case typ of
   554          end)
   529          end)
   555       fun make_facts eq_as_iff =
   530       fun make_facts eq_as_iff =
   556         map_filter (make_fact ctxt false eq_as_iff false)
   531         map_filter (make_fact ctxt false eq_as_iff false)
   557     in
   532     in
   558       metis_helpers
   533       metis_helpers
   559       |> maps (fn (metis_s, (needs_full_types, ths)) =>
   534       |> maps (fn (metis_s, (needs_some_types, ths)) =>
   560                   if metis_s <> unmangled_s orelse
   535                   if metis_s <> unmangled_s orelse
   561                      (needs_full_types andalso
   536                      (needs_some_types andalso
   562                       not (type_system_types_dangerous_types type_sys)) then
   537                       level_of_type_sys type_sys = Unsound) then
   563                     []
   538                     []
   564                   else
   539                   else
   565                     ths ~~ (1 upto length ths)
   540                     ths ~~ (1 upto length ths)
   566                     |> map (dub_and_inst mangled_s needs_full_types)
   541                     |> map (dub_and_inst mangled_s needs_some_types)
   567                     |> make_facts (not needs_full_types))
   542                     |> make_facts (not needs_some_types))
   568     end
   543     end
   569   | NONE => []
   544   | NONE => []
   570 fun helper_facts_for_sym_table ctxt type_sys sym_tab =
   545 fun helper_facts_for_sym_table ctxt type_sys sym_tab =
   571   Symtab.fold_rev (append o helper_facts_for_sym ctxt type_sys) sym_tab []
   546   Symtab.fold_rev (append o helper_facts_for_sym ctxt type_sys) sym_tab []
   572 
   547 
   630       case Typedef.get_info ctxt s of
   605       case Typedef.get_info ctxt s of
   631         ({rep_type, ...}, _) :: _ => is_type_dangerous ctxt rep_type
   606         ({rep_type, ...}, _) :: _ => is_type_dangerous ctxt rep_type
   632       | [] => true
   607       | [] => true
   633   end
   608   end
   634 
   609 
   635 fun should_tag_with_type ctxt (Tags full_types) T =
   610 fun should_encode_type _ Sound _ = true
   636     full_types orelse is_type_dangerous ctxt T
   611   | should_encode_type ctxt Half_Sound T = is_type_dangerous ctxt T
       
   612   | should_encode_type _ Unsound _ = false
       
   613 
       
   614 fun should_tag_with_type ctxt (Tags (_, level)) T =
       
   615     should_encode_type ctxt level T
   637   | should_tag_with_type _ _ _ = false
   616   | should_tag_with_type _ _ _ = false
       
   617 
       
   618 fun should_predicate_on_type ctxt (Mangled level) T =
       
   619     should_encode_type ctxt level T
       
   620   | should_predicate_on_type ctxt (Args (_, level)) T =
       
   621     should_encode_type ctxt level T
       
   622   | should_predicate_on_type _ _ _ = false
   638 
   623 
   639 fun type_pred_combatom type_sys T tm =
   624 fun type_pred_combatom type_sys T tm =
   640   CombApp (CombConst (`make_fixed_const type_pred_base, T --> @{typ bool}, [T]),
   625   CombApp (CombConst (`make_fixed_const type_pred_base, T --> @{typ bool}, [T]),
   641            tm)
   626            tm)
   642   |> impose_type_arg_policy_in_combterm type_sys
   627   |> impose_type_arg_policy_in_combterm type_sys
   662                 I)
   647                 I)
   663       end
   648       end
   664     val do_bound_type =
   649     val do_bound_type =
   665       if type_sys = Many_Typed then SOME o mangled_type_name else K NONE
   650       if type_sys = Many_Typed then SOME o mangled_type_name else K NONE
   666     fun do_out_of_bound_type (s, T) =
   651     fun do_out_of_bound_type (s, T) =
   667       if type_system_introduces_type_preds type_sys then
   652       if should_predicate_on_type ctxt type_sys T then
   668         type_pred_combatom type_sys T (CombVar (s, T))
   653         type_pred_combatom type_sys T (CombVar (s, T))
   669         |> do_formula |> SOME
   654         |> do_formula |> SOME
   670       else
   655       else
   671         NONE
   656         NONE
   672     and do_formula (AQuant (q, xs, phi)) =
   657     and do_formula (AQuant (q, xs, phi)) =
   747   (type_sys = Many_Typed orelse not pred_sym)
   732   (type_sys = Many_Typed orelse not pred_sym)
   748 
   733 
   749 fun add_combterm_syms_to_decl_table type_sys repaired_sym_tab =
   734 fun add_combterm_syms_to_decl_table type_sys repaired_sym_tab =
   750   let
   735   let
   751     fun declare_sym (decl as (_, _, T, _, _)) decls =
   736     fun declare_sym (decl as (_, _, T, _, _)) decls =
   752       if exists (curry Type.raw_instance T o #3) decls then decls
   737       case type_sys of
   753       else decl :: filter_out ((fn T' => Type.raw_instance (T', T)) o #3) decls
   738         Tags (false, Sound) =>
       
   739         if exists (curry Type.raw_instance T o #3) decls then
       
   740           decls
       
   741         else
       
   742           decl :: filter_out ((fn T' => Type.raw_instance (T', T)) o #3) decls
       
   743       | _ => insert (op =) decl decls
   754     fun do_term tm =
   744     fun do_term tm =
   755       let val (head, args) = strip_combterm_comb tm in
   745       let val (head, args) = strip_combterm_comb tm in
   756         (case head of
   746         (case head of
   757            CombConst ((s, s'), T, T_args) =>
   747            CombConst ((s, s'), T, T_args) =>
   758            let val pred_sym = is_pred_sym repaired_sym_tab s in
   748            let val pred_sym = is_pred_sym repaired_sym_tab s in
   768   in do_term end
   758   in do_term end
   769 fun add_fact_syms_to_decl_table type_sys repaired_sym_tab =
   759 fun add_fact_syms_to_decl_table type_sys repaired_sym_tab =
   770   fact_lift (formula_fold
   760   fact_lift (formula_fold
   771       (add_combterm_syms_to_decl_table type_sys repaired_sym_tab))
   761       (add_combterm_syms_to_decl_table type_sys repaired_sym_tab))
   772 fun sym_decl_table_for_facts type_sys repaired_sym_tab facts =
   762 fun sym_decl_table_for_facts type_sys repaired_sym_tab facts =
   773   Symtab.empty |> type_system_declares_sym_types type_sys
   763   Symtab.empty |> type_sys_declares_sym_types type_sys
   774                   ? fold (add_fact_syms_to_decl_table type_sys repaired_sym_tab)
   764                   ? fold (add_fact_syms_to_decl_table type_sys repaired_sym_tab)
   775                          facts
   765                          facts
   776 
   766 
   777 fun n_ary_strip_type 0 T = ([], T)
   767 fun n_ary_strip_type 0 T = ([], T)
   778   | n_ary_strip_type n (Type (@{type_name fun}, [dom_T, ran_T])) =
   768   | n_ary_strip_type n (Type (@{type_name fun}, [dom_T, ran_T])) =
   779     n_ary_strip_type (n - 1) ran_T |>> cons dom_T
   769     n_ary_strip_type (n - 1) ran_T |>> cons dom_T
   780   | n_ary_strip_type _ _ = raise Fail "unexpected non-function"
   770   | n_ary_strip_type _ _ = raise Fail "unexpected non-function"
   781 
   771 
   782 fun problem_line_for_sym_decl ctxt type_sys need_bound_types s j
   772 fun result_type_of_decl (_, _, T, _, ary) = n_ary_strip_type ary T |> snd
   783                               (s', T_args, T, pred_sym, ary) =
   773 
       
   774 fun decl_line_for_sym_decl s (s', _, T, pred_sym, ary) =
       
   775   let val (arg_Ts, res_T) = n_ary_strip_type ary T in
       
   776     Decl (sym_decl_prefix ^ ascii_of s, (s, s'),
       
   777           map mangled_type_name arg_Ts,
       
   778           if pred_sym then `I tptp_tff_bool_type else mangled_type_name res_T)
       
   779   end
       
   780 
       
   781 fun formula_line_for_sym_decl ctxt type_sys n s j (s', T_args, T, _, ary) =
       
   782   let
       
   783     val (arg_Ts, res_T) = n_ary_strip_type ary T
       
   784     val bound_names =
       
   785       1 upto length arg_Ts |> map (`I o make_bound_var o string_of_int)
       
   786     val bound_tms =
       
   787       bound_names ~~ arg_Ts |> map (fn (name, T) => CombConst (name, T, []))
       
   788     val bound_Ts =
       
   789       arg_Ts |> map (if n > 1 then SOME else K NONE)
       
   790     val freshener =
       
   791       case type_sys of Args _ => string_of_int j ^ "_" | _ => ""
       
   792   in
       
   793     Formula (sym_decl_prefix ^ freshener ^ "_" ^ ascii_of s, Axiom,
       
   794              CombConst ((s, s'), T, T_args)
       
   795              |> fold (curry (CombApp o swap)) bound_tms
       
   796              |> type_pred_combatom type_sys res_T
       
   797              |> mk_aquant AForall (bound_names ~~ bound_Ts)
       
   798              |> formula_from_combformula ctxt type_sys,
       
   799              NONE, NONE)
       
   800   end
       
   801 
       
   802 fun problem_lines_for_sym_decls ctxt type_sys (s, decls) =
   784   if type_sys = Many_Typed then
   803   if type_sys = Many_Typed then
   785     let val (arg_Ts, res_T) = n_ary_strip_type ary T in
   804     map (decl_line_for_sym_decl s) decls
   786       Decl (sym_decl_prefix ^ ascii_of s, (s, s'),
       
   787             map mangled_type_name arg_Ts,
       
   788             if pred_sym then `I tptp_tff_bool_type else mangled_type_name res_T)
       
   789     end
       
   790   else
   805   else
   791     let
   806     let
   792       val (arg_Ts, res_T) = n_ary_strip_type ary T
   807       val decls =
   793       val bound_names =
   808         case decls of
   794         1 upto length arg_Ts |> map (`I o make_bound_var o string_of_int)
   809           decl :: (decls' as _ :: _) =>
   795       val bound_tms =
   810           if forall (curry (op =) (result_type_of_decl decl)
   796         bound_names ~~ arg_Ts |> map (fn (name, T) => CombConst (name, T, []))
   811                      o result_type_of_decl) decls' then
   797       val bound_Ts = arg_Ts |> map (if need_bound_types then SOME else K NONE)
   812             [decl]
   798       val freshener =
   813           else
   799         case type_sys of Args _ => string_of_int j ^ "_" | _ => ""
   814             decls
       
   815         | _ => decls
       
   816       val n = length decls
       
   817       val decls =
       
   818         decls |> filter (should_predicate_on_type ctxt type_sys
       
   819                          o result_type_of_decl)
   800     in
   820     in
   801       Formula (sym_decl_prefix ^ freshener ^ "_" ^ ascii_of s, Axiom,
   821       map2 (formula_line_for_sym_decl ctxt type_sys n s)
   802                CombConst ((s, s'), T, T_args)
   822            (0 upto length decls - 1) decls
   803                |> fold (curry (CombApp o swap)) bound_tms
       
   804                |> type_pred_combatom type_sys res_T
       
   805                |> mk_aquant AForall (bound_names ~~ bound_Ts)
       
   806                |> formula_from_combformula ctxt type_sys,
       
   807                NONE, NONE)
       
   808     end
   823     end
   809 fun problem_lines_for_sym_decls ctxt type_sys (s, decls) =
   824 
   810   let
       
   811     val n = length decls
       
   812     fun result_type_of_decl (_, _, T, _, ary) = n_ary_strip_type ary T |> snd
       
   813     val need_bound_types =
       
   814       case decls of
       
   815         decl :: (decls as _ :: _) =>
       
   816         exists (curry (op <>) (result_type_of_decl decl)
       
   817                 o result_type_of_decl) decls
       
   818       | _ => false
       
   819   in
       
   820     map2 (problem_line_for_sym_decl ctxt type_sys need_bound_types s)
       
   821          (0 upto n - 1) decls
       
   822   end
       
   823 fun problem_lines_for_sym_decl_table ctxt type_sys sym_decl_tab =
   825 fun problem_lines_for_sym_decl_table ctxt type_sys sym_decl_tab =
   824   Symtab.fold_rev (append o problem_lines_for_sym_decls ctxt type_sys)
   826   Symtab.fold_rev (append o problem_lines_for_sym_decls ctxt type_sys)
   825                   sym_decl_tab []
   827                   sym_decl_tab []
   826 
   828 
   827 fun add_tff_types_in_formula (AQuant (_, xs, phi)) =
   829 fun add_tff_types_in_formula (AQuant (_, xs, phi)) =
   878                     (0 upto length facts - 1 ~~ facts)),
   880                     (0 upto length facts - 1 ~~ facts)),
   879        (class_relsN, map formula_line_for_class_rel_clause class_rel_clauses),
   881        (class_relsN, map formula_line_for_class_rel_clause class_rel_clauses),
   880        (aritiesN, map formula_line_for_arity_clause arity_clauses),
   882        (aritiesN, map formula_line_for_arity_clause arity_clauses),
   881        (helpersN, map (formula_line_for_fact ctxt helper_prefix type_sys)
   883        (helpersN, map (formula_line_for_fact ctxt helper_prefix type_sys)
   882                       (0 upto length helpers - 1 ~~ helpers)
   884                       (0 upto length helpers - 1 ~~ helpers)
   883                   |> (if type_sys = Tags false then cons (ti_ti_helper_fact ())
   885                   |> (case type_sys of
   884                       else I)),
   886                         Tags (_, Half_Sound) => cons (ti_ti_helper_fact ())
       
   887                       | _ => I)),
   885        (conjsN, map (formula_line_for_conjecture ctxt type_sys) conjs),
   888        (conjsN, map (formula_line_for_conjecture ctxt type_sys) conjs),
   886        (free_typesN, formula_lines_for_free_types type_sys (facts @ conjs))]
   889        (free_typesN, formula_lines_for_free_types type_sys (facts @ conjs))]
   887     val problem =
   890     val problem =
   888       problem
   891       problem
   889       |> (if type_sys = Many_Typed then
   892       |> (if type_sys = Many_Typed then