如何访问Z3列表中的最后一个元素?
(declare-const lst (List Int))
(assert (not (= lst nil)))
(assert (= (head lst) 1))
(assert (= (last_element lst) 2))
(check-sat)
答案 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几乎一无所知。