I'm trying to write a function in ACL2 (specifically ACL2s) that takes in a list and a natural number and returns the item in the list at the given index. So (select (list 1 2 3) 2) would return 3.
Here is my code:
;; select: List x Nat -> All
(defunc select (l n)
:input-contract (and (listp l) (natp n))
:output-contract t
(if (equal 0 n)
(first l)
(select (rest l) (- n 1))))
I'm receiving the following error:
Query: Testing body contracts ...
**Summary of Cgen/testing**
We tested 50 examples across 1 subgoals, of which 48 (48 unique) satisfied
the hypotheses, and found 1 counterexamples and 47 witnesses.
We falsified the conjecture. Here are counterexamples:
[found in : "top"]
-- ((L NIL) (N 0))
Test? found a counterexample.
Body contract falsified in:
-- (ACL2::EXTRA-INFO '(:GUARD (:BODY SELECT)) '(FIRST L))
Any help is much appreciated!
The message seems pretty clear to me: you are trying to get the first element of an empty list, which conflicts with your specification.
Based on this reference, it seems that first
expects a non-empty list, whereas car
returns nil
when your input is nil
.
Either you handle the nil
case explicitely with an endp
test or you use car
instead of first
.