@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
@@ -70,7 +70,7 @@ function getConstraintType(operation) {
70
70
  return DataFrameSemanticsMapper[operation].type;
71
71
  }
72
72
  function applyCreateSemantics(value, { colnames, rows }) {
73
- const colnamesValue = colnames?.every(assert_1.isNotUndefined) ? colnames : lattice_1.Top;
73
+ const colnamesValue = setRange(colnames);
74
74
  const colsValue = colnames !== undefined ? [colnames.length, colnames.length] : positive_interval_domain_1.PosIntervalTop;
75
75
  const rowsValue = Array.isArray(rows) ? rows : typeof rows === 'number' ? [rows, rows] : positive_interval_domain_1.PosIntervalTop;
76
76
  return new dataframe_domain_1.DataFrameDomain({
@@ -85,7 +85,7 @@ function applyReadSemantics(value, { colnames, rows }) {
85
85
  function applyAccessColsSemantics(value, { columns }) {
86
86
  if (columns?.every(col => typeof col === 'string')) {
87
87
  return new dataframe_domain_1.DataFrameDomain({
88
- colnames: value.colnames.join(columns),
88
+ colnames: value.colnames.union(setRange(columns)),
89
89
  cols: value.cols,
90
90
  rows: value.rows
91
91
  });
@@ -93,7 +93,7 @@ function applyAccessColsSemantics(value, { columns }) {
93
93
  else if (columns?.every(col => typeof col === 'number')) {
94
94
  return new dataframe_domain_1.DataFrameDomain({
95
95
  colnames: value.colnames,
96
- cols: columns?.reduce((current, col) => current.max([col, col]), value.cols),
96
+ cols: columns.reduce((current, col) => current.max([col, col]), value.cols),
97
97
  rows: value.rows
98
98
  });
99
99
  }
@@ -113,21 +113,21 @@ function applyAssignColsSemantics(value, { columns }) {
113
113
  if (columns?.every(col => typeof col === 'string')) {
114
114
  const cols = columns.length;
115
115
  return new dataframe_domain_1.DataFrameDomain({
116
- colnames: value.colnames.join(columns),
116
+ colnames: value.colnames.union(setRange(columns)),
117
117
  cols: value.cols.add([0, cols]).max([cols, cols]),
118
118
  rows: value.rows
119
119
  });
120
120
  }
121
121
  else if (columns?.every(col => typeof col === 'number')) {
122
122
  return new dataframe_domain_1.DataFrameDomain({
123
- colnames: value.colnames.top(),
123
+ colnames: value.colnames.widenUp(),
124
124
  cols: columns.reduce((current, col) => current.max([col, col]), value.cols),
125
125
  rows: value.rows
126
126
  });
127
127
  }
128
128
  return new dataframe_domain_1.DataFrameDomain({
129
- colnames: value.colnames.top(),
130
- cols: value.cols.extendUp(),
129
+ colnames: value.colnames.widenUp(),
130
+ cols: value.cols.widenUp(),
131
131
  rows: value.rows
132
132
  });
133
133
  }
@@ -142,28 +142,28 @@ function applyAssignRowsSemantics(value, { rows }) {
142
142
  return new dataframe_domain_1.DataFrameDomain({
143
143
  colnames: value.colnames,
144
144
  cols: value.cols,
145
- rows: value.rows.extendUp()
145
+ rows: value.rows.widenUp()
146
146
  });
147
147
  }
148
148
  function applySetColNamesSemantics(value, { colnames }, options) {
149
149
  if (options?.partial) {
150
150
  return new dataframe_domain_1.DataFrameDomain({
151
- colnames: colnames?.every(assert_1.isNotUndefined) ? value.colnames.join(colnames) : value.colnames.top(),
151
+ colnames: value.colnames.widenDown().union(setRange(colnames)),
152
152
  cols: value.cols,
153
153
  rows: value.rows
154
154
  });
155
155
  }
156
156
  const allColNames = colnames?.every(assert_1.isNotUndefined) && value.cols.value !== lattice_1.Bottom && colnames.length >= value.cols.value[1];
157
157
  return new dataframe_domain_1.DataFrameDomain({
158
- colnames: allColNames ? value.colnames.create(colnames) : value.colnames.top(),
158
+ colnames: allColNames ? value.colnames.create(setRange(colnames)) : value.colnames.widenDown().union(setRange(colnames)).widenUp(),
159
159
  cols: value.cols,
160
160
  rows: value.rows
161
161
  });
162
162
  }
163
163
  function applyAddColsSemantics(value, { colnames }) {
164
164
  return new dataframe_domain_1.DataFrameDomain({
165
- colnames: colnames?.every(assert_1.isNotUndefined) ? value.colnames.join(colnames) : value.colnames.top(),
166
- cols: colnames !== undefined ? value.cols.add([colnames.length, colnames.length]) : value.cols.extendUp(),
165
+ colnames: colnames !== undefined ? value.colnames.union(setRange(colnames)) : value.colnames.widenUp(),
166
+ cols: colnames !== undefined ? value.cols.add([colnames.length, colnames.length]) : value.cols.widenUp(),
167
167
  rows: value.rows
168
168
  });
169
169
  }
@@ -173,26 +173,26 @@ function applyAddRowsSemantics(value, { rows }) {
173
173
  ...value,
174
174
  colnames: value.colnames.top(),
175
175
  cols: rows !== undefined ? value.cols.add([1, 1]) : value.cols.top(),
176
- rows: rows !== undefined ? value.rows.add([rows, rows]) : value.rows.extendUp()
176
+ rows: rows !== undefined ? value.rows.add([rows, rows]) : value.rows.widenUp()
177
177
  });
178
178
  }
179
179
  return new dataframe_domain_1.DataFrameDomain({
180
180
  colnames: value.colnames,
181
181
  cols: value.cols,
182
- rows: rows !== undefined ? value.rows.add([rows, rows]) : value.rows.extendUp()
182
+ rows: rows !== undefined ? value.rows.add([rows, rows]) : value.rows.widenUp()
183
183
  });
184
184
  }
185
185
  function applyRemoveColsSemantics(value, { colnames }, options) {
186
186
  if (options?.maybe) {
187
187
  return new dataframe_domain_1.DataFrameDomain({
188
- colnames: colnames !== undefined ? value.colnames.subtract(colnames.filter(assert_1.isNotUndefined)) : value.colnames,
189
- cols: colnames !== undefined ? value.cols.subtract([colnames.length, 0]) : value.cols.extendDown(),
188
+ colnames: colnames !== undefined ? value.colnames.subtract(setRange(colnames)) : value.colnames.widenDown(),
189
+ cols: colnames !== undefined ? value.cols.subtract([colnames.length, 0]) : value.cols.widenDown(),
190
190
  rows: value.rows
191
191
  });
192
192
  }
193
193
  return new dataframe_domain_1.DataFrameDomain({
194
- colnames: colnames !== undefined ? value.colnames.subtract(colnames.filter(assert_1.isNotUndefined)) : value.colnames,
195
- cols: colnames !== undefined ? value.cols.subtract([colnames.length, colnames.length]) : value.cols.extendDown(),
194
+ colnames: colnames !== undefined ? value.colnames.subtract(setRange(colnames)) : value.colnames.widenDown(),
195
+ cols: colnames !== undefined ? value.cols.subtract([colnames.length, colnames.length]) : value.cols.widenDown(),
196
196
  rows: value.rows
197
197
  });
198
198
  }
@@ -201,18 +201,18 @@ function applyRemoveRowsSemantics(value, { rows }, options) {
201
201
  return new dataframe_domain_1.DataFrameDomain({
202
202
  colnames: value.colnames,
203
203
  cols: value.cols,
204
- rows: rows !== undefined ? value.rows.subtract([rows, 0]) : value.rows.extendDown()
204
+ rows: rows !== undefined ? value.rows.subtract([rows, 0]) : value.rows.widenDown()
205
205
  });
206
206
  }
207
207
  return new dataframe_domain_1.DataFrameDomain({
208
208
  colnames: value.colnames,
209
209
  cols: value.cols,
210
- rows: rows !== undefined ? value.rows.subtract([rows, rows]) : value.rows.extendDown()
210
+ rows: rows !== undefined ? value.rows.subtract([rows, rows]) : value.rows.widenDown()
211
211
  });
212
212
  }
213
213
  function applyConcatColsSemantics(value, { other }) {
214
214
  return new dataframe_domain_1.DataFrameDomain({
215
- colnames: value.colnames.join(other.colnames),
215
+ colnames: value.colnames.union(other.colnames),
216
216
  cols: value.cols.add(other.cols),
217
217
  rows: value.rows
218
218
  });
@@ -243,13 +243,13 @@ function applySubsetColsSemantics(value, { colnames }, options) {
243
243
  else if (options?.renamedCols) {
244
244
  return new dataframe_domain_1.DataFrameDomain({
245
245
  colnames: value.colnames.top(),
246
- cols: colnames !== undefined ? value.cols.min([colnames.length, colnames.length]) : value.cols.extendDown(),
246
+ cols: colnames !== undefined ? value.cols.min([colnames.length, colnames.length]) : value.cols.widenDown(),
247
247
  rows: value.rows
248
248
  });
249
249
  }
250
250
  return new dataframe_domain_1.DataFrameDomain({
251
- colnames: colnames?.every(assert_1.isNotUndefined) ? value.colnames.meet(colnames) : value.colnames,
252
- cols: colnames !== undefined ? value.cols.min([colnames.length, colnames.length]) : value.cols.extendDown(),
251
+ colnames: colnames !== undefined ? value.colnames.intersect(setRange(colnames)) : value.colnames.widenDown(),
252
+ cols: colnames !== undefined ? value.cols.min([colnames.length, colnames.length]) : value.cols.widenDown(),
253
253
  rows: value.rows
254
254
  });
255
255
  }
@@ -264,27 +264,27 @@ function applySubsetRowsSemantics(value, { rows }, options) {
264
264
  return new dataframe_domain_1.DataFrameDomain({
265
265
  colnames: value.colnames,
266
266
  cols: value.cols,
267
- rows: rows !== undefined ? value.rows.min([rows, rows]) : value.rows.extendDown()
267
+ rows: rows !== undefined ? value.rows.min([rows, rows]) : value.rows.widenDown()
268
268
  });
269
269
  }
270
270
  function applyFilterRowsSemantics(value, { condition }) {
271
271
  return new dataframe_domain_1.DataFrameDomain({
272
272
  colnames: value.colnames,
273
273
  cols: value.cols,
274
- rows: condition ? value.rows : condition === false ? value.rows.create([0, 0]) : value.rows.extendDown()
274
+ rows: condition ? value.rows : condition === false ? value.rows.create([0, 0]) : value.rows.widenDown()
275
275
  });
276
276
  }
277
277
  function applyMutateColsSemantics(value, { colnames }) {
278
278
  return new dataframe_domain_1.DataFrameDomain({
279
- colnames: colnames?.every(assert_1.isNotUndefined) ? value.colnames.join(colnames) : value.colnames.top(),
280
- cols: colnames !== undefined ? value.cols.add([0, colnames.length]).max([colnames.length, colnames.length]) : value.cols.extendUp(),
279
+ colnames: colnames !== undefined ? value.colnames.union(setRange(colnames)) : value.colnames.widenUp(),
280
+ cols: colnames !== undefined ? value.cols.add([0, colnames.length]).max([colnames.length, colnames.length]) : value.cols.widenUp(),
281
281
  rows: value.rows
282
282
  });
283
283
  }
284
284
  function applyGroupBySemantics(value, { by }, options) {
285
285
  if (options?.mutatedCols) {
286
286
  return new dataframe_domain_1.DataFrameDomain({
287
- colnames: by.every(assert_1.isNotUndefined) ? value.colnames.join(by) : value.colnames.top(),
287
+ colnames: value.colnames.union(setRange(by)),
288
288
  cols: value.cols.add([0, by.length]),
289
289
  rows: value.rows
290
290
  });
@@ -294,8 +294,8 @@ function applyGroupBySemantics(value, { by }, options) {
294
294
  }
295
295
  function applySummarizeSemantics(value, { colnames }) {
296
296
  return new dataframe_domain_1.DataFrameDomain({
297
- colnames: colnames?.every(assert_1.isNotUndefined) ? value.colnames.join(colnames) : value.colnames.top(),
298
- cols: colnames !== undefined ? value.cols.add([0, colnames.length]).min([colnames.length, +Infinity]) : value.cols.extendUp(),
297
+ colnames: colnames !== undefined ? value.colnames.join(setRange([])).union(setRange(colnames)) : value.colnames.widenUp(),
298
+ cols: colnames !== undefined ? value.cols.add([0, colnames.length]).min([colnames.length, +Infinity]) : value.cols.widenUp(),
299
299
  rows: value.rows.min([1, +Infinity]).max([0, 1])
300
300
  });
301
301
  }
@@ -318,35 +318,36 @@ function applyJoinSemantics(value, { other, by }, options) {
318
318
  return new positive_interval_domain_1.PosIntervalDomain([lower.value[0], interval1.value[1] * interval2.value[1]]);
319
319
  }
320
320
  };
321
- const commonCols = value.colnames.meet(other.colnames);
322
- let duplicateCols; // whether columns may be renamed due to occurrence in both data frames
321
+ let duplicateCols; // columns that may be renamed due to occurring in both data frames
323
322
  let productRows; // whether the resulting rows may be a Cartesian product of the rows of the data frames
324
323
  if (options?.natural) {
325
- duplicateCols = false;
326
- productRows = commonCols.isValue() && commonCols.value.size === 0;
324
+ const commonCols = value.colnames.intersect(other.colnames).upper();
325
+ duplicateCols = [];
326
+ productRows = commonCols !== lattice_1.Bottom && commonCols !== lattice_1.Top && commonCols.size === 0;
327
327
  }
328
328
  else if (by === undefined) {
329
- duplicateCols = true;
329
+ duplicateCols = undefined;
330
330
  productRows = true;
331
331
  }
332
332
  else if (by.length === 0) {
333
- duplicateCols = commonCols.isTop() || (commonCols.isValue() && commonCols.value.size > 0);
333
+ const commonCols = value.colnames.intersect(other.colnames).upper();
334
+ duplicateCols = commonCols !== lattice_1.Bottom ? commonCols !== lattice_1.Top ? [...commonCols] : undefined : [];
334
335
  productRows = true;
335
336
  }
336
337
  else if (by.every(assert_1.isNotUndefined)) {
337
- const remainingCols = commonCols.subtract(by);
338
- duplicateCols = remainingCols.isTop() || (remainingCols.isValue() && remainingCols.value.size > 0);
338
+ const remainingCols = value.colnames.intersect(other.colnames).subtract(setRange(by)).upper();
339
+ duplicateCols = remainingCols !== lattice_1.Bottom ? remainingCols !== lattice_1.Top ? [...remainingCols] : undefined : [];
339
340
  productRows = false;
340
341
  }
341
342
  else {
342
- duplicateCols = true;
343
+ duplicateCols = undefined;
343
344
  productRows = false;
344
345
  }
345
346
  const joinType = options?.join ?? 'inner';
346
347
  let rows;
347
348
  switch (joinType) {
348
349
  case 'inner':
349
- rows = value.rows.min(other.rows).extendDown();
350
+ rows = value.rows.min(other.rows).widenDown();
350
351
  break;
351
352
  case 'left':
352
353
  rows = value.rows;
@@ -362,7 +363,7 @@ function applyJoinSemantics(value, { other, by }, options) {
362
363
  }
363
364
  return new dataframe_domain_1.DataFrameDomain({
364
365
  ...value,
365
- colnames: duplicateCols ? value.colnames.top() : value.colnames.join(other.colnames),
366
+ colnames: duplicateCols === undefined ? value.colnames.top() : duplicateCols.length > 0 ? value.colnames.union(other.colnames).subtract(setRange(duplicateCols)).widenUp() : value.colnames.union(other.colnames),
366
367
  cols: by !== undefined ? value.cols.add(other.cols).subtract([by.length, by.length]) : mergeInterval(value.cols, other.cols),
367
368
  rows: productRows ? productInterval(rows, value.rows, other.rows) : rows
368
369
  });
@@ -377,4 +378,8 @@ function applyUnknownSemantics(value,
377
378
  _args) {
378
379
  return value.top();
379
380
  }
381
+ function setRange(colnames) {
382
+ const names = colnames?.filter(assert_1.isNotUndefined) ?? [];
383
+ return { min: names, range: names.length === colnames?.length ? [] : lattice_1.Top };
384
+ }
380
385
  //# sourceMappingURL=semantics.js.map
@@ -1,11 +1,11 @@
1
1
  import { type ControlFlowInformation } from '../../control-flow/control-flow-graph';
2
2
  import type { DataflowGraph } from '../../dataflow/graph/graph';
3
+ import type { ReadOnlyFlowrAnalyzerContext } from '../../project/context/flowr-analyzer-context';
3
4
  import type { RNode } from '../../r-bridge/lang-4.x/ast/model/model';
4
5
  import type { NormalizedAst, ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
5
6
  import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
6
7
  import { type AbstractInterpretationInfo } from './absint-info';
7
8
  import { type DataFrameDomain, DataFrameStateDomain } from './dataframe-domain';
8
- import type { ReadOnlyFlowrAnalyzerContext } from '../../project/context/flowr-analyzer-context';
9
9
  /**
10
10
  * Infers the shape of data frames by performing abstract interpretation using the control flow graph of a program.
11
11
  * This directly attaches the inferred data frames shapes to the AST (see {@link AbstractInterpretationInfo}).
@@ -5,6 +5,7 @@ import { type Lattice, Top } from './lattice';
5
5
  export declare const DEFAULT_INFERENCE_LIMIT = 50;
6
6
  /**
7
7
  * An abstract domain as complete lattice with a widening operator, narrowing operator, concretization function, and abstraction function.
8
+ * All operations of value abstract domains should not modify the domain in-place but return new values using {@link create}.
8
9
  * @template Concrete - Type of an concrete element of the concrete domain for the abstract domain
9
10
  * @template Abstract - Type of an abstract element of the abstract domain representing possible elements (excludes `Top` and `Bot`)
10
11
  * @template Top - Type of the Top element of the abstract domain representing all possible elements
@@ -11,6 +11,7 @@ const lattice_1 = require("./lattice");
11
11
  exports.DEFAULT_INFERENCE_LIMIT = 50;
12
12
  /**
13
13
  * An abstract domain as complete lattice with a widening operator, narrowing operator, concretization function, and abstraction function.
14
+ * All operations of value abstract domains should not modify the domain in-place but return new values using {@link create}.
14
15
  * @template Concrete - Type of an concrete element of the concrete domain for the abstract domain
15
16
  * @template Abstract - Type of an abstract element of the abstract domain representing possible elements (excludes `Top` and `Bot`)
16
17
  * @template Top - Type of the Top element of the abstract domain representing all possible elements
@@ -73,10 +74,10 @@ function domainElementToString(value) {
73
74
  return value.toString();
74
75
  }
75
76
  else if (value === lattice_1.Top) {
76
- return '⊤';
77
+ return lattice_1.TopSymbol;
77
78
  }
78
79
  else if (value === lattice_1.Bottom) {
79
- return '⊥';
80
+ return lattice_1.BottomSymbol;
80
81
  }
81
82
  return JSON.stringify(value);
82
83
  }
@@ -125,7 +125,7 @@ class BoundedSetDomain extends abstract_domain_1.AbstractDomain {
125
125
  }
126
126
  toString() {
127
127
  if (this.value === lattice_1.Top) {
128
- return '⊤';
128
+ return lattice_1.TopSymbol;
129
129
  }
130
130
  const string = this.value.values().map(abstract_domain_1.domainElementToString).toArray().join(', ');
131
131
  return `{${string}}`;
@@ -55,11 +55,11 @@ export declare class IntervalDomain<Value extends IntervalLift = IntervalLift> e
55
55
  /**
56
56
  * Extends the lower bound of the current abstract value down to -∞.
57
57
  */
58
- extendDown(): this;
58
+ widenDown(): this;
59
59
  /**
60
60
  * Extends the upper bound of the current abstract value up to +∞.
61
61
  */
62
- extendUp(): this;
62
+ widenUp(): this;
63
63
  toJson(): unknown;
64
64
  toString(): string;
65
65
  isTop(): this is IntervalDomain<IntervalTop>;
@@ -75,9 +75,6 @@ class IntervalDomain extends abstract_domain_1.AbstractDomain {
75
75
  if (this.value === lattice_1.Bottom || otherValue === lattice_1.Bottom) {
76
76
  return this.bottom();
77
77
  }
78
- else if (Math.max(this.value[0], otherValue[0]) > Math.min(this.value[1], otherValue[1])) {
79
- return this.bottom();
80
- }
81
78
  else {
82
79
  return this.create([Math.max(this.value[0], otherValue[0]), Math.min(this.value[1], otherValue[1])]);
83
80
  }
@@ -222,7 +219,7 @@ class IntervalDomain extends abstract_domain_1.AbstractDomain {
222
219
  /**
223
220
  * Extends the lower bound of the current abstract value down to -∞.
224
221
  */
225
- extendDown() {
222
+ widenDown() {
226
223
  if (this.value === lattice_1.Bottom) {
227
224
  return this.bottom();
228
225
  }
@@ -233,7 +230,7 @@ class IntervalDomain extends abstract_domain_1.AbstractDomain {
233
230
  /**
234
231
  * Extends the upper bound of the current abstract value up to +∞.
235
232
  */
236
- extendUp() {
233
+ widenUp() {
237
234
  if (this.value === lattice_1.Bottom) {
238
235
  return this.bottom();
239
236
  }
@@ -249,7 +246,7 @@ class IntervalDomain extends abstract_domain_1.AbstractDomain {
249
246
  }
250
247
  toString() {
251
248
  if (this.value === lattice_1.Bottom) {
252
- return '⊥';
249
+ return lattice_1.BottomSymbol;
253
250
  }
254
251
  return `[${isFinite(this.value[0]) ? this.value[0] : '-∞'}, ${isFinite(this.value[1]) ? this.value[1] : '+∞'}]`;
255
252
  }
@@ -2,10 +2,12 @@
2
2
  * The Top symbol to represent the Top element of complete lattices (e.g. of abstract domains).
3
3
  */
4
4
  export declare const Top: unique symbol;
5
+ export declare const TopSymbol = "\u22A4";
5
6
  /**
6
7
  * The Bottom symbol to represent the Bottom element of complete lattices (e.g. of abstract domains).
7
8
  */
8
9
  export declare const Bottom: unique symbol;
10
+ export declare const BottomSymbol = "\u22A5";
9
11
  /**
10
12
  * A complete lattice with a partially ordered set, join operator (LUB), meet operator (GLB), top element, and bottom element (e.g. for abstract domains).
11
13
  * @template Value - Type of a lattice element representing a value (may exclude `Top` and `Bot`)
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Bottom = exports.Top = void 0;
3
+ exports.BottomSymbol = exports.Bottom = exports.TopSymbol = exports.Top = void 0;
4
4
  /**
5
5
  * The Top symbol to represent the Top element of complete lattices (e.g. of abstract domains).
6
6
  */
7
7
  exports.Top = Symbol('top');
8
+ exports.TopSymbol = '⊤';
8
9
  /**
9
10
  * The Bottom symbol to represent the Bottom element of complete lattices (e.g. of abstract domains).
10
11
  */
11
12
  exports.Bottom = Symbol('bottom');
13
+ exports.BottomSymbol = '⊥';
12
14
  //# sourceMappingURL=lattice.js.map
@@ -30,7 +30,7 @@ export declare class PosIntervalDomain<Value extends PosIntervalLift = PosInterv
30
30
  /**
31
31
  * Extends the lower bound of the current abstract value down to 0.
32
32
  */
33
- extendDown(): this;
33
+ widenDown(): this;
34
34
  isTop(): this is PosIntervalDomain<PosIntervalTop>;
35
35
  }
36
36
  export {};
@@ -84,7 +84,7 @@ class PosIntervalDomain extends interval_domain_1.IntervalDomain {
84
84
  /**
85
85
  * Extends the lower bound of the current abstract value down to 0.
86
86
  */
87
- extendDown() {
87
+ widenDown() {
88
88
  if (this.value === lattice_1.Bottom) {
89
89
  return this.bottom();
90
90
  }
@@ -10,7 +10,7 @@ export interface SatisfiableDomain<T> {
10
10
  satisfies(value: T): Ternary;
11
11
  }
12
12
  /**
13
- * Represents the different types of numerical comparators for satifiability checks for an abstract domain.
13
+ * Represents the different types of numerical comparators for satisfiability checks for an abstract domain.
14
14
  */
15
15
  export declare enum NumericalComparator {
16
16
  Equal = 0,
@@ -20,7 +20,7 @@ export declare enum NumericalComparator {
20
20
  GreaterOrEqual = 4
21
21
  }
22
22
  /**
23
- * Represents the different types of set comparators for satifiability checks for an abstract domain.
23
+ * Represents the different types of set comparators for satisfiability checks for an abstract domain.
24
24
  */
25
25
  export declare enum SetComparator {
26
26
  Equal = 0,
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SetComparator = exports.NumericalComparator = void 0;
4
4
  /**
5
- * Represents the different types of numerical comparators for satifiability checks for an abstract domain.
5
+ * Represents the different types of numerical comparators for satisfiability checks for an abstract domain.
6
6
  */
7
7
  var NumericalComparator;
8
8
  (function (NumericalComparator) {
@@ -13,7 +13,7 @@ var NumericalComparator;
13
13
  NumericalComparator[NumericalComparator["GreaterOrEqual"] = 4] = "GreaterOrEqual";
14
14
  })(NumericalComparator || (exports.NumericalComparator = NumericalComparator = {}));
15
15
  /**
16
- * Represents the different types of set comparators for satifiability checks for an abstract domain.
16
+ * Represents the different types of set comparators for satisfiability checks for an abstract domain.
17
17
  */
18
18
  var SetComparator;
19
19
  (function (SetComparator) {
@@ -0,0 +1,98 @@
1
+ import { Ternary } from '../../util/logic';
2
+ import { AbstractDomain } from './abstract-domain';
3
+ import { Bottom, Top } from './lattice';
4
+ import type { SatisfiableDomain } from './satisfiable-domain';
5
+ import { SetComparator } from './satisfiable-domain';
6
+ /** The Top element of the set range domain with an empty set as minimum set and {@link Top} as range set */
7
+ export declare const SetRangeTop: {
8
+ readonly min: Set<never>;
9
+ readonly range: typeof Top;
10
+ };
11
+ /** The type of the actual values of the set range domain as tuple with a minimum set and range set of additional possible values (i.e. `[{"id","name"}, ∅]`, or `[{"id"}, {"score"}]`) */
12
+ type SetRangeValue<T> = {
13
+ readonly min: ReadonlySet<T>;
14
+ readonly range: ReadonlySet<T> | typeof Top;
15
+ };
16
+ /** The type of the Top element of the set range domain as tuple with the empty set as minimum set and {@link Top} as range set (i.e. `[∅, Top]`) */
17
+ type SetRangeTop = typeof SetRangeTop;
18
+ /** The type of the Bottom element of the set range domain as {@link Bottom} */
19
+ type SetRangeBottom = typeof Bottom;
20
+ /** The type of the abstract values of the set range domain that are Top, Bottom, or actual values */
21
+ type SetRangeLift<T> = SetRangeValue<T> | SetRangeTop | SetRangeBottom;
22
+ /** The type of the actual values of the set range domain as array tuple with a minimum array and range array for better readability (e.g. `[["id","name"], []]`, or `[["id"], ["score"]]`) */
23
+ export type ArrayRangeValue<T> = {
24
+ readonly min: T[];
25
+ readonly range: T[] | typeof Top;
26
+ };
27
+ /** The type for the maximum number of elements in the minimum set and maximum set of the set range domain before over-approximation */
28
+ export type SetRangeLimit = {
29
+ readonly min: number;
30
+ readonly range: number;
31
+ };
32
+ /**
33
+ * The set range abstract domain as range of possible value sets with a minimum set of values and a range of possible additional values
34
+ * (similar to an interval like structure with a lower bound and a difference to the upper bound).
35
+ * 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}.
36
+ * @template T - Type of the values in the sets in the abstract domain
37
+ * @template Value - Type of the constraint in the abstract domain (Top, Bottom, or an actual value)
38
+ */
39
+ export declare class SetRangeDomain<T, Value extends SetRangeLift<T> = SetRangeLift<T>> extends AbstractDomain<ReadonlySet<T>, SetRangeValue<T>, SetRangeTop, SetRangeBottom, Value> implements SatisfiableDomain<ReadonlySet<T>> {
40
+ readonly limit: SetRangeLimit;
41
+ private readonly setType;
42
+ /**
43
+ * @param limit - A limit for the maximum number of elements to store in the minimum set and maximum set before over-approximation
44
+ * @param newSet - An optional set constructor for the domain elements if the type `T` is not storable in a HashSet
45
+ */
46
+ constructor(value: Value | ArrayRangeValue<T>, limit?: SetRangeLimit | number, setType?: typeof Set<T>);
47
+ create(value: SetRangeLift<T> | ArrayRangeValue<T>): this;
48
+ /**
49
+ * The minimum set (lower bound) of the set range representing all values that must exist (subset of {@link upper}).
50
+ */
51
+ lower(): SetRangeValue<T>['min'] | typeof Bottom;
52
+ /**
53
+ * The maximum set (upper bound) of the set range representing all values that can possibly exist (union of {@link lower} and range).
54
+ */
55
+ upper(): SetRangeValue<T>['range'] | typeof Bottom;
56
+ static top<T>(limit?: SetRangeLimit | number, setType?: typeof Set<T>): SetRangeDomain<T, SetRangeTop>;
57
+ static bottom<T>(limit?: SetRangeLimit | number, setType?: typeof Set<T>): SetRangeDomain<T, SetRangeBottom>;
58
+ static abstract<T>(concrete: ReadonlySet<ReadonlySet<T>> | typeof Top, limit?: SetRangeLimit | number, setType?: typeof Set<T>): SetRangeDomain<T>;
59
+ top(): this & SetRangeDomain<T, SetRangeTop>;
60
+ bottom(): this & SetRangeDomain<T, SetRangeBottom>;
61
+ equals(other: this): boolean;
62
+ leq(other: this): boolean;
63
+ join(other: this): this;
64
+ join(other: SetRangeLift<T> | ArrayRangeValue<T>): this;
65
+ meet(other: this): this;
66
+ meet(other: SetRangeLift<T> | ArrayRangeValue<T>): this;
67
+ /**
68
+ * Creates the union of this abstract value and another abstract value by creating the union of the minimum and maximum set, respectively.
69
+ */
70
+ union(other: this | SetRangeLift<T> | ArrayRangeValue<T>): this;
71
+ /**
72
+ * Creates the intersection of this abstract value and another abstract value by creating the intersection of the minimum and maximum set, respectively.
73
+ */
74
+ intersect(other: this | SetRangeLift<T> | ArrayRangeValue<T>): this;
75
+ /**
76
+ * Subtracts another abstract value from the current abstract value by removing all elements of the other abstract value from the current abstract value.
77
+ */
78
+ subtract(other: this | SetRangeLift<T> | ArrayRangeValue<T>): this;
79
+ widen(other: this): this;
80
+ narrow(other: this): this;
81
+ concretize(limit: number): ReadonlySet<ReadonlySet<T>> | typeof Top;
82
+ abstract(concrete: ReadonlySet<ReadonlySet<T>> | typeof Top): this;
83
+ satisfies(set: ReadonlySet<T> | T[], comparator?: SetComparator): Ternary;
84
+ /**
85
+ * Extends the minimum set of the current abstract value down to the empty set.
86
+ */
87
+ widenDown(): this;
88
+ /**
89
+ * Extends the maximum set of the current abstract value up to {@link Top}.
90
+ */
91
+ widenUp(): this;
92
+ toJson(): unknown;
93
+ toString(): string;
94
+ isTop(): this is SetRangeDomain<T, SetRangeTop>;
95
+ isBottom(): this is SetRangeDomain<T, SetRangeBottom>;
96
+ isValue(): this is SetRangeDomain<T, SetRangeValue<T>>;
97
+ }
98
+ export {};