@@ -24,21 +24,36 @@ signature module MkSetsInp {
24
24
* class, `ValueSet`, that canonically represents a set of `Value`s. In
25
25
* particular, if two keys `k1` and `k2` relate to the same set of values, then
26
26
* `getValueSet(k1) = getValueSet(k2)`.
27
+ *
28
+ * If the given `totalorder` is not a total order, then the keys for which we
29
+ * cannot order the values cannot be given a canonical representation, and
30
+ * instead the key is simply reused as the set representation. This provides a
31
+ * reasonable fallback where `getValueSet(k).contains(v)` remains equivalent to
32
+ * `v = getAValue(k)`.
27
33
*/
28
34
module MakeSets< MkSetsInp Inp> {
29
35
private import Inp
30
36
37
+ private int totalorderExt ( Value v ) {
38
+ result = 0 and v = getAValue ( _) and not exists ( totalorder ( v ) )
39
+ or
40
+ result = totalorder ( v )
41
+ }
42
+
31
43
private predicate rankedValue ( Key k , Value v , int r ) {
32
- v = rank [ r ] ( Value v0 | v0 = getAValue ( k ) | v0 order by totalorder ( v0 ) )
44
+ v = rank [ r ] ( Value v0 | v0 = getAValue ( k ) | v0 order by totalorderExt ( v0 ) )
33
45
}
34
46
35
- private int maxRank ( Key k ) { result = max ( int r | rankedValue ( k , _, r ) ) }
47
+ private predicate unordered ( Key k ) {
48
+ strictcount ( int r | rankedValue ( k , _, r ) ) != strictcount ( getAValue ( k ) )
49
+ }
36
50
37
- predicate consistency ( int r , int bs ) { bs = strictcount ( Value v | totalorder ( v ) = r ) and bs != 1 }
51
+ private int maxRank ( Key k ) { result = max ( int r | rankedValue ( k , _ , r ) ) and not unordered ( k ) }
38
52
39
53
private newtype TValList =
40
54
TValListNil ( ) or
41
- TValListCons ( Value head , int r , TValList tail ) { hasValListCons ( _, head , r , tail ) }
55
+ TValListCons ( Value head , int r , TValList tail ) { hasValListCons ( _, head , r , tail ) } or
56
+ TValListUnordered ( Key k ) { exists ( getAValue ( k ) ) and unordered ( k ) }
42
57
43
58
private predicate hasValListCons ( Key k , Value head , int r , TValList tail ) {
44
59
rankedValue ( k , head , r ) and
@@ -54,21 +69,31 @@ module MakeSets<MkSetsInp Inp> {
54
69
)
55
70
}
56
71
57
- private predicate hasValueSet ( Key k , TValListCons vs ) { hasValList ( k , maxRank ( k ) , vs ) }
72
+ private predicate hasValueSet ( Key k , TValList vs ) {
73
+ hasValList ( k , maxRank ( k ) , vs ) or vs = TValListUnordered ( k )
74
+ }
58
75
59
76
/** A set of `Value`s. */
60
- class ValueSet extends TValListCons {
77
+ class ValueSet extends TValList {
61
78
ValueSet ( ) { hasValueSet ( _, this ) }
62
79
63
- string toString ( ) { result = "ValueSet" }
80
+ string toString ( ) {
81
+ this instanceof TValListCons and result = "ValueSet"
82
+ or
83
+ this instanceof TValListUnordered and result = "ValueSetUnordered"
84
+ }
64
85
65
86
private predicate sublist ( TValListCons l ) {
66
87
this = l or
67
88
this .sublist ( TValListCons ( _, _, l ) )
68
89
}
69
90
70
91
/** Holds if this set contains `v`. */
71
- predicate contains ( Value v ) { this .sublist ( TValListCons ( v , _, _) ) }
92
+ predicate contains ( Value v ) {
93
+ this .sublist ( TValListCons ( v , _, _) )
94
+ or
95
+ exists ( Key k | this = TValListUnordered ( k ) and v = getAValue ( k ) )
96
+ }
72
97
}
73
98
74
99
/**
0 commit comments