给定以下lambda表达式,其中\
类似于lambda
:
(\kf.f(\c.co)km)(\x.dox)(\le.le)
如果我将(\c.co)k
转换为ko
,是不是错了?我做到了,显然,这是错的。正确的方法是首先评估外部函数,这意味着(\f.f(\c.co)(\x.dox)m)(\le.le)
将成为理想的解决方案。
这是真的,因为在我们的讲义中找不到任何可以表明这一点的规则吗?如果是,为什么我不能先评估内部函数?我这样做了,我的解决方案是正确的。
问候。
答案 0 :(得分:2)
我问我的TA,他说应用程序是关联的,意思是
(\kf.f(\c.co)km)(\x.dox)(\le.le)
相当于
( [\kf.( [ f(\c.co) ]k )m ][\x.dox] )[ \le.le ]
这解释了为什么k
无法应用于(\c.co)
。:/
括号/圆括号仅用于使其更具可读性。
问候。
答案 1 :(得分:2)
因此,(无类型)lambda演算中的beta减少就是我们所说的汇合重写规则。这意味着,如果您可以通过缩减功能将A
重写为B
,并使用beta-reduction将A
重写为C
,那么您可以找到一些D
这样B
重写为D
和 C
重写为D
- 实际上会有一些共同的后代。为lambda演算显示此定理的定理通常称为 Church-Rosser theorem。整体属性有时被称为钻石属性,因为该图类似于钻石(两条路线分支出来,但最终又重新组合在一起)。这也意味着无论你如何选择应用beta减少,“终止”lambda表达式的最终结果都是相同的。
然而,并非所有lambda术语都有一个最终结果。这意味着无类型演算不是我们所说的规范化。有许多lambda术语将在beta-reduction下永远扩展(永远不会达到不可简化或正常形式)。在这些情况下,使用一些系统来命令重写是有用的,因为它可以确保对两个相同的程序进行相同的程序评估。
当然,您需要确保遵守lambda的绑定规则,因此不要尝试将术语应用于错误的lambda变量。
答案 2 :(得分:2)
在问题得到圆满解答之后,这显然是一种方式。但是,我不得不在评估顺序上挣扎一下#34;在lambda演算中,这个更精细的答案主要针对后代,以防其他人有同样的疑虑。 @danyel的答案是一个很大的帮助,我将在此基础上进行。
正如OP正确指出的那样,没有关于评估顺序的明确规则。但是,应用程序是左关联的规则会导致这样的规则 - 最外层的应用程序将在内部应用程序之前进行评估。
在表达式中,
(\kf.f(\c.co)km)(\x.dox)(\le.le)
:让我们首先进行一些简化(使用每个术语e
是变量x
,抽象\x.y
或应用程序e1e2
)的第一原则:
\c.co = e1
,\x.dox = e2
,\le.le = e3
。这导致原始表达式转换为:
(\kf.f(e1)km)(e2)(e3)
。让我们考虑上面表达式中最左边的术语:
(\kf.(f(e1)km)) = e4
仔细观察抽象的主体:
- (fe1)km
或(f(\c.co))km
beta redex(可简化表达式)是(\x.e1)e2
形式的表达式。上面的表达式看起来不像那样,并且不是beta redex(因为基于可用的信息,f不是抽象)。这就是为什么它无法减少以及为什么将\c.co
应用于k
是错误的原因。
因此,e4
不会减少并保持不变,这会导致:
((e4)(e2))(e3)
。 ((e4)(e2))
是第一个测试版重新索引,确实e2
取代了k
,正如所指出的那样。
另外一点,((e4)(e2))
并未首先应用于(e3)
,理由相同:它(((e4)(e2))e3
)不是测试版指针,其形式如下:
((\ kf.body)E2)E3。内部表达式(\ kf.body)e2)是第一个可以减少的有效beta重新索引。这样做可以得到答案。