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))