如何从函数中得出循环不变式?

时间:2019-04-11 22:37:43

标签: proof-of-correctness

此函数的循环不变性是什么?如何从该函数中导出它?

我一直在学习算法,以准备进一步的学习,但无法理解如何得出循环不变式。

private LocalDate birth = LocalDate.of(2000, 1, 0)

1 个答案:

答案 0 :(得分:0)

循环不变式是变量,条件等,它们在整个循环中不会改变。查找不变式的目的是弄清楚每次循环访问/假定哪些变量不需要重新计算/重新加载/重新建立。

不变值是在整个循环中不会改变的值,另一方面,不变条件通常更多地是关于正确性,例如确保不同的线程不会修改循环所遍历的数据结构。但是到那时,您可能会说不变有点重载。在这种情况下,您似乎只是在追求不变值。

因此,如果要查找循环不变值,它们将是a21和第二个{{1} }。

编辑:

我现在看到这不是一个实际的编程问题;这是计算机科学问题,可能属于CS SE。话虽如此,我想我能帮上忙。您应从this网站上的第1步开始。

总结:

  1. 将循环转换为更加熟悉的1循环。
  2. 手动运行一些迭代。
  3. 尝试找到一种模式,该模式为您提供了未按返回值递归定义的返回值公式。您希望它仅取决于当前迭代计数和循环中使用的其他变量/值。

步骤1

请注意,可以将代码转换为以下for循环:

for

现在,我们可以看到c = 1 for (b = 1; b <= a; b = b + 1) c = c * 2 + 1 end for 只是循环变量,而b是循环边界。为了使事情更清楚,我们可以将其编写为更传统的c样式a循环:

for

步骤2

c = 1;
for (i = 1; i <= n; i++) {
    c = c * 2 + 1;
}

步骤3

在其中查找一个模式,该模式将输出变量i_0: c = ? = 1 // Don't forget the initial value! Call that iteration 0. i_1: c = 1 * 2 + 1 = 3 i_2: c = 3 * 2 + 1 = 7 i_3: c = 7 * 2 + 1 = 15 i_4: c = 15 * 2 + 1 = 63 与当前迭代c相关联。

请注意,在这种情况下,i是指循环的当前迭代,而不是代码中变量i的值。

请注意,出现2幂幂模式:i

实际上可能会出现不止一个。我们怎么知道这是否有效?这就是基本迭代和归纳步骤的目的。

插入c_i = 2^(i+1) - 1进行迭代可以得到0,这为我们提供c_0 = 2^(0+1)-1 = 2-1 = 1的起始值,所以很好。

对于归纳步​​骤,我们需要显示c。问题是,我们不能只说一句而已。我们还需要c_(i+1) = 2^(i+2) - 1等于的其他内容。

幸运的是,这正是代码所提供的,这是一个用于计算新值c_(i+1)的公式,其中给出了上一次迭代的值c,其形式如下:

c = c * 2 + 1

我们假定不变式是正确的,并将其插入c_(i+1) = c_i * 2 + 1。然后,将整个事物设置为等于c_i

2^(i+2) - 1

c_(i+1) = (2^(i+1) - 1) * 2 + 1 = 2^(i+2) - 1

我们满足了基本情况和归纳步骤,因此我们知道我们的不变式是正确的。我们还证明了,因为循环在迭代时终止 (2^(i+1) - 1) * 2 + 1 = 2*2^(i+1) - 2 + 1 = 2^(i+2) - 1n

TL; DR

替换原始变量:

循环不变式:c = 2^(n+1) - 1
c = 2^(b+1) - 1maxint(a)