61 | bTs _ = [] |
61 | bTs _ = [] |
62 in bTs end; |
62 in bTs end; |
63 |
63 |
64 fun strip_type env T = (binder_types env T, body_type env T); |
64 fun strip_type env T = (binder_types env T, body_type env T); |
65 |
65 |
66 |
66 fun fastype env (Ts, t) = Envir.fastype env (map snd Ts) t; |
67 (*Put a term into head normal form for unification. |
|
68 Operands need not be in normal form. Does eta-expansions on the head, |
|
69 which involves renumbering (thus copying) the args. To avoid this |
|
70 inefficiency, avoid partial application: if an atom is applied to |
|
71 any arguments at all, apply it to its full number of arguments. |
|
72 For |
|
73 rbinder = [(x1,T),...,(xm,Tm)] (user's var names preserved!) |
|
74 args = [arg1,...,argn] |
|
75 the value of |
|
76 (xm,...,x1)(head(arg1,...,argn)) remains invariant. |
|
77 *) |
|
78 |
|
79 local exception SAME |
|
80 in |
|
81 fun head_norm (env,t) : term = |
|
82 let fun hnorm (Var (v,T)) = |
|
83 (case Envir.lookup (env,v) of |
|
84 Some u => head_norm (env, u) |
|
85 | None => raise SAME) |
|
86 | hnorm (Abs(a,T,body)) = Abs(a, T, hnorm body) |
|
87 | hnorm (Abs(_,_,body) $ t) = |
|
88 head_norm (env, subst_bound (t, body)) |
|
89 | hnorm (f $ t) = |
|
90 (case hnorm f of |
|
91 Abs(_,_,body) => |
|
92 head_norm (env, subst_bound (t, body)) |
|
93 | nf => nf $ t) |
|
94 | hnorm _ = raise SAME |
|
95 in hnorm t handle SAME=> t end |
|
96 end; |
|
97 |
|
98 |
|
99 (*finds type of term without checking that combinations are consistent |
|
100 rbinder holds types of bound variables*) |
|
101 fun fastype (Envir.Envir{iTs,...}) = |
|
102 let val funerr = "fastype: expected function type"; |
|
103 fun fast(rbinder, f$u) = |
|
104 (case (fast (rbinder, f)) of |
|
105 Type("fun",[_,T]) => T |
|
106 | TVar(ixn,_) => |
|
107 (case Vartab.lookup (iTs,ixn) of |
|
108 Some(Type("fun",[_,T])) => T |
|
109 | _ => raise TERM(funerr, [f$u])) |
|
110 | _ => raise TERM(funerr, [f$u])) |
|
111 | fast (rbinder, Const (_,T)) = T |
|
112 | fast (rbinder, Free (_,T)) = T |
|
113 | fast (rbinder, Bound i) = |
|
114 (#2 (nth_elem (i,rbinder)) |
|
115 handle LIST _=> raise TERM("fastype: Bound", [Bound i])) |
|
116 | fast (rbinder, Var (_,T)) = T |
|
117 | fast (rbinder, Abs (_,T,u)) = T --> fast (("",T) :: rbinder, u) |
|
118 in fast end; |
|
119 |
67 |
120 |
68 |
121 (*Eta normal form*) |
69 (*Eta normal form*) |
122 fun eta_norm(env as Envir.Envir{iTs,...}) = |
70 fun eta_norm(env as Envir.Envir{iTs,...}) = |
123 let fun etif (Type("fun",[T,U]), t) = |
71 let fun etif (Type("fun",[T,U]), t) = |
287 | new_dpair (rbinder, t1, t2, env) = ((rbinder, t1, t2), env); |
235 | new_dpair (rbinder, t1, t2, env) = ((rbinder, t1, t2), env); |
288 |
236 |
289 |
237 |
290 fun head_norm_dpair (env, (rbinder,t,u)) : dpair * Envir.env = |
238 fun head_norm_dpair (env, (rbinder,t,u)) : dpair * Envir.env = |
291 new_dpair (rbinder, |
239 new_dpair (rbinder, |
292 eta_norm env (rbinder, head_norm(env,t)), |
240 eta_norm env (rbinder, Envir.head_norm env t), |
293 eta_norm env (rbinder, head_norm(env,u)), env); |
241 eta_norm env (rbinder, Envir.head_norm env u), env); |
294 |
242 |
295 |
243 |
296 |
244 |
297 (*flexflex: the flex-flex pairs, flexrigid: the flex-rigid pairs |
245 (*flexflex: the flex-flex pairs, flexrigid: the flex-rigid pairs |
298 Does not perform assignments for flex-flex pairs: |
246 Does not perform assignments for flex-flex pairs: |
388 fun matchcopy vname = let fun mc(rbinder, targs, u, ed as (env,dpairs)) |
336 fun matchcopy vname = let fun mc(rbinder, targs, u, ed as (env,dpairs)) |
389 : (term * (Envir.env * dpair list))Seq.seq = |
337 : (term * (Envir.env * dpair list))Seq.seq = |
390 let (*Produce copies of uarg and cons them in front of uargs*) |
338 let (*Produce copies of uarg and cons them in front of uargs*) |
391 fun copycons uarg (uargs, (env, dpairs)) = |
339 fun copycons uarg (uargs, (env, dpairs)) = |
392 Seq.map(fn (uarg', ed') => (uarg'::uargs, ed')) |
340 Seq.map(fn (uarg', ed') => (uarg'::uargs, ed')) |
393 (mc (rbinder, targs,eta_norm env (rbinder,head_norm(env,uarg)), |
341 (mc (rbinder, targs,eta_norm env (rbinder, Envir.head_norm env uarg), |
394 (env, dpairs))); |
342 (env, dpairs))); |
395 (*Produce sequence of all possible ways of copying the arg list*) |
343 (*Produce sequence of all possible ways of copying the arg list*) |
396 fun copyargs [] = Seq.cons( ([],ed), Seq.empty) |
344 fun copyargs [] = Seq.cons( ([],ed), Seq.empty) |
397 | copyargs (uarg::uargs) = |
345 | copyargs (uarg::uargs) = |
398 Seq.flat (Seq.map (copycons uarg) (copyargs uargs)); |
346 Seq.flat (Seq.map (copycons uarg) (copyargs uargs)); |