使用Z3和SMT-LIB最多获得两个值

Joh*_*ith 3 smt z3

如何使用smt-lib2获得最大公式?

我想要这样的东西:

(declare-fun x () Int)
(declare-fun y () Int)
(declare-fun z () Int)
(assert (= x 2))
(assert (= y 4))
(assert (= z (max x y))
(check-sat)
(get-model)
(exit)
Run Code Online (Sandbox Code Playgroud)

当然,smtlibv2不知道'max'.那么,怎么做呢?

pad*_*pad 8

在Z3中,您可以轻松定义宏max并使用它来获取最多两个值:

(define-fun max ((x Int) (y Int)) Int
  (ite (< x y) y x))
Run Code Online (Sandbox Code Playgroud)

max使用未解释的函数进行建模还有另一个技巧,这将有助于与Z3 API一起使用:

(declare-fun max (Int Int) Int)
(assert (forall ((x Int) (y Int))
    (= (max x y) (ite (< x y) y x))))
Run Code Online (Sandbox Code Playgroud)

请注意,您必须设置(set-option :macro-finder true),因此Z3能够在检查可满足性时用函数体替换通用量词.

  • 列表的最大值更复杂.define-fun只是宏,不允许递归.选项`:macro-finder`不会检测"递归宏".你仍然可以为max-int-list编写一个"forall"公理.但是,Z3不会完整.也就是说,它可能会返回"未知".更确切地说,对于任何可满足的问题,它将返回"未知",并且对于一些不可满足的问题,可以通过Z3中使用的默认搜索限制来解决.在Z3的未来版本中,我们可以扩展归纳数据类型过程来处理折叠定义. (2认同)