使用方法结果时发生dafny断言冲突

使用方法结果时发生dafny断言冲突,dafny,Dafny,我编写了下面的程序来验证数组是否“干净”任何特定元素。我很难断言该方法的结果。当我试图断言方法的结果时,我不断得到断言冲突 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 (

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

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;
  
}


您需要在
isClean
上提供一个
assured
子句。当Dafny验证一个程序时,它一次只查看一个
方法。因此,当Dafny验证
Main
时,它根本不查看
isClean
的定义。相反,它只查看
requires
确保
子句

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

ensures clean <==> (forall k :: 0 <= k < a.Length ==> a[k] != key)
在调用
isClean
之后,发送到
Main
的主体


为清楚起见,以下是程序的完整版本,用于验证:

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;
}
methodmain(){
变量a:=新整数[3];
a[0],a[1],a[2]:=1,2,3;
var v:=isClean(a,1);
断言一个[0]==1;
断言v==false;
}
方法isClean(a:array,key:int)返回(clean:bool)
需要a。长度>0
确保干净(对于所有k::0 a[k]!=键)
{
变量i:=0;
while(i不变0您需要在
isClean
上给出一个
assured
子句。当Dafny验证一个程序时,它一次只查看一个
方法
。因此当Dafny验证
Main
时,它根本不查看
isClean
的定义。相反,它只查看
requires
assured
条款

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

ensures clean <==> (forall k :: 0 <= k < a.Length ==> a[k] != key)
在调用
isClean
之后,发送到
Main
的主体


为清楚起见,以下是程序的完整版本,用于验证:

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;
}
methodmain(){
变量a:=新整数[3];
a[0],a[1],a[2]:=1,2,3;
var v:=isClean(a,1);
断言一个[0]==1;
断言v==false;
}
方法isClean(a:array,key:int)返回(clean:bool)
需要a。长度>0
确保干净(对于所有k::0 a[k]!=键)
{
变量i:=0;
while(i谢谢你,詹姆斯。你总是那么乐于助人,这很有意义。詹姆斯。你总是那么乐于助人,这很有意义