在Dafny中使用不变量乘以两个整数的简单方法

时间:2017-12-14 14:12:12

标签: methods dafny

Q3方法通过将m0添加到res | n0 |来传递n0 * m0倍。如果n0为负,我们将n0和m0反转为n0 * m0 = -n0 * -m0成立。

我遇到的问题是我不知道我的不变量应该是什么样子,因为不变量必须是boolean类型。任何人都能告诉我不变的布尔条件是什么样的吗?我想过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
}

1 个答案:

答案 0 :(得分:1)

在尝试设计循环不变量时,首先向后工作会很有帮助。循环终止后你需要知道什么?

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

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

一个常见的模式在这里很有用:不变量应该讨论“到目前为止”所做的事情以及“剩下要做什么”。在这种情况下,到目前为止所执行的操作是res,剩下要做的是剩余的n m添加res + n * m == n0 * m0。循环的每次迭代都需要做一件工作,并且保持不变量。

换句话说,这个循环的良好不变量是M <- matrix(NA, nrow = max(v), ncol = sum(v == 1)) M[cbind(v, cumsum(v == 1))] <- unlist(df, use.names = FALSE) M # [,1] [,2] [,3] [,4] # [1,] -0.5604756 1.558708 0.07050839 0.1292877 # [2,] -0.2301775 NA NA 1.7150650 # [3,] NA NA NA 0.4609162

此外,Dafny Tutorial有一个关于循环不变量的部分,这可能会有所帮助。