summaryrefslogtreecommitdiff
path: root/prototypes
diff options
context:
space:
mode:
authorPéter Diviánszky <divipp@gmail.com>2016-04-08 16:04:25 +0200
committerPéter Diviánszky <divipp@gmail.com>2016-04-08 16:04:25 +0200
commit7912e245ab2af57eddc3152b12c07c2e287b5b21 (patch)
tree94b8d9cf081ddf7242e39499fed408f4f651d07f /prototypes
parentc7474d2ffee418c024d3f74bccff4e75178ca1d6 (diff)
begin to implement hnf
Diffstat (limited to 'prototypes')
-rw-r--r--prototypes/ShiftReducer.hs116
1 files changed, 77 insertions, 39 deletions
diff --git a/prototypes/ShiftReducer.hs b/prototypes/ShiftReducer.hs
index f40c7656..47261d65 100644
--- a/prototypes/ShiftReducer.hs
+++ b/prototypes/ShiftReducer.hs
@@ -41,7 +41,10 @@ data Shift a = Shift DBUsed a
41 deriving (Eq, Functor) 41 deriving (Eq, Functor)
42 42
43instance Show a => Show (Shift a) where 43instance Show a => Show (Shift a) where
44 show (Shift s a) = foldStream (:) (:":") ((\b -> if b then 'x' else '_') <$> s) ++ show a 44 showsPrec p (Shift s a) rest = parens (p > 0) (foldStream (:) (:":") ((\b -> if b then 'x' else '_') <$> s) ++ show a) ++ rest
45
46parens True s = "(" ++ s ++ ")"
47parens False s = s
45 48
46strip (Shift _ x) = x 49strip (Shift _ x) = x
47 50
@@ -150,6 +153,17 @@ filterSubsts u m = streamSubsts $ filterStream (Repeat Nothing) u $ substsStream
150 153
151------------------------------------------------------------ let expressions (substitutions + expression) 154------------------------------------------------------------ let expressions (substitutions + expression)
152 155
156{-
157In let expressions, de bruijn indices of variables can be arbitrary, because
158they cannot be seen from outside:
159
160let V 3 = 'c' in (V 4) (V 3) === let V 4 = 'c' in (V 3) (V 4) === let (V 0) = 'c' in (V 4) (V 0)
161
162So all let de bruinj indices could be numbered 0, 1, ..., n.
163
164Question: is it a good idea to store lets in this normal form?
165-}
166
153data Let e a = Let (Substs e) a 167data Let e a = Let (Substs e) a
154 deriving (Eq, Show, Functor) 168 deriving (Eq, Show, Functor)
155 169
@@ -261,9 +275,10 @@ instance Show Lit where
261data Exp e 275data Exp e
262 = ELit Lit 276 = ELit Lit
263 | EVar 277 | EVar
264 | ELamD (Exp e) -- lambda with unused argument
265 | ELam (WithLet (Exp e)) -- lambda with used argument 278 | ELam (WithLet (Exp e)) -- lambda with used argument
279-- | ELamD (Exp e) -- lambda with unused argument (optimization?)
266 | EApp (Shift (Exp e)) (Shift (Exp e)) -- application 280 | EApp (Shift (Exp e)) (Shift (Exp e)) -- application
281 | Delta String
267 | RHS e -- marks the beginning of right hand side (parts right to the equal sign) in fuction definitions 282 | RHS e -- marks the beginning of right hand side (parts right to the equal sign) in fuction definitions
268 -- e is either RHSExp or Void; Void means that this constructor cannot be used 283 -- e is either RHSExp or Void; Void means that this constructor cannot be used
269 deriving (Eq, Show) 284 deriving (Eq, Show)
@@ -273,16 +288,19 @@ type RHSExp = Exp Void
273-- left-hand-side expression (allows RHS constructor) 288-- left-hand-side expression (allows RHS constructor)
274type LHSExp = Exp RHSExp 289type LHSExp = Exp RHSExp
275 290
276-- TODO: make this constant time operation 291rhs :: LHSExp -> RHSExp
292rhs (RHS x) = x
293
277lhs :: RHSExp -> LHSExp 294lhs :: RHSExp -> LHSExp
278lhs = \case 295lhs = RHS
296{-\case
279 ELit l -> ELit l 297 ELit l -> ELit l
280 EVar -> EVar 298 EVar -> EVar
281 ELamD e -> ELamD $ lhs e 299-- ELamD e -> ELamD $ lhs e
282 ELam l -> ELam $ lhs <$> l 300 ELam l -> ELam $ lhs <$> l
283 EApp a b -> EApp (lhs <$> a) (lhs <$> b) 301 EApp a b -> EApp (lhs <$> a) (lhs <$> b)
284 RHS _ -> error "lhs: impossible" 302 RHS _ -> error "lhs: impossible"
285 303-}
286type WithLet a = MaybeLet (Shift LHSExp) a 304type WithLet a = MaybeLet (Shift LHSExp) a
287 305
288-------------------------------------------------------- 306--------------------------------------------------------
@@ -291,13 +309,18 @@ type SExp = Shift RHSExp
291type LExp = WithLet RHSExp 309type LExp = WithLet RHSExp
292type SLExp = Shift (WithLet RHSExp) -- SLExp is *the* expression type in the user API 310type SLExp = Shift (WithLet RHSExp) -- SLExp is *the* expression type in the user API
293 311
312-- TODO
313instance Arbitrary LExp where
314 arbitrary = NoLet <$> arbitrary
315
294instance GetDBUsed RHSExp where 316instance GetDBUsed RHSExp where
295 getDBUsed = \case 317 getDBUsed = \case
296 EApp (Shift ua a) (Shift ub b) -> ua <> ub 318 EApp (Shift ua a) (Shift ub b) -> ua <> ub
297 ELit{} -> mempty 319 ELit{} -> mempty
298 EVar{} -> cons True mempty 320 EVar{} -> cons True mempty
299 ELamD e -> sTail $ getDBUsed e 321-- ELamD e -> sTail $ getDBUsed e
300 ELam e -> sTail $ getDBUsed e 322 ELam e -> sTail $ getDBUsed e
323 Delta{} -> mempty
301 324
302instance Arbitrary RHSExp where 325instance Arbitrary RHSExp where
303 arbitrary = (\(Shift _ (NoLet e)) -> e) . getSimpleExp <$> arbitrary 326 arbitrary = (\(Shift _ (NoLet e)) -> e) . getSimpleExp <$> arbitrary
@@ -340,41 +363,44 @@ prop_upVar (getNonNegative -> k) (getNonNegative -> n) (getNonNegative -> i) = u
340prop_downVar (getNonNegative -> k) (getNonNegative -> i) = down_ k (Var i) == case compare k i of LT -> Just (Var $ i-1); EQ -> Nothing; GT -> Just (Var i) 363prop_downVar (getNonNegative -> k) (getNonNegative -> i) = down_ k (Var i) == case compare k i of LT -> Just (Var $ i-1); EQ -> Nothing; GT -> Just (Var i)
341 364
342lam :: SLExp -> SLExp 365lam :: SLExp -> SLExp
343lam (Shift u e) = Shift (sTail u) $ if sHead u then eLam e else eLamD e 366lam (Shift u e) = Shift (sTail u) $ eLam e -- TODO: if sHead u then eLam e else eLamD e
344 where 367 where
345 eLam (NoLet e) = NoLet $ ELam $ NoLet e
346 -- TODO: improve this by let-floating 368 -- TODO: improve this by let-floating
369 eLam = NoLet . ELam
370{-
371 eLam (NoLet e) = NoLet $ ELam $ NoLet e
347 eLam (HasLet (Let m e)) = NoLet $ ELam (HasLet (Let m{-(filterSubsts (not <$> c) m)-} e)) 372 eLam (HasLet (Let m e)) = NoLet $ ELam (HasLet (Let m{-(filterSubsts (not <$> c) m)-} e))
348 where 373 where
349 c = transitiveClosure (getDBUsed <$> m) $ Cons True $ Repeat False 374 c = transitiveClosure (getDBUsed <$> m) $ Cons True $ Repeat False
375-}
350 376
377{-
351 eLamD (NoLet e) = NoLet $ ELamD e 378 eLamD (NoLet e) = NoLet $ ELamD e
352 -- TODO: review 379 -- TODO: review
353 eLamD (HasLet (Let m (Shift u e))) = HasLet $ {-gc?-}Let (filterSubsts ul m) $ Shift (filterDBUsed ul u) $ ELamD e 380 eLamD (HasLet (Let m (Shift u e))) = HasLet $ {-gc?-}Let (filterSubsts ul m) $ Shift (filterDBUsed ul u) $ ELamD e
354 where 381 where
355 ul = Cons False $ Repeat True 382 ul = Cons False $ Repeat True
356 383-}
357lam_test_let = lam $ lets_ m e -- == Shift s (Let m' e') 384-- test without let floating, modify it after let floating is implemented
385lam_test_let = lam (lets_ m e) == Shift s (NoLet $ ELam $ HasLet $ Let m' $ Shift u e')
358 where 386 where
359 f (HasLet (Let m a)) = HasLet $ Let m a
360
361 e = Var 0 `app` Var 1 `app` Var 10 387 e = Var 0 `app` Var 1 `app` Var 10
362 m = Map.fromList 388 m = Map.fromList
363 [ (0, Var 13) 389 [ (0, Var 13)
364 , (2, Var 1) 390 , (2, Var 1)
365 , (3, Var 1) 391 , (3, Var 1) -- garbage
366 , (10, Var 0 `app` Var 2) 392 , (10, Var 0 `app` Var 2)
367 ] 393 ]
368{- 394
369 s = invTrueIndices [7] 395 s = invTrueIndices [6, 9]
370 e' = f [0] 396 (Shift u (NoLet e')) = Var 0 `app` Var 1 `app` Var 3
371 m' = Map.fromList 397 m' = Map.fromList
372 [ (0, f [2]) 398 [ (0, f $ Var 4)
373 , (1, f []) 399 , (2, f $ Var 1)
374 , (2, f [0, 1]) 400 , (3, f $ Var 0 `app` Var 2)
375 ] 401 ]
376-} 402
377-- f x = Shift (invTrueIndices x) () 403 f (Shift u (NoLet e)) = Shift u $ lhs e
378 404
379app :: SLExp -> SLExp -> SLExp 405app :: SLExp -> SLExp -> SLExp
380app (Shift ua (NoLet a)) (Shift ub (NoLet b)) 406app (Shift ua (NoLet a)) (Shift ub (NoLet b))
@@ -398,6 +424,9 @@ app x y = f x y
398 lb'@(Let mb eb) = pushShiftLet $ Shift ulb' lb 424 lb'@(Let mb eb) = pushShiftLet $ Shift ulb' lb
399 xa = transportIntoLet lb' $ Shift ula' la 425 xa = transportIntoLet lb' $ Shift ula' la
400 426
427lets :: Substs (Shift LHSExp) -> SLExp -> SLExp
428lets m e = fmap joinLets $ maybeLet $ mkLet m e
429
401-- TODO: handle lets inside 430-- TODO: handle lets inside
402lets_ :: Substs SLExp -> SLExp -> SLExp 431lets_ :: Substs SLExp -> SLExp -> SLExp
403lets_ m e = lets (f <$> m) e 432lets_ m e = lets (f <$> m) e
@@ -405,13 +434,6 @@ lets_ m e = lets (f <$> m) e
405 f :: SLExp -> Shift LHSExp 434 f :: SLExp -> Shift LHSExp
406 f (Shift u (NoLet e)) = Shift u $ lhs e 435 f (Shift u (NoLet e)) = Shift u $ lhs e
407 436
408lets :: Substs (Shift LHSExp) -> SLExp -> SLExp
409lets m e = fmap joinLets $ maybeLet $ mkLet m e
410
411-- TODO
412instance Arbitrary LExp where
413 arbitrary = NoLet <$> arbitrary
414
415let1 :: Int -> SLExp -> SLExp -> SLExp 437let1 :: Int -> SLExp -> SLExp -> SLExp
416let1 i (Shift u (NoLet x)) = lets $ Map.singleton i $ Shift u $ RHS x 438let1 i (Shift u (NoLet x)) = lets $ Map.singleton i $ Shift u $ RHS x
417let1 i (Shift u (HasLet l)) = lets $ m <> Map.singleton i' (RHS <$> e) 439let1 i (Shift u (HasLet l)) = lets $ m <> Map.singleton i' (RHS <$> e)
@@ -486,16 +508,32 @@ pushLet' (Shift u l) = case l of
486-- Delta_ f -> ExpL $ Delta_ f 508-- Delta_ f -> ExpL $ Delta_ f
487 509
488--------------------------------------------------------- 510---------------------------------------------------------
511-}
489 512
490hnf :: SLExp -> ExpL 513hnf :: SLExp -> SLExp
514hnf exp@(Shift u (NoLet e)) = case e of
515 EApp (Shift u' (EApp (Shift _ (Delta "add")) y)) x -> case hnf $ NoLet <$> y of
516 Int a -> case hnf $ NoLet <$> x of
517 Int b -> Int $ a + b
518 a -> error "hnf: TODO1"
519 EApp f x -> up u $ case hnf (NoLet <$> f) of
520 Shift u' (NoLet (ELam a)) -> hnf $ let1 0 (NoLet <$> x) $ Shift (Cons (sHead $ getDBUsed a) u') a -- beta reduction
521 ELam{} -> exp
522 ELit{} -> exp
523 x -> error $ "hnf: " ++ show x
524hnf exp@(Shift u (HasLet (Let m e'@(Shift u' e)))) = case NoLet <$> e' of
525 Var i -> case Map.lookup i m of
526 Just x -> hnf $ up u $ maybeLet $ mkLet m $ rhs <$> x
527 x -> error $ "hnf2: " ++ show x
528{-
491hnf e = case pushLet' e of 529hnf e = case pushLet' e of
492 (ExpL (LHS_ "add" [_, _])) -> error "ok" 530 (ExpL (LHS_ "add" [_, _])) -> error "ok"
493 x@(ExpL (EApp a b)) -> case hnf a of 531 x@(ExpL (EApp a b)) -> case hnf a of
494 ExpL (ELam a) -> hnf $ let1 0 b a 532 ExpL (ELam a) -> hnf $ let1 0 b a -- beta reduction
495 ExpL (LHS_ n acc) -> hnf $ LHS n (_ b: acc) 533-- ExpL (LHS_ n acc) -> hnf $ LHS n (_ b: acc)
496 _ -> x 534 _ -> x
497 x -> x 535 x -> x
498 536-}
499{- pattern synonyms 537{- pattern synonyms
500 538
501- BReduce e : at least one step of beta reduction, e is the result 539- BReduce e : at least one step of beta reduction, e is the result
@@ -507,17 +545,17 @@ hnf e = case pushLet' e of
507-} 545-}
508 546
509----------------------------------------------------------------------------------- 547-----------------------------------------------------------------------------------
510-} 548
511idE :: SLExp 549idE :: SLExp
512idE = lam $ Var 0 550idE = lam $ Var 0
513{- 551
514add :: SLExp 552add :: SLExp
515add = NoLet <$> mkShift (LHS "add" []) -- $ ELam $ NoLet $ ELam $ NoLet $ Delta f) 553add = hnf $ f `app` Int 10 `app` Int 20
516 where 554 where
517 f [Int i, Int j] = Int $ i + j 555 f = NoLet <$> mkShift (Delta "add")
518
519example1 = app (idE) (Int 10)
520 556
557example1 = hnf $ app idE (Int 10)
558{-
521example2 = app (app add (Int 10)) (Int 5) 559example2 = app (app add (Int 10)) (Int 5)
522 560
523 561