【问题标题】:Proving the partial correctness of the program证明程序的部分正确性
【发布时间】: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


【解决方案1】:

一般方案

  1. 函数后置条件Q

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

    可以从循环不变量L

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

    通过考虑循环退出条件i &gt; 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.upperL相当于

    ∀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 在循环之后得到满足,因此,当函数返回时,Q 为真。

最弱前置条件规则

上述证明依赖于以下最弱的前置条件规则:

  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)),类似的推理也适用。

【讨论】:

  • 非常感谢你,alexander,你能帮我做一件事吗?我无法弄清楚我们如何证明这一点(b =⇒ wp(S,P))∧(¬b =⇒ wp (T, P)) 在条件前置条件规则中?我认为这句话的意思是表明 b 不弱于最弱的前提条件是否正确?
  • @NoorAhmed,我们确实可以这么说。但是,有一个更好的直觉——“假设b 为真,最弱的前提是wp (S, P)”。我已经用解释更新了答案。
猜你喜欢
  • 1970-01-01
  • 2013-07-28
  • 1970-01-01
  • 1970-01-01
  • 2015-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多