src/Pure/unify.ML
changeset 12231 4a25f04bea61
parent 8406 a217b0cd304d
child 12262 11ff5f47df6e
equal deleted inserted replaced
12230:b06cc3834ee5 12231:4a25f04bea61
    61       | bTs _ = []
    61       | bTs _ = []
    62 in bTs end;
    62 in bTs end;
    63 
    63 
    64 fun strip_type env T = (binder_types env T, body_type env T);
    64 fun strip_type env T = (binder_types env T, body_type env T);
    65 
    65 
    66 
    66 fun fastype env (Ts, t) = Envir.fastype env (map snd Ts) t;
    67 (*Put a term into head normal form for unification.
       
    68   Operands need not be in normal form.  Does eta-expansions on the head,
       
    69   which involves renumbering (thus copying) the args.  To avoid this 
       
    70   inefficiency, avoid partial application:  if an atom is applied to
       
    71   any arguments at all, apply it to its full number of arguments.
       
    72   For
       
    73     rbinder = [(x1,T),...,(xm,Tm)]		(user's var names preserved!)
       
    74     args  =   [arg1,...,argn]
       
    75   the value of 
       
    76       (xm,...,x1)(head(arg1,...,argn))  remains invariant.
       
    77 *)
       
    78 
       
    79 local exception SAME
       
    80 in
       
    81   fun head_norm (env,t) : term =
       
    82     let fun hnorm (Var (v,T)) = 
       
    83 	      (case Envir.lookup (env,v) of
       
    84 		  Some u => head_norm (env, u)
       
    85 		| None   => raise SAME)
       
    86 	  | hnorm (Abs(a,T,body)) =  Abs(a, T, hnorm body)
       
    87 	  | hnorm (Abs(_,_,body) $ t) =
       
    88 	      head_norm (env, subst_bound (t, body))
       
    89 	  | hnorm (f $ t) =
       
    90 	      (case hnorm f of
       
    91 		 Abs(_,_,body) =>
       
    92 		   head_norm (env, subst_bound (t, body))
       
    93 	       | nf => nf $ t)
       
    94 	  | hnorm _ =  raise SAME
       
    95     in  hnorm t  handle SAME=> t  end
       
    96 end;
       
    97 
       
    98 
       
    99 (*finds type of term without checking that combinations are consistent
       
   100   rbinder holds types of bound variables*)
       
   101 fun fastype (Envir.Envir{iTs,...}) =
       
   102 let val funerr = "fastype: expected function type";
       
   103     fun fast(rbinder, f$u) =
       
   104 	(case (fast (rbinder, f)) of
       
   105 	   Type("fun",[_,T]) => T
       
   106 	 | TVar(ixn,_) =>
       
   107 		(case Vartab.lookup (iTs,ixn) of
       
   108 		   Some(Type("fun",[_,T])) => T
       
   109 		 | _ => raise TERM(funerr, [f$u]))
       
   110 	 | _ => raise TERM(funerr, [f$u]))
       
   111       | fast (rbinder, Const (_,T)) = T
       
   112       | fast (rbinder, Free (_,T)) = T
       
   113       | fast (rbinder, Bound i) =
       
   114 	(#2 (nth_elem (i,rbinder))
       
   115   	 handle LIST _=> raise TERM("fastype: Bound", [Bound i]))
       
   116       | fast (rbinder, Var (_,T)) = T 
       
   117       | fast (rbinder, Abs (_,T,u)) =  T --> fast (("",T) :: rbinder, u)
       
   118 in fast end;
       
   119 
    67 
   120 
    68 
   121 (*Eta normal form*)
    69 (*Eta normal form*)
   122 fun eta_norm(env as Envir.Envir{iTs,...}) =
    70 fun eta_norm(env as Envir.Envir{iTs,...}) =
   123   let fun etif (Type("fun",[T,U]), t) =
    71   let fun etif (Type("fun",[T,U]), t) =
   287     | new_dpair (rbinder, t1, t2, env) = ((rbinder, t1, t2), env);
   235     | new_dpair (rbinder, t1, t2, env) = ((rbinder, t1, t2), env);
   288 
   236 
   289 
   237 
   290 fun head_norm_dpair (env, (rbinder,t,u)) : dpair * Envir.env =
   238 fun head_norm_dpair (env, (rbinder,t,u)) : dpair * Envir.env =
   291      new_dpair (rbinder,
   239      new_dpair (rbinder,
   292 		eta_norm env (rbinder, head_norm(env,t)),
   240 		eta_norm env (rbinder, Envir.head_norm env t),
   293 	  	eta_norm env (rbinder, head_norm(env,u)), env);
   241 	  	eta_norm env (rbinder, Envir.head_norm env u), env);
   294 
   242 
   295 
   243 
   296 
   244 
   297 (*flexflex: the flex-flex pairs,  flexrigid: the flex-rigid pairs
   245 (*flexflex: the flex-flex pairs,  flexrigid: the flex-rigid pairs
   298   Does not perform assignments for flex-flex pairs:
   246   Does not perform assignments for flex-flex pairs:
   388 fun matchcopy vname = let fun mc(rbinder, targs, u, ed as (env,dpairs)) 
   336 fun matchcopy vname = let fun mc(rbinder, targs, u, ed as (env,dpairs)) 
   389 	: (term * (Envir.env * dpair list))Seq.seq =
   337 	: (term * (Envir.env * dpair list))Seq.seq =
   390 let (*Produce copies of uarg and cons them in front of uargs*)
   338 let (*Produce copies of uarg and cons them in front of uargs*)
   391     fun copycons uarg (uargs, (env, dpairs)) =
   339     fun copycons uarg (uargs, (env, dpairs)) =
   392 	Seq.map(fn (uarg', ed') => (uarg'::uargs, ed'))
   340 	Seq.map(fn (uarg', ed') => (uarg'::uargs, ed'))
   393 	    (mc (rbinder, targs,eta_norm env (rbinder,head_norm(env,uarg)),
   341 	    (mc (rbinder, targs,eta_norm env (rbinder, Envir.head_norm env uarg),
   394 		 (env, dpairs)));
   342 		 (env, dpairs)));
   395 	(*Produce sequence of all possible ways of copying the arg list*)
   343 	(*Produce sequence of all possible ways of copying the arg list*)
   396     fun copyargs [] = Seq.cons( ([],ed), Seq.empty)
   344     fun copyargs [] = Seq.cons( ([],ed), Seq.empty)
   397       | copyargs (uarg::uargs) =
   345       | copyargs (uarg::uargs) =
   398 	    Seq.flat (Seq.map (copycons uarg) (copyargs uargs));
   346 	    Seq.flat (Seq.map (copycons uarg) (copyargs uargs));