src/Pure/proofterm.ML
changeset 28803 d90258bbb18f
parent 28329 e6a5fa9f1e41
child 28812 413695e07bd4
equal deleted inserted replaced
28802:9ba30eeec7ce 28803:d90258bbb18f
    10 signature BASIC_PROOFTERM =
    10 signature BASIC_PROOFTERM =
    11 sig
    11 sig
    12   val proofs: int ref
    12   val proofs: int ref
    13 
    13 
    14   datatype proof =
    14   datatype proof =
    15      PBound of int
    15      MinProof
       
    16    | PBound of int
    16    | Abst of string * typ option * proof
    17    | Abst of string * typ option * proof
    17    | AbsP of string * term option * proof
    18    | AbsP of string * term option * proof
    18    | % of proof * term option
    19    | op % of proof * term option
    19    | %% of proof * proof
    20    | op %% of proof * proof
    20    | Hyp of term
    21    | Hyp of term
    21    | PThm of string * proof * term * typ list option
       
    22    | PAxm of string * term * typ list option
    22    | PAxm of string * term * typ list option
    23    | Oracle of string * term * typ list option
    23    | Oracle of string * term * typ list option
    24    | Promise of serial * term * typ list option
    24    | Promise of serial * term * typ list option
    25    | MinProof of ((string * term) * proof) list * (string * term) list * (string * term) list;
    25    | PThm of serial * ((string * term * typ list option) * proof_body Lazy.T)
       
    26   and proof_body = PBody of
       
    27     {oracles: (string * term) OrdList.T,
       
    28      thms: (serial * ((string * term * typ list option) * proof_body Lazy.T)) OrdList.T,
       
    29      proof: proof}
    26 
    30 
    27   val %> : proof * term -> proof
    31   val %> : proof * term -> proof
    28 end;
    32 end;
    29 
    33 
    30 signature PROOFTERM =
    34 signature PROOFTERM =
    31 sig
    35 sig
    32   include BASIC_PROOFTERM
    36   include BASIC_PROOFTERM
    33 
    37 
       
    38   val proof_of: proof_body -> proof
       
    39   val force_body: proof_body Lazy.T ->
       
    40    {oracles: (string * term) OrdList.T,
       
    41     thms: (serial * ((string * term * typ list option) * proof_body Lazy.T)) OrdList.T,
       
    42     proof: proof}
       
    43   val force_proof: proof_body Lazy.T -> proof
       
    44   val fold_body_thms: ((string * term * typ list option) * proof_body -> 'a -> 'a) ->
       
    45     proof_body list -> 'a -> 'a
       
    46   val fold_proof_atoms: bool -> (proof -> 'a -> 'a) -> proof list -> 'a -> 'a
       
    47 
       
    48   type oracle = string * term
       
    49   val oracle_ord: oracle * oracle -> order
       
    50   type pthm = serial * ((string * term * typ list option) * proof_body Lazy.T)
       
    51   val thm_ord: pthm * pthm -> order
       
    52   val make_proof_body: proof -> proof_body
       
    53   val merge_oracles: oracle OrdList.T -> oracle OrdList.T -> oracle OrdList.T
       
    54   val make_oracles: proof -> oracle OrdList.T
       
    55   val merge_thms: pthm OrdList.T -> pthm OrdList.T -> pthm OrdList.T
       
    56   val make_thms: proof -> pthm OrdList.T
       
    57 
    34   (** primitive operations **)
    58   (** primitive operations **)
    35   val min_proof : proof
    59   val proof_combt: proof * term list -> proof
    36   val proof_combt : proof * term list -> proof
    60   val proof_combt': proof * term option list -> proof
    37   val proof_combt' : proof * term option list -> proof
    61   val proof_combP: proof * proof list -> proof
    38   val proof_combP : proof * proof list -> proof
    62   val strip_combt: proof -> proof * term option list
    39   val strip_combt : proof -> proof * term option list
    63   val strip_combP: proof -> proof * proof list
    40   val strip_combP : proof -> proof * proof list
    64   val strip_thm: proof_body -> proof_body
    41   val strip_thm : proof -> proof
    65   val map_proof_terms_option: (term -> term option) -> (typ -> typ option) -> proof -> proof
    42   val map_proof_terms_option : (term -> term option) -> (typ -> typ option) -> proof -> proof
    66   val map_proof_terms: (term -> term) -> (typ -> typ) -> proof -> proof
    43   val map_proof_terms : (term -> term) -> (typ -> typ) -> proof -> proof
    67   val fold_proof_terms: (term -> 'a -> 'a) -> (typ -> 'a -> 'a) -> proof -> 'a -> 'a
    44   val fold_proof_terms : (term -> 'a -> 'a) -> (typ -> 'a -> 'a) -> proof -> 'a -> 'a
    68   val maxidx_proof: proof -> int -> int
    45   val maxidx_proof : proof -> int -> int
    69   val size_of_proof: proof -> int
    46   val size_of_proof : proof -> int
    70   val change_type: typ list option -> proof -> proof
    47   val change_type : typ list option -> proof -> proof
    71   val prf_abstract_over: term -> proof -> proof
    48   val prf_abstract_over : term -> proof -> proof
    72   val prf_incr_bv: int -> int -> int -> int -> proof -> proof
    49   val prf_incr_bv : int -> int -> int -> int -> proof -> proof
    73   val incr_pboundvars: int -> int -> proof -> proof
    50   val incr_pboundvars : int -> int -> proof -> proof
    74   val prf_loose_bvar1: proof -> int -> bool
    51   val prf_loose_bvar1 : proof -> int -> bool
    75   val prf_loose_Pbvar1: proof -> int -> bool
    52   val prf_loose_Pbvar1 : proof -> int -> bool
    76   val prf_add_loose_bnos: int -> int -> proof -> int list * int list -> int list * int list
    53   val prf_add_loose_bnos : int -> int -> proof ->
    77   val norm_proof: Envir.env -> proof -> proof
    54     int list * int list -> int list * int list
    78   val norm_proof': Envir.env -> proof -> proof
    55   val norm_proof : Envir.env -> proof -> proof
    79   val prf_subst_bounds: term list -> proof -> proof
    56   val norm_proof' : Envir.env -> proof -> proof
    80   val prf_subst_pbounds: proof list -> proof -> proof
    57   val prf_subst_bounds : term list -> proof -> proof
    81   val freeze_thaw_prf: proof -> proof * (proof -> proof)
    58   val prf_subst_pbounds : proof list -> proof -> proof
       
    59   val freeze_thaw_prf : proof -> proof * (proof -> proof)
       
    60   val proof_of_min_axm : string * term -> proof
       
    61   val proof_of_min_thm : (string * term) * proof -> proof
       
    62 
       
    63   val thms_of_proof : proof -> (term * proof) list Symtab.table ->
       
    64     (term * proof) list Symtab.table
       
    65   val thms_of_proof' : proof -> (term * proof) list Symtab.table ->
       
    66     (term * proof) list Symtab.table
       
    67   val axms_of_proof : proof -> proof Symtab.table -> proof Symtab.table
       
    68   val mk_min_proof : proof ->
       
    69    ((string * term) * proof) list * (string * term) list * (string * term) list ->
       
    70    ((string * term) * proof) list * (string * term) list * (string * term) list
       
    71   val add_oracles : bool -> proof -> (string * term) list -> (string * term) list
       
    72 
    82 
    73   (** proof terms for specific inference rules **)
    83   (** proof terms for specific inference rules **)
    74   val implies_intr_proof : term -> proof -> proof
    84   val implies_intr_proof: term -> proof -> proof
    75   val forall_intr_proof : term -> string -> proof -> proof
    85   val forall_intr_proof: term -> string -> proof -> proof
    76   val varify_proof : term -> (string * sort) list -> proof -> proof
    86   val varify_proof: term -> (string * sort) list -> proof -> proof
    77   val freezeT : term -> proof -> proof
    87   val freezeT: term -> proof -> proof
    78   val rotate_proof : term list -> term -> int -> proof -> proof
    88   val rotate_proof: term list -> term -> int -> proof -> proof
    79   val permute_prems_prf : term list -> int -> int -> proof -> proof
    89   val permute_prems_prf: term list -> int -> int -> proof -> proof
    80   val generalize: string list * string list -> int -> proof -> proof
    90   val generalize: string list * string list -> int -> proof -> proof
    81   val instantiate : ((indexname * sort) * typ) list * ((indexname * typ) * term) list
    91   val instantiate: ((indexname * sort) * typ) list * ((indexname * typ) * term) list
    82     -> proof -> proof
    92     -> proof -> proof
    83   val lift_proof : term -> int -> term -> proof -> proof
    93   val lift_proof: term -> int -> term -> proof -> proof
    84   val assumption_proof : term list -> term -> int -> proof -> proof
    94   val assumption_proof: term list -> term -> int -> proof -> proof
    85   val bicompose_proof : bool -> term list -> term list -> term list -> term option ->
    95   val bicompose_proof: bool -> term list -> term list -> term list -> term option ->
    86     int -> int -> proof -> proof -> proof
    96     int -> int -> proof -> proof -> proof
    87   val equality_axms : (string * term) list
    97   val equality_axms: (string * term) list
    88   val reflexive_axm : proof
    98   val reflexive_axm: proof
    89   val symmetric_axm : proof
    99   val symmetric_axm: proof
    90   val transitive_axm : proof
   100   val transitive_axm: proof
    91   val equal_intr_axm : proof
   101   val equal_intr_axm: proof
    92   val equal_elim_axm : proof
   102   val equal_elim_axm: proof
    93   val abstract_rule_axm : proof
   103   val abstract_rule_axm: proof
    94   val combination_axm : proof
   104   val combination_axm: proof
    95   val reflexive : proof
   105   val reflexive: proof
    96   val symmetric : proof -> proof
   106   val symmetric: proof -> proof
    97   val transitive : term -> typ -> proof -> proof -> proof
   107   val transitive: term -> typ -> proof -> proof -> proof
    98   val abstract_rule : term -> string -> proof -> proof
   108   val abstract_rule: term -> string -> proof -> proof
    99   val combination : term -> term -> term -> term -> typ -> proof -> proof -> proof
   109   val combination: term -> term -> term -> term -> typ -> proof -> proof -> proof
   100   val equal_intr : term -> term -> proof -> proof -> proof
   110   val equal_intr: term -> term -> proof -> proof -> proof
   101   val equal_elim : term -> term -> proof -> proof -> proof
   111   val equal_elim: term -> term -> proof -> proof -> proof
   102   val axm_proof : string -> term -> proof
   112   val axm_proof: string -> term -> proof
   103   val oracle_proof : string -> term -> proof
   113   val oracle_proof: string -> term -> proof
   104   val promise_proof : serial -> term -> proof
   114   val promise_proof: serial -> term -> proof
   105   val thm_proof : theory -> string -> term list -> term -> proof -> proof
   115   val fulfill_proof: (serial * proof Lazy.T) list -> proof_body -> proof_body
   106   val get_name : term list -> term -> proof -> string
   116   val thm_proof: theory -> string -> term list -> term ->
       
   117     (serial * proof Lazy.T) list -> proof_body -> pthm * proof
       
   118   val get_name: term list -> term -> proof -> string
   107 
   119 
   108   (** rewriting on proof terms **)
   120   (** rewriting on proof terms **)
   109   val add_prf_rrule : proof * proof -> theory -> theory
   121   val add_prf_rrule: proof * proof -> theory -> theory
   110   val add_prf_rproc : string * (Term.typ list -> proof -> proof option) ->
   122   val add_prf_rproc: (typ list -> proof -> proof option) -> theory -> theory
   111     theory -> theory
   123   val rewrite_proof: theory -> (proof * proof) list *
   112   val rewrite_proof : theory -> (proof * proof) list *
   124     (typ list -> proof -> proof option) list -> proof -> proof
   113     (string * (typ list -> proof -> proof option)) list -> proof -> proof
   125   val rewrite_proof_notypes: (proof * proof) list *
   114   val rewrite_proof_notypes : (proof * proof) list *
   126     (typ list -> proof -> proof option) list -> proof -> proof
   115     (string * (typ list -> proof -> proof option)) list -> proof -> proof
   127   val rew_proof: theory -> proof -> proof
   116   val rew_proof : theory -> proof -> proof
       
   117   val fulfill : proof Inttab.table -> proof -> proof
       
   118 end
   128 end
   119 
   129 
   120 structure Proofterm : PROOFTERM =
   130 structure Proofterm : PROOFTERM =
   121 struct
   131 struct
   122 
   132 
   123 open Envir;
   133 open Envir;
   124 
   134 
       
   135 
       
   136 (***** datatype proof *****)
       
   137 
   125 datatype proof =
   138 datatype proof =
   126    PBound of int
   139    MinProof
       
   140  | PBound of int
   127  | Abst of string * typ option * proof
   141  | Abst of string * typ option * proof
   128  | AbsP of string * term option * proof
   142  | AbsP of string * term option * proof
   129  | op % of proof * term option
   143  | op % of proof * term option
   130  | op %% of proof * proof
   144  | op %% of proof * proof
   131  | Hyp of term
   145  | Hyp of term
   132  | PThm of string * proof * term * typ list option
       
   133  | PAxm of string * term * typ list option
   146  | PAxm of string * term * typ list option
   134  | Oracle of string * term * typ list option
   147  | Oracle of string * term * typ list option
   135  | Promise of serial * term * typ list option
   148  | Promise of serial * term * typ list option
   136  | MinProof of ((string * term) * proof) list * (string * term) list * (string * term) list;
   149  | PThm of serial * ((string * term * typ list option) * proof_body Lazy.T)
   137 
   150 and proof_body = PBody of
   138 fun proof_of_min_axm (s, prop) = PAxm (s, prop, NONE);
   151   {oracles: (string * term) OrdList.T,
   139 fun proof_of_min_thm ((s, prop), prf) = PThm (s, prf, prop, NONE);
   152    thms: (serial * ((string * term * typ list option) * proof_body Lazy.T)) OrdList.T,
   140 
   153    proof: proof};
   141 val string_term_ord = prod_ord fast_string_ord Term.fast_term_ord;
   154 
   142 
   155 val force_body = Lazy.force #> (fn PBody args => args);
   143 fun oracles_of_proof prf oras =
   156 val force_proof = #proof o force_body;
   144   let
   157 
   145     fun oras_of (Abst (_, _, prf)) = oras_of prf
   158 fun proof_of (PBody {proof, ...}) = proof;
   146       | oras_of (AbsP (_, _, prf)) = oras_of prf
   159 
   147       | oras_of (prf % _) = oras_of prf
   160 
   148       | oras_of (prf1 %% prf2) = oras_of prf1 #> oras_of prf2
   161 (***** proof atoms *****)
   149       | oras_of (PThm (name, prf, prop, _)) = (fn tabs as (thms, oras) =>
   162 
   150           if member (op =) (Symtab.lookup_list thms name) prop then tabs
   163 fun fold_body_thms f =
   151           else oras_of prf (Symtab.cons_list (name, prop) thms, oras))
   164   let
   152       | oras_of (Oracle (s, prop, _)) =
   165     fun app (PBody {thms, ...}) = thms |> fold (fn (i, (stmt, body)) => fn (x, seen) =>
   153           apsnd (OrdList.insert string_term_ord (s, prop))
   166       if Inttab.defined seen i then (x, seen)
   154       | oras_of (MinProof (thms, _, oras)) =
   167       else
   155           apsnd (OrdList.union string_term_ord oras) #>
   168         let
   156           fold (oras_of o proof_of_min_thm) thms
   169           val body' = Lazy.force body;
   157       | oras_of _ = I
   170           val (x', seen') = app body' (x, Inttab.update (i, ()) seen);
   158   in
   171         in (f (stmt, body') x', seen') end);
   159     snd (oras_of prf (Symtab.empty, oras))
   172   in fn bodies => fn x => #1 (fold app bodies (x, Inttab.empty)) end;
   160   end;
   173 
   161 
   174 fun fold_proof_atoms all f =
   162 fun add_oracles false = K I
   175   let
   163   | add_oracles true = oracles_of_proof;
   176     fun app (Abst (_, _, prf)) = app prf
   164 
   177       | app (AbsP (_, _, prf)) = app prf
   165 fun thms_of_proof (Abst (_, _, prf)) = thms_of_proof prf
   178       | app (prf % _) = app prf
   166   | thms_of_proof (AbsP (_, _, prf)) = thms_of_proof prf
   179       | app (prf1 %% prf2) = app prf1 #> app prf2
   167   | thms_of_proof (prf1 %% prf2) = thms_of_proof prf1 #> thms_of_proof prf2
   180       | app (prf as PThm (i, (_, body))) = (fn (x, seen) =>
   168   | thms_of_proof (prf % _) = thms_of_proof prf
   181           if Inttab.defined seen i then (x, seen)
   169   | thms_of_proof (prf' as PThm (s, prf, prop, _)) = (fn tab =>
   182           else
   170       if exists (fn (p, _) => p = prop) (Symtab.lookup_list tab s) then tab
   183             let val res = (f prf x, Inttab.update (i, ()) seen)
   171       else thms_of_proof prf (Symtab.cons_list (s, (prop, prf')) tab))
   184             in if all then app (force_proof body) res else res
   172   | thms_of_proof (MinProof (prfs, _, _)) = fold (thms_of_proof o proof_of_min_thm) prfs
   185           end)
   173   | thms_of_proof _ = I;
   186       | app prf = (fn (x, seen) => (f prf x, seen));
   174 
   187   in fn prfs => fn x => #1 (fold app prfs (x, Inttab.empty)) end;
   175 (* this version does not recursively descend into proofs of (named) theorems *)
   188 
   176 fun thms_of_proof' (Abst (_, _, prf)) = thms_of_proof' prf
   189 
   177   | thms_of_proof' (AbsP (_, _, prf)) = thms_of_proof' prf
   190 (* atom kinds *)
   178   | thms_of_proof' (prf1 %% prf2) = thms_of_proof' prf1 #> thms_of_proof' prf2
   191 
   179   | thms_of_proof' (prf % _) = thms_of_proof' prf
   192 type oracle = string * term;
   180   | thms_of_proof' (PThm ("", prf, prop, _)) = thms_of_proof' prf
   193 val oracle_ord = prod_ord fast_string_ord Term.fast_term_ord;
   181   | thms_of_proof' (prf' as PThm (s, _, prop, _)) =
   194 
   182       Symtab.insert_list (eq_fst op =) (s, (prop, prf'))
   195 type pthm = serial * ((string * term * typ list option) * proof_body Lazy.T);
   183   | thms_of_proof' (MinProof (prfs, _, _)) = fold (thms_of_proof' o proof_of_min_thm) prfs
   196 fun thm_ord ((i, _): pthm, (j, _)) = int_ord (j, i);
   184   | thms_of_proof' _ = I;
   197 
   185 
   198 
   186 fun axms_of_proof (Abst (_, _, prf)) = axms_of_proof prf
   199 (* proof body *)
   187   | axms_of_proof (AbsP (_, _, prf)) = axms_of_proof prf
   200 
   188   | axms_of_proof (prf1 %% prf2) = axms_of_proof prf1 #> axms_of_proof prf2
   201 fun make_body prf =
   189   | axms_of_proof (prf % _) = axms_of_proof prf
   202   let
   190   | axms_of_proof (prf as PAxm (s, _, _)) = Symtab.update (s, prf)
   203     val (oracles, thms) = fold_proof_atoms false
   191   | axms_of_proof (MinProof (_, prfs, _)) = fold (axms_of_proof o proof_of_min_axm) prfs
   204       (fn Oracle (s, prop, _) => apfst (cons (s, prop))
   192   | axms_of_proof _ = I;
   205         | PThm thm => apsnd (cons thm)
   193 
   206         | _ => I) [prf] ([], []);
   194 (** collect all theorems, axioms and oracles **)
   207   in (OrdList.make oracle_ord oracles, OrdList.make thm_ord thms) end;
   195 
   208 
   196 fun map3 f g h (thms, axms, oras) = (f thms, g axms, h oras);
   209 fun make_proof_body prf =
   197 
   210   let val (oracles, thms) = make_body prf
   198 fun mk_min_proof (Abst (_, _, prf)) = mk_min_proof prf
   211   in PBody {oracles = oracles, thms = thms, proof = prf} end;
   199   | mk_min_proof (AbsP (_, _, prf)) = mk_min_proof prf
   212 
   200   | mk_min_proof (prf % _) = mk_min_proof prf
   213 val make_oracles = #1 o make_body;
   201   | mk_min_proof (prf1 %% prf2) = mk_min_proof prf1 #> mk_min_proof prf2
   214 val make_thms = #2 o make_body;
   202   | mk_min_proof (PThm (s, prf, prop, _)) =
   215 
   203       map3 (OrdList.insert (string_term_ord o pairself fst) ((s, prop), prf)) I I
   216 val merge_oracles = OrdList.union oracle_ord;
   204   | mk_min_proof (PAxm (s, prop, _)) =
   217 val merge_thms = OrdList.union thm_ord;
   205       map3 I (OrdList.insert string_term_ord (s, prop)) I
   218 
   206   | mk_min_proof (Oracle (s, prop, _)) =
   219 fun merge_body (oracles1, thms1) (oracles2, thms2) =
   207       map3 I I (OrdList.insert string_term_ord (s, prop))
   220  (merge_oracles oracles1 oracles2, merge_thms thms1 thms2);
   208   | mk_min_proof (MinProof (thms, axms, oras)) =
   221 
   209       map3 (OrdList.union (string_term_ord o pairself fst) thms)
   222 
   210         (OrdList.union string_term_ord axms) (OrdList.union string_term_ord oras)
   223 (***** proof objects with different levels of detail *****)
   211   | mk_min_proof _ = I;
       
   212 
       
   213 (** proof objects with different levels of detail **)
       
   214 
       
   215 val proofs = ref 2;
       
   216 
       
   217 val min_proof = MinProof ([], [], []);
       
   218 
   224 
   219 fun (prf %> t) = prf % SOME t;
   225 fun (prf %> t) = prf % SOME t;
   220 
   226 
   221 val proof_combt = Library.foldl (op %>);
   227 val proof_combt = Library.foldl (op %>);
   222 val proof_combt' = Library.foldl (op %);
   228 val proof_combt' = Library.foldl (op %);
   230 fun strip_combP prf =
   236 fun strip_combP prf =
   231     let fun stripc (prf %% prf', prfs) = stripc (prf, prf'::prfs)
   237     let fun stripc (prf %% prf', prfs) = stripc (prf, prf'::prfs)
   232           | stripc  x =  x
   238           | stripc  x =  x
   233     in  stripc (prf, [])  end;
   239     in  stripc (prf, [])  end;
   234 
   240 
   235 fun strip_thm prf = (case strip_combt (fst (strip_combP prf)) of
   241 fun strip_thm (body as PBody {proof, ...}) =
   236       (PThm (_, prf', _, _), _) => prf'
   242   (case strip_combt (fst (strip_combP proof)) of
   237     | _ => prf);
   243     (PThm (_, (_, body')), _) => Lazy.force body'
       
   244   | _ => body);
   238 
   245 
   239 val mk_Abst = fold_rev (fn (s, T:typ) => fn prf => Abst (s, NONE, prf));
   246 val mk_Abst = fold_rev (fn (s, T:typ) => fn prf => Abst (s, NONE, prf));
   240 fun mk_AbsP (i, prf) = funpow i (fn prf => AbsP ("H", NONE, prf)) prf;
   247 fun mk_AbsP (i, prf) = funpow i (fn prf => AbsP ("H", NONE, prf)) prf;
   241 
   248 
   242 fun apsome f NONE = raise SAME
   249 fun apsome f NONE = raise SAME
   259           handle SAME => AbsP (s, t, mapp prf))
   266           handle SAME => AbsP (s, t, mapp prf))
   260       | mapp (prf % t) = (mapp prf % (apsome f t handle SAME => t)
   267       | mapp (prf % t) = (mapp prf % (apsome f t handle SAME => t)
   261           handle SAME => prf % apsome f t)
   268           handle SAME => prf % apsome f t)
   262       | mapp (prf1 %% prf2) = (mapp prf1 %% mapph prf2
   269       | mapp (prf1 %% prf2) = (mapp prf1 %% mapph prf2
   263           handle SAME => prf1 %% mapp prf2)
   270           handle SAME => prf1 %% mapp prf2)
   264       | mapp (PThm (a, prf, prop, SOME Ts)) =
       
   265           PThm (a, prf, prop, SOME (map_typs Ts))
       
   266       | mapp (PAxm (a, prop, SOME Ts)) =
   271       | mapp (PAxm (a, prop, SOME Ts)) =
   267           PAxm (a, prop, SOME (map_typs Ts))
   272           PAxm (a, prop, SOME (map_typs Ts))
       
   273       | mapp (PThm (i, ((a, prop, SOME Ts), body))) =
       
   274           PThm (i, ((a, prop, SOME (map_typs Ts)), body))
   268       | mapp _ = raise SAME
   275       | mapp _ = raise SAME
   269     and mapph prf = (mapp prf handle SAME => prf)
   276     and mapph prf = (mapp prf handle SAME => prf)
   270 
   277 
   271   in mapph end;
   278   in mapph end;
   272 
   279 
   285   | fold_proof_terms f g (AbsP (_, NONE, prf)) = fold_proof_terms f g prf
   292   | fold_proof_terms f g (AbsP (_, NONE, prf)) = fold_proof_terms f g prf
   286   | fold_proof_terms f g (prf % SOME t) = fold_proof_terms f g prf #> f t
   293   | fold_proof_terms f g (prf % SOME t) = fold_proof_terms f g prf #> f t
   287   | fold_proof_terms f g (prf % NONE) = fold_proof_terms f g prf
   294   | fold_proof_terms f g (prf % NONE) = fold_proof_terms f g prf
   288   | fold_proof_terms f g (prf1 %% prf2) =
   295   | fold_proof_terms f g (prf1 %% prf2) =
   289       fold_proof_terms f g prf1 #> fold_proof_terms f g prf2
   296       fold_proof_terms f g prf1 #> fold_proof_terms f g prf2
   290   | fold_proof_terms _ g (PThm (_, _, _, SOME Ts)) = fold g Ts
       
   291   | fold_proof_terms _ g (PAxm (_, _, SOME Ts)) = fold g Ts
   297   | fold_proof_terms _ g (PAxm (_, _, SOME Ts)) = fold g Ts
       
   298   | fold_proof_terms _ g (PThm (_, ((_, _, SOME Ts), _))) = fold g Ts
   292   | fold_proof_terms _ _ _ = I;
   299   | fold_proof_terms _ _ _ = I;
   293 
   300 
   294 fun maxidx_proof prf = fold_proof_terms Term.maxidx_term Term.maxidx_typ prf;
   301 fun maxidx_proof prf = fold_proof_terms Term.maxidx_term Term.maxidx_typ prf;
   295 
   302 
   296 fun size_of_proof (Abst (_, _, prf)) = 1 + size_of_proof prf
   303 fun size_of_proof (Abst (_, _, prf)) = 1 + size_of_proof prf
   297   | size_of_proof (AbsP (_, t, prf)) = 1 + size_of_proof prf
   304   | size_of_proof (AbsP (_, t, prf)) = 1 + size_of_proof prf
       
   305   | size_of_proof (prf % _) = 1 + size_of_proof prf
   298   | size_of_proof (prf1 %% prf2) = size_of_proof prf1 + size_of_proof prf2
   306   | size_of_proof (prf1 %% prf2) = size_of_proof prf1 + size_of_proof prf2
   299   | size_of_proof (prf % _) = 1 + size_of_proof prf
       
   300   | size_of_proof _ = 1;
   307   | size_of_proof _ = 1;
   301 
   308 
   302 fun change_type opTs (PThm (name, prf, prop, _)) = PThm (name, prf, prop, opTs)
   309 fun change_type opTs (PAxm (name, prop, _)) = PAxm (name, prop, opTs)
   303   | change_type opTs (PAxm (name, prop, _)) = PAxm (name, prop, opTs)
       
   304   | change_type opTs (Oracle (name, prop, _)) = Oracle (name, prop, opTs)
   310   | change_type opTs (Oracle (name, prop, _)) = Oracle (name, prop, opTs)
   305   | change_type opTs (Promise (i, prop, _)) = Promise (i, prop, opTs)
   311   | change_type opTs (Promise (i, prop, _)) = Promise (i, prop, opTs)
       
   312   | change_type opTs (PThm (i, ((name, prop, _), body))) = PThm (i, ((name, prop, opTs), body))
   306   | change_type _ prf = prf;
   313   | change_type _ prf = prf;
   307 
   314 
   308 
   315 
   309 (***** utilities *****)
   316 (***** utilities *****)
   310 
   317 
   434           handle SAME => AbsP (s, t, norm prf))
   441           handle SAME => AbsP (s, t, norm prf))
   435       | norm (prf % t) = (norm prf % Option.map (htype norm_term) t
   442       | norm (prf % t) = (norm prf % Option.map (htype norm_term) t
   436           handle SAME => prf % apsome' (htype norm_term_same) t)
   443           handle SAME => prf % apsome' (htype norm_term_same) t)
   437       | norm (prf1 %% prf2) = (norm prf1 %% normh prf2
   444       | norm (prf1 %% prf2) = (norm prf1 %% normh prf2
   438           handle SAME => prf1 %% norm prf2)
   445           handle SAME => prf1 %% norm prf2)
   439       | norm (PThm (s, prf, t, Ts)) = PThm (s, prf, t, apsome' (htypeTs norm_types_same) Ts)
       
   440       | norm (PAxm (s, prop, Ts)) = PAxm (s, prop, apsome' (htypeTs norm_types_same) Ts)
   446       | norm (PAxm (s, prop, Ts)) = PAxm (s, prop, apsome' (htypeTs norm_types_same) Ts)
       
   447       | norm (PThm (i, ((s, t, Ts), body))) =
       
   448           PThm (i, ((s, t, apsome' (htypeTs norm_types_same) Ts), body))
   441       | norm _ = raise SAME
   449       | norm _ = raise SAME
   442     and normh prf = (norm prf handle SAME => prf);
   450     and normh prf = (norm prf handle SAME => prf);
   443   in normh end;
   451   in normh end;
       
   452 
   444 
   453 
   445 (***** Remove some types in proof term (to save space) *****)
   454 (***** Remove some types in proof term (to save space) *****)
   446 
   455 
   447 fun remove_types (Abs (s, _, t)) = Abs (s, dummyT, remove_types t)
   456 fun remove_types (Abs (s, _, t)) = Abs (s, dummyT, remove_types t)
   448   | remove_types (t $ u) = remove_types t $ remove_types u
   457   | remove_types (t $ u) = remove_types t $ remove_types u
   452 fun remove_types_env (Envir.Envir {iTs, asol, maxidx}) =
   461 fun remove_types_env (Envir.Envir {iTs, asol, maxidx}) =
   453   Envir.Envir {iTs = iTs, asol = Vartab.map (apsnd remove_types) asol,
   462   Envir.Envir {iTs = iTs, asol = Vartab.map (apsnd remove_types) asol,
   454     maxidx = maxidx};
   463     maxidx = maxidx};
   455 
   464 
   456 fun norm_proof' env prf = norm_proof (remove_types_env env) prf;
   465 fun norm_proof' env prf = norm_proof (remove_types_env env) prf;
       
   466 
   457 
   467 
   458 (**** substitution of bound variables ****)
   468 (**** substitution of bound variables ****)
   459 
   469 
   460 fun prf_subst_bounds args prf =
   470 fun prf_subst_bounds args prf =
   461   let
   471   let
   581 fun varify_proof t fixed prf =
   591 fun varify_proof t fixed prf =
   582   let
   592   let
   583     val fs = Term.fold_types (Term.fold_atyps
   593     val fs = Term.fold_types (Term.fold_atyps
   584       (fn TFree v => if member (op =) fixed v then I else insert (op =) v | _ => I)) t [];
   594       (fn TFree v => if member (op =) fixed v then I else insert (op =) v | _ => I)) t [];
   585     val ixns = add_term_tvar_ixns (t, []);
   595     val ixns = add_term_tvar_ixns (t, []);
   586     val fmap = fs ~~ Name.variant_list (map #1 ixns) (map fst fs)
   596     val fmap = fs ~~ Name.variant_list (map #1 ixns) (map fst fs);
   587     fun thaw (f as (a, S)) =
   597     fun thaw (f as (a, S)) =
   588       (case AList.lookup (op =) fmap f of
   598       (case AList.lookup (op =) fmap f of
   589         NONE => TFree f
   599         NONE => TFree f
   590       | SOME b => TVar ((b, 0), S));
   600       | SOME b => TVar ((b, 0), S));
   591   in map_proof_terms (map_types (map_type_tfree thaw)) (map_type_tfree thaw) prf
   601   in map_proof_terms (map_types (map_type_tfree thaw)) (map_type_tfree thaw) prf end;
   592   end;
       
   593 
   602 
   594 
   603 
   595 local
   604 local
   596 
   605 
   597 fun new_name (ix, (pairs,used)) =
   606 fun new_name (ix, (pairs,used)) =
   675            handle SAME => AbsP (s, t, lift' Us Ts prf))
   684            handle SAME => AbsP (s, t, lift' Us Ts prf))
   676       | lift' Us Ts (prf % t) = (lift' Us Ts prf % Option.map (lift'' Us Ts) t
   685       | lift' Us Ts (prf % t) = (lift' Us Ts prf % Option.map (lift'' Us Ts) t
   677           handle SAME => prf % apsome' (same (op =) (lift'' Us Ts)) t)
   686           handle SAME => prf % apsome' (same (op =) (lift'' Us Ts)) t)
   678       | lift' Us Ts (prf1 %% prf2) = (lift' Us Ts prf1 %% lifth' Us Ts prf2
   687       | lift' Us Ts (prf1 %% prf2) = (lift' Us Ts prf1 %% lifth' Us Ts prf2
   679           handle SAME => prf1 %% lift' Us Ts prf2)
   688           handle SAME => prf1 %% lift' Us Ts prf2)
   680       | lift' _ _ (PThm (s, prf, prop, Ts)) =
       
   681           PThm (s, prf, prop, apsome' (same (op =) (map (Logic.incr_tvar inc))) Ts)
       
   682       | lift' _ _ (PAxm (s, prop, Ts)) =
   689       | lift' _ _ (PAxm (s, prop, Ts)) =
   683           PAxm (s, prop, apsome' (same (op =) (map (Logic.incr_tvar inc))) Ts)
   690           PAxm (s, prop, apsome' (same (op =) (map (Logic.incr_tvar inc))) Ts)
       
   691       | lift' _ _ (PThm (i, ((s, prop, Ts), body))) =
       
   692           PThm (i, ((s, prop, apsome' (same (op =) (map (Logic.incr_tvar inc))) Ts), body))
   684       | lift' _ _ _ = raise SAME
   693       | lift' _ _ _ = raise SAME
   685     and lifth' Us Ts prf = (lift' Us Ts prf handle SAME => prf);
   694     and lifth' Us Ts prf = (lift' Us Ts prf handle SAME => prf);
   686 
   695 
   687     val ps = map (Logic.lift_all inc Bi) (Logic.strip_imp_prems prop);
   696     val ps = map (Logic.lift_all inc Bi) (Logic.strip_imp_prems prop);
   688     val k = length ps;
   697     val k = length ps;
   823 fun equal_elim A B prf1 prf2 =
   832 fun equal_elim A B prf1 prf2 =
   824   equal_elim_axm %> remove_types A %> remove_types B %% prf1 %% prf2;
   833   equal_elim_axm %> remove_types A %> remove_types B %% prf1 %% prf2;
   825 
   834 
   826 
   835 
   827 (***** axioms and theorems *****)
   836 (***** axioms and theorems *****)
       
   837 
       
   838 val proofs = ref 2;
   828 
   839 
   829 fun vars_of t = rev (fold_aterms (fn v as Var _ => insert (op =) v | _ => I) t []);
   840 fun vars_of t = rev (fold_aterms (fn v as Var _ => insert (op =) v | _ => I) t []);
   830 
   841 
   831 fun test_args _ [] = true
   842 fun test_args _ [] = true
   832   | test_args is (Bound i :: ts) =
   843   | test_args is (Bound i :: ts) =
   927           (if exists (fn SOME (Bound j) => lev-j <= List.nth (ls, i) | _ => true) ts
   938           (if exists (fn SOME (Bound j) => lev-j <= List.nth (ls, i) | _ => true) ts
   928              orelse has_duplicates (op =)
   939              orelse has_duplicates (op =)
   929                (Library.foldl (fn (js, SOME (Bound j)) => j :: js | (js, _) => js) ([], ts))
   940                (Library.foldl (fn (js, SOME (Bound j)) => j :: js | (js, _) => js) ([], ts))
   930              orelse exists #1 prfs then [i] else [], false, map (pair false) ts, prf)
   941              orelse exists #1 prfs then [i] else [], false, map (pair false) ts, prf)
   931       | shrink' ls lev ts prfs (Hyp t) = ([], false, map (pair false) ts, Hyp t)
   942       | shrink' ls lev ts prfs (Hyp t) = ([], false, map (pair false) ts, Hyp t)
   932       | shrink' ls lev ts prfs (prf as MinProof _) =
   943       | shrink' ls lev ts prfs MinProof = ([], false, map (pair false) ts, MinProof)
   933           ([], false, map (pair false) ts, prf)
       
   934       | shrink' ls lev ts prfs prf =
   944       | shrink' ls lev ts prfs prf =
   935           let
   945           let
   936             val prop = (case prf of PThm (_, _, prop, _) => prop | PAxm (_, prop, _) => prop
   946             val prop =
   937               | Oracle (_, prop, _) => prop | Promise (_, prop, _) => prop
   947               (case prf of
       
   948                 PAxm (_, prop, _) => prop
       
   949               | Oracle (_, prop, _) => prop
       
   950               | Promise (_, prop, _) => prop
       
   951               | PThm (_, ((_, prop, _), _)) => prop
   938               | _ => error "shrink: proof not in normal form");
   952               | _ => error "shrink: proof not in normal form");
   939             val vs = vars_of prop;
   953             val vs = vars_of prop;
   940             val (ts', ts'') = chop (length vs) ts;
   954             val (ts', ts'') = chop (length vs) ts;
   941             val insts = Library.take (length ts', map (fst o dest_Var) vs) ~~ ts';
   955             val insts = Library.take (length ts', map (fst o dest_Var) vs) ~~ ts';
   942             val nvs = Library.foldl (fn (ixns', (ixn, ixns)) =>
   956             val nvs = Library.foldl (fn (ixns', (ixn, ixns)) =>
  1013             (incr_pboundvars 0 1 prf1 %> Bound 0, prf2)
  1027             (incr_pboundvars 0 1 prf1 %> Bound 0, prf2)
  1014       | mtch Ts i j inst (AbsP (_, opt, prf1), AbsP (_, opu, prf2)) =
  1028       | mtch Ts i j inst (AbsP (_, opt, prf1), AbsP (_, opu, prf2)) =
  1015           mtch Ts (i+1) j (optmatch (matcht Ts j) inst (opt, opu)) (prf1, prf2)
  1029           mtch Ts (i+1) j (optmatch (matcht Ts j) inst (opt, opu)) (prf1, prf2)
  1016       | mtch Ts i j inst (prf1, AbsP (_, _, prf2)) =
  1030       | mtch Ts i j inst (prf1, AbsP (_, _, prf2)) =
  1017           mtch Ts (i+1) j inst (incr_pboundvars 1 0 prf1 %% PBound 0, prf2)
  1031           mtch Ts (i+1) j inst (incr_pboundvars 1 0 prf1 %% PBound 0, prf2)
  1018       | mtch Ts i j inst (PThm (name1, _, prop1, opTs), PThm (name2, _, prop2, opUs)) =
  1032       | mtch Ts i j inst (PAxm (s1, _, opTs), PAxm (s2, _, opUs)) =
  1019           if name1=name2 andalso prop1=prop2 then
  1033           if s1 = s2 then optmatch matchTs inst (opTs, opUs)
       
  1034           else raise PMatch
       
  1035       | mtch Ts i j inst (PThm (_, ((name1, prop1, opTs), _)), PThm (_, ((name2, prop2, opUs), _))) =
       
  1036           if name1 = name2 andalso prop1 = prop2 then
  1020             optmatch matchTs inst (opTs, opUs)
  1037             optmatch matchTs inst (opTs, opUs)
  1021           else raise PMatch
       
  1022       | mtch Ts i j inst (PAxm (s1, _, opTs), PAxm (s2, _, opUs)) =
       
  1023           if s1=s2 then optmatch matchTs inst (opTs, opUs)
       
  1024           else raise PMatch
  1038           else raise PMatch
  1025       | mtch _ _ _ inst (PBound i, PBound j) = if i = j then inst else raise PMatch
  1039       | mtch _ _ _ inst (PBound i, PBound j) = if i = j then inst else raise PMatch
  1026       | mtch _ _ _ _ _ = raise PMatch
  1040       | mtch _ _ _ _ _ = raise PMatch
  1027   in mtch Ts 0 0 end;
  1041   in mtch Ts 0 0 end;
  1028 
  1042 
  1046       | subst plev tlev (prf %% prf') = subst plev tlev prf %% subst plev tlev prf'
  1060       | subst plev tlev (prf %% prf') = subst plev tlev prf %% subst plev tlev prf'
  1047       | subst plev tlev (prf % t) = subst plev tlev prf % Option.map (subst' tlev) t
  1061       | subst plev tlev (prf % t) = subst plev tlev prf % Option.map (subst' tlev) t
  1048       | subst plev tlev (prf as Hyp (Var (ixn, _))) = (case AList.lookup (op =) pinst ixn of
  1062       | subst plev tlev (prf as Hyp (Var (ixn, _))) = (case AList.lookup (op =) pinst ixn of
  1049           NONE => prf
  1063           NONE => prf
  1050         | SOME prf' => incr_pboundvars plev tlev prf')
  1064         | SOME prf' => incr_pboundvars plev tlev prf')
  1051       | subst _ _ (PThm (id, prf, prop, Ts)) =
       
  1052           PThm (id, prf, prop, Option.map (map substT) Ts)
       
  1053       | subst _ _ (PAxm (id, prop, Ts)) =
  1065       | subst _ _ (PAxm (id, prop, Ts)) =
  1054           PAxm (id, prop, Option.map (map substT) Ts)
  1066           PAxm (id, prop, Option.map (map substT) Ts)
  1055       | subst _ _ t = t
  1067       | subst _ _ (PThm (i, ((id, prop, Ts), body))) =
       
  1068           PThm (i, ((id, prop, Option.map (map substT) Ts), body))
       
  1069       | subst _ _ t = t;
  1056   in subst 0 0 end;
  1070   in subst 0 0 end;
  1057 
  1071 
  1058 (*A fast unification filter: true unless the two terms cannot be unified.
  1072 (*A fast unification filter: true unless the two terms cannot be unified.
  1059   Terms must be NORMAL.  Treats all Vars as distinct. *)
  1073   Terms must be NORMAL.  Treats all Vars as distinct. *)
  1060 fun could_unify prf1 prf2 =
  1074 fun could_unify prf1 prf2 =
  1071       | head_of prf = prf
  1085       | head_of prf = prf
  1072 
  1086 
  1073   in case (head_of prf1, head_of prf2) of
  1087   in case (head_of prf1, head_of prf2) of
  1074         (_, Hyp (Var _)) => true
  1088         (_, Hyp (Var _)) => true
  1075       | (Hyp (Var _), _) => true
  1089       | (Hyp (Var _), _) => true
  1076       | (PThm (a, _, propa, _), PThm (b, _, propb, _)) =>
  1090       | (PAxm (a, _, _), PAxm (b, _, _)) => a = b andalso matchrands prf1 prf2
       
  1091       | (PThm (_, ((a, propa, _), _)), PThm (_, ((b, propb, _), _))) =>
  1077           a = b andalso propa = propb andalso matchrands prf1 prf2
  1092           a = b andalso propa = propb andalso matchrands prf1 prf2
  1078       | (PAxm (a, _, _), PAxm (b, _, _)) => a = b andalso matchrands prf1 prf2
  1093       | (PBound i, PBound j) => i = j andalso matchrands prf1 prf2
  1079       | (PBound i, PBound j) =>  i = j andalso matchrands prf1 prf2
       
  1080       | (AbsP _, _) =>  true   (*because of possible eta equality*)
  1094       | (AbsP _, _) =>  true   (*because of possible eta equality*)
  1081       | (Abst _, _) =>  true
  1095       | (Abst _, _) =>  true
  1082       | (_, AbsP _) =>  true
  1096       | (_, AbsP _) =>  true
  1083       | (_, Abst _) =>  true
  1097       | (_, Abst _) =>  true
  1084       | _ => false
  1098       | _ => false
  1091 
  1105 
  1092 fun rewrite_prf tymatch (rules, procs) prf =
  1106 fun rewrite_prf tymatch (rules, procs) prf =
  1093   let
  1107   let
  1094     fun rew _ (Abst (_, _, body) % SOME t) = SOME (prf_subst_bounds [t] body, skel0)
  1108     fun rew _ (Abst (_, _, body) % SOME t) = SOME (prf_subst_bounds [t] body, skel0)
  1095       | rew _ (AbsP (_, _, body) %% prf) = SOME (prf_subst_pbounds [prf] body, skel0)
  1109       | rew _ (AbsP (_, _, body) %% prf) = SOME (prf_subst_pbounds [prf] body, skel0)
  1096       | rew Ts prf = (case get_first (fn (_, r) => r Ts prf) procs of
  1110       | rew Ts prf = (case get_first (fn r => r Ts prf) procs of
  1097           SOME prf' => SOME (prf', skel0)
  1111           SOME prf' => SOME (prf', skel0)
  1098         | NONE => get_first (fn (prf1, prf2) => SOME (prf_subst
  1112         | NONE => get_first (fn (prf1, prf2) => SOME (prf_subst
  1099             (match_proof Ts tymatch ([], (Vartab.empty, [])) (prf1, prf)) prf2, prf2)
  1113             (match_proof Ts tymatch ([], (Vartab.empty, [])) (prf1, prf)) prf2, prf2)
  1100                handle PMatch => NONE) (List.filter (could_unify prf o fst) rules));
  1114                handle PMatch => NONE) (filter (could_unify prf o fst) rules));
  1101 
  1115 
  1102     fun rew0 Ts (prf as AbsP (_, _, prf' %% PBound 0)) =
  1116     fun rew0 Ts (prf as AbsP (_, _, prf' %% PBound 0)) =
  1103           if prf_loose_Pbvar1 prf' 0 then rew Ts prf
  1117           if prf_loose_Pbvar1 prf' 0 then rew Ts prf
  1104           else
  1118           else
  1105             let val prf'' = incr_pboundvars (~1) 0 prf'
  1119             let val prf'' = incr_pboundvars (~1) 0 prf'
  1160 fun rewrite_proof thy = rewrite_prf (fn (tyenv, f) =>
  1174 fun rewrite_proof thy = rewrite_prf (fn (tyenv, f) =>
  1161   Sign.typ_match thy (f ()) tyenv handle Type.TYPE_MATCH => raise PMatch);
  1175   Sign.typ_match thy (f ()) tyenv handle Type.TYPE_MATCH => raise PMatch);
  1162 
  1176 
  1163 fun rewrite_proof_notypes rews = rewrite_prf fst rews;
  1177 fun rewrite_proof_notypes rews = rewrite_prf fst rews;
  1164 
  1178 
  1165 fun fulfill tab = rewrite_proof_notypes
       
  1166   ([], [("Pure/fulfill", K (fn Promise (i, _, _) => Inttab.lookup tab i | _ => NONE))]);
       
  1167 
       
  1168 
  1179 
  1169 (**** theory data ****)
  1180 (**** theory data ****)
  1170 
  1181 
  1171 structure ProofData = TheoryDataFun
  1182 structure ProofData = TheoryDataFun
  1172 (
  1183 (
  1173   type T = (proof * proof) list * (string * (typ list -> proof -> proof option)) list;
  1184   type T = (stamp * (proof * proof)) list * (stamp * (typ list -> proof -> proof option)) list;
  1174 
  1185 
  1175   val empty = ([], []);
  1186   val empty = ([], []);
  1176   val copy = I;
  1187   val copy = I;
  1177   val extend = I;
  1188   val extend = I;
  1178   fun merge _ ((rules1, procs1) : T, (rules2, procs2)) =
  1189   fun merge _ ((rules1, procs1), (rules2, procs2)) : T =
  1179     (Library.merge (op =) (rules1, rules2),
  1190     (AList.merge (op =) (K true) (rules1, rules2),
  1180       AList.merge (op =) (K true) (procs1, procs2));
  1191       AList.merge (op =) (K true) (procs1, procs2));
  1181 );
  1192 );
  1182 
  1193 
  1183 fun rew_proof thy = rewrite_prf fst (ProofData.get thy);
  1194 fun get_data thy = let val (rules, procs) = ProofData.get thy in (map #2 rules, map #2 procs) end;
  1184 
  1195 fun rew_proof thy = rewrite_prf fst (get_data thy);
  1185 fun add_prf_rrule r = (ProofData.map o apfst) (insert (op =) r);
  1196 
  1186 
  1197 fun add_prf_rrule r = (ProofData.map o apfst) (cons (stamp (), r));
  1187 fun add_prf_rproc p = (ProofData.map o apsnd) (AList.update (op =) p);
  1198 fun add_prf_rproc p = (ProofData.map o apsnd) (cons (stamp (), p));
  1188 
  1199 
  1189 fun thm_proof thy name hyps prop prf =
  1200 
  1190   let
  1201 (***** theorems *****)
       
  1202 
       
  1203 fun fulfill_proof promises body0 =
       
  1204   let
       
  1205     val tab = Inttab.make promises;
       
  1206     fun fill (Promise (i, _, _)) = Option.map Lazy.force (Inttab.lookup tab i)
       
  1207       | fill _ = NONE;
       
  1208     val PBody {oracles = oracles0, thms = thms0, proof = proof0} = body0;
       
  1209     val proof = proof0 |> rewrite_proof_notypes ([], [K fill]);
       
  1210     val (oracles, thms) = (oracles0, thms0)
       
  1211       |> fold (merge_body o make_body o Lazy.force o #2) promises;
       
  1212   in PBody {oracles = oracles, thms = thms, proof = proof} end;
       
  1213 
       
  1214 fun thm_proof thy name hyps prop promises body =
       
  1215   let
       
  1216     val PBody {oracles = oracles0, thms = thms0, proof = prf} = body;
  1191     val prop = Logic.list_implies (hyps, prop);
  1217     val prop = Logic.list_implies (hyps, prop);
  1192     val nvs = needed_vars prop;
  1218     val nvs = needed_vars prop;
  1193     val args = map (fn (v as Var (ixn, _)) =>
  1219     val args = map (fn (v as Var (ixn, _)) =>
  1194         if member (op =) nvs ixn then SOME v else NONE) (vars_of prop) @
  1220         if member (op =) nvs ixn then SOME v else NONE) (vars_of prop) @
  1195       map SOME (sort Term.term_ord (term_frees prop));
  1221       map SOME (sort Term.term_ord (term_frees prop));
  1196     val opt_prf = if ! proofs = 2 then
  1222 
  1197         #4 (shrink_proof thy [] 0 (rewrite_prf fst (ProofData.get thy)
  1223     val proof0 =
  1198           (fold_rev implies_intr_proof hyps prf)))
  1224       if ! proofs = 2 then
  1199       else MinProof (mk_min_proof prf ([], [], []));
  1225         #4 (shrink_proof thy [] 0 (rew_proof thy (fold_rev implies_intr_proof hyps prf)))
  1200     val head = (case strip_combt (fst (strip_combP prf)) of
  1226       else MinProof;
  1201         (PThm (old_name, prf', prop', NONE), args') =>
  1227 
  1202           if (old_name="" orelse old_name=name) andalso
  1228     fun new_prf () = (serial (), ((name, prop, NONE),
  1203              prop = prop' andalso args = args' then
  1229       Lazy.lazy (fn () =>
  1204             PThm (name, prf', prop, NONE)
  1230         fulfill_proof promises (PBody {oracles = oracles0, thms = thms0, proof = proof0}))));
  1205           else
  1231 
  1206             PThm (name, opt_prf, prop, NONE)
  1232     val head =
  1207       | _ => PThm (name, opt_prf, prop, NONE))
  1233       (case strip_combt (fst (strip_combP prf)) of
       
  1234         (PThm (i, ((old_name, prop', NONE), body')), args') =>
       
  1235           if (old_name = "" orelse old_name = name) andalso
       
  1236              prop = prop' andalso args = args'
       
  1237           then (i, ((name, prop, NONE), body'))
       
  1238           else new_prf ()
       
  1239       | _ => new_prf ())
  1208   in
  1240   in
  1209     proof_combP (proof_combt' (head, args), map Hyp hyps)
  1241     (head, proof_combP (proof_combt' (PThm head, args), map Hyp hyps))
  1210   end;
  1242   end;
  1211 
  1243 
  1212 fun get_name hyps prop prf =
  1244 fun get_name hyps prop prf =
  1213   let val prop = Logic.list_implies (hyps, prop) in
  1245   let val prop = Logic.list_implies (hyps, prop) in
  1214     (case strip_combt (fst (strip_combP prf)) of
  1246     (case strip_combt (fst (strip_combP prf)) of
  1215       (PThm (name, _, prop', _), _) => if prop=prop' then name else ""
  1247       (PAxm (name, prop', _), _) => if prop = prop' then name else ""   (* FIXME !? *)
  1216     | (PAxm (name, prop', _), _) => if prop=prop' then name else ""
  1248     | (PThm (_, ((name, prop', _), _)), _) => if prop = prop' then name else ""
  1217     | _ => "")
  1249     | _ => "")
  1218   end;
  1250   end;
  1219 
  1251 
  1220 end;
  1252 end;
  1221 
  1253