Comparison of cyclic objects (was RE: [Python-Dev] trashcan and
PR#7)
Ka-Ping Yee
ping@lfw.org
Thu, 13 Apr 2000 17:41:44 -0500 (CDT)
On Thu, 13 Apr 2000, Jeremy Hylton wrote:
> >>>>> "TP" == Tim Peters <tim_one@email.msn.com> writes:
>
> TP> [Jeremy Hylton]>
> >> So the real problem is defining some reasonable semantics for
> >> comparison of recursive objects.
There is a "right" way to do this, i believe, and my friend
Mark Miller implemented it in E.
He tells me his algorithm is inspired by the method for
unification of cyclic structures in Prolog III. It's available
in the E source code (in the file elib/tables/Equalizer.java).
See interesting stuff on equality and cyclic data structures at
http://www.erights.org/javadoc/org/erights/e/elib/tables/Equalizer.html
http://www.erights.org/elang/same-ref.html
http://www.erights.org/elang/blocks/defVar.html
http://www.eros-os.org/~majordomo/e-lang/0698.html
There is also a thread about equality issues in general at:
http://www.eros-os.org/~majordomo/e-lang/0000.html
It's long, but worth perusing.
Here is my rough Python translation of the code in the E Equalizer.
Python 1.4 (Mar 25 2000) [C]
Copyright 1991-1997 Stichting Mathematisch Centrum, Amsterdam
Python Console v1.4 by Ka-Ping Yee <ping@lfw.org>
>>> def same(left, right, sofar={}):
... hypothesis = (id(left), id(right))
... if left is right or sofar.has_key(hypothesis): return 1
... if type(left) is not type(right): return 0
... if type(left) is type({}):
... left, right = left.items(), right.items()
... if type(left) is type([]):
... sofar[hypothesis] = 1
... try:
... for i in range(len(left)):
... if not same(left[i], right[i], sofar): return 0
... return 1
... finally:
... del sofar[hypothesis]
... return left == right
...
...
>>> same([3],[4])
0
>>> same([3],[3])
1
>>> a = [1,2,3]
>>> b = [1,2,3]
>>> c = [1,2,3]
>>> same(a,b)
1
>>> a[1] = a
>>> same(a,a)
1
>>> same(a,b)
0
>>> b[1] = b
>>> same(a,b)
1
>>> b[1] = c
>>> b
[1, [1, 2, 3], 3]
>>> same(a,b)
0
>>> c[1] = b
>>> same(a,b)
1
>>> same(b,c)
1
>>>
I would like to see Python's comparisons work this way (i.e.
"correct" as opposed to "we give up").
-- ?!ng