繁体   English   中英

不确定为什么此 Dafny 验证失败

[英]Unsure why this Dafny verification fails

function method abs(m: int): nat
{ if m>0 then m else -m }

method CalcTerm(m: int, n: nat) returns (res: int)
  ensures res == 5*m-3*n;
{
  var m1: nat := abs(m);
  var n1: nat := n;
  res := 0;

  while (m1!=0)
    invariant m1>=0
    invariant 0<=res
    invariant res <=5*abs(m)
    decreases m1
  {
    res := res+5;
    m1 := m1-1;
  }
  if (m<0) { res := -res; }

  while (n1!=0)
    invariant n1>=0 
    decreases n1
  {
    res := res-3;
    n1 := n1-1;
  }
}

我试图增加循环中的不变性。 在第一个循环中,我添加了条件 res<=5*abs(m) 但 Dafny 抱怨“这个循环不变量可能不会由循环维护”。 我不明白怎么不是。

我可能做错了什么?

如果通过在每次迭代后准确说明res等于什么来使循环不变性更强,Dafny 将能够验证它。

因此,在第一个 while 循环中,使用invariant res == 5*abs(m) - 5*m1而不是invariant res <= 5*abs(m) 当循环终止时, m1等于 0,因此res将为5*abs(m)

类似地,对于第二个 while 循环,定义invariant res == 5*m - 3*n + 3*n1 现在当这个循环终止时, n1等于 0,所以res将是5*m - 3*n并且 Dafny 将能够证明该方法的后置条件成立。

PS 我通常使用> 0而不是!= 0作为循环条件。

进行这些更改后,您将拥有:

function method abs(m: int): nat
{
    if m > 0 then m else -m
}

method CalcTerm(m: int, n: nat) returns (res: int)
    ensures res == 5*m - 3*n;
{
    var m1: nat := abs(m);
    var n1: nat := n;
    res := 0;

    while (m1 > 0)
        invariant m1 >= 0;
        invariant 0 <= res;
        invariant res == 5*abs(m) - 5*m1;
        decreases m1;
    {
        res := res + 5;
        m1 := m1 - 1;
    }
    if (m < 0)
    {
        res := -res;
    }

    while (n1 > 0)
        invariant n1 >= 0;
        invariant res == 5*m - 3*n + 3*n1;
        decreases n1;
    {
        res := res - 3;
        n1 := n1 - 1;
    }
}

在 Dafny 中进行验证。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM