繁体   English   中英

使用方法的结果时违反 dafny 断言

[英]dafny assertion violation when using the result of a method

我编写了下面的程序来验证数组是否“干净”了任何特定元素。 我无法断言该方法的结果。 尝试断言方法的结果时,我不断收到断言冲突。

method Main (){
 
  
  var a:= new int[3];
  
  a[0], a[1], a[2] := 1,2,3;
  var v := isClean (a, 1);
  assert v == false;

}



method isClean (a : array <int>, key : int) returns (clean : bool)
  
  requires a.Length > 0


{
  
  var i := 0;
  
  while (i < a.Length)
  
  invariant 0 <= i <= a.Length
  invariant forall k :: 0 <= k < i ==> a[k] != key
  
  {
    
    if (a[i] == key) {
      
      clean := false;
      return;
    }
    
    i := i + 1;
    
  }
  
  clean := true;
  
}

Dafny 2.3.0.10506
stdin.dfy(8,11): Error: assertion violation

Dafny program verifier finished with 2 verified, 1 error

你需要给一个ensures的条款isClean 当 Dafny 验证程序时,它一次只查看一种method 所以当 Dafny 验证Main ,它根本不看isClean的定义。 相反,它只查看requiresensures子句。

您已经在循环不变式中完成了证明的困难部分。 基本上,您只需要修改该不变量的副本,使其在调用者的上下文中有意义,作为ensures子句,如下所示:

ensures clean <==> (forall k :: 0 <= k < a.Length ==> a[k] != key)

(在isClean上的requires子句的正下方添加它。)在此ensures子句中, clean指的是isClean方法的命名返回值。 如果你添加这个子句,Dafny 仍然会抱怨,因为你要求它证明一个forall量词是false 这相当于试图证明exists量词true ,并且需要一个明确的“见证人”,它是使公式主体变成true / falsek值。

在这种情况下, isClean返回false的直观原因是因为a[0]的值为 1,因此a不是 1 的“干净”。我们可以通过添加断言向 Dafny 展示这个“见证”

assert a[0] == 1;

到身体Main的呼叫后立即isClean


为清楚起见,这里是一个完整的程序版本,用于验证:

method Main() {
  var a := new int[3];
  a[0], a[1], a[2] := 1,2,3;
  var v := isClean (a, 1);
  assert a[0] == 1;
  assert v == false;
}

method isClean(a: array <int>, key: int) returns (clean: bool)
  requires a.Length > 0
  ensures clean <==> (forall k :: 0 <= k < a.Length ==> a[k] != key)
{
  var i := 0;
  while (i < a.Length)
    invariant 0 <= i <= a.Length
    invariant forall k :: 0 <= k < i ==> a[k] != key
  {
    if (a[i] == key) {
      clean := false;
      return;
    }
    i := i + 1;
  }
  clean := true;
}

暂无
暂无

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

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