summaryrefslogtreecommitdiff
path: root/prototypes
diff options
context:
space:
mode:
authorPéter Diviánszky <divipp@gmail.com>2016-06-09 17:14:31 +0200
committerPéter Diviánszky <divipp@gmail.com>2016-06-09 17:14:31 +0200
commitd70ef80e63a0f84798071d31abbf80747c1fe639 (patch)
tree54f3d5dc021ad2e61a553fe711b17352d3f72a81 /prototypes
parent57fd497f487b83d6eab1e2ca05e6ff5722af6938 (diff)
use splay lists
Diffstat (limited to 'prototypes')
-rw-r--r--prototypes/FreeVars.hs256
-rw-r--r--prototypes/Inspector.hs4
-rw-r--r--prototypes/LamMachine.hs268
-rw-r--r--prototypes/SplayList.hs151
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
17module FreeVars where 20module 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
19import Data.List 31import Data.List
20import Data.Word 32import 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
72instance Monoid Nat where
73 mempty = 0
74 Nat a `mappend` Nat b = Nat (a + b)
75
60instance PShow Nat where pShow (Nat i) = pShow i 76instance PShow Nat where pShow (Nat i) = pShow i
61instance Show Nat where show = ppShow 77instance Show Nat where show = ppShow
62 78
63---------------------------------------------------------------------------------- 79----------------------------------------------------------------------------------
64 80
65data D1 a = D1 a 81-- Expand monoid
66 deriving (Functor, Foldable, Traversable, Eq, Ord, Show) 82newtype Expand = Expand {getExpand :: FV}
67 83 deriving (Eq, Show, Arbitrary)
68data D2 a = D2 a a
69 deriving (Functor, Foldable, Traversable, Eq, Ord, Show)
70
71data D3 a = D3 a a a
72 deriving (Functor, Foldable, Traversable, Eq, Ord, Show)
73
74instance Arbitrary a => Arbitrary (D1 a) where arbitrary = D1 <$> arbitrary
75instance Arbitrary a => Arbitrary (D2 a) where arbitrary = D2 <$> arbitrary <*> arbitrary
76instance Arbitrary a => Arbitrary (D3 a) where arbitrary = D3 <$> arbitrary <*> arbitrary <*> arbitrary
77
78----------------------------------------------------------------------------------
79
80class Monoid a => Expandable a where
81 84
82 expandT :: Traversable t => a -> t a -> t a 85instance 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
100diffT :: (Traversable t, Expandable a) => t a -> (a, t a)
101diffT u = (s, primContractT s u)
102 where
103 s = fold u
104 88
89{-
105diffTest u = u == uncurry expandT (diffT u) 90diffTest u = u == uncurry expandT (diffT u)
106 91
107assocTestL (D3 a b c) = (abc, D3 a'' b'' c'') == diffT (D3 a b c) 92assocTestL (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-}
119class 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
194prop_monoid_FV = prop_Monoid (T :: T FV) 173prop_monoid_FV = prop_Monoid (T :: T FV)
195prop_mappend_normal_FV (a :: FV) b = testNormalFV (a <> b) 174prop_mappend_normal_FV (a :: FV) b = testNormalFV (a <> b)
196 175
197instance Expandable FV where 176expand :: FV -> FV -> FV
198 expand _ FE = FE 177expand _ FE = FE
199 expand FE _ = FE 178expand FE _ = FE
200 expand (FV a b xs) (FV c d ys) 179expand (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 184primContract :: FV -> FV -> FV
206 primContract (FV a' b' us') (FV a b us) 185primContract x FE = FE
207 | a' + b' <= a = fv b' 0 $ primContract us' (FV (a - (a' + b')) b us) 186primContract (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 190contract :: FV -> FV -> FV
212 altersum FE = 0 191contract a b = primContract (a <> b) a
213 altersum (FV _ a cs) = a + altersum cs 192
193-- selfContract a = primContract a a
194selfContract :: FV -> FV
195selfContract xs = fv 0 (altersum xs) FE
196 where
197 altersum FE = 0
198 altersum (FV _ a cs) = a + altersum cs
214 199
215prop_expand_normal_FV (a :: FV) b = testNormalFV (expand a b) 200prop_expand_normal_FV (a :: FV) b = testNormalFV (expand a b)
216prop_contract_normal_FV (a :: FV) b = testNormalFV (contract a b) 201prop_contract_normal_FV (a :: FV) b = testNormalFV (contract a b)
217 202
218prop_diffTestFV1 = diffTest :: D1 FV -> Bool 203prop_monoid_Expand_FV = prop_Monoid (T :: T Expand)
219prop_diffTestFV2 = diffTest :: D2 FV -> Bool 204{-
220prop_diffTestFV3 = diffTest :: D3 FV -> Bool 205--prop_diffTestFV1 = diffTest :: D1 FV -> Bool
221 206--prop_diffTestFV2 = diffTest :: D2 FV -> Bool
222prop_assocTestL_FV = assocTestL :: D3 FV -> Bool 207--prop_diffTestFV3 = diffTest :: D3 FV -> Bool
223prop_assocTestR_FV = assocTestR :: D3 FV -> Bool
224 208
225instance 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 213sIndex :: FV -> Nat -> Bool
229 sIndex (FV n l us) i = i >= n && (i < l || sIndex us (i - l - n)) 214sIndex FE i = False
215sIndex (FV n l us) i = i >= n && (i < l || sIndex us (i - l - n))
230 216
231 sDrop _ FE = FE 217sDrop :: Nat -> FV -> FV
232 sDrop n (FV i j us) 218sDrop _ FE = FE
233 | i + j <= n = sDrop (n - (i + j)) us 219sDrop 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
249usedFVs :: FV -> [Nat]
250usedFVs = 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
256downFV :: Nat -> FV -> Maybe FV 235downFV :: Nat -> FV -> Maybe FV
257downFV i FE = Just FE 236downFV i FE = Just FE
@@ -265,7 +244,7 @@ fO i = FV i 10000 FE
265 244
266mkUp l n = fv 0 l $ fO n 245mkUp 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)
269upFV :: Nat -> Nat -> FV -> FV 248upFV :: Nat -> Nat -> FV -> FV
270upFV l n FE = FE 249upFV l n FE = FE
271upFV l n (FV n' l' us) 250upFV 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
276pattern VarFV i <- FV i _ _ 255--------------------------------------------
277 where VarFV i = FV i 1 FE 256
257type Lens a b = a -> (b, b -> a)
258
259(l1 `lComp` l2) (l1 -> (l2 -> (y, fy), fx)) = (y, fx . fy)
278 260
279incFV :: FV -> FV 261lConst e = (mempty, const e)
280incFV = FV{-ok-} 0 1
281 262
282-- compact u = r where (_, D2 r _) = cDiffT $ D2 (SFV 0 u) (SFV 1 FE) 263lId x = (x, id)
283compact :: FV -> FV 264
284compact xs@(FV 0 _ _) = selfContract xs 265lApp' f (a, b) = b (f a)
285compact xs = fv 1 0 $ selfContract xs 266
267------------
268
269class HasFV a where
270 fvLens :: Lens a FV
271
272appLens fx (fvLens -> (y, fy)) = (y, fx . fy)
273
274up l n = lApp' (upFV l n) . fvLens
275
276down i (fvLens -> (ux, fx)) = fx <$> downFV i ux
277
278usedVar :: HasFV x => Nat -> x -> Bool
279usedVar i x = sIndex (fst $ fvLens x :: FV) i
280
281instance HasFV FV where
282 fvLens = lId
283
284instance (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
291newtype LamFV u = LamFV {getLamFV :: u}
292 deriving (Eq, Show)
293
294instance 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
300data FVCache a b = FVCache !a !b
301 deriving (Eq, Show)
302
303instance Functor (FVCache a) where
304 fmap f (FVCache a b) = FVCache a (f b)
305
306instance HasFV (FVCache FV x) where
307 fvLens (FVCache u x) = (u, \u -> FVCache u x)
308
309pattern CacheFV a <- FVCache u (lApp' (expand u) . fvLens -> a)
310 where CacheFV (fvLens -> x@(ua, fa)) = FVCache ua $ lApp' selfContract x
311
312instance 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
321newtype VarFV = VarFV Nat
322 deriving (Eq, Show)
323
324instance 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
290data SFV = SFV !Nat !FV 330data SFV = SFV !Nat !FV
291 deriving (Eq, Show) 331 deriving (Eq, Show)
292 332
293padSFV (SFV n x) = SFV n $ fv 0 n $ sDrop n x
294
295fromSFV (SFV n u) = sDrop n u
296
297instance PShow SFV where pShow (SFV n x) = pShow n <> pShow x 333instance PShow SFV where pShow (SFV n x) = pShow n <> pShow x
298 334
299instance Arbitrary SFV where 335instance Arbitrary SFV where
@@ -302,22 +338,22 @@ instance Arbitrary SFV where
302instance Monoid SFV where 338instance 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
307prop_monoid_SFV = prop_Monoid (T :: T SFV) 343prop_monoid_SFV = prop_Monoid (T :: T SFV)
308 344
309instance Expandable SFV where 345instance 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
315prop_diffTest1_SFV = diffTest :: D1 SFV -> Bool 352--prop_assocTestL_SFV = assocTestL :: D3 SFV -> Bool
316prop_diffTest2_SFV = diffTest :: D2 SFV -> Bool 353--prop_assocTestR_SFV = assocTestR :: D3 SFV -> Bool
317prop_diffTest3_SFV = diffTest :: D3 SFV -> Bool 354-}
318 355
319prop_assocTestL_SFV = assocTestL :: D3 SFV -> Bool 356-----------------------------------------------------
320prop_assocTestR_SFV = assocTestR :: D3 SFV -> Bool
321 357
322return [] 358return []
323main = $quickCheckAll 359main = $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
12module LamMachine where 15module LamMachine where
13 16
@@ -16,6 +19,8 @@ import Data.Word
16import Data.Int 19import Data.Int
17import Data.Monoid 20import Data.Monoid
18import Data.Maybe 21import Data.Maybe
22--import Data.Foldable (toList)
23import qualified SplayList as F
19import Control.Arrow hiding ((<+>)) 24import Control.Arrow hiding ((<+>))
20import Control.Category hiding ((.), id) 25import Control.Category hiding ((.), id)
21import Control.Monad 26import Control.Monad
@@ -28,20 +33,20 @@ import FreeVars
28--------------------------------------------------------------------- data structures 33--------------------------------------------------------------------- data structures
29 34
30data Lit 35data 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
36data Exp_ 41data 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
47data Op1 = HNFMark | YOp | Round 52data Op1 = HNFMark | YOp | Round
@@ -55,29 +60,54 @@ pattern App a b = Op2 AppOp a b
55pattern Seq a b = Op2 SeqOp a b 60pattern Seq a b = Op2 SeqOp a b
56pattern Int i = Lit (LInt i) 61pattern Int i = Lit (LInt i)
57 62
58infixl 4 `App` 63pattern Var i = Var_ (VarFV i)
64pattern Lam n i = Lam_ n (CacheFV (LamFV i))
65pattern 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))
68pattern Con a b i = Con_ a b (CacheFV i)
69pattern Case a b c = Case_ a (CacheFV (b, c))
70pattern Op2 op a b = Op2_ op (CacheFV (a, b))
59 71
60-- cached and compressed free variables set 72infixl 4 `App`
61data Exp = Exp !FV !Exp_
62 deriving (Eq, Show)
63 73
64data EnvPiece 74data 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
72data DExp 82pattern ELet i x = ELet_ i x
73 = DExpNil -- variable 83pattern EDLet1 i x = EDLet1_ i (LamFV x)
74 | DExpCons_ !FV !EnvPiece !DExp 84pattern ECase op b = ECase_ op (CacheFV b)
75 deriving (Eq, Show) 85pattern EOp2_1 i x = EOp2_1_ i x
86pattern EOp2_2 i x = EOp2_2_ i x
76 87
77data DEnv 88type DEnv = F.SplayList EnvPiece
78 = DEnvNil 89
79 | DEnvCons !EnvPiece !DEnv 90pattern DEnvNil = F.Nil
80 deriving (Eq, Show) 91
92pattern DEnvCons :: EnvPiece -> DEnv -> DEnv
93pattern DEnvCons p e = F.Cons p e
94
95instance F.Measured EnvPiece where
96 type Measure EnvPiece = Nat
97 measure = \case
98 ELet_{} -> 1
99 _ -> 0
100--instance HasSFV DExp where
101
102
103type DExp = DEnv
104
105pattern DExpNil = DEnvNil
106
107pattern DExpCons :: EnvPiece -> DExp -> DExp
108pattern DExpCons p e = F.Snoc e p
109
110infixr 4 `DEnvCons`, `DExpCons`
81 111
82-- state of the machine 112-- state of the machine
83data MSt = MSt !DEnv !Exp 113data MSt = MSt !DEnv !Exp
@@ -89,122 +119,40 @@ type VarInfo = String
89type ConInfo = String 119type ConInfo = String
90type CaseInfo = [(String, [String])] 120type CaseInfo = [(String, [String])]
91 121
92--------------------------------------------------------------------- pattern synonyms 122--------------------------------------------------------------------- instances
93 123
94infixr 4 `DEnvCons`, `DExpCons` 124instance 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
135instance 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
96pattern 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
99pattern 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
107getEnvPiece = \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
115uppS (SFV _ x) (Exp u a) = Exp (expand x u) a
116
117pattern DExpCons :: EnvPiece -> DExp -> DExp
118pattern 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
125getDExpCons (DExpCons_ u x@(EnvPiece (SFV n _) _) b) = (uppEP u x, uppDE u n b)
126
127uppEP u (EnvPiece (SFV n x) y) = EnvPiece (SFV n $ onTail (u `expand`) n x) y
128
129upP i j = uppEP $ mkUp i j
130
131incFV' (SFV n u) = SFV (n + 1) $ incFV u
132
133uppDE :: FV -> Nat -> DExp -> DExp
134uppDE a _ DExpNil = DExpNil
135uppDE a n (DExpCons_ u x y) = DExpCons_ (onTail (expand a) n u) x y
136
137dDown i DExpNil = Just DExpNil
138dDown i (DExpCons_ u a b) = DExpCons_ <$> downFV i u <*> pure a <*> pure b
139
140---------------------------------------------------------------------
141
142pattern Lit i <- Exp _ (Lit_ i)
143 where Lit i = Exp mempty $ Lit_ i
144pattern 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
146pattern 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
148pattern Var' i = Exp (VarFV i) Var_
149pattern Var i = Var' i
150pattern 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
152pattern 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
154pattern 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
157pattern 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
161pattern InHNF a <- (getHNF -> Just a) 145pattern 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
167getHNF x = case x of 151getHNF 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
173delta2 (Exp ua a) (Exp ub b) = (s, Exp ua' a, Exp ub' b)
174 where
175 (s, ua', ub') = delta2' ua ub
176
177delta2' ua ub = (s, primContract s ua, primContract s ub)
178 where
179 s = ua <> ub
180
181deltas [] = (mempty, [])
182deltas [Exp x e] = (x, [Exp (selfContract x) e])
183deltas [Exp ua a, Exp ub b] = (s, [Exp (primContract s ua) a, Exp (primContract s ub) b])
184 where
185 s = ua <> ub
186deltas 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
192upp :: FV -> Exp -> Exp
193upp a (Exp b e) = Exp (expand a b) e
194
195up l n (Exp us x) = Exp (upFV l n us) x
196
197-- free variables set
198--fvs (Exp us _) = usedFVs us
199
200usedVar i (Exp us _) = sIndex us i
201
202usedVar' i DExpNil = False
203usedVar' i (DExpCons_ u _ _) = sIndex u i
204
205down i (Exp us e) = Exp <$> downFV i us <*> pure e
206
207---------------------------
208 156
209initSt :: Exp -> MSt 157initSt :: Exp -> MSt
210initSt e = MSt DEnvNil e 158initSt e = MSt DEnvNil e
@@ -221,30 +169,27 @@ hnf = justResult . initSt
221data StepTag = Begin String | End String | Step String 169data StepTag = Begin String | End String | Step String
222 deriving Show 170 deriving Show
223 171
224type GenSteps e 172focusNotUsed (EDLet1 _ x `DEnvCons` _) = False --not $ usedVar 0 x
225 = e
226 -> (StepTag -> MSt -> e)
227 -> MSt -> e
228
229focusNotUsed (MSt (EDLet1 _ x `DEnvCons` _) _) = not $ usedVar' 0 x
230focusNotUsed _ = True 173focusNotUsed _ = True
231 174
232inHNF :: MSt -> Bool 175inHNF :: MSt -> Bool
233inHNF (MSt _ (InHNF _)) = True 176inHNF (MSt _ (InHNF _)) = True
234inHNF _ = False 177inHNF _ = False
235 178
236steps :: forall e . GenSteps e 179steps :: forall e . e -> (StepTag -> MSt -> e) -> MSt -> e
237steps nostep bind (MSt vs e) = case e of 180steps 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
319instance ViewShow Exp where 265instance 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
447infixl 4 `sApp` 393infixl 4 `sApp`
448 394
449sApp a b = Seq b (App a b) 395sApp a b = Lam "s" (Seq (Var 0) (a `App` Var 0)) `App` b
450 396
451{- 397{-
452accsum acc [] = acc 398accsum acc [] = acc
@@ -477,14 +423,14 @@ inc = Lam "n" $ Op2 Add (Var 0) (Int 1)
477test'' = Lam "f" (Int 4) `App` Int 3 423test'' = Lam "f" (Int 4) `App` Int 3
478 424
479twiceTest n = (Lam "twice" $ (iterate (`App` Var 0) (Var 0) !! n) `App` inc `App` Int 0) `App` twice 425twiceTest n = (Lam "twice" $ (iterate (`App` Var 0) (Var 0) !! n) `App` inc `App` Int 0) `App` twice
480twiceTest2 = twice2 `App` twice2 `App` twice2 `App` twice2 `App` inc `App` Int 0 426twiceTest2 n = (Lam "twice" $ (iterate (`App` Var 0) (Var 0) !! n) `App` inc `App` Int 0) `App` twice2
481 427
482tests 428tests
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
15module SplayList
16 ( SplayList (..)
17 , pattern Cons, pattern Snoc
18 , Measured (..)
19 , split
20 ) where
21
22import Prelude hiding (null)
23import Control.Applicative hiding (empty)
24import Control.Monad
25import Control.Arrow
26
27import Data.Function
28import Data.Data
29import Data.Maybe
30import Data.Monoid
31
32import FreeVars
33
34------------------------------------------------------------------------
35
36data SplayList a
37 = Nil
38 | Singleton a
39 | Append_ !(Measure a) !FV (SplayList a) (SplayList a)
40 deriving (Typeable)
41
42deriving instance (Show a, Show (Measure a)) => Show (SplayList a)
43
44toList = 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
50instance (Measured a, Eq a) => Eq (SplayList a) where (==) = (==) `on` toList
51instance (Measured a, Ord a) => Ord (SplayList a) where compare = compare `on` toList
52
53--------------------------------------------
54
55class (HasFV a, Measure a ~ Nat) => Measured a where
56 type Measure a :: *
57 measure :: a -> Measure a
58
59instance 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
65instance (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
71instance (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
79getAppend (Append_ _ s x@(fvLens -> ~(ux, x')) z@(fvLens -> ~(uz, z')))
80 = Just (x' $ fv 0 (measure z) s `expand` ux, z' $ s `expand` uz)
81getAppend _ = Nothing
82
83pattern Append :: () => Measured a => SplayList a -> SplayList a -> SplayList a
84pattern 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
94pattern Cons a as <- (viewl -> Just (a, ascendL -> as))
95 where Cons a as = Singleton a <> as
96
97viewl Nil = Nothing
98viewl xs = Just $ go [] xs
99 where
100 go xs (Singleton a) = (a, xs)
101 go xs (Append l r) = go (r: xs) l
102
103ascendL [] = Nil
104ascendL (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
114pattern Snoc as a <- (viewr -> Just (a, ascendR -> as))
115 where Snoc as a = as <> Singleton a
116
117viewr Nil = Nothing
118viewr xs = Just $ go [] xs
119 where
120 go xs (Singleton a) = (a, xs)
121 go xs (Append l r) = go (l: xs) r
122
123ascendR [] = Nil
124ascendR (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.
135split :: Measured a => (Nat -> Bool) -> SplayList a -> (SplayList a, SplayList a)
136split _ Nil = (Nil, Nil)
137split 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