英文:
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:
- Why doesn't this verify?
{
for i:= 0 to 10
{
assert IsPerfectSquare(i*i);
}
}
- 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 >= 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:
- Why doesn't this verify?
method Main()
{
for i:= 0 to 10
{
assert IsPerfectSquare(i*i);
}
}
- 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 >= 0
{
IsPerfectSquareFunctional(n, 0)
}
predicate {:fuel 10} 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)
}
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 >= 0
{
exists k : int :: 0 <= k && k * k == n
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论