| author | paulson <lp15@cam.ac.uk> | 
| Thu, 16 Feb 2023 12:54:24 +0000 | |
| changeset 77278 | e20f5b9ad776 | 
| 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;  |