relationalai 0.13.5__py3-none-any.whl → 1.0.0a2__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 +1719 -0
  20. relationalai/semantics/frontend/core.py +179 -0
  21. relationalai/semantics/frontend/front_compiler.py +1316 -0
  22. relationalai/semantics/frontend/pprint.py +408 -0
  23. relationalai/semantics/metamodel/__init__.py +6 -40
  24. relationalai/semantics/metamodel/builtins.py +206 -772
  25. relationalai/semantics/metamodel/metamodel.py +465 -0
  26. relationalai/semantics/metamodel/metamodel_analyzer.py +519 -0
  27. relationalai/semantics/metamodel/pprint.py +414 -0
  28. relationalai/semantics/metamodel/rewriter.py +266 -0
  29. relationalai/semantics/metamodel/typer.py +1213 -0
  30. relationalai/semantics/std/__init__.py +60 -40
  31. relationalai/semantics/std/aggregates.py +148 -0
  32. relationalai/semantics/std/common.py +44 -0
  33. relationalai/semantics/std/constraints.py +37 -43
  34. relationalai/semantics/std/datetime.py +249 -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 +179 -0
  43. relationalai/shims/helpers.py +126 -0
  44. relationalai/shims/hoister.py +221 -0
  45. relationalai/shims/mm2v0.py +1394 -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.0a2.dist-info/METADATA +44 -0
  67. relationalai-1.0.0a2.dist-info/RECORD +489 -0
  68. relationalai-1.0.0a2.dist-info/WHEEL +5 -0
  69. relationalai-1.0.0a2.dist-info/entry_points.txt +3 -0
  70. relationalai-1.0.0a2.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 +2478 -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 +325 -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 +474 -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 +877 -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 +490 -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 +776 -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 +554 -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 +9019 -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
@@ -1,1056 +0,0 @@
1
- from relationalai.semantics.metamodel import ir, builtins, helpers, types
2
- from relationalai.semantics.metamodel.visitor import collect_by_type
3
- from relationalai.semantics.metamodel.util import FrozenOrderedSet, OrderedSet
4
- from relationalai.semantics.metamodel.compiler import group_tasks
5
- from relationalai.semantics.lqp import ir as lqp, utils, types as lqp_types
6
- from relationalai.semantics.lqp.primitives import lqp_avg_op, lqp_operator, build_primitive
7
- from relationalai.semantics.lqp.pragmas import pragma_to_lqp_name
8
- from relationalai.semantics.lqp.types import meta_type_to_lqp
9
- from relationalai.semantics.lqp.constructors import (
10
- mk_abstraction, mk_and, mk_exists, mk_or, mk_pragma, mk_primitive,
11
- mk_specialized_value, mk_type, mk_value, mk_attribute,
12
- )
13
- from relationalai.semantics.lqp.algorithms import (
14
- is_script, is_algorithm_script, is_algorithm_logical,
15
- is_while_loop, is_while_script, construct_monoid, is_empty_instruction
16
- )
17
- from relationalai.semantics.lqp.builtins import (
18
- has_global_annotation, get_upsert_annotation, get_monoid_annotation,
19
- get_monus_annotation, has_assign_annotation, get_arity, supported_lqp_annotations
20
- )
21
- from relationalai.semantics.lqp.utils import TranslationCtx, ExportDescriptor, gen_unique_var, gen_rel_id
22
- from relationalai.semantics.lqp.validators import assert_valid_input
23
- from relationalai.semantics.lqp.rewrite.functional_dependencies import (
24
- normalized_fd, contains_only_declarable_constraints
25
- )
26
- from decimal import Decimal as PyDecimal
27
- from datetime import datetime, date, timezone
28
- from typing import Sequence, Tuple, cast, Union, Optional
29
- from warnings import warn
30
- import re
31
- import uuid
32
-
33
- # Main access point for translating metamodel to lqp. Converts the model IR to an LQP epoch.
34
- def to_lqp(model: ir.Model, fragment_name: bytes, ctx: TranslationCtx) -> tuple[Optional[tuple], lqp.Epoch]:
35
- assert_valid_input(model)
36
- decls: list[lqp.Declaration] = []
37
- reads: list[lqp.Read] = []
38
-
39
- # LQP only accepts logical tasks
40
- # These are asserted at init time
41
- root = cast(ir.Logical, model.root)
42
- for subtask in root.body:
43
- assert isinstance(subtask, ir.Logical)
44
- new_decls = _translate_to_decls(ctx, subtask)
45
- decls.extend(new_decls)
46
-
47
- # Add pyrel error attributes to reads.
48
- for err_id in _extract_pyrel_error_ids(ctx, model):
49
- ctx.output_ids.append(err_id)
50
-
51
- reads.extend(_get_output_reads(ctx.output_ids))
52
-
53
- export_info = None
54
- if len(ctx.export_descriptors) > 0:
55
- export_filename, col_types, export_reads = _get_export_reads(ctx.export_descriptors)
56
- reads.extend(export_reads)
57
- export_info = (export_filename, col_types)
58
-
59
- debug_info = lqp.DebugInfo(id_to_orig_name=ctx.rel_id_to_orig_name, meta=None)
60
- fragment_id = lqp.FragmentId(id=fragment_name, meta=None)
61
- fragment = lqp.Fragment(id=fragment_id, declarations=decls, meta=None, debug_info=debug_info)
62
- define_op = lqp.Define(fragment=fragment, meta=None)
63
-
64
- txn = lqp.Epoch(
65
- reads=reads,
66
- writes=[lqp.Write(write_type=define_op, meta=None)],
67
- meta=None
68
- )
69
-
70
- return (export_info, txn)
71
-
72
- def _effect_bindings(effect: Union[ir.Output, ir.Update]) -> list[ir.Value]:
73
- if isinstance(effect, ir.Output):
74
- # Unions may not return anything. The generated IR contains a None value when this
75
- # happens. We ignore it here.
76
- return [v for v in helpers.output_values(effect.aliases) if v]
77
- else:
78
- return list(effect.args)
79
-
80
- def _get_output_reads(output_ids: list[tuple[lqp.RelationId, str]]) -> list[lqp.Read]:
81
- reads = []
82
- for (rel_id, name) in output_ids:
83
- assert isinstance(rel_id, lqp.RelationId)
84
- output = lqp.Output(name=name, relation_id=rel_id, meta=None)
85
- reads.append(lqp.Read(read_type=output, meta=None))
86
- return reads
87
-
88
- def _get_export_reads(descriptors: list[ExportDescriptor]) -> tuple[str, list, list[lqp.Read]]:
89
- reads = []
90
- csv_columns = []
91
- col_info = []
92
- for descriptor in sorted(descriptors, key=lambda x: x.column_number):
93
- csv_columns.append(lqp.ExportCSVColumn(
94
- column_name=descriptor.column_name,
95
- column_data=descriptor.relation_id,
96
- meta=None,
97
- ))
98
- col_info.append((descriptor.column_name, descriptor.column_type))
99
-
100
- # Generate a random name for the internal export path
101
- export_filename = "export_" + str(uuid.uuid4()).replace("-", "_")
102
-
103
- # Note that the engine will append the transaction id to the export path for access
104
- # control reasons. So the actual final path will be
105
- # `.../export/{export_filename}/data_{txn_id}`
106
- export_path = f"snowflake://APP_STATE.RAI_INTERNAL_STAGE/export/{export_filename}/data"
107
- export_csv_config = lqp.ExportCSVConfig(
108
- path=export_path,
109
- data_columns=csv_columns,
110
- compression="gzip",
111
- partition_size=200,
112
- syntax_escapechar='"', # To follow Snowflake's expected format
113
- meta=None,
114
- )
115
- reads.append(lqp.Read(read_type=lqp.Export(config=export_csv_config, meta=None), meta=None))
116
- return (export_filename, col_info, reads)
117
-
118
- def _translate_to_decls(ctx: TranslationCtx, rule: ir.Logical) -> list[lqp.Declaration]:
119
- if contains_only_declarable_constraints(rule):
120
- return _translate_to_constraint_decls(ctx, rule)
121
- elif is_algorithm_logical(rule):
122
- return _translate_algorithms(ctx, rule)
123
- else:
124
- return _translate_to_standard_decl(ctx, rule)
125
-
126
- def _translate_to_constraint_decls(ctx: TranslationCtx, rule: ir.Logical) -> list[lqp.Declaration]:
127
- constraint_decls: list[lqp.Declaration] = []
128
- for task in rule.body:
129
- if isinstance(task, ir.Logical):
130
- constraint_decls.extend(_translate_to_constraint_decls(ctx, task))
131
- continue
132
- else:
133
- assert isinstance(task, ir.Require)
134
- decl = _translate_to_constraint_decl(ctx, task)
135
- if decl is not None:
136
- constraint_decls.append(decl)
137
- return constraint_decls
138
-
139
- def _translate_to_constraint_decl(ctx: TranslationCtx, rule: ir.Require) -> Optional[lqp.Declaration]:
140
- fd = normalized_fd(rule)
141
- assert fd is not None
142
-
143
- # check for unresolved types
144
- if any(types.is_any(var.type) for var in fd.keys + fd.values):
145
- warn(f"Ignoring FD with unresolved type: {fd}")
146
- return None
147
-
148
- lqp_typed_keys = [_translate_term(ctx, key) for key in fd.keys]
149
- lqp_typed_values = [_translate_term(ctx, value) for value in fd.values]
150
- lqp_typed_vars:list[Tuple[lqp.Var, lqp.Type]] = lqp_typed_keys + lqp_typed_values # type: ignore
151
- lqp_guard_atoms = [_translate_to_atom(ctx, atom) for atom in fd.guard]
152
- lqp_guard = mk_abstraction(lqp_typed_vars, mk_and(lqp_guard_atoms))
153
- lqp_keys:list[lqp.Var] = [var for (var, _) in lqp_typed_keys] # type: ignore
154
- lqp_values:list[lqp.Var] = [var for (var, _) in lqp_typed_values] # type: ignore
155
- lqp_id = utils.lqp_hash(fd.canonical_str)
156
- lqp_name:lqp.RelationId = lqp.RelationId(id=lqp_id, meta=None)
157
-
158
- return lqp.FunctionalDependency(
159
- name=lqp_name,
160
- guard=lqp_guard,
161
- keys=lqp_keys,
162
- values=lqp_values,
163
- meta=None
164
- )
165
-
166
- def _translate_algorithms(ctx: TranslationCtx, task: ir.Logical) -> list[lqp.Declaration]:
167
- assert is_algorithm_logical(task)
168
- decls: list[lqp.Declaration] = []
169
- for subtask in task.body:
170
- assert is_algorithm_script(subtask), "Expected all subtasks to be algorithm scripts"
171
- decls.extend(_translate_algorithm_script(ctx, subtask))
172
- return decls
173
-
174
- def _translate_algorithm_script(ctx: TranslationCtx, alg_task: ir.Sequence) -> list[lqp.Declaration]:
175
- assert is_algorithm_script(alg_task), "Expected Sequence @algorithm @script "
176
-
177
- alg_globals = _find_algorithm_global_relation_ids(ctx, alg_task)
178
- alg_body = _translate_script(ctx, alg_task)
179
-
180
- return [lqp.Algorithm(global_=alg_globals, body=alg_body, meta=None)]
181
-
182
- def _find_algorithm_global_relation_ids(ctx: TranslationCtx, alg_task: ir.Sequence) -> list[lqp.RelationId]:
183
- result = []
184
- updates = collect_by_type(ir.Update, alg_task)
185
- for update in updates:
186
- if has_global_annotation(update):
187
- bindings = _effect_bindings(update)
188
- projection, _ = _translate_bindings(ctx, bindings)
189
- rel_id = get_relation_id(ctx, update.relation, projection)
190
- result.append(rel_id)
191
- return list(dict.fromkeys(result))
192
-
193
- def _translate_script(ctx: TranslationCtx, task: ir.Sequence) -> lqp.Script:
194
- assert is_script(task), "Expected a @script Sequence"
195
-
196
- constructs: list[lqp.Construct] = []
197
-
198
- for subtask in task.tasks:
199
- if is_empty_instruction(subtask):
200
- constructs.append(_translate_empty_instruction(ctx, subtask))
201
- elif isinstance(subtask, ir.Logical):
202
- constructs.extend(_translate_instruction(ctx, subtask))
203
- elif isinstance(subtask, ir.Break):
204
- constructs.append(_translate_break_instruction(ctx, subtask))
205
- elif is_while_loop(subtask):
206
- constructs.append(_translate_while_loop(ctx, subtask))
207
- else:
208
- raise Exception(f"Unsupported script instruction: {subtask}")
209
-
210
- return lqp.Script(constructs=constructs, meta=None)
211
-
212
- def _translate_while_loop(ctx: TranslationCtx, task: ir.Loop) -> lqp.Loop:
213
- assert is_while_loop(task), "Expected a @while Loop"
214
- assert len(task.iter) == 0, "Temporalized loops not supported"
215
-
216
- while_script_task = task.body
217
- assert is_while_script(while_script_task), "The body of a @while Loop must be a @while @script Sequence"
218
- body_script = _translate_script(ctx, while_script_task)
219
-
220
- # No init instructions in the translation of PyRel Loops to to LQP loops
221
- return lqp.Loop(init=[], body=body_script, meta=None)
222
-
223
- def _translate_break_instruction(ctx: TranslationCtx, task: ir.Break) -> lqp.Construct:
224
- body = _translate_to_formula(ctx, task.check)
225
-
226
- ctx.break_rule_counter += 1
227
-
228
- rel_id = gen_rel_id(ctx, "break_cond_" + str(ctx.break_rule_counter))
229
- return lqp.Break(
230
- name = rel_id,
231
- body = mk_abstraction([], body),
232
- attrs = [],
233
- meta = None,
234
- )
235
-
236
- def _translate_empty_instruction(ctx: TranslationCtx, rule: ir.Logical) -> lqp.Instruction:
237
- assert is_empty_instruction(rule)
238
- updates = collect_by_type(ir.Update, rule)
239
- assert len(updates) == 1
240
- update = updates[0]
241
- bindings = _effect_bindings(update)
242
-
243
- # We need to make sure that variable names have a leading underscore
244
- normalized_bindings:Sequence[ir.Var] = []
245
- for v in bindings:
246
- assert isinstance(v, ir.Var)
247
- if not v.name.startswith("_"):
248
- v = ir.Var(v.type, "_" + v.name)
249
- normalized_bindings.append(v)
250
-
251
- projection, eqs = _translate_bindings(ctx, normalized_bindings)
252
- assert len(eqs) == 0
253
- rel_id = get_relation_id(ctx, update.relation, projection)
254
- abstraction = mk_abstraction(projection, mk_or([])) # empty body = false
255
- return lqp.Assign(name = rel_id, body = abstraction, attrs = [], meta = None)
256
-
257
- def _translate_instruction(ctx: TranslationCtx, rule: ir.Logical) -> list[lqp.Instruction]:
258
- effects = collect_by_type((ir.Update, ir.Output), rule)
259
-
260
- if len(effects) == 0:
261
- return []
262
-
263
- conjuncts = _translate_to_formula(ctx, rule)
264
- res = []
265
- for effect in effects:
266
- assert isinstance(effect, ir.Update), f"Got an effect of type {type(effect)} in a loop, which is invalid."
267
-
268
- bindings = _effect_bindings(effect)
269
- projection, eqs = _translate_bindings(ctx, bindings)
270
-
271
- eqs.append(conjuncts)
272
- new_body = mk_and(eqs)
273
-
274
- rel_id = get_relation_id(ctx, effect.relation, projection)
275
- abstraction = mk_abstraction(projection, new_body)
276
-
277
- upsert = get_upsert_annotation(effect)
278
- monoid = get_monoid_annotation(effect)
279
- monus = get_monus_annotation(effect)
280
-
281
- if has_assign_annotation(effect):
282
- res.append(lqp.Assign(name = rel_id, body = abstraction, attrs = [], meta = None))
283
- elif upsert is not None:
284
- res.append(lqp.Upsert(value_arity=get_arity(upsert), name = rel_id, body = abstraction, attrs = [], meta = None))
285
- elif monoid is not None:
286
- res.append(lqp.MonoidDef(
287
- value_arity=get_arity(monoid),
288
- monoid=construct_monoid(monoid),
289
- name = rel_id,
290
- body = abstraction,
291
- attrs = [],
292
- meta = None
293
- ))
294
- elif monus is not None:
295
- res.append(lqp.MonusDef(
296
- value_arity=get_arity(monus),
297
- monoid=construct_monoid(monus),
298
- name = rel_id,
299
- body = abstraction,
300
- attrs = [],
301
- meta = None
302
- ))
303
-
304
- return res
305
-
306
- def _translate_to_standard_decl(ctx: TranslationCtx, rule: ir.Logical) -> list[lqp.Declaration]:
307
- effects = collect_by_type((ir.Output, ir.Update), rule)
308
-
309
- # TODO: should this ever actually come in as input?
310
- if len(effects) == 0:
311
- return []
312
-
313
- conjuncts = _translate_to_formula(ctx, rule)
314
- return [_translate_effect(ctx, effect, conjuncts) for effect in effects]
315
-
316
- def _translate_annotations(annotations: FrozenOrderedSet[ir.Annotation]) -> list[lqp.Attribute]:
317
- attributes = []
318
- for annotation in annotations:
319
-
320
- if annotation.relation.name in supported_lqp_annotations:
321
- if any(not isinstance(a, ir.Literal) for a in annotation.args):
322
- warn("LQP currently ignores annotation parameters with non-literal values")
323
- continue
324
-
325
- # Convert literal arguments to LQP values
326
- args = []
327
- for a in annotation.args:
328
- assert isinstance(a, ir.Literal)
329
- args.append(mk_value(a.value))
330
- attributes.append(mk_attribute(annotation.relation.name, args))
331
- return attributes
332
-
333
- # Translates an effect (export, output, or update) into the corresponding def. Note that
334
- # this method only generates the def and not the LQP read operation, which is added later by
335
- # `_get_output_reads` and `_get_export_reads`.
336
- def _translate_effect(ctx: TranslationCtx, effect: Union[ir.Output, ir.Update], body: lqp.Formula) -> lqp.Declaration:
337
- bindings = _effect_bindings(effect)
338
-
339
- if isinstance(effect, ir.Output):
340
- projection, eqs, suffix = _translate_output_bindings(ctx, bindings)
341
- meta_id = effect.id
342
-
343
- if helpers.is_export(effect):
344
- def_name = "export_relation" + suffix
345
- else:
346
- def_name = "output" + suffix
347
-
348
- def_name = ctx.output_names.get_name_by_id(meta_id, def_name)
349
- rel_id = get_output_id(ctx, def_name, meta_id)
350
- else:
351
- projection, eqs = _translate_bindings(ctx, bindings)
352
- def_name = effect.relation.name
353
- rel_id = get_relation_id(ctx, effect.relation, projection)
354
-
355
- eqs.append(body)
356
- new_body = mk_and(eqs)
357
-
358
- # Context bookkeeping for exports and outputs
359
- if helpers.is_export(effect):
360
- # The row id is the first n-1 elements, and the actual data is the last element. Its
361
- # type is stored in the first element of the tuple.
362
- col_type = projection[-1][1]
363
- _col_num_match = re.search(r"export_relation_col([0-9]+)", def_name)
364
- assert _col_num_match, f"Could not find column number in suffix: {def_name}"
365
- col_num = int(_col_num_match.group(1))
366
- col_name = f"col{col_num}"
367
- if isinstance(effect, ir.Output) and len(effect.aliases) > 0:
368
- aliases_list = list(effect.aliases)
369
- col_name = aliases_list[-1][0]
370
- ctx.export_descriptors.append(ExportDescriptor(
371
- relation_id=rel_id,
372
- column_name=col_name,
373
- column_number=col_num,
374
- column_type=col_type,
375
- ))
376
- elif isinstance(effect, ir.Output):
377
- ctx.output_ids.append((rel_id, def_name))
378
-
379
- # First we collect annotations on the effect itself, e.g. from something like
380
- # `select(...).annotate(...)`.
381
- annotations = effect.annotations
382
- if isinstance(effect, ir.Update):
383
- # Then we translate annotations on the relation itself, e.g.
384
- # ```
385
- # Bar.foo = model.Relationship(...)
386
- # Bar.foo.annotate(...)
387
- # ```
388
- annotations = annotations | effect.relation.annotations
389
-
390
- return lqp.Def(
391
- name = rel_id,
392
- body = mk_abstraction(projection, new_body),
393
- attrs = _translate_annotations(annotations),
394
- meta = None,
395
- )
396
-
397
- def _translate_output_bindings(ctx: TranslationCtx, bindings: list[ir.Value]) -> Tuple[list[Tuple[lqp.Var, lqp.Type]], list[lqp.Formula], str]:
398
- symbol_literals = []
399
- non_symbols = []
400
- for binding in bindings:
401
- if isinstance(binding, ir.Literal) and binding.type == types.Symbol:
402
- symbol_literals.append(binding.value)
403
- else:
404
- non_symbols.append(binding)
405
- projection, eqs = _translate_bindings(ctx, non_symbols)
406
- if len(symbol_literals) > 0:
407
- name_suffix = "_"
408
- name_suffix += "_".join(symbol_literals)
409
- else:
410
- name_suffix = ""
411
-
412
- return projection, eqs, name_suffix
413
-
414
- def _translate_rank(ctx: TranslationCtx, rank: ir.Rank, body: lqp.Formula) -> lqp.Formula:
415
- # Ascending rank is constructed using rel_primitive_sort. If a limit is added to an
416
- # ascending rank we can use rel_primitive_top for an efficient evaluation.
417
- #
418
- # Descending rank is constructed as an ascending sort, then the ascending rank is
419
- # subtracted from a count of the elements (plus 1 so that we still start at 1).
420
- # Adding a limit to a descending rank is done by adding a filter of rank <= limit.
421
-
422
- # Limits are the sort plus a filter on rank <= limit.
423
- if all(o for o in rank.arg_is_ascending):
424
- ascending = True
425
- elif all(not o for o in rank.arg_is_ascending):
426
- ascending = False
427
- else:
428
- raise Exception("Mixed orderings in rank are not supported yet.")
429
-
430
- # Filter out the group-by variables, since they are introduced outside the rank.
431
- input_args, input_eqs = _translate_bindings(ctx, list(rank.args))
432
- introduced_meta_projs = [arg for arg in rank.projection if arg not in rank.group and arg not in rank.args]
433
- projected_args, projected_eqs = _translate_bindings(ctx, list(introduced_meta_projs))
434
-
435
- # rank expects an Int128 result, but the primitive will return an Int64 result.
436
- # we need to set up an intermediary variable to hold the Int64 result, and a cast
437
- # to convert it to Int128.
438
- result_var, _ = _translate_term(ctx, rank.result)
439
- # The primitive will return an Int64 result, so we need a var to hold the intermediary.
440
- result_64_var = gen_unique_var(ctx, "v_rank")
441
- result_64_type = mk_type(lqp.TypeName.INT)
442
-
443
- cast = lqp.Cast(input=result_64_var, result=result_var, meta=None)
444
-
445
- body = mk_and([body] + input_eqs + projected_eqs)
446
- abstr_args = input_args + projected_args
447
-
448
- if ascending:
449
- ranker = _translate_ascending_rank(ctx, rank.limit, result_64_var, body, abstr_args)
450
- else:
451
- ranker = _translate_descending_rank(ctx, rank.limit, result_64_var, body, abstr_args)
452
-
453
- return mk_exists([(result_64_var, result_64_type)], mk_and([ranker, cast]))
454
-
455
- def _translate_descending_rank(ctx: TranslationCtx, limit: int, result: lqp.Var, body: lqp.Formula, abstr_args) -> lqp.Formula:
456
- result_var = result
457
- result_type = mk_type(lqp.TypeName.INT)
458
-
459
- # Rename abstracted args in the body to new variable names
460
- var_map = {var.name: gen_unique_var(ctx, 't_' + var.name) for (var, _) in abstr_args}
461
- body = utils.rename_vars_formula(body, var_map)
462
- new_abstr_args = [(var_map[var.name], typ) for (var, typ) in abstr_args]
463
-
464
- # Construct a conjunction of the ranking, a counter for the body, a subtraction
465
- # of the rank from the count and an addition of 1. Wrap this in an abstraction.
466
- count_res = gen_unique_var(ctx, "count_res")
467
-
468
- # Add one to the count to account for the rank starting at 1.
469
- one, one_eq = constant_to_var(ctx, to_lqp_value(1, types.Int64), "one")
470
- one_bigger = gen_unique_var(ctx, "one_bigger")
471
- addition = mk_primitive("rel_primitive_add_monotype", [count_res, one, one_bigger])
472
-
473
- # Subtract the rank from the count + 1
474
- asc_rank = gen_unique_var(ctx, "asc_rank")
475
- subtraction = mk_primitive("rel_primitive_subtract_monotype", [one_bigger, result_var, asc_rank])
476
-
477
- # Construct the ranking
478
- desc_ranking_terms = [asc_rank] + [v[0] for v in abstr_args]
479
- ranking = lqp.FFI(
480
- meta=None,
481
- name="rel_primitive_sort",
482
- args=[mk_abstraction(new_abstr_args, body)],
483
- terms=desc_ranking_terms,
484
- )
485
-
486
- # Count the number of rows in the body
487
- count_type = meta_type_to_lqp(types.Int64)
488
- count_var, count_eq = constant_to_var(ctx, to_lqp_value(1, types.Int64), "counter")
489
- desc_body = mk_and([body, count_eq])
490
- aggr_abstr_args = new_abstr_args + [(count_var, count_type)]
491
- count_aggr = lqp.Reduce(
492
- op=lqp_operator(
493
- ctx,
494
- "count",
495
- "count",
496
- mk_type(lqp.TypeName.INT)
497
- ),
498
- body=mk_abstraction(aggr_abstr_args, desc_body),
499
- terms=[count_res],
500
- meta=None
501
- )
502
-
503
- # Bring it all together and do the maths.
504
- ranking = mk_exists(
505
- vars=[
506
- (asc_rank, result_type),
507
- (count_res, result_type),
508
- (one, result_type),
509
- (one_bigger, result_type)
510
- ],
511
- value=mk_and([ranking, count_aggr, one_eq, addition, subtraction])
512
- )
513
-
514
- # If there is a limit, we need to add a filter to the ranking.
515
- # Wrap with a rank <= limit
516
- if limit != 0:
517
- limit_term, _ = _translate_term(ctx, ir.Literal(types.Int64, limit))
518
- limiter = mk_primitive("rel_primitive_lt_eq_monotype", [result_var, limit_term])
519
- ranking = mk_and([ranking, limiter])
520
-
521
- return ranking
522
-
523
- def _translate_ascending_rank(ctx: TranslationCtx, limit: int, result_var: lqp.Var, body: lqp.Formula, abstr_args) -> lqp.Formula:
524
- terms = [result_var] + [v[0] for v in abstr_args]
525
-
526
- # Rename abstracted args in the body to new variable names
527
- var_map = {var.name: gen_unique_var(ctx, 't_' + var.name) for (var, _) in abstr_args}
528
- body = utils.rename_vars_formula(body, var_map)
529
- new_abstr_args = [(var_map[var.name], typ) for (var, typ) in abstr_args]
530
- sort_abstr = mk_abstraction(new_abstr_args, body)
531
-
532
- if limit == 0:
533
- return lqp.FFI(
534
- meta=None,
535
- name="rel_primitive_sort",
536
- args=[sort_abstr],
537
- terms=terms,
538
- )
539
- else:
540
- limit_type = meta_type_to_lqp(types.Int64)
541
- limit_var, limit_eq = constant_to_var(ctx, to_lqp_value(limit, types.Int64), "limit")
542
- limit_abstr = mk_abstraction([(limit_var, limit_type)], limit_eq)
543
- return lqp.FFI(
544
- meta=None,
545
- name="rel_primitive_top",
546
- args=[sort_abstr, limit_abstr],
547
- terms=terms,
548
- )
549
-
550
- def _rename_shadowed_abstraction_vars(
551
- ctx: TranslationCtx,
552
- aggr: ir.Aggregate,
553
- abstr_args: list[Tuple[lqp.Var, lqp.Type]],
554
- body_conjs: list[lqp.Formula]
555
- ) -> list[Tuple[lqp.Var, lqp.Type]]:
556
- """
557
- Rename abstraction variables that shadow group-by variables.
558
-
559
- This can happen when the same variable appears in both aggr.group and as an input
560
- to the aggregation, e.g., min(Person.age).per(Person.age). The group-by variables
561
- are in the outer scope, while the abstraction parameters are in the inner scope,
562
- so we need different names to avoid shadowing.
563
- """
564
- # Get the LQP names of group-by variables
565
- group_var_names = set()
566
- for group_var in aggr.group:
567
- lqp_var = _translate_var(ctx, group_var)
568
- group_var_names.add(lqp_var.name)
569
-
570
- # Rename any abstraction parameters that conflict with group-by variables
571
- renamed_abstr_args = []
572
- for var, typ in abstr_args:
573
- if var.name in group_var_names:
574
- # This variable shadows a group-by variable, so rename it
575
- fresh_var = gen_unique_var(ctx, var.name)
576
- # Add an equality constraint: fresh_var == var
577
- # var is a free variable referring to the outer scope group-by variable
578
- body_conjs.append(mk_primitive("rel_primitive_eq", [fresh_var, var]))
579
- renamed_abstr_args.append((fresh_var, typ))
580
- else:
581
- renamed_abstr_args.append((var, typ))
582
-
583
- return renamed_abstr_args
584
-
585
- def _translate_aggregate(ctx: TranslationCtx, aggr: ir.Aggregate, body: lqp.Formula) -> Union[lqp.Reduce, lqp.Formula]:
586
- # TODO: handle this properly
587
- aggr_name = aggr.aggregation.name
588
- supported_aggrs = ("sum", "count", "avg", "min", "max", "rel_primitive_solverlib_ho_appl")
589
- assert aggr_name in supported_aggrs, f"only support {supported_aggrs} for now, not {aggr.aggregation.name}"
590
-
591
- meta_output_terms = []
592
- meta_input_terms = []
593
-
594
- for (field, arg) in zip(aggr.aggregation.fields, aggr.args):
595
- if field.input:
596
- meta_input_terms.append(arg)
597
- else:
598
- meta_output_terms.append(arg)
599
-
600
- output_terms = [_translate_term(ctx, term) for term in meta_output_terms]
601
- output_vars = [term[0] for term in output_terms]
602
-
603
- body_conjs = [body]
604
- input_args, input_eqs = _translate_bindings(ctx, meta_input_terms)
605
-
606
- # TODO: Can this safely be applied to all aggregates?
607
- if aggr_name in ("sum", "min", "max"):
608
- assert len(output_terms) == 1, f"{aggr_name} expects a single output variable"
609
- assert len(meta_input_terms) == 1, f"{aggr_name} expects a single input variable"
610
- assert isinstance(meta_output_terms[0], ir.Var)
611
- assert input_args[0][1] == output_terms[0][1], f"{aggr_name}({input_args[0][1].type_name}) had output type of {output_terms[0][1].type_name}"
612
-
613
- # Filter out the group-by variables, since they are introduced outside the aggregation.
614
- # Input terms are added later below.
615
- introduced_meta_projs = [arg for arg in aggr.projection if arg not in aggr.group and arg not in meta_input_terms]
616
- projected_args, projected_eqs = _translate_bindings(ctx, list(introduced_meta_projs))
617
- body_conjs.extend(input_eqs)
618
- body_conjs.extend(projected_eqs)
619
- abstr_args: list[Tuple[lqp.Var, lqp.Type]] = projected_args + input_args
620
-
621
- # Rename abstraction variables that shadow group-by variables
622
- abstr_args = _rename_shadowed_abstraction_vars(ctx, aggr, abstr_args, body_conjs)
623
-
624
- if aggr_name == "count":
625
- assert len(output_terms) == 1, "Count and avg expect a single output variable"
626
- assert isinstance(meta_output_terms[0], ir.Var)
627
- # Count sums up "1" for each row. We use the expected output type for the type
628
- # of the count variable.
629
- typ = meta_type_to_lqp(meta_output_terms[0].type)
630
- one_var, eq = constant_to_var(ctx, to_lqp_value(1, meta_output_terms[0].type), "one")
631
- body_conjs.append(eq)
632
- abstr_args.append((one_var, typ))
633
-
634
- # Average needs to wrap the reduce in Exists(Conjunction(Reduce, div))
635
- if aggr_name == "avg":
636
- assert len(output_vars) == 1, "avg should only have one output variable"
637
- output_var = output_vars[0]
638
-
639
- # Count sums up "1" for each row. We make the reasonably safe assumption that there
640
- # are less than 2^31 rows in the body.
641
- count_type = meta_type_to_lqp(types.Int64)
642
- one_var, eq = constant_to_var(ctx, to_lqp_value(1, types.Int64), "one")
643
- body_conjs.append(eq)
644
- abstr_args.append((one_var, count_type))
645
-
646
- # The average will produce two output variables: sum and count.
647
- sum_result = gen_unique_var(ctx, "sum")
648
- count_result = gen_unique_var(ctx, "count")
649
-
650
- # Second to last is the variable we're summing over.
651
- (sum_var, sum_type) = abstr_args[-2]
652
- body = mk_and(body_conjs)
653
-
654
- result = lqp.Reduce(
655
- op=lqp_avg_op(ctx, aggr.aggregation.name, sum_var.name, sum_type),
656
- body=mk_abstraction(abstr_args, body),
657
- terms=[sum_result, count_result],
658
- meta=None,
659
- )
660
-
661
- if sum_type == count_type:
662
- div = mk_primitive("rel_primitive_divide_monotype", [sum_result, count_result, output_var])
663
- conjunction = mk_and([result, div])
664
-
665
- # Finally, we need to wrap everything in an `exists` to project away the sum and
666
- # count variables and only keep the result of the division.
667
- result_terms = [(sum_result, sum_type), (count_result, count_type)]
668
- else:
669
- # If the sum type and count type don't match, we need to cast the count
670
- count_casted = gen_unique_var(ctx, "count_casted")
671
- count_cast = lqp.Cast(input=count_result, result=count_casted, meta=None)
672
-
673
- div = mk_primitive("rel_primitive_divide_monotype", [sum_result, count_casted, output_var])
674
- conjunction = mk_and([result, count_cast, div])
675
-
676
- # Finally, we need to wrap everything in an `exists` to project away the sum and
677
- # count variables and only keep the result of the division.
678
- result_terms = [(sum_result, sum_type), (count_result, count_type), (count_casted, sum_type)]
679
-
680
- return mk_exists(result_terms, conjunction)
681
-
682
- # `input_args` hold the types of the input arguments, but they may have been modified
683
- # if we're dealing with a count, so we use `abstr_args` to find the type.
684
- (aggr_arg, aggr_arg_type) = abstr_args[-1]
685
- body = mk_and(body_conjs)
686
-
687
- # Group-bys do not need to be handled at all, since they are introduced outside already
688
- reduce = lqp.Reduce(
689
- op=lqp_operator(ctx, aggr.aggregation.name, aggr_arg.name, aggr_arg_type),
690
- body=mk_abstraction(abstr_args, body),
691
- terms=output_vars,
692
- meta=None
693
- )
694
- return reduce
695
-
696
- def _translate_to_formula(ctx: TranslationCtx, task: ir.Task) -> lqp.Formula:
697
- if isinstance(task, ir.Logical):
698
- # For aggregates and ranks, the expected format is:
699
- #
700
- # Logical
701
- # body_task1
702
- # body_task2
703
- # ...
704
- # aggregate/rank task
705
- #
706
- # If we see that the Logical is in this format, it should be translated as an
707
- # aggregate/rank node.
708
- groups = group_tasks(task.body, {
709
- "aggregates": ir.Aggregate,
710
- "ranks": ir.Rank,
711
- })
712
-
713
- aggregates = groups.get("aggregates", OrderedSet[ir.Task]())
714
- ranks = groups.get("ranks", OrderedSet[ir.Task]())
715
-
716
- if aggregates or ranks:
717
- conjuncts = []
718
- body = mk_and([_translate_to_formula(ctx, t) for t in task.body])
719
- for aggr in aggregates:
720
- assert(isinstance(aggr, ir.Aggregate))
721
- conjuncts.append(_translate_aggregate(ctx, aggr, body))
722
- for rank in ranks:
723
- assert(isinstance(rank, ir.Rank))
724
- conjuncts.append(_translate_rank(ctx, rank, body))
725
- else:
726
- # If there are no aggregates or ranks, translate as a normal conjunction
727
- conjuncts = [_translate_to_formula(ctx, child) for child in task.body]
728
- return mk_and(conjuncts)
729
- elif isinstance(task, ir.Lookup):
730
- return _translate_to_atom(ctx, task)
731
- elif isinstance(task, ir.Not):
732
- return lqp.Not(arg=_translate_to_formula(ctx, task.task), meta=None)
733
- elif isinstance(task, ir.Exists):
734
- lqp_vars, conjuncts = _translate_bindings(ctx, list(task.vars))
735
- conjuncts.append(_translate_to_formula(ctx, task.task))
736
- return mk_exists(lqp_vars, mk_and(conjuncts))
737
- elif isinstance(task, ir.Construct):
738
- assert len(task.values) >= 1, "Construct should have at least one value"
739
- terms = [_translate_term(ctx, arg) for arg in task.values]
740
- result_term = _translate_term(ctx, task.id_var)
741
- terms.append(result_term)
742
- assert result_term[1].type_name == lqp.TypeName.UINT128, \
743
- f"Attempting to store a {task.id_var} in a type `{result_term[1].type_name}`"
744
-
745
- return mk_primitive("rel_primitive_hash_tuple_uint128", [v for v, _ in terms])
746
- elif isinstance(task, ir.Union):
747
- disjs = [_translate_to_formula(ctx, child) for child in task.tasks]
748
- return mk_or(disjs)
749
- elif isinstance(task, (ir.Output, ir.Update)):
750
- # Nothing to do here, handled in _translate_to_decls
751
- return mk_and([])
752
- elif isinstance(task, (ir.Aggregate, ir.Rank)):
753
- # Nothing to do here, handled at the Logical level
754
- return mk_and([])
755
- else:
756
- raise NotImplementedError(f"Unknown task type (formula): {type(task)}")
757
-
758
- # Only used for translating terms on relatoms, which can be specialized values.
759
- def _translate_relterm(ctx: TranslationCtx, term: ir.Value) -> Tuple[lqp.RelTerm, lqp.Type]:
760
- if isinstance(term, ir.Literal) and term.type == types.Symbol:
761
- if isinstance(term.value, str):
762
- value = mk_value(term.value)
763
- return mk_specialized_value(value), meta_type_to_lqp(types.String)
764
- elif isinstance(term.value, int):
765
- value = mk_value(term.value)
766
- return mk_specialized_value(value), meta_type_to_lqp(types.Int64)
767
- else:
768
- raise NotImplementedError(f"Cannot specialize literal of type {type(term.value)}")
769
- return _translate_term(ctx, term)
770
-
771
- def _translate_term(ctx: TranslationCtx, term: ir.Value) -> Tuple[lqp.Term, lqp.Type]:
772
- if isinstance(term, ir.ScalarType):
773
- # TODO: ScalarType is not like other terms, should be handled separately.
774
- return to_lqp_value(term.name, types.String), meta_type_to_lqp(types.String)
775
- elif isinstance(term, ir.Var):
776
- t = meta_type_to_lqp(term.type)
777
- return _translate_var(ctx, term), t
778
- else:
779
- assert isinstance(term, ir.Literal), f"Cannot translate value {term!r} of type {type(term)} to LQP Term; neither Var nor Literal."
780
- v = to_lqp_value(term.value, term.type)
781
- return v, meta_type_to_lqp(term.type)
782
-
783
- def _translate_to_atom(ctx: TranslationCtx, task: ir.Lookup) -> lqp.Formula:
784
- if task.relation == builtins.cast:
785
- assert len(task.args) == 3, f"expected three terms for {task.relation.name}, got {len(task.args)}"
786
-
787
- terms = []
788
- for arg in task.args[1:]:
789
- term, _ = _translate_relterm(ctx, arg)
790
- terms.append(term)
791
- return lqp.Cast(input=terms[0], result=terms[1], meta=None)
792
-
793
- if task.relation == builtins.join:
794
- return _translate_join(ctx, task)
795
- elif task.relation == builtins.infomap:
796
- return _translate_infomap(ctx, task)
797
- elif task.relation == builtins.louvain:
798
- return _translate_louvain(ctx, task)
799
- elif task.relation == builtins.label_propagation:
800
- return _translate_label_propagation(ctx, task)
801
-
802
- terms = []
803
- term_types = []
804
- for arg in task.args:
805
- # Handle varargs, which come wrapped in a tuple.
806
- if isinstance(arg, tuple):
807
- for vararg in arg:
808
- term, ty = _translate_relterm(ctx, vararg)
809
- terms.append(term)
810
- term_types.append(ty)
811
- else:
812
- term, ty = _translate_relterm(ctx, arg)
813
- terms.append(term)
814
- term_types.append(ty)
815
-
816
- if builtins.is_pragma(task.relation):
817
- lqp_name = pragma_to_lqp_name(task.relation.name)
818
- return mk_pragma(lqp_name, terms)
819
-
820
- if builtins.is_builtin(task.relation):
821
- return build_primitive(task.relation.name, terms, term_types)
822
-
823
- if helpers.is_external(task.relation):
824
- return lqp.RelAtom(name=task.relation.name, terms=terms, meta=None)
825
-
826
- projection, _ = _translate_bindings(ctx, list(task.args))
827
- rid = get_relation_id(ctx, task.relation, projection)
828
- return lqp.Atom(name=rid, terms=terms, meta=None)
829
-
830
-
831
- def get_relation_id(ctx: TranslationCtx, relation: ir.Relation, projection: list[Tuple[lqp.Var, lqp.Type]] = []) -> lqp.RelationId:
832
- types = "_".join([str(t.type_name) for (_, t) in projection])
833
- if types:
834
- types = "_" + types
835
- if relation.id in ctx.def_names.id_to_name:
836
- unique_name = ctx.def_names.id_to_name[relation.id]
837
- else:
838
- name = helpers.relation_name_prefix(relation) + relation.name
839
- name = helpers.sanitize(name)
840
- unique_name = ctx.def_names.get_name_by_id(relation.id, name)
841
-
842
- return utils.gen_rel_id(ctx, unique_name, types)
843
-
844
- def get_output_id(ctx: TranslationCtx, orig_name: str, metamodel_id: int) -> lqp.RelationId:
845
- unique_name = ctx.output_names.get_name_by_id(metamodel_id, orig_name)
846
- return utils.gen_rel_id(ctx, unique_name)
847
-
848
- def _translate_bindings(ctx: TranslationCtx, bindings: Sequence[ir.Value]) -> Tuple[list[Tuple[lqp.Var, lqp.Type]], list[lqp.Formula]]:
849
- lqp_vars = []
850
- conjuncts = []
851
- for binding in bindings:
852
- lqp_var, typ, eq = binding_to_lqp_var(ctx, binding)
853
- lqp_vars.append((lqp_var, typ))
854
- if eq is not None:
855
- conjuncts.append(eq)
856
-
857
- return lqp_vars, conjuncts
858
-
859
- def binding_to_lqp_var(ctx: TranslationCtx, binding: ir.Value) -> Tuple[lqp.Var, lqp.Type, Union[None, lqp.Formula]]:
860
- if isinstance(binding, ir.Var):
861
- var, typ = _translate_term(ctx, binding)
862
- assert isinstance(var, lqp.Var)
863
- return var, typ, None
864
- elif isinstance(binding, ir.Literal):
865
- lqp_value = to_lqp_value(binding.value, binding.type)
866
- var, formula = constant_to_var(ctx, lqp_value)
867
- return var, meta_type_to_lqp(binding.type), formula
868
- else:
869
- raise Exception(f"Unsupported binding type: {type(binding)}")
870
-
871
- def to_lqp_value(value: ir.PyValue, value_type: ir.Type) -> lqp.Value:
872
- typ = meta_type_to_lqp(value_type)
873
-
874
- # Ensure int values match the requested integer type.
875
- if typ.type_name == lqp.TypeName.INT and isinstance(value, int):
876
- assert lqp_types.INT_MIN <= value <= lqp_types.INT_MAX, f"{value} out of range for a 64-bit INT value"
877
- val = value
878
- elif typ.type_name == lqp.TypeName.INT128 and isinstance(value, int):
879
- assert lqp_types.INT128_MIN <= value <= lqp_types.INT128_MAX, f"{value} out of range for an INT128 value"
880
- val = lqp.Int128Value(value=value, meta=None)
881
- elif typ.type_name == lqp.TypeName.UINT128 and isinstance(value, int):
882
- assert lqp_types.UINT128_MIN <= value <= lqp_types.UINT128_MAX, f"{value} out of range for an UINT128 value"
883
- val = lqp.UInt128Value(value=value, meta=None)
884
- elif typ.type_name == lqp.TypeName.FLOAT and isinstance(value, float):
885
- val = value
886
- elif typ.type_name == lqp.TypeName.STRING and isinstance(value, str):
887
- val = value
888
- elif typ.type_name == lqp.TypeName.DECIMAL and isinstance(value, (int, float, PyDecimal)):
889
- precision = typ.parameters[0].value
890
- scale = typ.parameters[1].value
891
- assert isinstance(precision, int) and isinstance(scale, int)
892
- val = lqp.DecimalValue(precision=precision, scale=scale, value=PyDecimal(value), meta=None)
893
- elif typ.type_name == lqp.TypeName.DATE and isinstance(value, date):
894
- val = lqp.DateValue(value=value, meta=None)
895
- elif typ.type_name == lqp.TypeName.DATETIME and isinstance(value, datetime):
896
- utc_value = value.astimezone(timezone.utc) if value.tzinfo is not None else value # Convert to UTC cf. Iceberg
897
- val = lqp.DateTimeValue(value=utc_value, meta=None)
898
- elif typ.type_name == lqp.TypeName.BOOLEAN and isinstance(value, bool):
899
- val = lqp.BooleanValue(value=value, meta=None)
900
- else:
901
- raise Exception(f"Unsupported type for constant: {typ.type_name} with value {value} of type {type(value)}")
902
-
903
- return mk_value(val)
904
-
905
- def constant_to_var(ctx: TranslationCtx, value: lqp.Value, name_hint: str = "cvar") -> Tuple[lqp.Var, lqp.Formula]:
906
- var = gen_unique_var(ctx, name_hint)
907
- eq = mk_primitive("rel_primitive_eq", [var, value])
908
- return var, eq
909
-
910
- def _extract_pyrel_error_ids(ctx: TranslationCtx, model: ir.Model) -> list[Tuple[lqp.RelationId, str]]:
911
- effects = collect_by_type(ir.Update, model)
912
- pyrel_error_attrs = []
913
- # We use a separate counter here to avoid modifying the current model.
914
- i = 1
915
- for effect in effects:
916
- if "pyrel_error_attrs" not in effect.relation.name:
917
- continue
918
- projection, _ = _translate_bindings(ctx, _effect_bindings(effect))
919
- rel_id = get_relation_id(ctx, effect.relation, projection)
920
- name = f"{effect.relation.name}_{i}"
921
- pyrel_error_attrs.append((rel_id, name))
922
- i += 1
923
-
924
- return pyrel_error_attrs
925
-
926
- # Translate a relation reference into an abstraction over its fields.
927
- def _translate_relation_ref(ctx: TranslationCtx, relation: ir.Relation) -> lqp.Abstraction:
928
- projection = []
929
- for field in relation.fields:
930
- var = gen_unique_var(ctx, field.name)
931
- typ = meta_type_to_lqp(field.type)
932
- projection.append((var, typ))
933
-
934
- rid = get_relation_id(ctx, relation, projection)
935
- atom = lqp.Atom(name=rid, terms=[var for (var, _) in projection], meta=None)
936
- return mk_abstraction(projection, atom)
937
-
938
- # Common translation logic for graph algorithms.
939
- # task.args[0] : normalized weight list (int64, int64, float)
940
- # task.args[1] : normalized node count (relation or constant int64)
941
- # task.args[2] : normalized edge count (relation or constant int64)
942
- # task.args[3:-3] : algorithm parameters (var or constant)
943
- # task.args[-3] : diagnostic info
944
- # task.args[-2] : node index
945
- # task.args[-1] : community ident
946
- def _translate_graph_common(name: str, ctx: TranslationCtx, task: ir.Lookup):
947
- abstractions = []
948
-
949
- assert isinstance(task.args[0], ir.Relation), \
950
- f"Expected relation as first arg to {name}, got {task.args[0]}:{type(task.args[0])}"
951
- abstractions.append(_translate_relation_ref(ctx, task.args[0]))
952
-
953
- # Allow constant args for node and edge count
954
- for arg in task.args[1:3]:
955
- if isinstance(arg, ir.Relation):
956
- abst = _translate_relation_ref(ctx, arg)
957
- typ = abst.vars[0][1]
958
- assert typ.type_name == lqp.TypeName.INT, \
959
- f"Expected Int64 types for node and edge counts, got type {typ.type_name}"
960
- abstractions.append(abst)
961
- else:
962
- var, typ, eq = binding_to_lqp_var(ctx, arg)
963
- assert eq is not None, \
964
- f"Expected equality formula for {name} arg {arg}:{type(arg)}"
965
- abstractions.append(mk_abstraction([(var, typ)], mk_and([eq])))
966
-
967
- for arg in task.args[3:-3]:
968
- var, typ, eq = binding_to_lqp_var(ctx, arg)
969
- if eq:
970
- abstractions.append(mk_abstraction([(var, typ)], mk_and([eq])))
971
- else:
972
- print(f"Primitive graph algorithm arg without eq:\n var:{var}, typ:{typ}\n arg:{arg}:{type(arg)}")
973
- abstractions.append(mk_abstraction([(var, typ)], mk_and([])))
974
-
975
- terms = []
976
- for arg in task.args[-3:]:
977
- term, _ = _translate_relterm(ctx, arg)
978
- terms.append(term)
979
-
980
- return (abstractions, terms)
981
-
982
- def _translate_infomap(ctx: TranslationCtx, task: ir.Lookup) -> lqp.Formula:
983
- abstractions, terms = _translate_graph_common("infomap", ctx, task)
984
-
985
- return lqp.FFI(
986
- meta=None,
987
- name="rel_primitive_infomap",
988
- args=abstractions,
989
- terms=terms,
990
- )
991
-
992
- def _translate_louvain(ctx: TranslationCtx, task: ir.Lookup) -> lqp.Formula:
993
- abstractions, terms = _translate_graph_common("louvain", ctx, task)
994
-
995
- return lqp.FFI(
996
- meta=None,
997
- name="rel_primitive_louvain",
998
- args=abstractions,
999
- terms=terms,
1000
- )
1001
-
1002
- def _translate_label_propagation(ctx: TranslationCtx, task: ir.Lookup) -> lqp.Formula:
1003
- abstractions, terms = _translate_graph_common("label_propagation", ctx, task)
1004
-
1005
- return lqp.FFI(
1006
- meta=None,
1007
- name="rel_primitive_async_label_propagation",
1008
- args=abstractions,
1009
- terms=terms,
1010
- )
1011
-
1012
- # Hard-coded implementation of Rel's string_join
1013
- def _translate_join(ctx: TranslationCtx, task: ir.Lookup) -> lqp.Formula:
1014
- assert len(task.args) == 3
1015
- (strs, separator, target) = task.args
1016
- assert isinstance(separator, ir.Node)
1017
- assert isinstance(target, ir.Var)
1018
- assert isinstance(strs, tuple)
1019
-
1020
- # Enumerate the strings we're going to be reducing over
1021
- enumerated_conjunctions = []
1022
- index_var, index_type = gen_unique_var(ctx, "idx"), meta_type_to_lqp(types.Int64)
1023
- string_var, string_type = gen_unique_var(ctx, "s"), meta_type_to_lqp(types.String)
1024
- for i, s in enumerate(strs):
1025
- index = to_lqp_value(i, types.Int64)
1026
- string = _translate_term(ctx, s)[0]
1027
- eq_idx = mk_primitive("rel_primitive_eq", [index_var, index])
1028
- eq_string = mk_primitive("rel_primitive_eq", [string_var, string])
1029
- enumerated_conjunctions.append(mk_and([eq_idx, eq_string]))
1030
- body = mk_abstraction([(index_var, index_type), (string_var, string_type)], mk_or(enumerated_conjunctions))
1031
-
1032
- # Make the function we're reducing
1033
- a_var, a_type = gen_unique_var(ctx, "a"), meta_type_to_lqp(types.String)
1034
- b_var, b_type = gen_unique_var(ctx, "b"), meta_type_to_lqp(types.String)
1035
- curr_var, curr_type = gen_unique_var(ctx, "curr"), meta_type_to_lqp(types.String)
1036
- res_var, res_type = gen_unique_var(ctx, "res"), meta_type_to_lqp(types.String)
1037
-
1038
- sep, _ = _translate_term(ctx, separator)
1039
-
1040
- op = mk_abstraction(
1041
- [(a_var, a_type), (b_var, b_type), (curr_var, curr_type)],
1042
- mk_exists([(res_var, res_type)],
1043
- mk_and([
1044
- mk_primitive("rel_primitive_concat", [res_var, b_var, curr_var]),
1045
- mk_primitive("rel_primitive_concat", [a_var, sep, res_var])
1046
- ])
1047
- )
1048
- )
1049
-
1050
- output_term = _translate_term(ctx, target)[0]
1051
-
1052
- return lqp.Reduce(meta=None, op=op, body=body, terms=[output_term])
1053
-
1054
- def _translate_var(ctx: TranslationCtx, term: ir.Var) -> lqp.Var:
1055
- name = ctx.var_names.get_name_by_id(term.id, term.name)
1056
- return lqp.Var(name=name, meta=None)