src/HOL/Tools/Metis/metis_reconstruct.ML
changeset 57408 39b3562e9edc
parent 57400 13b06c626163
child 58070 27ee844c2b4d
equal deleted inserted replaced
57407:140e16bc2a40 57408:39b3562e9edc
    11 sig
    11 sig
    12   type type_enc = ATP_Problem_Generate.type_enc
    12   type type_enc = ATP_Problem_Generate.type_enc
    13 
    13 
    14   exception METIS_RECONSTRUCT of string * string
    14   exception METIS_RECONSTRUCT of string * string
    15 
    15 
    16   val hol_clause_of_metis :
    16   val hol_clause_of_metis : Proof.context -> type_enc -> int Symtab.table ->
    17     Proof.context -> type_enc -> int Symtab.table
    17     (string * term) list * (string * term) list -> Metis_Thm.thm -> term
    18     -> (string * term) list * (string * term) list -> Metis_Thm.thm -> term
       
    19   val lookth : (Metis_Thm.thm * 'a) list -> Metis_Thm.thm -> 'a
    18   val lookth : (Metis_Thm.thm * 'a) list -> Metis_Thm.thm -> 'a
    20   val replay_one_inference :
    19   val replay_one_inference : Proof.context -> type_enc ->
    21     Proof.context -> type_enc
    20     (string * term) list * (string * term) list -> int Symtab.table ->
    22     -> (string * term) list * (string * term) list -> int Symtab.table
    21     Metis_Thm.thm * Metis_Proof.inference -> (Metis_Thm.thm * thm) list ->
    23     -> Metis_Thm.thm * Metis_Proof.inference -> (Metis_Thm.thm * thm) list
    22     (Metis_Thm.thm * thm) list
    24     -> (Metis_Thm.thm * thm) list
    23   val discharge_skolem_premises : Proof.context -> (thm * term) option list -> thm -> thm
    25   val discharge_skolem_premises :
       
    26     Proof.context -> (thm * term) option list -> thm -> thm
       
    27 end;
    24 end;
    28 
    25 
    29 structure Metis_Reconstruct : METIS_RECONSTRUCT =
    26 structure Metis_Reconstruct : METIS_RECONSTRUCT =
    30 struct
    27 struct
    31 
    28 
    37 exception METIS_RECONSTRUCT of string * string
    34 exception METIS_RECONSTRUCT of string * string
    38 
    35 
    39 val meta_not_not = @{thms not_not[THEN eq_reflection]}
    36 val meta_not_not = @{thms not_not[THEN eq_reflection]}
    40 
    37 
    41 fun atp_name_of_metis type_enc s =
    38 fun atp_name_of_metis type_enc s =
    42   case find_first (fn (_, (f, _)) => f type_enc = s) metis_name_table of
    39   (case find_first (fn (_, (f, _)) => f type_enc = s) metis_name_table of
    43     SOME ((s, _), (_, swap)) => (s, swap)
    40     SOME ((s, _), (_, swap)) => (s, swap)
    44   | _ => (s, false)
    41   | _ => (s, false))
       
    42 
    45 fun atp_term_of_metis type_enc (Metis_Term.Fn (s, tms)) =
    43 fun atp_term_of_metis type_enc (Metis_Term.Fn (s, tms)) =
    46     let val (s, swap) = atp_name_of_metis type_enc (Metis_Name.toString s) in
    44     let val (s, swap) = atp_name_of_metis type_enc (Metis_Name.toString s) in
    47       ATerm ((s, []), tms |> map (atp_term_of_metis type_enc) |> swap ? rev)
    45       ATerm ((s, []), tms |> map (atp_term_of_metis type_enc) |> swap ? rev)
    48     end
    46     end
    49   | atp_term_of_metis _ (Metis_Term.Var s) =
    47   | atp_term_of_metis _ (Metis_Term.Var s) =
    53   atp_term_of_metis type_enc #> term_of_atp ctxt ATP_Problem.CNF type_enc false sym_tab NONE
    51   atp_term_of_metis type_enc #> term_of_atp ctxt ATP_Problem.CNF type_enc false sym_tab NONE
    54 
    52 
    55 fun atp_literal_of_metis type_enc (pos, atom) =
    53 fun atp_literal_of_metis type_enc (pos, atom) =
    56   atom |> Metis_Term.Fn |> atp_term_of_metis type_enc
    54   atom |> Metis_Term.Fn |> atp_term_of_metis type_enc
    57        |> AAtom |> not pos ? mk_anot
    55        |> AAtom |> not pos ? mk_anot
       
    56 
    58 fun atp_clause_of_metis _ [] = AAtom (ATerm ((tptp_false, []), []))
    57 fun atp_clause_of_metis _ [] = AAtom (ATerm ((tptp_false, []), []))
    59   | atp_clause_of_metis type_enc lits =
    58   | atp_clause_of_metis type_enc lits =
    60     lits |> map (atp_literal_of_metis type_enc) |> mk_aconns AOr
    59     lits |> map (atp_literal_of_metis type_enc) |> mk_aconns AOr
    61 
    60 
    62 fun polish_hol_terms ctxt (lifted, old_skolems) =
    61 fun polish_hol_terms ctxt (lifted, old_skolems) =
    69   #> atp_clause_of_metis type_enc
    68   #> atp_clause_of_metis type_enc
    70   #> prop_of_atp ctxt ATP_Problem.CNF type_enc false sym_tab
    69   #> prop_of_atp ctxt ATP_Problem.CNF type_enc false sym_tab
    71   #> singleton (polish_hol_terms ctxt concealed)
    70   #> singleton (polish_hol_terms ctxt concealed)
    72 
    71 
    73 fun hol_terms_of_metis ctxt type_enc concealed sym_tab fol_tms =
    72 fun hol_terms_of_metis ctxt type_enc concealed sym_tab fol_tms =
    74   let val ts = map (hol_term_of_metis ctxt type_enc sym_tab) fol_tms
    73   let
    75       val _ = trace_msg ctxt (fn () => "  calling type inference:")
    74     val ts = map (hol_term_of_metis ctxt type_enc sym_tab) fol_tms
    76       val _ = app (fn t => trace_msg ctxt
    75     val _ = trace_msg ctxt (fn () => "  calling type inference:")
    77                                      (fn () => Syntax.string_of_term ctxt t)) ts
    76     val _ = app (fn t => trace_msg ctxt (fn () => Syntax.string_of_term ctxt t)) ts
    78       val ts' = ts |> polish_hol_terms ctxt concealed
    77     val ts' = ts |> polish_hol_terms ctxt concealed
    79       val _ = app (fn t => trace_msg ctxt
    78     val _ = app (fn t => trace_msg ctxt
    80                     (fn () => "  final term: " ^ Syntax.string_of_term ctxt t ^
    79                   (fn () => "  final term: " ^ Syntax.string_of_term ctxt t ^
    81                               " of type " ^ Syntax.string_of_typ ctxt (type_of t)))
    80                             " of type " ^ Syntax.string_of_typ ctxt (type_of t))) ts'
    82                   ts'
    81   in ts' end
    83   in  ts'  end;
       
    84 
    82 
    85 (* ------------------------------------------------------------------------- *)
    83 (* ------------------------------------------------------------------------- *)
    86 (* FOL step Inference Rules                                                  *)
    84 (* FOL step Inference Rules                                                  *)
    87 (* ------------------------------------------------------------------------- *)
    85 (* ------------------------------------------------------------------------- *)
    88 
    86 
    89 fun lookth th_pairs fth =
    87 fun lookth th_pairs fth =
    90   the (AList.lookup (uncurry Metis_Thm.equal) th_pairs fth)
    88   the (AList.lookup (uncurry Metis_Thm.equal) th_pairs fth)
    91   handle Option.Option =>
    89   handle Option.Option => raise Fail ("Failed to find Metis theorem " ^ Metis_Thm.toString fth)
    92          raise Fail ("Failed to find Metis theorem " ^ Metis_Thm.toString fth)
    90 
    93 
    91 fun cterm_incr_types thy idx = cterm_of thy o (map_types (Logic.incr_tvar idx))
    94 fun cterm_incr_types thy idx = cterm_of thy o (map_types (Logic.incr_tvar idx));
       
    95 
    92 
    96 (* INFERENCE RULE: AXIOM *)
    93 (* INFERENCE RULE: AXIOM *)
    97 
    94 
    98 (* This causes variables to have an index of 1 by default. See also
    95 (* This causes variables to have an index of 1 by default. See also
    99    "term_of_atp" in "ATP_Proof_Reconstruct". *)
    96    "term_of_atp" in "ATP_Proof_Reconstruct". *)
   102 (* INFERENCE RULE: ASSUME *)
    99 (* INFERENCE RULE: ASSUME *)
   103 
   100 
   104 val EXCLUDED_MIDDLE = @{lemma "P ==> ~ P ==> False" by (rule notE)}
   101 val EXCLUDED_MIDDLE = @{lemma "P ==> ~ P ==> False" by (rule notE)}
   105 
   102 
   106 fun inst_excluded_middle thy i_atom =
   103 fun inst_excluded_middle thy i_atom =
   107   let val th = EXCLUDED_MIDDLE
   104   let
   108       val [vx] = Term.add_vars (prop_of th) []
   105     val th = EXCLUDED_MIDDLE
   109       val substs = [(cterm_of thy (Var vx), cterm_of thy i_atom)]
   106     val [vx] = Term.add_vars (prop_of th) []
   110   in  cterm_instantiate substs th  end;
   107     val substs = [(cterm_of thy (Var vx), cterm_of thy i_atom)]
       
   108   in
       
   109     cterm_instantiate substs th
       
   110   end
   111 
   111 
   112 fun assume_inference ctxt type_enc concealed sym_tab atom =
   112 fun assume_inference ctxt type_enc concealed sym_tab atom =
   113   inst_excluded_middle
   113   inst_excluded_middle (Proof_Context.theory_of ctxt)
   114       (Proof_Context.theory_of ctxt)
   114     (singleton (hol_terms_of_metis ctxt type_enc concealed sym_tab) (Metis_Term.Fn atom))
   115       (singleton (hol_terms_of_metis ctxt type_enc concealed sym_tab)
       
   116                  (Metis_Term.Fn atom))
       
   117 
   115 
   118 (* INFERENCE RULE: INSTANTIATE (SUBST). Type instantiations are ignored. Trying
   116 (* INFERENCE RULE: INSTANTIATE (SUBST). Type instantiations are ignored. Trying
   119    to reconstruct them admits new possibilities of errors, e.g. concerning
   117    to reconstruct them admits new possibilities of errors, e.g. concerning
   120    sorts. Instead we try to arrange that new TVars are distinct and that types
   118    sorts. Instead we try to arrange that new TVars are distinct and that types
   121    can be inferred from terms. *)
   119    can be inferred from terms. *)
   122 
   120 
   123 fun inst_inference ctxt type_enc concealed sym_tab th_pairs fsubst th =
   121 fun inst_inference ctxt type_enc concealed sym_tab th_pairs fsubst th =
   124   let val thy = Proof_Context.theory_of ctxt
   122   let
   125       val i_th = lookth th_pairs th
   123     val thy = Proof_Context.theory_of ctxt
   126       val i_th_vars = Term.add_vars (prop_of i_th) []
   124     val i_th = lookth th_pairs th
   127       fun find_var x = the (List.find (fn ((a,_),_) => a=x) i_th_vars)
   125     val i_th_vars = Term.add_vars (prop_of i_th) []
   128       fun subst_translation (x,y) =
   126 
   129         let val v = find_var x
   127     fun find_var x = the (List.find (fn ((a,_),_) => a=x) i_th_vars)
   130             (* We call "polish_hol_terms" below. *)
   128     fun subst_translation (x,y) =
   131             val t = hol_term_of_metis ctxt type_enc sym_tab y
   129       let
   132         in  SOME (cterm_of thy (Var v), t)  end
   130         val v = find_var x
   133         handle Option.Option =>
   131         (* We call "polish_hol_terms" below. *)
   134                (trace_msg ctxt (fn () => "\"find_var\" failed for " ^ x ^
   132         val t = hol_term_of_metis ctxt type_enc sym_tab y
   135                                          " in " ^ Display.string_of_thm ctxt i_th);
   133       in
   136                 NONE)
   134         SOME (cterm_of thy (Var v), t)
   137              | TYPE _ =>
   135       end
   138                (trace_msg ctxt (fn () => "\"hol_term_of_metis\" failed for " ^ x ^
   136       handle Option.Option =>
   139                                          " in " ^ Display.string_of_thm ctxt i_th);
   137              (trace_msg ctxt (fn () =>
   140                 NONE)
   138                 "\"find_var\" failed for " ^ x ^ " in " ^ Display.string_of_thm ctxt i_th);
   141       fun remove_typeinst (a, t) =
   139               NONE)
   142         let val a = Metis_Name.toString a in
   140            | TYPE _ =>
   143           case unprefix_and_unascii schematic_var_prefix a of
   141              (trace_msg ctxt (fn () =>
   144             SOME b => SOME (b, t)
   142                 "\"hol_term_of_metis\" failed for " ^ x ^ " in " ^ Display.string_of_thm ctxt i_th);
   145           | NONE =>
   143               NONE)
   146             case unprefix_and_unascii tvar_prefix a of
   144     fun remove_typeinst (a, t) =
   147               SOME _ => NONE (* type instantiations are forbidden *)
   145       let val a = Metis_Name.toString a in
   148             | NONE => SOME (a, t) (* internal Metis var? *)
   146         (case unprefix_and_unascii schematic_var_prefix a of
   149         end
   147           SOME b => SOME (b, t)
   150       val _ = trace_msg ctxt (fn () => "  isa th: " ^ Display.string_of_thm ctxt i_th)
   148         | NONE =>
   151       val substs = map_filter remove_typeinst (Metis_Subst.toList fsubst)
   149           (case unprefix_and_unascii tvar_prefix a of
   152       val (vars, tms) =
   150             SOME _ => NONE (* type instantiations are forbidden *)
   153         ListPair.unzip (map_filter subst_translation substs)
   151           | NONE => SOME (a, t) (* internal Metis var? *)))
   154         ||> polish_hol_terms ctxt concealed
   152       end
   155       val ctm_of = cterm_incr_types thy (1 + Thm.maxidx_of i_th)
   153     val _ = trace_msg ctxt (fn () => "  isa th: " ^ Display.string_of_thm ctxt i_th)
   156       val substs' = ListPair.zip (vars, map ctm_of tms)
   154     val substs = map_filter remove_typeinst (Metis_Subst.toList fsubst)
   157       val _ = trace_msg ctxt (fn () =>
   155     val (vars, tms) =
   158         cat_lines ("subst_translations:" ::
   156       ListPair.unzip (map_filter subst_translation substs)
   159           (substs' |> map (fn (x, y) =>
   157       ||> polish_hol_terms ctxt concealed
   160             Syntax.string_of_term ctxt (term_of x) ^ " |-> " ^
   158     val ctm_of = cterm_incr_types thy (1 + Thm.maxidx_of i_th)
   161             Syntax.string_of_term ctxt (term_of y)))));
   159     val substs' = ListPair.zip (vars, map ctm_of tms)
   162   in cterm_instantiate substs' i_th end
   160     val _ = trace_msg ctxt (fn () =>
       
   161       cat_lines ("subst_translations:" ::
       
   162         (substs' |> map (fn (x, y) =>
       
   163           Syntax.string_of_term ctxt (term_of x) ^ " |-> " ^
       
   164           Syntax.string_of_term ctxt (term_of y)))))
       
   165   in
       
   166     cterm_instantiate substs' i_th
       
   167   end
   163   handle THM (msg, _, _) => raise METIS_RECONSTRUCT ("inst_inference", msg)
   168   handle THM (msg, _, _) => raise METIS_RECONSTRUCT ("inst_inference", msg)
   164        | ERROR msg => raise METIS_RECONSTRUCT ("inst_inference", msg)
   169        | ERROR msg => raise METIS_RECONSTRUCT ("inst_inference", msg)
   165 
   170 
   166 (* INFERENCE RULE: RESOLVE *)
   171 (* INFERENCE RULE: RESOLVE *)
   167 
   172 
   168 (*Increment the indexes of only the type variables*)
   173 (*Increment the indexes of only the type variables*)
   169 fun incr_type_indexes inc th =
   174 fun incr_type_indexes inc th =
   170   let val tvs = Term.add_tvars (Thm.full_prop_of th) []
   175   let
   171       and thy = Thm.theory_of_thm th
   176     val tvs = Term.add_tvars (Thm.full_prop_of th) []
   172       fun inc_tvar ((a,i),s) = pairself (ctyp_of thy) (TVar ((a,i),s), TVar ((a,i+inc),s))
   177     val thy = Thm.theory_of_thm th
   173   in Thm.instantiate (map inc_tvar tvs, []) th end;
   178     fun inc_tvar ((a, i), s) = pairself (ctyp_of thy) (TVar ((a, i), s), TVar ((a, i + inc), s))
       
   179   in
       
   180     Thm.instantiate (map inc_tvar tvs, []) th
       
   181   end
   174 
   182 
   175 (* Like RSN, but we rename apart only the type variables. Vars here typically
   183 (* Like RSN, but we rename apart only the type variables. Vars here typically
   176    have an index of 1, and the use of RSN would increase this typically to 3.
   184    have an index of 1, and the use of RSN would increase this typically to 3.
   177    Instantiations of those Vars could then fail. *)
   185    Instantiations of those Vars could then fail. *)
   178 fun resolve_inc_tyvars ctxt tha i thb =
   186 fun resolve_inc_tyvars ctxt tha i thb =
   179   let
   187   let
   180     val tha = incr_type_indexes (1 + Thm.maxidx_of thb) tha
   188     val tha = incr_type_indexes (1 + Thm.maxidx_of thb) tha
   181     fun res (tha, thb) =
   189     fun res (tha, thb) =
   182       case Thm.bicompose {flatten = true, match = false, incremented = true}
   190       (case Thm.bicompose {flatten = true, match = false, incremented = true}
   183             (false, tha, nprems_of tha) i thb
   191             (false, tha, nprems_of tha) i thb
   184            |> Seq.list_of |> distinct Thm.eq_thm of
   192            |> Seq.list_of |> distinct Thm.eq_thm of
   185         [th] => th
   193         [th] => th
   186       | _ =>
   194       | _ =>
   187         let
   195         let
   190         in
   198         in
   191           if forall Thm.eq_thm_prop thaa'bb' then
   199           if forall Thm.eq_thm_prop thaa'bb' then
   192             raise THM ("resolve_inc_tyvars: unique result expected", i, [tha, thb])
   200             raise THM ("resolve_inc_tyvars: unique result expected", i, [tha, thb])
   193           else
   201           else
   194             res (tha', thb')
   202             res (tha', thb')
   195         end
   203         end)
   196   in
   204   in
   197     res (tha, thb)
   205     res (tha, thb)
   198     handle TERM z =>
   206     handle TERM z =>
   199       let
   207       let
   200         val thy = Proof_Context.theory_of ctxt
   208         val thy = Proof_Context.theory_of ctxt
   241 (* Permute a rule's premises to move the i-th premise to the last position. *)
   249 (* Permute a rule's premises to move the i-th premise to the last position. *)
   242 fun make_last i th =
   250 fun make_last i th =
   243   let val n = nprems_of th in
   251   let val n = nprems_of th in
   244     if i >= 1 andalso i <= n then Thm.permute_prems (i - 1) 1 th
   252     if i >= 1 andalso i <= n then Thm.permute_prems (i - 1) 1 th
   245     else raise THM ("select_literal", i, [th])
   253     else raise THM ("select_literal", i, [th])
   246   end;
   254   end
   247 
   255 
   248 (* Maps a rule that ends "... ==> P ==> False" to "... ==> ~ P" while avoiding
   256 (* Maps a rule that ends "... ==> P ==> False" to "... ==> ~ P" while avoiding
   249    to create double negations. The "select" wrapper is a trick to ensure that
   257    to create double negations. The "select" wrapper is a trick to ensure that
   250    "P ==> ~ False ==> False" is rewritten to "P ==> False", not to "~ P". We
   258    "P ==> ~ False ==> False" is rewritten to "P ==> False", not to "~ P". We
   251    don't use this trick in general because it makes the proof object uglier than
   259    don't use this trick in general because it makes the proof object uglier than
   280       in
   288       in
   281         (case index_of_literal (s_not i_atom) (prems_of i_th1) of
   289         (case index_of_literal (s_not i_atom) (prems_of i_th1) of
   282           0 => (trace_msg ctxt (fn () => "Failed to find literal in \"th1\""); i_th1)
   290           0 => (trace_msg ctxt (fn () => "Failed to find literal in \"th1\""); i_th1)
   283         | j1 =>
   291         | j1 =>
   284           (trace_msg ctxt (fn () => "  index th1: " ^ string_of_int j1);
   292           (trace_msg ctxt (fn () => "  index th1: " ^ string_of_int j1);
   285            case index_of_literal i_atom (prems_of i_th2) of
   293            (case index_of_literal i_atom (prems_of i_th2) of
   286              0 => (trace_msg ctxt (fn () => "Failed to find literal in \"th2\""); i_th2)
   294              0 => (trace_msg ctxt (fn () => "Failed to find literal in \"th2\""); i_th2)
   287            | j2 =>
   295            | j2 =>
   288              (trace_msg ctxt (fn () => "  index th2: " ^ string_of_int j2);
   296              (trace_msg ctxt (fn () => "  index th2: " ^ string_of_int j2);
   289               resolve_inc_tyvars ctxt (select_literal ctxt j1 i_th1) j2 i_th2
   297               resolve_inc_tyvars ctxt (select_literal ctxt j1 i_th1) j2 i_th2
   290               handle TERM (s, _) => raise METIS_RECONSTRUCT ("resolve_inference", s))))
   298               handle TERM (s, _) => raise METIS_RECONSTRUCT ("resolve_inference", s)))))
   291       end
   299       end
   292   end
   300   end
   293 
   301 
   294 (* INFERENCE RULE: REFL *)
   302 (* INFERENCE RULE: REFL *)
   295 
   303 
   366       val imax = maxidx_of_term (i_tm $ tm_abs $ tm_subst)  (*ill-typed but gives right max*)
   374       val imax = maxidx_of_term (i_tm $ tm_abs $ tm_subst)  (*ill-typed but gives right max*)
   367       val subst' = Thm.incr_indexes (imax+1) (if pos then subst_em else ssubst_em)
   375       val subst' = Thm.incr_indexes (imax+1) (if pos then subst_em else ssubst_em)
   368       val _ = trace_msg ctxt (fn () => "subst' " ^ Display.string_of_thm ctxt subst')
   376       val _ = trace_msg ctxt (fn () => "subst' " ^ Display.string_of_thm ctxt subst')
   369       val eq_terms = map (pairself (cterm_of thy))
   377       val eq_terms = map (pairself (cterm_of thy))
   370         (ListPair.zip (Misc_Legacy.term_vars (prop_of subst'), [tm_abs, tm_subst, i_tm]))
   378         (ListPair.zip (Misc_Legacy.term_vars (prop_of subst'), [tm_abs, tm_subst, i_tm]))
   371   in  cterm_instantiate eq_terms subst'  end;
   379   in
       
   380     cterm_instantiate eq_terms subst'
       
   381   end
   372 
   382 
   373 val factor = Seq.hd o distinct_subgoals_tac
   383 val factor = Seq.hd o distinct_subgoals_tac
   374 
   384 
   375 fun one_step ctxt type_enc concealed sym_tab th_pairs p =
   385 fun one_step ctxt type_enc concealed sym_tab th_pairs p =
   376   case p of
   386   (case p of
   377     (fol_th, Metis_Proof.Axiom _) => axiom_inference th_pairs fol_th |> factor
   387     (fol_th, Metis_Proof.Axiom _) => axiom_inference th_pairs fol_th |> factor
   378   | (_, Metis_Proof.Assume f_atom) => assume_inference ctxt type_enc concealed sym_tab f_atom
   388   | (_, Metis_Proof.Assume f_atom) => assume_inference ctxt type_enc concealed sym_tab f_atom
   379   | (_, Metis_Proof.Metis_Subst (f_subst, f_th1)) =>
   389   | (_, Metis_Proof.Metis_Subst (f_subst, f_th1)) =>
   380     inst_inference ctxt type_enc concealed sym_tab th_pairs f_subst f_th1 |> factor
   390     inst_inference ctxt type_enc concealed sym_tab th_pairs f_subst f_th1 |> factor
   381   | (_, Metis_Proof.Resolve(f_atom, f_th1, f_th2)) =>
   391   | (_, Metis_Proof.Resolve(f_atom, f_th1, f_th2)) =>
   382     resolve_inference ctxt type_enc concealed sym_tab th_pairs f_atom f_th1 f_th2 |> factor
   392     resolve_inference ctxt type_enc concealed sym_tab th_pairs f_atom f_th1 f_th2 |> factor
   383   | (_, Metis_Proof.Refl f_tm) => refl_inference ctxt type_enc concealed sym_tab f_tm
   393   | (_, Metis_Proof.Refl f_tm) => refl_inference ctxt type_enc concealed sym_tab f_tm
   384   | (_, Metis_Proof.Equality (f_lit, f_p, f_r)) =>
   394   | (_, Metis_Proof.Equality (f_lit, f_p, f_r)) =>
   385     equality_inference ctxt type_enc concealed sym_tab f_lit f_p f_r
   395     equality_inference ctxt type_enc concealed sym_tab f_lit f_p f_r)
   386 
   396 
   387 fun flexflex_first_order th =
   397 fun flexflex_first_order th =
   388   (case Thm.tpairs_of th of
   398   (case Thm.tpairs_of th of
   389     [] => th
   399     [] => th
   390   | pairs =>
   400   | pairs =>
   627   if prop_of prems_imp_false aconv @{prop False} then
   637   if prop_of prems_imp_false aconv @{prop False} then
   628     prems_imp_false
   638     prems_imp_false
   629   else
   639   else
   630     let
   640     let
   631       val thy = Proof_Context.theory_of ctxt
   641       val thy = Proof_Context.theory_of ctxt
       
   642 
   632       fun match_term p =
   643       fun match_term p =
   633         let
   644         let
   634           val (tyenv, tenv) =
   645           val (tyenv, tenv) =
   635             Pattern.first_order_match thy p (Vartab.empty, Vartab.empty)
   646             Pattern.first_order_match thy p (Vartab.empty, Vartab.empty)
   636           val tsubst =
   647           val tsubst =
   641                                       o fst o fst))
   652                                       o fst o fst))
   642                  |> map (Meson.term_pair_of
   653                  |> map (Meson.term_pair_of
   643                          #> pairself (Envir.subst_term_types tyenv))
   654                          #> pairself (Envir.subst_term_types tyenv))
   644           val tysubst = tyenv |> Vartab.dest
   655           val tysubst = tyenv |> Vartab.dest
   645         in (tysubst, tsubst) end
   656         in (tysubst, tsubst) end
       
   657 
   646       fun subst_info_of_prem subgoal_no prem =
   658       fun subst_info_of_prem subgoal_no prem =
   647         case prem of
   659         (case prem of
   648           _ $ (Const (@{const_name Meson.skolem}, _) $ (_ $ t $ num)) =>
   660           _ $ (Const (@{const_name Meson.skolem}, _) $ (_ $ t $ num)) =>
   649           let val ax_no = HOLogic.dest_nat num in
   661           let val ax_no = HOLogic.dest_nat num in
   650             (ax_no, (subgoal_no,
   662             (ax_no, (subgoal_no,
   651                      match_term (nth axioms ax_no |> the |> snd, t)))
   663                      match_term (nth axioms ax_no |> the |> snd, t)))
   652           end
   664           end
   653         | _ => raise TERM ("discharge_skolem_premises: Malformed premise",
   665         | _ => raise TERM ("discharge_skolem_premises: Malformed premise", [prem]))
   654                            [prem])
   666 
   655       fun cluster_of_var_name skolem s =
   667       fun cluster_of_var_name skolem s =
   656         case try Meson_Clausify.cluster_of_zapped_var_name s of
   668         (case try Meson_Clausify.cluster_of_zapped_var_name s of
   657           NONE => NONE
   669           NONE => NONE
   658         | SOME ((ax_no, (cluster_no, _)), skolem') =>
   670         | SOME ((ax_no, (cluster_no, _)), skolem') =>
   659           if skolem' = skolem andalso cluster_no > 0 then
   671           if skolem' = skolem andalso cluster_no > 0 then SOME (ax_no, cluster_no) else NONE)
   660             SOME (ax_no, cluster_no)
   672 
   661           else
       
   662             NONE
       
   663       fun clusters_in_term skolem t =
   673       fun clusters_in_term skolem t =
   664         Term.add_var_names t [] |> map_filter (cluster_of_var_name skolem o fst)
   674         Term.add_var_names t [] |> map_filter (cluster_of_var_name skolem o fst)
       
   675 
   665       fun deps_of_term_subst (var, t) =
   676       fun deps_of_term_subst (var, t) =
   666         case clusters_in_term false var of
   677         (case clusters_in_term false var of
   667           [] => NONE
   678           [] => NONE
   668         | [(ax_no, cluster_no)] =>
   679         | [(ax_no, cluster_no)] =>
   669           SOME ((ax_no, cluster_no),
   680           SOME ((ax_no, cluster_no),
   670                 clusters_in_term true t
   681             clusters_in_term true t |> cluster_no > 1 ? cons (ax_no, cluster_no - 1))
   671                 |> cluster_no > 1 ? cons (ax_no, cluster_no - 1))
   682         | _ => raise TERM ("discharge_skolem_premises: Expected Var", [var]))
   672         | _ => raise TERM ("discharge_skolem_premises: Expected Var", [var])
   683 
   673       val prems = Logic.strip_imp_prems (prop_of prems_imp_false)
   684       val prems = Logic.strip_imp_prems (prop_of prems_imp_false)
   674       val substs = prems |> map2 subst_info_of_prem (1 upto length prems)
   685       val substs = prems |> map2 subst_info_of_prem (1 upto length prems)
   675                          |> sort (int_ord o pairself fst)
   686                          |> sort (int_ord o pairself fst)
   676       val depss = maps (map_filter deps_of_term_subst o snd o snd o snd) substs
   687       val depss = maps (map_filter deps_of_term_subst o snd o snd o snd) substs
   677       val clusters = maps (op ::) depss
   688       val clusters = maps (op ::) depss
   703            |> filter (Meson_Clausify.is_zapped_var_name o fst)
   714            |> filter (Meson_Clausify.is_zapped_var_name o fst)
   704            |> map (`(Meson_Clausify.cluster_of_zapped_var_name o fst))
   715            |> map (`(Meson_Clausify.cluster_of_zapped_var_name o fst))
   705            |> filter (fn (((_, (cluster_no, _)), skolem), _) =>
   716            |> filter (fn (((_, (cluster_no, _)), skolem), _) =>
   706                          cluster_no = 0 andalso skolem)
   717                          cluster_no = 0 andalso skolem)
   707            |> sort shuffle_ord |> map (fst o snd)
   718            |> sort shuffle_ord |> map (fst o snd)
       
   719 
   708 (* for debugging only:
   720 (* for debugging only:
   709       fun string_of_subst_info (ax_no, (subgoal_no, (tysubst, tsubst))) =
   721       fun string_of_subst_info (ax_no, (subgoal_no, (tysubst, tsubst))) =
   710         "ax: " ^ string_of_int ax_no ^ "; asm: " ^ string_of_int subgoal_no ^
   722         "ax: " ^ string_of_int ax_no ^ "; asm: " ^ string_of_int subgoal_no ^
   711         "; tysubst: " ^ @{make_string} tysubst ^ "; tsubst: {" ^
   723         "; tysubst: " ^ @{make_string} tysubst ^ "; tsubst: {" ^
   712         commas (map ((fn (s, t) => s ^ " |-> " ^ t)
   724         commas (map ((fn (s, t) => s ^ " |-> " ^ t)
   715       val _ = tracing ("AXIOM COUNTS: " ^ @{make_string} ax_counts)
   727       val _ = tracing ("AXIOM COUNTS: " ^ @{make_string} ax_counts)
   716       val _ = tracing ("OUTER PARAMS: " ^ @{make_string} outer_param_names)
   728       val _ = tracing ("OUTER PARAMS: " ^ @{make_string} outer_param_names)
   717       val _ = tracing ("SUBSTS (" ^ string_of_int (length substs) ^ "):\n" ^
   729       val _ = tracing ("SUBSTS (" ^ string_of_int (length substs) ^ "):\n" ^
   718                        cat_lines (map string_of_subst_info substs))
   730                        cat_lines (map string_of_subst_info substs))
   719 *)
   731 *)
   720       fun cut_and_ex_tac axiom =
   732 
   721         cut_tac axiom 1
   733       fun cut_and_ex_tac axiom = cut_tac axiom 1 THEN TRY (REPEAT_ALL_NEW (etac @{thm exE}) 1)
   722         THEN TRY (REPEAT_ALL_NEW (etac @{thm exE}) 1)
       
   723       fun rotation_of_subgoal i =
   734       fun rotation_of_subgoal i =
   724         find_index (fn (_, (subgoal_no, _)) => subgoal_no = i) substs
   735         find_index (fn (_, (subgoal_no, _)) => subgoal_no = i) substs
       
   736 
   725       val ctxt' = fold Thm.declare_hyps (#hyps (Thm.crep_thm prems_imp_false)) ctxt
   737       val ctxt' = fold Thm.declare_hyps (#hyps (Thm.crep_thm prems_imp_false)) ctxt
   726     in
   738     in
   727       Goal.prove ctxt' [] [] @{prop False}
   739       Goal.prove ctxt' [] [] @{prop False}
   728           (K (DETERM (EVERY (map (cut_and_ex_tac o fst o the o nth axioms o fst
   740         (K (DETERM (EVERY (map (cut_and_ex_tac o fst o the o nth axioms o fst o fst) ax_counts)
   729                                   o fst) ax_counts)
   741               THEN rename_tac outer_param_names 1
   730                       THEN rename_tac outer_param_names 1
   742               THEN copy_prems_tac (map snd ax_counts) [] 1)
   731                       THEN copy_prems_tac (map snd ax_counts) [] 1)
   743             THEN release_clusters_tac thy ax_counts substs ordered_clusters 1
   732               THEN release_clusters_tac thy ax_counts substs ordered_clusters 1
   744             THEN match_tac [prems_imp_false] 1
   733               THEN match_tac [prems_imp_false] 1
   745             THEN ALLGOALS (fn i => rtac @{thm Meson.skolem_COMBK_I} i
   734               THEN ALLGOALS (fn i =>
   746               THEN rotate_tac (rotation_of_subgoal i) i
   735                        rtac @{thm Meson.skolem_COMBK_I} i
   747               THEN PRIMITIVE (unify_first_prem_with_concl thy i)
   736                        THEN rotate_tac (rotation_of_subgoal i) i
   748               THEN assume_tac i
   737                        THEN PRIMITIVE (unify_first_prem_with_concl thy i)
   749               THEN flexflex_tac)))
   738                        THEN assume_tac i
       
   739                        THEN flexflex_tac)))
       
   740       handle ERROR msg =>
   750       handle ERROR msg =>
   741         cat_error msg
   751         cat_error msg
   742           "Cannot replay Metis proof in Isabelle: error when discharging Skolem assumptions"
   752           "Cannot replay Metis proof in Isabelle: error when discharging Skolem assumptions"
   743     end
   753     end
   744 
   754