You might also want to refer to the Hyper-Card for ACL2 Programming in ACL2s.
AND
AND
Goal: Using the analogous method, find out about the function REVAPPEND.
Obtain and install ACL2s from the ACL2s home page. Read the beginning tutorial and the guide to usage.
Once you have Eclipse running with ACL2s, do the following (see the ACL2s beginning tutorial for details):
test.lisp, in Compatible mode.
test.lisp and test.lisp.a2s. The test.lisp
tab contains the code editor where you can type in your ACL2 code. The
test.lisp.a2s tab contains the session editor which
stores the history of ACL2 sessions you use to develop test.lisp.
test.lisp.a2s tab (session editor) by clicking the tab or
pressing Ctrl+Shift+o (Mac: Command+Shift+o).
ACL2 Version 3.1 built December 5, 2006 20:22:10.and some other text, ending with
ACL2 !>The part at the bottom is the ACL2 prompt.
:program (followed by return).
:redef (followed by return).
It should be
ACL2 p!>If it is not, something is wrong! Have you followed the directions above?
Note that the ``ACL2'' you see is not a sign that you
are in the ACL2 system. It is a sign that the ``current symbol package''
is ACL2. If you do not know what a symbol package is, don't worry
about it. Just know that it is not the ``ACL2'' that is important
about the prompt, it is the other parts!
t
T. The value of the Lisp
expression t is T.
Try these three:
(equal 1 2)
(if t 1 2)
(if nil 1 2)
NIL because 1 is
not 2. The second and third should return
1 and 2, respectively, because (if x y
z) means ``if x then
y, else z.''
One advantage of using ACL2s is that it will catch syntax errors that would throw you into the debugger if you were interacting with ACL2 directly. Try typing the following, including the period at the end of the line, and then type return:
(equal 1 1).
(equal 1 1) and leave
the . at the prompt. If you type return again, ACL2s will
produce an "Illegal dot" error message.
Here are some expressions to evaluate. But before you send each one to ACL2, think about what you believe the value will be. When you have a hypothesis, evalute the expression and see if you're right.
(cons 1 2)
(car (cons 1 2))
(cdr (cons 1 2))
(consp (cons 1 2))
(consp (car (cons 1 2)))
AND? Evaluate these expressions.
(and t t nil t)
(and t t t)
(and 1 2 3)
(car 1 2)
(car x)
Which of these expressions evaluates to (1 . 2)?
(cons 1 2)
(1 . 2)
'(1.2)
1.2 is a Common Lisp floating point
number and ACL2 doesn't support those.
More generally, if you want to write a dotted pair, you should put some
``whitespace'' before and after the dot! Write '(A . B) not
(A.B).
Which of these expressions evaluates to (1 2 3)?
(cons 1 2 3)
(cons 1 (cons 2 (cons 3 nil)))
(cons 1 (cons 2 3))
(A B)?
(CONS A (CONS B NIL))
(CONS 'A '(B))
(CONS 'A (B))
(A (B . C) D)?
(cons 'A (cons '(B . C) 'D))
'(A (B . C) . (D . NIL))
(A (B . C) D)
(revappend '(a b c) '(1 2 3))
(revappend '(a b c) nil)
(revappend '(a b c) 5)
You could just type the following at the ACL2 prompt. But don't!
(defun mem (e x)
(if (consp x)
(if (equal e (car list))
t
(mem e (cdr x))
nil)))
It is almost always a mistake to type more than one line directly to
Lisp! The reason is that Lisp will not let you edit your input after
you have typed a carriage return (it provides a one line buffer).
And there are typos in the defun above!
Type the definition in the code editor and then press the "Advance todo line"
button to send it to ACL2. This will cause an error. The trouble is that the
parentheses are not balanced correctly in the definition. The error message
says IF was given four arguments and expects three. Can you find
the problem? Hint: use ACL2s' parenthesis-highlighting capability.
Edit the defun to fix the problem. When you have fixed the paren
problem, resubmit the definition to ACL2.
Now what? The error message:
ACL2 Error in ( DEFUN MEM ...): The body of MEM contains a free occurrence of the variable symbol LIST.means that the
defun uses a variable that is not one of
the formal parameters. ACL2 does not have global variables!
The variable list in the defun should be
x. Fix it and try again.
Whenever we say something like ``define such-and-such'' in ACL2 we really mean for you to prepare the definition in the code editor, so you can correct your typos, and then submit it ACL2 as described above. If you always type new definitions at the bottom of the code editor, and submit them as you go, you will have a record of your definitions in the .lisp file and the associated ACL2 history in the .lisp.a2s file.
Ok, so you've defined mem. Test it on
(defun fact (n)
(if (equal n 0)
0
(* n (fact (- n 1)))))
Once you have done that, submit it to ACL2. Now run it:
(fact 4) ought to be 24.
You will be re-defining a function, which ACL2 takes somewhat
seriously. You should answer y when it asks you if you want
to redefine FACT.
n for which your image cannot compute (fact n) and
will exhibit a ``hard error'' like this:
Error: Invocation history stack overflow. Fast links are on: do (si::use-fast-links nil) for debugging Error signalled by IF.If you were interacting with ACL2 directly, you would see the Lisp debugger prompt. However, because you are using ACL2s, you will see the error message but still be able to proceed normally.
The stack overflowed because fact is being interpretted.
Compiled functions use less stack space. To compile fact, do
:comp fact
(fact 1000)
fact may cause a hard error and, again, if yours
computes (fact 1000) it still may not compute
(fact 10000), etc.
Suppose we have a cons pair, e.g., (1 . 2) and we want to flip it
around so that we have (2 . 1). Fill in the blank below so that
the function flip does this. (You should move
the defun to the code editor and prepare your definition there.)
(defun flip (p) ...)It doesn't matter what
flip does if p is
not a cons pair, because you should never call flip on such
a p.
Test your flip
(flip '(A . B))
(flip '((A . B) . (C . D)))
Now suppose we have a list of cons pairs, x, and we
want to flip each element of x. Fill in the blank
to make flip-list do that.
(defun flip-list (x) ...)
Test your flip-list
(flip-list '((A . 1) (B . 2) (C . 3)))
((1 . A) (2 . B) (3 . C)).
T.
(defun swap (x) ; Flip every cons pair in a binary tree. ...)
(equal (swap '((a . b) . (c . d)))
'((d . c) . (b . a)))
(defun size (x) ; Count the number of leaves in a binary tree. ...)
(equal (size '((a . b) . (c . d))) 4)
(defun depth (x) ; Compute the length of the longest branch in a binary tree. ...)
(equal (depth '(((a . b) . c) . (e . f))) 3)
(defun tsubst (x y z) ; Substitute x for each occurrence of y in the binary tree z. ; (We can't call this ``subst'' because such a function is ; already defined in ACL2.) ...)
(equal (tsubst 'x '(a . b) '(((a . b) a b) . ((a . b) a . b)))
'((x a b) . (x . x)))