blob: e621250e116a30a543badb0c692ed58200efe7fc [file] [log] [blame]
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?