Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add (un)equality operators to Object and Morphism.

Also extend the docstrings and the tests to cover the added semantics.
In morphism equality, composed morphisms are only compared by their
components.  Thus, the names of composed morphisms are insignificant at
comparison.
  • Loading branch information...
commit 9cf15ea4d00b687b6e53bf546cd06fe82b91112d 1 parent 9334d84
Sergiu Ivanov authored
50 sympy/categories/baseclasses.py
View
@@ -22,10 +22,28 @@ class Object(Basic):
While concrete categories may have some concrete SymPy classes as
object types, in abstract categories only the name of an object is
known.
+
+ Two objects with the same name are the same object. An unnamed
+ object is not equal to any other object.
"""
def __init__(self, name=""):
self.name = name
+ def __eq__(self, obj):
+ if (not obj.name) or (not self.name):
+ return False
+
+ return self.name == obj.name
+
+ def __ne__(self, obj):
+ if (not obj.name) or (not self.name):
+ return True
+
+ return self.name != obj.name
+
+ def __hash__(self):
+ return hash(self.name)
+
class Morphism(Basic):
"""
The base class for any kind of morphism in an abstract category.
@@ -34,6 +52,15 @@ class Morphism(Basic):
category objects. The object where the arrow starts is called the
domain, while the object where the arrow ends is called the
codomain.
+
+ Two simple (not composed) morphisms with the same name, domain,
+ and codomain are the same morphisms. A simple unnamed morphism is
+ not equal to any other morphism.
+
+ Two composed morphisms are equal if they have the same components,
+ in the same order (which guarantees the equality of domains and
+ codomains). The names of such composed morphisms are not taken in
+ consideration at comparison.
"""
def __init__(self, domain, codomain, name=""):
self.domain = domain
@@ -97,3 +124,26 @@ def flatten(self, new_name=""):
compose
"""
return Morphism(self.domain, self.codomain, new_name)
+
+ def __eq__(self, g):
+ if (len(self.components) == 1) and (len(g.components) == 1):
+ # We are comparing two simple morphisms.
+ if (not self.name) or (not g.name):
+ return False
+
+ return (self.name == g.name) and \
+ (self.domain == g.domain) and \
+ (self.codomain == g.codomain)
+ else:
+ # One of the morphisms is composed. Compare the
+ # components.
+ for (self_component, g_component) in zip(self.components, g.components):
+ if self_component != g_component:
+ return False
+ return True
+
+ def __ne__(self, g):
+ return not (self == g)
+
+ def __hash__(self):
+ return hash((self.name, self.domain, self.codomain))
14 sympy/categories/tests/test_baseclasses.py
View
@@ -5,6 +5,13 @@ def test_object():
assert A.name == "A"
+ assert A == Object("A")
+ assert A != Object("A1")
+ assert Object("") != A
+ assert Object("") != Object("")
+
+ assert hash(A) == hash(Object("A"))
+
def test_morphism():
A = Object("A")
B = Object("B")
@@ -60,3 +67,10 @@ def test_morphism():
assert u1.codomain == D
assert u1.name == "u"
assert u1.components == [u1]
+
+ assert f == Morphism(A, B, "f")
+ assert f != g
+ assert f != Morphism(A, B, "")
+ assert Morphism(A, B, "") != Morphism(A, B, "")
+
+ assert hash(f) == hash(Morphism(A, B, "f"))
Please sign in to comment.
Something went wrong with that request. Please try again.