Download Refinement and Theorem Proving*

Transcript
Suppose that we are defining recursive functions whose termination can be
shown with measure (len x), where x is the first argument to the function.
Instead of adding the required declarations to all of the functions under consideration, we might want to write a macro that generates the required defun.
Here is one way of doing this.
(defmacro defunm (name args body)
‘(defun ,name
,args
(declare (xargs :measure (len ,(first args))))
,body))
Notice that we define macros using defmacro, in a manner similar to function
definitions. Notice the use of what is called the backquote notation. The value
of a backquoted list is a list that has the same structure as the backquoted list
except that expressions preceded by a comma are replaced by their values. For
example, if the value of name is app, then the value of ‘(defun ,name) is (defun
app).
We can now use defunm as follows.
(defunm app (x y)
(if (consp x)
(cons (car x) (app (cdr x) y))
y))
This expands to the following.
(defun app (x y)
(declare (xargs :measure (len x)))
(if (consp x)
(cons (car x) (app (cdr x) y))
y))
When the above is processed, the result is that the function app is defined. In
more detail, the above macro is evaluated as follows. The macro formals name,
args, and body are bound to app, (x y), and (if (consp x) (cons (car x)
(app (cdr x) y)) y), respectively. Then, the macro body is evaluated. As per
the discussion on the backquote notation, the above expansion is produced.
We consider a final example to introduce ampersand markers. The example
is the list macro and its definition follows.
(defmacro list (&rest args)
(list-macro args))
Recall that (list 1 2) is an abbreviation for (cons 1 (cons 2 nil)). In addition, list can be called on an arbitrary number of arguments; this is accomplished with the use of the &rest ampersand marker. When this marker is used,
it results in the next formal, args, getting bound to the list of the remaining arguments. Thus, the value of (list 1 2) is the value of the expression
(list-macro ’(1 2)). In this way, an arbitrary number of objects are turned