fregel-1.2.0: compiler/DependencySimple.hs
{-# Language TypeSynonymInstances,FlexibleInstances,MultiParamTypeClasses,FunctionalDependencies,RankNTypes,FlexibleContexts,KindSignatures,ScopedTypeVariables #-}
{-
Collecting dependency info. as the last phase of transformation on ASTs. (10th step)
-}
module DependencySimple where
import Spec
import ASTData
import Control.Monad.State
import Data.Maybe
import Data.List
import Numeric (showHex)
import Debug.Trace
-- entry point
computeDependency p = let (p', _) = runState (depAnnotate p) ()
in p'
class DependencyAnnotatable a where
depAnnotate :: a -> State () a -- reannotate [name to which the given term depends]
depAnnotate x = return x -- default
instance DependencyAnnotatable (DProgramSpec DASTData) where
depAnnotate (DProgramSpec rs p a) =
do p' <- depAnnotate p
return (DProgramSpec rs p' a)
instance DependencyAnnotatable (DConst DASTData)
liftToGD def = DGDefSmpl def (getData def)
getDep :: forall (t :: * -> *) . (DAdditionalData (t DASTData) DASTData) => (t DASTData) -> [String]
getDep = (depOf . getData)
setDep :: forall (t :: * -> *) . (DAdditionalData (t DASTData) DASTData) => [String] -> (t DASTData) -> (t DASTData)
setDep deps x = setData ((getData x) { depOf = deps}) x
removeDep names deps = foldr delete deps names
instance DependencyAnnotatable (DProg DASTData) where
depAnnotate (DProg f defs e a) =
do defs' <- mapM depAnnotate defs
e' <- depAnnotate e
let deps = removeDep (concatMap getNames defs'++["g"]) $ normalizeDepsX $ map getDep defs' ++ [depOf (getData e')]
f' = setDep deps f
a' = a { depOf = deps}
return (DProg f' defs' e' a')
instance DependencyAnnotatable (DGroundDef DASTData) where
depAnnotate (DGDefVI d a) = do d' <- depAnnotate d
return (DGDefVI d' (a {depOf = getDep d'}) )
depAnnotate (DGDefVC d a) = do d' <- depAnnotate d
return (DGDefVC d' (a {depOf = getDep d'}))
depAnnotate (DGDefGV d a) = do d' <- depAnnotate d
return (DGDefGV d' (a {depOf = getDep d'}))
depAnnotate (DGDefGF d a) = do d' <- depAnnotate d
return (DGDefGF d' (a {depOf = getDep d'}))
depAnnotate (DGDefSmpl d a) = do d' <- depAnnotate d
return (DGDefSmpl d' (a {depOf = getDep d'}))
depAnnotateLet
:: forall (t :: * -> *) (v :: * -> *).
(DAdditionalData (v DASTData) DASTData,
DAdditionalData (t DASTData) DASTData,
DependencyAnnotatable (v DASTData)
)
=> [(t DASTData)] -> [(DSmplDef DASTData)] -> (v DASTData) -> DASTData -> [String] -> State () ([(t DASTData)], [(DSmplDef DASTData)], (v DASTData), DASTData)
depAnnotateLet vs defs e a names =
do defs' <- mapM depAnnotate defs
e' <- depAnnotate e
let deps = removeDep (concatMap getNames defs'++names) $ normalizeDepsX $ map getDep defs' ++ [depOf (getData e')]
vs' = map (setDep deps) vs
a' = a { depOf = deps}
return (vs', defs', e', a')
instance DependencyAnnotatable (DDefVertComp DASTData) where
depAnnotate (DDefVertComp f defs e a) =
do x <- depAnnotateLet [f] defs e a ["v", "prev", "curr"]
let ([f'], defs', e', a') = x
return (DDefVertComp f' defs' e' a')
instance DependencyAnnotatable (DDefVertInit DASTData) where
depAnnotate (DDefVertInit f defs e a) =
do x <- depAnnotateLet [f] defs e a ["v"]
let ([f'], defs', e', a') = x
return (DDefVertInit f' defs' e' a')
instance DependencyAnnotatable (DDefGraphVar DASTData) where
depAnnotate (DDefGraphVar v e a) =
do e' <- depAnnotate e
let v' = setDep (getDep e') v
return (DDefGraphVar v' e' (a {depOf = getDep v'}))
instance DependencyAnnotatable (DDefGraphFun DASTData) where
depAnnotate (DDefGraphFun f v defs e a) =
do defs' <- mapM depAnnotate defs
e' <- depAnnotate e
let ds = removeDep (getNames v ++ concatMap getNames defs)$ normalizeDepsX $ [getDep e'] ++ map getDep defs'
f' = setDep ds f
return (DDefGraphFun f' v defs' e' (a {depOf = getDep f'}))
instance DependencyAnnotatable (DSmplDef DASTData) where
depAnnotate (DDefFun f vs [] e a) =
do x <- depAnnotateLet [f] [] e a (concatMap getNames vs)
let ([f'], _, e', a') = x
return (DDefFun f' vs [] e' a')
depAnnotate (DDefVar v [] e a) =
do x <- depAnnotateLet [v] [] e a []
let ([v'], _, e', a') = x
return (DDefVar v' [] e' a')
depAnnotate (DDefTuple vs [] e a) =
do x <- depAnnotateLet vs [] e a (concatMap getNames vs)
let (vs', _, e', a') = x
return (DDefTuple vs' [] e' a')
instance DependencyAnnotatable (DTermination DASTData) where
depAnnotate (DTermF a) = return (DTermF a)
depAnnotate (DTermI e a) =
do e' <- depAnnotate e
return (DTermI e' (a { depOf = getDep e'}))
depAnnotate (DTermU e a) =
do e' <- depAnnotate e
return (DTermU e' (a { depOf = removeDep ["g"] (getDep e')}))
getDeps4 t1 t2 t3 t4 = normalizeDepsX $ [getDep t1, getDep t2, getDep t3, getDep t4]
getDeps3 t1 t2 t3 = normalizeDepsX $ [getDep t1, getDep t2, getDep t3]
getDeps t1 t2 = normalizeDepsX $ [getDep t1, getDep t2]
getDepsX ts = normalizeDepsX $ map getDep ts
normalizeDeps = nub -- remove duplicated dependency entries
normalizeDepsX = foldr (\a r -> normalizeDeps (a++r)) []
instance DependencyAnnotatable (DGraphExpr DASTData) where
depAnnotate (DPregel f0 ft x g a) =
do f0' <- depAnnotate f0
ft' <- depAnnotate ft
x' <- depAnnotate x
g' <- depAnnotate g
let ds = normalizeDepsX $ [getDeps4 f0' ft' x' g'] ++ [getNames f0', getNames ft'] --, getNames g' ]
return (DPregel f0' ft' x' g' (a {depOf = ds}))
depAnnotate (DGMap f g a) =
do f' <- depAnnotate f
g' <- depAnnotate g
let ds = normalizeDepsX $ [getDeps f' g'] -- ++ [getNames f', getNames g' ]
return (DGMap f' g' (a {depOf = ds}))
depAnnotate (DGZip g1 g2 a) =
do g1' <- depAnnotate g1
g2' <- depAnnotate g2
let ds = normalizeDepsX $ [getDeps g1' g2'] -- ++ [getNames g1', getNames g2' ]
return (DGZip g1' g2' (a {depOf = ds}))
depAnnotate (DGIter f0 ft x g a) =
do f0' <- depAnnotate f0
ft' <- depAnnotate ft
x' <- depAnnotate x
g' <- depAnnotate g
let ds = normalizeDepsX $ [getDeps4 f0' ft' x' g']++ [getNames f0', getNames ft'] -- , getNames g' ]
return (DGIter f0' ft' x' g' (a {depOf = ds}))
depAnnotate (DGVar v a) =
do v' <- depAnnotate v
return (DGVar v' (a {depOf = getDep v'}))
instance DependencyAnnotatable (DExpr DASTData) where
depAnnotate (DIf p t e a) =
do p' <- depAnnotate p
t' <- depAnnotate t
e' <- depAnnotate e
let ds = getDeps3 p' t' e'
return (DIf p' t' e' (a {depOf = ds}))
depAnnotate (DTuple es a) =
do es' <- mapM depAnnotate es
let ds = getDepsX es'
return (DTuple es' (a {depOf = ds}))
depAnnotate (DFunAp f es a) =
do f' <- depAnnotate f
es' <- mapM depAnnotate es
let ds = normalizeDepsX (getDep f' : map getDep es')
return (DFunAp f' es' (a {depOf = ds}))
depAnnotate (DConsAp c es a) =
do c' <- depAnnotate c
es' <- mapM depAnnotate es
let ds = normalizeDepsX (getDep c' : map getDep es')
return (DConsAp c' es' (a {depOf = ds}))
depAnnotate (DFieldAcc t fs a) =
do t' <- depAnnotate t
fs' <- mapM depAnnotate fs
let ds = normalizeDepsX (getDep t' : map getDep fs')
return (DFieldAcc t' fs' (a {depOf = ds}))
depAnnotate (DFieldAccE e fs a) =
do e' <- depAnnotate e
fs' <- mapM depAnnotate fs
let ds = normalizeDepsX (getDep e' : map getDep fs')
return (DFieldAccE e' fs' (a {depOf = ds}))
depAnnotate (DAggr a' e g es a) =
do a'' <- depAnnotate a'
g' <- depAnnotate g
e' <- depAnnotate e
es' <- mapM depAnnotate es
let ds = removeDep (case g of (DGenG _) -> ["u"]; (DGenTermG _) -> ["u"]; _ -> ["u","e"]) $ normalizeDepsX (getDep g' : getDep a'' : map (getDep) (e':es'))
return (DAggr a'' e' g' es' (a {depOf = ds}))
depAnnotate (DVExp v a) =
do v' <- depAnnotate v
return (DVExp v' (a {depOf = getDep v'}))
depAnnotate (DCExp c a) =
do c' <- depAnnotate c
return (DCExp c' (a {depOf = getDep c'}))
instance DependencyAnnotatable (DAgg DASTData) where
depAnnotate (DAggMin a) =
do return (DAggMin (a { depOf = ["minimum"] }))
depAnnotate (DAggMax a) =
do return (DAggMax (a { depOf = ["maximum"] }))
depAnnotate (DAggSum a) =
do return (DAggSum (a { depOf = ["sum"] }))
depAnnotate (DAggProd a) =
do return (DAggProd (a { depOf = ["prod"] }))
depAnnotate (DAggAnd a) =
do return (DAggAnd (a { depOf = ["and"] }))
depAnnotate (DAggOr a) =
do return (DAggOr (a { depOf = ["or"] }))
depAnnotate (DAggChoice x a) =
do x' <- depAnnotate x
let ds = getDep x'
return (DAggChoice x' (a { depOf = "random":ds }))
depAnnotate (DTupledAgg as a) =
do as' <- mapM depAnnotate as
let ds = getDepsX as'
return (DTupledAgg as' (a { depOf = ds }))
instance DependencyAnnotatable (DGen DASTData) where
depAnnotate (DGenI a) = return (DGenI (a {depOf = ["v"]}))
depAnnotate (DGenO a) = return (DGenO (a {depOf = ["v"]}))
depAnnotate (DGenG a) = return (DGenG (a {depOf = ["g"]}))
depAnnotate (DGenTermG a) = return (DGenTermG (a {depOf = ["g"]}))
instance DependencyAnnotatable (DEdge DASTData) where
depAnnotate (DEdge a) = return (DEdge (a {depOf = ["e"]}))
instance DependencyAnnotatable (DTableExpr DASTData) where
depAnnotate (DPrev v a) = return (DPrev v (a {depOf = [getName v, "prev"]}))
depAnnotate (DCurr v a) = return (DCurr v (a {depOf = [getName v, "curr"]}))
depAnnotate (DVal v a) = return (DVal v (a {depOf = [getName v, "val"]}))
instance DependencyAnnotatable (DField DASTData) where
-- depAnnotate (DFfst a) = return (DFfst (a {depOf = ["_fst"]}))
-- depAnnotate (DFsnd a) = return (DFsnd (a {depOf = ["_snd"]}))
depAnnotate (DField f a) = return (DField f (a {depOf = [f]}))
instance DependencyAnnotatable (DFun DASTData) where
depAnnotate (DBinOp f a) = return (DBinOp f (a {depOf = [f]}))
depAnnotate (DFun f a) = return (DFun f (a {depOf = [f]}))
instance DependencyAnnotatable (DVar DASTData) where
depAnnotate (DVar v a) = return (DVar v (a {depOf = [v]}))
instance DependencyAnnotatable (DConstructor DASTData) where
depAnnotate (DConstructor c a) = return (DConstructor c (a {depOf = [c]}))