我正在尝试将OpenJML与Z3结合使用,我试图推断double
或float
值:
class Test {
//@ requires b > 0;
void a(double b) {
}
void b() {
a(2.4);
}
}
我已经发现OpenJML使用AUFLIA
作为默认逻辑,不支持reals
。我现在正在使用AUFNIRA
。
不幸的是,该工具无法证明此类:
→ java -jar openjml.jar -esc -prover z3_4_3 -exec ./z3 Test.java -noInternalSpecs -logic AUFNIRA
Test.java:8: warning: The prover cannot establish an assertion (Precondition: Test.java:3: ) in method b
a(2.4);
^
Test.java:3: warning: Associated declaration: Test.java:8:
//@ requires b > 0;
^
2 warnings
为什么会这样?
答案 0 :(得分:9)
当涉及双打时,SMT翻译(用作z3
的输入)似乎有问题。在下面的程序B中,使用双精度而不是整数,调用或前置条件的常量永远不会被转换为SMT 。
这是openjml
的错误,而不是z3
- 因为z3
需要使用(define-fun _JML__tmp3 () Real 2345.0)
形式的某些内容(参见程序A的详细输出),但是openjml
从不生成它。一般来说,floating point support seems to be buggy。
计划A (带有整数):
class Test {
//@ requires b > 1234;
void a(int b) { }
void z() { a(2345); }
}
输出(与-verbose | grep 234
一起运行,以在详细输出中搜索1234
或2345
的提及):
// requires b > 1234;
Pre_1 = b > 1234;
// requires b > 1234;
assume Assignment Pre_1_0_21___4 == b_55 > 1234;
(assert (= BL_58bodyBegin_2 (=> (= _JML___exception_49_49___1 NULL) (=> (= _JML___termination_49_49___2 0) (=> (distinct THIS NULL) (=> (or (= THIS NULL) (and (and (distinct THIS NULL) (javaSubType (javaTypeOf THIS) T_Test)) (jmlSubType (jmlTypeOf THIS) JMLT_Test))) (=> (and (<= (- 2147483648) b_55) (<= b_55 2147483647)) (=> (select _isalloc___0 THIS) (=> (= (select _alloc___0 THIS) 0) (=> (= Pre_1_0_21___3 false) (=> (= Pre_1_0_21___4 (> b_55 1234)) (=> Pre_1_0_21___4 BL_49_AfterLabel_3))))))))))))
a(2345);
// a(2345)
int _JML__tmp3 = 2345;
boolean _JML__tmp6 = _JML__tmp3 > 1234;
// a(2345)
int _JML__tmp3 = 2345
boolean _JML__tmp6 = _JML__tmp3 > 1234
(define-fun _JML__tmp3 () Int 2345)
(define-fun _JML__tmp6 () Bool (> _JML__tmp3 1234))
结果:
EXECUTION
Proof result is unsat
Method checked OK
[total 427ms]
计划B (双打):
class Test {
//@ requires b > 1234.0;
void a(double b) { }
void z() { a(2345.0); }
}
输出(与-verbose | grep 234
一起运行,以在详细输出中搜索1234.0
或2345.0
的提及):
// requires b > 1234.0;
Pre_1 = b > 1234.0;
// requires b > 1234.0;
assume Assignment Pre_1_0_29___4 == b_72 > 1234.0;
a(2345.0);
// a(2345.0)
double _JML__tmp3 = 2345.0;
boolean _JML__tmp6 = _JML__tmp3 > 1234.0;
// a(2345.0)
double _JML__tmp3 = 2345.0
boolean _JML__tmp6 = _JML__tmp3 > 1234.0
void z() { a(2345.0); }
//@ requires b > 1234.0;
Test.java:4: a(2345.0)
VALUE: 2345.0 === 0.0
结果:
EXECUTION
Proof result is sat
Some assertion is not valid
Test.java:4: warning: The prover cannot establish an assertion (Precondition: Test.java:2: ) in method z
void z() { a(2345.0); }
^
Test.java:2: warning: Associated declaration: Test.java:4:
//@ requires b > 1234.0;
^
答案 1 :(得分:0)
您可以在以下链接中看到它们如何解释规范何时不完整。您的案例显示的行为与链接中的示例相同。即使您尝试其他数字也会失败,因为您需要添加更多openjml子句。