为什么Z3中的运算符'/'和'div'给出不同的结果?

时间:2014-09-24 22:30:45

标签: z3

我试图用两个整数表示一个实数,用它们作为实数的分子和分母。我写了以下程序:

(declare-const a Int)
(declare-const b Int)
(declare-const f Real)

(assert (= f (/ a b)))
(assert (= f 0.5))
(assert (> b 2))
(assert (> b a))

(check-sat)
(get-model)

该程序返回SAT结果如下:

sat
(model 
  (define-fun f () Real
    (/ 1.0 2.0))
  (define-fun b () Int
    4)
  (define-fun a () Int
    2)
)

但是,如果我写'(assert(= f(div a b)))'而不是'(assert(= f(/ a b)))',那么结果就是UNSAT。为什么div不会返回相同的结果?

而且,对我来说主要关注的是,我没有找到在z3 .Net API中使用运算符'/'的方法。我只能看到函数MkDiv,它实际上是运算符'div'。是否有一种方法可以在z3 .Net API的情况下应用运算符'/'?提前谢谢。

1 个答案:

答案 0 :(得分:3)

严格来说,这两个公式都不符合SMT-LIB2,因为/是一个接收两个Real输入并产生Real输出的函数,而div是一个接受两个Int输入的函数产生一个Int(见SMT-LIB Theories)。 Z3更放松并自动转换这些对象。如果我们启用选项smtlib2_compliant=true,那么它确实会在两种情况下报告错误。

div版本不可满足的原因是f根据(= f (/ a b))确实没有解决方案,但确实没有满足{{1}的整数}}