Le.hs revision 230aa1e8c53fcaffd75814c7d86bd37c8012596a
5784N/A{- |
5784N/AModule : $Header$
5784N/ADescription : the abstract syntax for analysis and final signature instance
5784N/ACopyright : (c) Christian Maeder and Uni Bremen 2003-2005
5784N/ALicense : similar to LGPL, see HetCATS/LICENSE.txt or LIZENZ.txt
5784N/A
5784N/AMaintainer : Christian.Maeder@dfki.de
5784N/AStability : experimental
5784N/APortability : portable
5784N/A
5784N/Aabstract syntax during static analysis
5784N/A-}
5784N/A
5784N/Amodule HasCASL.Le where
5784N/A
5784N/Aimport HasCASL.As
5784N/Aimport HasCASL.FoldType
5784N/Aimport HasCASL.AsUtils
5784N/Aimport qualified Data.Map as Map
5784N/Aimport qualified Data.Set as Set
5784N/Aimport qualified Common.Lib.State as State
5784N/Aimport Common.Result
5784N/Aimport Common.Id
5784N/Aimport Common.AS_Annotation (Named)
5784N/Aimport Common.GlobalAnnotations
5784N/Aimport Common.Prec
5784N/A
5784N/A-- * class info
5784N/A
5784N/A-- | store the raw kind and all superclasses of a class identifier
5784N/Adata ClassInfo = ClassInfo
5784N/A { rawKind :: RawKind
5784N/A , classKinds :: Set.Set Kind
5784N/A } deriving (Show, Eq)
5784N/A
5784N/A-- | mapping class identifiers to their definition
5784N/Atype ClassMap = Map.Map Id ClassInfo
5784N/A
5784N/A-- * type info
5784N/A
5784N/A-- | data type generatedness indicator
5784N/Adata GenKind = Free | Generated | Loose deriving (Show, Eq, Ord)
5784N/A
5784N/A-- | an analysed alternative with a list of (product) types
5784N/Adata AltDefn =
5784N/A Construct (Maybe Id) [Type] Partiality [[Selector]]
5784N/A -- only argument types
5784N/A deriving (Show, Eq, Ord)
5784N/A
5784N/A-- | an analysed component
5784N/Adata Selector =
5784N/A Select (Maybe Id) Type Partiality deriving (Show, Eq, Ord)
5784N/A -- only result type
5784N/A
5784N/A-- | a mapping of type (and disjoint class) identifiers
5784N/Atype IdMap = Map.Map Id Id
5784N/A
5784N/A-- | for data types the morphism needs to be kept as well
5784N/Adata DataEntry =
5784N/A DataEntry IdMap Id GenKind [TypeArg] RawKind (Set.Set AltDefn)
5784N/A deriving (Show, Eq, Ord)
5784N/A
5784N/A-- | possible definitions for type identifiers
5784N/Adata TypeDefn =
5784N/A NoTypeDefn
5784N/A | PreDatatype -- auxiliary entry for DatatypeDefn
5784N/A | DatatypeDefn DataEntry
5784N/A | AliasTypeDefn Type
5784N/A deriving (Show, Eq)
5784N/A
5784N/A-- | for type identifiers also store the raw kind, instances and supertypes
5784N/Adata TypeInfo = TypeInfo
5784N/A { typeKind :: RawKind
5784N/A , otherTypeKinds :: Set.Set Kind
5784N/A , superTypes :: Set.Set Id -- only declared or direct supertypes?
5784N/A , typeDefn :: TypeDefn
5784N/A } deriving Show
5784N/A
5784N/Ainstance Eq TypeInfo where
5784N/A t1 == t2 = (typeKind t1, otherTypeKinds t1, superTypes t1)
5784N/A == (typeKind t2, otherTypeKinds t2, superTypes t2)
5784N/A
5784N/A-- | mapping type identifiers to their definition
5784N/Atype TypeMap = Map.Map Id TypeInfo
5784N/A
5784N/A-- | the minimal information for a sort
5784N/AstarTypeInfo :: TypeInfo
5784N/AstarTypeInfo = TypeInfo rStar (Set.singleton universe) Set.empty NoTypeDefn
5784N/A
5784N/A-- | rename the type according to identifier map (for comorphisms)
5784N/AmapType :: IdMap -> Type -> Type
5784N/AmapType m = if Map.null m then id else
5784N/A foldType mapTypeRec
5784N/A { foldTypeName = \ t i k n -> if n /= 0 then t else
5784N/A case Map.lookup i m of
5784N/A Just j -> TypeName j k 0
5784N/A Nothing -> t }
5784N/A
5784N/A-- * sentences
5784N/A
5784N/A-- | data types are also special sentences because of their properties
5784N/Adata Sentence =
5784N/A Formula Term
5784N/A | DatatypeSen [DataEntry]
5784N/A | ProgEqSen Id TypeScheme ProgEq
5784N/A deriving (Show, Eq, Ord)
5784N/A
5784N/A-- * variables
5784N/A
5784N/A-- | type variable are kept separately
5784N/Adata TypeVarDefn = TypeVarDefn Variance VarKind RawKind Int deriving Show
5784N/A
5784N/A-- | mapping type variables to their definition
5784N/Atype LocalTypeVars = Map.Map Id TypeVarDefn
5784N/A
5784N/A-- | the type of a local variable
5784N/Adata VarDefn = VarDefn Type deriving Show
5784N/A
5784N/A-- * assumptions
5784N/A
5784N/A-- | name and scheme of a constructor
5784N/Adata ConstrInfo = ConstrInfo
5784N/A { constrId :: Id
5784N/A , constrType :: TypeScheme
5784N/A } deriving (Show, Eq, Ord)
5784N/A
5784N/A-- | possible definitions of functions
5784N/Adata OpDefn =
5784N/A NoOpDefn OpBrand
5784N/A | ConstructData Id -- ^ target type
5784N/A | SelectData (Set.Set ConstrInfo) Id -- ^ constructors of source type
5784N/A | Definition OpBrand Term
5784N/A deriving (Show, Eq)
5784N/A
5784N/A-- | scheme, attributes and definition for function identifiers
5784N/Adata OpInfo = OpInfo
5784N/A { opType :: TypeScheme
5784N/A , opAttrs :: Set.Set OpAttr
5784N/A , opDefn :: OpDefn
5784N/A } deriving Show
5784N/A
5784N/Ainstance Eq OpInfo where
5784N/A o1 == o2 = compare o1 o2 == EQ
5784N/A
5784N/Ainstance Ord OpInfo where
5784N/A compare o1 o2 = compare (opType o1) $ opType o2
5784N/A
5784N/A-- | test for constructor
5784N/AisConstructor :: OpInfo -> Bool
5784N/AisConstructor o = case opDefn o of
5784N/A ConstructData _ -> True
5784N/A _ -> False
5784N/A
5784N/A-- | mapping operation identifiers to their definition
5784N/Atype Assumps = Map.Map Id (Set.Set OpInfo)
5784N/A
5784N/A-- * the local environment and final signature
5784N/A
5784N/A-- | the signature is established by the classes, types and assumptions
5784N/Adata Env = Env
5784N/A { classMap :: ClassMap
5784N/A , typeMap :: TypeMap
5784N/A , localTypeVars :: LocalTypeVars
5784N/A , assumps :: Assumps
5784N/A , localVars :: Map.Map Id VarDefn
5784N/A , sentences :: [Named Sentence]
5784N/A , envDiags :: [Diagnosis]
5784N/A , preIds :: (PrecMap, Set.Set Id)
5784N/A , globAnnos :: GlobalAnnos
5784N/A , counter :: Int
5784N/A } deriving Show
5784N/A
5784N/Ainstance Eq Env where
5784N/A e1 == e2 = (classMap e1, typeMap e1, assumps e1) ==
5784N/A (classMap e2, typeMap e2, assumps e2)
5784N/A
5784N/A-- | the empty environment (fresh variables start with 1)
5784N/AinitialEnv :: Env
5784N/AinitialEnv = Env
5784N/A { classMap = Map.empty
5784N/A , typeMap = Map.empty
5784N/A , localTypeVars = Map.empty
5784N/A , assumps = Map.empty
5784N/A , localVars = Map.empty
5784N/A , sentences = []
5784N/A , envDiags = []
5784N/A , preIds = (emptyPrecMap, Set.empty)
5784N/A , globAnnos = emptyGlobalAnnos
5784N/A , counter = 1 }
5784N/A
5784N/A{- utils for singleton sets that could also be part of "Data.Set". These
5784N/Afunctions rely on 'Data.Set.size' being computable in constant time and
5784N/Awould need to be rewritten for set implementations with a size
5784N/Afunction that is only linear. -}
5784N/A
5784N/A-- | /O(1)/ test if the set's size is one
5784N/AisSingleton :: Set.Set a -> Bool
5784N/AisSingleton s = Set.size s == 1
5784N/A
5784N/A-- | /O(1)/ test if the set's size is greater one
5784N/AhasMany :: Set.Set a -> Bool
5784N/AhasMany s = Set.size s > 1
5784N/A
5784N/Adata Constrain = Kinding Type Kind
5784N/A | Subtyping Type Type
5784N/A deriving (Eq, Ord, Show)
5784N/A
5784N/A-- * accessing the environment
5784N/A
5784N/A-- | add diagnostic messages
5784N/AaddDiags :: [Diagnosis] -> State.State Env ()
5784N/AaddDiags ds = do
5784N/A e <- State.get
5784N/A State.put $ e {envDiags = reverse ds ++ envDiags e}
5784N/A
5784N/A-- | add sentences
5784N/AappendSentences :: [Named Sentence] -> State.State Env ()
5784N/AappendSentences fs = do
5784N/A e <- State.get
5784N/A State.put $ e {sentences = reverse fs ++ sentences e}
5784N/A
5784N/A-- | store a class map
5784N/AputClassMap :: ClassMap -> State.State Env ()
5784N/AputClassMap ce = do
5784N/A e <- State.get
5784N/A State.put e { classMap = ce }
5784N/A
5784N/A-- | store local assumptions
5784N/AputLocalVars :: Map.Map Id VarDefn -> State.State Env ()
5784N/AputLocalVars vs = do
5784N/A e <- State.get
5784N/A State.put e { localVars = vs }
5784N/A
5784N/A-- | converting a result to a state computation
5784N/AfromResult :: (Env -> Result a) -> State.State Env (Maybe a)
5784N/AfromResult f = do
5784N/A e <- State.get
5784N/A let Result ds mr = f e
5784N/A addDiags ds
5784N/A return mr
5784N/A
5784N/A-- | store local type variables
5784N/AputLocalTypeVars :: LocalTypeVars -> State.State Env ()
5784N/AputLocalTypeVars tvs = do
5784N/A e <- State.get
5784N/A State.put e { localTypeVars = tvs }
5784N/A
5784N/A-- | store a complete type map
5784N/AputTypeMap :: TypeMap -> State.State Env ()
5784N/AputTypeMap tm = do
5784N/A e <- State.get
5784N/A State.put e { typeMap = tm }
5784N/A
5784N/A-- | store assumptions
5784N/AputAssumps :: Assumps -> State.State Env ()
5784N/AputAssumps ops = do
5784N/A e <- State.get
5784N/A State.put e { assumps = ops }
5784N/A
5784N/A-- | get the variable
5784N/AgetVar :: VarDecl -> Id
5784N/AgetVar(VarDecl v _ _ _) = v
5784N/A
5784N/A-- | check uniqueness of variables
5784N/AcheckUniqueVars :: [VarDecl] -> State.State Env ()
5784N/AcheckUniqueVars = addDiags . checkUniqueness . map getVar
5784N/A
5784N/A-- * morphisms
5784N/A
5784N/A-- mapping qualified operation identifiers (aka renamings)
5784N/Atype FunMap = Map.Map (Id, TypeScheme) (Id, TypeScheme)
5784N/A
5784N/A-- | keep types and class disjoint and use a single identifier map for both
5784N/Adata Morphism = Morphism
5784N/A { msource :: Env
5784N/A , mtarget :: Env
5784N/A , typeIdMap :: IdMap
5784N/A , funMap :: FunMap
5784N/A } deriving Show
5784N/A
5784N/A-- | construct morphism for subsignatures
5784N/AmkMorphism :: Env -> Env -> Morphism
5784N/AmkMorphism e1 e2 = Morphism
5784N/A { msource = e1
5784N/A , mtarget = e2
5784N/A , typeIdMap = Map.empty
5784N/A , funMap = Map.empty }
5784N/A
5784N/A-- * symbol stuff
5784N/A
5784N/A-- | the type or kind of an identifier
5784N/Adata SymbolType a =
5784N/A OpAsItemType TypeScheme
5784N/A | TypeAsItemType (AnyKind a)
5784N/A | ClassAsItemType (AnyKind a)
5784N/A deriving (Show, Eq, Ord)
5784N/A
5784N/A-- | symbols with their type and env (to look up type aliases)
5784N/Adata Symbol =
5784N/A Symbol {symName :: Id, symType :: SymbolType (), symEnv :: Env}
5784N/A deriving Show
5784N/A
5784N/Ainstance Eq Symbol where
5784N/A s1 == s2 = compare s1 s2 == EQ
5784N/A
5784N/Ainstance Ord Symbol where
5784N/A compare s1 s2 = compare (symName s1, symType s1) (symName s2, symType s2)
5784N/A
5784N/A-- | mapping symbols to symbols
5784N/Atype SymbolMap = Map.Map Symbol Symbol
5784N/A
5784N/A-- | a set of symbols
5784N/Atype SymbolSet = Set.Set Symbol
5784N/A
5784N/A-- | create a type symbol
5784N/AidToTypeSymbol :: Env -> Id -> RawKind -> Symbol
5784N/AidToTypeSymbol e idt k = Symbol idt (TypeAsItemType k) e
5784N/A
5784N/A-- | create a class symbol
5784N/AidToClassSymbol :: Env -> Id -> RawKind -> Symbol
5784N/AidToClassSymbol e idt k = Symbol idt (ClassAsItemType k) e
5784N/A
5784N/A-- | create an operation symbol
5784N/AidToOpSymbol :: Env -> Id -> TypeScheme -> Symbol
5784N/AidToOpSymbol e idt typ = Symbol idt (OpAsItemType typ) e
5784N/A
5784N/A-- | raw symbols where the type of a qualified raw symbol is not yet analysed
5784N/Adata RawSymbol =
5784N/A AnID Id
5784N/A | AKindedId SymbKind Id
5784N/A | AQualId Id (SymbolType Id)
5784N/A | ASymbol Symbol
5784N/A deriving (Show, Eq, Ord)
5784N/A
5784N/A-- | mapping raw symbols to raw symbols
5784N/Atype RawSymbolMap = Map.Map RawSymbol RawSymbol
5784N/A
5784N/A-- | create a raw symbol from an identifier
5784N/AidToRaw :: Id -> RawSymbol
5784N/AidToRaw x = AnID x
5784N/A
5784N/A-- | extract the top identifer from a raw symbol
5784N/ArawSymName :: RawSymbol -> Id
5784N/ArawSymName r = case r of
5784N/A AnID i -> i
5784N/A AKindedId _ i -> i
5784N/A AQualId i _ -> i
5784N/A ASymbol s -> symName s
5784N/A
5784N/A-- | convert a symbol type to a symbol kind
5784N/AsymbTypeToKind :: SymbolType a -> SymbKind
5784N/AsymbTypeToKind s = case s of
5784N/A OpAsItemType _ -> SK_op
5784N/A TypeAsItemType _ -> SK_type
5784N/A ClassAsItemType _ -> SK_class
5784N/A
5784N/A-- | wrap a symbol as raw symbol (is 'ASymbol')
5784N/AsymbolToRaw :: Symbol -> RawSymbol
5784N/AsymbolToRaw sym = ASymbol sym
5784N/A
5784N/A-- | create a raw symbol from a symbol kind and an identifier
5784N/AsymbKindToRaw :: SymbKind -> Id -> RawSymbol
5784N/AsymbKindToRaw sk = case sk of
5784N/A Implicit -> AnID
5784N/A _ -> AKindedId $ case sk of
5784N/A SK_pred -> SK_op
5784N/A SK_fun -> SK_op
5784N/A SK_sort -> SK_type
5784N/A _ -> sk
5784N/A
5784N/AgetCompoundLists :: Env -> Set.Set [Id]
5784N/AgetCompoundLists e = Set.delete [] $ Set.map getCompound $ Set.union
5784N/A (Map.keysSet $ assumps e) $ Map.keysSet $ typeMap e
5784N/A where getCompound (Id _ cs _) = cs
5784N/A