我在lambda演算中对scc的替代定义是否正确?

时间:2014-09-16 11:06:49

标签: haskell lambda lambda-calculus

scc是一个组合者(继承者),它接受一个Church Numeral n并返回另一个Church数字。

我们记得教堂的数字定义如下:

c_0 = λs. λz. z;
c_1 = λs. λz. s z;
c_2 = λs. λz. s (s z);
c_3 = λs. λz. s (s (s z));
...

可以定义scc:

scc = λn. λs. λz. s (n s z);

定义是:

scc' = λn. λs. c_1 s n;

等效?

scc' = λn. λs. c_1 s n;
      λn. λs. (λs. λz. s z) s n;
      λn. λs. s n;

所以当scc'应用于教堂数字时,结果如下:

foo = scc' c_2
    = (λn. λs. s n) c_2
    = s c_2
    = s (s (s z))
    = c_3

1 个答案:

答案 0 :(得分:1)

没有。通过beta减少:

scc' = λn. λs. c_1 s n;
     = λn. λs. (λs. λz. s z) s n
     = λn. λs. (λz. s z) n
     = λn. λs. s n

更一般地说,对于任何教会数字x

x = λn. λs. x s n

可以通过归纳或观察它只是eta收缩的双重应用来证明。

编辑:扩展以解释这一切是如何运作的。

我们如何知道教堂数字是否正确?好吧,想象一下你用数字和基本算术扩展了lambda演算。然后定义以下函数

fromChurch = λc. c (λn. n + 1) 0

我声称fromChurch会按照您期望的方式将教会数字转换为数字

fromChurch c_0 
  = (λc. c (λn. n + 1) 0) (λs. λz. z) 
  = (λs. λz. z) (λn. n + 1) 0)
  = (λz. z) 0
  = 0
fromChurch c_1 
  = (λc. c (λn. n + 1) 0) (λs. λz. s z)
  = (λs. λz. s z) (λn. n + 1) 0
  = (λz. (λn. n + 1) z) 0
  = (λn. n + 1) 0
  = 0 + 1
  = 1
fromChurch c_2 
  = (λc. c (λn. n + 1) 0) (λs. λz. s (s z))
  = (λs. λz. s (s z)) (λn. n + 1) 0
  = (λz. (λn. n + 1) ((λn. n + 1) z) 0
  = (λn. n + 1) ((λn. n + 1) 0)
  = ((λn. n + 1) 0) + 1
  = (0 + 1) + 1
  = 2

接下来是成功函数(注意,你错过了λs

scc = λn. λs. λz. s (n s z)

这是succesor function

的正确性条件
fromChurch (scc x)
  = (λc. c (λn. n + 1) 0) ((λn. λs. λz. s (n s z)) x)
  = (λn. λs. λz. s (n s z)) x (λn. n + 1) 0
  = (λs. λz. s (x s z)) (λn. n + 1) 0
  = (λz. (λn. n + 1) (x (λn. n + 1) z)) 0
  = (λn. n + 1) (x (λn. n + 1) 0)
  = (x (λn. n + 1) 0) + 1
  = ((λc. c (λn. n + 1) 0) x) + 1 
  = (fromChurch x) + 1

请注意倒数第二步是beta扩展而不是beta降低。

关键是scc确实计算了一个整数值高一个的教会数字。

另一方面,λn. λs. c_1 s n不是从教会数字到教会数字的函数......它只是一个教会数字。实际上,它是1的教会数值。继承人绝不会这样做。

编辑2:

你给出的缩减序列

foo = scc' c_2
 = (λn. λs. s n) c_2
 = s c_2
 = s (s (s z))
 = c_3

不太正确

(λn. λs. s n) c_2
 = λs. s c_2

这样做是因为λs. s c_2是普通形式,因此不等于c_3