@eagleoutice/flowr 2.6.3 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/README.md +13 -13
  2. package/abstract-interpretation/data-frame/absint-visitor.d.ts +1 -1
  3. package/abstract-interpretation/data-frame/absint-visitor.js +3 -3
  4. package/abstract-interpretation/data-frame/dataframe-domain.d.ts +4 -7
  5. package/abstract-interpretation/data-frame/dataframe-domain.js +5 -11
  6. package/abstract-interpretation/data-frame/mappers/access-mapper.d.ts +3 -1
  7. package/abstract-interpretation/data-frame/mappers/access-mapper.js +3 -2
  8. package/abstract-interpretation/data-frame/mappers/arguments.js +2 -2
  9. package/abstract-interpretation/data-frame/mappers/assignment-mapper.d.ts +3 -1
  10. package/abstract-interpretation/data-frame/mappers/assignment-mapper.js +3 -2
  11. package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +1 -1
  12. package/abstract-interpretation/data-frame/mappers/function-mapper.js +8 -8
  13. package/abstract-interpretation/data-frame/mappers/replacement-mapper.d.ts +3 -1
  14. package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +3 -2
  15. package/abstract-interpretation/data-frame/semantics.js +47 -42
  16. package/abstract-interpretation/data-frame/shape-inference.d.ts +1 -1
  17. package/abstract-interpretation/domains/abstract-domain.d.ts +1 -0
  18. package/abstract-interpretation/domains/abstract-domain.js +3 -2
  19. package/abstract-interpretation/domains/bounded-set-domain.js +1 -1
  20. package/abstract-interpretation/domains/interval-domain.d.ts +2 -2
  21. package/abstract-interpretation/domains/interval-domain.js +3 -6
  22. package/abstract-interpretation/domains/lattice.d.ts +2 -0
  23. package/abstract-interpretation/domains/lattice.js +3 -1
  24. package/abstract-interpretation/domains/positive-interval-domain.d.ts +1 -1
  25. package/abstract-interpretation/domains/positive-interval-domain.js +1 -1
  26. package/abstract-interpretation/domains/satisfiable-domain.d.ts +2 -2
  27. package/abstract-interpretation/domains/satisfiable-domain.js +2 -2
  28. package/abstract-interpretation/domains/set-range-domain.d.ts +98 -0
  29. package/abstract-interpretation/domains/set-range-domain.js +400 -0
  30. package/abstract-interpretation/domains/set-upper-bound-domain.js +2 -2
  31. package/abstract-interpretation/domains/singleton-domain.js +2 -2
  32. package/benchmark/slicer.d.ts +2 -1
  33. package/benchmark/slicer.js +37 -15
  34. package/benchmark/stats/print.js +8 -5
  35. package/benchmark/stats/stats.d.ts +3 -2
  36. package/benchmark/summarizer/data.d.ts +11 -8
  37. package/benchmark/summarizer/first-phase/process.js +11 -8
  38. package/benchmark/summarizer/second-phase/process.js +24 -18
  39. package/control-flow/cfg-dead-code.js +3 -2
  40. package/control-flow/useless-loop.js +4 -2
  41. package/core/steps/all/static-slicing/00-slice.d.ts +3 -0
  42. package/core/steps/all/static-slicing/00-slice.js +2 -1
  43. package/core/steps/pipeline/default-pipelines.d.ts +42 -42
  44. package/dataflow/cluster.js +2 -2
  45. package/dataflow/environments/append.d.ts +5 -0
  46. package/dataflow/environments/append.js +6 -20
  47. package/dataflow/environments/built-in.d.ts +2 -1
  48. package/dataflow/environments/clone.d.ts +1 -1
  49. package/dataflow/environments/clone.js +3 -27
  50. package/dataflow/environments/define.d.ts +7 -3
  51. package/dataflow/environments/define.js +9 -56
  52. package/dataflow/environments/diff.js +1 -1
  53. package/dataflow/environments/environment.d.ts +48 -28
  54. package/dataflow/environments/environment.js +187 -62
  55. package/dataflow/environments/overwrite.js +2 -45
  56. package/dataflow/environments/reference-to-maybe.d.ts +13 -0
  57. package/dataflow/environments/reference-to-maybe.js +54 -0
  58. package/dataflow/environments/resolve-by-name.d.ts +6 -1
  59. package/dataflow/environments/resolve-by-name.js +56 -4
  60. package/dataflow/environments/scoping.d.ts +2 -2
  61. package/dataflow/environments/scoping.js +7 -7
  62. package/dataflow/eval/resolve/alias-tracking.d.ts +10 -4
  63. package/dataflow/eval/resolve/alias-tracking.js +15 -13
  64. package/dataflow/eval/resolve/resolve-argument.d.ts +2 -1
  65. package/dataflow/eval/resolve/resolve-argument.js +8 -8
  66. package/dataflow/eval/resolve/resolve.d.ts +13 -11
  67. package/dataflow/eval/resolve/resolve.js +16 -15
  68. package/dataflow/extractor.js +1 -7
  69. package/dataflow/fn/higher-order-function.d.ts +2 -1
  70. package/dataflow/fn/higher-order-function.js +4 -4
  71. package/dataflow/graph/dataflowgraph-builder.d.ts +9 -5
  72. package/dataflow/graph/dataflowgraph-builder.js +21 -11
  73. package/dataflow/graph/diff-dataflow-graph.js +2 -2
  74. package/dataflow/graph/graph.d.ts +10 -2
  75. package/dataflow/graph/graph.js +41 -12
  76. package/dataflow/graph/invert-dfg.d.ts +3 -2
  77. package/dataflow/graph/invert-dfg.js +3 -3
  78. package/dataflow/graph/resolve-graph.d.ts +2 -1
  79. package/dataflow/graph/resolve-graph.js +2 -2
  80. package/dataflow/graph/vertex.d.ts +3 -3
  81. package/dataflow/graph/vertex.js +3 -3
  82. package/dataflow/info.d.ts +1 -1
  83. package/dataflow/internal/linker.js +3 -7
  84. package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +7 -1
  85. package/dataflow/internal/process/functions/call/argument/unpack-argument.js +12 -3
  86. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +3 -3
  87. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +2 -2
  88. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +3 -1
  89. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +3 -3
  90. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +9 -9
  91. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +9 -7
  92. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +3 -3
  93. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +2 -1
  94. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +9 -13
  95. package/dataflow/internal/process/functions/call/built-in/built-in-get.js +1 -1
  96. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.d.ts +3 -1
  97. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +8 -6
  98. package/dataflow/internal/process/functions/call/built-in/built-in-library.js +1 -1
  99. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +1 -1
  100. package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +1 -1
  101. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +3 -3
  102. package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +6 -4
  103. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +1 -1
  104. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +5 -5
  105. package/dataflow/internal/process/functions/call/common.js +2 -3
  106. package/dataflow/internal/process/functions/call/known-call-handling.js +1 -1
  107. package/dataflow/internal/process/functions/call/unnamed-call-handling.js +1 -1
  108. package/dataflow/internal/process/functions/process-argument.js +1 -1
  109. package/dataflow/internal/process/process-symbol.js +1 -1
  110. package/dataflow/internal/process/process-value.d.ts +1 -1
  111. package/dataflow/internal/process/process-value.js +7 -7
  112. package/dataflow/processor.d.ts +1 -5
  113. package/documentation/doc-util/doc-dfg.js +3 -2
  114. package/documentation/doc-util/doc-normalized-ast.js +3 -2
  115. package/documentation/doc-util/doc-types.d.ts +1 -1
  116. package/documentation/doc-util/doc-types.js +2 -2
  117. package/documentation/wiki-analyzer.js +14 -1
  118. package/documentation/wiki-dataflow-graph.js +4 -5
  119. package/documentation/wiki-faq.js +0 -1
  120. package/documentation/wiki-linter.js +1 -1
  121. package/documentation/wiki-mk/doc-maker.js +2 -1
  122. package/linter/linter-rules.d.ts +2 -2
  123. package/linter/rules/absolute-path.js +4 -4
  124. package/linter/rules/dataframe-access-validation.d.ts +1 -1
  125. package/linter/rules/dataframe-access-validation.js +1 -1
  126. package/linter/rules/function-finder-util.d.ts +2 -2
  127. package/linter/rules/function-finder-util.js +1 -1
  128. package/linter/rules/network-functions.js +1 -1
  129. package/linter/rules/seeded-randomness.d.ts +1 -1
  130. package/linter/rules/seeded-randomness.js +5 -5
  131. package/package.json +1 -2
  132. package/project/context/flowr-analyzer-context.d.ts +7 -0
  133. package/project/context/flowr-analyzer-context.js +3 -0
  134. package/project/context/flowr-analyzer-environment-context.d.ts +47 -0
  135. package/project/context/flowr-analyzer-environment-context.js +50 -0
  136. package/queries/catalog/call-context-query/call-context-query-executor.js +1 -4
  137. package/queries/catalog/control-flow-query/control-flow-query-format.js +3 -2
  138. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-executor.js +1 -1
  139. package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -4
  140. package/queries/catalog/df-shape-query/df-shape-query-executor.d.ts +1 -1
  141. package/queries/catalog/df-shape-query/df-shape-query-executor.js +1 -1
  142. package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +4 -4
  143. package/queries/catalog/df-shape-query/df-shape-query-format.js +2 -2
  144. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +3 -3
  145. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +1 -1
  146. package/queries/catalog/static-slice-query/static-slice-query-executor.js +1 -1
  147. package/slicing/static/slice-call.d.ts +3 -2
  148. package/slicing/static/slice-call.js +4 -4
  149. package/slicing/static/static-slicer.d.ts +3 -1
  150. package/slicing/static/static-slicer.js +6 -7
  151. package/statistics/features/supported/control-flow/control-flow.js +1 -1
  152. package/statistics/features/supported/used-functions/used-functions.js +1 -1
  153. package/statistics/features/supported/variables/variables.js +2 -1
  154. package/util/containers.js +1 -1
  155. package/util/mermaid/dfg.d.ts +1 -0
  156. package/util/mermaid/dfg.js +3 -3
  157. package/util/simple-df/dfg-view.d.ts +2 -1
  158. package/util/simple-df/dfg-view.js +2 -2
  159. package/util/version.js +1 -1
  160. package/dataflow/environments/remove.d.ts +0 -12
  161. package/dataflow/environments/remove.js +0 -52
@@ -0,0 +1,400 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SetRangeDomain = exports.SetRangeTop = void 0;
4
+ const assert_1 = require("../../util/assert");
5
+ const set_1 = require("../../util/collections/set");
6
+ const logic_1 = require("../../util/logic");
7
+ const abstract_domain_1 = require("./abstract-domain");
8
+ const lattice_1 = require("./lattice");
9
+ const satisfiable_domain_1 = require("./satisfiable-domain");
10
+ /* eslint-disable @typescript-eslint/unified-signatures */
11
+ /** The Top element of the set range domain with an empty set as minimum set and {@link Top} as range set */
12
+ exports.SetRangeTop = { min: new Set(), range: lattice_1.Top };
13
+ const DefaultLimit = { min: abstract_domain_1.DEFAULT_INFERENCE_LIMIT, range: abstract_domain_1.DEFAULT_INFERENCE_LIMIT };
14
+ /**
15
+ * The set range abstract domain as range of possible value sets with a minimum set of values and a range of possible additional values
16
+ * (similar to an interval like structure with a lower bound and a difference to the upper bound).
17
+ * The Bottom element is defined as {@link Bottom} symbol and the Top element is defined as the range `[∅, Top]` where the minimum set is the empty set and the range is {@link Top}.
18
+ * @template T - Type of the values in the sets in the abstract domain
19
+ * @template Value - Type of the constraint in the abstract domain (Top, Bottom, or an actual value)
20
+ */
21
+ class SetRangeDomain extends abstract_domain_1.AbstractDomain {
22
+ limit;
23
+ setType;
24
+ /**
25
+ * @param limit - A limit for the maximum number of elements to store in the minimum set and maximum set before over-approximation
26
+ * @param newSet - An optional set constructor for the domain elements if the type `T` is not storable in a HashSet
27
+ */
28
+ constructor(value, limit = DefaultLimit, setType = Set) {
29
+ limit = typeof limit === 'number' ? { min: limit, range: limit } : limit;
30
+ if (value !== lattice_1.Bottom) {
31
+ const minSet = new setType(value.min);
32
+ const rangeSet = value.range === lattice_1.Top ? lattice_1.Top : new setType(value.range);
33
+ const minExceeds = minSet.size > limit.min;
34
+ const rangeExceeds = rangeSet === lattice_1.Top || rangeSet.size > limit.range || minSet.size + rangeSet.size > limit.min + limit.range;
35
+ const min = minExceeds ? new setType(minSet.values().take(limit.min)) : minSet;
36
+ const range = rangeExceeds ? lattice_1.Top : minSet.union(rangeSet).difference(min);
37
+ super({ min, range });
38
+ }
39
+ else {
40
+ super(value);
41
+ }
42
+ this.limit = limit;
43
+ this.setType = setType;
44
+ }
45
+ create(value) {
46
+ return new SetRangeDomain(value, this.limit, this.setType);
47
+ }
48
+ /**
49
+ * The minimum set (lower bound) of the set range representing all values that must exist (subset of {@link upper}).
50
+ */
51
+ lower() {
52
+ if (this.value === lattice_1.Bottom) {
53
+ return lattice_1.Bottom;
54
+ }
55
+ return this.value.min;
56
+ }
57
+ /**
58
+ * The maximum set (upper bound) of the set range representing all values that can possibly exist (union of {@link lower} and range).
59
+ */
60
+ upper() {
61
+ if (this.value === lattice_1.Bottom) {
62
+ return lattice_1.Bottom;
63
+ }
64
+ return this.value.range === lattice_1.Top ? lattice_1.Top : this.value.min.union(this.value.range);
65
+ }
66
+ static top(limit, setType) {
67
+ return new SetRangeDomain(exports.SetRangeTop, limit, setType);
68
+ }
69
+ static bottom(limit, setType) {
70
+ return new SetRangeDomain(lattice_1.Bottom, limit, setType);
71
+ }
72
+ static abstract(concrete, limit, setType) {
73
+ if (concrete === lattice_1.Top) {
74
+ return SetRangeDomain.top(limit, setType);
75
+ }
76
+ else if (concrete.size === 0) {
77
+ return SetRangeDomain.bottom(limit, setType);
78
+ }
79
+ const lower = concrete.values().reduce((result, set) => result.intersection(set));
80
+ const upper = concrete.values().reduce((result, set) => result.union(set));
81
+ return new SetRangeDomain({ min: lower, range: upper.difference(lower) }, limit, setType);
82
+ }
83
+ top() {
84
+ return SetRangeDomain.top(this.limit, this.setType);
85
+ }
86
+ bottom() {
87
+ return SetRangeDomain.bottom(this.limit, this.setType);
88
+ }
89
+ equals(other) {
90
+ if (this.value === other.value) {
91
+ return true;
92
+ }
93
+ else if (this.value === lattice_1.Bottom || other.value === lattice_1.Bottom || !(0, set_1.setEquals)(this.value.min, other.value.min)) {
94
+ return false;
95
+ }
96
+ else if (this.value.range === other.value.range) {
97
+ return true;
98
+ }
99
+ return this.value.range !== lattice_1.Top && other.value.range !== lattice_1.Top && (0, set_1.setEquals)(this.value.range, other.value.range);
100
+ }
101
+ leq(other) {
102
+ const thisLower = this.lower(), thisUpper = this.upper();
103
+ const otherLower = other.lower(), otherUpper = other.upper();
104
+ if (thisLower === lattice_1.Bottom || thisUpper === lattice_1.Bottom) {
105
+ return true;
106
+ }
107
+ else if (otherLower === lattice_1.Bottom || otherUpper === lattice_1.Bottom || !otherLower.isSubsetOf(thisLower)) {
108
+ return false;
109
+ }
110
+ else if (otherUpper === lattice_1.Top) {
111
+ return true;
112
+ }
113
+ return thisUpper !== lattice_1.Top && thisUpper.isSubsetOf(otherUpper);
114
+ }
115
+ join(other) {
116
+ other = other instanceof SetRangeDomain ? other : this.create(other);
117
+ const thisLower = this.lower(), thisUpper = this.upper();
118
+ const otherLower = other.lower(), otherUpper = other.upper();
119
+ if (thisLower === lattice_1.Bottom || thisUpper === lattice_1.Bottom) {
120
+ return this.create(other.value);
121
+ }
122
+ else if (otherLower === lattice_1.Bottom || otherUpper === lattice_1.Bottom) {
123
+ return this.create(this.value);
124
+ }
125
+ const joinLower = thisLower.intersection(otherLower);
126
+ let joinUpper;
127
+ if (thisUpper === lattice_1.Top || otherUpper === lattice_1.Top) {
128
+ joinUpper = lattice_1.Top;
129
+ }
130
+ else {
131
+ joinUpper = thisUpper.union(otherUpper);
132
+ }
133
+ return this.create({ min: joinLower, range: joinUpper === lattice_1.Top ? lattice_1.Top : joinUpper.difference(joinLower) });
134
+ }
135
+ meet(other) {
136
+ other = other instanceof SetRangeDomain ? other : this.create(other);
137
+ const thisLower = this.lower(), thisUpper = this.upper();
138
+ const otherLower = other.lower(), otherUpper = other.upper();
139
+ if (thisLower === lattice_1.Bottom || thisUpper === lattice_1.Bottom || otherLower === lattice_1.Bottom || otherUpper === lattice_1.Bottom) {
140
+ return this.bottom();
141
+ }
142
+ const meetLower = thisLower.union(otherLower);
143
+ let meetUpper;
144
+ if (thisUpper === lattice_1.Top) {
145
+ meetUpper = otherUpper;
146
+ }
147
+ else if (otherUpper === lattice_1.Top) {
148
+ meetUpper = thisUpper;
149
+ }
150
+ else {
151
+ meetUpper = thisUpper.intersection(otherUpper);
152
+ }
153
+ if (meetUpper !== lattice_1.Top && !meetLower.isSubsetOf(meetUpper)) {
154
+ return this.bottom();
155
+ }
156
+ return this.create({ min: meetLower, range: meetUpper === lattice_1.Top ? lattice_1.Top : meetUpper.difference(meetLower) });
157
+ }
158
+ /**
159
+ * Creates the union of this abstract value and another abstract value by creating the union of the minimum and maximum set, respectively.
160
+ */
161
+ union(other) {
162
+ other = other instanceof SetRangeDomain ? other : this.create(other);
163
+ const thisLower = this.lower(), thisUpper = this.upper();
164
+ const otherLower = other.lower(), otherUpper = other.upper();
165
+ if (thisLower === lattice_1.Bottom || thisUpper === lattice_1.Bottom) {
166
+ return this.create(other.value);
167
+ }
168
+ else if (otherLower === lattice_1.Bottom || otherUpper === lattice_1.Bottom) {
169
+ return this.create(this.value);
170
+ }
171
+ const unionLower = thisLower.union(otherLower);
172
+ let unionUpper;
173
+ if (thisUpper === lattice_1.Top || otherUpper === lattice_1.Top) {
174
+ unionUpper = lattice_1.Top;
175
+ }
176
+ else {
177
+ unionUpper = thisUpper.union(otherUpper);
178
+ }
179
+ return this.create({ min: unionLower, range: unionUpper === lattice_1.Top ? lattice_1.Top : unionUpper.difference(unionLower) });
180
+ }
181
+ /**
182
+ * Creates the intersection of this abstract value and another abstract value by creating the intersection of the minimum and maximum set, respectively.
183
+ */
184
+ intersect(other) {
185
+ other = other instanceof SetRangeDomain ? other : this.create(other);
186
+ const thisLower = this.lower(), thisUpper = this.upper();
187
+ const otherLower = other.lower(), otherUpper = other.upper();
188
+ if (thisLower === lattice_1.Bottom || thisUpper === lattice_1.Bottom || otherLower === lattice_1.Bottom || otherUpper === lattice_1.Bottom) {
189
+ return this.bottom();
190
+ }
191
+ const intersectLower = thisLower.intersection(otherLower);
192
+ let intersectUpper;
193
+ if (thisUpper === lattice_1.Top) {
194
+ intersectUpper = otherUpper;
195
+ }
196
+ else if (otherUpper === lattice_1.Top) {
197
+ intersectUpper = thisUpper;
198
+ }
199
+ else {
200
+ intersectUpper = thisUpper.intersection(otherUpper);
201
+ }
202
+ return this.create({ min: intersectLower, range: intersectUpper === lattice_1.Top ? lattice_1.Top : intersectUpper.difference(intersectLower) });
203
+ }
204
+ /**
205
+ * Subtracts another abstract value from the current abstract value by removing all elements of the other abstract value from the current abstract value.
206
+ */
207
+ subtract(other) {
208
+ other = other instanceof SetRangeDomain ? other : this.create(other);
209
+ const thisLower = this.lower(), thisUpper = this.upper();
210
+ const otherLower = other.lower(), otherUpper = other.upper();
211
+ if (thisLower === lattice_1.Bottom || thisUpper === lattice_1.Bottom) {
212
+ return this.bottom();
213
+ }
214
+ else if (otherLower === lattice_1.Bottom || otherUpper === lattice_1.Bottom) {
215
+ return this.create(this.value);
216
+ }
217
+ let subLower;
218
+ if (otherUpper === lattice_1.Top) {
219
+ subLower = new Set();
220
+ }
221
+ else {
222
+ subLower = thisLower.difference(otherUpper);
223
+ }
224
+ let subUpper;
225
+ if (thisUpper === lattice_1.Top) {
226
+ subUpper = lattice_1.Top;
227
+ }
228
+ else if (otherUpper === lattice_1.Top) {
229
+ subUpper = thisUpper.difference(otherLower);
230
+ }
231
+ else {
232
+ subUpper = thisUpper.difference(otherUpper);
233
+ }
234
+ return this.create({ min: subLower, range: subUpper === lattice_1.Top ? lattice_1.Top : subUpper.difference(subLower) });
235
+ }
236
+ widen(other) {
237
+ const thisLower = this.lower(), thisUpper = this.upper();
238
+ const otherLower = other.lower(), otherUpper = other.upper();
239
+ if (thisLower === lattice_1.Bottom || thisUpper === lattice_1.Bottom) {
240
+ return this.create(other.value);
241
+ }
242
+ else if (otherLower === lattice_1.Bottom || otherUpper === lattice_1.Bottom) {
243
+ return this.create(this.value);
244
+ }
245
+ let widenLower;
246
+ if (!thisLower.isSubsetOf(otherLower)) {
247
+ widenLower = new Set();
248
+ }
249
+ else {
250
+ widenLower = thisLower;
251
+ }
252
+ let widenUpper;
253
+ if (thisUpper === lattice_1.Top || otherUpper === lattice_1.Top || !otherUpper.isSubsetOf(thisUpper)) {
254
+ widenUpper = lattice_1.Top;
255
+ }
256
+ else {
257
+ widenUpper = thisUpper;
258
+ }
259
+ return this.create({ min: widenLower, range: widenUpper === lattice_1.Top ? lattice_1.Top : widenUpper.difference(widenLower) });
260
+ }
261
+ narrow(other) {
262
+ const thisLower = this.lower(), thisUpper = this.upper();
263
+ const otherLower = other.lower(), otherUpper = other.upper();
264
+ if (thisLower === lattice_1.Bottom || thisUpper === lattice_1.Bottom || otherLower === lattice_1.Bottom || otherUpper === lattice_1.Bottom) {
265
+ return this.bottom();
266
+ }
267
+ let meetUpper;
268
+ if (thisUpper === lattice_1.Top) {
269
+ meetUpper = otherUpper;
270
+ }
271
+ else if (otherUpper === lattice_1.Top) {
272
+ meetUpper = thisUpper;
273
+ }
274
+ else {
275
+ meetUpper = thisUpper.intersection(otherUpper);
276
+ }
277
+ if (meetUpper !== lattice_1.Top && !thisLower.union(otherLower).isSubsetOf(meetUpper)) {
278
+ return this.bottom();
279
+ }
280
+ let narrowLower;
281
+ if (thisLower.size === 0) {
282
+ narrowLower = otherLower;
283
+ }
284
+ else {
285
+ narrowLower = thisLower;
286
+ }
287
+ let narrowUpper;
288
+ if (thisUpper === lattice_1.Top) {
289
+ narrowUpper = otherUpper;
290
+ }
291
+ else {
292
+ narrowUpper = thisUpper;
293
+ }
294
+ return this.create({ min: narrowLower, range: narrowUpper === lattice_1.Top ? lattice_1.Top : narrowUpper.difference(narrowLower) });
295
+ }
296
+ concretize(limit) {
297
+ if (this.value === lattice_1.Bottom) {
298
+ return new Set();
299
+ }
300
+ else if (this.value.range === lattice_1.Top || 2 ** (this.value.range.size) > limit) {
301
+ return lattice_1.Top;
302
+ }
303
+ const subsets = [new this.setType()];
304
+ for (const element of this.value.range) {
305
+ const newSubsets = subsets.map(subset => new this.setType([...subset, element]));
306
+ for (const subset of newSubsets) {
307
+ subsets.push(subset);
308
+ }
309
+ }
310
+ return new Set(subsets.map(subset => this.value === lattice_1.Bottom ? subset : this.value.min.union(subset)));
311
+ }
312
+ abstract(concrete) {
313
+ return SetRangeDomain.abstract(concrete, this.limit);
314
+ }
315
+ satisfies(set, comparator = satisfiable_domain_1.SetComparator.Equal) {
316
+ const value = new this.setType(set);
317
+ const lower = this.lower(), upper = this.upper();
318
+ if (lower === lattice_1.Bottom || upper === lattice_1.Bottom) {
319
+ return logic_1.Ternary.Never;
320
+ }
321
+ switch (comparator) {
322
+ case satisfiable_domain_1.SetComparator.Equal: {
323
+ if (lower.isSubsetOf(value) && (upper === lattice_1.Top || value.isSubsetOf(upper))) {
324
+ return upper !== lattice_1.Top && lower.size === upper.size ? logic_1.Ternary.Always : logic_1.Ternary.Maybe;
325
+ }
326
+ return logic_1.Ternary.Never;
327
+ }
328
+ case satisfiable_domain_1.SetComparator.SubsetOrEqual: {
329
+ if (upper === lattice_1.Top || value.isSubsetOf(upper)) {
330
+ return value.isSubsetOf(lower) ? logic_1.Ternary.Always : logic_1.Ternary.Maybe;
331
+ }
332
+ return logic_1.Ternary.Never;
333
+ }
334
+ case satisfiable_domain_1.SetComparator.Subset: {
335
+ if (upper === lattice_1.Top || (value.isSubsetOf(upper) && !(0, set_1.setEquals)(value, upper))) {
336
+ return value.isSubsetOf(lower) && !(0, set_1.setEquals)(value, lower) ? logic_1.Ternary.Always : logic_1.Ternary.Maybe;
337
+ }
338
+ return logic_1.Ternary.Never;
339
+ }
340
+ default: {
341
+ (0, assert_1.assertUnreachable)(comparator);
342
+ }
343
+ }
344
+ }
345
+ /**
346
+ * Extends the minimum set of the current abstract value down to the empty set.
347
+ */
348
+ widenDown() {
349
+ const upper = this.upper();
350
+ if (upper === lattice_1.Bottom) {
351
+ return this.bottom();
352
+ }
353
+ else {
354
+ return this.create({ min: new this.setType(), range: upper });
355
+ }
356
+ }
357
+ /**
358
+ * Extends the maximum set of the current abstract value up to {@link Top}.
359
+ */
360
+ widenUp() {
361
+ const lower = this.lower();
362
+ if (lower === lattice_1.Bottom) {
363
+ return this.bottom();
364
+ }
365
+ else {
366
+ return this.create({ min: lower, range: lattice_1.Top });
367
+ }
368
+ }
369
+ toJson() {
370
+ if (this.value === lattice_1.Bottom) {
371
+ return this.value.description;
372
+ }
373
+ const min = this.value.min.values().toArray();
374
+ const range = this.value.range === lattice_1.Top ? this.value.range.description : this.value.range.values().toArray();
375
+ return { min, range };
376
+ }
377
+ toString() {
378
+ if (this.value === lattice_1.Bottom) {
379
+ return lattice_1.BottomSymbol;
380
+ }
381
+ else if (this.value.range === lattice_1.Top) {
382
+ const minString = this.value.min.values().map(abstract_domain_1.domainElementToString).toArray().join(', ');
383
+ return `[{${minString}}, ${lattice_1.TopSymbol}]`;
384
+ }
385
+ const minString = this.value.min.values().map(abstract_domain_1.domainElementToString).toArray().join(', ');
386
+ const rangeString = this.value.range.values().map(abstract_domain_1.domainElementToString).toArray().join(', ');
387
+ return `[{${minString}}, {${rangeString}}]`;
388
+ }
389
+ isTop() {
390
+ return this.value !== lattice_1.Bottom && this.value.min.size === 0 && this.value.range === lattice_1.Top;
391
+ }
392
+ isBottom() {
393
+ return this.value === lattice_1.Bottom;
394
+ }
395
+ isValue() {
396
+ return this.value !== lattice_1.Bottom;
397
+ }
398
+ }
399
+ exports.SetRangeDomain = SetRangeDomain;
400
+ //# sourceMappingURL=set-range-domain.js.map
@@ -175,10 +175,10 @@ class SetUpperBoundDomain extends abstract_domain_1.AbstractDomain {
175
175
  }
176
176
  toString() {
177
177
  if (this.value === lattice_1.Top) {
178
- return '⊤';
178
+ return lattice_1.TopSymbol;
179
179
  }
180
180
  else if (this.value === lattice_1.Bottom) {
181
- return '⊥';
181
+ return lattice_1.BottomSymbol;
182
182
  }
183
183
  const string = this.value.values().map(abstract_domain_1.domainElementToString).toArray().join(', ');
184
184
  return `{${string}}`;
@@ -109,10 +109,10 @@ class SingletonDomain extends abstract_domain_1.AbstractDomain {
109
109
  }
110
110
  toString() {
111
111
  if (this.value === lattice_1.Top) {
112
- return '⊤';
112
+ return lattice_1.TopSymbol;
113
113
  }
114
114
  else if (this.value === lattice_1.Bottom) {
115
- return '⊥';
115
+ return lattice_1.BottomSymbol;
116
116
  }
117
117
  return (0, abstract_domain_1.domainElementToString)(this.value);
118
118
  }
@@ -106,7 +106,8 @@ export declare class BenchmarkSlicer {
106
106
  * @returns The statistics of the data frame shape inference
107
107
  */
108
108
  inferDataFrameShapes(): SlicerStatsDfShape;
109
- private getInferredSize;
109
+ private getInferredRange;
110
+ private getInferredNumber;
110
111
  /** Bridging the gap between the new internal and the old names for the benchmarking */
111
112
  private measureCommonStep;
112
113
  private measureSimpleStep;
@@ -28,6 +28,8 @@ const config_1 = require("../config");
28
28
  const extract_cfg_1 = require("../control-flow/extract-cfg");
29
29
  const absint_info_1 = require("../abstract-interpretation/data-frame/absint-info");
30
30
  const shape_inference_1 = require("../abstract-interpretation/data-frame/shape-inference");
31
+ const lattice_1 = require("../abstract-interpretation/domains/lattice");
32
+ const set_range_domain_1 = require("../abstract-interpretation/domains/set-range-domain");
31
33
  const fs_1 = __importDefault(require("fs"));
32
34
  const flowr_analyzer_context_1 = require("../project/context/flowr-analyzer-context");
33
35
  /**
@@ -117,10 +119,10 @@ class BenchmarkSlicer {
117
119
  for (const [n, info] of vertices) {
118
120
  const outgoingEdges = this.dataflow.graph.outgoingEdges(n);
119
121
  numberOfEdges += outgoingEdges?.size ?? 0;
120
- if (info.tag === 'function-call') {
122
+ if (info.tag === vertex_1.VertexType.FunctionCall) {
121
123
  numberOfCalls++;
122
124
  }
123
- else if (info.tag === 'function-definition') {
125
+ else if (info.tag === vertex_1.VertexType.FunctionDefinition) {
124
126
  numberOfDefinitions++;
125
127
  }
126
128
  }
@@ -163,7 +165,7 @@ class BenchmarkSlicer {
163
165
  numberOfNormalizedTokensNoComments: nodesNoComments
164
166
  },
165
167
  dataflow: {
166
- numberOfNodes: [...this.dataflow.graph.vertices(true)].length,
168
+ numberOfNodes: this.dataflow.graph.vertices(true).toArray().length,
167
169
  numberOfEdges: numberOfEdges,
168
170
  numberOfCalls: numberOfCalls,
169
171
  numberOfFunctionDefinitions: numberOfDefinitions,
@@ -257,7 +259,7 @@ class BenchmarkSlicer {
257
259
  }).join('')}`);
258
260
  }
259
261
  // if it is not in the dataflow graph it was kept to be safe and should not count to the included nodes
260
- stats.numberOfDataflowNodesSliced = [...slicedOutput.result].filter(id => results.dataflow.graph.hasVertex(id, false)).length;
262
+ stats.numberOfDataflowNodesSliced = Array.from(slicedOutput.result).filter(id => results.dataflow.graph.hasVertex(id, false)).length;
261
263
  stats.timesHitThreshold = slicedOutput.timesHitThreshold;
262
264
  stats.measurements = measurements.get();
263
265
  return {
@@ -298,8 +300,8 @@ class BenchmarkSlicer {
298
300
  numberOfNonDataFrameFiles: 0,
299
301
  numberOfResultConstraints: 0,
300
302
  numberOfResultingValues: 0,
301
- numberOfResultingTop: 0,
302
303
  numberOfResultingBottom: 0,
304
+ numberOfResultingTop: 0,
303
305
  numberOfEmptyNodes: 0,
304
306
  numberOfOperationNodes: 0,
305
307
  numberOfValueNodes: 0,
@@ -338,11 +340,12 @@ class BenchmarkSlicer {
338
340
  nodeStats.mappedOperations = expression.operations.map(op => op.operation);
339
341
  stats.numberOfOperationNodes++;
340
342
  if (value !== undefined) {
341
- nodeStats.inferredColNames = value.colnames.isValue() ? value.colnames.value.size : value.colnames.isTop() ? 'top' : 'bottom';
342
- nodeStats.inferredColCount = this.getInferredSize(value.cols);
343
- nodeStats.inferredRowCount = this.getInferredSize(value.rows);
344
- nodeStats.approxRangeColCount = value.cols.isValue() ? value.cols.value[1] - value.cols.value[0] : 0;
345
- nodeStats.approxRangeRowCount = value.rows.isValue() ? value.rows.value[1] - value.rows.value[0] : 0;
343
+ nodeStats.inferredColNames = this.getInferredNumber(value.colnames);
344
+ nodeStats.inferredColCount = this.getInferredNumber(value.cols);
345
+ nodeStats.inferredRowCount = this.getInferredNumber(value.rows);
346
+ nodeStats.approxRangeColNames = this.getInferredRange(value.colnames);
347
+ nodeStats.approxRangeColCount = this.getInferredRange(value.cols);
348
+ nodeStats.approxRangeRowCount = this.getInferredRange(value.rows);
346
349
  }
347
350
  }
348
351
  if (value !== undefined) {
@@ -359,15 +362,34 @@ class BenchmarkSlicer {
359
362
  this.stats.dataFrameShape = stats;
360
363
  return stats;
361
364
  }
362
- getInferredSize(value) {
365
+ getInferredRange(value) {
366
+ if (value.isValue()) {
367
+ if (value instanceof set_range_domain_1.SetRangeDomain) {
368
+ return value.value.range === lattice_1.Top ? Infinity : value.value.range.size;
369
+ }
370
+ else {
371
+ return value.value[1] - value.value[0];
372
+ }
373
+ }
374
+ return 0;
375
+ }
376
+ getInferredNumber(value) {
363
377
  if (value.isTop()) {
364
378
  return 'top';
365
379
  }
366
- else if (value.isValue() && !isFinite(value.value[1])) {
367
- return 'infinite';
368
- }
369
380
  else if (value.isValue()) {
370
- return Math.floor((value.value[0] + value.value[1]) / 2);
381
+ if (value instanceof set_range_domain_1.SetRangeDomain) {
382
+ if (value.value.range === lattice_1.Top) {
383
+ return 'infinite';
384
+ }
385
+ return Math.floor(value.value.min.size + (value.value.range.size / 2));
386
+ }
387
+ else {
388
+ if (!isFinite(value.value[1])) {
389
+ return 'infinite';
390
+ }
391
+ return Math.floor((value.value[0] + value.value[1]) / 2);
392
+ }
371
393
  }
372
394
  return 'bottom';
373
395
  }
@@ -176,15 +176,16 @@ Dataframe shape inference:
176
176
  Number of total top: ${pad(stats.dataFrameShape.numberOfTotalTop)}
177
177
  Inferred column names per node: ${pad(stats.dataFrameShape.inferredColNames.mean)}
178
178
  Number of column names values: ${pad(stats.dataFrameShape.numberOfColNamesValues)}
179
- Number of column names Top: ${pad(stats.dataFrameShape.numberOfColNamesTop)}
179
+ Number of column names infinite:${pad(stats.dataFrameShape.numberOfColNamesInfinite)}
180
+ Number of column names top: ${pad(stats.dataFrameShape.numberOfColNamesTop)}
180
181
  Inferred column count per node: ${pad(stats.dataFrameShape.inferredColCount.mean)}
181
182
  Number of column count values: ${pad(stats.dataFrameShape.numberOfColCountValues)}
182
- Number of column count Top: ${pad(stats.dataFrameShape.numberOfColCountTop)}
183
183
  Number of column count infinite:${pad(stats.dataFrameShape.numberOfColCountInfinite)}
184
+ Number of column count top: ${pad(stats.dataFrameShape.numberOfColCountTop)}
184
185
  Inferred row count per node: ${pad(stats.dataFrameShape.inferredRowCount.mean)}
185
186
  Number of row count values: ${pad(stats.dataFrameShape.numberOfRowCountValues)}
186
- Number of row count Top: ${pad(stats.dataFrameShape.numberOfRowCountTop)}
187
187
  Number of row count infinite: ${pad(stats.dataFrameShape.numberOfRowCountInfinite)}
188
+ Number of row count top: ${pad(stats.dataFrameShape.numberOfRowCountTop)}
188
189
  Size of data frame shape info: ${convertNumberToNiceBytes(stats.dataFrameShape.sizeOfInfo)}`;
189
190
  }
190
191
  return result;
@@ -276,18 +277,20 @@ Dataframe shape inference:
276
277
  Number of total values: ${formatSummarizedMeasure(stats.dataFrameShape.numberOfTotalValues)}
277
278
  Number of total top: ${formatSummarizedMeasure(stats.dataFrameShape.numberOfTotalTop)}
278
279
  Inferred column names per node: ${formatSummarizedMeasure(stats.dataFrameShape.inferredColNames)}
280
+ Number of column names exact: ${formatSummarizedMeasure(stats.dataFrameShape.numberOfColNamesExact)}
279
281
  Number of column names values: ${formatSummarizedMeasure(stats.dataFrameShape.numberOfColNamesValues)}
282
+ Number of column names infinite:${formatSummarizedMeasure(stats.dataFrameShape.numberOfColNamesInfinite)}
280
283
  Number of column names top: ${formatSummarizedMeasure(stats.dataFrameShape.numberOfColNamesTop)}
281
284
  Inferred column count per node: ${formatSummarizedMeasure(stats.dataFrameShape.inferredColCount)}
282
285
  Number of column count exact: ${formatSummarizedMeasure(stats.dataFrameShape.numberOfColCountExact)}
283
286
  Number of column count values: ${formatSummarizedMeasure(stats.dataFrameShape.numberOfColCountValues)}
284
- Number of column count top: ${formatSummarizedMeasure(stats.dataFrameShape.numberOfColCountTop)}
285
287
  Number of column count infinite:${formatSummarizedMeasure(stats.dataFrameShape.numberOfColCountInfinite)}
288
+ Number of column count top: ${formatSummarizedMeasure(stats.dataFrameShape.numberOfColCountTop)}
286
289
  Inferred row count per node: ${formatSummarizedMeasure(stats.dataFrameShape.inferredRowCount)}
287
290
  Number of row count exact: ${formatSummarizedMeasure(stats.dataFrameShape.numberOfRowCountExact)}
288
291
  Number of row count values: ${formatSummarizedMeasure(stats.dataFrameShape.numberOfRowCountValues)}
289
- Number of row count top: ${formatSummarizedMeasure(stats.dataFrameShape.numberOfRowCountTop)}
290
292
  Number of row count infinite: ${formatSummarizedMeasure(stats.dataFrameShape.numberOfRowCountInfinite)}
293
+ Number of row count top: ${formatSummarizedMeasure(stats.dataFrameShape.numberOfRowCountTop)}
291
294
  Size of data frame shape info: ${formatSummarizedMeasure(stats.dataFrameShape.sizeOfInfo, convertNumberToNiceBytes)}`;
292
295
  }
293
296
  return result;
@@ -49,8 +49,8 @@ export interface SlicerStatsDfShape<T = number> {
49
49
  numberOfNonDataFrameFiles: T extends number ? 0 | 1 : number;
50
50
  numberOfResultConstraints: T;
51
51
  numberOfResultingValues: T;
52
- numberOfResultingTop: T;
53
52
  numberOfResultingBottom: T;
53
+ numberOfResultingTop: T;
54
54
  numberOfEmptyNodes: T;
55
55
  numberOfOperationNodes: T;
56
56
  numberOfValueNodes: T;
@@ -60,10 +60,11 @@ export interface SlicerStatsDfShape<T = number> {
60
60
  export interface PerNodeStatsDfShape<T = number> {
61
61
  numberOfEntries: T;
62
62
  mappedOperations?: DataFrameOperationName[];
63
- inferredColNames?: T | 'bottom' | 'top';
63
+ inferredColNames?: T | 'bottom' | 'infinite' | 'top';
64
64
  inferredColCount?: T | 'bottom' | 'infinite' | 'top';
65
65
  inferredRowCount?: T | 'bottom' | 'infinite' | 'top';
66
66
  /** difference between upper and lower bound of interval domain (to estimate approximation) */
67
+ approxRangeColNames?: T;
67
68
  approxRangeColCount?: T;
68
69
  approxRangeRowCount?: T;
69
70
  }
@@ -84,25 +84,28 @@ export interface SummarizedDfShapeStats<T = number> extends Omit<SlicerStatsDfSh
84
84
  numberOfEntriesPerNode: SummarizedMeasurement;
85
85
  numberOfOperations: T;
86
86
  numberOfTotalValues: T;
87
- numberOfTotalTop: T;
88
87
  numberOfTotalBottom: T;
88
+ numberOfTotalTop: T;
89
89
  inferredColNames: SummarizedMeasurement;
90
+ approxRangeColNames: SummarizedMeasurement;
91
+ numberOfColNamesExact: T;
90
92
  numberOfColNamesValues: T;
91
- numberOfColNamesTop: T;
92
93
  numberOfColNamesBottom: T;
94
+ numberOfColNamesInfinite: T;
95
+ numberOfColNamesTop: T;
93
96
  inferredColCount: SummarizedMeasurement;
97
+ approxRangeColCount: SummarizedMeasurement;
94
98
  numberOfColCountExact: T;
95
99
  numberOfColCountValues: T;
96
- numberOfColCountTop: T;
97
- numberOfColCountInfinite: T;
98
100
  numberOfColCountBottom: T;
99
- approxRangeColCount: SummarizedMeasurement;
101
+ numberOfColCountInfinite: T;
102
+ numberOfColCountTop: T;
100
103
  inferredRowCount: SummarizedMeasurement;
104
+ approxRangeRowCount: SummarizedMeasurement;
101
105
  numberOfRowCountExact: T;
102
106
  numberOfRowCountValues: T;
103
- numberOfRowCountTop: T;
104
- numberOfRowCountInfinite: T;
105
107
  numberOfRowCountBottom: T;
106
- approxRangeRowCount: SummarizedMeasurement;
108
+ numberOfRowCountInfinite: T;
109
+ numberOfRowCountTop: T;
107
110
  perOperationNumber: Map<DataFrameOperationName, T>;
108
111
  }