test_baseclasses.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. from sympy.categories import (Object, Morphism, IdentityMorphism,
  2. NamedMorphism, CompositeMorphism,
  3. Diagram, Category)
  4. from sympy.categories.baseclasses import Class
  5. from sympy.testing.pytest import raises
  6. from sympy.core.containers import (Dict, Tuple)
  7. from sympy.sets import EmptySet
  8. from sympy.sets.sets import FiniteSet
  9. def test_morphisms():
  10. A = Object("A")
  11. B = Object("B")
  12. C = Object("C")
  13. D = Object("D")
  14. # Test the base morphism.
  15. f = NamedMorphism(A, B, "f")
  16. assert f.domain == A
  17. assert f.codomain == B
  18. assert f == NamedMorphism(A, B, "f")
  19. # Test identities.
  20. id_A = IdentityMorphism(A)
  21. id_B = IdentityMorphism(B)
  22. assert id_A.domain == A
  23. assert id_A.codomain == A
  24. assert id_A == IdentityMorphism(A)
  25. assert id_A != id_B
  26. # Test named morphisms.
  27. g = NamedMorphism(B, C, "g")
  28. assert g.name == "g"
  29. assert g != f
  30. assert g == NamedMorphism(B, C, "g")
  31. assert g != NamedMorphism(B, C, "f")
  32. # Test composite morphisms.
  33. assert f == CompositeMorphism(f)
  34. k = g.compose(f)
  35. assert k.domain == A
  36. assert k.codomain == C
  37. assert k.components == Tuple(f, g)
  38. assert g * f == k
  39. assert CompositeMorphism(f, g) == k
  40. assert CompositeMorphism(g * f) == g * f
  41. # Test the associativity of composition.
  42. h = NamedMorphism(C, D, "h")
  43. p = h * g
  44. u = h * g * f
  45. assert h * k == u
  46. assert p * f == u
  47. assert CompositeMorphism(f, g, h) == u
  48. # Test flattening.
  49. u2 = u.flatten("u")
  50. assert isinstance(u2, NamedMorphism)
  51. assert u2.name == "u"
  52. assert u2.domain == A
  53. assert u2.codomain == D
  54. # Test identities.
  55. assert f * id_A == f
  56. assert id_B * f == f
  57. assert id_A * id_A == id_A
  58. assert CompositeMorphism(id_A) == id_A
  59. # Test bad compositions.
  60. raises(ValueError, lambda: f * g)
  61. raises(TypeError, lambda: f.compose(None))
  62. raises(TypeError, lambda: id_A.compose(None))
  63. raises(TypeError, lambda: f * None)
  64. raises(TypeError, lambda: id_A * None)
  65. raises(TypeError, lambda: CompositeMorphism(f, None, 1))
  66. raises(ValueError, lambda: NamedMorphism(A, B, ""))
  67. raises(NotImplementedError, lambda: Morphism(A, B))
  68. def test_diagram():
  69. A = Object("A")
  70. B = Object("B")
  71. C = Object("C")
  72. f = NamedMorphism(A, B, "f")
  73. g = NamedMorphism(B, C, "g")
  74. id_A = IdentityMorphism(A)
  75. id_B = IdentityMorphism(B)
  76. empty = EmptySet
  77. # Test the addition of identities.
  78. d1 = Diagram([f])
  79. assert d1.objects == FiniteSet(A, B)
  80. assert d1.hom(A, B) == (FiniteSet(f), empty)
  81. assert d1.hom(A, A) == (FiniteSet(id_A), empty)
  82. assert d1.hom(B, B) == (FiniteSet(id_B), empty)
  83. assert d1 == Diagram([id_A, f])
  84. assert d1 == Diagram([f, f])
  85. # Test the addition of composites.
  86. d2 = Diagram([f, g])
  87. homAC = d2.hom(A, C)[0]
  88. assert d2.objects == FiniteSet(A, B, C)
  89. assert g * f in d2.premises.keys()
  90. assert homAC == FiniteSet(g * f)
  91. # Test equality, inequality and hash.
  92. d11 = Diagram([f])
  93. assert d1 == d11
  94. assert d1 != d2
  95. assert hash(d1) == hash(d11)
  96. d11 = Diagram({f: "unique"})
  97. assert d1 != d11
  98. # Make sure that (re-)adding composites (with new properties)
  99. # works as expected.
  100. d = Diagram([f, g], {g * f: "unique"})
  101. assert d.conclusions == Dict({g * f: FiniteSet("unique")})
  102. # Check the hom-sets when there are premises and conclusions.
  103. assert d.hom(A, C) == (FiniteSet(g * f), FiniteSet(g * f))
  104. d = Diagram([f, g], [g * f])
  105. assert d.hom(A, C) == (FiniteSet(g * f), FiniteSet(g * f))
  106. # Check how the properties of composite morphisms are computed.
  107. d = Diagram({f: ["unique", "isomorphism"], g: "unique"})
  108. assert d.premises[g * f] == FiniteSet("unique")
  109. # Check that conclusion morphisms with new objects are not allowed.
  110. d = Diagram([f], [g])
  111. assert d.conclusions == Dict({})
  112. # Test an empty diagram.
  113. d = Diagram()
  114. assert d.premises == Dict({})
  115. assert d.conclusions == Dict({})
  116. assert d.objects == empty
  117. # Check a SymPy Dict object.
  118. d = Diagram(Dict({f: FiniteSet("unique", "isomorphism"), g: "unique"}))
  119. assert d.premises[g * f] == FiniteSet("unique")
  120. # Check the addition of components of composite morphisms.
  121. d = Diagram([g * f])
  122. assert f in d.premises
  123. assert g in d.premises
  124. # Check subdiagrams.
  125. d = Diagram([f, g], {g * f: "unique"})
  126. d1 = Diagram([f])
  127. assert d.is_subdiagram(d1)
  128. assert not d1.is_subdiagram(d)
  129. d = Diagram([NamedMorphism(B, A, "f'")])
  130. assert not d.is_subdiagram(d1)
  131. assert not d1.is_subdiagram(d)
  132. d1 = Diagram([f, g], {g * f: ["unique", "something"]})
  133. assert not d.is_subdiagram(d1)
  134. assert not d1.is_subdiagram(d)
  135. d = Diagram({f: "blooh"})
  136. d1 = Diagram({f: "bleeh"})
  137. assert not d.is_subdiagram(d1)
  138. assert not d1.is_subdiagram(d)
  139. d = Diagram([f, g], {f: "unique", g * f: "veryunique"})
  140. d1 = d.subdiagram_from_objects(FiniteSet(A, B))
  141. assert d1 == Diagram([f], {f: "unique"})
  142. raises(ValueError, lambda: d.subdiagram_from_objects(FiniteSet(A,
  143. Object("D"))))
  144. raises(ValueError, lambda: Diagram({IdentityMorphism(A): "unique"}))
  145. def test_category():
  146. A = Object("A")
  147. B = Object("B")
  148. C = Object("C")
  149. f = NamedMorphism(A, B, "f")
  150. g = NamedMorphism(B, C, "g")
  151. d1 = Diagram([f, g])
  152. d2 = Diagram([f])
  153. objects = d1.objects | d2.objects
  154. K = Category("K", objects, commutative_diagrams=[d1, d2])
  155. assert K.name == "K"
  156. assert K.objects == Class(objects)
  157. assert K.commutative_diagrams == FiniteSet(d1, d2)
  158. raises(ValueError, lambda: Category(""))