src/HOL/Tools/Sledgehammer/metis_tactics.ML
changeset 37399 34f080a12063
parent 37318 32b3d16b04f6
child 37402 12cb33916e37
equal deleted inserted replaced
37398:e194213451c9 37399:34f080a12063
    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 open Sledgehammer_Util
    21 open Sledgehammer_FOL_Clause
    22 open Sledgehammer_FOL_Clause
    22 open Sledgehammer_Fact_Preprocessor
    23 open Sledgehammer_Fact_Preprocessor
    23 open Sledgehammer_HOL_Clause
    24 open Sledgehammer_HOL_Clause
    24 open Sledgehammer_Proof_Reconstruct
    25 open Sledgehammer_Proof_Reconstruct
    25 open Sledgehammer_Fact_Filter
    26 open Sledgehammer_Fact_Filter
   116      (case strip_combterm_comb tm of
   117      (case strip_combterm_comb tm of
   117           (CombConst(("equal", _), _, _), tms) =>
   118           (CombConst(("equal", _), _, _), tms) =>
   118             metis_lit pol "=" (map hol_term_to_fol_FT tms)
   119             metis_lit pol "=" (map hol_term_to_fol_FT tms)
   119         | _ => metis_lit pol "{}" [hol_term_to_fol_FT tm])   (*hBOOL*);
   120         | _ => metis_lit pol "{}" [hol_term_to_fol_FT tm])   (*hBOOL*);
   120 
   121 
   121 fun literals_of_hol_thm thy mode t =
   122 fun literals_of_hol_term thy mode t =
   122       let val (lits, types_sorts) = literals_of_term thy t
   123       let val (lits, types_sorts) = literals_of_term thy t
   123       in  (map (hol_literal_to_fol mode) lits, types_sorts) end;
   124       in  (map (hol_literal_to_fol mode) lits, types_sorts) end;
   124 
   125 
   125 (*Sign should be "true" for conjecture type constraints, "false" for type lits in clauses.*)
   126 (*Sign should be "true" for conjecture type constraints, "false" for type lits in clauses.*)
   126 fun metis_of_type_literals pos (TyLitVar (s, (s', _))) =
   127 fun metis_of_type_literals pos (TyLitVar (s, (s', _))) =
   132   | default_sort ctxt (TFree (x, s)) = (s = the_default [] (Variable.def_sort ctxt (x, ~1)));
   133   | default_sort ctxt (TFree (x, s)) = (s = the_default [] (Variable.def_sort ctxt (x, ~1)));
   133 
   134 
   134 fun metis_of_tfree tf =
   135 fun metis_of_tfree tf =
   135   Metis.Thm.axiom (Metis.LiteralSet.singleton (metis_of_type_literals true tf));
   136   Metis.Thm.axiom (Metis.LiteralSet.singleton (metis_of_type_literals true tf));
   136 
   137 
   137 fun hol_thm_to_fol is_conjecture ctxt mode th =
   138 fun hol_thm_to_fol is_conjecture ctxt mode j skolem_somes th =
   138   let val thy = ProofContext.theory_of ctxt
   139   let
   139       val (mlits, types_sorts) =
   140     val thy = ProofContext.theory_of ctxt
   140              (literals_of_hol_thm thy mode o HOLogic.dest_Trueprop o prop_of) th
   141     val (skolem_somes, (mlits, types_sorts)) =
       
   142      th |> prop_of |> kill_skolem_Eps j skolem_somes
       
   143         ||> (HOLogic.dest_Trueprop #> literals_of_hol_term thy mode)
   141   in
   144   in
   142       if is_conjecture then
   145       if is_conjecture then
   143           (Metis.Thm.axiom (Metis.LiteralSet.fromList mlits),
   146           (Metis.Thm.axiom (Metis.LiteralSet.fromList mlits),
   144            type_literals_for_types types_sorts)
   147            type_literals_for_types types_sorts, skolem_somes)
   145       else
   148       else
   146         let val tylits = filter_out (default_sort ctxt) types_sorts
   149         let val tylits = filter_out (default_sort ctxt) types_sorts
   147                          |> type_literals_for_types
   150                          |> type_literals_for_types
   148             val mtylits = if Config.get ctxt type_lits
   151             val mtylits = if Config.get ctxt type_lits
   149                           then map (metis_of_type_literals false) tylits else []
   152                           then map (metis_of_type_literals false) tylits else []
   150         in
   153         in
   151           (Metis.Thm.axiom (Metis.LiteralSet.fromList(mtylits @ mlits)), [])
   154           (Metis.Thm.axiom (Metis.LiteralSet.fromList(mtylits @ mlits)), [],
       
   155            skolem_somes)
   152         end
   156         end
   153   end;
   157   end;
   154 
   158 
   155 (* ARITY CLAUSE *)
   159 (* ARITY CLAUSE *)
   156 
   160 
   229         | NONE    =>
   233         | NONE    =>
   230       case strip_prefix tfree_prefix x of
   234       case strip_prefix tfree_prefix x of
   231           SOME tf => mk_tfree ctxt tf
   235           SOME tf => mk_tfree ctxt tf
   232         | NONE    => error ("fol_type_to_isa: " ^ x));
   236         | NONE    => error ("fol_type_to_isa: " ^ x));
   233 
   237 
       
   238 fun reintroduce_skolem_Eps thy skolem_somes =
       
   239   let
       
   240     fun aux Ts args t =
       
   241       case t of
       
   242         t1 $ t2 => aux Ts (aux Ts [] t2 :: args) t1
       
   243       | Abs (s, T, t') => list_comb (Abs (s, T, aux (T :: Ts) [] t'), args)
       
   244       | Const (s, T) =>
       
   245         if String.isPrefix skolem_Eps_pseudo_theory s then
       
   246           let
       
   247             val (T', args', def') = AList.lookup (op =) skolem_somes s |> the
       
   248           in
       
   249             def' |> subst_free (args' ~~ args)
       
   250                  |> map_types Type_Infer.paramify_vars
       
   251           end
       
   252         else
       
   253           list_comb (t, args)
       
   254       | t => list_comb (t, args)
       
   255   in aux [] [] end
       
   256 
   234 (*Maps metis terms to isabelle terms*)
   257 (*Maps metis terms to isabelle terms*)
   235 fun fol_term_to_hol_RAW ctxt fol_tm =
   258 fun hol_term_from_fol_PT ctxt fol_tm =
   236   let val thy = ProofContext.theory_of ctxt
   259   let val thy = ProofContext.theory_of ctxt
   237       val _ = trace_msg (fn () => "fol_term_to_hol: " ^ Metis.Term.toString fol_tm)
   260       val _ = trace_msg (fn () => "hol_term_from_fol_PT: " ^
       
   261                                   Metis.Term.toString fol_tm)
   238       fun tm_to_tt (Metis.Term.Var v) =
   262       fun tm_to_tt (Metis.Term.Var v) =
   239              (case strip_prefix tvar_prefix v of
   263              (case strip_prefix tvar_prefix v of
   240                   SOME w => Type (make_tvar w)
   264                   SOME w => Type (make_tvar w)
   241                 | NONE =>
   265                 | NONE =>
   242               case strip_prefix schematic_var_prefix v of
   266               case strip_prefix schematic_var_prefix v of
   283             case strip_prefix fixed_var_prefix a of
   307             case strip_prefix fixed_var_prefix a of
   284                 SOME b =>
   308                 SOME b =>
   285                   let val opr = Term.Free(b, HOLogic.typeT)
   309                   let val opr = Term.Free(b, HOLogic.typeT)
   286                   in  apply_list opr (length ts) (map tm_to_tt ts)  end
   310                   in  apply_list opr (length ts) (map tm_to_tt ts)  end
   287               | NONE => error ("unexpected metis function: " ^ a)
   311               | NONE => error ("unexpected metis function: " ^ a)
   288   in  case tm_to_tt fol_tm of Term t => t | _ => error "fol_tm_to_tt: Term expected"  end;
   312   in
       
   313     case tm_to_tt fol_tm of
       
   314       Term t => t
       
   315     | _ => error "fol_tm_to_tt: Term expected"
       
   316   end
   289 
   317 
   290 (*Maps fully-typed metis terms to isabelle terms*)
   318 (*Maps fully-typed metis terms to isabelle terms*)
   291 fun fol_term_to_hol_FT ctxt fol_tm =
   319 fun hol_term_from_fol_FT ctxt fol_tm =
   292   let val _ = trace_msg (fn () => "fol_term_to_hol_FT: " ^ Metis.Term.toString fol_tm)
   320   let val _ = trace_msg (fn () => "hol_term_from_fol_FT: " ^
       
   321                                   Metis.Term.toString fol_tm)
   293       fun cvt (Metis.Term.Fn ("ti", [Metis.Term.Var v, _])) =
   322       fun cvt (Metis.Term.Fn ("ti", [Metis.Term.Var v, _])) =
   294              (case strip_prefix schematic_var_prefix v of
   323              (case strip_prefix schematic_var_prefix v of
   295                   SOME w =>  mk_var(w, dummyT)
   324                   SOME w =>  mk_var(w, dummyT)
   296                 | NONE   => mk_var(v, dummyT))
   325                 | NONE   => mk_var(v, dummyT))
   297         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn ("=",[]), _])) =
   326         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn ("=",[]), _])) =
   300            (case strip_prefix const_prefix x of
   329            (case strip_prefix const_prefix x of
   301                 SOME c => Const (invert_const c, dummyT)
   330                 SOME c => Const (invert_const c, dummyT)
   302               | NONE => (*Not a constant. Is it a fixed variable??*)
   331               | NONE => (*Not a constant. Is it a fixed variable??*)
   303             case strip_prefix fixed_var_prefix x of
   332             case strip_prefix fixed_var_prefix x of
   304                 SOME v => Free (v, fol_type_to_isa ctxt ty)
   333                 SOME v => Free (v, fol_type_to_isa ctxt ty)
   305               | NONE => error ("fol_term_to_hol_FT bad constant: " ^ x))
   334               | NONE => error ("hol_term_from_fol_FT bad constant: " ^ x))
   306         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn (".",[tm1,tm2]), _])) =
   335         | cvt (Metis.Term.Fn ("ti", [Metis.Term.Fn (".",[tm1,tm2]), _])) =
   307             cvt tm1 $ cvt tm2
   336             cvt tm1 $ cvt tm2
   308         | cvt (Metis.Term.Fn (".",[tm1,tm2])) = (*untyped application*)
   337         | cvt (Metis.Term.Fn (".",[tm1,tm2])) = (*untyped application*)
   309             cvt tm1 $ cvt tm2
   338             cvt tm1 $ cvt tm2
   310         | cvt (Metis.Term.Fn ("{}", [arg])) = cvt arg   (*hBOOL*)
   339         | cvt (Metis.Term.Fn ("{}", [arg])) = cvt arg   (*hBOOL*)
   314            (case strip_prefix const_prefix x of
   343            (case strip_prefix const_prefix x of
   315                 SOME c => Const (invert_const c, dummyT)
   344                 SOME c => Const (invert_const c, dummyT)
   316               | NONE => (*Not a constant. Is it a fixed variable??*)
   345               | NONE => (*Not a constant. Is it a fixed variable??*)
   317             case strip_prefix fixed_var_prefix x of
   346             case strip_prefix fixed_var_prefix x of
   318                 SOME v => Free (v, dummyT)
   347                 SOME v => Free (v, dummyT)
   319               | NONE => (trace_msg (fn () => "fol_term_to_hol_FT bad const: " ^ x);
   348               | NONE => (trace_msg (fn () => "hol_term_from_fol_FT bad const: " ^ x);
   320                   fol_term_to_hol_RAW ctxt t))
   349                   hol_term_from_fol_PT ctxt t))
   321         | cvt t = (trace_msg (fn () => "fol_term_to_hol_FT bad term: " ^ Metis.Term.toString t);
   350         | cvt t = (trace_msg (fn () => "hol_term_from_fol_FT bad term: " ^ Metis.Term.toString t);
   322             fol_term_to_hol_RAW ctxt t)
   351             hol_term_from_fol_PT ctxt t)
   323   in  cvt fol_tm   end;
   352   in fol_tm |> cvt end
   324 
   353 
   325 fun fol_term_to_hol ctxt FO = fol_term_to_hol_RAW ctxt
   354 fun hol_term_from_fol FT = hol_term_from_fol_FT
   326   | fol_term_to_hol ctxt HO = fol_term_to_hol_RAW ctxt
   355   | hol_term_from_fol _ = hol_term_from_fol_PT
   327   | fol_term_to_hol ctxt FT = fol_term_to_hol_FT ctxt;
   356 
   328 
   357 fun hol_terms_from_fol ctxt mode skolem_somes fol_tms =
   329 fun fol_terms_to_hol ctxt mode fol_tms =
   358   let val thy = ProofContext.theory_of ctxt
   330   let val ts = map (fol_term_to_hol ctxt mode) fol_tms
   359       val ts = map (hol_term_from_fol mode ctxt) fol_tms
   331       val _ = trace_msg (fn () => "  calling type inference:")
   360       val _ = trace_msg (fn () => "  calling type inference:")
   332       val _ = app (fn t => trace_msg (fn () => Syntax.string_of_term ctxt t)) ts
   361       val _ = app (fn t => trace_msg (fn () => Syntax.string_of_term ctxt t)) ts
   333       val ts' = infer_types ctxt ts;
   362       val ts' =
       
   363         ts |> map (reintroduce_skolem_Eps thy skolem_somes) |> infer_types ctxt
   334       val _ = app (fn t => trace_msg
   364       val _ = app (fn t => trace_msg
   335                     (fn () => "  final term: " ^ Syntax.string_of_term ctxt t ^
   365                     (fn () => "  final term: " ^ Syntax.string_of_term ctxt t ^
   336                               "  of type  " ^ Syntax.string_of_typ ctxt (type_of t)))
   366                               "  of type  " ^ Syntax.string_of_typ ctxt (type_of t)))
   337                   ts'
   367                   ts'
   338   in  ts'  end;
   368   in  ts'  end;
   369 (* INFERENCE RULE: AXIOM *)
   399 (* INFERENCE RULE: AXIOM *)
   370 fun axiom_inf thpairs th = Thm.incr_indexes 1 (lookth thpairs th);
   400 fun axiom_inf thpairs th = Thm.incr_indexes 1 (lookth thpairs th);
   371     (*This causes variables to have an index of 1 by default. SEE ALSO mk_var above.*)
   401     (*This causes variables to have an index of 1 by default. SEE ALSO mk_var above.*)
   372 
   402 
   373 (* INFERENCE RULE: ASSUME *)
   403 (* INFERENCE RULE: ASSUME *)
   374 fun assume_inf ctxt mode atm =
   404 fun assume_inf ctxt mode skolem_somes atm =
   375   inst_excluded_middle
   405   inst_excluded_middle
   376     (ProofContext.theory_of ctxt)
   406     (ProofContext.theory_of ctxt)
   377     (singleton (fol_terms_to_hol ctxt mode) (Metis.Term.Fn atm));
   407     (singleton (hol_terms_from_fol ctxt mode skolem_somes) (Metis.Term.Fn atm))
   378 
   408 
   379 (* INFERENCE RULE: INSTANTIATE (Subst). Type instantiations are ignored. Trying to reconstruct
   409 (* INFERENCE RULE: INSTANTIATE (Subst). Type instantiations are ignored. Trying to reconstruct
   380    them admits new possibilities of errors, e.g. concerning sorts. Instead we try to arrange
   410    them admits new possibilities of errors, e.g. concerning sorts. Instead we try to arrange
   381    that new TVars are distinct and that types can be inferred from terms.*)
   411    that new TVars are distinct and that types can be inferred from terms.*)
   382 fun inst_inf ctxt mode thpairs fsubst th =
   412 fun inst_inf ctxt mode skolem_somes thpairs fsubst th =
   383   let val thy = ProofContext.theory_of ctxt
   413   let val thy = ProofContext.theory_of ctxt
   384       val i_th   = lookth thpairs th
   414       val i_th   = lookth thpairs th
   385       val i_th_vars = Term.add_vars (prop_of i_th) []
   415       val i_th_vars = Term.add_vars (prop_of i_th) []
   386       fun find_var x = the (List.find (fn ((a,_),_) => a=x) i_th_vars)
   416       fun find_var x = the (List.find (fn ((a,_),_) => a=x) i_th_vars)
   387       fun subst_translation (x,y) =
   417       fun subst_translation (x,y) =
   388             let val v = find_var x
   418             let val v = find_var x
   389                 val t = fol_term_to_hol ctxt mode y (*we call infer_types below*)
   419                 (* We call "reintroduce_skolem_Eps" and "infer_types" below. *)
       
   420                 val t = hol_term_from_fol mode ctxt y
   390             in  SOME (cterm_of thy (Var v), t)  end
   421             in  SOME (cterm_of thy (Var v), t)  end
   391             handle Option =>
   422             handle Option =>
   392                 (trace_msg (fn() => "List.find failed for the variable " ^ x ^
   423                 (trace_msg (fn() => "List.find failed for the variable " ^ x ^
   393                                        " in " ^ Display.string_of_thm ctxt i_th);
   424                                        " in " ^ Display.string_of_thm ctxt i_th);
   394                  NONE)
   425                  NONE)
   399                 SOME _ => NONE          (*type instantiations are forbidden!*)
   430                 SOME _ => NONE          (*type instantiations are forbidden!*)
   400               | NONE   => SOME (a,t)    (*internal Metis var?*)
   431               | NONE   => SOME (a,t)    (*internal Metis var?*)
   401       val _ = trace_msg (fn () => "  isa th: " ^ Display.string_of_thm ctxt i_th)
   432       val _ = trace_msg (fn () => "  isa th: " ^ Display.string_of_thm ctxt i_th)
   402       val substs = map_filter remove_typeinst (Metis.Subst.toList fsubst)
   433       val substs = map_filter remove_typeinst (Metis.Subst.toList fsubst)
   403       val (vars,rawtms) = ListPair.unzip (map_filter subst_translation substs)
   434       val (vars,rawtms) = ListPair.unzip (map_filter subst_translation substs)
   404       val tms = infer_types ctxt rawtms;
   435       val tms = rawtms |> map (reintroduce_skolem_Eps thy skolem_somes)
       
   436                        |> infer_types ctxt
   405       val ctm_of = cterm_incr_types thy (1 + Thm.maxidx_of i_th)
   437       val ctm_of = cterm_incr_types thy (1 + Thm.maxidx_of i_th)
   406       val substs' = ListPair.zip (vars, map ctm_of tms)
   438       val substs' = ListPair.zip (vars, map ctm_of tms)
   407       val _ = trace_msg (fn () =>
   439       val _ = trace_msg (fn () =>
   408         cat_lines ("subst_translations:" ::
   440         cat_lines ("subst_translations:" ::
   409           (substs' |> map (fn (x, y) =>
   441           (substs' |> map (fn (x, y) =>
   410             Syntax.string_of_term ctxt (term_of x) ^ " |-> " ^
   442             Syntax.string_of_term ctxt (term_of x) ^ " |-> " ^
   411             Syntax.string_of_term ctxt (term_of y)))));
   443             Syntax.string_of_term ctxt (term_of y)))));
   412   in  cterm_instantiate substs' i_th end
   444   in cterm_instantiate substs' i_th end
   413   handle THM (msg, _, _) => error ("metis error (inst_inf):\n" ^ msg)
   445   handle THM (msg, _, _) => error ("metis error (inst_inf):\n" ^ msg)
   414        | ERROR msg => error ("metis error (inst_inf):\n" ^ msg ^
   446        | ERROR msg => error ("metis error (inst_inf):\n" ^ msg ^
   415                              "\n(Perhaps you want to try \"metisFT\".)")
   447                              "\n(Perhaps you want to try \"metisFT\" if you \
       
   448                              \haven't done so already.)")
   416 
   449 
   417 (* INFERENCE RULE: RESOLVE *)
   450 (* INFERENCE RULE: RESOLVE *)
   418 
   451 
   419 (*Like RSN, but we rename apart only the type variables. Vars here typically have an index
   452 (*Like RSN, but we rename apart only the type variables. Vars here typically have an index
   420   of 1, and the use of RSN would increase this typically to 3. Instantiations of those Vars
   453   of 1, and the use of RSN would increase this typically to 3. Instantiations of those Vars
   426       case distinct Thm.eq_thm ths of
   459       case distinct Thm.eq_thm ths of
   427         [th] => th
   460         [th] => th
   428       | _ => raise THM ("resolve_inc_tyvars: unique result expected", i, [tha,thb])
   461       | _ => raise THM ("resolve_inc_tyvars: unique result expected", i, [tha,thb])
   429   end;
   462   end;
   430 
   463 
   431 fun resolve_inf ctxt mode thpairs atm th1 th2 =
   464 fun resolve_inf ctxt mode skolem_somes thpairs atm th1 th2 =
   432   let
   465   let
   433     val i_th1 = lookth thpairs th1 and i_th2 = lookth thpairs th2
   466     val i_th1 = lookth thpairs th1 and i_th2 = lookth thpairs th2
   434     val _ = trace_msg (fn () => "  isa th1 (pos): " ^ Display.string_of_thm ctxt i_th1)
   467     val _ = trace_msg (fn () => "  isa th1 (pos): " ^ Display.string_of_thm ctxt i_th1)
   435     val _ = trace_msg (fn () => "  isa th2 (neg): " ^ Display.string_of_thm ctxt i_th2)
   468     val _ = trace_msg (fn () => "  isa th2 (neg): " ^ Display.string_of_thm ctxt i_th2)
   436   in
   469   in
   437     if is_TrueI i_th1 then i_th2 (*Trivial cases where one operand is type info*)
   470     if is_TrueI i_th1 then i_th2 (*Trivial cases where one operand is type info*)
   438     else if is_TrueI i_th2 then i_th1
   471     else if is_TrueI i_th2 then i_th1
   439     else
   472     else
   440       let
   473       let
   441         val i_atm = singleton (fol_terms_to_hol ctxt mode) (Metis.Term.Fn atm)
   474         val i_atm = singleton (hol_terms_from_fol ctxt mode skolem_somes)
       
   475                               (Metis.Term.Fn atm)
   442         val _ = trace_msg (fn () => "  atom: " ^ Syntax.string_of_term ctxt i_atm)
   476         val _ = trace_msg (fn () => "  atom: " ^ Syntax.string_of_term ctxt i_atm)
   443         val prems_th1 = prems_of i_th1
   477         val prems_th1 = prems_of i_th1
   444         val prems_th2 = prems_of i_th2
   478         val prems_th2 = prems_of i_th2
   445         val index_th1 = get_index (mk_not i_atm) prems_th1
   479         val index_th1 = get_index (mk_not i_atm) prems_th1
   446               handle Empty => error "Failed to find literal in th1"
   480               handle Empty => error "Failed to find literal in th1"
   453 
   487 
   454 (* INFERENCE RULE: REFL *)
   488 (* INFERENCE RULE: REFL *)
   455 val refl_x = cterm_of @{theory} (Var (hd (Term.add_vars (prop_of REFL_THM) [])));
   489 val refl_x = cterm_of @{theory} (Var (hd (Term.add_vars (prop_of REFL_THM) [])));
   456 val refl_idx = 1 + Thm.maxidx_of REFL_THM;
   490 val refl_idx = 1 + Thm.maxidx_of REFL_THM;
   457 
   491 
   458 fun refl_inf ctxt mode t =
   492 fun refl_inf ctxt mode skolem_somes t =
   459   let val thy = ProofContext.theory_of ctxt
   493   let val thy = ProofContext.theory_of ctxt
   460       val i_t = singleton (fol_terms_to_hol ctxt mode) t
   494       val i_t = singleton (hol_terms_from_fol ctxt mode skolem_somes) t
   461       val _ = trace_msg (fn () => "  term: " ^ Syntax.string_of_term ctxt i_t)
   495       val _ = trace_msg (fn () => "  term: " ^ Syntax.string_of_term ctxt i_t)
   462       val c_t = cterm_incr_types thy refl_idx i_t
   496       val c_t = cterm_incr_types thy refl_idx i_t
   463   in  cterm_instantiate [(refl_x, c_t)] REFL_THM  end;
   497   in  cterm_instantiate [(refl_x, c_t)] REFL_THM  end;
   464 
   498 
   465 fun get_ty_arg_size _ (Const (@{const_name "op ="}, _)) = 0  (*equality has no type arguments*)
   499 fun get_ty_arg_size _ (Const (@{const_name "op ="}, _)) = 0  (*equality has no type arguments*)
   466   | get_ty_arg_size thy (Const (c, _)) = (num_type_args thy c handle TYPE _ => 0)
   500   | get_ty_arg_size thy (Const (c, _)) = (num_type_args thy c handle TYPE _ => 0)
   467   | get_ty_arg_size _ _ = 0;
   501   | get_ty_arg_size _ _ = 0;
   468 
   502 
   469 (* INFERENCE RULE: EQUALITY *)
   503 (* INFERENCE RULE: EQUALITY *)
   470 fun equality_inf ctxt mode (pos, atm) fp fr =
   504 fun equality_inf ctxt mode skolem_somes (pos, atm) fp fr =
   471   let val thy = ProofContext.theory_of ctxt
   505   let val thy = ProofContext.theory_of ctxt
   472       val m_tm = Metis.Term.Fn atm
   506       val m_tm = Metis.Term.Fn atm
   473       val [i_atm,i_tm] = fol_terms_to_hol ctxt mode [m_tm, fr]
   507       val [i_atm,i_tm] = hol_terms_from_fol ctxt mode skolem_somes [m_tm, fr]
   474       val _ = trace_msg (fn () => "sign of the literal: " ^ Bool.toString pos)
   508       val _ = trace_msg (fn () => "sign of the literal: " ^ Bool.toString pos)
   475       fun replace_item_list lx 0 (_::ls) = lx::ls
   509       fun replace_item_list lx 0 (_::ls) = lx::ls
   476         | replace_item_list lx i (l::ls) = l :: replace_item_list lx (i-1) ls
   510         | replace_item_list lx i (l::ls) = l :: replace_item_list lx (i-1) ls
   477       fun path_finder_FO tm [] = (tm, Term.Bound 0)
   511       fun path_finder_FO tm [] = (tm, Term.Bound 0)
   478         | path_finder_FO tm (p::ps) =
   512         | path_finder_FO tm (p::ps) =
   537         (ListPair.zip (OldTerm.term_vars (prop_of subst'), [tm_abs, tm_subst, i_tm]))
   571         (ListPair.zip (OldTerm.term_vars (prop_of subst'), [tm_abs, tm_subst, i_tm]))
   538   in  cterm_instantiate eq_terms subst'  end;
   572   in  cterm_instantiate eq_terms subst'  end;
   539 
   573 
   540 val factor = Seq.hd o distinct_subgoals_tac;
   574 val factor = Seq.hd o distinct_subgoals_tac;
   541 
   575 
   542 fun step _ _ thpairs (fol_th, Metis.Proof.Axiom _) = factor (axiom_inf thpairs fol_th)
   576 fun step ctxt mode skolem_somes thpairs p =
   543   | step ctxt mode _ (_, Metis.Proof.Assume f_atm) = assume_inf ctxt mode f_atm
   577   case p of
   544   | step ctxt mode thpairs (_, Metis.Proof.Subst (f_subst, f_th1)) =
   578     (fol_th, Metis.Proof.Axiom _) => factor (axiom_inf thpairs fol_th)
   545       factor (inst_inf ctxt mode thpairs f_subst f_th1)
   579   | (_, Metis.Proof.Assume f_atm) => assume_inf ctxt mode skolem_somes f_atm
   546   | step ctxt mode thpairs (_, Metis.Proof.Resolve(f_atm, f_th1, f_th2)) =
   580   | (_, Metis.Proof.Subst (f_subst, f_th1)) =>
   547       factor (resolve_inf ctxt mode thpairs f_atm f_th1 f_th2)
   581     factor (inst_inf ctxt mode skolem_somes thpairs f_subst f_th1)
   548   | step ctxt mode _ (_, Metis.Proof.Refl f_tm) = refl_inf ctxt mode f_tm
   582   | (_, Metis.Proof.Resolve(f_atm, f_th1, f_th2)) =>
   549   | step ctxt mode _ (_, Metis.Proof.Equality (f_lit, f_p, f_r)) =
   583     factor (resolve_inf ctxt mode skolem_somes thpairs f_atm f_th1 f_th2)
   550       equality_inf ctxt mode f_lit f_p f_r;
   584   | (_, Metis.Proof.Refl f_tm) => refl_inf ctxt mode skolem_somes f_tm
       
   585   | (_, Metis.Proof.Equality (f_lit, f_p, f_r)) =>
       
   586     equality_inf ctxt mode skolem_somes f_lit f_p f_r
   551 
   587 
   552 fun real_literal (_, (c, _)) = not (String.isPrefix class_prefix c);
   588 fun real_literal (_, (c, _)) = not (String.isPrefix class_prefix c);
   553 
   589 
   554 fun translate _ _ thpairs [] = thpairs
   590 (* TODO: use "fold" instead *)
   555   | translate mode ctxt thpairs ((fol_th, inf) :: infpairs) =
   591 fun translate _ _ _ thpairs [] = thpairs
       
   592   | translate ctxt mode skolem_somes thpairs ((fol_th, inf) :: infpairs) =
   556       let val _ = trace_msg (fn () => "=============================================")
   593       let val _ = trace_msg (fn () => "=============================================")
   557           val _ = trace_msg (fn () => "METIS THM: " ^ Metis.Thm.toString fol_th)
   594           val _ = trace_msg (fn () => "METIS THM: " ^ Metis.Thm.toString fol_th)
   558           val _ = trace_msg (fn () => "INFERENCE: " ^ Metis.Proof.inferenceToString inf)
   595           val _ = trace_msg (fn () => "INFERENCE: " ^ Metis.Proof.inferenceToString inf)
   559           val th = Meson.flexflex_first_order (step ctxt mode thpairs (fol_th, inf))
   596           val th = Meson.flexflex_first_order (step ctxt mode skolem_somes
       
   597                                                     thpairs (fol_th, inf))
   560           val _ = trace_msg (fn () => "ISABELLE THM: " ^ Display.string_of_thm ctxt th)
   598           val _ = trace_msg (fn () => "ISABELLE THM: " ^ Display.string_of_thm ctxt th)
   561           val _ = trace_msg (fn () => "=============================================")
   599           val _ = trace_msg (fn () => "=============================================")
   562           val n_metis_lits =
   600           val n_metis_lits =
   563             length (filter real_literal (Metis.LiteralSet.toList (Metis.Thm.clause fol_th)))
   601             length (filter real_literal (Metis.LiteralSet.toList (Metis.Thm.clause fol_th)))
   564       in
   602       in
   565           if nprems_of th = n_metis_lits then ()
   603           if nprems_of th = n_metis_lits then ()
   566           else error "Metis: proof reconstruction has gone wrong";
   604           else error "Metis: proof reconstruction has gone wrong";
   567           translate mode ctxt ((fol_th, th) :: thpairs) infpairs
   605           translate ctxt mode skolem_somes ((fol_th, th) :: thpairs) infpairs
   568       end;
   606       end;
   569 
   607 
   570 (*Determining which axiom clauses are actually used*)
   608 (*Determining which axiom clauses are actually used*)
   571 fun used_axioms axioms (th, Metis.Proof.Axiom _) = SOME (lookth axioms th)
   609 fun used_axioms axioms (th, Metis.Proof.Axiom _) = SOME (lookth axioms th)
   572   | used_axioms _ _ = NONE;
   610   | used_axioms _ _ = NONE;
   590 (* Logic maps manage the interface between HOL and first-order logic.        *)
   628 (* Logic maps manage the interface between HOL and first-order logic.        *)
   591 (* ------------------------------------------------------------------------- *)
   629 (* ------------------------------------------------------------------------- *)
   592 
   630 
   593 type logic_map =
   631 type logic_map =
   594   {axioms: (Metis.Thm.thm * thm) list,
   632   {axioms: (Metis.Thm.thm * thm) list,
   595    tfrees: type_literal list};
   633    tfrees: type_literal list,
       
   634    skolem_somes: (string * (typ * term list * term)) list}
   596 
   635 
   597 fun const_in_metis c (pred, tm_list) =
   636 fun const_in_metis c (pred, tm_list) =
   598   let
   637   let
   599     fun in_mterm (Metis.Term.Var _) = false
   638     fun in_mterm (Metis.Term.Var _) = false
   600       | in_mterm (Metis.Term.Fn (".", tm_list)) = exists in_mterm tm_list
   639       | in_mterm (Metis.Term.Fn (".", tm_list)) = exists in_mterm tm_list
   608     |> type_literals_for_types
   647     |> type_literals_for_types
   609   end;
   648   end;
   610 
   649 
   611 (*transform isabelle type / arity clause to metis clause *)
   650 (*transform isabelle type / arity clause to metis clause *)
   612 fun add_type_thm [] lmap = lmap
   651 fun add_type_thm [] lmap = lmap
   613   | add_type_thm ((ith, mth) :: cls) {axioms, tfrees} =
   652   | add_type_thm ((ith, mth) :: cls) {axioms, tfrees, skolem_somes} =
   614       add_type_thm cls {axioms = (mth, ith) :: axioms,
   653       add_type_thm cls {axioms = (mth, ith) :: axioms, tfrees = tfrees,
   615                         tfrees = tfrees}
   654                         skolem_somes = skolem_somes}
   616 
   655 
   617 (*Insert non-logical axioms corresponding to all accumulated TFrees*)
   656 (*Insert non-logical axioms corresponding to all accumulated TFrees*)
   618 fun add_tfrees {axioms, tfrees} : logic_map =
   657 fun add_tfrees {axioms, tfrees, skolem_somes} : logic_map =
   619      {axioms = (map (fn tf => (metis_of_tfree tf, TrueI)) (distinct op= tfrees)) @ axioms,
   658      {axioms = map (rpair TrueI o metis_of_tfree) (distinct (op =) tfrees) @
   620       tfrees = tfrees};
   659                axioms,
       
   660       tfrees = tfrees, skolem_somes = skolem_somes}
   621 
   661 
   622 fun string_of_mode FO = "FO"
   662 fun string_of_mode FO = "FO"
   623   | string_of_mode HO = "HO"
   663   | string_of_mode HO = "HO"
   624   | string_of_mode FT = "FT"
   664   | string_of_mode FT = "FT"
   625 
   665 
   626 (* Function to generate metis clauses, including comb and type clauses *)
   666 (* Function to generate metis clauses, including comb and type clauses *)
   627 fun build_map mode0 ctxt cls ths =
   667 fun build_map mode0 ctxt cls ths =
   628   let val thy = ProofContext.theory_of ctxt
   668   let val thy = ProofContext.theory_of ctxt
   629       (*The modes FO and FT are sticky. HO can be downgraded to FO.*)
   669       (*The modes FO and FT are sticky. HO can be downgraded to FO.*)
   630       fun set_mode FO = FO
   670       fun set_mode FO = FO
   631         | set_mode HO = if forall (Meson.is_fol_term thy o prop_of) (cls@ths) then FO else HO
   671         | set_mode HO =
       
   672           if forall (is_quasi_fol_term thy o prop_of) (cls @ ths) then FO
       
   673           else HO
   632         | set_mode FT = FT
   674         | set_mode FT = FT
   633       val mode = set_mode mode0
   675       val mode = set_mode mode0
   634       (*transform isabelle clause to metis clause *)
   676       (*transform isabelle clause to metis clause *)
   635       fun add_thm is_conjecture ith {axioms, tfrees} : logic_map =
   677       fun add_thm is_conjecture ith {axioms, tfrees, skolem_somes} : logic_map =
   636         let val (mth, tfree_lits) = hol_thm_to_fol is_conjecture ctxt mode ith
   678         let
       
   679           val (mth, tfree_lits, skolem_somes) =
       
   680             hol_thm_to_fol is_conjecture ctxt mode (length axioms) skolem_somes
       
   681                            ith
   637         in
   682         in
   638            {axioms = (mth, Meson.make_meta_clause ith) :: axioms,
   683            {axioms = (mth, Meson.make_meta_clause ith) :: axioms,
   639             tfrees = union (op =) tfree_lits tfrees}
   684             tfrees = union (op =) tfree_lits tfrees,
       
   685             skolem_somes = skolem_somes}
   640         end;
   686         end;
   641       val lmap0 = fold (add_thm true) cls {axioms = [], tfrees = init_tfrees ctxt}
   687       val lmap = {axioms = [], tfrees = init_tfrees ctxt, skolem_somes = []}
   642       val lmap = fold (add_thm false) ths (add_tfrees lmap0)
   688                  |> fold (add_thm true) cls
       
   689                  |> add_tfrees
       
   690                  |> fold (add_thm false) ths
   643       val clause_lists = map (Metis.Thm.clause o #1) (#axioms lmap)
   691       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
   692       fun used c = exists (Metis.LiteralSet.exists (const_in_metis c o #2)) clause_lists
   645       (*Now check for the existence of certain combinators*)
   693       (*Now check for the existence of certain combinators*)
   646       val thI  = if used "c_COMBI" then [cnf_th @{theory} @{thm COMBI_def}] else []
   694       val thI  = if used "c_COMBI" then [cnf_th @{theory} @{thm COMBI_def}] else []
   647       val thK  = if used "c_COMBK" then [cnf_th @{theory} @{thm COMBK_def}] else []
   695       val thK  = if used "c_COMBK" then [cnf_th @{theory} @{thm COMBK_def}] else []
   648       val thB   = if used "c_COMBB" then [cnf_th @{theory} @{thm COMBB_def}] else []
   696       val thB   = if used "c_COMBB" then [cnf_th @{theory} @{thm COMBB_def}] else []
   649       val thC   = if used "c_COMBC" then [cnf_th @{theory} @{thm COMBC_def}] else []
   697       val thC   = if used "c_COMBC" then [cnf_th @{theory} @{thm COMBC_def}] else []
   650       val thS   = if used "c_COMBS" then [cnf_th @{theory} @{thm COMBS_def}] else []
   698       val thS   = if used "c_COMBS" then [cnf_th @{theory} @{thm COMBS_def}] else []
   651       val thEQ  = if used "c_fequal" then [cnf_th @{theory} @{thm fequal_imp_equal}, cnf_th @{theory} @{thm equal_imp_fequal}] else []
   699       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
   700       val lmap =
   653                   else fold (add_thm false) (thEQ @ thS @ thC @ thB @ thK @ thI) lmap
   701         lmap |> mode <> FO
       
   702                 ? fold (add_thm false) (thEQ @ thS @ thC @ thB @ thK @ thI)
   654   in
   703   in
   655       (mode, add_type_thm (type_ext thy (map prop_of (cls @ ths))) lmap')
   704       (mode, add_type_thm (type_ext thy (map prop_of (cls @ ths))) lmap)
   656   end;
   705   end;
   657 
   706 
   658 fun refute cls =
   707 fun refute cls =
   659     Metis.Resolution.loop (Metis.Resolution.new Metis.Resolution.default cls);
   708     Metis.Resolution.loop (Metis.Resolution.new Metis.Resolution.default cls);
   660 
   709 
   662 
   711 
   663 fun common_thm ths1 ths2 = exists (member Thm.eq_thm ths1) (map Meson.make_meta_clause ths2);
   712 fun common_thm ths1 ths2 = exists (member Thm.eq_thm ths1) (map Meson.make_meta_clause ths2);
   664 
   713 
   665 exception METIS of string;
   714 exception METIS of string;
   666 
   715 
   667 (* Main function to start metis prove and reconstruction *)
   716 (* Main function to start metis proof and reconstruction *)
   668 fun FOL_SOLVE mode ctxt cls ths0 =
   717 fun FOL_SOLVE mode ctxt cls ths0 =
   669   let val thy = ProofContext.theory_of ctxt
   718   let val thy = ProofContext.theory_of ctxt
   670       val th_cls_pairs =
   719       val th_cls_pairs =
   671         map (fn th => (Thm.get_name_hint th, cnf_axiom thy th)) ths0
   720         map (fn th => (Thm.get_name_hint th, cnf_axiom thy th)) ths0
   672       val ths = maps #2 th_cls_pairs
   721       val ths = maps #2 th_cls_pairs
   673       val _ = trace_msg (fn () => "FOL_SOLVE: CONJECTURE CLAUSES")
   722       val _ = trace_msg (fn () => "FOL_SOLVE: CONJECTURE CLAUSES")
   674       val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) cls
   723       val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) cls
   675       val _ = trace_msg (fn () => "THEOREM CLAUSES")
   724       val _ = trace_msg (fn () => "THEOREM CLAUSES")
   676       val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) ths
   725       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
   726       val (mode, {axioms, tfrees, skolem_somes}) = build_map mode ctxt cls ths
   678       val _ = if null tfrees then ()
   727       val _ = if null tfrees then ()
   679               else (trace_msg (fn () => "TFREE CLAUSES");
   728               else (trace_msg (fn () => "TFREE CLAUSES");
   680                     app (fn tf => trace_msg (fn _ => tptp_of_type_literal true tf NONE |> fst)) tfrees)
   729                     app (fn tf => trace_msg (fn _ => tptp_of_type_literal true tf NONE |> fst)) tfrees)
   681       val _ = trace_msg (fn () => "CLAUSES GIVEN TO METIS")
   730       val _ = trace_msg (fn () => "CLAUSES GIVEN TO METIS")
   682       val thms = map #1 axioms
   731       val thms = map #1 axioms
   692             let val _ = trace_msg (fn () => "METIS RECONSTRUCTION START: " ^
   741             let val _ = trace_msg (fn () => "METIS RECONSTRUCTION START: " ^
   693                           Metis.Thm.toString mth)
   742                           Metis.Thm.toString mth)
   694                 val ctxt' = fold Variable.declare_constraints (map prop_of cls) ctxt
   743                 val ctxt' = fold Variable.declare_constraints (map prop_of cls) ctxt
   695                              (*add constraints arising from converting goal to clause form*)
   744                              (*add constraints arising from converting goal to clause form*)
   696                 val proof = Metis.Proof.proof mth
   745                 val proof = Metis.Proof.proof mth
   697                 val result = translate mode ctxt' axioms proof
   746                 val result = translate ctxt' mode skolem_somes axioms proof
   698                 and used = map_filter (used_axioms axioms) proof
   747                 and used = map_filter (used_axioms axioms) proof
   699                 val _ = trace_msg (fn () => "METIS COMPLETED...clauses actually used:")
   748                 val _ = trace_msg (fn () => "METIS COMPLETED...clauses actually used:")
   700                 val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) used
   749                 val _ = app (fn th => trace_msg (fn () => Display.string_of_thm ctxt th)) used
   701                 val unused = th_cls_pairs |> map_filter (fn (name, cls) =>
   750                 val unused = th_cls_pairs |> map_filter (fn (name, cls) =>
   702                   if common_thm used cls then NONE else SOME name)
   751                   if common_thm used cls then NONE else SOME name)