Constrain.hs revision 793945d4ac7c0f22760589c87af8e71427c76118
66267bcb678a9c341272c323b299337bcfdb7cc5Christian MaederModule : $Header$
66267bcb678a9c341272c323b299337bcfdb7cc5Christian MaederCopyright : (c) Christian Maeder and Uni Bremen 2003-2005
66267bcb678a9c341272c323b299337bcfdb7cc5Christian MaederLicense : similar to LGPL, see HetCATS/LICENSE.txt or LIZENZ.txt
66267bcb678a9c341272c323b299337bcfdb7cc5Christian MaederMaintainer : maeder@tzi.de
ffd01020a4f35f434b912844ad6e0d6918fadffdChristian MaederStability : experimental
66267bcb678a9c341272c323b299337bcfdb7cc5Christian MaederPortability : portable
fb69cd512eab767747f109e40322df7cae2f7bdfChristian Maederconstraint resolution
fb69cd512eab767747f109e40322df7cae2f7bdfChristian Maeder ( Constraints
e8ffec0fa3d3061061bdc16e44247b9cf96b050fChristian Maeder , Constrain(..)
08b724e8dcbba5820d80f0974b9a5385140815baChristian Maeder , fromTypeMap
e7ce154edb906685b3fa7f6c0a764e18a4658068Christian Maederimport qualified Data.Set as Set
e7ce154edb906685b3fa7f6c0a764e18a4658068Christian Maederimport qualified Data.Map as Map
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maederimport qualified Common.Lib.Rel as Rel
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder{- utils for singleton sets that could also be part of "Data.Set". These
fb50920e621bfc152c19147cb52077ff06b3526bChristian Maederfunctions rely on 'Data.Set.size' being computable in constant time and
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maederwould need to be rewritten for set implementations with a size
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maederfunction that is only linear. -}
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder-- | /O(1)/ test if the set's size is one
05e2a3161e4589a717c6fe5c7306820273a473c5Christian MaederisSingleton :: Set.Set a -> Bool
05e2a3161e4589a717c6fe5c7306820273a473c5Christian MaederisSingleton s = Set.size s == 1
fb50920e621bfc152c19147cb52077ff06b3526bChristian Maeder-- | /O(1)/ test if the set's size is greater one
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian MaederhasMany :: Set.Set a -> Bool
05e2a3161e4589a717c6fe5c7306820273a473c5Christian MaederhasMany s = Set.size s > 1
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maederdata Constrain = Kinding Type Kind
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder | Subtyping Type Type
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder deriving (Eq, Ord, Show)
cf3232cec840a6945667bdb06f5b47b22243bc8fChristian Maederinstance Pretty Constrain where
c18e9c3c6d5039618f1f2c05526ece84c7794ea3Christian Maeder pretty c = case c of
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder Kinding ty k -> pretty $ KindedType ty k nullRange
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder Subtyping t1 t2 -> fsep [pretty t1, less <+> pretty t2]
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maederinstance PosItem Constrain where
fb69cd512eab767747f109e40322df7cae2f7bdfChristian Maeder getRange c = case c of
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder Kinding ty _ -> getRange ty
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder Subtyping t1 t2 -> getRange t1 `appRange` getRange t2
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maedertype Constraints = Set.Set Constrain
36c6cc568751e4235502cfee00ba7b597dae78dcChristian MaedernoC :: Constraints
31242f7541fd6ef179e4eb5be7522ddf54ae397bChristian MaederjoinC :: Constraints -> Constraints -> Constraints
31242f7541fd6ef179e4eb5be7522ddf54ae397bChristian MaederinsertC :: Constrain -> Constraints -> Constraints
628310b42327ad76ce471caf0dde6563d6fa6307Christian MaederinsertC c = case c of
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder Subtyping t1 t2 -> if t1 == t2 then id else Set.insert c
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder Kinding _ k -> if k == universe then id else Set.insert c
36c6cc568751e4235502cfee00ba7b597dae78dcChristian MaedersubstC :: Subst -> Constraints -> Constraints
36c6cc568751e4235502cfee00ba7b597dae78dcChristian MaedersubstC s = Set.fold (insertC . ( \ c -> case c of
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder Kinding ty k -> Kinding (subst s ty) k
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder Subtyping t1 t2 -> Subtyping (subst s t1) $ subst s t2)) noC
628310b42327ad76ce471caf0dde6563d6fa6307Christian Maedersimplify :: TypeEnv -> Constraints -> ([Diagnosis], Constraints)
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maedersimplify te rs =
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder if Set.null rs then ([], noC)
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder else let (r, rt) = Set.deleteFindMin rs
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder Result ds m = entail te r
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder (es, cs) = simplify te rt
ffd01020a4f35f434b912844ad6e0d6918fadffdChristian Maeder in (ds ++ es, case m of
ffd01020a4f35f434b912844ad6e0d6918fadffdChristian Maeder Nothing -> insertC r cs)
e1839fb37a3a2ccd457464cb0dcc5efd466dbe22Christian Maederentail :: Monad m => TypeEnv -> Constrain -> m ()
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder do is <- byInst te p
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder mapM_ (entail te) $ Set.toList is
88ece6e49930670e8fd3ee79c89a2e918d2fbd0cChristian MaederbyInst :: Monad m => TypeEnv -> Constrain -> m Constraints
05e2a3161e4589a717c6fe5c7306820273a473c5Christian MaederbyInst te c = let cm = classMap te in case c of
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder Kinding ty k -> if k == universe then
c1031ac42b3f3d7d0fe7d9d6b54423a092d473a0Christian Maeder assert (rawKindOfType ty == ClassKind ())
e7ce154edb906685b3fa7f6c0a764e18a4658068Christian Maeder $ return noC else
e7ce154edb906685b3fa7f6c0a764e18a4658068Christian Maeder let Result _ds mk = inferKinds (Just True) ty te in
e7ce154edb906685b3fa7f6c0a764e18a4658068Christian Maeder Nothing -> fail $ "constrain '" ++
e7ce154edb906685b3fa7f6c0a764e18a4658068Christian Maeder showDoc c "' is unprovable"
fb69cd512eab767747f109e40322df7cae2f7bdfChristian Maeder Just ((_, ks), _) -> if any ( \ j -> lesserKind cm j k) ks
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder then return noC
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder else fail $ "constrain '" ++
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder showDoc c "' is unprovable"
88ece6e49930670e8fd3ee79c89a2e918d2fbd0cChristian Maeder ++ "\n known kinds are: " ++
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder concat (intersperse ", " $
88ece6e49930670e8fd3ee79c89a2e918d2fbd0cChristian Maeder map (flip showDoc "") ks)
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder Subtyping t1 t2 -> if lesserType te t1 t2 then return noC
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder else fail ("unable to prove: " ++ showDoc t1 " < "
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder ++ showDoc t2 "")
36c6cc568751e4235502cfee00ba7b597dae78dcChristian MaederfreshTypeVarT :: Type -> State Int Type
36c6cc568751e4235502cfee00ba7b597dae78dcChristian MaederfreshTypeVarT t =
36c6cc568751e4235502cfee00ba7b597dae78dcChristian Maeder do (var, c) <- freshVar $ getRange t
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder return $ TypeName var (rawKindOfType t) c
05e2a3161e4589a717c6fe5c7306820273a473c5Christian MaedertoPairState :: State Int a -> State (Int, b) a
05e2a3161e4589a717c6fe5c7306820273a473c5Christian MaedertoPairState p =
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder do (a, b) <- get
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder let (r, c) = runState p a
05e2a3161e4589a717c6fe5c7306820273a473c5Christian MaederaddSubst :: Subst -> State (Int, Subst) ()
05e2a3161e4589a717c6fe5c7306820273a473c5Christian MaederaddSubst s = do
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder (c, o) <- get
08b724e8dcbba5820d80f0974b9a5385140815baChristian Maeder put (c, compSubst o s)
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maederswap :: (a, b) -> (b, a)
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maederswap (a, b) = (b, a)
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian MaedersubstPairList :: Subst -> [(Type, Type)] -> [(Type, Type)]
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian MaedersubstPairList s = map ( \ (a, b) -> (subst s a, subst s b))
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maeder-- pre: shapeMatch succeeds
05e2a3161e4589a717c6fe5c7306820273a473c5Christian MaedershapeMgu :: TypeEnv -> [(Type, Type)] -> State (Int, Subst) [(Type, Type)]
05e2a3161e4589a717c6fe5c7306820273a473c5Christian MaedershapeMgu te cs =
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder let (atoms, structs) = partition ( \ p -> case p of
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maeder (TypeName _ _ _, TypeName _ _ _) -> True
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder _ -> False) cs
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maeder in if null structs then return atoms else
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maeder let (t1, t2) = head structs
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maeder tl = tail structs
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maeder rest = tl ++ atoms
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maeder in case (t1, t2) of
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maeder (ExpandedType _ t, _) -> shapeMgu te $ (t, t2) : rest
05e2a3161e4589a717c6fe5c7306820273a473c5Christian Maeder (_, ExpandedType _ t) -> shapeMgu te $ (t1, t) : rest
4fb19f237193a3bd6778f8aee3b6dd8da5856665Christian Maeder (TypeAppl (TypeName l _ _) t, _) | l == lazyTypeId ->
let s = Map.singleton v1 (TypeAppl vf va)
let s = Map.singleton v1 t2
collapser :: Rel.Rel Type -> Result Subst
let t = Rel.sccOfClosure r
ks = map (Set.partition ( \ e -> case e of
if Set.null cs then
extendSubst s $ Set.deleteFindMin vs
else extendSubst s (Set.findMin cs, vs)) eps ks
let (c1, rs) = Set.deleteFindMin cs
c2 = Set.findMin rs
extendSubst :: Subst -> (Type, Set.Set Type) -> Subst
extendSubst s (t, vs) = Set.fold ( \ (TypeName _ _ n) ->
Map.insert n t) s vs
partitionC = Set.partition ( \ c -> case c of
toListC l = [ (t1, t2) | Subtyping t1 t2 <- Set.toList l ]
-> State Int (Result (Subst, Constraints, Rel.Rel Type))
es = Map.foldWithKey ( \ t1 st l1 ->
TypeName _ _ 0 -> Set.fold ( \ t2 l2 ->
_ -> l1) [] $ Rel.toMap r
Rel.fromList $ substPairList s2 atoms)
monoSubst :: TypeEnv -> Rel.Rel Type -> Type -> Subst
let varSet = Set.fromList . leaves (> 0)
(Rel.predecessors r $
(Rel.succs r $
Rel.succs r $ TypeName n rk i
Rel.predecessors r $ TypeName n rk i
s = Rel.predecessors r tn
$ map (Rel.succs r)
$ Set.toList s
s = Rel.succs r tn
$ map (Rel.predecessors r)
$ Set.toList s
else Map.fromDistinctAscList $ map ( \ (i, (n, rk)) ->
else Map.fromDistinctAscList $ map ( \ (i, (n, rk)) ->
monoSubsts :: TypeEnv -> Rel.Rel Type -> Type -> Subst
if Map.null s then s else
fromTypeMap :: TypeMap -> Rel.Rel Type
fromTypeMap = Map.foldWithKey (\ t ti r -> let k = typeKind ti in
$ superTypes ti) Rel.empty