| author | wenzelm | 
| Sat, 03 Jan 2015 20:48:10 +0100 | |
| changeset 59248 | 167c2ebdfab4 | 
| parent 58949 | e9559088ba29 | 
| child 63615 | d786d54efc70 | 
| permissions | -rw-r--r-- | 
| 247 
bc10568855ee
added is_empty: env -> bool, minidx: env -> int option;
 wenzelm parents: 
0diff
changeset | 1 | (* Title: Pure/envir.ML | 
| 
bc10568855ee
added is_empty: env -> bool, minidx: env -> int option;
 wenzelm parents: 
0diff
changeset | 2 | Author: Lawrence C Paulson, Cambridge University Computer Laboratory | 
| 10485 | 3 | |
| 32031 | 4 | Free-form environments. The type of a term variable / sort of a type variable is | 
| 5 | part of its name. The lookup function must apply type substitutions, | |
| 15797 | 6 | since they may change the identity of a variable. | 
| 0 | 7 | *) | 
| 8 | ||
| 247 
bc10568855ee
added is_empty: env -> bool, minidx: env -> int option;
 wenzelm parents: 
0diff
changeset | 9 | signature ENVIR = | 
| 0 | 10 | sig | 
| 32018 | 11 | type tenv = (typ * term) Vartab.table | 
| 32031 | 12 |   datatype env = Envir of {maxidx: int, tenv: tenv, tyenv: Type.tyenv}
 | 
| 13 | val maxidx_of: env -> int | |
| 14 | val term_env: env -> tenv | |
| 15797 | 15 | val type_env: env -> Type.tyenv | 
| 32031 | 16 | val is_empty: env -> bool | 
| 17 | val empty: int -> env | |
| 18 | val merge: env * env -> env | |
| 26638 | 19 | val insert_sorts: env -> sort list -> sort list | 
| 10485 | 20 | val genvars: string -> env * typ list -> env * term list | 
| 21 | val genvar: string -> env * typ -> env * term | |
| 51700 | 22 | val lookup1: tenv -> indexname * typ -> term option | 
| 23 | val lookup: env -> indexname * typ -> term option | |
| 24 | val update: (indexname * typ) * term -> env -> env | |
| 19861 | 25 | val above: env -> int -> bool | 
| 51700 | 26 | val vupdate: (indexname * typ) * term -> env -> env | 
| 32018 | 27 | val norm_type_same: Type.tyenv -> typ Same.operation | 
| 28 | val norm_types_same: Type.tyenv -> typ list Same.operation | |
| 15797 | 29 | val norm_type: Type.tyenv -> typ -> typ | 
| 32018 | 30 | val norm_term_same: env -> term Same.operation | 
| 31 | val norm_term: env -> term -> term | |
| 10485 | 32 | val beta_norm: term -> term | 
| 12231 
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
 berghofe parents: 
11513diff
changeset | 33 | val head_norm: env -> term -> term | 
| 52131 | 34 | val eta_long: typ list -> term -> term | 
| 18937 | 35 | val eta_contract: term -> term | 
| 36 | val beta_eta_contract: term -> term | |
| 52131 | 37 | val aeconv: term * term -> bool | 
| 52221 | 38 | val body_type: env -> typ -> typ | 
| 39 | val binder_types: env -> typ -> typ list | |
| 40 | val strip_type: env -> typ -> typ list * typ | |
| 12231 
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
 berghofe parents: 
11513diff
changeset | 41 | val fastype: env -> typ list -> term -> typ | 
| 32034 | 42 | val subst_type_same: Type.tyenv -> typ Same.operation | 
| 43 | val subst_term_types_same: Type.tyenv -> term Same.operation | |
| 44 | val subst_term_same: Type.tyenv * tenv -> term Same.operation | |
| 45 | val subst_type: Type.tyenv -> typ -> typ | |
| 46 | val subst_term_types: Type.tyenv -> term -> term | |
| 47 | val subst_term: Type.tyenv * tenv -> term -> term | |
| 19422 | 48 | val expand_atom: typ -> typ * term -> term | 
| 21695 | 49 | val expand_term: (term -> (typ * term) option) -> term -> term | 
| 21795 | 50 | val expand_term_frees: ((string * typ) * term) list -> term -> term | 
| 0 | 51 | end; | 
| 52 | ||
| 32031 | 53 | structure Envir: ENVIR = | 
| 0 | 54 | struct | 
| 55 | ||
| 32031 | 56 | (** datatype env **) | 
| 57 | ||
| 58 | (*Updating can destroy environment in 2 ways! | |
| 59 | (1) variables out of range | |
| 60 | (2) circular assignments | |
| 0 | 61 | *) | 
| 32031 | 62 | |
| 32018 | 63 | type tenv = (typ * term) Vartab.table; | 
| 15797 | 64 | |
| 0 | 65 | datatype env = Envir of | 
| 32031 | 66 |  {maxidx: int,          (*upper bound of maximum index of vars*)
 | 
| 67 | tenv: tenv, (*assignments to Vars*) | |
| 68 | tyenv: Type.tyenv}; (*assignments to TVars*) | |
| 69 | ||
| 32796 | 70 | fun make_env (maxidx, tenv, tyenv) = | 
| 71 |   Envir {maxidx = maxidx, tenv = tenv, tyenv = tyenv};
 | |
| 32031 | 72 | |
| 73 | fun maxidx_of (Envir {maxidx, ...}) = maxidx;
 | |
| 74 | fun term_env (Envir {tenv, ...}) = tenv;
 | |
| 75 | fun type_env (Envir {tyenv, ...}) = tyenv;
 | |
| 76 | ||
| 77 | fun is_empty env = | |
| 78 | Vartab.is_empty (term_env env) andalso | |
| 79 | Vartab.is_empty (type_env env); | |
| 0 | 80 | |
| 32031 | 81 | |
| 82 | (* build env *) | |
| 83 | ||
| 84 | fun empty maxidx = make_env (maxidx, Vartab.empty, Vartab.empty); | |
| 0 | 85 | |
| 32031 | 86 | fun merge | 
| 87 |    (Envir {maxidx = maxidx1, tenv = tenv1, tyenv = tyenv1},
 | |
| 88 |     Envir {maxidx = maxidx2, tenv = tenv2, tyenv = tyenv2}) =
 | |
| 89 | make_env (Int.max (maxidx1, maxidx2), | |
| 90 | Vartab.merge (op =) (tenv1, tenv2), | |
| 91 | Vartab.merge (op =) (tyenv1, tyenv2)); | |
| 92 | ||
| 93 | ||
| 94 | (*NB: type unification may invent new sorts*) (* FIXME tenv!? *) | |
| 26638 | 95 | val insert_sorts = Vartab.fold (fn (_, (_, T)) => Sorts.insert_typ T) o type_env; | 
| 96 | ||
| 0 | 97 | (*Generate a list of distinct variables. | 
| 98 | Increments index to make them distinct from ALL present variables. *) | |
| 32031 | 99 | fun genvars name (Envir {maxidx, tenv, tyenv}, Ts) : env * term list =
 | 
| 32018 | 100 | let | 
| 101 | fun genvs (_, [] : typ list) : term list = [] | |
| 102 | | genvs (n, [T]) = [Var ((name, maxidx + 1), T)] | |
| 103 | | genvs (n, T :: Ts) = | |
| 104 | Var ((name ^ radixstring (26, "a" , n), maxidx + 1), T) | |
| 105 | :: genvs (n + 1, Ts); | |
| 32031 | 106 |   in (Envir {maxidx = maxidx + 1, tenv = tenv, tyenv = tyenv}, genvs (0, Ts)) end;
 | 
| 0 | 107 | |
| 108 | (*Generate a variable.*) | |
| 32018 | 109 | fun genvar name (env, T) : env * term = | 
| 110 | let val (env', [v]) = genvars name (env, [T]) | |
| 111 | in (env', v) end; | |
| 0 | 112 | |
| 32031 | 113 | fun var_clash xi T T' = | 
| 51701 
1e29891759c4
tuned exceptions -- avoid composing error messages in low-level situations;
 wenzelm parents: 
51700diff
changeset | 114 |   raise TYPE ("Variable has two distinct types", [], [Var (xi, T'), Var (xi, T)]);
 | 
| 0 | 115 | |
| 32031 | 116 | fun lookup_check check tenv (xi, T) = | 
| 117 | (case Vartab.lookup tenv xi of | |
| 32018 | 118 | NONE => NONE | 
| 32031 | 119 | | SOME (U, t) => if check (T, U) then SOME t else var_clash xi T U); | 
| 15797 | 120 | |
| 51700 | 121 | (*When dealing with environments produced by matching instead | 
| 122 | of unification, there is no need to chase assigned TVars. | |
| 123 | In this case, we can simply ignore the type substitution | |
| 124 | and use = instead of eq_type.*) | |
| 51707 | 125 | fun lookup1 tenv = lookup_check (op =) tenv; | 
| 15797 | 126 | |
| 58949 
e9559088ba29
clarified name of Type.unified, to emphasize its connection to the "unify" family;
 wenzelm parents: 
58945diff
changeset | 127 | fun lookup (Envir {tenv, tyenv, ...}) = lookup_check (Type.unified tyenv) tenv;
 | 
| 0 | 128 | |
| 51700 | 129 | fun update ((xi, T), t) (Envir {maxidx, tenv, tyenv}) =
 | 
| 32031 | 130 |   Envir {maxidx = maxidx, tenv = Vartab.update_new (xi, (T, t)) tenv, tyenv = tyenv};
 | 
| 247 
bc10568855ee
added is_empty: env -> bool, minidx: env -> int option;
 wenzelm parents: 
0diff
changeset | 131 | |
| 2142 
20f208ff085d
Deleted Olist constructor.  Replaced minidx by "above" function
 paulson parents: 
1500diff
changeset | 132 | (*Determine if the least index updated exceeds lim*) | 
| 32031 | 133 | fun above (Envir {tenv, tyenv, ...}) lim =
 | 
| 52049 | 134 | (case Vartab.min tenv of SOME ((_, i), _) => i > lim | NONE => true) andalso | 
| 135 | (case Vartab.min tyenv of SOME ((_, i), _) => i > lim | NONE => true); | |
| 247 
bc10568855ee
added is_empty: env -> bool, minidx: env -> int option;
 wenzelm parents: 
0diff
changeset | 136 | |
| 0 | 137 | (*Update, checking Var-Var assignments: try to suppress higher indexes*) | 
| 51700 | 138 | fun vupdate (aU as (a, U), t) (env as Envir {tyenv, ...}) =
 | 
| 32031 | 139 | (case t of | 
| 140 | Var (nT as (name', T)) => | |
| 141 | if a = name' then env (*cycle!*) | |
| 35408 | 142 | else if Term_Ord.indexname_ord (a, name') = LESS then | 
| 51700 | 143 | (case lookup env nT of (*if already assigned, chase*) | 
| 144 | NONE => update (nT, Var (a, T)) env | |
| 145 | | SOME u => vupdate (aU, u) env) | |
| 146 | else update (aU, t) env | |
| 147 | | _ => update (aU, t) env); | |
| 0 | 148 | |
| 149 | ||
| 150 | ||
| 32031 | 151 | (** beta normalization wrt. environment **) | 
| 0 | 152 | |
| 32031 | 153 | (*Chases variables in env. Does not exploit sharing of variable bindings | 
| 154 | Does not check types, so could loop.*) | |
| 1500 | 155 | |
| 32018 | 156 | local | 
| 157 | ||
| 32031 | 158 | fun norm_type0 tyenv : typ Same.operation = | 
| 32018 | 159 | let | 
| 160 | fun norm (Type (a, Ts)) = Type (a, Same.map norm Ts) | |
| 161 | | norm (TFree _) = raise Same.SAME | |
| 162 | | norm (TVar v) = | |
| 32031 | 163 | (case Type.lookup tyenv v of | 
| 32018 | 164 | SOME U => Same.commit norm U | 
| 165 | | NONE => raise Same.SAME); | |
| 166 | in norm end; | |
| 0 | 167 | |
| 32031 | 168 | fun norm_term1 tenv : term Same.operation = | 
| 32018 | 169 | let | 
| 170 | fun norm (Var v) = | |
| 51700 | 171 | (case lookup1 tenv v of | 
| 32018 | 172 | SOME u => Same.commit norm u | 
| 173 | | NONE => raise Same.SAME) | |
| 32031 | 174 | | norm (Abs (a, T, body)) = Abs (a, T, norm body) | 
| 32018 | 175 | | norm (Abs (_, _, body) $ t) = Same.commit norm (subst_bound (t, body)) | 
| 176 | | norm (f $ t) = | |
| 177 | ((case norm f of | |
| 178 | Abs (_, _, body) => Same.commit norm (subst_bound (t, body)) | |
| 179 | | nf => nf $ Same.commit norm t) | |
| 180 | handle Same.SAME => f $ norm t) | |
| 181 | | norm _ = raise Same.SAME; | |
| 182 | in norm end; | |
| 0 | 183 | |
| 58945 | 184 | fun norm_term2 (envir as Envir {tenv, tyenv, ...}) : term Same.operation =
 | 
| 32018 | 185 | let | 
| 32031 | 186 | val normT = norm_type0 tyenv; | 
| 32018 | 187 | fun norm (Const (a, T)) = Const (a, normT T) | 
| 188 | | norm (Free (a, T)) = Free (a, normT T) | |
| 189 | | norm (Var (xi, T)) = | |
| 58945 | 190 | (case lookup envir (xi, T) of | 
| 32018 | 191 | SOME u => Same.commit norm u | 
| 192 | | NONE => Var (xi, normT T)) | |
| 193 | | norm (Abs (a, T, body)) = | |
| 194 | (Abs (a, normT T, Same.commit norm body) | |
| 195 | handle Same.SAME => Abs (a, T, norm body)) | |
| 196 | | norm (Abs (_, _, body) $ t) = Same.commit norm (subst_bound (t, body)) | |
| 197 | | norm (f $ t) = | |
| 198 | ((case norm f of | |
| 199 | Abs (_, _, body) => Same.commit norm (subst_bound (t, body)) | |
| 200 | | nf => nf $ Same.commit norm t) | |
| 201 | handle Same.SAME => f $ norm t) | |
| 202 | | norm _ = raise Same.SAME; | |
| 203 | in norm end; | |
| 11513 | 204 | |
| 32018 | 205 | in | 
| 206 | ||
| 32031 | 207 | fun norm_type_same tyenv T = | 
| 208 | if Vartab.is_empty tyenv then raise Same.SAME | |
| 209 | else norm_type0 tyenv T; | |
| 0 | 210 | |
| 32031 | 211 | fun norm_types_same tyenv Ts = | 
| 212 | if Vartab.is_empty tyenv then raise Same.SAME | |
| 213 | else Same.map (norm_type0 tyenv) Ts; | |
| 32018 | 214 | |
| 32031 | 215 | fun norm_type tyenv T = norm_type_same tyenv T handle Same.SAME => T; | 
| 11513 | 216 | |
| 58945 | 217 | fun norm_term_same (envir as Envir {tenv, tyenv, ...}) =
 | 
| 32031 | 218 | if Vartab.is_empty tyenv then norm_term1 tenv | 
| 58945 | 219 | else norm_term2 envir; | 
| 10485 | 220 | |
| 32018 | 221 | fun norm_term envir t = norm_term_same envir t handle Same.SAME => t; | 
| 25471 
ca009b7ce693
Optimized beta_norm: only tries to normalize term when it contains
 berghofe parents: 
24670diff
changeset | 222 | fun beta_norm t = if Term.has_abs t then norm_term (empty 0) t else t; | 
| 719 
e3e1d1a6d408
Pure/envir/norm_term: replaced equality test for [] by null
 lcp parents: 
247diff
changeset | 223 | |
| 32018 | 224 | end; | 
| 11513 | 225 | |
| 226 | ||
| 52131 | 227 | (* head normal form for unification *) | 
| 12231 
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
 berghofe parents: 
11513diff
changeset | 228 | |
| 32018 | 229 | fun head_norm env = | 
| 12231 
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
 berghofe parents: 
11513diff
changeset | 230 | let | 
| 32018 | 231 | fun norm (Var v) = | 
| 51700 | 232 | (case lookup env v of | 
| 15531 | 233 | SOME u => head_norm env u | 
| 32018 | 234 | | NONE => raise Same.SAME) | 
| 235 | | norm (Abs (a, T, body)) = Abs (a, T, norm body) | |
| 236 | | norm (Abs (_, _, body) $ t) = Same.commit norm (subst_bound (t, body)) | |
| 237 | | norm (f $ t) = | |
| 238 | (case norm f of | |
| 239 | Abs (_, _, body) => Same.commit norm (subst_bound (t, body)) | |
| 240 | | nf => nf $ t) | |
| 241 | | norm _ = raise Same.SAME; | |
| 242 | in Same.commit norm end; | |
| 12231 
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
 berghofe parents: 
11513diff
changeset | 243 | |
| 
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
 berghofe parents: 
11513diff
changeset | 244 | |
| 52131 | 245 | (* eta-long beta-normal form *) | 
| 246 | ||
| 247 | fun eta_long Ts (Abs (s, T, t)) = Abs (s, T, eta_long (T :: Ts) t) | |
| 248 | | eta_long Ts t = | |
| 249 | (case strip_comb t of | |
| 250 | (Abs _, _) => eta_long Ts (beta_norm t) | |
| 251 | | (u, ts) => | |
| 252 | let | |
| 253 | val Us = binder_types (fastype_of1 (Ts, t)); | |
| 254 | val i = length Us; | |
| 52132 | 255 | val long = eta_long (rev Us @ Ts); | 
| 52131 | 256 | in | 
| 257 | fold_rev (Term.abs o pair "x") Us | |
| 52132 | 258 | (list_comb (incr_boundvars i u, | 
| 259 | map (long o incr_boundvars i) ts @ map (long o Bound) (i - 1 downto 0))) | |
| 52131 | 260 | end); | 
| 261 | ||
| 262 | ||
| 263 | (* full eta contraction *) | |
| 18937 | 264 | |
| 22174 | 265 | local | 
| 266 | ||
| 32018 | 267 | fun decr lev (Bound i) = if i >= lev then Bound (i - 1) else raise Same.SAME | 
| 22174 | 268 | | decr lev (Abs (a, T, body)) = Abs (a, T, decr (lev + 1) body) | 
| 32018 | 269 | | decr lev (t $ u) = (decr lev t $ decrh lev u handle Same.SAME => t $ decr lev u) | 
| 270 | | decr _ _ = raise Same.SAME | |
| 271 | and decrh lev t = (decr lev t handle Same.SAME => t); | |
| 20670 | 272 | |
| 22174 | 273 | fun eta (Abs (a, T, body)) = | 
| 274 | ((case eta body of | |
| 275 | body' as (f $ Bound 0) => | |
| 42083 
e1209fc7ecdc
added Term.is_open and Term.is_dependent convenience, to cover common situations of loose bounds;
 wenzelm parents: 
35408diff
changeset | 276 | if Term.is_dependent f then Abs (a, T, body') | 
| 22174 | 277 | else decrh 0 f | 
| 32018 | 278 | | body' => Abs (a, T, body')) handle Same.SAME => | 
| 22174 | 279 | (case body of | 
| 280 | f $ Bound 0 => | |
| 42083 
e1209fc7ecdc
added Term.is_open and Term.is_dependent convenience, to cover common situations of loose bounds;
 wenzelm parents: 
35408diff
changeset | 281 | if Term.is_dependent f then raise Same.SAME | 
| 22174 | 282 | else decrh 0 f | 
| 32018 | 283 | | _ => raise Same.SAME)) | 
| 284 | | eta (t $ u) = (eta t $ Same.commit eta u handle Same.SAME => t $ eta u) | |
| 285 | | eta _ = raise Same.SAME; | |
| 22174 | 286 | |
| 287 | in | |
| 288 | ||
| 289 | fun eta_contract t = | |
| 32018 | 290 | if Term.has_abs t then Same.commit eta t else t; | 
| 18937 | 291 | |
| 52131 | 292 | end; | 
| 293 | ||
| 18937 | 294 | val beta_eta_contract = eta_contract o beta_norm; | 
| 295 | ||
| 52131 | 296 | fun aeconv (t, u) = t aconv u orelse eta_contract t aconv eta_contract u; | 
| 22174 | 297 | |
| 18937 | 298 | |
| 52221 | 299 | fun body_type env (Type ("fun", [_, T])) = body_type env T
 | 
| 300 | | body_type env (T as TVar v) = | |
| 52128 
7f3549a316f4
tuned signature -- slightly more general operations (cf. term.ML);
 wenzelm parents: 
52049diff
changeset | 301 | (case Type.lookup (type_env env) v of | 
| 
7f3549a316f4
tuned signature -- slightly more general operations (cf. term.ML);
 wenzelm parents: 
52049diff
changeset | 302 | NONE => T | 
| 52221 | 303 | | SOME T' => body_type env T') | 
| 304 | | body_type _ T = T; | |
| 52128 
7f3549a316f4
tuned signature -- slightly more general operations (cf. term.ML);
 wenzelm parents: 
52049diff
changeset | 305 | |
| 52221 | 306 | fun binder_types env (Type ("fun", [T, U])) = T :: binder_types env U
 | 
| 307 | | binder_types env (TVar v) = | |
| 52128 
7f3549a316f4
tuned signature -- slightly more general operations (cf. term.ML);
 wenzelm parents: 
52049diff
changeset | 308 | (case Type.lookup (type_env env) v of | 
| 
7f3549a316f4
tuned signature -- slightly more general operations (cf. term.ML);
 wenzelm parents: 
52049diff
changeset | 309 | NONE => [] | 
| 52221 | 310 | | SOME T' => binder_types env T') | 
| 311 | | binder_types _ _ = []; | |
| 52128 
7f3549a316f4
tuned signature -- slightly more general operations (cf. term.ML);
 wenzelm parents: 
52049diff
changeset | 312 | |
| 52221 | 313 | fun strip_type env T = (binder_types env T, body_type env T); | 
| 52128 
7f3549a316f4
tuned signature -- slightly more general operations (cf. term.ML);
 wenzelm parents: 
52049diff
changeset | 314 | |
| 12231 
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
 berghofe parents: 
11513diff
changeset | 315 | (*finds type of term without checking that combinations are consistent | 
| 
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
 berghofe parents: 
11513diff
changeset | 316 | Ts holds types of bound variables*) | 
| 32031 | 317 | fun fastype (Envir {tyenv, ...}) =
 | 
| 318 | let | |
| 319 | val funerr = "fastype: expected function type"; | |
| 12231 
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
 berghofe parents: 
11513diff
changeset | 320 | fun fast Ts (f $ u) = | 
| 32648 
143e0b0a6b33
Correct chasing of type variable instantiations during type unification.
 paulson parents: 
32034diff
changeset | 321 | (case Type.devar tyenv (fast Ts f) of | 
| 32031 | 322 |             Type ("fun", [_, T]) => T
 | 
| 32648 
143e0b0a6b33
Correct chasing of type variable instantiations during type unification.
 paulson parents: 
32034diff
changeset | 323 | | TVar v => raise TERM (funerr, [f $ u]) | 
| 32031 | 324 | | _ => raise TERM (funerr, [f $ u])) | 
| 12231 
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
 berghofe parents: 
11513diff
changeset | 325 | | fast Ts (Const (_, T)) = T | 
| 
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
 berghofe parents: 
11513diff
changeset | 326 | | fast Ts (Free (_, T)) = T | 
| 
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
 berghofe parents: 
11513diff
changeset | 327 | | fast Ts (Bound i) = | 
| 43278 | 328 |           (nth Ts i handle General.Subscript => raise TERM ("fastype: Bound", [Bound i]))
 | 
| 20670 | 329 | | fast Ts (Var (_, T)) = T | 
| 32031 | 330 | | fast Ts (Abs (_, T, u)) = T --> fast (T :: Ts) u; | 
| 331 | in fast end; | |
| 12231 
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
 berghofe parents: 
11513diff
changeset | 332 | |
| 15797 | 333 | |
| 32034 | 334 | (** plain substitution -- without variable chasing **) | 
| 335 | ||
| 336 | local | |
| 15797 | 337 | |
| 32034 | 338 | fun subst_type0 tyenv = Term_Subst.map_atypsT_same | 
| 339 | (fn TVar v => | |
| 340 | (case Type.lookup tyenv v of | |
| 341 | SOME U => U | |
| 342 | | NONE => raise Same.SAME) | |
| 343 | | _ => raise Same.SAME); | |
| 344 | ||
| 345 | fun subst_term1 tenv = Term_Subst.map_aterms_same | |
| 346 | (fn Var v => | |
| 51700 | 347 | (case lookup1 tenv v of | 
| 32034 | 348 | SOME u => u | 
| 349 | | NONE => raise Same.SAME) | |
| 350 | | _ => raise Same.SAME); | |
| 15797 | 351 | |
| 32034 | 352 | fun subst_term2 tenv tyenv : term Same.operation = | 
| 353 | let | |
| 354 | val substT = subst_type0 tyenv; | |
| 355 | fun subst (Const (a, T)) = Const (a, substT T) | |
| 356 | | subst (Free (a, T)) = Free (a, substT T) | |
| 357 | | subst (Var (xi, T)) = | |
| 51700 | 358 | (case lookup1 tenv (xi, T) of | 
| 32034 | 359 | SOME u => u | 
| 360 | | NONE => Var (xi, substT T)) | |
| 361 | | subst (Bound _) = raise Same.SAME | |
| 362 | | subst (Abs (a, T, t)) = | |
| 363 | (Abs (a, substT T, Same.commit subst t) | |
| 364 | handle Same.SAME => Abs (a, T, subst t)) | |
| 365 | | subst (t $ u) = (subst t $ Same.commit subst u handle Same.SAME => t $ subst u); | |
| 366 | in subst end; | |
| 367 | ||
| 368 | in | |
| 15797 | 369 | |
| 32034 | 370 | fun subst_type_same tyenv T = | 
| 371 | if Vartab.is_empty tyenv then raise Same.SAME | |
| 372 | else subst_type0 tyenv T; | |
| 373 | ||
| 374 | fun subst_term_types_same tyenv t = | |
| 375 | if Vartab.is_empty tyenv then raise Same.SAME | |
| 376 | else Term_Subst.map_types_same (subst_type0 tyenv) t; | |
| 377 | ||
| 378 | fun subst_term_same (tyenv, tenv) = | |
| 379 | if Vartab.is_empty tenv then subst_term_types_same tyenv | |
| 380 | else if Vartab.is_empty tyenv then subst_term1 tenv | |
| 381 | else subst_term2 tenv tyenv; | |
| 382 | ||
| 383 | fun subst_type tyenv T = subst_type_same tyenv T handle Same.SAME => T; | |
| 384 | fun subst_term_types tyenv t = subst_term_types_same tyenv t handle Same.SAME => t; | |
| 385 | fun subst_term envs t = subst_term_same envs t handle Same.SAME => t; | |
| 386 | ||
| 387 | end; | |
| 15797 | 388 | |
| 18937 | 389 | |
| 32034 | 390 | |
| 391 | (** expand defined atoms -- with local beta reduction **) | |
| 18937 | 392 | |
| 19422 | 393 | fun expand_atom T (U, u) = | 
| 32034 | 394 | subst_term_types (Type.raw_match (U, T) Vartab.empty) u | 
| 32031 | 395 |     handle Type.TYPE_MATCH => raise TYPE ("expand_atom: ill-typed replacement", [T, U], [u]);
 | 
| 18937 | 396 | |
| 21795 | 397 | fun expand_term get = | 
| 21695 | 398 | let | 
| 399 | fun expand tm = | |
| 400 | let | |
| 401 | val (head, args) = Term.strip_comb tm; | |
| 402 | val args' = map expand args; | |
| 403 | fun comb head' = Term.list_comb (head', args'); | |
| 404 | in | |
| 405 | (case head of | |
| 406 | Abs (x, T, t) => comb (Abs (x, T, expand t)) | |
| 407 | | _ => | |
| 32031 | 408 | (case get head of | 
| 409 | SOME def => Term.betapplys (expand_atom (Term.fastype_of head) def, args') | |
| 410 | | NONE => comb head)) | |
| 21695 | 411 | end; | 
| 412 | in expand end; | |
| 413 | ||
| 21795 | 414 | fun expand_term_frees defs = | 
| 415 | let | |
| 416 | val eqs = map (fn ((x, U), u) => (x, (U, u))) defs; | |
| 417 | val get = fn Free (x, _) => AList.lookup (op =) eqs x | _ => NONE; | |
| 418 | in expand_term get end; | |
| 419 | ||
| 0 | 420 | end; |