logo
Association Predicates < TMQL Introduction < < Home 

PrevUpNext

Association Predicates

Predicates are tests, so they either return true or false depending on whether the claim they represent is verifyable or not. In this sense, predicates are specialized functions. And since functions can be declared in the meta map, so can predicates.

As example let us consider that our queried map contains associations of type has-created where we have recorded which artist (single or group) has created which album, such as "U2 as creator has created an opus 'Rattle and Hum'", or "'Leonard Cohen as creator has created an opus 'Various Positions'".

It lies in the nature of associations of type has-created that if a group has created something, then we might also deduce that every member of the group also has created that thing. Naturally, we do not want to change our map and add all this redundant information to it. Instead we would like add a rule to the purpose of "if an individual belongs to a group and the group has created something, so has the individual".

"""
has-created-indirect isa tmql:predicate
where: """
     has-created (creator: $creator, opus: $opus)
     |
     is-part-of  (member : $creator, whole: $group) &
     has-created (creator: $group,   opus : $opus)
"""
Obviously, this predicate is nothing else than a boolean condition. Different to functions, though, is that there are no parameters that a caller must provide. How the predicate is operating depends on its use:
select $person
where
     $person isa person &
     $thing  isa *      &
     has-created-indirect (creator: $person, opus: $thing)
Here we iterate over all persons and all things in the map. For each of these pairings we then invoke the predicate whereby we pass one person as creator and one thing as opus. In the predicate now the only unbound variable is $group. The processor will now try to evaluate the predicate whereby it will keep $creator and $opus fixed, but will vary the only unbound variable $group by letting it iterate over all possible values.

The obvious benefit of such rules is to keep redundancy in maps itself low, while not burdening the query itself; it would have been completely equivalent to hard-code it there:

select $person
where
     $person isa person &
     $thing  isa *      &
     (
     	has-created (creator: $person, opus: $thing)
     	|
     	is-part-of  (member : $person, whole: $group) &
     	has-created (creator: $group,  opus : $thing)
     )


PrevUpNext