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