summaryrefslogtreecommitdiff
path: root/prototypes
diff options
context:
space:
mode:
authorPéter Diviánszky <divipp@gmail.com>2016-05-16 04:33:58 +0200
committerPéter Diviánszky <divipp@gmail.com>2016-05-16 07:24:34 +0200
commitde20e6bd0dc14e1f1d35a9e3d2ea3516cef6d1c3 (patch)
tree79b285200265a84b01be78340e28a49ada0be696 /prototypes
parent503ff0250240f487d7562ec1c83e4c3251479f0b (diff)
add Ups
Diffstat (limited to 'prototypes')
-rw-r--r--prototypes/LamMachine.hs253
1 files changed, 192 insertions, 61 deletions
diff --git a/prototypes/LamMachine.hs b/prototypes/LamMachine.hs
index 3bfbe104..ccbe7517 100644
--- a/prototypes/LamMachine.hs
+++ b/prototypes/LamMachine.hs
@@ -33,7 +33,8 @@ data Exp_
33 | Op1_ Op1 Exp 33 | Op1_ Op1 Exp
34 | Op2_ Op2 Exp Exp 34 | Op2_ Op2 Exp Exp
35 | Y_ Exp 35 | Y_ Exp
36 deriving (Eq) 36 | Ups_ [Up] Exp
37-- deriving (Eq)
37 38
38data Op1 = Round 39data Op1 = Round
39 deriving (Eq, Show) 40 deriving (Eq, Show)
@@ -52,7 +53,7 @@ data MSt = MSt [(FreeVars, Exp)] -- TODO: use finger tree instead of list
52--------------------------------------------------------------------- toolbox: pretty print 53--------------------------------------------------------------------- toolbox: pretty print
53 54
54instance PShow Exp where 55instance PShow Exp where
55 pShow = \case 56 pShow x = case pushUps x of
56 Var i -> DVar i 57 Var i -> DVar i
57 App a b -> DApp (pShow a) (pShow b) 58 App a b -> DApp (pShow a) (pShow b)
58 Seq a b -> DOp "`seq`" (Infix 1) (pShow a) (pShow b) 59 Seq a b -> DOp "`seq`" (Infix 1) (pShow a) (pShow b)
@@ -87,56 +88,176 @@ instance PShow MSt where
87 88
88--------------------------------------------------------------------- toolbox: free variables 89--------------------------------------------------------------------- toolbox: free variables
89 90
90instance Eq Exp where Exp _ a == Exp _ b = a == b 91--instance Eq Exp where Exp _ a == Exp _ b = a == b
91 92
92instance HasFreeVars Exp where 93instance HasFreeVars Exp where
93 getFreeVars (Exp fv _) = fv 94 getFreeVars (Exp fv _) = fv
94 95
96upss [] e = e
97upss u e = Ups u e
98
99dup2 f (Ups a ax) (Ups b bx) = Ups_ s $ Exp (getFreeVars az <> getFreeVars bz) $ f az bz where
100 (s, [a', b']) = deltaUps [a, b]
101 az = upss a' ax
102 bz = upss b' bx
103dup2 f a b = f a b
104dup1 f (Ups a ax) = Ups_ a $ Exp (getFreeVars ax) $ f ax
105dup1 f x = f x
106
107getUs (Ups x y) = (x, y)
108getUs y = ([], y)
109
110dupCon f [] = f []
111dupCon f [Ups a ax] = Ups_ a $ Exp (getFreeVars ax) $ f [ax]
112dupCon f (unzip . map getUs -> (b, bx)) = Ups_ s $ Exp (foldMap getFreeVars bz) $ f bz where
113 (s, b') = deltaUps b
114 bz = zipWith upss b' bx
115
116dupCase f (getUs -> (a, ax)) (unzip -> (ss, unzip . map getUs -> (b, bx)))
117 = Ups_ s $ Exp (getFreeVars az <> foldMap getFreeVars bz) $ f az $ zip ss bz
118 where
119 (s, a': b') = deltaUps $ a: b
120 az = upss a' ax
121 bz = zipWith upss b' bx
122
123dupLam f (Ups a ax) = Ups_ (ff a) $ Exp (shiftFreeVars (-1) $ getFreeVars ax') $ f ax'
124 where
125 ax' = case a of
126 Up 0 n: _ -> up (Up 0 n) ax
127 _ -> ax
128 ff (Up 0 n: us) = incUp (-1) <$> us
129 ff us = incUp (-1) <$> us
130dupLam f x = f x
131
132
95pattern Int i <- Exp _ (Int_ i) 133pattern Int i <- Exp _ (Int_ i)
96 where Int i = Exp mempty $ Int_ i 134 where Int i = Exp mempty $ Int_ i
97pattern App a b <- Exp _ (App_ a b) 135pattern App a b <- Exp _ (App_ a b)
98 where App a b = Exp (getFreeVars a <> getFreeVars b) $ App_ a b 136 where App a b = Exp (getFreeVars a <> getFreeVars b) $ dup2 App_ a b
99pattern Seq a b <- Exp _ (Seq_ a b) 137pattern Seq a b <- Exp _ (Seq_ a b)
100 where Seq a b = Exp (getFreeVars a <> getFreeVars b) $ Seq_ a b 138 where Seq a b = Exp (getFreeVars a <> getFreeVars b) $ dup2 Seq_ a b
101pattern Op2 op a b <- Exp _ (Op2_ op a b) 139pattern Op2 op a b <- Exp _ (Op2_ op a b)
102 where Op2 op a b = Exp (getFreeVars a <> getFreeVars b) $ Op2_ op a b 140 where Op2 op a b = Exp (getFreeVars a <> getFreeVars b) $ dup2 (Op2_ op) a b
103pattern Op1 op a <- Exp _ (Op1_ op a) 141pattern Op1 op a <- Exp _ (Op1_ op a)
104 where Op1 op a = Exp (getFreeVars a) $ Op1_ op a 142 where Op1 op a = Exp (getFreeVars a) $ dup1 (Op1_ op) a
105pattern Var i <- Exp _ (Var_ i) 143pattern Var i <- Exp _ (Var_ i)
106 where Var i = Exp (freeVar i) $ Var_ i 144 where Var 0 = Exp (freeVar 0) $ Var_ 0
145 Var i = Ups [Up 0 i] $ Exp (freeVar 0) $ Var_ 0
107pattern Lam i <- Exp _ (Lam_ i) 146pattern Lam i <- Exp _ (Lam_ i)
108 where Lam i = Exp (shiftFreeVars (-1) $ getFreeVars i) $ Lam_ i 147 where Lam i = Exp (shiftFreeVars (-1) $ getFreeVars i) $ dupLam Lam_ i
109pattern Y i <- Exp _ (Y_ i) 148pattern Y i <- Exp _ (Y_ i)
110 where Y i = Exp (getFreeVars i) $ Y_ i 149 where Y i = Exp (getFreeVars i) $ dup1 Y_ i
111pattern Con a b i <- Exp _ (Con_ a b i) 150pattern Con a b i <- Exp _ (Con_ a b i)
112 where Con a b i = Exp (foldMap getFreeVars i) $ Con_ a b i 151 where Con a b i = Exp (foldMap getFreeVars i) $ dupCon (Con_ a b) i
113pattern Case a b <- Exp _ (Case_ a b) 152pattern Case a b <- Exp _ (Case_ a b)
114 where Case a b = Exp (getFreeVars a <> foldMap (getFreeVars . snd) b) $ Case_ a b 153 where Case a b = Exp (getFreeVars a <> foldMap (getFreeVars . snd) b) $ dupCase Case_ a b
154pattern Ups op a <- Exp _ (Ups_ op a)
155 where Ups op a = Exp (upsFreeVars op $ getFreeVars a) $ Ups_ op a
115 156
116infixl 4 `App` 157infixl 4 `App`
117 158
118--------------------------------------------------------------------- toolbox: de bruijn index shifting 159--------------------------------------------------------------------- toolbox: de bruijn index shifting
119-- TODO: speedup these with reification 160-- TODO: speedup these with reification
120 161
162rearr (Up l n) = rearrangeFreeVars (RFUp n) l
163
164upsFreeVars xs s = foldr rearr s xs
165
166pushUps (Ups us e) = foldr pushUp e us
167pushUps e = e
168
169showUps us = foldr f [] us where
170 f (Up l n) is = take n [l..] ++ map (n+) is
171
172sectUps' a b = sect (showUps a) (showUps b) -- sectUps 0 a 0 b
173
174sect [] _ = []
175sect _ [] = []
176sect (x:xs) (y:ys)
177 | x == y = x: sect xs ys
178 | x < y = sect xs (y: ys)
179 | x > y = sect (x: xs) ys
180
181{- TODO
182sectUps _ u _ [] = []
183sectUps _ [] _ u = []
184sectUps k us_@(Up l n: us) k' us_'@(Up l' n': us')
185 | k + l + n <= k' + l' = sectUps (k + n) us k' us_'
186 | k' + l' + n' <= k + l = sectUps k us_ (k' + n') us'
187 | otherwise = insertUp (Up l'' n'') $ sectUps (k + n - c) (Up b c: us) (k' + n' - c') (Up b c': us')
188 where
189 l'' = max l l'
190 b = min (l + n) (l' + n')
191 n'' = b - l''
192 c = l + n - b
193 c' = l' + n' - b
194
195diffUps [] u = u
196diffUps [] [] = []
197diffUps (Up l n: us) (Up l' n': us') = insertUp (Up l' (l - l')) $ diffUps us (Up (l + n) (l' + n' - l - n): us')
198-}
199
200diffUps = diffUps' 0
201
202diffUps' n u [] = (+(-n)) <$> u
203diffUps' n (x: xs) (y: ys)
204 | x < y = (x - n): diffUps' n xs (y: ys)
205 | x == y = diffUps' (n+1) xs ys
206
207mkUps = f 0
208 where
209 f i [] = []
210 f i (x: xs) = insertUp (Up (x-i) 1) $ f (i+1) xs
211
212deltaUps us = (mkUps s, [mkUps $ showUps u `diffUps` s | u <- us])
213 where
214 s = foldr1 sect $ showUps <$> us
215
216joinUps a b = foldr insertUp b a
217
218diffUpsTest xs | and $ zipWith (\a b -> s `joinUps` a == b) ys xs = "ok"
219 where
220 (s, ys) = deltaUps xs
221
222diffUpsTest' = diffUpsTest [x,y] --diffUpsTest x y
223 where
224 x = [Up 1 2, Up 3 4, Up 8 2]
225 y = [Up 2 2, Up 5 1, Up 6 2, Up 7 2]
226
227insertUp u@(Up l n) [] = [u]
228insertUp u@(Up l n) us_@(u'@(Up l' n'): us)
229 | l < l' = u: us_
230 | l >= l' && l <= l' + n' = Up l' (n' + n): us
231 | otherwise = u': insertUp (Up (l-n') n) us
232
233addUp (Up _ 0) e = e
234addUp u (Exp s (Ups_ us e)) = Exp (rearr u s) $ Ups_ (insertUp u us) e
235addUp u e = Ups [u] e
236
237pushUp u@(Up i num) e@(Exp s x)
238 | dbGE i s = e
239 | otherwise = Exp (rearrangeFreeVars (RFUp num) i s) $ case x of
240 App_ a b -> App_ (f a) (f b)
241 Seq_ a b -> Seq_ (f a) (f b)
242 Con_ cn s xs -> Con_ cn s (f <$> xs)
243 Case_ s xs -> Case_ (f s) (second f <$> xs)
244 Lam_ e -> Lam_ (up (Up (i+1) num) e)
245 Var_ k | i <= k -> Var_ (k + num)
246 | otherwise -> Var_ k
247 x@Int_{} -> x
248 Y_ a -> Y_ $ f a
249 Op1_ op a -> Op1_ op (f a)
250 Op2_ op a b -> Op2_ op (f a) (f b)
251 where
252 f = up u
253
121data Up = Up !Int{-level-} !Int{-num-} 254data Up = Up !Int{-level-} !Int{-num-}
255 deriving (Eq, Show)
122 256
123up :: Up -> Exp -> Exp 257up :: Up -> Exp -> Exp
124up (Up i num) e = f i e where 258up u@(Up i num) e@(Exp s x)
125 f i e@(Exp s x) 259 | dbGE i s = e
126 | dbGE i s = e 260 | otherwise = addUp u e
127 | otherwise = Exp (rearrangeFreeVars (RFUp num) i s) $ case x of
128 App_ a b -> App_ (f i a) (f i b)
129 Seq_ a b -> Seq_ (f i a) (f i b)
130 Con_ cn s xs -> Con_ cn s (f i <$> xs)
131 Case_ s xs -> Case_ (f i s) (second (f i) <$> xs)
132 Lam_ e -> Lam_ (f (i+1) e)
133 Var_ k | i <= k -> Var_ (k + num)
134 | otherwise -> Var_ k
135 x@Int_{} -> x
136 Y_ a -> Y_ $ f i a
137 Op1_ op a -> Op1_ op (f i a)
138 Op2_ op a b -> Op2_ op (f i a) (f i b)
139
140 261
141ups' a b = ups $ Up a b 262ups' a b = ups $ Up a b
142 263
@@ -160,7 +281,13 @@ down i x = Just $ down_ i x
160 281
161down_ i e@(Exp s x) 282down_ i e@(Exp s x)
162 | dbGE i s = e 283 | dbGE i s = e
163 | otherwise = Exp (delVar i s) $ case x of 284down_ i (Ups us e) = f i us e where
285 f i [] e = down_ i e
286 f i (u@(Up j n): us) e
287 | i < j = addUp (Up (j-1) n) $ f i us e
288 | i >= j + n = addUp u $ f (i-n) us e
289 | otherwise = addUp (Up j $ n-1) $ Ups us e
290down_ i e@(Exp s x) = Exp (delVar i s) $ case x of
164 Var_ j | j > i -> Var_ $ j - 1 291 Var_ j | j > i -> Var_ $ j - 1
165 | otherwise -> Var_ j 292 | otherwise -> Var_ j
166 Lam_ e -> Lam_ $ down_ (i+1) e 293 Lam_ e -> Lam_ $ down_ (i+1) e
@@ -175,7 +302,7 @@ down_ i e@(Exp s x)
175 302
176tryRemoves xs = tryRemoves_ (Var <$> freeVars xs) 303tryRemoves xs = tryRemoves_ (Var <$> freeVars xs)
177tryRemoves_ [] dt = dt 304tryRemoves_ [] dt = dt
178tryRemoves_ (Var i: vs) dt 305tryRemoves_ ((pushUps -> Var i): vs) dt
179 | Just dt' <- tryRemove_ i dt 306 | Just dt' <- tryRemove_ i dt
180 = tryRemoves_ (catMaybes $ down i <$> vs) dt' 307 = tryRemoves_ (catMaybes $ down i <$> vs) dt'
181 | otherwise = tryRemoves_ vs dt 308 | otherwise = tryRemoves_ vs dt
@@ -247,7 +374,7 @@ runMachinePure e = putStr $ unlines $ ppShow t: []
247 374
248-- big step 375-- big step
249step :: MachineMonad m => MSt -> m MSt 376step :: MachineMonad m => MSt -> m MSt
250step dt@(MSt t e vs) = case e of 377step dt@(MSt t e vs) = case pushUps e of
251 378
252 Int{} -> return dt 379 Int{} -> return dt
253 380
@@ -263,39 +390,43 @@ step dt@(MSt t e vs) = case e of
263 f i (x: xs) | simple x = (up (Up 0 lz) x, []): f i xs 390 f i (x: xs) | simple x = (up (Up 0 lz) x, []): f i xs
264 | otherwise = (Var i, [up (Up 0 (lz - i - 1)) x]): f (i+1) xs 391 | otherwise = (Var i, [up (Up 0 (lz - i - 1)) x]): f (i+1) xs
265 392
266 Var i -> lookupHNF "var" (\e (Var i) -> e) i dt 393 Var i -> lookupHNF "var" (\e _ -> e) i dt
267 394
268 Seq Int{} b -> stepMsg "seq" $ MSt t b vs 395 Seq a b -> case pushUps a of
269 Seq a@Lam{} b -> stepMsg "seq" $ tryRemoves (getFreeVars a) $ MSt t b vs 396 Int{} -> stepMsg "seq" $ MSt t b vs
270 Seq a@Con{} b -> stepMsg "seq" $ tryRemoves (getFreeVars a) $ MSt t b vs 397 Lam{} -> stepMsg "seq" $ tryRemoves (getFreeVars a) $ MSt t b vs
271 Seq (Var i) _ -> lookupHNF' "seqvar" (\e (Seq _ b) -> b) i dt 398 Con{} -> stepMsg "seq" $ tryRemoves (getFreeVars a) $ MSt t b vs
272 Seq a b -> stepMsg "seqexp" $ MSt (ups' 1 1 t) (Seq (Var 0) $ up (Up 0 1) b) $ a: vs 399 Var i -> lookupHNF' "seqvar" (\e (pushUps -> Seq _ b) -> b) i dt
400 _ -> stepMsg "seqexp" $ MSt (ups' 1 1 t) (Seq (Var 0) $ up (Up 0 1) b) $ a: vs
273 401
274 -- TODO: handle recursive constants 402 -- TODO: handle recursive constants
275 Y (Lam x) -> stepMsg "Y" $ MSt (ups' 1 1 t) x $ e: vs 403 Y (pushUps -> Lam x) -> stepMsg "Y" $ MSt (ups' 1 1 t) x $ e: vs
276 404
277 App (Lam x) b | usedVar 0 x 405 App a b -> case pushUps a of
278 -> stepMsg "app" $ MSt (ups' 1 1 t) x $ b: vs 406 Lam x | usedVar 0 x
279 App (Lam x) b -> stepMsg "appdel" $ tryRemoves (getFreeVars b) $ MSt t x vs 407 -> stepMsg "app" $ MSt (ups' 1 1 t) x $ b: vs
280 App (Var i) _ -> lookupHNF' "appvar" (\e (App _ y) -> App e y) i dt 408 Lam x -> stepMsg "appdel" $ tryRemoves (getFreeVars b) $ MSt t x vs
281 App a b -> stepMsg "appexp" $ MSt (ups' 1 1 t) (App (Var 0) $ up (Up 0 1) b) $ a: vs 409 Var i -> lookupHNF' "appvar" (\e (pushUps -> App _ y) -> App e y) i dt
282 410 _ -> stepMsg "appexp" $ MSt (ups' 1 1 t) (App (Var 0) $ up (Up 0 1) b) $ a: vs
283 Case (Con cn i es) cs -> stepMsg "case" $ tryRemoves (foldMap (getFreeVars . snd) $ delElem i cs) $ (MSt t (foldl App (snd $ cs !! i) es) vs) 411
284 Case (Var i) _ -> lookupHNF' "casevar" (\e (Case _ cs) -> Case e cs) i dt 412 Case a cs -> case pushUps a of
285 Case v cs -> stepMsg "caseexp" $ MSt (ups' 1 1 t) (Case (Var 0) $ second (up (Up 0 1)) <$> cs) $ v: vs 413 Con cn i es -> stepMsg "case" $ tryRemoves (foldMap (getFreeVars . snd) $ delElem i cs) $ (MSt t (foldl App (snd $ cs !! i) es) vs)
286 414 Var i -> lookupHNF' "casevar" (\e (pushUps -> Case _ cs) -> Case e cs) i dt
287 Op2 op (Int e) (Int f) -> return $ MSt t (int op e f) vs 415 _ -> stepMsg "caseexp" $ MSt (ups' 1 1 t) (Case (Var 0) $ second (up (Up 0 1)) <$> cs) $ a: vs
288 where 416
289 int Add a b = Int $ a + b 417 Op2 op x y -> case (pushUps x, pushUps y) of
290 int Sub a b = Int $ a - b 418 (Int e, Int f) -> return $ MSt t (int op e f) vs
291 int Mod a b = Int $ a `mod` b 419 where
292 int LessEq a b = if a <= b then T else F 420 int Add a b = Int $ a + b
293 int EqInt a b = if a == b then T else F 421 int Sub a b = Int $ a - b
294 Op2 op (Var i) _ -> lookupHNF' "op2-1var" (\e (Op2 op _ y) -> Op2 op e y) i dt 422 int Mod a b = Int $ a `mod` b
295 Op2 op _ (Var i) -> lookupHNF' "op2-2var" (\e (Op2 op x _) -> Op2 op x e) i dt 423 int LessEq a b = if a <= b then T else F
296 Op2 op x@Int{} y -> stepMsg "op2" $ MSt (ups' 1 1 t) (Op2 op x (Var 0)) $ y: vs 424 int EqInt a b = if a == b then T else F
297 Op2 op y x@Int{} -> stepMsg "op2" $ MSt (ups' 1 1 t) (Op2 op (Var 0) x) $ y: vs 425 (Var i, _) -> lookupHNF' "op2-1var" (\e (pushUps -> Op2 op _ y) -> Op2 op e y) i dt
298 Op2 op x y -> stepMsg "op2" $ MSt (ups' 1 2 t) (Op2 op (Var 0) (Var 1)) $ x: y: vs 426 (_, Var i) -> lookupHNF' "op2-2var" (\e (pushUps -> Op2 op x _) -> Op2 op x e) i dt
427 (Int{}, _) -> stepMsg "op2" $ MSt (ups' 1 1 t) (Op2 op x (Var 0)) $ y: vs
428 (_, Int{}) -> stepMsg "op2" $ MSt (ups' 1 1 t) (Op2 op (Var 0) y) $ x: vs
429 _ -> stepMsg "op2" $ MSt (ups' 1 2 t) (Op2 op (Var 0) (Var 1)) $ x: y: vs
299 430
300stepMsg :: MachineMonad m => String -> MSt -> m MSt 431stepMsg :: MachineMonad m => String -> MSt -> m MSt
301stepMsg msg dt = do 432stepMsg msg dt = do