证明程序的部分正确性

时间:2018-04-13 03:25:02

标签: algorithm induction eiffel correctness

下面是在数组中找到最大数字的函数, 所以教授教我们证明部分正确性。 他给出了证明循环不变的解决方案。 任何机构都可以向我解释解决方案吗?

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

1 个答案:

答案 0 :(得分:0)

一般方案

  1. 功能后置条件 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 为真并且由循环保留就足够了。

  2. 对于第一次迭代(i := a.lowerResult := a [i]),循环不变量变为

    ∀j | a.lower ≤ j < a.lower • Result ≥ a [j]
    

    这是非常正确的(因为j的范围是空的。)

  3. 让我们找到循环中最弱的前提条件,条件是在每次迭代结束时, 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 在循环体之前为真。第二个谓词也可以这样做。

  4. 考虑到在循环的第一次迭代之前满足 L 并且每次迭代都保留了 L ,我们得出结论,在循环之后满足 L ,因此,当函数返回时, Q 为真。

  5. 最弱的前提规则

    上面列出的证据依赖于以下最弱的先决条件规则:

    1. 顺序组成

      wp (S;T, P) = wp (S, wp (T, P))
      
    2. 分配

      wp (x := e, P) = P [e/x]
      
    3. 条件

      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))。如果我们假设bFalse(第一部分变为True而第二部分变为wp (T, P)),则类似的推理也适用。