File: DEFABBREV.html

package info (click to toggle)
acl2 3.1-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 36,712 kB
  • ctags: 38,396
  • sloc: lisp: 464,023; makefile: 5,470; sh: 86; csh: 47; cpp: 25; ansic: 22
file content (101 lines) | stat: -rw-r--r-- 4,302 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<html>
<head><title>DEFABBREV.html  --  ACL2 Version 3.1</title></head>
<body text=#000000 bgcolor="#FFFFFF">
<h2>DEFABBREV</h2>a convenient form of macro definition for simple expansions
<pre>Major Section:  <a href="EVENTS.html">EVENTS</a>
</pre><p>


<pre>
Examples:
(defabbrev snoc (x y) (append y (list x)))
(defabbrev sq (x) (declare (type (signed-byte 8) x)) (* x x))<p>

General Form:
(defabbrev name (v1 ... vn) doc-string decl1 ... declk body)
</pre>

where <code>name</code> is a new function symbol, the <code>vi</code> are distinct
variable symbols, and <code>body</code> is a term.  The <code>decli</code>, if supplied,
should be legal <code>declare</code> forms; see <a href="DECLARE.html">declare</a>.  <code>Doc-string</code> is
an optional <a href="DOCUMENTATION.html">documentation</a> string; see <a href="DOC-STRING.html">doc-string</a>.<p>

Roughly speaking, the <code>defabbrev</code> event is akin to defining
<code>f</code> so that <code>(f v1 ... vn) = body</code>.  But rather than do this
by adding a new axiom, <code>defabbrev</code> defines <code>f</code> to be a macro
so that <code>(f a1 ... an)</code> expands to <code>body</code>, with the ``formals,''
<code>vi</code>, replaced by the ``actuals,'' <code>ai</code>.
<p>
For example, if <code>snoc</code> is defined as shown in the first example
above, then <code>(snoc (+ i j) temp)</code> is just an abbreviation for

<pre>
(append temp (list (+ i j))).
</pre>
<p>

In order to generate efficiently executable Lisp code,
the macro that <code>defabbrev</code> introduces uses a <code><a href="LET.html">let</a></code> to
bind the ``formals'' to the ``actuals.''  Consider the second
example above.  Logically speaking, <code>(sq (ack i j))</code> is an
abbreviation for <code>(* (ack i j) (ack i j))</code>.  But in fact
the macro for <code>sq</code> introduced by <code>defabbrev</code> actually
arranges for <code>(sq (ack i j))</code> to expand to:

<pre>
(let ((x (ack i j)))
  (* x x))
</pre>

which executes more efficiently than <code>(* (ack i j) (ack i j))</code>.<p>

In the theorem prover, the <code>let</code> above expands to

<pre>
((lambda (x) (* x x)) (ack i j))
</pre>

and thence to <code>(* (ack i j) (ack i j))</code>.<p>

It is important to note that the term in <code>body</code> should not contain a
call of <code>name</code> -- i.e., <code>defabbrev</code> should not be used in place of
<code>defun</code> when the function is recursive.  ACL2 will not complain when
the <code>defabbrev</code> form is processed, but instead ACL2 will more than
likely go into an infinite loop during macroexpansion of any form that
has a call of <code>name</code>.<p>

It is also important to note that the parameters of any call of a
macro defined by defabbrev will, as is the case for the parameters
of a function call, be evaluated before the body is evaluated, since
this is the evaluation order of <code><a href="LET.html">let</a></code>.  This may lead to some
errors or unexpected inefficiencies during evaluation if the body
contains any conditionally evaluted forms like <code>cond</code>, <code>case</code>,
or <code>if</code>.  Consider the following example.

<pre>
(defabbrev foo (x y)
  (if (test x) (bar y) nil))
</pre>

Notice a typical one-step expansion of a call of <code>foo</code>
(see <a href="TRANS1.html">trans1</a>):

<pre>
ACL2 !&gt;:trans1 (foo expr1 expr2)
 (LET ((X EXPR1) (Y EXPR2))
      (IF (TEST X) (BAR Y) NIL))
ACL2 !&gt;
</pre>

Now imagine that <code>expr2</code> is a complicated expression whose
evaluation is intended only when the predicate <code>test</code> holds of
<code>expr1</code>.  The expansion above suggests that <code>expr2</code> will always
be evaluated by the call <code>(foo expr1 expr2)</code>, which may be
inefficient (since perhaps we only need that value when <code>test</code> is
true of <code>expr1</code>).  The evaluation of <code>expr2</code> may even cause an
error, for example in <code>:</code><code><a href="PROGRAM.html">program</a></code> mode if the expression <code>expr2</code> has
been constructed in a manner that could cause a guard violation
unless <code>test</code> holds of <code>expr1</code>.
<br><br><br><a href="acl2-doc.html"><img src="llogo.gif"></a> <a href="acl2-doc-index.html"><img src="index.gif"></a>
</body>
</html>