GENERALIZED-BOOLEANS

potential soundness issues related to ACL2 predicates
Major Section:  MISCELLANEOUS

The discussion below outlines a potential source of unsoundness in ACL2. Although to our knowledge there is no existing Lisp implementation in which this problem can arise, nevertheless we feel compelled to explain this situation.

Consider for example the question: What is the value of (equal 3 3)? According to the ACL2 axioms, it's t. And as far as we know, based on considerable testing, the value is t in every Common Lisp implementation. However, according the Common Lisp draft proposed ANSI standard, any non-nil value could result. Thus for example, (equal 3 3) is allowed by the standard to be 17.

The Common Lisp standard specifies (or soon will) that a number of Common Lisp functions that one might expect to return Boolean values may, in fact, return arbitrary values. Examples of such functions are equal, rationalp, and <; a much more complete list is given below. Indeed, we dare to say that every Common Lisp function that one may believe returns only Booleans is, nevertheless, not specified by the standard to have that property, with the exceptions of the functions not and null. The standard refers to such arbitrary values as ``generalized Booleans,'' but in fact this terminology makes no restriction on those values. Rather, it merely specifies that they are to be viewed, in an informal sense, as being either nil or not nil.

This situation is problematic for ACL2, which axiomatizes these functions to return Booleans. The problem is that because (for efficiency and simplicity) ACL2 makes very direct use of compiled Common Lisp functions to support the execution of its functions, there is in principle a potential for unsoundness due to these ``generalized Booleans.'' For example, ACL2's equal function is defined to be Common Lisp's equal. Hence if in Common Lisp the form (equal 3 3) were to evaluate to 17, then in ACL2 we could prove (using the :executable-counterpart of equal) (equal (equal 3 3) 17). However, ACL2 can also prove (equal (equal x x) t), and these two terms together are contradictory, since they imply (instantiating x in the second term by 3) that (equal 3 3) is both equal to 17 and to t.

To make matters worse, the standard allows (equal 3 3) to evaluate to different non-nil values every time. That is: equal need not even be a function!

Fortunately, no existing Lisp implementation takes advantage of the flexibility to have (most of) its predicates return generalized Booleans, as far as we know. We may implement appropriate safeguards in future releases of ACL2, in analogy to (indeed, probably extending) the existing safeguards by way of guards (see guard). For now, we'll sleep a bit better knowing that we have been up-front about this potential problem.

The following list of functions contains all those that are defined in Common Lisp to return generalized Booleans but are assumed by ACL2 to return Booleans. In addition, the functions acl2-numberp and complex-rationalp are directly defined in terms of respective Common Lisp functions numberp and complexp.

/=
<
=
alpha-char-p
atom
char-equal
char<
char<=
char>
char>=
characterp
consp
digit-char-p
endp
eq
eql
equal
evenp
integerp
keywordp
listp
logbitp
logtest
lower-case-p
minusp
oddp
plusp
rationalp
standard-char-p
string-equal
string<
string<=
string>
string>=
stringp
subsetp
symbolp
upper-case-p
zerop