src/HOL/Tools/ATP/atp_translate.ML
changeset 43159 29b55f292e0b
parent 43139 9ed5d8ad8fa0
child 43167 839f599bc7ed
equal deleted inserted replaced
43158:686fa0a0696e 43159:29b55f292e0b
    75   val class_rel_clause_prefix : string
    75   val class_rel_clause_prefix : string
    76   val arity_clause_prefix : string
    76   val arity_clause_prefix : string
    77   val tfree_clause_prefix : string
    77   val tfree_clause_prefix : string
    78   val typed_helper_suffix : string
    78   val typed_helper_suffix : string
    79   val untyped_helper_suffix : string
    79   val untyped_helper_suffix : string
       
    80   val type_tag_idempotence_helper_name : string
    80   val predicator_name : string
    81   val predicator_name : string
    81   val app_op_name : string
    82   val app_op_name : string
    82   val type_tag_name : string
    83   val type_tag_name : string
    83   val type_pred_name : string
    84   val type_pred_name : string
    84   val simple_type_prefix : string
    85   val simple_type_prefix : string
    85   val prefixed_app_op_name : string
    86   val prefixed_app_op_name : string
    86   val prefixed_type_tag_name : string
    87   val prefixed_type_tag_name : string
    87   val ascii_of: string -> string
    88   val ascii_of: string -> string
    88   val unascii_of: string -> string
    89   val unascii_of: string -> string
    89   val strip_prefix_and_unascii : string -> string -> string option
    90   val strip_prefix_and_unascii : string -> string -> string option
    90   val proxify_const : string -> (int * (string * string)) option
    91   val proxy_table : (string * (string * (thm * (string * string)))) list
       
    92   val proxify_const : string -> (string * string) option
    91   val invert_const: string -> string
    93   val invert_const: string -> string
    92   val unproxify_const: string -> string
    94   val unproxify_const: string -> string
    93   val make_bound_var : string -> string
    95   val make_bound_var : string -> string
    94   val make_schematic_var : string * int -> string
    96   val make_schematic_var : string * int -> string
    95   val make_fixed_var : string -> string
    97   val make_fixed_var : string -> string
   123   val unmangled_const : string -> string * string fo_term list
   125   val unmangled_const : string -> string * string fo_term list
   124   val translate_atp_fact :
   126   val translate_atp_fact :
   125     Proof.context -> format -> type_sys -> bool -> (string * locality) * thm
   127     Proof.context -> format -> type_sys -> bool -> (string * locality) * thm
   126     -> translated_formula option * ((string * locality) * thm)
   128     -> translated_formula option * ((string * locality) * thm)
   127   val helper_table : (string * (bool * thm list)) list
   129   val helper_table : (string * (bool * thm list)) list
       
   130   val should_specialize_helper : type_sys -> term -> bool
   128   val tfree_classes_of_terms : term list -> string list
   131   val tfree_classes_of_terms : term list -> string list
   129   val tvar_classes_of_terms : term list -> string list
   132   val tvar_classes_of_terms : term list -> string list
   130   val type_consts_of_terms : theory -> term list -> string list
   133   val type_consts_of_terms : theory -> term list -> string list
   131   val prepare_atp_problem :
   134   val prepare_atp_problem :
   132     Proof.context -> format -> formula_kind -> formula_kind -> type_sys
   135     Proof.context -> format -> formula_kind -> formula_kind -> type_sys
   181 val preds_sym_formula_prefix = "psy_"
   184 val preds_sym_formula_prefix = "psy_"
   182 val lightweight_tags_sym_formula_prefix = "tsy_"
   185 val lightweight_tags_sym_formula_prefix = "tsy_"
   183 val fact_prefix = "fact_"
   186 val fact_prefix = "fact_"
   184 val conjecture_prefix = "conj_"
   187 val conjecture_prefix = "conj_"
   185 val helper_prefix = "help_"
   188 val helper_prefix = "help_"
   186 val class_rel_clause_prefix = "crel_"
   189 val class_rel_clause_prefix = "clar_"
   187 val arity_clause_prefix = "arity_"
   190 val arity_clause_prefix = "arity_"
   188 val tfree_clause_prefix = "tfree_"
   191 val tfree_clause_prefix = "tfree_"
   189 
   192 
   190 val typed_helper_suffix = "_T"
   193 val typed_helper_suffix = "_T"
   191 val untyped_helper_suffix = "_U"
   194 val untyped_helper_suffix = "_U"
       
   195 val type_tag_idempotence_helper_name = helper_prefix ^ "ti_idem"
   192 
   196 
   193 val predicator_name = "hBOOL"
   197 val predicator_name = "hBOOL"
   194 val app_op_name = "hAPP"
   198 val app_op_name = "hAPP"
   195 val type_tag_name = "ti"
   199 val type_tag_name = "ti"
   196 val type_pred_name = "is"
   200 val type_pred_name = "is"
   255   if String.isPrefix s1 s then
   259   if String.isPrefix s1 s then
   256     SOME (unascii_of (String.extract (s, size s1, NONE)))
   260     SOME (unascii_of (String.extract (s, size s1, NONE)))
   257   else
   261   else
   258     NONE
   262     NONE
   259 
   263 
   260 val proxies =
   264 val proxy_table =
   261   [("c_False",
   265   [("c_False", (@{const_name False}, (@{thm fFalse_def},
   262     (@{const_name False}, (0, ("fFalse", @{const_name ATP.fFalse})))),
   266        ("fFalse", @{const_name ATP.fFalse})))),
   263    ("c_True", (@{const_name True}, (0, ("fTrue", @{const_name ATP.fTrue})))),
   267    ("c_True", (@{const_name True}, (@{thm fTrue_def},
   264    ("c_Not", (@{const_name Not}, (1, ("fNot", @{const_name ATP.fNot})))),
   268        ("fTrue", @{const_name ATP.fTrue})))),
   265    ("c_conj", (@{const_name conj}, (2, ("fconj", @{const_name ATP.fconj})))),
   269    ("c_Not", (@{const_name Not}, (@{thm fNot_def},
   266    ("c_disj", (@{const_name disj}, (2, ("fdisj", @{const_name ATP.fdisj})))),
   270        ("fNot", @{const_name ATP.fNot})))),
   267    ("c_implies",
   271    ("c_conj", (@{const_name conj}, (@{thm fconj_def},
   268     (@{const_name implies}, (2, ("fimplies", @{const_name ATP.fimplies})))),
   272        ("fconj", @{const_name ATP.fconj})))),
   269    ("equal",
   273    ("c_disj", (@{const_name disj}, (@{thm fdisj_def},
   270     (@{const_name HOL.eq}, (2, ("fequal", @{const_name ATP.fequal}))))]
   274        ("fdisj", @{const_name ATP.fdisj})))),
   271 
   275    ("c_implies", (@{const_name implies}, (@{thm fimplies_def},
   272 val proxify_const = AList.lookup (op =) proxies #> Option.map snd
   276        ("fimplies", @{const_name ATP.fimplies})))),
       
   277    ("equal", (@{const_name HOL.eq}, (@{thm fequal_def},
       
   278        ("fequal", @{const_name ATP.fequal}))))]
       
   279 
       
   280 val proxify_const = AList.lookup (op =) proxy_table #> Option.map (snd o snd)
   273 
   281 
   274 (* Readable names for the more common symbolic functions. Do not mess with the
   282 (* Readable names for the more common symbolic functions. Do not mess with the
   275    table unless you know what you are doing. *)
   283    table unless you know what you are doing. *)
   276 val const_trans_table =
   284 val const_trans_table =
   277   [(@{type_name Product_Type.prod}, "prod"),
   285   [(@{type_name Product_Type.prod}, "prod"),
   289    (@{const_name Meson.COMBK}, "COMBK"),
   297    (@{const_name Meson.COMBK}, "COMBK"),
   290    (@{const_name Meson.COMBB}, "COMBB"),
   298    (@{const_name Meson.COMBB}, "COMBB"),
   291    (@{const_name Meson.COMBC}, "COMBC"),
   299    (@{const_name Meson.COMBC}, "COMBC"),
   292    (@{const_name Meson.COMBS}, "COMBS")]
   300    (@{const_name Meson.COMBS}, "COMBS")]
   293   |> Symtab.make
   301   |> Symtab.make
   294   |> fold (Symtab.update o swap o snd o snd o snd) proxies
   302   |> fold (Symtab.update o swap o snd o snd o snd) proxy_table
   295 
   303 
   296 (* Invert the table of translations between Isabelle and ATPs. *)
   304 (* Invert the table of translations between Isabelle and ATPs. *)
   297 val const_trans_table_inv =
   305 val const_trans_table_inv =
   298   const_trans_table |> Symtab.dest |> map swap |> Symtab.make
   306   const_trans_table |> Symtab.dest |> map swap |> Symtab.make
   299 val const_trans_table_unprox =
   307 val const_trans_table_unprox =
   300   Symtab.empty
   308   Symtab.empty
   301   |> fold (fn (_, (isa, (_, (_, metis)))) => Symtab.update (metis, isa)) proxies
   309   |> fold (fn (_, (isa, (_, (_, atp)))) => Symtab.update (atp, isa)) proxy_table
   302 
   310 
   303 val invert_const = perhaps (Symtab.lookup const_trans_table_inv)
   311 val invert_const = perhaps (Symtab.lookup const_trans_table_inv)
   304 val unproxify_const = perhaps (Symtab.lookup const_trans_table_unprox)
   312 val unproxify_const = perhaps (Symtab.lookup const_trans_table_unprox)
   305 
   313 
   306 fun lookup_const c =
   314 fun lookup_const c =
   791   let
   799   let
   792     fun intro top_level (CombApp (tm1, tm2)) =
   800     fun intro top_level (CombApp (tm1, tm2)) =
   793         CombApp (intro top_level tm1, intro false tm2)
   801         CombApp (intro top_level tm1, intro false tm2)
   794       | intro top_level (CombConst (name as (s, _), T, T_args)) =
   802       | intro top_level (CombConst (name as (s, _), T, T_args)) =
   795         (case proxify_const s of
   803         (case proxify_const s of
   796            SOME (_, proxy_base) =>
   804            SOME proxy_base =>
   797            if top_level orelse is_setting_higher_order format type_sys then
   805            if top_level orelse is_setting_higher_order format type_sys then
   798              case (top_level, s) of
   806              case (top_level, s) of
   799                (_, "c_False") => (`I tptp_false, [])
   807                (_, "c_False") => (`I tptp_false, [])
   800              | (_, "c_True") => (`I tptp_true, [])
   808              | (_, "c_True") => (`I tptp_true, [])
   801              | (false, "c_Not") => (`I tptp_not, [])
   809              | (false, "c_Not") => (`I tptp_not, [])
  1282    ("fimplies",
  1290    ("fimplies",
  1283     (false, @{lemma "P | fimplies P Q" "~ Q | fimplies P Q"
  1291     (false, @{lemma "P | fimplies P Q" "~ Q | fimplies P Q"
  1284                     "~ fimplies P Q | ~ P | Q"
  1292                     "~ fimplies P Q | ~ P | Q"
  1285                 by (unfold fimplies_def) fast+})),
  1293                 by (unfold fimplies_def) fast+})),
  1286    ("If", (true, @{thms if_True if_False True_or_False}))]
  1294    ("If", (true, @{thms if_True if_False True_or_False}))]
       
  1295   |> map (apsnd (apsnd (map zero_var_indexes)))
  1287 
  1296 
  1288 val type_tag = `make_fixed_const type_tag_name
  1297 val type_tag = `make_fixed_const type_tag_name
  1289 
  1298 
  1290 fun ti_ti_helper_fact () =
  1299 fun type_tag_idempotence_fact () =
  1291   let
  1300   let
  1292     fun var s = ATerm (`I s, [])
  1301     fun var s = ATerm (`I s, [])
  1293     fun tag tm = ATerm (type_tag, [var "X", tm])
  1302     fun tag tm = ATerm (type_tag, [var "T", tm])
       
  1303     val tagged_x = tag (var "X")
  1294   in
  1304   in
  1295     Formula (helper_prefix ^ "ti_ti", Axiom,
  1305     Formula (type_tag_idempotence_helper_name, Axiom,
  1296              AAtom (ATerm (`I tptp_equal, [tag (tag (var "Y")), tag (var "Y")]))
  1306              AAtom (ATerm (`I tptp_equal, [tag tagged_x, tagged_x]))
  1297              |> close_formula_universally, simp_info, NONE)
  1307              |> close_formula_universally, simp_info, NONE)
  1298   end
  1308   end
       
  1309 
       
  1310 fun should_specialize_helper type_sys t =
       
  1311   case general_type_arg_policy type_sys of
       
  1312     Mangled_Type_Args _ => not (null (Term.hidden_polymorphism t))
       
  1313   | _ => false
  1299 
  1314 
  1300 fun helper_facts_for_sym ctxt format type_sys (s, {types, ...} : sym_info) =
  1315 fun helper_facts_for_sym ctxt format type_sys (s, {types, ...} : sym_info) =
  1301   case strip_prefix_and_unascii const_prefix s of
  1316   case strip_prefix_and_unascii const_prefix s of
  1302     SOME mangled_s =>
  1317     SOME mangled_s =>
  1303     let
  1318     let
  1304       val thy = Proof_Context.theory_of ctxt
  1319       val thy = Proof_Context.theory_of ctxt
  1305       val unmangled_s = mangled_s |> unmangled_const_name
  1320       val unmangled_s = mangled_s |> unmangled_const_name
  1306       fun dub_and_inst c needs_fairly_sound (th, j) =
  1321       fun dub_and_inst needs_fairly_sound (th, j) =
  1307         ((c ^ "_" ^ string_of_int j ^
  1322         ((unmangled_s ^ "_" ^ string_of_int j ^
       
  1323           (if mangled_s = unmangled_s then "" else "_" ^ ascii_of mangled_s) ^
  1308           (if needs_fairly_sound then typed_helper_suffix
  1324           (if needs_fairly_sound then typed_helper_suffix
  1309            else untyped_helper_suffix),
  1325            else untyped_helper_suffix),
  1310           General),
  1326           General),
  1311          let val t = th |> prop_of in
  1327          let val t = th |> prop_of in
  1312            t |> ((case general_type_arg_policy type_sys of
  1328            t |> should_specialize_helper type_sys t
  1313                     Mangled_Type_Args _ => true
       
  1314                   | _ => false) andalso
       
  1315                  not (null (Term.hidden_polymorphism t)))
       
  1316                 ? (case types of
  1329                 ? (case types of
  1317                      [T] => specialize_type thy (invert_const unmangled_s, T)
  1330                      [T] => specialize_type thy (invert_const unmangled_s, T)
  1318                    | _ => I)
  1331                    | _ => I)
  1319          end)
  1332          end)
  1320       fun make_facts eq_as_iff =
  1333       val make_facts =
  1321         map_filter (make_fact ctxt format type_sys true false eq_as_iff false)
  1334         map_filter (make_fact ctxt format type_sys false false false false)
  1322       val fairly_sound = is_type_sys_fairly_sound type_sys
  1335       val fairly_sound = is_type_sys_fairly_sound type_sys
  1323     in
  1336     in
  1324       helper_table
  1337       helper_table
  1325       |> maps (fn (metis_s, (needs_fairly_sound, ths)) =>
  1338       |> maps (fn (helper_s, (needs_fairly_sound, ths)) =>
  1326                   if metis_s <> unmangled_s orelse
  1339                   if helper_s <> unmangled_s orelse
  1327                      (needs_fairly_sound andalso not fairly_sound) then
  1340                      (needs_fairly_sound andalso not fairly_sound) then
  1328                     []
  1341                     []
  1329                   else
  1342                   else
  1330                     ths ~~ (1 upto length ths)
  1343                     ths ~~ (1 upto length ths)
  1331                     |> map (dub_and_inst mangled_s needs_fairly_sound)
  1344                     |> map (dub_and_inst needs_fairly_sound)
  1332                     |> make_facts (not needs_fairly_sound))
  1345                     |> make_facts)
  1333     end
  1346     end
  1334   | NONE => []
  1347   | NONE => []
  1335 fun helper_facts_for_sym_table ctxt format type_sys sym_tab =
  1348 fun helper_facts_for_sym_table ctxt format type_sys sym_tab =
  1336   Symtab.fold_rev (append o helper_facts_for_sym ctxt format type_sys) sym_tab
  1349   Symtab.fold_rev (append o helper_facts_for_sym ctxt format type_sys) sym_tab
  1337                   []
  1350                   []
  1507   |> close_formula_universally
  1520   |> close_formula_universally
  1508 
  1521 
  1509 (* Each fact is given a unique fact number to avoid name clashes (e.g., because
  1522 (* Each fact is given a unique fact number to avoid name clashes (e.g., because
  1510    of monomorphization). The TPTP explicitly forbids name clashes, and some of
  1523    of monomorphization). The TPTP explicitly forbids name clashes, and some of
  1511    the remote provers might care. *)
  1524    the remote provers might care. *)
  1512 fun formula_line_for_fact ctxt format prefix nonmono_Ts type_sys
  1525 fun formula_line_for_fact ctxt format prefix encode freshen nonmono_Ts type_sys
  1513                           (j, formula as {name, locality, kind, ...}) =
  1526                           (j, formula as {name, locality, kind, ...}) =
  1514   Formula (prefix ^ (if polymorphism_of_type_sys type_sys = Polymorphic then ""
  1527   Formula (prefix ^
  1515                      else string_of_int j ^ "_") ^
  1528            (if freshen andalso
  1516            ascii_of name,
  1529                polymorphism_of_type_sys type_sys <> Polymorphic then
       
  1530               string_of_int j ^ "_"
       
  1531             else
       
  1532               "") ^ encode name,
  1517            kind, formula_for_fact ctxt format nonmono_Ts type_sys formula, NONE,
  1533            kind, formula_for_fact ctxt format nonmono_Ts type_sys formula, NONE,
  1518            case locality of
  1534            case locality of
  1519              Intro => intro_info
  1535              Intro => intro_info
  1520            | Elim => elim_info
  1536            | Elim => elim_info
  1521            | Simp => simp_info
  1537            | Simp => simp_info
  1772   |> sort_wrt fst
  1788   |> sort_wrt fst
  1773   |> rpair []
  1789   |> rpair []
  1774   |-> fold_rev (append o problem_lines_for_sym_decls ctxt format conj_sym_kind
  1790   |-> fold_rev (append o problem_lines_for_sym_decls ctxt format conj_sym_kind
  1775                                                      nonmono_Ts type_sys)
  1791                                                      nonmono_Ts type_sys)
  1776 
  1792 
  1777 fun should_add_ti_ti_helper (Tags (Polymorphic, level, Heavyweight)) =
  1793 fun needs_type_tag_idempotence (Tags (Polymorphic, level, Heavyweight)) =
  1778     level = Nonmonotonic_Types orelse level = Finite_Types
  1794     level = Nonmonotonic_Types orelse level = Finite_Types
  1779   | should_add_ti_ti_helper _ = false
  1795   | needs_type_tag_idempotence _ = false
  1780 
  1796 
  1781 fun offset_of_heading_in_problem _ [] j = j
  1797 fun offset_of_heading_in_problem _ [] j = j
  1782   | offset_of_heading_in_problem needle ((heading, lines) :: problem) j =
  1798   | offset_of_heading_in_problem needle ((heading, lines) :: problem) j =
  1783     if heading = needle then j
  1799     if heading = needle then j
  1784     else offset_of_heading_in_problem needle problem (j + length lines)
  1800     else offset_of_heading_in_problem needle problem (j + length lines)
  1820       |> sym_decl_table_for_facts ctxt type_sys repaired_sym_tab
  1836       |> sym_decl_table_for_facts ctxt type_sys repaired_sym_tab
  1821       |> problem_lines_for_sym_decl_table ctxt format conj_sym_kind
  1837       |> problem_lines_for_sym_decl_table ctxt format conj_sym_kind
  1822                                           lavish_nonmono_Ts type_sys
  1838                                           lavish_nonmono_Ts type_sys
  1823     val helper_lines =
  1839     val helper_lines =
  1824       0 upto length helpers - 1 ~~ helpers
  1840       0 upto length helpers - 1 ~~ helpers
  1825       |> map (formula_line_for_fact ctxt format helper_prefix lavish_nonmono_Ts
  1841       |> map (formula_line_for_fact ctxt format helper_prefix I false
  1826                                     type_sys)
  1842                                     lavish_nonmono_Ts type_sys)
  1827       |> (if should_add_ti_ti_helper type_sys then cons (ti_ti_helper_fact ())
  1843       |> (if needs_type_tag_idempotence type_sys then
  1828           else I)
  1844             cons (type_tag_idempotence_fact ())
       
  1845           else
       
  1846             I)
  1829     (* Reordering these might confuse the proof reconstruction code or the SPASS
  1847     (* Reordering these might confuse the proof reconstruction code or the SPASS
  1830        FLOTTER hack. *)
  1848        FLOTTER hack. *)
  1831     val problem =
  1849     val problem =
  1832       [(explicit_declsN, sym_decl_lines),
  1850       [(explicit_declsN, sym_decl_lines),
  1833        (factsN,
  1851        (factsN,
  1834         map (formula_line_for_fact ctxt format fact_prefix nonmono_Ts type_sys)
  1852         map (formula_line_for_fact ctxt format fact_prefix ascii_of true
       
  1853                                    nonmono_Ts type_sys)
  1835             (0 upto length facts - 1 ~~ facts)),
  1854             (0 upto length facts - 1 ~~ facts)),
  1836        (class_relsN, map formula_line_for_class_rel_clause class_rel_clauses),
  1855        (class_relsN, map formula_line_for_class_rel_clause class_rel_clauses),
  1837        (aritiesN, map formula_line_for_arity_clause arity_clauses),
  1856        (aritiesN, map formula_line_for_arity_clause arity_clauses),
  1838        (helpersN, helper_lines),
  1857        (helpersN, helper_lines),
  1839        (conjsN,
  1858        (conjsN,