102 fun mkhnf (binders,is,G,js) = mkabs (binders, is, app(G,js)); |
104 fun mkhnf (binders,is,G,js) = mkabs (binders, is, app(G,js)); |
103 |
105 |
104 fun mknewhnf(env,binders,is,F as (a,_),T,js) = |
106 fun mknewhnf(env,binders,is,F as (a,_),T,js) = |
105 let val (env',G) = Envir.genvar a (env,type_of_G(T,length is,js)) |
107 let val (env',G) = Envir.genvar a (env,type_of_G(T,length is,js)) |
106 in Envir.update((F,mkhnf(binders,is,G,js)),env') end; |
108 in Envir.update((F,mkhnf(binders,is,G,js)),env') end; |
107 |
|
108 |
|
109 fun devar env t = case strip_comb t of |
|
110 (Var(F,_),ys) => |
|
111 (case Envir.lookup(env,F) of |
|
112 Some(t) => devar env (red t (ints_of ys) []) |
|
113 | None => t) |
|
114 | _ => t; |
|
115 |
109 |
116 |
110 |
117 (* mk_proj_list(is) = [ |is| - k | 1 <= k <= |is| and is[k] >= 0 ] *) |
111 (* mk_proj_list(is) = [ |is| - k | 1 <= k <= |is| and is[k] >= 0 ] *) |
118 fun mk_proj_list is = |
112 fun mk_proj_list is = |
119 let fun mk(i::is,j) = if i >= 0 then j :: mk(is,j-1) else mk(is,j-1) |
113 let fun mk(i::is,j) = if i >= 0 then j :: mk(is,j-1) else mk(is,j-1) |
120 | mk([],_) = [] |
114 | mk([],_) = [] |
121 in mk(is,length is - 1) end; |
115 in mk(is,length is - 1) end; |
122 |
116 |
123 fun proj(s,env,binders,is) = |
117 fun proj(s,env,binders,is) = |
124 let fun trans d i = if i<d then i else (idx is (i-d))+d; |
118 let fun trans d i = if i<d then i else (idx is (i-d))+d; |
125 fun pr(s,env,d,binders) = (case devar env s of |
119 fun pr(s,env,d,binders) = (case Envir.head_norm env s of |
126 Abs(a,T,t) => let val (t',env') = pr(t,env,d+1,((a,T)::binders)) |
120 Abs(a,T,t) => let val (t',env') = pr(t,env,d+1,((a,T)::binders)) |
127 in (Abs(a,T,t'),env') end |
121 in (Abs(a,T,t'),env') end |
128 | t => (case strip_comb t of |
122 | t => (case strip_comb t of |
129 (c as Const _,ts) => |
123 (c as Const _,ts) => |
130 let val (ts',env') = prs(ts,env,d,binders) |
124 let val (ts',env') = prs(ts,env,d,binders) |
137 in if j < 0 then raise Unif |
131 in if j < 0 then raise Unif |
138 else let val (ts',env') = prs(ts,env,d,binders) |
132 else let val (ts',env') = prs(ts,env,d,binders) |
139 in (list_comb(Bound j,ts'),env') end |
133 in (list_comb(Bound j,ts'),env') end |
140 end |
134 end |
141 | (Var(F as (a,_),Fty),ts) => |
135 | (Var(F as (a,_),Fty),ts) => |
142 let val js = ints_of ts; |
136 let val js = ints_of' env ts; |
143 val js' = map (trans d) js; |
137 val js' = map (trans d) js; |
144 val ks = mk_proj_list js'; |
138 val ks = mk_proj_list js'; |
145 val ls = filter (fn i => i >= 0) js' |
139 val ls = filter (fn i => i >= 0) js' |
146 val Hty = type_of_G(Fty,length js,ks) |
140 val Hty = type_of_G(Fty,length js,ks) |
147 val (env',H) = Envir.genvar a (env,Hty) |
141 val (env',H) = Envir.genvar a (env,Hty) |
191 if T=U then env |
185 if T=U then env |
192 else let val (iTs',maxidx') = Type.unify (!tsgr) maxidx iTs (U,T) |
186 else let val (iTs',maxidx') = Type.unify (!tsgr) maxidx iTs (U,T) |
193 in Envir.Envir{asol=asol,maxidx=maxidx',iTs=iTs'} end |
187 in Envir.Envir{asol=asol,maxidx=maxidx',iTs=iTs'} end |
194 handle Type.TUNIFY => raise Unif; |
188 handle Type.TUNIFY => raise Unif; |
195 |
189 |
196 fun unif binders (env,(s,t)) = case (devar env s,devar env t) of |
190 fun unif binders (env,(s,t)) = case (Envir.head_norm env s, Envir.head_norm env t) of |
197 (Abs(ns,Ts,ts),Abs(nt,Tt,tt)) => |
191 (Abs(ns,Ts,ts),Abs(nt,Tt,tt)) => |
198 let val name = if ns = "" then nt else ns |
192 let val name = if ns = "" then nt else ns |
199 in unif ((name,Ts)::binders) (env,(ts,tt)) end |
193 in unif ((name,Ts)::binders) (env,(ts,tt)) end |
200 | (Abs(ns,Ts,ts),t) => unif ((ns,Ts)::binders) (env,(ts,(incr t)$Bound(0))) |
194 | (Abs(ns,Ts,ts),t) => unif ((ns,Ts)::binders) (env,(ts,(incr t)$Bound(0))) |
201 | (t,Abs(nt,Tt,tt)) => unif ((nt,Tt)::binders) (env,((incr t)$Bound(0),tt)) |
195 | (t,Abs(nt,Tt,tt)) => unif ((nt,Tt)::binders) (env,((incr t)$Bound(0),tt)) |
202 | p => cases(binders,env,p) |
196 | p => cases(binders,env,p) |
203 |
197 |
204 and cases(binders,env,(s,t)) = case (strip_comb s,strip_comb t) of |
198 and cases(binders,env,(s,t)) = case (strip_comb s,strip_comb t) of |
205 ((Var(F,Fty),ss),(Var(G,Gty),ts)) => |
199 ((Var(F,Fty),ss),(Var(G,Gty),ts)) => |
206 if F = G then flexflex1(env,binders,F,Fty,ints_of ss,ints_of ts) |
200 if F = G then flexflex1(env,binders,F,Fty,ints_of' env ss,ints_of' env ts) |
207 else flexflex2(env,binders,F,Fty,ints_of ss,G,Gty,ints_of ts) |
201 else flexflex2(env,binders,F,Fty,ints_of' env ss,G,Gty,ints_of' env ts) |
208 | ((Var(F,_),ss),_) => flexrigid(env,binders,F,ints_of ss,t) |
202 | ((Var(F,_),ss),_) => flexrigid(env,binders,F,ints_of' env ss,t) |
209 | (_,(Var(F,_),ts)) => flexrigid(env,binders,F,ints_of ts,s) |
203 | (_,(Var(F,_),ts)) => flexrigid(env,binders,F,ints_of' env ts,s) |
210 | ((Const c,ss),(Const d,ts)) => rigidrigid(env,binders,c,d,ss,ts) |
204 | ((Const c,ss),(Const d,ts)) => rigidrigid(env,binders,c,d,ss,ts) |
211 | ((Free(f),ss),(Free(g),ts)) => rigidrigid(env,binders,f,g,ss,ts) |
205 | ((Free(f),ss),(Free(g),ts)) => rigidrigid(env,binders,f,g,ss,ts) |
212 | ((Bound(i),ss),(Bound(j),ts)) => rigidrigidB (env,binders,i,j,ss,ts) |
206 | ((Bound(i),ss),(Bound(j),ts)) => rigidrigidB (env,binders,i,j,ss,ts) |
213 | ((Abs(_),_),_) => raise Pattern |
207 | ((Abs(_),_),_) => raise Pattern |
214 | (_,(Abs(_),_)) => raise Pattern |
208 | (_,(Abs(_),_)) => raise Pattern |
239 if loose_bvar1(f,0) then Abs(a,T,body') |
233 if loose_bvar1(f,0) then Abs(a,T,body') |
240 else incr_boundvars ~1 f |
234 else incr_boundvars ~1 f |
241 | body' => Abs(a,T,body')) |
235 | body' => Abs(a,T,body')) |
242 | eta_contract(f$t) = eta_contract f $ eta_contract t |
236 | eta_contract(f$t) = eta_contract f $ eta_contract t |
243 | eta_contract t = t; |
237 | eta_contract t = t; |
244 |
|
245 |
|
246 (* sharing: |
|
247 local |
|
248 |
|
249 fun eta(Abs(x,T,t)) = |
|
250 (case eta t of |
|
251 None => (case t of |
|
252 f $ Bound 0 => if loose_bvar1(f,0) |
|
253 then None |
|
254 else Some(incr_boundvars ~1 f) |
|
255 | _ => None) |
|
256 | Some(t') => (case t' of |
|
257 f $ Bound 0 => if loose_bvar1(f,0) |
|
258 then Some(Abs(x,T,t')) |
|
259 else Some(incr_boundvars ~1 f) |
|
260 | _ => Some(Abs(x,T,t')))) |
|
261 | eta(s$t) = (case (eta s,eta t) of |
|
262 (None, None) => None |
|
263 | (None, Some t') => Some(s $ t') |
|
264 | (Some s',None) => Some(s' $ t) |
|
265 | (Some s',Some t') => Some(s' $ t')) |
|
266 | eta _ = None |
|
267 |
|
268 in |
|
269 |
|
270 fun eta_contract t = case eta t of None => t | Some(t') => t'; |
|
271 |
|
272 end; *) |
|
273 |
238 |
274 (*Eta-contract a term from outside: just enough to reduce it to an atom |
239 (*Eta-contract a term from outside: just enough to reduce it to an atom |
275 DOESN'T QUITE WORK! |
240 DOESN'T QUITE WORK! |
276 *) |
241 *) |
277 fun eta_contract_atom (t0 as Abs(a, T, body)) = |
242 fun eta_contract_atom (t0 as Abs(a, T, body)) = |