A Registration represents an AndFilter with only elementary or negated
elementary filters. (In a future version, a Registration can represent
multiple equal such AndFilters.)

A Registration is entered into all tables for whose type its AndFilter
contains an elementary filter.

Each table maps a value for the filter criterion to a YesSet and a
NoSet. The YesSet contains all Registrations where a non-negated
elementary filter for the key criterion occurred. The NoSet contains
all Registrations where a negated elementary filter for the key
criterion occurred.

When an event occurs, it matches a Registration if and only if all
(negated and non-negated) elementary filters of the registration are
matched. This means that:

 - if a Registration is in table t's YesSet, it MUST be matched by the
   event e (R1). This in particular requires that e affects t.

 - if a Registration is in a table t's NoSet, it MUST NOT be matched by
   the event e (R2). This is in particular the case if e does not
   affect t.

Formally, we can define a test function that for a given Registration
r and a given event e determines if the Registration if matched by the
event:

   matches(r, e) := tables->forAll(t |
                       (t.allYes->includes(r) implies
                         (t.yes(e)->includes(r) and t.affectedBy(e)))
                  and  (t.allNo->includes(r) implies
                         (not t.affectedBy(e) or not t.no(e)->includes(r))))

Transformed:

   matches(r, e) := tables->forAll(t | matches(t, r, e))
   matches(t, r, e) :=
		(not t.allYes->includes(r) or t.yes(e)->includes(r) and t.affectedBy(e))
	and	(not t.allNo->includes(r) or not (t.no(e)->includes(r) and t.affectedBy(e)))

which shows that registrations neither in the allYes nor allNo of a
table t are matched by that table.

Thinking in sets, the set of registrations matching e is the
intersection of the sets of registrations matched by each table. The
problem with this definition is only that the "universe" of all
registrations to be considered is the union of all allYes and allNo
sets of all tables, computing which would be inefficient.


The challenge now is to compute all r for a given event e for which
matches(r, e) holds. Fast operations (O(1)) are t.allNo, t.allYes,
t.yes(e), t.no(e), also t.affectedBy(e). The number of Registrations r
may be large, and so may be t.allYes, t.allNo, t.yes(e) and t.no(e),
although typically t.allNo is fairly small, and so is t.no(e),
particularly in the context of the OCL impact analysis.

We also know that the union of t.allYes->union(t.allNo) over all
tables t results in the complete set of all Registrations. In other
words, each Registration to be considered is in the allYes or allNo
set of at least one table. The number of tables is constant and fairly
small (usually <10).

We are looking for a function

    registrations(e) := all registrations r such that matches(r, e)

that can be computed efficiently.



TODO Special handling for multi-registrations, such as for multiple
classes in the class filter table: In this case the Registration is
matched if any of the multiple criteria are matched by the event. TODO
What happens for a negated filter that would expand to multiple
criteria?
