z3 在同时使用 Floats 和 Reals 时返回未知?

z3 returning unknown when using Floats and Reals together?

当我在同一个 .smt2 文件中使用 Floats 和 Reals 时,我注意到这通常会导致结果“未知”。我已经看到这个提到 here 但是自从这个答案以来已经过去了一段时间我想问问我是否只是没有使用正确的设置(例如我是否应该在 check-sat 中将策略作为参数传递线?或缩小设置逻辑?)

这是一个展示该行为的示例:

(set-logic ALL)
(set-option :produce-models true)
(set-info :smt-lib-version 2.6)

(set-info :status unknown)
(define-sort FPN () (_ FloatingPoint  8  24))

(declare-fun a () Real)
(declare-fun b () Real)
(declare-fun c () Real)

(declare-fun x0 () FPN)
(declare-fun y0 () FPN)
(declare-fun z0 () FPN)

(declare-fun x1 () FPN)
(declare-fun y1 () FPN)
(declare-fun z1 () FPN)

(define-fun fun ( (x FPN) (y FPN) (z FPN) (arg0 Real) (arg1 Real) (arg2 Real)) FPN (fp.add RNE 
                                                                                           (fp.add RNE (fp.mul RNE ((_ to_fp 8 24) RNE arg0) x)
                                                                                                       (fp.mul RNE ((_ to_fp 8 24) RNE arg1) y))
                                                                                           (fp.mul RNE ((_ to_fp 8 24) RNE arg2) z)) )

(assert (fp.eq x0 ((_ to_fp 8 24) RNE 1)))
(assert (fp.eq y0 ((_ to_fp 8 24) RNE 0)))
(assert (fp.eq z0 ((_ to_fp 8 24) RNE 0)))

(assert (fp.eq x1 ((_ to_fp 8 24) RNE 0)))
(assert (fp.eq y1 ((_ to_fp 8 24) RNE 0)))
(assert (fp.eq z1 ((_ to_fp 8 24) RNE 0)))

(assert
  (fp.gt (fun x0 y0 z0 a b c) (fun x1 y1 z1 a b c))
)


(check-sat)
(get-info :reason-unknown)
(get-model)
(exit)

非常感谢您的任何回复!

恐怕从那时起就没有太大变化。像这样混合浮点数和实数会给 SMT 求解器带来非常困难的问题。您可以在 z3 问题跟踪器 (https://github.com/Z3Prover/z3/issues) 上提交特定案例以提醒开发人员,唉,我怀疑很快就会有很大改进。

请注意,尝试其他求解器总是一个好主意。 CVC5 和 MathSAT 都同时支持浮点数和实数。不幸的是,当我针对你的问题调用 mathsat 时,它会因语法错误而出错(我认为这是 mathsat 本身的错误),但 CVC5 确实找到了以下模型:

(
(define-fun a () Real (/ 1 4294967296))
(define-fun b () Real (- 1.0))
(define-fun c () Real (- 1.0))
(define-fun x0 () (_ FloatingPoint 8 24) (fp #b0 #b01111111 #b00000000000000000000000))
(define-fun y0 () (_ FloatingPoint 8 24) (fp #b0 #b00000000 #b00000000000000000000000))
(define-fun z0 () (_ FloatingPoint 8 24) (fp #b0 #b00000000 #b00000000000000000000000))
(define-fun x1 () (_ FloatingPoint 8 24) (fp #b0 #b00000000 #b00000000000000000000000))
(define-fun y1 () (_ FloatingPoint 8 24) (fp #b0 #b00000000 #b00000000000000000000000))
(define-fun z1 () (_ FloatingPoint 8 24) (fp #b0 #b00000000 #b00000000000000000000000))
)

我还没有检查模型是否真的有效,但好消息是 CVC5 可以处理这个问题out-of-the-box(而且速度很快。)