gpt4 book ai didi

haskell - 在 Haskell 中解释 Parigot 的 lambda-mu 演算

转载 作者:行者123 更新时间:2023-12-04 07:21:24 28 4
gpt4 key购买 nike

可以解释 Haskell 中的 lambda 演算:

data Expr = Var String | Lam String Expr | App Expr Expr

data Value a = V a | F (Value a -> Value a)

interpret :: [(String, Value a)] -> Expr -> Value a
interpret env (Var x) = case lookup x env of
Nothing -> error "undefined variable"
Just v -> v
interpret env (Lam x e) = F (\v -> interpret ((x, v):env) e)
interpret env (App e1 e2) = case interpret env e1 of
V _ -> error "not a function"
F f -> f (interpret env e2)

如何将上述解释器扩展到 lambda-mu calculus ?我的猜测是它应该使用延续来解释这个演算中的附加结构。 (15) 和 (16) 来自 Bernardi&Moortgat paper是我期望的那种翻译。

因为 Haskell 是图灵完备的,所以这是可能的,但是如何实现呢?

提示:请参阅第 197 页上的评论 this research paper对于 mu binder 的直观含义。

最佳答案

这是论文中减少规则的无意识音译,使用@user2407038 的表示(如您所见,当我说无意识时,我真的是指无意识):

{-# LANGUAGE DataKinds, KindSignatures, GADTs #-}
{-# LANGUAGE StandaloneDeriving #-}

import Control.Monad.Writer
import Control.Applicative
import Data.Monoid

data TermType = Named | Unnamed

type Var = String
type MuVar = String

data Expr (n :: TermType) where
Var :: Var -> Expr Unnamed
Lam :: Var -> Expr Unnamed -> Expr Unnamed
App :: Expr Unnamed -> Expr Unnamed -> Expr Unnamed
Freeze :: MuVar -> Expr Unnamed -> Expr Named
Mu :: MuVar -> Expr Named -> Expr Unnamed
deriving instance Show (Expr n)

substU :: Var -> Expr Unnamed -> Expr n -> Expr n
substU x e = go
where
go :: Expr n -> Expr n
go (Var y) = if y == x then e else Var y
go (Lam y e) = Lam y $ if y == x then e else go e
go (App f e) = App (go f) (go e)
go (Freeze alpha e) = Freeze alpha (go e)
go (Mu alpha u) = Mu alpha (go u)

renameN :: MuVar -> MuVar -> Expr n -> Expr n
renameN beta alpha = go
where
go :: Expr n -> Expr n
go (Var x) = Var x
go (Lam x e) = Lam x (go e)
go (App f e) = App (go f) (go e)
go (Freeze gamma e) = Freeze (if gamma == beta then alpha else gamma) (go e)
go (Mu gamma u) = Mu gamma $ if gamma == beta then u else go u

appN :: MuVar -> Expr Unnamed -> Expr n -> Expr n
appN beta v = go
where
go :: Expr n -> Expr n
go (Var x) = Var x
go (Lam x e) = Lam x (go e)
go (App f e) = App (go f) (go e)
go (Freeze alpha w) = Freeze alpha $ if alpha == beta then App (go w) v else go w
go (Mu alpha u) = Mu alpha $ if alpha /= beta then go u else u

reduceTo :: a -> Writer Any a
reduceTo x = tell (Any True) >> return x

reduce0 :: Expr n -> Writer Any (Expr n)
reduce0 (App (Lam x u) v) = reduceTo $ substU x v u
reduce0 (App (Mu beta u) v) = reduceTo $ Mu beta $ appN beta v u
reduce0 (Freeze alpha (Mu beta u)) = reduceTo $ renameN beta alpha u
reduce0 e = return e

reduce1 :: Expr n -> Writer Any (Expr n)
reduce1 (Var x) = return $ Var x
reduce1 (Lam x e) = reduce0 =<< (Lam x <$> reduce1 e)
reduce1 (App f e) = reduce0 =<< (App <$> reduce1 f <*> reduce1 e)
reduce1 (Freeze alpha e) = reduce0 =<< (Freeze alpha <$> reduce1 e)
reduce1 (Mu alpha u) = reduce0 =<< (Mu alpha <$> reduce1 u)

reduce :: Expr n -> Expr n
reduce e = case runWriter (reduce1 e) of
(e', Any changed) -> if changed then reduce e' else e

它对论文中的示例“有效”:
example 0 = App (App t (Var "x")) (Var "y")
where
t = Lam "x" $ Lam "y" $ Mu "delta" $ Freeze "phi" $ App (Var "x") (Var "y")
example n = App (example (n-1)) (Var ("z_" ++ show n))

我可以减少 example n到预期的结果:
*Main> reduce (example 10)
Mu "delta" (Freeze "phi" (App (Var "x") (Var "y")))

我在上面的“作品”周围加上吓人的引号的原因是我对 λμ 演算没有直觉,所以我不知道它应该做什么。

关于haskell - 在 Haskell 中解释 Parigot 的 lambda-mu 演算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28752112/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com