Search code examples
functional-programminglispacl2

Writing a select() function in ACL2


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!


Solution

  • 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.