Notes on how to use tables efficiently
(Thanks to Jared Davis for contributing this documentation topic, to which we have made only minor modifications.)
Suppose your book contains table events, or macros that
expand into
(table my-table 'my-field <computation>)
Then
See also defconsts for an analogous trick involving defconst.
As an example, suppose we want to store numbers in a table only if they
satisfy some computationally expensive predicate. We'll introduce a new book,
(table number-table 'data nil)
Instead of implementing a ``computationally expensive predicate,'' we'll write a function that just prints a message when it is called and accepts even numbers:
(defun expensive-computation (n) (prog2$ (cw "Expensive computation on ~x0.~%" n) (evenp n)))
Now we'll implement a macro,
(defmacro add-number (n) `(table number-table 'data (let ((current-data (cdr (assoc-eq 'data (table-alist 'number-table world))))) (if (expensive-computation ,n) (cons ,n current-data) current-data))))
Finally, we'll call
(add-number 1) (add-number 2) (add-number 3)
When we now invoke
ACL2 !>(include-book "number-table") Expensive computation on 1. Expensive computation on 2. Expensive computation on 3.
To avoid these repeated executions, we can pull the test out of the
(defmacro add-number (n) `(make-event (if (expensive-computation ,n) '(table number-table 'data (cons ,n (cdr (assoc 'data (table-alist 'number-table world))))) '(value-triple :expensive-computation-failed))))
When we recertify