Merge pull request #1464 from scolobb/set-sort_key

Set: Fix the sort_key.
Start the diagram_drawing module.

This commit adds the new module, a docstring, and the declaration of
DiagramOutline.  The class itself will be implemented later.
Add _GrowableGrid and corresponding tests.

This class represents a simple grid (two-dimensional array) which can be
grown in any of the four directions by appending empty rows and columns.
Have Diagram add components of composite morphisms automatically.

Previously, diagram would not add the components of composite morphisms.
This leaved some subtle ambiguities as to how to handle composite
morphisms which had some components not included into the diagram.  This
commit fixes those ambiguities.
Add some rudimentary tests for DiagramGrid.

The goal of having this tests is assuring that DiagramGrid.__new__ is
invoked.  Further tests will come together the corresponding
functionality.
DiagramGrid: Simplify the premises and conclusions and merge them.

At the drawing stage, the separation between the premises and
conclusions of the diagram is not relevant; DiagramGrid discards this
separation.  If a morphism is included both in premises and in
conclusions, after the merging the morphism will have the properties it
had in conclusions.
DiagramGrid: Build the undirected skeleton.

The skeleton of a diagram is the (undirected) graph whose vertices are
the objects of the diagram and which contains an edge between any pair
of objects between which in (the simplified, cf. previous commit)
diagram there is at least one morphism.  The skeleton also includes
edges between vertices A and C, such that there exists and object B
which is connected by at least one morphism with A and at least one
morphism with C.

The construction of this skeleton is one of the core tricks of the
layouting functionality.  The skeleton is constructed in such a way that
it can always be split into triangles.

Note that the term "skeleton" as used in the code, is defined ad-hoc.
DiagramGrid: Build meaningful triangles from the skeleton of the diagram.

DiagramGrid now sees which triangles are there in the skeleton, but also
discards the triangles which have less than 2 edges corresponding to
morphisms.  Such triangles may appear because of the how the skeleton is
constructed (cf. previous commit) and are irrelevant to laying the
diagram out, because only one edge of them will eventually be shown.
Note that such triangles are actually redundant in the sense that the
objects and morphisms they refer to will eventually be pulled into the
grid by other, more meaningful triangles.  This redundancy arises from
how the triangles are built and may be a point of further improvement
and/or optimisation.
DiagramGrid: Add some triangle utility functions.

This commit adds _triangle_objects which returns the set of vertices
of a triangle and _other_vertex, which, given a triangle and an edge,
returns the vertex which opposes the edge.
DiagramGrid: Lay down the beginnings of the main construction loop.

This commit enables DiagramGrid to add the first edge to the layout and
introduces the (currently empty) function _weld_triangle, which welds
one triangle to the current fringe.

All triangles which are relevant to the plot are assumed to form a
prefix of the list of triangles.  Whether this is true will be later
revealed by further tests and the details of functionality.
DiagramGrid: Find the place to attach a triangle to the existing fringe.

This commit adds and utilises _find_triangle_welding, which finds a
place in the fringe to weld the supplied triangle to.
DiagramGrid: Prepare to fixing some of the degenerate situations in the fringe.

This commit adds _fix_degenerate which, given an edge from the fringe
and two points, checks whether one of the two points defines an edge,
which is in the fringe, and which is perpendicular on the given edge.
If such a situation is found, _fix_degenerate drops the two edges and
adds the corresponding diagonal to the fringe.
DiagramGrid: Decide how to place the outstanding vertex of the welded triangle.

While _find_triangle_welding shows how to place one edge of the
triangle, it is important and nontrivial to decide where to place the
third vertex.  DiagramGrid is now capable to make this decision, while
also fixing some possible degenerate situations in the fringe.
DiagramGrid: Finalise the basic layouting functionality.

DiagramGrid.__new__ now can cope with some simple diagrams.  It can
maybe cope with more complex diagrams; I don't know yet.
DiagramGrid: Add _choose_target_cell.

This commit factors out the functionality of choosing one of the two
points above or below of a horizontal edge and to the left or to the
right of a vertical edge.  The new function will be later extended to
allow Diagram to avoid some of the intersections of the representations
of morphisms.
DiagramGrid: Extend _choose_target_cell to choose the point better.

This commit enables _choose_target_cell (cf. previous commit) to
intelligently treat the situation when both points are free.  If this is
the case, the function now makes such a choice that, should the triangle
have only two visible edges, the edge different from the welding edge
will be drawn perpendicular to the welding edge.  This will eventually
help avoid some of the intersections of morphisms.
DiagramGrid: Use _put_object also to update the target cell.

If _put_object prepends the grid with a row or a column, the coordinates
of the target cell become different as well.  This must be taken into
account.
DiagramGrid: Remove _fix_degenerate.

It turns out that the situations which I considered when implementing
_fix_degenerate are not at all degenerate.  Therefore, at the moment,
very little is done to minimise the size of the fringe after adding a
triangle to the grid.  I will analyse the question of keeping only the
outer edges of the structure in the fringe later.
DiagramGrid: Keep track of the objects added to the diagram.

DiagramGrid now stops laying out the diagram when all objects have been
added to the grid.  Previously, it would zealously work on until all
triangles have been exhausted.
DiagramGrid: Prefer going down and to the right when building diagrams.

This will in most cases result in a more natural placing of the objects
of the diagram, because of how humans read from left to right, from top
to bottom.