Lists and Recursion
Jeremy Johnson
Kurt Schmidt
Drexel University
Lists: L = (x1 … xn)
A list is either empty () [same as nil] or made up of Cons cells
consp : All → Boolean cons : All × List → Cons
(cons x L) = (x x1 … xn)
first : Cons → All (first (cons x L)) = x
rest : Cons → List (rest (cons x L)) = L
2
List Examples
(list x1 … xn) [macro – variable # of args]
(cons x1 (cons x2 … (cons xn nil)…)) (consp ()) = nil (cons 1 ()) = (1) (consp (cons 1 ())) = t (cons 1 (cons 2 (cons 3 ()))) = (1 2 3) (list 1 2 3) = (1 2 3) (cons (cons 1 ()) ()) = ((1))
3
Exercise
How do you construct the list ((1) 2)?
4
Exercise
How do you construct the list ((1) 2)? (cons 1 ()) = (1) (cons 2 ()) = (2)
Want (cons x y) where x = (1) and y = (2) (cons (cons 1 ()) (cons 2 ())) = ((1) 2)
Test this (and try additional examples) in ACL2 REPL
5
More About cons
A cons cell contains two fields first [also called car] rest [also called cdr]
For a list the rest field must be a list Generally both fields of a cons All
(cons 1 2) = (1 . 2) Called a dotted pair
6
List Processing
Recursive Definition List : nil | cons All List Process lists using these two cases and use
recursion to recursively process lists in cons Use first and rest to access components
of cons
7
Recursion and listp1
(defunc listp (l)
:input-contract t
:output-contract (booleanp (listp l))
(if (consp l)
(listp (rest l))
(equal l () )))
1. listp is a built-in function in the full ACL2 mode
8
Incorrect listp Nonterminating ACL will not accept functions it can not prove terminate
(defunc listp (a)
:input-contract t
:output-contract (booleanp (listp a))
(if (consp a)
(listp a)
(equal a nil)))
9
Version 2 of listp
(defunc listp (l)
:input-contract t
:output-contract (booleanp (listp l))
(if (equal l nil)
t
(if (consp l)
(listp (rest l))
nil)))
10
Version 3 of listp
(defunc listp (l)
:input-contract t
:output-contract (booleanp (listp l))
(cond
((equal l nil) t)
((consp l) (listp (rest l)))
nil))
11
Length1,2
(defun length (l)
(if (equal l nil)
0
( ) ))
1: defun is used instead of defunc since ACL can not prove termination and contract satisfaction without induction, which the bare bones mode does not support
2. Length is a built-in function in the full ACL2 mode
12
Length1,2
(defun length (l)
(if (equal l nil)
0
(+ 1 (length (rest l))) ))
The recursive function can be “thought of” as a definition of length
1: defun is used instead of defunc since ACL can not prove termination and contract satisfaction without induction, which the bare bones mode does not support
2. Length is a built-in function in the full ACL2 mode
13
Member1
(defun member (x l)
(cond
((equal l nil) nil)
( )
( )))
1. Member is a built-in function in the full ACL2 mode
14
Member1
(defun member (x l)
(cond
((equal l nil) nil)
((equal x (first l)) t)
((member x (rest l) )))
1. Member is a built-in function in the full ACL2 mode
15
Member1
(defun member (x l)
(cond
((equal l nil) nil)
((equal x (first l)) t)
((member x (rest l)))))
1. Member is a built-in function in the full ACL2 mode
16
Append1
(defun append (x y)
)
(append ‘(1 2 3) ‘(4 5 6)) (1 2 3 4 5 6)
Recurse on the first input
1. Append is a built-in function in the full ACL2 mode
17
Append1
(defun append (x y)
(if (equal x nil)
y
(cons (first x) (append (rest x) y))))
Recurse on the first input
1. Append is a built-in function in the full ACL2 mode
18
Reverse1
(defun reverse (l)
)
(reverse ‘(1 2 3)) (3 2 1)
1. Reverse is a built-in function in the full ACL2 mode
19
Reverse1
(defun reverse (l)
(if (equal l nil)
nil
(append (reverse (rest l)) (cons (first l) nil))))
1. Reverse is a built-in function in the full ACL2 mode
20
Numatoms
(defun atomp (x)
(not (consp x)))
(defun numatoms (x)
(cond
((equal x nil) 0)
((atomp x) 1)
((+ (numatoms (first x)) (numatoms (rest x))))))
21
Shallow vs Deep Recursion Length and Member only recurse on the rest
field for lists that are conses Such recursion is called shallow – it does not matter
whether the lists contain atoms or lists (length ‘((1 2) 3 4)) = 3
Numatoms recurses in both the first and rest fields Such recursion is called deep – it completely
traverses the list when elements are lists (numatoms ‘((1 2) 3 4)) = 4
22