通过Java实现在Z3中定义一个函数?

时间:2016-05-22 13:38:04

标签: z3 smt

所以这就是我要做的事情。

让我们说我希望在类似于此的表达式中使用Z3(及其Java绑定)找到op的值:

((exists (op Int)) (= (foo op) 2)

所以我想在foo变量上调用一个函数op并检查函数返回的操作值是哪个。我想在Java中定义一个函数foo并认为存在Z3访问这些函数定义的一种方法。我想这样做,因为函数实际上是在HashMap中查找,很容易在Java中实现。

由于我一般是SMT求解器的初学者,所以我可能想做一些无法做到的事情。因此,我对所有关于该主题的建议持开放态度。

提前感谢您的时间和答案!

1 个答案:

答案 0 :(得分:2)

这将是非常好的,但目前Z3不能使用其他语言/ API的函数定义。对于查找表的情况,它应该很容易,因为它们可以很容易地编码为if-then-else级联,例如如下:

;; define foo
(define-fun foo ((x Int)) Int
    (ite (= x 1) 42
    (ite (= x 2) 43
    ;; ...
                 78)))

;; use foo
(assert (exists ((op Int)) (= (foo op) 43)))
(apply skip)

产生

(goal
  (exists ((op Int)) (= (ite (= op 1) 42 (ite (= op 2) 43 78)) 43))
  :precision precise :depth 0)
)

(也很快解决了。)

通过API执行此操作的最简单方法是使用函数声明设置问题,然后通过macro-finder策略识别的通用量词提供宏定义:

;; declare foo
(declare-fun foo ((Int)) Int)

;; define foo
(assert (forall ((x Int)) (= (foo x)
    (ite (= x 1) 42
    (ite (= x 2) 43
    ;; ...
                 78)))))

;; use foo
(assert (exists ((op Int)) (= (foo op) 43)))
(apply macro-finder) ;; replaces foo with it's definition

为了让宏查找器获取函数定义,量词必须具有

形式
(forall ((x ...)) (= (foo x) (... definition ...))