15.4.5. Keys for aspects
We’ve shown how to construct keys in runtime from the types of the instances. The most complicated keys are derived from RoleBindingDeltas, consisting of two ContextTypes and one RoleType. But each of these types can be composed of Aspects. What are the consequences for the keys that should be constructed?
Each instance has a collection of types. A key is a triplet; should we construct all triplets from the type collections? At least we know that all relevant keys are in this product, but there are constraints on the combinations:
-
Aspect Roles and Aspect Contexts of a Role- and ContextType pair cannot be freely combined. We must treat Role- and ContextTypes as fixed pairs, where the RoleType is the lexically embedded in precisely one ContextType.
-
The possible fillers of a role are constrained by the possible fillers of its Aspects. If we say that Driver is constrained to be filled by a Human, we cannot have a role ArmouredCarDriver that uses Driver as Aspect but should be filled by a Robot (unless we let Robot have Human as Aspect).
As a consequence, on constructing triplet keys for queries starting on the filledBy step we can work as follows:
-
We start with the Filled role type;
-
We add to that all its Aspects;
-
For each of these we construct a key that consists of:
-
Its context type;
-
The type of its Filler;
-
The type of the lexical context of that Filler.
-
So, from a single RoleBindingDelta, we construct as many triplet keys for the filledBy step as there are types of the filled role instance.
For the fills step we follow the same procedure (working from the Filled role type), but we construct the key by leaving out the type of the Filler role instance instead of that of the Filled role instance.
15.4.5.1. Handling complex filler types
But we’re not done yet. A role may have a complex filler type, expressed as an ADT RoleInContext. Let’s consider the role Parent to be filled by either Father or Mother, so its filler type is SUM Father Mother. Clearly, we can derive two keys from that filler type.
So our final algorithm is:
-
Start with the Filled role type;
-
We add to that all its Aspects, forming the set of FilledTypes;
-
For each element FilledType of FilledTypes we construct a number of keys, by
-
Listing all of the EnumeratedRoleTypes in FilledType’s Filler type;
-
for each of those Filler types we construct for the filledBy step a single key from
-
FilledType’s context type;
-
Filler;
-
The type of the lexical context of Filler.
-
-
And this is how we construct keys for the fills step instead. Take
-
FilledType’s context type;
-
FilledType;
-
The type of the lexical context of Filler.
-
-