Z3中的可判定sqrt函数

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的方法

因为,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
的方法表明,通过引入辅助变量,所有实根都可以被推入
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
更符合我的用例