使用Lambda微积分表示负数和复数


Answers:


18

首先编码自然数和对,如jmad所述。

将整数为一对自然数,使得。然后,您可以将整数的常规运算定义为(对 -calculus 使用Haskell表示法):k(a,b)k=abλ

neg = \k -> (snd k, fst k)
add = \k m -> (fst k + fst m, snd k + snd m)
sub = \k m -> add k (neg m)
mul = \k m -> (fst k * fst m + snd k * snd m, fst k * snd m + snd k * fst m)

就复数被编码为一对实数的意义而言,复数的情况相似。但是一个更复杂的问题是如何对实数进行编码。在这里,您必须做更多的工作:

  1. 将有理数编码为对,其中是整数,是自然数,并且q(k,a)kaq=k/(1+a)
  2. 编码实数由函数˚F使得对于每一个自然ķ Ñ˚F ķ编码有理数q使得| x q | < 2 - k。换句话说,一个真正的被编码为有理数以速率收敛到它的序列ķ 2 - ķxfkNfkq|xq|<2kk2k

对实数进行编码是一项繁重的工作,您不想在微积分中实际进行编码。但是,例如,请参见Marshall的子目录,以了解纯Haskell中实数的简单实现。原则上,这可以转换为纯λ微积分。λetc/haskellλ


1
哇=)我在直觉上想知道这是什么意思……例如,使用教堂数字编码……即。整数值n的教会数由将函数应用于值n次的函数表示。对和负lambda值是否具有与它们相似的直观感觉?
zcaudate 2012年

1
教会编码编码自然数12,...这不编码负数。在上面的答案中,我假设您已经了解自然数的编码,因此我解释了如何获取整数。我所编码的整数是更正式的结构,与教堂数字不同,教堂数字与λ微积分的联系更加复杂。我认为“负lambda值”不是一个有意义的短语。012λ
Andrej Bauer 2012年

@zcaudate [类型注释:i:ℤx:af,u,s:a→ap:(a→a,a→a)]如果编码ℤ作为(Sign,ℕ)然后,给定一对功能(s,f)p,术语λi.λp.λx.(fst i) (fst p) id ((snd i) (snd p) x)会产生任一f(…f(x)…)s(f(…f(x)…))(如果结果是负的)。如果将encode编码为(ℕ,ℕ),则需要一个具有反函数的函数-给定一个对,(f,u)并且x该函数λi.λp.λx.(snd i)(snd p)((fst i)(fst p) x)将产生u(…u(f(…f(x)…))…),将把f应用i时间赋予x。两者都在不同的上下文中工作(结果可以被“翻转” || f是可逆的)。
没人

@zcaudate额外的功能是必需的,因为教会编码的数字“自己递归”,但是配对将只为您提供组件。辅助函数仅按“正确”顺序将组件粘合在一起(nat自动发生)。另请参见:en.wikipedia.org/wiki/…–教堂编码基本上fold . ctor适用于任何构造函数,且该类型的foldr)。(这就是为什么对于递归类型,数据将“自行递归”的原因。对于非递归类型,它更像是case/模式匹配。)
没人

13

Lambda演算可以编码大多数数据结构和基本类型。例如,您可以使用通常用于编码非负整数和布尔值的相同的Church编码,在lambda演算中对一对现有项进行编码:

FST = λ p p λ X ý X SND = λ p p λ X ý ÿ

=λXÿžžXÿ
fst=λppλXÿX
snd=λppλXÿÿ

那么p = a b 对 ,如果你想取回ab,你可以做fst  p snd  p 一种bp=对 一种b一种bfst psnd p

这意味着您可以轻松地用一对来代表正整数和负整数:左侧的符号和右侧的绝对值。该符号是一个布尔值,指定数字是否为正。右边是使用Church编码的自然数。

s一世Gññ

现在您有了相对整数。乘法很容易定义,您只需要在符号上应用函数异或,并在绝对值上对自然数应用乘法

mult=λab.pair  (xor(fst a)(fst b))  (mult(snd a)(snd b))

要定义加法,您必须比较两个自然数并在符号不同时使用减法,因此这不是λ项,但是如果您确实想满足以下条件,可以对其进行调整:

=λ一种b{真正snd 一种snd b如果 一种0b0snd 一种snd b如果 一种<0b<0真正snd 一种snd b如果 一种0b<0|一种||b|snd bsnd 一种如果 一种0b<0|一种|<|b|真正snd bsnd 一种如果 一种<0b0|一种|<|b|snd 一种snd b如果 一种<0b0|一种||b|

但是减法真的很容易定义:

= λ一个b添加减去 b

减去=λ一种fst 一种snd 一种
=λ一种b一种减去b

一旦有了正整数和负整数,就可以非常容易地定义复数整数:它只是一对两个整数,代表a + b i。然后加法是逐点的,乘法是照常进行的,但是我不会写,应该很容易:一种b一种+b一世

add[i]=λz1z2.pair(add(fst z1)(fst z2))(add(snd z1)(snd z2))

6
如果将整数表示为一对自然数a b ,使得k = a - b 则可以避免区分大小写。ķ一种bķ=一种-b
Andrej Bauer 2012年

可以使用复数整数,但是他要的是复数。再说一遍,由于它们是不可数的,它们当然不能代表。
HDM

@AndrejBauer:非常不错的技巧(也许不是那么简单)HdM:即使不是全部,也可以做到。但是我认为使用Church编码在λ微积分中构建东西的方法在这里更为重要/适当。
jmad 2012年

我希望我能给出两个正确的答案=)当我问复数时,我什至没有想到实数可以表示,但是你走了!
zcaudate 2012年
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.