Skip to content

Commit

Permalink
Implement identity morphisms.
Browse files Browse the repository at this point in the history
A Morphism can now be defined to be an identity.  Identity morphisms are
defined not to influence composition.  All identity morphisms of one and
the same object are equal.
  • Loading branch information
scolobb committed Jun 15, 2012
1 parent c9b027b commit fa74c09
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
34 changes: 32 additions & 2 deletions sympy/categories/baseclasses.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ class Morphism(Basic):
codomains). The names of such composed morphisms are not taken in codomains). The names of such composed morphisms are not taken in
consideration at comparison. consideration at comparison.
Morphisms with the same domain and codomain can be defined to be
identity morphisms. Identity morphisms with the same (co)domains
are equal. Identity morphisms are identities with respect to
composition.
Examples Examples
======== ========
Expand All @@ -92,16 +97,29 @@ class Morphism(Basic):
Morphism(Object("B"), Object("C"), "g") * Morphism(Object("B"), Object("C"), "g") *
Morphism(Object("A"), Object("B"), "f") Morphism(Object("A"), Object("B"), "f")
>>> id_A = Morphism(A, A, identity=True)
>>> id_A == Morphism(A, A, identity=True)
True
>>> f * id_A == f
True
""" """
def __new__(cls, domain, codomain, name=""): def __new__(cls, domain, codomain, name="", identity=False):
new_morphism = Basic.__new__(cls, domain, codomain, name) new_morphism = Basic.__new__(cls, domain, codomain, name, identity)


new_morphism.domain = domain new_morphism.domain = domain
new_morphism.codomain = codomain new_morphism.codomain = codomain
new_morphism.name = name new_morphism.name = name


new_morphism.components = [new_morphism] new_morphism.components = [new_morphism]


new_morphism.identity = identity

if identity and (domain != codomain):
raise ValueError(
"identity morphisms must have the same domain and codomain")

return new_morphism return new_morphism


def compose(self, g, new_name=""): def compose(self, g, new_name=""):
Expand Down Expand Up @@ -138,6 +156,11 @@ def compose(self, g, new_name=""):
if g.codomain != self.domain: if g.codomain != self.domain:
return None return None


if self.identity:
return g
if g.identity:
return self

composite = Morphism(g.domain, self.codomain, new_name) composite = Morphism(g.domain, self.codomain, new_name)
composite.components = g.components + self.components composite.components = g.components + self.components


Expand Down Expand Up @@ -184,6 +207,13 @@ def flatten(self, new_name=""):
return Morphism(self.domain, self.codomain, new_name) return Morphism(self.domain, self.codomain, new_name)


def __eq__(self, g): def __eq__(self, g):
if self.identity and g.identity:
# All identities are equal.
return self.domain == g.domain
elif self.identity or g.identity:
# One of the morphisms is an identity, but not both.
return False

if (len(self.components) == 1) and (len(g.components) == 1): if (len(self.components) == 1) and (len(g.components) == 1):
# We are comparing two simple morphisms. # We are comparing two simple morphisms.
if (not self.name) or (not g.name): if (not self.name) or (not g.name):
Expand Down
15 changes: 14 additions & 1 deletion sympy/categories/tests/test_baseclasses.py
Original file line number Original file line Diff line number Diff line change
@@ -1,5 +1,5 @@
from sympy.categories import Object, Morphism, Diagram from sympy.categories import Object, Morphism, Diagram
from sympy.utilities.pytest import XFAIL from sympy.utilities.pytest import XFAIL, raises
from sympy import FiniteSet, EmptySet from sympy import FiniteSet, EmptySet


def test_object(): def test_object():
Expand Down Expand Up @@ -77,6 +77,19 @@ def test_morphism():


assert hash(f) == hash(Morphism(A, B, "f")) assert hash(f) == hash(Morphism(A, B, "f"))


id_A = Morphism(A, A, identity=True)
id_B = Morphism(B, B, identity=True)

assert id_A.identity == True
assert id_A == Morphism(A, A, name="f", identity=True)
assert id_A != Morphism(A, A, name="f")

assert id_A * id_A == id_A
assert f * id_A == f
assert id_B * f == f

raises(ValueError, lambda: Morphism(A, B, identity=True))

@XFAIL @XFAIL
def test_diagram(): def test_diagram():
A = Object("A") A = Object("A")
Expand Down

0 comments on commit fa74c09

Please sign in to comment.