在使用 leon 和有理数时,我遇到了以下问题:inverse1
函数的验证给出了一个反例,但它没有多大意义,而inverse2
验证。
import leon.lang._
case class Rational (n: BigInt, d: BigInt) {
def +(that: Rational): Rational = {
require(isRational && that.isRational)
Rational(n * that.d + that.n * d, d * that.d)
} ensuring { _.isRational }
def *(that: Rational): Rational = {
require(isRational && that.isRational)
Rational(n * that.n, d * that.d)
} ensuring { _.isRational }
def <=(that: Rational): Boolean = {
require(isRational && that.isRational)
if (that.d * d > 0)
n * that.d <= d * that.n
else
n * that.d >= d * that.n
}
def ==(that: Rational): Boolean = {
require(isRational && that.isRational)
//that <= this && this <= that
true // for testing purpose of course!
}
// fails to verify
def inverse1: Rational = {
require(isRational && nonZero)
Rational(d, n)
}.ensuring { res => res.isRational && res.nonZero && res * this == Rational(1, 1) }
// verifies
def inverse2: Rational = {
require(isRational && nonZero)
Rational(d, n)
}.ensuring { res => res.isRational && res.nonZero /*&& res * this == Rational(1, 1)*/ }
def isRational = !(d == 0)
def nonZero = n != 0
}
莱昂给我的反例是这样的:
[ Info ] - Now considering 'postcondition' VC for Rational$inverse1 @33:16...
[ Error ] => INVALID
[ Error ] Found counter-example:
[ Error ] $this -> Rational(-2, -2)
但从数学上讲,这没有任何意义。
我期待这段代码调用==
我定义的运算符,但由于这个总是返回true
并且函数没有验证,我倾向于不这样认为......
有人可以指出这个程序有什么问题或我对 Scala/leon 的理解吗?谢谢。