![同构:编程中的数学](https://wfqqreader-1252317822.image.myqcloud.com/cover/165/48213165/b_48213165.jpg)
1.3 自然数和计算机程序
现代计算机系统和在其上构建的程序已经非常复杂宏伟了。人们并非先建立了计算机程序的公理系统,然后演绎出这些成果;而是先取得了应用的巨大成功,然后才逐渐将计算机科学的基石数学化、形式化、严谨化。这种有趣的现象在人类历史上已经不是第一次了。牛顿和莱布尼茨在17世纪发展了微积分,然后被几代数学家应用到了各种领域,包括流体力学、天文学等。但是直到19世纪才由魏尔斯特拉斯、柯西等人将微积分的理论严格化[4]。
我们也模仿一下这样的过程,看看如何根据皮亚诺公理,用计算机程序定义自然数。在一个没有0、1、2、……这些数字的程序系统中,我们可以这样定义自然数[4]:
![](https://epubservercos.yuewen.com/7F4CCD/27732751902824706/epubprivate/OEBPS/Images/16_01.jpg?sign=1739349734-NiSHsSEBEvjXpjTkNfCj9q2NU13LUt6g-0-0bc1d5df32928201f3f3a374eac79adf)
这一定义说:一个自然数或者为零,或者是另一自然数的后继。符号“|”表示互斥的关系。它自然蕴含了零不是任何自然数后继这一公理。在此基础上,我们可以进一步定义出自然数的加法:
![](https://epubservercos.yuewen.com/7F4CCD/27732751902824706/epubprivate/OEBPS/Images/16_02.jpg?sign=1739349734-6nZI3mtBYtbDuNbKoeVL3wDJuG96k5a0-0-2b86f38deb3c8efbe8d456cd50a93179)
加法定义包含两部分。首先任何自然数和零相加等于它本身;并且某个自然数和另一个数的后继相加,等于这两个数相加的后继。写成数学符号为
![](https://epubservercos.yuewen.com/7F4CCD/27732751902824706/epubprivate/OEBPS/Images/16_03.jpg?sign=1739349734-kOnbTjeOzFimm0LoIPVOUpXgg6SaGBhx-0-0a6031dbeb6841e5e3ae8cf5eb39550a)
我们来验证一下2+3。自然数2为succ(succ zero),而3为succ(succ(succ zero))。根据加法的定义2+3为
![](https://epubservercos.yuewen.com/7F4CCD/27732751902824706/epubprivate/OEBPS/Images/17_01.jpg?sign=1739349734-vd2XYgb6JENiSMhP9sd6qeOS5emDuo9i-0-9e422f5eec20da8e6017ff1c97fe5c69)
最终结果的确是零的五重后继,也就是5。从零开始一次一次地套用后继函数很麻烦。如果要表示100,这种记法要写很多行并且容易出错。为此,我们用下面的简单记法表示自然数n:
![](https://epubservercos.yuewen.com/7F4CCD/27732751902824706/epubprivate/OEBPS/Images/17_02.jpg?sign=1739349734-XBuseUVCutjIEkvvGAo9QHnKJhaBdQGL-0-4fe3951085447360a497b598a0700553)
它表示从零开始,不断叠加使用succ函数n次。foldn函数可以具体实现如下:
![](https://epubservercos.yuewen.com/7F4CCD/27732751902824706/epubprivate/OEBPS/Images/17_03.jpg?sign=1739349734-pSRAVP8wEHGxyO1PSUSaYBxQWJarnUcD-0-31a4746f1824cc5cb535a87c51d3617e)
foldn定义了在自然数上的一种操作,只要令z为zero,令f为succ就可以实现叠加后继若干次,从而获得某个特定的自然数。我们可以用前几个自然数验证一下:
![](https://epubservercos.yuewen.com/7F4CCD/27732751902824706/epubprivate/OEBPS/Images/17_04.jpg?sign=1739349734-SchWz09UvO0vGLNTouKMIPEO5hbEVQ8P-0-eba5497b6ae6d8db2662f6eb47858345)
定义好加法之后,我们再来定义自然数的乘法:
![](https://epubservercos.yuewen.com/7F4CCD/27732751902824706/epubprivate/OEBPS/Images/17_05.jpg?sign=1739349734-yFs1cLvYK53LBbiXjnaNi01mILApvKby-0-c1fadbab84447b4d6673a9394d56d377)
这里使用了刚定义好的加法。这一定义写成数学符号为
![](https://epubservercos.yuewen.com/7F4CCD/27732751902824706/epubprivate/OEBPS/Images/17_06.jpg?sign=1739349734-SLCnWS3C2F8U24PhqnbfXoksdxuHDnjV-0-3f7e7bf2cf565f68d2478f5b771afd30)
与通常的观念不同,加法和乘法的交换律、结合律既不是公理,也不是公设。它们都是定理,可以用皮亚诺公理和定义证明。以加法结合律为例,如图1.4所示。结合律是说(a+b)+c=a+(b+c)。我们先证明当c=0时它是对的。根据加法定义的第一条规则:
![](https://epubservercos.yuewen.com/7F4CCD/27732751902824706/epubprivate/OEBPS/Images/17_07.jpg?sign=1739349734-l3wbCw96xDsKtfe0nz5TfXwQHzmZAI6T-0-6dc5c2b1495d6c2c31ce5586f2b7713d)
然后是递推步骤,假设(a+b)+c=a+(b+c)成立,我们要推出(a+b)+c′=a+(b+c′)。
![](https://epubservercos.yuewen.com/7F4CCD/27732751902824706/epubprivate/OEBPS/Images/17_08.jpg?sign=1739349734-mWXTCIAHW1AjIkTXE1vQfMSaaU8NdXIx-0-cbf6e1c0cd1feb4f8fd3a4402266bd5e)
![](https://epubservercos.yuewen.com/7F4CCD/27732751902824706/epubprivate/OEBPS/Images/18_01.jpg?sign=1739349734-C0HcVNoKhskoQqCCifw9aZwe5110uL7t-0-a4689acb23188682298fe6fbe3df9788)
这样就证明了加法的结合律。但加法交换律的证明却并不简单,如图1.5所示,本书附录给出了完整的证明。
![](https://epubservercos.yuewen.com/7F4CCD/27732751902824706/epubprivate/OEBPS/Images/18_02.jpg?sign=1739349734-fzia9CNL3jCUoSp7Po0Mz6fZjAkbB7rW-0-95ee0043184185d91f29def72b5e21dc)
图1.4 加法结合律:上下面积相等
![](https://epubservercos.yuewen.com/7F4CCD/27732751902824706/epubprivate/OEBPS/Images/18_03.jpg?sign=1739349734-TikS0b6rzjU6k8H6m68PBCM6N1xEkcDa-0-1d219f77ec998a509a564bb8a1bbed54)
图1.5 加法交换律:将上方的图形倒过来看,或者在镜中看
练习1.1
1.定义0的后继为1,证明对于任何自然数都有a·1=a。
2.证明乘法分配律。
3.证明乘法结合律和交换律。
4.如何利用皮亚诺公理验证3+147=150?
5.试给出乘法分配律、乘法结合律和乘法交换律的几何解释。