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