给出典型的列表数据类型:
(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中可行吗?如果是这样,解决问题的最佳方法是什么? 谢谢
答案 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获取每晚构建。)