class_docstr: Represents a diagram in a certain category.
  
  Explanation
  ===========
  
  Informally, a diagram is a collection of objects of a category and
  certain morphisms between them.  A diagram is still a monoid with
  respect to morphism composition; i.e., identity morphisms, as well
  as all composites of morphisms included in the diagram belong to
  the diagram.  For a more formal approach to this notion see
  [Pare1970].
  
  The components of composite morphisms are also added to the
  diagram.  No properties are assigned to such morphisms by default.
  
  A commutative diagram is often accompanied by a statement of the
  following kind: "if such morphisms with such properties exist,
  then such morphisms which such properties exist and the diagram is
  commutative".  To represent this, an instance of :class:`Diagram`
  includes a collection of morphisms which are the premises and
  another collection of conclusions.  ``premises`` and
  ``conclusions`` associate morphisms belonging to the corresponding
  categories with the :class:`~.FiniteSet`'s of their properties.
  
  The set of properties of a composite morphism is the intersection
  of the sets of properties of its components.  The domain and
  codomain of a conclusion morphism should be among the domains and
  codomains of the morphisms listed as the premises of a diagram.
  
  No checks are carried out of whether the supplied object and
  morphisms do belong to one and the same category.
  
  Examples
  ========
  
  >>> from sympy.categories import Object, NamedMorphism, Diagram
  >>> from sympy import pprint, default_sort_key
  >>> A = Object("A")
  >>> B = Object("B")
  >>> C = Object("C")
  >>> f = NamedMorphism(A, B, "f")
  >>> g = NamedMorphism(B, C, "g")
  >>> d = Diagram([f, g])
  >>> premises_keys = sorted(d.premises.keys(), key=default_sort_key)
  >>> pprint(premises_keys, use_unicode=False)
  [g*f:A-->C, id:A-->A, id:B-->B, id:C-->C, f:A-->B, g:B-->C]
  >>> pprint(d.premises, use_unicode=False)
  {g*f:A-->C: EmptySet, id:A-->A: EmptySet, id:B-->B: EmptySet, id:C-->C: EmptyS >
  <BLANKLINE>
  > et, f:A-->B: EmptySet, g:B-->C: EmptySet}
  >>> d = Diagram([f, g], {g * f: "unique"})
  >>> pprint(d.conclusions,use_unicode=False)
  {g*f:A-->C: {unique}}
  
  References
  ==========
  
  [Pare1970] B. Pareigis: Categories and functors.  Academic Press, 1970.
class_docstr_tok: ["Represents","a","diagram","in","a","certain","category",".","Explanation","===========","Informally",",","a","diagram","is","a","collection","of","objects","of","a","category","and","certain","morphisms","between","them",".","A","diagram","is","still","a","monoid","with","respect","to","morphism","composition",";","i.e.",",","identity","morphisms",",","as","well","as","all","composites","of","morphisms","included","in","the","diagram","belong","to","the","diagram",".","For","a","more","formal","approach","to","this","notion","see","[","Pare1970","]",".","The","components","of","composite","morphisms","are","also","added","to","the","diagram",".","No","properties","are","assigned","to","such","morphisms","by","default",".","A","commutative","diagram","is","often","accompanied","by","a","statement","of","the","following","kind",":","``","if","such","morphisms","with","such","properties","exist",",","then","such","morphisms","which","such","properties","exist","and","the","diagram","is","commutative","''",".","To","represent","this",",","an","instance","of",":","class",":","`","Diagram","`","includes","a","collection","of","morphisms","which","are","the","premises","and","another","collection","of","conclusions",".","``","premises","``","and","``","conclusions","``","associate","morphisms","belonging","to","the","corresponding","categories","with","the",":","class",":","`","~.FiniteSet","`","'s","of","their","properties",".","The","set","of","properties","of","a","composite","morphism","is","the","intersection","of","the","sets","of","properties","of","its","components",".","The","domain","and","codomain","of","a","conclusion","morphism","should","be","among","the","domains","and","codomains","of","the","morphisms","listed","as","the","premises","of","a","diagram",".","No","checks","are","carried","out","of","whether","the","supplied","object","and","morphisms","do","belong","to","one","and","the","same","category",".","Examples","========",">",">",">","from","sympy.categories","import","Object",",","NamedMorphism",",","Diagram",">",">",">","from","sympy","import","pprint",",","default_sort_key",">",">",">","A","=","Object","(","``","A","''",")",">",">",">","B","=","Object","(","``","B","''",")",">",">",">","C","=","Object","(","``","C","''",")",">",">",">","f","=","NamedMorphism","(","A",",","B",",","``","f","''",")",">",">",">","g","=","NamedMorphism","(","B",",","C",",","``","g","''",")",">",">",">","d","=","Diagram","(","[","f",",","g","]",")",">",">",">","premises_keys","=","sorted","(","d.premises.keys","(",")",",","key=default_sort_key",")",">",">",">","pprint","(","premises_keys",",","use_unicode=False",")","[","g","*","f",":","A","--",">","C",",","id",":","A","--",">","A",",","id",":","B","--",">","B",",","id",":","C","--",">","C",",","f",":","A","--",">","B",",","g",":","B","--",">","C","]",">",">",">","pprint","(","d.premises",",","use_unicode=False",")","{","g","*","f",":","A","--",">","C",":","EmptySet",",","id",":","A","--",">","A",":","EmptySet",",","id",":","B","--",">","B",":","EmptySet",",","id",":","C","--",">","C",":","EmptyS",">","<","BLANKLINE",">",">","et",",","f",":","A","--",">","B",":","EmptySet",",","g",":","B","--",">","C",":","EmptySet","}",">",">",">","d","=","Diagram","(","[","f",",","g","]",",","{","g","*","f",":","``","unique","''","}",")",">",">",">","pprint","(","d.conclusions",",","use_unicode=False",")","{","g","*","f",":","A","--",">","C",":","{","unique","}","}","References","==========","[","Pare1970","]","B.","Pareigis",":","Categories","and","functors",".","Academic","Press",",","1970","."]
docstr: Construct a new instance of Diagram.
  
  Explanation
  ===========
  
  If no arguments are supplied, an empty diagram is created.
  
  If at least an argument is supplied, ``args[0]`` is
  interpreted as the premises of the diagram.  If ``args[0]`` is
  a list, it is interpreted as a list of :class:`Morphism`'s, in
  which each :class:`Morphism` has an empty set of properties.
  If ``args[0]`` is a Python dictionary or a :class:`Dict`, it
  is interpreted as a dictionary associating to some
  :class:`Morphism`'s some properties.
  
  If at least two arguments are supplied ``args[1]`` is
  interpreted as the conclusions of the diagram.  The type of
  ``args[1]`` is interpreted in exactly the same way as the type
  of ``args[0]``.  If only one argument is supplied, the diagram
  has no conclusions.
  
  Examples
  ========
  
  >>> from sympy.categories import Object, NamedMorphism
  >>> from sympy.categories import IdentityMorphism, Diagram
  >>> A = Object("A")
  >>> B = Object("B")
  >>> C = Object("C")
  >>> f = NamedMorphism(A, B, "f")
  >>> g = NamedMorphism(B, C, "g")
  >>> d = Diagram([f, g])
  >>> IdentityMorphism(A) in d.premises.keys()
  True
  >>> g * f in d.premises.keys()
  True
  >>> d = Diagram([f, g], {g * f: "unique"})
  >>> d.conclusions[g * f]
  {unique}
docstr_tok: ["Construct","a","new","instance","of","Diagram",".","Explanation","===========","If","no","arguments","are","supplied",",","an","empty","diagram","is","created",".","If","at","least","an","argument","is","supplied",",","``","args","[","0","]","``","is","interpreted","as","the","premises","of","the","diagram",".","If","``","args","[","0","]","``","is","a","list",",","it","is","interpreted","as","a","list","of",":","class",":","`","Morphism","`","'s",",","in","which","each",":","class",":","`","Morphism","`","has","an","empty","set","of","properties",".","If","``","args","[","0","]","``","is","a","Python","dictionary","or","a",":","class",":","`","Dict","`",",","it","is","interpreted","as","a","dictionary","associating","to","some",":","class",":","`","Morphism","`","'s","some","properties",".","If","at","least","two","arguments","are","supplied","``","args","[","1","]","``","is","interpreted","as","the","conclusions","of","the","diagram",".","The","type","of","``","args","[","1","]","``","is","interpreted","in","exactly","the","same","way","as","the","type","of","``","args","[","0","]","``",".","If","only","one","argument","is","supplied",",","the","diagram","has","no","conclusions",".","Examples","========",">",">",">","from","sympy.categories","import","Object",",","NamedMorphism",">",">",">","from","sympy.categories","import","IdentityMorphism",",","Diagram",">",">",">","A","=","Object","(","``","A","''",")",">",">",">","B","=","Object","(","``","B","''",")",">",">",">","C","=","Object","(","``","C","''",")",">",">",">","f","=","NamedMorphism","(","A",",","B",",","``","f","''",")",">",">",">","g","=","NamedMorphism","(","B",",","C",",","``","g","''",")",">",">",">","d","=","Diagram","(","[","f",",","g","]",")",">",">",">","IdentityMorphism","(","A",")","in","d.premises.keys","(",")","True",">",">",">","g","*","f","in","d.premises.keys","(",")","True",">",">",">","d","=","Diagram","(","[","f",",","g","]",",","{","g","*","f",":","``","unique","''","}",")",">",">",">","d.conclusions","[","g","*","f","]","{","unique","}"]
code: def __new__(cls, *args):
      """
      Construct a new instance of Diagram.
  
      Explanation
      ===========
  
      If no arguments are supplied, an empty diagram is created.
  
      If at least an argument is supplied, ``args[0]`` is
      interpreted as the premises of the diagram.  If ``args[0]`` is
      a list, it is interpreted as a list of :class:`Morphism`'s, in
      which each :class:`Morphism` has an empty set of properties.
      If ``args[0]`` is a Python dictionary or a :class:`Dict`, it
      is interpreted as a dictionary associating to some
      :class:`Morphism`'s some properties.
  
      If at least two arguments are supplied ``args[1]`` is
      interpreted as the conclusions of the diagram.  The type of
      ``args[1]`` is interpreted in exactly the same way as the type
      of ``args[0]``.  If only one argument is supplied, the diagram
      has no conclusions.
  
      Examples
      ========
  
      >>> from sympy.categories import Object, NamedMorphism
      >>> from sympy.categories import IdentityMorphism, Diagram
      >>> A = Object("A")
      >>> B = Object("B")
      >>> C = Object("C")
      >>> f = NamedMorphism(A, B, "f")
      >>> g = NamedMorphism(B, C, "g")
      >>> d = Diagram([f, g])
      >>> IdentityMorphism(A) in d.premises.keys()
      True
      >>> g * f in d.premises.keys()
      True
      >>> d = Diagram([f, g], {g * f: "unique"})
      >>> d.conclusions[g * f]
      {unique}
  
      """
      premises = {}
      conclusions = {}
  
      # Here we will keep track of the objects which appear in the
      # premises.
      objects = EmptySet
  
      if len(args) >= 1:
          # We've got some premises in the arguments.
          premises_arg = args[0]
  
          if isinstance(premises_arg, list):
              # The user has supplied a list of morphisms, none of
              # which have any attributes.
              empty = EmptySet
  
              for morphism in premises_arg:
                  objects |= FiniteSet(
                      morphism.domain, morphism.codomain
                  )
                  Diagram._add_morphism_closure(
                      premises, morphism, empty
                  )
          elif isinstance(premises_arg, (dict, Dict)):
              # The user has supplied a dictionary of morphisms and
              # their properties.
              for morphism, props in premises_arg.items():
                  objects |= FiniteSet(
                      morphism.domain, morphism.codomain
                  )
                  Diagram._add_morphism_closure(
                      premises,
                      morphism,
                      FiniteSet(*props)
                      if iterable(props)
                      else FiniteSet(props),
                  )
  
      if len(args) >= 2:
          # We also have some conclusions.
          conclusions_arg = args[1]
  
          if isinstance(conclusions_arg, list):
              # The user has supplied a list of morphisms, none of
              # which have any attributes.
              empty = EmptySet
  
              for morphism in conclusions_arg:
                  # Check that no new objects appear in conclusions.
                  if (
                      sympify(objects.contains(morphism.domain))
                      is S.true
                  ) and (
                      sympify(objects.contains(morphism.codomain))
                      is S.true
                  ):
                      # No need to add identities and recurse
                      # composites this time.
                      Diagram._add_morphism_closure(
                          conclusions,
                          morphism,
                          empty,
                          add_identities=False,
                          recurse_composites=False,
                      )
          elif isinstance(conclusions_arg, (dict, Dict)):
              # The user has supplied a dictionary of morphisms and
              # their properties.
              for morphism, props in conclusions_arg.items():
                  # Check that no new objects appear in conclusions.
                  if (morphism.domain in objects) and (
                      morphism.codomain in objects
                  ):
                      # No need to add identities and recurse
                      # composites this time.
                      Diagram._add_morphism_closure(
                          conclusions,
                          morphism,
                          FiniteSet(*props)
                          if iterable(props)
                          else FiniteSet(props),
                          add_identities=False,
                          recurse_composites=False,
                      )
  
      return Basic.__new__(
          cls, Dict(premises), Dict(conclusions), objects
      )
  
imports: from sympy.core import S, Basic, Dict, Symbol, Tuple, sympify
  from sympy.core.symbol import Str
  from sympy.sets import Set, FiniteSet, EmptySet
  from sympy.utilities.iterables import iterable
label_desc: Use image node_id 3 for calling the Diagram obj's underlying member method code with example usage: obj.__new__(cls) and returns: Basic