Constrain.hs revision 117f087bc4e24ad34fac1bf8aa4385681bba4524
934473566cf3a8e4044ed10e408b4c44079684b1Christian MaederModule : $Header$
aa4679922a8363b4e494079f53aaf4f64554aae0Christian MaederCopyright : (c) Christian Maeder and Uni Bremen 2003-2005
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian MaederLicense : similar to LGPL, see HetCATS/LICENSE.txt or LIZENZ.txt
aa4679922a8363b4e494079f53aaf4f64554aae0Christian MaederMaintainer : maeder@tzi.de
934473566cf3a8e4044ed10e408b4c44079684b1Christian MaederStability : experimental
1d581e55c7ec020a445684310394c3a5fc056e96Christian MaederPortability : portable
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maederconstraint resolution
7ff59aa438d7a210789cad2c2c745bc9967eff82Till Mossakowskiimport qualified Common.Lib.Set as Set
7ff59aa438d7a210789cad2c2c745bc9967eff82Till Mossakowskiimport qualified Common.Lib.Map as Map
7ff59aa438d7a210789cad2c2c745bc9967eff82Till Mossakowskiimport qualified Common.Lib.Rel as Rel
b10d6cef708b7a659f2d3b367e8e0db0d03ae3f5Till Mossakowskidata Constrain = Kinding Type Kind
b10d6cef708b7a659f2d3b367e8e0db0d03ae3f5Till Mossakowski | Subtyping Type Type
b10d6cef708b7a659f2d3b367e8e0db0d03ae3f5Till Mossakowski deriving (Eq, Ord, Show)
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maederinstance PrettyPrint Constrain where
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder printText0 ga c = case c of
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder Kinding ty k -> printText0 ga ty <+> colon
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder <+> printText0 ga k
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder Subtyping t1 t2 -> printText0 ga t1 <+> text lessS
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder <+> printText0 ga t2
1549f3abf73c1122acff724f718b615c82fa3648Till Mossakowskiinstance PosItem Constrain where
934473566cf3a8e4044ed10e408b4c44079684b1Christian Maeder get_pos c = case c of
b10d6cef708b7a659f2d3b367e8e0db0d03ae3f5Till Mossakowski Kinding ty _ -> get_pos ty
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder Subtyping t1 t2 -> get_pos t1 ++ get_pos t2
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maedertype Constraints = Set.Set Constrain
f2d72b2254513ef810b0951f0b13a62c2921cb4dTill MossakowskinoC :: Constraints
6d9f68d2b5fafea0b5e0fc59a1d557174e032c02Christian MaederjoinC :: Constraints -> Constraints -> Constraints
4336edf6ada5b582667322f91e705b4366798953Dominik LueckeinsertC :: Constrain -> Constraints -> Constraints
aa4679922a8363b4e494079f53aaf4f64554aae0Christian MaederinsertC c = case c of
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder Subtyping t1 t2 -> if t1 == t2 then id else Set.insert c
c64d33a7fbeae730cbe65193fe3cc24e7aa1ddd6Christian MaedersubstC :: Subst -> Constraints -> Constraints
b565cd55a13dbccc4e66c344316da525c961e4caTill MossakowskisubstC s = Set.fold (insertC . ( \ c -> case c of
b565cd55a13dbccc4e66c344316da525c961e4caTill Mossakowski Kinding ty k -> Kinding (subst s ty) k
fe0e5e7c16ae2d6172cc583e0a9b8a54fce0dd55Christian Maeder Subtyping t1 t2 -> Subtyping (subst s t1) $ subst s t2)) noC
51e836611726885f6d2719d959ed1b51f8fd06f4Klaus Luettichsimplify :: TypeEnv -> Constraints -> ([Diagnosis], Constraints)
c4e3cade80a00690374e97f050fb5ade9d292850Till Mossakowskisimplify te rs =
b3dca469a9e267d6d71acfdeca7bf284d0581dc7Till Mossakowski if Set.null rs then ([], noC)
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder else let (r, rt) = Set.deleteFindMin rs
c64d33a7fbeae730cbe65193fe3cc24e7aa1ddd6Christian Maeder Result ds m = entail te r
c0c2380bced8159ff0297ece14eba948bd236471Christian Maeder (es, cs) = simplify te rt
c0c2380bced8159ff0297ece14eba948bd236471Christian Maeder in (ds ++ es, case m of
58b429c45eeb9eea394b6efb521e7489feef75a6Christian Maeder Nothing -> insertC r cs)
ad270004874ce1d0697fb30d7309f180553bb315Christian Maederentail :: Monad m => TypeEnv -> Constrain -> m ()
b10d6cef708b7a659f2d3b367e8e0db0d03ae3f5Till Mossakowski do is <- byInst te p
bf76f4fcf07abaebea587df8135de8356c26a363Till Mossakowski mapM_ (entail te) $ Set.toList is
b10d6cef708b7a659f2d3b367e8e0db0d03ae3f5Till MossakowskibyInst :: Monad m => TypeEnv -> Constrain -> m Constraints
aa4679922a8363b4e494079f53aaf4f64554aae0Christian MaederbyInst te c = let cm = classMap te in case c of
b10d6cef708b7a659f2d3b367e8e0db0d03ae3f5Till Mossakowski Kinding ty k -> case ty of
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder ExpandedType _ t -> byInst te $ Kinding t k
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder _ -> if k == star then return noC else case k of
b10d6cef708b7a659f2d3b367e8e0db0d03ae3f5Till Mossakowski ExtKind ek _ _ -> byInst te (Kinding ty ek)
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder ClassKind _ -> let (topTy, args) = getTypeAppl ty in
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder case topTy of
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder TypeName i _ _ -> let Result _ mk = getIdKind te i in
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder Nothing -> fail $ "remaining variable '"
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder ++ showPretty i "'"
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder Just ((_, ks), _) -> do
b10d6cef708b7a659f2d3b367e8e0db0d03ae3f5Till Mossakowski if null args then
2b565fe5cfb9f99857fd25b52304758d8544e266Mihai Codescu if any ( \ j -> lesserKind cm j k) ks
2b565fe5cfb9f99857fd25b52304758d8544e266Mihai Codescu then return noC
2b565fe5cfb9f99857fd25b52304758d8544e266Mihai Codescu else fail $ "constrain '" ++
2b565fe5cfb9f99857fd25b52304758d8544e266Mihai Codescu showPretty c "' is unprovable"
2b565fe5cfb9f99857fd25b52304758d8544e266Mihai Codescu ++ "\n known kinds are: " ++
2b565fe5cfb9f99857fd25b52304758d8544e266Mihai Codescu showPretty ks ""
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder let kas = concatMap ( \ j ->
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder getKindAppl cm j args) ks
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder newKs <- dom cm k kas
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder return $ Set.fromList $ zipWith Kinding args newKs
c64d33a7fbeae730cbe65193fe3cc24e7aa1ddd6Christian Maeder _ -> error "byInst: unexpected Type"
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder _ -> error "byInst: unexpected Kind"
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder Subtyping t1 t2 -> if lesserType te t1 t2 then return noC
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder else fail ("unable to prove: " ++ showPretty t1 " < "
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder ++ showPretty t2 "")
aa4679922a8363b4e494079f53aaf4f64554aae0Christian MaedermaxKind :: ClassMap -> Kind -> Kind -> Maybe Kind
aa4679922a8363b4e494079f53aaf4f64554aae0Christian MaedermaxKind cm k1 k2 = if lesserKind cm k1 k2 then Just k1 else
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder if lesserKind cm k2 k1 then Just k2 else Nothing
6e29f2565572024b963af2f6d486b567307dc770Till MossakowskimaxKinds :: ClassMap -> [Kind] -> Maybe Kind
aa4679922a8363b4e494079f53aaf4f64554aae0Christian MaedermaxKinds cm l = case l of
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder [] -> Nothing
bb4d3b6e93db1495f02de46aff5076862e30517bChristian Maeder [k] -> Just k
7ff59aa438d7a210789cad2c2c745bc9967eff82Till Mossakowski [k1, k2] -> maxKind cm k1 k2
7ff59aa438d7a210789cad2c2c745bc9967eff82Till Mossakowski k1 : k2 : ks -> case maxKind cm k1 k2 of
b565cd55a13dbccc4e66c344316da525c961e4caTill Mossakowski Just k -> maxKinds cm (k : ks)
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder Nothing -> do k <- maxKinds cm (k2 : ks)
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder maxKind cm k1 k
7ff59aa438d7a210789cad2c2c745bc9967eff82Till MossakowskimaxKindss :: ClassMap -> [[Kind]] -> Maybe [Kind]
7ff59aa438d7a210789cad2c2c745bc9967eff82Till MossakowskimaxKindss cm l = let margs = map (maxKinds cm) $ transpose l in
7ff59aa438d7a210789cad2c2c745bc9967eff82Till Mossakowski if all isJust margs then Just $ map fromJust margs
b565cd55a13dbccc4e66c344316da525c961e4caTill Mossakowskidom :: Monad m => ClassMap -> Kind -> [([Kind], Kind)] -> m [Kind]
7c8e78fd66aca3d24b77a9f9635f201e2f576d27Christian Maeder let fks = filter ( \ (_, rk) -> lesserKind cm rk k ) ks
7c8e78fd66aca3d24b77a9f9635f201e2f576d27Christian Maeder margs = maxKindss cm $ map fst fks
7c8e78fd66aca3d24b77a9f9635f201e2f576d27Christian Maeder in if null fks then fail ("class not found " ++ showPretty k "")
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maeder else case margs of
6e29f2565572024b963af2f6d486b567307dc770Till Mossakowski Nothing -> fail "dom: maxKind"
bf76f4fcf07abaebea587df8135de8356c26a363Till Mossakowski Just args -> if any ((args ==) . fst) fks then return args
6e29f2565572024b963af2f6d486b567307dc770Till Mossakowski else fail "dom: not coregular"
6e29f2565572024b963af2f6d486b567307dc770Till MossakowskifreshTypeVarT :: Type -> State Int Type
934473566cf3a8e4044ed10e408b4c44079684b1Christian MaederfreshTypeVarT t =
6e29f2565572024b963af2f6d486b567307dc770Till Mossakowski do (var, c) <- freshVar $ posOfType t
6e29f2565572024b963af2f6d486b567307dc770Till Mossakowski return $ TypeName var (rawKindOfType t) c
9d34a8049237647d0188ee2ec88db2dc45f1f848Till MossakowskifreshVarsT :: [Type] -> State Int [Type]
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian MaederfreshVarsT l = mapM freshTypeVarT l
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian MaedertoPairState :: State Int a -> State (Int, b) a
2b565fe5cfb9f99857fd25b52304758d8544e266Mihai CodescutoPairState p =
2b565fe5cfb9f99857fd25b52304758d8544e266Mihai Codescu do (a, b) <- get
2b565fe5cfb9f99857fd25b52304758d8544e266Mihai Codescu let (r, c) = runState p a
aa4679922a8363b4e494079f53aaf4f64554aae0Christian MaederaddSubst :: Subst -> State (Int, Subst) ()
aa4679922a8363b4e494079f53aaf4f64554aae0Christian MaederaddSubst s = do
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder (c, o) <- get
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder put (c, compSubst o s)
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maederswap :: (a, b) -> (b, a)
cf7e0d6750e408ddb47545d6b8349a70cf0b47afChristian Maederswap (a, b) = (b, a)
aa4679922a8363b4e494079f53aaf4f64554aae0Christian Maeder-- pre: shapeMatch succeeds
let s = Map.singleton v1 $ ProductType nts ps
let s = Map.singleton v1 $ FunType v3 ar v4 ps
let s = Map.singleton v1 $ mkTypeAppl topTy vs
collapser :: Rel.Rel Type -> Result Subst
let t = Rel.sccOfClosure r
ks = map (Set.partition ( \ e -> case e of
ws = filter (\ p -> Set.size (fst p) > 1) 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 $ subst s2 atoms)
monoSubst :: TypeEnv -> Rel.Rel Type -> Type -> Subst
let varSet = Set.fromList . leaves (> 0)
(True, _) -> 1 == Set.size
(Rel.predecessors r $
(_, True) -> 1 == Set.size
(Rel.succs r $
(True, True) -> 1 < Set.size
(Rel.succs r $
(True, True) -> 1 < Set.size
(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.fromAscList $ map ( \ (i, (n, rk)) ->
else Map.fromAscList $ 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 ->
foldr (Rel.insert (TypeName t (typeKind ti) 0)) r
superTypes ti ]) Rel.empty