【发布时间】:2018-04-13 03:25:02
【问题描述】:
下面是在数组中找到最大数的函数, 所以教授教我们证明部分正确性。 他给出了证明循环不变量保持不变的解决方案。 任何人都可以向我解释解决方案吗?
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
解决方案。 我们首先计算循环体的wp 以保持 LI(循环不变量):
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)不弱于上面计算的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
【问题讨论】:
-
注意:您的功能是一个返回整数的函数。因此,它应该有一个名称的名词短语,而不是动词短语。 Rational Eiffel 编码标准,您不会说“列表中的 find_maximum 值是多少?”或“你想要 get_fries 吗?”
标签: algorithm induction eiffel correctness