(defmacro define-complement (function complement)
"Define the complement of FUNCTION to be COMPLEMENT, both symbols."
`(eval-when (:compile-toplevel :load-toplevel :execute)
(setf (get ',function 'complement-function) ',complement)
(setf (get ',complement 'complement-function) ',function)))
(defun complement (function)
"Return a function that returns the boolean complement of FUNCTION."
(let* ((function-symbol
(typecase function
(symbol function)
#+allegro (compiled-function (excl::func_name function))
(t nil)))
(complement-symbol
(and (fboundp function-symbol)
(get function-symbol 'complement-function))))
(if complement-function
(symbol-function complement-function)
(lambda (&rest arguments)
(not (apply function arguments))))))
(define-complement = /=)
(define-complement < >=)
(define-complement > <=)
(define-complement char= char/=)
(define-complement char< char>=)
(define-complement char> char<=)
(define-complement char-equal char-not-equal)
(define-complement char-lessp char-not-lessp)
(define-complement char-greaterp char-not-greaterp)
(define-complement string= string/=)
(define-complement string< string>=)
(define-complement string> string<=)
(define-complement string-equal string-not-equal)
(define-complement string-lessp string-not-lessp)
(define-complement string-greaterp string-not-greaterp)
(defun ¬eq (object1 object2)
(declare (optimize (speed 3) (safety 0) (debug 0)))
(not (eq object1 object2)))
(defun ¬eql (object1 object2)
(declare (optimize (speed 3) (safety 0) (debug 0)))
(not (eql object1 object2)))
(defun ¬equal (object1 object2)
(declare (optimize (speed 3) (safety 0) (debug 0)))
(not (equal object1 object2)))
(defun ¬equalp (object1 object2)
(declare (optimize (speed 3) (safety 0) (debug 0)))
(not (equalp object1 object2)))
(define-complement eq ¬eq)
(define-complement eql ¬eql)
(define-complement equal ¬equal)
(define-complement equalp ¬equalp)
I keep adding complements as I need them, so I have no complete list, but
if others think this is a good idea, maybe all the usefully complemented
predicates can be complemented, if necessary with internal functions,
like those above. (¬ is the NOT operator, as per ISO 8859-1.)
#:Erik
--
@1999-07-22T00:37:33Z -- pi billion seconds since the turn of the century
interestingly, this (and many other) seemingly complementary functions
are only complementary with two arguments. with one argument, as in
(= 1), most of these predicates yield true, and a complement should yield
false. with three or more arguments, as in (= 1 1 2), both may be false
and (not (= ...)) is thus very different from (/= ...). oh, well.