0

一个非常简单的乘法代码:

method Product1 (m: nat, n: nat) returns (res:nat) 
ensures res == m * n;      
{  
    var m1: nat := 0; 
    var n1: nat := 0; 
    res := 0; 
    while (m1 < m)    
    { 
        n1 := 0; 
        while (n1 < n)  
        { 
            res := res + 1;
            n1 := n1 + 1; 
        } 
        m1 := m1 + 1; 
    } 
}

当我用 dafny 验证它时,它说:

    Description                                        Line Column
1   A postcondition might not hold on this return path. 8   4
2   This is the postcondition that might not hold.      2   16

我明白它在某些条件下会说 res != m*n,但我无法弄清楚。

4

2 回答 2

3

更新!

在在线网站上尝试了 dafny ,看起来它是错误?

method Test(m: nat) returns (r: nat) 
{
  var m1: nat := 0;
  while (m1 < m) {
    m1 := m1 + 1;
  }
  assert m == m1; // fail assert
}

更多尝试:

method Test(m: nat) returns (r: nat) 
{
  var m1: nat := 0;
  while (m1 < m) {
    assert m1 < m;
    m1 := m1 + 1;
  }
  assert !(m1 < m);   // pass
  assert m1 == m || m1 > m;  // pass
  assert m1 == m;  // fail
}

经过一番深入了解,我知道它应该使用Loop Invariantsfor dafny 来解决这个问题。

我修改后的代码:

method Product1 (m: nat, n: nat) returns (res:nat) 
ensures res == m * n;      
{  
    var m1: nat := 0; 
    var n1: nat := 0; 
    res := 0; 
    while (m1 < m)
    invariant 0 <= m1 <= m
    invariant res == m1 * n
    { 
        var temp: nat := res; 
        n1 := 0; 
        while (n1 < n)
        invariant 0 <= n1 <= n
        invariant res == temp+n1   
        { 
            res := res + 1;
            n1 := n1 + 1; 
        } 
        m1 := m1 + 1; 
    }
    assert m1 == m;  // success
}

然后删除 tmp var:

method Product1 (m: nat, n: nat) returns (res:nat) 
ensures res == m * n;      
{  
    var m1: nat := 0; 
    var n1: nat := 0; 
    res := 0; 
    while (m1 < m)
    invariant 0 <= m1 <= m
    invariant res == m1 * n
    {
        n1 := 0; 
        while (n1 < n)
        invariant 0 <= n1 <= n
        invariant res == n1 + m1*n  
        { 
            res := res + 1;
            n1 := n1 + 1; 
        } 
        m1 := m1 + 1; 
    }
    assert m1 == m;  // success
}
于 2016-09-14T02:19:50.760 回答
0

您的循环没有任何循环不变量。至少,两个循环都需要不变量。否则,Dafny 将无法弄清楚循环之后的内容......

于 2016-09-14T23:00:24.757 回答