Lambda calculus 为什么要给教会下定义';数字
我想理解,为什么Church会这样定义数字:Lambda calculus 为什么要给教会下定义';数字,lambda-calculus,Lambda Calculus,我想理解,为什么Church会这样定义数字: 0 = λ f . λ x . x 1 = λ f . λ x . f x 2 = λ f . λ x . f f x 3 = λ f . λ x . f f f x 4 = λ f . λ x . f f f f x 背后的逻辑是什么 为什么0表示为: 0 = λ f . λ x . x 丘奇并不想实际。他试图证明lambda演算的表达能力的结果-原则上任何可能的计算都可以用λ演算来完成,因此λ演算可以作为可计算性研究的理论基础。为了做到这一点
0 = λ f . λ x . x
1 = λ f . λ x . f x
2 = λ f . λ x . f f x
3 = λ f . λ x . f f f x
4 = λ f . λ x . f f f f x
背后的逻辑是什么
为什么0表示为:
0 = λ f . λ x . x
丘奇并不想实际。他试图证明lambda演算的表达能力的结果-原则上任何可能的计算都可以用λ演算来完成,因此λ演算可以作为可计算性研究的理论基础。为了做到这一点,有必要将数字编码为lambda表达式,这样后续函数之类的东西就很容易定义。这是展示lambda演算和(关于自然数上的可计算函数)等价性的关键一步。教堂数字基本上是一种方便的数字编码,尽管可读性不强。从某种意义上说,它没有任何深刻的逻辑。这种说法并不是说1本质上是
λf。λx。f x
,但后者是前者的可用编码
这并不意味着它是一种任意编码。这是有一定逻辑的。对一个数字进行编码的最自然的方法是通过一些涉及到n
的东西。教堂数字使用n
函数应用程序。自然数n
由将函数n
次数应用于输入的高阶函数表示<代码>1由应用一次的函数编码,2
由应用两次的函数编码,依此类推。这是一种非常自然的编码,特别是在lambda演算的上下文中。此外,在它们上定义算术很容易,这一事实简化了lambda演算等价于递归函数的证明
要在实践中看到这一点,可以运行以下Python3脚本:
#some Church numerals:
ZERO = lambda f: lambda x: x
ONE = lambda f: lambda x: f(x)
TWO = lambda f: lambda x: f(f(x))
THREE = lambda f: lambda x: f(f(f(x)))
#function to apply these numerals to:
def square(x): return x**2
#so ZERO(square), ONE(square), etc. are functions
#apply these to 2 and print the results:
print(ZERO(square)(2), ONE(square)(2), TWO(square)(2),THREE(square)(2))
输出:
2 4 16 256
请注意,这些数字是通过将数字2分别平方0倍、1倍、2倍和3倍得到的。根据,对于另一个自然数n,自然数为0或S(n):
您可以将教堂数字视为Peano数字的泛化,您可以提供自己的0和S:
由于这是一个编程论坛,让我们在EcmaScript 6中创建一些教堂数字:
const ZERO = s => z => z;
const ONE = s => z => s(z);
const TWO = s => z => s(s(z));
...
通过提供适当的零和后续数字,可以将这些教堂数字转换为JavaScript数字:
function toInt(n) {
return n(i => i + 1)(0);
}
然后:
> toInt(TWO)
2
你可以用教堂数字做一些实际的事情:
function shout(text) {
return text + "!";
}
> shout("hi")
"hi!"
> NINE(shout)("hi")
"hi!!!!!!!!!"
你可以在这里试试:下面的文章把它给我分解得很好
从一开始就需要掌握的要点:
- 所有Church数字都是具有两个参数的函数李>
- 在任何数字的教会代表中,暗示:
-是“后继”函数(即接受教堂数字并返回传递数字旁边的教堂数字的函数,它基本上是递增的)李>f
-是一个(教堂数字)值,表示“零”(计数起点)x
λf . λx . x
如果我们通过适当的f
(“后继”-增量函数)和x
(“零”-计数起点),则将等于零。在这种特殊情况下,什么函数将作为f
传递并不重要,因为它从未应用:
这:
将评估为1:
λf . λx . INCREMENT ZERO
以及以下各项:
λf . λx . f f x
将等同于2:
λf . λx . INCREMENT(INCREMENT ZERO)
依此类推,对于所有连续的数字
奖金(教堂数字的加法、乘法和幂运算): 下面是一个Python代码片段,用于说明(并扩展)上述内容:
ZERO = lambda f: lambda x: x
ONE = lambda f: lambda x: f(x)
TWO = lambda f: lambda x: f(f(x))
THREE = lambda f: lambda x: f(f(f(x)))
SUCC = lambda x: x + 1
ADD = lambda f: lambda x: lambda n: lambda m: n(f)(m(f)(x))
MULT = lambda f: lambda x: lambda n: lambda m: n(m(f))(x)
EXPON = lambda m: lambda n: n(m)
ADD
利用了一个事实,即任何教堂数字都接受一个“零”计数起点,作为它的参数-它只从m开始计数到n
。因此,ADD(SUCC)(0)(三)(二)
将只计算到3,但从2开始,这样我们就得到了2+1+1+1=5
MULT
利用了一个事实,即“后继”函数只是一个教会数字的参数,因此可以被替换。因此,MULT(SUCC)(0)(二)(三)
将返回3两次,这与2*3=6
相同
EXPON
有点棘手(至少对我来说是这样),这里的关键是跟踪what返回的内容。它的基本功能是使用Church数词表示的内在机制(尤其是f
应用程序的递归)。以下是一些例子来说明:
三十
三十一
十三,
我投票结束这个问题,因为它是一个纯粹的数学问题,只是一个与编程无关的应用。按照堆栈溢出规则的要求,这当然不是一个实际的编程问题。你可以试着继续提问。@CodyGray考虑到诸如lambda演算
,图灵机
等标记的存在,声称有关计算基础的问题与堆栈溢出无关是不太可能的。如果是这样的话,至少有六个标签需要移除。数学和计算机科学之间没有明显的界限。Lambda演算是在模糊区域中它们重叠的地方。@john在我看来,重叠应该是你在编程问题的上下文中询问这些概念的地方。这就是标签存在的原因。当然,它不是黑白的,但正如我所说的,这似乎是一个纯粹的数学问题,这使得它不是编程。还有一个问答网站,这可能是一个更好的解决这个问题的地方。总的来说,我认为这些抽象的计算机科学问题在这里是离题的,但你可以随意不同意。@CodyGray我同意理论计算机科学网站可能是这样的问题的更好的家,但这并不意味着它们应该被禁止
λf . λx . INCREMENT ZERO
λf . λx . f f x
λf . λx . INCREMENT(INCREMENT ZERO)
ZERO = lambda f: lambda x: x
ONE = lambda f: lambda x: f(x)
TWO = lambda f: lambda x: f(f(x))
THREE = lambda f: lambda x: f(f(f(x)))
SUCC = lambda x: x + 1
ADD = lambda f: lambda x: lambda n: lambda m: n(f)(m(f)(x))
MULT = lambda f: lambda x: lambda n: lambda m: n(m(f))(x)
EXPON = lambda m: lambda n: n(m)
EXPON(THREE)(ZERO)(SUCC)(0)
↓
lambda n: n(THREE)(ZERO)(SUCC)(0)
↓
ZERO(THREE)(SUCC)(0)
↓
lambda x: (SUCC)(0)
↓
SUCC(0)
↓
1
EXPON(THREE)(ONE)(SUCC)(0)
↓
lambda n: n(THREE)(ONE)(SUCC)(0)
↓
ONE(THREE)(SUCC)(0)
↓
lambda x: THREE(x)(SUCC)(0)
↓
THREE(SUCC)(0)
↓
3
EXPON(ONE)(THREE)(SUCC)(0)
↓
lambda n: n(ONE)(THREE)(SUCC)(0)
↓
THREE(ONE)(SUCC)(0)
↓
lambda x: ONE(ONE(ONE(x)))(SUCC)(0)
↓
ONE(ONE(ONE(SUCC)))(0)
↓
ONE(ONE(lambda x: SUCC(x)))(0)
↓
lambda x:(lambda x: (lambda x: SUCC(x)) (x))(x)(0)
↓
SUCC(0)
↓
1