Z3中的可判定sqrt函数

时间:2016-06-23 16:59:32

标签: z3

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中,我怎样才能在实数中定义一个能产生可判定理论的平方根函数?

1 个答案:

答案 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)))形式的语句来表明yx的平方根。这样的断言在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); } 更符合我的用例。