diff options
author | Péter Diviánszky <divipp@gmail.com> | 2016-05-24 19:20:42 +0200 |
---|---|---|
committer | Péter Diviánszky <divipp@gmail.com> | 2016-05-24 19:20:42 +0200 |
commit | ac41cbea6ca348e662cf8996d2b7127066825af5 (patch) | |
tree | 60c8455bc6a83c88a2f1fd8ebc54db3f849c4037 | |
parent | 2fcc441833425f2e013c43fbfd90e0ef2cb67422 (diff) |
refactoring: first part of env implementation
-rw-r--r-- | prototypes/Inspector.hs | 2 | ||||
-rw-r--r-- | prototypes/LamMachine.hs | 121 |
2 files changed, 80 insertions, 43 deletions
diff --git a/prototypes/Inspector.hs b/prototypes/Inspector.hs index 663594f8..b725294d 100644 --- a/prototypes/Inspector.hs +++ b/prototypes/Inspector.hs | |||
@@ -92,7 +92,7 @@ main = do | |||
92 | (LeftArrow, st@(_, _:_:_)) -> cycle' $ iterate goLeft st !! 100 | 92 | (LeftArrow, st@(_, _:_:_)) -> cycle' $ iterate goLeft st !! 100 |
93 | (RightArrow, st@(_:_, _)) -> cycle' $ iterate goRight st !! 100 | 93 | (RightArrow, st@(_:_, _)) -> cycle' $ iterate goRight st !! 100 |
94 | (IntArg n, _) -> cycle' ([], stepList $ t' n) | 94 | (IntArg n, _) -> cycle' ([], stepList $ t' n) |
95 | (ProgramChange, _) -> cycle' ([], stepList $ t'' 0) | 95 | (ProgramChange, _) -> cycle' ([], stepList $ test) --t'' 0) |
96 | _ -> cycle False st | 96 | _ -> cycle False st |
97 | 97 | ||
98 | cycle' st@(h, (_, x): _) = do | 98 | cycle' st@(h, (_, x): _) = do |
diff --git a/prototypes/LamMachine.hs b/prototypes/LamMachine.hs index e95960d2..cbb0d479 100644 --- a/prototypes/LamMachine.hs +++ b/prototypes/LamMachine.hs | |||
@@ -47,7 +47,13 @@ data Exp = Exp_ !FV !Exp_ | |||
47 | deriving Eq | 47 | deriving Eq |
48 | 48 | ||
49 | -- state of the machine | 49 | -- state of the machine |
50 | data MSt = MSt Exp Exp ![Exp] | 50 | data MSt = MSt Exp ![Env] |
51 | deriving Eq | ||
52 | |||
53 | data Env | ||
54 | = ELet Exp | ||
55 | | ELet1 Exp | ||
56 | | EApp1 !Int Exp | ||
51 | deriving Eq | 57 | deriving Eq |
52 | 58 | ||
53 | --------------------------------------------------------------------- toolbox: pretty print | 59 | --------------------------------------------------------------------- toolbox: pretty print |
@@ -72,7 +78,12 @@ instance PShow Exp where | |||
72 | $ foldr1 DSemi [DArr_ "->" (text a) (pShow b) | (a, b) <- zip cn xs] | 78 | $ foldr1 DSemi [DArr_ "->" (text a) (pShow b) | (a, b) <- zip cn xs] |
73 | 79 | ||
74 | instance PShow MSt where | 80 | instance PShow MSt where |
75 | pShow (MSt as b bs) = pShow $ foldl (flip Let) (Let (HNF (-1) b) as) bs | 81 | pShow (MSt b bs) = pShow $ foldl f (HNF (-1) b) bs |
82 | where | ||
83 | f y = \case | ||
84 | ELet x -> Let x y | ||
85 | ELet1 x -> Let y x | ||
86 | EApp1 i x -> HNF i $ App y x | ||
76 | 87 | ||
77 | shUps a b = DPreOp (-20) (SimpleAtom $ show a) b | 88 | shUps a b = DPreOp (-20) (SimpleAtom $ show a) b |
78 | shUps' a x b = DPreOp (-20) (SimpleAtom $ show a ++ show x) b | 89 | shUps' a x b = DPreOp (-20) (SimpleAtom $ show a ++ show x) b |
@@ -116,14 +127,11 @@ pattern Seq a b = Op2 SeqOp a b | |||
116 | infixl 4 `App` | 127 | infixl 4 `App` |
117 | 128 | ||
118 | initSt :: Exp -> MSt | 129 | initSt :: Exp -> MSt |
119 | initSt e = MSt (Var 0) e [] | 130 | initSt e = MSt e [] |
120 | 131 | ||
121 | -- for statistics | 132 | -- for statistics |
122 | size :: MSt -> Int | 133 | size :: MSt -> Int |
123 | size (MSt xs _ ys) = length (getLets xs) + length ys | 134 | size (MSt _ ys) = length ys |
124 | where | ||
125 | getLets (Let x y) = x: getLets y | ||
126 | getLets x = [x] | ||
127 | 135 | ||
128 | delta2 (Exp_ ua a) (Exp_ ub b) = (s, Exp_ (delFV ua s) a, Exp_ (delFV ub s) b) | 136 | delta2 (Exp_ ua a) (Exp_ ub b) = (s, Exp_ (delFV ua s) a, Exp_ (delFV ub s) b) |
129 | where | 137 | where |
@@ -159,11 +167,13 @@ tryRemoves xs = tryRemoves_ (Var' <$> xs) | |||
159 | tryRemoves_ [] dt = dt | 167 | tryRemoves_ [] dt = dt |
160 | tryRemoves_ (Var' i: vs) dt = maybe (tryRemoves_ vs dt) (\(is, st) -> tryRemoves_ (is ++ catMaybes (down i <$> vs)) st) $ tryRemove_ i dt | 168 | tryRemoves_ (Var' i: vs) dt = maybe (tryRemoves_ vs dt) (\(is, st) -> tryRemoves_ (is ++ catMaybes (down i <$> vs)) st) $ tryRemove_ i dt |
161 | where | 169 | where |
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 | 170 | tryRemove_ i (MSt e es) = (\b (is, c) -> (is, MSt b c)) <$> down i e <*> downDown i es |
163 | 171 | ||
164 | downDown i [] = Just ([], []) | 172 | downDown i [] = Just ([], []) |
165 | downDown 0 (x: xs) = Just (Var' <$> fvs x, xs) | 173 | downDown 0 (ELet x: xs) = Just (Var' <$> fvs x, xs) |
166 | downDown i (x: xs) = (\x (is, xs) -> (up 0 1 <$> is, x: xs)) <$> down (i-1) x <*> downDown (i-1) xs | 174 | downDown i (ELet x: xs) = (\x (is, xs) -> (up 0 1 <$> is, ELet x: xs)) <$> down (i-1) x <*> downDown (i-1) xs |
175 | downDown i (ELet1 x: xs) = (\x (is, xs) -> (is, ELet1 x: xs)) <$> down (i+1) x <*> downDown i xs | ||
176 | downDown i (EApp1 j x: xs) = (\x (is, xs) -> (is, EApp1 j x: xs)) <$> down i x <*> downDown i xs | ||
167 | 177 | ||
168 | ----------------------------------------------------------- machine code begins here | 178 | ----------------------------------------------------------- machine code begins here |
169 | 179 | ||
@@ -184,13 +194,13 @@ type GenSteps e | |||
184 | type StepTag = String | 194 | type StepTag = String |
185 | 195 | ||
186 | steps :: forall e . Int -> GenSteps e | 196 | steps :: forall e . Int -> GenSteps e |
187 | steps lev nostep {-ready-} bind cont dt@(MSt t e vs) = case e of | 197 | steps lev nostep {-ready-} bind cont dt@(MSt e vs) = case e of |
188 | 198 | ||
189 | Int{} -> nostep dt --ready "hnf int" | 199 | Int{} -> nostep dt --ready "hnf int" |
190 | Lam{} -> nostep dt --ready "hnf lam" | 200 | Lam{} -> nostep dt --ready "hnf lam" |
191 | 201 | ||
192 | Con cn i xs | 202 | Con cn i xs |
193 | | lz > 0 -> step "copy con" $ MSt (up 1 lz t) (Con cn i xs') $ zs ++ vs -- share complex constructor arguments | 203 | | lz > 0 -> step "copy con" $ MSt (Con cn i xs') $ (ELet <$> zs) ++ vs -- share complex constructor arguments |
194 | | otherwise -> nostep dt --ready "hnf con" | 204 | | otherwise -> nostep dt --ready "hnf con" |
195 | where | 205 | where |
196 | lz = Nat $ length zs | 206 | lz = Nat $ length zs |
@@ -202,30 +212,35 @@ steps lev nostep {-ready-} bind cont dt@(MSt t e vs) = case e of | |||
202 | Var i -> lookupHNF_ nostep "var" const i dt | 212 | Var i -> lookupHNF_ nostep "var" const i dt |
203 | 213 | ||
204 | Seq a b -> case a of | 214 | Seq a b -> case a of |
205 | Int{} -> step "seq" $ MSt t b vs | 215 | Int{} -> step "seq" $ MSt b vs |
206 | Lam{} -> step "seq" $ tryRemoves (fvs a) $ MSt t b vs | 216 | Lam{} -> step "seq" $ tryRemoves (fvs a) $ MSt b vs |
207 | Con{} -> step "seq" $ tryRemoves (fvs a) $ MSt t b vs | 217 | Con{} -> step "seq" $ tryRemoves (fvs a) $ MSt b vs |
208 | Var i -> lookupHNF' "seqvar" (\e (Seq _ b) -> b) i dt | 218 | Var i -> lookupHNF' "seqvar" (\e (Seq _ b) -> b) i dt |
209 | _ -> step "seqexp" $ MSt (up 1 1 t) (Seq (Var 0) $ up 0 1 b) $ a: vs | 219 | _ -> step "seqexp" $ MSt (Seq (Var 0) $ up 0 1 b) $ ELet a: vs |
210 | 220 | ||
211 | -- TODO: handle recursive constants | 221 | -- TODO: handle recursive constants |
212 | Y (Lam x) -> step "Y" $ MSt (up 1 1 t) x $ e: vs | 222 | Y (Lam x) -> step "Y" $ MSt x $ ELet e: vs |
213 | 223 | ||
214 | App a b -> case a of | 224 | App a b -> case a of |
215 | Lam x | usedVar 0 x | 225 | Lam x | usedVar 0 x |
216 | -> step "app" $ MSt (up 1 1 t) x $ b: vs | 226 | -> step "app" $ MSt x $ ELet b: vs |
217 | Lam x -> step "appdel" $ tryRemoves (fvs b) $ MSt t x vs | 227 | Lam x -> step "appdel" $ tryRemoves (fvs b) $ MSt x vs |
218 | Var i -> lookupHNF' "appvar" (\e (App _ y) -> App e y) i dt | 228 | -- Var i -> lookupHNF' "appvar" (\e (App _ y) -> App e y) i dt |
219 | _ -> step "appexp" $ MSt (up 1 1 t) (App (Var 0) $ up 0 1 b) $ a: vs | 229 | _ -> bind "app1" (hnf "app1 hnf" (step "appexp" . focus)) $ MSt a $ EApp1 lev b: vs |
220 | -- _ -> bind "appexp" (lookupHNF' "app1var" (\e (App _ y) -> App e y) 0) $ MSt (up 1 1 t) (App (Var 0) $ up 0 1 b) $ a: vs | 230 | where |
231 | focus (MSt b xs) = MSt (App b c) xs' | ||
232 | where | ||
233 | (c, xs') = f xs | ||
234 | f (EApp1 _ c: xs) = (c, xs) | ||
235 | f (ELet x: (f -> (c, xs))) = (up 0 1 c, ELet x: xs) | ||
221 | 236 | ||
222 | Case cn a cs -> case a of | 237 | Case cn a cs -> case a of |
223 | Con cn i es -> step "case" $ tryRemoves (nub $ foldMap fvs $ delElem i cs) $ (MSt t (foldl App (cs !! i) es) vs) | 238 | Con cn i es -> step "case" $ tryRemoves (nub $ foldMap fvs $ delElem i cs) $ MSt (foldl App (cs !! i) es) vs |
224 | Var i -> lookupHNF' "casevar" (\e (Case cn _ cs) -> Case cn e cs) i dt | 239 | Var i -> lookupHNF' "casevar" (\e (Case cn _ cs) -> Case cn e cs) i dt |
225 | _ -> step "caseexp" $ MSt (up 1 1 t) (Case cn (Var 0) $ up 0 1 <$> cs) $ a: vs | 240 | _ -> step "caseexp" $ MSt (Case cn (Var 0) $ up 0 1 <$> cs) $ ELet a: vs |
226 | 241 | ||
227 | Op2 op x y -> case (x, y) of | 242 | Op2 op x y -> case (x, y) of |
228 | (Int e, Int f) -> step "op-done" $ MSt t (int op e f) vs | 243 | (Int e, Int f) -> step "op-done" $ MSt (int op e f) vs |
229 | where | 244 | where |
230 | int Add a b = Int $ a + b | 245 | int Add a b = Int $ a + b |
231 | int Sub a b = Int $ a - b | 246 | int Sub a b = Int $ a - b |
@@ -234,27 +249,30 @@ steps lev nostep {-ready-} bind cont dt@(MSt t e vs) = case e of | |||
234 | int EqInt a b = if a == b then T else F | 249 | int EqInt a b = if a == b then T else F |
235 | (Var i, _) -> lookupHNF' "op2-1var" (\e (Op2 op _ y) -> Op2 op e y) i dt | 250 | (Var i, _) -> lookupHNF' "op2-1var" (\e (Op2 op _ y) -> Op2 op e y) i dt |
236 | (_, Var i) -> lookupHNF' "op2-2var" (\e (Op2 op x _) -> Op2 op x e) i dt | 251 | (_, Var i) -> lookupHNF' "op2-2var" (\e (Op2 op x _) -> Op2 op x e) i dt |
237 | (Int{}, _) -> step "op2" $ MSt (up 1 1 t) (Op2 op x (Var 0)) $ y: vs | 252 | (Int{}, _) -> step "op2" $ MSt (Op2 op x (Var 0)) $ ELet y: vs |
238 | (_, Int{}) -> step "op2" $ MSt (up 1 1 t) (Op2 op (Var 0) y) $ x: vs | 253 | (_, Int{}) -> step "op2" $ MSt (Op2 op (Var 0) y) $ ELet x: vs |
239 | _ -> step "op2" $ MSt (up 1 2 t) (Op2 op (Var 0) (Var 1)) $ x: y: vs | 254 | _ -> step "op2" $ MSt (Op2 op (Var 0) (Var 1)) $ ELet x: ELet y: vs |
240 | where | 255 | where |
241 | rec i = steps i nostep bind cont | 256 | rec i = steps i nostep bind cont |
242 | 257 | ||
243 | step :: StepTag -> MSt -> e | 258 | step :: StepTag -> MSt -> e |
244 | step t = bind t (rec lev) | 259 | step t = bind t (rec lev) |
245 | 260 | ||
246 | hnf :: (MSt -> e) -> MSt -> e | 261 | hnf :: StepTag -> (MSt -> e) -> MSt -> e |
247 | hnf f = cont "hnf" f (rec $ 1 + lev) | 262 | hnf t f = cont t f (rec $ 1 + lev) |
248 | 263 | ||
249 | hnfTag (MSt a b c) = MSt a (HNF lev b) c | 264 | hnfTag (MSt b c) = MSt (HNF lev b) c |
250 | 265 | ||
251 | -- lookup var in head normal form | 266 | -- lookup var in head normal form |
252 | lookupHNF_ :: (MSt -> e) -> StepTag -> (Exp -> Exp -> Exp) -> Nat -> MSt -> e | 267 | lookupHNF_ :: (MSt -> e) -> StepTag -> (Exp -> Exp -> Exp) -> Nat -> MSt -> e |
253 | lookupHNF_ end msg f i@(Nat i') dt = bind msg (hnf shiftLookup) $ iterate shiftL (hnfTag dt) !! (i'+1) | 268 | lookupHNF_ end msg f i@(Nat i') dt = bind msg (hnf "lookup" shiftLookup) dt' |
254 | where | 269 | where |
255 | shiftLookup dt@(MSt _ e _) | 270 | (path, dt') = shiftL [] i' $ hnfTag dt |
256 | = case iterate shiftR dt !! (i'+1) of | 271 | |
257 | MSt xs (HNF lev z) es -> bind "shiftR" (tryRemove i) $ MSt xs (f (up 0 (i+1) e) z) es | 272 | shiftLookup st |
273 | = case boot (shiftR path . pakol') st of | ||
274 | (q, MSt (HNF lev z) es) -> bind "shiftR" (tryRemove i) $ MSt (f (up 0 1 q) z) es | ||
275 | st -> error $ "sl: " ++ ppShow st | ||
258 | 276 | ||
259 | tryRemove i st = {-maybe (end st)-} (bind "remove" end) $ tryRemoves [i] st | 277 | tryRemove i st = {-maybe (end st)-} (bind "remove" end) $ tryRemoves [i] st |
260 | 278 | ||
@@ -262,9 +280,23 @@ steps lev nostep {-ready-} bind cont dt@(MSt t e vs) = case e of | |||
262 | lookupHNF' :: StepTag -> (Exp -> Exp -> Exp) -> Nat -> MSt -> e | 280 | lookupHNF' :: StepTag -> (Exp -> Exp -> Exp) -> Nat -> MSt -> e |
263 | lookupHNF' msg f i dt = lookupHNF_ (rec lev) msg f i dt | 281 | lookupHNF' msg f i dt = lookupHNF_ (rec lev) msg f i dt |
264 | 282 | ||
265 | shiftL (MSt xs x (e: es)) = MSt (Let x xs) e es | 283 | shiftL path 0 (MSt x (ELet e: es)) = (path, MSt e $ ELet1 x: es) |
284 | shiftL path n (MSt x (ELet e: es)) = shiftL (TELet: path) (n-1) $ MSt (Let e x) es | ||
285 | shiftL path n (MSt x (EApp1 i e: es)) = shiftL (TEApp1: path) n $ MSt (HNF i $ App x e) es | ||
286 | shiftL path n (MSt x (ELet1 e: es)) = shiftL (TELet1: path) n $ MSt (Let x e) es | ||
287 | shiftL path n st = error $ "shiftL: " ++ show (path, n) ++ "\n" ++ ppShow st | ||
288 | |||
289 | boot c (MSt e (ELet x: xs)) = boot (c . pakol) (MSt (Let x e) xs) | ||
290 | boot c st = c st | ||
291 | |||
292 | pakol (MSt (Let x e) (ELet1 y: xs)) = MSt e (ELet1 (up 1 1 y): ELet x: xs) | ||
293 | pakol' (MSt x (ELet1 y: xs)) = (x, MSt y (ELet x: xs)) | ||
266 | 294 | ||
267 | shiftR (MSt (Let x xs) e es) = MSt xs x $ e: es | 295 | shiftR [] st = st |
296 | shiftR (TELet: n) (y, MSt (Let e x) es) = shiftR n (up 0 1 y, MSt x $ ELet e: es) | ||
297 | shiftR (TEApp1: n) (y, MSt (HNF l (App x e)) es) = shiftR n (y, MSt x $ EApp1 l e: es) | ||
298 | shiftR (TELet1: n) (y, MSt (Let x e) es) = shiftR n (y, MSt x $ ELet1 e: es) | ||
299 | shiftR path x = error $ "shiftR: " ++ show path ++ "\n" ++ ppShow x | ||
268 | 300 | ||
269 | simple = \case | 301 | simple = \case |
270 | Var{} -> True | 302 | Var{} -> True |
@@ -273,9 +305,14 @@ steps lev nostep {-ready-} bind cont dt@(MSt t e vs) = case e of | |||
273 | 305 | ||
274 | delElem i xs = take i xs ++ drop (i+1) xs | 306 | delElem i xs = take i xs ++ drop (i+1) xs |
275 | 307 | ||
308 | data TE = TELet | TELet1 | TEApp1 | ||
309 | deriving Show | ||
310 | |||
276 | ---------------------------------------------------------------------------------------- examples | 311 | ---------------------------------------------------------------------------------------- examples |
277 | 312 | ||
278 | runMachinePure = putStrLn . ppShow . hnf | 313 | pPrint = putStrLn . ppShow |
314 | |||
315 | runMachinePure = pPrint . hnf | ||
279 | 316 | ||
280 | pattern F = Con "False" 0 [] | 317 | pattern F = Con "False" 0 [] |
281 | pattern T = Con "True" 1 [] | 318 | pattern T = Con "True" 1 [] |
@@ -291,9 +328,9 @@ if_ b t f = caseBool b f t | |||
291 | 328 | ||
292 | not_ x = caseBool x T F | 329 | not_ x = caseBool x T F |
293 | 330 | ||
294 | test = hnf (id_ `App` id_ `App` id_ `App` id_ `App` Int 13) | 331 | test = id_ `App` id_ `App` id_ `App` id_ `App` Int 13 |
295 | 332 | ||
296 | test' = hnf (id_ `App` (id_ `App` Int 14)) | 333 | test' = id_ `App` (id_ `App` Int 14) |
297 | 334 | ||
298 | foldr_ 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)) | 335 | foldr_ 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)) |
299 | 336 | ||
@@ -345,8 +382,8 @@ main = primes !! 3000 | |||
345 | -} | 382 | -} |
346 | 383 | ||
347 | tests | 384 | tests |
348 | = test == hnf (Int 13) | 385 | = hnf test == hnf (Int 13) |
349 | && test' == hnf (Int 14) | 386 | && hnf test' == hnf (Int 14) |
350 | && hnf (Lam (Int 4) `App` Int 3) == hnf (Int 4) | 387 | && hnf (Lam (Int 4) `App` Int 3) == hnf (Int 4) |
351 | && hnf (t' 10) == hnf (Int 55) | 388 | && hnf (t' 10) == hnf (Int 55) |
352 | && hnf (t'' 10) == hnf (Int 55) | 389 | && hnf (t'' 10) == hnf (Int 55) |