Skip to content

Commit ba94efd

Browse files
committed
print out all optimizations
1 parent 4cef0e1 commit ba94efd

File tree

3 files changed

+114
-91
lines changed

3 files changed

+114
-91
lines changed

app/Main.hs

+50-51
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import Kiselyov
1717
import System.TimeIt
1818
import Text.RawString.QQ
1919

20+
2021
printGraph :: ST s (STRef s (Graph s)) -> ST s String
2122
printGraph graph = do
2223
gP <- graph
@@ -32,54 +33,66 @@ main = do
3233
hSetEncoding stdin utf8 -- this is required to handle UTF-8 characters like λ
3334
hSetEncoding stdout utf8 -- this is required to handle UTF-8 characters like λ
3435

35-
-- testSource <-readFile "test/tak.ths"
36-
let testSource = "main = (\\x y -> + x x) 3 4"
37-
putStrLn "The sourcecode: "
38-
putStrLn testSource
36+
--let testSource = "main = (\\x y -> + x x) 3 4"
37+
mapM_ showCompilations [factorial, fibonacci, ackermann, tak]
38+
--demo
3939

40-
let env = parseEnvironment testSource
40+
type SourceCode = String
41+
tak :: SourceCode
42+
tak = [r|
43+
tak = y(λf x y z -> (if (geq y x) z (f (f (sub1 x) y z) (f (sub1 y) z x) (f (sub1 z) x y ))))
44+
main = tak 7 4 2 --18 6 3
45+
|]
46+
47+
ackermann :: SourceCode
48+
ackermann = [r|
49+
ack = y(λf n m -> if (is0 n) (+ m 1) (if (is0 m) (f (sub1 n) 1) (f (sub1 n) (f n (sub1 m)))))
50+
main = ack 2 2
51+
|]
52+
53+
factorial :: SourceCode
54+
factorial = [r|
55+
fact = y(λf n -> if (is0 n) 1 (* n (f (sub1 n))))
56+
main = fact 100
57+
|]
58+
59+
fibonacci :: SourceCode
60+
fibonacci = [r|
61+
fib = y(λf n -> if (is0 n) 1 (if (eql n 1) 1 (+ (f (sub1 n)) (f (sub n 2)))))
62+
main = fib 10
63+
|]
64+
65+
showCompilations :: SourceCode -> IO ()
66+
showCompilations source = do
67+
let env = parseEnvironment source
4168
putStrLn "The parsed environment of named lambda expressions:"
4269
mapM_ print env
4370
putStrLn ""
4471

4572
let expr = compile env abstractToSKI
46-
putStrLn "The main expression compiled to SICKYB combinator expressions:"
73+
putStrLn "The main expression compiled to SICKBY combinator expressions:"
4774
print expr
4875
putStrLn ""
4976

50-
let graph = allocate expr
51-
putStrLn "The allocated graph:"
52-
putStrLn $ runST $ printGraph graph
53-
54-
let reducedGraph = reduceGraph graph
55-
56-
putStrLn "The result after reducing the graph:"
57-
putStrLn $ runST $ printGraph reducedGraph
58-
77+
let expr' = compileEta env
78+
putStrLn "The main expression compiled to SICKBY combinator expressions with eta optimization:"
79+
print expr'
80+
putStrLn ""
5981

60-
--demo
82+
let expr'' = compileBulk env
83+
putStrLn "The main expression compiled to SICKBY combinator expressions with bulk combinators:"
84+
print expr''
85+
putStrLn ""
6186

62-
type SourceCode = String
87+
let expr''' = compileBulkLinear env
88+
putStrLn "The main expression compiled to SICKBY combinator expressions with bulk combinators and linear elimination:"
89+
print expr'''
90+
putStrLn ""
6391

64-
loadTestCase :: String -> IO CL
65-
loadTestCase name = do
66-
src <- readFile $ "test/" ++ name ++ ".ths"
67-
putStrLn "The source: "
68-
putStrLn src
69-
let pEnv = parseEnvironment src
70-
expr = compile pEnv abstractToSKI
71-
return expr
72-
73-
graphReductionDemo :: IO CL -> IO ()
74-
graphReductionDemo ioexpr = do
75-
expr <- ioexpr
76-
let graph = allocate expr
77-
result = reduceGraph graph
78-
actual = runST $ printGraph result
79-
putStrLn "allocated graph:"
80-
print expr
81-
putStrLn "after graph reduction:"
82-
print actual
92+
let expr'''' = compileBulkLog env
93+
putStrLn "The main expression compiled to SICKBY combinator expressions with bulk combinators and logarithmic elimination:"
94+
print expr''''
95+
putStrLn ""
8396

8497

8598
hhiReductionDemo :: IO CL -> IO ()
@@ -91,18 +104,4 @@ hhiReductionDemo ioexpr = do
91104
putStrLn "after graph reduction:"
92105
print actual
93106

94-
demo :: IO ()
95-
demo = do
96-
let testCases =
97-
[
98-
"factorial"
99-
, "fibonacci"
100-
, "tak"
101-
, "ackermann"
102-
, "gaussian"
103-
]
104-
putStrLn "Graph-Reduction"
105-
mapM_ (loadTestCase >>> graphReductionDemo) testCases
106-
107-
putStrLn "HHI Reduction"
108-
mapM_ (loadTestCase >>> hhiReductionDemo) testCases
107+

src/HhiReducer.hs

+14-23
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
module HhiReducer where
22

3-
import Parser ( Expr(..) )
3+
import Parser ( Expr(..) )
44
import Control.Monad.Fix (fix)
5-
import CLTerm
5+
import CLTerm
66
import Data.Maybe (fromJust)
77

88
-- | a compiled expression
9-
data CExpr =
9+
data CExpr =
1010
CComb Combinator
1111
| CApp CExpr CExpr
1212
| CFun (CExpr -> CExpr)
@@ -73,8 +73,8 @@ primitives = let (-->) = (,) in
7373
, S --> comS --CFun (\f -> CFun $ \g -> CFun $ \x -> f!x!(g!x)) -- S F G X = F X (G X)
7474
, B --> comB --CFun (\f -> CFun $ \g -> CFun $ \x -> f!(g!x)) -- B F G X = F (G X)
7575
, C --> comC --CFun (\f -> CFun $ \g -> CFun $ \x -> f!x!g) -- C F G X = F X G
76-
, R --> CFun (\f -> CFun $ \g -> CFun $ \x -> g!x!f) -- R F G X = G X F
77-
-- , T --> CFun (\x -> CFun $ \y -> x) -- T X Y = X
76+
, R --> CFun (\f -> CFun $ \g -> CFun $ \x -> g!x!f) -- R F G X = G X F
77+
, T --> CFun (CFun . const) -- T X Y = X
7878
, B' --> comB' --CFun (\p -> CFun $ \q -> CFun $ \r -> CFun $ \s -> p!q!(r!s)) -- B' P Q R S = P Q (R S)
7979
, C' --> comC' --CFun (\p -> CFun $ \q -> CFun $ \r -> CFun $ \s -> p!(q!s)!r) -- C' P Q R S = P (Q S) R
8080
, S' --> comS' --CFun (\p -> CFun $ \q -> CFun $ \r -> CFun $ \s -> p!(q!s)!(r!s)) -- S' P Q R S = P (Q S) (R S)
@@ -108,39 +108,30 @@ resolveBulkLog (BulkCom c n) = breakBulkLog (fromString c) n
108108
bits n = r:if q == 0 then [] else bits q where (q, r) = divMod n 2
109109

110110
resolveBulk :: Combinator -> CExpr
111-
resolveBulk (BulkCom "B" n) = iterate (comB' !) comB !! (n-1)
111+
resolveBulk (BulkCom "B" n) = iterate (comB' !) comB !! (n-1)
112112
resolveBulk (BulkCom "C" n) = iterate (comC' !) comC !! (n-1)
113-
resolveBulk (BulkCom "S" n) = iterate (comS' !) comS !! (n-1)
113+
resolveBulk (BulkCom "S" n) = iterate (comS' !) comS !! (n-1)
114114
resolveBulk anyOther = error $ "not a known combinator: " ++ show anyOther
115115

116116
comI :: CExpr
117117
comI = CFun id
118118

119119
comS :: CExpr
120-
comS = CFun (\f -> CFun $ \g -> CFun $ \x -> f!x!(g!x)) -- S F G X = F X (G X)
120+
comS = CFun (\f -> CFun $ \g -> CFun $ \x -> f!x!(g!x)) -- S F G X = F X (G X)
121121

122122
comS' :: CExpr
123123
comS' = CFun (\p -> CFun $ \q -> CFun $ \r -> CFun $ \s -> p!(q!s)!(r!s)) -- S' P Q R S = P (Q S) (R S)
124124

125-
comS2 :: CExpr
126-
comS2 = comS' ! comS
127-
128-
comS3 = comS' ! comS2
129-
comS4 = comS' ! comS3
130-
131-
comB = CFun (\f -> CFun $ \g -> CFun $ \x -> f!(g!x)) -- B F G X = F (G X)
125+
comB :: CExpr
126+
comB = CFun (\f -> CFun $ \g -> CFun $ \x -> f!(g!x)) -- B F G X = F (G X)
127+
comB' :: CExpr
132128
comB' = CFun (\p -> CFun $ \q -> CFun $ \r -> CFun $ \s -> p!q!(r!s)) -- B' P Q R S = P Q (R S)
133129

134-
comB2 = comB' ! comB
135-
comB3 = comB' ! comB2
136-
137-
comC = CFun (\f -> CFun $ \g -> CFun $ \x -> f!x!g) -- C F G X = F X G
130+
comC :: CExpr
131+
comC = CFun (\f -> CFun $ \g -> CFun $ \x -> f!x!g) -- C F G X = F X G
132+
comC' :: CExpr
138133
comC' = CFun (\p -> CFun $ \q -> CFun $ \r -> CFun $ \s -> p!(q!s)!r) -- C' P Q R S = P (Q S) R
139134

140-
comC2 = comC' ! comC
141-
comC3 = comC' ! comC2
142-
143-
144135
arith :: (Integer -> Integer -> Integer) -> CExpr
145136
arith op = CFun $ \(CInt a) -> CFun $ \(CInt b) -> CInt (op a b)
146137

src/Kiselyov.hs

+50-17
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ module Kiselyov
33
(
44
deBruijn,
55
bulkOpt,
6-
--compileKiEither,
76
compileBulk,
87
compileEta,
8+
compileBulkLinear,
9+
compileBulkLog,
910
optK,
1011
optEta
1112
)
@@ -39,11 +40,6 @@ bulk :: Combinator -> Int -> CL
3940
bulk c 1 = Com c
4041
bulk c n = Com $ BulkCom (show c) n
4142

42-
-- compileKiEither :: Environment -> (Environment -> DB -> ([Bool],CL)) -> Either String CL
43-
-- compileKiEither env convertFun = case lookup "main" env of
44-
-- Nothing -> Left $ error "main function missing in " ++ show env
45-
-- Just main -> Right $ snd $ convertFun env $ deBruijn main
46-
4743
compileEta :: Environment -> CL
4844
compileEta env = case lookup "main" env of
4945
Nothing -> error "main function missing"
@@ -54,6 +50,16 @@ compileBulk env = case lookup "main" env of
5450
Nothing -> error "main function missing"
5551
Just main -> snd $ bulkOpt bulk env (deBruijn main)
5652

53+
compileBulkLinear :: Environment -> CL
54+
compileBulkLinear env = case lookup "main" env of
55+
Nothing -> error "main function missing"
56+
Just main -> snd $ bulkOpt breakBulkLinear env (deBruijn main)
57+
58+
compileBulkLog :: Environment -> CL
59+
compileBulkLog env = case lookup "main" env of
60+
Nothing -> error "main function missing"
61+
Just main -> snd $ bulkOpt breakBulkLog env (deBruijn main)
62+
5763
convertBool :: (([Bool], CL) -> ([Bool], CL) -> CL) -> Environment -> DB -> ([Bool], CL)
5864
convertBool (#) env = \case
5965
N Z -> (True:[], Com I)
@@ -107,45 +113,45 @@ zipWithDefault d f [] ys = f d <$> ys
107113
zipWithDefault d f xs [] = flip f d <$> xs
108114
zipWithDefault d f (x:xt) (y:yt) = f x y : zipWithDefault d f xt yt
109115

110-
bulkLookup :: String -> Environment -> ([Bool], CL)
111-
bulkLookup s env = case lookup s env of
116+
bulkLookup :: String -> Environment -> (Combinator -> Int -> CL) -> ([Bool], CL)
117+
bulkLookup s env bulkFun = case lookup s env of
112118
Nothing -> ([], Com (fromString s))
113-
Just t -> bulkOpt bulk env (deBruijn t)
119+
Just t -> bulkOpt bulkFun env (deBruijn t)
114120

115121
bulkOpt :: (Combinator -> Int -> CL) -> Environment -> DB -> ([Bool], CL)
116-
bulkOpt bulk env = \case
122+
bulkOpt bulkFun env = \case
117123
N Z -> ([True], Com I)
118124
N (Su e) -> first (False:) $ rec env $ N e
119125
L e -> case rec env e of
120126
([], d) -> ([], Com K :@ d)
121127
(False:g, d) -> ([], Com K) ## (g, d)
122128
(True:g, d) -> (g, d)
123129
A e1 e2 -> rec env e1 ## rec env e2
124-
Free s -> bulkLookup s env --([], Com s)
130+
Free s -> bulkLookup s env bulkFun--([], Com s)
125131
IN i -> ([False], INT i)
126132
where
127-
rec = bulkOpt bulk
133+
rec = bulkOpt bulkFun
128134
([], d1) ## ([], d2) = ([], d1 :@ d2)
129135
([], d1) ## ([True], Com I) = ([True], d1)
130-
([], d1) ## (g2, Com I) | and g2 = (g2, bulk B (length g2 - 1) :@ d1)
136+
([], d1) ## (g2, Com I) | and g2 = (g2, bulkFun B (length g2 - 1) :@ d1)
131137
([], d1) ## (g2@(h:_), d2) = first (pre++) $ ([], fun1 d1) ## (post, d2)
132138
where
133139
fun1 = case h of
134-
True -> (bulk B (length pre) :@)
140+
True -> (bulkFun B (length pre) :@)
135141
False -> id
136142
(pre, post) = span (h ==) g2
137143

138144
([True], Com I) ## ([], d2) = ([True], Com T :@ d2)
139145
(g1@(h:_), d1) ## ([], d2) = first (pre++) $ case h of
140-
True -> ([], Com C :@ bulk C (length pre) :@ d2) ## (post, d1)
146+
True -> ([], Com C :@ bulkFun C (length pre) :@ d2) ## (post, d1)
141147
False -> (post, d1) ## ([], d2)
142148
where
143149
(pre, post) = span (h ==) g1
144150

145151
([True], Com I) ## (False:g2, d2) = first (True:) $ ([], Com T) ## (g2, d2)
146152
(False:g1, d1) ## ([True], Com I) = (True:g1, d1)
147153
(g1, d1) ## (g2, Com I) | and g2, let n = length g2, all not $ take n g1 =
148-
first (g2++) $ ([], bulk B $ n - 1) ## (drop n g1, d1)
154+
first (g2++) $ ([], bulkFun B $ n - 1) ## (drop n g1, d1)
149155
(g1, d1) ## (g2, d2) = pre $ fun1 (drop count g1, d1) ## (drop count g2, d2)
150156
where
151157
(h, count) = headGroup $ zip g1 g2
@@ -155,11 +161,38 @@ bulkOpt bulk env = \case
155161
(True, False) -> apply C
156162
(True, True) -> apply S
157163
pre = first (replicate count (uncurry (||) h) ++)
158-
apply s = (([], bulk s count) ##)
164+
apply s = (([], bulkFun s count) ##)
159165

160166
first :: (t -> a) -> (t, b) -> (a, b)
161167
first f (x, y) = (f x, y);
162168

163169
headGroup :: Eq a => [a] -> (a, Int)
164170
headGroup (h:t) = (h, 1 + length (takeWhile (== h) t))
165171

172+
breakBulkLinear :: Combinator -> Int -> CL
173+
breakBulkLinear B n = iterate (comB' :@) (Com B) !! (n - 1)
174+
breakBulkLinear C n = iterate (comC' :@) (Com C) !! (n - 1)
175+
breakBulkLinear S n = iterate (comS' :@) (Com S) !! (n - 1)
176+
177+
comB' :: CL
178+
comB' = Com B:@ Com B
179+
comC' :: CL
180+
comC' = Com B :@ (Com B :@ Com C) :@ Com B
181+
comS' :: CL
182+
comS' = Com B :@ (Com B :@ Com S) :@ Com B
183+
184+
185+
186+
breakBulkLog :: Combinator -> Int -> CL
187+
breakBulkLog c 1 = Com c
188+
breakBulkLog B n = foldr (:@) (Com B) $ map (bs!!) $ init $ bits n where
189+
bs = [sbi, Com B :@ (Com B :@ Com B) :@ sbi]
190+
breakBulkLog c n = (foldr (:@) (prime c) $ map (bs!!) $ init $ bits n) :@ Com I where
191+
bs = [sbi, Com B :@ (Com B :@ prime c) :@ sbi]
192+
prime c = Com B :@ (Com B :@ Com c) :@ Com B
193+
194+
bits :: Int -> [Int]
195+
bits n = r:if q == 0 then [] else bits q where (q, r) = divMod n 2
196+
197+
sbi :: CL
198+
sbi = Com S :@ Com B :@ Com I

0 commit comments

Comments
 (0)