begin refactoring Labeler

Change `Labeler` into an abstract class, to be used as a factory later)
and create a new `BitSetLabeler` which implements it and creates
`BitSetLabel`s. Needs tests and unification with `IntLabeler`, which
was renamed from `Labeler`.
add masking functionality to Labeler

Get rid of the idea of a `Mask` object, which was problematice for
encapsulation. Instead, allow the `Labeler`s to `partition` `Label`
objects that they know how to deal with. Implent it in the
`BitSetLabeler`, but don't unify it with `IntLabeler` or test it yet.
reorganize label-related classes

The original labeler now extends `Labeler` as `IntLabeler`, and same
for `Label` and `IntLabel`. Public mask objects are no more; instead,
a `Labeler` object knows how to `partition` it's own labels, and that's
that. Change objects where possible to be declared instances of the
interface isntead of the implementations. Tests still needed.
cleanup Lattice and its tests

Change `ILattice` to `Lattice`, since having the `I` doesn't seem to do
much, and there's no similar marking for the abstract classes. Simplify
its tests, which no longer need to deal with multiple constructor
types.

Simplify the `HeterogeneousLattice` tests as well by using the
`fromString` functionality. Improve related documentation, as well.
organize and write labeler tests

Create a general labeler test for testing all `Labeler`
implementations. Put the implementation-specific tests in their own
files. Refactor/document here and there on the way.
band-aid the changing outcome in hetero supras

The outcome in heterogeneous supracontexts, produced by
`HeterogeneousLattice`, is not deterministic; it depends on what
subcontext it is first given, and that comes out of an unordered set.
This caused intermittent test failures. For now, the band-aid is to
specifically ignore outcomes during comparison. However, there clearly
needs to be another kind of `Supracontext` for use by
`HeterogeneousLattice`.
squash with labeler changes
move hetero declaration logic into Supracontext

Move the logic for deciding if a `Supracontext` is heterogeneous or not
into the `Supracontext` class. Now the various lattices do not have to
keep track of it. Also, the outcome in heterogeneous `Supracontext`
objects will be determined by the contained data, not by the order the
data was added, so remove the workarounds from the previous commit.

This is still not a great design because now time is wasted on deciding
heterogeneity even when it is not needed because the `Supracontexts`
are not final (see `SupracontextCombiner` line 58).
test Label

Write interface- and implementation-specific tests for `Label`. Add
a copy constructor to `IntLabel` so that other `Label` objects can be
normalized, hashed, and compared for equality. Update documentation
where possible.
fix bug turning supras back into homogeneous

Fix a bug whereby already heterogeneous supracontexts could become
homogeneous by having a deterministic subcontext added to them.
Add a regression test.

Also re-write `add(sub)` so that it only changes `outcome` when it has
to. This takes more logic, but it makes it clearer how heterogeneity
works.
fix incorrect code checking for empty supra

The code in `BasicLattice` should be checking for the known `emptySupracontext` object, not just any supra with count of zero. The algorithm will not try to decrement any other supra with count zero, and if it did it would result in an error. This unifies the code with the `DistributedLattice` implementation.