src/Pure/pattern.ML
changeset 13642 a3d97348ceb6
parent 13195 98975cc13d28
child 13645 430310b12c5b
equal deleted inserted replaced
13641:63d1790a43ed 13642:a3d97348ceb6
    17 signature PATTERN =
    17 signature PATTERN =
    18   sig
    18   sig
    19   type type_sig
    19   type type_sig
    20   type sg
    20   type sg
    21   type env
    21   type env
       
    22   val trace_unify_fail  : bool ref
    22   val aeconv            : term * term -> bool
    23   val aeconv            : term * term -> bool
    23   val eta_contract      : term -> term
    24   val eta_contract      : term -> term
    24   val beta_eta_contract : term -> term
    25   val beta_eta_contract : term -> term
    25   val eta_contract_atom : term -> term
    26   val eta_contract_atom : term -> term
    26   val match             : type_sig -> term * term
    27   val match             : type_sig -> term * term
    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 
   470       | rew2 _ _ = None
   539       | rew2 _ _ = None
   471 
   540 
   472   in if_none (rew1 skel0 tm) tm end;
   541   in if_none (rew1 skel0 tm) tm end;
   473 
   542 
   474 end;
   543 end;
       
   544 
       
   545 val trace_unify_fail = Pattern.trace_unify_fail;