@@ -285,9 +285,9 @@ Built-in modules
285
285
****************
286
286
287
287
QL 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.
291
291
292
292
Equivalence relations
293
293
=====================
@@ -347,3 +347,80 @@ The above select clause returns the following partial equivalence relation:
347
347
+---+---+
348
348
| 4 | 4 |
349
349
+---+---+
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