src/Pure/unify.ML
changeset 15570 8d8c70b41bab
parent 15531 08c8dad8e399
child 15574 b1d1b5bfc464
equal deleted inserted replaced
15569:1b3115d1a8df 15570:8d8c70b41bab
   289 
   289 
   290 (*Recursion needed if any of the 'head variables' have been updated
   290 (*Recursion needed if any of the 'head variables' have been updated
   291   Clever would be to re-do just the affected dpairs*)
   291   Clever would be to re-do just the affected dpairs*)
   292 fun SIMPL (env,dpairs) : Envir.env * dpair list * dpair list =
   292 fun SIMPL (env,dpairs) : Envir.env * dpair list * dpair list =
   293     let val all as (env',flexflex,flexrigid) =
   293     let val all as (env',flexflex,flexrigid) =
   294 	    foldr SIMPL0 (dpairs, (env,[],[]));
   294 	    Library.foldr SIMPL0 (dpairs, (env,[],[]));
   295 	val dps = flexrigid@flexflex
   295 	val dps = flexrigid@flexflex
   296     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
   297        then SIMPL(env',dps) else all
   297        then SIMPL(env',dps) else all
   298     end;
   298     end;
   299 
   299 
   456 fun change_bnos banned =
   456 fun change_bnos banned =
   457   let fun change lev (Bound i) = 
   457   let fun change lev (Bound i) = 
   458 	    if i<lev then Bound i
   458 	    if i<lev then Bound i
   459 	    else  if (i-lev) mem_int banned  
   459 	    else  if (i-lev) mem_int banned  
   460 		  then raise CHANGE_FAIL (**flexible occurrence: give up**)
   460 		  then raise CHANGE_FAIL (**flexible occurrence: give up**)
   461 	    else  Bound (i - length (filter (fn j => j < i-lev) banned))
   461 	    else  Bound (i - length (List.filter (fn j => j < i-lev) banned))
   462 	| change lev (Abs (a,T,t)) = Abs (a, T, change(lev+1) t)
   462 	| change lev (Abs (a,T,t)) = Abs (a, T, change(lev+1) t)
   463 	| change lev (t$u) = change lev t $ change lev u
   463 	| change lev (t$u) = change lev t $ change lev u
   464 	| change lev t = t
   464 	| change lev t = t
   465   in  change 0  end;
   465   in  change 0  end;
   466 
   466 
   486 fun clean_term banned (env,t) =
   486 fun clean_term banned (env,t) =
   487     let val (Var(v,T), ts) = strip_comb t
   487     let val (Var(v,T), ts) = strip_comb t
   488 	val (Ts,U) = strip_type env T
   488 	val (Ts,U) = strip_type env T
   489 	and js = length ts - 1  downto 0
   489 	and js = length ts - 1  downto 0
   490 	val args = sort (make_ord arg_less)
   490 	val args = sort (make_ord arg_less)
   491 		(foldr (change_arg banned) (flexargs (js,ts,Ts), []))
   491 		(Library.foldr (change_arg banned) (flexargs (js,ts,Ts), []))
   492 	val ts' = map (#t) args
   492 	val ts' = map (#t) args
   493     in
   493     in
   494     if decreasing (length Ts) args then (env, (list_comb(Var(v,T), ts')))
   494     if decreasing (length Ts) args then (env, (list_comb(Var(v,T), ts')))
   495     else let val (env',v') = Envir.genvar (#1v) (env, map (#T) args ---> U)
   495     else let val (env',v') = Envir.genvar (#1v) (env, map (#T) args ---> U)
   496 	     val body = list_comb(v', map (Bound o #j) args)
   496 	     val body = list_comb(v', map (Bound o #j) args)
   519       fun add_index (((a,T), j), (bnos, newbinder)) = 
   519       fun add_index (((a,T), j), (bnos, newbinder)) = 
   520             if  j mem_int loot  andalso  j mem_int loou 
   520             if  j mem_int loot  andalso  j mem_int loou 
   521             then  (bnos, (a,T)::newbinder)	(*needed by both: keep*)
   521             then  (bnos, (a,T)::newbinder)	(*needed by both: keep*)
   522             else  (j::bnos, newbinder);		(*remove*)
   522             else  (j::bnos, newbinder);		(*remove*)
   523       val indices = 0 upto (length rbinder - 1);
   523       val indices = 0 upto (length rbinder - 1);
   524       val (banned,rbin') = foldr add_index (rbinder~~indices, ([],[]));
   524       val (banned,rbin') = Library.foldr add_index (rbinder~~indices, ([],[]));
   525       val (env', t') = clean_term banned (env, t);
   525       val (env', t') = clean_term banned (env, t);
   526       val (env'',u') = clean_term banned (env',u)
   526       val (env'',u') = clean_term banned (env',u)
   527   in  (ff_assign(env'', rbin', t', u'), tpairs)
   527   in  (ff_assign(env'', rbin', t', u'), tpairs)
   528       handle ASSIGN => (ff_assign(env'', rbin', u', t'), tpairs)
   528       handle ASSIGN => (ff_assign(env'', rbin', u', t'), tpairs)
   529       handle ASSIGN => (env'', add_tpair(rbin', (t',u'), tpairs))
   529       handle ASSIGN => (env'', add_tpair(rbin', (t',u'), tpairs))
   558         let fun termT t = Sign.pretty_term (!sgr)
   558         let fun termT t = Sign.pretty_term (!sgr)
   559                               (Envir.norm_term env (rlist_abs(rbinder,t)))
   559                               (Envir.norm_term env (rlist_abs(rbinder,t)))
   560             val bsymbs = [termT u, Pretty.str" =?=", Pretty.brk 1,
   560             val bsymbs = [termT u, Pretty.str" =?=", Pretty.brk 1,
   561                           termT t];
   561                           termT t];
   562         in tracing(Pretty.string_of(Pretty.blk(0,bsymbs))) end;
   562         in tracing(Pretty.string_of(Pretty.blk(0,bsymbs))) end;
   563   in  tracing msg;  seq pdp dpairs  end;
   563   in  tracing msg;  List.app pdp dpairs  end;
   564 
   564 
   565 
   565 
   566 (*Unify the dpairs in the environment.
   566 (*Unify the dpairs in the environment.
   567   Returns flex-flex disagreement pairs NOT IN normal form. 
   567   Returns flex-flex disagreement pairs NOT IN normal form. 
   568   SIMPL may raise exception CANTUNIFY. *)
   568   SIMPL may raise exception CANTUNIFY. *)
   573 	  let val (env',flexflex,flexrigid) = 
   573 	  let val (env',flexflex,flexrigid) = 
   574 	       (if tdepth> !trace_bound andalso !trace_simp
   574 	       (if tdepth> !trace_bound andalso !trace_simp
   575 		then print_dpairs "Enter SIMPL" (env,dpairs)  else ();
   575 		then print_dpairs "Enter SIMPL" (env,dpairs)  else ();
   576 		SIMPL (env,dpairs))
   576 		SIMPL (env,dpairs))
   577 	  in case flexrigid of
   577 	  in case flexrigid of
   578 	      [] => SOME (foldr add_ffpair (flexflex, (env',[])), reseq)
   578 	      [] => SOME (Library.foldr add_ffpair (flexflex, (env',[])), reseq)
   579 	    | dp::frigid' => 
   579 	    | dp::frigid' => 
   580 		if tdepth > !search_bound then
   580 		if tdepth > !search_bound then
   581 		    (warning "Unification bound exceeded"; Seq.pull reseq)
   581 		    (warning "Unification bound exceeded"; Seq.pull reseq)
   582 		else
   582 		else
   583 		(if tdepth > !trace_bound then
   583 		(if tdepth > !trace_bound then
   624   end;
   624   end;
   625 
   625 
   626 
   626 
   627 (*Smash all flex-flexpairs.  Should allow selection of pairs by a predicate?*)
   627 (*Smash all flex-flexpairs.  Should allow selection of pairs by a predicate?*)
   628 fun smash_flexflex (env,tpairs) : Envir.env =
   628 fun smash_flexflex (env,tpairs) : Envir.env =
   629   foldr smash_flexflex1 (tpairs, env);
   629   Library.foldr smash_flexflex1 (tpairs, env);
   630 
   630 
   631 (*Returns unifiers with no remaining disagreement pairs*)
   631 (*Returns unifiers with no remaining disagreement pairs*)
   632 fun smash_unifiers (sg, env, tus) : Envir.env Seq.seq =
   632 fun smash_unifiers (sg, env, tus) : Envir.env Seq.seq =
   633     Seq.map smash_flexflex (unifiers(sg,env,tus));
   633     Seq.map smash_flexflex (unifiers(sg,env,tus));
   634 
   634