Methods 用不变量乘Dafny中两个整数的简便方法

Methods 用不变量乘Dafny中两个整数的简便方法,methods,dafny,Methods,Dafny,此Q3方法通过将m0与res | n0 |次相加,对n0*m0进行换算。如果n0为负,我们将n0和m0反转为n0*m0=-n0*-m0保持不变 我的问题是,我不知道我的不变量应该是什么样子,因为不变量必须是布尔类型。有人能告诉我不变布尔条件是什么样子吗?我考虑过Abs((n0)-n)*m==res,但这不起作用 method Q3(n0 : int, m0 : int) returns (res : int) ensures n0*m0 == res { var n, m : int;

Q3
方法通过将m0与res | n0 |次相加,对n0*m0进行换算。如果n0为负,我们将n0和m0反转为n0*m0=-n0*-m0保持不变

我的问题是,我不知道我的不变量应该是什么样子,因为不变量必须是布尔类型。有人能告诉我不变布尔条件是什么样子吗?我考虑过Abs((n0)-n)*m==res,但这不起作用

method Q3(n0 : int, m0 : int) returns (res : int)
  ensures n0*m0 == res
{

  var n, m : int;
  res := 0;
  if (n0 >= 0) 
     {n,m := n0, m0;} 
  else 
     {n,m := -n0, -m0;}

  while (0 < n) 
  invariant Abs((n0)-n)*m
  { 
    res := res + m; 
    n := n - 1; 
  }
}

function Abs(x: int): int
{
  if x < 0 then -x else x
}
方法Q3(n0:int,m0:int)返回(res:int)
确保n0*m0==res
{
var n,m:int;
res:=0;
如果(n0>=0)
{n,m:=n0,m0;}
其他的
{n,m:=-n0,-m0;}
而(0
当尝试设计循环不变量时,首先向后工作会很有帮助。循环终止后,您需要知道什么

对于这种方法,一旦循环终止,您将需要建立后置条件
n0*m0==res
,因此这是循环不变量的起点

由于
res
被循环更改,
n0*m0==res
本身不是一个不变量。相反,我们必须思考循环如何朝着这个目标“取得进展”。这个循环通过将
m
添加到
res
中来取得进展,粗略地说,这样做总共是
n
次。当
n
为0时,循环终止

一个常见的模式在这里很有用:不变量应该讨论“到目前为止”做了什么以及“剩下要做什么”。在本例中,到目前为止所做的是
res
,剩下的是
n
添加的
m
。循环的每一次迭代都需要做一件剩余的工作,并保持不变

换句话说,这个循环的一个很好的不变量是
res+n*m==n0*m0

此外,还有一节介绍循环不变量,这可能会有所帮助