module Normal (main) where import Criterion.Main import Criterion.Types import Language.Syntactic import Language.Syntactic.Functional main :: IO () main = defaultMainWith (defaultConfig {csvFile = Just "bench-results/normal.csv"}) [ bgroup "Eval Tree 10" [ bench "gadt" $ nf evl (gadtExpr 10) , bench "syntactic" $ nf evalDen (syntacticExpr 10)] , bgroup "Eval Tree 15" [ bench "gadt" $ nf evl (gadtExpr 15) , bench "syntactic" $ nf evalDen(syntacticExpr 15)] , bgroup "Eval Tree 20" [ bench "gadt" $ nf evl (gadtExpr 20) , bench "syntactic" $ nf evalDen(syntacticExpr 20) ] , bgroup "Size Tree 10" [ bench "gadt" $ nf gSize (gadtExpr 10) , bench "syntactic" $ nf size (syntacticExpr 10)] , bgroup "Size Tree 15" [ bench "gadt" $ nf gSize (gadtExpr 15) , bench "syntactic" $ nf size (syntacticExpr 15)] , bgroup "Size Tree 20" [ bench "gadt" $ nf gSize (gadtExpr 20) , bench "syntactic" $ nf size (syntacticExpr 20)] , bgroup "Eval IFTree 10" [ bench "if gadt" $ nf evl (gadtExpr 10) , bench "syntactic" $ nf evalDen(syntacticExpr 10)] , bgroup "Eval IFTree 15" [ bench "gadt" $ nf evl (gadtExpr 15) , bench "syntactic" $ nf evalDen(syntacticExpr 15)] , bgroup "Eval IFTree 20" [ bench "gadt" $ nf evl (gadtExpr 20) , bench "syntactic" $ nf evalDen(syntacticExpr 20) ] , bgroup "Size IFTree 10" [ bench "gadt" $ nf gSize (gadtExpr 10) , bench "syntactic" $ nf evalDen(syntacticExpr 10)] , bgroup "Size IFTree 15" [ bench "gadt" $ nf gSize (gadtExpr 15) , bench "syntactic" $ nf evalDen(syntacticExpr 15)] , bgroup "Size IFTree 20" [ bench "gadt" $ nf gSize (gadtExpr 20) , bench "syntactic" $ nf evalDen(syntacticExpr 20) ]] -- Expressions gadtExpr :: Int -> Expr Int gadtExpr 0 = (If ((LitI 5) :== (LitI 4)) (LitI 5) (LitI 0)) gadtExpr n = gadtExpr (n-1) :+ gadtExpr (n-1) gadtExprIf :: Int -> Expr Int gadtExprIf 0 = (If ((LitI 5) :== (LitI 4)) (LitI 5) (LitI 0)) gadtExprIf n = (If (gadtExprIf (n-1) :== (LitI 0)) (gadtExprIf (n-1)) (gadtExprIf (n-1))) syntacticExpr :: Int -> ExprS' Int syntacticExpr 0 = if' (eq (int 5) (int 4)) (int 5) (int 0) syntacticExpr n = (add (syntacticExpr (n-1)) (syntacticExpr (n-1))) -- We also test an expression with several ifs so the tree has higher width. syntacticExprIf :: Int -> ExprS' Int syntacticExprIf 0 = if' (eq (int 5) (int 4)) (int 5) (int 0) syntacticExprIf n = if' (eq (syntacticExprIf(n-1)) (int 0)) (syntacticExprIf (n-1)) (syntacticExprIf (n-1)) -- Comparing Syntactic with GADTs -- GADTs data Expr t where LitI :: Int -> Expr Int LitB :: Bool -> Expr Bool (:+) :: Expr Int -> Expr Int -> Expr Int (:==) :: Eq t => Expr t -> Expr t -> Expr Bool If :: Expr Bool -> Expr t -> Expr t -> Expr t evl :: Expr t -> t evl (LitI n) = n evl (LitB b) = b evl (e1 :+ e2) = evl e1 + evl e2 evl (e1 :== e2) = evl e1 == evl e2 evl (If b t e) = if evl b then evl t else evl e gSize :: Expr t -> Int gSize (LitI n) = 1 gSize (LitB b) = 1 gSize (e1 :+ e2) = gSize e1 + gSize e2 gSize (e1 :== e2) = gSize e1 + gSize e2 gSize (If b t e) = gSize b + gSize t + gSize e -- Syntactic data ExprS t where EI :: Int -> ExprS (Full Int) EB :: Bool -> ExprS (Full Bool) EAdd :: ExprS (Int :-> Int :-> Full Int) EEq :: (Eq t) => ExprS (t :-> t :-> Full Bool) EIf :: ExprS (Bool :-> a :-> a :-> Full a) type ExprS' a = AST ExprS (Full a) -- Smart constructors int :: Int -> ExprS' Int int = Sym . EI bool :: Bool -> ExprS' Bool bool = Sym . EB add :: ExprS' Int -> ExprS' Int -> ExprS' Int add a b = Sym EAdd :$ a :$ b eq :: (Eq a) => ExprS' a -> ExprS' a -> ExprS' Bool eq a b = Sym EEq :$ a :$ b if' :: ExprS' Bool -> ExprS' a -> ExprS' a -> ExprS' a if' c a b = Sym EIf :$ c :$ a :$ b instance Render ExprS where renderSym (EI n) = "EI" renderSym (EB b) = "EB" renderSym EAdd = "EAdd" renderSym EEq = "EEq" renderSym EIf = "EIf" instance Equality ExprS instance StringTree ExprS instance Eval ExprS where evalSym (EI n) = n evalSym (EB b) = b evalSym EAdd = (+) evalSym EEq = (==) evalSym EIf = \c a b -> if c then a else b instance EvalEnv ExprS env where compileSym p (EI n) = compileSymDefault signature p (EI n) compileSym p (EB b) = compileSymDefault signature p (EB b) compileSym p EAdd = compileSymDefault signature p EAdd compileSym p EEq = compileSymDefault signature p EEq compileSym p EIf = compileSymDefault signature p EIf