src/Pure/unify.ML
changeset 41422 8a765db7e0f8
parent 39997 b654fa27fbc4
child 42279 6da43a5018e2
equal deleted inserted replaced
41421:2db1d3d2ed54 41422:8a765db7e0f8
   202 
   202 
   203 
   203 
   204 exception CANTUNIFY;  (*Signals non-unifiability.  Does not signal errors!*)
   204 exception CANTUNIFY;  (*Signals non-unifiability.  Does not signal errors!*)
   205 exception ASSIGN;  (*Raised if not an assignment*)
   205 exception ASSIGN;  (*Raised if not an assignment*)
   206 
   206 
   207 
       
   208 fun self_asgt (ix,(_,TVar (ix',_))) = (ix = ix')
       
   209   | self_asgt (ix, _) = false;
       
   210 
       
   211 fun check_tyenv msg tys tyenv = 
       
   212   if Vartab.exists self_asgt tyenv
       
   213   then raise TYPE (msg ^ ": looping type envir!!", tys, []) 
       
   214   else tyenv;
       
   215 
   207 
   216 fun unify_types thy (T, U, env) =
   208 fun unify_types thy (T, U, env) =
   217   if T = U then env
   209   if T = U then env
   218   else
   210   else
   219     let
   211     let
   470 
   462 
   471 (*Form the arguments into records for deletion/sorting.*)
   463 (*Form the arguments into records for deletion/sorting.*)
   472 fun flexargs ([], [], []) = [] : flarg list
   464 fun flexargs ([], [], []) = [] : flarg list
   473   | flexargs (j :: js, t :: ts, T :: Ts) = {j = j, t = t, T = T} :: flexargs (js, ts, Ts)
   465   | flexargs (j :: js, t :: ts, T :: Ts) = {j = j, t = t, T = T} :: flexargs (js, ts, Ts)
   474   | flexargs _ = raise CHANGE_FAIL;
   466   | flexargs _ = raise CHANGE_FAIL;
   475 (*We give up if we see a variable of function type not applied to a full list of 
   467 (*We give up if we see a variable of function type not applied to a full list of
   476   arguments (remember, this code assumes that terms are fully eta-expanded).  This situation 
   468   arguments (remember, this code assumes that terms are fully eta-expanded).  This situation
   477   can occur if a type variable is instantiated with a function type.
   469   can occur if a type variable is instantiated with a function type.
   478 *)
   470 *)
   479 
   471 
   480 (*Check whether the 'banned' bound var indices occur rigidly in t*)
   472 (*Check whether the 'banned' bound var indices occur rigidly in t*)
   481 fun rigid_bound (lev, banned) t =
   473 fun rigid_bound (lev, banned) t =
   525 fun clean_term banned (env,t) =
   517 fun clean_term banned (env,t) =
   526   let
   518   let
   527     val (Var (v, T), ts) = strip_comb t;
   519     val (Var (v, T), ts) = strip_comb t;
   528     val (Ts, U) = strip_type env T
   520     val (Ts, U) = strip_type env T
   529     and js = length ts - 1  downto 0;
   521     and js = length ts - 1  downto 0;
   530     val args = sort (make_ord arg_less) (List.foldr (change_arg banned) [] (flexargs (js, ts, Ts))) 
   522     val args = sort (make_ord arg_less) (List.foldr (change_arg banned) [] (flexargs (js, ts, Ts)))
   531     val ts' = map #t args;
   523     val ts' = map #t args;
   532   in
   524   in
   533     if decreasing (length Ts) args then (env, (list_comb (Var (v, T), ts')))
   525     if decreasing (length Ts) args then (env, (list_comb (Var (v, T), ts')))
   534     else
   526     else
   535       let
   527       let
   688 fun first_order_matchers thy pairs (Envir.Envir {maxidx, tenv, tyenv}) =
   680 fun first_order_matchers thy pairs (Envir.Envir {maxidx, tenv, tyenv}) =
   689   let val (tyenv', tenv') = fold (Pattern.first_order_match thy) pairs (tyenv, tenv)
   681   let val (tyenv', tenv') = fold (Pattern.first_order_match thy) pairs (tyenv, tenv)
   690   in Seq.single (Envir.Envir {maxidx = maxidx, tenv = tenv', tyenv = tyenv'}) end
   682   in Seq.single (Envir.Envir {maxidx = maxidx, tenv = tenv', tyenv = tyenv'}) end
   691   handle Pattern.MATCH => Seq.empty;
   683   handle Pattern.MATCH => Seq.empty;
   692 
   684 
   693 (*General matching -- keeps variables disjoint*)
   685 (*General matching -- keep variables disjoint*)
   694 fun matchers _ [] = Seq.single (Envir.empty ~1)
   686 fun matchers _ [] = Seq.single (Envir.empty ~1)
   695   | matchers thy pairs =
   687   | matchers thy pairs =
   696       let
   688       let
   697         val maxidx = fold (Term.maxidx_term o #2) pairs ~1;
   689         val maxidx = fold (Term.maxidx_term o #2) pairs ~1;
   698         val offset = maxidx + 1;
   690         val offset = maxidx + 1;
   709           Term.map_types decr_indexesT #>
   701           Term.map_types decr_indexesT #>
   710           Term.map_aterms (fn t as Var ((x, i), T) =>
   702           Term.map_aterms (fn t as Var ((x, i), T) =>
   711             if i > maxidx then Var ((x, i - offset), T) else t | t => t);
   703             if i > maxidx then Var ((x, i - offset), T) else t | t => t);
   712 
   704 
   713         fun norm_tvar env ((x, i), S) =
   705         fun norm_tvar env ((x, i), S) =
   714           ((x, i - offset),
   706           let
   715             (S, decr_indexesT (Envir.norm_type (Envir.type_env env) (TVar ((x, i), S)))));
   707             val tyenv = Envir.type_env env;
       
   708             val T' = Envir.norm_type tyenv (TVar ((x, i), S));
       
   709           in
       
   710             if (case T' of TVar (v, _) => v = (x, i) | _ => false) then NONE
       
   711             else SOME ((x, i - offset), (S, decr_indexesT T'))
       
   712           end;
       
   713 
   716         fun norm_var env ((x, i), T) =
   714         fun norm_var env ((x, i), T) =
   717           let
   715           let
   718             val tyenv = Envir.type_env env;
   716             val tyenv = Envir.type_env env;
   719             val T' = Envir.norm_type tyenv T;
   717             val T' = Envir.norm_type tyenv T;
   720             val t' = Envir.norm_term env (Var ((x, i), T'));
   718             val t' = Envir.norm_term env (Var ((x, i), T'));
   721           in ((x, i - offset), (decr_indexesT T', decr_indexes t')) end;
   719           in
       
   720             if (case t' of Var (v, _) => v = (x, i) | _ => false) then NONE
       
   721             else SOME ((x, i - offset), (decr_indexesT T', decr_indexes t'))
       
   722           end;
   722 
   723 
   723         fun result env =
   724         fun result env =
   724           if Envir.above env maxidx then   (* FIXME proper handling of generated vars!? *)
   725           if Envir.above env maxidx then   (* FIXME proper handling of generated vars!? *)
   725             SOME (Envir.Envir {maxidx = maxidx,
   726             SOME (Envir.Envir {maxidx = maxidx,
   726               tyenv = Vartab.make (filter_out self_asgt (map (norm_tvar env) pat_tvars)),
   727               tyenv = Vartab.make (map_filter (norm_tvar env) pat_tvars),
   727               tenv = Vartab.make (map (norm_var env) pat_vars)})
   728               tenv = Vartab.make (map_filter (norm_var env) pat_vars)})
   728           else NONE;
   729           else NONE;
   729 
   730 
   730         val empty = Envir.empty maxidx';
   731         val empty = Envir.empty maxidx';
   731       in
   732       in
   732         Seq.append
   733         Seq.append