TypeAna.hs revision 72909c6c1cfe9702f5910d0a135c8b55729c7917
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederModule : $Header$
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederDescription : infer the kinds of types
75a6279dbae159d018ef812185416cf6df386c10Till MossakowskiCopyright : (c) Christian Maeder and Uni Bremen 2003-2005
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederLicense : similar to LGPL, see HetCATS/LICENSE.txt or LIZENZ.txt
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederMaintainer : Christian.Maeder@dfki.de
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederStability : experimental
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederPortability : portable
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maederimport qualified Data.Map as Map
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maederimport qualified Data.Set as Set
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maeder-- * infer kind
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder-- | extract kinds of type identifier
715ffaf874309df081d1e1cd8e05073fc1227729Christian MaedergetIdKind :: Env -> Id -> Result ((Variance, RawKind, Set.Set Kind), Type)
715ffaf874309df081d1e1cd8e05073fc1227729Christian MaedergetIdKind te i =
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder case Map.lookup i $ localTypeVars te of
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder Nothing -> case Map.lookup i $ typeMap te of
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder Nothing -> mkError "unknown type" i
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder Just (TypeInfo rk l _ _) ->
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder return ((InVar, rk, l), TypeName i rk 0)
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder Just (TypeVarDefn v vk rk c) ->
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder return ((v, rk, Set.singleton $ toKind vk), TypeName i rk c)
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder-- | extract kinds of co- or invariant type identifiers
715ffaf874309df081d1e1cd8e05073fc1227729Christian MaedergetCoVarKind :: Maybe Bool -> Env -> Id
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder -> Result ((RawKind, Set.Set Kind), Type)
715ffaf874309df081d1e1cd8e05073fc1227729Christian MaedergetCoVarKind b te i = do
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder ((v, rk, l), ty) <- getIdKind te i
38775225cf810f5895cc03b4acbcfe8f84f2513aChristian Maeder case (v, b) of
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maeder (ContraVar, Just True) -> Result
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maeder [mkDiag Hint "wrong contravariance of" i]
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maeder $ Just ((rk, Set.empty), ty)
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder (CoVar, Just False) -> Result
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder [mkDiag Hint "wrong covariance of" i]
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder $ Just ((rk, Set.empty), ty)
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maeder _ -> return ((rk, l), ty)
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder-- | check if there is at least one solution
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaedersubKinds :: DiagKind -> ClassMap -> Type -> Set.Set Kind -> Set.Set Kind
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaedersubKinds dk cm ty sk ks res =
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder if Set.null $ Set.filter (flip (newKind cm) ks) sk then return res
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder else Result [Diag dk
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder ("no kind found for '" ++ showDoc ty "'" ++
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder if Set.null ks then "" else expected sk ks)
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder $ getRange ty] $ Just Set.empty
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder-- | add an analysed type argument (warn on redeclared types)
715ffaf874309df081d1e1cd8e05073fc1227729Christian MaederaddTypeVarDecl :: Bool -> TypeArg -> State Env ()
d17834302eaa101395b4b806cd73670fd864445fChristian MaederaddTypeVarDecl warn (TypeArg i v vk rk c _ _) =
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maeder addLocalTypeVar warn (TypeVarDefn v vk rk c) i
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian MaederaddLocalTypeVar :: Bool -> TypeVarDefn -> Id -> State Env ()
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian MaederaddLocalTypeVar warn tvd i = do
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder tvs <- gets localTypeVars
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder if warn then do
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder tm <- gets typeMap
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder Nothing -> case Map.lookup i tvs of
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder Nothing -> return ()
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder Just _ -> addDiags [mkDiag Hint "rebound type variable" i]
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder Just _ -> addDiags [mkDiag Hint
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder "type variable shadows type constructor" i]
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder else return ()
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder putLocalTypeVars $ Map.insert i tvd tvs
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder-- | infer all minimal kinds
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian MaederinferKinds :: Maybe Bool -> Type -> Env
836e72a3c413366ba9801726f3b249c7791cb9caChristian Maeder -> Result ((RawKind, Set.Set Kind), Type)
836e72a3c413366ba9801726f3b249c7791cb9caChristian MaederinferKinds b ty te@Env{classMap = cm} = case ty of
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder TypeName i _ _ -> getCoVarKind b te i
7dec34aee2b609b9535c48d060e0f7baf3536457Christian Maeder TypeAppl t1 t2 -> do
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder ((rk, ks), t3) <- inferKinds b t1 te
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder FunKind v _ rr _ -> do
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder ((_, l), t4) <- inferKinds (case v of
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder ContraVar -> Just $ maybe False not b
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder CoVar -> Just $ maybe True id b
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder InVar -> Nothing) t2 te
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder kks <- mapM (getFunKinds cm) $ Set.toList ks
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maeder rs <- mapM ( \ fk -> case fk of
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder FunKind _ arg res _ -> subKinds Hint cm t2
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder _ -> error "inferKinds: no function kind"
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder ) $ Set.toList $ keepMinKinds cm kks
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder return ((rr, keepMinKinds cm rs), TypeAppl t3 t4)
797f811e57952d59e73b8cd03b667eef276db972Christian Maeder _ -> mkError "unexpected type argument" t2
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder TypeAbs ta@(TypeArg _ v k r _ _ q) t ps -> do
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder let newEnv = execState (addTypeVarDecl False ta) te
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder ((rk, ks), nt) <- inferKinds Nothing t newEnv
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder return (( FunKind v r rk q
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder , keepMinKinds cm
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder [Set.map (\ j -> FunKind v (toKind k) j q) ks])
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder , TypeAbs ta nt ps)
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder KindedType kt kind ps -> do
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maeder let Result ds _ = mapM (flip anaKindM cm) $ Set.toList kind
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maeder sk <- if null ds then return kind else Result ds Nothing
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder ((rk, ks), t) <- inferKinds b kt te
d17834302eaa101395b4b806cd73670fd864445fChristian Maeder l <- subKinds Hint cm kt sk ks sk
e1839fb37a3a2ccd457464cb0dcc5efd466dbe22Christian Maeder return ((rk, l), KindedType t sk ps)
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder ExpandedType t1 t2 -> do
e774ab5733a1d673b123b0e63b14dd533e6fd4fcChristian Maeder ((rk, ks), t4) <- inferKinds b t2 te
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder ((_, aks), t3) <- inferKinds b t1 te
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder return ((rk, keepMinKinds cm [aks, ks]), ExpandedType t3 t4)
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder _ -> error "inferKinds"
7dec34aee2b609b9535c48d060e0f7baf3536457Christian Maeder-- * converting type terms
1738d16957389457347bee85075d3d33d002158fChristian Maeder-- | throw away alias or kind information
1738d16957389457347bee85075d3d33d002158fChristian MaederstripType :: String -> Type -> Type
33a5d53a412ba0a4e5847f7538d6da2e22bd116cChristian MaederstripType msg ty = case ty of
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder ExpandedType _ t -> t
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder KindedType t _ _ -> t
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder _ -> error $ "stripType " ++ msg
c70d42540b8f8c3c141cc0779599d25f7eb69bbfChristian Maeder-- * subtyping relation
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder-- | extract the raw kind from a type term
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian MaederrawKindOfType :: Type -> RawKind
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian MaederrawKindOfType ty = case ty of
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder TypeName _ k _ -> k
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder TypeAppl t1 _ -> case rawKindOfType t1 of
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder FunKind _ _ rk _ -> rk
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder _ -> error "rawKindOfType"
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder TypeAbs (TypeArg _ v _ r _ _ _) t ps ->
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder FunKind v r (rawKindOfType t) ps
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder _ -> rawKindOfType $ stripType "rawKindOfType" ty
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder-- | subtyping relation
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian MaederlesserType :: Env -> Type -> Type -> Bool
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian MaederlesserType te t1 t2 = case (t1, t2) of
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder (TypeAppl c1 a1, TypeAppl c2 a2) ->
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder let b1 = lesserType te a1 a2
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder b2 = lesserType te a2 a1
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder in (case (rawKindOfType c1, rawKindOfType c2) of
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder (FunKind v1 _ _ _, FunKind v2 _ _ _) ->
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder if v1 == v2 then case v1 of
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder ContraVar -> b2
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder _ -> error "lesserType: no FunKind") && lesserType te c1 c2
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder (TypeName i1 _ _, TypeName i2 _ _) | i1 == i2 -> True
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder (TypeName i k _, _) -> case Map.lookup i $ localTypeVars te of
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder Nothing -> case Map.lookup i $ typeMap te of
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder Nothing -> False
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder Just ti -> any ( \ j -> lesserType te (TypeName j k 0) t2) $
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder Set.toList $ superTypes ti
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder Just (TypeVarDefn _ vk _ _) -> case vk of
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder Downset t -> lesserType te t t2
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder (TypeAppl _ _, TypeName _ _ _) -> False
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder (TypeAppl _ _, TypeAbs _ _ _) -> False
TypeAppl t1 t2 -> leaves b t1 `List.union` leaves b t2
List.delete (c, (i, r)) $ leaves b ty
idsOf :: (Int -> Bool) -> Type -> Set.Set Id
idsOf b = Set.fromList . map (fst . snd) . leaves b
repl :: Map.Map Id Type -> Type -> Type
case Map.lookup i m of
superIds :: TypeMap -> Id -> Set.Set Id
if Set.null new then known else
let more = Set.unions $ map ( \ i -> superTypes
$ Map.findWithDefault starTypeInfo i tm)
$ Set.toList new
newKnown = Set.union known new
filterAliases = Map.filter ( \ ti -> case typeDefn ti of
expandAliases tm = if Map.null tm then id else expandAux tm
case Map.lookup i tm of
Map.keysSet $ filterAliases tm
anaTypeM :: (Maybe Kind, Type) -> Env -> Result ((RawKind, Set.Set Kind), Type)
Just k -> subKinds Error cm parsedType (Set.singleton k) ks $
Set.filter (flip (lesserKind cm) k) ks
anaStarTypeM :: Type -> Env -> Result ((RawKind, Set.Set Kind), Type)
cyclicType i ty = Set.member i $ idsOf (==0) ty