How can I access the last element in Z3 list?
(declare-const lst (List Int))
(assert (not (= lst nil)))
(assert (= (head lst) 1))
(assert (= (last_element lst) 2))
(check-sat)
How can I access the last element in Z3 list?
(declare-const lst (List Int))
(assert (not (= lst nil)))
(assert (= (head lst) 1))
(assert (= (last_element lst) 2))
(check-sat)
AFAIK, Z3 has no built-in function to access the last element of a list. Since SMT-Lib2 does not support recursive functions (see this answer), you have to declare and axiomatise an uninterpreted last_element
function yourself.
Declaration:
(declare-fun last_element ((List Int) (Int)) Bool)
Axiom "nil has no last element":
(assert (forall ((x Int)) (!
(not (last_element nil x))
:pattern ((last_element nil x))
)))
Axiom "If xs is the list x:nil then x is the last element of xs":
(assert (forall ((xs (List Int)) (x Int)) (!
(implies
(= xs (insert x nil))
(last_element xs x))
:pattern ((last_element xs x))
)))
Axiom "If x is the last element of the tail of xs, then it is also the last element of xs itself":
(assert (forall ((xs (List Int)) (x Int)) (!
(implies
(last_element (tail xs) x)
(last_element xs x))
:pattern ((last_element xs x))
)))
See this rise4fun-link for an example.
Please note: The linked example switches of model based quantifier instantiation (MBQI, see the Z3 guide) and thus relies on E-matching. This is also the reason why explicit patterns are provided, see this question. If you want to give MBQI a try you might have to change the axiomatisation, but I hardly know anything about MBQI.