172 |
175 |
173 exception CANTUNIFY; (*Signals non-unifiability. Does not signal errors!*) |
176 exception CANTUNIFY; (*Signals non-unifiability. Does not signal errors!*) |
174 exception ASSIGN; (*Raised if not an assignment*) |
177 exception ASSIGN; (*Raised if not an assignment*) |
175 |
178 |
176 |
179 |
177 fun unify_types thy (T,U, env as Envir.Envir{asol,iTs,maxidx}) = |
180 fun unify_types(T,U, env as Envir.Envir{asol,iTs,maxidx}) = |
178 if T=U then env |
181 if T=U then env |
179 else let val (iTs',maxidx') = Type.unify (Sign.tsig_of thy) (iTs, maxidx) (U, T) |
182 else let val (iTs',maxidx') = Type.unify (Sign.tsig_of (thy ())) (iTs, maxidx) (U, T) |
180 in Envir.Envir{asol=asol,maxidx=maxidx',iTs=iTs'} end |
183 in Envir.Envir{asol=asol,maxidx=maxidx',iTs=iTs'} end |
181 handle Type.TUNIFY => raise CANTUNIFY; |
184 handle Type.TUNIFY => raise CANTUNIFY; |
182 |
185 |
183 fun test_unify_types thy (args as (T,U,_)) = |
186 fun test_unify_types(args as (T,U,_)) = |
184 let val str_of = Sign.string_of_typ thy; |
187 let val sot = Sign.string_of_typ (thy ()); |
185 fun warn() = tracing ("Potential loss of completeness: " ^ str_of U ^ " = " ^ str_of T); |
188 fun warn() = tracing ("Potential loss of completeness: "^sot U^" = "^sot T); |
186 val env' = unify_types thy args |
189 val env' = unify_types(args) |
187 in if is_TVar(T) orelse is_TVar(U) then warn() else (); |
190 in if is_TVar(T) orelse is_TVar(U) then warn() else (); |
188 env' |
191 env' |
189 end; |
192 end; |
190 |
193 |
191 (*Is the term eta-convertible to a single variable with the given rbinder? |
194 (*Is the term eta-convertible to a single variable with the given rbinder? |
204 |
207 |
205 |
208 |
206 (*Solve v=u by assignment -- "fixedpoint" to Huet -- if v not in u. |
209 (*Solve v=u by assignment -- "fixedpoint" to Huet -- if v not in u. |
207 If v occurs rigidly then nonunifiable. |
210 If v occurs rigidly then nonunifiable. |
208 If v occurs nonrigidly then must use full algorithm. *) |
211 If v occurs nonrigidly then must use full algorithm. *) |
209 fun assignment thy (env, rbinder, t, u) = |
212 fun assignment (env, rbinder, t, u) = |
210 let val vT as (v,T) = get_eta_var (rbinder, 0, t) |
213 let val vT as (v,T) = get_eta_var (rbinder, 0, t) |
211 in case rigid_occurs_term (ref [], env, v, u) of |
214 in case rigid_occurs_term (ref [], env, v, u) of |
212 NoOcc => let val env = unify_types thy (body_type env T, |
215 NoOcc => let val env = unify_types(body_type env T, |
213 fastype env (rbinder,u),env) |
216 fastype env (rbinder,u),env) |
214 in Envir.update ((vT, rlist_abs (rbinder, u)), env) end |
217 in Envir.update ((vT, rlist_abs (rbinder, u)), env) end |
215 | Nonrigid => raise ASSIGN |
218 | Nonrigid => raise ASSIGN |
216 | Rigid => raise CANTUNIFY |
219 | Rigid => raise CANTUNIFY |
217 end; |
220 end; |
220 (*Extends an rbinder with a new disagreement pair, if both are abstractions. |
223 (*Extends an rbinder with a new disagreement pair, if both are abstractions. |
221 Tries to unify types of the bound variables! |
224 Tries to unify types of the bound variables! |
222 Checks that binders have same length, since terms should be eta-normal; |
225 Checks that binders have same length, since terms should be eta-normal; |
223 if not, raises TERM, probably indicating type mismatch. |
226 if not, raises TERM, probably indicating type mismatch. |
224 Uses variable a (unless the null string) to preserve user's naming.*) |
227 Uses variable a (unless the null string) to preserve user's naming.*) |
225 fun new_dpair thy (rbinder, Abs(a,T,body1), Abs(b,U,body2), env) = |
228 fun new_dpair (rbinder, Abs(a,T,body1), Abs(b,U,body2), env) = |
226 let val env' = unify_types thy (T,U,env) |
229 let val env' = unify_types(T,U,env) |
227 val c = if a="" then b else a |
230 val c = if a="" then b else a |
228 in new_dpair thy ((c,T) :: rbinder, body1, body2, env') end |
231 in new_dpair((c,T) :: rbinder, body1, body2, env') end |
229 | new_dpair _ (_, Abs _, _, _) = raise TERM ("new_dpair", []) |
232 | new_dpair (_, Abs _, _, _) = raise TERM ("new_dpair", []) |
230 | new_dpair _ (_, _, Abs _, _) = raise TERM ("new_dpair", []) |
233 | new_dpair (_, _, Abs _, _) = raise TERM ("new_dpair", []) |
231 | new_dpair _ (rbinder, t1, t2, env) = ((rbinder, t1, t2), env); |
234 | new_dpair (rbinder, t1, t2, env) = ((rbinder, t1, t2), env); |
232 |
235 |
233 |
236 |
234 fun head_norm_dpair thy (env, (rbinder,t,u)) : dpair * Envir.env = |
237 fun head_norm_dpair (env, (rbinder,t,u)) : dpair * Envir.env = |
235 new_dpair thy (rbinder, |
238 new_dpair (rbinder, |
236 eta_norm env (rbinder, Envir.head_norm env t), |
239 eta_norm env (rbinder, Envir.head_norm env t), |
237 eta_norm env (rbinder, Envir.head_norm env u), env); |
240 eta_norm env (rbinder, Envir.head_norm env u), env); |
238 |
241 |
239 |
242 |
240 |
243 |
242 Does not perform assignments for flex-flex pairs: |
245 Does not perform assignments for flex-flex pairs: |
243 may create nonrigid paths, which prevent other assignments. |
246 may create nonrigid paths, which prevent other assignments. |
244 Does not even identify Vars in dpairs such as ?a =?= ?b; an attempt to |
247 Does not even identify Vars in dpairs such as ?a =?= ?b; an attempt to |
245 do so caused numerous problems with no compensating advantage. |
248 do so caused numerous problems with no compensating advantage. |
246 *) |
249 *) |
247 fun SIMPL0 thy (dp0, (env,flexflex,flexrigid)) |
250 fun SIMPL0 (dp0, (env,flexflex,flexrigid)) |
248 : Envir.env * dpair list * dpair list = |
251 : Envir.env * dpair list * dpair list = |
249 let val (dp as (rbinder,t,u), env) = head_norm_dpair thy (env,dp0); |
252 let val (dp as (rbinder,t,u), env) = head_norm_dpair(env,dp0); |
250 fun SIMRANDS(f$t, g$u, env) = |
253 fun SIMRANDS(f$t, g$u, env) = |
251 SIMPL0 thy ((rbinder,t,u), SIMRANDS(f,g,env)) |
254 SIMPL0((rbinder,t,u), SIMRANDS(f,g,env)) |
252 | SIMRANDS (t as _$_, _, _) = |
255 | SIMRANDS (t as _$_, _, _) = |
253 raise TERM ("SIMPL: operands mismatch", [t,u]) |
256 raise TERM ("SIMPL: operands mismatch", [t,u]) |
254 | SIMRANDS (t, u as _$_, _) = |
257 | SIMRANDS (t, u as _$_, _) = |
255 raise TERM ("SIMPL: operands mismatch", [t,u]) |
258 raise TERM ("SIMPL: operands mismatch", [t,u]) |
256 | SIMRANDS(_,_,env) = (env,flexflex,flexrigid); |
259 | SIMRANDS(_,_,env) = (env,flexflex,flexrigid); |
257 in case (head_of t, head_of u) of |
260 in case (head_of t, head_of u) of |
258 (Var(_,T), Var(_,U)) => |
261 (Var(_,T), Var(_,U)) => |
259 let val T' = body_type env T and U' = body_type env U; |
262 let val T' = body_type env T and U' = body_type env U; |
260 val env = unify_types thy (T',U',env) |
263 val env = unify_types(T',U',env) |
261 in (env, dp::flexflex, flexrigid) end |
264 in (env, dp::flexflex, flexrigid) end |
262 | (Var _, _) => |
265 | (Var _, _) => |
263 ((assignment thy (env,rbinder,t,u), flexflex, flexrigid) |
266 ((assignment (env,rbinder,t,u), flexflex, flexrigid) |
264 handle ASSIGN => (env, flexflex, dp::flexrigid)) |
267 handle ASSIGN => (env, flexflex, dp::flexrigid)) |
265 | (_, Var _) => |
268 | (_, Var _) => |
266 ((assignment thy (env,rbinder,u,t), flexflex, flexrigid) |
269 ((assignment (env,rbinder,u,t), flexflex, flexrigid) |
267 handle ASSIGN => (env, flexflex, (rbinder,u,t)::flexrigid)) |
270 handle ASSIGN => (env, flexflex, (rbinder,u,t)::flexrigid)) |
268 | (Const(a,T), Const(b,U)) => |
271 | (Const(a,T), Const(b,U)) => |
269 if a=b then SIMRANDS(t,u, unify_types thy (T,U,env)) |
272 if a=b then SIMRANDS(t,u, unify_types(T,U,env)) |
270 else raise CANTUNIFY |
273 else raise CANTUNIFY |
271 | (Bound i, Bound j) => |
274 | (Bound i, Bound j) => |
272 if i=j then SIMRANDS(t,u,env) else raise CANTUNIFY |
275 if i=j then SIMRANDS(t,u,env) else raise CANTUNIFY |
273 | (Free(a,T), Free(b,U)) => |
276 | (Free(a,T), Free(b,U)) => |
274 if a=b then SIMRANDS(t,u, unify_types thy (T,U,env)) |
277 if a=b then SIMRANDS(t,u, unify_types(T,U,env)) |
275 else raise CANTUNIFY |
278 else raise CANTUNIFY |
276 | _ => raise CANTUNIFY |
279 | _ => raise CANTUNIFY |
277 end; |
280 end; |
278 |
281 |
279 |
282 |
284 | changed _ = false; |
287 | changed _ = false; |
285 |
288 |
286 |
289 |
287 (*Recursion needed if any of the 'head variables' have been updated |
290 (*Recursion needed if any of the 'head variables' have been updated |
288 Clever would be to re-do just the affected dpairs*) |
291 Clever would be to re-do just the affected dpairs*) |
289 fun SIMPL thy (env,dpairs) : Envir.env * dpair list * dpair list = |
292 fun SIMPL (env,dpairs) : Envir.env * dpair list * dpair list = |
290 let val all as (env',flexflex,flexrigid) = |
293 let val all as (env',flexflex,flexrigid) = |
291 foldr (SIMPL0 thy) (env,[],[]) dpairs; |
294 foldr SIMPL0 (env,[],[]) dpairs; |
292 val dps = flexrigid@flexflex |
295 val dps = flexrigid@flexflex |
293 in if exists (fn ((_,t,u)) => changed(env',t) orelse changed(env',u)) dps |
296 in if exists (fn ((_,t,u)) => changed(env',t) orelse changed(env',u)) dps |
294 then SIMPL thy (env',dps) else all |
297 then SIMPL(env',dps) else all |
295 end; |
298 end; |
296 |
299 |
297 |
300 |
298 (*computes t(Bound(n+k-1),...,Bound(n)) *) |
301 (*computes t(Bound(n+k-1),...,Bound(n)) *) |
299 fun combound (t, n, k) = |
302 fun combound (t, n, k) = |
327 or if u is a variable (flex-flex dpair). |
330 or if u is a variable (flex-flex dpair). |
328 Returns long sequence of every way of copying u, for backtracking |
331 Returns long sequence of every way of copying u, for backtracking |
329 For example, projection in ?b'(?a) may be wrong if other dpairs constrain ?a. |
332 For example, projection in ?b'(?a) may be wrong if other dpairs constrain ?a. |
330 The order for trying projections is crucial in ?b'(?a) |
333 The order for trying projections is crucial in ?b'(?a) |
331 NB "vname" is only used in the call to make_args!! *) |
334 NB "vname" is only used in the call to make_args!! *) |
332 fun matchcopy thy vname = let fun mc(rbinder, targs, u, ed as (env,dpairs)) |
335 fun matchcopy vname = let fun mc(rbinder, targs, u, ed as (env,dpairs)) |
333 : (term * (Envir.env * dpair list))Seq.seq = |
336 : (term * (Envir.env * dpair list))Seq.seq = |
334 let (*Produce copies of uarg and cons them in front of uargs*) |
337 let (*Produce copies of uarg and cons them in front of uargs*) |
335 fun copycons uarg (uargs, (env, dpairs)) = |
338 fun copycons uarg (uargs, (env, dpairs)) = |
336 Seq.map(fn (uarg', ed') => (uarg'::uargs, ed')) |
339 Seq.map(fn (uarg', ed') => (uarg'::uargs, ed')) |
337 (mc (rbinder, targs,eta_norm env (rbinder, Envir.head_norm env uarg), |
340 (mc (rbinder, targs,eta_norm env (rbinder, Envir.head_norm env uarg), |
344 val base = body_type env (fastype env (rbinder,uhead)); |
347 val base = body_type env (fastype env (rbinder,uhead)); |
345 fun joinargs (uargs',ed') = (list_comb(uhead,uargs'), ed'); |
348 fun joinargs (uargs',ed') = (list_comb(uhead,uargs'), ed'); |
346 (*attempt projection on argument with given typ*) |
349 (*attempt projection on argument with given typ*) |
347 val Ts = map (curry (fastype env) rbinder) targs; |
350 val Ts = map (curry (fastype env) rbinder) targs; |
348 fun projenv (head, (Us,bary), targ, tail) = |
351 fun projenv (head, (Us,bary), targ, tail) = |
349 let val env = if !trace_types then test_unify_types thy (base,bary,env) |
352 let val env = if !trace_types then test_unify_types(base,bary,env) |
350 else unify_types thy (base,bary,env) |
353 else unify_types(base,bary,env) |
351 in Seq.make (fn () => |
354 in Seq.make (fn () => |
352 let val (env',args) = make_args vname (Ts,env,Us); |
355 let val (env',args) = make_args vname (Ts,env,Us); |
353 (*higher-order projection: plug in targs for bound vars*) |
356 (*higher-order projection: plug in targs for bound vars*) |
354 fun plugin arg = list_comb(head_of arg, targs); |
357 fun plugin arg = list_comb(head_of arg, targs); |
355 val dp = (rbinder, list_comb(targ, map plugin args), u); |
358 val dp = (rbinder, list_comb(targ, map plugin args), u); |
356 val (env2,frigid,fflex) = SIMPL thy (env', dp::dpairs) |
359 val (env2,frigid,fflex) = SIMPL (env', dp::dpairs) |
357 (*may raise exception CANTUNIFY*) |
360 (*may raise exception CANTUNIFY*) |
358 in SOME ((list_comb(head,args), (env2, frigid@fflex)), |
361 in SOME ((list_comb(head,args), (env2, frigid@fflex)), |
359 tail) |
362 tail) |
360 end handle CANTUNIFY => Seq.pull tail) |
363 end handle CANTUNIFY => Seq.pull tail) |
361 end handle CANTUNIFY => tail; |
364 end handle CANTUNIFY => tail; |
388 end |
391 end |
389 in mc end; |
392 in mc end; |
390 |
393 |
391 |
394 |
392 (*Call matchcopy to produce assignments to the variable in the dpair*) |
395 (*Call matchcopy to produce assignments to the variable in the dpair*) |
393 fun MATCH thy (env, (rbinder,t,u), dpairs) |
396 fun MATCH (env, (rbinder,t,u), dpairs) |
394 : (Envir.env * dpair list)Seq.seq = |
397 : (Envir.env * dpair list)Seq.seq = |
395 let val (Var (vT as (v, T)), targs) = strip_comb t; |
398 let val (Var (vT as (v, T)), targs) = strip_comb t; |
396 val Ts = binder_types env T; |
399 val Ts = binder_types env T; |
397 fun new_dset (u', (env',dpairs')) = |
400 fun new_dset (u', (env',dpairs')) = |
398 (*if v was updated to s, must unify s with u' *) |
401 (*if v was updated to s, must unify s with u' *) |
399 case Envir.lookup (env', vT) of |
402 case Envir.lookup (env', vT) of |
400 NONE => (Envir.update ((vT, types_abs(Ts, u')), env'), dpairs') |
403 NONE => (Envir.update ((vT, types_abs(Ts, u')), env'), dpairs') |
401 | SOME s => (env', ([], s, types_abs(Ts, u'))::dpairs') |
404 | SOME s => (env', ([], s, types_abs(Ts, u'))::dpairs') |
402 in Seq.map new_dset |
405 in Seq.map new_dset |
403 (matchcopy thy (#1 v) (rbinder, targs, u, (env,dpairs))) |
406 (matchcopy (#1 v) (rbinder, targs, u, (env,dpairs))) |
404 end; |
407 end; |
405 |
408 |
406 |
409 |
407 |
410 |
408 (**** Flex-flex processing ****) |
411 (**** Flex-flex processing ****) |
409 |
412 |
410 (*At end of unification, do flex-flex assignments like ?a -> ?f(?b) |
413 (*At end of unification, do flex-flex assignments like ?a -> ?f(?b) |
411 Attempts to update t with u, raising ASSIGN if impossible*) |
414 Attempts to update t with u, raising ASSIGN if impossible*) |
412 fun ff_assign thy (env, rbinder, t, u) : Envir.env = |
415 fun ff_assign(env, rbinder, t, u) : Envir.env = |
413 let val vT as (v,T) = get_eta_var(rbinder,0,t) |
416 let val vT as (v,T) = get_eta_var(rbinder,0,t) |
414 in if occurs_terms (ref [], env, v, [u]) then raise ASSIGN |
417 in if occurs_terms (ref [], env, v, [u]) then raise ASSIGN |
415 else let val env = unify_types thy (body_type env T, |
418 else let val env = unify_types(body_type env T, |
416 fastype env (rbinder,u), |
419 fastype env (rbinder,u), |
417 env) |
420 env) |
418 in Envir.vupdate ((vT, rlist_abs (rbinder, u)), env) end |
421 in Envir.vupdate ((vT, rlist_abs (rbinder, u)), env) end |
419 end; |
422 end; |
420 |
423 |
509 in if exists same tpairs then tpairs else (t,u)::tpairs end; |
512 in if exists same tpairs then tpairs else (t,u)::tpairs end; |
510 |
513 |
511 |
514 |
512 (*Simplify both terms and check for assignments. |
515 (*Simplify both terms and check for assignments. |
513 Bound vars in the binder are "banned" unless used in both t AND u *) |
516 Bound vars in the binder are "banned" unless used in both t AND u *) |
514 fun clean_ffpair thy ((rbinder, t, u), (env,tpairs)) = |
517 fun clean_ffpair ((rbinder, t, u), (env,tpairs)) = |
515 let val loot = loose_bnos t and loou = loose_bnos u |
518 let val loot = loose_bnos t and loou = loose_bnos u |
516 fun add_index (((a,T), j), (bnos, newbinder)) = |
519 fun add_index (((a,T), j), (bnos, newbinder)) = |
517 if j mem_int loot andalso j mem_int loou |
520 if j mem_int loot andalso j mem_int loou |
518 then (bnos, (a,T)::newbinder) (*needed by both: keep*) |
521 then (bnos, (a,T)::newbinder) (*needed by both: keep*) |
519 else (j::bnos, newbinder); (*remove*) |
522 else (j::bnos, newbinder); (*remove*) |
520 val indices = 0 upto (length rbinder - 1); |
523 val indices = 0 upto (length rbinder - 1); |
521 val (banned,rbin') = foldr add_index ([],[]) (rbinder~~indices); |
524 val (banned,rbin') = foldr add_index ([],[]) (rbinder~~indices); |
522 val (env', t') = clean_term banned (env, t); |
525 val (env', t') = clean_term banned (env, t); |
523 val (env'',u') = clean_term banned (env',u) |
526 val (env'',u') = clean_term banned (env',u) |
524 in (ff_assign thy (env'', rbin', t', u'), tpairs) |
527 in (ff_assign(env'', rbin', t', u'), tpairs) |
525 handle ASSIGN => (ff_assign thy (env'', rbin', u', t'), tpairs) |
528 handle ASSIGN => (ff_assign(env'', rbin', u', t'), tpairs) |
526 handle ASSIGN => (env'', add_tpair(rbin', (t',u'), tpairs)) |
529 handle ASSIGN => (env'', add_tpair(rbin', (t',u'), tpairs)) |
527 end |
530 end |
528 handle CHANGE_FAIL => (env, add_tpair(rbinder, (t,u), tpairs)); |
531 handle CHANGE_FAIL => (env, add_tpair(rbinder, (t,u), tpairs)); |
529 |
532 |
530 |
533 |
531 (*IF the flex-flex dpair is an assignment THEN do it ELSE put in tpairs |
534 (*IF the flex-flex dpair is an assignment THEN do it ELSE put in tpairs |
532 eliminates trivial tpairs like t=t, as well as repeated ones |
535 eliminates trivial tpairs like t=t, as well as repeated ones |
533 trivial tpairs can easily escape SIMPL: ?A=t, ?A=?B, ?B=t gives t=t |
536 trivial tpairs can easily escape SIMPL: ?A=t, ?A=?B, ?B=t gives t=t |
534 Resulting tpairs MAY NOT be in normal form: assignments may occur here.*) |
537 Resulting tpairs MAY NOT be in normal form: assignments may occur here.*) |
535 fun add_ffpair thy ((rbinder,t0,u0), (env,tpairs)) |
538 fun add_ffpair ((rbinder,t0,u0), (env,tpairs)) |
536 : Envir.env * (term*term)list = |
539 : Envir.env * (term*term)list = |
537 let val t = Envir.norm_term env t0 and u = Envir.norm_term env u0 |
540 let val t = Envir.norm_term env t0 and u = Envir.norm_term env u0 |
538 in case (head_of t, head_of u) of |
541 in case (head_of t, head_of u) of |
539 (Var(v,T), Var(w,U)) => (*Check for identical variables...*) |
542 (Var(v,T), Var(w,U)) => (*Check for identical variables...*) |
540 if eq_ix(v,w) then (*...occur check would falsely return true!*) |
543 if eq_ix(v,w) then (*...occur check would falsely return true!*) |
541 if T=U then (env, add_tpair (rbinder, (t,u), tpairs)) |
544 if T=U then (env, add_tpair (rbinder, (t,u), tpairs)) |
542 else raise TERM ("add_ffpair: Var name confusion", [t,u]) |
545 else raise TERM ("add_ffpair: Var name confusion", [t,u]) |
543 else if xless(v,w) then (*prefer to update the LARGER variable*) |
546 else if xless(v,w) then (*prefer to update the LARGER variable*) |
544 clean_ffpair thy ((rbinder, u, t), (env,tpairs)) |
547 clean_ffpair ((rbinder, u, t), (env,tpairs)) |
545 else clean_ffpair thy ((rbinder, t, u), (env,tpairs)) |
548 else clean_ffpair ((rbinder, t, u), (env,tpairs)) |
546 | _ => raise TERM ("add_ffpair: Vars expected", [t,u]) |
549 | _ => raise TERM ("add_ffpair: Vars expected", [t,u]) |
547 end; |
550 end; |
548 |
551 |
549 |
552 |
550 (*Print a tracing message + list of dpairs. |
553 (*Print a tracing message + list of dpairs. |
551 In t==u print u first because it may be rigid or flexible -- |
554 In t==u print u first because it may be rigid or flexible -- |
552 t is always flexible.*) |
555 t is always flexible.*) |
553 fun print_dpairs thy msg (env,dpairs) = |
556 fun print_dpairs msg (env,dpairs) = |
554 let fun pdp (rbinder,t,u) = |
557 let fun pdp (rbinder,t,u) = |
555 let fun termT t = Sign.pretty_term thy |
558 let fun termT t = Sign.pretty_term (thy ()) |
556 (Envir.norm_term env (rlist_abs(rbinder,t))) |
559 (Envir.norm_term env (rlist_abs(rbinder,t))) |
557 val bsymbs = [termT u, Pretty.str" =?=", Pretty.brk 1, |
560 val bsymbs = [termT u, Pretty.str" =?=", Pretty.brk 1, |
558 termT t]; |
561 termT t]; |
559 in tracing(Pretty.string_of(Pretty.blk(0,bsymbs))) end; |
562 in tracing(Pretty.string_of(Pretty.blk(0,bsymbs))) end; |
560 in tracing msg; List.app pdp dpairs end; |
563 in tracing msg; List.app pdp dpairs end; |
567 : (Envir.env * (term*term)list)Seq.seq = |
570 : (Envir.env * (term*term)list)Seq.seq = |
568 let fun add_unify tdepth ((env,dpairs), reseq) = |
571 let fun add_unify tdepth ((env,dpairs), reseq) = |
569 Seq.make (fn()=> |
572 Seq.make (fn()=> |
570 let val (env',flexflex,flexrigid) = |
573 let val (env',flexflex,flexrigid) = |
571 (if tdepth> !trace_bound andalso !trace_simp |
574 (if tdepth> !trace_bound andalso !trace_simp |
572 then print_dpairs thy "Enter SIMPL" (env,dpairs) else (); |
575 then print_dpairs "Enter SIMPL" (env,dpairs) else (); |
573 SIMPL thy (env,dpairs)) |
576 SIMPL (env,dpairs)) |
574 in case flexrigid of |
577 in case flexrigid of |
575 [] => SOME (foldr (add_ffpair thy) (env',[]) flexflex, reseq) |
578 [] => SOME (foldr add_ffpair (env',[]) flexflex, reseq) |
576 | dp::frigid' => |
579 | dp::frigid' => |
577 if tdepth > !search_bound then |
580 if tdepth > !search_bound then |
578 (warning "Unification bound exceeded"; Seq.pull reseq) |
581 (warning "Unification bound exceeded"; Seq.pull reseq) |
579 else |
582 else |
580 (if tdepth > !trace_bound then |
583 (if tdepth > !trace_bound then |
581 print_dpairs thy "Enter MATCH" (env',flexrigid@flexflex) |
584 print_dpairs "Enter MATCH" (env',flexrigid@flexflex) |
582 else (); |
585 else (); |
583 Seq.pull (Seq.it_right (add_unify (tdepth+1)) |
586 Seq.pull (Seq.it_right (add_unify (tdepth+1)) |
584 (MATCH thy (env',dp, frigid'@flexflex), reseq))) |
587 (MATCH (env',dp, frigid'@flexflex), reseq))) |
585 end |
588 end |
586 handle CANTUNIFY => |
589 handle CANTUNIFY => |
587 (if tdepth > !trace_bound then tracing"Failure node" else (); |
590 (if tdepth > !trace_bound then tracing"Failure node" else (); |
588 Seq.pull reseq)); |
591 Seq.pull reseq)); |
589 val dps = map (fn(t,u)=> ([],t,u)) tus |
592 val dps = map (fn(t,u)=> ([],t,u)) tus |
|
593 val _ = thy_ref := SOME thy; |
590 in add_unify 1 ((env, dps), Seq.empty) end; |
594 in add_unify 1 ((env, dps), Seq.empty) end; |
591 |
595 |
592 fun unifiers params = |
596 fun unifiers params = |
593 Seq.cons ((Pattern.unify params, []), Seq.empty) |
597 Seq.cons ((Pattern.unify params, []), Seq.empty) |
594 handle Pattern.Unif => Seq.empty |
598 handle Pattern.Unif => Seq.empty |