type thm: fully internal derivation, no longer exported;
authorwenzelm
Mon, 22 Sep 2008 15:26:14 +0200
changeset 283219f4499bf9384
parent 28320 c6aef67f964d
child 28322 6f4cf302c798
type thm: fully internal derivation, no longer exported;
incorporate former deriv.ML as internal abstract type;
added rudimentary promise interface;
tuned;
added is_named (does not require finished derivation);
src/Pure/thm.ML
     1.1 --- a/src/Pure/thm.ML	Mon Sep 22 15:26:14 2008 +0200
     1.2 +++ b/src/Pure/thm.ML	Mon Sep 22 15:26:14 2008 +0200
     1.3 @@ -4,7 +4,8 @@
     1.4      Copyright   1994  University of Cambridge
     1.5  
     1.6  The very core of Isabelle's Meta Logic: certified types and terms,
     1.7 -meta theorems, meta rules (including lifting and resolution).
     1.8 +derivations, theorems, framework rules (including lifting and
     1.9 +resolution), oracles.
    1.10  *)
    1.11  
    1.12  signature BASIC_THM =
    1.13 @@ -35,13 +36,13 @@
    1.14    val cterm_of: theory -> term -> cterm
    1.15    val ctyp_of_term: cterm -> ctyp
    1.16  
    1.17 -  (*meta theorems*)
    1.18 +  (*theorems*)
    1.19 +  type deriv
    1.20    type thm
    1.21    type conv = cterm -> thm
    1.22    type attribute = Context.generic * thm -> Context.generic * thm
    1.23    val rep_thm: thm ->
    1.24     {thy_ref: theory_ref,
    1.25 -    der: Deriv.T,
    1.26      tags: Properties.T,
    1.27      maxidx: int,
    1.28      shyps: sort list,
    1.29 @@ -50,7 +51,6 @@
    1.30      prop: term}
    1.31    val crep_thm: thm ->
    1.32     {thy_ref: theory_ref,
    1.33 -    der: Deriv.T,
    1.34      tags: Properties.T,
    1.35      maxidx: int,
    1.36      shyps: sort list,
    1.37 @@ -60,6 +60,7 @@
    1.38    exception THM of string * int * thm list
    1.39    val theory_of_thm: thm -> theory
    1.40    val prop_of: thm -> term
    1.41 +  val oracle_of: thm -> bool
    1.42    val proof_of: thm -> Proofterm.proof
    1.43    val tpairs_of: thm -> (term * term) list
    1.44    val concl_of: thm -> term
    1.45 @@ -112,6 +113,7 @@
    1.46    val compose_no_flatten: bool -> thm * int -> int -> thm -> thm Seq.seq
    1.47    val bicompose: bool -> bool * thm * int -> int -> thm -> thm Seq.seq
    1.48    val biresolution: bool -> (bool * thm) list -> int -> thm -> thm Seq.seq
    1.49 +  val promise: thm Future.T -> cterm -> thm
    1.50    val extern_oracles: theory -> xstring list
    1.51    val add_oracle: bstring * ('a -> cterm) -> theory -> (string * ('a -> thm)) * theory
    1.52  end;
    1.53 @@ -333,17 +335,21 @@
    1.54  
    1.55  
    1.56  
    1.57 -(*** Meta theorems ***)
    1.58 +(*** Derivations and Theorems ***)
    1.59  
    1.60 -abstype thm = Thm of
    1.61 - {thy_ref: theory_ref,         (*dynamic reference to theory*)
    1.62 -  der: Deriv.T,                (*derivation*)
    1.63 -  tags: Properties.T,          (*additional annotations/comments*)
    1.64 -  maxidx: int,                 (*maximum index of any Var or TVar*)
    1.65 -  shyps: sort list,            (*sort hypotheses as ordered list*)
    1.66 -  hyps: term list,             (*hypotheses as ordered list*)
    1.67 -  tpairs: (term * term) list,  (*flex-flex pairs*)
    1.68 -  prop: term}                  (*conclusion*)
    1.69 +abstype deriv = Deriv of
    1.70 + {oracle: bool,                                       (*oracle occurrence flag*)
    1.71 +  proof: Pt.proof,                                    (*proof term*)
    1.72 +  promises: (serial * (theory * thm Future.T)) list}  (*promised derivations*)
    1.73 +and thm = Thm of
    1.74 + deriv *                                              (*derivation*)
    1.75 + {thy_ref: theory_ref,                                (*dynamic reference to theory*)
    1.76 +  tags: Properties.T,                                 (*additional annotations/comments*)
    1.77 +  maxidx: int,                                        (*maximum index of any Var or TVar*)
    1.78 +  shyps: sort list,                                   (*sort hypotheses as ordered list*)
    1.79 +  hyps: term list,                                    (*hypotheses as ordered list*)
    1.80 +  tpairs: (term * term) list,                         (*flex-flex pairs*)
    1.81 +  prop: term}                                         (*conclusion*)
    1.82  with
    1.83  
    1.84  type conv = cterm -> thm;
    1.85 @@ -354,11 +360,11 @@
    1.86  (*errors involving theorems*)
    1.87  exception THM of string * int * thm list;
    1.88  
    1.89 -fun rep_thm (Thm args) = args;
    1.90 +fun rep_thm (Thm (_, args)) = args;
    1.91  
    1.92 -fun crep_thm (Thm {thy_ref, der, tags, maxidx, shyps, hyps, tpairs, prop}) =
    1.93 +fun crep_thm (Thm (_, {thy_ref, tags, maxidx, shyps, hyps, tpairs, prop})) =
    1.94    let fun cterm max t = Cterm {thy_ref = thy_ref, t = t, T = propT, maxidx = max, sorts = shyps} in
    1.95 -   {thy_ref = thy_ref, der = der, tags = tags, maxidx = maxidx, shyps = shyps,
    1.96 +   {thy_ref = thy_ref, tags = tags, maxidx = maxidx, shyps = shyps,
    1.97      hyps = map (cterm ~1) hyps,
    1.98      tpairs = map (pairself (cterm maxidx)) tpairs,
    1.99      prop = cterm maxidx prop}
   1.100 @@ -373,29 +379,30 @@
   1.101  fun attach_tpairs tpairs prop =
   1.102    Logic.list_implies (map Logic.mk_equals tpairs, prop);
   1.103  
   1.104 -fun full_prop_of (Thm {tpairs, prop, ...}) = attach_tpairs tpairs prop;
   1.105 +fun full_prop_of (Thm (_, {tpairs, prop, ...})) = attach_tpairs tpairs prop;
   1.106  
   1.107  val union_hyps = OrdList.union Term.fast_term_ord;
   1.108  
   1.109  
   1.110  (* merge theories of cterms/thms -- trivial absorption only *)
   1.111  
   1.112 -fun merge_thys1 (Cterm {thy_ref = r1, ...}) (th as Thm {thy_ref = r2, ...}) =
   1.113 +fun merge_thys1 (Cterm {thy_ref = r1, ...}) (th as Thm (_, {thy_ref = r2, ...})) =
   1.114    Theory.merge_refs (r1, r2);
   1.115  
   1.116 -fun merge_thys2 (th1 as Thm {thy_ref = r1, ...}) (th2 as Thm {thy_ref = r2, ...}) =
   1.117 +fun merge_thys2 (th1 as Thm (_, {thy_ref = r1, ...})) (th2 as Thm (_, {thy_ref = r2, ...})) =
   1.118    Theory.merge_refs (r1, r2);
   1.119  
   1.120  
   1.121  (* basic components *)
   1.122  
   1.123 -fun theory_of_thm (Thm {thy_ref, ...}) = Theory.deref thy_ref;
   1.124 -fun maxidx_of (Thm {maxidx, ...}) = maxidx;
   1.125 +val theory_of_thm = Theory.deref o #thy_ref o rep_thm;
   1.126 +val maxidx_of = #maxidx o rep_thm;
   1.127  fun maxidx_thm th i = Int.max (maxidx_of th, i);
   1.128 -fun hyps_of (Thm {hyps, ...}) = hyps;
   1.129 -fun prop_of (Thm {prop, ...}) = prop;
   1.130 -fun proof_of (Thm {der, ...}) = Deriv.proof_of der;
   1.131 -fun tpairs_of (Thm {tpairs, ...}) = tpairs;
   1.132 +val hyps_of = #hyps o rep_thm;
   1.133 +val prop_of = #prop o rep_thm;
   1.134 +fun oracle_of (Thm (Deriv {oracle, ...}, _)) = oracle;   (* FIXME finish proof *)
   1.135 +fun proof_of (Thm (Deriv {proof, ...}, _)) = proof;   (* FIXME finish proof *)
   1.136 +val tpairs_of = #tpairs o rep_thm;
   1.137  
   1.138  val concl_of = Logic.strip_imp_concl o prop_of;
   1.139  val prems_of = Logic.strip_imp_prems o prop_of;
   1.140 @@ -408,17 +415,17 @@
   1.141    | [] => raise THM ("major_prem_of: rule with no premises", 0, [th]));
   1.142  
   1.143  (*the statement of any thm is a cterm*)
   1.144 -fun cprop_of (Thm {thy_ref, maxidx, shyps, prop, ...}) =
   1.145 +fun cprop_of (Thm (_, {thy_ref, maxidx, shyps, prop, ...})) =
   1.146    Cterm {thy_ref = thy_ref, maxidx = maxidx, T = propT, t = prop, sorts = shyps};
   1.147  
   1.148 -fun cprem_of (th as Thm {thy_ref, maxidx, shyps, prop, ...}) i =
   1.149 +fun cprem_of (th as Thm (_, {thy_ref, maxidx, shyps, prop, ...})) i =
   1.150    Cterm {thy_ref = thy_ref, maxidx = maxidx, T = propT, sorts = shyps,
   1.151      t = Logic.nth_prem (i, prop) handle TERM _ => raise THM ("cprem_of", i, [th])};
   1.152  
   1.153  (*explicit transfer to a super theory*)
   1.154  fun transfer thy' thm =
   1.155    let
   1.156 -    val Thm {thy_ref, der, tags, maxidx, shyps, hyps, tpairs, prop} = thm;
   1.157 +    val Thm (der, {thy_ref, tags, maxidx, shyps, hyps, tpairs, prop}) = thm;
   1.158      val thy = Theory.deref thy_ref;
   1.159      val _ = Theory.subthy (thy, thy') orelse raise THM ("transfer: not a super theory", 0, [thm]);
   1.160      val is_eq = Theory.eq_thy (thy, thy');
   1.161 @@ -426,60 +433,106 @@
   1.162    in
   1.163      if is_eq then thm
   1.164      else
   1.165 -      Thm {thy_ref = Theory.check_thy thy',
   1.166 -        der = der,
   1.167 +      Thm (der,
   1.168 +       {thy_ref = Theory.check_thy thy',
   1.169          tags = tags,
   1.170          maxidx = maxidx,
   1.171          shyps = shyps,
   1.172          hyps = hyps,
   1.173          tpairs = tpairs,
   1.174 -        prop = prop}
   1.175 +        prop = prop})
   1.176    end;
   1.177  
   1.178  (*explicit weakening: maps |- B to A |- B*)
   1.179  fun weaken raw_ct th =
   1.180    let
   1.181      val ct as Cterm {t = A, T, sorts, maxidx = maxidxA, ...} = adjust_maxidx_cterm ~1 raw_ct;
   1.182 -    val Thm {der, tags, maxidx, shyps, hyps, tpairs, prop, ...} = th;
   1.183 +    val Thm (der, {tags, maxidx, shyps, hyps, tpairs, prop, ...}) = th;
   1.184    in
   1.185      if T <> propT then
   1.186        raise THM ("weaken: assumptions must have type prop", 0, [])
   1.187      else if maxidxA <> ~1 then
   1.188        raise THM ("weaken: assumptions may not contain schematic variables", maxidxA, [])
   1.189      else
   1.190 -      Thm {thy_ref = merge_thys1 ct th,
   1.191 -        der = der,
   1.192 +      Thm (der,
   1.193 +       {thy_ref = merge_thys1 ct th,
   1.194          tags = tags,
   1.195          maxidx = maxidx,
   1.196          shyps = Sorts.union sorts shyps,
   1.197          hyps = OrdList.insert Term.fast_term_ord A hyps,
   1.198          tpairs = tpairs,
   1.199 -        prop = prop}
   1.200 +        prop = prop})
   1.201    end;
   1.202  
   1.203  
   1.204  
   1.205  (** sort contexts of theorems **)
   1.206  
   1.207 -fun present_sorts (Thm {hyps, tpairs, prop, ...}) =
   1.208 +fun present_sorts (Thm (_, {hyps, tpairs, prop, ...})) =
   1.209    fold (fn (t, u) => Sorts.insert_term t o Sorts.insert_term u) tpairs
   1.210      (Sorts.insert_terms hyps (Sorts.insert_term prop []));
   1.211  
   1.212  (*remove extra sorts that are non-empty by virtue of type signature information*)
   1.213 -fun strip_shyps (thm as Thm {shyps = [], ...}) = thm
   1.214 -  | strip_shyps (thm as Thm {thy_ref, der, tags, maxidx, shyps, hyps, tpairs, prop}) =
   1.215 +fun strip_shyps (thm as Thm (_, {shyps = [], ...})) = thm
   1.216 +  | strip_shyps (thm as Thm (der, {thy_ref, tags, maxidx, shyps, hyps, tpairs, prop})) =
   1.217        let
   1.218          val thy = Theory.deref thy_ref;
   1.219          val present = present_sorts thm;
   1.220          val extra = Sorts.subtract present shyps;
   1.221          val shyps' = Sorts.subtract (map #2 (Sign.witness_sorts thy present extra)) shyps;
   1.222        in
   1.223 -        Thm {thy_ref = Theory.check_thy thy, der = der, tags = tags, maxidx = maxidx,
   1.224 -          shyps = shyps', hyps = hyps, tpairs = tpairs, prop = prop}
   1.225 +        Thm (der, {thy_ref = Theory.check_thy thy, tags = tags, maxidx = maxidx,
   1.226 +          shyps = shyps', hyps = hyps, tpairs = tpairs, prop = prop})
   1.227        end;
   1.228  
   1.229  (*dangling sort constraints of a thm*)
   1.230 -fun extra_shyps (th as Thm {shyps, ...}) = Sorts.subtract (present_sorts th) shyps;
   1.231 +fun extra_shyps (th as Thm (_, {shyps, ...})) = Sorts.subtract (present_sorts th) shyps;
   1.232 +
   1.233 +
   1.234 +
   1.235 +(** derivations **)
   1.236 +
   1.237 +local
   1.238 +
   1.239 +fun make_deriv oracle promises proof =
   1.240 +  Deriv {oracle = oracle, promises = promises, proof = proof};
   1.241 +
   1.242 +val empty_deriv = make_deriv false [] Pt.min_proof;
   1.243 +
   1.244 +fun add_oracles false = K I
   1.245 +  | add_oracles true = Pt.oracles_of_proof;
   1.246 +
   1.247 +in
   1.248 +
   1.249 +fun deriv_rule2 f
   1.250 +    (Deriv {oracle = ora1, promises = ps1, proof = prf1})
   1.251 +    (Deriv {oracle = ora2, promises = ps2, proof = prf2}) =
   1.252 +  let
   1.253 +    val ora = ora1 orelse ora2;
   1.254 +    val ps = OrdList.union (int_ord o pairself #1) ps1 ps2;
   1.255 +    val prf =
   1.256 +      (case ! Pt.proofs of
   1.257 +        2 => f prf1 prf2
   1.258 +      | 1 => MinProof (([], [], []) |> Pt.mk_min_proof prf1 |> Pt.mk_min_proof prf2)
   1.259 +      | 0 =>
   1.260 +          if ora then MinProof ([], [], [] |> add_oracles ora1 prf1 |> add_oracles ora2 prf2)
   1.261 +          else Pt.min_proof
   1.262 +      | i => error ("Illegal level of detail for proof objects: " ^ string_of_int i));
   1.263 +  in make_deriv ora ps prf end;
   1.264 +
   1.265 +fun deriv_rule1 f = deriv_rule2 (K f) empty_deriv;
   1.266 +fun deriv_rule0 prf = deriv_rule1 I (make_deriv false [] prf);
   1.267 +
   1.268 +fun deriv_oracle name prop =
   1.269 +  make_deriv true [] (Pt.oracle_proof name prop);
   1.270 +
   1.271 +fun deriv_promise i thy future prop =
   1.272 +  make_deriv false [(i, (thy, future))] (Pt.promise_proof i prop);
   1.273 +
   1.274 +fun deriv_uncond_rule f (Deriv {oracle, promises, proof}) =
   1.275 +  make_deriv oracle promises (f proof);
   1.276 +
   1.277 +end;
   1.278  
   1.279  
   1.280  
   1.281 @@ -492,12 +545,12 @@
   1.282        Symtab.lookup (Theory.axiom_table thy) name
   1.283        |> Option.map (fn prop =>
   1.284             let
   1.285 -             val der = Deriv.rule0 (Pt.axm_proof name prop);
   1.286 +             val der = deriv_rule0 (Pt.axm_proof name prop);
   1.287               val maxidx = maxidx_of_term prop;
   1.288               val shyps = Sorts.insert_term prop [];
   1.289             in
   1.290 -             Thm {thy_ref = Theory.check_thy thy, der = der, tags = [],
   1.291 -               maxidx = maxidx, shyps = shyps, hyps = [], tpairs = [], prop = prop}
   1.292 +             Thm (der, {thy_ref = Theory.check_thy thy, tags = [],
   1.293 +               maxidx = maxidx, shyps = shyps, hyps = [], tpairs = [], prop = prop})
   1.294             end);
   1.295    in
   1.296      (case get_first get_ax (theory :: Theory.ancestors_of theory) of
   1.297 @@ -523,43 +576,42 @@
   1.298  
   1.299  (* official name and additional tags *)
   1.300  
   1.301 -fun get_name (Thm {hyps, prop, der, ...}) =
   1.302 -  Pt.get_name hyps prop (Deriv.proof_of der);
   1.303 +fun get_name th = Pt.get_name (hyps_of th) (prop_of th) (proof_of th);  (*finished proof!*)
   1.304  
   1.305 -fun put_name name (Thm {thy_ref, der, tags, maxidx, shyps, hyps, tpairs = [], prop}) =
   1.306 +fun is_named (Thm (Deriv {proof, ...}, _)) = Pt.is_named proof;
   1.307 +
   1.308 +fun put_name name (thm as Thm (der, args as {thy_ref, hyps, prop, tpairs, ...})) =
   1.309        let
   1.310 +        val _ = null tpairs orelse
   1.311 +          raise THM ("name_thm: unsolved flex-flex constraints", 0, [thm]);
   1.312          val thy = Theory.deref thy_ref;
   1.313 -        val der' = Deriv.uncond_rule (Pt.thm_proof thy name hyps prop) der;
   1.314 -      in
   1.315 -        Thm {thy_ref = Theory.check_thy thy, der = der', tags = tags, maxidx = maxidx,
   1.316 -          shyps = shyps, hyps = hyps, tpairs = [], prop = prop}
   1.317 -      end
   1.318 -  | put_name _ thm = raise THM ("name_thm: unsolved flex-flex constraints", 0, [thm]);
   1.319 +        val der' = deriv_uncond_rule (Pt.thm_proof thy name hyps prop) der;
   1.320 +        val _ = Theory.check_thy thy;
   1.321 +      in Thm (der', args) end;
   1.322 +
   1.323  
   1.324  val get_tags = #tags o rep_thm;
   1.325  
   1.326 -fun map_tags f (Thm {thy_ref, der, tags, maxidx, shyps, hyps, tpairs, prop}) =
   1.327 -  Thm {thy_ref = thy_ref, der = der, tags = f tags, maxidx = maxidx,
   1.328 -    shyps = shyps, hyps = hyps, tpairs = tpairs, prop = prop};
   1.329 +fun map_tags f (Thm (der, {thy_ref, tags, maxidx, shyps, hyps, tpairs, prop})) =
   1.330 +  Thm (der, {thy_ref = thy_ref, tags = f tags, maxidx = maxidx,
   1.331 +    shyps = shyps, hyps = hyps, tpairs = tpairs, prop = prop});
   1.332  
   1.333  
   1.334 -fun norm_proof (Thm {thy_ref, der, tags, maxidx, shyps, hyps, tpairs, prop}) =
   1.335 +fun norm_proof (Thm (der, args as {thy_ref, ...})) =
   1.336    let
   1.337      val thy = Theory.deref thy_ref;
   1.338 -    val der' = Deriv.rule1 (Pt.rew_proof thy) der;
   1.339 -  in
   1.340 -    Thm {thy_ref = Theory.check_thy thy, der = der', tags = tags, maxidx = maxidx,
   1.341 -      shyps = shyps, hyps = hyps, tpairs = tpairs, prop = prop}
   1.342 -  end;
   1.343 +    val der' = deriv_rule1 (Pt.rew_proof thy) der;
   1.344 +    val _ = Theory.check_thy thy;
   1.345 +  in Thm (der', args) end;
   1.346  
   1.347 -fun adjust_maxidx_thm i (th as Thm {thy_ref, der, tags, maxidx, shyps, hyps, tpairs, prop}) =
   1.348 +fun adjust_maxidx_thm i (th as Thm (der, {thy_ref, tags, maxidx, shyps, hyps, tpairs, prop})) =
   1.349    if maxidx = i then th
   1.350    else if maxidx < i then
   1.351 -    Thm {maxidx = i, thy_ref = thy_ref, der = der, tags = tags, shyps = shyps,
   1.352 -      hyps = hyps, tpairs = tpairs, prop = prop}
   1.353 +    Thm (der, {maxidx = i, thy_ref = thy_ref, tags = tags, shyps = shyps,
   1.354 +      hyps = hyps, tpairs = tpairs, prop = prop})
   1.355    else
   1.356 -    Thm {maxidx = Int.max (maxidx_tpairs tpairs (maxidx_of_term prop), i), thy_ref = thy_ref,
   1.357 -      der = der, tags = tags, shyps = shyps, hyps = hyps, tpairs = tpairs, prop = prop};
   1.358 +    Thm (der, {maxidx = Int.max (maxidx_tpairs tpairs (maxidx_of_term prop), i), thy_ref = thy_ref,
   1.359 +      tags = tags, shyps = shyps, hyps = hyps, tpairs = tpairs, prop = prop});
   1.360  
   1.361  
   1.362  
   1.363 @@ -574,14 +626,14 @@
   1.364        raise THM ("assume: prop", 0, [])
   1.365      else if maxidx <> ~1 then
   1.366        raise THM ("assume: variables", maxidx, [])
   1.367 -    else Thm {thy_ref = thy_ref,
   1.368 -      der = Deriv.rule0 (Pt.Hyp prop),
   1.369 +    else Thm (deriv_rule0 (Pt.Hyp prop),
   1.370 +     {thy_ref = thy_ref,
   1.371        tags = [],
   1.372        maxidx = ~1,
   1.373        shyps = sorts,
   1.374        hyps = [prop],
   1.375        tpairs = [],
   1.376 -      prop = prop}
   1.377 +      prop = prop})
   1.378    end;
   1.379  
   1.380  (*Implication introduction
   1.381 @@ -593,18 +645,18 @@
   1.382  *)
   1.383  fun implies_intr
   1.384      (ct as Cterm {t = A, T, maxidx = maxidxA, sorts, ...})
   1.385 -    (th as Thm {der, maxidx, hyps, shyps, tpairs, prop, ...}) =
   1.386 +    (th as Thm (der, {maxidx, hyps, shyps, tpairs, prop, ...})) =
   1.387    if T <> propT then
   1.388      raise THM ("implies_intr: assumptions must have type prop", 0, [th])
   1.389    else
   1.390 -    Thm {thy_ref = merge_thys1 ct th,
   1.391 -      der = Deriv.rule1 (Pt.implies_intr_proof A) der,
   1.392 +    Thm (deriv_rule1 (Pt.implies_intr_proof A) der,
   1.393 +     {thy_ref = merge_thys1 ct th,
   1.394        tags = [],
   1.395        maxidx = Int.max (maxidxA, maxidx),
   1.396        shyps = Sorts.union sorts shyps,
   1.397        hyps = OrdList.remove Term.fast_term_ord A hyps,
   1.398        tpairs = tpairs,
   1.399 -      prop = Logic.mk_implies (A, prop)};
   1.400 +      prop = Logic.mk_implies (A, prop)});
   1.401  
   1.402  
   1.403  (*Implication elimination
   1.404 @@ -614,22 +666,22 @@
   1.405  *)
   1.406  fun implies_elim thAB thA =
   1.407    let
   1.408 -    val Thm {maxidx = maxA, der = derA, hyps = hypsA, shyps = shypsA, tpairs = tpairsA,
   1.409 -      prop = propA, ...} = thA
   1.410 -    and Thm {der, maxidx, hyps, shyps, tpairs, prop, ...} = thAB;
   1.411 +    val Thm (derA, {maxidx = maxA, hyps = hypsA, shyps = shypsA, tpairs = tpairsA,
   1.412 +      prop = propA, ...}) = thA
   1.413 +    and Thm (der, {maxidx, hyps, shyps, tpairs, prop, ...}) = thAB;
   1.414      fun err () = raise THM ("implies_elim: major premise", 0, [thAB, thA]);
   1.415    in
   1.416      case prop of
   1.417        Const ("==>", _) $ A $ B =>
   1.418          if A aconv propA then
   1.419 -          Thm {thy_ref = merge_thys2 thAB thA,
   1.420 -            der = Deriv.rule2 (curry Pt.%%) der derA,
   1.421 +          Thm (deriv_rule2 (curry Pt.%%) der derA,
   1.422 +           {thy_ref = merge_thys2 thAB thA,
   1.423              tags = [],
   1.424              maxidx = Int.max (maxA, maxidx),
   1.425              shyps = Sorts.union shypsA shyps,
   1.426              hyps = union_hyps hypsA hyps,
   1.427              tpairs = union_tpairs tpairsA tpairs,
   1.428 -            prop = B}
   1.429 +            prop = B})
   1.430          else err ()
   1.431      | _ => err ()
   1.432    end;
   1.433 @@ -643,17 +695,17 @@
   1.434  *)
   1.435  fun forall_intr
   1.436      (ct as Cterm {t = x, T, sorts, ...})
   1.437 -    (th as Thm {der, maxidx, shyps, hyps, tpairs, prop, ...}) =
   1.438 +    (th as Thm (der, {maxidx, shyps, hyps, tpairs, prop, ...})) =
   1.439    let
   1.440      fun result a =
   1.441 -      Thm {thy_ref = merge_thys1 ct th,
   1.442 -        der = Deriv.rule1 (Pt.forall_intr_proof x a) der,
   1.443 +      Thm (deriv_rule1 (Pt.forall_intr_proof x a) der,
   1.444 +       {thy_ref = merge_thys1 ct th,
   1.445          tags = [],
   1.446          maxidx = maxidx,
   1.447          shyps = Sorts.union sorts shyps,
   1.448          hyps = hyps,
   1.449          tpairs = tpairs,
   1.450 -        prop = Term.all T $ Abs (a, T, abstract_over (x, prop))};
   1.451 +        prop = Term.all T $ Abs (a, T, abstract_over (x, prop))});
   1.452      fun check_occs a x ts =
   1.453        if exists (fn t => Logic.occs (x, t)) ts then
   1.454          raise THM ("forall_intr: variable " ^ quote a ^ " free in assumptions", 0, [th])
   1.455 @@ -672,20 +724,20 @@
   1.456  *)
   1.457  fun forall_elim
   1.458      (ct as Cterm {t, T, maxidx = maxt, sorts, ...})
   1.459 -    (th as Thm {der, maxidx, shyps, hyps, tpairs, prop, ...}) =
   1.460 +    (th as Thm (der, {maxidx, shyps, hyps, tpairs, prop, ...})) =
   1.461    (case prop of
   1.462      Const ("all", Type ("fun", [Type ("fun", [qary, _]), _])) $ A =>
   1.463        if T <> qary then
   1.464          raise THM ("forall_elim: type mismatch", 0, [th])
   1.465        else
   1.466 -        Thm {thy_ref = merge_thys1 ct th,
   1.467 -          der = Deriv.rule1 (Pt.% o rpair (SOME t)) der,
   1.468 +        Thm (deriv_rule1 (Pt.% o rpair (SOME t)) der,
   1.469 +         {thy_ref = merge_thys1 ct th,
   1.470            tags = [],
   1.471            maxidx = Int.max (maxidx, maxt),
   1.472            shyps = Sorts.union sorts shyps,
   1.473            hyps = hyps,
   1.474            tpairs = tpairs,
   1.475 -          prop = Term.betapply (A, t)}
   1.476 +          prop = Term.betapply (A, t)})
   1.477    | _ => raise THM ("forall_elim: not quantified", 0, [th]));
   1.478  
   1.479  
   1.480 @@ -695,31 +747,31 @@
   1.481    t == t
   1.482  *)
   1.483  fun reflexive (ct as Cterm {thy_ref, t, T, maxidx, sorts}) =
   1.484 -  Thm {thy_ref = thy_ref,
   1.485 -    der = Deriv.rule0 Pt.reflexive,
   1.486 +  Thm (deriv_rule0 Pt.reflexive,
   1.487 +   {thy_ref = thy_ref,
   1.488      tags = [],
   1.489      maxidx = maxidx,
   1.490      shyps = sorts,
   1.491      hyps = [],
   1.492      tpairs = [],
   1.493 -    prop = Logic.mk_equals (t, t)};
   1.494 +    prop = Logic.mk_equals (t, t)});
   1.495  
   1.496  (*Symmetry
   1.497    t == u
   1.498    ------
   1.499    u == t
   1.500  *)
   1.501 -fun symmetric (th as Thm {thy_ref, der, maxidx, shyps, hyps, tpairs, prop, ...}) =
   1.502 +fun symmetric (th as Thm (der, {thy_ref, maxidx, shyps, hyps, tpairs, prop, ...})) =
   1.503    (case prop of
   1.504      (eq as Const ("==", Type (_, [T, _]))) $ t $ u =>
   1.505 -      Thm {thy_ref = thy_ref,
   1.506 -        der = Deriv.rule1 Pt.symmetric der,
   1.507 +      Thm (deriv_rule1 Pt.symmetric der,
   1.508 +       {thy_ref = thy_ref,
   1.509          tags = [],
   1.510          maxidx = maxidx,
   1.511          shyps = shyps,
   1.512          hyps = hyps,
   1.513          tpairs = tpairs,
   1.514 -        prop = eq $ u $ t}
   1.515 +        prop = eq $ u $ t})
   1.516      | _ => raise THM ("symmetric", 0, [th]));
   1.517  
   1.518  (*Transitivity
   1.519 @@ -729,24 +781,24 @@
   1.520  *)
   1.521  fun transitive th1 th2 =
   1.522    let
   1.523 -    val Thm {der = der1, maxidx = max1, hyps = hyps1, shyps = shyps1, tpairs = tpairs1,
   1.524 -      prop = prop1, ...} = th1
   1.525 -    and Thm {der = der2, maxidx = max2, hyps = hyps2, shyps = shyps2, tpairs = tpairs2,
   1.526 -      prop = prop2, ...} = th2;
   1.527 +    val Thm (der1, {maxidx = max1, hyps = hyps1, shyps = shyps1, tpairs = tpairs1,
   1.528 +      prop = prop1, ...}) = th1
   1.529 +    and Thm (der2, {maxidx = max2, hyps = hyps2, shyps = shyps2, tpairs = tpairs2,
   1.530 +      prop = prop2, ...}) = th2;
   1.531      fun err msg = raise THM ("transitive: " ^ msg, 0, [th1, th2]);
   1.532    in
   1.533      case (prop1, prop2) of
   1.534        ((eq as Const ("==", Type (_, [T, _]))) $ t1 $ u, Const ("==", _) $ u' $ t2) =>
   1.535          if not (u aconv u') then err "middle term"
   1.536          else
   1.537 -          Thm {thy_ref = merge_thys2 th1 th2,
   1.538 -            der = Deriv.rule2 (Pt.transitive u T) der1 der2,
   1.539 +          Thm (deriv_rule2 (Pt.transitive u T) der1 der2,
   1.540 +           {thy_ref = merge_thys2 th1 th2,
   1.541              tags = [],
   1.542              maxidx = Int.max (max1, max2),
   1.543              shyps = Sorts.union shyps1 shyps2,
   1.544              hyps = union_hyps hyps1 hyps2,
   1.545              tpairs = union_tpairs tpairs1 tpairs2,
   1.546 -            prop = eq $ t1 $ t2}
   1.547 +            prop = eq $ t1 $ t2})
   1.548       | _ =>  err "premises"
   1.549    end;
   1.550  
   1.551 @@ -761,35 +813,35 @@
   1.552        (case t of Abs (_, _, bodt) $ u => subst_bound (u, bodt)
   1.553        | _ => raise THM ("beta_conversion: not a redex", 0, []));
   1.554    in
   1.555 -    Thm {thy_ref = thy_ref,
   1.556 -      der = Deriv.rule0 Pt.reflexive,
   1.557 +    Thm (deriv_rule0 Pt.reflexive,
   1.558 +     {thy_ref = thy_ref,
   1.559        tags = [],
   1.560        maxidx = maxidx,
   1.561        shyps = sorts,
   1.562        hyps = [],
   1.563        tpairs = [],
   1.564 -      prop = Logic.mk_equals (t, t')}
   1.565 +      prop = Logic.mk_equals (t, t')})
   1.566    end;
   1.567  
   1.568  fun eta_conversion (Cterm {thy_ref, t, T, maxidx, sorts}) =
   1.569 -  Thm {thy_ref = thy_ref,
   1.570 -    der = Deriv.rule0 Pt.reflexive,
   1.571 +  Thm (deriv_rule0 Pt.reflexive,
   1.572 +   {thy_ref = thy_ref,
   1.573      tags = [],
   1.574      maxidx = maxidx,
   1.575      shyps = sorts,
   1.576      hyps = [],
   1.577      tpairs = [],
   1.578 -    prop = Logic.mk_equals (t, Envir.eta_contract t)};
   1.579 +    prop = Logic.mk_equals (t, Envir.eta_contract t)});
   1.580  
   1.581  fun eta_long_conversion (Cterm {thy_ref, t, T, maxidx, sorts}) =
   1.582 -  Thm {thy_ref = thy_ref,
   1.583 -    der = Deriv.rule0 Pt.reflexive,
   1.584 +  Thm (deriv_rule0 Pt.reflexive,
   1.585 +   {thy_ref = thy_ref,
   1.586      tags = [],
   1.587      maxidx = maxidx,
   1.588      shyps = sorts,
   1.589      hyps = [],
   1.590      tpairs = [],
   1.591 -    prop = Logic.mk_equals (t, Pattern.eta_long [] t)};
   1.592 +    prop = Logic.mk_equals (t, Pattern.eta_long [] t)});
   1.593  
   1.594  (*The abstraction rule.  The Free or Var x must not be free in the hypotheses.
   1.595    The bound variable will be named "a" (since x will be something like x320)
   1.596 @@ -799,20 +851,20 @@
   1.597  *)
   1.598  fun abstract_rule a
   1.599      (Cterm {t = x, T, sorts, ...})
   1.600 -    (th as Thm {thy_ref, der, maxidx, hyps, shyps, tpairs, prop, ...}) =
   1.601 +    (th as Thm (der, {thy_ref, maxidx, hyps, shyps, tpairs, prop, ...})) =
   1.602    let
   1.603      val (t, u) = Logic.dest_equals prop
   1.604        handle TERM _ => raise THM ("abstract_rule: premise not an equality", 0, [th]);
   1.605      val result =
   1.606 -      Thm {thy_ref = thy_ref,
   1.607 -        der = Deriv.rule1 (Pt.abstract_rule x a) der,
   1.608 +      Thm (deriv_rule1 (Pt.abstract_rule x a) der,
   1.609 +       {thy_ref = thy_ref,
   1.610          tags = [],
   1.611          maxidx = maxidx,
   1.612          shyps = Sorts.union sorts shyps,
   1.613          hyps = hyps,
   1.614          tpairs = tpairs,
   1.615          prop = Logic.mk_equals
   1.616 -          (Abs (a, T, abstract_over (x, t)), Abs (a, T, abstract_over (x, u)))};
   1.617 +          (Abs (a, T, abstract_over (x, t)), Abs (a, T, abstract_over (x, u)))});
   1.618      fun check_occs a x ts =
   1.619        if exists (fn t => Logic.occs (x, t)) ts then
   1.620          raise THM ("abstract_rule: variable " ^ quote a ^ " free in assumptions", 0, [th])
   1.621 @@ -831,10 +883,10 @@
   1.622  *)
   1.623  fun combination th1 th2 =
   1.624    let
   1.625 -    val Thm {der = der1, maxidx = max1, shyps = shyps1, hyps = hyps1, tpairs = tpairs1,
   1.626 -      prop = prop1, ...} = th1
   1.627 -    and Thm {der = der2, maxidx = max2, shyps = shyps2, hyps = hyps2, tpairs = tpairs2,
   1.628 -      prop = prop2, ...} = th2;
   1.629 +    val Thm (der1, {maxidx = max1, shyps = shyps1, hyps = hyps1, tpairs = tpairs1,
   1.630 +      prop = prop1, ...}) = th1
   1.631 +    and Thm (der2, {maxidx = max2, shyps = shyps2, hyps = hyps2, tpairs = tpairs2,
   1.632 +      prop = prop2, ...}) = th2;
   1.633      fun chktypes fT tT =
   1.634        (case fT of
   1.635          Type ("fun", [T1, T2]) =>
   1.636 @@ -847,14 +899,14 @@
   1.637        (Const ("==", Type ("fun", [fT, _])) $ f $ g,
   1.638         Const ("==", Type ("fun", [tT, _])) $ t $ u) =>
   1.639          (chktypes fT tT;
   1.640 -          Thm {thy_ref = merge_thys2 th1 th2,
   1.641 -            der = Deriv.rule2 (Pt.combination f g t u fT) der1 der2,
   1.642 +          Thm (deriv_rule2 (Pt.combination f g t u fT) der1 der2,
   1.643 +           {thy_ref = merge_thys2 th1 th2,
   1.644              tags = [],
   1.645              maxidx = Int.max (max1, max2),
   1.646              shyps = Sorts.union shyps1 shyps2,
   1.647              hyps = union_hyps hyps1 hyps2,
   1.648              tpairs = union_tpairs tpairs1 tpairs2,
   1.649 -            prop = Logic.mk_equals (f $ t, g $ u)})
   1.650 +            prop = Logic.mk_equals (f $ t, g $ u)}))
   1.651       | _ => raise THM ("combination: premises", 0, [th1, th2])
   1.652    end;
   1.653  
   1.654 @@ -865,23 +917,23 @@
   1.655  *)
   1.656  fun equal_intr th1 th2 =
   1.657    let
   1.658 -    val Thm {der = der1, maxidx = max1, shyps = shyps1, hyps = hyps1, tpairs = tpairs1,
   1.659 -      prop = prop1, ...} = th1
   1.660 -    and Thm {der = der2, maxidx = max2, shyps = shyps2, hyps = hyps2, tpairs = tpairs2,
   1.661 -      prop = prop2, ...} = th2;
   1.662 +    val Thm (der1, {maxidx = max1, shyps = shyps1, hyps = hyps1, tpairs = tpairs1,
   1.663 +      prop = prop1, ...}) = th1
   1.664 +    and Thm (der2, {maxidx = max2, shyps = shyps2, hyps = hyps2, tpairs = tpairs2,
   1.665 +      prop = prop2, ...}) = th2;
   1.666      fun err msg = raise THM ("equal_intr: " ^ msg, 0, [th1, th2]);
   1.667    in
   1.668      case (prop1, prop2) of
   1.669        (Const("==>", _) $ A $ B, Const("==>", _) $ B' $ A') =>
   1.670          if A aconv A' andalso B aconv B' then
   1.671 -          Thm {thy_ref = merge_thys2 th1 th2,
   1.672 -            der = Deriv.rule2 (Pt.equal_intr A B) der1 der2,
   1.673 +          Thm (deriv_rule2 (Pt.equal_intr A B) der1 der2,
   1.674 +           {thy_ref = merge_thys2 th1 th2,
   1.675              tags = [],
   1.676              maxidx = Int.max (max1, max2),
   1.677              shyps = Sorts.union shyps1 shyps2,
   1.678              hyps = union_hyps hyps1 hyps2,
   1.679              tpairs = union_tpairs tpairs1 tpairs2,
   1.680 -            prop = Logic.mk_equals (A, B)}
   1.681 +            prop = Logic.mk_equals (A, B)})
   1.682          else err "not equal"
   1.683      | _ =>  err "premises"
   1.684    end;
   1.685 @@ -893,23 +945,23 @@
   1.686  *)
   1.687  fun equal_elim th1 th2 =
   1.688    let
   1.689 -    val Thm {der = der1, maxidx = max1, shyps = shyps1, hyps = hyps1,
   1.690 -      tpairs = tpairs1, prop = prop1, ...} = th1
   1.691 -    and Thm {der = der2, maxidx = max2, shyps = shyps2, hyps = hyps2,
   1.692 -      tpairs = tpairs2, prop = prop2, ...} = th2;
   1.693 +    val Thm (der1, {maxidx = max1, shyps = shyps1, hyps = hyps1,
   1.694 +      tpairs = tpairs1, prop = prop1, ...}) = th1
   1.695 +    and Thm (der2, {maxidx = max2, shyps = shyps2, hyps = hyps2,
   1.696 +      tpairs = tpairs2, prop = prop2, ...}) = th2;
   1.697      fun err msg = raise THM ("equal_elim: " ^ msg, 0, [th1, th2]);
   1.698    in
   1.699      case prop1 of
   1.700        Const ("==", _) $ A $ B =>
   1.701          if prop2 aconv A then
   1.702 -          Thm {thy_ref = merge_thys2 th1 th2,
   1.703 -            der = Deriv.rule2 (Pt.equal_elim A B) der1 der2,
   1.704 +          Thm (deriv_rule2 (Pt.equal_elim A B) der1 der2,
   1.705 +           {thy_ref = merge_thys2 th1 th2,
   1.706              tags = [],
   1.707              maxidx = Int.max (max1, max2),
   1.708              shyps = Sorts.union shyps1 shyps2,
   1.709              hyps = union_hyps hyps1 hyps2,
   1.710              tpairs = union_tpairs tpairs1 tpairs2,
   1.711 -            prop = B}
   1.712 +            prop = B})
   1.713          else err "not equal"
   1.714       | _ =>  err"major premise"
   1.715    end;
   1.716 @@ -922,7 +974,7 @@
   1.717    Instantiates the theorem and deletes trivial tpairs.  Resulting
   1.718    sequence may contain multiple elements if the tpairs are not all
   1.719    flex-flex.*)
   1.720 -fun flexflex_rule (th as Thm {thy_ref, der, maxidx, shyps, hyps, tpairs, prop, ...}) =
   1.721 +fun flexflex_rule (th as Thm (der, {thy_ref, maxidx, shyps, hyps, tpairs, prop, ...})) =
   1.722    let val thy = Theory.deref thy_ref in
   1.723      Unify.smash_unifiers thy tpairs (Envir.empty maxidx)
   1.724      |> Seq.map (fn env =>
   1.725 @@ -932,13 +984,13 @@
   1.726              val tpairs' = tpairs |> map (pairself (Envir.norm_term env))
   1.727                (*remove trivial tpairs, of the form t==t*)
   1.728                |> filter_out (op aconv);
   1.729 -            val der = Deriv.rule1 (Pt.norm_proof' env) der;
   1.730 +            val der' = deriv_rule1 (Pt.norm_proof' env) der;
   1.731              val prop' = Envir.norm_term env prop;
   1.732              val maxidx = maxidx_tpairs tpairs' (maxidx_of_term prop');
   1.733              val shyps = Envir.insert_sorts env shyps;
   1.734            in
   1.735 -            Thm {thy_ref = Theory.check_thy thy, der = der, tags = [], maxidx = maxidx,
   1.736 -              shyps = shyps, hyps = hyps, tpairs = tpairs', prop = prop'}
   1.737 +            Thm (der', {thy_ref = Theory.check_thy thy, tags = [], maxidx = maxidx,
   1.738 +              shyps = shyps, hyps = hyps, tpairs = tpairs', prop = prop'})
   1.739            end)
   1.740    end;
   1.741  
   1.742 @@ -952,7 +1004,7 @@
   1.743  fun generalize ([], []) _ th = th
   1.744    | generalize (tfrees, frees) idx th =
   1.745        let
   1.746 -        val Thm {thy_ref, der, maxidx, shyps, hyps, tpairs, prop, ...} = th;
   1.747 +        val Thm (der, {thy_ref, maxidx, shyps, hyps, tpairs, prop, ...}) = th;
   1.748          val _ = idx <= maxidx andalso raise THM ("generalize: bad index", idx, [th]);
   1.749  
   1.750          val bad_type = if null tfrees then K false else
   1.751 @@ -971,15 +1023,14 @@
   1.752          val tpairs' = map (pairself gen) tpairs;
   1.753          val maxidx' = maxidx_tpairs tpairs' (maxidx_of_term prop');
   1.754        in
   1.755 -        Thm {
   1.756 -          thy_ref = thy_ref,
   1.757 -          der = Deriv.rule1 (Pt.generalize (tfrees, frees) idx) der,
   1.758 +        Thm (deriv_rule1 (Pt.generalize (tfrees, frees) idx) der,
   1.759 +         {thy_ref = thy_ref,
   1.760            tags = [],
   1.761            maxidx = maxidx',
   1.762            shyps = shyps,
   1.763            hyps = hyps,
   1.764            tpairs = tpairs',
   1.765 -          prop = prop'}
   1.766 +          prop = prop'})
   1.767        end;
   1.768  
   1.769  
   1.770 @@ -1035,7 +1086,7 @@
   1.771  fun instantiate ([], []) th = th
   1.772    | instantiate (instT, inst) th =
   1.773        let
   1.774 -        val Thm {thy_ref, der, hyps, shyps, tpairs, prop, ...} = th;
   1.775 +        val Thm (der, {thy_ref, hyps, shyps, tpairs, prop, ...}) = th;
   1.776          val (inst', (instT', (thy_ref', shyps'))) =
   1.777            (thy_ref, shyps) |> fold_map add_inst inst ||> fold_map add_instT instT;
   1.778          val subst = TermSubst.instantiate_maxidx (instT', inst');
   1.779 @@ -1043,15 +1094,14 @@
   1.780          val (tpairs', maxidx') =
   1.781            fold_map (fn (t, u) => fn i => subst t i ||>> subst u) tpairs maxidx1;
   1.782        in
   1.783 -        Thm {thy_ref = thy_ref',
   1.784 -          der = Deriv.rule1 (fn d =>
   1.785 -            Pt.instantiate (map (apsnd #1) instT', map (apsnd #1) inst') d) der,
   1.786 +        Thm (deriv_rule1 (fn d => Pt.instantiate (map (apsnd #1) instT', map (apsnd #1) inst') d) der,
   1.787 +         {thy_ref = thy_ref',
   1.788            tags = [],
   1.789            maxidx = maxidx',
   1.790            shyps = shyps',
   1.791            hyps = hyps,
   1.792            tpairs = tpairs',
   1.793 -          prop = prop'}
   1.794 +          prop = prop'})
   1.795        end
   1.796        handle TYPE (msg, _, _) => raise THM (msg, 0, [th]);
   1.797  
   1.798 @@ -1077,14 +1127,14 @@
   1.799    if T <> propT then
   1.800      raise THM ("trivial: the term must have type prop", 0, [])
   1.801    else
   1.802 -    Thm {thy_ref = thy_ref,
   1.803 -      der = Deriv.rule0 (Pt.AbsP ("H", NONE, Pt.PBound 0)),
   1.804 +    Thm (deriv_rule0 (Pt.AbsP ("H", NONE, Pt.PBound 0)),
   1.805 +     {thy_ref = thy_ref,
   1.806        tags = [],
   1.807        maxidx = maxidx,
   1.808        shyps = sorts,
   1.809        hyps = [],
   1.810        tpairs = [],
   1.811 -      prop = Logic.mk_implies (A, A)};
   1.812 +      prop = Logic.mk_implies (A, A)});
   1.813  
   1.814  (*Axiom-scheme reflecting signature contents: "OFCLASS(?'a::c, c_class)" *)
   1.815  fun class_triv thy c =
   1.816 @@ -1092,16 +1142,16 @@
   1.817      val Cterm {t, maxidx, sorts, ...} =
   1.818        cterm_of thy (Logic.mk_inclass (TVar ((Name.aT, 0), [c]), Sign.certify_class thy c))
   1.819          handle TERM (msg, _) => raise THM ("class_triv: " ^ msg, 0, []);
   1.820 -    val der = Deriv.rule0 (Pt.PAxm ("Pure.class_triv:" ^ c, t, SOME []));
   1.821 +    val der = deriv_rule0 (Pt.PAxm ("Pure.class_triv:" ^ c, t, SOME []));
   1.822    in
   1.823 -    Thm {thy_ref = Theory.check_thy thy, der = der, tags = [], maxidx = maxidx,
   1.824 -      shyps = sorts, hyps = [], tpairs = [], prop = t}
   1.825 +    Thm (der, {thy_ref = Theory.check_thy thy, tags = [], maxidx = maxidx,
   1.826 +      shyps = sorts, hyps = [], tpairs = [], prop = t})
   1.827    end;
   1.828  
   1.829  (*Internalize sort constraints of type variable*)
   1.830  fun unconstrainT
   1.831      (Ctyp {thy_ref = thy_ref1, T, ...})
   1.832 -    (th as Thm {thy_ref = thy_ref2, der, maxidx, shyps, hyps, tpairs, prop, ...}) =
   1.833 +    (th as Thm (_, {thy_ref = thy_ref2, maxidx, shyps, hyps, tpairs, prop, ...})) =
   1.834    let
   1.835      val ((x, i), S) = Term.dest_TVar T handle TYPE _ =>
   1.836        raise THM ("unconstrainT: not a type variable", 0, [th]);
   1.837 @@ -1109,58 +1159,58 @@
   1.838      val unconstrain = Term.map_types (Term.map_atyps (fn U => if U = T then T' else U));
   1.839      val constraints = map (curry Logic.mk_inclass T') S;
   1.840    in
   1.841 -    Thm {thy_ref = Theory.merge_refs (thy_ref1, thy_ref2),
   1.842 -      der = Deriv.rule0 (Pt.PAxm ("Pure.unconstrainT", prop, SOME [])),
   1.843 +    Thm (deriv_rule0 (Pt.PAxm ("Pure.unconstrainT", prop, SOME [])),
   1.844 +     {thy_ref = Theory.merge_refs (thy_ref1, thy_ref2),
   1.845        tags = [],
   1.846        maxidx = Int.max (maxidx, i),
   1.847        shyps = Sorts.remove_sort S shyps,
   1.848        hyps = hyps,
   1.849        tpairs = map (pairself unconstrain) tpairs,
   1.850 -      prop = Logic.list_implies (constraints, unconstrain prop)}
   1.851 +      prop = Logic.list_implies (constraints, unconstrain prop)})
   1.852    end;
   1.853  
   1.854  (* Replace all TFrees not fixed or in the hyps by new TVars *)
   1.855 -fun varifyT' fixed (Thm {thy_ref, der, maxidx, shyps, hyps, tpairs, prop, ...}) =
   1.856 +fun varifyT' fixed (Thm (der, {thy_ref, maxidx, shyps, hyps, tpairs, prop, ...})) =
   1.857    let
   1.858      val tfrees = List.foldr add_term_tfrees fixed hyps;
   1.859      val prop1 = attach_tpairs tpairs prop;
   1.860      val (al, prop2) = Type.varify tfrees prop1;
   1.861      val (ts, prop3) = Logic.strip_prems (length tpairs, [], prop2);
   1.862    in
   1.863 -    (al, Thm {thy_ref = thy_ref,
   1.864 -      der = Deriv.rule1 (Pt.varify_proof prop tfrees) der,
   1.865 +    (al, Thm (deriv_rule1 (Pt.varify_proof prop tfrees) der,
   1.866 +     {thy_ref = thy_ref,
   1.867        tags = [],
   1.868        maxidx = Int.max (0, maxidx),
   1.869        shyps = shyps,
   1.870        hyps = hyps,
   1.871        tpairs = rev (map Logic.dest_equals ts),
   1.872 +      prop = prop3}))
   1.873 +  end;
   1.874 +
   1.875 +val varifyT = #2 o varifyT' [];
   1.876 +
   1.877 +(* Replace all TVars by new TFrees *)
   1.878 +fun freezeT (Thm (der, {thy_ref, maxidx, shyps, hyps, tpairs, prop, ...})) =
   1.879 +  let
   1.880 +    val prop1 = attach_tpairs tpairs prop;
   1.881 +    val prop2 = Type.freeze prop1;
   1.882 +    val (ts, prop3) = Logic.strip_prems (length tpairs, [], prop2);
   1.883 +  in
   1.884 +    Thm (deriv_rule1 (Pt.freezeT prop1) der,
   1.885 +     {thy_ref = thy_ref,
   1.886 +      tags = [],
   1.887 +      maxidx = maxidx_of_term prop2,
   1.888 +      shyps = shyps,
   1.889 +      hyps = hyps,
   1.890 +      tpairs = rev (map Logic.dest_equals ts),
   1.891        prop = prop3})
   1.892    end;
   1.893  
   1.894 -val varifyT = #2 o varifyT' [];
   1.895 -
   1.896 -(* Replace all TVars by new TFrees *)
   1.897 -fun freezeT (Thm {thy_ref, der, maxidx, shyps, hyps, tpairs, prop, ...}) =
   1.898 -  let
   1.899 -    val prop1 = attach_tpairs tpairs prop;
   1.900 -    val prop2 = Type.freeze prop1;
   1.901 -    val (ts, prop3) = Logic.strip_prems (length tpairs, [], prop2);
   1.902 -  in
   1.903 -    Thm {thy_ref = thy_ref,
   1.904 -      der = Deriv.rule1 (Pt.freezeT prop1) der,
   1.905 -      tags = [],
   1.906 -      maxidx = maxidx_of_term prop2,
   1.907 -      shyps = shyps,
   1.908 -      hyps = hyps,
   1.909 -      tpairs = rev (map Logic.dest_equals ts),
   1.910 -      prop = prop3}
   1.911 -  end;
   1.912 -
   1.913  
   1.914  (*** Inference rules for tactics ***)
   1.915  
   1.916  (*Destruct proof state into constraints, other goals, goal(i), rest *)
   1.917 -fun dest_state (state as Thm{prop,tpairs,...}, i) =
   1.918 +fun dest_state (state as Thm (_, {prop,tpairs,...}), i) =
   1.919    (case  Logic.strip_prems(i, [], prop) of
   1.920        (B::rBs, C) => (tpairs, rev rBs, B, C)
   1.921      | _ => raise THM("dest_state", i, [state]))
   1.922 @@ -1174,46 +1224,45 @@
   1.923      val inc = gmax + 1;
   1.924      val lift_abs = Logic.lift_abs inc gprop;
   1.925      val lift_all = Logic.lift_all inc gprop;
   1.926 -    val Thm {der, maxidx, shyps, hyps, tpairs, prop, ...} = orule;
   1.927 +    val Thm (der, {maxidx, shyps, hyps, tpairs, prop, ...}) = orule;
   1.928      val (As, B) = Logic.strip_horn prop;
   1.929    in
   1.930      if T <> propT then raise THM ("lift_rule: the term must have type prop", 0, [])
   1.931      else
   1.932 -      Thm {thy_ref = merge_thys1 goal orule,
   1.933 -        der = Deriv.rule1 (Pt.lift_proof gprop inc prop) der,
   1.934 +      Thm (deriv_rule1 (Pt.lift_proof gprop inc prop) der,
   1.935 +       {thy_ref = merge_thys1 goal orule,
   1.936          tags = [],
   1.937          maxidx = maxidx + inc,
   1.938          shyps = Sorts.union shyps sorts,  (*sic!*)
   1.939          hyps = hyps,
   1.940          tpairs = map (pairself lift_abs) tpairs,
   1.941 -        prop = Logic.list_implies (map lift_all As, lift_all B)}
   1.942 +        prop = Logic.list_implies (map lift_all As, lift_all B)})
   1.943    end;
   1.944  
   1.945 -fun incr_indexes i (thm as Thm {thy_ref, der, maxidx, shyps, hyps, tpairs, prop, ...}) =
   1.946 +fun incr_indexes i (thm as Thm (der, {thy_ref, maxidx, shyps, hyps, tpairs, prop, ...})) =
   1.947    if i < 0 then raise THM ("negative increment", 0, [thm])
   1.948    else if i = 0 then thm
   1.949    else
   1.950 -    Thm {thy_ref = thy_ref,
   1.951 -      der = Deriv.rule1 (Pt.map_proof_terms (Logic.incr_indexes ([], i)) (Logic.incr_tvar i)) der,
   1.952 +    Thm (deriv_rule1 (Pt.map_proof_terms (Logic.incr_indexes ([], i)) (Logic.incr_tvar i)) der,
   1.953 +     {thy_ref = thy_ref,
   1.954        tags = [],
   1.955        maxidx = maxidx + i,
   1.956        shyps = shyps,
   1.957        hyps = hyps,
   1.958        tpairs = map (pairself (Logic.incr_indexes ([], i))) tpairs,
   1.959 -      prop = Logic.incr_indexes ([], i) prop};
   1.960 +      prop = Logic.incr_indexes ([], i) prop});
   1.961  
   1.962  (*Solve subgoal Bi of proof state B1...Bn/C by assumption. *)
   1.963  fun assumption i state =
   1.964    let
   1.965 -    val Thm {thy_ref, der, maxidx, shyps, hyps, prop, ...} = state;
   1.966 +    val Thm (der, {thy_ref, maxidx, shyps, hyps, prop, ...}) = state;
   1.967      val thy = Theory.deref thy_ref;
   1.968      val (tpairs, Bs, Bi, C) = dest_state (state, i);
   1.969      fun newth n (env as Envir.Envir {maxidx, ...}, tpairs) =
   1.970 -      Thm {
   1.971 -        der = Deriv.rule1
   1.972 +      Thm (deriv_rule1
   1.973            ((if Envir.is_empty env then I else (Pt.norm_proof' env)) o
   1.974              Pt.assumption_proof Bs Bi n) der,
   1.975 -        tags = [],
   1.976 +       {tags = [],
   1.977          maxidx = maxidx,
   1.978          shyps = Envir.insert_sorts env shyps,
   1.979          hyps = hyps,
   1.980 @@ -1225,7 +1274,7 @@
   1.981              Logic.list_implies (Bs, C)
   1.982            else (*normalize the new rule fully*)
   1.983              Envir.norm_term env (Logic.list_implies (Bs, C)),
   1.984 -        thy_ref = Theory.check_thy thy};
   1.985 +        thy_ref = Theory.check_thy thy});
   1.986      fun addprfs [] _ = Seq.empty
   1.987        | addprfs ((t, u) :: apairs) n = Seq.make (fn () => Seq.pull
   1.988            (Seq.mapp (newth n)
   1.989 @@ -1237,27 +1286,27 @@
   1.990    Checks if Bi's conclusion is alpha-convertible to one of its assumptions*)
   1.991  fun eq_assumption i state =
   1.992    let
   1.993 -    val Thm {thy_ref, der, maxidx, shyps, hyps, prop, ...} = state;
   1.994 +    val Thm (der, {thy_ref, maxidx, shyps, hyps, prop, ...}) = state;
   1.995      val (tpairs, Bs, Bi, C) = dest_state (state, i);
   1.996    in
   1.997      (case find_index Pattern.aeconv (Logic.assum_pairs (~1, Bi)) of
   1.998        ~1 => raise THM ("eq_assumption", 0, [state])
   1.999      | n =>
  1.1000 -        Thm {thy_ref = thy_ref,
  1.1001 -          der = Deriv.rule1 (Pt.assumption_proof Bs Bi (n + 1)) der,
  1.1002 +        Thm (deriv_rule1 (Pt.assumption_proof Bs Bi (n + 1)) der,
  1.1003 +         {thy_ref = thy_ref,
  1.1004            tags = [],
  1.1005            maxidx = maxidx,
  1.1006            shyps = shyps,
  1.1007            hyps = hyps,
  1.1008            tpairs = tpairs,
  1.1009 -          prop = Logic.list_implies (Bs, C)})
  1.1010 +          prop = Logic.list_implies (Bs, C)}))
  1.1011    end;
  1.1012  
  1.1013  
  1.1014  (*For rotate_tac: fast rotation of assumptions of subgoal i*)
  1.1015  fun rotate_rule k i state =
  1.1016    let
  1.1017 -    val Thm {thy_ref, der, maxidx, shyps, hyps, prop, ...} = state;
  1.1018 +    val Thm (der, {thy_ref, maxidx, shyps, hyps, prop, ...}) = state;
  1.1019      val (tpairs, Bs, Bi, C) = dest_state (state, i);
  1.1020      val params = Term.strip_all_vars Bi
  1.1021      and rest   = Term.strip_all_body Bi;
  1.1022 @@ -1272,14 +1321,14 @@
  1.1023          in list_all (params, Logic.list_implies (qs @ ps, concl)) end
  1.1024        else raise THM ("rotate_rule", k, [state]);
  1.1025    in
  1.1026 -    Thm {thy_ref = thy_ref,
  1.1027 -      der = Deriv.rule1 (Pt.rotate_proof Bs Bi m) der,
  1.1028 +    Thm (deriv_rule1 (Pt.rotate_proof Bs Bi m) der,
  1.1029 +     {thy_ref = thy_ref,
  1.1030        tags = [],
  1.1031        maxidx = maxidx,
  1.1032        shyps = shyps,
  1.1033        hyps = hyps,
  1.1034        tpairs = tpairs,
  1.1035 -      prop = Logic.list_implies (Bs @ [Bi'], C)}
  1.1036 +      prop = Logic.list_implies (Bs @ [Bi'], C)})
  1.1037    end;
  1.1038  
  1.1039  
  1.1040 @@ -1288,7 +1337,7 @@
  1.1041    number of premises.  Useful with etac and underlies defer_tac*)
  1.1042  fun permute_prems j k rl =
  1.1043    let
  1.1044 -    val Thm {thy_ref, der, maxidx, shyps, hyps, tpairs, prop, ...} = rl;
  1.1045 +    val Thm (der, {thy_ref, maxidx, shyps, hyps, tpairs, prop, ...}) = rl;
  1.1046      val prems = Logic.strip_imp_prems prop
  1.1047      and concl = Logic.strip_imp_concl prop;
  1.1048      val moved_prems = List.drop (prems, j)
  1.1049 @@ -1303,14 +1352,14 @@
  1.1050          in Logic.list_implies (fixed_prems @ qs @ ps, concl) end
  1.1051        else raise THM ("permute_prems: k", k, [rl]);
  1.1052    in
  1.1053 -    Thm {thy_ref = thy_ref,
  1.1054 -      der = Deriv.rule1 (Pt.permute_prems_prf prems j m) der,
  1.1055 +    Thm (deriv_rule1 (Pt.permute_prems_prf prems j m) der,
  1.1056 +     {thy_ref = thy_ref,
  1.1057        tags = [],
  1.1058        maxidx = maxidx,
  1.1059        shyps = shyps,
  1.1060        hyps = hyps,
  1.1061        tpairs = tpairs,
  1.1062 -      prop = prop'}
  1.1063 +      prop = prop'})
  1.1064    end;
  1.1065  
  1.1066  
  1.1067 @@ -1322,7 +1371,7 @@
  1.1068    preceding parameters may be renamed to make all params distinct.*)
  1.1069  fun rename_params_rule (cs, i) state =
  1.1070    let
  1.1071 -    val Thm {thy_ref, der, tags, maxidx, shyps, hyps, ...} = state;
  1.1072 +    val Thm (der, {thy_ref, tags, maxidx, shyps, hyps, ...}) = state;
  1.1073      val (tpairs, Bs, Bi, C) = dest_state (state, i);
  1.1074      val iparams = map #1 (Logic.strip_params Bi);
  1.1075      val short = length iparams - length cs;
  1.1076 @@ -1338,31 +1387,30 @@
  1.1077        (case cs inter_string freenames of
  1.1078          a :: _ => (warning ("Can't rename.  Bound/Free variable clash: " ^ a); state)
  1.1079        | [] =>
  1.1080 -        Thm {thy_ref = thy_ref,
  1.1081 -          der = der,
  1.1082 +        Thm (der,
  1.1083 +         {thy_ref = thy_ref,
  1.1084            tags = tags,
  1.1085            maxidx = maxidx,
  1.1086            shyps = shyps,
  1.1087            hyps = hyps,
  1.1088            tpairs = tpairs,
  1.1089 -          prop = Logic.list_implies (Bs @ [newBi], C)}))
  1.1090 +          prop = Logic.list_implies (Bs @ [newBi], C)})))
  1.1091    end;
  1.1092  
  1.1093  
  1.1094  (*** Preservation of bound variable names ***)
  1.1095  
  1.1096 -fun rename_boundvars pat obj (thm as Thm {thy_ref, der, tags, maxidx, shyps, hyps, tpairs, prop}) =
  1.1097 +fun rename_boundvars pat obj (thm as Thm (der, {thy_ref, tags, maxidx, shyps, hyps, tpairs, prop})) =
  1.1098    (case Term.rename_abs pat obj prop of
  1.1099      NONE => thm
  1.1100 -  | SOME prop' => Thm
  1.1101 +  | SOME prop' => Thm (der,
  1.1102        {thy_ref = thy_ref,
  1.1103 -       der = der,
  1.1104         tags = tags,
  1.1105         maxidx = maxidx,
  1.1106         hyps = hyps,
  1.1107         shyps = shyps,
  1.1108         tpairs = tpairs,
  1.1109 -       prop = prop'});
  1.1110 +       prop = prop'}));
  1.1111  
  1.1112  
  1.1113  (* strip_apply f (A, B) strips off all assumptions/parameters from A
  1.1114 @@ -1445,9 +1493,9 @@
  1.1115  in
  1.1116  fun bicompose_aux flatten match (state, (stpairs, Bs, Bi, C), lifted)
  1.1117                          (eres_flg, orule, nsubgoal) =
  1.1118 - let val Thm{der=sder, maxidx=smax, shyps=sshyps, hyps=shyps, ...} = state
  1.1119 -     and Thm{der=rder, maxidx=rmax, shyps=rshyps, hyps=rhyps,
  1.1120 -             tpairs=rtpairs, prop=rprop,...} = orule
  1.1121 + let val Thm (sder, {maxidx=smax, shyps=sshyps, hyps=shyps, ...}) = state
  1.1122 +     and Thm (rder, {maxidx=rmax, shyps=rshyps, hyps=rhyps,
  1.1123 +             tpairs=rtpairs, prop=rprop,...}) = orule
  1.1124           (*How many hyps to skip over during normalization*)
  1.1125       and nlift = Logic.count_prems (strip_all_body Bi) + (if eres_flg then ~1 else 0)
  1.1126       val thy = Theory.deref (merge_thys2 state orule);
  1.1127 @@ -1469,20 +1517,20 @@
  1.1128                    (ntps, (map normt (Bs @ As), normt C))
  1.1129               end
  1.1130             val th =
  1.1131 -             Thm{der = Deriv.rule2
  1.1132 +             Thm (deriv_rule2
  1.1133                     ((if Envir.is_empty env then I
  1.1134                       else if Envir.above env smax then
  1.1135                         (fn f => fn der => f (Pt.norm_proof' env der))
  1.1136                       else
  1.1137                         curry op oo (Pt.norm_proof' env))
  1.1138                      (Pt.bicompose_proof flatten Bs oldAs As A n (nlift+1))) rder' sder,
  1.1139 -                 tags = [],
  1.1140 +                {tags = [],
  1.1141                   maxidx = maxidx,
  1.1142                   shyps = Envir.insert_sorts env (Sorts.union rshyps sshyps),
  1.1143                   hyps = union_hyps rhyps shyps,
  1.1144                   tpairs = ntpairs,
  1.1145                   prop = Logic.list_implies normp,
  1.1146 -                 thy_ref = Theory.check_thy thy}
  1.1147 +                 thy_ref = Theory.check_thy thy})
  1.1148          in  Seq.cons th thq  end  handle COMPOSE => thq;
  1.1149       val (rAs,B) = Logic.strip_prems(nsubgoal, [], rprop)
  1.1150         handle TERM _ => raise THM("bicompose: rule", 0, [orule,state]);
  1.1151 @@ -1491,7 +1539,7 @@
  1.1152         let val (As1, rder') =
  1.1153           if not lifted then (As0, rder)
  1.1154           else (map (rename_bvars(dpairs,tpairs,B)) As0,
  1.1155 -           Deriv.rule1 (Pt.map_proof_terms
  1.1156 +           deriv_rule1 (Pt.map_proof_terms
  1.1157               (rename_bvars (dpairs, tpairs, Bound 0)) I) rder);
  1.1158         in (map (if flatten then (Logic.flatten_params n) else I) As1, As1, rder', n)
  1.1159            handle TERM _ =>
  1.1160 @@ -1555,6 +1603,28 @@
  1.1161      in  Seq.flat (res brules)  end;
  1.1162  
  1.1163  
  1.1164 +
  1.1165 +(*** Promises ***)
  1.1166 +
  1.1167 +fun promise future ct =
  1.1168 +  let
  1.1169 +    val {thy_ref = thy_ref, t = prop, T, maxidx, sorts} = rep_cterm ct;
  1.1170 +    val thy = Context.reject_draft (Theory.deref thy_ref);
  1.1171 +    val _ = T <> propT andalso raise CTERM ("promise: prop expected", [ct]);
  1.1172 +    val i = serial ();
  1.1173 +  in
  1.1174 +    Thm (deriv_promise i thy future prop,
  1.1175 +     {thy_ref = thy_ref,
  1.1176 +      tags = [],
  1.1177 +      maxidx = maxidx,
  1.1178 +      shyps = sorts,
  1.1179 +      hyps = [],
  1.1180 +      tpairs = [],
  1.1181 +      prop = prop})
  1.1182 +  end;
  1.1183 +
  1.1184 +
  1.1185 +
  1.1186  (*** Oracles ***)
  1.1187  
  1.1188  (* oracle rule *)
  1.1189 @@ -1564,14 +1634,14 @@
  1.1190      if T <> propT then
  1.1191        raise THM ("Oracle's result must have type prop: " ^ name, 0, [])
  1.1192      else
  1.1193 -      Thm {thy_ref = Theory.merge_refs (thy_ref1, thy_ref2),
  1.1194 -        der = Deriv.oracle name prop,
  1.1195 +      Thm (deriv_oracle name prop,
  1.1196 +       {thy_ref = Theory.merge_refs (thy_ref1, thy_ref2),
  1.1197          tags = [],
  1.1198          maxidx = maxidx,
  1.1199          shyps = sorts,
  1.1200          hyps = [],
  1.1201          tpairs = [],
  1.1202 -        prop = prop}
  1.1203 +        prop = prop})
  1.1204    end;
  1.1205  
  1.1206  end;