归纳规范:自上而下 vs 自下而上 vs 推理规则?
Posted
技术标签:
【中文标题】归纳规范:自上而下 vs 自下而上 vs 推理规则?【英文标题】:Inductive Specification: Top-down vs Bottom-up vs Rules of Inference? 【发布时间】:2012-02-28 13:29:49 【问题描述】:请多多包涵。我将首先描述书中的一个例子,然后在最后提出我的问题。
根据编程语言范式上的文字:
归纳规范是指定一组 价值观。为了说明这种方法,我们用它来描述某个 自然数 N = 0, 1, 2, . . ..
自上而下的定义:
一个自然数n在S中当且仅当
-
n = 0,或
n -3 ∈ S.
我们知道 0 ∈ S。因此 3 ∈ S,因为 (3 − 3) = 0 并且 0 ∈ S。类似地 6 ∈ S,因为 (6−3) = 3 和 3 ∈ S。继续这样,我们 可以得出结论,3的所有倍数都在S中。
其他自然数呢? 1 ∈ S 吗?我们知道 1 != 0,所以 第一个条件不满足。此外,(1−3) = −2,这不是自然的 数,因此不是 S 的成员。因此,第二个条件 不满意。
自下而上的定义:
定义集合 S 为 N 中包含且满足的最小集合 以下两个属性:
-
0 ∈ S,且
如果 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
这只是先前版本定义的简写符号。 每个条目被称为一个推理规则,或者只是一个规则;水平的 行被读作“如果-那么”。线以上的部分称为假设 或先行词;线以下的部分称为结论或结果。 当列出两个或多个假设时,它们通过以下方式连接 一个隐含的“和”
现在问题来了。
可能最重要的问题是为什么我需要了解这些归纳定义,以及它们在实际案例中有何用处? 为什么 Google 几乎没有返回归纳定义的结果? 如果自上而下、自下而上和推理规则本质上显示相同的内容,为什么我们需要 3 种方式来编写相同的内容? 为什么我很难找到比本书示例更复杂的问题的归纳定义,如下所示。我想找到以下 2 个问题的自上而下、自下而上和推理定义。您不必给我答案,但我确实想知道如何推导出归纳定义。我从哪里开始?是否有解决此类问题的系统方法(秘诀)?
1. 2n+3m +1 | n,m ∈ N
2. (n, 2n+1) | n ∈ N
【问题讨论】:
【参考方案1】:您在这里问了很多问题,所以希望这个回复能回答所有问题。如果您有什么想澄清的,请告诉我。
您的第一个问题 - 为什么我们需要归纳定义? - 最容易回答。在计算机科学中,大量的结构被归纳定义。例如,您的简单链表具有归纳定义
空列表是链表。 单个节点后跟链表就是链表或者二叉树:
空树是二叉树。 具有两个作为二叉树的子节点的节点是二叉树。或正则表达式:
∅ 是一个正则表达式。 ε 是一个正则表达式。 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 树是平衡的。
我们可以类似地使用这些类型的定义来证明有关编程语言的属性。大多数语言都有某种归纳定义,因此通过证明程序的每个部分都保留了一些信息,我们可以从头开始构建正确性证明。
您的第二个问题 - 为什么 Google 不提供归纳定义的任何示例? - 我认为是因为它将其解释为“定义归纳”,而不是一个术语本身。如果你查看递归定义,你会发现很多归纳定义的例子,因为归纳定义和递归定义非常相似。
您的第三个问题 - 为什么我们需要多种方式来表达同一件事? - 也很容易。如果您想证明有关系统的某些内容,归纳定义非常好。如果您证明它适用于基本元素,然后证明较大的元素保留了该属性,您可以证明它总是正确的。递归定义有利于编写程序,因为递归函数倾向于向后运行归纳。推理规则与逻辑证明系统相关联,并为使用经典逻辑证明系统属性提供了一个起点。
您的第四个问题 - 为什么找不到任何示例? - 可以通过花一分钟时间查看您所知道的经典数据结构和算法来轻松解决。你可以归纳定义多少个数据结构?尝试查看链表、二叉树、红黑树、AVL 树等以获得灵感。您将如何定义图表? DAG?同样,尝试查看句法结构。例如,您将如何归纳定义平衡括号的字符串? C 中的函数原型怎么样?
您的最后一个问题 - 是否有解决这些问题的系统方法? - 有否定的答案。您可以定义等效于在输入上模拟任意图灵机的递归,并且由于停止问题是不可判定的,因此没有解决此类问题的通用程序。但是,确实存在许多方法。尝试查看 Graham、Knuth 和 Patashnik 的“具体数学”,以获取有关如何通过重复进行工作的灵感。
希望这会有所帮助!
【讨论】:
【参考方案2】:除了“使用你的大脑”之外,没有系统的方法。 但是你很幸运,因为这两个例子确实非常接近原始例子:
1
。如果 a) k = 1
或 b) k-2 ∈ S
或 c) k-3 ∈ S
,则自然数 k 在 S 中
1
。 a) 0 ∈ S
b) If n ∈ S, then n+2 ∈ S
c) If n ∈ S, then n+3 ∈ S
2
。如果 a) k=0 and l=1
或 b) (k-1, l-2) ∈ S
,则一对自然数 (k,l) 在 S 中
2
。 a) (0,0) ∈ S
b) If (k,l) ∈ S, then (k+1, l+2) ∈ S
【讨论】:
【参考方案3】:为什么我需要知道这些归纳定义,以及它们在实际案例中有何用处?
归纳定义可用于:
-
证明关于集合成员的属性。例如lambda terms 可以归纳定义,然后您可以证明有关这些术语的定理。您将使用一种称为Structural Induction 的证明技术。
编写操作集合成员的函数。我们在函数式编程中一直这样做。例如列表可以归纳定义。然后使用algebraic data type 在代码中表示该归纳定义,然后我们可以在列表上编写函数,如下面的
length
函数。另一个例子是归纳图,看看这篇论文Inductive Graphs and Functional Graph Algorithms。
type List a
= Empty
| Cons a (List a)
length : List a -> Int
length list =
case list of
Empty ->
0
Cons _ xs ->
1 + length xs
为什么 Google 几乎没有返回归纳定义的结果?
我不知道,但是这个 book 有一个很好的章节(第 3 章 - 构造技术),其中包含大量示例。
为什么我们需要 3 种方式来编写相同的东西?
不同的视角为您提供了不同的方式来思考同一件事,它们可以帮助您塑造自己的直觉。阅读Developing Your Intuition for Math。在这种特殊情况下,自上而下的定义适用于计算对象何时是集合的成员,而自下而上的定义(推理规则只是自下而上定义的简写)适用于生成集合的成员.
为什么我很难找到比书中示例更复杂的问题的归纳定义。
我在上面分享的这本书Discrete Structures, Logic, and Computability (4th Edition),在第 3 章中有大量示例和练习,供您分别理解和练习。
如何推导归纳定义?我从哪里开始?
感受集合中的元素。我将首先列出集合中的一些元素,看看它们如何相互关联。我会寻找不能用更简单的元素来定义的基本元素,然后从这些基本元素中我会寻找我可以写下哪些规则来获取其他元素。
在你尝试了几个小时之前不要看。
Answer 到 1。
Answer 到 2。
有系统的方法吗?
没有。解决问题。提出想法并进行测试。阅读 Polya 的 How to Solve It 以培养您解决问题的能力。
【讨论】:
以上是关于归纳规范:自上而下 vs 自下而上 vs 推理规则?的主要内容,如果未能解决你的问题,请参考以下文章