专栏名称: 贺小三
纨绔子弟、贺百万、贺英俊、贺七七、贺叔叔、贺百科、贺会玩、贺好帅、贺天才、贺虚伪、贺薄情、乔帅格的远房表哥、妮妮的欧洲养老院同伴、资深王教人、小尼克。创业失败,娶妻生子。学术无果,回家种地。
今天看啥  ›  专栏  ›  贺小三

The time-stamped CESK* Machine

贺小三  · 简书  ·  · 2017-10-03 09:44
-- The time-stamped CESK* Machine

{-# LANGUAGE ViewPatterns #-}    
{-# LANGUAGE TypeOperators #-}

import Data.Map hiding (foldl)

---------------  syntax  --------------

type Var = String

data Lambda = Var :=> Exp
    deriving (Show,Eq,Ord)

data Exp = Ref Var
         | Lam Lambda
         | Exp :@ Exp
    deriving (Show,Eq,Ord)

---------------  reachability  --------------

terminal :: (a -> a) -> (a -> Bool) -> a -> a
terminal f isFinal ς0 | isFinal ς0 = ς0
                      | otherwise  = terminal f isFinal (f(ς0))

collect :: (a -> a) -> (a -> Bool) -> a -> [a]
collect f isFinal ς0 | isFinal ς0 = [ς0]
                     | otherwise  = ς0 : (collect f isFinal (f(ς0)))

---------------  auxiliary functions  --------------

type k :-> v = Map k v

(==>) :: a -> b -> (a,b)
(==>) x y = (x,y)

(//) :: Ord a => (a :-> b) -> [(a,b)] -> (a :-> b)
(//) f [(x,y)] = Data.Map.insert x y f

-----------------------------

type Σ = (Exp,Env,Store,Kont,Time)

data Storable = Clo (Lambda, Env) | Cont Kont

type Env = Var :-> Addr

type Store = Addr :-> Storable

data Kont = Mt | Ar (Exp,Env,Addr) | Fn (Lambda,Env,Addr)

type Addr = Int

type Time = Int

inject :: Exp -> Σ
inject (e) = (e, ρ0, σ0, κ0, t0)
    where ρ0 = Data.Map.empty
          σ0 = Data.Map.empty 
          κ0 = Mt
          t0 = 0

isFinal :: Σ -> Bool
isFinal (Lam _, _, σ, Mt, _) = True
isFinal _ = False

evaluate :: Exp -> Exp
evaluate e = case terminal step isFinal (inject(e)) of 
    (e', _, _, _, _) -> e'

step :: Σ -> Σ
step ς@(Ref x, ρ, σ, κ, t) = (Lam lam, ρ', σ, κ, t')  
    where 
        Clo(lam, ρ') = σ!(ρ!x)
        t' = tick(ς)

step ς@(f :@ e, ρ, σ, κ, t) = (f, ρ, σ', κ', t')
    where
        a' = alloc(ς)
        σ' = σ // [a' ==> Cont κ]
        κ' = Ar(e, ρ, a')
        t' = tick(ς)

step ς@(Lam lam, ρ, σ, Ar(e, ρ', a'), t) = (e, ρ', σ, Fn(lam, ρ, a'), t') 
    where
        t' = tick(ς)

step ς@(Lam lam, ρ, σ, Fn(x :=> e, ρ', a), t) = (e, ρ' // [x ==> a'], σ // [a' ==> Clo(lam, ρ)], κ, t')
    where
        Cont κ = σ!a
        a' = alloc(ς)
        t' = tick(ς)

alloc :: Σ -> Addr
alloc (_,_,σ,_,_) = (foldl max 0 $! keys σ) + 1

tick :: Σ -> Time
tick (_,_,_,_,t) = t + 1

-----------------------------

main :: IO ()
main = do
    print (evaluate $! ((Lam ("x" :=> Ref "x")) :@ (Lam ("z" :=> Ref "z"))) :@ (Lam ("a" :=> Ref "a")))
    return ()

--  ((Lam ("x" :=> Ref "x")) :@ (Lam ("z" :=> Ref "z"))) :@ (Lam ("a" :=> Ref "a"))

--  (((Lam ("x" :=> Ref "x")) :@ (Lam ("z" :=> Ref "z"))) :@ (Lam ("a" :=> Ref "a")),
--                                                        fromList [],
--                                                        fromList [],
--                                                        Mt,
--                                                        0)

--  ((Lam ("x" :=> Ref "x")) :@ (Lam ("z" :=> Ref "z")),
--                                                      fromList [],
--                                                      fromList [(1, Cont(Mt))],
--                                                      Ar((Lam ("a" :=> Ref "a"))), fromList [], 1),
--                                                      1)

--  ((Lam ("x" :=> Ref "x")),
--                          fromList [],
--                          fromList [(1, Cont(Mt)), (2, Cont(Ar((Lam ("a" :=> Ref "a"))), fromList [], 1))))],
--                          Ar((Lam ("z" :=> Ref "z")), fromList [], 2),
--                          2)

--  ((Lam ("z" :=> Ref "z")),
--                          fromList [],
--                          fromList [(1, Cont(Mt)), (2, Cont(Ar((Lam ("a" :=> Ref "a"))), fromList [], 1))))],
--                          Fn(("x" :=> Ref "x"), fromList [], 2),
--                          3)

--  (Ref "x",
--       fromList [("x", 3)],
--       fromList [(1, Cont(Mt)), (2, Cont(Ar((Lam ("a" :=> Ref "a"))), fromList [], 1)), (3, Clo(("z" :=> Ref "z"), fromList []))],
--       Cont(Ar((Lam ("a" :=> Ref "a"))), fromList [], 1),
--       4)

--  ((Lam ("z" :=> Ref "z")),
--                          fromList [],
--                          fromList [(1, Cont(Mt)), (2, Cont(Ar((Lam ("a" :=> Ref "a"))), fromList [], 1)), (3, Clo(("z" :=> Ref "z"), fromList []))],
--                          Cont(Ar((Lam ("a" :=> Ref "a"))), fromList [], 1),,
--                          5)

--  ((Lam ("a" :=> Ref "a")),
--                          fromList [],
--                          fromList [(1, Cont(Mt)), (2, Cont(Ar((Lam ("a" :=> Ref "a"))), fromList [], 1)), (3, Clo(("z" :=> Ref "z"), fromList []))],
--                          Fn(("z" :=> Ref "z"), fromList [], 1),
--                          6)

--  (Ref "z",
--       fromList [("z", 4)],
--       fromList [(1, Cont(Mt)), (2, Cont(Ar((Lam ("a" :=> Ref "a"))), fromList [], 1)), (3, Clo(("z" :=> Ref "z"), fromList [])), (4, Clo(("a" :=> Ref "a"), fromList []))],
--       Cont(Mt),
--       7)

--  ((Lam ("a" :=> Ref "a")),
--        fromList [],
--        fromList [(1, Cont(Mt)), (2, Cont(Ar((Lam ("a" :=> Ref "a"))), fromList [], 1)), (3, Clo(("z" :=> Ref "z"), fromList [])), (4, Clo(("a" :=> Ref "a"), fromList []))],
--        Cont(Mt),
--        8)

Systematic abstraction of abstract machines




原文地址:访问原文地址
快照地址: 访问文章快照