@@ -3,9 +3,10 @@ module Kiselyov
3
3
(
4
4
deBruijn ,
5
5
bulkOpt ,
6
- -- compileKiEither,
7
6
compileBulk ,
8
7
compileEta ,
8
+ compileBulkLinear ,
9
+ compileBulkLog ,
9
10
optK ,
10
11
optEta
11
12
)
@@ -39,11 +40,6 @@ bulk :: Combinator -> Int -> CL
39
40
bulk c 1 = Com c
40
41
bulk c n = Com $ BulkCom (show c) n
41
42
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
-
47
43
compileEta :: Environment -> CL
48
44
compileEta env = case lookup " main" env of
49
45
Nothing -> error " main function missing"
@@ -54,6 +50,16 @@ compileBulk env = case lookup "main" env of
54
50
Nothing -> error " main function missing"
55
51
Just main -> snd $ bulkOpt bulk env (deBruijn main)
56
52
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
+
57
63
convertBool :: (([Bool ], CL ) -> ([Bool ], CL ) -> CL ) -> Environment -> DB -> ([Bool ], CL )
58
64
convertBool (#) env = \ case
59
65
N Z -> (True : [] , Com I )
@@ -107,45 +113,45 @@ zipWithDefault d f [] ys = f d <$> ys
107
113
zipWithDefault d f xs [] = flip f d <$> xs
108
114
zipWithDefault d f (x: xt) (y: yt) = f x y : zipWithDefault d f xt yt
109
115
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
112
118
Nothing -> ([] , Com (fromString s))
113
- Just t -> bulkOpt bulk env (deBruijn t)
119
+ Just t -> bulkOpt bulkFun env (deBruijn t)
114
120
115
121
bulkOpt :: (Combinator -> Int -> CL ) -> Environment -> DB -> ([Bool ], CL )
116
- bulkOpt bulk env = \ case
122
+ bulkOpt bulkFun env = \ case
117
123
N Z -> ([True ], Com I )
118
124
N (Su e) -> first (False : ) $ rec env $ N e
119
125
L e -> case rec env e of
120
126
([] , d) -> ([] , Com K :@ d)
121
127
(False : g, d) -> ([] , Com K ) ## (g, d)
122
128
(True : g, d) -> (g, d)
123
129
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)
125
131
IN i -> ([False ], INT i)
126
132
where
127
- rec = bulkOpt bulk
133
+ rec = bulkOpt bulkFun
128
134
([] , d1) ## ([] , d2) = ([] , d1 :@ d2)
129
135
([] , 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)
131
137
([] , d1) ## (g2@ (h: _), d2) = first (pre++ ) $ ([] , fun1 d1) ## (post, d2)
132
138
where
133
139
fun1 = case h of
134
- True -> (bulk B (length pre) :@ )
140
+ True -> (bulkFun B (length pre) :@ )
135
141
False -> id
136
142
(pre, post) = span (h == ) g2
137
143
138
144
([True ], Com I ) ## ([] , d2) = ([True ], Com T :@ d2)
139
145
(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)
141
147
False -> (post, d1) ## ([] , d2)
142
148
where
143
149
(pre, post) = span (h == ) g1
144
150
145
151
([True ], Com I ) ## (False : g2, d2) = first (True : ) $ ([] , Com T ) ## (g2, d2)
146
152
(False : g1, d1) ## ([True ], Com I ) = (True : g1, d1)
147
153
(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)
149
155
(g1, d1) ## (g2, d2) = pre $ fun1 (drop count g1, d1) ## (drop count g2, d2)
150
156
where
151
157
(h, count) = headGroup $ zip g1 g2
@@ -155,11 +161,38 @@ bulkOpt bulk env = \case
155
161
(True , False ) -> apply C
156
162
(True , True ) -> apply S
157
163
pre = first (replicate count (uncurry (||) h) ++ )
158
- apply s = (([] , bulk s count) ## )
164
+ apply s = (([] , bulkFun s count) ## )
159
165
160
166
first :: (t -> a ) -> (t , b ) -> (a , b )
161
167
first f (x, y) = (f x, y);
162
168
163
169
headGroup :: Eq a => [a ] -> (a , Int )
164
170
headGroup (h: t) = (h, 1 + length (takeWhile (== h) t))
165
171
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