summaryrefslogtreecommitdiff
path: root/prototypes/LamMachine.hs
diff options
context:
space:
mode:
Diffstat (limited to 'prototypes/LamMachine.hs')
-rw-r--r--prototypes/LamMachine.hs277
1 files changed, 86 insertions, 191 deletions
diff --git a/prototypes/LamMachine.hs b/prototypes/LamMachine.hs
index f88062b0..e95960d2 100644
--- a/prototypes/LamMachine.hs
+++ b/prototypes/LamMachine.hs
@@ -11,43 +11,51 @@
11module LamMachine where 11module LamMachine where
12 12
13import Data.List 13import Data.List
14import Data.Word
15import Data.Int
16import Data.Monoid
14import Data.Maybe 17import Data.Maybe
15import Control.Arrow 18import Control.Arrow hiding ((<+>))
16import Control.Category hiding ((.), id) 19import Control.Category hiding ((.), id)
17--import Debug.Trace 20import Control.Monad
21import Debug.Trace
18 22
19import LambdaCube.Compiler.Pretty 23import LambdaCube.Compiler.Pretty
20 24
25import FreeVars
26
21--------------------------------------------------------------------- data structures 27--------------------------------------------------------------------- data structures
22 28
23data Exp_ 29data Exp_
24 = Var_ 30 = Var_
25 | Int_ !Int -- ~ constructor with 0 args 31 | Int_ !Int -- ~ constructor with 0 args
26 | Lam_ Exp 32 | Lam_ !Exp
27 | Con_ String Int [Exp] 33 | Op1_ !Op1 !Exp
28 | Case_ [String]{-for pretty print-} Exp [Exp] -- --> simplify 34 | Con_ String !Int [Exp]
29 | Op1_ !Op1 Exp 35 | Case_ [String]{-for pretty print-} !Exp ![Exp] -- --> simplify
30 | Op2_ !Op2 Exp Exp 36 | Op2_ !Op2 !Exp !Exp
31 37 deriving Eq
32data Op1 = YOp | Round 38
39data Op1 = HNF_ !Int | YOp | Round
33 deriving (Eq, Show) 40 deriving (Eq, Show)
34 41
35data Op2 = AppOp | SeqOp | Add | Sub | Mod | LessEq | EqInt 42data Op2 = AppOp | SeqOp | Add | Sub | Mod | LessEq | EqInt
36 deriving (Eq, Show) 43 deriving (Eq, Show)
37 44
38-- cached and compressed free variables set 45-- cached and compressed free variables set
39type FV = [Int] 46data Exp = Exp_ !FV !Exp_
40 47 deriving Eq
41data Exp = Exp !FV Exp_
42 48
43-- state of the machine 49-- state of the machine
44data MSt = MSt Exp Exp [Exp] 50data MSt = MSt Exp Exp ![Exp]
51 deriving Eq
45 52
46--------------------------------------------------------------------- toolbox: pretty print 53--------------------------------------------------------------------- toolbox: pretty print
47 54
48instance PShow Exp where 55instance PShow Exp where
49 pShow e@(Exp _ x) = case e of -- shUps' u t $ case Exp [] t x of 56 pShow e@(Exp_ fv _) = --(("[" <> pShow fv <> "]") <+>) $
50 Var i -> DVar i 57 case e of
58 Var (Nat i) -> DVar i
51 Let a b -> shLet (pShow a) $ pShow b 59 Let a b -> shLet (pShow a) $ pShow b
52 App a b -> DApp (pShow a) (pShow b) 60 App a b -> DApp (pShow a) (pShow b)
53 Seq a b -> DOp "`seq`" (Infix 1) (pShow a) (pShow b) 61 Seq a b -> DOp "`seq`" (Infix 1) (pShow a) (pShow b)
@@ -55,6 +63,7 @@ instance PShow Exp where
55 Con s i xs -> foldl DApp (text s) $ pShow <$> xs 63 Con s i xs -> foldl DApp (text s) $ pShow <$> xs
56 Int i -> pShow i 64 Int i -> pShow i
57 Y e -> "Y" `DApp` pShow e 65 Y e -> "Y" `DApp` pShow e
66 Op1 (HNF_ i) x -> DGlue (InfixL 40) (onred $ white $ if i == -1 then "this" else pShow i) $ DBrace (pShow x)
58 Op1 o x -> text (show o) `DApp` pShow x 67 Op1 o x -> text (show o) `DApp` pShow x
59 Op2 EqInt x y -> DOp "==" (Infix 4) (pShow x) (pShow y) 68 Op2 EqInt x y -> DOp "==" (Infix 4) (pShow x) (pShow y)
60 Op2 Add x y -> DOp "+" (InfixL 6) (pShow x) (pShow y) 69 Op2 Add x y -> DOp "+" (InfixL 6) (pShow x) (pShow y)
@@ -63,8 +72,7 @@ instance PShow Exp where
63 $ foldr1 DSemi [DArr_ "->" (text a) (pShow b) | (a, b) <- zip cn xs] 72 $ foldr1 DSemi [DArr_ "->" (text a) (pShow b) | (a, b) <- zip cn xs]
64 73
65instance PShow MSt where 74instance PShow MSt where
66 pShow (MSt as b bs) = case foldl (flip (:)) (DBrace (pShow b): [pShow x | x <- bs]) $ [pShow as] of 75 pShow (MSt as b bs) = pShow $ foldl (flip Let) (Let (HNF (-1) b) as) bs
67 x: xs -> foldl (flip shLet) x xs
68 76
69shUps a b = DPreOp (-20) (SimpleAtom $ show a) b 77shUps a b = DPreOp (-20) (SimpleAtom $ show a) b
70shUps' a x b = DPreOp (-20) (SimpleAtom $ show a ++ show x) b 78shUps' a x b = DPreOp (-20) (SimpleAtom $ show a ++ show x) b
@@ -84,48 +92,29 @@ showLet x y = DLet' x y
84 92
85--------------------------------------------------------------------- pattern synonyms 93--------------------------------------------------------------------- pattern synonyms
86 94
87pattern Int i <- Exp _ (Int_ i) 95pattern Int i <- Exp_ _ (Int_ i)
88 where Int i = Exp [0] $ Int_ i 96 where Int i = Exp_ mempty $ Int_ i
89pattern Op2 op a b <- Exp u (Op2_ op (upp u -> a) (upp u -> b)) 97pattern Op2 op a b <- Exp_ u (Op2_ op (upp u -> a) (upp u -> b))
90 where Op2 op a b = Exp s $ Op2_ op az bz where (s, az, bz) = delta2 a b 98 where Op2 op a b = Exp_ s $ Op2_ op az bz where (s, az, bz) = delta2 a b
91pattern Op1 op a <- Exp u (Op1_ op (upp u -> a)) 99pattern Op1 op a <- Exp_ u (Op1_ op (upp u -> a))
92 where Op1 op a = dup1 (Op1_ op) a 100 where Op1 op (Exp_ ab x) = Exp_ ab $ Op1_ op $ Exp_ (delUnused ab) x
93pattern Var i <- Exp (varIndex -> i) Var_ 101pattern Var' i = Exp_ (VarFV i) Var_
94 where Var 0 = Exp [1] Var_ 102pattern Var i = Var' i
95 Var i = Exp [0, i, i+1] Var_ 103pattern Lam i <- Exp_ u (Lam_ (upp (incFV u) -> i))
96pattern Lam i <- Exp u (Lam_ (upp ((+1) <$> u) -> i)) 104 where Lam (Exp_ vs ax) = Exp_ (del1 vs) $ Lam_ $ Exp_ (compact vs) ax
97 where Lam i = dupLam i 105pattern Con a b i <- Exp_ u (Con_ a b (map (upp u) -> i))
98pattern Con a b i <- Exp u (Con_ a b (map (upp u) -> i)) 106 where Con a b x = Exp_ s $ Con_ a b bz where (s, bz) = deltas x
99 where Con a b [] = Exp [0] $ Con_ a b [] 107pattern Case a b c <- Exp_ u (Case_ a (upp u -> b) (map (upp u) -> c))
100 Con a b [x] = dup1 (Con_ a b . (:[])) x 108 where Case cn a b = Exp_ s $ Case_ cn az bz where (s, az: bz) = deltas $ a: b
101 Con a b [x, y] = Exp s $ Con_ a b [xz, yz] where (s, xz, yz) = delta2 x y
102 Con a b x = Exp s $ Con_ a b bz where (s, bz) = deltas x
103pattern Case a b c <- Exp u (Case_ a (upp u -> b) (map (upp u) -> c))
104 where Case cn a b = Exp s $ Case_ cn az bz where (s, az: bz) = deltas $ a: b
105 109
106pattern Let i x = App (Lam x) i 110pattern Let i x = App (Lam x) i
107pattern Y a = Op1 YOp a 111pattern Y a = Op1 YOp a
112pattern HNF i a = Op1 (HNF_ i) a
108pattern App a b = Op2 AppOp a b 113pattern App a b = Op2 AppOp a b
109pattern Seq a b = Op2 SeqOp a b 114pattern Seq a b = Op2 SeqOp a b
110 115
111infixl 4 `App` 116infixl 4 `App`
112 117
113varIndex (_: i: _) = i
114varIndex _ = 0
115
116dupLam (Exp vs ax) = Exp (f vs) $ Lam_ $ Exp (g vs) ax
117 where
118 f (0: nus) = 0 .: map (+(-1)) nus
119 f us = map (+(-1)) us
120
121 g xs@(0: _) = [0, 1, altersum xs + 1]
122 g xs = [altersum xs]
123
124dup1 f (Exp ab x) = Exp ab $ f $ Exp [altersum ab] x
125
126altersum [x] = x
127altersum (a: b: cs) = a - b + altersum cs
128
129initSt :: Exp -> MSt 118initSt :: Exp -> MSt
130initSt e = MSt (Var 0) e [] 119initSt e = MSt (Var 0) e []
131 120
@@ -136,98 +125,50 @@ size (MSt xs _ ys) = length (getLets xs) + length ys
136 getLets (Let x y) = x: getLets y 125 getLets (Let x y) = x: getLets y
137 getLets x = [x] 126 getLets x = [x]
138 127
139--------------------------------------------------------------------- toolbox: de bruijn index shifting 128delta2 (Exp_ ua a) (Exp_ ub b) = (s, Exp_ (delFV ua s) a, Exp_ (delFV ub s) b)
140
141upp [k] ys = ys
142upp (x: y: xs) ys = upp xs (up x (y - x) ys)
143
144up i 0 e = e
145up i num (Exp us x) = Exp (f i (i + num) us) x
146 where 129 where
147 f l n [s] 130 s = ua <> ub
148 | l >= s = [s]
149 | otherwise = [l, n, s+n-l]
150 f l n us_@(l': n': us)
151 | l < l' = l : n: map (+(n-l)) us_
152 | l <= n' = l': n' + n - l: map (+(n-l)) us
153 | otherwise = l': n': f l n us
154 131
155-- free variables set 132deltas [] = (mempty, [])
156fvs (Exp us _) = gen 0 us where 133deltas [Exp_ x e] = (x, [Exp_ (delUnused x) e])
157 gen i (a: xs) = [i..a-1] ++ gen' xs 134deltas [Exp_ ua a, Exp_ ub b] = (s, [Exp_ (delFV ua s) a, Exp_ (delFV ub s) b])
158 gen' [] = []
159 gen' (a: xs) = gen a xs
160
161(.:) :: Int -> [Int] -> [Int]
162a .: (x: y: xs) | a == x = y: xs
163a .: xs = a: xs
164
165usedVar i (Exp us _) = f us where
166 f [fv] = i < fv
167 f (l: n: us) = i < l || i >= n && f us
168
169down i (Exp us e) = Exp <$> f us <*> pure e where
170 f [fv]
171 | i < fv = Nothing
172 | otherwise = Just [fv]
173 f vs@(j: vs'@(n: us))
174 | i < j = Nothing
175 | i < n = Just $ j .: map (+(-1)) vs'
176 | otherwise = (j:) . (n .:) <$> f us
177
178delta2 (Exp (add0 -> ua) a) (Exp (add0 -> ub) b) = (add0 s, Exp (dLadders 0 ua s) a, Exp (dLadders 0 ub s) b)
179 where 135 where
180 s = iLadders ua ub 136 s = ua <> ub
181 137deltas es = (s, [Exp_ (delFV u s) e | (u, Exp_ _ e) <- zip xs es])
182deltas [] = ([0], [])
183deltas es = (add0 s, [Exp (dLadders 0 u s) e | (u, Exp _ e) <- zip xs es])
184 where 138 where
185 xs = [add0 ue | Exp ue _ <- es] 139 xs = [ue | Exp_ ue _ <- es]
186 140
187 s = foldr1 iLadders xs 141 s = mconcat xs
188 142
189iLadders :: [Int] -> [Int] -> [Int] 143upp :: FV -> Exp -> Exp
190iLadders x [] = x 144upp a (Exp_ b e) = Exp_ (compFV a b) e
191iLadders [] x = x
192iLadders x@(a: b: us) x'@(a': b': us')
193 | b <= a' = addL a b $ iLadders us x'
194 | b' <= a = addL a' b' $ iLadders x us'
195 | otherwise = addL (min a a') c $ iLadders (addL c b us) (addL c b' us')
196 where
197 c = min b b'
198 145
199addL a b cs | a == b = cs 146up l n (Exp_ us x) = Exp_ (upFV l n us) x
200addL a b (c: cs) | b == c = a: cs 147
201addL a b cs = a: b: cs 148-- free variables set
149fvs (Exp_ us _) = usedFVs us
202 150
203add0 [] = [0] 151usedVar i (Exp_ us _) = usedFV i us
204add0 (0: cs) = cs
205add0 cs = 0: cs
206 152
207dLadders :: Int -> [Int] -> [Int] -> [Int] 153down i (Exp_ us e) = Exp_ <$> downFV i us <*> pure e
208dLadders s [] x = [s]
209dLadders s x@(a: b: us) x'@(a': b': us')
210 | b' <= a = addL s (s + b' - a') $ dLadders (s + b' - a') x us'
211 | a' < a = addL s (s + a - a') $ dLadders (s + a - a') x (addL a b' us')
212 | a' == a = dLadders (s + b - a) us (addL b b' us')
213 154
214--------------------------- 155---------------------------
215 156
216tryRemoves xs = tryRemoves_ (Var <$> xs) 157tryRemoves xs = tryRemoves_ (Var' <$> xs)
217 158
218tryRemoves_ [] dt = dt 159tryRemoves_ [] dt = dt
219tryRemoves_ (Var i: vs) dt = maybe (tryRemoves_ vs dt) (\(is, st) -> tryRemoves_ (is ++ catMaybes (down i <$> vs)) st) $ tryRemove_ i dt 160tryRemoves_ (Var' i: vs) dt = maybe (tryRemoves_ vs dt) (\(is, st) -> tryRemoves_ (is ++ catMaybes (down i <$> vs)) st) $ tryRemove_ i dt
220 where 161 where
221 tryRemove_ i (MSt xs e es) = (\a b (is, c) -> (is, MSt a b c)) <$> down (i+1) xs <*> down i e <*> downDown i es 162 tryRemove_ i (MSt xs e es) = (\a b (is, c) -> (is, MSt a b c)) <$> down (i+1) xs <*> down i e <*> downDown i es
222 163
223 downDown i [] = Just ([], []) 164 downDown i [] = Just ([], [])
224 downDown 0 (x: xs) = Just (Var <$> fvs x, xs) 165 downDown 0 (x: xs) = Just (Var' <$> fvs x, xs)
225 downDown i (x: xs) = (\x (is, xs) -> (up 0 1 <$> is, x: xs)) <$> down (i-1) x <*> downDown (i-1) xs 166 downDown i (x: xs) = (\x (is, xs) -> (up 0 1 <$> is, x: xs)) <$> down (i-1) x <*> downDown (i-1) xs
226 167
227----------------------------------------------------------- machine code begins here 168----------------------------------------------------------- machine code begins here
228 169
229justResult :: MSt -> MSt 170justResult :: MSt -> MSt
230justResult = steps id (const ($)) (const (.)) 171justResult = steps 0 id (const ($)) (const (.))
231 172
232hnf = justResult . initSt 173hnf = justResult . initSt
233 174
@@ -242,23 +183,23 @@ type GenSteps e
242 183
243type StepTag = String 184type StepTag = String
244 185
245steps :: forall e . GenSteps e 186steps :: forall e . Int -> GenSteps e
246steps nostep {-ready-} bind cont dt@(MSt t e vs) = case e of 187steps lev nostep {-ready-} bind cont dt@(MSt t e vs) = case e of
247 188
248 Int{} -> nostep dt --ready "hnf int" 189 Int{} -> nostep dt --ready "hnf int"
249 Lam{} -> nostep dt --ready "hnf lam" 190 Lam{} -> nostep dt --ready "hnf lam"
250 191
251 Con cn i xs 192 Con cn i xs
252 | lz /= 0 -> step "copy con" $ MSt (up 1 lz t) (Con cn i xs') $ zs ++ vs -- share complex constructor arguments 193 | lz > 0 -> step "copy con" $ MSt (up 1 lz t) (Con cn i xs') $ zs ++ vs -- share complex constructor arguments
253 | otherwise -> nostep dt --ready "hnf con" 194 | otherwise -> nostep dt --ready "hnf con"
254 where 195 where
255 lz = length zs 196 lz = Nat $ length zs
256 (xs', concat -> zs) = unzip $ f 0 xs 197 (xs', concat -> zs) = unzip $ f 0 xs
257 f i [] = [] 198 f i [] = []
258 f i (x: xs) | simple x = (up 0 lz x, []): f i xs 199 f i (x: xs) | simple x = (up 0 lz x, []): f i xs
259 | otherwise = (Var i, [up 0 (lz - i - 1) x]): f (i+1) xs 200 | otherwise = (Var' i, [up 0 (lz - i - 1) x]): f (i+1) xs
260 201
261 Var i -> lookupHNF_ rec "var" const i dt 202 Var i -> lookupHNF_ nostep "var" const i dt
262 203
263 Seq a b -> case a of 204 Seq a b -> case a of
264 Int{} -> step "seq" $ MSt t b vs 205 Int{} -> step "seq" $ MSt t b vs
@@ -297,27 +238,29 @@ steps nostep {-ready-} bind cont dt@(MSt t e vs) = case e of
297 (_, Int{}) -> step "op2" $ MSt (up 1 1 t) (Op2 op (Var 0) y) $ x: vs 238 (_, Int{}) -> step "op2" $ MSt (up 1 1 t) (Op2 op (Var 0) y) $ x: vs
298 _ -> step "op2" $ MSt (up 1 2 t) (Op2 op (Var 0) (Var 1)) $ x: y: vs 239 _ -> step "op2" $ MSt (up 1 2 t) (Op2 op (Var 0) (Var 1)) $ x: y: vs
299 where 240 where
300 rec = steps nostep bind cont 241 rec i = steps i nostep bind cont
301 242
302 step :: StepTag -> MSt -> e 243 step :: StepTag -> MSt -> e
303 step t = bind t rec 244 step t = bind t (rec lev)
304 245
305 hnf :: (MSt -> e) -> MSt -> e 246 hnf :: (MSt -> e) -> MSt -> e
306 hnf f = cont "hnf" f rec 247 hnf f = cont "hnf" f (rec $ 1 + lev)
248
249 hnfTag (MSt a b c) = MSt a (HNF lev b) c
307 250
308 -- lookup var in head normal form 251 -- lookup var in head normal form
309 lookupHNF_ :: (MSt -> e) -> StepTag -> (Exp -> Exp -> Exp) -> Int -> MSt -> e 252 lookupHNF_ :: (MSt -> e) -> StepTag -> (Exp -> Exp -> Exp) -> Nat -> MSt -> e
310 lookupHNF_ end msg f i dt = bind msg (hnf shiftLookup) $ iterate shiftL dt !! (i+1) 253 lookupHNF_ end msg f i@(Nat i') dt = bind msg (hnf shiftLookup) $ iterate shiftL (hnfTag dt) !! (i'+1)
311 where 254 where
312 shiftLookup dt@(MSt _ e _) 255 shiftLookup dt@(MSt _ e _)
313 = case iterate shiftR dt !! (i+1) of 256 = case iterate shiftR dt !! (i'+1) of
314 MSt xs z es -> bind "shiftR" (tryRemove i) $ MSt xs (f (up 0 (i+1) e) z) es 257 MSt xs (HNF lev z) es -> bind "shiftR" (tryRemove i) $ MSt xs (f (up 0 (i+1) e) z) es
315 258
316 tryRemove i st = {-maybe (end st)-} (bind "remove" end) $ tryRemoves [i] st 259 tryRemove i st = {-maybe (end st)-} (bind "remove" end) $ tryRemoves [i] st
317 260
318 -- lookup & step 261 -- lookup & step
319 lookupHNF' :: StepTag -> (Exp -> Exp -> Exp) -> Int -> MSt -> e 262 lookupHNF' :: StepTag -> (Exp -> Exp -> Exp) -> Nat -> MSt -> e
320 lookupHNF' msg f i dt = lookupHNF_ rec msg f i dt 263 lookupHNF' msg f i dt = lookupHNF_ (rec lev) msg f i dt
321 264
322 shiftL (MSt xs x (e: es)) = MSt (Let x xs) e es 265 shiftL (MSt xs x (e: es)) = MSt (Let x xs) e es
323 266
@@ -348,9 +291,9 @@ if_ b t f = caseBool b f t
348 291
349not_ x = caseBool x T F 292not_ x = caseBool x T F
350 293
351test = runMachinePure (id_ `App` id_ `App` id_ `App` id_ `App` Con "()" 0 []) 294test = hnf (id_ `App` id_ `App` id_ `App` id_ `App` Int 13)
352 295
353test' = runMachinePure (id_ `App` (id_ `App` Con "()" 0 [])) 296test' = hnf (id_ `App` (id_ `App` Int 14))
354 297
355foldr_ f e = Y $ Lam $ Lam $ caseList (Var 0) (up 0 2 e) (Lam $ Lam $ up 0 4 f `App` Var 1 `App` (Var 3 `App` Var 0)) 298foldr_ f e = Y $ Lam $ Lam $ caseList (Var 0) (up 0 2 e) (Lam $ Lam $ up 0 4 f `App` Var 1 `App` (Var 3 `App` Var 0))
356 299
@@ -401,60 +344,12 @@ primes = 2:3: filter (\n -> and $ map (\p -> n `mod` p /= 0) (takeWhile (\x -> x
401main = primes !! 3000 344main = primes !! 3000
402-} 345-}
403 346
347tests
348 = test == hnf (Int 13)
349 && test' == hnf (Int 14)
350 && hnf (Lam (Int 4) `App` Int 3) == hnf (Int 4)
351 && hnf (t' 10) == hnf (Int 55)
352 && hnf (t'' 10) == hnf (Int 55)
404 353
405 354
406-------------------------------------------------------------
407
408{- alternative presentation
409
410sect [] xs = xs
411sect xs [] = xs
412sect (x:xs) (y:ys) = (x || y): sect xs ys
413
414diffUps a b = diffUps' 0 (back a) (back b)
415
416diffUps' n u [] = (+(-n)) <$> u
417diffUps' n [] _ = []
418diffUps' n (x: xs) (y: ys)
419 | x < y = (x - n): diffUps' n xs (y: ys)
420 | x == y = diffUps' (n+1) xs ys
421
422back = map fst . filter (not . snd) . zip [0..]
423
424mkUps = f 0
425 where
426 f i [] = []
427 f i (x: xs) = insertUp (Up (x-i) 1) $ f (i+1) xs
428
429showUps us n = foldr f (replicate n True) us where
430 f (Up l n) is = take l is ++ replicate n False ++ drop l is
431
432deltaUps_ (map $ uncurry showUps -> us) = (mkUps $ back s, [mkUps $ u `diffUps` s | u <- us])
433 where
434 s = foldr1 sect $ us
435
436joinUps a b = foldr insertUp b a
437
438diffUpsTest xs
439 | and $ zipWith (\a (b, _) -> s `joinUps` a == b) ys xs = show (s, ys)
440 | otherwise = error $ unlines $ map (show . toLadder) xs ++ "----": map show xs ++ "-----": show s: show s_: "-----": map show ys ++ "------": map (show . joinUps s) ys
441 where
442 (s, ys) = deltaUps_ xs
443 s_ = foldr1 iLadders $ toLadder <$> xs
444
445diffUpsTest' = diffUpsTest [x,y] --diffUpsTest x y
446
447--x = ([Up 8 2], 200)
448--y = ([], 28)
449x = ([Up 1 2, Up 3 4, Up 8 2], 200)
450y = ([Up 2 2, Up 5 1, Up 6 2, Up 7 2], 28)
451
452-- TODO: remove
453insertUp (Up l 0) us = us
454insertUp u [] = [u]
455insertUp u@(Up l n) us_@(u'@(Up l' n'): us)
456 | l < l' = u: us_
457 | l >= l' && l <= l' + n' = Up l' (n' + n): us
458 | otherwise = u': insertUp (Up (l-n') n) us
459-}
460 355