src/HOL/Tools/Sledgehammer/metis_tactics.ML
changeset 35865 2f8fb5242799
parent 35826 1590abc3d42a
child 36001 992839c4be90
equal deleted inserted replaced
35843:23908b4dbc2f 35865:2f8fb5242799
    16 end
    16 end
    17 
    17 
    18 structure Metis_Tactics : METIS_TACTICS =
    18 structure Metis_Tactics : METIS_TACTICS =
    19 struct
    19 struct
    20 
    20 
    21 structure SFC = Sledgehammer_FOL_Clause
    21 open Sledgehammer_FOL_Clause
    22 structure SHC = Sledgehammer_HOL_Clause
    22 open Sledgehammer_Fact_Preprocessor
    23 structure SPR = Sledgehammer_Proof_Reconstruct
    23 open Sledgehammer_HOL_Clause
       
    24 open Sledgehammer_Proof_Reconstruct
       
    25 open Sledgehammer_Fact_Filter
    24 
    26 
    25 val trace = Unsynchronized.ref false;
    27 val trace = Unsynchronized.ref false;
    26 fun trace_msg msg = if !trace then tracing (msg ()) else ();
    28 fun trace_msg msg = if !trace then tracing (msg ()) else ();
    27 
    29 
    28 val (type_lits, type_lits_setup) = Attrib.config_bool "metis_type_lits" true;
    30 val (type_lits, type_lits_setup) = Attrib.config_bool "metis_type_lits" true;
    65 fun fn_isa_to_met "equal" = "="
    67 fun fn_isa_to_met "equal" = "="
    66   | fn_isa_to_met x       = x;
    68   | fn_isa_to_met x       = x;
    67 
    69 
    68 fun metis_lit b c args = (b, (c, args));
    70 fun metis_lit b c args = (b, (c, args));
    69 
    71 
    70 fun hol_type_to_fol (SFC.AtomV x) = Metis.Term.Var x
    72 fun hol_type_to_fol (AtomV x) = Metis.Term.Var x
    71   | hol_type_to_fol (SFC.AtomF x) = Metis.Term.Fn(x,[])
    73   | hol_type_to_fol (AtomF x) = Metis.Term.Fn (x, [])
    72   | hol_type_to_fol (SFC.Comp(tc,tps)) = Metis.Term.Fn(tc, map hol_type_to_fol tps);
    74   | hol_type_to_fol (Comp (tc, tps)) =
       
    75     Metis.Term.Fn (tc, map hol_type_to_fol tps);
    73 
    76 
    74 (*These two functions insert type literals before the real literals. That is the
    77 (*These two functions insert type literals before the real literals. That is the
    75   opposite order from TPTP linkup, but maybe OK.*)
    78   opposite order from TPTP linkup, but maybe OK.*)
    76 
    79 
    77 fun hol_term_to_fol_FO tm =
    80 fun hol_term_to_fol_FO tm =
    78   case SHC.strip_comb tm of
    81   case strip_combterm_comb tm of
    79       (SHC.CombConst(c,_,tys), tms) =>
    82       (CombConst(c,_,tys), tms) =>
    80         let val tyargs = map hol_type_to_fol tys
    83         let val tyargs = map hol_type_to_fol tys
    81             val args   = map hol_term_to_fol_FO tms
    84             val args   = map hol_term_to_fol_FO tms
    82         in Metis.Term.Fn (c, tyargs @ args) end
    85         in Metis.Term.Fn (c, tyargs @ args) end
    83     | (SHC.CombVar(v,_), []) => Metis.Term.Var v
    86     | (CombVar(v,_), []) => Metis.Term.Var v
    84     | _ => error "hol_term_to_fol_FO";
    87     | _ => error "hol_term_to_fol_FO";
    85 
    88 
    86 fun hol_term_to_fol_HO (SHC.CombVar (a, _)) = Metis.Term.Var a
    89 fun hol_term_to_fol_HO (CombVar (a, _)) = Metis.Term.Var a
    87   | hol_term_to_fol_HO (SHC.CombConst (a, _, tylist)) =
    90   | hol_term_to_fol_HO (CombConst (a, _, tylist)) =
    88       Metis.Term.Fn (fn_isa_to_met a, map hol_type_to_fol tylist)
    91       Metis.Term.Fn (fn_isa_to_met a, map hol_type_to_fol tylist)
    89   | hol_term_to_fol_HO (SHC.CombApp (tm1, tm2)) =
    92   | hol_term_to_fol_HO (CombApp (tm1, tm2)) =
    90        Metis.Term.Fn (".", map hol_term_to_fol_HO [tm1, tm2]);
    93        Metis.Term.Fn (".", map hol_term_to_fol_HO [tm1, tm2]);
    91 
    94 
    92 (*The fully-typed translation, to avoid type errors*)
    95 (*The fully-typed translation, to avoid type errors*)
    93 fun wrap_type (tm, ty) = Metis.Term.Fn("ti", [tm, hol_type_to_fol ty]);
    96 fun wrap_type (tm, ty) = Metis.Term.Fn("ti", [tm, hol_type_to_fol ty]);
    94 
    97 
    95 fun hol_term_to_fol_FT (SHC.CombVar(a, ty)) =
    98 fun hol_term_to_fol_FT (CombVar(a, ty)) = wrap_type (Metis.Term.Var a, ty)
    96       wrap_type (Metis.Term.Var a, ty)
    99   | hol_term_to_fol_FT (CombConst(a, ty, _)) =
    97   | hol_term_to_fol_FT (SHC.CombConst(a, ty, _)) =
       
    98       wrap_type (Metis.Term.Fn(fn_isa_to_met a, []), ty)
   100       wrap_type (Metis.Term.Fn(fn_isa_to_met a, []), ty)
    99   | hol_term_to_fol_FT (tm as SHC.CombApp(tm1,tm2)) =
   101   | hol_term_to_fol_FT (tm as CombApp(tm1,tm2)) =
   100        wrap_type (Metis.Term.Fn(".", map hol_term_to_fol_FT [tm1,tm2]),
   102        wrap_type (Metis.Term.Fn(".", map hol_term_to_fol_FT [tm1,tm2]),
   101                   SHC.type_of_combterm tm);
   103                   type_of_combterm tm);
   102 
   104 
   103 fun hol_literal_to_fol FO (SHC.Literal (pol, tm)) =
   105 fun hol_literal_to_fol FO (Literal (pol, tm)) =
   104       let val (SHC.CombConst(p,_,tys), tms) = SHC.strip_comb tm
   106       let val (CombConst(p,_,tys), tms) = strip_combterm_comb tm
   105           val tylits = if p = "equal" then [] else map hol_type_to_fol tys
   107           val tylits = if p = "equal" then [] else map hol_type_to_fol tys
   106           val lits = map hol_term_to_fol_FO tms
   108           val lits = map hol_term_to_fol_FO tms
   107       in metis_lit pol (fn_isa_to_met p) (tylits @ lits) end
   109       in metis_lit pol (fn_isa_to_met p) (tylits @ lits) end
   108   | hol_literal_to_fol HO (SHC.Literal (pol, tm)) =
   110   | hol_literal_to_fol HO (Literal (pol, tm)) =
   109      (case SHC.strip_comb tm of
   111      (case strip_combterm_comb tm of
   110           (SHC.CombConst("equal",_,_), tms) =>
   112           (CombConst("equal",_,_), tms) =>
   111             metis_lit pol "=" (map hol_term_to_fol_HO tms)
   113             metis_lit pol "=" (map hol_term_to_fol_HO tms)
   112         | _ => metis_lit pol "{}" [hol_term_to_fol_HO tm])   (*hBOOL*)
   114         | _ => metis_lit pol "{}" [hol_term_to_fol_HO tm])   (*hBOOL*)
   113   | hol_literal_to_fol FT (SHC.Literal (pol, tm)) =
   115   | hol_literal_to_fol FT (Literal (pol, tm)) =
   114      (case SHC.strip_comb tm of
   116      (case strip_combterm_comb tm of
   115           (SHC.CombConst("equal",_,_), tms) =>
   117           (CombConst("equal",_,_), tms) =>
   116             metis_lit pol "=" (map hol_term_to_fol_FT tms)
   118             metis_lit pol "=" (map hol_term_to_fol_FT tms)
   117         | _ => metis_lit pol "{}" [hol_term_to_fol_FT tm])   (*hBOOL*);
   119         | _ => metis_lit pol "{}" [hol_term_to_fol_FT tm])   (*hBOOL*);
   118 
   120 
   119 fun literals_of_hol_thm thy mode t =
   121 fun literals_of_hol_thm thy mode t =
   120       let val (lits, types_sorts) = SHC.literals_of_term thy t
   122       let val (lits, types_sorts) = literals_of_term thy t
   121       in  (map (hol_literal_to_fol mode) lits, types_sorts) end;
   123       in  (map (hol_literal_to_fol mode) lits, types_sorts) end;
   122 
   124 
   123 (*Sign should be "true" for conjecture type constraints, "false" for type lits in clauses.*)
   125 (*Sign should be "true" for conjecture type constraints, "false" for type lits in clauses.*)
   124 fun metis_of_typeLit pos (SFC.LTVar (s,x))  = metis_lit pos s [Metis.Term.Var x]
   126 fun metis_of_typeLit pos (LTVar (s,x))  = metis_lit pos s [Metis.Term.Var x]
   125   | metis_of_typeLit pos (SFC.LTFree (s,x)) = metis_lit pos s [Metis.Term.Fn(x,[])];
   127   | metis_of_typeLit pos (LTFree (s,x)) = metis_lit pos s [Metis.Term.Fn(x,[])];
   126 
   128 
   127 fun default_sort _ (TVar _) = false
   129 fun default_sort _ (TVar _) = false
   128   | default_sort ctxt (TFree (x, s)) = (s = the_default [] (Variable.def_sort ctxt (x, ~1)));
   130   | default_sort ctxt (TFree (x, s)) = (s = the_default [] (Variable.def_sort ctxt (x, ~1)));
   129 
   131 
   130 fun metis_of_tfree tf =
   132 fun metis_of_tfree tf =
   134   let val thy = ProofContext.theory_of ctxt
   136   let val thy = ProofContext.theory_of ctxt
   135       val (mlits, types_sorts) =
   137       val (mlits, types_sorts) =
   136              (literals_of_hol_thm thy mode o HOLogic.dest_Trueprop o prop_of) th
   138              (literals_of_hol_thm thy mode o HOLogic.dest_Trueprop o prop_of) th
   137   in
   139   in
   138       if is_conjecture then
   140       if is_conjecture then
   139           (Metis.Thm.axiom (Metis.LiteralSet.fromList mlits), SFC.add_typs types_sorts)
   141           (Metis.Thm.axiom (Metis.LiteralSet.fromList mlits), add_typs types_sorts)
   140       else
   142       else
   141         let val tylits = SFC.add_typs
   143         let val tylits = add_typs (filter (not o default_sort ctxt) types_sorts)
   142                            (filter (not o default_sort ctxt) types_sorts)
       
   143             val mtylits = if Config.get ctxt type_lits
   144             val mtylits = if Config.get ctxt type_lits
   144                           then map (metis_of_typeLit false) tylits else []
   145                           then map (metis_of_typeLit false) tylits else []
   145         in
   146         in
   146           (Metis.Thm.axiom (Metis.LiteralSet.fromList(mtylits @ mlits)), [])
   147           (Metis.Thm.axiom (Metis.LiteralSet.fromList(mtylits @ mlits)), [])
   147         end
   148         end
   148   end;
   149   end;
   149 
   150 
   150 (* ARITY CLAUSE *)
   151 (* ARITY CLAUSE *)
   151 
   152 
   152 fun m_arity_cls (SFC.TConsLit (c,t,args)) =
   153 fun m_arity_cls (TConsLit (c,t,args)) =
   153       metis_lit true (SFC.make_type_class c) [Metis.Term.Fn(t, map Metis.Term.Var args)]
   154       metis_lit true (make_type_class c) [Metis.Term.Fn(t, map Metis.Term.Var args)]
   154   | m_arity_cls (SFC.TVarLit (c,str))     =
   155   | m_arity_cls (TVarLit (c,str))     =
   155       metis_lit false (SFC.make_type_class c) [Metis.Term.Var str];
   156       metis_lit false (make_type_class c) [Metis.Term.Var str];
   156 
   157 
   157 (*TrueI is returned as the Isabelle counterpart because there isn't any.*)
   158 (*TrueI is returned as the Isabelle counterpart because there isn't any.*)
   158 fun arity_cls (SFC.ArityClause{conclLit,premLits,...}) =
   159 fun arity_cls (ArityClause {conclLit, premLits, ...}) =
   159   (TrueI,
   160   (TrueI,
   160    Metis.Thm.axiom (Metis.LiteralSet.fromList (map m_arity_cls (conclLit :: premLits))));
   161    Metis.Thm.axiom (Metis.LiteralSet.fromList (map m_arity_cls (conclLit :: premLits))));
   161 
   162 
   162 (* CLASSREL CLAUSE *)
   163 (* CLASSREL CLAUSE *)
   163 
   164 
   164 fun m_classrel_cls subclass superclass =
   165 fun m_classrel_cls subclass superclass =
   165   [metis_lit false subclass [Metis.Term.Var "T"], metis_lit true superclass [Metis.Term.Var "T"]];
   166   [metis_lit false subclass [Metis.Term.Var "T"], metis_lit true superclass [Metis.Term.Var "T"]];
   166 
   167 
   167 fun classrel_cls (SFC.ClassrelClause {subclass, superclass, ...}) =
   168 fun classrel_cls (ClassrelClause {subclass, superclass, ...}) =
   168   (TrueI, Metis.Thm.axiom (Metis.LiteralSet.fromList (m_classrel_cls subclass superclass)));
   169   (TrueI, Metis.Thm.axiom (Metis.LiteralSet.fromList (m_classrel_cls subclass superclass)));
   169 
   170 
   170 (* ------------------------------------------------------------------------- *)
   171 (* ------------------------------------------------------------------------- *)
   171 (* FOL to HOL  (Metis to Isabelle)                                           *)
   172 (* FOL to HOL  (Metis to Isabelle)                                           *)
   172 (* ------------------------------------------------------------------------- *)
   173 (* ------------------------------------------------------------------------- *)
   211 (*Remove the "apply" operator from an HO term*)
   212 (*Remove the "apply" operator from an HO term*)
   212 fun strip_happ args (Metis.Term.Fn(".",[t,u])) = strip_happ (u::args) t
   213 fun strip_happ args (Metis.Term.Fn(".",[t,u])) = strip_happ (u::args) t
   213   | strip_happ args x = (x, args);
   214   | strip_happ args x = (x, args);
   214 
   215 
   215 fun fol_type_to_isa _ (Metis.Term.Var v) =
   216 fun fol_type_to_isa _ (Metis.Term.Var v) =
   216      (case SPR.strip_prefix SFC.tvar_prefix v of
   217      (case strip_prefix tvar_prefix v of
   217           SOME w => SPR.make_tvar w
   218           SOME w => make_tvar w
   218         | NONE   => SPR.make_tvar v)
   219         | NONE   => make_tvar v)
   219   | fol_type_to_isa ctxt (Metis.Term.Fn(x, tys)) =
   220   | fol_type_to_isa ctxt (Metis.Term.Fn(x, tys)) =
   220      (case SPR.strip_prefix SFC.tconst_prefix x of
   221      (case strip_prefix tconst_prefix x of
   221           SOME tc => Term.Type (SPR.invert_type_const tc, map (fol_type_to_isa ctxt) tys)
   222           SOME tc => Term.Type (invert_type_const tc, map (fol_type_to_isa ctxt) tys)
   222         | NONE    =>
   223         | NONE    =>
   223       case SPR.strip_prefix SFC.tfree_prefix x of
   224       case strip_prefix tfree_prefix x of
   224           SOME tf => mk_tfree ctxt tf
   225           SOME tf => mk_tfree ctxt tf
   225         | NONE    => error ("fol_type_to_isa: " ^ x));
   226         | NONE    => error ("fol_type_to_isa: " ^ x));
   226 
   227 
   227 (*Maps metis terms to isabelle terms*)
   228 (*Maps metis terms to isabelle terms*)
   228 fun fol_term_to_hol_RAW ctxt fol_tm =
   229 fun fol_term_to_hol_RAW ctxt fol_tm =
   229   let val thy = ProofContext.theory_of ctxt
   230   let val thy = ProofContext.theory_of ctxt
   230       val _ = trace_msg (fn () => "fol_term_to_hol: " ^ Metis.Term.toString fol_tm)
   231       val _ = trace_msg (fn () => "fol_term_to_hol: " ^ Metis.Term.toString fol_tm)
   231       fun tm_to_tt (Metis.Term.Var v) =
   232       fun tm_to_tt (Metis.Term.Var v) =
   232              (case SPR.strip_prefix SFC.tvar_prefix v of
   233              (case strip_prefix tvar_prefix v of
   233                   SOME w => Type (SPR.make_tvar w)
   234                   SOME w => Type (make_tvar w)
   234                 | NONE =>
   235                 | NONE =>
   235               case SPR.strip_prefix SFC.schematic_var_prefix v of
   236               case strip_prefix schematic_var_prefix v of
   236                   SOME w => Term (mk_var (w, HOLogic.typeT))
   237                   SOME w => Term (mk_var (w, HOLogic.typeT))
   237                 | NONE   => Term (mk_var (v, HOLogic.typeT)) )
   238                 | NONE   => Term (mk_var (v, HOLogic.typeT)) )
   238                     (*Var from Metis with a name like _nnn; possibly a type variable*)
   239                     (*Var from Metis with a name like _nnn; possibly a type variable*)
   239         | tm_to_tt (Metis.Term.Fn ("{}", [arg])) = tm_to_tt arg   (*hBOOL*)
   240         | tm_to_tt (Metis.Term.Fn ("{}", [arg])) = tm_to_tt arg   (*hBOOL*)
   240         | tm_to_tt (t as Metis.Term.Fn (".",_)) =
   241         | tm_to_tt (t as Metis.Term.Fn (".",_)) =
   245                              Term t => Term (list_comb(t, terms_of (map tm_to_tt rands)))
   246                              Term t => Term (list_comb(t, terms_of (map tm_to_tt rands)))
   246                            | _ => error "tm_to_tt: HO application"
   247                            | _ => error "tm_to_tt: HO application"
   247             end
   248             end
   248         | tm_to_tt (Metis.Term.Fn (fname, args)) = applic_to_tt (fname,args)
   249         | tm_to_tt (Metis.Term.Fn (fname, args)) = applic_to_tt (fname,args)
   249       and applic_to_tt ("=",ts) =
   250       and applic_to_tt ("=",ts) =
   250             Term (list_comb(Const ("op =", HOLogic.typeT), terms_of (map tm_to_tt ts)))
   251             Term (list_comb(Const (@{const_name "op ="}, HOLogic.typeT), terms_of (map tm_to_tt ts)))
   251         | applic_to_tt (a,ts) =
   252         | applic_to_tt (a,ts) =
   252             case SPR.strip_prefix SFC.const_prefix a of
   253             case strip_prefix const_prefix a of
   253                 SOME b =>
   254                 SOME b =>
   254                   let val c = SPR.invert_const b
   255                   let val c = invert_const b
   255                       val ntypes = SPR.num_typargs thy c
   256                       val ntypes = num_typargs thy c
   256                       val nterms = length ts - ntypes
   257                       val nterms = length ts - ntypes
   257                       val tts = map tm_to_tt ts
   258                       val tts = map tm_to_tt ts
   258                       val tys = types_of (List.take(tts,ntypes))
   259                       val tys = types_of (List.take(tts,ntypes))
   259                       val ntyargs = SPR.num_typargs thy c
   260                       val ntyargs = num_typargs thy c
   260                   in if length tys = ntyargs then
   261                   in if length tys = ntyargs then
   261                          apply_list (Const (c, dummyT)) nterms (List.drop(tts,ntypes))
   262                          apply_list (Const (c, dummyT)) nterms (List.drop(tts,ntypes))
   262                      else error ("Constant " ^ c ^ " expects " ^ Int.toString ntyargs ^
   263                      else error ("Constant " ^ c ^ " expects " ^ Int.toString ntyargs ^
   263                                  " but gets " ^ Int.toString (length tys) ^
   264                                  " but gets " ^ Int.toString (length tys) ^
   264                                  " type arguments\n" ^
   265                                  " type arguments\n" ^
   265                                  cat_lines (map (Syntax.string_of_typ ctxt) tys) ^
   266                                  cat_lines (map (Syntax.string_of_typ ctxt) tys) ^
   266                                  " the terms are \n" ^
   267                                  " the terms are \n" ^
   267                                  cat_lines (map (Syntax.string_of_term ctxt) (terms_of tts)))
   268                                  cat_lines (map (Syntax.string_of_term ctxt) (terms_of tts)))
   268                      end
   269                      end
   269               | NONE => (*Not a constant. Is it a type constructor?*)
   270               | NONE => (*Not a constant. Is it a type constructor?*)
   270             case SPR.strip_prefix SFC.tconst_prefix a of
   271             case strip_prefix tconst_prefix a of
   271                 SOME b =>
   272                 SOME b =>
   272                   Type (Term.Type (SPR.invert_type_const b, types_of (map tm_to_tt ts)))
   273                   Type (Term.Type (invert_type_const b, types_of (map tm_to_tt ts)))
   273               | NONE => (*Maybe a TFree. Should then check that ts=[].*)
   274               | NONE => (*Maybe a TFree. Should then check that ts=[].*)
   274             case SPR.strip_prefix SFC.tfree_prefix a of
   275             case strip_prefix tfree_prefix a of
   275                 SOME b => Type (mk_tfree ctxt b)
   276                 SOME b => Type (mk_tfree ctxt b)
   276               | NONE => (*a fixed variable? They are Skolem functions.*)
   277               | NONE => (*a fixed variable? They are Skolem functions.*)
   277             case SPR.strip_prefix SFC.fixed_var_prefix a of
   278             case strip_prefix fixed_var_prefix a of
   278                 SOME b =>
   279                 SOME b =>
   279                   let val opr = Term.Free(b, HOLogic.typeT)
   280                   let val opr = Term.Free(b, HOLogic.typeT)
   280                   in  apply_list opr (length ts) (map tm_to_tt ts)  end
   281                   in  apply_list opr (length ts) (map tm_to_tt ts)  end
   281               | NONE => error ("unexpected metis function: " ^ a)
   282               | NONE => error ("unexpected metis function: " ^ a)
   282   in  case tm_to_tt fol_tm of Term t => t | _ => error "fol_tm_to_tt: Term expected"  end;
   283   in  case tm_to_tt fol_tm of Term t => t | _ => error "fol_tm_to_tt: Term expected"  end;
   283 
   284 
   284 (*Maps fully-typed metis terms to isabelle terms*)
   285 (*Maps fully-typed metis terms to isabelle terms*)
   285 fun fol_term_to_hol_FT ctxt fol_tm =
   286 fun fol_term_to_hol_FT ctxt fol_tm =
   286   let val _ = trace_msg (fn () => "fol_term_to_hol_FT: " ^ Metis.Term.toString fol_tm)
   287   let val _ = trace_msg (fn () => "fol_term_to_hol_FT: " ^ Metis.Term.toString fol_tm)
   287       fun cvt (Metis.Term.Fn ("ti", [Metis.Term.Var v, _])) =
   288       fun cvt (Metis.Term.Fn ("ti", [Metis.Term.Var v, _])) =
   288              (case SPR.strip_prefix SFC.schematic_var_prefix v of
   289              (case strip_prefix schematic_var_prefix v of
   289                   SOME w =>  mk_var(w, dummyT)
   290                   SOME w =>  mk_var(w, dummyT)
   290                 | NONE   => mk_var(v, dummyT))
   291                 | NONE   => mk_var(v, dummyT))
   291         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn ("=",[]), _])) =
   292         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn ("=",[]), _])) =
   292             Const ("op =", HOLogic.typeT)
   293             Const ("op =", HOLogic.typeT)
   293         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn (x,[]), ty])) =
   294         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn (x,[]), ty])) =
   294            (case SPR.strip_prefix SFC.const_prefix x of
   295            (case strip_prefix const_prefix x of
   295                 SOME c => Const (SPR.invert_const c, dummyT)
   296                 SOME c => Const (invert_const c, dummyT)
   296               | NONE => (*Not a constant. Is it a fixed variable??*)
   297               | NONE => (*Not a constant. Is it a fixed variable??*)
   297             case SPR.strip_prefix SFC.fixed_var_prefix x of
   298             case strip_prefix fixed_var_prefix x of
   298                 SOME v => Free (v, fol_type_to_isa ctxt ty)
   299                 SOME v => Free (v, fol_type_to_isa ctxt ty)
   299               | NONE => error ("fol_term_to_hol_FT bad constant: " ^ x))
   300               | NONE => error ("fol_term_to_hol_FT bad constant: " ^ x))
   300         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn (".",[tm1,tm2]), _])) =
   301         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn (".",[tm1,tm2]), _])) =
   301             cvt tm1 $ cvt tm2
   302             cvt tm1 $ cvt tm2
   302         | cvt (Metis.Term.Fn (".",[tm1,tm2])) = (*untyped application*)
   303         | cvt (Metis.Term.Fn (".",[tm1,tm2])) = (*untyped application*)
   303             cvt tm1 $ cvt tm2
   304             cvt tm1 $ cvt tm2
   304         | cvt (Metis.Term.Fn ("{}", [arg])) = cvt arg   (*hBOOL*)
   305         | cvt (Metis.Term.Fn ("{}", [arg])) = cvt arg   (*hBOOL*)
   305         | cvt (Metis.Term.Fn ("=", [tm1,tm2])) =
   306         | cvt (Metis.Term.Fn ("=", [tm1,tm2])) =
   306             list_comb(Const ("op =", HOLogic.typeT), map cvt [tm1,tm2])
   307             list_comb(Const (@{const_name "op ="}, HOLogic.typeT), map cvt [tm1,tm2])
   307         | cvt (t as Metis.Term.Fn (x, [])) =
   308         | cvt (t as Metis.Term.Fn (x, [])) =
   308            (case SPR.strip_prefix SFC.const_prefix x of
   309            (case strip_prefix const_prefix x of
   309                 SOME c => Const (SPR.invert_const c, dummyT)
   310                 SOME c => Const (invert_const c, dummyT)
   310               | NONE => (*Not a constant. Is it a fixed variable??*)
   311               | NONE => (*Not a constant. Is it a fixed variable??*)
   311             case SPR.strip_prefix SFC.fixed_var_prefix x of
   312             case strip_prefix fixed_var_prefix x of
   312                 SOME v => Free (v, dummyT)
   313                 SOME v => Free (v, dummyT)
   313               | NONE => (trace_msg (fn () => "fol_term_to_hol_FT bad const: " ^ x);
   314               | NONE => (trace_msg (fn () => "fol_term_to_hol_FT bad const: " ^ x);
   314                   fol_term_to_hol_RAW ctxt t))
   315                   fol_term_to_hol_RAW ctxt t))
   315         | cvt t = (trace_msg (fn () => "fol_term_to_hol_FT bad term: " ^ Metis.Term.toString t);
   316         | cvt t = (trace_msg (fn () => "fol_term_to_hol_FT bad term: " ^ Metis.Term.toString t);
   316             fol_term_to_hol_RAW ctxt t)
   317             fol_term_to_hol_RAW ctxt t)
   329                     (fn () => "  final term: " ^ Syntax.string_of_term ctxt t ^
   330                     (fn () => "  final term: " ^ Syntax.string_of_term ctxt t ^
   330                               "  of type  " ^ Syntax.string_of_typ ctxt (type_of t)))
   331                               "  of type  " ^ Syntax.string_of_typ ctxt (type_of t)))
   331                   ts'
   332                   ts'
   332   in  ts'  end;
   333   in  ts'  end;
   333 
   334 
   334 fun mk_not (Const ("Not", _) $ b) = b
   335 fun mk_not (Const (@{const_name Not}, _) $ b) = b
   335   | mk_not b = HOLogic.mk_not b;
   336   | mk_not b = HOLogic.mk_not b;
   336 
   337 
   337 val metis_eq = Metis.Term.Fn ("=", []);
   338 val metis_eq = Metis.Term.Fn ("=", []);
   338 
   339 
   339 (* ------------------------------------------------------------------------- *)
   340 (* ------------------------------------------------------------------------- *)
   385             handle Option =>
   386             handle Option =>
   386                 (trace_msg (fn() => "List.find failed for the variable " ^ x ^
   387                 (trace_msg (fn() => "List.find failed for the variable " ^ x ^
   387                                        " in " ^ Display.string_of_thm ctxt i_th);
   388                                        " in " ^ Display.string_of_thm ctxt i_th);
   388                  NONE)
   389                  NONE)
   389       fun remove_typeinst (a, t) =
   390       fun remove_typeinst (a, t) =
   390             case SPR.strip_prefix SFC.schematic_var_prefix a of
   391             case strip_prefix schematic_var_prefix a of
   391                 SOME b => SOME (b, t)
   392                 SOME b => SOME (b, t)
   392               | NONE   => case SPR.strip_prefix SFC.tvar_prefix a of
   393               | NONE   => case strip_prefix tvar_prefix a of
   393                 SOME _ => NONE          (*type instantiations are forbidden!*)
   394                 SOME _ => NONE          (*type instantiations are forbidden!*)
   394               | NONE   => SOME (a,t)    (*internal Metis var?*)
   395               | NONE   => SOME (a,t)    (*internal Metis var?*)
   395       val _ = trace_msg (fn () => "  isa th: " ^ Display.string_of_thm ctxt i_th)
   396       val _ = trace_msg (fn () => "  isa th: " ^ Display.string_of_thm ctxt i_th)
   396       val substs = map_filter remove_typeinst (Metis.Subst.toList fsubst)
   397       val substs = map_filter remove_typeinst (Metis.Subst.toList fsubst)
   397       val (vars,rawtms) = ListPair.unzip (map_filter subst_translation substs)
   398       val (vars,rawtms) = ListPair.unzip (map_filter subst_translation substs)
   453       val i_t = singleton (fol_terms_to_hol ctxt mode) t
   454       val i_t = singleton (fol_terms_to_hol ctxt mode) t
   454       val _ = trace_msg (fn () => "  term: " ^ Syntax.string_of_term ctxt i_t)
   455       val _ = trace_msg (fn () => "  term: " ^ Syntax.string_of_term ctxt i_t)
   455       val c_t = cterm_incr_types thy refl_idx i_t
   456       val c_t = cterm_incr_types thy refl_idx i_t
   456   in  cterm_instantiate [(refl_x, c_t)] REFL_THM  end;
   457   in  cterm_instantiate [(refl_x, c_t)] REFL_THM  end;
   457 
   458 
   458 fun get_ty_arg_size _ (Const ("op =", _)) = 0  (*equality has no type arguments*)
   459 fun get_ty_arg_size _ (Const (@{const_name "op ="}, _)) = 0  (*equality has no type arguments*)
   459   | get_ty_arg_size thy (Const (c, _)) = (SPR.num_typargs thy c handle TYPE _ => 0)
   460   | get_ty_arg_size thy (Const (c, _)) = (num_typargs thy c handle TYPE _ => 0)
   460   | get_ty_arg_size _ _ = 0;
   461   | get_ty_arg_size _ _ = 0;
   461 
   462 
   462 (* INFERENCE RULE: EQUALITY *)
   463 (* INFERENCE RULE: EQUALITY *)
   463 fun equality_inf ctxt mode (pos, atm) fp fr =
   464 fun equality_inf ctxt mode (pos, atm) fp fr =
   464   let val thy = ProofContext.theory_of ctxt
   465   let val thy = ProofContext.theory_of ctxt
   467       val _ = trace_msg (fn () => "sign of the literal: " ^ Bool.toString pos)
   468       val _ = trace_msg (fn () => "sign of the literal: " ^ Bool.toString pos)
   468       fun replace_item_list lx 0 (_::ls) = lx::ls
   469       fun replace_item_list lx 0 (_::ls) = lx::ls
   469         | replace_item_list lx i (l::ls) = l :: replace_item_list lx (i-1) ls
   470         | replace_item_list lx i (l::ls) = l :: replace_item_list lx (i-1) ls
   470       fun path_finder_FO tm [] = (tm, Term.Bound 0)
   471       fun path_finder_FO tm [] = (tm, Term.Bound 0)
   471         | path_finder_FO tm (p::ps) =
   472         | path_finder_FO tm (p::ps) =
   472             let val (tm1,args) = Term.strip_comb tm
   473             let val (tm1,args) = strip_comb tm
   473                 val adjustment = get_ty_arg_size thy tm1
   474                 val adjustment = get_ty_arg_size thy tm1
   474                 val p' = if adjustment > p then p else p-adjustment
   475                 val p' = if adjustment > p then p else p-adjustment
   475                 val tm_p = List.nth(args,p')
   476                 val tm_p = List.nth(args,p')
   476                   handle Subscript => error ("equality_inf: " ^ Int.toString p ^ " adj " ^
   477                   handle Subscript => error ("equality_inf: " ^ Int.toString p ^ " adj " ^
   477                     Int.toString adjustment  ^ " term " ^  Syntax.string_of_term ctxt tm)
   478                     Int.toString adjustment  ^ " term " ^  Syntax.string_of_term ctxt tm)
   494         | path_finder_FT tm ps t = error ("equality_inf, path_finder_FT: path = " ^
   495         | path_finder_FT tm ps t = error ("equality_inf, path_finder_FT: path = " ^
   495                                         space_implode " " (map Int.toString ps) ^
   496                                         space_implode " " (map Int.toString ps) ^
   496                                         " isa-term: " ^  Syntax.string_of_term ctxt tm ^
   497                                         " isa-term: " ^  Syntax.string_of_term ctxt tm ^
   497                                         " fol-term: " ^ Metis.Term.toString t)
   498                                         " fol-term: " ^ Metis.Term.toString t)
   498       fun path_finder FO tm ps _ = path_finder_FO tm ps
   499       fun path_finder FO tm ps _ = path_finder_FO tm ps
   499         | path_finder HO (tm as Const("op =",_) $ _ $ _) (p::ps) _ =
   500         | path_finder HO (tm as Const(@{const_name "op ="},_) $ _ $ _) (p::ps) _ =
   500              (*equality: not curried, as other predicates are*)
   501              (*equality: not curried, as other predicates are*)
   501              if p=0 then path_finder_HO tm (0::1::ps)  (*select first operand*)
   502              if p=0 then path_finder_HO tm (0::1::ps)  (*select first operand*)
   502              else path_finder_HO tm (p::ps)        (*1 selects second operand*)
   503              else path_finder_HO tm (p::ps)        (*1 selects second operand*)
   503         | path_finder HO tm (_ :: ps) (Metis.Term.Fn ("{}", [_])) =
   504         | path_finder HO tm (_ :: ps) (Metis.Term.Fn ("{}", [_])) =
   504              path_finder_HO tm ps      (*if not equality, ignore head to skip hBOOL*)
   505              path_finder_HO tm ps      (*if not equality, ignore head to skip hBOOL*)
   505         | path_finder FT (tm as Const("op =",_) $ _ $ _) (p::ps)
   506         | path_finder FT (tm as Const(@{const_name "op ="}, _) $ _ $ _) (p::ps)
   506                             (Metis.Term.Fn ("=", [t1,t2])) =
   507                             (Metis.Term.Fn ("=", [t1,t2])) =
   507              (*equality: not curried, as other predicates are*)
   508              (*equality: not curried, as other predicates are*)
   508              if p=0 then path_finder_FT tm (0::1::ps)
   509              if p=0 then path_finder_FT tm (0::1::ps)
   509                           (Metis.Term.Fn (".", [Metis.Term.Fn (".", [metis_eq,t1]), t2]))
   510                           (Metis.Term.Fn (".", [Metis.Term.Fn (".", [metis_eq,t1]), t2]))
   510                           (*select first operand*)
   511                           (*select first operand*)
   512                    (Metis.Term.Fn (".", [metis_eq,t2]))
   513                    (Metis.Term.Fn (".", [metis_eq,t2]))
   513                    (*1 selects second operand*)
   514                    (*1 selects second operand*)
   514         | path_finder FT tm (_ :: ps) (Metis.Term.Fn ("{}", [t1])) = path_finder_FT tm ps t1
   515         | path_finder FT tm (_ :: ps) (Metis.Term.Fn ("{}", [t1])) = path_finder_FT tm ps t1
   515              (*if not equality, ignore head to skip the hBOOL predicate*)
   516              (*if not equality, ignore head to skip the hBOOL predicate*)
   516         | path_finder FT tm ps t = path_finder_FT tm ps t  (*really an error case!*)
   517         | path_finder FT tm ps t = path_finder_FT tm ps t  (*really an error case!*)
   517       fun path_finder_lit ((nt as Term.Const ("Not", _)) $ tm_a) idx =
   518       fun path_finder_lit ((nt as Const (@{const_name Not}, _)) $ tm_a) idx =
   518             let val (tm, tm_rslt) = path_finder mode tm_a idx m_tm
   519             let val (tm, tm_rslt) = path_finder mode tm_a idx m_tm
   519             in (tm, nt $ tm_rslt) end
   520             in (tm, nt $ tm_rslt) end
   520         | path_finder_lit tm_a idx = path_finder mode tm_a idx m_tm
   521         | path_finder_lit tm_a idx = path_finder mode tm_a idx m_tm
   521       val (tm_subst, body) = path_finder_lit i_atm fp
   522       val (tm_subst, body) = path_finder_lit i_atm fp
   522       val tm_abs = Term.Abs("x", Term.type_of tm_subst, body)
   523       val tm_abs = Term.Abs("x", Term.type_of tm_subst, body)
   540       factor (resolve_inf ctxt mode thpairs f_atm f_th1 f_th2)
   541       factor (resolve_inf ctxt mode thpairs f_atm f_th1 f_th2)
   541   | step ctxt mode _ (_, Metis.Proof.Refl f_tm) = refl_inf ctxt mode f_tm
   542   | step ctxt mode _ (_, Metis.Proof.Refl f_tm) = refl_inf ctxt mode f_tm
   542   | step ctxt mode _ (_, Metis.Proof.Equality (f_lit, f_p, f_r)) =
   543   | step ctxt mode _ (_, Metis.Proof.Equality (f_lit, f_p, f_r)) =
   543       equality_inf ctxt mode f_lit f_p f_r;
   544       equality_inf ctxt mode f_lit f_p f_r;
   544 
   545 
   545 fun real_literal (_, (c, _)) = not (String.isPrefix SFC.class_prefix c);
   546 fun real_literal (_, (c, _)) = not (String.isPrefix class_prefix c);
   546 
   547 
   547 fun translate _ _ thpairs [] = thpairs
   548 fun translate _ _ thpairs [] = thpairs
   548   | translate mode ctxt thpairs ((fol_th, inf) :: infpairs) =
   549   | translate mode ctxt thpairs ((fol_th, inf) :: infpairs) =
   549       let val _ = trace_msg (fn () => "=============================================")
   550       let val _ = trace_msg (fn () => "=============================================")
   550           val _ = trace_msg (fn () => "METIS THM: " ^ Metis.Thm.toString fol_th)
   551           val _ = trace_msg (fn () => "METIS THM: " ^ Metis.Thm.toString fol_th)
   566 
   567 
   567 (* ------------------------------------------------------------------------- *)
   568 (* ------------------------------------------------------------------------- *)
   568 (* Translation of HO Clauses                                                 *)
   569 (* Translation of HO Clauses                                                 *)
   569 (* ------------------------------------------------------------------------- *)
   570 (* ------------------------------------------------------------------------- *)
   570 
   571 
   571 fun cnf_th thy th = hd (Sledgehammer_Fact_Preprocessor.cnf_axiom thy th);
   572 fun cnf_th thy th = hd (cnf_axiom thy th);
   572 
       
   573 val equal_imp_fequal' = cnf_th @{theory} @{thm equal_imp_fequal};
       
   574 val fequal_imp_equal' = cnf_th @{theory} @{thm fequal_imp_equal};
       
   575 
       
   576 val comb_I = cnf_th @{theory} SHC.comb_I;
       
   577 val comb_K = cnf_th @{theory} SHC.comb_K;
       
   578 val comb_B = cnf_th @{theory} SHC.comb_B;
       
   579 val comb_C = cnf_th @{theory} SHC.comb_C;
       
   580 val comb_S = cnf_th @{theory} SHC.comb_S;
       
   581 
   573 
   582 fun type_ext thy tms =
   574 fun type_ext thy tms =
   583   let val subs = Sledgehammer_Fact_Filter.tfree_classes_of_terms tms
   575   let val subs = tfree_classes_of_terms tms
   584       val supers = Sledgehammer_Fact_Filter.tvar_classes_of_terms tms
   576       val supers = tvar_classes_of_terms tms
   585       and tycons = Sledgehammer_Fact_Filter.type_consts_of_terms thy tms
   577       and tycons = type_consts_of_terms thy tms
   586       val (supers', arity_clauses) = SFC.make_arity_clauses thy tycons supers
   578       val (supers', arity_clauses) = make_arity_clauses thy tycons supers
   587       val classrel_clauses = SFC.make_classrel_clauses thy subs supers'
   579       val classrel_clauses = make_classrel_clauses thy subs supers'
   588   in  map classrel_cls classrel_clauses @ map arity_cls arity_clauses
   580   in  map classrel_cls classrel_clauses @ map arity_cls arity_clauses
   589   end;
   581   end;
   590 
   582 
   591 (* ------------------------------------------------------------------------- *)
   583 (* ------------------------------------------------------------------------- *)
   592 (* Logic maps manage the interface between HOL and first-order logic.        *)
   584 (* Logic maps manage the interface between HOL and first-order logic.        *)
   593 (* ------------------------------------------------------------------------- *)
   585 (* ------------------------------------------------------------------------- *)
   594 
   586 
   595 type logic_map =
   587 type logic_map =
   596   {axioms : (Metis.Thm.thm * thm) list,
   588   {axioms: (Metis.Thm.thm * thm) list,
   597    tfrees : SFC.type_literal list};
   589    tfrees: type_literal list};
   598 
   590 
   599 fun const_in_metis c (pred, tm_list) =
   591 fun const_in_metis c (pred, tm_list) =
   600   let
   592   let
   601     fun in_mterm (Metis.Term.Var _) = false
   593     fun in_mterm (Metis.Term.Var _) = false
   602       | in_mterm (Metis.Term.Fn (".", tm_list)) = exists in_mterm tm_list
   594       | in_mterm (Metis.Term.Fn (".", tm_list)) = exists in_mterm tm_list
   604   in  c = pred orelse exists in_mterm tm_list  end;
   596   in  c = pred orelse exists in_mterm tm_list  end;
   605 
   597 
   606 (*Extract TFree constraints from context to include as conjecture clauses*)
   598 (*Extract TFree constraints from context to include as conjecture clauses*)
   607 fun init_tfrees ctxt =
   599 fun init_tfrees ctxt =
   608   let fun add ((a,i),s) Ts = if i = ~1 then TFree(a,s) :: Ts else Ts
   600   let fun add ((a,i),s) Ts = if i = ~1 then TFree(a,s) :: Ts else Ts
   609   in  SFC.add_typs (Vartab.fold add (#2 (Variable.constraints_of ctxt)) []) end;
   601   in  add_typs (Vartab.fold add (#2 (Variable.constraints_of ctxt)) []) end;
   610 
   602 
   611 (*transform isabelle type / arity clause to metis clause *)
   603 (*transform isabelle type / arity clause to metis clause *)
   612 fun add_type_thm [] lmap = lmap
   604 fun add_type_thm [] lmap = lmap
   613   | add_type_thm ((ith, mth) :: cls) {axioms, tfrees} =
   605   | add_type_thm ((ith, mth) :: cls) {axioms, tfrees} =
   614       add_type_thm cls {axioms = (mth, ith) :: axioms,
   606       add_type_thm cls {axioms = (mth, ith) :: axioms,
   641       val lmap0 = fold (add_thm true) cls {axioms = [], tfrees = init_tfrees ctxt}
   633       val lmap0 = fold (add_thm true) cls {axioms = [], tfrees = init_tfrees ctxt}
   642       val lmap = fold (add_thm false) ths (add_tfrees lmap0)
   634       val lmap = fold (add_thm false) ths (add_tfrees lmap0)
   643       val clause_lists = map (Metis.Thm.clause o #1) (#axioms lmap)
   635       val clause_lists = map (Metis.Thm.clause o #1) (#axioms lmap)
   644       fun used c = exists (Metis.LiteralSet.exists (const_in_metis c o #2)) clause_lists
   636       fun used c = exists (Metis.LiteralSet.exists (const_in_metis c o #2)) clause_lists
   645       (*Now check for the existence of certain combinators*)
   637       (*Now check for the existence of certain combinators*)
   646       val thI  = if used "c_COMBI" then [comb_I] else []
   638       val thI  = if used "c_COMBI" then [cnf_th @{theory} @{thm COMBI_def}] else []
   647       val thK  = if used "c_COMBK" then [comb_K] else []
   639       val thK  = if used "c_COMBK" then [cnf_th @{theory} @{thm COMBK_def}] else []
   648       val thB   = if used "c_COMBB" then [comb_B] else []
   640       val thB   = if used "c_COMBB" then [cnf_th @{theory} @{thm COMBB_def}] else []
   649       val thC   = if used "c_COMBC" then [comb_C] else []
   641       val thC   = if used "c_COMBC" then [cnf_th @{theory} @{thm COMBC_def}] else []
   650       val thS   = if used "c_COMBS" then [comb_S] else []
   642       val thS   = if used "c_COMBS" then [cnf_th @{theory} @{thm COMBS_def}] else []
   651       val thEQ  = if used "c_fequal" then [fequal_imp_equal', equal_imp_fequal'] else []
   643       val thEQ  = if used "c_fequal" then [cnf_th @{theory} @{thm fequal_imp_equal}, cnf_th @{theory} @{thm equal_imp_fequal}] else []
   652       val lmap' = if mode=FO then lmap
   644       val lmap' = if mode=FO then lmap
   653                   else fold (add_thm false) (thEQ @ thS @ thC @ thB @ thK @ thI) lmap
   645                   else fold (add_thm false) (thEQ @ thS @ thC @ thB @ thK @ thI) lmap
   654   in
   646   in
   655       (mode, add_type_thm (type_ext thy (map prop_of (cls @ ths))) lmap')
   647       (mode, add_type_thm (type_ext thy (map prop_of (cls @ ths))) lmap')
   656   end;
   648   end;
   666 
   658 
   667 (* Main function to start metis prove and reconstruction *)
   659 (* Main function to start metis prove and reconstruction *)
   668 fun FOL_SOLVE mode ctxt cls ths0 =
   660 fun FOL_SOLVE mode ctxt cls ths0 =
   669   let val thy = ProofContext.theory_of ctxt
   661   let val thy = ProofContext.theory_of ctxt
   670       val th_cls_pairs =
   662       val th_cls_pairs =
   671         map (fn th => (Thm.get_name_hint th, Sledgehammer_Fact_Preprocessor.cnf_axiom thy th)) ths0
   663         map (fn th => (Thm.get_name_hint th, cnf_axiom thy th)) ths0
   672       val ths = maps #2 th_cls_pairs
   664       val ths = maps #2 th_cls_pairs
   673       val _ = trace_msg (fn () => "FOL_SOLVE: CONJECTURE CLAUSES")
   665       val _ = trace_msg (fn () => "FOL_SOLVE: CONJECTURE CLAUSES")
   674       val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) cls
   666       val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) cls
   675       val _ = trace_msg (fn () => "THEOREM CLAUSES")
   667       val _ = trace_msg (fn () => "THEOREM CLAUSES")
   676       val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) ths
   668       val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) ths
   677       val (mode, {axioms,tfrees}) = build_map mode ctxt cls ths
   669       val (mode, {axioms,tfrees}) = build_map mode ctxt cls ths
   678       val _ = if null tfrees then ()
   670       val _ = if null tfrees then ()
   679               else (trace_msg (fn () => "TFREE CLAUSES");
   671               else (trace_msg (fn () => "TFREE CLAUSES");
   680                     app (fn tf => trace_msg (fn _ => SFC.tptp_of_typeLit true tf)) tfrees)
   672                     app (fn tf => trace_msg (fn _ => tptp_of_typeLit true tf)) tfrees)
   681       val _ = trace_msg (fn () => "CLAUSES GIVEN TO METIS")
   673       val _ = trace_msg (fn () => "CLAUSES GIVEN TO METIS")
   682       val thms = map #1 axioms
   674       val thms = map #1 axioms
   683       val _ = app (fn th => trace_msg (fn () => Metis.Thm.toString th)) thms
   675       val _ = app (fn th => trace_msg (fn () => Metis.Thm.toString th)) thms
   684       val _ = trace_msg (fn () => "mode = " ^ string_of_mode mode)
   676       val _ = trace_msg (fn () => "mode = " ^ string_of_mode mode)
   685       val _ = trace_msg (fn () => "START METIS PROVE PROCESS")
   677       val _ = trace_msg (fn () => "START METIS PROVE PROCESS")
   717 
   709 
   718 fun metis_general_tac mode ctxt ths i st0 =
   710 fun metis_general_tac mode ctxt ths i st0 =
   719   let val _ = trace_msg (fn () =>
   711   let val _ = trace_msg (fn () =>
   720         "Metis called with theorems " ^ cat_lines (map (Display.string_of_thm ctxt) ths))
   712         "Metis called with theorems " ^ cat_lines (map (Display.string_of_thm ctxt) ths))
   721   in
   713   in
   722     if exists_type Sledgehammer_Fact_Preprocessor.type_has_topsort (prop_of st0)
   714     if exists_type type_has_topsort (prop_of st0)
   723     then raise METIS "Metis: Proof state contains the universal sort {}"
   715     then raise METIS "Metis: Proof state contains the universal sort {}"
   724     else
   716     else
   725       (Meson.MESON Sledgehammer_Fact_Preprocessor.neg_clausify
   717       (Meson.MESON neg_clausify
   726         (fn cls => resolve_tac (FOL_SOLVE mode ctxt cls ths) 1) ctxt i
   718         (fn cls => resolve_tac (FOL_SOLVE mode ctxt cls ths) 1) ctxt i
   727           THEN Sledgehammer_Fact_Preprocessor.expand_defs_tac st0) st0
   719           THEN Meson_Tactic.expand_defs_tac st0) st0
   728   end
   720   end
   729   handle METIS s => (warning ("Metis: " ^ s); Seq.empty);
   721   handle METIS s => (warning ("Metis: " ^ s); Seq.empty);
   730 
   722 
   731 val metis_tac = metis_general_tac HO;
   723 val metis_tac = metis_general_tac HO;
   732 val metisF_tac = metis_general_tac FO;
   724 val metisF_tac = metis_general_tac FO;
   735 fun method name mode comment = Method.setup name (Attrib.thms >> (fn ths => fn ctxt =>
   727 fun method name mode comment = Method.setup name (Attrib.thms >> (fn ths => fn ctxt =>
   736   SIMPLE_METHOD' (CHANGED_PROP o metis_general_tac mode ctxt ths))) comment;
   728   SIMPLE_METHOD' (CHANGED_PROP o metis_general_tac mode ctxt ths))) comment;
   737 
   729 
   738 val setup =
   730 val setup =
   739   type_lits_setup #>
   731   type_lits_setup #>
   740   method @{binding metis} HO "METIS for FOL & HOL problems" #>
   732   method @{binding metis} HO "METIS for FOL and HOL problems" #>
   741   method @{binding metisF} FO "METIS for FOL problems" #>
   733   method @{binding metisF} FO "METIS for FOL problems" #>
   742   method @{binding metisFT} FT "METIS with fully-typed translation" #>
   734   method @{binding metisFT} FT "METIS with fully-typed translation" #>
   743   Method.setup @{binding finish_clausify}
   735   Method.setup @{binding finish_clausify}
   744     (Scan.succeed (K (SIMPLE_METHOD (Sledgehammer_Fact_Preprocessor.expand_defs_tac refl))))
   736     (Scan.succeed (K (SIMPLE_METHOD (Meson_Tactic.expand_defs_tac refl))))
   745     "cleanup after conversion to clauses";
   737     "cleanup after conversion to clauses";
   746 
   738 
   747 end;
   739 end;