python学数学1-2:认识数字--自然数加法


目前的数字,只能通过这样的方式来定义。
    z = zero()
    one = next(z)
    two = next(one)
    three = next(two)
    four = next(three)
而且除了定义之外,我们对这些数字还不能做什么。

让我们首先建立自然数的加法运算

我们利用归纳公理,这样定义加法的规则:

  • ①任何数N加上0都不变(N+0 => N)
  • ②任何数N加上“M的后继”,等于(N+M)的后继(N+ next(M) => next(N+M))

根据规则②,我们可以看到
N+one(N+“zero的后继”)=> N+ next(z) => next(N+z) => next(N)
N+two(等于N+“one的后继”)=> N+ next(one) => next(N+one) => next(next(N))
...
以此类推
然后我们用python的代码来实现这个规则(自然数加法nAdd)。

def nAdd(a1, a2):
    if isZero(a2):
        return a1
    return nNext(nAdd(a1, nPre(a2)))


代码说明几乎可以省略了,归纳公理,非常恰当地用递归来实现。

为了验证加法的正确性,我们再根据自然公理定义一下什么叫做两个自然数相等。
公理④说明:不同元素有不同的后继。那么显然根据逆否命题,如果两个自然数的前驱相同,就代表这两个自然数相同。

我们这样定义相等的规则:

  • ①0与0相等
  • ②0与其他任何自然数都不相等
  • ③任何两个自然数是否相等,取决于它们的前驱数是否相等

自然数相等(nEq)的代码实现如下:

def nEq(a1, a2):
    if isZero(a1) and isZero(a2):
        return True
    elif isZero(a1) or isZero(a2):
        return False
    else:
        return nEq(nPre(a1), nPre(a2))

代码说明也相当直接:如果a1和a2同时为None,肯定是相同;否则,两者任何单一为None都说明不相同。两个数字都不为None时,则取决于他们的前驱是否相同。这时,我们可以做一些测试。

from nature import *
import pytest

def test_basic():
    z = zero()
    one = nNext(z)
    two = nNext(one)
    three = nNext(two)
    four = nNext(three)
    five = nNext(four)
    a= nNext(zero())
    b= nAdd(z, one)
    c= nPre(a)
    d= nAdd(two, three)
    e= nAdd(two, four)
    # 这个时候还没有-1的定义,应当报错
    with pytest.raises(TypeError):
            minusOne= nPre(z) 
    # 不相同判断
    assert not nEq(two, one)
    assert not nEq(b, three)
    assert not nEq(four, nNext(five))
    # 相同判断
    assert nEq(z, nPre(one))
    assert nEq(d, five)
    assert nEq(e, nNext(five))
    # 加法交换律
    assert nEq(nAdd(three, four), nAdd(four, three))
    # 加法结合律
    assert nEq(nAdd(five, nAdd(three, four)), nAdd(nAdd(five, three), four))

测试用了pytest,用法相当简洁的一个测试框架。
 

猜你喜欢

转载自blog.csdn.net/xiaorang/article/details/105401992