归纳规范:自上而下 vs 自下而上 vs 推理规则?

Sah*_*bov 5 theory math recursion logic induction

请多多包涵。我将首先描述书中的一个例子,然后在最后提出我的问题。

根据编程语言范式的文本:

归纳指定是指定一组值的强大方法。为了说明这个方法,我们用它来描述 自然数 N = {0, 1, 2, ... . .} .

自上而下的定义:

一个自然数 n 在 S 中当且仅当

  1. n = 0,或
  2. ? 3 ? S。

我们知道 0 ? S. 因此 3 ? S,因为 (3 ? 3) = 0 和 0 ? S. 同样 6 ? S,因为 (6?3) = 3 和 3 ? S. 以这种方式继续,我们可以得出结论,所有 3 的倍数都在 S 中。

其他自然数呢?是 1 吗?? 我们知道 1 != 0,所以不满足第一个条件。此外,(1?3) = ?2,它不是自然数,因此不是 S 的成员。因此不满足第二个条件。

自下而上的定义:

定义集合 S 为包含在 N 中的最小集合,并满足以下两个性质:

  1. 0 ? 沙
  2. 如果 n ? S,然后 n +3 ?S。

“最小集合”是满足性质 1 和 2 的集合,并且是满足性质 1 和 2 的任何其他集合的子集。很容易看出只能有一个这样的集合:如果 S1 和 S2 都满足性质1 和 2,而且都是最小的,那么 S1 ? S2(因为 S1 最小),而 S2 ? S1(因为 S2 最小),因此 S1 = S2。我们需要这个额外的条件,否则有很多集合满足剩下的两个条件

推理规则:

_____
0 ? S

n ? S
---------
(n+3) ? S
Run Code Online (Sandbox Code Playgroud)

这只是之前版本定义的简写符号。每个条目都称为推理规则,或者只是规则;水平线读作“if-then”。线以上的部分称为假设前提;线以下的部分称为结论结果。当列出两个或多个假设时,它们通过隐含的“和”连接起来


现在问题来了。

  • 可能最重要的问题是为什么我需要知道这些归纳定义,以及它们在现实世界中的用途?
  • 为什么 Google 在 Inductive Definition 上几乎没有返回任何结果?
  • 如果自顶向下、自底向上和推理规则本质上显示相同的东西,为什么我们需要 3 种方式来编写相同的东西?
  • 为什么我很难找到比书中例子更复杂的问题的归纳定义,如下所示。

我想找到以下 2 个问题的自上而下、自下而上和推理的定义。您不必给我答案,但我确实想知道如何推导出归纳定义。我从哪里开始?是否有解决此类问题的系统方法(食谱)?

1. {2n+3m +1 | n,m ? N}
2. {(n, 2n+1) | n ? N}
Run Code Online (Sandbox Code Playgroud)

tem*_*def 3

您在这里问了很多问题,所以希望这个答复能够回答所有问题。如果您想澄清一些事情,请告诉我。

你的第一个问题——为什么我们需要归纳定义?- 最容易回答。在计算机科学中,大量的结构是通过归纳定义的。例如,您的简单链表具有归纳定义

  • 空列表是一个链表。
  • 单个节点后面跟的链表就是链表

或者二叉树:

  • 空树是二叉树。
  • 具有两个二叉树子节点的节点是二叉树。

或者正则表达式:

  • ∅ 是正则表达式。
  • ε 是正则表达式。
  • a 是每个字符 a 的正则表达式
  • 如果R1和R2是正则表达式,则R1 | R2 是正则表达式。
  • 如果R1和R2是正则表达式,则R1 R2是正则表达式。
  • 如果 R 是正则表达式,则 R* 也是正则表达式。
  • 如果R是正则表达式,则(R)是正则表达式。

这些定义有许多很好的属性。首先,它们适合递归算法。如果要访问二叉树中的每个节点,我们可以使用二叉树的归纳定义来构建一个简单的访问算法:

  • 访问空树时,无需执行任何操作。
  • 访问由一个节点和两个子树组成的树:
    • 访问节点
    • 访问左子树
    • 访问右子树

类似地,如果我们想要操纵正则表达式的结构(例如,可能为其构建匹配的自动机),那么归纳定义可以让我们从正则表达式分段构建自动机。

归纳定义也可用于形式化证明结构的属性。例如,下面是 AVL 树的正式定义:

  • 单个节点是0阶AVL树
  • 如果一个节点有一个或两个子节点是 0 阶 AVL 树,那么该节点就是 1 阶 AVL 树。
  • 具有两个子节点(均为 n - 1 阶 AVL 树)的节点,或者具有一个子节点(为 n - 1 阶 AVL 树)和另一个子节点(为 n - 3 阶 AVL 树)的节点,是一棵 n 阶 AVL 树。

使用这个定义,可以正式证明 AVL 树是平衡的。

我们可以类似地使用这些类型的定义来证明编程语言的属性。大多数语言都有某种归纳定义,因此通过证明程序的每个部分都保留了一些信息,我们可以从头开始构建正确性证明。

你的第二个问题 - 为什么谷歌没有提供任何归纳定义的例子?- 我认为是因为它将其解释为“定义归纳法”,而不是一个术语本身。如果你查找递归定义,那么您会发现大量归纳定义的示例,因为归纳定义和递归定义彼此非常相似。

你的第三个问题——为什么我们需要多种方式来表达同一件事?- 也很容易。如果你想证明一个系统的某些东西,归纳定义是很好的选择。如果你证明它适用于基本元素,然后证明较大的元素保留该属性,你就可以证明它总是正确的。递归定义有利于编写程序,因为递归函数倾向于向后运行归纳。推理规则与逻辑证明系统相关,并为使用经典逻辑证明系统的属性提供了起点。

你的第四个问题——为什么你找不到任何例子?- 只需花一分钟时间查看您所知道的经典数据结构和算法即可轻松修复。您可以归纳定义多少种数据结构?尝试查看链表、二叉树、红黑树、AVL 树等来获取灵感。你会如何定义图表?有向无环图?同样,尝试查看句法结构。例如,您将如何归纳定义平衡括号字符串?C 语言中的函数原型怎么样?

您的最后一个问题 - 是否有系统的方法来解决这些问题?- 有否定的答案。您可以定义相当于在输入上模拟任意图灵机的递归,并且由于停止问题是不可判定的,因此没有解决此类问题的通用过程。不过,确实存在许多方法。尝试阅读 Graham、Knuth 和 Patashnik 所著的《具体数学》,以获取有关如何处理递归的灵感。

希望这可以帮助!