src/HOL/Tools/Metis/metis_tactics.ML
changeset 43228 2ed2f092e990
parent 43212 050a03afe024
child 43235 3a8d49bc06e1
equal deleted inserted replaced
43227:359c190ede75 43228:2ed2f092e990
     8 *)
     8 *)
     9 
     9 
    10 signature METIS_TACTICS =
    10 signature METIS_TACTICS =
    11 sig
    11 sig
    12   val metisN : string
    12   val metisN : string
    13   val metisFT_N : string
    13   val full_typesN : string
    14   val default_unsound_type_sys : string
    14   val partial_typesN : string
    15   val default_sound_type_sys : string
    15   val no_typesN : string
       
    16   val full_type_sys : string
       
    17   val partial_type_sys : string
       
    18   val no_type_sys : string
    16   val trace : bool Config.T
    19   val trace : bool Config.T
    17   val verbose : bool Config.T
    20   val verbose : bool Config.T
    18   val new_skolemizer : bool Config.T
    21   val new_skolemizer : bool Config.T
    19   val metis_tac : string list -> Proof.context -> thm list -> int -> tactic
    22   val metis_tac : string list -> Proof.context -> thm list -> int -> tactic
    20   val metisFT_tac : Proof.context -> thm list -> int -> tactic
       
    21   val setup : theory -> theory
    23   val setup : theory -> theory
    22 end
    24 end
    23 
    25 
    24 structure Metis_Tactics : METIS_TACTICS =
    26 structure Metis_Tactics : METIS_TACTICS =
    25 struct
    27 struct
    27 open ATP_Translate
    29 open ATP_Translate
    28 open Metis_Translate
    30 open Metis_Translate
    29 open Metis_Reconstruct
    31 open Metis_Reconstruct
    30 
    32 
    31 val metisN = Binding.qualified_name_of @{binding metis}
    33 val metisN = Binding.qualified_name_of @{binding metis}
    32 val metisFT_N = Binding.qualified_name_of @{binding metisFT}
    34 
    33 val full_typesN = "full_types"
    35 val full_typesN = "full_types"
    34 
    36 val partial_typesN = "partial_types"
    35 val default_unsound_type_sys = "poly_args"
    37 val no_typesN = "no_types"
    36 val default_sound_type_sys = "poly_preds_heavy_query"
    38 
       
    39 val full_type_sys = "poly_preds_heavy_query"
       
    40 val partial_type_sys = "poly_args"
       
    41 val no_type_sys = "erased"
       
    42 
       
    43 val type_sys_aliases =
       
    44   [(full_typesN, full_type_sys),
       
    45    (partial_typesN, partial_type_sys),
       
    46    (no_typesN, no_type_sys)]
    37 
    47 
    38 fun method_call_for_type_sys type_sys =
    48 fun method_call_for_type_sys type_sys =
    39   if type_sys = default_sound_type_sys then
    49   metisN ^ " (" ^
    40     (@{binding metisFT}, "")
    50   (case AList.find (op =) type_sys_aliases type_sys of
    41   else
    51      [alias] => alias
    42     (@{binding metis},
    52    | _ => type_sys) ^ ")"
    43      if type_sys = default_unsound_type_sys then "" else type_sys)
       
    44 
    53 
    45 val new_skolemizer =
    54 val new_skolemizer =
    46   Attrib.setup_config_bool @{binding metis_new_skolemizer} (K false)
    55   Attrib.setup_config_bool @{binding metis_new_skolemizer} (K false)
    47 
    56 
    48 (* Designed to work also with monomorphic instances of polymorphic theorems. *)
    57 (* Designed to work also with monomorphic instances of polymorphic theorems. *)
   166          case fallback_type_syss of
   175          case fallback_type_syss of
   167            [] => error ("Failed to replay Metis proof in Isabelle." ^
   176            [] => error ("Failed to replay Metis proof in Isabelle." ^
   168                         (if Config.get ctxt verbose then "\n" ^ loc ^ ": " ^ msg
   177                         (if Config.get ctxt verbose then "\n" ^ loc ^ ": " ^ msg
   169                          else ""))
   178                          else ""))
   170          | type_sys :: _ =>
   179          | type_sys :: _ =>
   171            let val (binding, arg) = method_call_for_type_sys type_sys in
   180            (verbose_warning ctxt
   172              (verbose_warning ctxt
   181                 ("Falling back on " ^
   173                   ("Falling back on " ^
   182                  quote (method_call_for_type_sys type_sys) ^ "...");
   174                    quote (Binding.qualified_name_of binding ^
   183             FOL_SOLVE fallback_type_syss ctxt cls ths0)
   175                           (arg |> arg <> "" ? enclose " (" ")")) ^ "...");
       
   176               FOL_SOLVE fallback_type_syss ctxt cls ths0)
       
   177             end
       
   178 
   184 
   179 val neg_clausify =
   185 val neg_clausify =
   180   single
   186   single
   181   #> Meson.make_clauses_unsorted
   187   #> Meson.make_clauses_unsorted
   182   #> map Meson_Clausify.introduce_combinators_in_theorem
   188   #> map Meson_Clausify.introduce_combinators_in_theorem
   205        Seq.empty)
   211        Seq.empty)
   206     else
   212     else
   207       Meson.MESON (preskolem_tac ctxt) (maps neg_clausify) tac ctxt i st0
   213       Meson.MESON (preskolem_tac ctxt) (maps neg_clausify) tac ctxt i st0
   208   end
   214   end
   209 
   215 
   210 val metis_default_type_syss = [default_unsound_type_sys, default_sound_type_sys]
   216 val metis_default_type_syss = [partial_type_sys, full_type_sys]
   211 val metisFT_type_syss = [default_sound_type_sys]
   217 val metisFT_type_syss = [full_type_sys]
   212 
   218 
   213 fun metis_tac [] = generic_metis_tac metis_default_type_syss
   219 fun metis_tac [] = generic_metis_tac metis_default_type_syss
   214   | metis_tac type_syss = generic_metis_tac type_syss
   220   | metis_tac type_syss = generic_metis_tac type_syss
   215 val metisFT_tac = generic_metis_tac metisFT_type_syss
       
   216 
   221 
   217 (* Whenever "X" has schematic type variables, we treat "using X by metis" as
   222 (* Whenever "X" has schematic type variables, we treat "using X by metis" as
   218    "by (metis X)" to prevent "Subgoal.FOCUS" from freezing the type variables.
   223    "by (metis X)" to prevent "Subgoal.FOCUS" from freezing the type variables.
   219    We don't do it for nonschematic facts "X" because this breaks a few proofs
   224    We don't do it for nonschematic facts "X" because this breaks a few proofs
   220    (in the rare and subtle case where a proof relied on extensionality not being
   225    (in the rare and subtle case where a proof relied on extensionality not being
   222 val has_tvar =
   227 val has_tvar =
   223   exists_type (exists_subtype (fn TVar _ => true | _ => false)) o prop_of
   228   exists_type (exists_subtype (fn TVar _ => true | _ => false)) o prop_of
   224 
   229 
   225 fun method type_syss (type_sys, ths) ctxt facts =
   230 fun method type_syss (type_sys, ths) ctxt facts =
   226   let
   231   let
       
   232     val _ =
       
   233       if type_syss = metisFT_type_syss then
       
   234         legacy_feature "Old 'metisFT' method -- \
       
   235                        \use 'metis (full_types)' instead"
       
   236       else
       
   237         ()
   227     val (schem_facts, nonschem_facts) = List.partition has_tvar facts
   238     val (schem_facts, nonschem_facts) = List.partition has_tvar facts
   228     val type_syss = type_sys |> Option.map single |> the_default type_syss
   239     val type_syss = type_sys |> Option.map single |> the_default type_syss
   229   in
   240   in
   230     HEADGOAL (Method.insert_tac nonschem_facts THEN'
   241     HEADGOAL (Method.insert_tac nonschem_facts THEN'
   231               CHANGED_PROP
   242               CHANGED_PROP
   232               o generic_metis_tac type_syss ctxt (schem_facts @ ths))
   243               o generic_metis_tac type_syss ctxt (schem_facts @ ths))
   233   end
   244   end
   234 
   245 
   235 fun setup_method (type_syss as type_sys :: _) =
   246 fun setup_method (binding, type_syss as type_sys :: _) =
   236   (if type_syss = metis_default_type_syss then
   247   (if type_syss = metis_default_type_syss then
   237      (Args.parens Parse.short_ident
   248      (Args.parens Parse.short_ident
   238       >> (fn s => if s = full_typesN then default_sound_type_sys else s))
   249       >> (fn s => AList.lookup (op =) type_sys_aliases s |> the_default s))
   239      |> Scan.option |> Scan.lift
   250      |> Scan.option |> Scan.lift
   240    else
   251    else
   241      Scan.succeed NONE)
   252      Scan.succeed NONE)
   242   -- Attrib.thms >> (METHOD oo method type_syss)
   253   -- Attrib.thms >> (METHOD oo method type_syss)
   243   |> Method.setup (fst (method_call_for_type_sys type_sys))
   254   |> Method.setup binding
   244 
   255 
   245 val setup =
   256 val setup =
   246   [(metis_default_type_syss, "Metis for FOL and HOL problems"),
   257   [((@{binding metis}, metis_default_type_syss),
   247    (metisFT_type_syss,
   258     "Metis for FOL and HOL problems"),
       
   259    ((@{binding metisFT}, metisFT_type_syss),
   248     "Metis for FOL/HOL problems with fully-typed translation")]
   260     "Metis for FOL/HOL problems with fully-typed translation")]
   249   |> fold (uncurry setup_method)
   261   |> fold (uncurry setup_method)
   250 
   262 
   251 end;
   263 end;