从disabling unsound simplification of root objects开始,Z3现在将在这个涉及平方根的简单模型上失败:
(define-fun sqrt ((x Real)) Real (^ x 0.5))
(declare-fun y () Real)
(declare-fun x () Real)
(assert (= y (sqrt x)))
(check-sat)
这将返回sat
与Z3 4.4.1,但unknown
与主。
如果我将问题定义更改为使用this question中Nikolaj定义的is_sqrt
,则Z3 master将返回sat
。使用is_sqrt
的方法表明,通过引入辅助变量可以将所有真实的根推入QF_NRA
,所以我认为Z3应该能够解决涉及实数上的根的所有问题。
如果假设模型的其余部分位于QF_NRA
中,我怎样才能在实数中定义一个能产生可判定理论的平方根函数?
答案 0 :(得分:1)
(assert (= y (^ x 0.5)))
和(assert (and (= x (* y y)) (> y 0.0)))
之间存在细微差别。不同之处在于要求Z3(和SMT-LIB)中的所有功能都是总计。这意味着,例如,y=1/x, x=0
is considered satisfiable。鉴于Z3中^
总计,(assert (and (= y (^ x 0.5)) (< x 0.0)))
被认为是可以满足的。我们无法将(= y (^ x 0.5))
转换为(and (= x (* y y)) (> y 0.0))
,因为如果x < 0
那么前者被认为是可以满足的,但后者是不可满足的。同样,SMT-LIB中定义的任何sqrt
函数也将是总计,因此我们无法通过任何其他方式定义sqrt
函数,以使(assert (= y (sqrt x)))
等效于(assert (and (= x (* y y)) (> y 0.0)))
。除了y = sqrt(x), x < 0
(伪代码)是否被认为是可满足的上述差异之外,(assert (and (= x (* y y)) (> y 0.0)))
是可判定的(它在QF_NRA中),而(assert (= y (^ x 0.5)))
是不
出于我的目的,解决方案是不对平方根使用Z3或SMT-LIB函数定义。相反,我将使用(assert (and (= x (* y y)) (> y 0.0)))
形式的语句来表明y
是x
的平方根。这样的断言在QF_NRA内,因此以这种方式构建的模型将是可判定的。此外,如果y = sqrt(x), x < 0
(伪代码)通过语句unsat
和(assert (and (= x (* y y)) (> y 0.0)))
在SMT-LIB中表示,则其优势在于(assert (< x 0.0))
(伪代码)将返回unsat
。要为此示例返回public void UserClickedButtonNumbered(int digitNumber)
{
Debug.Log("that button name is " +digitNumber);
}
更符合我的用例。