author | wenzelm |
Wed, 14 Sep 2022 23:09:02 +0200 | |
changeset 76158 | 0302bdf63a08 |
parent 74575 | ccf599864beb |
child 77730 | 4a174bea55e2 |
permissions | -rw-r--r-- |
247
bc10568855ee
added is_empty: env -> bool, minidx: env -> int option;
wenzelm
parents:
0
diff
changeset
|
1 |
(* Title: Pure/envir.ML |
bc10568855ee
added is_empty: env -> bool, minidx: env -> int option;
wenzelm
parents:
0
diff
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:
0
diff
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:
11513
diff
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:
11513
diff
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 |
74575 | 51 |
val expand_term_defs: (term -> string * typ) -> ((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:
51700
diff
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:
58945
diff
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:
0
diff
changeset
|
133 |
|
2142
20f208ff085d
Deleted Olist constructor. Replaced minidx by "above" function
paulson
parents:
1500
diff
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:
0
diff
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:
247
diff
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:
11513
diff
changeset
|
232 |
|
32018 | 233 |
fun head_norm env = |
12231
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
berghofe
parents:
11513
diff
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:
11513
diff
changeset
|
247 |
|
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
berghofe
parents:
11513
diff
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:
35408
diff
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:
35408
diff
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:
52049
diff
changeset
|
305 |
(case Type.lookup (type_env env) v of |
7f3549a316f4
tuned signature -- slightly more general operations (cf. term.ML);
wenzelm
parents:
52049
diff
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:
52049
diff
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:
52049
diff
changeset
|
312 |
(case Type.lookup (type_env env) v of |
7f3549a316f4
tuned signature -- slightly more general operations (cf. term.ML);
wenzelm
parents:
52049
diff
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:
52049
diff
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:
52049
diff
changeset
|
318 |
|
12231
4a25f04bea61
Moved head_norm and fastype from unify.ML to envir.ML
berghofe
parents:
11513
diff
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:
11513
diff
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:
11513
diff
changeset
|
324 |
fun fast Ts (f $ u) = |
32648
143e0b0a6b33
Correct chasing of type variable instantiations during type unification.
paulson
parents:
32034
diff
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:
11513
diff
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:
11513
diff
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) = |
74232 | 398 |
subst_term_types (Vartab.build (Type.raw_match (U, T))) 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 |
||
74575 | 418 |
fun expand_term_defs dest defs = |
21795 | 419 |
let |
74575 | 420 |
val eqs = map (fn ((x, U), u) => (x: string, (U, u))) defs; |
421 |
fun get t = (case try dest t of SOME (x, _: typ) => AList.lookup (op =) eqs x | _ => NONE); |
|
21795 | 422 |
in expand_term get end; |
423 |
||
0 | 424 |
end; |