我一直在建模任务中使用抽象的引理和函数(没有实体)。在这个例子中,
lemma py(c : int) returns (a: int, b :int)
ensures a*a + b*b == c*c
lemma main(c : int) returns (a: int, b :int)
ensures a*a + b*b == c*c
{
a, b := py(c);
}
在main中调用py确保后置条件为真,而不管py是如何实现的。我有两个问题:
在Dafny中使用抽象的引理/函数是否安全? Dafny对以上代码进行了以下修改:
lemma py(c : int) returns (a: int, b :int)
ensures a*a + b*b == c*c
ensures a*a + b*b != c*c
虽然我认为可能是Dafny应该抛出错误。
我应该说lemma {:axiom} py(...)
吗?我没有发现包括{:axiom}
或{:imported}
。
答案 0 :(得分:1)
正如詹姆斯所提到的,在建模你未实施的行为时,没有身体的引理会很有用。如果您不给身体,则验证者不会尝试验证引理的正确性。因此,它本质上是一个公理。
即使没有James提到的/noCheating
标志,Dafny编译器也会抱怨没有身体的引理(以及方法和功能)。请注意,在验证器满足之后,编译器才会启动。 {:axiom}
属性表示您愿意接受引理真相的责任。对于无体非重影方法,您还可以使用{:extern}
属性,该属性允许您链接使用其他语言编写的代码。同样,您对该外部代码的正确性负责,因为Dafny验证程序无法检查它。
Rustan
答案 1 :(得分:0)
在对您未实施的系统部分进行建模时,没有实体的方法和函数确实很有用。
但是,在提供后置条件的这些方法和函数时必须要小心,因为那些变为可信,并且不会被Dafny检查。换句话说,如果它们具有后置条件,那么在没有实体的情况下使用lemma或函数可能不安全。
也就是说,这些方法和功能对于建模是必不可少的,因此它们可能不安全的事实并不意味着你不应该使用它们。相反,在写下后置条件时,你应该格外小心,因为它们不会被检查。
如果你传递Dafny /noCheating:1
标志,它会抱怨没有具有后置条件的实体的任何方法或函数,并强制你使用{:axiom}
属性。即使没有传递/noCheating:1
,这也很有用,只是为了标记后置条件是可信的这一事实。是否通过/noCheating:1
或是否仍然使用该属性取决于您。