relationalai 0.13.5__py3-none-any.whl → 1.0.0a1__py3-none-any.whl

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 (856) hide show
  1. relationalai/__init__.py +1 -256
  2. relationalai/config/__init__.py +56 -0
  3. relationalai/config/config.py +289 -0
  4. relationalai/config/config_fields.py +86 -0
  5. relationalai/config/connections/__init__.py +46 -0
  6. relationalai/config/connections/base.py +23 -0
  7. relationalai/config/connections/duckdb.py +29 -0
  8. relationalai/config/connections/snowflake.py +243 -0
  9. relationalai/config/external/__init__.py +17 -0
  10. relationalai/config/external/dbt_converter.py +101 -0
  11. relationalai/config/external/dbt_models.py +93 -0
  12. relationalai/config/external/snowflake_converter.py +41 -0
  13. relationalai/config/external/snowflake_models.py +85 -0
  14. relationalai/config/external/utils.py +19 -0
  15. relationalai/config/shims.py +1 -0
  16. relationalai/semantics/__init__.py +146 -22
  17. relationalai/semantics/backends/lqp/annotations.py +11 -0
  18. relationalai/semantics/backends/sql/sql_compiler.py +327 -0
  19. relationalai/semantics/frontend/base.py +1716 -0
  20. relationalai/semantics/frontend/core.py +179 -0
  21. relationalai/semantics/frontend/front_compiler.py +1313 -0
  22. relationalai/semantics/frontend/pprint.py +408 -0
  23. relationalai/semantics/metamodel/__init__.py +6 -40
  24. relationalai/semantics/metamodel/builtins.py +205 -772
  25. relationalai/semantics/metamodel/metamodel.py +437 -0
  26. relationalai/semantics/metamodel/metamodel_analyzer.py +519 -0
  27. relationalai/semantics/metamodel/pprint.py +412 -0
  28. relationalai/semantics/metamodel/rewriter.py +266 -0
  29. relationalai/semantics/metamodel/typer.py +1186 -0
  30. relationalai/semantics/std/__init__.py +60 -40
  31. relationalai/semantics/std/aggregates.py +149 -0
  32. relationalai/semantics/std/common.py +44 -0
  33. relationalai/semantics/std/constraints.py +37 -43
  34. relationalai/semantics/std/datetime.py +246 -135
  35. relationalai/semantics/std/decimals.py +45 -52
  36. relationalai/semantics/std/floats.py +13 -5
  37. relationalai/semantics/std/integers.py +26 -11
  38. relationalai/semantics/std/math.py +183 -112
  39. relationalai/semantics/std/numbers.py +86 -0
  40. relationalai/semantics/std/re.py +80 -62
  41. relationalai/semantics/std/strings.py +101 -46
  42. relationalai/shims/executor.py +161 -0
  43. relationalai/shims/helpers.py +126 -0
  44. relationalai/shims/hoister.py +221 -0
  45. relationalai/shims/mm2v0.py +1324 -0
  46. relationalai/tools/cli/__init__.py +6 -0
  47. relationalai/tools/cli/cli.py +90 -0
  48. relationalai/tools/cli/components/__init__.py +5 -0
  49. relationalai/tools/cli/components/progress_reader.py +1524 -0
  50. relationalai/tools/cli/components/utils.py +58 -0
  51. relationalai/tools/cli/config_template.py +45 -0
  52. relationalai/tools/cli/dev.py +19 -0
  53. relationalai/tools/debugger.py +289 -183
  54. relationalai/tools/typer_debugger.py +93 -0
  55. relationalai/util/dataclasses.py +43 -0
  56. relationalai/util/docutils.py +40 -0
  57. relationalai/util/error.py +199 -0
  58. relationalai/util/format.py +48 -109
  59. relationalai/util/naming.py +145 -0
  60. relationalai/util/python.py +35 -0
  61. relationalai/util/runtime.py +156 -0
  62. relationalai/util/schema.py +197 -0
  63. relationalai/util/source.py +185 -0
  64. relationalai/util/structures.py +163 -0
  65. relationalai/util/tracing.py +261 -0
  66. relationalai-1.0.0a1.dist-info/METADATA +44 -0
  67. relationalai-1.0.0a1.dist-info/RECORD +489 -0
  68. relationalai-1.0.0a1.dist-info/WHEEL +5 -0
  69. relationalai-1.0.0a1.dist-info/entry_points.txt +3 -0
  70. relationalai-1.0.0a1.dist-info/top_level.txt +2 -0
  71. v0/relationalai/__init__.py +216 -0
  72. v0/relationalai/clients/__init__.py +5 -0
  73. v0/relationalai/clients/azure.py +477 -0
  74. v0/relationalai/clients/client.py +912 -0
  75. v0/relationalai/clients/config.py +673 -0
  76. v0/relationalai/clients/direct_access_client.py +118 -0
  77. v0/relationalai/clients/hash_util.py +31 -0
  78. v0/relationalai/clients/local.py +571 -0
  79. v0/relationalai/clients/profile_polling.py +73 -0
  80. v0/relationalai/clients/result_helpers.py +420 -0
  81. v0/relationalai/clients/snowflake.py +3869 -0
  82. v0/relationalai/clients/types.py +113 -0
  83. v0/relationalai/clients/use_index_poller.py +980 -0
  84. v0/relationalai/clients/util.py +356 -0
  85. v0/relationalai/debugging.py +389 -0
  86. v0/relationalai/dsl.py +1749 -0
  87. v0/relationalai/early_access/builder/__init__.py +30 -0
  88. v0/relationalai/early_access/builder/builder/__init__.py +35 -0
  89. v0/relationalai/early_access/builder/snowflake/__init__.py +12 -0
  90. v0/relationalai/early_access/builder/std/__init__.py +25 -0
  91. v0/relationalai/early_access/builder/std/decimals/__init__.py +12 -0
  92. v0/relationalai/early_access/builder/std/integers/__init__.py +12 -0
  93. v0/relationalai/early_access/builder/std/math/__init__.py +12 -0
  94. v0/relationalai/early_access/builder/std/strings/__init__.py +14 -0
  95. v0/relationalai/early_access/devtools/__init__.py +12 -0
  96. v0/relationalai/early_access/devtools/benchmark_lqp/__init__.py +12 -0
  97. v0/relationalai/early_access/devtools/extract_lqp/__init__.py +12 -0
  98. v0/relationalai/early_access/dsl/adapters/orm/adapter_qb.py +427 -0
  99. v0/relationalai/early_access/dsl/adapters/orm/parser.py +636 -0
  100. v0/relationalai/early_access/dsl/adapters/owl/adapter.py +176 -0
  101. v0/relationalai/early_access/dsl/adapters/owl/parser.py +160 -0
  102. v0/relationalai/early_access/dsl/bindings/common.py +402 -0
  103. v0/relationalai/early_access/dsl/bindings/csv.py +170 -0
  104. v0/relationalai/early_access/dsl/bindings/legacy/binding_models.py +143 -0
  105. v0/relationalai/early_access/dsl/bindings/snowflake.py +64 -0
  106. v0/relationalai/early_access/dsl/codegen/binder.py +411 -0
  107. v0/relationalai/early_access/dsl/codegen/common.py +79 -0
  108. v0/relationalai/early_access/dsl/codegen/helpers.py +23 -0
  109. v0/relationalai/early_access/dsl/codegen/relations.py +700 -0
  110. v0/relationalai/early_access/dsl/codegen/weaver.py +417 -0
  111. v0/relationalai/early_access/dsl/core/builders/__init__.py +47 -0
  112. v0/relationalai/early_access/dsl/core/builders/logic.py +19 -0
  113. v0/relationalai/early_access/dsl/core/builders/scalar_constraint.py +11 -0
  114. v0/relationalai/early_access/dsl/core/constraints/predicate/atomic.py +455 -0
  115. v0/relationalai/early_access/dsl/core/constraints/predicate/universal.py +73 -0
  116. v0/relationalai/early_access/dsl/core/constraints/scalar.py +310 -0
  117. v0/relationalai/early_access/dsl/core/context.py +13 -0
  118. v0/relationalai/early_access/dsl/core/cset.py +132 -0
  119. v0/relationalai/early_access/dsl/core/exprs/__init__.py +116 -0
  120. v0/relationalai/early_access/dsl/core/exprs/relational.py +18 -0
  121. v0/relationalai/early_access/dsl/core/exprs/scalar.py +412 -0
  122. v0/relationalai/early_access/dsl/core/instances.py +44 -0
  123. v0/relationalai/early_access/dsl/core/logic/__init__.py +193 -0
  124. v0/relationalai/early_access/dsl/core/logic/aggregation.py +98 -0
  125. v0/relationalai/early_access/dsl/core/logic/exists.py +223 -0
  126. v0/relationalai/early_access/dsl/core/logic/helper.py +163 -0
  127. v0/relationalai/early_access/dsl/core/namespaces.py +32 -0
  128. v0/relationalai/early_access/dsl/core/relations.py +276 -0
  129. v0/relationalai/early_access/dsl/core/rules.py +112 -0
  130. v0/relationalai/early_access/dsl/core/std/__init__.py +45 -0
  131. v0/relationalai/early_access/dsl/core/temporal/recall.py +6 -0
  132. v0/relationalai/early_access/dsl/core/types/__init__.py +270 -0
  133. v0/relationalai/early_access/dsl/core/types/concepts.py +128 -0
  134. v0/relationalai/early_access/dsl/core/types/constrained/__init__.py +267 -0
  135. v0/relationalai/early_access/dsl/core/types/constrained/nominal.py +143 -0
  136. v0/relationalai/early_access/dsl/core/types/constrained/subtype.py +124 -0
  137. v0/relationalai/early_access/dsl/core/types/standard.py +92 -0
  138. v0/relationalai/early_access/dsl/core/types/unconstrained.py +50 -0
  139. v0/relationalai/early_access/dsl/core/types/variables.py +203 -0
  140. v0/relationalai/early_access/dsl/ir/compiler.py +318 -0
  141. v0/relationalai/early_access/dsl/ir/executor.py +260 -0
  142. v0/relationalai/early_access/dsl/ontologies/constraints.py +88 -0
  143. v0/relationalai/early_access/dsl/ontologies/export.py +30 -0
  144. v0/relationalai/early_access/dsl/ontologies/models.py +453 -0
  145. v0/relationalai/early_access/dsl/ontologies/python_printer.py +303 -0
  146. v0/relationalai/early_access/dsl/ontologies/readings.py +60 -0
  147. v0/relationalai/early_access/dsl/ontologies/relationships.py +322 -0
  148. v0/relationalai/early_access/dsl/ontologies/roles.py +87 -0
  149. v0/relationalai/early_access/dsl/ontologies/subtyping.py +55 -0
  150. v0/relationalai/early_access/dsl/orm/constraints.py +438 -0
  151. v0/relationalai/early_access/dsl/orm/measures/dimensions.py +200 -0
  152. v0/relationalai/early_access/dsl/orm/measures/initializer.py +16 -0
  153. v0/relationalai/early_access/dsl/orm/measures/measure_rules.py +275 -0
  154. v0/relationalai/early_access/dsl/orm/measures/measures.py +299 -0
  155. v0/relationalai/early_access/dsl/orm/measures/role_exprs.py +268 -0
  156. v0/relationalai/early_access/dsl/orm/models.py +256 -0
  157. v0/relationalai/early_access/dsl/orm/object_oriented_printer.py +344 -0
  158. v0/relationalai/early_access/dsl/orm/printer.py +469 -0
  159. v0/relationalai/early_access/dsl/orm/reasoners.py +480 -0
  160. v0/relationalai/early_access/dsl/orm/relations.py +19 -0
  161. v0/relationalai/early_access/dsl/orm/relationships.py +251 -0
  162. v0/relationalai/early_access/dsl/orm/types.py +42 -0
  163. v0/relationalai/early_access/dsl/orm/utils.py +79 -0
  164. v0/relationalai/early_access/dsl/orm/verb.py +204 -0
  165. v0/relationalai/early_access/dsl/physical_metadata/tables.py +133 -0
  166. v0/relationalai/early_access/dsl/relations.py +170 -0
  167. v0/relationalai/early_access/dsl/rulesets.py +69 -0
  168. v0/relationalai/early_access/dsl/schemas/__init__.py +450 -0
  169. v0/relationalai/early_access/dsl/schemas/builder.py +48 -0
  170. v0/relationalai/early_access/dsl/schemas/comp_names.py +51 -0
  171. v0/relationalai/early_access/dsl/schemas/components.py +203 -0
  172. v0/relationalai/early_access/dsl/schemas/contexts.py +156 -0
  173. v0/relationalai/early_access/dsl/schemas/exprs.py +89 -0
  174. v0/relationalai/early_access/dsl/schemas/fragments.py +464 -0
  175. v0/relationalai/early_access/dsl/serialization.py +79 -0
  176. v0/relationalai/early_access/dsl/serialize/exporter.py +163 -0
  177. v0/relationalai/early_access/dsl/snow/api.py +104 -0
  178. v0/relationalai/early_access/dsl/snow/common.py +76 -0
  179. v0/relationalai/early_access/dsl/state_mgmt/__init__.py +129 -0
  180. v0/relationalai/early_access/dsl/state_mgmt/state_charts.py +125 -0
  181. v0/relationalai/early_access/dsl/state_mgmt/transitions.py +130 -0
  182. v0/relationalai/early_access/dsl/types/__init__.py +40 -0
  183. v0/relationalai/early_access/dsl/types/concepts.py +12 -0
  184. v0/relationalai/early_access/dsl/types/entities.py +135 -0
  185. v0/relationalai/early_access/dsl/types/values.py +17 -0
  186. v0/relationalai/early_access/dsl/utils.py +102 -0
  187. v0/relationalai/early_access/graphs/__init__.py +13 -0
  188. v0/relationalai/early_access/lqp/__init__.py +12 -0
  189. v0/relationalai/early_access/lqp/compiler/__init__.py +12 -0
  190. v0/relationalai/early_access/lqp/constructors/__init__.py +18 -0
  191. v0/relationalai/early_access/lqp/executor/__init__.py +12 -0
  192. v0/relationalai/early_access/lqp/ir/__init__.py +12 -0
  193. v0/relationalai/early_access/lqp/passes/__init__.py +12 -0
  194. v0/relationalai/early_access/lqp/pragmas/__init__.py +12 -0
  195. v0/relationalai/early_access/lqp/primitives/__init__.py +12 -0
  196. v0/relationalai/early_access/lqp/types/__init__.py +12 -0
  197. v0/relationalai/early_access/lqp/utils/__init__.py +12 -0
  198. v0/relationalai/early_access/lqp/validators/__init__.py +12 -0
  199. v0/relationalai/early_access/metamodel/__init__.py +58 -0
  200. v0/relationalai/early_access/metamodel/builtins/__init__.py +12 -0
  201. v0/relationalai/early_access/metamodel/compiler/__init__.py +12 -0
  202. v0/relationalai/early_access/metamodel/dependency/__init__.py +12 -0
  203. v0/relationalai/early_access/metamodel/factory/__init__.py +17 -0
  204. v0/relationalai/early_access/metamodel/helpers/__init__.py +12 -0
  205. v0/relationalai/early_access/metamodel/ir/__init__.py +14 -0
  206. v0/relationalai/early_access/metamodel/rewrite/__init__.py +7 -0
  207. v0/relationalai/early_access/metamodel/typer/__init__.py +3 -0
  208. v0/relationalai/early_access/metamodel/typer/typer/__init__.py +12 -0
  209. v0/relationalai/early_access/metamodel/types/__init__.py +15 -0
  210. v0/relationalai/early_access/metamodel/util/__init__.py +15 -0
  211. v0/relationalai/early_access/metamodel/visitor/__init__.py +12 -0
  212. v0/relationalai/early_access/rel/__init__.py +12 -0
  213. v0/relationalai/early_access/rel/executor/__init__.py +12 -0
  214. v0/relationalai/early_access/rel/rel_utils/__init__.py +12 -0
  215. v0/relationalai/early_access/rel/rewrite/__init__.py +7 -0
  216. v0/relationalai/early_access/solvers/__init__.py +19 -0
  217. v0/relationalai/early_access/sql/__init__.py +11 -0
  218. v0/relationalai/early_access/sql/executor/__init__.py +3 -0
  219. v0/relationalai/early_access/sql/rewrite/__init__.py +3 -0
  220. v0/relationalai/early_access/tests/logging/__init__.py +12 -0
  221. v0/relationalai/early_access/tests/test_snapshot_base/__init__.py +12 -0
  222. v0/relationalai/early_access/tests/utils/__init__.py +12 -0
  223. v0/relationalai/environments/__init__.py +35 -0
  224. v0/relationalai/environments/base.py +381 -0
  225. v0/relationalai/environments/colab.py +14 -0
  226. v0/relationalai/environments/generic.py +71 -0
  227. v0/relationalai/environments/ipython.py +68 -0
  228. v0/relationalai/environments/jupyter.py +9 -0
  229. v0/relationalai/environments/snowbook.py +169 -0
  230. v0/relationalai/errors.py +2455 -0
  231. v0/relationalai/experimental/SF.py +38 -0
  232. v0/relationalai/experimental/inspect.py +47 -0
  233. v0/relationalai/experimental/pathfinder/__init__.py +158 -0
  234. v0/relationalai/experimental/pathfinder/api.py +160 -0
  235. v0/relationalai/experimental/pathfinder/automaton.py +584 -0
  236. v0/relationalai/experimental/pathfinder/bridge.py +226 -0
  237. v0/relationalai/experimental/pathfinder/compiler.py +416 -0
  238. v0/relationalai/experimental/pathfinder/datalog.py +214 -0
  239. v0/relationalai/experimental/pathfinder/diagnostics.py +56 -0
  240. v0/relationalai/experimental/pathfinder/filter.py +236 -0
  241. v0/relationalai/experimental/pathfinder/glushkov.py +439 -0
  242. v0/relationalai/experimental/pathfinder/options.py +265 -0
  243. v0/relationalai/experimental/pathfinder/rpq.py +344 -0
  244. v0/relationalai/experimental/pathfinder/transition.py +200 -0
  245. v0/relationalai/experimental/pathfinder/utils.py +26 -0
  246. v0/relationalai/experimental/paths/api.py +143 -0
  247. v0/relationalai/experimental/paths/benchmarks/grid_graph.py +37 -0
  248. v0/relationalai/experimental/paths/examples/basic_example.py +40 -0
  249. v0/relationalai/experimental/paths/examples/minimal_engine_warmup.py +3 -0
  250. v0/relationalai/experimental/paths/examples/movie_example.py +77 -0
  251. v0/relationalai/experimental/paths/examples/paths_benchmark.py +115 -0
  252. v0/relationalai/experimental/paths/examples/paths_example.py +116 -0
  253. v0/relationalai/experimental/paths/examples/pattern_to_automaton.py +28 -0
  254. v0/relationalai/experimental/paths/find_paths_via_automaton.py +85 -0
  255. v0/relationalai/experimental/paths/graph.py +185 -0
  256. v0/relationalai/experimental/paths/path_algorithms/find_paths.py +280 -0
  257. v0/relationalai/experimental/paths/path_algorithms/one_sided_ball_repetition.py +26 -0
  258. v0/relationalai/experimental/paths/path_algorithms/one_sided_ball_upto.py +111 -0
  259. v0/relationalai/experimental/paths/path_algorithms/single.py +59 -0
  260. v0/relationalai/experimental/paths/path_algorithms/two_sided_balls_repetition.py +39 -0
  261. v0/relationalai/experimental/paths/path_algorithms/two_sided_balls_upto.py +103 -0
  262. v0/relationalai/experimental/paths/path_algorithms/usp-old.py +130 -0
  263. v0/relationalai/experimental/paths/path_algorithms/usp-tuple.py +183 -0
  264. v0/relationalai/experimental/paths/path_algorithms/usp.py +150 -0
  265. v0/relationalai/experimental/paths/product_graph.py +93 -0
  266. v0/relationalai/experimental/paths/rpq/automaton.py +584 -0
  267. v0/relationalai/experimental/paths/rpq/diagnostics.py +56 -0
  268. v0/relationalai/experimental/paths/rpq/rpq.py +378 -0
  269. v0/relationalai/experimental/paths/tests/tests_limit_sp_max_length.py +90 -0
  270. v0/relationalai/experimental/paths/tests/tests_limit_sp_multiple.py +119 -0
  271. v0/relationalai/experimental/paths/tests/tests_limit_sp_single.py +104 -0
  272. v0/relationalai/experimental/paths/tests/tests_limit_walks_multiple.py +113 -0
  273. v0/relationalai/experimental/paths/tests/tests_limit_walks_single.py +149 -0
  274. v0/relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_multiple.py +70 -0
  275. v0/relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_single.py +64 -0
  276. v0/relationalai/experimental/paths/tests/tests_one_sided_ball_upto_multiple.py +115 -0
  277. v0/relationalai/experimental/paths/tests/tests_one_sided_ball_upto_single.py +75 -0
  278. v0/relationalai/experimental/paths/tests/tests_single_paths.py +152 -0
  279. v0/relationalai/experimental/paths/tests/tests_single_walks.py +208 -0
  280. v0/relationalai/experimental/paths/tests/tests_single_walks_undirected.py +297 -0
  281. v0/relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_multiple.py +107 -0
  282. v0/relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_single.py +76 -0
  283. v0/relationalai/experimental/paths/tests/tests_two_sided_balls_upto_multiple.py +76 -0
  284. v0/relationalai/experimental/paths/tests/tests_two_sided_balls_upto_single.py +110 -0
  285. v0/relationalai/experimental/paths/tests/tests_usp_nsp_multiple.py +229 -0
  286. v0/relationalai/experimental/paths/tests/tests_usp_nsp_single.py +108 -0
  287. v0/relationalai/experimental/paths/tree_agg.py +168 -0
  288. v0/relationalai/experimental/paths/utilities/iterators.py +27 -0
  289. v0/relationalai/experimental/paths/utilities/prefix_sum.py +91 -0
  290. v0/relationalai/experimental/solvers.py +1087 -0
  291. v0/relationalai/loaders/csv.py +195 -0
  292. v0/relationalai/loaders/loader.py +177 -0
  293. v0/relationalai/loaders/types.py +23 -0
  294. v0/relationalai/rel_emitter.py +373 -0
  295. v0/relationalai/rel_utils.py +185 -0
  296. v0/relationalai/semantics/__init__.py +29 -0
  297. v0/relationalai/semantics/devtools/benchmark_lqp.py +536 -0
  298. v0/relationalai/semantics/devtools/compilation_manager.py +294 -0
  299. v0/relationalai/semantics/devtools/extract_lqp.py +110 -0
  300. v0/relationalai/semantics/internal/internal.py +3785 -0
  301. v0/relationalai/semantics/internal/snowflake.py +324 -0
  302. v0/relationalai/semantics/lqp/builtins.py +16 -0
  303. v0/relationalai/semantics/lqp/compiler.py +22 -0
  304. v0/relationalai/semantics/lqp/constructors.py +68 -0
  305. v0/relationalai/semantics/lqp/executor.py +469 -0
  306. v0/relationalai/semantics/lqp/intrinsics.py +24 -0
  307. v0/relationalai/semantics/lqp/ir.py +124 -0
  308. v0/relationalai/semantics/lqp/model2lqp.py +839 -0
  309. v0/relationalai/semantics/lqp/passes.py +680 -0
  310. v0/relationalai/semantics/lqp/primitives.py +252 -0
  311. v0/relationalai/semantics/lqp/result_helpers.py +202 -0
  312. v0/relationalai/semantics/lqp/rewrite/__init__.py +18 -0
  313. v0/relationalai/semantics/lqp/rewrite/annotate_constraints.py +57 -0
  314. v0/relationalai/semantics/lqp/rewrite/cdc.py +216 -0
  315. v0/relationalai/semantics/lqp/rewrite/extract_common.py +338 -0
  316. v0/relationalai/semantics/lqp/rewrite/extract_keys.py +449 -0
  317. v0/relationalai/semantics/lqp/rewrite/function_annotations.py +114 -0
  318. v0/relationalai/semantics/lqp/rewrite/functional_dependencies.py +314 -0
  319. v0/relationalai/semantics/lqp/rewrite/quantify_vars.py +296 -0
  320. v0/relationalai/semantics/lqp/rewrite/splinter.py +76 -0
  321. v0/relationalai/semantics/lqp/types.py +101 -0
  322. v0/relationalai/semantics/lqp/utils.py +160 -0
  323. v0/relationalai/semantics/lqp/validators.py +57 -0
  324. v0/relationalai/semantics/metamodel/__init__.py +40 -0
  325. v0/relationalai/semantics/metamodel/builtins.py +774 -0
  326. v0/relationalai/semantics/metamodel/compiler.py +133 -0
  327. v0/relationalai/semantics/metamodel/dependency.py +862 -0
  328. v0/relationalai/semantics/metamodel/executor.py +61 -0
  329. v0/relationalai/semantics/metamodel/factory.py +287 -0
  330. v0/relationalai/semantics/metamodel/helpers.py +361 -0
  331. v0/relationalai/semantics/metamodel/ir.py +923 -0
  332. v0/relationalai/semantics/metamodel/rewrite/__init__.py +7 -0
  333. v0/relationalai/semantics/metamodel/rewrite/discharge_constraints.py +39 -0
  334. v0/relationalai/semantics/metamodel/rewrite/dnf_union_splitter.py +210 -0
  335. v0/relationalai/semantics/metamodel/rewrite/extract_nested_logicals.py +78 -0
  336. v0/relationalai/semantics/metamodel/rewrite/flatten.py +549 -0
  337. v0/relationalai/semantics/metamodel/rewrite/format_outputs.py +165 -0
  338. v0/relationalai/semantics/metamodel/typer/checker.py +353 -0
  339. v0/relationalai/semantics/metamodel/typer/typer.py +1395 -0
  340. v0/relationalai/semantics/metamodel/util.py +505 -0
  341. v0/relationalai/semantics/metamodel/visitor.py +944 -0
  342. v0/relationalai/semantics/reasoners/__init__.py +10 -0
  343. v0/relationalai/semantics/reasoners/graph/__init__.py +37 -0
  344. v0/relationalai/semantics/reasoners/graph/core.py +9020 -0
  345. v0/relationalai/semantics/reasoners/optimization/__init__.py +68 -0
  346. v0/relationalai/semantics/reasoners/optimization/common.py +88 -0
  347. v0/relationalai/semantics/reasoners/optimization/solvers_dev.py +568 -0
  348. v0/relationalai/semantics/reasoners/optimization/solvers_pb.py +1163 -0
  349. v0/relationalai/semantics/rel/builtins.py +40 -0
  350. v0/relationalai/semantics/rel/compiler.py +989 -0
  351. v0/relationalai/semantics/rel/executor.py +359 -0
  352. v0/relationalai/semantics/rel/rel.py +482 -0
  353. v0/relationalai/semantics/rel/rel_utils.py +276 -0
  354. v0/relationalai/semantics/snowflake/__init__.py +3 -0
  355. v0/relationalai/semantics/sql/compiler.py +2503 -0
  356. v0/relationalai/semantics/sql/executor/duck_db.py +52 -0
  357. v0/relationalai/semantics/sql/executor/result_helpers.py +64 -0
  358. v0/relationalai/semantics/sql/executor/snowflake.py +145 -0
  359. v0/relationalai/semantics/sql/rewrite/denormalize.py +222 -0
  360. v0/relationalai/semantics/sql/rewrite/double_negation.py +49 -0
  361. v0/relationalai/semantics/sql/rewrite/recursive_union.py +127 -0
  362. v0/relationalai/semantics/sql/rewrite/sort_output_query.py +246 -0
  363. v0/relationalai/semantics/sql/sql.py +504 -0
  364. v0/relationalai/semantics/std/__init__.py +54 -0
  365. v0/relationalai/semantics/std/constraints.py +43 -0
  366. v0/relationalai/semantics/std/datetime.py +363 -0
  367. v0/relationalai/semantics/std/decimals.py +62 -0
  368. v0/relationalai/semantics/std/floats.py +7 -0
  369. v0/relationalai/semantics/std/integers.py +22 -0
  370. v0/relationalai/semantics/std/math.py +141 -0
  371. v0/relationalai/semantics/std/pragmas.py +11 -0
  372. v0/relationalai/semantics/std/re.py +83 -0
  373. v0/relationalai/semantics/std/std.py +14 -0
  374. v0/relationalai/semantics/std/strings.py +63 -0
  375. v0/relationalai/semantics/tests/__init__.py +0 -0
  376. v0/relationalai/semantics/tests/test_snapshot_abstract.py +143 -0
  377. v0/relationalai/semantics/tests/test_snapshot_base.py +9 -0
  378. v0/relationalai/semantics/tests/utils.py +46 -0
  379. v0/relationalai/std/__init__.py +70 -0
  380. v0/relationalai/tools/__init__.py +0 -0
  381. v0/relationalai/tools/cli.py +1940 -0
  382. v0/relationalai/tools/cli_controls.py +1826 -0
  383. v0/relationalai/tools/cli_helpers.py +390 -0
  384. v0/relationalai/tools/debugger.py +183 -0
  385. v0/relationalai/tools/debugger_client.py +109 -0
  386. v0/relationalai/tools/debugger_server.py +302 -0
  387. v0/relationalai/tools/dev.py +685 -0
  388. v0/relationalai/tools/qb_debugger.py +425 -0
  389. v0/relationalai/util/clean_up_databases.py +95 -0
  390. v0/relationalai/util/format.py +123 -0
  391. v0/relationalai/util/list_databases.py +9 -0
  392. v0/relationalai/util/otel_configuration.py +25 -0
  393. v0/relationalai/util/otel_handler.py +484 -0
  394. v0/relationalai/util/snowflake_handler.py +88 -0
  395. v0/relationalai/util/span_format_test.py +43 -0
  396. v0/relationalai/util/span_tracker.py +207 -0
  397. v0/relationalai/util/spans_file_handler.py +72 -0
  398. v0/relationalai/util/tracing_handler.py +34 -0
  399. frontend/debugger/dist/.gitignore +0 -2
  400. frontend/debugger/dist/assets/favicon-Dy0ZgA6N.png +0 -0
  401. frontend/debugger/dist/assets/index-Cssla-O7.js +0 -208
  402. frontend/debugger/dist/assets/index-DlHsYx1V.css +0 -9
  403. frontend/debugger/dist/index.html +0 -17
  404. relationalai/clients/__init__.py +0 -18
  405. relationalai/clients/client.py +0 -946
  406. relationalai/clients/config.py +0 -673
  407. relationalai/clients/direct_access_client.py +0 -118
  408. relationalai/clients/exec_txn_poller.py +0 -153
  409. relationalai/clients/hash_util.py +0 -31
  410. relationalai/clients/local.py +0 -594
  411. relationalai/clients/profile_polling.py +0 -73
  412. relationalai/clients/resources/__init__.py +0 -8
  413. relationalai/clients/resources/azure/azure.py +0 -502
  414. relationalai/clients/resources/snowflake/__init__.py +0 -20
  415. relationalai/clients/resources/snowflake/cli_resources.py +0 -98
  416. relationalai/clients/resources/snowflake/direct_access_resources.py +0 -739
  417. relationalai/clients/resources/snowflake/engine_service.py +0 -381
  418. relationalai/clients/resources/snowflake/engine_state_handlers.py +0 -315
  419. relationalai/clients/resources/snowflake/error_handlers.py +0 -240
  420. relationalai/clients/resources/snowflake/export_procedure.py.jinja +0 -249
  421. relationalai/clients/resources/snowflake/resources_factory.py +0 -99
  422. relationalai/clients/resources/snowflake/snowflake.py +0 -3193
  423. relationalai/clients/resources/snowflake/use_index_poller.py +0 -1019
  424. relationalai/clients/resources/snowflake/use_index_resources.py +0 -188
  425. relationalai/clients/resources/snowflake/util.py +0 -387
  426. relationalai/clients/result_helpers.py +0 -420
  427. relationalai/clients/types.py +0 -118
  428. relationalai/clients/util.py +0 -356
  429. relationalai/debugging.py +0 -389
  430. relationalai/dsl.py +0 -1749
  431. relationalai/early_access/builder/__init__.py +0 -30
  432. relationalai/early_access/builder/builder/__init__.py +0 -35
  433. relationalai/early_access/builder/snowflake/__init__.py +0 -12
  434. relationalai/early_access/builder/std/__init__.py +0 -25
  435. relationalai/early_access/builder/std/decimals/__init__.py +0 -12
  436. relationalai/early_access/builder/std/integers/__init__.py +0 -12
  437. relationalai/early_access/builder/std/math/__init__.py +0 -12
  438. relationalai/early_access/builder/std/strings/__init__.py +0 -14
  439. relationalai/early_access/devtools/__init__.py +0 -12
  440. relationalai/early_access/devtools/benchmark_lqp/__init__.py +0 -12
  441. relationalai/early_access/devtools/extract_lqp/__init__.py +0 -12
  442. relationalai/early_access/dsl/adapters/orm/adapter_qb.py +0 -427
  443. relationalai/early_access/dsl/adapters/orm/parser.py +0 -636
  444. relationalai/early_access/dsl/adapters/owl/adapter.py +0 -176
  445. relationalai/early_access/dsl/adapters/owl/parser.py +0 -160
  446. relationalai/early_access/dsl/bindings/common.py +0 -402
  447. relationalai/early_access/dsl/bindings/csv.py +0 -170
  448. relationalai/early_access/dsl/bindings/legacy/binding_models.py +0 -143
  449. relationalai/early_access/dsl/bindings/snowflake.py +0 -64
  450. relationalai/early_access/dsl/codegen/binder.py +0 -411
  451. relationalai/early_access/dsl/codegen/common.py +0 -79
  452. relationalai/early_access/dsl/codegen/helpers.py +0 -23
  453. relationalai/early_access/dsl/codegen/relations.py +0 -700
  454. relationalai/early_access/dsl/codegen/weaver.py +0 -417
  455. relationalai/early_access/dsl/core/builders/__init__.py +0 -47
  456. relationalai/early_access/dsl/core/builders/logic.py +0 -19
  457. relationalai/early_access/dsl/core/builders/scalar_constraint.py +0 -11
  458. relationalai/early_access/dsl/core/constraints/predicate/atomic.py +0 -455
  459. relationalai/early_access/dsl/core/constraints/predicate/universal.py +0 -73
  460. relationalai/early_access/dsl/core/constraints/scalar.py +0 -310
  461. relationalai/early_access/dsl/core/context.py +0 -13
  462. relationalai/early_access/dsl/core/cset.py +0 -132
  463. relationalai/early_access/dsl/core/exprs/__init__.py +0 -116
  464. relationalai/early_access/dsl/core/exprs/relational.py +0 -18
  465. relationalai/early_access/dsl/core/exprs/scalar.py +0 -412
  466. relationalai/early_access/dsl/core/instances.py +0 -44
  467. relationalai/early_access/dsl/core/logic/__init__.py +0 -193
  468. relationalai/early_access/dsl/core/logic/aggregation.py +0 -98
  469. relationalai/early_access/dsl/core/logic/exists.py +0 -223
  470. relationalai/early_access/dsl/core/logic/helper.py +0 -163
  471. relationalai/early_access/dsl/core/namespaces.py +0 -32
  472. relationalai/early_access/dsl/core/relations.py +0 -276
  473. relationalai/early_access/dsl/core/rules.py +0 -112
  474. relationalai/early_access/dsl/core/std/__init__.py +0 -45
  475. relationalai/early_access/dsl/core/temporal/recall.py +0 -6
  476. relationalai/early_access/dsl/core/types/__init__.py +0 -270
  477. relationalai/early_access/dsl/core/types/concepts.py +0 -128
  478. relationalai/early_access/dsl/core/types/constrained/__init__.py +0 -267
  479. relationalai/early_access/dsl/core/types/constrained/nominal.py +0 -143
  480. relationalai/early_access/dsl/core/types/constrained/subtype.py +0 -124
  481. relationalai/early_access/dsl/core/types/standard.py +0 -92
  482. relationalai/early_access/dsl/core/types/unconstrained.py +0 -50
  483. relationalai/early_access/dsl/core/types/variables.py +0 -203
  484. relationalai/early_access/dsl/ir/compiler.py +0 -318
  485. relationalai/early_access/dsl/ir/executor.py +0 -260
  486. relationalai/early_access/dsl/ontologies/constraints.py +0 -88
  487. relationalai/early_access/dsl/ontologies/export.py +0 -30
  488. relationalai/early_access/dsl/ontologies/models.py +0 -453
  489. relationalai/early_access/dsl/ontologies/python_printer.py +0 -303
  490. relationalai/early_access/dsl/ontologies/readings.py +0 -60
  491. relationalai/early_access/dsl/ontologies/relationships.py +0 -322
  492. relationalai/early_access/dsl/ontologies/roles.py +0 -87
  493. relationalai/early_access/dsl/ontologies/subtyping.py +0 -55
  494. relationalai/early_access/dsl/orm/constraints.py +0 -438
  495. relationalai/early_access/dsl/orm/measures/dimensions.py +0 -200
  496. relationalai/early_access/dsl/orm/measures/initializer.py +0 -16
  497. relationalai/early_access/dsl/orm/measures/measure_rules.py +0 -275
  498. relationalai/early_access/dsl/orm/measures/measures.py +0 -299
  499. relationalai/early_access/dsl/orm/measures/role_exprs.py +0 -268
  500. relationalai/early_access/dsl/orm/models.py +0 -256
  501. relationalai/early_access/dsl/orm/object_oriented_printer.py +0 -344
  502. relationalai/early_access/dsl/orm/printer.py +0 -469
  503. relationalai/early_access/dsl/orm/reasoners.py +0 -480
  504. relationalai/early_access/dsl/orm/relations.py +0 -19
  505. relationalai/early_access/dsl/orm/relationships.py +0 -251
  506. relationalai/early_access/dsl/orm/types.py +0 -42
  507. relationalai/early_access/dsl/orm/utils.py +0 -79
  508. relationalai/early_access/dsl/orm/verb.py +0 -204
  509. relationalai/early_access/dsl/physical_metadata/tables.py +0 -133
  510. relationalai/early_access/dsl/relations.py +0 -170
  511. relationalai/early_access/dsl/rulesets.py +0 -69
  512. relationalai/early_access/dsl/schemas/__init__.py +0 -450
  513. relationalai/early_access/dsl/schemas/builder.py +0 -48
  514. relationalai/early_access/dsl/schemas/comp_names.py +0 -51
  515. relationalai/early_access/dsl/schemas/components.py +0 -203
  516. relationalai/early_access/dsl/schemas/contexts.py +0 -156
  517. relationalai/early_access/dsl/schemas/exprs.py +0 -89
  518. relationalai/early_access/dsl/schemas/fragments.py +0 -464
  519. relationalai/early_access/dsl/serialization.py +0 -79
  520. relationalai/early_access/dsl/serialize/exporter.py +0 -163
  521. relationalai/early_access/dsl/snow/api.py +0 -105
  522. relationalai/early_access/dsl/snow/common.py +0 -76
  523. relationalai/early_access/dsl/state_mgmt/__init__.py +0 -129
  524. relationalai/early_access/dsl/state_mgmt/state_charts.py +0 -125
  525. relationalai/early_access/dsl/state_mgmt/transitions.py +0 -130
  526. relationalai/early_access/dsl/types/__init__.py +0 -40
  527. relationalai/early_access/dsl/types/concepts.py +0 -12
  528. relationalai/early_access/dsl/types/entities.py +0 -135
  529. relationalai/early_access/dsl/types/values.py +0 -17
  530. relationalai/early_access/dsl/utils.py +0 -102
  531. relationalai/early_access/graphs/__init__.py +0 -13
  532. relationalai/early_access/lqp/__init__.py +0 -12
  533. relationalai/early_access/lqp/compiler/__init__.py +0 -12
  534. relationalai/early_access/lqp/constructors/__init__.py +0 -18
  535. relationalai/early_access/lqp/executor/__init__.py +0 -12
  536. relationalai/early_access/lqp/ir/__init__.py +0 -12
  537. relationalai/early_access/lqp/passes/__init__.py +0 -12
  538. relationalai/early_access/lqp/pragmas/__init__.py +0 -12
  539. relationalai/early_access/lqp/primitives/__init__.py +0 -12
  540. relationalai/early_access/lqp/types/__init__.py +0 -12
  541. relationalai/early_access/lqp/utils/__init__.py +0 -12
  542. relationalai/early_access/lqp/validators/__init__.py +0 -12
  543. relationalai/early_access/metamodel/__init__.py +0 -58
  544. relationalai/early_access/metamodel/builtins/__init__.py +0 -12
  545. relationalai/early_access/metamodel/compiler/__init__.py +0 -12
  546. relationalai/early_access/metamodel/dependency/__init__.py +0 -12
  547. relationalai/early_access/metamodel/factory/__init__.py +0 -17
  548. relationalai/early_access/metamodel/helpers/__init__.py +0 -12
  549. relationalai/early_access/metamodel/ir/__init__.py +0 -14
  550. relationalai/early_access/metamodel/rewrite/__init__.py +0 -7
  551. relationalai/early_access/metamodel/typer/__init__.py +0 -3
  552. relationalai/early_access/metamodel/typer/typer/__init__.py +0 -12
  553. relationalai/early_access/metamodel/types/__init__.py +0 -15
  554. relationalai/early_access/metamodel/util/__init__.py +0 -15
  555. relationalai/early_access/metamodel/visitor/__init__.py +0 -12
  556. relationalai/early_access/rel/__init__.py +0 -12
  557. relationalai/early_access/rel/executor/__init__.py +0 -12
  558. relationalai/early_access/rel/rel_utils/__init__.py +0 -12
  559. relationalai/early_access/rel/rewrite/__init__.py +0 -7
  560. relationalai/early_access/solvers/__init__.py +0 -19
  561. relationalai/early_access/sql/__init__.py +0 -11
  562. relationalai/early_access/sql/executor/__init__.py +0 -3
  563. relationalai/early_access/sql/rewrite/__init__.py +0 -3
  564. relationalai/early_access/tests/logging/__init__.py +0 -12
  565. relationalai/early_access/tests/test_snapshot_base/__init__.py +0 -12
  566. relationalai/early_access/tests/utils/__init__.py +0 -12
  567. relationalai/environments/__init__.py +0 -35
  568. relationalai/environments/base.py +0 -381
  569. relationalai/environments/colab.py +0 -14
  570. relationalai/environments/generic.py +0 -71
  571. relationalai/environments/ipython.py +0 -68
  572. relationalai/environments/jupyter.py +0 -9
  573. relationalai/environments/snowbook.py +0 -169
  574. relationalai/errors.py +0 -2496
  575. relationalai/experimental/SF.py +0 -38
  576. relationalai/experimental/inspect.py +0 -47
  577. relationalai/experimental/pathfinder/__init__.py +0 -158
  578. relationalai/experimental/pathfinder/api.py +0 -160
  579. relationalai/experimental/pathfinder/automaton.py +0 -584
  580. relationalai/experimental/pathfinder/bridge.py +0 -226
  581. relationalai/experimental/pathfinder/compiler.py +0 -416
  582. relationalai/experimental/pathfinder/datalog.py +0 -214
  583. relationalai/experimental/pathfinder/diagnostics.py +0 -56
  584. relationalai/experimental/pathfinder/filter.py +0 -236
  585. relationalai/experimental/pathfinder/glushkov.py +0 -439
  586. relationalai/experimental/pathfinder/options.py +0 -265
  587. relationalai/experimental/pathfinder/pathfinder-v0.7.0.rel +0 -1951
  588. relationalai/experimental/pathfinder/rpq.py +0 -344
  589. relationalai/experimental/pathfinder/transition.py +0 -200
  590. relationalai/experimental/pathfinder/utils.py +0 -26
  591. relationalai/experimental/paths/README.md +0 -107
  592. relationalai/experimental/paths/api.py +0 -143
  593. relationalai/experimental/paths/benchmarks/grid_graph.py +0 -37
  594. relationalai/experimental/paths/code_organization.md +0 -2
  595. relationalai/experimental/paths/examples/Movies.ipynb +0 -16328
  596. relationalai/experimental/paths/examples/basic_example.py +0 -40
  597. relationalai/experimental/paths/examples/minimal_engine_warmup.py +0 -3
  598. relationalai/experimental/paths/examples/movie_example.py +0 -77
  599. relationalai/experimental/paths/examples/movies_data/actedin.csv +0 -193
  600. relationalai/experimental/paths/examples/movies_data/directed.csv +0 -45
  601. relationalai/experimental/paths/examples/movies_data/follows.csv +0 -7
  602. relationalai/experimental/paths/examples/movies_data/movies.csv +0 -39
  603. relationalai/experimental/paths/examples/movies_data/person.csv +0 -134
  604. relationalai/experimental/paths/examples/movies_data/produced.csv +0 -16
  605. relationalai/experimental/paths/examples/movies_data/ratings.csv +0 -10
  606. relationalai/experimental/paths/examples/movies_data/wrote.csv +0 -11
  607. relationalai/experimental/paths/examples/paths_benchmark.py +0 -115
  608. relationalai/experimental/paths/examples/paths_example.py +0 -116
  609. relationalai/experimental/paths/examples/pattern_to_automaton.py +0 -28
  610. relationalai/experimental/paths/find_paths_via_automaton.py +0 -85
  611. relationalai/experimental/paths/graph.py +0 -185
  612. relationalai/experimental/paths/path_algorithms/find_paths.py +0 -280
  613. relationalai/experimental/paths/path_algorithms/one_sided_ball_repetition.py +0 -26
  614. relationalai/experimental/paths/path_algorithms/one_sided_ball_upto.py +0 -111
  615. relationalai/experimental/paths/path_algorithms/single.py +0 -59
  616. relationalai/experimental/paths/path_algorithms/two_sided_balls_repetition.py +0 -39
  617. relationalai/experimental/paths/path_algorithms/two_sided_balls_upto.py +0 -103
  618. relationalai/experimental/paths/path_algorithms/usp-old.py +0 -130
  619. relationalai/experimental/paths/path_algorithms/usp-tuple.py +0 -183
  620. relationalai/experimental/paths/path_algorithms/usp.py +0 -150
  621. relationalai/experimental/paths/product_graph.py +0 -93
  622. relationalai/experimental/paths/rpq/automaton.py +0 -584
  623. relationalai/experimental/paths/rpq/diagnostics.py +0 -56
  624. relationalai/experimental/paths/rpq/rpq.py +0 -378
  625. relationalai/experimental/paths/tests/tests_limit_sp_max_length.py +0 -90
  626. relationalai/experimental/paths/tests/tests_limit_sp_multiple.py +0 -119
  627. relationalai/experimental/paths/tests/tests_limit_sp_single.py +0 -104
  628. relationalai/experimental/paths/tests/tests_limit_walks_multiple.py +0 -113
  629. relationalai/experimental/paths/tests/tests_limit_walks_single.py +0 -149
  630. relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_multiple.py +0 -70
  631. relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_single.py +0 -64
  632. relationalai/experimental/paths/tests/tests_one_sided_ball_upto_multiple.py +0 -115
  633. relationalai/experimental/paths/tests/tests_one_sided_ball_upto_single.py +0 -75
  634. relationalai/experimental/paths/tests/tests_single_paths.py +0 -152
  635. relationalai/experimental/paths/tests/tests_single_walks.py +0 -208
  636. relationalai/experimental/paths/tests/tests_single_walks_undirected.py +0 -297
  637. relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_multiple.py +0 -107
  638. relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_single.py +0 -76
  639. relationalai/experimental/paths/tests/tests_two_sided_balls_upto_multiple.py +0 -76
  640. relationalai/experimental/paths/tests/tests_two_sided_balls_upto_single.py +0 -110
  641. relationalai/experimental/paths/tests/tests_usp_nsp_multiple.py +0 -229
  642. relationalai/experimental/paths/tests/tests_usp_nsp_single.py +0 -108
  643. relationalai/experimental/paths/tree_agg.py +0 -168
  644. relationalai/experimental/paths/utilities/iterators.py +0 -27
  645. relationalai/experimental/paths/utilities/prefix_sum.py +0 -91
  646. relationalai/experimental/solvers.py +0 -1095
  647. relationalai/loaders/csv.py +0 -195
  648. relationalai/loaders/loader.py +0 -177
  649. relationalai/loaders/types.py +0 -23
  650. relationalai/rel_emitter.py +0 -373
  651. relationalai/rel_utils.py +0 -185
  652. relationalai/semantics/designs/query_builder/identify_by.md +0 -106
  653. relationalai/semantics/devtools/benchmark_lqp.py +0 -535
  654. relationalai/semantics/devtools/compilation_manager.py +0 -294
  655. relationalai/semantics/devtools/extract_lqp.py +0 -110
  656. relationalai/semantics/internal/internal.py +0 -3785
  657. relationalai/semantics/internal/snowflake.py +0 -329
  658. relationalai/semantics/lqp/README.md +0 -34
  659. relationalai/semantics/lqp/algorithms.py +0 -173
  660. relationalai/semantics/lqp/builtins.py +0 -213
  661. relationalai/semantics/lqp/compiler.py +0 -22
  662. relationalai/semantics/lqp/constructors.py +0 -68
  663. relationalai/semantics/lqp/executor.py +0 -518
  664. relationalai/semantics/lqp/export_rewriter.py +0 -40
  665. relationalai/semantics/lqp/intrinsics.py +0 -24
  666. relationalai/semantics/lqp/ir.py +0 -150
  667. relationalai/semantics/lqp/model2lqp.py +0 -1056
  668. relationalai/semantics/lqp/passes.py +0 -38
  669. relationalai/semantics/lqp/primitives.py +0 -252
  670. relationalai/semantics/lqp/result_helpers.py +0 -266
  671. relationalai/semantics/lqp/rewrite/__init__.py +0 -32
  672. relationalai/semantics/lqp/rewrite/algorithm.py +0 -385
  673. relationalai/semantics/lqp/rewrite/annotate_constraints.py +0 -69
  674. relationalai/semantics/lqp/rewrite/cdc.py +0 -216
  675. relationalai/semantics/lqp/rewrite/constants_to_vars.py +0 -70
  676. relationalai/semantics/lqp/rewrite/deduplicate_vars.py +0 -104
  677. relationalai/semantics/lqp/rewrite/eliminate_data.py +0 -108
  678. relationalai/semantics/lqp/rewrite/extract_common.py +0 -340
  679. relationalai/semantics/lqp/rewrite/extract_keys.py +0 -577
  680. relationalai/semantics/lqp/rewrite/flatten_script.py +0 -301
  681. relationalai/semantics/lqp/rewrite/function_annotations.py +0 -114
  682. relationalai/semantics/lqp/rewrite/functional_dependencies.py +0 -348
  683. relationalai/semantics/lqp/rewrite/period_math.py +0 -77
  684. relationalai/semantics/lqp/rewrite/quantify_vars.py +0 -339
  685. relationalai/semantics/lqp/rewrite/splinter.py +0 -76
  686. relationalai/semantics/lqp/rewrite/unify_definitions.py +0 -323
  687. relationalai/semantics/lqp/types.py +0 -101
  688. relationalai/semantics/lqp/utils.py +0 -170
  689. relationalai/semantics/lqp/validators.py +0 -70
  690. relationalai/semantics/metamodel/compiler.py +0 -134
  691. relationalai/semantics/metamodel/dependency.py +0 -880
  692. relationalai/semantics/metamodel/executor.py +0 -78
  693. relationalai/semantics/metamodel/factory.py +0 -287
  694. relationalai/semantics/metamodel/helpers.py +0 -368
  695. relationalai/semantics/metamodel/ir.py +0 -924
  696. relationalai/semantics/metamodel/rewrite/__init__.py +0 -8
  697. relationalai/semantics/metamodel/rewrite/discharge_constraints.py +0 -39
  698. relationalai/semantics/metamodel/rewrite/dnf_union_splitter.py +0 -220
  699. relationalai/semantics/metamodel/rewrite/extract_nested_logicals.py +0 -78
  700. relationalai/semantics/metamodel/rewrite/flatten.py +0 -590
  701. relationalai/semantics/metamodel/rewrite/format_outputs.py +0 -256
  702. relationalai/semantics/metamodel/rewrite/handle_aggregations_and_ranks.py +0 -237
  703. relationalai/semantics/metamodel/typer/checker.py +0 -355
  704. relationalai/semantics/metamodel/typer/typer.py +0 -1396
  705. relationalai/semantics/metamodel/util.py +0 -506
  706. relationalai/semantics/metamodel/visitor.py +0 -945
  707. relationalai/semantics/reasoners/__init__.py +0 -10
  708. relationalai/semantics/reasoners/graph/README.md +0 -620
  709. relationalai/semantics/reasoners/graph/__init__.py +0 -37
  710. relationalai/semantics/reasoners/graph/core.py +0 -9019
  711. relationalai/semantics/reasoners/graph/design/beyond_demand_transform.md +0 -797
  712. relationalai/semantics/reasoners/graph/tests/README.md +0 -21
  713. relationalai/semantics/reasoners/optimization/__init__.py +0 -68
  714. relationalai/semantics/reasoners/optimization/common.py +0 -88
  715. relationalai/semantics/reasoners/optimization/solvers_dev.py +0 -568
  716. relationalai/semantics/reasoners/optimization/solvers_pb.py +0 -1407
  717. relationalai/semantics/rel/builtins.py +0 -40
  718. relationalai/semantics/rel/compiler.py +0 -994
  719. relationalai/semantics/rel/executor.py +0 -363
  720. relationalai/semantics/rel/rel.py +0 -482
  721. relationalai/semantics/rel/rel_utils.py +0 -276
  722. relationalai/semantics/snowflake/__init__.py +0 -3
  723. relationalai/semantics/sql/compiler.py +0 -2503
  724. relationalai/semantics/sql/executor/duck_db.py +0 -52
  725. relationalai/semantics/sql/executor/result_helpers.py +0 -64
  726. relationalai/semantics/sql/executor/snowflake.py +0 -149
  727. relationalai/semantics/sql/rewrite/denormalize.py +0 -222
  728. relationalai/semantics/sql/rewrite/double_negation.py +0 -49
  729. relationalai/semantics/sql/rewrite/recursive_union.py +0 -127
  730. relationalai/semantics/sql/rewrite/sort_output_query.py +0 -246
  731. relationalai/semantics/sql/sql.py +0 -504
  732. relationalai/semantics/std/pragmas.py +0 -11
  733. relationalai/semantics/std/std.py +0 -14
  734. relationalai/semantics/tests/lqp/algorithms.py +0 -345
  735. relationalai/semantics/tests/test_snapshot_abstract.py +0 -144
  736. relationalai/semantics/tests/test_snapshot_base.py +0 -9
  737. relationalai/semantics/tests/utils.py +0 -46
  738. relationalai/std/__init__.py +0 -70
  739. relationalai/tools/cli.py +0 -2089
  740. relationalai/tools/cli_controls.py +0 -1975
  741. relationalai/tools/cli_helpers.py +0 -802
  742. relationalai/tools/debugger_client.py +0 -109
  743. relationalai/tools/debugger_server.py +0 -302
  744. relationalai/tools/dev.py +0 -685
  745. relationalai/tools/notes +0 -7
  746. relationalai/tools/qb_debugger.py +0 -425
  747. relationalai/tools/txn_progress.py +0 -188
  748. relationalai/util/clean_up_databases.py +0 -95
  749. relationalai/util/list_databases.py +0 -9
  750. relationalai/util/otel_configuration.py +0 -26
  751. relationalai/util/otel_handler.py +0 -484
  752. relationalai/util/snowflake_handler.py +0 -88
  753. relationalai/util/span_format_test.py +0 -43
  754. relationalai/util/span_tracker.py +0 -207
  755. relationalai/util/spans_file_handler.py +0 -72
  756. relationalai/util/tracing_handler.py +0 -34
  757. relationalai-0.13.5.dist-info/METADATA +0 -74
  758. relationalai-0.13.5.dist-info/RECORD +0 -473
  759. relationalai-0.13.5.dist-info/WHEEL +0 -4
  760. relationalai-0.13.5.dist-info/entry_points.txt +0 -3
  761. relationalai-0.13.5.dist-info/licenses/LICENSE +0 -202
  762. relationalai_test_util/__init__.py +0 -4
  763. relationalai_test_util/fixtures.py +0 -233
  764. relationalai_test_util/snapshot.py +0 -252
  765. relationalai_test_util/traceback.py +0 -118
  766. /relationalai/{analysis → semantics/frontend}/__init__.py +0 -0
  767. /relationalai/{auth/__init__.py → semantics/metamodel/metamodel_compiler.py} +0 -0
  768. /relationalai/{early_access → shims}/__init__.py +0 -0
  769. {relationalai/early_access/dsl/adapters → v0/relationalai/analysis}/__init__.py +0 -0
  770. {relationalai → v0/relationalai}/analysis/mechanistic.py +0 -0
  771. {relationalai → v0/relationalai}/analysis/whynot.py +0 -0
  772. {relationalai/early_access/dsl/adapters/orm → v0/relationalai/auth}/__init__.py +0 -0
  773. {relationalai → v0/relationalai}/auth/jwt_generator.py +0 -0
  774. {relationalai → v0/relationalai}/auth/oauth_callback_server.py +0 -0
  775. {relationalai → v0/relationalai}/auth/token_handler.py +0 -0
  776. {relationalai → v0/relationalai}/auth/util.py +0 -0
  777. {relationalai/clients/resources/snowflake → v0/relationalai/clients}/cache_store.py +0 -0
  778. {relationalai → v0/relationalai}/compiler.py +0 -0
  779. {relationalai → v0/relationalai}/dependencies.py +0 -0
  780. {relationalai → v0/relationalai}/docutils.py +0 -0
  781. {relationalai/early_access/dsl/adapters/owl → v0/relationalai/early_access}/__init__.py +0 -0
  782. {relationalai → v0/relationalai}/early_access/dsl/__init__.py +0 -0
  783. {relationalai/early_access/dsl/bindings → v0/relationalai/early_access/dsl/adapters}/__init__.py +0 -0
  784. {relationalai/early_access/dsl/bindings/legacy → v0/relationalai/early_access/dsl/adapters/orm}/__init__.py +0 -0
  785. {relationalai → v0/relationalai}/early_access/dsl/adapters/orm/model.py +0 -0
  786. {relationalai/early_access/dsl/codegen → v0/relationalai/early_access/dsl/adapters/owl}/__init__.py +0 -0
  787. {relationalai → v0/relationalai}/early_access/dsl/adapters/owl/model.py +0 -0
  788. {relationalai/early_access/dsl/core/temporal → v0/relationalai/early_access/dsl/bindings}/__init__.py +0 -0
  789. {relationalai/early_access/dsl/ir → v0/relationalai/early_access/dsl/bindings/legacy}/__init__.py +0 -0
  790. {relationalai/early_access/dsl/ontologies → v0/relationalai/early_access/dsl/codegen}/__init__.py +0 -0
  791. {relationalai → v0/relationalai}/early_access/dsl/constants.py +0 -0
  792. {relationalai → v0/relationalai}/early_access/dsl/core/__init__.py +0 -0
  793. {relationalai → v0/relationalai}/early_access/dsl/core/constraints/__init__.py +0 -0
  794. {relationalai → v0/relationalai}/early_access/dsl/core/constraints/predicate/__init__.py +0 -0
  795. {relationalai → v0/relationalai}/early_access/dsl/core/stack.py +0 -0
  796. {relationalai/early_access/dsl/orm → v0/relationalai/early_access/dsl/core/temporal}/__init__.py +0 -0
  797. {relationalai → v0/relationalai}/early_access/dsl/core/utils.py +0 -0
  798. {relationalai/early_access/dsl/orm/measures → v0/relationalai/early_access/dsl/ir}/__init__.py +0 -0
  799. {relationalai/early_access/dsl/physical_metadata → v0/relationalai/early_access/dsl/ontologies}/__init__.py +0 -0
  800. {relationalai → v0/relationalai}/early_access/dsl/ontologies/raw_source.py +0 -0
  801. {relationalai/early_access/dsl/serialize → v0/relationalai/early_access/dsl/orm}/__init__.py +0 -0
  802. {relationalai/early_access/dsl/snow → v0/relationalai/early_access/dsl/orm/measures}/__init__.py +0 -0
  803. {relationalai → v0/relationalai}/early_access/dsl/orm/reasoner_errors.py +0 -0
  804. {relationalai/loaders → v0/relationalai/early_access/dsl/physical_metadata}/__init__.py +0 -0
  805. {relationalai/semantics/tests → v0/relationalai/early_access/dsl/serialize}/__init__.py +0 -0
  806. {relationalai → v0/relationalai}/early_access/dsl/serialize/binding_model.py +0 -0
  807. {relationalai → v0/relationalai}/early_access/dsl/serialize/model.py +0 -0
  808. {relationalai/semantics/tests/lqp → v0/relationalai/early_access/dsl/snow}/__init__.py +0 -0
  809. {relationalai → v0/relationalai}/early_access/tests/__init__.py +0 -0
  810. {relationalai → v0/relationalai}/environments/ci.py +0 -0
  811. {relationalai → v0/relationalai}/environments/hex.py +0 -0
  812. {relationalai → v0/relationalai}/environments/terminal.py +0 -0
  813. {relationalai → v0/relationalai}/experimental/__init__.py +0 -0
  814. {relationalai → v0/relationalai}/experimental/graphs.py +0 -0
  815. {relationalai → v0/relationalai}/experimental/paths/__init__.py +0 -0
  816. {relationalai → v0/relationalai}/experimental/paths/benchmarks/__init__.py +0 -0
  817. {relationalai → v0/relationalai}/experimental/paths/path_algorithms/__init__.py +0 -0
  818. {relationalai → v0/relationalai}/experimental/paths/rpq/__init__.py +0 -0
  819. {relationalai → v0/relationalai}/experimental/paths/rpq/filter.py +0 -0
  820. {relationalai → v0/relationalai}/experimental/paths/rpq/glushkov.py +0 -0
  821. {relationalai → v0/relationalai}/experimental/paths/rpq/transition.py +0 -0
  822. {relationalai → v0/relationalai}/experimental/paths/utilities/__init__.py +0 -0
  823. {relationalai → v0/relationalai}/experimental/paths/utilities/utilities.py +0 -0
  824. {relationalai/tools → v0/relationalai/loaders}/__init__.py +0 -0
  825. {relationalai → v0/relationalai}/metagen.py +0 -0
  826. {relationalai → v0/relationalai}/metamodel.py +0 -0
  827. {relationalai → v0/relationalai}/rel.py +0 -0
  828. {relationalai → v0/relationalai}/semantics/devtools/__init__.py +0 -0
  829. {relationalai → v0/relationalai}/semantics/internal/__init__.py +0 -0
  830. {relationalai → v0/relationalai}/semantics/internal/annotations.py +0 -0
  831. {relationalai → v0/relationalai}/semantics/lqp/__init__.py +0 -0
  832. {relationalai → v0/relationalai}/semantics/lqp/pragmas.py +0 -0
  833. {relationalai → v0/relationalai}/semantics/metamodel/dataflow.py +0 -0
  834. {relationalai → v0/relationalai}/semantics/metamodel/typer/__init__.py +0 -0
  835. {relationalai → v0/relationalai}/semantics/metamodel/types.py +0 -0
  836. {relationalai → v0/relationalai}/semantics/reasoners/experimental/__init__.py +0 -0
  837. {relationalai → v0/relationalai}/semantics/rel/__init__.py +0 -0
  838. {relationalai → v0/relationalai}/semantics/sql/__init__.py +0 -0
  839. {relationalai → v0/relationalai}/semantics/sql/executor/__init__.py +0 -0
  840. {relationalai → v0/relationalai}/semantics/sql/rewrite/__init__.py +0 -0
  841. {relationalai → v0/relationalai}/semantics/tests/logging.py +0 -0
  842. {relationalai → v0/relationalai}/std/aggregates.py +0 -0
  843. {relationalai → v0/relationalai}/std/dates.py +0 -0
  844. {relationalai → v0/relationalai}/std/graphs.py +0 -0
  845. {relationalai → v0/relationalai}/std/inspect.py +0 -0
  846. {relationalai → v0/relationalai}/std/math.py +0 -0
  847. {relationalai → v0/relationalai}/std/re.py +0 -0
  848. {relationalai → v0/relationalai}/std/strings.py +0 -0
  849. {relationalai → v0/relationalai}/tools/cleanup_snapshots.py +0 -0
  850. {relationalai → v0/relationalai}/tools/constants.py +0 -0
  851. {relationalai → v0/relationalai}/tools/query_utils.py +0 -0
  852. {relationalai → v0/relationalai}/tools/snapshot_viewer.py +0 -0
  853. {relationalai → v0/relationalai}/util/__init__.py +0 -0
  854. {relationalai → v0/relationalai}/util/constants.py +0 -0
  855. {relationalai → v0/relationalai}/util/graph.py +0 -0
  856. {relationalai → v0/relationalai}/util/timeout.py +0 -0
@@ -0,0 +1,923 @@
1
+ """
2
+ Intermediate Representation of RelationalAI programs.
3
+ """
4
+ from __future__ import annotations
5
+ from dataclasses import dataclass, field
6
+ from enum import Enum
7
+ from io import StringIO
8
+ from itertools import count
9
+
10
+ from pandas import DataFrame
11
+ from more_itertools import peekable
12
+ from typing import Any, Iterator, Optional, Tuple, TypeVar, Union as PyUnion, IO, Iterable
13
+ from copy import copy
14
+ from itertools import islice
15
+ from datetime import datetime, date
16
+ from decimal import Decimal as PyDecimal
17
+ import numpy as np
18
+
19
+ from .util import FrozenOrderedSet, Printer as BasePrinter, NameCache
20
+
21
+ import json
22
+ import re
23
+
24
+ #--------------------------------------------------
25
+ # IR Nodes
26
+ #--------------------------------------------------
27
+
28
+ _global_id = peekable(count(0))
29
+ def next_id():
30
+ return next(_global_id)
31
+
32
+ def reconstructor(cls):
33
+ """
34
+ A decorator that adds a `reconstruct` method to the class.
35
+ The method reconstructs the object with new values for its fields.
36
+ The `reconstruct` method can take either positional arguments in field order
37
+ (excluding the `id` field) or keyword arguments for specific fields.
38
+ For positional arguments, fields of superclasses precede fields of subclasses.
39
+ If there is no difference between the current values of the fields and the new values,
40
+ `self` is returned, otherwise the object is copied and modified.
41
+ Note that the `id` field is not updated, unlike when creating a new node.
42
+ """
43
+ # Get the names of all fields from the class, except "id".
44
+ fnames = [fname for fname in cls.__dataclass_fields__ if fname != "id"]
45
+
46
+ # Add reconstruct method that can handle both positional and keyword arguments
47
+ def reconstruct(self, *args, **kwargs):
48
+ """
49
+ Reconstruct the object with new values for its fields.
50
+
51
+ Can be called in two ways:
52
+ 1. With positional arguments in the same order as the fields in the class
53
+ 2. With keyword arguments for specific fields to update
54
+
55
+ It is an error to provide both positional and keyword arguments.
56
+ Returns self if no changes are needed, otherwise returns a new instance.
57
+ """
58
+ # Validate arguments
59
+ if args and kwargs:
60
+ raise ValueError("Cannot provide both positional and keyword arguments")
61
+
62
+ # Handle positional arguments
63
+ if args:
64
+ if len(args) != len(fnames):
65
+ raise ValueError(f"Expected {len(fnames)} positional arguments, got {len(args)}")
66
+
67
+ # Check if any values differ from current values
68
+ has_changes = False
69
+ for fname, value in zip(fnames, args):
70
+ if getattr(self, fname) is not value:
71
+ has_changes = True
72
+ break
73
+
74
+ if not has_changes:
75
+ return self
76
+
77
+ # Create a new instance with updated values
78
+ new_obj = copy(self)
79
+ for fname, value in zip(fnames, args):
80
+ object.__setattr__(new_obj, fname, value)
81
+
82
+ return new_obj
83
+
84
+ # Handle keyword arguments
85
+ else:
86
+ # Check if any values differ from current values
87
+ has_changes = False
88
+ for fname, value in kwargs.items():
89
+ if fname not in fnames:
90
+ raise ValueError(f"Field '{fname}' is not a valid field for this object")
91
+ if getattr(self, fname) is not value:
92
+ has_changes = True
93
+ break
94
+
95
+ if not has_changes:
96
+ return self
97
+
98
+ # Create a new instance with updated values
99
+ new_obj = copy(self)
100
+ for fname, value in kwargs.items():
101
+ if fname in fnames:
102
+ object.__setattr__(new_obj, fname, value)
103
+
104
+ return new_obj
105
+
106
+ setattr(cls, "reconstruct", reconstruct)
107
+
108
+ # Also add a clone method that will recreate the node with the same data but with a
109
+ # new, distinct node id.
110
+ def clone(self):
111
+ """
112
+ Reconstruct a node with the same values, but it will get a new id.
113
+ """
114
+ args = []
115
+ for fname in fnames:
116
+ args.append(getattr(self, fname))
117
+ return self.__class__(*args)
118
+
119
+ setattr(cls, "clone", clone)
120
+
121
+ return cls
122
+
123
+ def acceptor(cls):
124
+ """
125
+ A decorator that adds an `accept` method to the class.
126
+ The `accept` method calls the appropriate handler method
127
+ of a Dispatcher.
128
+
129
+ Using a decorator here allows us to compute the handler name once
130
+ for the class rather than each time we dispatch.
131
+ """
132
+ attr_name = f"visit_{cls.__name__.lower()}"
133
+ def accept(self, v, parent=None):
134
+ return getattr(v, attr_name)(self, parent)
135
+ cls.accept = accept
136
+ return cls
137
+
138
+ def annotations_field() -> FrozenOrderedSet[Annotation]:
139
+ return field(default_factory=lambda: FrozenOrderedSet([]), compare=False, hash=False)
140
+
141
+ @dataclass(frozen=True)
142
+ class Node:
143
+ # A generated id that is not used on comparisons and hashes
144
+ id: int = field(default_factory=next_id, init=False, compare=False, hash=False)
145
+
146
+ @property
147
+ def kind(self):
148
+ return self.__class__.__name__.lower()
149
+
150
+ def __str__(self):
151
+ return node_to_string(self)
152
+
153
+ def accept(self, v, parent=None):
154
+ raise NotImplementedError(f"accept not implemented for {self.kind}")
155
+
156
+ def reconstruct(self, *args, **kwargs):
157
+ raise NotImplementedError(f"reconstruct not implemented for {self.kind}")
158
+
159
+ def clone(self, *args):
160
+ raise NotImplementedError(f"clone not implemented for {self.kind}")
161
+
162
+
163
+ #-------------------------------------------------
164
+ # Public Types - Model
165
+ #-------------------------------------------------
166
+
167
+ @acceptor
168
+ @reconstructor
169
+ @dataclass(frozen=True)
170
+ class Model(Node):
171
+ """Represents the whole universe of elements that make up a program."""
172
+ engines: FrozenOrderedSet["Engine"]
173
+ relations: FrozenOrderedSet["Relation"]
174
+ types: FrozenOrderedSet["Type"]
175
+ root: Task
176
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
177
+
178
+
179
+ #-------------------------------------------------
180
+ # Public Types - Engine
181
+ #-------------------------------------------------
182
+
183
+ @acceptor
184
+ @reconstructor
185
+ @dataclass(frozen=True)
186
+ class Capability(Node):
187
+ """Engine capabilities, such as 'graph algorithms', 'solver', 'constant time count', etc"""
188
+ name: str
189
+
190
+ @acceptor
191
+ @reconstructor
192
+ @dataclass(frozen=True)
193
+ class Engine(Node):
194
+ """The entity that owns a Task and provides access to certain relations."""
195
+ name: str
196
+ platform: str # SQL, Rel, JS, OpenAI, etc
197
+ info: Any
198
+ capabilities: FrozenOrderedSet[Capability]
199
+ relations: FrozenOrderedSet["Relation"]
200
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
201
+
202
+
203
+ #-------------------------------------------------
204
+ # Public Types - Data Model
205
+ #-------------------------------------------------
206
+
207
+ @acceptor
208
+ @reconstructor
209
+ @dataclass(frozen=True)
210
+ class Type(Node):
211
+ """The type of a field in a relation."""
212
+ pass
213
+
214
+ @acceptor
215
+ @dataclass(frozen=True)
216
+ class ScalarType(Type):
217
+ """The named type."""
218
+ name: str
219
+ super_types: FrozenOrderedSet[ScalarType] = field(default_factory=lambda: FrozenOrderedSet([]))
220
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
221
+
222
+ def __eq__(self, other):
223
+ return isinstance(other, ScalarType) and other.id == self.id
224
+
225
+ def __hash__(self):
226
+ return hash(self.id)
227
+
228
+ @acceptor
229
+ @dataclass(frozen=True)
230
+ class DecimalType(ScalarType):
231
+ precision: int = 38
232
+ scale: int = 14
233
+
234
+ def __eq__(self, other):
235
+ # note that we are not checking the name, only precision and scale
236
+ return isinstance(other, DecimalType) and other.precision == self.precision and other.scale == self.scale
237
+
238
+
239
+ @acceptor
240
+ @reconstructor
241
+ @dataclass(frozen=True)
242
+ class ListType(Type):
243
+ """A type that represents a list of elements of some other type."""
244
+ element_type: Type
245
+
246
+ @acceptor
247
+ @reconstructor
248
+ @dataclass(frozen=True)
249
+ class UnionType(Type):
250
+ """A type that represents either one of a set of types."""
251
+ types: FrozenOrderedSet[Type]
252
+
253
+ def __eq__(self, other):
254
+ return isinstance(other, UnionType) and len(self.types) == len(other.types) and self.types.includes(other.types)
255
+
256
+ @acceptor
257
+ @dataclass(frozen=True)
258
+ class TupleType(Type):
259
+ """A type that represents a tuple of elements of some other types."""
260
+ types: Tuple[Type, ...]
261
+
262
+ @acceptor
263
+ @reconstructor
264
+ @dataclass(frozen=True)
265
+ class Field(Node):
266
+ """A named field in a relation."""
267
+ name: str
268
+ type: Type
269
+ input: bool # must be grounded as the relation cannot compute it
270
+
271
+ def __eq__(self, other):
272
+ return isinstance(other, Field) and other.id == self.id
273
+
274
+ def __hash__(self):
275
+ return hash(self.id)
276
+
277
+
278
+ @acceptor
279
+ @reconstructor
280
+ @dataclass(frozen=True)
281
+ class Relation(Node):
282
+ """A relation represents the schema of a set of tuples."""
283
+ name: str
284
+ fields: Tuple[Field, ...]
285
+ requires: FrozenOrderedSet[Capability]
286
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
287
+ overloads: FrozenOrderedSet[Relation] = field(default_factory=lambda: FrozenOrderedSet([]))
288
+
289
+ def __eq__(self, other):
290
+ return isinstance(other, Relation) and other.id == self.id
291
+
292
+ def __hash__(self):
293
+ return hash(self.id)
294
+
295
+
296
+ #-------------------------------------------------
297
+ # Public Types - Tasks
298
+ #-------------------------------------------------
299
+
300
+ @acceptor
301
+ @reconstructor
302
+ @dataclass(frozen=True)
303
+ class Task(Node):
304
+ engine: Optional[Engine]
305
+
306
+ #
307
+ # Task composition
308
+ #
309
+
310
+ @acceptor
311
+ @reconstructor
312
+ @dataclass(frozen=True)
313
+ class Logical(Task):
314
+ """Execute sub-tasks up to fix-point."""
315
+ # Executes tasks concurrently. Succeeds if every task succeeds.
316
+ hoisted: Tuple[VarOrDefault, ...]
317
+ body: Tuple[Task, ...]
318
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
319
+
320
+ @acceptor
321
+ @reconstructor
322
+ @dataclass(frozen=True)
323
+ class Union(Task):
324
+ """Execute sub-tasks in any order."""
325
+ # Executes tasks concurrently. Succeeds if at least one task succeeds.
326
+ hoisted: Tuple[VarOrDefault, ...]
327
+ tasks: Tuple[Task, ...]
328
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
329
+
330
+ @acceptor
331
+ @reconstructor
332
+ @dataclass(frozen=True)
333
+ class Sequence(Task):
334
+ """Execute sub-tasks one at a time, in this order."""
335
+ # Executes tasks in order. Stops when a task fails. Succeeds if all tasks succeed.
336
+ hoisted: Tuple[VarOrDefault, ...]
337
+ tasks: Tuple[Task, ...]
338
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
339
+
340
+ @acceptor
341
+ @reconstructor
342
+ @dataclass(frozen=True)
343
+ class Match(Task):
344
+ """Execute sub-tasks in order until the first succeeds."""
345
+ # Executes tasks in order. Stops when a task succeeds. Succeeds if some task succeeds.
346
+ hoisted: Tuple[VarOrDefault, ...]
347
+ tasks: Tuple[Task, ...]
348
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
349
+
350
+ @acceptor
351
+ @reconstructor
352
+ @dataclass(frozen=True)
353
+ class Check(Node):
354
+ check: Task
355
+ error: Optional[Task]
356
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
357
+
358
+ @acceptor
359
+ @reconstructor
360
+ @dataclass(frozen=True)
361
+ class Require(Task):
362
+ """Execute the domain task and verify the checks. If a check is not satisfied, execute its error task."""
363
+ domain: Task
364
+ checks: Tuple[Check, ...]
365
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
366
+
367
+ @acceptor
368
+ @reconstructor
369
+ @dataclass(frozen=True)
370
+ class Until(Task):
371
+ """Execute both `check` and `body` concurrently, until check succeeds."""
372
+ hoisted: Tuple[VarOrDefault, ...]
373
+ check: Task
374
+ body: Task
375
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
376
+
377
+ @acceptor
378
+ @reconstructor
379
+ @dataclass(frozen=True)
380
+ class Wait(Task):
381
+ hoisted: Tuple[VarOrDefault, ...]
382
+ check: Task
383
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
384
+
385
+ # TODO: DynamicLookup
386
+
387
+
388
+ #
389
+ # Logical Quantifiers
390
+ #
391
+
392
+ @acceptor
393
+ @reconstructor
394
+ @dataclass(frozen=True)
395
+ class Not(Task):
396
+ """Logical negation of the sub-task."""
397
+ task: Task
398
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
399
+
400
+ @acceptor
401
+ @reconstructor
402
+ @dataclass(frozen=True)
403
+ class Exists(Task):
404
+ """Existential quantification over the sub-task."""
405
+ vars: Tuple[Var, ...]
406
+ task: Task
407
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
408
+
409
+ @acceptor
410
+ @reconstructor
411
+ @dataclass(frozen=True)
412
+ class ForAll(Task):
413
+ """Universal quantification over the sub-task."""
414
+ vars: Tuple[Var, ...]
415
+ task: Task
416
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
417
+
418
+ #
419
+ # Iteration (Loops)
420
+ #
421
+
422
+ # loops body until a break condition is met
423
+ @acceptor
424
+ @reconstructor
425
+ @dataclass(frozen=True)
426
+ class Loop(Task):
427
+ """Execute the body in a loop, incrementing the iter variable, until a break sub-task in
428
+ the body succeeds."""
429
+ hoisted: Tuple[VarOrDefault, ...]
430
+ iter: Var
431
+ body: Task
432
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
433
+
434
+ @acceptor
435
+ @reconstructor
436
+ @dataclass(frozen=True)
437
+ class Break(Task):
438
+ """Break a surrounding Loop if the `check` succeeds."""
439
+ check: Task
440
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
441
+
442
+
443
+ #
444
+ # Relational Operations
445
+ #
446
+
447
+ @acceptor
448
+ @reconstructor
449
+ @dataclass(frozen=True)
450
+ class Var(Node):
451
+ """A named variable that can point to objects of this type."""
452
+ type: Type
453
+ name: str
454
+
455
+ def __eq__(self, other):
456
+ return isinstance(other, Var) and other.id == self.id
457
+
458
+ def __hash__(self):
459
+ return hash(self.id)
460
+
461
+
462
+ @acceptor
463
+ @reconstructor
464
+ @dataclass(frozen=True)
465
+ class Default(Node):
466
+ """A variable with a default value. This can be used in 'hoisted' attributes to
467
+ represent the value to assign a variable if the underlying task fails."""
468
+ var: Var
469
+ value: Value
470
+
471
+ VarOrDefault = PyUnion[Var, Default]
472
+
473
+ @acceptor
474
+ @reconstructor
475
+ @dataclass(frozen=True)
476
+ class Literal(Node):
477
+ """A literal value with a specific type."""
478
+ type: Type
479
+ value: Any
480
+
481
+ @acceptor
482
+ @reconstructor
483
+ @dataclass(frozen=True)
484
+ class Data(Task):
485
+ """A table of data"""
486
+ data: DataFrame
487
+ vars: tuple[Var, ...]
488
+
489
+ def __eq__(self, other):
490
+ return (
491
+ isinstance(other, Data)
492
+ and self.data is other.data
493
+ and self.vars == other.vars
494
+ )
495
+
496
+ def __hash__(self):
497
+ # Use id() to get the reference of the DataFrame
498
+ data_ref_hash = hash(id(self.data))
499
+ vars_hash = hash(self.vars)
500
+ return data_ref_hash ^ vars_hash
501
+
502
+ def __len__(self):
503
+ return len(self.data)
504
+
505
+ def __iter__(self) -> Iterator[tuple[Any, ...]]:
506
+ return iter(self.data.itertuples(index=True))
507
+
508
+ PyValue = PyUnion[str, int, float, PyDecimal, bool, date, datetime]
509
+ Value = PyUnion[Var, Default, Literal, Type, Relation, None, Tuple["Value", ...], FrozenOrderedSet["Value"]]
510
+
511
+ @acceptor
512
+ @reconstructor
513
+ @dataclass(frozen=True)
514
+ class Annotation(Node):
515
+ """Meta information that can be attached to Updates."""
516
+ relation: Relation
517
+ args: Tuple[Value, ...]
518
+
519
+ class Effect(Enum):
520
+ """Possible effects of an Update."""
521
+ derive = "derive"
522
+ insert = "insert"
523
+ delete = "delete"
524
+
525
+ @acceptor
526
+ @reconstructor
527
+ @dataclass(frozen=True)
528
+ class Update(Task):
529
+ """Updates the relation with these arguments. The update can derive new tuples
530
+ temporarily, can insert new tuples persistently, or delete previously persisted tuples."""
531
+ relation: Relation
532
+ args: Tuple[Value, ...]
533
+ effect: Effect
534
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
535
+
536
+ @acceptor
537
+ @reconstructor
538
+ @dataclass(frozen=True)
539
+ class Lookup(Task):
540
+ """Lookup tuples from this relation, filtering with these arguments."""
541
+ relation: Relation
542
+ args: Tuple[Value, ...]
543
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
544
+
545
+ @acceptor
546
+ @reconstructor
547
+ @dataclass(frozen=True)
548
+ class Output(Task):
549
+ """Output the value of these vars, giving them these column names."""
550
+ aliases: FrozenOrderedSet[Tuple[str, Value]]
551
+ keys: Optional[FrozenOrderedSet[Var]]
552
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
553
+
554
+ @acceptor
555
+ @reconstructor
556
+ @dataclass(frozen=True)
557
+ class Construct(Task):
558
+ """Construct an id from these values, and bind the id to this var."""
559
+ values: Tuple[Value, ...]
560
+ id_var: Var
561
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
562
+
563
+ @acceptor
564
+ @reconstructor
565
+ @dataclass(frozen=True)
566
+ class Aggregate(Task):
567
+ """Perform an aggregation with these arguments."""
568
+ aggregation: Relation
569
+ projection: Tuple[Var, ...]
570
+ group: Tuple[Var, ...]
571
+ args: Tuple[Value, ...]
572
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
573
+
574
+ @acceptor
575
+ @reconstructor
576
+ @dataclass(frozen=True)
577
+ class Rank(Task):
578
+ """Perform a rank with these arguments."""
579
+ projection: Tuple[Var, ...]
580
+ group: Tuple[Var, ...]
581
+ args: Tuple[Var, ...]
582
+ # True if the argument is ascending, False if descending
583
+ arg_is_ascending: Tuple[bool, ...]
584
+ result: Var
585
+ limit: int = 0
586
+ annotations:FrozenOrderedSet[Annotation] = annotations_field()
587
+
588
+
589
+ #--------------------------------------------------
590
+ # Name helpers
591
+ #--------------------------------------------------
592
+
593
+ # TODO - extract the printer from here, and then use the method from helpers
594
+ def sanitize(name:str) -> str:
595
+ """ Cleanup the name to make it more palatable to names. """
596
+ x = re.sub(r"[ ,\.\(\)\|]", "_", name)
597
+ return x[0:-1] if x[-1] == "_" else x
598
+
599
+ #--------------------------------------------------
600
+ # Printer
601
+ #--------------------------------------------------
602
+
603
+ infix = ["+", "-", "*", "/", "%", "=", "!=", "<", "<=", ">", ">="]
604
+
605
+ T = TypeVar('T', bound=Node)
606
+ def node_to_string(node:Node|Tuple[T, ...]|FrozenOrderedSet[T], print_ids=False) -> str:
607
+ io = StringIO()
608
+ printer = Printer(io)
609
+ printer.pprint(node, print_ids=print_ids)
610
+ return io.getvalue()
611
+
612
+ def value_to_string(value:PyUnion[Value, Tuple[Value, ...]]) -> str:
613
+ return Printer().value_to_string(value)
614
+
615
+ def type_to_string(t:Type) -> str:
616
+ return value_to_string(t).strip()
617
+
618
+ def types_to_string(ts: Iterable[Type]) -> str:
619
+ """Join a collection of types with commas."""
620
+ return ', '.join(type_to_string(t) for t in ts)
621
+
622
+ @dataclass(frozen=True)
623
+ class Printer(BasePrinter):
624
+ name_cache: NameCache = field(default_factory=NameCache)
625
+
626
+ def print_hoisted(self, depth, name, hoisted: Tuple[VarOrDefault, ...]):
627
+ if hoisted:
628
+ self._indent_print_nl(depth, f"{name} ⇑[{', '.join([self.value_to_string(h) for h in hoisted])}]")
629
+ else:
630
+ self._indent_print_nl(depth, name)
631
+
632
+ def value_to_string(self, value:PyUnion[PyValue, Value, Tuple[Value, ...]]) -> str:
633
+ """ Return a string representation of the value. """
634
+ if isinstance(value, (int, float, bool)):
635
+ return json.dumps(value)
636
+ if isinstance(value, str):
637
+ return f"\"{value}\""
638
+ if isinstance(value, PyDecimal):
639
+ return str(value)
640
+ if isinstance(value, (date, datetime)):
641
+ return json.dumps(value.isoformat())
642
+ elif value is None:
643
+ return "None"
644
+ elif isinstance(value, Var):
645
+ return f"{self.name_cache.get_name(value.id, sanitize(value.name))}::{self.value_to_string(value.type)}"
646
+ elif isinstance(value, Default):
647
+ return f"{self.name_cache.get_name(value.var.id, sanitize(value.var.name))}={value.value}"
648
+ elif isinstance(value, Literal):
649
+ return f"{self.value_to_string(value.value)}::{self.value_to_string(value.type)}"
650
+ elif isinstance(value, ListType):
651
+ return f"[{self.value_to_string(value.element_type)}]"
652
+ elif isinstance(value, UnionType):
653
+ return f"{{{'; '.join(map(self.value_to_string, value.types))}}}"
654
+ elif isinstance(value, TupleType):
655
+ return f"({', '.join(map(self.value_to_string, value.types))})"
656
+ elif isinstance(value, DecimalType):
657
+ return f"Decimal({value.precision},{value.scale})"
658
+ elif isinstance(value, ScalarType):
659
+ annos_str = "" if not value.annotations else f" {' '.join(f'@{a.relation.name}' for a in value.annotations)}"
660
+ return f"{value.name}{annos_str}"
661
+ elif isinstance(value, Relation):
662
+ return value.name
663
+ elif isinstance(value, Tuple):
664
+ return f"({', '.join(map(self.value_to_string, value))})"
665
+ elif isinstance(value, FrozenOrderedSet):
666
+ return f"{{{', '.join(map(self.value_to_string, value))}}}"
667
+ elif isinstance(value, DataFrame):
668
+ length = len(value)
669
+ vals = islice(value, min(length, 3))
670
+ vals_str = ", ".join([f"({', '.join(map(self.value_to_string, v))})" for v in vals]) # type: ignore
671
+ if length > 3:
672
+ vals_str += f", ... ({length} total)"
673
+ final_str = f"{{{vals_str}}}"
674
+ return final_str
675
+ else:
676
+ raise NotImplementedError(f"value_to_string not implemented for {type(value)}")
677
+
678
+ T = TypeVar('T', bound=Node)
679
+ def pprint(self, node:Node|Tuple[T, ...]|FrozenOrderedSet[T], depth=0, print_ids=False) -> None:
680
+ """ Pretty print the node into the io, starting with indentation based on depth. If io is None,
681
+ print into the standard output. """
682
+
683
+ if print_ids and not (isinstance(node, Tuple) or isinstance(node, FrozenOrderedSet)):
684
+ self._print(f"|{node.id}|")
685
+
686
+ # deal with annotations more generically
687
+ annos = getattr(node, "annotations", [])
688
+ annos_str = "" if not annos else f" {' '.join(f'@{a.relation.name}' for a in annos)}"
689
+
690
+ if isinstance(node, Tuple) or isinstance(node, FrozenOrderedSet):
691
+ for n in node:
692
+ self.pprint(n, depth, print_ids=print_ids)
693
+ # model
694
+ elif isinstance(node, Model):
695
+ self._indent_print_nl(depth, f"Model{annos_str}")
696
+ if len(node.engines) > 0:
697
+ self._indent_print_nl(depth + 1, "engines:")
698
+ self.pprint(node.engines, depth + 2, print_ids=print_ids)
699
+ if len(node.relations) > 0:
700
+ self._indent_print_nl(depth + 1, "relations:")
701
+ self.pprint(node.relations, depth + 2, print_ids=print_ids)
702
+ if len(node.types) > 0:
703
+ self._indent_print_nl(depth + 1, "types:")
704
+ self.pprint(node.types, depth + 2, print_ids=print_ids)
705
+ self._indent_print_nl(depth + 1, "root:")
706
+ self.pprint(node.root, depth + 2, print_ids=print_ids)
707
+
708
+ # engine
709
+ elif isinstance(node, Capability):
710
+ self._indent_print_nl(depth, node.name)
711
+ elif isinstance(node, Engine):
712
+ self._indent_print_nl(depth, f"Engine ({node.name}, {node.platform}){annos_str}")
713
+ self._indent_print_nl(depth + 1, node.info)
714
+ self._indent_print_nl(depth + 1, ', '.join([c.name for c in node.capabilities]))
715
+ self.pprint(node.relations, depth + 1, print_ids=print_ids)
716
+
717
+ # data model
718
+ elif isinstance(node, Type):
719
+ self._indent_print_nl(depth, self.value_to_string(node))
720
+ elif isinstance(node, Field):
721
+ s = f"{node.name}: {self.value_to_string(node.type)}{' (input)' if node.input else ''}"
722
+ self._indent_print_nl(depth, s)
723
+ elif isinstance(node, Relation):
724
+ self._indent_print_nl(depth, node.name)
725
+ for anno in annos:
726
+ self._indent_print(depth + 1, anno)
727
+ self.pprint(node.fields, depth + 1, print_ids=print_ids)
728
+ if len(node.requires) > 0:
729
+ self._indent_print_nl(depth + 1, "requires:")
730
+ self.pprint(node.requires, depth + 2, print_ids=print_ids)
731
+
732
+ # tasks
733
+
734
+ # Task composition
735
+ elif isinstance(node, Logical):
736
+ self.print_hoisted(depth, f"Logical{annos_str}", node.hoisted)
737
+ self.pprint(node.body, depth + 1, print_ids=print_ids)
738
+ elif isinstance(node, Sequence):
739
+ self.print_hoisted(depth, f"Sequence{annos_str}", node.hoisted)
740
+ self.pprint(node.tasks, depth + 1, print_ids=print_ids)
741
+ elif isinstance(node, Union):
742
+ self.print_hoisted(depth, f"Union{annos_str}", node.hoisted)
743
+ self.pprint(node.tasks, depth + 1, print_ids=print_ids)
744
+ elif isinstance(node, Match):
745
+ self.print_hoisted(depth, f"Match{annos_str}", node.hoisted)
746
+ self.pprint(node.tasks, depth + 1, print_ids=print_ids)
747
+ elif isinstance(node, Until):
748
+ self.print_hoisted(depth, f"Until{annos_str}", node.hoisted)
749
+ self.pprint(node.check, depth + 1, print_ids=print_ids)
750
+ self.pprint(node.body, depth + 1, print_ids=print_ids)
751
+ elif isinstance(node, Wait):
752
+ self.print_hoisted(depth, f"Match{annos_str}", node.hoisted)
753
+ self.pprint(node.check, depth + 1, print_ids=print_ids)
754
+ elif isinstance(node, Require):
755
+ self._indent_print_nl(depth, f"Require{annos_str}")
756
+ self._indent_print_nl(depth + 1, "domain: ")
757
+ self.pprint(node.domain, depth + 2, print_ids=print_ids)
758
+ self._indent_print_nl(depth + 1, "checks: ")
759
+ for check in node.checks:
760
+ self.pprint(check, depth + 2, print_ids=print_ids)
761
+ elif isinstance(node, Check):
762
+ self._indent_print_nl(depth, f"Check{annos_str}")
763
+ self._indent_print_nl(depth + 1, "check: ")
764
+ self.pprint(node.check, depth + 2, print_ids=print_ids)
765
+ self._indent_print_nl(depth + 1, "error: ")
766
+ if node.error:
767
+ self.pprint(node.error, depth + 2, print_ids=print_ids)
768
+ else:
769
+ self._indent_print_nl(depth + 2, "None")
770
+
771
+ # Relational Operations
772
+ elif isinstance(node, Var):
773
+ self._indent_print_nl(0, self.value_to_string(node))
774
+ elif isinstance(node, Default):
775
+ self._indent_print_nl(depth, f"{self.value_to_string(node.var)} (default: {self.value_to_string(node.value)})")
776
+ elif isinstance(node, Literal):
777
+ self._indent_print_nl(0, self.value_to_string(node))
778
+ elif isinstance(node, Annotation):
779
+ if node.args:
780
+ self._indent_print_nl(depth, f"@{node.relation.name}{self.value_to_string(node.args)}")
781
+ else:
782
+ self._indent_print_nl(depth, f"@{node.relation.name}")
783
+ elif isinstance(node, Update):
784
+ rel_name = node.relation.name
785
+ self._indent_print_nl(depth, f"→ {node.effect.value} {rel_name}{self.value_to_string(node.args)}{annos_str}")
786
+ elif isinstance(node, Lookup):
787
+ rel_name = node.relation.name
788
+ if rel_name in infix:
789
+ args = [self.value_to_string(arg) for arg in node.args]
790
+ if len(node.args) == 2:
791
+ self._indent_print_nl(depth, f"{args[0]} {rel_name} {args[1]}{annos_str}")
792
+ elif len(node.args) == 1:
793
+ self._indent_print_nl(depth, f"{rel_name}{args[0]}{annos_str}")
794
+ elif len(node.args) == 3:
795
+ self._indent_print_nl(depth, f"{args[2]} = {args[0]} {rel_name} {args[1]}{annos_str}")
796
+ else:
797
+ self._indent_print_nl(depth, f"{rel_name}{self.value_to_string(node.args)}{annos_str}")
798
+ elif isinstance(node, Output):
799
+ keys = []
800
+ if node.keys:
801
+ for k in node.keys:
802
+ keys.append(self.value_to_string(k))
803
+ args = []
804
+ for k, v in node.aliases:
805
+ ppv = self.value_to_string(v)
806
+ if k != ppv:
807
+ args.append(f"{ppv} as '{k}'")
808
+ else:
809
+ args.append(ppv)
810
+ keys_str = f"[{', '.join(keys)}]" if keys else ""
811
+ self._indent_print_nl(depth, f"→ output{keys_str}({', '.join(args)}){annos_str}")
812
+ elif isinstance(node, Construct):
813
+ values = [self.value_to_string(v) for v in node.values]
814
+ self._indent_print_nl(depth, f"construct({', '.join(values)}, {self.value_to_string(node.id_var)}){annos_str}")
815
+ elif isinstance(node, Aggregate):
816
+ projection = ", ".join([self.value_to_string(v) for v in node.projection])
817
+ group = ", ".join([self.value_to_string(v) for v in node.group])
818
+ args = ", ".join([self.value_to_string(v) for v in node.args])
819
+ self._indent_print_nl(depth, f"{node.aggregation.name}([{projection}], [{group}], [{args}]){annos_str}")
820
+ elif isinstance(node, Rank):
821
+ def str_rank_var(v, o):
822
+ up, down = "'↑'", "'↓'"
823
+ return f"{self.value_to_string(v)}{up if o else down}"
824
+ projection = ", ".join([self.value_to_string(v) for v in node.projection])
825
+ group = ", ".join([self.value_to_string(v) for v in node.group])
826
+ assert len(node.args) == len(node.arg_is_ascending)
827
+ args = ", ".join([str_rank_var(v, o) for v, o in zip(node.args, node.arg_is_ascending)])
828
+ result = self.value_to_string(node.result)
829
+ limit = f"[limit={node.limit}]" if node.limit != 0 else ""
830
+ self._indent_print_nl(depth, f"rank{limit}([{projection}], [{group}], [{args}], {result}){annos_str}")
831
+ elif isinstance(node, Data):
832
+ length = len(node)
833
+ vals = islice(node, min(length, 3))
834
+ def unwrap_val(v):
835
+ if isinstance(v, (np.integer, np.floating)):
836
+ # convert DataFrame number types to native Python types
837
+ v = v.item()
838
+ return self.value_to_string(v)
839
+ vals_str = ", ".join([f"({', '.join(map(unwrap_val, v))})" for v in vals])
840
+ if length > 3:
841
+ vals_str += f", ... ({length} total)"
842
+ vars_str = ", ".join([self.value_to_string(v) for v in node.vars])
843
+ final_str = f"{{{vals_str}}}({vars_str})"
844
+ self._indent_print_nl(depth, final_str)
845
+
846
+ # Logical Quantifiers
847
+ elif isinstance(node, Not):
848
+ self._indent_print_nl(depth, f"Not{annos_str}")
849
+ self.pprint(node.task, depth + 1, print_ids=print_ids)
850
+ elif isinstance(node, Exists):
851
+ self._indent_print_nl(depth, f"Exists({', '.join([self.value_to_string(v) for v in node.vars])}){annos_str}")
852
+ self.pprint(node.task, depth + 1, print_ids=print_ids)
853
+ elif isinstance(node, ForAll):
854
+ self._indent_print_nl(depth, f"ForAll({', '.join([self.value_to_string(v) for v in node.vars])}){annos_str}")
855
+ self.pprint(node.task, depth + 1, print_ids=print_ids)
856
+
857
+ # Iteration (Loops)
858
+ elif isinstance(node, Loop):
859
+ self.print_hoisted(depth, f"Loop ⇓[{self.value_to_string(node.iter)}]{annos_str}", node.hoisted)
860
+ self.pprint(node.body, depth + 1, print_ids=print_ids)
861
+
862
+ elif isinstance(node, Break):
863
+ self._indent_print_nl(depth, f"Break{annos_str}")
864
+ self.pprint(node.check, depth + 1, print_ids=print_ids)
865
+
866
+ elif isinstance(node, Task):
867
+ self._indent_print_nl(depth, "Success")
868
+
869
+ else:
870
+ # return
871
+ raise NotImplementedError(f"pprint not implemented for {type(node)}")
872
+
873
+ def dump_to_string(node: Node|Tuple[T, ...]|FrozenOrderedSet[T], depth=0, io: Optional[IO[str]] = None) -> str:
874
+ """Dump a node to a string."""
875
+ output = StringIO()
876
+ dump(node, depth, output)
877
+ return output.getvalue()
878
+
879
+
880
+ def dump(node: Node|Tuple[T, ...]|FrozenOrderedSet[T], depth=0, io: Optional[IO[str]] = None) -> None:
881
+ """Print complete IR information, including node IDs and all fields."""
882
+
883
+ def indent_print(depth, io: Optional[IO[str]], *args) -> None:
884
+ """ Helper to print the arguments into the io with indented based on depth. """
885
+ if io is None:
886
+ print(" " * depth + " ".join(map(str, args)))
887
+ else:
888
+ io.write(" " * depth + " ".join(map(str, args)) + "\n")
889
+
890
+ def print_node_header(n: Node, depth: int):
891
+ indent_print(depth, io, f"{n.__class__.__name__} (id={n.id})")
892
+
893
+ if isinstance(node, (Tuple, FrozenOrderedSet)):
894
+ for n in node:
895
+ if isinstance(n, Tuple) and len(n) == 2 and isinstance(n[0], str) and isinstance(n[1], Node):
896
+ indent_print(depth, io, f"{n[0]}:")
897
+ dump(n[1], depth + 1, io)
898
+ elif isinstance(n, (Node, Tuple, FrozenOrderedSet)):
899
+ dump(n, depth, io)
900
+ else:
901
+ indent_print(depth, io, f"{value_to_string(n)}")
902
+ return
903
+
904
+ if not isinstance(node, Node):
905
+ raise TypeError(f"Expected Node but got {type(node)}")
906
+
907
+ print_node_header(node, depth)
908
+
909
+ # Print all fields of the dataclass
910
+ for field_name, field_value in node.__dict__.items():
911
+ if field_name == 'id': # Already printed in header
912
+ continue
913
+
914
+ assert not isinstance(field_value, list), f"{node.__class__.__name__}.{field_name} is a {type(field_value)}"
915
+ assert not isinstance(field_value, set), f"{node.__class__.__name__}.{field_name} is a {type(field_value)}"
916
+
917
+ if isinstance(field_value, (Node, Tuple, FrozenOrderedSet)) and not isinstance(field_value, Type):
918
+ indent_print(depth + 1, io, f"{field_name}:")
919
+ dump(field_value, depth + 2, io)
920
+ elif isinstance(field_value, Effect):
921
+ indent_print(depth + 1, io, f"{field_name}: {field_value.value}")
922
+ else:
923
+ indent_print(depth + 1, io, f"{field_name}: {value_to_string(field_value)}")