Z3中的可判定sqrt函数
因为,Z3现在将在这个涉及平方根的简单模型上失败:Z3中的可判定sqrt函数,z3,Z3,因为,Z3现在将在这个涉及平方根的简单模型上失败: (define-fun sqrt ((x Real)) Real (^ x 0.5)) (declare-fun y () Real) (declare-fun x () Real) (assert (= y (sqrt x))) (check-sat) 这将返回Z3 4.4.1中的sat,但主程序返回unknown。 如果我将问题定义更改为使用Nikolaj在中定义的issqrt,那么Z3 master将返回sat。使用is_sqrt的方法
(define-fun sqrt ((x Real)) Real (^ x 0.5))
(declare-fun y () Real)
(declare-fun x () Real)
(assert (= y (sqrt x)))
(check-sat)
这将返回Z3 4.4.1中的sat
,但主程序返回unknown
。
如果我将问题定义更改为使用Nikolaj在中定义的issqrt
,那么Z3 master将返回sat
。使用is_sqrt
的方法表明,通过引入辅助变量,所有实根都可以被推入QF_NRA
,因此我认为Z3应该能够解决所有涉及实上根的问题
假设模型的其余部分在
QF_NRA
中,我如何在实数中定义一个平方根函数,从而产生一个可判定的理论?在(assert(=y(^x 0.5))
和(assert(and(=x(*y))(>y0.0))
之间有细微的区别。不同之处在于要求Z3(和SMT-LIB)中的所有函数都是合计的。例如,这意味着。考虑到Z3中的^
总计,(断言(和(=y(^x 0.5))(
被认为是可满足的。我们不能将(=y(^x 0.5))
转换为(和(=x(*y))(>y 0.0))
,因为如果x<0
,则前者被认为是可满足的,但后者是不可满足的。类似地,SMT-LIB中定义的任何sqrt
函数也将是总计的,因此我们不能通过任何其他方式定义sqrt
函数,使得(assert(=y(sqrt x))
等同于(assert(and(=x(*y))(>y0.0))
。除了上述关于y=sqrt(x),x<0
(伪代码)是否被认为是可满足的区别之外,同样的情况是(断言(和(=x(*y))(>y0.0))
是可判定的(它在QF_NRA中),而(断言(=y(^x0.5))
是不可判定的
我的解决方案是不使用Z3或SMT-LIB函数定义平方根。相反,我将使用形式为(assert(和(=x(*y))(>y0.0))
的语句来指示y
是x
的平方根。这种断言在QF_NRA中,因此以这种方式构建的模型是可判定的。此外,如果通过语句(assert(和(=x(*y))(>y0.0))
和(assert(
在SMT-LIB中表示unsat
,则这具有这样的优势。在本例中,返回unsat
更符合我的用例