@eagleoutice/flowr 2.6.3 → 2.7.2

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 (276) hide show
  1. package/README.md +22 -22
  2. package/abstract-interpretation/absint-visitor.d.ts +160 -0
  3. package/abstract-interpretation/absint-visitor.js +279 -0
  4. package/abstract-interpretation/data-frame/dataframe-domain.d.ts +4 -7
  5. package/abstract-interpretation/data-frame/dataframe-domain.js +26 -16
  6. package/abstract-interpretation/data-frame/mappers/access-mapper.d.ts +6 -4
  7. package/abstract-interpretation/data-frame/mappers/access-mapper.js +11 -14
  8. package/abstract-interpretation/data-frame/mappers/arguments.d.ts +10 -9
  9. package/abstract-interpretation/data-frame/mappers/arguments.js +8 -5
  10. package/abstract-interpretation/data-frame/mappers/function-mapper.d.ts +18 -18
  11. package/abstract-interpretation/data-frame/mappers/function-mapper.js +53 -58
  12. package/abstract-interpretation/data-frame/mappers/replacement-mapper.d.ts +7 -5
  13. package/abstract-interpretation/data-frame/mappers/replacement-mapper.js +26 -29
  14. package/abstract-interpretation/data-frame/semantics.js +48 -44
  15. package/abstract-interpretation/data-frame/shape-inference.d.ts +52 -28
  16. package/abstract-interpretation/data-frame/shape-inference.js +67 -90
  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.d.ts +2 -2
  20. package/abstract-interpretation/domains/bounded-set-domain.js +1 -1
  21. package/abstract-interpretation/domains/interval-domain.d.ts +4 -4
  22. package/abstract-interpretation/domains/interval-domain.js +3 -6
  23. package/abstract-interpretation/domains/lattice.d.ts +2 -0
  24. package/abstract-interpretation/domains/lattice.js +3 -1
  25. package/abstract-interpretation/domains/positive-interval-domain.d.ts +1 -1
  26. package/abstract-interpretation/domains/positive-interval-domain.js +1 -1
  27. package/abstract-interpretation/domains/satisfiable-domain.d.ts +2 -2
  28. package/abstract-interpretation/domains/satisfiable-domain.js +2 -2
  29. package/abstract-interpretation/domains/set-range-domain.d.ts +104 -0
  30. package/abstract-interpretation/domains/set-range-domain.js +406 -0
  31. package/abstract-interpretation/domains/set-upper-bound-domain.d.ts +2 -2
  32. package/abstract-interpretation/domains/set-upper-bound-domain.js +2 -2
  33. package/abstract-interpretation/domains/singleton-domain.d.ts +2 -2
  34. package/abstract-interpretation/domains/singleton-domain.js +2 -2
  35. package/benchmark/slicer.d.ts +2 -1
  36. package/benchmark/slicer.js +50 -29
  37. package/benchmark/stats/print.js +8 -5
  38. package/benchmark/stats/stats.d.ts +3 -2
  39. package/benchmark/summarizer/data.d.ts +11 -8
  40. package/benchmark/summarizer/first-phase/process.js +11 -8
  41. package/benchmark/summarizer/second-phase/process.js +24 -18
  42. package/cli/common/options.d.ts +431 -8
  43. package/cli/common/options.js +1 -1
  44. package/cli/common/scripts-info.d.ts +431 -7
  45. package/cli/flowr-main-options.d.ts +102 -2
  46. package/cli/flowr.d.ts +102 -2
  47. package/cli/repl/commands/repl-commands.d.ts +25 -0
  48. package/cli/repl/commands/repl-query.js +17 -5
  49. package/cli/wiki.d.ts +13 -0
  50. package/cli/wiki.js +7 -2
  51. package/config.d.ts +4 -4
  52. package/config.js +1 -1
  53. package/control-flow/basic-cfg-guided-visitor.js +7 -8
  54. package/control-flow/cfg-dead-code.js +3 -2
  55. package/control-flow/control-flow-graph.d.ts +1 -1
  56. package/control-flow/semantic-cfg-guided-visitor.d.ts +1 -1
  57. package/control-flow/semantic-cfg-guided-visitor.js +1 -1
  58. package/control-flow/useless-loop.js +4 -2
  59. package/core/steps/all/static-slicing/00-slice.d.ts +3 -0
  60. package/core/steps/all/static-slicing/00-slice.js +2 -1
  61. package/core/steps/pipeline/default-pipelines.d.ts +42 -42
  62. package/dataflow/cluster.js +2 -2
  63. package/dataflow/environments/append.d.ts +5 -0
  64. package/dataflow/environments/append.js +6 -20
  65. package/dataflow/environments/built-in.d.ts +2 -1
  66. package/dataflow/environments/clone.d.ts +1 -1
  67. package/dataflow/environments/clone.js +3 -27
  68. package/dataflow/environments/define.d.ts +7 -3
  69. package/dataflow/environments/define.js +9 -56
  70. package/dataflow/environments/diff.js +1 -1
  71. package/dataflow/environments/environment.d.ts +48 -28
  72. package/dataflow/environments/environment.js +187 -62
  73. package/dataflow/environments/overwrite.js +2 -45
  74. package/dataflow/environments/reference-to-maybe.d.ts +13 -0
  75. package/dataflow/environments/reference-to-maybe.js +54 -0
  76. package/dataflow/environments/resolve-by-name.d.ts +6 -1
  77. package/dataflow/environments/resolve-by-name.js +56 -4
  78. package/dataflow/environments/scoping.d.ts +2 -2
  79. package/dataflow/environments/scoping.js +7 -7
  80. package/dataflow/eval/resolve/alias-tracking.d.ts +10 -4
  81. package/dataflow/eval/resolve/alias-tracking.js +16 -14
  82. package/dataflow/eval/resolve/resolve-argument.d.ts +2 -1
  83. package/dataflow/eval/resolve/resolve-argument.js +8 -8
  84. package/dataflow/eval/resolve/resolve.d.ts +13 -11
  85. package/dataflow/eval/resolve/resolve.js +16 -15
  86. package/dataflow/extractor.js +1 -7
  87. package/dataflow/fn/higher-order-function.d.ts +2 -1
  88. package/dataflow/fn/higher-order-function.js +4 -4
  89. package/dataflow/graph/dataflowgraph-builder.d.ts +9 -5
  90. package/dataflow/graph/dataflowgraph-builder.js +21 -11
  91. package/dataflow/graph/diff-dataflow-graph.js +2 -2
  92. package/dataflow/graph/graph.d.ts +10 -2
  93. package/dataflow/graph/graph.js +41 -12
  94. package/dataflow/graph/invert-dfg.d.ts +3 -2
  95. package/dataflow/graph/invert-dfg.js +3 -3
  96. package/dataflow/graph/resolve-graph.d.ts +2 -1
  97. package/dataflow/graph/resolve-graph.js +2 -2
  98. package/dataflow/graph/vertex.d.ts +3 -3
  99. package/dataflow/graph/vertex.js +3 -3
  100. package/dataflow/info.d.ts +1 -1
  101. package/dataflow/internal/linker.d.ts +2 -0
  102. package/dataflow/internal/linker.js +13 -19
  103. package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +7 -1
  104. package/dataflow/internal/process/functions/call/argument/unpack-argument.js +12 -3
  105. package/dataflow/internal/process/functions/call/built-in/built-in-access.js +3 -3
  106. package/dataflow/internal/process/functions/call/built-in/built-in-apply.js +2 -2
  107. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.d.ts +3 -1
  108. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +3 -3
  109. package/dataflow/internal/process/functions/call/built-in/built-in-eval.js +9 -9
  110. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +9 -7
  111. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +3 -3
  112. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.d.ts +2 -1
  113. package/dataflow/internal/process/functions/call/built-in/built-in-function-definition.js +9 -13
  114. package/dataflow/internal/process/functions/call/built-in/built-in-get.js +1 -1
  115. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.d.ts +3 -1
  116. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +8 -6
  117. package/dataflow/internal/process/functions/call/built-in/built-in-library.js +1 -1
  118. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +1 -1
  119. package/dataflow/internal/process/functions/call/built-in/built-in-repeat-loop.js +1 -1
  120. package/dataflow/internal/process/functions/call/built-in/built-in-replacement.js +3 -3
  121. package/dataflow/internal/process/functions/call/built-in/built-in-rm.js +6 -4
  122. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +1 -1
  123. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +5 -5
  124. package/dataflow/internal/process/functions/call/common.js +2 -3
  125. package/dataflow/internal/process/functions/call/known-call-handling.js +1 -1
  126. package/dataflow/internal/process/functions/call/unnamed-call-handling.js +1 -1
  127. package/dataflow/internal/process/functions/process-argument.js +1 -1
  128. package/dataflow/internal/process/process-symbol.js +1 -1
  129. package/dataflow/internal/process/process-value.d.ts +1 -1
  130. package/dataflow/internal/process/process-value.js +7 -7
  131. package/dataflow/processor.d.ts +1 -5
  132. package/documentation/doc-capabilities.d.ts +1 -1
  133. package/documentation/doc-readme.d.ts +1 -1
  134. package/documentation/doc-util/doc-cfg.js +1 -1
  135. package/documentation/doc-util/doc-cli-option.d.ts +6 -6
  136. package/documentation/doc-util/doc-cli-option.js +3 -3
  137. package/documentation/doc-util/doc-dfg.d.ts +1 -1
  138. package/documentation/doc-util/doc-dfg.js +3 -2
  139. package/documentation/doc-util/doc-files.d.ts +3 -0
  140. package/documentation/doc-util/doc-files.js +4 -1
  141. package/documentation/doc-util/doc-normalized-ast.js +5 -4
  142. package/documentation/doc-util/doc-types.d.ts +1 -1
  143. package/documentation/doc-util/doc-types.js +2 -2
  144. package/documentation/issue-linting-rule.d.ts +1 -1
  145. package/documentation/wiki-analyzer.d.ts +1 -1
  146. package/documentation/wiki-analyzer.js +14 -1
  147. package/documentation/wiki-cfg.d.ts +1 -1
  148. package/documentation/wiki-core.d.ts +1 -1
  149. package/documentation/wiki-dataflow-graph.d.ts +1 -1
  150. package/documentation/wiki-dataflow-graph.js +10 -11
  151. package/documentation/wiki-engine.d.ts +1 -1
  152. package/documentation/wiki-engine.js +9 -10
  153. package/documentation/wiki-faq.d.ts +1 -1
  154. package/documentation/wiki-faq.js +0 -1
  155. package/documentation/wiki-interface.d.ts +1 -1
  156. package/documentation/wiki-interface.js +12 -13
  157. package/documentation/wiki-linter.d.ts +1 -1
  158. package/documentation/wiki-linter.js +1 -1
  159. package/documentation/wiki-linting-and-testing.d.ts +1 -1
  160. package/documentation/wiki-mk/doc-context.d.ts +54 -1
  161. package/documentation/wiki-mk/doc-context.js +17 -0
  162. package/documentation/wiki-mk/doc-maker.d.ts +5 -5
  163. package/documentation/wiki-mk/doc-maker.js +5 -2
  164. package/documentation/wiki-normalized-ast.d.ts +1 -1
  165. package/documentation/wiki-onboarding.d.ts +1 -1
  166. package/documentation/wiki-overview.d.ts +9 -0
  167. package/documentation/wiki-overview.js +248 -0
  168. package/documentation/wiki-query.d.ts +1 -1
  169. package/documentation/wiki-query.js +17 -1
  170. package/documentation/wiki-search.d.ts +1 -1
  171. package/documentation/wiki-setup.d.ts +9 -0
  172. package/documentation/wiki-setup.js +122 -0
  173. package/linter/linter-rules.d.ts +2 -2
  174. package/linter/rules/absolute-path.js +4 -4
  175. package/linter/rules/dataframe-access-validation.d.ts +2 -2
  176. package/linter/rules/dataframe-access-validation.js +9 -11
  177. package/linter/rules/function-finder-util.d.ts +2 -2
  178. package/linter/rules/function-finder-util.js +1 -1
  179. package/linter/rules/network-functions.js +1 -1
  180. package/linter/rules/seeded-randomness.d.ts +1 -1
  181. package/linter/rules/seeded-randomness.js +5 -5
  182. package/linter/rules/unused-definition.js +1 -1
  183. package/package.json +1 -2
  184. package/project/context/flowr-analyzer-context.d.ts +11 -0
  185. package/project/context/flowr-analyzer-context.js +3 -0
  186. package/project/context/flowr-analyzer-environment-context.d.ts +47 -0
  187. package/project/context/flowr-analyzer-environment-context.js +50 -0
  188. package/project/context/flowr-analyzer-files-context.d.ts +9 -1
  189. package/project/context/flowr-analyzer-files-context.js +4 -0
  190. package/project/context/flowr-file.d.ts +2 -0
  191. package/project/context/flowr-file.js +2 -0
  192. package/project/plugins/file-plugins/{flowr-description-file.d.ts → files/flowr-description-file.d.ts} +1 -1
  193. package/project/plugins/file-plugins/files/flowr-description-file.js +75 -0
  194. package/project/plugins/file-plugins/files/flowr-news-file.d.ts +27 -0
  195. package/project/plugins/file-plugins/files/flowr-news-file.js +152 -0
  196. package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.d.ts +1 -1
  197. package/project/plugins/file-plugins/flowr-analyzer-description-file-plugin.js +1 -1
  198. package/project/plugins/file-plugins/flowr-analyzer-news-file-plugin.d.ts +23 -0
  199. package/project/plugins/file-plugins/flowr-analyzer-news-file-plugin.js +35 -0
  200. package/project/plugins/file-plugins/notebooks/flowr-analyzer-jupyter-file-plugin.d.ts +1 -1
  201. package/project/plugins/file-plugins/notebooks/flowr-analyzer-jupyter-file-plugin.js +1 -1
  202. package/project/plugins/file-plugins/notebooks/flowr-analyzer-qmd-file-plugin.d.ts +1 -1
  203. package/project/plugins/file-plugins/notebooks/flowr-analyzer-qmd-file-plugin.js +1 -1
  204. package/project/plugins/file-plugins/notebooks/flowr-analyzer-rmd-file-plugin.d.ts +1 -1
  205. package/project/plugins/file-plugins/notebooks/flowr-analyzer-rmd-file-plugin.js +1 -1
  206. package/project/plugins/flowr-analyzer-plugin-defaults.js +2 -0
  207. package/project/plugins/plugin-registry.d.ts +2 -1
  208. package/project/plugins/plugin-registry.js +2 -0
  209. package/project/plugins/project-discovery/flowr-analyzer-project-discovery-plugin.js +7 -1
  210. package/queries/catalog/call-context-query/call-context-query-executor.js +1 -4
  211. package/queries/catalog/control-flow-query/control-flow-query-format.js +3 -2
  212. package/queries/catalog/dataflow-lens-query/dataflow-lens-query-executor.js +1 -1
  213. package/queries/catalog/dependencies-query/dependencies-query-executor.js +4 -4
  214. package/queries/catalog/df-shape-query/df-shape-query-executor.d.ts +1 -1
  215. package/queries/catalog/df-shape-query/df-shape-query-executor.js +5 -3
  216. package/queries/catalog/df-shape-query/df-shape-query-format.d.ts +4 -4
  217. package/queries/catalog/df-shape-query/df-shape-query-format.js +2 -2
  218. package/queries/catalog/files-query/files-query-executor.d.ts +6 -0
  219. package/queries/catalog/files-query/files-query-executor.js +49 -0
  220. package/queries/catalog/files-query/files-query-format.d.ts +36 -0
  221. package/queries/catalog/files-query/files-query-format.js +114 -0
  222. package/queries/catalog/inspect-higher-order-query/inspect-higher-order-query-executor.js +3 -3
  223. package/queries/catalog/linter-query/linter-query-format.js +1 -1
  224. package/queries/catalog/resolve-value-query/resolve-value-query-executor.js +1 -1
  225. package/queries/catalog/static-slice-query/static-slice-query-executor.js +1 -1
  226. package/queries/query.d.ts +10 -1
  227. package/queries/query.js +3 -1
  228. package/r-bridge/lang-4.x/ast/model/model.d.ts +1 -1
  229. package/r-bridge/lang-4.x/ast/model/processing/decorate.js +8 -8
  230. package/r-bridge/lang-4.x/ast/model/processing/role.d.ts +8 -8
  231. package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-parameter.js +0 -1
  232. package/r-bridge/lang-4.x/tree-sitter/tree-sitter-normalize.js +0 -1
  233. package/slicing/static/slice-call.d.ts +3 -2
  234. package/slicing/static/slice-call.js +4 -4
  235. package/slicing/static/static-slicer.d.ts +3 -1
  236. package/slicing/static/static-slicer.js +6 -7
  237. package/statistics/features/supported/control-flow/control-flow.js +1 -1
  238. package/statistics/features/supported/data-access/data-access.js +1 -1
  239. package/statistics/features/supported/used-functions/used-functions.js +1 -1
  240. package/statistics/features/supported/variables/variables.js +2 -1
  241. package/util/containers.js +2 -2
  242. package/util/files.d.ts +0 -7
  243. package/util/files.js +0 -41
  244. package/util/mermaid/ast.d.ts +3 -2
  245. package/util/mermaid/ast.js +13 -7
  246. package/util/mermaid/cfg.d.ts +3 -2
  247. package/util/mermaid/cfg.js +26 -6
  248. package/util/mermaid/dfg.d.ts +2 -7
  249. package/util/mermaid/dfg.js +10 -6
  250. package/util/mermaid/info.d.ts +17 -0
  251. package/util/mermaid/info.js +5 -0
  252. package/util/prefix.d.ts +9 -5
  253. package/util/prefix.js +14 -6
  254. package/util/r-regex.d.ts +21 -0
  255. package/util/r-regex.js +25 -0
  256. package/util/simple-df/dfg-view.d.ts +2 -1
  257. package/util/simple-df/dfg-view.js +2 -2
  258. package/util/text/args.js +12 -3
  259. package/util/version.js +1 -1
  260. package/abstract-interpretation/data-frame/absint-info.d.ts +0 -109
  261. package/abstract-interpretation/data-frame/absint-info.js +0 -31
  262. package/abstract-interpretation/data-frame/absint-visitor.d.ts +0 -57
  263. package/abstract-interpretation/data-frame/absint-visitor.js +0 -176
  264. package/abstract-interpretation/data-frame/mappers/assignment-mapper.d.ts +0 -19
  265. package/abstract-interpretation/data-frame/mappers/assignment-mapper.js +0 -33
  266. package/dataflow/environments/remove.d.ts +0 -12
  267. package/dataflow/environments/remove.js +0 -52
  268. package/documentation/doc-util/doc-print.d.ts +0 -5
  269. package/documentation/doc-util/doc-print.js +0 -36
  270. package/project/plugins/file-plugins/flowr-description-file.js +0 -37
  271. package/project/plugins/file-plugins/notebooks/notebook.d.ts +0 -0
  272. package/project/plugins/file-plugins/notebooks/notebook.js +0 -2
  273. /package/project/plugins/file-plugins/{notebooks → files}/flowr-jupyter-file.d.ts +0 -0
  274. /package/project/plugins/file-plugins/{notebooks → files}/flowr-jupyter-file.js +0 -0
  275. /package/project/plugins/file-plugins/{notebooks → files}/flowr-rmarkdown-file.d.ts +0 -0
  276. /package/project/plugins/file-plugins/{notebooks → files}/flowr-rmarkdown-file.js +0 -0
@@ -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
  }
@@ -111,23 +111,22 @@ function applyAccessRowsSemantics(value, { rows }) {
111
111
  }
112
112
  function applyAssignColsSemantics(value, { columns }) {
113
113
  if (columns?.every(col => typeof col === 'string')) {
114
- const cols = columns.length;
115
114
  return new dataframe_domain_1.DataFrameDomain({
116
- colnames: value.colnames.join(columns),
117
- cols: value.cols.add([0, cols]).max([cols, cols]),
115
+ colnames: value.colnames.union(setRange(columns)),
116
+ cols: value.cols.add([0, columns.length]).max([columns.length, columns.length]),
118
117
  rows: value.rows
119
118
  });
120
119
  }
121
120
  else if (columns?.every(col => typeof col === 'number')) {
122
121
  return new dataframe_domain_1.DataFrameDomain({
123
- colnames: value.colnames.top(),
122
+ colnames: value.colnames.widenUp(),
124
123
  cols: columns.reduce((current, col) => current.max([col, col]), value.cols),
125
124
  rows: value.rows
126
125
  });
127
126
  }
128
127
  return new dataframe_domain_1.DataFrameDomain({
129
- colnames: value.colnames.top(),
130
- cols: value.cols.extendUp(),
128
+ colnames: value.colnames.widenUp(),
129
+ cols: value.cols.widenUp(),
131
130
  rows: value.rows
132
131
  });
133
132
  }
@@ -142,28 +141,28 @@ function applyAssignRowsSemantics(value, { rows }) {
142
141
  return new dataframe_domain_1.DataFrameDomain({
143
142
  colnames: value.colnames,
144
143
  cols: value.cols,
145
- rows: value.rows.extendUp()
144
+ rows: value.rows.widenUp()
146
145
  });
147
146
  }
148
147
  function applySetColNamesSemantics(value, { colnames }, options) {
149
148
  if (options?.partial) {
150
149
  return new dataframe_domain_1.DataFrameDomain({
151
- colnames: colnames?.every(assert_1.isNotUndefined) ? value.colnames.join(colnames) : value.colnames.top(),
150
+ colnames: value.colnames.widenDown().union(setRange(colnames)),
152
151
  cols: value.cols,
153
152
  rows: value.rows
154
153
  });
155
154
  }
156
155
  const allColNames = colnames?.every(assert_1.isNotUndefined) && value.cols.value !== lattice_1.Bottom && colnames.length >= value.cols.value[1];
157
156
  return new dataframe_domain_1.DataFrameDomain({
158
- colnames: allColNames ? value.colnames.create(colnames) : value.colnames.top(),
157
+ colnames: allColNames ? value.colnames.create(setRange(colnames)) : value.colnames.create(setRange(colnames)).widenUp(),
159
158
  cols: value.cols,
160
159
  rows: value.rows
161
160
  });
162
161
  }
163
162
  function applyAddColsSemantics(value, { colnames }) {
164
163
  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(),
164
+ colnames: colnames !== undefined ? value.colnames.union(setRange(colnames)) : value.colnames.widenUp(),
165
+ cols: colnames !== undefined ? value.cols.add([colnames.length, colnames.length]) : value.cols.widenUp(),
167
166
  rows: value.rows
168
167
  });
169
168
  }
@@ -173,26 +172,26 @@ function applyAddRowsSemantics(value, { rows }) {
173
172
  ...value,
174
173
  colnames: value.colnames.top(),
175
174
  cols: rows !== undefined ? value.cols.add([1, 1]) : value.cols.top(),
176
- rows: rows !== undefined ? value.rows.add([rows, rows]) : value.rows.extendUp()
175
+ rows: rows !== undefined ? value.rows.add([rows, rows]) : value.rows.widenUp()
177
176
  });
178
177
  }
179
178
  return new dataframe_domain_1.DataFrameDomain({
180
179
  colnames: value.colnames,
181
180
  cols: value.cols,
182
- rows: rows !== undefined ? value.rows.add([rows, rows]) : value.rows.extendUp()
181
+ rows: rows !== undefined ? value.rows.add([rows, rows]) : value.rows.widenUp()
183
182
  });
184
183
  }
185
184
  function applyRemoveColsSemantics(value, { colnames }, options) {
186
185
  if (options?.maybe) {
187
186
  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(),
187
+ colnames: colnames !== undefined ? value.colnames.subtract(setRange(colnames)) : value.colnames.widenDown(),
188
+ cols: colnames !== undefined ? value.cols.subtract([colnames.length, 0]) : value.cols.widenDown(),
190
189
  rows: value.rows
191
190
  });
192
191
  }
193
192
  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(),
193
+ colnames: colnames !== undefined ? value.colnames.subtract(setRange(colnames)) : value.colnames.widenDown(),
194
+ cols: colnames !== undefined ? value.cols.subtract([colnames.length, colnames.length]) : value.cols.widenDown(),
196
195
  rows: value.rows
197
196
  });
198
197
  }
@@ -201,18 +200,18 @@ function applyRemoveRowsSemantics(value, { rows }, options) {
201
200
  return new dataframe_domain_1.DataFrameDomain({
202
201
  colnames: value.colnames,
203
202
  cols: value.cols,
204
- rows: rows !== undefined ? value.rows.subtract([rows, 0]) : value.rows.extendDown()
203
+ rows: rows !== undefined ? value.rows.subtract([rows, 0]) : value.rows.widenDown()
205
204
  });
206
205
  }
207
206
  return new dataframe_domain_1.DataFrameDomain({
208
207
  colnames: value.colnames,
209
208
  cols: value.cols,
210
- rows: rows !== undefined ? value.rows.subtract([rows, rows]) : value.rows.extendDown()
209
+ rows: rows !== undefined ? value.rows.subtract([rows, rows]) : value.rows.widenDown()
211
210
  });
212
211
  }
213
212
  function applyConcatColsSemantics(value, { other }) {
214
213
  return new dataframe_domain_1.DataFrameDomain({
215
- colnames: value.colnames.join(other.colnames),
214
+ colnames: value.colnames.union(other.colnames),
216
215
  cols: value.cols.add(other.cols),
217
216
  rows: value.rows
218
217
  });
@@ -243,13 +242,13 @@ function applySubsetColsSemantics(value, { colnames }, options) {
243
242
  else if (options?.renamedCols) {
244
243
  return new dataframe_domain_1.DataFrameDomain({
245
244
  colnames: value.colnames.top(),
246
- cols: colnames !== undefined ? value.cols.min([colnames.length, colnames.length]) : value.cols.extendDown(),
245
+ cols: colnames !== undefined ? value.cols.min([colnames.length, colnames.length]) : value.cols.widenDown(),
247
246
  rows: value.rows
248
247
  });
249
248
  }
250
249
  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(),
250
+ colnames: colnames !== undefined ? value.colnames.intersect(setRange(colnames)) : value.colnames.widenDown(),
251
+ cols: colnames !== undefined ? value.cols.min([colnames.length, colnames.length]) : value.cols.widenDown(),
253
252
  rows: value.rows
254
253
  });
255
254
  }
@@ -264,27 +263,27 @@ function applySubsetRowsSemantics(value, { rows }, options) {
264
263
  return new dataframe_domain_1.DataFrameDomain({
265
264
  colnames: value.colnames,
266
265
  cols: value.cols,
267
- rows: rows !== undefined ? value.rows.min([rows, rows]) : value.rows.extendDown()
266
+ rows: rows !== undefined ? value.rows.min([rows, rows]) : value.rows.widenDown()
268
267
  });
269
268
  }
270
269
  function applyFilterRowsSemantics(value, { condition }) {
271
270
  return new dataframe_domain_1.DataFrameDomain({
272
271
  colnames: value.colnames,
273
272
  cols: value.cols,
274
- rows: condition ? value.rows : condition === false ? value.rows.create([0, 0]) : value.rows.extendDown()
273
+ rows: condition ? value.rows : condition === false ? value.rows.create([0, 0]) : value.rows.widenDown()
275
274
  });
276
275
  }
277
276
  function applyMutateColsSemantics(value, { colnames }) {
278
277
  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(),
278
+ colnames: colnames !== undefined ? value.colnames.union(setRange(colnames)) : value.colnames.widenUp(),
279
+ cols: colnames !== undefined ? value.cols.add([0, colnames.length]).max([colnames.length, colnames.length]) : value.cols.widenUp(),
281
280
  rows: value.rows
282
281
  });
283
282
  }
284
283
  function applyGroupBySemantics(value, { by }, options) {
285
284
  if (options?.mutatedCols) {
286
285
  return new dataframe_domain_1.DataFrameDomain({
287
- colnames: by.every(assert_1.isNotUndefined) ? value.colnames.join(by) : value.colnames.top(),
286
+ colnames: value.colnames.union(setRange(by)),
288
287
  cols: value.cols.add([0, by.length]),
289
288
  rows: value.rows
290
289
  });
@@ -294,8 +293,8 @@ function applyGroupBySemantics(value, { by }, options) {
294
293
  }
295
294
  function applySummarizeSemantics(value, { colnames }) {
296
295
  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(),
296
+ colnames: colnames !== undefined ? value.colnames.join(setRange([])).union(setRange(colnames)) : value.colnames.widenUp(),
297
+ cols: colnames !== undefined ? value.cols.add([0, colnames.length]).min([colnames.length, +Infinity]) : value.cols.widenUp(),
299
298
  rows: value.rows.min([1, +Infinity]).max([0, 1])
300
299
  });
301
300
  }
@@ -318,35 +317,36 @@ function applyJoinSemantics(value, { other, by }, options) {
318
317
  return new positive_interval_domain_1.PosIntervalDomain([lower.value[0], interval1.value[1] * interval2.value[1]]);
319
318
  }
320
319
  };
321
- const commonCols = value.colnames.meet(other.colnames);
322
- let duplicateCols; // whether columns may be renamed due to occurrence in both data frames
320
+ let duplicateCols; // columns that may be renamed due to occurring in both data frames
323
321
  let productRows; // whether the resulting rows may be a Cartesian product of the rows of the data frames
324
322
  if (options?.natural) {
325
- duplicateCols = false;
326
- productRows = commonCols.isValue() && commonCols.value.size === 0;
323
+ const commonCols = value.colnames.intersect(other.colnames).upper();
324
+ duplicateCols = [];
325
+ productRows = commonCols !== lattice_1.Bottom && commonCols !== lattice_1.Top && commonCols.size === 0;
327
326
  }
328
327
  else if (by === undefined) {
329
- duplicateCols = true;
328
+ duplicateCols = undefined;
330
329
  productRows = true;
331
330
  }
332
331
  else if (by.length === 0) {
333
- duplicateCols = commonCols.isTop() || (commonCols.isValue() && commonCols.value.size > 0);
332
+ const commonCols = value.colnames.intersect(other.colnames).upper();
333
+ duplicateCols = commonCols !== lattice_1.Bottom ? commonCols !== lattice_1.Top ? [...commonCols] : undefined : [];
334
334
  productRows = true;
335
335
  }
336
336
  else if (by.every(assert_1.isNotUndefined)) {
337
- const remainingCols = commonCols.subtract(by);
338
- duplicateCols = remainingCols.isTop() || (remainingCols.isValue() && remainingCols.value.size > 0);
337
+ const remainingCols = value.colnames.intersect(other.colnames).subtract(setRange(by)).upper();
338
+ duplicateCols = remainingCols !== lattice_1.Bottom ? remainingCols !== lattice_1.Top ? [...remainingCols] : undefined : [];
339
339
  productRows = false;
340
340
  }
341
341
  else {
342
- duplicateCols = true;
342
+ duplicateCols = undefined;
343
343
  productRows = false;
344
344
  }
345
345
  const joinType = options?.join ?? 'inner';
346
346
  let rows;
347
347
  switch (joinType) {
348
348
  case 'inner':
349
- rows = value.rows.min(other.rows).extendDown();
349
+ rows = value.rows.min(other.rows).widenDown();
350
350
  break;
351
351
  case 'left':
352
352
  rows = value.rows;
@@ -362,7 +362,7 @@ function applyJoinSemantics(value, { other, by }, options) {
362
362
  }
363
363
  return new dataframe_domain_1.DataFrameDomain({
364
364
  ...value,
365
- colnames: duplicateCols ? value.colnames.top() : value.colnames.join(other.colnames),
365
+ colnames: duplicateCols === undefined ? value.colnames.top() : duplicateCols.length > 0 ? value.colnames.union(other.colnames).subtract(setRange(duplicateCols)).widenUp() : value.colnames.union(other.colnames),
366
366
  cols: by !== undefined ? value.cols.add(other.cols).subtract([by.length, by.length]) : mergeInterval(value.cols, other.cols),
367
367
  rows: productRows ? productInterval(rows, value.rows, other.rows) : rows
368
368
  });
@@ -377,4 +377,8 @@ function applyUnknownSemantics(value,
377
377
  _args) {
378
378
  return value.top();
379
379
  }
380
+ function setRange(colnames) {
381
+ const names = colnames?.filter(assert_1.isNotUndefined) ?? [];
382
+ return { min: names, range: names.length === colnames?.length ? [] : lattice_1.Top };
383
+ }
380
384
  //# sourceMappingURL=semantics.js.map
@@ -1,35 +1,59 @@
1
- import { type ControlFlowInformation } from '../../control-flow/control-flow-graph';
2
- import type { DataflowGraph } from '../../dataflow/graph/graph';
3
- import type { RNode } from '../../r-bridge/lang-4.x/ast/model/model';
4
- import type { NormalizedAst, ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
1
+ import type { DataflowGraphVertexFunctionCall } from '../../dataflow/graph/vertex';
2
+ import type { NoInfo } from '../../r-bridge/lang-4.x/ast/model/model';
5
3
  import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
6
- import { type AbstractInterpretationInfo } from './absint-info';
7
- import { type DataFrameDomain, DataFrameStateDomain } from './dataframe-domain';
8
- import type { ReadOnlyFlowrAnalyzerContext } from '../../project/context/flowr-analyzer-context';
4
+ import { AbstractInterpretationVisitor, type AbsintVisitorConfiguration } from '../absint-visitor';
5
+ import { DataFrameDomain, DataFrameStateDomain } from './dataframe-domain';
6
+ import { ConstraintType, type DataFrameOperationArgs, type DataFrameOperationName, type DataFrameOperationOptions } from './semantics';
7
+ interface Operation<Name extends DataFrameOperationName> {
8
+ /** The type of the abstract data frame operation (see {@link DataFrameOperationName}) */
9
+ operation: Name;
10
+ /** The ID of the data frame operand of the operation (may be `undefined`) */
11
+ operand: NodeId | undefined;
12
+ /** The optional constraint type to overwrite the default type of the operation (see {@link ConstraintType}) */
13
+ type?: ConstraintType;
14
+ /** The optional additional options for the abstract operation (see {@link DataFrameOperationOptions}) */
15
+ options?: DataFrameOperationOptions<Name>;
16
+ }
9
17
  /**
10
- * Infers the shape of data frames by performing abstract interpretation using the control flow graph of a program.
11
- * This directly attaches the inferred data frames shapes to the AST (see {@link AbstractInterpretationInfo}).
12
- * @param cfinfo - The control flow information containing the control flow graph
13
- * @param dfg - The data flow graph to resolve variable origins and function arguments
14
- * @param ast - The abstract syntax tree to resolve node IDs to AST nodes
15
- * @param ctx - The current flowr analyzer context
16
- * @returns The abstract data frame state at the exit node of the control flow graph (see {@link DataFrameStateDomain}).
17
- * The abstract data frame states for all other nodes are attached to the AST.
18
+ * An abstract data frame operation.
18
19
  */
19
- export declare function inferDataFrameShapes(cfinfo: ControlFlowInformation, dfg: DataflowGraph, ast: NormalizedAst<ParentInformation & AbstractInterpretationInfo>, ctx: ReadOnlyFlowrAnalyzerContext): DataFrameStateDomain;
20
+ export type DataFrameOperation<OperationName extends DataFrameOperationName = DataFrameOperationName> = {
21
+ [Name in OperationName]: Operation<Name> & DataFrameOperationArgs<Name>;
22
+ }[OperationName];
20
23
  /**
21
- * Resolves the abstract data frame shape of a node in the AST.
22
- * This requires that the data frame shape inference has been executed before using {@link inferDataFrameShapes}.
23
- * @param id - The node or node ID to get the data frame shape for
24
- * @param dfg - The data flow graph used to resolve the data frame shape
25
- * @param domain - An optional abstract data frame state domain used to resolve the data frame shape (defaults to the state at the requested node)
26
- * @returns The abstract data frame shape of the node, or `undefined` if no data frame shape was inferred for the node
24
+ * An abstract data frame operation without additional options.
27
25
  */
28
- export declare function resolveIdToDataFrameShape(id: RNode<ParentInformation & AbstractInterpretationInfo> | NodeId | undefined, dfg: DataflowGraph | undefined, domain?: DataFrameStateDomain): DataFrameDomain | undefined;
26
+ export type DataFrameOperationType<OperationName extends DataFrameOperationName = DataFrameOperationName> = {
27
+ [Name in OperationName]: Omit<Operation<Name>, 'type' | 'options'> & DataFrameOperationArgs<Name>;
28
+ }[OperationName];
29
29
  /**
30
- * Gets all origins of a variable in the data flow graph that have already been visited.
31
- * @param node - The node to get the origins for
32
- * @param dfg - The data flow graph for resolving the origins
33
- * @returns The origins nodes of the variable
30
+ * A possible `undefined` array of abstract data frame operations (see {@link DataFrameOperation}).
34
31
  */
35
- export declare function getVariableOrigins(node: NodeId, dfg: DataflowGraph): RNode<ParentInformation & AbstractInterpretationInfo>[];
32
+ export type DataFrameOperations<OperationName extends DataFrameOperationName = DataFrameOperationName> = DataFrameOperation<OperationName>[] | undefined;
33
+ interface DataFrameShapeInferenceConfiguration extends Omit<AbsintVisitorConfiguration<DataFrameDomain>, 'domain'> {
34
+ readonly trackOperations?: boolean;
35
+ }
36
+ /**
37
+ * The control flow graph visitor to infer the shape of data frames using abstract interpretation
38
+ */
39
+ export declare class DataFrameShapeInferenceVisitor extends AbstractInterpretationVisitor<DataFrameDomain, NoInfo, DataFrameShapeInferenceConfiguration & {
40
+ domain: DataFrameStateDomain;
41
+ }> {
42
+ /**
43
+ * The abstract data frame operations the function call nodes are mapped to.
44
+ */
45
+ private readonly operations?;
46
+ constructor({ trackOperations, ...config }: DataFrameShapeInferenceConfiguration);
47
+ /**
48
+ * Gets the mapped abstract data frame operations for an AST node (this only includes direct function calls, replacement calls, or access operations).
49
+ * This requires that the abstract interpretation visitor has been completed, or at least started.
50
+ * @param id - The ID of the node to get the mapped abstract operations for
51
+ * @returns The mapped abstract data frame operations for the node, or `undefined` if no abstract operation was mapped for the node or storing mapped abstract operations is disabled via the visitor config.
52
+ */
53
+ getAbstractOperations(id: NodeId | undefined): Readonly<DataFrameOperations>;
54
+ protected evalFunctionCall(call: DataflowGraphVertexFunctionCall, state: DataFrameStateDomain): DataFrameStateDomain;
55
+ protected evalReplacementCall(call: DataflowGraphVertexFunctionCall, target: NodeId, source: NodeId, state: DataFrameStateDomain): DataFrameStateDomain;
56
+ protected evalAccessCall(call: DataflowGraphVertexFunctionCall, state: DataFrameStateDomain): DataFrameStateDomain;
57
+ private applyDataFrameExpression;
58
+ }
59
+ export {};
@@ -1,109 +1,86 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.inferDataFrameShapes = inferDataFrameShapes;
4
- exports.resolveIdToDataFrameShape = resolveIdToDataFrameShape;
5
- exports.getVariableOrigins = getVariableOrigins;
6
- const control_flow_graph_1 = require("../../control-flow/control-flow-graph");
7
- const vertex_1 = require("../../dataflow/graph/vertex");
8
- const dfg_get_origin_1 = require("../../dataflow/origin/dfg-get-origin");
9
- const r_function_call_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-call");
10
- const type_1 = require("../../r-bridge/lang-4.x/ast/model/type");
11
- const assert_1 = require("../../util/assert");
12
- const abstract_domain_1 = require("../domains/abstract-domain");
13
- const absint_info_1 = require("./absint-info");
14
- const absint_visitor_1 = require("./absint-visitor");
3
+ exports.DataFrameShapeInferenceVisitor = void 0;
4
+ const absint_visitor_1 = require("../absint-visitor");
15
5
  const dataframe_domain_1 = require("./dataframe-domain");
6
+ const access_mapper_1 = require("./mappers/access-mapper");
7
+ const function_mapper_1 = require("./mappers/function-mapper");
8
+ const replacement_mapper_1 = require("./mappers/replacement-mapper");
9
+ const semantics_1 = require("./semantics");
16
10
  /**
17
- * Infers the shape of data frames by performing abstract interpretation using the control flow graph of a program.
18
- * This directly attaches the inferred data frames shapes to the AST (see {@link AbstractInterpretationInfo}).
19
- * @param cfinfo - The control flow information containing the control flow graph
20
- * @param dfg - The data flow graph to resolve variable origins and function arguments
21
- * @param ast - The abstract syntax tree to resolve node IDs to AST nodes
22
- * @param ctx - The current flowr analyzer context
23
- * @returns The abstract data frame state at the exit node of the control flow graph (see {@link DataFrameStateDomain}).
24
- * The abstract data frame states for all other nodes are attached to the AST.
11
+ * The control flow graph visitor to infer the shape of data frames using abstract interpretation
25
12
  */
26
- function inferDataFrameShapes(cfinfo, dfg, ast, ctx) {
27
- const visitor = new absint_visitor_1.DataFrameShapeInferenceVisitor({ controlFlow: cfinfo, dfg: dfg, normalizedAst: ast, ctx });
28
- visitor.start();
29
- const exitPoints = cfinfo.exitPoints.map(id => cfinfo.graph.getVertex(id)).filter(assert_1.isNotUndefined);
30
- const exitNodes = exitPoints.map(vertex => ast.idMap.get((0, control_flow_graph_1.getVertexRootId)(vertex))).filter(assert_1.isNotUndefined);
31
- const domains = exitNodes.map(node => node.info.dataFrame?.domain).filter(assert_1.isNotUndefined);
32
- return dataframe_domain_1.DataFrameStateDomain.bottom().joinAll(domains);
33
- }
34
- /**
35
- * Resolves the abstract data frame shape of a node in the AST.
36
- * This requires that the data frame shape inference has been executed before using {@link inferDataFrameShapes}.
37
- * @param id - The node or node ID to get the data frame shape for
38
- * @param dfg - The data flow graph used to resolve the data frame shape
39
- * @param domain - An optional abstract data frame state domain used to resolve the data frame shape (defaults to the state at the requested node)
40
- * @returns The abstract data frame shape of the node, or `undefined` if no data frame shape was inferred for the node
41
- */
42
- function resolveIdToDataFrameShape(id, dfg, domain) {
43
- const node = id === undefined || typeof id === 'object' ? id : dfg?.idMap?.get(id);
44
- domain ??= node?.info.dataFrame?.domain;
45
- if (dfg === undefined || node === undefined || domain === undefined) {
46
- return;
13
+ class DataFrameShapeInferenceVisitor extends absint_visitor_1.AbstractInterpretationVisitor {
14
+ /**
15
+ * The abstract data frame operations the function call nodes are mapped to.
16
+ */
17
+ operations;
18
+ constructor({ trackOperations = true, ...config }) {
19
+ super({ ...config, domain: dataframe_domain_1.DataFrameStateDomain.bottom() });
20
+ if (trackOperations) {
21
+ this.operations = new Map();
22
+ }
47
23
  }
48
- else if (domain.has(node.info.id)) {
49
- return domain.get(node.info.id);
24
+ /**
25
+ * Gets the mapped abstract data frame operations for an AST node (this only includes direct function calls, replacement calls, or access operations).
26
+ * This requires that the abstract interpretation visitor has been completed, or at least started.
27
+ * @param id - The ID of the node to get the mapped abstract operations for
28
+ * @returns The mapped abstract data frame operations for the node, or `undefined` if no abstract operation was mapped for the node or storing mapped abstract operations is disabled via the visitor config.
29
+ */
30
+ getAbstractOperations(id) {
31
+ return id !== undefined ? this.operations?.get(id) : undefined;
50
32
  }
51
- const vertex = dfg.getVertex(node.info.id);
52
- const call = vertex?.tag === vertex_1.VertexType.FunctionCall ? vertex : undefined;
53
- const origins = Array.isArray(call?.origin) ? call.origin : [];
54
- if (node.type === type_1.RType.Symbol) {
55
- const values = getVariableOrigins(node.info.id, dfg).map(origin => domain.get(origin.info.id));
56
- if (values.length > 0 && values.every(assert_1.isNotUndefined)) {
57
- return abstract_domain_1.AbstractDomain.joinAll(values);
33
+ evalFunctionCall(call, state) {
34
+ const node = this.getNormalizedAst(call.id);
35
+ if (node === undefined) {
36
+ return state;
58
37
  }
38
+ const operations = (0, function_mapper_1.mapDataFrameFunctionCall)(node, this, this.config.dfg, this.config.ctx);
39
+ return this.applyDataFrameExpression(node, operations, state);
59
40
  }
60
- else if (node.type === type_1.RType.Argument && node.value !== undefined) {
61
- return resolveIdToDataFrameShape(node.value, dfg, domain);
62
- }
63
- else if (node.type === type_1.RType.ExpressionList && node.children.length > 0) {
64
- return resolveIdToDataFrameShape(node.children[node.children.length - 1], dfg, domain);
41
+ evalReplacementCall(call, target, source, state) {
42
+ const node = this.getNormalizedAst(call.id);
43
+ const targetNode = this.getNormalizedAst(target);
44
+ const sourceNode = this.getNormalizedAst(source);
45
+ if (node === undefined || targetNode === undefined || sourceNode === undefined) {
46
+ return state;
47
+ }
48
+ const operations = (0, replacement_mapper_1.mapDataFrameReplacementFunction)(node, sourceNode, this, this.config.dfg, this.config.ctx);
49
+ return this.applyDataFrameExpression(node, operations, state);
65
50
  }
66
- else if (node.type === type_1.RType.Pipe) {
67
- return resolveIdToDataFrameShape(node.rhs, dfg, domain);
51
+ evalAccessCall(call, state) {
52
+ const node = this.getNormalizedAst(call.id);
53
+ if (node === undefined) {
54
+ return state;
55
+ }
56
+ const operations = (0, access_mapper_1.mapDataFrameAccess)(node, this, this.config.dfg, this.config.ctx);
57
+ return this.applyDataFrameExpression(node, operations, state);
68
58
  }
69
- else if (origins.includes('builtin:pipe')) {
70
- if (node.type === type_1.RType.BinaryOp) {
71
- return resolveIdToDataFrameShape(node.rhs, dfg, domain);
59
+ applyDataFrameExpression(node, operations, state) {
60
+ if (operations === undefined) {
61
+ return state;
72
62
  }
73
- else if (call?.args.length === 2 && call?.args[1] !== r_function_call_1.EmptyArgument) {
74
- return resolveIdToDataFrameShape(call.args[1].nodeId, dfg, domain);
63
+ else if (this.operations !== undefined) {
64
+ this.operations.set(node.info.id, operations);
75
65
  }
76
- }
77
- else if (node.type === type_1.RType.IfThenElse) {
78
- if (node.otherwise !== undefined) {
79
- const values = [node.then, node.otherwise].map(entry => resolveIdToDataFrameShape(entry, dfg, domain));
80
- if (values.length > 0 && values.every(assert_1.isNotUndefined)) {
81
- return abstract_domain_1.AbstractDomain.joinAll(values);
66
+ const maxColNames = this.config.ctx.config.abstractInterpretation.dataFrame.maxColNames;
67
+ let value = dataframe_domain_1.DataFrameDomain.top(maxColNames);
68
+ for (const { operation, operand, type, options, ...args } of operations) {
69
+ const operandValue = operand !== undefined ? this.getAbstractValue(operand, state) : value;
70
+ value = (0, semantics_1.applyDataFrameSemantics)(operation, operandValue ?? dataframe_domain_1.DataFrameDomain.top(maxColNames), args, options);
71
+ const constraintType = type ?? (0, semantics_1.getConstraintType)(operation);
72
+ if (operand !== undefined && constraintType === semantics_1.ConstraintType.OperandModification) {
73
+ state.set(operand, value);
74
+ for (const origin of this.getVariableOrigins(operand)) {
75
+ state.set(origin, value);
76
+ }
82
77
  }
83
- }
84
- }
85
- else if (origins.includes('builtin:if-then-else') && call?.args.every(arg => arg !== r_function_call_1.EmptyArgument)) {
86
- if (call.args.length === 3) {
87
- const values = call.args.slice(1, 3).map(entry => resolveIdToDataFrameShape(entry.nodeId, dfg, domain));
88
- if (values.length > 0 && values.every(assert_1.isNotUndefined)) {
89
- return abstract_domain_1.AbstractDomain.joinAll(values);
78
+ else if (constraintType === semantics_1.ConstraintType.ResultPostcondition) {
79
+ state.set(node.info.id, value);
90
80
  }
91
81
  }
82
+ return state;
92
83
  }
93
84
  }
94
- /**
95
- * Gets all origins of a variable in the data flow graph that have already been visited.
96
- * @param node - The node to get the origins for
97
- * @param dfg - The data flow graph for resolving the origins
98
- * @returns The origins nodes of the variable
99
- */
100
- function getVariableOrigins(node, dfg) {
101
- // get each variable origin that has already been visited and whose assignment has already been processed
102
- return (0, dfg_get_origin_1.getOriginInDfg)(dfg, node)
103
- ?.filter(origin => origin.type === 0 /* OriginType.ReadVariableOrigin */)
104
- .map(entry => dfg.idMap?.get(entry.id))
105
- .filter(assert_1.isNotUndefined)
106
- .filter(origin => origin.info.dataFrame?.domain !== undefined)
107
- .filter(origin => !(0, absint_info_1.hasDataFrameInfoMarker)(origin, absint_info_1.DataFrameInfoMarker.Unassigned)) ?? [];
108
- }
85
+ exports.DataFrameShapeInferenceVisitor = DataFrameShapeInferenceVisitor;
109
86
  //# sourceMappingURL=shape-inference.js.map
@@ -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
  }
@@ -34,10 +34,10 @@ export declare class BoundedSetDomain<T, Value extends BoundedSetLift<T> = Bound
34
34
  bottom(): this & BoundedSetDomain<T, BoundedSetBottom>;
35
35
  equals(other: this): boolean;
36
36
  leq(other: this): boolean;
37
- join(other: this): this;
38
37
  join(other: BoundedSetLift<T> | T[]): this;
39
- meet(other: this): this;
38
+ join(other: this): this;
40
39
  meet(other: BoundedSetLift<T> | T[]): this;
40
+ meet(other: this): this;
41
41
  /**
42
42
  * Subtracts another abstract value from the current abstract value by removing all elements of the other abstract value from the current abstract value.
43
43
  */
@@ -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}}`;
@@ -27,10 +27,10 @@ export declare class IntervalDomain<Value extends IntervalLift = IntervalLift> e
27
27
  bottom(): this & IntervalDomain<IntervalBottom>;
28
28
  equals(other: this): boolean;
29
29
  leq(other: this): boolean;
30
- join(other: this): this;
31
30
  join(other: IntervalLift): this;
32
- meet(other: this): this;
31
+ join(other: this): this;
33
32
  meet(other: IntervalLift): this;
33
+ meet(other: this): this;
34
34
  widen(other: this): this;
35
35
  narrow(other: this): this;
36
36
  concretize(limit: number): ReadonlySet<number> | typeof Top;
@@ -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>;