src/HOL/Tools/Sledgehammer/metis_tactics.ML
changeset 35826 1590abc3d42a
parent 35825 a6aad5a70ed4
child 35865 2f8fb5242799
equal deleted inserted replaced
35825:a6aad5a70ed4 35826:1590abc3d42a
     1 (*  Title:      HOL/Tools/metis_tools.ML
     1 (*  Title:      HOL/Tools/Sledgehammer/metis_tactics.ML
     2     Author:     Kong W. Susanto and Lawrence C. Paulson, CU Computer Laboratory
     2     Author:     Kong W. Susanto and Lawrence C. Paulson, CU Computer Laboratory
     3     Copyright   Cambridge University 2007
     3     Copyright   Cambridge University 2007
     4 
     4 
     5 HOL setup for the Metis prover.
     5 HOL setup for the Metis prover.
     6 *)
     6 *)
     7 
     7 
     8 signature METIS_TOOLS =
     8 signature METIS_TACTICS =
     9 sig
     9 sig
    10   val trace: bool Unsynchronized.ref
    10   val trace: bool Unsynchronized.ref
    11   val type_lits: bool Config.T
    11   val type_lits: bool Config.T
    12   val metis_tac: Proof.context -> thm list -> int -> tactic
    12   val metis_tac: Proof.context -> thm list -> int -> tactic
    13   val metisF_tac: Proof.context -> thm list -> int -> tactic
    13   val metisF_tac: Proof.context -> thm list -> int -> tactic
    14   val metisFT_tac: Proof.context -> thm list -> int -> tactic
    14   val metisFT_tac: Proof.context -> thm list -> int -> tactic
    15   val setup: theory -> theory
    15   val setup: theory -> theory
    16 end
    16 end
    17 
    17 
    18 structure MetisTools: METIS_TOOLS =
    18 structure Metis_Tactics : METIS_TACTICS =
    19 struct
    19 struct
    20 
    20 
       
    21 structure SFC = Sledgehammer_FOL_Clause
       
    22 structure SHC = Sledgehammer_HOL_Clause
       
    23 structure SPR = Sledgehammer_Proof_Reconstruct
       
    24 
    21 val trace = Unsynchronized.ref false;
    25 val trace = Unsynchronized.ref false;
    22 fun trace_msg msg = if ! trace then tracing (msg ()) else ();
    26 fun trace_msg msg = if !trace then tracing (msg ()) else ();
    23 
    27 
    24 val (type_lits, type_lits_setup) = Attrib.config_bool "metis_type_lits" true;
    28 val (type_lits, type_lits_setup) = Attrib.config_bool "metis_type_lits" true;
    25 
    29 
    26 datatype mode = FO | HO | FT  (*first-order, higher-order, fully-typed*)
    30 datatype mode = FO | HO | FT  (* first-order, higher-order, fully-typed *)
    27 
    31 
    28 (* ------------------------------------------------------------------------- *)
    32 (* ------------------------------------------------------------------------- *)
    29 (* Useful Theorems                                                           *)
    33 (* Useful Theorems                                                           *)
    30 (* ------------------------------------------------------------------------- *)
    34 (* ------------------------------------------------------------------------- *)
    31 val EXCLUDED_MIDDLE = @{lemma "P ==> ~ P ==> False" by (rule notE)}
    35 val EXCLUDED_MIDDLE = @{lemma "P ==> ~ P ==> False" by (rule notE)}
    61 fun fn_isa_to_met "equal" = "="
    65 fun fn_isa_to_met "equal" = "="
    62   | fn_isa_to_met x       = x;
    66   | fn_isa_to_met x       = x;
    63 
    67 
    64 fun metis_lit b c args = (b, (c, args));
    68 fun metis_lit b c args = (b, (c, args));
    65 
    69 
    66 fun hol_type_to_fol (Res_Clause.AtomV x) = Metis.Term.Var x
    70 fun hol_type_to_fol (SFC.AtomV x) = Metis.Term.Var x
    67   | hol_type_to_fol (Res_Clause.AtomF x) = Metis.Term.Fn(x,[])
    71   | hol_type_to_fol (SFC.AtomF x) = Metis.Term.Fn(x,[])
    68   | hol_type_to_fol (Res_Clause.Comp(tc,tps)) = Metis.Term.Fn(tc, map hol_type_to_fol tps);
    72   | hol_type_to_fol (SFC.Comp(tc,tps)) = Metis.Term.Fn(tc, map hol_type_to_fol tps);
    69 
    73 
    70 (*These two functions insert type literals before the real literals. That is the
    74 (*These two functions insert type literals before the real literals. That is the
    71   opposite order from TPTP linkup, but maybe OK.*)
    75   opposite order from TPTP linkup, but maybe OK.*)
    72 
    76 
    73 fun hol_term_to_fol_FO tm =
    77 fun hol_term_to_fol_FO tm =
    74   case Res_HOL_Clause.strip_comb tm of
    78   case SHC.strip_comb tm of
    75       (Res_HOL_Clause.CombConst(c,_,tys), tms) =>
    79       (SHC.CombConst(c,_,tys), tms) =>
    76         let val tyargs = map hol_type_to_fol tys
    80         let val tyargs = map hol_type_to_fol tys
    77             val args   = map hol_term_to_fol_FO tms
    81             val args   = map hol_term_to_fol_FO tms
    78         in Metis.Term.Fn (c, tyargs @ args) end
    82         in Metis.Term.Fn (c, tyargs @ args) end
    79     | (Res_HOL_Clause.CombVar(v,_), []) => Metis.Term.Var v
    83     | (SHC.CombVar(v,_), []) => Metis.Term.Var v
    80     | _ => error "hol_term_to_fol_FO";
    84     | _ => error "hol_term_to_fol_FO";
    81 
    85 
    82 fun hol_term_to_fol_HO (Res_HOL_Clause.CombVar (a, _)) = Metis.Term.Var a
    86 fun hol_term_to_fol_HO (SHC.CombVar (a, _)) = Metis.Term.Var a
    83   | hol_term_to_fol_HO (Res_HOL_Clause.CombConst (a, _, tylist)) =
    87   | hol_term_to_fol_HO (SHC.CombConst (a, _, tylist)) =
    84       Metis.Term.Fn (fn_isa_to_met a, map hol_type_to_fol tylist)
    88       Metis.Term.Fn (fn_isa_to_met a, map hol_type_to_fol tylist)
    85   | hol_term_to_fol_HO (Res_HOL_Clause.CombApp (tm1, tm2)) =
    89   | hol_term_to_fol_HO (SHC.CombApp (tm1, tm2)) =
    86        Metis.Term.Fn (".", map hol_term_to_fol_HO [tm1, tm2]);
    90        Metis.Term.Fn (".", map hol_term_to_fol_HO [tm1, tm2]);
    87 
    91 
    88 (*The fully-typed translation, to avoid type errors*)
    92 (*The fully-typed translation, to avoid type errors*)
    89 fun wrap_type (tm, ty) = Metis.Term.Fn("ti", [tm, hol_type_to_fol ty]);
    93 fun wrap_type (tm, ty) = Metis.Term.Fn("ti", [tm, hol_type_to_fol ty]);
    90 
    94 
    91 fun hol_term_to_fol_FT (Res_HOL_Clause.CombVar(a, ty)) =
    95 fun hol_term_to_fol_FT (SHC.CombVar(a, ty)) =
    92       wrap_type (Metis.Term.Var a, ty)
    96       wrap_type (Metis.Term.Var a, ty)
    93   | hol_term_to_fol_FT (Res_HOL_Clause.CombConst(a, ty, _)) =
    97   | hol_term_to_fol_FT (SHC.CombConst(a, ty, _)) =
    94       wrap_type (Metis.Term.Fn(fn_isa_to_met a, []), ty)
    98       wrap_type (Metis.Term.Fn(fn_isa_to_met a, []), ty)
    95   | hol_term_to_fol_FT (tm as Res_HOL_Clause.CombApp(tm1,tm2)) =
    99   | hol_term_to_fol_FT (tm as SHC.CombApp(tm1,tm2)) =
    96        wrap_type (Metis.Term.Fn(".", map hol_term_to_fol_FT [tm1,tm2]),
   100        wrap_type (Metis.Term.Fn(".", map hol_term_to_fol_FT [tm1,tm2]),
    97                   Res_HOL_Clause.type_of_combterm tm);
   101                   SHC.type_of_combterm tm);
    98 
   102 
    99 fun hol_literal_to_fol FO (Res_HOL_Clause.Literal (pol, tm)) =
   103 fun hol_literal_to_fol FO (SHC.Literal (pol, tm)) =
   100       let val (Res_HOL_Clause.CombConst(p,_,tys), tms) = Res_HOL_Clause.strip_comb tm
   104       let val (SHC.CombConst(p,_,tys), tms) = SHC.strip_comb tm
   101           val tylits = if p = "equal" then [] else map hol_type_to_fol tys
   105           val tylits = if p = "equal" then [] else map hol_type_to_fol tys
   102           val lits = map hol_term_to_fol_FO tms
   106           val lits = map hol_term_to_fol_FO tms
   103       in metis_lit pol (fn_isa_to_met p) (tylits @ lits) end
   107       in metis_lit pol (fn_isa_to_met p) (tylits @ lits) end
   104   | hol_literal_to_fol HO (Res_HOL_Clause.Literal (pol, tm)) =
   108   | hol_literal_to_fol HO (SHC.Literal (pol, tm)) =
   105      (case Res_HOL_Clause.strip_comb tm of
   109      (case SHC.strip_comb tm of
   106           (Res_HOL_Clause.CombConst("equal",_,_), tms) =>
   110           (SHC.CombConst("equal",_,_), tms) =>
   107             metis_lit pol "=" (map hol_term_to_fol_HO tms)
   111             metis_lit pol "=" (map hol_term_to_fol_HO tms)
   108         | _ => metis_lit pol "{}" [hol_term_to_fol_HO tm])   (*hBOOL*)
   112         | _ => metis_lit pol "{}" [hol_term_to_fol_HO tm])   (*hBOOL*)
   109   | hol_literal_to_fol FT (Res_HOL_Clause.Literal (pol, tm)) =
   113   | hol_literal_to_fol FT (SHC.Literal (pol, tm)) =
   110      (case Res_HOL_Clause.strip_comb tm of
   114      (case SHC.strip_comb tm of
   111           (Res_HOL_Clause.CombConst("equal",_,_), tms) =>
   115           (SHC.CombConst("equal",_,_), tms) =>
   112             metis_lit pol "=" (map hol_term_to_fol_FT tms)
   116             metis_lit pol "=" (map hol_term_to_fol_FT tms)
   113         | _ => metis_lit pol "{}" [hol_term_to_fol_FT tm])   (*hBOOL*);
   117         | _ => metis_lit pol "{}" [hol_term_to_fol_FT tm])   (*hBOOL*);
   114 
   118 
   115 fun literals_of_hol_thm thy mode t =
   119 fun literals_of_hol_thm thy mode t =
   116       let val (lits, types_sorts) = Res_HOL_Clause.literals_of_term thy t
   120       let val (lits, types_sorts) = SHC.literals_of_term thy t
   117       in  (map (hol_literal_to_fol mode) lits, types_sorts) end;
   121       in  (map (hol_literal_to_fol mode) lits, types_sorts) end;
   118 
   122 
   119 (*Sign should be "true" for conjecture type constraints, "false" for type lits in clauses.*)
   123 (*Sign should be "true" for conjecture type constraints, "false" for type lits in clauses.*)
   120 fun metis_of_typeLit pos (Res_Clause.LTVar (s,x))  = metis_lit pos s [Metis.Term.Var x]
   124 fun metis_of_typeLit pos (SFC.LTVar (s,x))  = metis_lit pos s [Metis.Term.Var x]
   121   | metis_of_typeLit pos (Res_Clause.LTFree (s,x)) = metis_lit pos s [Metis.Term.Fn(x,[])];
   125   | metis_of_typeLit pos (SFC.LTFree (s,x)) = metis_lit pos s [Metis.Term.Fn(x,[])];
   122 
   126 
   123 fun default_sort _ (TVar _) = false
   127 fun default_sort _ (TVar _) = false
   124   | default_sort ctxt (TFree (x, s)) = (s = the_default [] (Variable.def_sort ctxt (x, ~1)));
   128   | default_sort ctxt (TFree (x, s)) = (s = the_default [] (Variable.def_sort ctxt (x, ~1)));
   125 
   129 
   126 fun metis_of_tfree tf =
   130 fun metis_of_tfree tf =
   130   let val thy = ProofContext.theory_of ctxt
   134   let val thy = ProofContext.theory_of ctxt
   131       val (mlits, types_sorts) =
   135       val (mlits, types_sorts) =
   132              (literals_of_hol_thm thy mode o HOLogic.dest_Trueprop o prop_of) th
   136              (literals_of_hol_thm thy mode o HOLogic.dest_Trueprop o prop_of) th
   133   in
   137   in
   134       if is_conjecture then
   138       if is_conjecture then
   135           (Metis.Thm.axiom (Metis.LiteralSet.fromList mlits), Res_Clause.add_typs types_sorts)
   139           (Metis.Thm.axiom (Metis.LiteralSet.fromList mlits), SFC.add_typs types_sorts)
   136       else
   140       else
   137         let val tylits = Res_Clause.add_typs
   141         let val tylits = SFC.add_typs
   138                            (filter (not o default_sort ctxt) types_sorts)
   142                            (filter (not o default_sort ctxt) types_sorts)
   139             val mtylits = if Config.get ctxt type_lits
   143             val mtylits = if Config.get ctxt type_lits
   140                           then map (metis_of_typeLit false) tylits else []
   144                           then map (metis_of_typeLit false) tylits else []
   141         in
   145         in
   142           (Metis.Thm.axiom (Metis.LiteralSet.fromList(mtylits @ mlits)), [])
   146           (Metis.Thm.axiom (Metis.LiteralSet.fromList(mtylits @ mlits)), [])
   143         end
   147         end
   144   end;
   148   end;
   145 
   149 
   146 (* ARITY CLAUSE *)
   150 (* ARITY CLAUSE *)
   147 
   151 
   148 fun m_arity_cls (Res_Clause.TConsLit (c,t,args)) =
   152 fun m_arity_cls (SFC.TConsLit (c,t,args)) =
   149       metis_lit true (Res_Clause.make_type_class c) [Metis.Term.Fn(t, map Metis.Term.Var args)]
   153       metis_lit true (SFC.make_type_class c) [Metis.Term.Fn(t, map Metis.Term.Var args)]
   150   | m_arity_cls (Res_Clause.TVarLit (c,str))     =
   154   | m_arity_cls (SFC.TVarLit (c,str))     =
   151       metis_lit false (Res_Clause.make_type_class c) [Metis.Term.Var str];
   155       metis_lit false (SFC.make_type_class c) [Metis.Term.Var str];
   152 
   156 
   153 (*TrueI is returned as the Isabelle counterpart because there isn't any.*)
   157 (*TrueI is returned as the Isabelle counterpart because there isn't any.*)
   154 fun arity_cls (Res_Clause.ArityClause{conclLit,premLits,...}) =
   158 fun arity_cls (SFC.ArityClause{conclLit,premLits,...}) =
   155   (TrueI,
   159   (TrueI,
   156    Metis.Thm.axiom (Metis.LiteralSet.fromList (map m_arity_cls (conclLit :: premLits))));
   160    Metis.Thm.axiom (Metis.LiteralSet.fromList (map m_arity_cls (conclLit :: premLits))));
   157 
   161 
   158 (* CLASSREL CLAUSE *)
   162 (* CLASSREL CLAUSE *)
   159 
   163 
   160 fun m_classrel_cls subclass superclass =
   164 fun m_classrel_cls subclass superclass =
   161   [metis_lit false subclass [Metis.Term.Var "T"], metis_lit true superclass [Metis.Term.Var "T"]];
   165   [metis_lit false subclass [Metis.Term.Var "T"], metis_lit true superclass [Metis.Term.Var "T"]];
   162 
   166 
   163 fun classrel_cls (Res_Clause.ClassrelClause {subclass, superclass, ...}) =
   167 fun classrel_cls (SFC.ClassrelClause {subclass, superclass, ...}) =
   164   (TrueI, Metis.Thm.axiom (Metis.LiteralSet.fromList (m_classrel_cls subclass superclass)));
   168   (TrueI, Metis.Thm.axiom (Metis.LiteralSet.fromList (m_classrel_cls subclass superclass)));
   165 
   169 
   166 (* ------------------------------------------------------------------------- *)
   170 (* ------------------------------------------------------------------------- *)
   167 (* FOL to HOL  (Metis to Isabelle)                                           *)
   171 (* FOL to HOL  (Metis to Isabelle)                                           *)
   168 (* ------------------------------------------------------------------------- *)
   172 (* ------------------------------------------------------------------------- *)
   207 (*Remove the "apply" operator from an HO term*)
   211 (*Remove the "apply" operator from an HO term*)
   208 fun strip_happ args (Metis.Term.Fn(".",[t,u])) = strip_happ (u::args) t
   212 fun strip_happ args (Metis.Term.Fn(".",[t,u])) = strip_happ (u::args) t
   209   | strip_happ args x = (x, args);
   213   | strip_happ args x = (x, args);
   210 
   214 
   211 fun fol_type_to_isa _ (Metis.Term.Var v) =
   215 fun fol_type_to_isa _ (Metis.Term.Var v) =
   212      (case Res_Reconstruct.strip_prefix Res_Clause.tvar_prefix v of
   216      (case SPR.strip_prefix SFC.tvar_prefix v of
   213           SOME w => Res_Reconstruct.make_tvar w
   217           SOME w => SPR.make_tvar w
   214         | NONE   => Res_Reconstruct.make_tvar v)
   218         | NONE   => SPR.make_tvar v)
   215   | fol_type_to_isa ctxt (Metis.Term.Fn(x, tys)) =
   219   | fol_type_to_isa ctxt (Metis.Term.Fn(x, tys)) =
   216      (case Res_Reconstruct.strip_prefix Res_Clause.tconst_prefix x of
   220      (case SPR.strip_prefix SFC.tconst_prefix x of
   217           SOME tc => Term.Type (Res_Reconstruct.invert_type_const tc, map (fol_type_to_isa ctxt) tys)
   221           SOME tc => Term.Type (SPR.invert_type_const tc, map (fol_type_to_isa ctxt) tys)
   218         | NONE    =>
   222         | NONE    =>
   219       case Res_Reconstruct.strip_prefix Res_Clause.tfree_prefix x of
   223       case SPR.strip_prefix SFC.tfree_prefix x of
   220           SOME tf => mk_tfree ctxt tf
   224           SOME tf => mk_tfree ctxt tf
   221         | NONE    => error ("fol_type_to_isa: " ^ x));
   225         | NONE    => error ("fol_type_to_isa: " ^ x));
   222 
   226 
   223 (*Maps metis terms to isabelle terms*)
   227 (*Maps metis terms to isabelle terms*)
   224 fun fol_term_to_hol_RAW ctxt fol_tm =
   228 fun fol_term_to_hol_RAW ctxt fol_tm =
   225   let val thy = ProofContext.theory_of ctxt
   229   let val thy = ProofContext.theory_of ctxt
   226       val _ = trace_msg (fn () => "fol_term_to_hol: " ^ Metis.Term.toString fol_tm)
   230       val _ = trace_msg (fn () => "fol_term_to_hol: " ^ Metis.Term.toString fol_tm)
   227       fun tm_to_tt (Metis.Term.Var v) =
   231       fun tm_to_tt (Metis.Term.Var v) =
   228              (case Res_Reconstruct.strip_prefix Res_Clause.tvar_prefix v of
   232              (case SPR.strip_prefix SFC.tvar_prefix v of
   229                   SOME w => Type (Res_Reconstruct.make_tvar w)
   233                   SOME w => Type (SPR.make_tvar w)
   230                 | NONE =>
   234                 | NONE =>
   231               case Res_Reconstruct.strip_prefix Res_Clause.schematic_var_prefix v of
   235               case SPR.strip_prefix SFC.schematic_var_prefix v of
   232                   SOME w => Term (mk_var (w, HOLogic.typeT))
   236                   SOME w => Term (mk_var (w, HOLogic.typeT))
   233                 | NONE   => Term (mk_var (v, HOLogic.typeT)) )
   237                 | NONE   => Term (mk_var (v, HOLogic.typeT)) )
   234                     (*Var from Metis with a name like _nnn; possibly a type variable*)
   238                     (*Var from Metis with a name like _nnn; possibly a type variable*)
   235         | tm_to_tt (Metis.Term.Fn ("{}", [arg])) = tm_to_tt arg   (*hBOOL*)
   239         | tm_to_tt (Metis.Term.Fn ("{}", [arg])) = tm_to_tt arg   (*hBOOL*)
   236         | tm_to_tt (t as Metis.Term.Fn (".",_)) =
   240         | tm_to_tt (t as Metis.Term.Fn (".",_)) =
   243             end
   247             end
   244         | tm_to_tt (Metis.Term.Fn (fname, args)) = applic_to_tt (fname,args)
   248         | tm_to_tt (Metis.Term.Fn (fname, args)) = applic_to_tt (fname,args)
   245       and applic_to_tt ("=",ts) =
   249       and applic_to_tt ("=",ts) =
   246             Term (list_comb(Const ("op =", HOLogic.typeT), terms_of (map tm_to_tt ts)))
   250             Term (list_comb(Const ("op =", HOLogic.typeT), terms_of (map tm_to_tt ts)))
   247         | applic_to_tt (a,ts) =
   251         | applic_to_tt (a,ts) =
   248             case Res_Reconstruct.strip_prefix Res_Clause.const_prefix a of
   252             case SPR.strip_prefix SFC.const_prefix a of
   249                 SOME b =>
   253                 SOME b =>
   250                   let val c = Res_Reconstruct.invert_const b
   254                   let val c = SPR.invert_const b
   251                       val ntypes = Res_Reconstruct.num_typargs thy c
   255                       val ntypes = SPR.num_typargs thy c
   252                       val nterms = length ts - ntypes
   256                       val nterms = length ts - ntypes
   253                       val tts = map tm_to_tt ts
   257                       val tts = map tm_to_tt ts
   254                       val tys = types_of (List.take(tts,ntypes))
   258                       val tys = types_of (List.take(tts,ntypes))
   255                       val ntyargs = Res_Reconstruct.num_typargs thy c
   259                       val ntyargs = SPR.num_typargs thy c
   256                   in if length tys = ntyargs then
   260                   in if length tys = ntyargs then
   257                          apply_list (Const (c, dummyT)) nterms (List.drop(tts,ntypes))
   261                          apply_list (Const (c, dummyT)) nterms (List.drop(tts,ntypes))
   258                      else error ("Constant " ^ c ^ " expects " ^ Int.toString ntyargs ^
   262                      else error ("Constant " ^ c ^ " expects " ^ Int.toString ntyargs ^
   259                                  " but gets " ^ Int.toString (length tys) ^
   263                                  " but gets " ^ Int.toString (length tys) ^
   260                                  " type arguments\n" ^
   264                                  " type arguments\n" ^
   261                                  cat_lines (map (Syntax.string_of_typ ctxt) tys) ^
   265                                  cat_lines (map (Syntax.string_of_typ ctxt) tys) ^
   262                                  " the terms are \n" ^
   266                                  " the terms are \n" ^
   263                                  cat_lines (map (Syntax.string_of_term ctxt) (terms_of tts)))
   267                                  cat_lines (map (Syntax.string_of_term ctxt) (terms_of tts)))
   264                      end
   268                      end
   265               | NONE => (*Not a constant. Is it a type constructor?*)
   269               | NONE => (*Not a constant. Is it a type constructor?*)
   266             case Res_Reconstruct.strip_prefix Res_Clause.tconst_prefix a of
   270             case SPR.strip_prefix SFC.tconst_prefix a of
   267                 SOME b =>
   271                 SOME b =>
   268                   Type (Term.Type (Res_Reconstruct.invert_type_const b, types_of (map tm_to_tt ts)))
   272                   Type (Term.Type (SPR.invert_type_const b, types_of (map tm_to_tt ts)))
   269               | NONE => (*Maybe a TFree. Should then check that ts=[].*)
   273               | NONE => (*Maybe a TFree. Should then check that ts=[].*)
   270             case Res_Reconstruct.strip_prefix Res_Clause.tfree_prefix a of
   274             case SPR.strip_prefix SFC.tfree_prefix a of
   271                 SOME b => Type (mk_tfree ctxt b)
   275                 SOME b => Type (mk_tfree ctxt b)
   272               | NONE => (*a fixed variable? They are Skolem functions.*)
   276               | NONE => (*a fixed variable? They are Skolem functions.*)
   273             case Res_Reconstruct.strip_prefix Res_Clause.fixed_var_prefix a of
   277             case SPR.strip_prefix SFC.fixed_var_prefix a of
   274                 SOME b =>
   278                 SOME b =>
   275                   let val opr = Term.Free(b, HOLogic.typeT)
   279                   let val opr = Term.Free(b, HOLogic.typeT)
   276                   in  apply_list opr (length ts) (map tm_to_tt ts)  end
   280                   in  apply_list opr (length ts) (map tm_to_tt ts)  end
   277               | NONE => error ("unexpected metis function: " ^ a)
   281               | NONE => error ("unexpected metis function: " ^ a)
   278   in  case tm_to_tt fol_tm of Term t => t | _ => error "fol_tm_to_tt: Term expected"  end;
   282   in  case tm_to_tt fol_tm of Term t => t | _ => error "fol_tm_to_tt: Term expected"  end;
   279 
   283 
   280 (*Maps fully-typed metis terms to isabelle terms*)
   284 (*Maps fully-typed metis terms to isabelle terms*)
   281 fun fol_term_to_hol_FT ctxt fol_tm =
   285 fun fol_term_to_hol_FT ctxt fol_tm =
   282   let val _ = trace_msg (fn () => "fol_term_to_hol_FT: " ^ Metis.Term.toString fol_tm)
   286   let val _ = trace_msg (fn () => "fol_term_to_hol_FT: " ^ Metis.Term.toString fol_tm)
   283       fun cvt (Metis.Term.Fn ("ti", [Metis.Term.Var v, _])) =
   287       fun cvt (Metis.Term.Fn ("ti", [Metis.Term.Var v, _])) =
   284              (case Res_Reconstruct.strip_prefix Res_Clause.schematic_var_prefix v of
   288              (case SPR.strip_prefix SFC.schematic_var_prefix v of
   285                   SOME w =>  mk_var(w, dummyT)
   289                   SOME w =>  mk_var(w, dummyT)
   286                 | NONE   => mk_var(v, dummyT))
   290                 | NONE   => mk_var(v, dummyT))
   287         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn ("=",[]), _])) =
   291         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn ("=",[]), _])) =
   288             Const ("op =", HOLogic.typeT)
   292             Const ("op =", HOLogic.typeT)
   289         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn (x,[]), ty])) =
   293         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn (x,[]), ty])) =
   290            (case Res_Reconstruct.strip_prefix Res_Clause.const_prefix x of
   294            (case SPR.strip_prefix SFC.const_prefix x of
   291                 SOME c => Const (Res_Reconstruct.invert_const c, dummyT)
   295                 SOME c => Const (SPR.invert_const c, dummyT)
   292               | NONE => (*Not a constant. Is it a fixed variable??*)
   296               | NONE => (*Not a constant. Is it a fixed variable??*)
   293             case Res_Reconstruct.strip_prefix Res_Clause.fixed_var_prefix x of
   297             case SPR.strip_prefix SFC.fixed_var_prefix x of
   294                 SOME v => Free (v, fol_type_to_isa ctxt ty)
   298                 SOME v => Free (v, fol_type_to_isa ctxt ty)
   295               | NONE => error ("fol_term_to_hol_FT bad constant: " ^ x))
   299               | NONE => error ("fol_term_to_hol_FT bad constant: " ^ x))
   296         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn (".",[tm1,tm2]), _])) =
   300         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn (".",[tm1,tm2]), _])) =
   297             cvt tm1 $ cvt tm2
   301             cvt tm1 $ cvt tm2
   298         | cvt (Metis.Term.Fn (".",[tm1,tm2])) = (*untyped application*)
   302         | cvt (Metis.Term.Fn (".",[tm1,tm2])) = (*untyped application*)
   299             cvt tm1 $ cvt tm2
   303             cvt tm1 $ cvt tm2
   300         | cvt (Metis.Term.Fn ("{}", [arg])) = cvt arg   (*hBOOL*)
   304         | cvt (Metis.Term.Fn ("{}", [arg])) = cvt arg   (*hBOOL*)
   301         | cvt (Metis.Term.Fn ("=", [tm1,tm2])) =
   305         | cvt (Metis.Term.Fn ("=", [tm1,tm2])) =
   302             list_comb(Const ("op =", HOLogic.typeT), map cvt [tm1,tm2])
   306             list_comb(Const ("op =", HOLogic.typeT), map cvt [tm1,tm2])
   303         | cvt (t as Metis.Term.Fn (x, [])) =
   307         | cvt (t as Metis.Term.Fn (x, [])) =
   304            (case Res_Reconstruct.strip_prefix Res_Clause.const_prefix x of
   308            (case SPR.strip_prefix SFC.const_prefix x of
   305                 SOME c => Const (Res_Reconstruct.invert_const c, dummyT)
   309                 SOME c => Const (SPR.invert_const c, dummyT)
   306               | NONE => (*Not a constant. Is it a fixed variable??*)
   310               | NONE => (*Not a constant. Is it a fixed variable??*)
   307             case Res_Reconstruct.strip_prefix Res_Clause.fixed_var_prefix x of
   311             case SPR.strip_prefix SFC.fixed_var_prefix x of
   308                 SOME v => Free (v, dummyT)
   312                 SOME v => Free (v, dummyT)
   309               | NONE => (trace_msg (fn () => "fol_term_to_hol_FT bad const: " ^ x);
   313               | NONE => (trace_msg (fn () => "fol_term_to_hol_FT bad const: " ^ x);
   310                   fol_term_to_hol_RAW ctxt t))
   314                   fol_term_to_hol_RAW ctxt t))
   311         | cvt t = (trace_msg (fn () => "fol_term_to_hol_FT bad term: " ^ Metis.Term.toString t);
   315         | cvt t = (trace_msg (fn () => "fol_term_to_hol_FT bad term: " ^ Metis.Term.toString t);
   312             fol_term_to_hol_RAW ctxt t)
   316             fol_term_to_hol_RAW ctxt t)
   381             handle Option =>
   385             handle Option =>
   382                 (trace_msg (fn() => "List.find failed for the variable " ^ x ^
   386                 (trace_msg (fn() => "List.find failed for the variable " ^ x ^
   383                                        " in " ^ Display.string_of_thm ctxt i_th);
   387                                        " in " ^ Display.string_of_thm ctxt i_th);
   384                  NONE)
   388                  NONE)
   385       fun remove_typeinst (a, t) =
   389       fun remove_typeinst (a, t) =
   386             case Res_Reconstruct.strip_prefix Res_Clause.schematic_var_prefix a of
   390             case SPR.strip_prefix SFC.schematic_var_prefix a of
   387                 SOME b => SOME (b, t)
   391                 SOME b => SOME (b, t)
   388               | NONE   => case Res_Reconstruct.strip_prefix Res_Clause.tvar_prefix a of
   392               | NONE   => case SPR.strip_prefix SFC.tvar_prefix a of
   389                 SOME _ => NONE          (*type instantiations are forbidden!*)
   393                 SOME _ => NONE          (*type instantiations are forbidden!*)
   390               | NONE   => SOME (a,t)    (*internal Metis var?*)
   394               | NONE   => SOME (a,t)    (*internal Metis var?*)
   391       val _ = trace_msg (fn () => "  isa th: " ^ Display.string_of_thm ctxt i_th)
   395       val _ = trace_msg (fn () => "  isa th: " ^ Display.string_of_thm ctxt i_th)
   392       val substs = map_filter remove_typeinst (Metis.Subst.toList fsubst)
   396       val substs = map_filter remove_typeinst (Metis.Subst.toList fsubst)
   393       val (vars,rawtms) = ListPair.unzip (map_filter subst_translation substs)
   397       val (vars,rawtms) = ListPair.unzip (map_filter subst_translation substs)
   450       val _ = trace_msg (fn () => "  term: " ^ Syntax.string_of_term ctxt i_t)
   454       val _ = trace_msg (fn () => "  term: " ^ Syntax.string_of_term ctxt i_t)
   451       val c_t = cterm_incr_types thy refl_idx i_t
   455       val c_t = cterm_incr_types thy refl_idx i_t
   452   in  cterm_instantiate [(refl_x, c_t)] REFL_THM  end;
   456   in  cterm_instantiate [(refl_x, c_t)] REFL_THM  end;
   453 
   457 
   454 fun get_ty_arg_size _ (Const ("op =", _)) = 0  (*equality has no type arguments*)
   458 fun get_ty_arg_size _ (Const ("op =", _)) = 0  (*equality has no type arguments*)
   455   | get_ty_arg_size thy (Const (c, _)) = (Res_Reconstruct.num_typargs thy c handle TYPE _ => 0)
   459   | get_ty_arg_size thy (Const (c, _)) = (SPR.num_typargs thy c handle TYPE _ => 0)
   456   | get_ty_arg_size _ _ = 0;
   460   | get_ty_arg_size _ _ = 0;
   457 
   461 
   458 (* INFERENCE RULE: EQUALITY *)
   462 (* INFERENCE RULE: EQUALITY *)
   459 fun equality_inf ctxt mode (pos, atm) fp fr =
   463 fun equality_inf ctxt mode (pos, atm) fp fr =
   460   let val thy = ProofContext.theory_of ctxt
   464   let val thy = ProofContext.theory_of ctxt
   536       factor (resolve_inf ctxt mode thpairs f_atm f_th1 f_th2)
   540       factor (resolve_inf ctxt mode thpairs f_atm f_th1 f_th2)
   537   | step ctxt mode _ (_, Metis.Proof.Refl f_tm) = refl_inf ctxt mode f_tm
   541   | step ctxt mode _ (_, Metis.Proof.Refl f_tm) = refl_inf ctxt mode f_tm
   538   | step ctxt mode _ (_, Metis.Proof.Equality (f_lit, f_p, f_r)) =
   542   | step ctxt mode _ (_, Metis.Proof.Equality (f_lit, f_p, f_r)) =
   539       equality_inf ctxt mode f_lit f_p f_r;
   543       equality_inf ctxt mode f_lit f_p f_r;
   540 
   544 
   541 fun real_literal (_, (c, _)) = not (String.isPrefix Res_Clause.class_prefix c);
   545 fun real_literal (_, (c, _)) = not (String.isPrefix SFC.class_prefix c);
   542 
   546 
   543 fun translate _ _ thpairs [] = thpairs
   547 fun translate _ _ thpairs [] = thpairs
   544   | translate mode ctxt thpairs ((fol_th, inf) :: infpairs) =
   548   | translate mode ctxt thpairs ((fol_th, inf) :: infpairs) =
   545       let val _ = trace_msg (fn () => "=============================================")
   549       let val _ = trace_msg (fn () => "=============================================")
   546           val _ = trace_msg (fn () => "METIS THM: " ^ Metis.Thm.toString fol_th)
   550           val _ = trace_msg (fn () => "METIS THM: " ^ Metis.Thm.toString fol_th)
   562 
   566 
   563 (* ------------------------------------------------------------------------- *)
   567 (* ------------------------------------------------------------------------- *)
   564 (* Translation of HO Clauses                                                 *)
   568 (* Translation of HO Clauses                                                 *)
   565 (* ------------------------------------------------------------------------- *)
   569 (* ------------------------------------------------------------------------- *)
   566 
   570 
   567 fun cnf_th thy th = hd (Res_Axioms.cnf_axiom thy th);
   571 fun cnf_th thy th = hd (Sledgehammer_Fact_Preprocessor.cnf_axiom thy th);
   568 
   572 
   569 val equal_imp_fequal' = cnf_th @{theory} @{thm equal_imp_fequal};
   573 val equal_imp_fequal' = cnf_th @{theory} @{thm equal_imp_fequal};
   570 val fequal_imp_equal' = cnf_th @{theory} @{thm fequal_imp_equal};
   574 val fequal_imp_equal' = cnf_th @{theory} @{thm fequal_imp_equal};
   571 
   575 
   572 val comb_I = cnf_th @{theory} Res_HOL_Clause.comb_I;
   576 val comb_I = cnf_th @{theory} SHC.comb_I;
   573 val comb_K = cnf_th @{theory} Res_HOL_Clause.comb_K;
   577 val comb_K = cnf_th @{theory} SHC.comb_K;
   574 val comb_B = cnf_th @{theory} Res_HOL_Clause.comb_B;
   578 val comb_B = cnf_th @{theory} SHC.comb_B;
   575 val comb_C = cnf_th @{theory} Res_HOL_Clause.comb_C;
   579 val comb_C = cnf_th @{theory} SHC.comb_C;
   576 val comb_S = cnf_th @{theory} Res_HOL_Clause.comb_S;
   580 val comb_S = cnf_th @{theory} SHC.comb_S;
   577 
   581 
   578 fun type_ext thy tms =
   582 fun type_ext thy tms =
   579   let val subs = Res_ATP.tfree_classes_of_terms tms
   583   let val subs = Sledgehammer_Fact_Filter.tfree_classes_of_terms tms
   580       val supers = Res_ATP.tvar_classes_of_terms tms
   584       val supers = Sledgehammer_Fact_Filter.tvar_classes_of_terms tms
   581       and tycons = Res_ATP.type_consts_of_terms thy tms
   585       and tycons = Sledgehammer_Fact_Filter.type_consts_of_terms thy tms
   582       val (supers', arity_clauses) = Res_Clause.make_arity_clauses thy tycons supers
   586       val (supers', arity_clauses) = SFC.make_arity_clauses thy tycons supers
   583       val classrel_clauses = Res_Clause.make_classrel_clauses thy subs supers'
   587       val classrel_clauses = SFC.make_classrel_clauses thy subs supers'
   584   in  map classrel_cls classrel_clauses @ map arity_cls arity_clauses
   588   in  map classrel_cls classrel_clauses @ map arity_cls arity_clauses
   585   end;
   589   end;
   586 
   590 
   587 (* ------------------------------------------------------------------------- *)
   591 (* ------------------------------------------------------------------------- *)
   588 (* Logic maps manage the interface between HOL and first-order logic.        *)
   592 (* Logic maps manage the interface between HOL and first-order logic.        *)
   589 (* ------------------------------------------------------------------------- *)
   593 (* ------------------------------------------------------------------------- *)
   590 
   594 
   591 type logic_map =
   595 type logic_map =
   592   {axioms : (Metis.Thm.thm * thm) list,
   596   {axioms : (Metis.Thm.thm * thm) list,
   593    tfrees : Res_Clause.type_literal list};
   597    tfrees : SFC.type_literal list};
   594 
   598 
   595 fun const_in_metis c (pred, tm_list) =
   599 fun const_in_metis c (pred, tm_list) =
   596   let
   600   let
   597     fun in_mterm (Metis.Term.Var _) = false
   601     fun in_mterm (Metis.Term.Var _) = false
   598       | in_mterm (Metis.Term.Fn (".", tm_list)) = exists in_mterm tm_list
   602       | in_mterm (Metis.Term.Fn (".", tm_list)) = exists in_mterm tm_list
   600   in  c = pred orelse exists in_mterm tm_list  end;
   604   in  c = pred orelse exists in_mterm tm_list  end;
   601 
   605 
   602 (*Extract TFree constraints from context to include as conjecture clauses*)
   606 (*Extract TFree constraints from context to include as conjecture clauses*)
   603 fun init_tfrees ctxt =
   607 fun init_tfrees ctxt =
   604   let fun add ((a,i),s) Ts = if i = ~1 then TFree(a,s) :: Ts else Ts
   608   let fun add ((a,i),s) Ts = if i = ~1 then TFree(a,s) :: Ts else Ts
   605   in  Res_Clause.add_typs (Vartab.fold add (#2 (Variable.constraints_of ctxt)) []) end;
   609   in  SFC.add_typs (Vartab.fold add (#2 (Variable.constraints_of ctxt)) []) end;
   606 
   610 
   607 (*transform isabelle type / arity clause to metis clause *)
   611 (*transform isabelle type / arity clause to metis clause *)
   608 fun add_type_thm [] lmap = lmap
   612 fun add_type_thm [] lmap = lmap
   609   | add_type_thm ((ith, mth) :: cls) {axioms, tfrees} =
   613   | add_type_thm ((ith, mth) :: cls) {axioms, tfrees} =
   610       add_type_thm cls {axioms = (mth, ith) :: axioms,
   614       add_type_thm cls {axioms = (mth, ith) :: axioms,
   661 exception METIS of string;
   665 exception METIS of string;
   662 
   666 
   663 (* Main function to start metis prove and reconstruction *)
   667 (* Main function to start metis prove and reconstruction *)
   664 fun FOL_SOLVE mode ctxt cls ths0 =
   668 fun FOL_SOLVE mode ctxt cls ths0 =
   665   let val thy = ProofContext.theory_of ctxt
   669   let val thy = ProofContext.theory_of ctxt
   666       val th_cls_pairs = map (fn th => (Thm.get_name_hint th, Res_Axioms.cnf_axiom thy th)) ths0
   670       val th_cls_pairs =
       
   671         map (fn th => (Thm.get_name_hint th, Sledgehammer_Fact_Preprocessor.cnf_axiom thy th)) ths0
   667       val ths = maps #2 th_cls_pairs
   672       val ths = maps #2 th_cls_pairs
   668       val _ = trace_msg (fn () => "FOL_SOLVE: CONJECTURE CLAUSES")
   673       val _ = trace_msg (fn () => "FOL_SOLVE: CONJECTURE CLAUSES")
   669       val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) cls
   674       val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) cls
   670       val _ = trace_msg (fn () => "THEOREM CLAUSES")
   675       val _ = trace_msg (fn () => "THEOREM CLAUSES")
   671       val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) ths
   676       val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) ths
   672       val (mode, {axioms,tfrees}) = build_map mode ctxt cls ths
   677       val (mode, {axioms,tfrees}) = build_map mode ctxt cls ths
   673       val _ = if null tfrees then ()
   678       val _ = if null tfrees then ()
   674               else (trace_msg (fn () => "TFREE CLAUSES");
   679               else (trace_msg (fn () => "TFREE CLAUSES");
   675                     app (fn tf => trace_msg (fn _ => Res_Clause.tptp_of_typeLit true tf)) tfrees)
   680                     app (fn tf => trace_msg (fn _ => SFC.tptp_of_typeLit true tf)) tfrees)
   676       val _ = trace_msg (fn () => "CLAUSES GIVEN TO METIS")
   681       val _ = trace_msg (fn () => "CLAUSES GIVEN TO METIS")
   677       val thms = map #1 axioms
   682       val thms = map #1 axioms
   678       val _ = app (fn th => trace_msg (fn () => Metis.Thm.toString th)) thms
   683       val _ = app (fn th => trace_msg (fn () => Metis.Thm.toString th)) thms
   679       val _ = trace_msg (fn () => "mode = " ^ string_of_mode mode)
   684       val _ = trace_msg (fn () => "mode = " ^ string_of_mode mode)
   680       val _ = trace_msg (fn () => "START METIS PROVE PROCESS")
   685       val _ = trace_msg (fn () => "START METIS PROVE PROCESS")
   712 
   717 
   713 fun metis_general_tac mode ctxt ths i st0 =
   718 fun metis_general_tac mode ctxt ths i st0 =
   714   let val _ = trace_msg (fn () =>
   719   let val _ = trace_msg (fn () =>
   715         "Metis called with theorems " ^ cat_lines (map (Display.string_of_thm ctxt) ths))
   720         "Metis called with theorems " ^ cat_lines (map (Display.string_of_thm ctxt) ths))
   716   in
   721   in
   717     if exists_type Res_Axioms.type_has_topsort (prop_of st0)
   722     if exists_type Sledgehammer_Fact_Preprocessor.type_has_topsort (prop_of st0)
   718     then raise METIS "Metis: Proof state contains the universal sort {}"
   723     then raise METIS "Metis: Proof state contains the universal sort {}"
   719     else
   724     else
   720       (Meson.MESON Res_Axioms.neg_clausify
   725       (Meson.MESON Sledgehammer_Fact_Preprocessor.neg_clausify
   721         (fn cls => resolve_tac (FOL_SOLVE mode ctxt cls ths) 1) ctxt i
   726         (fn cls => resolve_tac (FOL_SOLVE mode ctxt cls ths) 1) ctxt i
   722           THEN Res_Axioms.expand_defs_tac st0) st0
   727           THEN Sledgehammer_Fact_Preprocessor.expand_defs_tac st0) st0
   723   end
   728   end
   724   handle METIS s => (warning ("Metis: " ^ s); Seq.empty);
   729   handle METIS s => (warning ("Metis: " ^ s); Seq.empty);
   725 
   730 
   726 val metis_tac = metis_general_tac HO;
   731 val metis_tac = metis_general_tac HO;
   727 val metisF_tac = metis_general_tac FO;
   732 val metisF_tac = metis_general_tac FO;
   734   type_lits_setup #>
   739   type_lits_setup #>
   735   method @{binding metis} HO "METIS for FOL & HOL problems" #>
   740   method @{binding metis} HO "METIS for FOL & HOL problems" #>
   736   method @{binding metisF} FO "METIS for FOL problems" #>
   741   method @{binding metisF} FO "METIS for FOL problems" #>
   737   method @{binding metisFT} FT "METIS with fully-typed translation" #>
   742   method @{binding metisFT} FT "METIS with fully-typed translation" #>
   738   Method.setup @{binding finish_clausify}
   743   Method.setup @{binding finish_clausify}
   739     (Scan.succeed (K (SIMPLE_METHOD (Res_Axioms.expand_defs_tac refl))))
   744     (Scan.succeed (K (SIMPLE_METHOD (Sledgehammer_Fact_Preprocessor.expand_defs_tac refl))))
   740     "cleanup after conversion to clauses";
   745     "cleanup after conversion to clauses";
   741 
   746 
   742 end;
   747 end;