Skip to content

Commit 486eaad

Browse files
committed
Shared: Add MakeSets module.
1 parent 44f666c commit 486eaad

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* INTERNAL: This module may be replaced without notice.
3+
*
4+
* Provides a module to create first-class representations of sets of values.
5+
*/
6+
7+
/** The input signature for `MakeSets`. */
8+
signature module MkSetsInp {
9+
class Key;
10+
11+
class Value;
12+
13+
Value getAValue(Key k);
14+
15+
int totalorder(Value v);
16+
}
17+
18+
/**
19+
* Given a binary predicate `getAValue`, this module groups the `Value` column
20+
* by `Key` and constructs the corresponding sets of `Value`s as single entities.
21+
*
22+
* The output is a functional predicate, `getValueSet`, such that
23+
* `getValueSet(k).contains(v)` is equivalent to `v = getAValue(k)`, and a
24+
* class, `ValueSet`, that canonically represents a set of `Value`s. In
25+
* particular, if two keys `k1` and `k2` relate to the same set of values, then
26+
* `getValueSet(k1) = getValueSet(k2)`.
27+
*/
28+
module MakeSets<MkSetsInp Inp> {
29+
private import Inp
30+
31+
private predicate rankedValue(Key k, Value v, int r) {
32+
v = rank[r](Value v0 | v0 = getAValue(k) | v0 order by totalorder(v0))
33+
}
34+
35+
private int maxRank(Key k) { result = max(int r | rankedValue(k, _, r)) }
36+
37+
predicate consistency(int r, int bs) { bs = strictcount(Value v | totalorder(v) = r) and bs != 1 }
38+
39+
private newtype TValList =
40+
TValListNil() or
41+
TValListCons(Value head, int r, TValList tail) { hasValListCons(_, head, r, tail) }
42+
43+
private predicate hasValListCons(Key k, Value head, int r, TValList tail) {
44+
rankedValue(k, head, r) and
45+
hasValList(k, r - 1, tail)
46+
}
47+
48+
private predicate hasValList(Key k, int r, TValList l) {
49+
exists(getAValue(k)) and r = 0 and l = TValListNil()
50+
or
51+
exists(Value head, TValList tail |
52+
l = TValListCons(head, r, tail) and
53+
hasValListCons(k, head, r, tail)
54+
)
55+
}
56+
57+
private predicate hasValueSet(Key k, TValListCons vs) { hasValList(k, maxRank(k), vs) }
58+
59+
/** A set of `Value`s. */
60+
class ValueSet extends TValListCons {
61+
ValueSet() { hasValueSet(_, this) }
62+
63+
string toString() { result = "ValueSet" }
64+
65+
private predicate sublist(TValListCons l) {
66+
this = l or
67+
this.sublist(TValListCons(_, _, l))
68+
}
69+
70+
/** Holds if this set contains `v`. */
71+
predicate contains(Value v) { this.sublist(TValListCons(v, _, _)) }
72+
}
73+
74+
/**
75+
* Gets the set of values such that `getValueSet(k).contains(v)` is equivalent
76+
* to `v = getAValue(k)`.
77+
*/
78+
ValueSet getValueSet(Key k) { hasValueSet(k, result) }
79+
}

0 commit comments

Comments
 (0)