带有反射的


23

我在寻找一个简单的演算,支持推理反射,即内省和正在运行的程序的操作。

是否存在未类型化的微积分扩展,从而使人们可以将λ-项转换为可以在语法上进行处理然后进行评估的形式?λλ

我认为微积分有两个主要附加术语:

  • :取 v和产生的表示 v易于进行句法操纵。reflect vvv
  • :对一个术语进行句法表示并对其进行评估。eval v

为了支持反思,需要术语的句法表示。它看起来像:

  • 将被表示为术语大号中号 - [R ë ,其中 [R é 是的反射版本 ëλx.e(LAM R(e))R(e)e
  • 将被表示为项A P P R e R e ',并且e e(APP R(e) R(e))
  • 将被表示为V A R x x(VAR x)

通过这种表示,模式匹配可用于操纵术语。

但是我们遇到了一个问题。Ë v 一个需要被编码为术语一样,模式匹配。添加R E F L E C TE V A LM A T C H似乎很简单,但是我是否需要添加其他术语来支持对它们的操纵?reflectevalREFLECTEVALMATCH

有一些设计选择。应该采取什么函数上文提到做的主体- [R ë ˚F È Ç Ë v 一个?是否应[R - 变换身体或没有?R()reflectevalR()

由于我对研究反射本身不太感兴趣-微积分可以用作其他研究的载体-我不想重新发明轮子。

是否有任何与我刚才描述相符的结石?

据我所知,注释中建议的诸如MetaML之类的演算可以走很长一段路,但它们不包括模式匹配和解构已经构建的代码片段的功能。

我想做的一件事是:

  • let x=λy.y in reflect x(LAM (VAR y) (VAR y))

然后对结果执行模式匹配以构建完全不同的表达式。

这当然不是对微积分的保守扩展,并且元理论可能很丑陋,但这是我的应用的重点。我想分开λ-抽象。λλ


MetaML是一种类型化的反射语言,其操作员会进行包围,以执行您的REFLECT并取消包围EVAL。键入是基本的,但是您可以在本文这样的工作中看到从模式S4继承的片段,这可能会对您有所帮助。
ex0du5

@ ex0du5:谢谢,但是据我所知,这还远远不够。当然,我可以在各个阶段构建代码,但是我似乎无法拆开术语。(我会仔细阅读,看我是否错过了任何事情。)
Dave Clarke

方案(没有变异性和其他并发症)?
吉尔(Gilles)'所以

@吉尔斯:Scheme是一种编程语言,而不是演算。此外,我认为它无法满足我的需求。
戴夫·克拉克

@DaveClarke编程语言是一种有很多疣的演算。乍一看,Scheme核心似乎很合适,但是我没有给出足够的想法来确定您的要求。您认为什么不起作用?(如果愿意,可以聊天。)
吉尔斯(Gilles)'所以

Answers:


15

让·路易斯·克里文(Jean Louis Krivine)引入了一种抽象演算,该演算以非常简单的方式扩展了“克里文机器”(请注意,克里文机器已经支持lisp的call / cc指令):

他介绍了在“引用”操作本文通过以下方式确定:如果λ -term,注意ñ φ的图像φ一些双射π Λ →交通ñ从lambda项自然数。注意¯ Ñ其对应于教会标号Ñ Ñ。克里维纳定义了操作者χ由评估规则: χ φ →交通φ ¯ Ñ φϕλnϕϕπ:ΛNn¯nNχ

χ ϕϕ nϕ¯
我相信Kleene向导会证明这足以满足您的要求:即,如果是可计算的,则定义一个引号和eval运算符。π

请注意,众所周知,Krivine难以阅读(请不要生气,Jean-Louis!),并且一些研究人员已经采取了慈善行动,试图以更具可读性的方式提取技术内容。您可以尝试看看Christophe Raffali的这些笔记

希望这可以帮助!


在我看来,还有另一种可能与您的兴趣相关的参考:Jay和Kesner 的《纯模式演算》形式化了演算的一种变体,该变体将变量的简单抽象扩展为表示模式演算的模式的抽象本身。这具有惊人的表现力,特别是允许人们解构应用程序本身:如果我没记错的话,该术语是:λ

(λ(x y).x)((λx.x x) (λy.y))

λx.x x


我想赞成这个看似合理的答案,但我不知道它是否甚至开始回答这个问题。
拉斐尔

@Raphael阅读了文章并发现了:)实际上,这只是部分答案:文章确实确实形式化了Lambda演算中未发现的Lisp的一个重要功能:即QUOTE运算符。尽管没有进行广泛的元理论研究,他们只是将其介绍为表达一种奇怪的非透明计算的手段,以实现复杂的集合论公理。
科迪2012年

1
(λx.x x) (λy.y)λy.y(x y)

1
quotereflectquote

8

要做到这一点,即使不可行,也是非常困难的。就是说,我怀疑您对毛发的元理论是正确的。另一方面,可以设计一种组合器演算,该演算器可以表示所有图灵可计算函数,并且具有检查其项的全部功能:请参阅Jay和Give-Wilson

我相信拥有这种能力确实会对您的方程式理论带来一些不利影响。特别是,如果the等于不超过alpha等价项,您往往只能证明两个值相等。

我尚未阅读与之链接的Krivine论文,但我应该注意,在古典逻辑中,您基本上只有两件事:对与错。一切都等同于其中之一。就是说,无论如何,您总是倾向于崩溃的方程理论。


1
请注意,Krivine演算不是命题演算,而是这些命题的实现者,它们具有非常重要的等式理论。
cody 2013年

5

在编程语言理论中,您所说的功能通常称为“引号”。例如,约翰·朗利(John Longley)在他的一些作品中对此进行了描述,请参见本文

如果您只是出于理论考虑(而不是实际有用的实现),则可以通过返回其参数的Gödel代码来声明quote(或reflect称其为)整数类型,从而简化事情nat。然后,您可以像抽象语法树一样分解数字。此外,您不需要,eval因为可以用该语言实现–它实质上是该语言的解释器。

nmφn(m)φnnλquote

如果您告诉我要做什么,我也许可以为您提供更具体的参考。

顺便说一句,这是一个开放的问题:

λquoteξ

ξ

e1e2λx.e1λx.e2
λλquotequote
e1e2quotee1quotee2,
quote((λx.x)y)quotey.
quoteλ

βquoteλξ

ξβ

以下论文显示了(ξ)方程的一些问题:Lambda微积分是代数,Peter Selinger。有趣的是,我不知道有什么新东西!凉。
无限数

4

这是一个替代的答案,而不是使用我的名义方法(该方法仍处于试验阶段),还有一些更成熟的方法可以追溯到本文:

LEAP:具有评估和多态性的语言
Frank Pfenning和Peter Lee
https://www.cs.cmu.edu/~fp/papers/tapsoft89.pdf

本文以以下内容开头:

然后,这引发了我们一个由雷诺兹首先提出的问题,即强类型语言是否允许元循环解释器。传统观点似乎表明答案是“否”。我们的答案是“差不多”。

请注意,LEAP比OP想要的要强大得多。首先输入它。其次,它要求元圆度,这意味着例如eval可以执行自己的定义。在Prolog中,您获得了solve / 1的元圆度:

solve(true).
solve((A,B)) :- solve(A), solve(B).
solve(H) :- clause(H,B), solve(B).

如果将以下子句添加到solve / 1:

solve(clause(H,B)) :- clause(H,B).

而且,如果您看到它,则子句/ 2还将返回solve / 1的子句。然后,您可以调用resolve(solve(...))并查看Solve如何执行。

自我表征的问题仍在推动一些研究,例如:

吉拉德系统中的自我表示U
马特·布朗(Jatt Palsberg)
http://compilers.cs.ucla.edu/popl15/popl15-full.pdf


3

该问题已在Coq和Isabelle / HOL等举证助手的附近被发现。它的缩写是HOAS。关于λ-Prolog有一些主张,即通过新的∇量词可以做到这一点。但我仍无法掌握这一说法。我想到目前为止,我的主要见解是没有确定的方法,有两种可能的方法。

我自己的观点(尚未完成)是受到保尔森最近关于证明哥德尔斯不完全性的论文的启发。我将对象级别的绑定程序与具有元级别名称的某些数据结构结合使用。基本上与OP中的数据结构相似但又截然不同,并且使用Church编码,因为我对相关类型感兴趣:

datatype Expr = var Name                 /* written as n */
              | app Expr Expr            /* written as s t */
              | abs Name Expr Expr       /* written as λn:s.t */

元级别表达式可以与对象级别表达式区分开,因为我们使用变量名n,m,..等来表示名称。而我们在对象级别使用变量名称x,y,..等。然后,在对象逻辑中对元术语的解释如下。让我们写[t]σ来解释名义上下文σ中的名义术语t,这应该给出一个对象术语。然后,我们将拥有:

 [n]σ = lookup σ n
 [s t]σ = [s]σ [t]σ
 [λn:s.t]σ = λx:[s]σ.[t]σ,n:x

上面将定义OP调用的EVAL函数。与Paulson的区别很小,σ只是一个有限列表,而不是一个函数。我认为,只能引入EVAL函数而不是REFLECT函数。由于在对象级别,您可能具有一些相等性,因此不同的lambda表达式相同。如果需要,您需要做的是使用eval进行推理。

如果要破坏名义和非名义之间的隔离墙,则需要采用Prolog之类的极端方法,什么也不能扩展。但是,正如λ-Prolog系统示例所示,在高阶情况下,还会引出其他问题,例如,只有通过引入新的手段(例如∇量词)才能以逻辑方式克服这些问题!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.