src/Pure/unify.ML
changeset 16622 f90894e13a3e
parent 16602 0eda2f8a74aa
child 16664 7b2e29dcd349
equal deleted inserted replaced
16621:78b32293a8b1 16622:f90894e13a3e
    33 val trace_bound = ref 25	(*tracing starts above this depth, 0 for full*)
    33 val trace_bound = ref 25	(*tracing starts above this depth, 0 for full*)
    34 and search_bound = ref 30	(*unification quits above this depth*)
    34 and search_bound = ref 30	(*unification quits above this depth*)
    35 and trace_simp = ref false	(*print dpairs before calling SIMPL*)
    35 and trace_simp = ref false	(*print dpairs before calling SIMPL*)
    36 and trace_types = ref false	(*announce potential incompleteness
    36 and trace_types = ref false	(*announce potential incompleteness
    37 				  of type unification*)
    37 				  of type unification*)
       
    38 
       
    39 val thy_ref = ref (NONE: theory option);
       
    40 fun thy () = the (! thy_ref);
    38 
    41 
    39 type binderlist = (string*typ) list;
    42 type binderlist = (string*typ) list;
    40 
    43 
    41 type dpair = binderlist * term * term;
    44 type dpair = binderlist * term * term;
    42 
    45 
   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