| author | haftmann | 
| Fri, 20 Apr 2007 13:11:47 +0200 | |
| changeset 22751 | 1bfd75c1f232 | 
| parent 22727 | 473c7f67c64f | 
| child 23064 | 6ee131d1a618 | 
| permissions | -rw-r--r-- | 
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 1 | (* Title: Provers/eqsubst.ML | 
| 16434 | 2 | ID: $Id$ | 
| 18598 | 3 | Author: Lucas Dixon, University of Edinburgh, lucas.dixon@ed.ac.uk | 
| 15481 | 4 | |
| 18598 | 5 | A proof method to perform a substiution using an equation. | 
| 6 | *) | |
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 7 | |
| 18591 | 8 | signature EQSUBST = | 
| 15481 | 9 | sig | 
| 19871 | 10 | (* a type abriviation for match information *) | 
| 11 | type match = | |
| 12 | ((indexname * (sort * typ)) list (* type instantiations *) | |
| 13 | * (indexname * (typ * term)) list) (* term instantiations *) | |
| 14 | * (string * typ) list (* fake named type abs env *) | |
| 15 | * (string * typ) list (* type abs env *) | |
| 16 | * term (* outer term *) | |
| 17 | ||
| 18 | type searchinfo = | |
| 19 | theory | |
| 20 | * int (* maxidx *) | |
| 21 | * Zipper.T (* focusterm to search under *) | |
| 22 | ||
| 23 | exception eqsubst_occL_exp of | |
| 24 | string * int list * Thm.thm list * int * Thm.thm | |
| 25 | ||
| 26 | (* low level substitution functions *) | |
| 27 | val apply_subst_in_asm : | |
| 28 | int -> | |
| 29 | Thm.thm -> | |
| 30 | Thm.thm -> | |
| 31 | (Thm.cterm list * int * 'a * Thm.thm) * match -> Thm.thm Seq.seq | |
| 32 | val apply_subst_in_concl : | |
| 33 | int -> | |
| 34 | Thm.thm -> | |
| 35 | Thm.cterm list * Thm.thm -> | |
| 36 | Thm.thm -> match -> Thm.thm Seq.seq | |
| 37 | ||
| 38 | (* matching/unification within zippers *) | |
| 39 | val clean_match_z : | |
| 40 | Context.theory -> Term.term -> Zipper.T -> match option | |
| 41 | val clean_unify_z : | |
| 42 | Context.theory -> int -> Term.term -> Zipper.T -> match Seq.seq | |
| 43 | ||
| 44 | (* skipping things in seq seq's *) | |
| 45 | ||
| 46 | (* skipping non-empty sub-sequences but when we reach the end | |
| 47 | of the seq, remembering how much we have left to skip. *) | |
| 48 | datatype 'a skipseq = SkipMore of int | |
| 49 | | SkipSeq of 'a Seq.seq Seq.seq; | |
| 50 | ||
| 51 | val skip_first_asm_occs_search : | |
| 52 |        ('a -> 'b -> 'c Seq.seq Seq.seq) ->
 | |
| 53 | 'a -> int -> 'b -> 'c skipseq | |
| 54 | val skip_first_occs_search : | |
| 55 |        int -> ('a -> 'b -> 'c Seq.seq Seq.seq) -> 'a -> 'b -> 'c Seq.seq
 | |
| 56 | val skipto_skipseq : int -> 'a Seq.seq Seq.seq -> 'a skipseq | |
| 57 | ||
| 58 | (* tactics *) | |
| 59 | val eqsubst_asm_tac : | |
| 60 | Proof.context -> | |
| 61 | int list -> Thm.thm list -> int -> Thm.thm -> Thm.thm Seq.seq | |
| 62 | val eqsubst_asm_tac' : | |
| 63 | Proof.context -> | |
| 64 | (searchinfo -> int -> Term.term -> match skipseq) -> | |
| 65 | int -> Thm.thm -> int -> Thm.thm -> Thm.thm Seq.seq | |
| 66 | val eqsubst_tac : | |
| 67 | Proof.context -> | |
| 22727 | 68 | int list -> (* list of occurences to rewrite, use [0] for any *) | 
| 69 | Thm.thm list -> int -> Thm.thm -> Thm.thm Seq.seq | |
| 19871 | 70 | val eqsubst_tac' : | 
| 22727 | 71 | Proof.context -> (* proof context *) | 
| 72 | (searchinfo -> Term.term -> match Seq.seq) (* search function *) | |
| 73 | -> Thm.thm (* equation theorem to rewrite with *) | |
| 74 | -> int (* subgoal number in goal theorem *) | |
| 75 | -> Thm.thm (* goal theorem *) | |
| 76 | -> Thm.thm Seq.seq (* rewritten goal theorem *) | |
| 19871 | 77 | |
| 78 | ||
| 79 | val fakefree_badbounds : | |
| 80 | (string * Term.typ) list -> | |
| 81 | Term.term -> | |
| 82 | (string * Term.typ) list * (string * Term.typ) list * Term.term | |
| 83 | ||
| 84 | val mk_foo_match : | |
| 85 | (Term.term -> Term.term) -> | |
| 86 |        ('a * Term.typ) list -> Term.term -> Term.term
 | |
| 87 | ||
| 88 | (* preparing substitution *) | |
| 89 | val prep_meta_eq : Proof.context -> Thm.thm -> Thm.thm list | |
| 90 | val prep_concl_subst : | |
| 91 | int -> Thm.thm -> (Thm.cterm list * Thm.thm) * searchinfo | |
| 92 | val prep_subst_in_asm : | |
| 93 | int -> Thm.thm -> int -> | |
| 94 | (Thm.cterm list * int * int * Thm.thm) * searchinfo | |
| 95 | val prep_subst_in_asms : | |
| 96 | int -> Thm.thm -> | |
| 97 | ((Thm.cterm list * int * int * Thm.thm) * searchinfo) list | |
| 98 | val prep_zipper_match : | |
| 99 | Zipper.T -> Term.term * ((string * Term.typ) list * (string * Term.typ) list * Term.term) | |
| 100 | ||
| 101 | (* search for substitutions *) | |
| 102 | val valid_match_start : Zipper.T -> bool | |
| 103 | val search_lr_all : Zipper.T -> Zipper.T Seq.seq | |
| 104 | val search_lr_valid : (Zipper.T -> bool) -> Zipper.T -> Zipper.T Seq.seq | |
| 105 | val searchf_lr_unify_all : | |
| 106 | searchinfo -> Term.term -> match Seq.seq Seq.seq | |
| 107 | val searchf_lr_unify_valid : | |
| 108 | searchinfo -> Term.term -> match Seq.seq Seq.seq | |
| 109 | ||
| 110 | ||
| 111 | (* syntax tools *) | |
| 112 | val ith_syntax : Args.T list -> int list * Args.T list | |
| 113 | val options_syntax : Args.T list -> bool * Args.T list | |
| 114 | ||
| 115 | (* Isar level hooks *) | |
| 20289 | 116 | val eqsubst_asm_meth : Proof.context -> int list -> Thm.thm list -> Proof.method | 
| 117 | val eqsubst_meth : Proof.context -> int list -> Thm.thm list -> Proof.method | |
| 118 | val subst_meth : Method.src -> Proof.context -> Proof.method | |
| 19871 | 119 | val setup : theory -> theory | 
| 120 | ||
| 15481 | 121 | end; | 
| 122 | ||
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 123 | structure EqSubst | 
| 19871 | 124 | : EQSUBST | 
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 125 | = struct | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 126 | |
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 127 | structure Z = Zipper; | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 128 | |
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 129 | (* changes object "=" to meta "==" which prepares a given rewrite rule *) | 
| 18598 | 130 | fun prep_meta_eq ctxt = | 
| 131 |   let val (_, {mk_rews = {mk, ...}, ...}) = Simplifier.rep_ss (Simplifier.local_simpset_of ctxt)
 | |
| 132 | in mk #> map Drule.zero_var_indexes end; | |
| 133 | ||
| 15481 | 134 | |
| 15915 
b0e8b37642a4
lucas - improved interface to isand.ML and cleaned up clean-unification code, and added some better comments.
 dixon parents: 
15855diff
changeset | 135 | (* a type abriviation for match information *) | 
| 16978 | 136 | type match = | 
| 137 | ((indexname * (sort * typ)) list (* type instantiations *) | |
| 138 | * (indexname * (typ * term)) list) (* term instantiations *) | |
| 139 | * (string * typ) list (* fake named type abs env *) | |
| 140 | * (string * typ) list (* type abs env *) | |
| 141 | * term (* outer term *) | |
| 15550 
806214035275
lucas - added more comments and an extra type to clarify the code.
 dixon parents: 
15538diff
changeset | 142 | |
| 16978 | 143 | type searchinfo = | 
| 18598 | 144 | theory | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 145 | * int (* maxidx *) | 
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 146 | * Zipper.T (* focusterm to search under *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 147 | |
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 148 | |
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 149 | (* skipping non-empty sub-sequences but when we reach the end | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 150 | of the seq, remembering how much we have left to skip. *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 151 | datatype 'a skipseq = SkipMore of int | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 152 | | SkipSeq of 'a Seq.seq Seq.seq; | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 153 | (* given a seqseq, skip the first m non-empty seq's, note deficit *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 154 | fun skipto_skipseq m s = | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 155 | let | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 156 | fun skip_occs n sq = | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 157 | case Seq.pull sq of | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 158 | NONE => SkipMore n | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 159 | | SOME (h,t) => | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 160 | (case Seq.pull h of NONE => skip_occs n t | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 161 | | SOME _ => if n <= 1 then SkipSeq (Seq.cons h t) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 162 | else skip_occs (n - 1) t) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 163 | in (skip_occs m s) end; | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 164 | |
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 165 | (* note: outerterm is the taget with the match replaced by a bound | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 166 | variable : ie: "P lhs" beocmes "%x. P x" | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 167 | insts is the types of instantiations of vars in lhs | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 168 | and typinsts is the type instantiations of types in the lhs | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 169 | Note: Final rule is the rule lifted into the ontext of the | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 170 | taget thm. *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 171 | fun mk_foo_match mkuptermfunc Ts t = | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 172 | let | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 173 | val ty = Term.type_of t | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 174 | val bigtype = (rev (map snd Ts)) ---> ty | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 175 | fun mk_foo 0 t = t | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 176 | | mk_foo i t = mk_foo (i - 1) (t $ (Bound (i - 1))) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 177 | val num_of_bnds = (length Ts) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 178 | (* foo_term = "fooabs y0 ... yn" where y's are local bounds *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 179 | val foo_term = mk_foo num_of_bnds (Bound num_of_bnds) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 180 |     in Abs("fooabs", bigtype, mkuptermfunc foo_term) end;
 | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 181 | |
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 182 | (* T is outer bound vars, n is number of locally bound vars *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 183 | (* THINK: is order of Ts correct...? or reversed? *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 184 | fun fakefree_badbounds Ts t = | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 185 | let val (FakeTs,Ts,newnames) = | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 186 | List.foldr (fn ((n,ty),(FakeTs,Ts,usednames)) => | 
| 20071 
8f3e1ddb50e6
replaced Term.variant(list) by Name.variant(_list);
 wenzelm parents: 
19975diff
changeset | 187 | let val newname = Name.variant usednames n | 
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 188 | in ((RWTools.mk_fake_bound_name newname,ty)::FakeTs, | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 189 | (newname,ty)::Ts, | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 190 | newname::usednames) end) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 191 | ([],[],[]) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 192 | Ts | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 193 | in (FakeTs, Ts, Term.subst_bounds (map Free FakeTs, t)) end; | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 194 | |
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 195 | (* before matching we need to fake the bound vars that are missing an | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 196 | abstraction. In this function we additionally construct the | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 197 | abstraction environment, and an outer context term (with the focus | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 198 | abstracted out) for use in rewriting with RWInst.rw *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 199 | fun prep_zipper_match z = | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 200 | let | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 201 | val t = Z.trm z | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 202 | val c = Z.ctxt z | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 203 | val Ts = Z.C.nty_ctxt c | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 204 | val (FakeTs', Ts', t') = fakefree_badbounds Ts t | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 205 | val absterm = mk_foo_match (Z.C.apply c) Ts' t' | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 206 | in | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 207 | (t', (FakeTs', Ts', absterm)) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 208 | end; | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 209 | |
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 210 | (* Matching and Unification with exception handled *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 211 | fun clean_match thy (a as (pat, t)) = | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 212 | let val (tyenv, tenv) = Pattern.match thy a (Vartab.empty, Vartab.empty) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 213 | in SOME (Vartab.dest tyenv, Vartab.dest tenv) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 214 | end handle Pattern.MATCH => NONE; | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 215 | (* given theory, max var index, pat, tgt; returns Seq of instantiations *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 216 | fun clean_unify sgn ix (a as (pat, tgt)) = | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 217 | let | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 218 | (* type info will be re-derived, maybe this can be cached | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 219 | for efficiency? *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 220 | val pat_ty = Term.type_of pat; | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 221 | val tgt_ty = Term.type_of tgt; | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 222 | (* is it OK to ignore the type instantiation info? | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 223 | or should I be using it? *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 224 | val typs_unify = | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 225 | SOME (Sign.typ_unify sgn (pat_ty, tgt_ty) (Term.Vartab.empty, ix)) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 226 | handle Type.TUNIFY => NONE; | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 227 | in | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 228 | case typs_unify of | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 229 | SOME (typinsttab, ix2) => | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 230 | let | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 231 | (* is it right to throw away the flexes? | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 232 | or should I be using them somehow? *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 233 | fun mk_insts env = | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 234 | (Vartab.dest (Envir.type_env env), | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 235 | Envir.alist_of env); | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 236 |           val initenv = Envir.Envir {asol = Vartab.empty,
 | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 237 | iTs = typinsttab, maxidx = ix2}; | 
| 19861 | 238 | val useq = Unify.smash_unifiers sgn [a] initenv | 
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 239 | handle UnequalLengths => Seq.empty | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 240 | | Term.TERM _ => Seq.empty; | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 241 | fun clean_unify' useq () = | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 242 | (case (Seq.pull useq) of | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 243 | NONE => NONE | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 244 | | SOME (h,t) => SOME (mk_insts h, Seq.make (clean_unify' t))) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 245 | handle UnequalLengths => NONE | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 246 | | Term.TERM _ => NONE; | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 247 | in | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 248 | (Seq.make (clean_unify' useq)) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 249 | end | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 250 | | NONE => Seq.empty | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 251 | end; | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 252 | |
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 253 | (* Matching and Unification for zippers *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 254 | (* Note: Ts is a modified version of the original names of the outer | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 255 | bound variables. New names have been introduced to make sure they are | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 256 | unique w.r.t all names in the term and each other. usednames' is | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 257 | oldnames + new names. *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 258 | fun clean_match_z thy pat z = | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 259 | let val (t, (FakeTs,Ts,absterm)) = prep_zipper_match z in | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 260 | case clean_match thy (pat, t) of | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 261 | NONE => NONE | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 262 | | SOME insts => SOME (insts, FakeTs, Ts, absterm) end; | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 263 | (* ix = max var index *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 264 | fun clean_unify_z sgn ix pat z = | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 265 | let val (t, (FakeTs, Ts,absterm)) = prep_zipper_match z in | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 266 | Seq.map (fn insts => (insts, FakeTs, Ts, absterm)) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 267 | (clean_unify sgn ix (t, pat)) end; | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 268 | |
| 15550 
806214035275
lucas - added more comments and an extra type to clarify the code.
 dixon parents: 
15538diff
changeset | 269 | |
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 270 | (* FOR DEBUGGING... | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 271 | type trace_subst_errT = int (* subgoal *) | 
| 16978 | 272 | * thm (* thm with all goals *) | 
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 273 | * (Thm.cterm list (* certified free var placeholders for vars *) | 
| 16978 | 274 | * thm) (* trivial thm of goal concl *) | 
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 275 | (* possible matches/unifiers *) | 
| 16978 | 276 | * thm (* rule *) | 
| 277 | * (((indexname * typ) list (* type instantiations *) | |
| 278 | * (indexname * term) list ) (* term instantiations *) | |
| 279 | * (string * typ) list (* Type abs env *) | |
| 280 | * term) (* outer term *); | |
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 281 | |
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 282 | val trace_subst_err = (ref NONE : trace_subst_errT option ref); | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 283 | val trace_subst_search = ref false; | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 284 | exception trace_subst_exp of trace_subst_errT; | 
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 285 | *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 286 | |
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 287 | |
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 288 | fun bot_left_leaf_of (l $ r) = bot_left_leaf_of l | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 289 | | bot_left_leaf_of (Abs(s,ty,t)) = bot_left_leaf_of t | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 290 | | bot_left_leaf_of x = x; | 
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 291 | |
| 19975 
ecd684d62808
fix to subst in order to allow subst when head of a term is a bound variable.
 dixon parents: 
19871diff
changeset | 292 | (* Avoid considering replacing terms which have a var at the head as | 
| 
ecd684d62808
fix to subst in order to allow subst when head of a term is a bound variable.
 dixon parents: 
19871diff
changeset | 293 | they always succeed trivially, and uninterestingly. *) | 
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 294 | fun valid_match_start z = | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 295 | (case bot_left_leaf_of (Z.trm z) of | 
| 19975 
ecd684d62808
fix to subst in order to allow subst when head of a term is a bound variable.
 dixon parents: 
19871diff
changeset | 296 | Var _ => false | 
| 
ecd684d62808
fix to subst in order to allow subst when head of a term is a bound variable.
 dixon parents: 
19871diff
changeset | 297 | | _ => true); | 
| 
ecd684d62808
fix to subst in order to allow subst when head of a term is a bound variable.
 dixon parents: 
19871diff
changeset | 298 | |
| 15814 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15550diff
changeset | 299 | (* search from top, left to right, then down *) | 
| 19871 | 300 | val search_lr_all = ZipperSearch.all_bl_ur; | 
| 15481 | 301 | |
| 15814 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15550diff
changeset | 302 | (* search from top, left to right, then down *) | 
| 19871 | 303 | fun search_lr_valid validf = | 
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 304 | let | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 305 | fun sf_valid_td_lr z = | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 306 | let val here = if validf z then [Z.Here z] else [] in | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 307 | case Z.trm z | 
| 19871 | 308 | of _ $ _ => [Z.LookIn (Z.move_down_left z)] | 
| 309 | @ here | |
| 310 | @ [Z.LookIn (Z.move_down_right z)] | |
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 311 | | Abs _ => here @ [Z.LookIn (Z.move_down_abs z)] | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 312 | | _ => here | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 313 | end; | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 314 | in Z.lzy_search sf_valid_td_lr end; | 
| 15814 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15550diff
changeset | 315 | |
| 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15550diff
changeset | 316 | (* search all unifications *) | 
| 19871 | 317 | fun searchf_lr_unify_all (sgn, maxidx, z) lhs = | 
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 318 | Seq.map (clean_unify_z sgn maxidx lhs) | 
| 19871 | 319 | (Z.limit_apply search_lr_all z); | 
| 15481 | 320 | |
| 15814 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15550diff
changeset | 321 | (* search only for 'valid' unifiers (non abs subterms and non vars) *) | 
| 19871 | 322 | fun searchf_lr_unify_valid (sgn, maxidx, z) lhs = | 
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 323 | Seq.map (clean_unify_z sgn maxidx lhs) | 
| 19871 | 324 | (Z.limit_apply (search_lr_valid valid_match_start) z); | 
| 15929 
68bd1e16552a
lucas - added option to select occurance to rewrite e.g. (occ 4)
 dixon parents: 
15915diff
changeset | 325 | |
| 15814 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15550diff
changeset | 326 | |
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 327 | (* apply a substitution in the conclusion of the theorem th *) | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 328 | (* cfvs are certified free var placeholders for goal params *) | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 329 | (* conclthm is a theorem of for just the conclusion *) | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 330 | (* m is instantiation/match information *) | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 331 | (* rule is the equation for substitution *) | 
| 16978 | 332 | fun apply_subst_in_concl i th (cfvs, conclthm) rule m = | 
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 333 | (RWInst.rw m rule conclthm) | 
| 15855 | 334 | |> IsaND.unfix_frees cfvs | 
| 15915 
b0e8b37642a4
lucas - improved interface to isand.ML and cleaned up clean-unification code, and added some better comments.
 dixon parents: 
15855diff
changeset | 335 | |> RWInst.beta_eta_contract | 
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 336 | |> (fn r => Tactic.rtac r i th); | 
| 15481 | 337 | |
| 338 | (* substitute within the conclusion of goal i of gth, using a meta | |
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 339 | equation rule. Note that we assume rule has var indicies zero'd *) | 
| 16978 | 340 | fun prep_concl_subst i gth = | 
| 341 | let | |
| 15481 | 342 | val th = Thm.incr_indexes 1 gth; | 
| 343 | val tgt_term = Thm.prop_of th; | |
| 344 | ||
| 22578 | 345 | val sgn = Thm.theory_of_thm th; | 
| 15481 | 346 | val ctermify = Thm.cterm_of sgn; | 
| 347 | val trivify = Thm.trivial o ctermify; | |
| 348 | ||
| 349 | val (fixedbody, fvs) = IsaND.fix_alls_term i tgt_term; | |
| 350 | val cfvs = rev (map ctermify fvs); | |
| 351 | ||
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 352 | val conclterm = Logic.strip_imp_concl fixedbody; | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 353 | val conclthm = trivify conclterm; | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 354 | val maxidx = Term.maxidx_of_term conclterm; | 
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 355 | val ft = ((Z.move_down_right (* ==> *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 356 | o Z.move_down_left (* Trueprop *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 357 | o Z.mktop | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 358 | o Thm.prop_of) conclthm) | 
| 15481 | 359 | in | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 360 | ((cfvs, conclthm), (sgn, maxidx, ft)) | 
| 15481 | 361 | end; | 
| 362 | ||
| 363 | (* substitute using an object or meta level equality *) | |
| 18598 | 364 | fun eqsubst_tac' ctxt searchf instepthm i th = | 
| 16978 | 365 | let | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 366 | val (cvfsconclthm, searchinfo) = prep_concl_subst i th; | 
| 18598 | 367 | val stepthms = Seq.of_list (prep_meta_eq ctxt instepthm); | 
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 368 | fun rewrite_with_thm r = | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 369 | let val (lhs,_) = Logic.dest_equals (Thm.concl_of r); | 
| 18598 | 370 | in searchf searchinfo lhs | 
| 371 | |> Seq.maps (apply_subst_in_concl i th cvfsconclthm r) end; | |
| 372 | in stepthms |> Seq.maps rewrite_with_thm end; | |
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 373 | |
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 374 | |
| 19047 | 375 | (* distinct subgoals *) | 
| 15959 
366d39e95d3c
lucas - fixed bug with uninstantiated type contexts in eqsubst and added the automatic removal of duplicate subgoals (when there are no flex-flex constraints)
 dixon parents: 
15936diff
changeset | 376 | fun distinct_subgoals th = | 
| 19047 | 377 | the_default th (SINGLE distinct_subgoals_tac th); | 
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 378 | |
| 19047 | 379 | (* General substitution of multiple occurances using one of | 
| 15936 
817ac93ee786
lucas - added ability to provide multiple replacements for subst: syntax is now: subst (1 3) myrule
 dixon parents: 
15929diff
changeset | 380 | the given theorems*) | 
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 381 | |
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 382 | |
| 16978 | 383 | exception eqsubst_occL_exp of | 
| 384 | string * (int list) * (thm list) * int * thm; | |
| 385 | fun skip_first_occs_search occ srchf sinfo lhs = | |
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 386 | case (skipto_skipseq occ (srchf sinfo lhs)) of | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 387 | SkipMore _ => Seq.empty | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 388 | | SkipSeq ss => Seq.flat ss; | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 389 | |
| 22727 | 390 | (* The occL is a list of integers indicating which occurence | 
| 391 | w.r.t. the search order, to rewrite. Backtracking will also find later | |
| 392 | occurences, but all earlier ones are skipped. Thus you can use [0] to | |
| 393 | just find all rewrites. *) | |
| 394 | ||
| 18598 | 395 | fun eqsubst_tac ctxt occL thms i th = | 
| 15936 
817ac93ee786
lucas - added ability to provide multiple replacements for subst: syntax is now: subst (1 3) myrule
 dixon parents: 
15929diff
changeset | 396 | let val nprems = Thm.nprems_of th in | 
| 
817ac93ee786
lucas - added ability to provide multiple replacements for subst: syntax is now: subst (1 3) myrule
 dixon parents: 
15929diff
changeset | 397 | if nprems < i then Seq.empty else | 
| 16978 | 398 | let val thmseq = (Seq.of_list thms) | 
| 399 | fun apply_occ occ th = | |
| 18598 | 400 | thmseq |> Seq.maps | 
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 401 | (fn r => eqsubst_tac' | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 402 | ctxt | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 403 | (skip_first_occs_search | 
| 19871 | 404 | occ searchf_lr_unify_valid) r | 
| 15936 
817ac93ee786
lucas - added ability to provide multiple replacements for subst: syntax is now: subst (1 3) myrule
 dixon parents: 
15929diff
changeset | 405 | (i + ((Thm.nprems_of th) - nprems)) | 
| 
817ac93ee786
lucas - added ability to provide multiple replacements for subst: syntax is now: subst (1 3) myrule
 dixon parents: 
15929diff
changeset | 406 | th); | 
| 16978 | 407 | val sortedoccL = | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 408 | Library.sort (Library.rev_order o Library.int_ord) occL; | 
| 15936 
817ac93ee786
lucas - added ability to provide multiple replacements for subst: syntax is now: subst (1 3) myrule
 dixon parents: 
15929diff
changeset | 409 | in | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 410 | Seq.map distinct_subgoals (Seq.EVERY (map apply_occ sortedoccL) th) | 
| 15936 
817ac93ee786
lucas - added ability to provide multiple replacements for subst: syntax is now: subst (1 3) myrule
 dixon parents: 
15929diff
changeset | 411 | end | 
| 15959 
366d39e95d3c
lucas - fixed bug with uninstantiated type contexts in eqsubst and added the automatic removal of duplicate subgoals (when there are no flex-flex constraints)
 dixon parents: 
15936diff
changeset | 412 | end | 
| 
366d39e95d3c
lucas - fixed bug with uninstantiated type contexts in eqsubst and added the automatic removal of duplicate subgoals (when there are no flex-flex constraints)
 dixon parents: 
15936diff
changeset | 413 |     handle THM _ => raise eqsubst_occL_exp ("THM",occL,thms,i,th);
 | 
| 
366d39e95d3c
lucas - fixed bug with uninstantiated type contexts in eqsubst and added the automatic removal of duplicate subgoals (when there are no flex-flex constraints)
 dixon parents: 
15936diff
changeset | 414 | |
| 15481 | 415 | |
| 416 | (* inthms are the given arguments in Isar, and treated as eqstep with | |
| 417 | the first one, then the second etc *) | |
| 18598 | 418 | fun eqsubst_meth ctxt occL inthms = | 
| 21588 | 419 | Method.SIMPLE_METHOD' (eqsubst_tac ctxt occL inthms); | 
| 15481 | 420 | |
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 421 | (* apply a substitution inside assumption j, keeps asm in the same place *) | 
| 16978 | 422 | fun apply_subst_in_asm i th rule ((cfvs, j, ngoalprems, pth),m) = | 
| 423 | let | |
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 424 | val th2 = Thm.rotate_rule (j - 1) i th; (* put premice first *) | 
| 16978 | 425 | val preelimrule = | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 426 | (RWInst.rw m rule pth) | 
| 21708 | 427 | |> (Seq.hd o prune_params_tac) | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 428 | |> Thm.permute_prems 0 ~1 (* put old asm first *) | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 429 | |> IsaND.unfix_frees cfvs (* unfix any global params *) | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 430 | |> RWInst.beta_eta_contract; (* normal form *) | 
| 16978 | 431 | (* val elimrule = | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 432 | preelimrule | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 433 | |> Tactic.make_elim (* make into elim rule *) | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 434 | |> Thm.lift_rule (th2, i); (* lift into context *) | 
| 16007 
4dcccaa11a13
lucas - bugfix to subst in assumptions: fixed index error for conditional rules.
 dixon parents: 
16004diff
changeset | 435 | *) | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 436 | in | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 437 | (* ~j because new asm starts at back, thus we subtract 1 *) | 
| 16007 
4dcccaa11a13
lucas - bugfix to subst in assumptions: fixed index error for conditional rules.
 dixon parents: 
16004diff
changeset | 438 | Seq.map (Thm.rotate_rule (~j) ((Thm.nprems_of rule) + i)) | 
| 
4dcccaa11a13
lucas - bugfix to subst in assumptions: fixed index error for conditional rules.
 dixon parents: 
16004diff
changeset | 439 | (Tactic.dtac preelimrule i th2) | 
| 
4dcccaa11a13
lucas - bugfix to subst in assumptions: fixed index error for conditional rules.
 dixon parents: 
16004diff
changeset | 440 | |
| 16978 | 441 | (* (Thm.bicompose | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 442 | false (* use unification *) | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 443 | (true, (* elim resolution *) | 
| 16007 
4dcccaa11a13
lucas - bugfix to subst in assumptions: fixed index error for conditional rules.
 dixon parents: 
16004diff
changeset | 444 | elimrule, (2 + (Thm.nprems_of rule)) - ngoalprems) | 
| 
4dcccaa11a13
lucas - bugfix to subst in assumptions: fixed index error for conditional rules.
 dixon parents: 
16004diff
changeset | 445 | i th2) *) | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 446 | end; | 
| 15481 | 447 | |
| 448 | ||
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 449 | (* prepare to substitute within the j'th premise of subgoal i of gth, | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 450 | using a meta-level equation. Note that we assume rule has var indicies | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 451 | zero'd. Note that we also assume that premt is the j'th premice of | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 452 | subgoal i of gth. Note the repetition of work done for each | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 453 | assumption, i.e. this can be made more efficient for search over | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 454 | multiple assumptions. *) | 
| 16978 | 455 | fun prep_subst_in_asm i gth j = | 
| 456 | let | |
| 15481 | 457 | val th = Thm.incr_indexes 1 gth; | 
| 458 | val tgt_term = Thm.prop_of th; | |
| 459 | ||
| 22578 | 460 | val sgn = Thm.theory_of_thm th; | 
| 15481 | 461 | val ctermify = Thm.cterm_of sgn; | 
| 462 | val trivify = Thm.trivial o ctermify; | |
| 463 | ||
| 464 | val (fixedbody, fvs) = IsaND.fix_alls_term i tgt_term; | |
| 465 | val cfvs = rev (map ctermify fvs); | |
| 466 | ||
| 18011 
685d95c793ff
cleaned up nth, nth_update, nth_map and nth_string functions
 haftmann parents: 
17795diff
changeset | 467 | val asmt = nth (Logic.strip_imp_prems fixedbody) (j - 1); | 
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 468 | val asm_nprems = length (Logic.strip_imp_prems asmt); | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 469 | |
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 470 | val pth = trivify asmt; | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 471 | val maxidx = Term.maxidx_of_term asmt; | 
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 472 | |
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 473 | val ft = ((Z.move_down_right (* trueprop *) | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 474 | o Z.mktop | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 475 | o Thm.prop_of) pth) | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 476 | in ((cfvs, j, asm_nprems, pth), (sgn, maxidx, ft)) end; | 
| 15481 | 477 | |
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 478 | (* prepare subst in every possible assumption *) | 
| 16978 | 479 | fun prep_subst_in_asms i gth = | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 480 | map (prep_subst_in_asm i gth) | 
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 481 | ((fn l => Library.upto (1, length l)) | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 482 | (Logic.prems_of_goal (Thm.prop_of gth) i)); | 
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 483 | |
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 484 | |
| 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 485 | (* substitute in an assumption using an object or meta level equality *) | 
| 18598 | 486 | fun eqsubst_asm_tac' ctxt searchf skipocc instepthm i th = | 
| 16978 | 487 | let | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 488 | val asmpreps = prep_subst_in_asms i th; | 
| 18598 | 489 | val stepthms = Seq.of_list (prep_meta_eq ctxt instepthm); | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 490 | fun rewrite_with_thm r = | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 491 | let val (lhs,_) = Logic.dest_equals (Thm.concl_of r) | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 492 | fun occ_search occ [] = Seq.empty | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 493 | | occ_search occ ((asminfo, searchinfo)::moreasms) = | 
| 16978 | 494 | (case searchf searchinfo occ lhs of | 
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 495 | SkipMore i => occ_search i moreasms | 
| 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 496 | | SkipSeq ss => | 
| 19861 | 497 | Seq.append (Seq.map (Library.pair asminfo) (Seq.flat ss)) | 
| 498 | (occ_search 1 moreasms)) | |
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 499 | (* find later substs also *) | 
| 16978 | 500 | in | 
| 18598 | 501 | occ_search skipocc asmpreps |> Seq.maps (apply_subst_in_asm i th r) | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 502 | end; | 
| 18598 | 503 | in stepthms |> Seq.maps rewrite_with_thm end; | 
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 504 | |
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 505 | |
| 16978 | 506 | fun skip_first_asm_occs_search searchf sinfo occ lhs = | 
| 19835 
81d6dc597559
added updated version of IsaPlanner and substitution.
 dixon parents: 
19473diff
changeset | 507 | skipto_skipseq occ (searchf sinfo lhs); | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 508 | |
| 18598 | 509 | fun eqsubst_asm_tac ctxt occL thms i th = | 
| 16978 | 510 | let val nprems = Thm.nprems_of th | 
| 15538 
d8edf54cc28c
lucas - re-arranged code and added comments. Also added check to make sure the subgoal that we are being applied to exists. If it does not, empty seq is returned.
 dixon parents: 
15486diff
changeset | 511 | in | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 512 | if nprems < i then Seq.empty else | 
| 16978 | 513 | let val thmseq = (Seq.of_list thms) | 
| 514 | fun apply_occ occK th = | |
| 18598 | 515 | thmseq |> Seq.maps | 
| 16978 | 516 | (fn r => | 
| 18598 | 517 | eqsubst_asm_tac' ctxt (skip_first_asm_occs_search | 
| 19871 | 518 | searchf_lr_unify_valid) occK r | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 519 | (i + ((Thm.nprems_of th) - nprems)) | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 520 | th); | 
| 16978 | 521 | val sortedoccs = | 
| 16004 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 522 | Library.sort (Library.rev_order o Library.int_ord) occL | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 523 | in | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 524 | Seq.map distinct_subgoals | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 525 | (Seq.EVERY (map apply_occ sortedoccs) th) | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 526 | end | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 527 | end | 
| 
031f56012483
lucas - fixed subst in assumptions to count redexes from left to right.
 dixon parents: 
15959diff
changeset | 528 |     handle THM _ => raise eqsubst_occL_exp ("THM",occL,thms,i,th);
 | 
| 15481 | 529 | |
| 530 | (* inthms are the given arguments in Isar, and treated as eqstep with | |
| 531 | the first one, then the second etc *) | |
| 18598 | 532 | fun eqsubst_asm_meth ctxt occL inthms = | 
| 21588 | 533 | Method.SIMPLE_METHOD' (eqsubst_asm_tac ctxt occL inthms); | 
| 15481 | 534 | |
| 535 | (* syntax for options, given "(asm)" will give back true, without | |
| 536 | gives back false *) | |
| 537 | val options_syntax = | |
| 538 | (Args.parens (Args.$$$ "asm") >> (K true)) || | |
| 539 | (Scan.succeed false); | |
| 15936 
817ac93ee786
lucas - added ability to provide multiple replacements for subst: syntax is now: subst (1 3) myrule
 dixon parents: 
15929diff
changeset | 540 | |
| 15929 
68bd1e16552a
lucas - added option to select occurance to rewrite e.g. (occ 4)
 dixon parents: 
15915diff
changeset | 541 | val ith_syntax = | 
| 15936 
817ac93ee786
lucas - added ability to provide multiple replacements for subst: syntax is now: subst (1 3) myrule
 dixon parents: 
15929diff
changeset | 542 | (Args.parens (Scan.repeat Args.nat)) | 
| 
817ac93ee786
lucas - added ability to provide multiple replacements for subst: syntax is now: subst (1 3) myrule
 dixon parents: 
15929diff
changeset | 543 | || (Scan.succeed [0]); | 
| 15481 | 544 | |
| 18598 | 545 | (* combination method that takes a flag (true indicates that subst | 
| 546 | should be done to an assumption, false = apply to the conclusion of | |
| 547 | the goal) as well as the theorems to use *) | |
| 548 | fun subst_meth src = | |
| 18988 | 549 | Method.syntax ((Scan.lift options_syntax) -- (Scan.lift ith_syntax) -- Attrib.thms) src | 
| 21879 | 550 | #> (fn (((asmflag, occL), inthms), ctxt) => | 
| 18598 | 551 | (if asmflag then eqsubst_asm_meth else eqsubst_meth) ctxt occL inthms); | 
| 15481 | 552 | |
| 18598 | 553 | |
| 16978 | 554 | val setup = | 
| 18833 | 555 |   Method.add_method ("subst", subst_meth, "single-step substitution");
 | 
| 15481 | 556 | |
| 16978 | 557 | end; |