@@ -285,9 +285,9 @@ Built-in modules
285285****************
286286
287287QL defines a ``QlBuiltins `` module that is always in scope.
288- Currently, it defines a single parameterized sub-module
289- ``EquivalenceRelation ``, that provides an efficient abstraction for working with
290- (partial) equivalence relations in QL.
288+ `` QlBuiltins `` defines parameterized sub-modules for working with
289+ (partial) equivalence relations ( ``EquivalenceRelation ``) and sets
290+ (`` InternSets ``) in QL.
291291
292292Equivalence relations
293293=====================
@@ -347,3 +347,80 @@ The above select clause returns the following partial equivalence relation:
347347+---+---+
348348| 4 | 4 |
349349+---+---+
350+
351+ Sets
352+ ====
353+
354+ The built-in ``InternSets `` module is parameterized by ``Key `` and ``Value `` types
355+ and a ``Value getAValue(Key key) `` relation. The module groups the ``Value ``
356+ column by ``Key `` and creates a set for each group of values related by a key.
357+
358+ The ``InternSets `` module exports a functional ``Set getSet(Key key) `` relation
359+ that relates keys with the set of value related to the given key by
360+ ``getAValue ``. Sets are represented by the exported ``Set `` type which exposes
361+ a ``contains(Value v) `` member predicate that holds for values contained in the
362+ given set. `getSet(k).contains(v) ` is thus equivalent to `v = getAValue(k) ` as
363+ illustrated by the following ``InternSets `` example:
364+
365+ .. code-block :: ql
366+
367+ int getAValue(int key) {
368+ key = 1 and result = 1
369+ or
370+ key = 2 and
371+ (result = 1 or result = 2)
372+ or
373+ key = 3 and result = 1
374+ or
375+ key = 4 and result = 2
376+ }
377+
378+ module Sets = QlBuiltins::InternSets<int, int, getAValue/1>;
379+
380+ from int k, int v
381+ where Sets::getSet(k).contains(v)
382+ select k, v
383+
384+ This evalutes to the `getAValue ` relation:
385+
386+ +---+---+
387+ | k | v |
388+ +===+===+
389+ | 1 | 1 |
390+ +---+---+
391+ | 2 | 1 |
392+ +---+---+
393+ | 2 | 2 |
394+ +---+---+
395+ | 3 | 1 |
396+ +---+---+
397+ | 4 | 2 |
398+ +---+---+
399+
400+ If two keys `k1 ` and `k2 ` relate to the same set of values, then `getSet(k1) = getSet(k2) `.
401+ For the above example, keys 1 and 3 relate to the same set of values (namely the singleton
402+ set containing 1) and are therefore related to the same set by ``getSet ``:
403+
404+ .. code-block :: ql
405+
406+ from int k1, int k2
407+ where Sets::getSet(k1) = Sets::getSet(k2)
408+ select k1, k2
409+
410+ The above query therefore evalutes to:
411+
412+ +----+----+
413+ | k1 | k2 |
414+ +====+====+
415+ | 1 | 1 |
416+ +----+----+
417+ | 1 | 3 |
418+ +----+----+
419+ | 2 | 2 |
420+ +----+----+
421+ | 3 | 1 |
422+ +----+----+
423+ | 3 | 3 |
424+ +----+----+
425+ | 4 | 4 |
426+ +----+----+
0 commit comments