Files
kraken/koka_bench/haskell/cfold.hs
2022-05-18 23:59:18 -04:00

66 lines
1.9 KiB
Haskell

-- Adapted from https://github.com/leanprover/lean4/blob/IFL19/tests/bench/const_fold.hs
import System.Environment
data Expr = Var Integer
| Val Integer
| Add Expr Expr
| Mul Expr Expr
mk_expr :: Integer -> Integer -> Expr
mk_expr 0 v = if v == 0 then Var 1 else Val v
mk_expr n v = Add (mk_expr (n-1) (v+1)) (mk_expr (n-1) (max (v-1) 0))
append_add :: Expr -> Expr -> Expr
append_add (Add e e) e = Add e (append_add e e)
append_add e e = Add e e
append_mul :: Expr -> Expr -> Expr
append_mul (Mul e e) e = Mul e (append_mul e e)
append_mul e e = Mul e e
reassoc :: Expr -> Expr
reassoc (Add e e) =
let e' = reassoc e in
let e' = reassoc e in
append_add e' e₂'
reassoc (Mul e e) =
let e' = reassoc e in
let e' = reassoc e in
append_mul e' e₂'
reassoc e = e
const_folding :: Expr -> Expr
const_folding (Add e e) =
let e' = const_folding e in
let e' = const_folding e in
(case (e', e₂') of
(Val a, Val b ) -> Val (a+b)
(Val a, Add e (Val b)) -> Add (Val (a+b)) e
(Val a, Add (Val b) e) -> Add (Val (a+b)) e
(_, _ ) -> Add e' e₂')
const_folding (Mul e e) =
let e' = const_folding e in
let e' = const_folding e in
(case (e', e₂') of
(Val a, Val b ) -> Val (a*b)
(Val a, Mul e (Val b)) -> Mul (Val (a*b)) e
(Val a, Mul (Val b) e) -> Mul (Val (a*b)) e
(_, _ ) -> Mul e' e₂')
const_folding e = e
eval :: Expr -> Integer
eval (Var _) = 0
eval (Val v) = v
eval (Add l r) = eval l + eval r
eval (Mul l r) = eval l * eval r
main :: IO ()
main = do
[arg] <- getArgs
let n = read arg
let e = (mk_expr n 1)
let v = eval e
let v = eval (const_folding (reassoc e))
putStrLn (show v ++ " " ++ show v)