Certain events do not allow loop$s or lambda$s
Certain events, including defconst, defmacro, and
defpkg, prohibit the use of loop$ and lambda$. The
prohibition of
If you have submitted an event that provoked an error citing this topic you must restate the event to avoid those prohibited constructions. Unfortunately, you must also consider ancestral occurrences of the prohibited constructions! We first give two examples of the problem to drive home the message and then we discuss various ways the problem can be dealt with.
ACL2 !>(defconst *2^10* (apply$ (lambda$ (x) (expt 2 x)) '(10))) ACL2 Error in ( DEFCONST *2^10* ...): We prohibit certain events, including DEFCONST, DEFPKG, and DEFMACRO, from being ancestrally dependent on loop$ and lambda$ expressions. But at least one of these prohibited expressions occurs in this event. See :DOC prohibition-of-loop$-and- lambda$.
We will discuss how to avoid such errors in the next section.
Here is an example of an ancestral use of
(defun string-to-rat (str) (let* ((lst (coerce str 'list)) (right-of-pt (length (cdr (loop$ for d in lst as tail on lst thereis (if (eql #. d) tail nil)))))) (loop$ for tail on lst when (not (eql (car tail) #.)) sum (* (- (char-code (car tail)) 48) (expt 10 (- (loop$ for d in tail sum (if (eql d #.) 0 1)) (+ 1 right-of-pt))))))) (defmacro rat (str) (string-to-rat str))
The attempt to define the macro will provoke the error shown above for
The only way to avoid these errors is to not use
(defconst *2^10* (apply$ 'expt '(2 10)))
or, better yet, by
(defconst *2^10* (expt 2 10))
since there is reason
When it is hard to avoid the prohibited constructs you might be able to
use
(make-event `(defconst *2^10* ',(apply$ (lambda$ (x) (expt 2 x)) '(10))))
However, in general, removing all uses of
(defun old-fashioned-string-to-rat1 (lst power) (cond ((endp lst) 0) ((eql (car lst) #.) (old-fashioned-string-to-rat1 (cdr lst) power)) (t (+ (* (- (char-code (car lst)) 48) (expt 10 power)) (old-fashioned-string-to-rat1 (cdr lst) (- power 1)))))) (defun left-of-pt (lst) (cond ((endp lst) 0) ((eql (car lst) #.) 0) (t (+ 1 (left-of-pt (cdr lst)))))) (defun old-fashioned-string-to-rat (str) (let ((lst (coerce str 'list))) (old-fashioned-string-to-rat1 lst (- (left-of-pt lst) 1)))) (defmacro rat (str) (old-fashioned-string-to-rat str))
Another way to eliminate
(defun string-to-rat (str) ((LAMBDA (LST) ((LAMBDA (RIGHT-OF-PT LST) (SUM$+ '(LAMBDA (LOOP$-GVARS LOOP$-IVARS) (DECLARE (IGNORABLE LOOP$-GVARS LOOP$-IVARS)) ((LAMBDA (RIGHT-OF-PT TAIL) (BINARY-* (BINARY-+ '-48 (CHAR-CODE (CAR TAIL))) (EXPT '10 (BINARY-+ (SUM$ '(LAMBDA (LOOP$-IVAR) (DECLARE (IGNORABLE LOOP$-IVAR)) ((LAMBDA (D) (IF (EQL D '#.) '0 '1)) LOOP$-IVAR)) TAIL) (UNARY-- (BINARY-+ '1 RIGHT-OF-PT)))))) (CAR LOOP$-GVARS) (CAR LOOP$-IVARS))) (CONS RIGHT-OF-PT 'NIL) (WHEN$+ '(LAMBDA (LOOP$-GVARS LOOP$-IVARS) (DECLARE (IGNORABLE LOOP$-GVARS LOOP$-IVARS)) ((LAMBDA (TAIL) (NOT (EQL (CAR TAIL) '#.))) (CAR LOOP$-IVARS))) 'NIL (LOOP$-AS (CONS (TAILS LST) 'NIL))))) (LENGTH (CDR (THEREIS$+ '(LAMBDA (LOOP$-GVARS LOOP$-IVARS) (DECLARE (IGNORABLE LOOP$-GVARS LOOP$-IVARS)) ((LAMBDA (D TAIL) (IF (EQL '#. D) TAIL 'NIL)) (CAR LOOP$-IVARS) (CAR (CDR LOOP$-IVARS)))) 'NIL (LOOP$-AS (CONS LST (CONS (TAILS LST) 'NIL)))))) LST)) (COERCE STR 'LIST)))
If we define
But there are several arguments against this approach in general:
There may be cases where no user-defined functions are involved,
efficiency doesn't matter, and the