module LOAG.Common where
import qualified Data.Array as A
import qualified Data.Map as M
import qualified Data.IntMap as IM
import qualified Data.IntSet as IS
import qualified Data.Set as S
import qualified Data.Sequence as Seq
import Data.Maybe (isNothing)
import Data.STRef
import Data.Array.ST
import Data.List (intercalate, foldl', nub)
import CommonTypes
import Control.Arrow
import Control.Monad.ST
import Control.Monad (forM, when, forM_, forM_, foldM)
import LOAG.Graphs
data Ag = Ag (Int,Int)
(Int,Int)
[Edge]
[Nt]
data Nt = Nt String
[Edge]
[Edge]
[(Vertex,[Vertex],Direction)]
[(Vertex,[Vertex],Direction)]
[Pr]
deriving (Show)
data Pr = Pr PLabel
[Edge]
[(Edge,Edge,Bool)]
[Fd]
deriving (Show)
data Fd = Fd String
String
[(Vertex,Vertex)]
[(Vertex,Vertex)]
deriving (Show)
type Attrs = [Attr]
data Attr = Attr String Direction MyType
deriving (Show, Eq, Ord)
data Direction = Inh | AnyDir | Syn
deriving (Show, Ord, Enum)
foldM' :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
foldM' _ a [] = return a
foldM' f a (x:xs) = f a x >>= \fax -> fax `seq` foldM f fax xs
modifyArray r k f = do
v <- readArray r k
writeArray r k (f v)
setConcatMap f = S.foldr (S.union . f) S.empty
isLoc (MyOccurrence (_,f) _) = f == "loc" || f == "inst"
instance Eq Direction where
Inh == Syn = False
Syn == Inh = False
_ == _ = True
data MyType = TyInt
| TyBool
| TyString
| TyData String
| TyLit String
| TyArr MyType MyType
| NoType
| AnyType
type SchedRef s = (STArray s Vertex (Maybe Int),ThreadRef s)
type AttrAssRef s = STArray s Vertex (Maybe Int)
type ThreadRef s = STRef s InterfaceRes
type PLabel = (MyType,String)
type FLabel = String
type ALabel = (String, Direction)
type AI_N = M.Map MyType MyAttributes
type AS_N = M.Map MyType MyAttributes
type A_N = M.Map MyType MyAttributes
type A_P = M.Map PLabel MyOccurrences
type FTY = M.Map (PLabel, FLabel) MyType
type TYFS = M.Map MyType [(PLabel, FLabel)]
type SF_P = M.Map MyOccurrence (S.Set MyOccurrence)
type PMP = M.Map Int MyOccurrence
type PMP_R = M.Map MyOccurrence Int
type NMP = M.Map Int MyAttribute
type NMP_R = M.Map MyAttribute Int
type FMap = M.Map (PLabel,FLabel) (S.Set MyOccurrence, S.Set MyOccurrence)
type FsInP = M.Map PLabel [(PLabel, FLabel)]
type LOAGRes = ( Maybe TDPRes
, InterfaceRes
, ADSRes)
type VisCount= (Int, Int, Float)
type ADSRes = [Edge]
type TDPRes = A.Array Vertex Vertices
type TDPGraph = (IM.IntMap Vertices, IM.IntMap Vertices)
type InterfaceRes = M.Map String (IM.IntMap [Vertex])
type HOMap = M.Map PLabel (S.Set FLabel)
data CType = T1 | T2
| T3 [Edge]
deriving (Show)
findWithErr :: (Ord k, Show k, Show a) => M.Map k a -> String -> k -> a
findWithErr m err k = maybe (error err) id $ M.lookup k m
findWithErr' m err k= maybe (error err) id $ IM.lookup k m
type MyAttributes = [MyAttribute]
data MyAttribute = MyAttribute {typeOf :: MyType, alab :: ALabel}
deriving (Ord, Eq)
(<.>) = MyAttribute
infixl 7 <.>
instance Show MyAttribute where
show (MyAttribute t a) = show t ++ "<.>" ++ show a
type MyOccurrences = [MyOccurrence]
data MyOccurrence = MyOccurrence {argsOf :: (PLabel, FLabel), attr :: ALabel}
deriving (Ord, Eq)
(>.<) = MyOccurrence
infixl 8 >.<
instance Show MyOccurrence where
show (MyOccurrence ((t,p),f) a) =
intercalate "." [show t,p,f] ++ "."++ show a
dirOfOcc :: MyOccurrence -> Direction
dirOfOcc = snd . attr
handOut :: (PLabel, FLabel) -> MyAttribute -> MyOccurrence
handOut p = (p >.<) . alab
handAllOut :: (PLabel, FLabel) -> MyAttributes -> MyOccurrences
handAllOut p os = map (handOut p) os
map2F :: (Ord a) => M.Map a [b] -> a -> [b]
map2F m a = case M.lookup a m of
Nothing -> []
Just bs -> bs
map2F' :: (Ord a) => M.Map a (S.Set b) -> a -> (S.Set b)
map2F' m a = case M.lookup a m of
Nothing -> S.empty
Just bs -> bs
flipDir :: Direction -> Direction
flipDir Syn = Inh
flipDir Inh = Syn
pairs :: [a] -> [(a,a)]
pairs [] = []
pairs (x:xs) = map ((,) x) xs ++ pairs xs
toMyTy :: Type -> MyType
toMyTy (Haskell str) = TyLit str
toMyTy (NT id _ _ ) = TyData $ getName id
toMyTy Self = error "Type Self in phase 3"
fromMyTy :: MyType -> Type
fromMyTy (TyLit str) = (Haskell str)
fromMyTy (TyData id) = NT (identifier id) [] False
toMyAttr :: Direction -> MyType -> Attributes -> MyAttributes
toMyAttr d dty = M.foldrWithKey
(\ident ty as -> dty <.> (getName ident,d):as) []
completing :: FrGraph -> SchedRef s -> [Nt] -> ST s InterfaceRes
completing ids sched nts = do
ims <- forM nts $ completingN ids (fst sched)
let threads = (M.fromList ims)
writeSTRef (snd sched) threads
return $ threads
completingN :: FrGraph -> AttrAssRef s -> Nt ->
ST s ((String, IM.IntMap [Vertex]))
completingN ids@(idsf, idst) schedA
(Nt nt_id _ _ inhs syns _) = do
schedS <- newSTRef IM.empty
let attrs = inhs ++ syns
dty = TyData nt_id
assign (attr,_,dAttr) = do
let succs = idsf A.! attr
assigned <- freeze schedA
when (isNothing $ assigned A.! attr) $ do
case IS.toList succs of
[] ->wrap_up attr(if Syn==dAttr then 1 else 2)
ss ->case selMax $ map (id&&&(assigned A.!)) ss of
Nothing -> return ()
Just (a,mx) -> do
let dA | even mx = Inh
| otherwise = Syn
wrap_up attr (if dA == dAttr
then mx else mx+1)
wrap_up attr k = do
modifySTRef schedS (IM.insertWith (++) k [attr])
writeArray schedA attr (Just k)
forM_ attrs assign
selMax :: [(Vertex, Maybe Int)] -> Maybe (Vertex, Int)
selMax [(v,mi)] = fmap ((,) v) mi
selMax (x:xs) = case x of
(a', Nothing) -> Nothing
(a', Just i') ->
case selMax xs of
Nothing -> Nothing
Just (a,i) ->
case compare i i' of
LT -> Just (a',i')
_ -> Just (a,i)
case attrs of
[] -> return (nt_id, IM.fromList [(1,[]),(2,[])])
as -> forM_ as assign >> readSTRef schedS >>= return . ((,) nt_id)
fetchEdges :: FrGraph -> InterfaceRes -> [Nt] -> ([Edge],[Edge])
fetchEdges ids threads nts =
let ivdNs = map (fetchEdgesN ids threads) nts
in (concat *** concat) $ unzip ivdNs
fetchEdgesN :: FrGraph -> InterfaceRes -> Nt
-> ([Edge],[Edge])
fetchEdgesN (idsf, idst) threads
(Nt nt_id _ _ _ _ _) =
let sched = findWithErr threads "schedule err" nt_id
mx = if IM.null sched then 0 else fst $ IM.findMax sched
findK 0 = []
findK k = (maybe [] id $ IM.lookup k sched) ++ findK (k-1)
ivd = [ (f,t) | k <- [2..mx]
, f <- maybe [] id $ IM.lookup k sched
, t <- findK (k-1)]
in (ivd, [ (f, t) | (f, t) <- ivd
, not $ IS.member t (idsf A.! f) ])
instance Show MyType where
show TyInt = "Int"
show TyBool = "Bool"
show TyString = "String"
show (TyData t) = t
show (TyLit t) = show t
show (TyArr a b) = show a ++ " -> (" ++ show b ++ ")"
show NoType = error "Trying to show NoType"
show AnyType = "AnyType"
instance Eq MyType where
TyInt == TyInt = True
TyBool == TyBool = True
TyString == TyString = True
TyData n == TyData n' = n == n'
TyLit ty == TyLit ty' = ty == ty'
TyArr l r == TyArr l' r' = l == l' && r == r'
NoType == _ = False
_ == NoType = False
AnyType == _ = True
_ == AnyType = True
_ == _ = False
instance Ord MyType where
NoType `compare` _ = LT
_ `compare` NoType = GT
AnyType `compare` _ = EQ
_ `compare` AnyType = EQ
TyInt `compare` TyInt = EQ
TyInt `compare` _ = LT
TyBool `compare` TyInt = GT
TyBool `compare` TyBool = EQ
TyBool `compare` _ = LT
TyString `compare` TyInt = GT
TyString `compare` TyBool = GT
TyString `compare` TyString = EQ
TyString `compare` _ = LT
TyData _ `compare` TyInt = GT
TyData _ `compare` TyBool = GT
TyData _ `compare` TyString = GT
TyData a `compare` TyData b = compare a b
TyData _ `compare` _ = LT
TyLit a `compare` TyLit b = compare a b
TyLit _ `compare` TyArr _ _= LT
TyLit _ `compare` _ = GT
TyArr a a' `compare` TyArr b b' =
case compare a b of
LT -> LT
GT -> GT
EQ -> compare a' b'
TyArr _ _ `compare` _ = GT