{- |
Module : ./CSL/GuardedDependencies.hs
Description : Guarded Dependency Store
Copyright : (c) Ewaryst Schulz, DFKI Bremen 2011
License : GPLv2 or higher, see LICENSE.txt
Maintainer : Ewaryst.Schulz@dfki.de
Stability : experimental
Portability : portable
Definition of guarded dependencies resulting from the use of extended
parameters.
-}
module CSL.GuardedDependencies
where
import Common.AS_Annotation
import Common.Doc
import Common.DocUtils
import CSL.AS_BASIC_CSL
import CSL.ASUtils
import CSL.Sign as Sign
import CSL.EPRelation
import Control.Monad
import qualified Data.Set as Set
import qualified Data.Map as Map
-- ** Datatypes and guarded definitions
{- | A guard consists of the guard range and the corresponding expression
together with a name, a set of not propagated parameters and a set of
constrained parameters (in the extended parameter specification) -}
data Guard a = Guard { range :: a
, definition :: EXPRESSION
, assName :: String
, filtered :: Set.Set String
, constrained :: Set.Set String }
prettyGuard :: (a -> Doc) -> Guard a -> Doc
prettyGuard f g = f (range g) <+> text "-->" <+> pretty (definition g)
instance Functor Guard where
fmap f (Guard x e an fs ct) = Guard (f x) e an fs ct
instance Pretty a => Pretty (Guard a) where
pretty = prettyGuard pretty
instance Pretty a => Show (Guard a) where
show = show . pretty
{- | A guarded constant consists of the argument list (for function definitions)
and a list of guard-expressions -}
data Guarded a = Guarded { argvars :: [String]
, guards :: [Guard a] }
{- Comment it in if needed later
undefinedGuard :: String -> a -> Guard a
undefinedGuard s x = Guard { range = x
, definition = err
, assName = err
, filtered = err
, constrained = err }
where err = error $ "undefinedGuard: " ++ s
undefinedGuarded :: String -> a -> Guarded a
undefinedGuarded s x = Guarded { argvars = []
, guards = [undefinedGuard s x] }
-}
prettyGuarded :: (a -> Doc) -> Guarded a -> Doc
prettyGuarded f grdd = vcat $ map (prettyGuard f) $ guards grdd
instance Functor Guarded where
fmap f grdd = grdd { guards = map (fmap f) $ guards grdd }
instance Pretty a => Pretty (Guarded a) where
pretty = prettyGuarded pretty
instance Pretty a => Show (Guarded a) where
show = show . pretty
type GuardedMap a = Map.Map String (Guarded a)
addAssignment :: String -> OpDecl -> EXPRESSION -> GuardedMap [EXTPARAM]
-> GuardedMap [EXTPARAM]
addAssignment n (OpDecl sc epl al _) def m =
let combf x y | argvars x == argvars y = y { guards = guards y ++ guards x }
| otherwise =
error "addAssignment: the argument vars does not match."
grd = Guarded (map varDeclName al) [uncurry (Guard epl def n)
$ filteredConstrainedParams epl]
in Map.insertWith combf (simpleName $ OpUser sc) grd m
{- TODO:
1. analysis for missing definitions and undeclared extparams
2. Integrating extparam domain definitions
3. check for each constant if the Guards exhaust the extparam domain (in splitAS)
-}
-- | Splits the Commands into the AssignmentStore and a program sequence
splitAS :: [Named CMD] -> (GuardedMap [EXTPARAM], [Named CMD])
splitAS cl =
let f nc (m, l) = case sentence nc of
Ass c def -> (addAssignment (senAttr nc) c def m, l)
_ -> (m, nc : l)
in foldr f (Map.empty, []) cl