Unify.hs revision 793945d4ac7c0f22760589c87af8e71427c76118
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannModule : $Header$
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannCopyright : (c) Christian Maeder and Uni Bremen 2003-2005
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannLicense : similar to LGPL, see HetCATS/LICENSE.txt or LIZENZ.txt
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannMaintainer : maeder@tzi.de
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannStability : experimental
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannPortability : portable
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmannsubstitution and unification of types
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmannimport qualified Data.Map as Map
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmannimport qualified Data.Set as Set
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann-- | bound vars
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmanngenVarsOf :: Type -> [(Id, RawKind)]
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmanngenVarsOf = map snd . leaves (<0)
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann-- | composition (reversed: first substitution first!)
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmanncompSubst :: Subst -> Subst -> Subst
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmanncompSubst s1 s2 = Map.union (Map.map (subst s2) s1) s2
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann-- | unifiability of type schemes including instantiation with fresh variables
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann-- (and looking up type aliases)
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannisUnifiable :: TypeMap -> Int -> TypeScheme -> TypeScheme -> Bool
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannisUnifiable tm c = asSchemes c (unify tm)
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann-- | test if second scheme is a substitution instance
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmanninstScheme :: TypeMap -> Int -> TypeScheme -> TypeScheme -> Bool
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmanninstScheme tm c = asSchemes c (subsume tm)
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann-- | lift 'State' Int to 'State' Env
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmanntoEnvState :: State Int a -> State Env a
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmanntoEnvState p =
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann let (r, c) = runState p $ counter s
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann put s { counter = c }
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmanntoSchemes :: (Type -> Type -> a) -> TypeScheme -> TypeScheme -> State Int a
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmanntoSchemes f sc1 sc2 =
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann do t1 <- freshInst sc1
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann t2 <- freshInst sc2
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann return $ f t1 t2
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannasSchemes :: Int -> (Type -> Type -> a) -> TypeScheme -> TypeScheme -> a
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannasSchemes c f sc1 sc2 = fst $ runState (toSchemes f sc1 sc2) c
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann-- -------------------------------------------------------------------------
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannfreshInst :: TypeScheme -> State Int Type
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannfreshInst (TypeScheme _ t _) =
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann do let ls = leaves (< 0) t -- generic vars
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann vs = map snd ls
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann ts <- mkSubst vs
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann return $ subst (Map.fromList $ zip (map fst ls) ts) t
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmanninc :: State Int Int
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannfreshVar :: Range -> State Int (Id, Int)
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannfreshVar ps = do
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann return (simpleIdToId $ Token ("_v" ++ show c) ps, c)
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannmkSingleSubst :: (Id, RawKind) -> State Int Type
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannmkSingleSubst (i, rk) = do
type Subst = Map.Map Int Type
eps = Map.empty
else if v1 > 0 && b1 then return $ Map.singleton v1 ty2
else if v2 > 0 && b2 then return $ Map.singleton v2 ty1
else if not b1 && b2 && v1 == 0 && v2 == 0 && Set.member i1
else if b1 && not b2 && v1 == 0 && v2 == 0 && Set.member i2
return $ Map.singleton v1 ty2
case Map.lookup n m of
subst $ Map.fromList $ zipWith