Algorithm 证明程序的部分正确性
下面是查找数组中最大数的函数, 所以教授教我们证明部分正确性。 他给出了证明循环不变量保持不变的解。 有人能给我解释一下解决办法吗Algorithm 证明程序的部分正确性,algorithm,induction,eiffel,correctness,Algorithm,Induction,Eiffel,Correctness,下面是查找数组中最大数的函数, 所以教授教我们证明部分正确性。 他给出了证明循环不变量保持不变的解。 有人能给我解释一下解决办法吗 find_max (a: ARRAY [INTEGER]): INTEGER require not_empty: a.count > 0 local i: INTEGER do from i := a.lower Result := a [i] invari
find_max (a: ARRAY [INTEGER]): INTEGER
require
not_empty: a.count > 0
local
i: INTEGER
do
from
i := a.lower
Result := a [i]
invariant
−− Predicate Equivalent: ∀j | a.lower ≤ j < i • Result ≥ a[j]
across a.lower |..| (i − 1) as j all Result >= a [j.item] end
until
i > a.upper
loop
-- { ∀j ∣ a.lower ≤ j < i ● Result ≥ a [j] ∧ ¬(i > a.upper) }
if a [i] > Result then
Result := a [i]
end
-- { ∀j ∣ a.lower ≤ j < i ● Result ≥ a [j] }
i := i + 1
variant
a.upper − i + 1
end
ensure
−− Predicate Equivalent: ∀j | a.lower ≤ j ≤ a.upper • Result ≥ a[j]
across ... all ... end
end
然后,我们证明前提条件,即退出条件和LI不弱于上述计算的wp:
¬(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
总体方案
后条件Q的函数
可以从循环不变量L导出
这是非常正确的,因为j的范围是空的
让我们找出循环最薄弱的前提条件,前提是在每次迭代结束时,L应该为真。在回路内部,根据出口条件i≤ a、 上,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在循环之后满足,因此,当函数返回时,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在上面的公式中替换为真时,就会发生这种情况=⇒ wp S,P变为wp S,P和-b=⇒ wp T,P为真,因此整个公式简化为wp S,P。类似的推理适用,如果我们假设b为假,第一部分为真,第二部分为wp T,P
非常感谢你,亚历山大,你能帮我再做一件事吗?我不知道我们如何证明这一点=⇒ wp S,P∧ -b=⇒ wp T,P在条件前提规则中?我认为这句话的意思是表明b不是较弱的,然后是最弱的先决条件,对吗?@NoorAhmed,我们确实可以这么说。然而,有一个更好的直觉——假设b为真,最弱的前提条件是wp S,P。我已经用解释更新了答案。注意:你的特性是一个返回整数的函数。因此,它应该有一个名词短语作为名称,而不是动词短语。Rational Eiffel编码标准,您不会说“列表中的find_最大值是多少?”或“您想用它来获得薯条吗?”
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]
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))