class_docstr: Constructs and holds the fitting of the diagram into a grid.
  
  Explanation
  ===========
  
  The mission of this class is to analyse the structure of the
  supplied diagram and to place its objects on a grid such that,
  when the objects and the morphisms are actually drawn, the diagram
  would be "readable", in the sense that there will not be many
  intersections of moprhisms.  This class does not perform any
  actual drawing.  It does strive nevertheless to offer sufficient
  metadata to draw a diagram.
  
  Consider the following simple diagram.
  
  >>> from sympy.categories import Object, NamedMorphism
  >>> from sympy.categories import Diagram, DiagramGrid
  >>> from sympy import pprint
  >>> A = Object("A")
  >>> B = Object("B")
  >>> C = Object("C")
  >>> f = NamedMorphism(A, B, "f")
  >>> g = NamedMorphism(B, C, "g")
  >>> diagram = Diagram([f, g])
  
  The simplest way to have a diagram laid out is the following:
  
  >>> grid = DiagramGrid(diagram)
  >>> (grid.width, grid.height)
  (2, 2)
  >>> pprint(grid)
  A  B
  <BLANKLINE>
     C
  
  Sometimes one sees the diagram as consisting of logical groups.
  One can advise ``DiagramGrid`` as to such groups by employing the
  ``groups`` keyword argument.
  
  Consider the following diagram:
  
  >>> D = Object("D")
  >>> f = NamedMorphism(A, B, "f")
  >>> g = NamedMorphism(B, C, "g")
  >>> h = NamedMorphism(D, A, "h")
  >>> k = NamedMorphism(D, B, "k")
  >>> diagram = Diagram([f, g, h, k])
  
  Lay it out with generic layout:
  
  >>> grid = DiagramGrid(diagram)
  >>> pprint(grid)
  A  B  D
  <BLANKLINE>
     C
  
  Now, we can group the objects `A` and `D` to have them near one
  another:
  
  >>> grid = DiagramGrid(diagram, groups=[[A, D], B, C])
  >>> pprint(grid)
  B     C
  <BLANKLINE>
  A  D
  
  Note how the positioning of the other objects changes.
  
  Further indications can be supplied to the constructor of
  :class:`DiagramGrid` using keyword arguments.  The currently
  supported hints are explained in the following paragraphs.
  
  :class:`DiagramGrid` does not automatically guess which layout
  would suit the supplied diagram better.  Consider, for example,
  the following linear diagram:
  
  >>> E = Object("E")
  >>> f = NamedMorphism(A, B, "f")
  >>> g = NamedMorphism(B, C, "g")
  >>> h = NamedMorphism(C, D, "h")
  >>> i = NamedMorphism(D, E, "i")
  >>> diagram = Diagram([f, g, h, i])
  
  When laid out with the generic layout, it does not get to look
  linear:
  
  >>> grid = DiagramGrid(diagram)
  >>> pprint(grid)
  A  B
  <BLANKLINE>
     C  D
  <BLANKLINE>
        E
  
  To get it laid out in a line, use ``layout="sequential"``:
  
  >>> grid = DiagramGrid(diagram, layout="sequential")
  >>> pprint(grid)
  A  B  C  D  E
  
  One may sometimes need to transpose the resulting layout.  While
  this can always be done by hand, :class:`DiagramGrid` provides a
  hint for that purpose:
  
  >>> grid = DiagramGrid(diagram, layout="sequential", transpose=True)
  >>> pprint(grid)
  A
  <BLANKLINE>
  B
  <BLANKLINE>
  C
  <BLANKLINE>
  D
  <BLANKLINE>
  E
  
  Separate hints can also be provided for each group.  For an
  example, refer to ``tests/test_drawing.py``, and see the different
  ways in which the five lemma [FiveLemma] can be laid out.
  
  See Also
  ========
  
  Diagram
  
  References
  ==========
  
  .. [FiveLemma] https://en.wikipedia.org/wiki/Five_lemma
class_docstr_tok: ["Constructs","and","holds","the","fitting","of","the","diagram","into","a","grid",".","Explanation","===========","The","mission","of","this","class","is","to","analyse","the","structure","of","the","supplied","diagram","and","to","place","its","objects","on","a","grid","such","that",",","when","the","objects","and","the","morphisms","are","actually","drawn",",","the","diagram","would","be","``","readable","''",",","in","the","sense","that","there","will","not","be","many","intersections","of","moprhisms",".","This","class","does","not","perform","any","actual","drawing",".","It","does","strive","nevertheless","to","offer","sufficient","metadata","to","draw","a","diagram",".","Consider","the","following","simple","diagram",".",">",">",">","from","sympy.categories","import","Object",",","NamedMorphism",">",">",">","from","sympy.categories","import","Diagram",",","DiagramGrid",">",">",">","from","sympy","import","pprint",">",">",">","A","=","Object","(","``","A","''",")",">",">",">","B","=","Object","(","``","B","''",")",">",">",">","C","=","Object","(","``","C","''",")",">",">",">","f","=","NamedMorphism","(","A",",","B",",","``","f","''",")",">",">",">","g","=","NamedMorphism","(","B",",","C",",","``","g","''",")",">",">",">","diagram","=","Diagram","(","[","f",",","g","]",")","The","simplest","way","to","have","a","diagram","laid","out","is","the","following",":",">",">",">","grid","=","DiagramGrid","(","diagram",")",">",">",">","(","grid.width",",","grid.height",")","(","2",",","2",")",">",">",">","pprint","(","grid",")","A","B","<","BLANKLINE",">","C","Sometimes","one","sees","the","diagram","as","consisting","of","logical","groups",".","One","can","advise","``","DiagramGrid","``","as","to","such","groups","by","employing","the","``","groups","``","keyword","argument",".","Consider","the","following","diagram",":",">",">",">","D","=","Object","(","``","D","''",")",">",">",">","f","=","NamedMorphism","(","A",",","B",",","``","f","''",")",">",">",">","g","=","NamedMorphism","(","B",",","C",",","``","g","''",")",">",">",">","h","=","NamedMorphism","(","D",",","A",",","``","h","''",")",">",">",">","k","=","NamedMorphism","(","D",",","B",",","``","k","''",")",">",">",">","diagram","=","Diagram","(","[","f",",","g",",","h",",","k","]",")","Lay","it","out","with","generic","layout",":",">",">",">","grid","=","DiagramGrid","(","diagram",")",">",">",">","pprint","(","grid",")","A","B","D","<","BLANKLINE",">","C","Now",",","we","can","group","the","objects","`","A","`","and","`","D","`","to","have","them","near","one","another",":",">",">",">","grid","=","DiagramGrid","(","diagram",",","groups=","[","[","A",",","D","]",",","B",",","C","]",")",">",">",">","pprint","(","grid",")","B","C","<","BLANKLINE",">","A","D","Note","how","the","positioning","of","the","other","objects","changes",".","Further","indications","can","be","supplied","to","the","constructor","of",":","class",":","`","DiagramGrid","`","using","keyword","arguments",".","The","currently","supported","hints","are","explained","in","the","following","paragraphs",".",":","class",":","`","DiagramGrid","`","does","not","automatically","guess","which","layout","would","suit","the","supplied","diagram","better",".","Consider",",","for","example",",","the","following","linear","diagram",":",">",">",">","E","=","Object","(","``","E","''",")",">",">",">","f","=","NamedMorphism","(","A",",","B",",","``","f","''",")",">",">",">","g","=","NamedMorphism","(","B",",","C",",","``","g","''",")",">",">",">","h","=","NamedMorphism","(","C",",","D",",","``","h","''",")",">",">",">","i","=","NamedMorphism","(","D",",","E",",","``","i","''",")",">",">",">","diagram","=","Diagram","(","[","f",",","g",",","h",",","i","]",")","When","laid","out","with","the","generic","layout",",","it","does","not","get","to","look","linear",":",">",">",">","grid","=","DiagramGrid","(","diagram",")",">",">",">","pprint","(","grid",")","A","B","<","BLANKLINE",">","C","D","<","BLANKLINE",">","E","To","get","it","laid","out","in","a","line",",","use","``","layout=","''","sequential","''","``",":",">",">",">","grid","=","DiagramGrid","(","diagram",",","layout=","''","sequential","''",")",">",">",">","pprint","(","grid",")","A","B","C","D","E","One","may","sometimes","need","to","transpose","the","resulting","layout",".","While","this","can","always","be","done","by","hand",",",":","class",":","`","DiagramGrid","`","provides","a","hint","for","that","purpose",":",">",">",">","grid","=","DiagramGrid","(","diagram",",","layout=","''","sequential","''",",","transpose=True",")",">",">",">","pprint","(","grid",")","A","<","BLANKLINE",">","B","<","BLANKLINE",">","C","<","BLANKLINE",">","D","<","BLANKLINE",">","E","Separate","hints","can","also","be","provided","for","each","group",".","For","an","example",",","refer","to","``","tests\/test_drawing.py","``",",","and","see","the","different","ways","in","which","the","five","lemma","[","FiveLemma","]","can","be","laid","out",".","See","Also","========","Diagram","References","==========","..","[","FiveLemma","]","https",":","\/\/en.wikipedia.org\/wiki\/Five_lemma"]
docstr: Returns a dictionary mapping triangles to their minimal sizes.
  The minimal size of a triangle is the sum of maximal lengths
  of morphisms associated to the sides of the triangle.  The
  length of a morphism is the number of components it consists
  of.  A non-composite morphism is of length 1.
  
  Sorting triangles by this metric attempts to address two
  aspects of layout.  For triangles with only simple morphisms
  in the edge, this assures that triangles with all three edges
  visible will get typeset after triangles with less visible
  edges, which sometimes minimizes the necessity in diagonal
  arrows.  For triangles with composite morphisms in the edges,
  this assures that objects connected with shorter morphisms
  will be laid out first, resulting the visual proximity of
  those objects which are connected by shorter morphisms.
docstr_tok: ["Returns","a","dictionary","mapping","triangles","to","their","minimal","sizes",".","The","minimal","size","of","a","triangle","is","the","sum","of","maximal","lengths","of","morphisms","associated","to","the","sides","of","the","triangle",".","The","length","of","a","morphism","is","the","number","of","components","it","consists","of",".","A","non-composite","morphism","is","of","length","1",".","Sorting","triangles","by","this","metric","attempts","to","address","two","aspects","of","layout",".","For","triangles","with","only","simple","morphisms","in","the","edge",",","this","assures","that","triangles","with","all","three","edges","visible","will","get","typeset","after","triangles","with","less","visible","edges",",","which","sometimes","minimizes","the","necessity","in","diagonal","arrows",".","For","triangles","with","composite","morphisms","in","the","edges",",","this","assures","that","objects","connected","with","shorter","morphisms","will","be","laid","out","first",",","resulting","the","visual","proximity","of","those","objects","which","are","connected","by","shorter","morphisms","."]
code: def _compute_triangle_min_sizes(triangles, edges):
      r"""
      Returns a dictionary mapping triangles to their minimal sizes.
      The minimal size of a triangle is the sum of maximal lengths
      of morphisms associated to the sides of the triangle.  The
      length of a morphism is the number of components it consists
      of.  A non-composite morphism is of length 1.
  
      Sorting triangles by this metric attempts to address two
      aspects of layout.  For triangles with only simple morphisms
      in the edge, this assures that triangles with all three edges
      visible will get typeset after triangles with less visible
      edges, which sometimes minimizes the necessity in diagonal
      arrows.  For triangles with composite morphisms in the edges,
      this assures that objects connected with shorter morphisms
      will be laid out first, resulting the visual proximity of
      those objects which are connected by shorter morphisms.
      """
      triangle_sizes = {}
      for triangle in triangles:
          size = 0
          for e in triangle:
              morphisms = edges[e]
              if morphisms:
                  size += max(
                      DiagramGrid._morphism_length(m) for m in morphisms
                  )
          triangle_sizes[triangle] = size
      return triangle_sizes
  
imports: from sympy.categories import CompositeMorphism, IdentityMorphism, NamedMorphism, Diagram
  from sympy.core import Dict, Symbol, default_sort_key
  from sympy.printing.latex import latex
  from sympy.sets import FiniteSet
  from sympy.utilities.iterables import iterable
  from sympy.utilities.decorator import doctest_depends_on
  from itertools import chain
label_desc: Use image node_id 9 for calling the DiagramGrid obj's underlying member method code with example usage: obj._compute_triangle_min_sizes(triangles, edges) and returns: triangle_sizes