下面是在数组中找到最大数字的函数, 所以教授教我们证明部分正确性。 他给出了证明循环不变的解决方案。 任何机构都可以向我解释解决方案吗?
wp (if a[i] > Result then Result := a[i] end; i := i + 1,
∀j | a.lower ≤ j ≤ i − 1 • a.lower ≤ j ∧ j ≤ a.upper ∧ Result ≥ a [j])
= {wp rule for seq. comp. }
wp (if a[i] > Result then Result := a[i] end, wp (i := i + 1,
∀j | a.lower ≤ j ≤ i − 1 • a.lower ≤ j ∧ j ≤ a.upper ∧ Result ≥ a [j]))
= {wp rule for assignment}
wp (if a[i] > Result then Result := a[i] end,
∀j | a.lower ≤ j ≤ i • a.lower ≤ j ∧ j ≤ a.upper ∧ Result ≥ a [j])
= {wp rule for conditional}
a [i] > Result =⇒ wp (Result := a[i],
∀j | a.lower ≤ j ≤ i • a.lower ≤ j ∧ j ≤ a.upper ∧ Result ≥ a [j])
∧
a [i] ≤ Result =⇒ wp (Result := Result,
∀j | a.lower ≤ j ≤ i • a.lower ≤ j ∧ j ≤ a.upper ∧ Result ≥ a [j])
= {wp rule for assignment, twice}
a [i] > Result =⇒ ∀j | a.lower ≤ j ≤ i • a.lower ≤ j ∧ j ≤ a.upper ∧ a [i] ≥ a[j]
∧
a [i] ≤ Result =⇒ ∀j | a.lower ≤ j ≤ i • a.lower ≤ j ∧ j ≤ a.upper ∧ Result ≥ a[j]
解决方案。我们首先计算循环体的¬(exit condition)
以维持LI(循环不变量):
¬(i > a.upper) ∧ ( ∀j | a.lower ≤ j ≤ i − 1 • a.lower ≤ j ∧ j ≤ a.upper ∧ Result ≥ a[j] ) =⇒ a [i] > Result =⇒
∀j | a.lower ≤ j ≤ i • a.lower ≤ j ∧ j ≤ a.upper ∧ a [i] ≥ a [j]
∀j | a.lower ≤ j ≤ i • a.lower ≤ j ∧ j ≤ a.upper ∧ a [i] ≥ a [j]
≡ {split range: ∀j | a.lower ≤ j ≤ i • P (j) ≡ (∀j | a.lower ≤ j ≤ i − 1) ∧ P (i)}
(∀j | a.lower ≤ j ≤ i - 1 • a.lower ≤ j ∧ j ≤ a.upper ∧ a[i] ≥ a[j]) ∧
(a.lower ≤ i ∧ i ≤ a.upper ∧ a[i] ≥ a[i])
≡ {antecedent: a[i] > Result; and RHS of precond: ∀j | a.lower ≤ j ≤ i − 1 • a.lower ≤ j ∧ j ≤ a.upper ∧ Result ≥ a[j]}
true ∧ (a.lower ≤ i ∧ i ≤ a.upper ∧ a[i] ≥ a[i])
≡ {LHS of precond: ¬(i > a.upper) and a[i] ≥ a[i] ≡ true}
(Exercise )
true
然后我们证明前提条件(即{{1}}和LI)并不弱于上面计算的wp:
{{1}}
答案 0 :(得分:0)
功能后置条件 Q
∀j | a.lower ≤ j ≤ a.upper • Result ≥ a [j]
可以从循环不变 L
派生∀j | a.lower ≤ j < i • Result ≥ a [j]
考虑循环退出条件i > a.upper
。假设i
在每次迭代时在循环中递增1
,则满足退出条件的第一个值为i = a.upper + 1
。将此值替换为 L 会产生 Q 。因此,在第一次迭代之前证明 L 为真并且由循环保留就足够了。
对于第一次迭代(i := a.lower
和Result := a [i]
),循环不变量变为
∀j | a.lower ≤ j < a.lower • Result ≥ a [j]
这是非常正确的(因为j
的范围是空的。)
让我们找到循环中最弱的前提条件,条件是在每次迭代结束时, L 应该为真。在循环内部,根据退出条件i ≤ a.upper
, L 相当于
∀j | a.lower ≤ j ≤ i − 1 • a.lower ≤ j ∧ j ≤ a.upper ∧ Result ≥ a [j]
反过来,使用最弱前提条件(见下文),可以简化为两个谓词的结合
a [i] > Result =⇒ ∀j | a.lower ≤ j ≤ i • a.lower ≤ j ∧ j ≤ a.upper ∧ a [i] ≥ a[j]
a [i] ≤ Result =⇒ ∀j | a.lower ≤ j ≤ i • a.lower ≤ j ∧ j ≤ a.upper ∧ Result ≥ a[j]
如解决方案中所示,第一个减少为真,假设退出条件不满足且循环不变 L 在循环体之前为真。第二个谓词也可以这样做。
考虑到在循环的第一次迭代之前满足 L 并且每次迭代都保留了 L ,我们得出结论,在循环之后满足 L ,因此,当函数返回时, Q 为真。
上面列出的证据依赖于以下最弱的先决条件规则:
顺序组成
wp (S;T, P) = wp (S, wp (T, P))
分配
wp (x := e, P) = P [e/x]
条件
wp (if b then S else T end, P) = (b =⇒ wp (S, P)) ∧ (¬b =⇒ wp (T, P))
解释。 b
的值事先未知。但是,如果我们假设b
为真,则整个指令减少到S
,最弱的前提条件应为wp (S, P)
。实际上,当上面的公式中b
替换为True
时会发生这种情况(b =⇒ wp (S, P)
变为wp (S, P)
而¬b =⇒ wp (T, P)
变为True
,所以整个公式减少到wp (S, P)
)。如果我们假设b
为False
(第一部分变为True
而第二部分变为wp (T, P)
),则类似的推理也适用。