IsPerfectSquare(Dafny)

huangapple go评论50阅读模式
英文:

IsPerfectSquare (Dafny)

问题

I have this IsPerfectSquare predicate that is used in post/pre conditions and invariants. It can't be a method.

    requires n >= 0
{
    IsPerfectSquareFunctional(n, 0)
}

predicate IsPerfectSquareFunctional(n: int, sqrt_candidate: int) 
    requires n >= 0
    requires sqrt_candidate >= 0
    decreases n - sqrt_candidate
{
    // Unfortunately, this is not valid Dafny
    //exists k: int :: 0 <= k && k * k == n
    if sqrt_candidate * sqrt_candidate >= n then sqrt_candidate*sqrt_candidate == n
    else IsPerfectSquareFunctional(n, sqrt_candidate+1)
}

Two questions:

  1. Why doesn't this verify?
{
    for i:= 0 to 10
    {
        assert IsPerfectSquare(i*i);
    }
}
  1. Is there any way of expressing the postcondition of the predicate with an existential? Because that's the natural way of expressing what a perfect square is.

Thanks.

英文:

I have this IsPerfectSquare predicate that is used in post/pre conditions and invariants. It can't be a method.

predicate IsPerfectSquare(n: int)
    requires n &gt;= 0
{
    IsPerfectSquareFunctional(n, 0)
}

predicate IsPerfectSquareFunctional(n: int, sqrt_candidate: int) 
    requires n &gt;= 0
    requires sqrt_candidate &gt;= 0
    decreases n - sqrt_candidate
{
    // Unfortunately, this is not valid Dafny
    //exists k: int :: 0 &lt;= k &amp;&amp; k * k == n
    if sqrt_candidate * sqrt_candidate &gt;= n then sqrt_candidate*sqrt_candidate == n
    else IsPerfectSquareFunctional(n, sqrt_candidate+1)
}

Two questions:

  1. Why doesn't this verify?
method Main()
{
    for i:= 0 to 10
    {
        assert IsPerfectSquare(i*i);
    }
}
  1. Is there any way of expressing the postcondition of the predicate with an existential? Because that's the natural way of expressing what a perfect square is.

Thanks.

答案1

得分: 0

在函数的后置条件缺失情况下,Dafny使用定义的展开来验证断言。Dafny将展开限制在由燃料参数控制的固定深度上。

添加足够的燃料将使程序验证。

predicate IsPerfectSquare(n: int)
  requires n >= 0
{
  IsPerfectSquareFunctional(n, 0)
}

predicate {:fuel 10} IsPerfectSquareFunctional(n: int, sqrt_candidate: int) 
  requires n >= 0
  requires sqrt_candidate >= 0
  decreases n - sqrt_candidate
{
  // 不幸的是,这不是有效的Dafny
  //exists k: int :: 0 <= k && k * k == n
  if sqrt_candidate * sqrt_candidate >= n then sqrt_candidate*sqrt_candidate == n
  else IsPerfectSquareFunctional(n, sqrt_candidate+1)
}

method Main()
{
  for i:= 0 to 10
    {
      assert IsPerfectSquare(i*i);
    }
}

回答您的第二个问题,可以在幽灵上下文中使用存在性来表示一个数是完全平方数。

ghost predicate IsPerfectSquare(n: int)
  requires n >= 0
{
   exists k : int :: 0 <= k && k * k == n
}
英文:

In absence of post condition of function, Dafny uses unrolling of definition to verify assertion. Dafny restricts unrolling up to fixed depth controlled by fuel parameter.

Adding sufficient fuel will make program verify.

predicate IsPerfectSquare(n: int)
  requires n &gt;= 0
{
  IsPerfectSquareFunctional(n, 0)
}

predicate {:fuel 10} IsPerfectSquareFunctional(n: int, sqrt_candidate: int) 
  requires n &gt;= 0
  requires sqrt_candidate &gt;= 0
  decreases n - sqrt_candidate
{
  // Unfortunately, this is not valid Dafny
  //exists k: int :: 0 &lt;= k &amp;&amp; k * k == n
  if sqrt_candidate * sqrt_candidate &gt;= n then sqrt_candidate*sqrt_candidate == n
  else IsPerfectSquareFunctional(n, sqrt_candidate+1)
}


method Main()
{
  for i:= 0 to 10
    {
      assert IsPerfectSquare(i*i);
    }
}

To answer your second question, it is possible to express number is square using existential in ghost context

ghost predicate IsPerfectSquare(n: int)
  requires n &gt;= 0
{
   exists k : int :: 0 &lt;= k &amp;&amp; k * k == n
}

huangapple
  • 本文由 发表于 2023年6月13日 10:14:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76461323.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定