Constrain.hs revision 7ff1eb5756da8554a5676f3dc3c1225fc15c3682
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 Hausmannconstraint resolution
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmannimport qualified Common.Lib.Set as Set
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmannimport qualified Common.Lib.Map as Map
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmannimport qualified Common.Lib.Rel as Rel
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmanndata Constrain = Kinding Type Kind
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann | Subtyping Type Type
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann deriving (Eq, Ord, Show)
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmanninstance Pretty Constrain where
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann pretty c = case c of
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann Kinding ty k -> fsep [pretty ty, colon, pretty k]
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann Subtyping t1 t2 -> fsep [pretty t1, less, pretty t2]
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmanninstance PosItem Constrain where
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann getRange c = case c of
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann Kinding ty _ -> getRange ty
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann Subtyping t1 t2 -> getRange t1 `appRange` getRange t2
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmanntype Constraints = Set.Set Constrain
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannnoC :: Constraints
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannjoinC :: Constraints -> Constraints -> Constraints
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmanninsertC :: Constrain -> Constraints -> Constraints
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmanninsertC c = case c of
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann Subtyping t1 t2 -> if t1 == t2 then id else Set.insert c
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann Kinding _ k -> if k == universe then id else Set.insert c
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannsubstC :: Subst -> Constraints -> Constraints
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannsubstC s = Set.fold (insertC . ( \ c -> case c of
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann Kinding ty k -> Kinding (subst s ty) k
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann Subtyping t1 t2 -> Subtyping (subst s t1) $ subst s t2)) noC
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmannsimplify :: TypeEnv -> Constraints -> ([Diagnosis], Constraints)
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmannsimplify te rs =
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann if Set.null rs then ([], noC)
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann else let (r, rt) = Set.deleteFindMin rs
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann Result ds m = entail te r
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann (es, cs) = simplify te rt
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann in (ds ++ es, case m of
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann Nothing -> insertC r cs)
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmannentail :: Monad m => TypeEnv -> Constrain -> m ()
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann do is <- byInst te p
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann mapM_ (entail te) $ Set.toList is
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannbyInst :: Monad m => TypeEnv -> Constrain -> m Constraints
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannbyInst te c = let cm = classMap te in case c of
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann Kinding ty k -> if k == universe then
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann assert (rawKindOfType ty == ClassKind ())
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann $ return noC else
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann let Result _ds mk = inferKinds (Just True) ty te in
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann Nothing -> fail $ "constrain '" ++
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann showPretty c "' is unprovable"
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann Just ((_, ks), _) -> if any ( \ j -> lesserKind cm j k) ks
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann then return noC
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann else fail $ "constrain '" ++
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann showPretty c "' is unprovable"
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann ++ "\n known kinds are: " ++
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann concat (intersperse ", " $
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann map (flip showPretty "") ks)
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann Subtyping t1 t2 -> if lesserType te t1 t2 then return noC
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann else fail ("unable to prove: " ++ showPretty t1 " < "
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann ++ showPretty t2 "")
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannfreshTypeVarT :: Type -> State Int Type
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannfreshTypeVarT t =
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann do (var, c) <- freshVar $ getRange t
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann return $ TypeName var (rawKindOfType t) c
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannfreshVarsT :: [Type] -> State Int [Type]
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannfreshVarsT l = mapM freshTypeVarT l
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmanntoPairState :: State Int a -> State (Int, b) a
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmanntoPairState p =
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann do (a, b) <- get
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann let (r, c) = runState p a
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannaddSubst :: Subst -> State (Int, Subst) ()
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannaddSubst s = do
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann (c, o) <- get
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann put (c, compSubst o s)
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmannswap :: (a, b) -> (b, a)
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmannswap (a, b) = (b, a)
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannsubstPairList :: Subst -> [(Type, Type)] -> [(Type, Type)]
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannsubstPairList s = map ( \ (a, b) -> (subst s a, subst s b))
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann-- pre: shapeMatch succeeds
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannshapeMgu :: TypeEnv -> [(Type, Type)] -> State (Int, Subst) [(Type, Type)]
2450a4210dee64b064499a3a1154129bdfc74981Daniel HausmannshapeMgu te cs =
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann let (atoms, structs) = partition ( \ p -> case p of
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann (TypeName _ _ _, TypeName _ _ _) -> True
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann _ -> False) cs
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann in if null structs then return atoms else
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann let p@(t1, t2) = head structs
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann tl = tail structs
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann rest = tl ++ atoms
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann (ExpandedType _ t, _) -> shapeMgu te $ (t, t2) : rest
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann (_, ExpandedType _ t) -> shapeMgu te $ (t1, t) : rest
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann (TypeAppl (TypeName l _ _) t, _) | l == lazyTypeId ->
2450a4210dee64b064499a3a1154129bdfc74981Daniel Hausmann shapeMgu te $ (t, t2) : rest
let s = Map.singleton v1 (TypeAppl vf va)
collapser :: Rel.Rel Type -> Result Subst
let t = Rel.sccOfClosure r
ks = map (Set.partition ( \ e -> case e of
ws = filter (\ p -> Set.compareSize 1 (fst p) == LT) ks
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)
(True, _) -> Set.isSingleton
(Rel.predecessors r $
(_, True) -> Set.isSingleton
(Rel.succs r $
(True, True) -> Set.compareSize 1
(Rel.succs r $
(True, True) -> Set.compareSize 1
(Rel.predecessors r $
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