我试图用两个整数表示一个实数,用它们作为实数的分子和分母。我写了以下程序:
(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的情况下应用运算符'/'?提前谢谢。
答案 0 :(得分:3)
严格来说,这两个公式都不符合SMT-LIB2,因为/
是一个接收两个Real输入并产生Real输出的函数,而div
是一个接受两个Int输入的函数产生一个Int(见SMT-LIB Theories)。 Z3更放松并自动转换这些对象。如果我们启用选项smtlib2_compliant=true
,那么它确实会在两种情况下报告错误。
div
版本不可满足的原因是f
根据(= f (/ a b))
确实没有解决方案,但确实没有满足{{1}的整数}}