46 type sg = Sign.sg |
47 type sg = Sign.sg |
47 type env = Envir.env |
48 type env = Envir.env |
48 |
49 |
49 exception Unif; |
50 exception Unif; |
50 exception Pattern; |
51 exception Pattern; |
|
52 |
|
53 val trace_unify_fail = ref false; |
|
54 |
|
55 (* Only for communication between unification and error message printing *) |
|
56 val sgr = ref Sign.pre_pure |
|
57 |
|
58 fun string_of_term env binders t = Sign.string_of_term (!sgr) |
|
59 (Envir.norm_term env (subst_bounds(map Free binders,t))); |
|
60 |
|
61 fun bname binders i = fst(nth_elem(i,binders)); |
|
62 fun bnames binders is = space_implode " " (map (bname binders) is); |
|
63 |
|
64 fun norm_typ tye = |
|
65 let fun chase(v,s) = |
|
66 (case Vartab.lookup (tye, v) of |
|
67 Some U => norm_typ tye U |
|
68 | None => TVar(v,s)) |
|
69 in map_type_tvar chase end |
|
70 |
|
71 fun typ_clash(tye,T,U) = |
|
72 if !trace_unify_fail |
|
73 then let val t = Sign.string_of_typ (!sgr) (norm_typ tye T) |
|
74 and u = Sign.string_of_typ (!sgr) (norm_typ tye U) |
|
75 in tracing("The following types do not unify:\n" ^ t ^ "\n" ^ u) end |
|
76 else () |
|
77 |
|
78 fun clash a b = |
|
79 if !trace_unify_fail then tracing("Clash: " ^ a ^ " =/= " ^ b) else () |
|
80 |
|
81 fun boundVar binders i = |
|
82 "bound variable " ^ bname binders i ^ " (depth " ^ string_of_int i ^ ")"; |
|
83 |
|
84 fun clashBB binders i j = |
|
85 if !trace_unify_fail then clash (boundVar binders i) (boundVar binders j) |
|
86 else () |
|
87 |
|
88 fun clashB binders i s = |
|
89 if !trace_unify_fail then clash (boundVar binders i) s |
|
90 else () |
|
91 |
|
92 fun proj_fail(env,binders,F,is,t) = |
|
93 if !trace_unify_fail |
|
94 then let val f = Syntax.string_of_vname F |
|
95 val xs = bnames binders is |
|
96 val u = string_of_term env binders t |
|
97 val ys = bnames binders (loose_bnos t \\ is) |
|
98 in tracing("Cannot unify variable " ^ f ^ |
|
99 " (depending on bound variables " ^ xs ^ ")\nwith term " ^ u ^ |
|
100 "\nTerm contains additional bound variable(s) " ^ ys) |
|
101 end |
|
102 else () |
|
103 |
|
104 fun ocheck_fail(F,t,binders,env) = |
|
105 if !trace_unify_fail |
|
106 then let val f = Syntax.string_of_vname F |
|
107 val u = string_of_term env binders t |
|
108 in tracing("Variable " ^ f ^ " occurs in term\n" ^ u ^ |
|
109 "\nCannot unify!\n") |
|
110 end |
|
111 else () |
51 |
112 |
52 fun occurs(F,t,env) = |
113 fun occurs(F,t,env) = |
53 let fun occ(Var(G,_)) = (case Envir.lookup(env,G) of |
114 let fun occ(Var(G,_)) = (case Envir.lookup(env,G) of |
54 Some(t) => occ t |
115 Some(t) => occ t |
55 | None => F=G) |
116 | None => F=G) |
186 |
247 |
187 fun unify_types(T,U, env as Envir.Envir{asol,iTs,maxidx}) = |
248 fun unify_types(T,U, env as Envir.Envir{asol,iTs,maxidx}) = |
188 if T=U then env |
249 if T=U then env |
189 else let val (iTs',maxidx') = Type.unify (!tsgr) (iTs, maxidx) (U, T) |
250 else let val (iTs',maxidx') = Type.unify (!tsgr) (iTs, maxidx) (U, T) |
190 in Envir.Envir{asol=asol,maxidx=maxidx',iTs=iTs'} end |
251 in Envir.Envir{asol=asol,maxidx=maxidx',iTs=iTs'} end |
191 handle Type.TUNIFY => raise Unif; |
252 handle Type.TUNIFY => (typ_clash(iTs,T,U); raise Unif); |
192 |
253 |
193 fun unif binders (env,(s,t)) = case (Envir.head_norm env s, Envir.head_norm env t) of |
254 fun unif binders (env,(s,t)) = case (Envir.head_norm env s, Envir.head_norm env t) of |
194 (Abs(ns,Ts,ts),Abs(nt,Tt,tt)) => |
255 (Abs(ns,Ts,ts),Abs(nt,Tt,tt)) => |
195 let val name = if ns = "" then nt else ns |
256 let val name = if ns = "" then nt else ns |
196 in unif ((name,Ts)::binders) (env,(ts,tt)) end |
257 in unif ((name,Ts)::binders) (env,(ts,tt)) end |
207 | ((Const c,ss),(Const d,ts)) => rigidrigid(env,binders,c,d,ss,ts) |
268 | ((Const c,ss),(Const d,ts)) => rigidrigid(env,binders,c,d,ss,ts) |
208 | ((Free(f),ss),(Free(g),ts)) => rigidrigid(env,binders,f,g,ss,ts) |
269 | ((Free(f),ss),(Free(g),ts)) => rigidrigid(env,binders,f,g,ss,ts) |
209 | ((Bound(i),ss),(Bound(j),ts)) => rigidrigidB (env,binders,i,j,ss,ts) |
270 | ((Bound(i),ss),(Bound(j),ts)) => rigidrigidB (env,binders,i,j,ss,ts) |
210 | ((Abs(_),_),_) => raise Pattern |
271 | ((Abs(_),_),_) => raise Pattern |
211 | (_,(Abs(_),_)) => raise Pattern |
272 | (_,(Abs(_),_)) => raise Pattern |
212 | _ => raise Unif |
273 | ((Const(c,_),_),(Free(f,_),_)) => (clash c f; raise Unif) |
|
274 | ((Const(c,_),_),(Bound i,_)) => (clashB binders i c; raise Unif) |
|
275 | ((Free(f,_),_),(Const(c,_),_)) => (clash f c; raise Unif) |
|
276 | ((Free(f,_),_),(Bound i,_)) => (clashB binders i f; raise Unif) |
|
277 | ((Bound i,_),(Const(c,_),_)) => (clashB binders i c; raise Unif) |
|
278 | ((Bound i,_),(Free(f,_),_)) => (clashB binders i f; raise Unif) |
|
279 |
213 |
280 |
214 and rigidrigid (env,binders,(a,Ta),(b,Tb),ss,ts) = |
281 and rigidrigid (env,binders,(a,Ta),(b,Tb),ss,ts) = |
215 if a<>b then raise Unif |
282 if a<>b then (clash a b; raise Unif) |
216 else foldl (unif binders) (unify_types(Ta,Tb,env), ss~~ts) |
283 else foldl (unif binders) (unify_types(Ta,Tb,env), ss~~ts) |
217 |
284 |
218 and rigidrigidB (env,binders,i,j,ss,ts) = |
285 and rigidrigidB (env,binders,i,j,ss,ts) = |
219 if i <> j then raise Unif else foldl (unif binders) (env ,ss~~ts) |
286 if i <> j then (clashBB binders i j; raise Unif) |
220 |
287 else foldl (unif binders) (env ,ss~~ts) |
221 and flexrigid (env,binders,F,is,t) = |
288 |
222 if occurs(F,t,env) then raise Unif |
289 and flexrigid (params as (env,binders,F,is,t)) = |
223 else let val (u,env') = proj(t,env,binders,is) |
290 if occurs(F,t,env) then (ocheck_fail(F,t,binders,env); raise Unif) |
224 in Envir.update((F,mkabs(binders,is,u)),env') end; |
291 else (let val (u,env') = proj(t,env,binders,is) |
225 |
292 in Envir.update((F,mkabs(binders,is,u)),env') end |
226 fun unify(sg,env,tus) = (tsgr := #tsig(Sign.rep_sg sg); |
293 handle Unif => (proj_fail params; raise Unif)); |
|
294 |
|
295 fun unify(sg,env,tus) = (sgr := sg; tsgr := #tsig(Sign.rep_sg sg); |
227 foldl (unif []) (env,tus)); |
296 foldl (unif []) (env,tus)); |
228 |
297 |
229 |
298 |
230 (*Eta-contract a term (fully)*) |
299 (*Eta-contract a term (fully)*) |
231 |
300 |