fregel-1.2.0: compiler/Spec.lhs
> {-# LANGUAGE FlexibleContexts,FlexibleInstances,MultiParamTypeClasses,FunctionalDependencies #-}
> module Spec where
> import Control.Monad.State
> import Data.List
BNF of the DSL (ver 1.0p2)
position of let-bindings is limited.
Program specification is I/O type definitions and a program body
ProgramSpec := RecordSpec* Prog
RecordSpec := 'data' Constructor '=' Constructor '{' Field '::' Type (',' Field '::' Type )* '}' 'deriving' '(' 'Eq' ',' 'Show' ')'
-- simple version Constructor '{' Field '::' Type (',' Field '::' Type )* '}'
-- not runnable in Haskell, though
> data DProgramSpec a = DProgramSpec [DRecordSpec a] (DProg a) a deriving (Show, Eq)
> data DRecordSpec a = DRecordSpec (DConstructor a) [(DField a, DType a)] a deriving (Show, Eq)
A program body is a graph function with ground definitions.
The argument is 'g'! (this will be used in all global aggregations)
Prog := Fun 'g' '=' 'let' GroundDefs 'in' GraphExpr
GroundDefs := GroundDef (';' GraphDef)* -- not indentation-based
> data DProg a = DProg (DFun a) [DGroundDef a] (DGraphExpr a) a deriving (Show, Eq)
A ground definition can contain definitions of vertex-compute functions.
A vertex-compute function receives two special tables Prev and Curr.
GroundDef := DefVertComp | DefVertInit | DefGraphFun | DefGraphVar | SmplDef
DefVertComp := Fun 'v' 'prev' 'curr' '=' (Expr | 'let' SmplDefs 'in' Expr)
DefVertInit := Fun 'v' '=' (Expr | 'let' SmplDefs 'in' Expr)
DefGraphVar := Var '=' GraphExpr
DefGraphFun := Fun Var '=' (GraphExpr | 'let' DefGraphVars 'in' GraphExpr)
> data DGroundDef a = DGDefVC (DDefVertComp a) a
> | DGDefVI (DDefVertInit a) a
> | DGDefGV (DDefGraphVar a) a
> | DGDefGF (DDefGraphFun a) a
> | DGDefSmpl (DSmplDef a) a
> deriving (Show, Eq)
> data DDefVertComp a = DDefVertComp (DFun a) [DSmplDef a] (DExpr a) a deriving (Show, Eq)
> data DDefVertInit a = DDefVertInit (DFun a) [DSmplDef a] (DExpr a) a deriving (Show, Eq)
> data DDefGraphVar a = DDefGraphVar (DVar a) (DGraphExpr a) a deriving (Show, Eq)
> data DDefGraphFun a = DDefGraphFun (DFun a) (DVar a) [DDefGraphVar a] (DGraphExpr a) a deriving (Show, Eq)
A graph expression is made by 'pregel', 'gmap', 'gzip', 'giter', ... and restricted 'let' expressions.
-- pregel can be invoked on a variable and not on an expression
GraphExpr := 'fregel' Fun Fun Termination Var
| 'gmap' Fun Var
| 'gzip' Var Var
| 'giter' Fun Fun Termination Var
| Var
Termination := 'Fix'
| '(' 'Iter' Expr ')'
| '(' 'UntilAny' PredVExpr ')'
| '(' 'UntilAll' PredVExpr ')'
| '(' 'Until' PredExpr ')'
| '(' 'While' PredExpr ')'
| '(' Termination ')'
UltilAny, UntilAll, While are replaced with Until + aux.
PredExpr := '(' '\' 'g' '->' Expr ')' # "\g->" is necessary to be run on Haskell
PredVExpr := '(' '\' 'v' '->' Expr ')' # "\v->" is necessary to be run on Haskell
DefGraphVars := DefGraphVar (';' DefGraphVar)* -- not indentation-based
> data DGraphExpr a = DPregel (DFun a) (DFun a) (DTermination a) (DGraphExpr a) a -- (DVar a) a
> | DGMap (DFun a) (DGraphExpr a) a -- (DVar a) a
> | DGZip (DGraphExpr a) (DGraphExpr a) a --(DVar a) (DVar a) a
> | DGIter (DFun a) (DFun a) (DTermination a) (DGraphExpr a) a -- (DVar a) a
> | DGVar (DVar a) a
> deriving (Show, Eq)
> data DTermination a = DTermF a
> | DTermI (DExpr a) a
> | DTermU (DExpr a) a
> | DTermV2H a -- for internal use
> deriving (Show, Eq)
Definition of simple functions and variables (+ tuple binding).
(Is it necessary to distiguish these two?)
SmplDef := DefFun | DefVar | DefTuple
DefFun := Fun Var+ '=' (Expr | 'let' SmplDefs 'in' Expr)
DefVar := Var '=' (Expr | 'let' SmplDefs 'in' Expr)
DefTuple := '(' Var (',' Var)+ ')' '=' (Expr | 'let' SmplDefs 'in' Expr)
SmplDefs := SmplDef (';' SmplDef)* -- not indentation-based
> data DSmplDef a = DDefFun (DFun a) [DVar a] [DSmplDef a] (DExpr a) a
> | DDefVar (DVar a) [DSmplDef a] (DExpr a) a
> | DDefTuple [DVar a] [DSmplDef a] (DExpr a) a
> deriving (Show, Eq)
Expressions.
No anonimous function.
No let-expression ("let" is only allowed in the head of a function definition).
Expr := If | Tuple | FunAp | Var | Const | FieldAccess | Aggr
| '(' Expr ')' -- this is for concrete syntax
If := 'if' Expr 'then' Expr 'else' Expr
Tuple := '(' Expr (',' Expr)+ ')'
FunAp := Fun Expr+
| Constructor Expr+
| Expr '`' Fun '`' Expr
| Expr BinOp Expr
FieldAccess := (TableExpr | Edge ) (('.^' ('_fst' | '_snd'))* '.^' Field)?
TableExpr := 'curr' Var | 'prev' Var | 'val' Var
Aggr := Agg '[' Expr '|' Gen (',' Expr )* ']'
| Agg Expr '[' Expr '|' Gen (',' Expr )* ']'
Edge := 'e'
Gen := '(' 'e' ',' 'u' ')' '<-' 'is' 'v'
| '(' 'e' ',' 'u' ')' '<-' 'rs' 'v'
| 'u' '<-' 'g'
> data DExpr a = DIf (DExpr a) (DExpr a) (DExpr a) a
> | DTuple [DExpr a] a
> | DFunAp (DFun a) [DExpr a] a
> | DConsAp (DConstructor a) [DExpr a] a
> | DFieldAcc (DTableExpr a) [DField a] a
> | DFieldAccE (DEdge a) [DField a] a
> | DAggr (DAgg a) (DExpr a) (DGen a) [DExpr a] a
> | DCheckTerm (DExpr a) a -- Iwasaki: condition for termination
> | DVExp (DVar a) a
> | DCExp (DConst a) a
> deriving (Show, Eq)
> data DGen a = DGenI a
> | DGenO a
> | DGenG a
> | DGenTermG a -- Iwasaki; aggregation for judging termination
> deriving (Show, Eq)
> data DEdge a = DEdge a deriving (Show, Eq)
> data DTableExpr a = DPrev (DVar a) a
> | DCurr (DVar a) a
> | DVal (DVar a) a
> deriving (Show, Eq)
The identities must start with small letters or the underscore.
Prime symbols are allowed only at the end.
BinOP := '+' | '-' | '*' | '/'
| '==' | '!=' | '<' | '>' | '>=' | '<='
| '&&' | '||'
Agg := 'minimum' | 'maximum' | 'sum' | 'prod' | 'and' | 'or' | 'choice'
Fun := [a-z_][a-zA-Z_0-9]*[']*
Var := [a-z_][a-zA-Z_0-9]*[']*
Field := [a-z_][a-zA-Z_0-9]*[']*
Constructor := [A-Z][a-zA-Z_0-9]*[']*
> data DAgg a = DAggMin a
> | DAggMax a
> | DAggSum a
> | DAggProd a
> | DAggAnd a
> | DAggOr a
> | DAggChoice (DExpr a) a -- random choice with default value
> | DTupledAgg [DAgg a] a -- for internal use
> deriving (Show, Eq)
> data DConstructor a = DConstructor String a deriving (Show, Eq)
> data DFun a = DFun String a
> | DBinOp String a
> deriving (Show, Eq)
> data DVar a = DVar String a deriving (Show, Eq)
> data DField a = {- DFfst a | DFsnd a | -} DField String a deriving (Show, Eq)
Constants (integer, boolean, string, floating point number, ...)
Const := Integer | Boolean | String | Double
Integer := '-'? ( [1-9][0-9]* | '0' )
Boolean := 'True' | 'False'
String := '"' [^"]* '"' -- simple definition
Double := '-'? ( [1-9][0-9]* | '0' ) '.' [0-9]*
> data DConst a = DCInt Int a
> | DCBool Bool a
> | DCString String a
> | DCDouble Double a
> deriving (Show, Eq)
Types of each component in the I/O records.
Type := 'Int' | 'Bool' | 'String' | 'Double' | '(' Type (',' Type)* ')'
> data DType a = DTInt a
> | DTBool a
> | DTString a
> | DTDouble a
> | DTTuple [DType a] a
> | DTRecord (DConstructor a) [DType a] a -- for internal use
> deriving (Show, Eq)
------------------------- pretty printer? ------------------
> ppList :: String -> [String] -> String
> ppList c ss = foldr (\(s, c) r -> c ++ s ++ r) "" $ zip ss ("":repeat c)
> ppProgramSpec :: DProgramSpec a -> [String]
> ppProgramSpec (DProgramSpec rs p _) =
> (concatMap ppRecordSpec rs) ++ ppProg p
> ppRecordSpec :: DRecordSpec a -> [String]
> ppRecordSpec (DRecordSpec c fts _) =
> ["data " ++ ppConstructor c ++ " = " ++ ppConstructor c ++ "{" ++ ppfts ++ "} deriving (Eq, Show)"]
> where ppfts = ppList ", " (map (\(f, t) -> ppField f++"::"++ppType t) fts)
> indentWith :: String -> [String] -> [String]
> indentWith s (l:ls) = (s++l) :map ((map (const ' ') s)++) ls
> indentWith s ([]) = []
> indent :: [String] -> [String]
> indent ls = indentWith " " ls
> ppProg :: DProg a -> [String]
> ppProg (DProg f ds e _) = [ppFun f ++ " g = "] ++ rest
> where rest = if length ds == 0 then indent (ppGraphExpr e)
> else indent $ let_in (concat $ insList ";" "" $ map ppGroundDef ds) (ppGraphExpr e)
> let_in :: [String] -> [String] -> [String]
> let_in ds e = indentWith "let " ds ++ indentWith "in " e
> ppGroundDef :: DGroundDef a -> [String]
> ppGroundDef (DGDefVC d _) = ppDefVertComp d
> ppGroundDef (DGDefVI d _) = ppDefVertInit d
> ppGroundDef (DGDefGV d _) = ppDefGraphVar d
> ppGroundDef (DGDefGF d _) = ppDefGraphFun d
> ppGroundDef (DGDefSmpl d _) = ppSmplDef d
> ppDefVertComp :: DDefVertComp a -> [String]
> ppDefVertComp (DDefVertComp f ds e _) =
> if length ds == 0 then indentWith (ppFun f ++ " v prev curr = ") (ppExpr e)
> else [ppFun f ++" v prev curr = "] ++ indent (let_in (concat $ insList ";" "" $map ppSmplDef ds) (ppExpr e))
> ppDefVertInit :: DDefVertInit a -> [String]
> ppDefVertInit (DDefVertInit f ds e _) =
> if length ds == 0 then indentWith (ppFun f ++ " v = ") (ppExpr e)
> else [ppFun f ++" v = "] ++ indent (let_in (concat $ insList ";" "" $map ppSmplDef ds) (ppExpr e))
> ppDefGraphVar :: DDefGraphVar a -> [String]
> ppDefGraphVar (DDefGraphVar v e _) =
> indentWith (ppVar v ++ " = ") (ppGraphExpr e)
>
> ppDefGraphFun :: DDefGraphFun a -> [String]
> ppDefGraphFun (DDefGraphFun f v ds e _) =
> if length ds == 0
> then header ++ indent (ppGraphExpr e)
> else header ++ indent (let_in (concat $ insList ";" "" $ map ppDefGraphVar ds) (ppGraphExpr e))
> where header = [ ppFun f ++ " " ++ (ppVar v) ++ " = " ]
> ppGraphExpr :: DGraphExpr a -> [String] -- this is a singleton list (of String)
> ppGraphExpr (DPregel f0 ft t g _) =
> [ppList " " (["fregel", ppFun f0, ppFun ft, ppTermination t] ++ (addParen $ ppGraphExpr g))]
> ppGraphExpr (DGMap f g _) =
> [ppList " " (["gmap", ppFun f] ++ (addParen $ ppGraphExpr g))]
> ppGraphExpr (DGZip g1 g2 _) =
> [ppList " " (["gzip"] ++ (addParen $ ppGraphExpr g1) ++ (addParen $ ppGraphExpr g2))]
> ppGraphExpr (DGIter f0 ft t g _) =
> [ppList " " (["giter", ppFun f0, ppFun ft, ppTermination t] ++ (addParen $ ppGraphExpr g))]
> ppGraphExpr (DGVar g _) =
> [ppVar g]
> addParen [s] = ["(" ++ s ++ ")"]
> ppTermination :: DTermination a -> String
> ppTermination (DTermF _)= "Fix"
> ppTermination (DTermI e _) = "(Iter (" ++ ppList " " (ppExpr e) ++ "))"
> ppTermination (DTermU e _) = "(Until (\\g->" ++ ppList " " (ppExpr e) ++ "))"
> ppTermination (DTermV2H _) = "V2H"
> ppSmplDef :: DSmplDef a -> [String]
> ppSmplDef (DDefFun f vs ds e _) =
> if length ds == 0
> then header ++ indent (ppExpr e)
> else header ++ indent (let_in (concat $ insList ";" "" $map ppSmplDef ds) (ppExpr e))
> where header = [ ppFun f ++ " " ++ ppList " " (map ppVar vs) ++ " = " ]
> ppSmplDef (DDefVar v ds e _) =
> if length ds == 0
> then header ++ indent (ppExpr e)
> else header ++ indent (let_in (concat $ insList ";" "" $map ppSmplDef ds) (ppExpr e))
> where header = [ ppVar v ++ " = "]
> ppSmplDef (DDefTuple vs ds e _) =
> if length ds == 0
> then header ++ indent (ppExpr e)
> else header ++ indent (let_in (concat $ insList ";" "" $map ppSmplDef ds) (ppExpr e))
> where header = ["(" ++ ppList ", " (map ppVar vs) ++ ") = "]
> ppExpr :: DExpr a-> [String]
> ppExpr (DIf c t e _) = indentWith "if " (ppExpr c) ++
> indentWith "then " (ppExpr t) ++
> indentWith "else " (ppExpr e)
> ppExpr (DTuple es _) = indentWith "(" (concat $ insList "," ")" $ map ppExpr es)
> ppExpr (DFunAp (DBinOp o _) (e1:e2:[]) _) = [flatE e1 ++ " " ++ o ++ " " ++ flatE e2]
> ppExpr (DFunAp f es _) = [ppList " " (ppFun f: map flatE es)]
> ppExpr (DConsAp c es _) = [ppList " " (ppConstructor c: map flatE es)]
> ppExpr (DFieldAcc e fs _) = [ ppTableExpr e ++ (concat $ map ((".^"++).ppField) fs) ]
> ppExpr (DFieldAccE e fs _) = [ ppEdge e ++ (concat $ map ((".^"++).ppField) fs) ]
> ppExpr (DAggr a e g es _) =
> [ppAgg a ++ " [ " ++ flatE2 e ++ " | " ++ ppGen g ++ ps ++ " ] "]
> where ps = if length es == 0 then ""
> else "," ++ ppList "," (map flatE es)
> ppExpr (DVExp v _) = [ppVar v]
> ppExpr (DCExp c _) = [ppConst c]
> ppTableExpr (DPrev v _) = "prev " ++ ppVar v
> ppTableExpr (DCurr v _) = "curr " ++ ppVar v
> ppTableExpr (DVal v _) = "val " ++ ppVar v
> ppEdge (DEdge _) = "e"
> ppAgg (DAggMin _) = "minimum"
> ppAgg (DAggMax _) = "maximum"
> ppAgg (DAggSum _) = "sum"
> ppAgg (DAggProd _) = "prod"
> ppAgg (DAggAnd _) = "and"
> ppAgg (DAggOr _) = "or"
> ppAgg (DAggChoice x _) = "random " ++ flatE x
> ppGen (DGenI _) = "(e, u) <- is v"
> ppGen (DGenO _) = "(e, u) <- rs v"
> ppGen (DGenG _) = "u <- g"
> ppGen (DGenTermG _) = "u <- g"
> flatE :: DExpr a -> String
> flatE = enclose . ppList " " . ppExpr
> flatE2 :: DExpr a -> String
> flatE2 = ppList " " . ppExpr
> enclose :: String -> String
> enclose s = "(" ++ s ++ ")"
> insList :: String -> String -> [[String]] -> [[String]]
> insList c cl sss = map (\(ss, s) -> init ss ++ ((last ss++s):[])) $ reverse $ zip (reverse sss) (cl:repeat c)
> ppField (DField f _) = f
> -- ppField (DFfst _) = "_fst"
> -- ppField (DFsnd _) = "_snd"
> ppFun (DFun f _) = f
> ppFun (DBinOp f _) = "(" ++ f ++ ")"
> ppVar (DVar v _) = v
> ppType (DTInt _) = "Int"
> ppType (DTBool _) = "Bool"
> ppType (DTString _) = "String"
> ppType (DTDouble _) = "Double"
> ppType (DTTuple ts _) = "(" ++ ppList ", " (map ppType ts) ++ ")"
> ppType (DTRecord c [] _) = getName c
> ppType (DTRecord c ts _) = "(" ++ getName c ++ concatMap (" "++) (map ppType ts) ++ ")"
> ppConstructor (DConstructor c _) = c
> ppConst (DCInt i _) = show i
> ppConst (DCBool b _) = show b
> ppConst (DCString s _) = "\"" ++ s ++ "\""
> ppConst (DCDouble d _) = show d
> ppAST :: DProgramSpec a -> String
> ppAST = unlines . ppProgramSpec
> right (Right a) = a
> right (Left a) = error $ show a
> class PrettyShow a where
> prettyShow :: a -> String
> flattening = removeMultiSpace . ppList " "
> removeMultiSpace s = map fst $ filter (\(a, b) -> not (a == ' ' && b == ' ')) $ zip s ('@':init s)
> instance PrettyShow (DProgramSpec a) where
> prettyShow = flattening . ppProgramSpec
> instance PrettyShow (DTermination a) where
> prettyShow = ppTermination
> instance PrettyShow (DDefGraphFun a) where
> prettyShow = flattening . ppDefGraphFun
> instance PrettyShow (DDefGraphVar a) where
> prettyShow = flattening . ppDefGraphVar
> instance PrettyShow (DRecordSpec a) where
> prettyShow = flattening . ppRecordSpec
> instance PrettyShow (DProg a) where
> prettyShow = flattening . ppProg
> instance PrettyShow (DGroundDef a) where
> prettyShow = flattening . ppGroundDef
> instance PrettyShow (DExpr a) where
> prettyShow = flattening . ppExpr
> instance PrettyShow (DSmplDef a) where
> prettyShow = flattening . ppSmplDef
> instance PrettyShow (DDefVertInit a) where
> prettyShow = flattening . ppDefVertInit
> instance PrettyShow (DDefVertComp a) where
> prettyShow = flattening . ppDefVertComp
> class DAdditionalData a b | a -> b where
> getData :: a -> b
> setData :: b -> a -> a
> instance DAdditionalData (DProgramSpec a) a where
> getData (DProgramSpec _ _ a) = a
> setData b (DProgramSpec rs p _) = DProgramSpec rs p b
> instance DAdditionalData (DRecordSpec a) a where
> getData (DRecordSpec _ _ a) = a
> setData b (DRecordSpec c fs _) = DRecordSpec c fs b
> instance DAdditionalData (DProg a) a where
> getData (DProg _ _ _ a) = a
> setData b (DProg f ds e _) = DProg f ds e b
> instance DAdditionalData (DGroundDef a) a where
> getData (DGDefVC _ a) = a
> getData (DGDefVI _ a) = a
> getData (DGDefGV _ a) = a
> getData (DGDefGF _ a) = a
> getData (DGDefSmpl _ a) = a
> setData b (DGDefVC x _) = DGDefVC x b
> setData b (DGDefVI x _) = DGDefVI x b
> setData b (DGDefGV x _) = DGDefGV x b
> setData b (DGDefGF x _) = DGDefGF x b
> setData b (DGDefSmpl x _) = DGDefSmpl x b
> instance DAdditionalData (DDefVertComp a) a where
> getData (DDefVertComp _ _ _ a) = a
> setData b (DDefVertComp f ds e _) = DDefVertComp f ds e b
> instance DAdditionalData (DDefVertInit a) a where
> getData (DDefVertInit _ _ _ a) = a
> setData b (DDefVertInit f ds e _) = DDefVertInit f ds e b
> instance DAdditionalData (DDefGraphVar a) a where
> getData (DDefGraphVar _ _ a) = a
> setData b (DDefGraphVar v e _) = DDefGraphVar v e b
> instance DAdditionalData (DDefGraphFun a) a where
> getData (DDefGraphFun _ _ _ _ a) = a
> setData b (DDefGraphFun f v ds e _) = DDefGraphFun f v ds e b
> instance DAdditionalData (DGraphExpr a) a where
> getData (DPregel _ _ _ _ a) = a
> getData (DGMap _ _ a) = a
> getData (DGZip _ _ a) = a
> getData (DGIter _ _ _ _ a) = a
> getData (DGVar _ a) = a
> setData b (DPregel f0 ft x g _) = DPregel f0 ft x g b
> setData b (DGMap f g _) = DGMap f g b
> setData b (DGZip g1 g2 _) = DGZip g1 g2 b
> setData b (DGIter f0 ft x g _) = DGIter f0 ft x g b
> setData b (DGVar g _) = DGVar g b
> instance DAdditionalData (DTermination a) a where
> getData (DTermF a) = a
> getData (DTermI _ a) = a
> getData (DTermU _ a) = a
> getData (DTermV2H a) = a
> setData b (DTermF _) = DTermF b
> setData b (DTermI e _) = DTermI e b
> setData b (DTermU e _) = DTermU e b
> setData b (DTermV2H _) = DTermV2H b
> instance DAdditionalData (DSmplDef a) a where
> getData (DDefFun _ _ _ _ a) = a
> getData (DDefVar _ _ _ a) = a
> getData (DDefTuple _ _ _ a) = a
> setData b (DDefFun f vs ds e _) = DDefFun f vs ds e b
> setData b (DDefVar v ds e _) = DDefVar v ds e b
> setData b (DDefTuple vs ds e _) = DDefTuple vs ds e b
> instance DAdditionalData (DExpr a) a where
> getData (DIf _ _ _ a) = a
> getData (DTuple _ a) = a
> getData (DFunAp _ _ a) = a
> getData (DConsAp _ _ a) = a
> getData (DFieldAcc _ _ a) = a
> getData (DFieldAccE _ _ a) = a
> getData (DAggr _ _ _ _ a) = a
> getData (DVExp _ a) = a
> getData (DCExp _ a) = a
> setData b (DIf p t e _) = DIf p t e b
> setData b (DTuple es _) = DTuple es b
> setData b (DFunAp f es _) = DFunAp f es b
> setData b (DConsAp c es _) = DConsAp c es b
> setData b (DFieldAcc t fs _) = DFieldAcc t fs b
> setData b (DFieldAccE e fs _) = DFieldAccE e fs b
> setData b (DAggr a e g es _) = DAggr a e g es b
> setData b (DVExp v _) = DVExp v b
> setData b (DCExp v _) = DCExp v b
> instance DAdditionalData (DGen a) a where
> getData (DGenI a) = a
> getData (DGenO a) = a
> getData (DGenG a) = a
> getData (DGenTermG a) = a
> setData b (DGenI _) = DGenI b
> setData b (DGenO _) = DGenO b
> setData b (DGenG _) = DGenG b
> setData b (DGenTermG _) = DGenTermG b
> instance DAdditionalData (DEdge a) a where
> getData (DEdge a) = a
> setData b (DEdge _) = DEdge b
> instance DAdditionalData (DTableExpr a) a where
> getData (DPrev _ a) = a
> getData (DCurr _ a) = a
> getData (DVal _ a) = a
> setData b (DPrev v _) = DPrev v b
> setData b (DCurr v _) = DCurr v b
> setData b (DVal v _) = DVal v b
> instance DAdditionalData (DAgg a) a where
> getData (DAggMin a) = a
> getData (DAggMax a) = a
> getData (DAggSum a) = a
> getData (DAggProd a) = a
> getData (DAggAnd a) = a
> getData (DAggOr a) = a
> getData (DAggChoice x a) = a
> getData (DTupledAgg _ a) = a
> setData b (DAggMin _) = DAggMin b
> setData b (DAggMax _) = DAggMax b
> setData b (DAggSum _) = DAggSum b
> setData b (DAggProd _) = DAggProd b
> setData b (DAggAnd _) = DAggAnd b
> setData b (DAggOr _) = DAggOr b
> setData b (DAggChoice x _) = DAggChoice x b
> setData b (DTupledAgg ags _) = DTupledAgg ags b
> instance DAdditionalData (DConstructor a) a where
> getData (DConstructor _ a) = a
> setData b (DConstructor c _) = DConstructor c b
> instance DAdditionalData (DFun a) a where
> getData (DFun _ a) = a
> getData (DBinOp _ a) = a
> setData b (DFun f _) = DFun f b
> setData b (DBinOp f _) = DBinOp f b
> instance DAdditionalData (DVar a) a where
> getData (DVar _ a) = a
> setData b (DVar v _) = DVar v b
> instance DAdditionalData (DField a) a where
> -- getData (DFfst a) = a
> -- getData (DFsnd a) = a
> getData (DField _ a) = a
> -- setData b (DFfst _) = DFfst b
> -- setData b (DFsnd _) = DFsnd b
> setData b (DField f _) = DField f b
> instance DAdditionalData (DConst a) a where
> getData (DCInt _ a) = a
> getData (DCBool _ a) = a
> getData (DCString _ a) = a
> getData (DCDouble _ a) = a
> setData b (DCInt c _) = DCInt c b
> setData b (DCBool c _) = DCBool c b
> setData b (DCString c _) = DCString c b
> setData b (DCDouble c _) = DCDouble c b
> instance DAdditionalData (DType a) a where
> getData (DTInt a) = a
> getData (DTBool a) = a
> getData (DTString a) = a
> getData (DTDouble a) = a
> getData (DTTuple _ a) = a
> getData (DTRecord _ _ a) = a
> setData b (DTInt _) = DTInt b
> setData b (DTBool _) = DTBool b
> setData b (DTString _) = DTString b
> setData b (DTDouble _) = DTDouble b
> setData b (DTTuple ts _) = DTTuple ts b
> setData b (DTRecord c fs _) = DTRecord c fs b
> getName :: (DNamed a) => a -> String
> getName = head . getNames
> class DNamed a where
> getNames :: a -> [String]
> setNames :: a -> State [String] a
> nextName :: State [String] String
> nextName = do xs <- get; put (tail xs); return (head xs)
> instance DNamed (DFun a) where
> getNames (DFun f _) = [f]
> getNames (DBinOp f _) = [f]
> setNames (DFun _ a) =
> do n <- nextName
> return (DFun n a)
> setNames (DBinOp _ a) =
> do n <- nextName
> return (DFun n a)
> instance DNamed (DField a) where
> getNames (DField f _) = [f]
> setNames (DField _ a) =
> do n <- nextName
> return (DField n a)
> instance DNamed (DVar a) where
> getNames (DVar f _) = [f]
> setNames (DVar _ a) =
> do n <- nextName
> return (DVar n a)
> instance DNamed (DConstructor a) where
> getNames (DConstructor c _) = [c]
> setNames (DConstructor _ a) =
> do n <- nextName
> return (DConstructor n a)
> instance DNamed (DRecordSpec a) where
> getNames (DRecordSpec c fts _) = getNames c ++ concatMap getNames (map fst fts)
> setNames (DRecordSpec c fts a) =
> do c' <- setNames c
> fs' <- mapM setNames (map fst fts)
> let fts' = zipWith (\ft f -> (f, snd ft)) fts fs'
> return (DRecordSpec c' fts' a)
> instance DNamed (DGroundDef a) where
> getNames (DGDefVI d _) = getNames d
> getNames (DGDefVC d _) = getNames d
> getNames (DGDefGV d _) = getNames d
> getNames (DGDefGF d _) = getNames d
> getNames (DGDefSmpl d _) = getNames d
> setNames (DGDefVI d a) = do d' <- setNames d; return (DGDefVI d' a)
> setNames (DGDefVC d a) = do d' <- setNames d; return (DGDefVC d' a)
> setNames (DGDefGV d a) = do d' <- setNames d; return (DGDefGV d' a)
> setNames (DGDefGF d a) = do d' <- setNames d; return (DGDefGF d' a)
> setNames (DGDefSmpl d a) = do d' <- setNames d; return (DGDefSmpl d' a)
> instance DNamed (DProgramSpec a) where
> getNames (DProgramSpec _ p _) = getNames p
> setNames (DProgramSpec rs p a) = do p' <- setNames p; return (DProgramSpec rs p' a)
> instance DNamed (DProg a) where
> getNames (DProg f _ _ _) = getNames f
> setNames (DProg f ds e a) = do f' <- setNames f; return (DProg f' ds e a)
> instance DNamed (DDefVertComp a) where
> getNames (DDefVertComp f _ _ _) = getNames f
> setNames (DDefVertComp f ds e a) = do f' <- setNames f; return (DDefVertComp f' ds e a)
> instance DNamed (DDefVertInit a) where
> getNames (DDefVertInit f _ _ _) = getNames f
> setNames (DDefVertInit f ds e a) = do f' <- setNames f; return (DDefVertInit f' ds e a)
> instance DNamed (DDefGraphVar a) where
> getNames (DDefGraphVar v _ _) = getNames v
> setNames (DDefGraphVar v e a) = do v' <- setNames v; return (DDefGraphVar v' e a)
> instance DNamed (DDefGraphFun a) where
> getNames (DDefGraphFun f _ _ _ _) = getNames f
> setNames (DDefGraphFun f vs ds e a) = do f' <- setNames f; return (DDefGraphFun f' vs ds e a)
> instance DNamed (DSmplDef a) where
> getNames (DDefFun f _ _ _ _) = getNames f
> getNames (DDefVar v _ _ _) = getNames v
> getNames (DDefTuple vs _ _ _) = concatMap getNames vs
> setNames (DDefFun f vs ds e a) = do f' <- setNames f; return (DDefFun f' vs ds e a)
> setNames (DDefVar v ds e a) = do v' <- setNames v; return (DDefVar v' ds e a)
> setNames (DDefTuple vs ds e a) = do vs' <- mapM setNames vs; return (DDefTuple vs' ds e a)
> instance DNamed (DGen a) where
> getNames (DGenI _) = ["e", "u"]
> getNames (DGenO _) = ["e", "u"]
> getNames (DGenG _) = ["u"]
> getNames (DGenTermG _) = ["u"]
> setNames (DGenI a) = do nextName; nextName; return (DGenI a)
> setNames (DGenO a) = do nextName; nextName; return (DGenO a)
> setNames (DGenG a) = do nextName; return (DGenG a)
> setNames (DGenTermG a) = do nextName; return (DGenTermG a)
> mmapData f = map (mapData f)
> class DAdditionalData2 a b c d | a c -> b d where
> mapData :: (b -> c) -> a -> d
> instance DAdditionalData2 (DProgramSpec a) a c (DProgramSpec c) where
> mapData f (DProgramSpec rs p a) = DProgramSpec (mmapData f rs) (mapData f p) (f a)
> instance DAdditionalData2 (DRecordSpec a) a c (DRecordSpec c) where
> mapData f (DRecordSpec c fs a) = DRecordSpec (mapData f c) fs' (f a)
> where fs' = zip (mmapData f $ map fst fs) (mmapData f $ map snd fs)
> instance DAdditionalData2 (DProg a) a c (DProg c) where
> mapData f (DProg f' ds e a) = DProg (mapData f f') (mmapData f ds) (mapData f e) (f a)
> instance DAdditionalData2 (DGroundDef a) a c (DGroundDef c) where
> mapData f (DGDefVI x a) = DGDefVI (mapData f x) (f a)
> mapData f (DGDefVC x a) = DGDefVC (mapData f x) (f a)
> mapData f (DGDefGV x a) = DGDefGV (mapData f x) (f a)
> mapData f (DGDefGF x a) = DGDefGF (mapData f x) (f a)
> mapData f (DGDefSmpl x a) = DGDefSmpl (mapData f x) (f a)
> instance DAdditionalData2 (DDefVertComp a) a c (DDefVertComp c) where
> mapData f (DDefVertComp f' ds e a) = DDefVertComp (mapData f f') (mmapData f ds) (mapData f e) (f a)
> instance DAdditionalData2 (DDefVertInit a) a c (DDefVertInit c) where
> mapData f (DDefVertInit f' ds e a) = DDefVertInit (mapData f f') (mmapData f ds) (mapData f e) (f a)
> instance DAdditionalData2 (DDefGraphVar a) a c (DDefGraphVar c) where
> mapData f (DDefGraphVar v e a) = DDefGraphVar (mapData f v) (mapData f e) (f a)
> instance DAdditionalData2 (DDefGraphFun a) a c (DDefGraphFun c) where
> mapData f (DDefGraphFun f' v ds e a) = DDefGraphFun (mapData f f') (mapData f v) (mmapData f ds) (mapData f e) (f a)
> instance DAdditionalData2 (DGraphExpr a) a c (DGraphExpr c) where
> mapData f (DPregel f0 ft x g a) = DPregel (mapData f f0) (mapData f ft) (mapData f x) (mapData f g) (f a)
> mapData f (DGMap f' g a) = DGMap (mapData f f') (mapData f g) (f a)
> mapData f (DGZip g1 g2 a) = DGZip (mapData f g1) (mapData f g2) (f a)
> mapData f (DGIter f0 ft x g a) = DGIter (mapData f f0) (mapData f ft) (mapData f x) (mapData f g) (f a)
> mapData f (DGVar g a) = DGVar (mapData f g) (f a)
> instance DAdditionalData2 (DTermination a) a c (DTermination c) where
> mapData f (DTermF a) = DTermF (f a)
> mapData f (DTermI e a) = DTermI (mapData f e) (f a)
> mapData f (DTermU e a) = DTermU (mapData f e) (f a)
> mapData f (DTermV2H a) = DTermV2H (f a)
> instance DAdditionalData2 (DSmplDef a) a c (DSmplDef c) where
> mapData f (DDefFun f' vs ds e a) = DDefFun (mapData f f') (mmapData f vs) (mmapData f ds) (mapData f e) (f a)
> mapData f (DDefVar v ds e a) = DDefVar (mapData f v) (mmapData f ds) (mapData f e) (f a)
> mapData f (DDefTuple vs ds e a) = DDefTuple (mmapData f vs) (mmapData f ds) (mapData f e) (f a)
> instance DAdditionalData2 (DExpr a) a c (DExpr c) where
> mapData f (DIf p t e a) = DIf (mapData f p) (mapData f t) (mapData f e) (f a)
> mapData f (DTuple es a) = DTuple (mmapData f es) (f a)
> mapData f (DFunAp f' es a) = DFunAp (mapData f f') (mmapData f es) (f a)
> mapData f (DConsAp c es a) = DConsAp (mapData f c) (mmapData f es) (f a)
> mapData f (DFieldAcc t fs a) = DFieldAcc (mapData f t) (mmapData f fs) (f a)
> mapData f (DFieldAccE e fs a) = DFieldAccE (mapData f e) (mmapData f fs) (f a)
> mapData f (DAggr a' e g es a) = DAggr (mapData f a') (mapData f e) (mapData f g) (mmapData f es) (f a)
> mapData f (DVExp v a) = DVExp (mapData f v) (f a)
> mapData f (DCExp v a) = DCExp (mapData f v) (f a)
> instance DAdditionalData2 (DGen a) a c (DGen c) where
> mapData f (DGenI a) = DGenI (f a)
> mapData f (DGenO a) = DGenO (f a)
> mapData f (DGenG a) = DGenG (f a)
> mapData f (DGenTermG a) = DGenTermG (f a)
> instance DAdditionalData2 (DEdge a) a c (DEdge c) where
> mapData f (DEdge a) = DEdge (f a)
> instance DAdditionalData2 (DTableExpr a) a c (DTableExpr c) where
> mapData f (DPrev v a) = DPrev (mapData f v) (f a)
> mapData f (DCurr v a) = DCurr (mapData f v) (f a)
> mapData f (DVal v a) = DVal (mapData f v) (f a)
> instance DAdditionalData2 (DAgg a) a c (DAgg c) where
> mapData f (DAggMin a) = DAggMin (f a)
> mapData f (DAggMax a) = DAggMax (f a)
> mapData f (DAggSum a) = DAggSum (f a)
> mapData f (DAggProd a) = DAggProd (f a)
> mapData f (DAggAnd a) = DAggAnd (f a)
> mapData f (DAggOr a) = DAggOr (f a)
> mapData f (DAggChoice x a) = DAggChoice (mapData f x) (f a)
> mapData f (DTupledAgg ags a) = DTupledAgg (mmapData f ags) (f a)
> instance DAdditionalData2 (DConstructor a) a c (DConstructor c) where
> mapData f (DConstructor c a) = DConstructor c (f a)
> instance DAdditionalData2 (DFun a) a c (DFun c) where
> mapData f (DFun f' a) = DFun f' (f a)
> mapData f (DBinOp f' a) = DBinOp f' (f a)
> instance DAdditionalData2 (DVar a) a c (DVar c) where
> mapData f (DVar v a) = DVar v (f a)
> instance DAdditionalData2 (DField a) a c (DField c) where
> -- mapData f (DFfst a) = DFfst (f a)
> -- mapData f (DFsnd a) = DFsnd (f a)
> mapData f (DField f' a) = DField f' (f a)
> instance DAdditionalData2 (DConst a) a c (DConst c) where
> mapData f (DCInt c a) = DCInt c (f a)
> mapData f (DCBool c a) = DCBool c (f a)
> mapData f (DCString c a) = DCString c (f a)
> mapData f (DCDouble c a) = DCDouble c (f a)
> instance DAdditionalData2 (DType a) a c (DType c) where
> mapData f (DTInt a) = DTInt (f a)
> mapData f (DTBool a) = DTBool (f a)
> mapData f (DTString a) = DTString (f a)
> mapData f (DTDouble a) = DTDouble (f a)
> mapData f (DTTuple ts a) = DTTuple (mmapData f ts) (f a)
> mapData f (DTRecord c fs a) = DTRecord (mapData f c) (mmapData f fs) (f a)
generaing all subexpressions of the given one
> subExprs :: DExpr a -> [DExpr a]
> subExprs (x@(DIf p t e _)) = x : (subExprs p ++ subExprs t ++ subExprs e)
> subExprs (x@(DTuple es _)) = x : concatMap subExprs es
> subExprs (x@(DFunAp f es _)) = x : concatMap subExprs es
> subExprs (x@(DConsAp c es _)) = x : concatMap subExprs es
> subExprs (x@(DFieldAcc t fs a)) = map (\fs -> DFieldAcc t fs (case fs of [] -> getData t ; otherwise -> getData (last fs))) (reverse $ inits fs) ++ [DVExp v va]
> where v = getTableVar t
> va = getData v
> subExprs (x@(DFieldAccE e fs a)) = map (\fs -> DFieldAccE e fs (case fs of [] -> getData e ; otherwise -> getData (last fs))) (reverse $ inits fs)
> subExprs (x@(DAggr a e g es _)) = x:subExprs e ++ concatMap subExprs es
> subExprs (x@(DVExp v _)) = [x]
> subExprs (x@(DCExp v _)) = [x]
> getTableVar (DPrev v a) = v
> getTableVar (DCurr v a) = v
> getTableVar (DVal v a) = v
Expression builders
> dd = "" -- dummy data
>
> expIf p t e = DIf p t e dd
>
> expBin bop e1 e2 = DFunAp (DBinOp bop dd) [e1, e2] dd
>
> expFieldAcc tbl v fs = DFieldAcc te (map (\f -> DField f dd) fs) dd
> where te | tbl == "prev" = DPrev (DVar v dd) dd
> | tbl == "curr" = DCurr (DVar v dd) dd
> | tbl == "val" = DVal (DVar v dd) dd
>
> expConstructor c es = DConsAp (DConstructor c dd) es dd
> expConstructor' c es ac a = DConsAp (DConstructor c ac) es a
>
> expFun f es = DFunAp (DFun f dd) es dd
>
> expInt i = DCExp (DCInt i dd) dd
> expBool b = DCExp (DCBool b dd) dd
>
> expVar v = DVExp (DVar v dd) dd
>
> expAggr agg body gen ps = DAggr agg' body gen' ps dd
> where agg' | agg == "minimum" = DAggMin dd
> | agg == "maximum" = DAggMax dd
> | agg == "sum" = DAggSum dd
> | agg == "prod" = DAggProd dd
> | agg == "and" = DAggAnd dd
> | agg == "or" = DAggOr dd
> gen' | gen == "g" = DGenG dd
> | gen == "tg" = DGenTermG dd
> | gen == "is" = DGenI dd
> | gen == "rs" = DGenO dd
>
> expCheckTerm v = DCheckTerm (expVar v) dd
>
> defVar v defs e = DDefVar (DVar v dd) defs e dd
>
> defFun f vs defs e = DDefFun (DFun f dd) (map (\v -> DVar v dd) vs) defs e dd
>
> defVertComp f defs e = DDefVertComp (DFun f dd) defs e dd
>
> (^==) = expBin "=="
> (^&&) = expBin "&&"
> (^>) = expBin ">"