sxhash
has to satisfy four requirements:
- objects which are
equal
(and hence objects which are eql
, eq
, but not necessarily equalp
will have the same sxhash
value;
- the
sxhash
value of an object must not change during the life of single image unless the object is changed in such a way as to not make it equal
to a copy of it before the change;
- objects of various types which have a well-defined notion of similarity between images then their
sxhash
value must be the same in each image.
- computation of
sxhash
must always terminate.
(There is another vague requirement of 'being a good hash code').
(1) means that two objects which are not equal
may have the same code but may not, but two objects which are equal
must have the same value. A terrible but possible implementation of sxhash
would be:
(defun sxhash/terrible (it)
(declare (ignore it))
0)
This fails the 'being a good hash code' test, but that's not something that can really be enforced.
What you are seeing is that two objects which are not equal
do have the same sxhash
value: that's fine.
Indeed, (1) together with (4) mean that if an implementation is going to compute sxhash
on conses in such a way that it walks the graph, then it has to be pretty careful about that: it either needs an occurs check or it needs to only go so deep.
However it is quite possible that sxhash
does descend into cons trees. As an example here is LispWorks doing just that:
> (sxhash '(1 2 3))
11890816076270616
> (sxhash '(1 2 3 (4)))
369102953153702944
> (sxhash '(1 2 3 (4)))
740958182301008344
> (sxhash '(1 2 3 (5)))
740958455027237144
> (sxhash '(1 2 3 (5 6)))
741326672350173760
> (sxhash '(1 2 3 (5 (6))))
925006242171775434
Equally it is quite plausible that sxhash
treats all instances of a given structure class (or of a given instance of standard-class
) as having the same value, because the address of such an object is not constant and there's no obvious place to store the hash code without burning memory. But that's in no way a requirement.