访问Z3列表中的最后一个元素

时间:2013-06-11 15:27:02

标签: z3

如何访问Z3列表中的最后一个元素?

(declare-const lst (List Int))
(assert (not (= lst nil)))
(assert (= (head lst) 1))
(assert (= (last_element lst) 2))
(check-sat)

1 个答案:

答案 0 :(得分:0)

AFAIK,Z3没有内置函数来访问列表的最后一个元素。由于SMT-Lib2不支持递归函数(参见this answer),因此您必须自己声明和解释未解释的last_element函数。

声明:

(declare-fun last_element ((List Int) (Int)) Bool)

Axiom“ nil 没有最后一个元素”:

(assert (forall ((x Int)) (!
  (not (last_element nil x))
  :pattern ((last_element nil x))
)))

Axiom“如果 xs 是列表 x:nil ,那么 x xs ”的最后一个元素:

(assert (forall ((xs (List Int)) (x Int)) (!
  (implies
    (= xs (insert x nil))
    (last_element xs x))
  :pattern ((last_element xs x))
)))

Axiom“如果 x xs 尾部的最后一个元素,那么它也是 xs 本身的最后一个元素”:

(assert (forall ((xs (List Int)) (x Int)) (!
  (implies
    (last_element (tail xs) x)
    (last_element xs x))
  :pattern ((last_element xs x))
)))

有关示例,请参阅此rise4fun-link


请注意:基于模型的量词实例化的链接示例切换(MBQI,请参阅Z3 guide),因此依赖于E匹配。这也是提供显式模式的原因,请参阅this question。如果你想尝试MBQI,你可能不得不改变公理化,但我对MBQI几乎一无所知。