Start the commutativity module.

This commit adds the commutativity module, the function
diagram_embeddings, and some tests for this function, which currently
fail.  The tests for diagram_embeddings are not exhaustive at the
moment; I will add the necessary tests as I go.
Embeddings: Transition to simple graphs.

Diagrams are essentially multigraphs.  To be able to list all embeddings,
we will need to first convert both the pattern and the model to a simple
graph, then apply Ullman's algorithm (see references in the code) to
generate all subgraph embeddings, and then, from these embeddings, generate
the multigraph embeddings.

To apply Ullman's algorithm, we will need to do matrix multiplication
with adjacency matrices, this is why we set up bidirectional mappings
between the objects of the diagrams and their indices.

This commit introduces the main magic which will eventually allow
``diagram_embeddings`` to work with infinite diagrams.
Embeddings: Compute the input and output degrees.

Note that the degrees of the vertices are computed as they are in the
original multigraph.  The comment in the code gives a little bit more
details.
Embeddings: Initialise M_0.

This is the first stage of the matrix M which will eventually represent
subgraph isomorphisms.  For more details, see the references in the
code.
Embeddings: Implement Ullman's algorithm.

This implementation follows [Ullm1976] as closely as it would make
sense.  Note, however, that since we are actually dealing with directed
multigraphs, there are deviations.  The code abounds in comments,
though.
Embeddings: Construct actual morphism embeddings.

This commit enables the function ``digram_embeddings`` to actually produce
multigraph embeddings basing on graph embeddings generated by the previously
implemented Ullman's algorithm.

Note that these are not yet total diagram embeddings: we only know how
the generator morphisms of the pattern are mapped right now.
Embeddings: Generate actual diagram embeddings.

This commit finalises the functionality of ``diagram_embeddings`` by
making this function provide complete embeddings.  Note again that for
an infinite pattern only the information about the embeddings of
expanded generators of the pattern will be provided.  (See the dosctring
of ``Diagram`` for more details.)

This commit makes the tests pass.
Embeddings: Simplify pattern generators as much as possible.

This commit makes ``diagram_embeddings`` drop _all_ composites in the
generators of the pattern.  The reason why it is OK to do it here, but
not OK to do in ``Diagram`` is explained in the comment.
Embeddings: Test embeddings with properties.

Previously, there was only a test for embeddings without properties.
This commit essentially repeats that test, and adds morphism properties.
Embeddings: Apply the refinement procedure.

This commit applies the version the refinement procedure from [Ullm1976]
adapted to directed graphs (page 9).
Embeddings: Improve the morphism property matching strategy.

Previously, ``match_morphisms`` would only consider two morphisms to
match if they had exactly the same set of properties.  This commit
changes this behaviour; a morphism from the pattern now matches a
morphism from the model if its properties in the pattern are a subset of
the properties in the model.

Apparently, this is more consistent with the idea of pattern matching in
general.  However, this change is more of an intuitive one.  If it
doesn't work out well, I will revert it.
diagram_embeddings: Fix how the refinement condition is applied.

``subgraph_isomorphisms`` used to terminate rather prematurely after it
found that refined failed at least once.  This commit makes this
function react properly and thus always produce the correct embeddings.
Embeddings: Add more complex tests.

This commit adds a number of new tests, including some tests with
infinite diagrams.
diagram_embeddings: Remove is_subgraph_isomorphism.

This check has essentially become redundant once we had the refinement
procedure in place.  The redundancy is confirmed by tests.
Assure 97% test coverage and explain the 3% in a comment.

Essentially, I cannot come up with a test case which would cover the
currently uncovered 5 lines.  However, since [Ullm1976] does it, I
prefer to keep those checks, even though they may be redundant.
Start implementing and write a basic test for commutativity inference.

This commit adds the function ``_check_commutativity_with_diagrams`` and
a trivial test for it.  This function will eventually be able to carry out
the commutativity stage of the inference process, i.e., see whether a
diagram is commutative basing on a list of diagrams known to be
commutative.  In that context, more extensive tests will be written.
_check...diagrams: Add functions to get reachability information.

This commit adds the functions ``reachable_objects`` and
``reverse_reachable_objects`` to ``_check_commutativity_with_diagrams``.
This functions will later be used in deciding whether two commutative
subdiagrams can be merged.
_check...diagrams: Verify the commutativity of a ``Diagram``.

This commit finalises the function
``_check_commutativity_with_diagrams``.  It does not provide extensive
docstrings yet.
Start _apply_implication.

This function will be used to investigate all possible applications of
an implication to a diagram.  This commit also adds some tests with
explanations.
Implement _apply_implication.

This commit makes the tests pass.