Z3 在QF_UFNRA中得到实的分数部分
使用smtlib,我想使用QF_UFNRA制作一些类似模的东西。这使我无法使用mod,to_int,to_real这样的东西 最后,我想在下面的代码中得到z的分数部分:Z3 在QF_UFNRA中得到实的分数部分,z3,smt,cvc4,Z3,Smt,Cvc4,使用smtlib,我想使用QF_UFNRA制作一些类似模的东西。这使我无法使用mod,to_int,to_real这样的东西 最后,我想在下面的代码中得到z的分数部分: (set-logic QF_UFNRA) (declare-fun z () Real) (declare-fun z1 () Real) (define-fun zval_1 ((x Real)) Real x ) (declare-fun zval (Real) Real) (assert (= z 1
(set-logic QF_UFNRA)
(declare-fun z () Real)
(declare-fun z1 () Real)
(define-fun zval_1 ((x Real)) Real
x
)
(declare-fun zval (Real) Real)
(assert (= z 1.5));
(assert (=> (and (<= 0.0 z) (< z 1.0)) (= (zval z) (zval_1 z))))
(assert (=> (>= z 1.0) (= (zval z) (zval (- z 1.0)))))
(assert (= z1 (zval z)))
(设置逻辑QF\u UFNRA)
(声明funz()真实)
(声明乐趣z1()真实)
(定义fun zval_1((x Real))Real
x
)
(宣布有趣的zval(真实)真实)
(断言(=z 1.5));
(断言(=>(和(>=z1.0)(=(zvalz)(zval(-z1.0);)))
(断言(=z1(zvalz)))
当然,正如我在这里提出的这个问题所暗示的,它没有成功
有人知道如何使用逻辑QF_UFNRA将z的分数部分转换成z1吗?这是一个很好的问题。不幸的是,如果你将自己限制在
QF_UFNRA
,你想做的通常是不可能的
如果你能对这样的函数进行编码,那么你就可以决定任意的丢番图方程。你只需将给定的丢番图方程转换成实,计算“分数”用这种所谓的方法求出实解,并断言分数是0
。由于实是可判定的,这将给你一个丢番图方程的判定过程,完成不可能的事情。(这被称为希尔伯特第十个问题。)
因此,尽管任务看起来很简单,但实际上是不可行的。但这并不意味着你不能用一些扩展对其进行编码,也可能让解算器成功地决定它的实例
如果允许使用量词和递归函数
如果允许自己使用量词和递归函数,则可以编写:
(set-logic UFNRA)
(define-fun-rec frac ((x Real)) Real (ite (< x 1) x (frac (- x 1))))
(declare-fun res () Real)
(assert (= (frac 1.5) res))
(check-sat)
(get-value (res))
请注意,我们使用了允许量化的UFNRA
逻辑,由于使用了define-fun-rec
构造,这里隐式要求量化。(有关详细信息,请参阅SMTLib手册。)这基本上就是您在问题中试图编码的内容,但使用递归函数定义工具而不是隐式编码。但是,在SMTLib中使用递归函数时有几个注意事项:特别是,您可以编写使系统不一致的函数。有关详细信息,请参阅的第4.2.3节细节
如果你能用QF_UFNIRA
如果移动到QF_UFNIRA
,即允许混合实数和整数,则编码很容易:
(set-logic QF_UFNIRA)
(declare-fun z () Real)
(declare-fun zF () Real)
(declare-fun zI () Int)
(assert (= z (+ zF zI)))
(assert (<= 0 zF))
(assert (< zF 1))
(assert (= z 1.5))
(check-sat)
(get-value (zF zI))
(当z<0
时,您可能必须小心计算zI
,但想法是一样的。)
请注意,仅仅因为编码简单并不意味着z3总是能够成功地回答查询。由于混合了Real
和Integer
,问题仍然无法确定,如前所述。如果您对z
有其他限制,z3很可能会对该编码作出unknown
的响应。在这种特殊情况下,它恰好足够简单,因此z3能够找到一个模型
如果您有sin
和pi
:
这与其说是一个真正的替代方案,不如说是一个思维实验。如果SMTLib允许sin
和pi
,那么您可以检查sin(zI*pi)是否
为0
,对于适当约束的zI
。此查询的任何令人满意的模型都将确保zI
为整数。然后可以使用此值通过从z
中减去zI
来提取小数部分
但这是徒劳的,因为SMTLib既不允许sin
也不允许pi
。而且有很好的理由:可判定性将丢失。话虽如此,也许一些勇敢的灵魂可以设计一种支持sin
,pi
等的逻辑,并成功地正确回答您的查询,同时在pr这个问题对于解算器来说太难了。非线性算法和QF_UFNIRA
片段已经是这样了:解算器通常会放弃,但它使用的启发式方法可能会解决实际感兴趣的问题
对理性的限制
从理论上来说,如果你把自己局限于理性(而不是实际的现实)然后你就可以写一个一阶公式来识别整数了。然而,这种编码并不适合心脏虚弱的人。此外,由于编码涉及量词,SMT解算器很可能无法很好地处理基于这种思想的公式
[顺便说一句,我应该感谢我的同事们;这个问题在午餐时间进行了一次精彩的交谈!]谢谢你的回答!实际上,我的问题是(和是)近似sin(和其他三角函数)作为SMT问题。为了实现这一点,我希望将传入变量计算为0。您应该检查
dReal
:。我个人没有使用过它,但它声称使用δ-可满足性的概念支持三角函数。(一般来说,这个问题是无法确定的,但是如果你考虑到一定的精度损失,可以检查可满足性。)另外:如果你可以转移到定理证明环境中,MetiTarski是一个支持超验的强大工具:我尝试了dReal3。非常好,但缺少模型和未经测试的核心。只是让你知道。
(set-logic QF_UFNIRA)
(declare-fun z () Real)
(declare-fun zF () Real)
(declare-fun zI () Int)
(assert (= z (+ zF zI)))
(assert (<= 0 zF))
(assert (< zF 1))
(assert (= z 1.5))
(check-sat)
(get-value (zF zI))
sat
((zF (/ 1.0 2.0))
(zI 1))