src/Pure/envir.ML
changeset 15797 a63605582573
parent 15570 8d8c70b41bab
child 16652 4ecf94235ec7
equal deleted inserted replaced
15796:348ce23d2fc2 15797:a63605582573
     1 (*  Title:      Pure/envir.ML
     1 (*  Title:      Pure/envir.ML
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     4     Copyright   1988  University of Cambridge
     4     Copyright   1988  University of Cambridge
     5 
     5 
     6 Environments.  They don't take account that typ is part of variable
     6 Environments.  The type of a term variable / sort of a type variable is
     7 name.  Therefore we check elsewhere that two variables with same names
     7 part of its name. The lookup function must apply type substitutions,
     8 and different types cannot occur.
     8 since they may change the identity of a variable.
     9 *)
     9 *)
    10 
    10 
    11 signature ENVIR =
    11 signature ENVIR =
    12 sig
    12 sig
    13   datatype env = Envir of {asol: term Vartab.table, iTs: typ Vartab.table, maxidx: int}
    13   type tenv
    14   val type_env: env -> typ Vartab.table
    14   datatype env = Envir of {asol: tenv, iTs: Type.tyenv, maxidx: int}
       
    15   val type_env: env -> Type.tyenv
    15   exception SAME
    16   exception SAME
    16   val genvars: string -> env * typ list -> env * term list
    17   val genvars: string -> env * typ list -> env * term list
    17   val genvar: string -> env * typ -> env * term
    18   val genvar: string -> env * typ -> env * term
    18   val lookup: env * indexname -> term option
    19   val lookup: env * (indexname * typ) -> term option
    19   val update: (indexname * term) * env -> env
    20   val lookup': (Type.tyenv * tenv) * (indexname * typ) -> term option
       
    21   val update: ((indexname * typ) * term) * env -> env
    20   val empty: int -> env
    22   val empty: int -> env
    21   val is_empty: env -> bool
    23   val is_empty: env -> bool
    22   val above: int * env -> bool
    24   val above: int * env -> bool
    23   val vupdate: (indexname * term) * env -> env
    25   val vupdate: ((indexname * typ) * term) * env -> env
    24   val alist_of: env -> (indexname * term) list
    26   val alist_of: env -> (indexname * (typ * term)) list
    25   val norm_term: env -> term -> term
    27   val norm_term: env -> term -> term
    26   val norm_term_same: env -> term -> term
    28   val norm_term_same: env -> term -> term
    27   val norm_type: typ Vartab.table -> typ -> typ
    29   val norm_type: Type.tyenv -> typ -> typ
    28   val norm_type_same: typ Vartab.table -> typ -> typ
    30   val norm_type_same: Type.tyenv -> typ -> typ
    29   val norm_types_same: typ Vartab.table -> typ list -> typ list
    31   val norm_types_same: Type.tyenv -> typ list -> typ list
    30   val beta_norm: term -> term
    32   val beta_norm: term -> term
    31   val head_norm: env -> term -> term
    33   val head_norm: env -> term -> term
    32   val fastype: env -> typ list -> term -> typ
    34   val fastype: env -> typ list -> term -> typ
       
    35   val typ_subst_TVars: Type.tyenv -> typ -> typ
       
    36   val subst_TVars: Type.tyenv -> term -> term
       
    37   val subst_Vars: tenv -> term -> term
       
    38   val subst_vars: Type.tyenv * tenv -> term -> term
    33 end;
    39 end;
    34 
    40 
    35 structure Envir : ENVIR =
    41 structure Envir : ENVIR =
    36 struct
    42 struct
    37 
    43 
    38 (*updating can destroy environment in 2 ways!!
    44 (*updating can destroy environment in 2 ways!!
    39    (1) variables out of range   (2) circular assignments
    45    (1) variables out of range   (2) circular assignments
    40 *)
    46 *)
       
    47 type tenv = (typ * term) Vartab.table
       
    48 
    41 datatype env = Envir of
    49 datatype env = Envir of
    42     {maxidx: int,               (*maximum index of vars*)
    50     {maxidx: int,      (*maximum index of vars*)
    43      asol: term Vartab.table,   (*table of assignments to Vars*)
    51      asol: tenv,       (*table of assignments to Vars*)
    44      iTs: typ Vartab.table}     (*table of assignments to TVars*)
    52      iTs: Type.tyenv}  (*table of assignments to TVars*)
    45 
    53 
    46 fun type_env (Envir {iTs, ...}) = iTs;
    54 fun type_env (Envir {iTs, ...}) = iTs;
    47 
    55 
    48 (*Generate a list of distinct variables.
    56 (*Generate a list of distinct variables.
    49   Increments index to make them distinct from ALL present variables. *)
    57   Increments index to make them distinct from ALL present variables. *)
    58 (*Generate a variable.*)
    66 (*Generate a variable.*)
    59 fun genvar name (env,T) : env * term =
    67 fun genvar name (env,T) : env * term =
    60   let val (env',[v]) = genvars name (env,[T])
    68   let val (env',[v]) = genvars name (env,[T])
    61   in  (env',v)  end;
    69   in  (env',v)  end;
    62 
    70 
    63 fun lookup (Envir{asol,...}, xname) : term option = Vartab.lookup (asol, xname);
    71 (* de-reference TVars. When dealing with environments produced by *)
    64 
    72 (* matching instead of unification, there is no need to chase     *)
    65 fun update ((xname, t), Envir{maxidx, asol, iTs}) =
    73 (* assigned TVars. In this case, set b to false.                  *)
    66   Envir{maxidx=maxidx, asol=Vartab.update_new ((xname,t), asol), iTs=iTs};
    74 fun devar b iTs (T as TVar vT) = (case Type.lookup (iTs, vT) of
       
    75       NONE => T
       
    76     | SOME T' => if b then devar true iTs T' else T')
       
    77   | devar b iTs T = T;
       
    78 
       
    79 fun eq_type b iTs (T, T') =
       
    80   (case (devar b iTs T, devar b iTs T') of
       
    81      (Type (s, Ts), Type (s', Ts')) =>
       
    82        s = s' andalso ListPair.all (eq_type b iTs) (Ts, Ts')
       
    83    | (U, U') => U = U');
       
    84 
       
    85 fun var_clash ixn T T' = raise TYPE ("Variable " ^
       
    86   quote (Syntax.string_of_vname ixn) ^ " has two distinct types",
       
    87   [T', T], []);
       
    88 
       
    89 fun gen_lookup f asol (xname, T) =
       
    90   (case Vartab.lookup (asol, xname) of
       
    91      NONE => NONE
       
    92    | SOME (U, t) => if f (T, U) then SOME t
       
    93        else var_clash xname T U);
       
    94 
       
    95 (* version ignoring type substitutions *)
       
    96 fun lookup1 asol = gen_lookup op = asol;
       
    97 
       
    98 fun gen_lookup2 b (iTs, asol) =
       
    99   if Vartab.is_empty iTs then lookup1 asol
       
   100   else gen_lookup (eq_type b iTs) asol;
       
   101 
       
   102 fun lookup2 env = gen_lookup2 true env;
       
   103 
       
   104 fun lookup (Envir {asol, iTs, ...}, p) = lookup2 (iTs, asol) p;
       
   105 
       
   106 (* version for matching algorithms, does not chase TVars *)
       
   107 fun lookup' (env, p) = gen_lookup2 false env p;
       
   108 
       
   109 fun update (((xname, T), t), Envir {maxidx, asol, iTs}) =
       
   110   Envir{maxidx=maxidx, asol=Vartab.update_new ((xname, (T, t)), asol), iTs=iTs};
    67 
   111 
    68 (*The empty environment.  New variables will start with the given index+1.*)
   112 (*The empty environment.  New variables will start with the given index+1.*)
    69 fun empty m = Envir{maxidx=m, asol=Vartab.empty, iTs=Vartab.empty};
   113 fun empty m = Envir{maxidx=m, asol=Vartab.empty, iTs=Vartab.empty};
    70 
   114 
    71 (*Test for empty environment*)
   115 (*Test for empty environment*)
    78    | (SOME (_, i), NONE) => i > lim
   122    | (SOME (_, i), NONE) => i > lim
    79    | (NONE, SOME (_, i')) => i' > lim
   123    | (NONE, SOME (_, i')) => i' > lim
    80    | (SOME (_, i), SOME (_, i')) => i > lim andalso i' > lim);
   124    | (SOME (_, i), SOME (_, i')) => i > lim andalso i' > lim);
    81 
   125 
    82 (*Update, checking Var-Var assignments: try to suppress higher indexes*)
   126 (*Update, checking Var-Var assignments: try to suppress higher indexes*)
    83 fun vupdate((a,t), env) = case t of
   127 fun vupdate ((aU as (a, U), t), env as Envir {iTs, ...}) = case t of
    84       Var(name',T) =>
   128       Var (nT as (name', T)) =>
    85         if a=name' then env     (*cycle!*)
   129         if a = name' then env     (*cycle!*)
    86         else if xless(a, name')  then
   130         else if xless(a, name')  then
    87            (case lookup(env,name') of  (*if already assigned, chase*)
   131            (case lookup (env, nT) of  (*if already assigned, chase*)
    88                 NONE => update((name', Var(a,T)), env)
   132                 NONE => update ((nT, Var (a, T)), env)
    89               | SOME u => vupdate((a,u), env))
   133               | SOME u => vupdate ((aU, u), env))
    90         else update((a,t), env)
   134         else update ((aU, t), env)
    91     | _ => update((a,t), env);
   135     | _ => update ((aU, t), env);
    92 
   136 
    93 
   137 
    94 (*Convert environment to alist*)
   138 (*Convert environment to alist*)
    95 fun alist_of (Envir{asol,...}) = Vartab.dest asol;
   139 fun alist_of (Envir{asol,...}) = Vartab.dest asol;
    96 
   140 
   101 
   145 
   102 (*raised when norm has no effect on a term, to do sharing instead of copying*)
   146 (*raised when norm has no effect on a term, to do sharing instead of copying*)
   103 exception SAME;
   147 exception SAME;
   104 
   148 
   105 fun norm_term1 same (asol,t) : term =
   149 fun norm_term1 same (asol,t) : term =
   106   let fun norm (Var (w,T)) =
   150   let fun norm (Var wT) =
   107             (case Vartab.lookup (asol, w) of
   151             (case lookup1 asol wT of
   108                 SOME u => (norm u handle SAME => u)
   152                 SOME u => (norm u handle SAME => u)
   109               | NONE   => raise SAME)
   153               | NONE   => raise SAME)
   110         | norm (Abs(a,T,body)) =  Abs(a, T, norm body)
   154         | norm (Abs(a,T,body)) =  Abs(a, T, norm body)
   111         | norm (Abs(_,_,body) $ t) = normh(subst_bound (t, body))
   155         | norm (Abs(_,_,body) $ t) = normh(subst_bound (t, body))
   112         | norm (f $ t) =
   156         | norm (f $ t) =
   118       and normh t = norm t handle SAME => t
   162       and normh t = norm t handle SAME => t
   119   in (if same then norm else normh) t end
   163   in (if same then norm else normh) t end
   120 
   164 
   121 fun normT iTs (Type (a, Ts)) = Type (a, normTs iTs Ts)
   165 fun normT iTs (Type (a, Ts)) = Type (a, normTs iTs Ts)
   122   | normT iTs (TFree _) = raise SAME
   166   | normT iTs (TFree _) = raise SAME
   123   | normT iTs (TVar(v, _)) = (case Vartab.lookup (iTs, v) of
   167   | normT iTs (TVar vS) = (case Type.lookup (iTs, vS) of
   124           SOME U => normTh iTs U
   168           SOME U => normTh iTs U
   125         | NONE => raise SAME)
   169         | NONE => raise SAME)
   126 and normTh iTs T = ((normT iTs T) handle SAME => T)
   170 and normTh iTs T = ((normT iTs T) handle SAME => T)
   127 and normTs iTs [] = raise SAME
   171 and normTs iTs [] = raise SAME
   128   | normTs iTs (T :: Ts) =
   172   | normTs iTs (T :: Ts) =
   131 
   175 
   132 fun norm_term2 same (asol, iTs, t) : term =
   176 fun norm_term2 same (asol, iTs, t) : term =
   133   let fun norm (Const (a, T)) = Const(a, normT iTs T)
   177   let fun norm (Const (a, T)) = Const(a, normT iTs T)
   134         | norm (Free (a, T)) = Free(a, normT iTs T)
   178         | norm (Free (a, T)) = Free(a, normT iTs T)
   135         | norm (Var (w, T)) =
   179         | norm (Var (w, T)) =
   136             (case Vartab.lookup (asol, w) of
   180             (case lookup2 (iTs, asol) (w, T) of
   137                 SOME u => normh u
   181                 SOME u => normh u
   138               | NONE   => Var(w, normT iTs T))
   182               | NONE   => Var(w, normT iTs T))
   139         | norm (Abs (a, T, body)) =
   183         | norm (Abs (a, T, body)) =
   140                (Abs (a, normT iTs T, normh body) handle SAME => Abs (a, T, norm body))
   184                (Abs (a, normT iTs T, normh body) handle SAME => Abs (a, T, norm body))
   141         | norm (Abs(_, _, body) $ t) = normh (subst_bound (t, body))
   185         | norm (Abs(_, _, body) $ t) = normh (subst_bound (t, body))
   167 
   211 
   168 (*Put a term into head normal form for unification.*)
   212 (*Put a term into head normal form for unification.*)
   169 
   213 
   170 fun head_norm env t =
   214 fun head_norm env t =
   171   let
   215   let
   172     fun hnorm (Var (v, T)) = (case lookup (env, v) of
   216     fun hnorm (Var vT) = (case lookup (env, vT) of
   173           SOME u => head_norm env u
   217           SOME u => head_norm env u
   174         | NONE => raise SAME)
   218         | NONE => raise SAME)
   175       | hnorm (Abs (a, T, body)) =  Abs (a, T, hnorm body)
   219       | hnorm (Abs (a, T, body)) =  Abs (a, T, hnorm body)
   176       | hnorm (Abs (_, _, body) $ t) =
   220       | hnorm (Abs (_, _, body) $ t) =
   177           head_norm env (subst_bound (t, body))
   221           head_norm env (subst_bound (t, body))
   187 fun fastype (Envir {iTs, ...}) =
   231 fun fastype (Envir {iTs, ...}) =
   188 let val funerr = "fastype: expected function type";
   232 let val funerr = "fastype: expected function type";
   189     fun fast Ts (f $ u) =
   233     fun fast Ts (f $ u) =
   190 	(case fast Ts f of
   234 	(case fast Ts f of
   191 	   Type ("fun", [_, T]) => T
   235 	   Type ("fun", [_, T]) => T
   192 	 | TVar(ixn, _) =>
   236 	 | TVar ixnS =>
   193 		(case Vartab.lookup (iTs, ixn) of
   237 		(case Type.lookup (iTs, ixnS) of
   194 		   SOME (Type ("fun", [_, T])) => T
   238 		   SOME (Type ("fun", [_, T])) => T
   195 		 | _ => raise TERM (funerr, [f $ u]))
   239 		 | _ => raise TERM (funerr, [f $ u]))
   196 	 | _ => raise TERM (funerr, [f $ u]))
   240 	 | _ => raise TERM (funerr, [f $ u]))
   197       | fast Ts (Const (_, T)) = T
   241       | fast Ts (Const (_, T)) = T
   198       | fast Ts (Free (_, T)) = T
   242       | fast Ts (Free (_, T)) = T
   201   	 handle Subscript => raise TERM ("fastype: Bound", [Bound i]))
   245   	 handle Subscript => raise TERM ("fastype: Bound", [Bound i]))
   202       | fast Ts (Var (_, T)) = T 
   246       | fast Ts (Var (_, T)) = T 
   203       | fast Ts (Abs (_, T, u)) = T --> fast (T :: Ts) u
   247       | fast Ts (Abs (_, T, u)) = T --> fast (T :: Ts) u
   204 in fast end;
   248 in fast end;
   205 
   249 
       
   250 
       
   251 (*Substitute for type Vars in a type*)
       
   252 fun typ_subst_TVars iTs T = if Vartab.is_empty iTs then T else
       
   253   let fun subst(Type(a, Ts)) = Type(a, map subst Ts)
       
   254         | subst(T as TFree _) = T
       
   255         | subst(T as TVar ixnS) =
       
   256             (case Type.lookup (iTs, ixnS) of NONE => T | SOME(U) => U)
       
   257   in subst T end;
       
   258 
       
   259 (*Substitute for type Vars in a term*)
       
   260 val subst_TVars = map_term_types o typ_subst_TVars;
       
   261 
       
   262 (*Substitute for Vars in a term *)
       
   263 fun subst_Vars itms t = if Vartab.is_empty itms then t else
       
   264   let fun subst (v as Var ixnT) = getOpt (lookup1 itms ixnT, v)
       
   265         | subst (Abs (a, T, t)) = Abs (a, T, subst t)
       
   266         | subst (f $ t) = subst f $ subst t
       
   267         | subst t = t
       
   268   in subst t end;
       
   269 
       
   270 (*Substitute for type/term Vars in a term *)
       
   271 fun subst_vars (env as (iTs, itms)) =
       
   272   if Vartab.is_empty iTs then subst_Vars itms else
       
   273   let fun subst (Const (a, T)) = Const(a, typ_subst_TVars iTs T)
       
   274         | subst (Free (a, T)) = Free (a, typ_subst_TVars iTs T)
       
   275         | subst (Var (ixn, T)) = (case lookup' (env, (ixn, T)) of
       
   276             NONE   => Var (ixn, typ_subst_TVars iTs T)
       
   277           | SOME t => t)
       
   278         | subst (b as Bound _) = b
       
   279         | subst (Abs (a, T, t)) = Abs(a, typ_subst_TVars iTs T, subst t)
       
   280         | subst (f $ t) = subst f $ subst t
       
   281   in subst end;
       
   282 
   206 end;
   283 end;