packages feed

fregel-1.2.0: compiler/ASTData.hs

{-# Language TypeSynonymInstances,FlexibleInstances,MultiParamTypeClasses,FunctionalDependencies,RankNTypes,FlexibleContexts,KindSignatures,ScopedTypeVariables #-}

{-

Defining
  
  - data structure of aux. data on ASTs
  - initial environment

-}

module ASTData where

import Numeric (showHex)
import Spec (DAdditionalData, getData, setData, DRecordSpec (DRecordSpec), DConstructor(DConstructor), PrettyShow (prettyShow), ppList)

-- compilation targets
data TargetSystem = Giraph | PregelPlus | IROnly | NASTOnly | ASTOnly | NoSystem
                    deriving (Eq, Show)

-- compilation option
data Option =
  Option { normLevel :: Int           -- normalization level (1--10)
         , zipOpt :: Bool             -- -oz:  zip-elimination
         , pcFusionOpt :: Bool        -- -opc: prev-curr fusion
         , mzFusionOpt :: Bool        -- -omz: map*zip* fusion
         , elimCommOpt :: Bool        -- -oec: eliminate communications
         , elimIdOpt :: Bool          -- -oei: elmiminate sending id values
         , useV2HOpt :: Bool          -- -ovh: use voteToHalt
         , useMsgCombOpt :: Bool      -- -omc: use message combiner
         , useSmt :: Bool             -- -smt: use SMT solver
         , smtPath :: String          -- -smtpath path: specify path of z3
         , smtOption :: String        -- -smtoption option: option of z3
         , smtTimeout:: Int           -- -smttimeout time: specify timeout
         , printSmt :: Bool
         , genMode :: TargetSystem
         , outputFile :: Maybe String
         }
-- defaultOpt = Option 100 False False False Giraph Nothing
defaultOpt = Option { normLevel = 100
                    , zipOpt = False
                    , pcFusionOpt = False
                    , mzFusionOpt = False
                    , elimCommOpt = False
                    , elimIdOpt = False
                    , useV2HOpt = False
                    , useMsgCombOpt = False
                    , useSmt = False
                    , smtPath = "/usr/local/bin/z3"
                    , smtOption = "-smt2 -in"
                    , smtTimeout = 5 * 10 ^ 6
                    , printSmt = False
                    , genMode = Giraph
                    , outputFile = Nothing
                    }

-- optimization information
type CanElimComm = Bool
type CanVoteToHalt = Bool
type CombineMessages = Bool

type OptimizeInfo = (CanElimComm, CanVoteToHalt, CombineMessages)

-- dependency info.
type DVarName = String

-- type info.
type Id = String
data DTypeTerm = DTypeVar Id
               | DTypeTerm Id [DTypeTerm]
               deriving (Eq, Show)

type DTypeInfo = DTypeTerm
type VarTypeBind = (DVarName, DTypeInfo)

type DUnique = Int

-- the AST data (type info. and dependency info.)
data DASTData = DASTData { typeOf :: DTypeTerm, depOf :: [DVarName] }
              deriving (Eq, Show)

-- type builders
typeVar a = DTypeVar a
typeDTInt = DTypeTerm "Int" []
typeDTBool = DTypeTerm "Bool" []
typeDTString = DTypeTerm "String" []
typeDTDouble = DTypeTerm "Double" []
typeTuple ts = DTypeTerm "(,)" ts
typeRecord c ts = DTypeTerm c ts
getTupleTypes (DTypeTerm "(,)" ts) = ts
typeSolid name = DTypeTerm name []
typeVertex (ts@[tv, te]) = DTypeTerm "Vertex" ts
typeGraph (ts@[tv, te]) = DTypeTerm "Graph" ts
typePair (ts@[tv, te]) = DTypeTerm "Pair" ts
resultTypeVarName = "@@ResultingType@@"
typeNull = DTypeTerm "Null" []
getTypeName (DTypeTerm n _) = n
typeParams (DTypeTerm _ ps) = ps

nullRecordSpec = DRecordSpec (DConstructor "Null" (DASTData typeNull [])) [] (DASTData typeNull [])

getType :: forall (t :: * -> *). 
            (DAdditionalData (t DASTData) DASTData) 
            => t DASTData -> DTypeInfo
getType = typeOf . getData

setType :: forall (t :: * -> *). 
            (DAdditionalData (t DASTData) DASTData) 
            => DTypeInfo -> t DASTData -> t DASTData
setType t x = setData ((getData x) { typeOf = t }) x


isTupleType "(,)" = True
isPrimitive t = t == "Int" || t == "Bool" || t == "String"  || t == "Double" 

typeFunction ts =  foldr1 (\t ft -> DTypeTerm "->" [t, ft]) ts
getInputType (DTypeTerm "->" (x:_)) = x
getVertexType (DTypeTerm "Graph" [tv, te]) = tv
getEdgeType (DTypeTerm "Graph" [tv, te]) = te

-- initial environment: 
initEnv :: [VarTypeBind]
initEnv =
   [("fst", typeFunction [typeTuple [typeVar "a", typeVar "b"], typeVar "a"]),
    ("snd", typeFunction [typeTuple [typeVar "a", typeVar "b"], typeVar "b"]),
    ("Pair", typeFunction [typeVar "a", typeVar "b", typePair [typeVar "a", typeVar "b"]]),
    ("_fst", typeFunction [typePair [typeVar "a", typeVar "b"], typeVar "a"]),
    ("_snd", typeFunction [typePair [typeVar "a", typeVar "b"], typeVar "b"]),
    ("+", typeFunction [typeVar "a", typeVar "a", typeVar "a"]),
    ("/", typeFunction [typeVar "a", typeVar "a", typeVar "a"]),
    ("*", typeFunction [typeVar "a", typeVar "a", typeVar "a"]),
    ("-", typeFunction [typeVar "a", typeVar "a", typeVar "a"]),
    ("neg", typeFunction [typeVar "a", typeVar "a"]),
    ("!=", typeFunction [typeVar "a", typeVar "a", typeDTBool]),
    ("==", typeFunction [typeVar "a", typeVar "a", typeDTBool]),
    (">=", typeFunction [typeVar "a", typeVar "a", typeDTBool]),
    ("<=", typeFunction [typeVar "a", typeVar "a", typeDTBool]),
    ("<", typeFunction [typeVar "a", typeVar "a", typeDTBool]),
    (">", typeFunction [typeVar "a", typeVar "a", typeDTBool]),
    ("||", typeFunction [typeDTBool, typeDTBool, typeDTBool]),
    ("&&", typeFunction [typeDTBool, typeDTBool, typeDTBool]),
    ("not", typeFunction [typeDTBool, typeDTBool]),
    ("min", typeFunction [typeVar "a", typeVar "a", typeVar "a"]),
    ("max", typeFunction [typeVar "a", typeVar "a", typeVar "a"]),
    ("mod", typeFunction [typeVar "a", typeVar "a", typeVar "a"]),
    ("val", typeFunction [typeVertex [typeVar "a", typeVar "b"], typeVar "a"]),
    ("vid", typeFunction [typeVertex [typeVar "a", typeVar "b"], typeDTInt]),
    -- dummy
    ("bot", typeVar "a")]


genNewName i s = (s ++ "_X"++((showHex i "")), i+1) 
getBaseName s = s --if isPrefixOf "_X" s then else s

-- util
lookupBy :: Eq b => (a -> b) -> b -> [a] -> Maybe a
lookupBy _ _ [] = Nothing
lookupBy f key (x:xs) = if f x == key then Just x else lookupBy f key xs

instance PrettyShow [(String, DTypeInfo)] where
  prettyShow env = unlines $ map (\(v, t) -> v ++ "::" ++ prettyShow t) env
                   
instance PrettyShow DTypeInfo where
  prettyShow (DTypeVar a) = a
  prettyShow (DTypeTerm "(,)" ts) = "(" ++ ppList ", " (map prettyShow ts) ++ ")"
  prettyShow (DTypeTerm "->" [h,t]) = "(" ++ prettyShow h ++ " -> " ++ prettyShow t ++ ")"
  prettyShow (DTypeTerm s []) = s
  prettyShow (DTypeTerm s ts) = "(" ++ s ++ " " ++ ppList " " (map prettyShow ts) ++ ")"