【问题标题】:How to prove Dafny count < size如何证明 Dafny count < size
【发布时间】:2017-07-16 17:01:29
【问题描述】:

我目前正在学习 Dafny。我完全被引理弄糊涂了,我不知道如何使用它。该教程没有那么有用。如果我想证明怎么办 count(a) &lt;= |a| 我该怎么做。感谢您的帮助。

function count(a: seq<bool>): nat
ensures count(a) <= |a|;
{
   if |a| == 0 then 0 else
   (if a[0] then 1 else 0) + count(a[1..])
}

【问题讨论】:

    标签: verification formal-verification dafny


    【解决方案1】:

    你已经证明了!你写了你想要的属性作为函数的后置条件,Dafny 毫无怨言地验证它。就是这样。

    您还可以使用引理来证明该属性。这是一个例子:

    function count(a: seq<bool>): nat
    {
      if |a| == 0 then 0 else
      (if a[0] then 1 else 0) + count(a[1..])
    }
    
    lemma CountProperty(a: seq<bool>)
      ensures count(a) <= |a|
    {
    }
    

    再次,Dafny 验证了引理,没有发出任何投诉,所以你已经证明了它!

    假设 Dafny 总是会自动为您证明事情是不正确的。因此,学习如何手动编写证明也是一个好主意。这是此属性的手动证明。只是为了确保 Dafny 不会尝试自动进行归纳,我使用了一个指令将其关闭(从而使我们的生活比 Dafny 通常更难):

    lemma {:induction false} CountProperty(a: seq<bool>)
      ensures count(a) <= |a|
    {
      // Let's consider two cases, just like the definition of "count"
      // considers two cases.
      if |a| == 0 {
        // In this case, we have:
        assert count(a) == 0 && |a| == 0;
        // so the postcondition follows easily.
      } else {
        // By the definition of "count", we have:
        assert count(a) == (if a[0] then 1 else 0) + count(a[1..]);
        // We know an upper bound on the first term of the addition:
        assert (if a[0] then 1 else 0) <= 1;
        // We can also obtain an upper bound on the second term by
        // calling the lemma recursively.  We do that here:
        CountProperty(a[1..]);
        // The call we just did gives us the following property:
        assert count(a[1..]) <= |a[1..]|;
        // Putting these two upper bounds together, we have:
        assert count(a) <= 1 + |a[1..]|;
        // We're almost done.  We just need to relate |a[1..]| to |a|.
        // This is easy:
        assert |a[1..]| == |a| - 1;
        // By the last two assertions, we now have:
        assert count(a) <= 1 + |a| - 1;
        // which is the postcondition we have to prove.
      }
    }
    

    编写此类证明的更好方法是使用经过验证的计算,Dafny 将其称为“计算语句”:

    lemma {:induction false} CountProperty(a: seq<bool>)
      ensures count(a) <= |a|
    {
      if |a| == 0 {
        // trivial
      } else {
        calc {
          count(a);
        ==  // def. count
          (if a[0] then 1 else 0) + count(a[1..]);
        <=  // left term is bounded by 1
          1 + count(a[1..]);
        <=  { CountProperty(a[1..]); }  // induction hypothesis gives a bound for the right term
          1 + |a[1..]|;
        ==  { assert |a[1..]| == |a| - 1; }
          |a|;
        }
      }
    }
    

    我希望这能让你开始。

    安全编程,

    鲁斯坦

    【讨论】:

      猜你喜欢
      • 2020-11-21
      • 2022-11-21
      • 1970-01-01
      • 2021-03-10
      • 2021-12-30
      • 2020-01-27
      • 1970-01-01
      • 2019-10-18
      • 2020-04-07
      相关资源
      最近更新 更多