diff options
author | Péter Diviánszky <divipp@gmail.com> | 2016-06-09 17:14:31 +0200 |
---|---|---|
committer | Péter Diviánszky <divipp@gmail.com> | 2016-06-09 17:14:31 +0200 |
commit | d70ef80e63a0f84798071d31abbf80747c1fe639 (patch) | |
tree | 54f3d5dc021ad2e61a553fe711b17352d3f72a81 /prototypes | |
parent | 57fd497f487b83d6eab1e2ca05e6ff5722af6938 (diff) |
use splay lists
Diffstat (limited to 'prototypes')
-rw-r--r-- | prototypes/FreeVars.hs | 256 | ||||
-rw-r--r-- | prototypes/Inspector.hs | 4 | ||||
-rw-r--r-- | prototypes/LamMachine.hs | 268 | ||||
-rw-r--r-- | prototypes/SplayList.hs | 151 |
4 files changed, 406 insertions, 273 deletions
diff --git a/prototypes/FreeVars.hs b/prototypes/FreeVars.hs index eefea309..71c0a99c 100644 --- a/prototypes/FreeVars.hs +++ b/prototypes/FreeVars.hs | |||
@@ -6,15 +6,27 @@ | |||
6 | {-# LANGUAGE ScopedTypeVariables #-} | 6 | {-# LANGUAGE ScopedTypeVariables #-} |
7 | {-# LANGUAGE TypeSynonymInstances #-} | 7 | {-# LANGUAGE TypeSynonymInstances #-} |
8 | {-# LANGUAGE FlexibleInstances #-} | 8 | {-# LANGUAGE FlexibleInstances #-} |
9 | {-# LANGUAGE FlexibleContexts #-} | ||
9 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} | 10 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} |
10 | {-# LANGUAGE BangPatterns #-} | 11 | {-# LANGUAGE BangPatterns #-} |
11 | {-# LANGUAGE TypeFamilies #-} | 12 | {-# LANGUAGE TypeFamilies #-} |
12 | {-# LANGUAGE DeriveFoldable #-} | 13 | {-# LANGUAGE DeriveFoldable #-} |
13 | {-# LANGUAGE DeriveTraversable #-} | 14 | {-# LANGUAGE DeriveTraversable #-} |
14 | {-# LANGUAGE DeriveFunctor #-} | 15 | {-# LANGUAGE DeriveFunctor #-} |
16 | {-# LANGUAGE MultiParamTypeClasses #-} | ||
15 | {-# language TemplateHaskell #-} -- for testing | 17 | {-# language TemplateHaskell #-} -- for testing |
18 | {-# LANGUAGE NoMonomorphismRestriction #-} | ||
16 | 19 | ||
17 | module FreeVars where | 20 | module FreeVars |
21 | ( SFV(..), FV, Nat(..), pattern Nat | ||
22 | , HasFV (..), Lens | ||
23 | , up, down, usedVar, appLens, lComp, lConst | ||
24 | , FVCache(..), LamFV(..), VarFV(..) | ||
25 | , pattern CacheFV | ||
26 | |||
27 | , expand, fv, primContract | ||
28 | ) | ||
29 | where | ||
18 | 30 | ||
19 | import Data.List | 31 | import Data.List |
20 | import Data.Word | 32 | import Data.Word |
@@ -57,51 +69,24 @@ instance Num Nat where | |||
57 | abs _ = error "abs @Nat" | 69 | abs _ = error "abs @Nat" |
58 | signum _ = error "signum @Nat" | 70 | signum _ = error "signum @Nat" |
59 | 71 | ||
72 | instance Monoid Nat where | ||
73 | mempty = 0 | ||
74 | Nat a `mappend` Nat b = Nat (a + b) | ||
75 | |||
60 | instance PShow Nat where pShow (Nat i) = pShow i | 76 | instance PShow Nat where pShow (Nat i) = pShow i |
61 | instance Show Nat where show = ppShow | 77 | instance Show Nat where show = ppShow |
62 | 78 | ||
63 | ---------------------------------------------------------------------------------- | 79 | ---------------------------------------------------------------------------------- |
64 | 80 | ||
65 | data D1 a = D1 a | 81 | -- Expand monoid |
66 | deriving (Functor, Foldable, Traversable, Eq, Ord, Show) | 82 | newtype Expand = Expand {getExpand :: FV} |
67 | 83 | deriving (Eq, Show, Arbitrary) | |
68 | data D2 a = D2 a a | ||
69 | deriving (Functor, Foldable, Traversable, Eq, Ord, Show) | ||
70 | |||
71 | data D3 a = D3 a a a | ||
72 | deriving (Functor, Foldable, Traversable, Eq, Ord, Show) | ||
73 | |||
74 | instance Arbitrary a => Arbitrary (D1 a) where arbitrary = D1 <$> arbitrary | ||
75 | instance Arbitrary a => Arbitrary (D2 a) where arbitrary = D2 <$> arbitrary <*> arbitrary | ||
76 | instance Arbitrary a => Arbitrary (D3 a) where arbitrary = D3 <$> arbitrary <*> arbitrary <*> arbitrary | ||
77 | |||
78 | ---------------------------------------------------------------------------------- | ||
79 | |||
80 | class Monoid a => Expandable a where | ||
81 | 84 | ||
82 | expandT :: Traversable t => a -> t a -> t a | 85 | instance Monoid Expand where |
83 | expandT = fmap . expand | 86 | mempty = Expand $ fO 0 |
84 | 87 | Expand a `mappend` Expand b = Expand (a `expand` b) | |
85 | expand :: a -> a -> a | ||
86 | expand u = runIdentity . expandT u . Identity | ||
87 | |||
88 | primContractT :: Traversable t => a -> t a -> t a | ||
89 | primContractT = fmap . primContract | ||
90 | |||
91 | primContract :: a -> a -> a | ||
92 | primContract u = runIdentity . primContractT u . Identity | ||
93 | |||
94 | contract :: a -> a -> a | ||
95 | contract a b = primContract (a <> b) a | ||
96 | |||
97 | selfContract :: a -> a | ||
98 | selfContract a = primContract a a | ||
99 | |||
100 | diffT :: (Traversable t, Expandable a) => t a -> (a, t a) | ||
101 | diffT u = (s, primContractT s u) | ||
102 | where | ||
103 | s = fold u | ||
104 | 88 | ||
89 | {- | ||
105 | diffTest u = u == uncurry expandT (diffT u) | 90 | diffTest u = u == uncurry expandT (diffT u) |
106 | 91 | ||
107 | assocTestL (D3 a b c) = (abc, D3 a'' b'' c'') == diffT (D3 a b c) | 92 | assocTestL (D3 a b c) = (abc, D3 a'' b'' c'') == diffT (D3 a b c) |
@@ -115,13 +100,7 @@ assocTestR (D3 a b c) = (abc, D3 a'' b'' c'') == diffT (D3 a b c) | |||
115 | (bc, D2 b' c') = diffT $ D2 b c | 100 | (bc, D2 b' c') = diffT $ D2 b c |
116 | (abc, D2 a'' bc') = diffT $ D2 a bc | 101 | (abc, D2 a'' bc') = diffT $ D2 a bc |
117 | D2 b'' c'' = expandT bc' $ D2 b' c' | 102 | D2 b'' c'' = expandT bc' $ D2 b' c' |
118 | 103 | -} | |
119 | class StreamLike a where | ||
120 | type StreamElem a | ||
121 | |||
122 | sDrop :: Nat -> a -> a | ||
123 | |||
124 | sIndex :: a -> Nat -> StreamElem a | ||
125 | 104 | ||
126 | ---------------------------------------------------------------------------------- | 105 | ---------------------------------------------------------------------------------- |
127 | 106 | ||
@@ -194,45 +173,53 @@ instance Monoid FV where | |||
194 | prop_monoid_FV = prop_Monoid (T :: T FV) | 173 | prop_monoid_FV = prop_Monoid (T :: T FV) |
195 | prop_mappend_normal_FV (a :: FV) b = testNormalFV (a <> b) | 174 | prop_mappend_normal_FV (a :: FV) b = testNormalFV (a <> b) |
196 | 175 | ||
197 | instance Expandable FV where | 176 | expand :: FV -> FV -> FV |
198 | expand _ FE = FE | 177 | expand _ FE = FE |
199 | expand FE _ = FE | 178 | expand FE _ = FE |
200 | expand (FV a b xs) (FV c d ys) | 179 | expand (FV a b xs) (FV c d ys) |
201 | | c + d <= b = fv (a + c) d $ expand (FV 0 (b - (c + d)) xs) ys | 180 | | c + d <= b = fv (a + c) d $ expand (FV 0 (b - (c + d)) xs) ys |
202 | | c <= b = fv (a + c) (b - c) $ expand xs (FV 0 (d - (b - c)) ys) | 181 | | c <= b = fv (a + c) (b - c) $ expand xs (FV 0 (d - (b - c)) ys) |
203 | | otherwise = fv (a + b) 0 $ expand xs (FV (c - b) d ys) | 182 | | otherwise = fv (a + b) 0 $ expand xs (FV (c - b) d ys) |
204 | 183 | ||
205 | primContract x FE = FE | 184 | primContract :: FV -> FV -> FV |
206 | primContract (FV a' b' us') (FV a b us) | 185 | primContract x FE = FE |
207 | | a' + b' <= a = fv b' 0 $ primContract us' (FV (a - (a' + b')) b us) | 186 | primContract (FV a' b' us') (FV a b us) |
208 | | otherwise = fv (a - a') b $ primContract (FV 0 ((a' + b') - (a + b)) us') us | 187 | | a' + b' <= a = fv b' 0 $ primContract us' (FV (a - (a' + b')) b us) |
209 | 188 | | otherwise = fv (a - a') b $ primContract (FV 0 ((a' + b') - (a + b)) us') us | |
210 | selfContract xs = fv 0 (altersum xs) FE | 189 | |
211 | where | 190 | contract :: FV -> FV -> FV |
212 | altersum FE = 0 | 191 | contract a b = primContract (a <> b) a |
213 | altersum (FV _ a cs) = a + altersum cs | 192 | |
193 | -- selfContract a = primContract a a | ||
194 | selfContract :: FV -> FV | ||
195 | selfContract xs = fv 0 (altersum xs) FE | ||
196 | where | ||
197 | altersum FE = 0 | ||
198 | altersum (FV _ a cs) = a + altersum cs | ||
214 | 199 | ||
215 | prop_expand_normal_FV (a :: FV) b = testNormalFV (expand a b) | 200 | prop_expand_normal_FV (a :: FV) b = testNormalFV (expand a b) |
216 | prop_contract_normal_FV (a :: FV) b = testNormalFV (contract a b) | 201 | prop_contract_normal_FV (a :: FV) b = testNormalFV (contract a b) |
217 | 202 | ||
218 | prop_diffTestFV1 = diffTest :: D1 FV -> Bool | 203 | prop_monoid_Expand_FV = prop_Monoid (T :: T Expand) |
219 | prop_diffTestFV2 = diffTest :: D2 FV -> Bool | 204 | {- |
220 | prop_diffTestFV3 = diffTest :: D3 FV -> Bool | 205 | --prop_diffTestFV1 = diffTest :: D1 FV -> Bool |
221 | 206 | --prop_diffTestFV2 = diffTest :: D2 FV -> Bool | |
222 | prop_assocTestL_FV = assocTestL :: D3 FV -> Bool | 207 | --prop_diffTestFV3 = diffTest :: D3 FV -> Bool |
223 | prop_assocTestR_FV = assocTestR :: D3 FV -> Bool | ||
224 | 208 | ||
225 | instance StreamLike FV where | 209 | --prop_assocTestL_FV = assocTestL :: D3 FV -> Bool |
226 | type StreamElem FV = Bool | 210 | --prop_assocTestR_FV = assocTestR :: D3 FV -> Bool |
211 | -} | ||
227 | 212 | ||
228 | sIndex FE i = False | 213 | sIndex :: FV -> Nat -> Bool |
229 | sIndex (FV n l us) i = i >= n && (i < l || sIndex us (i - l - n)) | 214 | sIndex FE i = False |
215 | sIndex (FV n l us) i = i >= n && (i < l || sIndex us (i - l - n)) | ||
230 | 216 | ||
231 | sDrop _ FE = FE | 217 | sDrop :: Nat -> FV -> FV |
232 | sDrop n (FV i j us) | 218 | sDrop _ FE = FE |
233 | | i + j <= n = sDrop (n - (i + j)) us | 219 | sDrop n (FV i j us) |
234 | | n <= i = FV (i - n) j us | 220 | | i + j <= n = sDrop (n - (i + j)) us |
235 | | otherwise = FV 0 (j - (n - i)) us | 221 | | n <= i = FV (i - n) j us |
222 | | otherwise = FV 0 (j - (n - i)) us | ||
236 | 223 | ||
237 | ------------------------------------------------ | 224 | ------------------------------------------------ |
238 | 225 | ||
@@ -244,14 +231,6 @@ onTail f n (FV i j us) | |||
244 | | n <= i = fv n 0 $ f $ FV (i - n) j us | 231 | | n <= i = fv n 0 $ f $ FV (i - n) j us |
245 | | otherwise = fv i (n - i) $ f $ FV 0 (j - (n - i)) us | 232 | | otherwise = fv i (n - i) $ f $ FV 0 (j - (n - i)) us |
246 | 233 | ||
247 | -- usedFVs s = filter (sIndex s) [0..] | ||
248 | -- TODO: remove | ||
249 | usedFVs :: FV -> [Nat] | ||
250 | usedFVs = f 0 | ||
251 | where | ||
252 | f _ FE = [] | ||
253 | f s (FV i a xs) = [s+i..(s+i+a)-1] ++ f (s+i+a) xs | ||
254 | |||
255 | -- downFV i u = if sIndex u i then Just $ fv 0 i (FO 1) `contract` u else Nothing | 234 | -- downFV i u = if sIndex u i then Just $ fv 0 i (FO 1) `contract` u else Nothing |
256 | downFV :: Nat -> FV -> Maybe FV | 235 | downFV :: Nat -> FV -> Maybe FV |
257 | downFV i FE = Just FE | 236 | downFV i FE = Just FE |
@@ -265,7 +244,7 @@ fO i = FV i 10000 FE | |||
265 | 244 | ||
266 | mkUp l n = fv 0 l $ fO n | 245 | mkUp l n = fv 0 l $ fO n |
267 | 246 | ||
268 | --upFV l n = expand (fv 0 l $ FO n) | 247 | --upFV l n = expand (mkUp l n) |
269 | upFV :: Nat -> Nat -> FV -> FV | 248 | upFV :: Nat -> Nat -> FV -> FV |
270 | upFV l n FE = FE | 249 | upFV l n FE = FE |
271 | upFV l n (FV n' l' us) | 250 | upFV l n (FV n' l' us) |
@@ -273,16 +252,77 @@ upFV l n (FV n' l' us) | |||
273 | | l' <= l - n' = FV n' l' $ upFV (l - n' - l') n us | 252 | | l' <= l - n' = FV n' l' $ upFV (l - n' - l') n us |
274 | | otherwise = FV n' (l - n') $ FV n (l' - (l - n')) us | 253 | | otherwise = FV n' (l - n') $ FV n (l' - (l - n')) us |
275 | 254 | ||
276 | pattern VarFV i <- FV i _ _ | 255 | -------------------------------------------- |
277 | where VarFV i = FV i 1 FE | 256 | |
257 | type Lens a b = a -> (b, b -> a) | ||
258 | |||
259 | (l1 `lComp` l2) (l1 -> (l2 -> (y, fy), fx)) = (y, fx . fy) | ||
278 | 260 | ||
279 | incFV :: FV -> FV | 261 | lConst e = (mempty, const e) |
280 | incFV = FV{-ok-} 0 1 | ||
281 | 262 | ||
282 | -- compact u = r where (_, D2 r _) = cDiffT $ D2 (SFV 0 u) (SFV 1 FE) | 263 | lId x = (x, id) |
283 | compact :: FV -> FV | 264 | |
284 | compact xs@(FV 0 _ _) = selfContract xs | 265 | lApp' f (a, b) = b (f a) |
285 | compact xs = fv 1 0 $ selfContract xs | 266 | |
267 | ------------ | ||
268 | |||
269 | class HasFV a where | ||
270 | fvLens :: Lens a FV | ||
271 | |||
272 | appLens fx (fvLens -> (y, fy)) = (y, fx . fy) | ||
273 | |||
274 | up l n = lApp' (upFV l n) . fvLens | ||
275 | |||
276 | down i (fvLens -> (ux, fx)) = fx <$> downFV i ux | ||
277 | |||
278 | usedVar :: HasFV x => Nat -> x -> Bool | ||
279 | usedVar i x = sIndex (fst $ fvLens x :: FV) i | ||
280 | |||
281 | instance HasFV FV where | ||
282 | fvLens = lId | ||
283 | |||
284 | instance (HasFV a, HasFV b) => HasFV (a, b) where | ||
285 | fvLens (fvLens -> (ux, x'), fvLens -> (uy, y')) = (s, \s' -> (x' $ s' `expand` primContract s ux, y' $ s' `expand` primContract s uy)) where | ||
286 | s = ux <> uy | ||
287 | |||
288 | --prop_HasFV_D2 (a :: FV) b = contractFV (D2 a b) == diffT (D2 a b) | ||
289 | --prop_HasFV_D2' (s :: FV) a b = expandFV s (D2 a b) == expandT s (D2 a b) | ||
290 | |||
291 | newtype LamFV u = LamFV {getLamFV :: u} | ||
292 | deriving (Eq, Show) | ||
293 | |||
294 | instance HasFV a => HasFV (LamFV a) where | ||
295 | fvLens (LamFV (fvLens -> x@(ux, fx))) = (sDrop 1 ux, \s -> LamFV $ lApp' (onTail (const s) 1) x) | ||
296 | |||
297 | --prop_LamFV (u :: FV) = contractFV (LamFV u) == (sDrop 1 u, LamFV $ onTail selfContract 1 u) | ||
298 | --prop_LamFV' s (u :: FV) = expandFV s (LamFV u) == LamFV (fv 0 1 s `expand` u) | ||
299 | |||
300 | data FVCache a b = FVCache !a !b | ||
301 | deriving (Eq, Show) | ||
302 | |||
303 | instance Functor (FVCache a) where | ||
304 | fmap f (FVCache a b) = FVCache a (f b) | ||
305 | |||
306 | instance HasFV (FVCache FV x) where | ||
307 | fvLens (FVCache u x) = (u, \u -> FVCache u x) | ||
308 | |||
309 | pattern CacheFV a <- FVCache u (lApp' (expand u) . fvLens -> a) | ||
310 | where CacheFV (fvLens -> x@(ua, fa)) = FVCache ua $ lApp' selfContract x | ||
311 | |||
312 | instance HasFV a => HasFV [a] where | ||
313 | fvLens [] = lConst [] | ||
314 | fvLens [fvLens -> (u, fx)] = (u, \s -> [fx s]) | ||
315 | fvLens [fvLens -> (u, fx), fvLens -> (u', fy)] = (s, \s' -> [fx $ s' `expand` primContract s u, fy $ s' `expand` primContract s u' ]) | ||
316 | where | ||
317 | s = u <> u' | ||
318 | fvLens (unzip . map fvLens -> (us, fs)) = let | ||
319 | s = mconcat us in (s, \s -> zipWith (\f u -> f $ s `expand` primContract s u) fs us) | ||
320 | |||
321 | newtype VarFV = VarFV Nat | ||
322 | deriving (Eq, Show) | ||
323 | |||
324 | instance HasFV VarFV where | ||
325 | fvLens (VarFV i) = (FV i 1 FE, \(FV i _ _) -> VarFV i) | ||
286 | 326 | ||
287 | ---------------------------------------------------------------------------------- skewed free vars set | 327 | ---------------------------------------------------------------------------------- skewed free vars set |
288 | 328 | ||
@@ -290,10 +330,6 @@ compact xs = fv 1 0 $ selfContract xs | |||
290 | data SFV = SFV !Nat !FV | 330 | data SFV = SFV !Nat !FV |
291 | deriving (Eq, Show) | 331 | deriving (Eq, Show) |
292 | 332 | ||
293 | padSFV (SFV n x) = SFV n $ fv 0 n $ sDrop n x | ||
294 | |||
295 | fromSFV (SFV n u) = sDrop n u | ||
296 | |||
297 | instance PShow SFV where pShow (SFV n x) = pShow n <> pShow x | 333 | instance PShow SFV where pShow (SFV n x) = pShow n <> pShow x |
298 | 334 | ||
299 | instance Arbitrary SFV where | 335 | instance Arbitrary SFV where |
@@ -302,22 +338,22 @@ instance Arbitrary SFV where | |||
302 | instance Monoid SFV where | 338 | instance Monoid SFV where |
303 | mempty = SFV 0 mempty | 339 | mempty = SFV 0 mempty |
304 | 340 | ||
305 | SFV m b `mappend` SFV n a = SFV (n + m) $ b <> fv m 0 a | 341 | SFV m b `mappend` SFV n a = SFV (n + m) $ sDrop n b <> a |
306 | 342 | ||
307 | prop_monoid_SFV = prop_Monoid (T :: T SFV) | 343 | prop_monoid_SFV = prop_Monoid (T :: T SFV) |
308 | 344 | ||
309 | instance Expandable SFV where | 345 | instance HasFV SFV where |
310 | 346 | fvLens (SFV n u) = (u, SFV n) | |
311 | expandT (padSFV -> SFV n b) = flip evalState b . traverse (\(SFV n a) -> state $ \u -> (SFV n $ u `expand` a, sDrop n u)) | 347 | {- |
312 | 348 | --prop_diffTest1_SFV = diffTest :: D1 SFV -> Bool | |
313 | primContractT (padSFV -> SFV _ b) = flip evalState b . traverse (\(SFV n a) -> state $ \u -> (SFV n $ u `primContract` a, sDrop n u)) | 349 | --prop_diffTest2_SFV = diffTest :: D2 SFV -> Bool |
350 | --prop_diffTest3_SFV = diffTest :: D3 SFV -> Bool | ||
314 | 351 | ||
315 | prop_diffTest1_SFV = diffTest :: D1 SFV -> Bool | 352 | --prop_assocTestL_SFV = assocTestL :: D3 SFV -> Bool |
316 | prop_diffTest2_SFV = diffTest :: D2 SFV -> Bool | 353 | --prop_assocTestR_SFV = assocTestR :: D3 SFV -> Bool |
317 | prop_diffTest3_SFV = diffTest :: D3 SFV -> Bool | 354 | -} |
318 | 355 | ||
319 | prop_assocTestL_SFV = assocTestL :: D3 SFV -> Bool | 356 | ----------------------------------------------------- |
320 | prop_assocTestR_SFV = assocTestR :: D3 SFV -> Bool | ||
321 | 357 | ||
322 | return [] | 358 | return [] |
323 | main = $quickCheckAll | 359 | main = $quickCheckAll |
diff --git a/prototypes/Inspector.hs b/prototypes/Inspector.hs index 1d88577e..317fc326 100644 --- a/prototypes/Inspector.hs +++ b/prototypes/Inspector.hs | |||
@@ -139,7 +139,7 @@ programs = cycle $ map stepList | |||
139 | , iterate (\x -> x `App` x) id_ !! 5 | 139 | , iterate (\x -> x `App` x) id_ !! 5 |
140 | , twiceTest 2 | 140 | , twiceTest 2 |
141 | , twiceTest 3 | 141 | , twiceTest 3 |
142 | , twiceTest2 | 142 | , twiceTest2 2 |
143 | , t' 20 | 143 | , t' 20 |
144 | , t'' 20 | 144 | , t'' 20 |
145 | ] | 145 | ] |
@@ -149,7 +149,7 @@ main = do | |||
149 | hSetBuffering stdout NoBuffering | 149 | hSetBuffering stdout NoBuffering |
150 | getArgs >>= \case | 150 | getArgs >>= \case |
151 | ["twice"] -> pPrint $ hnf $ twiceTest 3 | 151 | ["twice"] -> pPrint $ hnf $ twiceTest 3 |
152 | ["twice2"] -> pPrint $ hnf twiceTest2 | 152 | ["twice2"] -> pPrint $ hnf $ twiceTest2 3 |
153 | [b, n] -> | 153 | [b, n] -> |
154 | putStrLn $ ppShow $ hnf $ case b of | 154 | putStrLn $ ppShow $ hnf $ case b of |
155 | "lazy" -> t' $ read n | 155 | "lazy" -> t' $ read n |
diff --git a/prototypes/LamMachine.hs b/prototypes/LamMachine.hs index d878bcb4..f5375d7f 100644 --- a/prototypes/LamMachine.hs +++ b/prototypes/LamMachine.hs | |||
@@ -7,7 +7,10 @@ | |||
7 | {-# LANGUAGE TypeSynonymInstances #-} | 7 | {-# LANGUAGE TypeSynonymInstances #-} |
8 | {-# LANGUAGE FlexibleInstances #-} | 8 | {-# LANGUAGE FlexibleInstances #-} |
9 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} | 9 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} |
10 | {-# LANGUAGE MultiParamTypeClasses #-} | ||
11 | {-# LANGUAGE FlexibleContexts #-} | ||
10 | {-# LANGUAGE NoMonomorphismRestriction #-} | 12 | {-# LANGUAGE NoMonomorphismRestriction #-} |
13 | {-# LANGUAGE TypeFamilies #-} | ||
11 | 14 | ||
12 | module LamMachine where | 15 | module LamMachine where |
13 | 16 | ||
@@ -16,6 +19,8 @@ import Data.Word | |||
16 | import Data.Int | 19 | import Data.Int |
17 | import Data.Monoid | 20 | import Data.Monoid |
18 | import Data.Maybe | 21 | import Data.Maybe |
22 | --import Data.Foldable (toList) | ||
23 | import qualified SplayList as F | ||
19 | import Control.Arrow hiding ((<+>)) | 24 | import Control.Arrow hiding ((<+>)) |
20 | import Control.Category hiding ((.), id) | 25 | import Control.Category hiding ((.), id) |
21 | import Control.Monad | 26 | import Control.Monad |
@@ -28,20 +33,20 @@ import FreeVars | |||
28 | --------------------------------------------------------------------- data structures | 33 | --------------------------------------------------------------------- data structures |
29 | 34 | ||
30 | data Lit | 35 | data Lit |
31 | = LInt !Int | 36 | = LInt !Int |
32 | | LChar !Char | 37 | | LChar !Char |
33 | | LFloat !Double | 38 | | LFloat !Double |
34 | deriving Eq | 39 | deriving Eq |
35 | 40 | ||
36 | data Exp_ | 41 | data Exp |
37 | = Var_ | 42 | = Var_ !VarFV |
38 | | Lam_ VarInfo !Exp | 43 | | Lam_ VarInfo !(FVCache FV (LamFV Exp)) |
39 | | Let_ VarInfo !Exp !Exp | 44 | | Let_ VarInfo !(FVCache FV (Exp, LamFV Exp)) |
40 | | Con_ ConInfo !Int [Exp] | 45 | | Con_ ConInfo !Int (FVCache FV [Exp]) |
41 | | Case_ CaseInfo !Exp ![Exp] | 46 | | Case_ CaseInfo !(FVCache FV (Exp, [Exp])) |
42 | | Lit_ !Lit | 47 | | Lit !Lit |
43 | | Op1_ !Op1 !Exp | 48 | | Op1 !Op1 !Exp |
44 | | Op2_ !Op2 !Exp !Exp | 49 | | Op2_ !Op2 !(FVCache FV (Exp, Exp)) |
45 | deriving (Eq, Show) | 50 | deriving (Eq, Show) |
46 | 51 | ||
47 | data Op1 = HNFMark | YOp | Round | 52 | data Op1 = HNFMark | YOp | Round |
@@ -55,29 +60,54 @@ pattern App a b = Op2 AppOp a b | |||
55 | pattern Seq a b = Op2 SeqOp a b | 60 | pattern Seq a b = Op2 SeqOp a b |
56 | pattern Int i = Lit (LInt i) | 61 | pattern Int i = Lit (LInt i) |
57 | 62 | ||
58 | infixl 4 `App` | 63 | pattern Var i = Var_ (VarFV i) |
64 | pattern Lam n i = Lam_ n (CacheFV (LamFV i)) | ||
65 | pattern Let n i x <- Let_ n (CacheFV (i, LamFV x)) | ||
66 | where Let _ _ (down 0 -> Just x) = x | ||
67 | Let n i x = Let_ n (CacheFV (i, LamFV x)) | ||
68 | pattern Con a b i = Con_ a b (CacheFV i) | ||
69 | pattern Case a b c = Case_ a (CacheFV (b, c)) | ||
70 | pattern Op2 op a b = Op2_ op (CacheFV (a, b)) | ||
59 | 71 | ||
60 | -- cached and compressed free variables set | 72 | infixl 4 `App` |
61 | data Exp = Exp !FV !Exp_ | ||
62 | deriving (Eq, Show) | ||
63 | 73 | ||
64 | data EnvPiece | 74 | data EnvPiece |
65 | = ELet VarInfo !Exp | 75 | = ELet_ VarInfo !Exp |
66 | | EDLet1 VarInfo !DExp | 76 | | EDLet1_ VarInfo !(LamFV DExp) |
67 | | ECase_ CaseInfo !FV ![Exp] | 77 | | ECase_ CaseInfo !(FVCache FV [Exp]) |
68 | | EOp2_1 !Op2 !Exp | 78 | | EOp2_1_ !Op2 !Exp |
69 | | EOp2_2 !Op2 !Exp | 79 | | EOp2_2_ !Op2 !Exp |
70 | deriving (Eq, Show) | 80 | deriving (Eq, Show) |
71 | 81 | ||
72 | data DExp | 82 | pattern ELet i x = ELet_ i x |
73 | = DExpNil -- variable | 83 | pattern EDLet1 i x = EDLet1_ i (LamFV x) |
74 | | DExpCons_ !FV !EnvPiece !DExp | 84 | pattern ECase op b = ECase_ op (CacheFV b) |
75 | deriving (Eq, Show) | 85 | pattern EOp2_1 i x = EOp2_1_ i x |
86 | pattern EOp2_2 i x = EOp2_2_ i x | ||
76 | 87 | ||
77 | data DEnv | 88 | type DEnv = F.SplayList EnvPiece |
78 | = DEnvNil | 89 | |
79 | | DEnvCons !EnvPiece !DEnv | 90 | pattern DEnvNil = F.Nil |
80 | deriving (Eq, Show) | 91 | |
92 | pattern DEnvCons :: EnvPiece -> DEnv -> DEnv | ||
93 | pattern DEnvCons p e = F.Cons p e | ||
94 | |||
95 | instance F.Measured EnvPiece where | ||
96 | type Measure EnvPiece = Nat | ||
97 | measure = \case | ||
98 | ELet_{} -> 1 | ||
99 | _ -> 0 | ||
100 | --instance HasSFV DExp where | ||
101 | |||
102 | |||
103 | type DExp = DEnv | ||
104 | |||
105 | pattern DExpNil = DEnvNil | ||
106 | |||
107 | pattern DExpCons :: EnvPiece -> DExp -> DExp | ||
108 | pattern DExpCons p e = F.Snoc e p | ||
109 | |||
110 | infixr 4 `DEnvCons`, `DExpCons` | ||
81 | 111 | ||
82 | -- state of the machine | 112 | -- state of the machine |
83 | data MSt = MSt !DEnv !Exp | 113 | data MSt = MSt !DEnv !Exp |
@@ -89,122 +119,40 @@ type VarInfo = String | |||
89 | type ConInfo = String | 119 | type ConInfo = String |
90 | type CaseInfo = [(String, [String])] | 120 | type CaseInfo = [(String, [String])] |
91 | 121 | ||
92 | --------------------------------------------------------------------- pattern synonyms | 122 | --------------------------------------------------------------------- instances |
93 | 123 | ||
94 | infixr 4 `DEnvCons`, `DExpCons` | 124 | instance HasFV Exp where |
125 | fvLens = \case | ||
126 | Op1 op e -> appLens (Op1 op) e | ||
127 | Op2_ op e -> appLens (Op2_ op) e | ||
128 | Con_ x op e -> appLens (Con_ x op) e | ||
129 | Case_ op e -> appLens (Case_ op) e | ||
130 | Let_ op e -> appLens (Let_ op) e | ||
131 | Lam_ op e -> appLens (Lam_ op) e | ||
132 | Var_ e -> appLens Var_ e | ||
133 | Lit l -> lConst $ Lit l | ||
134 | |||
135 | instance HasFV EnvPiece where | ||
136 | fvLens = \case | ||
137 | EOp2_1_ op e -> appLens (EOp2_1_ op) e | ||
138 | EOp2_2_ op e -> appLens (EOp2_2_ op) e | ||
139 | ECase_ op e -> appLens (ECase_ op) e | ||
140 | ELet_ op e -> appLens (ELet_ op) e | ||
141 | EDLet1_ op e -> appLens (EDLet1_ op) e | ||
95 | 142 | ||
96 | pattern ECase op e <- ECase_ op u (map (upp u) -> e) | 143 | --------------------------- |
97 | where ECase op b = ECase_ op u bz where (u, bz) = deltas b | ||
98 | |||
99 | pattern EnvPiece sfv p <- (getEnvPiece -> (sfv, p)) | ||
100 | where EnvPiece sfv@(SFV n u') = \case | ||
101 | EOp2_1 op e -> EOp2_1 op (uppS sfv e) | ||
102 | EOp2_2 op e -> EOp2_2 op (uppS sfv e) | ||
103 | ECase_ s u es -> ECase_ s (expand u' u) es | ||
104 | ELet n (Exp u e) -> ELet n (Exp (sDrop 1 u' `expand` u) e) | ||
105 | EDLet1 n z -> EDLet1 n $ uppDE u' 1 z | ||
106 | |||
107 | getEnvPiece = \case | ||
108 | EOp2_1 op (Exp u e) -> (SFV 0 u, EOp2_1 op (Exp (selfContract u) e)) | ||
109 | EOp2_2 op (Exp u e) -> (SFV 0 u, EOp2_2 op (Exp (selfContract u) e)) | ||
110 | ECase_ s u es -> (SFV 0 u, ECase_ s (selfContract u) es) | ||
111 | ELet n (Exp u e) -> (SFV 1 $ fv 1 0 u, ELet n $ Exp (selfContract u) e) | ||
112 | EDLet1 n DExpNil -> (mempty, EDLet1 n DExpNil) | ||
113 | EDLet1 n (DExpCons_ u x y) -> (SFV 0 $ sDrop 1 u, EDLet1 n $ DExpCons_ (onTail selfContract 1 u) x y) | ||
114 | |||
115 | uppS (SFV _ x) (Exp u a) = Exp (expand x u) a | ||
116 | |||
117 | pattern DExpCons :: EnvPiece -> DExp -> DExp | ||
118 | pattern DExpCons a b <- (getDExpCons -> (a, b)) | ||
119 | where DExpCons (EnvPiece ux a) DExpNil = DExpCons_ (fromSFV s) (EnvPiece ux' a) DExpNil | ||
120 | where (s, D1 ux') = diffT $ D1 ux | ||
121 | DExpCons (ELet _ a) (dDown 0 -> Just d) = d | ||
122 | DExpCons (EnvPiece ux a) (DExpCons_ u x y) = DExpCons_ (fromSFV s) (EnvPiece ux' a) (DExpCons_ u' x y) | ||
123 | where (s, D2 (SFV 0 u') ux') = diffT $ D2 (SFV 0 u) ux | ||
124 | |||
125 | getDExpCons (DExpCons_ u x@(EnvPiece (SFV n _) _) b) = (uppEP u x, uppDE u n b) | ||
126 | |||
127 | uppEP u (EnvPiece (SFV n x) y) = EnvPiece (SFV n $ onTail (u `expand`) n x) y | ||
128 | |||
129 | upP i j = uppEP $ mkUp i j | ||
130 | |||
131 | incFV' (SFV n u) = SFV (n + 1) $ incFV u | ||
132 | |||
133 | uppDE :: FV -> Nat -> DExp -> DExp | ||
134 | uppDE a _ DExpNil = DExpNil | ||
135 | uppDE a n (DExpCons_ u x y) = DExpCons_ (onTail (expand a) n u) x y | ||
136 | |||
137 | dDown i DExpNil = Just DExpNil | ||
138 | dDown i (DExpCons_ u a b) = DExpCons_ <$> downFV i u <*> pure a <*> pure b | ||
139 | |||
140 | --------------------------------------------------------------------- | ||
141 | |||
142 | pattern Lit i <- Exp _ (Lit_ i) | ||
143 | where Lit i = Exp mempty $ Lit_ i | ||
144 | pattern Op2 op a b <- Exp u (Op2_ op (upp u -> a) (upp u -> b)) | ||
145 | where Op2 op a b = Exp s $ Op2_ op az bz where (s, az, bz) = delta2 a b | ||
146 | pattern Op1 op a <- Exp u (Op1_ op (upp u -> a)) | ||
147 | where Op1 op (Exp ab x) = Exp ab $ Op1_ op $ Exp (selfContract ab) x | ||
148 | pattern Var' i = Exp (VarFV i) Var_ | ||
149 | pattern Var i = Var' i | ||
150 | pattern Lam n i <- Exp u (Lam_ n (upp (incFV u) -> i)) | ||
151 | where Lam n (Exp vs ax) = Exp (sDrop 1 vs) $ Lam_ n $ Exp (compact vs) ax | ||
152 | pattern Con a b i <- Exp u (Con_ a b (map (upp u) -> i)) | ||
153 | where Con a b x = Exp s $ Con_ a b bz where (s, bz) = deltas x | ||
154 | pattern Case a b c <- Exp u (Case_ a (upp u -> b) (map (upp u) -> c)) | ||
155 | where Case cn a b = Exp s $ Case_ cn az bz where (s, az: bz) = deltas $ a: b | ||
156 | |||
157 | pattern Let n i x <- Exp u (Let_ n (upp u -> i) (upp (incFV u) -> x)) | ||
158 | where Let _ _ (down 0 -> Just x) = x | ||
159 | Let n a b = Exp s (Let_ n a' b') where (s, a', Lam _ b') = delta2 a $ Lam n b | ||
160 | 144 | ||
161 | pattern InHNF a <- (getHNF -> Just a) | 145 | pattern InHNF a <- (getHNF -> Just a) |
162 | where InHNF a@Lit{} = a | 146 | where InHNF a@Lit{} = a |
163 | InHNF a@Lam{} = a | 147 | InHNF a@Lam{} = a |
164 | InHNF a@(Op1 HNFMark _) = a | 148 | InHNF a@(Op1 HNFMark _) = a |
165 | InHNF a = Op1 HNFMark a | 149 | InHNF a = Op1 HNFMark a |
166 | 150 | ||
167 | getHNF x = case x of | 151 | getHNF x = case x of |
168 | Lit{} -> Just x | 152 | Lit{} -> Just x |
169 | Lam{} -> Just x | 153 | Lam{} -> Just x |
170 | Op1 HNFMark a -> Just a | 154 | Op1 HNFMark a -> Just a |
171 | _ -> Nothing | 155 | _ -> Nothing |
172 | |||
173 | delta2 (Exp ua a) (Exp ub b) = (s, Exp ua' a, Exp ub' b) | ||
174 | where | ||
175 | (s, ua', ub') = delta2' ua ub | ||
176 | |||
177 | delta2' ua ub = (s, primContract s ua, primContract s ub) | ||
178 | where | ||
179 | s = ua <> ub | ||
180 | |||
181 | deltas [] = (mempty, []) | ||
182 | deltas [Exp x e] = (x, [Exp (selfContract x) e]) | ||
183 | deltas [Exp ua a, Exp ub b] = (s, [Exp (primContract s ua) a, Exp (primContract s ub) b]) | ||
184 | where | ||
185 | s = ua <> ub | ||
186 | deltas es = (s, [Exp (primContract s u) e | (u, Exp _ e) <- zip xs es]) | ||
187 | where | ||
188 | xs = [ue | Exp ue _ <- es] | ||
189 | |||
190 | s = mconcat xs | ||
191 | |||
192 | upp :: FV -> Exp -> Exp | ||
193 | upp a (Exp b e) = Exp (expand a b) e | ||
194 | |||
195 | up l n (Exp us x) = Exp (upFV l n us) x | ||
196 | |||
197 | -- free variables set | ||
198 | --fvs (Exp us _) = usedFVs us | ||
199 | |||
200 | usedVar i (Exp us _) = sIndex us i | ||
201 | |||
202 | usedVar' i DExpNil = False | ||
203 | usedVar' i (DExpCons_ u _ _) = sIndex u i | ||
204 | |||
205 | down i (Exp us e) = Exp <$> downFV i us <*> pure e | ||
206 | |||
207 | --------------------------- | ||
208 | 156 | ||
209 | initSt :: Exp -> MSt | 157 | initSt :: Exp -> MSt |
210 | initSt e = MSt DEnvNil e | 158 | initSt e = MSt DEnvNil e |
@@ -221,30 +169,27 @@ hnf = justResult . initSt | |||
221 | data StepTag = Begin String | End String | Step String | 169 | data StepTag = Begin String | End String | Step String |
222 | deriving Show | 170 | deriving Show |
223 | 171 | ||
224 | type GenSteps e | 172 | focusNotUsed (EDLet1 _ x `DEnvCons` _) = False --not $ usedVar 0 x |
225 | = e | ||
226 | -> (StepTag -> MSt -> e) | ||
227 | -> MSt -> e | ||
228 | |||
229 | focusNotUsed (MSt (EDLet1 _ x `DEnvCons` _) _) = not $ usedVar' 0 x | ||
230 | focusNotUsed _ = True | 173 | focusNotUsed _ = True |
231 | 174 | ||
232 | inHNF :: MSt -> Bool | 175 | inHNF :: MSt -> Bool |
233 | inHNF (MSt _ (InHNF _)) = True | 176 | inHNF (MSt _ (InHNF _)) = True |
234 | inHNF _ = False | 177 | inHNF _ = False |
235 | 178 | ||
236 | steps :: forall e . GenSteps e | 179 | steps :: forall e . e -> (StepTag -> MSt -> e) -> MSt -> e |
237 | steps nostep bind (MSt vs e) = case e of | 180 | steps nostep bind (MSt vs e) = case e of |
238 | 181 | ||
182 | e | EDLet1 _ (down 0 -> Just d) `DEnvCons` vs <- vs -> zipUp e vs d | ||
183 | |||
239 | Con cn i xs | 184 | Con cn i xs |
240 | | lz == 0 || focusNotUsed (MSt vs e) -> step (cn ++ " hnf") $ MSt vs $ InHNF e | 185 | | focusNotUsed vs || lz == 0 -> step (cn ++ " hnf") $ MSt vs $ InHNF e |
241 | | otherwise -> step (cn ++ " copy") $ MSt (foldr DEnvCons vs $ ELet "" <$> zs) $ InHNF $ Con cn i xs' -- share complex constructor arguments | 186 | | otherwise -> step (cn ++ " copy") $ MSt (foldr DEnvCons vs $ ELet "" <$> zs) $ InHNF $ Con cn i xs' -- share complex constructor arguments |
242 | where | 187 | where |
243 | lz = Nat $ length zs | 188 | lz = Nat $ length zs |
244 | (xs', concat -> zs) = unzip $ f 0 xs | 189 | (xs', concat -> zs) = unzip $ f 0 xs |
245 | f i [] = [] | 190 | f i [] = [] |
246 | f i (x: xs) | simple x = (up 0 lz x, []): f i xs | 191 | f i (x: xs) | simple x = (up 0 lz x, []): f i xs |
247 | | otherwise = (Var' i, [up 0 (lz - i - 1) x]): f (i+1) xs | 192 | | otherwise = (Var i, [up 0 (lz - i - 1) x]): f (i+1) xs |
248 | 193 | ||
249 | -- TODO: handle recursive constants | 194 | -- TODO: handle recursive constants |
250 | Y x -> step "Y" $ MSt vs $ App x (Y x) | 195 | Y x -> step "Y" $ MSt vs $ App x (Y x) |
@@ -257,14 +202,15 @@ steps nostep bind (MSt vs e) = case e of | |||
257 | 202 | ||
258 | DEnvNil -> nostep | 203 | DEnvNil -> nostep |
259 | 204 | ||
260 | ELet n x `DEnvCons` vs -> step "goUp" $ MSt vs $ InHNF $ Let n x $ InHNF a | 205 | ELet n x `DEnvCons` vs -> step "goUp" $ MSt vs $ InHNF $ Let n x $ InHNF a -- TODO: speed up? |
261 | x `DEnvCons` vs | Let n y e <- a -> step "pakol" $ MSt (upP 0 1 x `DEnvCons` ELet n y `DEnvCons` vs) e | 206 | x `DEnvCons` vs | Let n y e <- a -> step "pakol" $ MSt (up 0 1 x `DEnvCons` ELet n y `DEnvCons` vs) e -- TODO: speed up |
262 | x `DEnvCons` vs -> case x of | 207 | x `DEnvCons` vs -> case x of |
263 | ECase cns cs -> end "case" $ case a of | 208 | ECase cns cs -> end "case" $ case a of |
264 | Con cn i es -> MSt vs $ foldl App (cs !! i) es -- TODO: remove unused cases | 209 | Con cn i es -> MSt vs $ foldl App (cs !! i) es -- TODO: remove unused cases |
265 | _ -> MSt vs $ InHNF $ Case cns (InHNF a) cs | 210 | _ -> MSt vs $ InHNF $ Case cns (InHNF a) cs |
266 | EOp2_1 AppOp b -> end "AppOp" $ case a of | 211 | EOp2_1 AppOp b -> end "AppOp" $ case a of |
267 | Lam _ (down 0 -> Just x) -> MSt vs x -- TODO: remove b | 212 | Lam _ (down 0 -> Just x) -> MSt vs x -- TODO: remove b |
213 | -- TODO: optimize out Var 0 application | ||
268 | Lam n x -> MSt (ELet n b `DEnvCons` vs) x | 214 | Lam n x -> MSt (ELet n b `DEnvCons` vs) x |
269 | _ -> MSt vs $ InHNF $ App (InHNF a) b | 215 | _ -> MSt vs $ InHNF $ App (InHNF a) b |
270 | EOp2_1 SeqOp b -> end "SeqOp" $ case a of | 216 | EOp2_1 SeqOp b -> end "SeqOp" $ case a of |
@@ -282,17 +228,17 @@ steps nostep bind (MSt vs e) = case e of | |||
282 | int LessEq a b = if a <= b then T else F | 228 | int LessEq a b = if a <= b then T else F |
283 | int EqInt a b = if a == b then T else F | 229 | int EqInt a b = if a == b then T else F |
284 | _ -> MSt vs $ InHNF $ Op2 op b (InHNF a) | 230 | _ -> MSt vs $ InHNF $ Op2 op b (InHNF a) |
285 | EDLet1 _ (dDown 0 -> Just d) -> zipUp (InHNF a) vs d | ||
286 | EDLet1 n d -> zipUp (up 0 1 a) (ELet n (InHNF a) `DEnvCons` vs) d | 231 | EDLet1 n d -> zipUp (up 0 1 a) (ELet n (InHNF a) `DEnvCons` vs) d |
287 | 232 | ||
288 | where | 233 | where |
289 | zipDown 0 e (ELet n z `DEnvCons` zs) = MSt (EDLet1 n e `DEnvCons` zs) z | 234 | zipDown j e (F.split (> j) -> (t, ELet n z `DEnvCons` zs)) |
290 | zipDown j e (z@ELet{} `DEnvCons` zs) = zipDown (j-1) (z `DExpCons` e) zs | 235 | = MSt (EDLet1 n (f e t) `DEnvCons` zs) z |
291 | zipDown j e (z `DEnvCons` zs) = zipDown j (z `DExpCons` e) zs | 236 | where |
237 | f e t = t <> e | ||
292 | 238 | ||
293 | zipUp x xs DExpNil = end "var" $ MSt xs x | 239 | zipUp x xs e = end "var" $ MSt (e <> xs) $ up 0 n x |
294 | zipUp x xs (DExpCons a@ELet{} as) = zipUp (up 0 1 x) (a `DEnvCons` xs) as | 240 | where |
295 | zipUp x xs (DExpCons a as) = zipUp x (a `DEnvCons` xs) as | 241 | n = F.measure e |
296 | 242 | ||
297 | begin t = bind (Begin t) | 243 | begin t = bind (Begin t) |
298 | next t = bind (Step t) | 244 | next t = bind (Step t) |
@@ -318,7 +264,7 @@ class ViewShow a where | |||
318 | 264 | ||
319 | instance ViewShow Exp where | 265 | instance ViewShow Exp where |
320 | viewShow vi = pShow where | 266 | viewShow vi = pShow where |
321 | pShow e@(Exp fv x) = showFE green vi fv $ | 267 | pShow e = showFE green vi (fst $ fvLens e :: FV) $ |
322 | case {-if vi then Exp_ (selfContract fv) x else-} e of | 268 | case {-if vi then Exp_ (selfContract fv) x else-} e of |
323 | Var (Nat i) -> DVar i | 269 | Var (Nat i) -> DVar i |
324 | Let n a b -> shLet n (pShow a) $ pShow b | 270 | Let n a b -> shLet n (pShow a) $ pShow b |
@@ -366,7 +312,7 @@ instance ViewShow MSt where | |||
366 | EOp2_2 op x -> shOp2 op (pShow x) y | 312 | EOp2_2 op x -> shOp2 op (pShow x) y |
367 | 313 | ||
368 | h n DExpNil = onred $ white $ DVar n | 314 | h n DExpNil = onred $ white $ DVar n |
369 | h n z@(DExpCons p (h (adj p n) -> y)) = showFE blue vi (case p of EnvPiece f _ -> f) $ case p of | 315 | h n z@(DExpCons p (h (adj p n) -> y)) = showFE blue vi (fst $ fvLens p :: FV) $ case p of |
370 | EDLet1 n x -> shLet n y (h 0 x) | 316 | EDLet1 n x -> shLet n y (h 0 x) |
371 | ELet n x -> shLet n (pShow x) y | 317 | ELet n x -> shLet n (pShow x) y |
372 | ECase cns xs -> shCase cns y pShow xs | 318 | ECase cns xs -> shCase cns y pShow xs |
@@ -446,7 +392,7 @@ sum' = Y $ Lam "sum" $ Lam "xs" $ caseList (Var 0) (Int 0) $ Lam "y" $ Lam "ys" | |||
446 | 392 | ||
447 | infixl 4 `sApp` | 393 | infixl 4 `sApp` |
448 | 394 | ||
449 | sApp a b = Seq b (App a b) | 395 | sApp a b = Lam "s" (Seq (Var 0) (a `App` Var 0)) `App` b |
450 | 396 | ||
451 | {- | 397 | {- |
452 | accsum acc [] = acc | 398 | accsum acc [] = acc |
@@ -477,14 +423,14 @@ inc = Lam "n" $ Op2 Add (Var 0) (Int 1) | |||
477 | test'' = Lam "f" (Int 4) `App` Int 3 | 423 | test'' = Lam "f" (Int 4) `App` Int 3 |
478 | 424 | ||
479 | twiceTest n = (Lam "twice" $ (iterate (`App` Var 0) (Var 0) !! n) `App` inc `App` Int 0) `App` twice | 425 | twiceTest n = (Lam "twice" $ (iterate (`App` Var 0) (Var 0) !! n) `App` inc `App` Int 0) `App` twice |
480 | twiceTest2 = twice2 `App` twice2 `App` twice2 `App` twice2 `App` inc `App` Int 0 | 426 | twiceTest2 n = (Lam "twice" $ (iterate (`App` Var 0) (Var 0) !! n) `App` inc `App` Int 0) `App` twice2 |
481 | 427 | ||
482 | tests | 428 | tests |
483 | = hnf test == hnf (Int 13) | 429 | = hnf test == hnf (Int 13) |
484 | && hnf test' == hnf (Int 14) | 430 | && hnf test' == hnf (Int 14) |
485 | && hnf test'' == hnf (Int 4) | 431 | && hnf test'' == hnf (Int 4) |
486 | && hnf (t' 10) == hnf (Int 55) | 432 | && hnf (t' 10) == hnf (Int 55) |
487 | && hnf (t'' 10) == hnf (Int 55) | 433 | -- && hnf (t'' 10) == hnf (Int 55) |
488 | 434 | ||
489 | 435 | ||
490 | 436 | ||
diff --git a/prototypes/SplayList.hs b/prototypes/SplayList.hs new file mode 100644 index 00000000..fee995ed --- /dev/null +++ b/prototypes/SplayList.hs | |||
@@ -0,0 +1,151 @@ | |||
1 | {-# LANGUAGE FlexibleContexts #-} | ||
2 | {-# LANGUAGE FlexibleInstances #-} | ||
3 | {-# LANGUAGE UndecidableInstances #-} | ||
4 | {-# LANGUAGE TypeFamilies #-} | ||
5 | {-# LANGUAGE GADTs #-} | ||
6 | {-# LANGUAGE BangPatterns #-} | ||
7 | {-# LANGUAGE StandaloneDeriving #-} | ||
8 | {-# LANGUAGE PatternSynonyms #-} | ||
9 | {-# LANGUAGE PatternGuards #-} | ||
10 | {-# LANGUAGE ViewPatterns #-} | ||
11 | {-# LANGUAGE LambdaCase #-} | ||
12 | {-# LANGUAGE MultiParamTypeClasses #-} | ||
13 | {-# LANGUAGE NoMonomorphismRestriction #-} | ||
14 | |||
15 | module SplayList | ||
16 | ( SplayList (..) | ||
17 | , pattern Cons, pattern Snoc | ||
18 | , Measured (..) | ||
19 | , split | ||
20 | ) where | ||
21 | |||
22 | import Prelude hiding (null) | ||
23 | import Control.Applicative hiding (empty) | ||
24 | import Control.Monad | ||
25 | import Control.Arrow | ||
26 | |||
27 | import Data.Function | ||
28 | import Data.Data | ||
29 | import Data.Maybe | ||
30 | import Data.Monoid | ||
31 | |||
32 | import FreeVars | ||
33 | |||
34 | ------------------------------------------------------------------------ | ||
35 | |||
36 | data SplayList a | ||
37 | = Nil | ||
38 | | Singleton a | ||
39 | | Append_ !(Measure a) !FV (SplayList a) (SplayList a) | ||
40 | deriving (Typeable) | ||
41 | |||
42 | deriving instance (Show a, Show (Measure a)) => Show (SplayList a) | ||
43 | |||
44 | toList = go [] | ||
45 | where | ||
46 | go i Nil = i | ||
47 | go i (Singleton a) = a: i | ||
48 | go acc (Append l r) = go (go acc r) l | ||
49 | |||
50 | instance (Measured a, Eq a) => Eq (SplayList a) where (==) = (==) `on` toList | ||
51 | instance (Measured a, Ord a) => Ord (SplayList a) where compare = compare `on` toList | ||
52 | |||
53 | -------------------------------------------- | ||
54 | |||
55 | class (HasFV a, Measure a ~ Nat) => Measured a where | ||
56 | type Measure a :: * | ||
57 | measure :: a -> Measure a | ||
58 | |||
59 | instance Measured a => Monoid (SplayList a) where | ||
60 | mempty = Nil | ||
61 | Nil `mappend` ys = ys | ||
62 | xs `mappend` Nil = xs | ||
63 | xs `mappend` ys = Append xs ys | ||
64 | |||
65 | instance (Measured a, HasFV a) => HasFV (SplayList a) where | ||
66 | fvLens = \case | ||
67 | Nil -> lConst Nil | ||
68 | Singleton (fvLens -> (s, f)) -> (s, Singleton . f) | ||
69 | Append_ n s l r -> (s, \s -> Append_ n s l r) | ||
70 | |||
71 | instance (Measured a) => Measured (SplayList a) where | ||
72 | type Measure (SplayList a) = Measure a | ||
73 | measure Nil = mempty | ||
74 | measure (Singleton a) = measure a | ||
75 | measure (Append_ n _ _ _) = n | ||
76 | |||
77 | -------------------------------------------- | ||
78 | |||
79 | getAppend (Append_ _ s x@(fvLens -> ~(ux, x')) z@(fvLens -> ~(uz, z'))) | ||
80 | = Just (x' $ fv 0 (measure z) s `expand` ux, z' $ s `expand` uz) | ||
81 | getAppend _ = Nothing | ||
82 | |||
83 | pattern Append :: () => Measured a => SplayList a -> SplayList a -> SplayList a | ||
84 | pattern Append l r <- (getAppend -> Just (l, r)) | ||
85 | where Append x@(fvLens -> (ux, x')) z@(fvLens -> (uz, z')) = Append_ us s (x' ux') (z' uz') | ||
86 | where | ||
87 | SFV us s = SFV (measure x) ux <> SFV mz uz | ||
88 | |||
89 | mz = measure z | ||
90 | |||
91 | ux' = fv 0 mz s `primContract` ux | ||
92 | uz' = s `primContract` uz | ||
93 | |||
94 | pattern Cons a as <- (viewl -> Just (a, ascendL -> as)) | ||
95 | where Cons a as = Singleton a <> as | ||
96 | |||
97 | viewl Nil = Nothing | ||
98 | viewl xs = Just $ go [] xs | ||
99 | where | ||
100 | go xs (Singleton a) = (a, xs) | ||
101 | go xs (Append l r) = go (r: xs) l | ||
102 | |||
103 | ascendL [] = Nil | ||
104 | ascendL (x: xs) = go x xs | ||
105 | where | ||
106 | go !a = \case | ||
107 | [] -> a | ||
108 | b: [] -> a `app` b | ||
109 | b: c: xs -> go (a `app` Append b c) xs | ||
110 | |||
111 | Append a b `app` c = Append a (Append b c) | ||
112 | a `app` b = Append a b | ||
113 | |||
114 | pattern Snoc as a <- (viewr -> Just (a, ascendR -> as)) | ||
115 | where Snoc as a = as <> Singleton a | ||
116 | |||
117 | viewr Nil = Nothing | ||
118 | viewr xs = Just $ go [] xs | ||
119 | where | ||
120 | go xs (Singleton a) = (a, xs) | ||
121 | go xs (Append l r) = go (l: xs) r | ||
122 | |||
123 | ascendR [] = Nil | ||
124 | ascendR (x: xs) = go x xs | ||
125 | where | ||
126 | go !c = \case | ||
127 | [] -> c | ||
128 | a: [] -> a `app` c | ||
129 | b: a: xs -> go (Append a b `app` c) xs | ||
130 | |||
131 | a `app` Append b c = Append (Append a b) c | ||
132 | a `app` b = Append a b | ||
133 | |||
134 | -- | Split a list at the point where the predicate on the measure changes from False to True. | ||
135 | split :: Measured a => (Nat -> Bool) -> SplayList a -> (SplayList a, SplayList a) | ||
136 | split _ Nil = (Nil, Nil) | ||
137 | split p xs | ||
138 | | p mempty = (Nil, xs) | ||
139 | | p (measure xs) = go mempty [] [] xs | ||
140 | | otherwise = (xs, Nil) | ||
141 | where | ||
142 | go m ls rs = \case | ||
143 | Append l r | ||
144 | | p n -> go m ls (r: rs) l | ||
145 | | otherwise -> go n (l: ls) rs r | ||
146 | where | ||
147 | n = m <> measure l | ||
148 | |||
149 | xs | p (m <> measure xs) -> (ascendR ls, ascendL $ xs: rs) | ||
150 | | otherwise -> (ascendR $ xs: ls, ascendL rs) | ||
151 | |||