src/HOL/Tools/ATP/atp_translate.ML
changeset 45511 9b0f8ca4388e
parent 45509 624872fc47bf
child 45513 25388cf06437
equal deleted inserted replaced
45510:96696c360b3e 45511:9b0f8ca4388e
    44   val tfree_prefix : string
    44   val tfree_prefix : string
    45   val const_prefix : string
    45   val const_prefix : string
    46   val type_const_prefix : string
    46   val type_const_prefix : string
    47   val class_prefix : string
    47   val class_prefix : string
    48   val lambda_lifted_prefix : string
    48   val lambda_lifted_prefix : string
       
    49   val lambda_lifted_mono_prefix : string
       
    50   val lambda_lifted_poly_prefix : string
    49   val skolem_const_prefix : string
    51   val skolem_const_prefix : string
    50   val old_skolem_const_prefix : string
    52   val old_skolem_const_prefix : string
    51   val new_skolem_const_prefix : string
    53   val new_skolem_const_prefix : string
    52   val type_decl_prefix : string
    54   val type_decl_prefix : string
    53   val sym_decl_prefix : string
    55   val sym_decl_prefix : string
    57   val conjecture_prefix : string
    59   val conjecture_prefix : string
    58   val helper_prefix : string
    60   val helper_prefix : string
    59   val class_rel_clause_prefix : string
    61   val class_rel_clause_prefix : string
    60   val arity_clause_prefix : string
    62   val arity_clause_prefix : string
    61   val tfree_clause_prefix : string
    63   val tfree_clause_prefix : string
       
    64   val lambda_fact_prefix : string
    62   val typed_helper_suffix : string
    65   val typed_helper_suffix : string
    63   val untyped_helper_suffix : string
    66   val untyped_helper_suffix : string
    64   val type_tag_idempotence_helper_name : string
    67   val type_tag_idempotence_helper_name : string
    65   val predicator_name : string
    68   val predicator_name : string
    66   val app_op_name : string
    69   val app_op_name : string
    70   val prefixed_predicator_name : string
    73   val prefixed_predicator_name : string
    71   val prefixed_app_op_name : string
    74   val prefixed_app_op_name : string
    72   val prefixed_type_tag_name : string
    75   val prefixed_type_tag_name : string
    73   val ascii_of : string -> string
    76   val ascii_of : string -> string
    74   val unascii_of : string -> string
    77   val unascii_of : string -> string
    75   val strip_prefix_and_unascii : string -> string -> string option
    78   val unprefix_and_unascii : string -> string -> string option
    76   val proxy_table : (string * (string * (thm * (string * string)))) list
    79   val proxy_table : (string * (string * (thm * (string * string)))) list
    77   val proxify_const : string -> (string * string) option
    80   val proxify_const : string -> (string * string) option
    78   val invert_const : string -> string
    81   val invert_const : string -> string
    79   val unproxify_const : string -> string
    82   val unproxify_const : string -> string
    80   val new_skolem_var_name_from_const : string -> string
    83   val new_skolem_var_name_from_const : string -> string
   226       | un rcs (c :: cs) = un (c :: rcs) cs
   229       | un rcs (c :: cs) = un (c :: rcs) cs
   227   in un [] o String.explode end
   230   in un [] o String.explode end
   228 
   231 
   229 (* If string s has the prefix s1, return the result of deleting it,
   232 (* If string s has the prefix s1, return the result of deleting it,
   230    un-ASCII'd. *)
   233    un-ASCII'd. *)
   231 fun strip_prefix_and_unascii s1 s =
   234 fun unprefix_and_unascii s1 s =
   232   if String.isPrefix s1 s then
   235   if String.isPrefix s1 s then
   233     SOME (unascii_of (String.extract (s, size s1, NONE)))
   236     SOME (unascii_of (String.extract (s, size s1, NONE)))
   234   else
   237   else
   235     NONE
   238     NONE
   236 
   239 
   486   |> space_implode Long_Name.separator
   489   |> space_implode Long_Name.separator
   487 
   490 
   488 fun robust_const_type thy s =
   491 fun robust_const_type thy s =
   489   if s = app_op_name then
   492   if s = app_op_name then
   490     Logic.varifyT_global @{typ "('a => 'b) => 'a => 'b"}
   493     Logic.varifyT_global @{typ "('a => 'b) => 'a => 'b"}
   491   else if String.isPrefix lambda_lifted_poly_prefix s then
   494   else if String.isPrefix lambda_lifted_prefix s then
   492     Logic.varifyT_global @{typ "'a => 'b"}
   495     Logic.varifyT_global @{typ "'a => 'b"}
   493   else
   496   else
   494     (* Old Skolems throw a "TYPE" exception here, which will be caught. *)
   497     (* Old Skolems throw a "TYPE" exception here, which will be caught. *)
   495     s |> Sign.the_const_type thy
   498     s |> Sign.the_const_type thy
   496 
   499 
   498 fun robust_const_typargs thy (s, T) =
   501 fun robust_const_typargs thy (s, T) =
   499   if s = app_op_name then
   502   if s = app_op_name then
   500     let val (T1, T2) = T |> domain_type |> dest_funT in [T1, T2] end
   503     let val (T1, T2) = T |> domain_type |> dest_funT in [T1, T2] end
   501   else if String.isPrefix old_skolem_const_prefix s then
   504   else if String.isPrefix old_skolem_const_prefix s then
   502     [] |> Term.add_tvarsT T |> rev |> map TVar
   505     [] |> Term.add_tvarsT T |> rev |> map TVar
   503   else if String.isPrefix lambda_lifted_poly_prefix s then
   506   else if String.isPrefix lambda_lifted_prefix s then
   504     let val (T1, T2) = T |> dest_funT in [T1, T2] end
   507     if String.isPrefix lambda_lifted_poly_prefix s then
       
   508       let val (T1, T2) = T |> dest_funT in [T1, T2] end
       
   509     else
       
   510       []
   505   else
   511   else
   506     (s, T) |> Sign.const_typargs thy
   512     (s, T) |> Sign.const_typargs thy
   507 
   513 
   508 (* Converts an Isabelle/HOL term (with combinators) into an intermediate term.
   514 (* Converts an Isabelle/HOL term (with combinators) into an intermediate term.
   509    Also accumulates sort infomation. *)
   515    Also accumulates sort infomation. *)
   676   | constify_lifted (Abs (s, T, t)) = Abs (s, T, constify_lifted t)
   682   | constify_lifted (Abs (s, T, t)) = Abs (s, T, constify_lifted t)
   677   | constify_lifted (Free (x as (s, _))) =
   683   | constify_lifted (Free (x as (s, _))) =
   678     (if String.isPrefix lambda_lifted_prefix s then Const else Free) x
   684     (if String.isPrefix lambda_lifted_prefix s then Const else Free) x
   679   | constify_lifted t = t
   685   | constify_lifted t = t
   680 
   686 
       
   687 (* Requires bound variables to have distinct names and not to clash with any
       
   688    schematic variables (as should be the case right after lambda-lifting). *)
       
   689 fun open_form (Const (@{const_name All}, _) $ Abs (s, T, t)) =
       
   690     open_form (subst_bound (Var ((s, 0), T), t))
       
   691   | open_form t = t
       
   692 
   681 fun lift_lambdas ctxt type_enc =
   693 fun lift_lambdas ctxt type_enc =
   682   map (close_form o Envir.eta_contract) #> rpair ctxt
   694   map (Envir.eta_contract #> close_form) #> rpair ctxt
   683   #-> Lambda_Lifting.lift_lambdas
   695   #-> Lambda_Lifting.lift_lambdas
   684           (SOME (if polymorphism_of_type_enc type_enc = Polymorphic then
   696           (SOME (if polymorphism_of_type_enc type_enc = Polymorphic then
   685                    lambda_lifted_poly_prefix
   697                    lambda_lifted_poly_prefix
   686                  else
   698                  else
   687                    lambda_lifted_mono_prefix))
   699                    lambda_lifted_mono_prefix))
   688           Lambda_Lifting.is_quantifier
   700           Lambda_Lifting.is_quantifier
   689   #> fst
   701   #> fst #> pairself (map (open_form o constify_lifted))
   690   #> pairself (map constify_lifted)
       
   691 
   702 
   692 fun intentionalize_def (Const (@{const_name All}, _) $ Abs (_, _, t)) =
   703 fun intentionalize_def (Const (@{const_name All}, _) $ Abs (_, _, t)) =
   693     intentionalize_def t
   704     intentionalize_def t
   694   | intentionalize_def (Const (@{const_name HOL.eq}, _) $ t $ u) =
   705   | intentionalize_def (Const (@{const_name HOL.eq}, _) $ t $ u) =
   695     let
   706     let
   966   if polymorphism_of_type_enc type_enc = Mangled_Monomorphic then
   977   if polymorphism_of_type_enc type_enc = Mangled_Monomorphic then
   967     let
   978     let
   968       fun mangle (IApp (tm1, tm2)) = IApp (mangle tm1, mangle tm2)
   979       fun mangle (IApp (tm1, tm2)) = IApp (mangle tm1, mangle tm2)
   969         | mangle (tm as IConst (_, _, [])) = tm
   980         | mangle (tm as IConst (_, _, [])) = tm
   970         | mangle (tm as IConst (name as (s, _), T, T_args)) =
   981         | mangle (tm as IConst (name as (s, _), T, T_args)) =
   971           (case strip_prefix_and_unascii const_prefix s of
   982           (case unprefix_and_unascii const_prefix s of
   972              NONE => tm
   983              NONE => tm
   973            | SOME s'' =>
   984            | SOME s'' =>
   974              case type_arg_policy type_enc (invert_const s'') of
   985              case type_arg_policy type_enc (invert_const s'') of
   975                Mangled_Type_Args =>
   986                Mangled_Type_Args =>
   976                IConst (mangled_const_name format type_enc T_args name, T, [])
   987                IConst (mangled_const_name format type_enc T_args name, T, [])
  1002 fun filter_type_args_in_iterm thy type_enc =
  1013 fun filter_type_args_in_iterm thy type_enc =
  1003   let
  1014   let
  1004     fun filt ary (IApp (tm1, tm2)) = IApp (filt (ary + 1) tm1, filt 0 tm2)
  1015     fun filt ary (IApp (tm1, tm2)) = IApp (filt (ary + 1) tm1, filt 0 tm2)
  1005       | filt _ (tm as IConst (_, _, [])) = tm
  1016       | filt _ (tm as IConst (_, _, [])) = tm
  1006       | filt ary (IConst (name as (s, _), T, T_args)) =
  1017       | filt ary (IConst (name as (s, _), T, T_args)) =
  1007         (case strip_prefix_and_unascii const_prefix s of
  1018         (case unprefix_and_unascii const_prefix s of
  1008            NONE =>
  1019            NONE =>
  1009            (name,
  1020            (name,
  1010             if level_of_type_enc type_enc = No_Types orelse s = tptp_choice then
  1021             if level_of_type_enc type_enc = No_Types orelse s = tptp_choice then
  1011               []
  1022               []
  1012             else
  1023             else
  1221             |> make_formula ctxt format type_enc (format <> CNF) name loc kind)
  1232             |> make_formula ctxt format type_enc (format <> CNF) name loc kind)
  1222 
  1233 
  1223 (** Finite and infinite type inference **)
  1234 (** Finite and infinite type inference **)
  1224 
  1235 
  1225 fun tvar_footprint thy s ary =
  1236 fun tvar_footprint thy s ary =
  1226   (case strip_prefix_and_unascii const_prefix s of
  1237   (case unprefix_and_unascii const_prefix s of
  1227      SOME s =>
  1238      SOME s =>
  1228      s |> invert_const |> robust_const_type thy |> chop_fun ary |> fst
  1239      s |> invert_const |> robust_const_type thy |> chop_fun ary |> fst
  1229        |> map (fn T => Term.add_tvarsT T [] |> map fst)
  1240        |> map (fn T => Term.add_tvarsT T [] |> map fst)
  1230    | NONE => [])
  1241    | NONE => [])
  1231   handle TYPE _ => []
  1242   handle TYPE _ => []
  1444 
  1455 
  1445 fun min_ary_of sym_tab s =
  1456 fun min_ary_of sym_tab s =
  1446   case Symtab.lookup sym_tab s of
  1457   case Symtab.lookup sym_tab s of
  1447     SOME ({min_ary, ...} : sym_info) => min_ary
  1458     SOME ({min_ary, ...} : sym_info) => min_ary
  1448   | NONE =>
  1459   | NONE =>
  1449     case strip_prefix_and_unascii const_prefix s of
  1460     case unprefix_and_unascii const_prefix s of
  1450       SOME s =>
  1461       SOME s =>
  1451       let val s = s |> unmangled_const_name |> invert_const in
  1462       let val s = s |> unmangled_const_name |> invert_const in
  1452         if s = predicator_name then 1
  1463         if s = predicator_name then 1
  1453         else if s = app_op_name then 2
  1464         else if s = app_op_name then 2
  1454         else if s = type_guard_name then 1
  1465         else if s = type_guard_name then 1
  1579   polymorphism_of_type_enc type_enc <> Polymorphic andalso
  1590   polymorphism_of_type_enc type_enc <> Polymorphic andalso
  1580   level_of_type_enc type_enc <> No_Types andalso
  1591   level_of_type_enc type_enc <> No_Types andalso
  1581   not (null (Term.hidden_polymorphism t))
  1592   not (null (Term.hidden_polymorphism t))
  1582 
  1593 
  1583 fun helper_facts_for_sym ctxt format type_enc (s, {types, ...} : sym_info) =
  1594 fun helper_facts_for_sym ctxt format type_enc (s, {types, ...} : sym_info) =
  1584   case strip_prefix_and_unascii const_prefix s of
  1595   case unprefix_and_unascii const_prefix s of
  1585     SOME mangled_s =>
  1596     SOME mangled_s =>
  1586     let
  1597     let
  1587       val thy = Proof_Context.theory_of ctxt
  1598       val thy = Proof_Context.theory_of ctxt
  1588       val unmangled_s = mangled_s |> unmangled_const_name
  1599       val unmangled_s = mangled_s |> unmangled_const_name
  1589       fun dub needs_fairly_sound j k =
  1600       fun dub needs_fairly_sound j k =
  1655   in add end
  1666   in add end
  1656 
  1667 
  1657 fun type_constrs_of_terms thy ts =
  1668 fun type_constrs_of_terms thy ts =
  1658   Symtab.keys (fold (add_type_constrs_in_term thy) ts Symtab.empty)
  1669   Symtab.keys (fold (add_type_constrs_in_term thy) ts Symtab.empty)
  1659 
  1670 
  1660 val extract_lambda_def =
  1671 fun extract_lambda_def (Const (@{const_name HOL.eq}, _) $ t $ u) =
  1661   let
  1672     let val (head, args) = strip_comb t in
  1662     fun extr [] (@{const Trueprop} $ t) = extr [] t
  1673       (head |> dest_Const |> fst,
  1663       | extr bs (Const (@{const_name All}, _) $ Abs (s, T, t)) =
  1674        fold_rev (fn t as Var ((s, _), T) =>
  1664         extr ((s, T) :: bs) t
  1675                     (fn u => Abs (s, T, abstract_over (t, u)))
  1665       | extr bs (Const (@{const_name HOL.eq}, _) $ t $ u) =
  1676                   | _ => raise Fail "expected Var") args u)
  1666         (t |> head_of |> dest_Const |> fst,
  1677     end
  1667          fold_rev (fn (s, T) => fn u => Abs (s, T, u)) bs u)
  1678   | extract_lambda_def _ = raise Fail "malformed lifted lambda"
  1668       | extr _ _ = raise Fail "malformed lifted lambda"
  1679 
  1669   in extr [] end
  1680 fun translate_formulas ctxt format prem_kind type_enc lambda_trans presimp
  1670 
       
  1671 fun translate_formulas ctxt format prem_kind type_enc trans_lambdas preproc
       
  1672                        hyp_ts concl_t facts =
  1681                        hyp_ts concl_t facts =
  1673   let
  1682   let
  1674     val thy = Proof_Context.theory_of ctxt
  1683     val thy = Proof_Context.theory_of ctxt
       
  1684     val trans_lambdas =
       
  1685       if lambda_trans = no_lambdasN then
       
  1686         rpair []
       
  1687       else if lambda_trans = concealedN then
       
  1688         lift_lambdas ctxt type_enc ##> K []
       
  1689       else if lambda_trans = liftingN then
       
  1690         lift_lambdas ctxt type_enc
       
  1691       else if lambda_trans = combinatorsN then
       
  1692         map (introduce_combinators ctxt) #> rpair []
       
  1693       else if lambda_trans = hybridN then
       
  1694         lift_lambdas ctxt type_enc
       
  1695         ##> maps (fn t => [t, introduce_combinators ctxt
       
  1696                                   (intentionalize_def t)])
       
  1697       else if lambda_trans = lambdasN then
       
  1698         map (Envir.eta_contract) #> rpair []
       
  1699       else
       
  1700         error ("Unknown lambda translation method: " ^
       
  1701                quote lambda_trans ^ ".")
  1675     val presimp_consts = Meson.presimplified_consts ctxt
  1702     val presimp_consts = Meson.presimplified_consts ctxt
  1676     val fact_ts = facts |> map snd
  1703     val fact_ts = facts |> map snd
  1677     (* Remove existing facts from the conjecture, as this can dramatically
  1704     (* Remove existing facts from the conjecture, as this can dramatically
  1678        boost an ATP's performance (for some reason). *)
  1705        boost an ATP's performance (for some reason). *)
  1679     val hyp_ts =
  1706     val hyp_ts =
  1683     val conjs =
  1710     val conjs =
  1684       map (pair prem_kind) hyp_ts @ [(Conjecture, s_not_trueprop concl_t)]
  1711       map (pair prem_kind) hyp_ts @ [(Conjecture, s_not_trueprop concl_t)]
  1685       |> map (apsnd freeze_term)
  1712       |> map (apsnd freeze_term)
  1686       |> map2 (pair o rpair Local o string_of_int) (0 upto length hyp_ts)
  1713       |> map2 (pair o rpair Local o string_of_int) (0 upto length hyp_ts)
  1687     val ((conjs, facts), lambda_facts) =
  1714     val ((conjs, facts), lambda_facts) =
  1688       if preproc then
  1715       (conjs, facts)
  1689         conjs @ facts
  1716       |> presimp
  1690         |> map (apsnd (uncurry (presimp_prop ctxt presimp_consts)))
  1717          ? pairself (map (apsnd (uncurry (presimp_prop ctxt presimp_consts))))
  1691         |> preprocess_abstractions_in_terms trans_lambdas
  1718       |> (if lambda_trans = no_lambdasN then
  1692         |>> chop (length conjs)
  1719             rpair []
  1693       else
  1720           else
  1694         ((conjs, facts), [])
  1721             op @
       
  1722             #> preprocess_abstractions_in_terms trans_lambdas
       
  1723             #>> chop (length conjs))
  1695     val conjs = conjs |> make_conjecture ctxt format type_enc
  1724     val conjs = conjs |> make_conjecture ctxt format type_enc
  1696     val (fact_names, facts) =
  1725     val (fact_names, facts) =
  1697       facts
  1726       facts
  1698       |> map_filter (fn (name, (_, t)) =>
  1727       |> map_filter (fn (name, (_, t)) =>
  1699                         make_fact ctxt format type_enc true (name, t)
  1728                         make_fact ctxt format type_enc true (name, t)
  2113   let
  2142   let
  2114     val thy = Proof_Context.theory_of ctxt
  2143     val thy = Proof_Context.theory_of ctxt
  2115     val (T, T_args) =
  2144     val (T, T_args) =
  2116       if null T_args then
  2145       if null T_args then
  2117         (T, [])
  2146         (T, [])
  2118       else case strip_prefix_and_unascii const_prefix s of
  2147       else case unprefix_and_unascii const_prefix s of
  2119         SOME s' =>
  2148         SOME s' =>
  2120         let
  2149         let
  2121           val s' = s' |> invert_const
  2150           val s' = s' |> invert_const
  2122           val T = s' |> robust_const_type thy
  2151           val T = s' |> robust_const_type thy
  2123         in (T, robust_const_typargs thy (s', T)) end
  2152         in (T, robust_const_typargs thy (s', T)) end
  2321               not (is_type_enc_higher_order type_enc) then
  2350               not (is_type_enc_higher_order type_enc) then
  2322         error ("Lambda translation method incompatible with first-order \
  2351         error ("Lambda translation method incompatible with first-order \
  2323                \encoding.")
  2352                \encoding.")
  2324       else
  2353       else
  2325         lambda_trans
  2354         lambda_trans
  2326     val trans_lambdas =
       
  2327       if lambda_trans = no_lambdasN then
       
  2328         rpair []
       
  2329       else if lambda_trans = concealedN then
       
  2330         lift_lambdas ctxt type_enc ##> K []
       
  2331       else if lambda_trans = liftingN then
       
  2332         lift_lambdas ctxt type_enc
       
  2333       else if lambda_trans = combinatorsN then
       
  2334         map (introduce_combinators ctxt) #> rpair []
       
  2335       else if lambda_trans = hybridN then
       
  2336         lift_lambdas ctxt type_enc
       
  2337         ##> maps (fn t => [t, introduce_combinators ctxt
       
  2338                                   (intentionalize_def t)])
       
  2339       else if lambda_trans = lambdasN then
       
  2340         map (Envir.eta_contract) #> rpair []
       
  2341       else
       
  2342         error ("Unknown lambda translation method: " ^
       
  2343                quote lambda_trans ^ ".")
       
  2344     val (fact_names, classes, conjs, facts, class_rel_clauses, arity_clauses,
  2355     val (fact_names, classes, conjs, facts, class_rel_clauses, arity_clauses,
  2345          lifted) =
  2356          lifted) =
  2346       translate_formulas ctxt format prem_kind type_enc trans_lambdas preproc
  2357       translate_formulas ctxt format prem_kind type_enc lambda_trans preproc
  2347                          hyp_ts concl_t facts
  2358                          hyp_ts concl_t facts
  2348     val sym_tab =
  2359     val sym_tab =
  2349       sym_table_for_facts ctxt type_enc explicit_apply conjs facts
  2360       sym_table_for_facts ctxt type_enc explicit_apply conjs facts
  2350     val mono = conjs @ facts |> mononotonicity_info_for_facts ctxt type_enc
  2361     val mono = conjs @ facts |> mononotonicity_info_for_facts ctxt type_enc
  2351     val firstorderize = firstorderize_fact thy format type_enc sym_tab
  2362     val firstorderize = firstorderize_fact thy format type_enc sym_tab