90 likes | 102 Views
Learn the various equality checks in programming like EQ, EQL, =, EQUAL, and EQUALP, based on data types to ensure accurate comparisons. Symbols, numbers, structures, and sequences are compared differently.
E N D
01/12/98 Equality Checking • What to does it mean to ask • is object A equal to object B • There are a variety of answers, depending on the data types • share the same physical memory • numerically equal • “structurally similar”
01/12/98 LISP Agent Continued • Administrative • PS1 on the web now • Last time • agent system high-level design and control flow • the structure of sense reports and percepts • LISP concepts • lists as data structures • defstruct and its effects • This time • percept and behavior code • equality checking
X X Y Y Z Z EQ: equality in the strongest sense • The predicate (EQ A B) is true if and only if A and B point to the same location in memory (setf A ’(X Y Z)) (setf B A) (eq A B) => T (setf A ’(a b c)) (setf B ’(a b c)) (eq A B) => NIL
X EQ and the special case of symbols • Defined in the CommonLisp language: two symbols with the same print name are stored in the same area of memory • So, EQ is the appropriate equality check for symbols. (setf A ’X) (setf B ’X) (eq A B) => T
EQL: “Conceptually Equal” • EQ is strictly stronger than EQL: any two objects that are EQ are also EQL, but the converse is not true. • X and Y are EQL if they are of the same value and type • two symbols: (EQL ’X ’X) => T • two characters: (EQL #\a #\a) => T • two numbers of the same type: (EQL 3.2 3.2) => T • But does not apply to sequences or mixed types • (EQL 3 3.0) => NIL • (EQL “a” “a”) => NIL • (EQL ’(X Y) ’(X Y)) => NIL • EQL is the default equality test for many built-in functions • MEMBER, REMOVE, etc.
= : Numerically Equal • The equal sign is a special-purpose equality checker for numbers. • The main thing it does is cast numbers to equivalent types, then compares them EQL • It should always be used to compare numbers. • Will signal an error if its arguments are non-numeric.
EQUAL: Comparing sequences • A sequence generically refers to a list, a string, or a vector. • Numbers, symbols, and characters are EQUAL if and only if they are EQL • Two sequences are EQUAL if • they are the same length • they are element-by-element EQUAL • Examples • (EQUAL ’(X (Y Z) W) ’(X (Y Z) W)) => T • (EQUAL “AbCdE” “AbCdE”) => T • (EQUAL “AbCdE” “aBcDe”) => NIL • EQUAL is the equality predicate of choice for strings, vectors, lists
EQUALP: testing “generic equivalence” • Any two objects that are EQ, EQL, EQUAL, or = are also EQUALP • Two structures are EQUALP if they are • the same type • all of the fields are pairwise EQUALP (defstruct foo x) (setf s1 (make-foo :x “abcde”)) (setf s2 (make-foo :x “abcde”)) (eq s1 s2) => ??? (eql s1 s2) => ??? (= s1 s2) => ??? (equal s1 s2) => ??? (equalp s1 s2) => ???
Summary of equality checking • Several different senses of equality that depends on the objects’ data types • EQ, EQL, =,EQUAL, EQUALP • The choice of the right predicate is generally clear: you know the objects’ data types, and there is only one appropriate equality checker: • EQ for symbols • EQL for symbols, characters • = for numbers • EQUAL for strings, lists, arrays • EQUALP for structure instances • If you declare a structure, it never hurts to declare a special-purpose equality tester and use it