列表"包含"功能在Z3中

时间:2018-05-23 18:00:04

标签: z3 smt

给出典型的列表数据类型:

(declare-datatypes (X)(
  (Lst
    (nil)
    (insert
      (head X)
      (tail Lst)))))

我试图创建一个函数来返回给定元素是否在给定列表中。看起来我必须使用未解释的功能。我尝试过不同的方法而没有成功。例如:

(declare-fun is-in-lst ((Int)(Lst Int)) Bool)

(assert (forall((elem Int)(lst (Lst Int)))
  (=
    (is-in-lst elem lst)
    (and
      (is-insert lst)
      (or
        (= elem (head lst))
        (is-in-lst elem (tail lst)))))))

(declare-const l1 (Lst Int))

(assert (is-in-lst 6 l1))
(assert (is-in-lst 5 l1))

这在Z3中可行吗?如果是这样,解决问题的最佳方法是什么? 谢谢

1 个答案:

答案 0 :(得分:1)

最新的SMTLib标准允许递归定义。此外,List是在Z3中预定义的,因此您无需自己定义它。您可以将您的功能编码为:

(define-fun-rec elem ((e Int) (l (List Int))) Bool
   (ite (= l nil) false (or (= e (head l)) (elem e (tail l)))))

(declare-const l1 (List Int))
(assert (elem 6 l1))
(assert (elem 5 l1))

(check-sat)
(get-value (l1))

为此,z3回复:

sat
((l1 (let ((a!1 (insert 6 (insert 4 (insert 7 (insert 5 nil))))))
  (insert 0 (insert 1 (insert 3 (insert 2 a!1)))))))

您可能必须从他们的夜间版本中获取最新版本的Z3,因为对递归函数的支持相当新,因此最新的官方版本(4.6.0)可能会或可能不会与此一起使用。 (您可以从https://github.com/Z3Prover/bin/tree/master/nightly获取每晚构建。)