relationalai 0.13.0.dev0__py3-none-any.whl → 0.13.2__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.
- frontend/debugger/dist/.gitignore +2 -0
- frontend/debugger/dist/assets/favicon-Dy0ZgA6N.png +0 -0
- frontend/debugger/dist/assets/index-Cssla-O7.js +208 -0
- frontend/debugger/dist/assets/index-DlHsYx1V.css +9 -0
- frontend/debugger/dist/index.html +17 -0
- relationalai/__init__.py +256 -1
- relationalai/clients/__init__.py +18 -0
- relationalai/clients/client.py +947 -0
- relationalai/clients/config.py +673 -0
- relationalai/clients/direct_access_client.py +118 -0
- relationalai/clients/exec_txn_poller.py +91 -0
- relationalai/clients/hash_util.py +31 -0
- relationalai/clients/local.py +586 -0
- relationalai/clients/profile_polling.py +73 -0
- relationalai/clients/resources/__init__.py +8 -0
- relationalai/clients/resources/azure/azure.py +502 -0
- relationalai/clients/resources/snowflake/__init__.py +20 -0
- relationalai/clients/resources/snowflake/cli_resources.py +98 -0
- relationalai/clients/resources/snowflake/direct_access_resources.py +734 -0
- relationalai/clients/resources/snowflake/engine_service.py +381 -0
- relationalai/clients/resources/snowflake/engine_state_handlers.py +315 -0
- relationalai/clients/resources/snowflake/error_handlers.py +240 -0
- relationalai/clients/resources/snowflake/export_procedure.py.jinja +249 -0
- relationalai/clients/resources/snowflake/resources_factory.py +99 -0
- relationalai/clients/resources/snowflake/snowflake.py +3185 -0
- relationalai/clients/resources/snowflake/use_index_poller.py +1019 -0
- relationalai/clients/resources/snowflake/use_index_resources.py +188 -0
- relationalai/clients/resources/snowflake/util.py +387 -0
- relationalai/clients/result_helpers.py +420 -0
- relationalai/clients/types.py +118 -0
- relationalai/clients/util.py +356 -0
- relationalai/debugging.py +389 -0
- relationalai/dsl.py +1749 -0
- relationalai/early_access/builder/__init__.py +30 -0
- relationalai/early_access/builder/builder/__init__.py +35 -0
- relationalai/early_access/builder/snowflake/__init__.py +12 -0
- relationalai/early_access/builder/std/__init__.py +25 -0
- relationalai/early_access/builder/std/decimals/__init__.py +12 -0
- relationalai/early_access/builder/std/integers/__init__.py +12 -0
- relationalai/early_access/builder/std/math/__init__.py +12 -0
- relationalai/early_access/builder/std/strings/__init__.py +14 -0
- relationalai/early_access/devtools/__init__.py +12 -0
- relationalai/early_access/devtools/benchmark_lqp/__init__.py +12 -0
- relationalai/early_access/devtools/extract_lqp/__init__.py +12 -0
- relationalai/early_access/dsl/adapters/orm/adapter_qb.py +427 -0
- relationalai/early_access/dsl/adapters/orm/parser.py +636 -0
- relationalai/early_access/dsl/adapters/owl/adapter.py +176 -0
- relationalai/early_access/dsl/adapters/owl/parser.py +160 -0
- relationalai/early_access/dsl/bindings/common.py +402 -0
- relationalai/early_access/dsl/bindings/csv.py +170 -0
- relationalai/early_access/dsl/bindings/legacy/binding_models.py +143 -0
- relationalai/early_access/dsl/bindings/snowflake.py +64 -0
- relationalai/early_access/dsl/codegen/binder.py +411 -0
- relationalai/early_access/dsl/codegen/common.py +79 -0
- relationalai/early_access/dsl/codegen/helpers.py +23 -0
- relationalai/early_access/dsl/codegen/relations.py +700 -0
- relationalai/early_access/dsl/codegen/weaver.py +417 -0
- relationalai/early_access/dsl/core/builders/__init__.py +47 -0
- relationalai/early_access/dsl/core/builders/logic.py +19 -0
- relationalai/early_access/dsl/core/builders/scalar_constraint.py +11 -0
- relationalai/early_access/dsl/core/constraints/predicate/atomic.py +455 -0
- relationalai/early_access/dsl/core/constraints/predicate/universal.py +73 -0
- relationalai/early_access/dsl/core/constraints/scalar.py +310 -0
- relationalai/early_access/dsl/core/context.py +13 -0
- relationalai/early_access/dsl/core/cset.py +132 -0
- relationalai/early_access/dsl/core/exprs/__init__.py +116 -0
- relationalai/early_access/dsl/core/exprs/relational.py +18 -0
- relationalai/early_access/dsl/core/exprs/scalar.py +412 -0
- relationalai/early_access/dsl/core/instances.py +44 -0
- relationalai/early_access/dsl/core/logic/__init__.py +193 -0
- relationalai/early_access/dsl/core/logic/aggregation.py +98 -0
- relationalai/early_access/dsl/core/logic/exists.py +223 -0
- relationalai/early_access/dsl/core/logic/helper.py +163 -0
- relationalai/early_access/dsl/core/namespaces.py +32 -0
- relationalai/early_access/dsl/core/relations.py +276 -0
- relationalai/early_access/dsl/core/rules.py +112 -0
- relationalai/early_access/dsl/core/std/__init__.py +45 -0
- relationalai/early_access/dsl/core/temporal/recall.py +6 -0
- relationalai/early_access/dsl/core/types/__init__.py +270 -0
- relationalai/early_access/dsl/core/types/concepts.py +128 -0
- relationalai/early_access/dsl/core/types/constrained/__init__.py +267 -0
- relationalai/early_access/dsl/core/types/constrained/nominal.py +143 -0
- relationalai/early_access/dsl/core/types/constrained/subtype.py +124 -0
- relationalai/early_access/dsl/core/types/standard.py +92 -0
- relationalai/early_access/dsl/core/types/unconstrained.py +50 -0
- relationalai/early_access/dsl/core/types/variables.py +203 -0
- relationalai/early_access/dsl/ir/compiler.py +318 -0
- relationalai/early_access/dsl/ir/executor.py +260 -0
- relationalai/early_access/dsl/ontologies/constraints.py +88 -0
- relationalai/early_access/dsl/ontologies/export.py +30 -0
- relationalai/early_access/dsl/ontologies/models.py +453 -0
- relationalai/early_access/dsl/ontologies/python_printer.py +303 -0
- relationalai/early_access/dsl/ontologies/readings.py +60 -0
- relationalai/early_access/dsl/ontologies/relationships.py +322 -0
- relationalai/early_access/dsl/ontologies/roles.py +87 -0
- relationalai/early_access/dsl/ontologies/subtyping.py +55 -0
- relationalai/early_access/dsl/orm/constraints.py +438 -0
- relationalai/early_access/dsl/orm/measures/dimensions.py +200 -0
- relationalai/early_access/dsl/orm/measures/initializer.py +16 -0
- relationalai/early_access/dsl/orm/measures/measure_rules.py +275 -0
- relationalai/early_access/dsl/orm/measures/measures.py +299 -0
- relationalai/early_access/dsl/orm/measures/role_exprs.py +268 -0
- relationalai/early_access/dsl/orm/models.py +256 -0
- relationalai/early_access/dsl/orm/object_oriented_printer.py +344 -0
- relationalai/early_access/dsl/orm/printer.py +469 -0
- relationalai/early_access/dsl/orm/reasoners.py +480 -0
- relationalai/early_access/dsl/orm/relations.py +19 -0
- relationalai/early_access/dsl/orm/relationships.py +251 -0
- relationalai/early_access/dsl/orm/types.py +42 -0
- relationalai/early_access/dsl/orm/utils.py +79 -0
- relationalai/early_access/dsl/orm/verb.py +204 -0
- relationalai/early_access/dsl/physical_metadata/tables.py +133 -0
- relationalai/early_access/dsl/relations.py +170 -0
- relationalai/early_access/dsl/rulesets.py +69 -0
- relationalai/early_access/dsl/schemas/__init__.py +450 -0
- relationalai/early_access/dsl/schemas/builder.py +48 -0
- relationalai/early_access/dsl/schemas/comp_names.py +51 -0
- relationalai/early_access/dsl/schemas/components.py +203 -0
- relationalai/early_access/dsl/schemas/contexts.py +156 -0
- relationalai/early_access/dsl/schemas/exprs.py +89 -0
- relationalai/early_access/dsl/schemas/fragments.py +464 -0
- relationalai/early_access/dsl/serialization.py +79 -0
- relationalai/early_access/dsl/serialize/exporter.py +163 -0
- relationalai/early_access/dsl/snow/api.py +105 -0
- relationalai/early_access/dsl/snow/common.py +76 -0
- relationalai/early_access/dsl/state_mgmt/__init__.py +129 -0
- relationalai/early_access/dsl/state_mgmt/state_charts.py +125 -0
- relationalai/early_access/dsl/state_mgmt/transitions.py +130 -0
- relationalai/early_access/dsl/types/__init__.py +40 -0
- relationalai/early_access/dsl/types/concepts.py +12 -0
- relationalai/early_access/dsl/types/entities.py +135 -0
- relationalai/early_access/dsl/types/values.py +17 -0
- relationalai/early_access/dsl/utils.py +102 -0
- relationalai/early_access/graphs/__init__.py +13 -0
- relationalai/early_access/lqp/__init__.py +12 -0
- relationalai/early_access/lqp/compiler/__init__.py +12 -0
- relationalai/early_access/lqp/constructors/__init__.py +18 -0
- relationalai/early_access/lqp/executor/__init__.py +12 -0
- relationalai/early_access/lqp/ir/__init__.py +12 -0
- relationalai/early_access/lqp/passes/__init__.py +12 -0
- relationalai/early_access/lqp/pragmas/__init__.py +12 -0
- relationalai/early_access/lqp/primitives/__init__.py +12 -0
- relationalai/early_access/lqp/types/__init__.py +12 -0
- relationalai/early_access/lqp/utils/__init__.py +12 -0
- relationalai/early_access/lqp/validators/__init__.py +12 -0
- relationalai/early_access/metamodel/__init__.py +58 -0
- relationalai/early_access/metamodel/builtins/__init__.py +12 -0
- relationalai/early_access/metamodel/compiler/__init__.py +12 -0
- relationalai/early_access/metamodel/dependency/__init__.py +12 -0
- relationalai/early_access/metamodel/factory/__init__.py +17 -0
- relationalai/early_access/metamodel/helpers/__init__.py +12 -0
- relationalai/early_access/metamodel/ir/__init__.py +14 -0
- relationalai/early_access/metamodel/rewrite/__init__.py +7 -0
- relationalai/early_access/metamodel/typer/__init__.py +3 -0
- relationalai/early_access/metamodel/typer/typer/__init__.py +12 -0
- relationalai/early_access/metamodel/types/__init__.py +15 -0
- relationalai/early_access/metamodel/util/__init__.py +15 -0
- relationalai/early_access/metamodel/visitor/__init__.py +12 -0
- relationalai/early_access/rel/__init__.py +12 -0
- relationalai/early_access/rel/executor/__init__.py +12 -0
- relationalai/early_access/rel/rel_utils/__init__.py +12 -0
- relationalai/early_access/rel/rewrite/__init__.py +7 -0
- relationalai/early_access/solvers/__init__.py +19 -0
- relationalai/early_access/sql/__init__.py +11 -0
- relationalai/early_access/sql/executor/__init__.py +3 -0
- relationalai/early_access/sql/rewrite/__init__.py +3 -0
- relationalai/early_access/tests/logging/__init__.py +12 -0
- relationalai/early_access/tests/test_snapshot_base/__init__.py +12 -0
- relationalai/early_access/tests/utils/__init__.py +12 -0
- relationalai/environments/__init__.py +35 -0
- relationalai/environments/base.py +381 -0
- relationalai/environments/colab.py +14 -0
- relationalai/environments/generic.py +71 -0
- relationalai/environments/ipython.py +68 -0
- relationalai/environments/jupyter.py +9 -0
- relationalai/environments/snowbook.py +169 -0
- relationalai/errors.py +2496 -0
- relationalai/experimental/SF.py +38 -0
- relationalai/experimental/inspect.py +47 -0
- relationalai/experimental/pathfinder/__init__.py +158 -0
- relationalai/experimental/pathfinder/api.py +160 -0
- relationalai/experimental/pathfinder/automaton.py +584 -0
- relationalai/experimental/pathfinder/bridge.py +226 -0
- relationalai/experimental/pathfinder/compiler.py +416 -0
- relationalai/experimental/pathfinder/datalog.py +214 -0
- relationalai/experimental/pathfinder/diagnostics.py +56 -0
- relationalai/experimental/pathfinder/filter.py +236 -0
- relationalai/experimental/pathfinder/glushkov.py +439 -0
- relationalai/experimental/pathfinder/options.py +265 -0
- relationalai/experimental/pathfinder/pathfinder-v0.7.0.rel +1951 -0
- relationalai/experimental/pathfinder/rpq.py +344 -0
- relationalai/experimental/pathfinder/transition.py +200 -0
- relationalai/experimental/pathfinder/utils.py +26 -0
- relationalai/experimental/paths/README.md +107 -0
- relationalai/experimental/paths/api.py +143 -0
- relationalai/experimental/paths/benchmarks/grid_graph.py +37 -0
- relationalai/experimental/paths/code_organization.md +2 -0
- relationalai/experimental/paths/examples/Movies.ipynb +16328 -0
- relationalai/experimental/paths/examples/basic_example.py +40 -0
- relationalai/experimental/paths/examples/minimal_engine_warmup.py +3 -0
- relationalai/experimental/paths/examples/movie_example.py +77 -0
- relationalai/experimental/paths/examples/movies_data/actedin.csv +193 -0
- relationalai/experimental/paths/examples/movies_data/directed.csv +45 -0
- relationalai/experimental/paths/examples/movies_data/follows.csv +7 -0
- relationalai/experimental/paths/examples/movies_data/movies.csv +39 -0
- relationalai/experimental/paths/examples/movies_data/person.csv +134 -0
- relationalai/experimental/paths/examples/movies_data/produced.csv +16 -0
- relationalai/experimental/paths/examples/movies_data/ratings.csv +10 -0
- relationalai/experimental/paths/examples/movies_data/wrote.csv +11 -0
- relationalai/experimental/paths/examples/paths_benchmark.py +115 -0
- relationalai/experimental/paths/examples/paths_example.py +116 -0
- relationalai/experimental/paths/examples/pattern_to_automaton.py +28 -0
- relationalai/experimental/paths/find_paths_via_automaton.py +85 -0
- relationalai/experimental/paths/graph.py +185 -0
- relationalai/experimental/paths/path_algorithms/find_paths.py +280 -0
- relationalai/experimental/paths/path_algorithms/one_sided_ball_repetition.py +26 -0
- relationalai/experimental/paths/path_algorithms/one_sided_ball_upto.py +111 -0
- relationalai/experimental/paths/path_algorithms/single.py +59 -0
- relationalai/experimental/paths/path_algorithms/two_sided_balls_repetition.py +39 -0
- relationalai/experimental/paths/path_algorithms/two_sided_balls_upto.py +103 -0
- relationalai/experimental/paths/path_algorithms/usp-old.py +130 -0
- relationalai/experimental/paths/path_algorithms/usp-tuple.py +183 -0
- relationalai/experimental/paths/path_algorithms/usp.py +150 -0
- relationalai/experimental/paths/product_graph.py +93 -0
- relationalai/experimental/paths/rpq/automaton.py +584 -0
- relationalai/experimental/paths/rpq/diagnostics.py +56 -0
- relationalai/experimental/paths/rpq/rpq.py +378 -0
- relationalai/experimental/paths/tests/tests_limit_sp_max_length.py +90 -0
- relationalai/experimental/paths/tests/tests_limit_sp_multiple.py +119 -0
- relationalai/experimental/paths/tests/tests_limit_sp_single.py +104 -0
- relationalai/experimental/paths/tests/tests_limit_walks_multiple.py +113 -0
- relationalai/experimental/paths/tests/tests_limit_walks_single.py +149 -0
- relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_multiple.py +70 -0
- relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_single.py +64 -0
- relationalai/experimental/paths/tests/tests_one_sided_ball_upto_multiple.py +115 -0
- relationalai/experimental/paths/tests/tests_one_sided_ball_upto_single.py +75 -0
- relationalai/experimental/paths/tests/tests_single_paths.py +152 -0
- relationalai/experimental/paths/tests/tests_single_walks.py +208 -0
- relationalai/experimental/paths/tests/tests_single_walks_undirected.py +297 -0
- relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_multiple.py +107 -0
- relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_single.py +76 -0
- relationalai/experimental/paths/tests/tests_two_sided_balls_upto_multiple.py +76 -0
- relationalai/experimental/paths/tests/tests_two_sided_balls_upto_single.py +110 -0
- relationalai/experimental/paths/tests/tests_usp_nsp_multiple.py +229 -0
- relationalai/experimental/paths/tests/tests_usp_nsp_single.py +108 -0
- relationalai/experimental/paths/tree_agg.py +168 -0
- relationalai/experimental/paths/utilities/iterators.py +27 -0
- relationalai/experimental/paths/utilities/prefix_sum.py +91 -0
- relationalai/experimental/solvers.py +1087 -0
- relationalai/loaders/csv.py +195 -0
- relationalai/loaders/loader.py +177 -0
- relationalai/loaders/types.py +23 -0
- relationalai/rel_emitter.py +373 -0
- relationalai/rel_utils.py +185 -0
- relationalai/semantics/__init__.py +22 -146
- relationalai/semantics/designs/query_builder/identify_by.md +106 -0
- relationalai/semantics/devtools/benchmark_lqp.py +535 -0
- relationalai/semantics/devtools/compilation_manager.py +294 -0
- relationalai/semantics/devtools/extract_lqp.py +110 -0
- relationalai/semantics/internal/internal.py +3785 -0
- relationalai/semantics/internal/snowflake.py +325 -0
- relationalai/semantics/lqp/README.md +34 -0
- relationalai/semantics/lqp/builtins.py +16 -0
- relationalai/semantics/lqp/compiler.py +22 -0
- relationalai/semantics/lqp/constructors.py +68 -0
- relationalai/semantics/lqp/executor.py +469 -0
- relationalai/semantics/lqp/intrinsics.py +24 -0
- relationalai/semantics/lqp/model2lqp.py +877 -0
- relationalai/semantics/lqp/passes.py +680 -0
- relationalai/semantics/lqp/primitives.py +252 -0
- relationalai/semantics/lqp/result_helpers.py +202 -0
- relationalai/semantics/lqp/rewrite/annotate_constraints.py +57 -0
- relationalai/semantics/lqp/rewrite/cdc.py +216 -0
- relationalai/semantics/lqp/rewrite/extract_common.py +338 -0
- relationalai/semantics/lqp/rewrite/extract_keys.py +512 -0
- relationalai/semantics/lqp/rewrite/function_annotations.py +114 -0
- relationalai/semantics/lqp/rewrite/functional_dependencies.py +314 -0
- relationalai/semantics/lqp/rewrite/quantify_vars.py +296 -0
- relationalai/semantics/lqp/rewrite/splinter.py +76 -0
- relationalai/semantics/lqp/types.py +101 -0
- relationalai/semantics/lqp/utils.py +160 -0
- relationalai/semantics/lqp/validators.py +57 -0
- relationalai/semantics/metamodel/__init__.py +40 -6
- relationalai/semantics/metamodel/builtins.py +771 -205
- relationalai/semantics/metamodel/compiler.py +133 -0
- relationalai/semantics/metamodel/dependency.py +862 -0
- relationalai/semantics/metamodel/executor.py +61 -0
- relationalai/semantics/metamodel/factory.py +287 -0
- relationalai/semantics/metamodel/helpers.py +361 -0
- relationalai/semantics/metamodel/rewrite/discharge_constraints.py +39 -0
- relationalai/semantics/metamodel/rewrite/dnf_union_splitter.py +210 -0
- relationalai/semantics/metamodel/rewrite/extract_nested_logicals.py +78 -0
- relationalai/semantics/metamodel/rewrite/flatten.py +554 -0
- relationalai/semantics/metamodel/rewrite/format_outputs.py +165 -0
- relationalai/semantics/metamodel/typer/checker.py +353 -0
- relationalai/semantics/metamodel/typer/typer.py +1399 -0
- relationalai/semantics/metamodel/util.py +506 -0
- relationalai/semantics/reasoners/__init__.py +10 -0
- relationalai/semantics/reasoners/graph/README.md +620 -0
- relationalai/semantics/reasoners/graph/__init__.py +37 -0
- relationalai/semantics/reasoners/graph/core.py +9019 -0
- relationalai/semantics/reasoners/graph/design/beyond_demand_transform.md +797 -0
- relationalai/semantics/reasoners/graph/tests/README.md +21 -0
- relationalai/semantics/reasoners/optimization/__init__.py +68 -0
- relationalai/semantics/reasoners/optimization/common.py +88 -0
- relationalai/semantics/reasoners/optimization/solvers_dev.py +568 -0
- relationalai/semantics/reasoners/optimization/solvers_pb.py +1414 -0
- relationalai/semantics/rel/builtins.py +40 -0
- relationalai/semantics/rel/compiler.py +989 -0
- relationalai/semantics/rel/executor.py +362 -0
- relationalai/semantics/rel/rel.py +482 -0
- relationalai/semantics/rel/rel_utils.py +276 -0
- relationalai/semantics/snowflake/__init__.py +3 -0
- relationalai/semantics/sql/compiler.py +2503 -0
- relationalai/semantics/sql/executor/duck_db.py +52 -0
- relationalai/semantics/sql/executor/result_helpers.py +64 -0
- relationalai/semantics/sql/executor/snowflake.py +149 -0
- relationalai/semantics/sql/rewrite/denormalize.py +222 -0
- relationalai/semantics/sql/rewrite/double_negation.py +49 -0
- relationalai/semantics/sql/rewrite/recursive_union.py +127 -0
- relationalai/semantics/sql/rewrite/sort_output_query.py +246 -0
- relationalai/semantics/sql/sql.py +504 -0
- relationalai/semantics/std/__init__.py +40 -60
- relationalai/semantics/std/constraints.py +43 -37
- relationalai/semantics/std/datetime.py +135 -246
- relationalai/semantics/std/decimals.py +52 -45
- relationalai/semantics/std/floats.py +5 -13
- relationalai/semantics/std/integers.py +11 -26
- relationalai/semantics/std/math.py +112 -183
- relationalai/semantics/std/pragmas.py +11 -0
- relationalai/semantics/std/re.py +62 -80
- relationalai/semantics/std/std.py +14 -0
- relationalai/semantics/std/strings.py +60 -117
- relationalai/semantics/tests/test_snapshot_abstract.py +143 -0
- relationalai/semantics/tests/test_snapshot_base.py +9 -0
- relationalai/semantics/tests/utils.py +46 -0
- relationalai/std/__init__.py +70 -0
- relationalai/tools/cli.py +2089 -0
- relationalai/tools/cli_controls.py +1826 -0
- relationalai/tools/cli_helpers.py +802 -0
- relationalai/tools/debugger.py +183 -289
- relationalai/tools/debugger_client.py +109 -0
- relationalai/tools/debugger_server.py +302 -0
- relationalai/tools/dev.py +685 -0
- relationalai/tools/notes +7 -0
- relationalai/tools/qb_debugger.py +425 -0
- relationalai/util/clean_up_databases.py +95 -0
- relationalai/util/format.py +106 -48
- relationalai/util/list_databases.py +9 -0
- relationalai/util/otel_configuration.py +26 -0
- relationalai/util/otel_handler.py +484 -0
- relationalai/util/snowflake_handler.py +88 -0
- relationalai/util/span_format_test.py +43 -0
- relationalai/util/span_tracker.py +207 -0
- relationalai/util/spans_file_handler.py +72 -0
- relationalai/util/tracing_handler.py +34 -0
- relationalai-0.13.2.dist-info/METADATA +74 -0
- relationalai-0.13.2.dist-info/RECORD +460 -0
- relationalai-0.13.2.dist-info/WHEEL +4 -0
- relationalai-0.13.2.dist-info/entry_points.txt +3 -0
- relationalai-0.13.2.dist-info/licenses/LICENSE +202 -0
- relationalai_test_util/__init__.py +4 -0
- relationalai_test_util/fixtures.py +233 -0
- relationalai_test_util/snapshot.py +252 -0
- relationalai_test_util/traceback.py +118 -0
- relationalai/config/__init__.py +0 -56
- relationalai/config/config.py +0 -289
- relationalai/config/config_fields.py +0 -86
- relationalai/config/connections/__init__.py +0 -46
- relationalai/config/connections/base.py +0 -23
- relationalai/config/connections/duckdb.py +0 -29
- relationalai/config/connections/snowflake.py +0 -243
- relationalai/config/external/__init__.py +0 -17
- relationalai/config/external/dbt_converter.py +0 -101
- relationalai/config/external/dbt_models.py +0 -93
- relationalai/config/external/snowflake_converter.py +0 -41
- relationalai/config/external/snowflake_models.py +0 -85
- relationalai/config/external/utils.py +0 -19
- relationalai/semantics/backends/lqp/annotations.py +0 -11
- relationalai/semantics/backends/sql/sql_compiler.py +0 -327
- relationalai/semantics/frontend/base.py +0 -1707
- relationalai/semantics/frontend/core.py +0 -179
- relationalai/semantics/frontend/front_compiler.py +0 -1313
- relationalai/semantics/frontend/pprint.py +0 -408
- relationalai/semantics/metamodel/metamodel.py +0 -437
- relationalai/semantics/metamodel/metamodel_analyzer.py +0 -519
- relationalai/semantics/metamodel/metamodel_compiler.py +0 -0
- relationalai/semantics/metamodel/pprint.py +0 -412
- relationalai/semantics/metamodel/rewriter.py +0 -266
- relationalai/semantics/metamodel/typer.py +0 -1378
- relationalai/semantics/std/aggregates.py +0 -149
- relationalai/semantics/std/common.py +0 -44
- relationalai/semantics/std/numbers.py +0 -86
- relationalai/shims/executor.py +0 -147
- relationalai/shims/helpers.py +0 -126
- relationalai/shims/hoister.py +0 -221
- relationalai/shims/mm2v0.py +0 -1290
- relationalai/tools/cli/__init__.py +0 -6
- relationalai/tools/cli/cli.py +0 -90
- relationalai/tools/cli/components/__init__.py +0 -5
- relationalai/tools/cli/components/progress_reader.py +0 -1524
- relationalai/tools/cli/components/utils.py +0 -58
- relationalai/tools/cli/config_template.py +0 -45
- relationalai/tools/cli/dev.py +0 -19
- relationalai/tools/typer_debugger.py +0 -93
- relationalai/util/dataclasses.py +0 -43
- relationalai/util/docutils.py +0 -40
- relationalai/util/error.py +0 -199
- relationalai/util/naming.py +0 -145
- relationalai/util/python.py +0 -35
- relationalai/util/runtime.py +0 -156
- relationalai/util/schema.py +0 -197
- relationalai/util/source.py +0 -185
- relationalai/util/structures.py +0 -163
- relationalai/util/tracing.py +0 -261
- relationalai-0.13.0.dev0.dist-info/METADATA +0 -46
- relationalai-0.13.0.dev0.dist-info/RECORD +0 -488
- relationalai-0.13.0.dev0.dist-info/WHEEL +0 -5
- relationalai-0.13.0.dev0.dist-info/entry_points.txt +0 -3
- relationalai-0.13.0.dev0.dist-info/top_level.txt +0 -2
- v0/relationalai/__init__.py +0 -216
- v0/relationalai/clients/__init__.py +0 -5
- v0/relationalai/clients/azure.py +0 -477
- v0/relationalai/clients/client.py +0 -912
- v0/relationalai/clients/config.py +0 -673
- v0/relationalai/clients/direct_access_client.py +0 -118
- v0/relationalai/clients/hash_util.py +0 -31
- v0/relationalai/clients/local.py +0 -571
- v0/relationalai/clients/profile_polling.py +0 -73
- v0/relationalai/clients/result_helpers.py +0 -420
- v0/relationalai/clients/snowflake.py +0 -3869
- v0/relationalai/clients/types.py +0 -113
- v0/relationalai/clients/use_index_poller.py +0 -980
- v0/relationalai/clients/util.py +0 -356
- v0/relationalai/debugging.py +0 -389
- v0/relationalai/dsl.py +0 -1749
- v0/relationalai/early_access/builder/__init__.py +0 -30
- v0/relationalai/early_access/builder/builder/__init__.py +0 -35
- v0/relationalai/early_access/builder/snowflake/__init__.py +0 -12
- v0/relationalai/early_access/builder/std/__init__.py +0 -25
- v0/relationalai/early_access/builder/std/decimals/__init__.py +0 -12
- v0/relationalai/early_access/builder/std/integers/__init__.py +0 -12
- v0/relationalai/early_access/builder/std/math/__init__.py +0 -12
- v0/relationalai/early_access/builder/std/strings/__init__.py +0 -14
- v0/relationalai/early_access/devtools/__init__.py +0 -12
- v0/relationalai/early_access/devtools/benchmark_lqp/__init__.py +0 -12
- v0/relationalai/early_access/devtools/extract_lqp/__init__.py +0 -12
- v0/relationalai/early_access/dsl/adapters/orm/adapter_qb.py +0 -427
- v0/relationalai/early_access/dsl/adapters/orm/parser.py +0 -636
- v0/relationalai/early_access/dsl/adapters/owl/adapter.py +0 -176
- v0/relationalai/early_access/dsl/adapters/owl/parser.py +0 -160
- v0/relationalai/early_access/dsl/bindings/common.py +0 -402
- v0/relationalai/early_access/dsl/bindings/csv.py +0 -170
- v0/relationalai/early_access/dsl/bindings/legacy/binding_models.py +0 -143
- v0/relationalai/early_access/dsl/bindings/snowflake.py +0 -64
- v0/relationalai/early_access/dsl/codegen/binder.py +0 -411
- v0/relationalai/early_access/dsl/codegen/common.py +0 -79
- v0/relationalai/early_access/dsl/codegen/helpers.py +0 -23
- v0/relationalai/early_access/dsl/codegen/relations.py +0 -700
- v0/relationalai/early_access/dsl/codegen/weaver.py +0 -417
- v0/relationalai/early_access/dsl/core/builders/__init__.py +0 -47
- v0/relationalai/early_access/dsl/core/builders/logic.py +0 -19
- v0/relationalai/early_access/dsl/core/builders/scalar_constraint.py +0 -11
- v0/relationalai/early_access/dsl/core/constraints/predicate/atomic.py +0 -455
- v0/relationalai/early_access/dsl/core/constraints/predicate/universal.py +0 -73
- v0/relationalai/early_access/dsl/core/constraints/scalar.py +0 -310
- v0/relationalai/early_access/dsl/core/context.py +0 -13
- v0/relationalai/early_access/dsl/core/cset.py +0 -132
- v0/relationalai/early_access/dsl/core/exprs/__init__.py +0 -116
- v0/relationalai/early_access/dsl/core/exprs/relational.py +0 -18
- v0/relationalai/early_access/dsl/core/exprs/scalar.py +0 -412
- v0/relationalai/early_access/dsl/core/instances.py +0 -44
- v0/relationalai/early_access/dsl/core/logic/__init__.py +0 -193
- v0/relationalai/early_access/dsl/core/logic/aggregation.py +0 -98
- v0/relationalai/early_access/dsl/core/logic/exists.py +0 -223
- v0/relationalai/early_access/dsl/core/logic/helper.py +0 -163
- v0/relationalai/early_access/dsl/core/namespaces.py +0 -32
- v0/relationalai/early_access/dsl/core/relations.py +0 -276
- v0/relationalai/early_access/dsl/core/rules.py +0 -112
- v0/relationalai/early_access/dsl/core/std/__init__.py +0 -45
- v0/relationalai/early_access/dsl/core/temporal/recall.py +0 -6
- v0/relationalai/early_access/dsl/core/types/__init__.py +0 -270
- v0/relationalai/early_access/dsl/core/types/concepts.py +0 -128
- v0/relationalai/early_access/dsl/core/types/constrained/__init__.py +0 -267
- v0/relationalai/early_access/dsl/core/types/constrained/nominal.py +0 -143
- v0/relationalai/early_access/dsl/core/types/constrained/subtype.py +0 -124
- v0/relationalai/early_access/dsl/core/types/standard.py +0 -92
- v0/relationalai/early_access/dsl/core/types/unconstrained.py +0 -50
- v0/relationalai/early_access/dsl/core/types/variables.py +0 -203
- v0/relationalai/early_access/dsl/ir/compiler.py +0 -318
- v0/relationalai/early_access/dsl/ir/executor.py +0 -260
- v0/relationalai/early_access/dsl/ontologies/constraints.py +0 -88
- v0/relationalai/early_access/dsl/ontologies/export.py +0 -30
- v0/relationalai/early_access/dsl/ontologies/models.py +0 -453
- v0/relationalai/early_access/dsl/ontologies/python_printer.py +0 -303
- v0/relationalai/early_access/dsl/ontologies/readings.py +0 -60
- v0/relationalai/early_access/dsl/ontologies/relationships.py +0 -322
- v0/relationalai/early_access/dsl/ontologies/roles.py +0 -87
- v0/relationalai/early_access/dsl/ontologies/subtyping.py +0 -55
- v0/relationalai/early_access/dsl/orm/constraints.py +0 -438
- v0/relationalai/early_access/dsl/orm/measures/dimensions.py +0 -200
- v0/relationalai/early_access/dsl/orm/measures/initializer.py +0 -16
- v0/relationalai/early_access/dsl/orm/measures/measure_rules.py +0 -275
- v0/relationalai/early_access/dsl/orm/measures/measures.py +0 -299
- v0/relationalai/early_access/dsl/orm/measures/role_exprs.py +0 -268
- v0/relationalai/early_access/dsl/orm/models.py +0 -256
- v0/relationalai/early_access/dsl/orm/object_oriented_printer.py +0 -344
- v0/relationalai/early_access/dsl/orm/printer.py +0 -469
- v0/relationalai/early_access/dsl/orm/reasoners.py +0 -480
- v0/relationalai/early_access/dsl/orm/relations.py +0 -19
- v0/relationalai/early_access/dsl/orm/relationships.py +0 -251
- v0/relationalai/early_access/dsl/orm/types.py +0 -42
- v0/relationalai/early_access/dsl/orm/utils.py +0 -79
- v0/relationalai/early_access/dsl/orm/verb.py +0 -204
- v0/relationalai/early_access/dsl/physical_metadata/tables.py +0 -133
- v0/relationalai/early_access/dsl/relations.py +0 -170
- v0/relationalai/early_access/dsl/rulesets.py +0 -69
- v0/relationalai/early_access/dsl/schemas/__init__.py +0 -450
- v0/relationalai/early_access/dsl/schemas/builder.py +0 -48
- v0/relationalai/early_access/dsl/schemas/comp_names.py +0 -51
- v0/relationalai/early_access/dsl/schemas/components.py +0 -203
- v0/relationalai/early_access/dsl/schemas/contexts.py +0 -156
- v0/relationalai/early_access/dsl/schemas/exprs.py +0 -89
- v0/relationalai/early_access/dsl/schemas/fragments.py +0 -464
- v0/relationalai/early_access/dsl/serialization.py +0 -79
- v0/relationalai/early_access/dsl/serialize/exporter.py +0 -163
- v0/relationalai/early_access/dsl/snow/api.py +0 -104
- v0/relationalai/early_access/dsl/snow/common.py +0 -76
- v0/relationalai/early_access/dsl/state_mgmt/__init__.py +0 -129
- v0/relationalai/early_access/dsl/state_mgmt/state_charts.py +0 -125
- v0/relationalai/early_access/dsl/state_mgmt/transitions.py +0 -130
- v0/relationalai/early_access/dsl/types/__init__.py +0 -40
- v0/relationalai/early_access/dsl/types/concepts.py +0 -12
- v0/relationalai/early_access/dsl/types/entities.py +0 -135
- v0/relationalai/early_access/dsl/types/values.py +0 -17
- v0/relationalai/early_access/dsl/utils.py +0 -102
- v0/relationalai/early_access/graphs/__init__.py +0 -13
- v0/relationalai/early_access/lqp/__init__.py +0 -12
- v0/relationalai/early_access/lqp/compiler/__init__.py +0 -12
- v0/relationalai/early_access/lqp/constructors/__init__.py +0 -18
- v0/relationalai/early_access/lqp/executor/__init__.py +0 -12
- v0/relationalai/early_access/lqp/ir/__init__.py +0 -12
- v0/relationalai/early_access/lqp/passes/__init__.py +0 -12
- v0/relationalai/early_access/lqp/pragmas/__init__.py +0 -12
- v0/relationalai/early_access/lqp/primitives/__init__.py +0 -12
- v0/relationalai/early_access/lqp/types/__init__.py +0 -12
- v0/relationalai/early_access/lqp/utils/__init__.py +0 -12
- v0/relationalai/early_access/lqp/validators/__init__.py +0 -12
- v0/relationalai/early_access/metamodel/__init__.py +0 -58
- v0/relationalai/early_access/metamodel/builtins/__init__.py +0 -12
- v0/relationalai/early_access/metamodel/compiler/__init__.py +0 -12
- v0/relationalai/early_access/metamodel/dependency/__init__.py +0 -12
- v0/relationalai/early_access/metamodel/factory/__init__.py +0 -17
- v0/relationalai/early_access/metamodel/helpers/__init__.py +0 -12
- v0/relationalai/early_access/metamodel/ir/__init__.py +0 -14
- v0/relationalai/early_access/metamodel/rewrite/__init__.py +0 -7
- v0/relationalai/early_access/metamodel/typer/__init__.py +0 -3
- v0/relationalai/early_access/metamodel/typer/typer/__init__.py +0 -12
- v0/relationalai/early_access/metamodel/types/__init__.py +0 -15
- v0/relationalai/early_access/metamodel/util/__init__.py +0 -15
- v0/relationalai/early_access/metamodel/visitor/__init__.py +0 -12
- v0/relationalai/early_access/rel/__init__.py +0 -12
- v0/relationalai/early_access/rel/executor/__init__.py +0 -12
- v0/relationalai/early_access/rel/rel_utils/__init__.py +0 -12
- v0/relationalai/early_access/rel/rewrite/__init__.py +0 -7
- v0/relationalai/early_access/solvers/__init__.py +0 -19
- v0/relationalai/early_access/sql/__init__.py +0 -11
- v0/relationalai/early_access/sql/executor/__init__.py +0 -3
- v0/relationalai/early_access/sql/rewrite/__init__.py +0 -3
- v0/relationalai/early_access/tests/logging/__init__.py +0 -12
- v0/relationalai/early_access/tests/test_snapshot_base/__init__.py +0 -12
- v0/relationalai/early_access/tests/utils/__init__.py +0 -12
- v0/relationalai/environments/__init__.py +0 -35
- v0/relationalai/environments/base.py +0 -381
- v0/relationalai/environments/colab.py +0 -14
- v0/relationalai/environments/generic.py +0 -71
- v0/relationalai/environments/ipython.py +0 -68
- v0/relationalai/environments/jupyter.py +0 -9
- v0/relationalai/environments/snowbook.py +0 -169
- v0/relationalai/errors.py +0 -2455
- v0/relationalai/experimental/SF.py +0 -38
- v0/relationalai/experimental/inspect.py +0 -47
- v0/relationalai/experimental/pathfinder/__init__.py +0 -158
- v0/relationalai/experimental/pathfinder/api.py +0 -160
- v0/relationalai/experimental/pathfinder/automaton.py +0 -584
- v0/relationalai/experimental/pathfinder/bridge.py +0 -226
- v0/relationalai/experimental/pathfinder/compiler.py +0 -416
- v0/relationalai/experimental/pathfinder/datalog.py +0 -214
- v0/relationalai/experimental/pathfinder/diagnostics.py +0 -56
- v0/relationalai/experimental/pathfinder/filter.py +0 -236
- v0/relationalai/experimental/pathfinder/glushkov.py +0 -439
- v0/relationalai/experimental/pathfinder/options.py +0 -265
- v0/relationalai/experimental/pathfinder/rpq.py +0 -344
- v0/relationalai/experimental/pathfinder/transition.py +0 -200
- v0/relationalai/experimental/pathfinder/utils.py +0 -26
- v0/relationalai/experimental/paths/api.py +0 -143
- v0/relationalai/experimental/paths/benchmarks/grid_graph.py +0 -37
- v0/relationalai/experimental/paths/examples/basic_example.py +0 -40
- v0/relationalai/experimental/paths/examples/minimal_engine_warmup.py +0 -3
- v0/relationalai/experimental/paths/examples/movie_example.py +0 -77
- v0/relationalai/experimental/paths/examples/paths_benchmark.py +0 -115
- v0/relationalai/experimental/paths/examples/paths_example.py +0 -116
- v0/relationalai/experimental/paths/examples/pattern_to_automaton.py +0 -28
- v0/relationalai/experimental/paths/find_paths_via_automaton.py +0 -85
- v0/relationalai/experimental/paths/graph.py +0 -185
- v0/relationalai/experimental/paths/path_algorithms/find_paths.py +0 -280
- v0/relationalai/experimental/paths/path_algorithms/one_sided_ball_repetition.py +0 -26
- v0/relationalai/experimental/paths/path_algorithms/one_sided_ball_upto.py +0 -111
- v0/relationalai/experimental/paths/path_algorithms/single.py +0 -59
- v0/relationalai/experimental/paths/path_algorithms/two_sided_balls_repetition.py +0 -39
- v0/relationalai/experimental/paths/path_algorithms/two_sided_balls_upto.py +0 -103
- v0/relationalai/experimental/paths/path_algorithms/usp-old.py +0 -130
- v0/relationalai/experimental/paths/path_algorithms/usp-tuple.py +0 -183
- v0/relationalai/experimental/paths/path_algorithms/usp.py +0 -150
- v0/relationalai/experimental/paths/product_graph.py +0 -93
- v0/relationalai/experimental/paths/rpq/automaton.py +0 -584
- v0/relationalai/experimental/paths/rpq/diagnostics.py +0 -56
- v0/relationalai/experimental/paths/rpq/rpq.py +0 -378
- v0/relationalai/experimental/paths/tests/tests_limit_sp_max_length.py +0 -90
- v0/relationalai/experimental/paths/tests/tests_limit_sp_multiple.py +0 -119
- v0/relationalai/experimental/paths/tests/tests_limit_sp_single.py +0 -104
- v0/relationalai/experimental/paths/tests/tests_limit_walks_multiple.py +0 -113
- v0/relationalai/experimental/paths/tests/tests_limit_walks_single.py +0 -149
- v0/relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_multiple.py +0 -70
- v0/relationalai/experimental/paths/tests/tests_one_sided_ball_repetition_single.py +0 -64
- v0/relationalai/experimental/paths/tests/tests_one_sided_ball_upto_multiple.py +0 -115
- v0/relationalai/experimental/paths/tests/tests_one_sided_ball_upto_single.py +0 -75
- v0/relationalai/experimental/paths/tests/tests_single_paths.py +0 -152
- v0/relationalai/experimental/paths/tests/tests_single_walks.py +0 -208
- v0/relationalai/experimental/paths/tests/tests_single_walks_undirected.py +0 -297
- v0/relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_multiple.py +0 -107
- v0/relationalai/experimental/paths/tests/tests_two_sided_balls_repetition_single.py +0 -76
- v0/relationalai/experimental/paths/tests/tests_two_sided_balls_upto_multiple.py +0 -76
- v0/relationalai/experimental/paths/tests/tests_two_sided_balls_upto_single.py +0 -110
- v0/relationalai/experimental/paths/tests/tests_usp_nsp_multiple.py +0 -229
- v0/relationalai/experimental/paths/tests/tests_usp_nsp_single.py +0 -108
- v0/relationalai/experimental/paths/tree_agg.py +0 -168
- v0/relationalai/experimental/paths/utilities/iterators.py +0 -27
- v0/relationalai/experimental/paths/utilities/prefix_sum.py +0 -91
- v0/relationalai/experimental/solvers.py +0 -1087
- v0/relationalai/loaders/csv.py +0 -195
- v0/relationalai/loaders/loader.py +0 -177
- v0/relationalai/loaders/types.py +0 -23
- v0/relationalai/rel_emitter.py +0 -373
- v0/relationalai/rel_utils.py +0 -185
- v0/relationalai/semantics/__init__.py +0 -29
- v0/relationalai/semantics/devtools/benchmark_lqp.py +0 -536
- v0/relationalai/semantics/devtools/compilation_manager.py +0 -294
- v0/relationalai/semantics/devtools/extract_lqp.py +0 -110
- v0/relationalai/semantics/internal/internal.py +0 -3785
- v0/relationalai/semantics/internal/snowflake.py +0 -324
- v0/relationalai/semantics/lqp/builtins.py +0 -16
- v0/relationalai/semantics/lqp/compiler.py +0 -22
- v0/relationalai/semantics/lqp/constructors.py +0 -68
- v0/relationalai/semantics/lqp/executor.py +0 -469
- v0/relationalai/semantics/lqp/intrinsics.py +0 -24
- v0/relationalai/semantics/lqp/model2lqp.py +0 -839
- v0/relationalai/semantics/lqp/passes.py +0 -680
- v0/relationalai/semantics/lqp/primitives.py +0 -252
- v0/relationalai/semantics/lqp/result_helpers.py +0 -202
- v0/relationalai/semantics/lqp/rewrite/annotate_constraints.py +0 -57
- v0/relationalai/semantics/lqp/rewrite/cdc.py +0 -216
- v0/relationalai/semantics/lqp/rewrite/extract_common.py +0 -338
- v0/relationalai/semantics/lqp/rewrite/extract_keys.py +0 -449
- v0/relationalai/semantics/lqp/rewrite/function_annotations.py +0 -114
- v0/relationalai/semantics/lqp/rewrite/functional_dependencies.py +0 -314
- v0/relationalai/semantics/lqp/rewrite/quantify_vars.py +0 -296
- v0/relationalai/semantics/lqp/rewrite/splinter.py +0 -76
- v0/relationalai/semantics/lqp/types.py +0 -101
- v0/relationalai/semantics/lqp/utils.py +0 -160
- v0/relationalai/semantics/lqp/validators.py +0 -57
- v0/relationalai/semantics/metamodel/__init__.py +0 -40
- v0/relationalai/semantics/metamodel/builtins.py +0 -774
- v0/relationalai/semantics/metamodel/compiler.py +0 -133
- v0/relationalai/semantics/metamodel/dependency.py +0 -862
- v0/relationalai/semantics/metamodel/executor.py +0 -61
- v0/relationalai/semantics/metamodel/factory.py +0 -287
- v0/relationalai/semantics/metamodel/helpers.py +0 -361
- v0/relationalai/semantics/metamodel/rewrite/discharge_constraints.py +0 -39
- v0/relationalai/semantics/metamodel/rewrite/dnf_union_splitter.py +0 -210
- v0/relationalai/semantics/metamodel/rewrite/extract_nested_logicals.py +0 -78
- v0/relationalai/semantics/metamodel/rewrite/flatten.py +0 -549
- v0/relationalai/semantics/metamodel/rewrite/format_outputs.py +0 -165
- v0/relationalai/semantics/metamodel/typer/checker.py +0 -353
- v0/relationalai/semantics/metamodel/typer/typer.py +0 -1395
- v0/relationalai/semantics/metamodel/util.py +0 -505
- v0/relationalai/semantics/reasoners/__init__.py +0 -10
- v0/relationalai/semantics/reasoners/graph/__init__.py +0 -37
- v0/relationalai/semantics/reasoners/graph/core.py +0 -9020
- v0/relationalai/semantics/reasoners/optimization/__init__.py +0 -68
- v0/relationalai/semantics/reasoners/optimization/common.py +0 -88
- v0/relationalai/semantics/reasoners/optimization/solvers_dev.py +0 -568
- v0/relationalai/semantics/reasoners/optimization/solvers_pb.py +0 -1163
- v0/relationalai/semantics/rel/builtins.py +0 -40
- v0/relationalai/semantics/rel/compiler.py +0 -989
- v0/relationalai/semantics/rel/executor.py +0 -359
- v0/relationalai/semantics/rel/rel.py +0 -482
- v0/relationalai/semantics/rel/rel_utils.py +0 -276
- v0/relationalai/semantics/snowflake/__init__.py +0 -3
- v0/relationalai/semantics/sql/compiler.py +0 -2503
- v0/relationalai/semantics/sql/executor/duck_db.py +0 -52
- v0/relationalai/semantics/sql/executor/result_helpers.py +0 -64
- v0/relationalai/semantics/sql/executor/snowflake.py +0 -145
- v0/relationalai/semantics/sql/rewrite/denormalize.py +0 -222
- v0/relationalai/semantics/sql/rewrite/double_negation.py +0 -49
- v0/relationalai/semantics/sql/rewrite/recursive_union.py +0 -127
- v0/relationalai/semantics/sql/rewrite/sort_output_query.py +0 -246
- v0/relationalai/semantics/sql/sql.py +0 -504
- v0/relationalai/semantics/std/__init__.py +0 -54
- v0/relationalai/semantics/std/constraints.py +0 -43
- v0/relationalai/semantics/std/datetime.py +0 -363
- v0/relationalai/semantics/std/decimals.py +0 -62
- v0/relationalai/semantics/std/floats.py +0 -7
- v0/relationalai/semantics/std/integers.py +0 -22
- v0/relationalai/semantics/std/math.py +0 -141
- v0/relationalai/semantics/std/pragmas.py +0 -11
- v0/relationalai/semantics/std/re.py +0 -83
- v0/relationalai/semantics/std/std.py +0 -14
- v0/relationalai/semantics/std/strings.py +0 -63
- v0/relationalai/semantics/tests/__init__.py +0 -0
- v0/relationalai/semantics/tests/test_snapshot_abstract.py +0 -143
- v0/relationalai/semantics/tests/test_snapshot_base.py +0 -9
- v0/relationalai/semantics/tests/utils.py +0 -46
- v0/relationalai/std/__init__.py +0 -70
- v0/relationalai/tools/__init__.py +0 -0
- v0/relationalai/tools/cli.py +0 -1940
- v0/relationalai/tools/cli_controls.py +0 -1826
- v0/relationalai/tools/cli_helpers.py +0 -390
- v0/relationalai/tools/debugger.py +0 -183
- v0/relationalai/tools/debugger_client.py +0 -109
- v0/relationalai/tools/debugger_server.py +0 -302
- v0/relationalai/tools/dev.py +0 -685
- v0/relationalai/tools/qb_debugger.py +0 -425
- v0/relationalai/util/clean_up_databases.py +0 -95
- v0/relationalai/util/format.py +0 -123
- v0/relationalai/util/list_databases.py +0 -9
- v0/relationalai/util/otel_configuration.py +0 -25
- v0/relationalai/util/otel_handler.py +0 -484
- v0/relationalai/util/snowflake_handler.py +0 -88
- v0/relationalai/util/span_format_test.py +0 -43
- v0/relationalai/util/span_tracker.py +0 -207
- v0/relationalai/util/spans_file_handler.py +0 -72
- v0/relationalai/util/tracing_handler.py +0 -34
- /relationalai/{semantics/frontend → analysis}/__init__.py +0 -0
- {v0/relationalai → relationalai}/analysis/mechanistic.py +0 -0
- {v0/relationalai → relationalai}/analysis/whynot.py +0 -0
- /relationalai/{shims → auth}/__init__.py +0 -0
- {v0/relationalai → relationalai}/auth/jwt_generator.py +0 -0
- {v0/relationalai → relationalai}/auth/oauth_callback_server.py +0 -0
- {v0/relationalai → relationalai}/auth/token_handler.py +0 -0
- {v0/relationalai → relationalai}/auth/util.py +0 -0
- {v0/relationalai/clients → relationalai/clients/resources/snowflake}/cache_store.py +0 -0
- {v0/relationalai → relationalai}/compiler.py +0 -0
- {v0/relationalai → relationalai}/dependencies.py +0 -0
- {v0/relationalai → relationalai}/docutils.py +0 -0
- {v0/relationalai/analysis → relationalai/early_access}/__init__.py +0 -0
- {v0/relationalai → relationalai}/early_access/dsl/__init__.py +0 -0
- {v0/relationalai/auth → relationalai/early_access/dsl/adapters}/__init__.py +0 -0
- {v0/relationalai/early_access → relationalai/early_access/dsl/adapters/orm}/__init__.py +0 -0
- {v0/relationalai → relationalai}/early_access/dsl/adapters/orm/model.py +0 -0
- {v0/relationalai/early_access/dsl/adapters → relationalai/early_access/dsl/adapters/owl}/__init__.py +0 -0
- {v0/relationalai → relationalai}/early_access/dsl/adapters/owl/model.py +0 -0
- {v0/relationalai/early_access/dsl/adapters/orm → relationalai/early_access/dsl/bindings}/__init__.py +0 -0
- {v0/relationalai/early_access/dsl/adapters/owl → relationalai/early_access/dsl/bindings/legacy}/__init__.py +0 -0
- {v0/relationalai/early_access/dsl/bindings → relationalai/early_access/dsl/codegen}/__init__.py +0 -0
- {v0/relationalai → relationalai}/early_access/dsl/constants.py +0 -0
- {v0/relationalai → relationalai}/early_access/dsl/core/__init__.py +0 -0
- {v0/relationalai → relationalai}/early_access/dsl/core/constraints/__init__.py +0 -0
- {v0/relationalai → relationalai}/early_access/dsl/core/constraints/predicate/__init__.py +0 -0
- {v0/relationalai → relationalai}/early_access/dsl/core/stack.py +0 -0
- {v0/relationalai/early_access/dsl/bindings/legacy → relationalai/early_access/dsl/core/temporal}/__init__.py +0 -0
- {v0/relationalai → relationalai}/early_access/dsl/core/utils.py +0 -0
- {v0/relationalai/early_access/dsl/codegen → relationalai/early_access/dsl/ir}/__init__.py +0 -0
- {v0/relationalai/early_access/dsl/core/temporal → relationalai/early_access/dsl/ontologies}/__init__.py +0 -0
- {v0/relationalai → relationalai}/early_access/dsl/ontologies/raw_source.py +0 -0
- {v0/relationalai/early_access/dsl/ir → relationalai/early_access/dsl/orm}/__init__.py +0 -0
- {v0/relationalai/early_access/dsl/ontologies → relationalai/early_access/dsl/orm/measures}/__init__.py +0 -0
- {v0/relationalai → relationalai}/early_access/dsl/orm/reasoner_errors.py +0 -0
- {v0/relationalai/early_access/dsl/orm → relationalai/early_access/dsl/physical_metadata}/__init__.py +0 -0
- {v0/relationalai/early_access/dsl/orm/measures → relationalai/early_access/dsl/serialize}/__init__.py +0 -0
- {v0/relationalai → relationalai}/early_access/dsl/serialize/binding_model.py +0 -0
- {v0/relationalai → relationalai}/early_access/dsl/serialize/model.py +0 -0
- {v0/relationalai/early_access/dsl/physical_metadata → relationalai/early_access/dsl/snow}/__init__.py +0 -0
- {v0/relationalai → relationalai}/early_access/tests/__init__.py +0 -0
- {v0/relationalai → relationalai}/environments/ci.py +0 -0
- {v0/relationalai → relationalai}/environments/hex.py +0 -0
- {v0/relationalai → relationalai}/environments/terminal.py +0 -0
- {v0/relationalai → relationalai}/experimental/__init__.py +0 -0
- {v0/relationalai → relationalai}/experimental/graphs.py +0 -0
- {v0/relationalai → relationalai}/experimental/paths/__init__.py +0 -0
- {v0/relationalai → relationalai}/experimental/paths/benchmarks/__init__.py +0 -0
- {v0/relationalai → relationalai}/experimental/paths/path_algorithms/__init__.py +0 -0
- {v0/relationalai → relationalai}/experimental/paths/rpq/__init__.py +0 -0
- {v0/relationalai → relationalai}/experimental/paths/rpq/filter.py +0 -0
- {v0/relationalai → relationalai}/experimental/paths/rpq/glushkov.py +0 -0
- {v0/relationalai → relationalai}/experimental/paths/rpq/transition.py +0 -0
- {v0/relationalai → relationalai}/experimental/paths/utilities/__init__.py +0 -0
- {v0/relationalai → relationalai}/experimental/paths/utilities/utilities.py +0 -0
- {v0/relationalai/early_access/dsl/serialize → relationalai/loaders}/__init__.py +0 -0
- {v0/relationalai → relationalai}/metagen.py +0 -0
- {v0/relationalai → relationalai}/metamodel.py +0 -0
- {v0/relationalai → relationalai}/rel.py +0 -0
- {v0/relationalai → relationalai}/semantics/devtools/__init__.py +0 -0
- {v0/relationalai → relationalai}/semantics/internal/__init__.py +0 -0
- {v0/relationalai → relationalai}/semantics/internal/annotations.py +0 -0
- {v0/relationalai → relationalai}/semantics/lqp/__init__.py +0 -0
- {v0/relationalai → relationalai}/semantics/lqp/ir.py +0 -0
- {v0/relationalai → relationalai}/semantics/lqp/pragmas.py +0 -0
- {v0/relationalai → relationalai}/semantics/lqp/rewrite/__init__.py +0 -0
- {v0/relationalai → relationalai}/semantics/metamodel/dataflow.py +0 -0
- {v0/relationalai → relationalai}/semantics/metamodel/ir.py +0 -0
- {v0/relationalai → relationalai}/semantics/metamodel/rewrite/__init__.py +0 -0
- {v0/relationalai → relationalai}/semantics/metamodel/typer/__init__.py +0 -0
- {v0/relationalai → relationalai}/semantics/metamodel/types.py +0 -0
- {v0/relationalai → relationalai}/semantics/metamodel/visitor.py +0 -0
- {v0/relationalai → relationalai}/semantics/reasoners/experimental/__init__.py +0 -0
- {v0/relationalai → relationalai}/semantics/rel/__init__.py +0 -0
- {v0/relationalai → relationalai}/semantics/sql/__init__.py +0 -0
- {v0/relationalai → relationalai}/semantics/sql/executor/__init__.py +0 -0
- {v0/relationalai → relationalai}/semantics/sql/rewrite/__init__.py +0 -0
- {v0/relationalai/early_access/dsl/snow → relationalai/semantics/tests}/__init__.py +0 -0
- {v0/relationalai → relationalai}/semantics/tests/logging.py +0 -0
- {v0/relationalai → relationalai}/std/aggregates.py +0 -0
- {v0/relationalai → relationalai}/std/dates.py +0 -0
- {v0/relationalai → relationalai}/std/graphs.py +0 -0
- {v0/relationalai → relationalai}/std/inspect.py +0 -0
- {v0/relationalai → relationalai}/std/math.py +0 -0
- {v0/relationalai → relationalai}/std/re.py +0 -0
- {v0/relationalai → relationalai}/std/strings.py +0 -0
- {v0/relationalai/loaders → relationalai/tools}/__init__.py +0 -0
- {v0/relationalai → relationalai}/tools/cleanup_snapshots.py +0 -0
- {v0/relationalai → relationalai}/tools/constants.py +0 -0
- {v0/relationalai → relationalai}/tools/query_utils.py +0 -0
- {v0/relationalai → relationalai}/tools/snapshot_viewer.py +0 -0
- {v0/relationalai → relationalai}/util/__init__.py +0 -0
- {v0/relationalai → relationalai}/util/constants.py +0 -0
- {v0/relationalai → relationalai}/util/graph.py +0 -0
- {v0/relationalai → relationalai}/util/timeout.py +0 -0
|
@@ -0,0 +1,989 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Any, Iterable, Sequence as PySequence, cast, Tuple, Union
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from decimal import Decimal as PyDecimal
|
|
5
|
+
|
|
6
|
+
from relationalai.semantics.metamodel import ir, compiler as c, builtins as bt, types, visitor, helpers, factory as f
|
|
7
|
+
from relationalai.semantics.metamodel.typer import Checker, InferTypes
|
|
8
|
+
from relationalai.semantics.metamodel.typer.typer import to_base_primitive, to_type, _NON_PARAMETRIC_PRIMITIVES
|
|
9
|
+
from relationalai.semantics.metamodel.visitor import ReadWriteVisitor
|
|
10
|
+
from relationalai.semantics.metamodel.util import OrderedSet, group_by, NameCache, ordered_set
|
|
11
|
+
|
|
12
|
+
from relationalai.semantics.rel import rel, rel_utils as u, builtins as rel_bt
|
|
13
|
+
|
|
14
|
+
from ..metamodel.rewrite import (Flatten, ExtractNestedLogicals, DNFUnionSplitter, DischargeConstraints, FormatOutputs)
|
|
15
|
+
from ..lqp.rewrite import CDC, ExtractCommon, ExtractKeys, FunctionAnnotations, QuantifyVars, Splinter, SplitMultiCheckRequires
|
|
16
|
+
|
|
17
|
+
import math
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
#--------------------------------------------------
|
|
21
|
+
# Compiler
|
|
22
|
+
#--------------------------------------------------
|
|
23
|
+
|
|
24
|
+
class Compiler(c.Compiler):
|
|
25
|
+
def __init__(self):
|
|
26
|
+
super().__init__([
|
|
27
|
+
SplitMultiCheckRequires(),
|
|
28
|
+
FunctionAnnotations(),
|
|
29
|
+
DischargeConstraints(),
|
|
30
|
+
Checker(),
|
|
31
|
+
CDC(), # specialize to physical relations before extracting nested and typing
|
|
32
|
+
ExtractNestedLogicals(), # before InferTypes to avoid extracting casts
|
|
33
|
+
InferTypes(),
|
|
34
|
+
DNFUnionSplitter(),
|
|
35
|
+
ExtractKeys(),
|
|
36
|
+
FormatOutputs(),
|
|
37
|
+
ExtractCommon(),
|
|
38
|
+
Flatten(),
|
|
39
|
+
Splinter(),
|
|
40
|
+
QuantifyVars(),
|
|
41
|
+
])
|
|
42
|
+
self.model_to_rel = ModelToRel()
|
|
43
|
+
|
|
44
|
+
def do_compile(self, model: ir.Model, options:dict={}) -> str:
|
|
45
|
+
return str(self.model_to_rel.to_rel(model, options=options))
|
|
46
|
+
|
|
47
|
+
COMPILER_OPTIONS = [
|
|
48
|
+
# do not generated declarations for relations read by the model but not written to
|
|
49
|
+
"no_declares",
|
|
50
|
+
# do not GNF the output relation, keeping it wide
|
|
51
|
+
"wide_outputs"
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
@dataclass
|
|
55
|
+
class ModelToRel:
|
|
56
|
+
""" Generates Rel from an IR Model, assuming the compiler rewrites were done. """
|
|
57
|
+
|
|
58
|
+
relation_name_cache: NameCache = field(default_factory=NameCache)
|
|
59
|
+
rule_name_cache: NameCache = field(default_factory=NameCache)
|
|
60
|
+
|
|
61
|
+
# Map a rel variable to one with a different name
|
|
62
|
+
var_map: dict[rel.Var, rel.Var] = field(default_factory=dict)
|
|
63
|
+
|
|
64
|
+
#--------------------------------------------------
|
|
65
|
+
# Public API
|
|
66
|
+
#--------------------------------------------------
|
|
67
|
+
|
|
68
|
+
def to_rel(self, model: ir.Model, options:dict = {}) -> rel.Program:
|
|
69
|
+
self._register_external_relations(model)
|
|
70
|
+
|
|
71
|
+
rules = self._generate_rules(model)
|
|
72
|
+
reads = self._rel_reads(rules)
|
|
73
|
+
declares = [] if options.get("no_declares") else self._generate_declares(model)
|
|
74
|
+
self._rel_reads(declares, reads)
|
|
75
|
+
return rel.Program(tuple([
|
|
76
|
+
*self._generate_builtin_defs(model, reads),
|
|
77
|
+
*declares,
|
|
78
|
+
*rules,
|
|
79
|
+
]))
|
|
80
|
+
|
|
81
|
+
#--------------------------------------------------
|
|
82
|
+
# Top level handlers
|
|
83
|
+
#--------------------------------------------------
|
|
84
|
+
|
|
85
|
+
def _generate_builtin_defs(self, model: ir.Model, reads:OrderedSet[str]) -> list[rel.Def]:
|
|
86
|
+
defs = []
|
|
87
|
+
|
|
88
|
+
for t in model.types:
|
|
89
|
+
# TODO - some of these types are never used, we should not generate them, but we
|
|
90
|
+
# need to replace the rel_reads function with something that collects those types
|
|
91
|
+
# during generation
|
|
92
|
+
if isinstance(t, ir.DecimalType):
|
|
93
|
+
defs.append(
|
|
94
|
+
rel.Def(u.rel_typename(t),
|
|
95
|
+
tuple([rel.Var("x")]),
|
|
96
|
+
rel.atom("::std::common::FixedDecimal",
|
|
97
|
+
tuple([rel.MetaValue(types.digits_to_bits(t.precision)), rel.MetaValue(t.scale), rel.Var("x")])),
|
|
98
|
+
tuple([rel.Annotation("inline", ())]),
|
|
99
|
+
),
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
if "pyrel_inf" in reads:
|
|
103
|
+
defs.append(
|
|
104
|
+
rel.Def("pyrel_inf",
|
|
105
|
+
tuple([rel.Var("x")]),
|
|
106
|
+
rel.atom("::std::common::infinity", tuple([rel.MetaValue(64), rel.Var("x")])),
|
|
107
|
+
tuple([rel.Annotation("inline", ())]),
|
|
108
|
+
),
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
if "pyrel_NaN" in reads:
|
|
112
|
+
defs.append(
|
|
113
|
+
rel.Def("pyrel_NaN",
|
|
114
|
+
tuple([rel.Var("x")]),
|
|
115
|
+
rel.atom("::std::common::nan", tuple([rel.MetaValue(64), rel.Var("x")])),
|
|
116
|
+
tuple([rel.Annotation("inline", ())]),
|
|
117
|
+
),
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
if "pyrel_ID" in reads:
|
|
121
|
+
defs.append(rel.Def("pyrel_ID",
|
|
122
|
+
tuple([rel.Var("x")]),
|
|
123
|
+
rel.Or(OrderedSet[rel.Expr].from_iterable([
|
|
124
|
+
rel.atom("::std::common::UInt128", tuple([rel.Var("x")])),
|
|
125
|
+
rel.atom("::std::common::Missing", tuple([rel.Var("x")])),
|
|
126
|
+
])),
|
|
127
|
+
tuple([rel.Annotation("inline", ())]),
|
|
128
|
+
))
|
|
129
|
+
|
|
130
|
+
if "pyrel_count" in reads:
|
|
131
|
+
defs.append(
|
|
132
|
+
rel.Def("pyrel_count",
|
|
133
|
+
tuple([rel.Var("{R}"), rel.Var("y")]),
|
|
134
|
+
rel.Exists(
|
|
135
|
+
tuple([rel.Var("z")]),
|
|
136
|
+
rel.And(ordered_set(
|
|
137
|
+
rel.atom("::std::common::count", tuple([rel.Var("R"), rel.Var("z")])),
|
|
138
|
+
rel.Atom(self._convert_abs(types.Int64, types.Int128), tuple([rel.Var("z"), rel.Var("y")])),
|
|
139
|
+
)),
|
|
140
|
+
),
|
|
141
|
+
tuple([rel.Annotation("inline", ())]),
|
|
142
|
+
),
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
if "pyrel_sort" in reads:
|
|
146
|
+
defs.append(
|
|
147
|
+
rel.Def("pyrel_sort",
|
|
148
|
+
tuple([rel.Var("{R}"), rel.Var("n"), rel.Var("r", varargs=True)]),
|
|
149
|
+
rel.Exists(
|
|
150
|
+
tuple([rel.Var("z")]),
|
|
151
|
+
rel.And(ordered_set(
|
|
152
|
+
rel.atom("::std::common::sort", tuple([rel.Var("R"), rel.Var("z"), rel.Var("r", varargs=True)])),
|
|
153
|
+
rel.Atom(self._convert_abs(types.Int64, types.Int128), tuple([rel.Var("z"), rel.Var("n")])),
|
|
154
|
+
)),
|
|
155
|
+
),
|
|
156
|
+
tuple([rel.Annotation("inline", ())]),
|
|
157
|
+
),
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
if "pyrel_reverse_sort" in reads:
|
|
161
|
+
defs.append(
|
|
162
|
+
rel.Def("pyrel_reverse_sort",
|
|
163
|
+
tuple([rel.Var("{R}"), rel.Var("n"), rel.Var("r", varargs=True)]),
|
|
164
|
+
rel.Exists(
|
|
165
|
+
tuple([rel.Var("z")]),
|
|
166
|
+
rel.And(ordered_set(
|
|
167
|
+
rel.atom("::std::common::reverse_sort", tuple([rel.Var("R"), rel.Var("z"), rel.Var("r", varargs=True)])),
|
|
168
|
+
rel.Atom(self._convert_abs(types.Int64, types.Int128), tuple([rel.Var("z"), rel.Var("n")])),
|
|
169
|
+
)),
|
|
170
|
+
),
|
|
171
|
+
tuple([rel.Annotation("inline", ())]),
|
|
172
|
+
),
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
if "pyrel_top" in reads:
|
|
176
|
+
defs.append(
|
|
177
|
+
rel.Def("pyrel_top",
|
|
178
|
+
tuple([rel.Var("k"), rel.Var("{R}"), rel.Var("n"), rel.Var("r", varargs=True)]),
|
|
179
|
+
rel.Exists(
|
|
180
|
+
tuple([rel.Var("z")]),
|
|
181
|
+
rel.And(ordered_set(
|
|
182
|
+
rel.atom("::std::common::top", tuple([rel.Var("k"), rel.Var("R"), rel.Var("z"), rel.Var("r", varargs=True)])),
|
|
183
|
+
rel.Atom(self._convert_abs(types.Int64, types.Int128), tuple([rel.Var("z"), rel.Var("n")])),
|
|
184
|
+
)),
|
|
185
|
+
),
|
|
186
|
+
tuple([rel.Annotation("inline", ())]),
|
|
187
|
+
),
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
if "pyrel_bottom" in reads:
|
|
191
|
+
defs.append(
|
|
192
|
+
rel.Def("pyrel_bottom",
|
|
193
|
+
tuple([rel.Var("k"), rel.Var("{R}"), rel.Var("n"), rel.Var("r", varargs=True)]),
|
|
194
|
+
rel.Exists(
|
|
195
|
+
tuple([rel.Var("z")]),
|
|
196
|
+
rel.And(ordered_set(
|
|
197
|
+
rel.atom("::std::common::bottom", tuple([rel.Var("k"),rel.Var("R"), rel.Var("z"), rel.Var("r", varargs=True)])),
|
|
198
|
+
rel.Atom(self._convert_abs(types.Int64, types.Int128), tuple([rel.Var("z"), rel.Var("n")])),
|
|
199
|
+
)),
|
|
200
|
+
),
|
|
201
|
+
tuple([rel.Annotation("inline", ())]),
|
|
202
|
+
),
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
if "pyrel_dates_period_days" in reads:
|
|
206
|
+
defs.append(
|
|
207
|
+
rel.Def("pyrel_dates_period_days",
|
|
208
|
+
tuple([rel.Var("a"), rel.Var("b"), rel.Var("c")]),
|
|
209
|
+
rel.Exists(
|
|
210
|
+
tuple([rel.Var("d")]),
|
|
211
|
+
rel.And(ordered_set(
|
|
212
|
+
rel.atom("::std::common::dates_period_days",
|
|
213
|
+
tuple([rel.Var("a"), rel.Var("b"), rel.Var("d")])),
|
|
214
|
+
rel.atom("::std::common::^Day",
|
|
215
|
+
tuple([rel.Var("c"), rel.Var("d")]))
|
|
216
|
+
)),
|
|
217
|
+
),
|
|
218
|
+
tuple([rel.Annotation("inline", ())]),
|
|
219
|
+
),
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
if "pyrel_datetimes_period_milliseconds" in reads:
|
|
223
|
+
defs.append(
|
|
224
|
+
rel.Def("pyrel_datetimes_period_milliseconds",
|
|
225
|
+
tuple([rel.Var("a"), rel.Var("b"), rel.Var("c")]),
|
|
226
|
+
rel.Exists(
|
|
227
|
+
tuple([rel.Var("m")]),
|
|
228
|
+
rel.And(ordered_set(
|
|
229
|
+
rel.atom("::std::common::datetimes_period_milliseconds",
|
|
230
|
+
tuple([rel.Var("a"), rel.Var("b"), rel.Var("m")])),
|
|
231
|
+
rel.atom("::std::common::^Millisecond",
|
|
232
|
+
tuple([rel.Var("c"), rel.Var("m")]))
|
|
233
|
+
)),
|
|
234
|
+
),
|
|
235
|
+
tuple([rel.Annotation("inline", ())]),
|
|
236
|
+
),
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
if "pyrel_regex_search" in reads:
|
|
240
|
+
raise NotImplementedError("pyrel_regex_search is not implemented")
|
|
241
|
+
|
|
242
|
+
return defs
|
|
243
|
+
|
|
244
|
+
@staticmethod
|
|
245
|
+
def _convert_abs(from_type: ir.Type, to_type: ir.Type):
|
|
246
|
+
if from_type == types.Int64 and to_type == types.Float:
|
|
247
|
+
return rel.Identifier("::std::common::int_float_convert")
|
|
248
|
+
elif from_type == types.Float and to_type == types.Int64:
|
|
249
|
+
return rel.Identifier("::std::common::float_int_convert")
|
|
250
|
+
else:
|
|
251
|
+
input_type = u.rel_typename(from_type)
|
|
252
|
+
output_type = u.rel_typename(to_type)
|
|
253
|
+
return rel.RelationalAbstraction(
|
|
254
|
+
tuple([rel.Var("val_x", type=input_type), rel.Var("val_y", type=output_type)]),
|
|
255
|
+
rel.Exists(
|
|
256
|
+
tuple([rel.Var("type_x"), rel.Var("type_y")]),
|
|
257
|
+
rel.And(ordered_set(
|
|
258
|
+
# Since we declared them to be the types we're converting from and to, we can just use the types of x and y here.
|
|
259
|
+
# The Rel compiler will use the static type of the variable to compute the Type values.
|
|
260
|
+
rel.atom("rel_primitive_typeof", tuple([rel.Var("val_x"), rel.Var("type_x")])),
|
|
261
|
+
rel.atom("rel_primitive_typeof", tuple([rel.Var("val_y"), rel.Var("type_y")])),
|
|
262
|
+
rel.atom("rel_primitive_convert", tuple([rel.Var("type_x"), rel.Var("type_y"), rel.Var("val_x"), rel.Var("val_y")])),
|
|
263
|
+
)),
|
|
264
|
+
)
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
def _generate_declares(self, m: ir.Model) -> list[rel.Declare]:
|
|
268
|
+
"""
|
|
269
|
+
Generate declare statements for relations declared by the model and:
|
|
270
|
+
- not built-ins
|
|
271
|
+
- not used as an annotation
|
|
272
|
+
- not annotated as external
|
|
273
|
+
- do not start with ^ (for hardcoded Rel constructors)
|
|
274
|
+
- and are never the target of an update
|
|
275
|
+
"""
|
|
276
|
+
rw = ReadWriteVisitor()
|
|
277
|
+
m.accept(rw)
|
|
278
|
+
|
|
279
|
+
root = cast(ir.Logical, m.root)
|
|
280
|
+
|
|
281
|
+
annotations = [anno.relation for anno in visitor.collect_by_type(ir.Annotation, m.root)]
|
|
282
|
+
reads = m.relations - rw.writes(root) - bt.builtin_relations - bt.builtin_overloads - bt.builtin_annotations - annotations
|
|
283
|
+
reads = list(filter(lambda r: not r.name.startswith('^') and not helpers.is_external(r), reads))
|
|
284
|
+
|
|
285
|
+
primitive_type_names = OrderedSet.from_iterable([t.name for t in _NON_PARAMETRIC_PRIMITIVES])
|
|
286
|
+
declares: list[rel.Declare] = []
|
|
287
|
+
for r in reads:
|
|
288
|
+
if r.name in rel.infix or r.name in u.OPERATORS:
|
|
289
|
+
continue
|
|
290
|
+
|
|
291
|
+
if helpers.is_from_cast(r):
|
|
292
|
+
continue
|
|
293
|
+
|
|
294
|
+
# TODO: should address the root of the issue
|
|
295
|
+
# In some cases we might end up with explicit Concepts for primitives in the model
|
|
296
|
+
if r.name in primitive_type_names or r.name.startswith("Decimal("):
|
|
297
|
+
continue
|
|
298
|
+
|
|
299
|
+
# In case parameter name starts with ':' use its name instead of type name
|
|
300
|
+
def requires_name(fld: ir.Field):
|
|
301
|
+
if isinstance(fld.type, ir.ScalarType):
|
|
302
|
+
t = fld.type
|
|
303
|
+
if t == types.Symbol:
|
|
304
|
+
return rel.MetaValue(fld.name[1:])
|
|
305
|
+
else:
|
|
306
|
+
return rel.Var(name=u.sanitize(fld.name.lower()), type=u.rel_typename(t))
|
|
307
|
+
else:
|
|
308
|
+
return rel.Var(u.sanitize(fld.name.lower()))
|
|
309
|
+
head = tuple([requires_name(f) for f in r.fields])
|
|
310
|
+
|
|
311
|
+
# Example: declare test(:a, _x0 in Int, _x1 in String) requires true
|
|
312
|
+
declares.append(rel.Declare(
|
|
313
|
+
rel.atom(self._relation_name(r), head),
|
|
314
|
+
rel.true # `requires true` does not generate any constraints, that affects performance on the RAI side
|
|
315
|
+
))
|
|
316
|
+
return declares
|
|
317
|
+
|
|
318
|
+
def _generate_rules(self, m: ir.Model) -> list[Union[rel.Def, rel.RawSource]]:
|
|
319
|
+
""" Generate rules for the root of this model.
|
|
320
|
+
|
|
321
|
+
Assumes the model already was processed such that it contains a root Logical with
|
|
322
|
+
children that are also Logical tasks representing the rules to generate.
|
|
323
|
+
"""
|
|
324
|
+
rules: list[Union[rel.Def, rel.RawSource]] = []
|
|
325
|
+
root = cast(ir.Logical, m.root)
|
|
326
|
+
for child in root.body:
|
|
327
|
+
rules.extend(self._generate_rule(cast(ir.Logical, child)))
|
|
328
|
+
return rules
|
|
329
|
+
|
|
330
|
+
def _generate_rule(self, rule: ir.Logical) -> list[Union[rel.Def, rel.RawSource]]:
|
|
331
|
+
""" Generate rules for a nested Logical in a model.
|
|
332
|
+
|
|
333
|
+
This is for a top-level Logical, under the root Logical.
|
|
334
|
+
"""
|
|
335
|
+
# reset the name cache for each rule
|
|
336
|
+
self.rule_name_cache = NameCache()
|
|
337
|
+
effects, other, aggregates, ranks = self._split_tasks(rule.body)
|
|
338
|
+
if not effects or (aggregates and ranks):
|
|
339
|
+
# nothing to generate for this Logical
|
|
340
|
+
return []
|
|
341
|
+
|
|
342
|
+
elif len(effects) == 1:
|
|
343
|
+
# a single effect with a body becomes a single rule
|
|
344
|
+
effect = effects[0]
|
|
345
|
+
|
|
346
|
+
# deal with raw sources
|
|
347
|
+
if isinstance(effect, ir.Update) and effect.relation == bt.raw_source:
|
|
348
|
+
# TODO: remove this once the type checker checks this.
|
|
349
|
+
assert(len(effect.args) == 2 and isinstance(effect.args[0], ir.Literal) and isinstance(effect.args[1], ir.Literal))
|
|
350
|
+
if effect.args[0].value != "rel":
|
|
351
|
+
return []
|
|
352
|
+
return [rel.RawSource(cast(str, effect.args[1].value))]
|
|
353
|
+
else:
|
|
354
|
+
args, lookups, rel_equiv = self._effect_args(effect)
|
|
355
|
+
if lookups:
|
|
356
|
+
other.extend(lookups)
|
|
357
|
+
return [rel.Def(
|
|
358
|
+
self._effect_name(effect),
|
|
359
|
+
args,
|
|
360
|
+
rel.create_and([
|
|
361
|
+
self.generate_logical_body(other, aggregates, ranks),
|
|
362
|
+
*rel_equiv
|
|
363
|
+
]),
|
|
364
|
+
self.generate_annotations(effect.annotations)
|
|
365
|
+
)]
|
|
366
|
+
else:
|
|
367
|
+
# currently we can only deal with multiple effects if they are all updates with
|
|
368
|
+
# no body, which is the pattern for inserting hardcoded data.
|
|
369
|
+
if other or aggregates:
|
|
370
|
+
raise NotImplementedError("Body in logical task with multiple effects.")
|
|
371
|
+
if any(isinstance(effect, ir.Output) for effect in effects):
|
|
372
|
+
raise NotImplementedError("Output in logical task with multiple effects.")
|
|
373
|
+
sample = cast(ir.Update, effects[0]).effect
|
|
374
|
+
if any(cast(ir.Update, effect).effect != sample for effect in effects):
|
|
375
|
+
raise NotImplementedError("Different types of effects in logical task.")
|
|
376
|
+
|
|
377
|
+
# Group updates by relation name
|
|
378
|
+
relation_groups = group_by(cast(list[ir.Update], effects), lambda e: self._relation_name(e.relation))
|
|
379
|
+
|
|
380
|
+
# Process each relation group
|
|
381
|
+
defs = []
|
|
382
|
+
for name, updates in relation_groups.items():
|
|
383
|
+
effects_to_union = []
|
|
384
|
+
for update in updates:
|
|
385
|
+
update_args, lookups, rel_equiv = self._effect_args(update)
|
|
386
|
+
if update_args:
|
|
387
|
+
defs.append(
|
|
388
|
+
rel.Def(
|
|
389
|
+
name,
|
|
390
|
+
update_args,
|
|
391
|
+
rel.create_and([
|
|
392
|
+
self.generate_body_expr(lookups),
|
|
393
|
+
*rel_equiv
|
|
394
|
+
]),
|
|
395
|
+
self.generate_annotations(update.annotations)
|
|
396
|
+
)
|
|
397
|
+
)
|
|
398
|
+
else:
|
|
399
|
+
effects_to_union.append(update)
|
|
400
|
+
|
|
401
|
+
if effects_to_union:
|
|
402
|
+
update = updates.some()
|
|
403
|
+
args, lookups, rel_equiv = self._effect_args(update)
|
|
404
|
+
bodies = []
|
|
405
|
+
for update in effects_to_union:
|
|
406
|
+
bodies.append(self.handle(update))
|
|
407
|
+
for lookup in lookups:
|
|
408
|
+
bodies.append(self.handle(lookup))
|
|
409
|
+
|
|
410
|
+
defs.append(
|
|
411
|
+
rel.Def(
|
|
412
|
+
name,
|
|
413
|
+
args,
|
|
414
|
+
rel.create_and([
|
|
415
|
+
rel.Union(tuple(bodies)),
|
|
416
|
+
*rel_equiv
|
|
417
|
+
]),
|
|
418
|
+
self.generate_annotations(update.annotations)
|
|
419
|
+
)
|
|
420
|
+
)
|
|
421
|
+
return defs
|
|
422
|
+
|
|
423
|
+
def generate_logical_body(self, other, aggregates, ranks):
|
|
424
|
+
""" Generate the body of a rule for a Logical that contains these aggregates/ranks
|
|
425
|
+
and other tasks (i.e., no effects)."""
|
|
426
|
+
|
|
427
|
+
if aggregates:
|
|
428
|
+
# push the body into the aggregates; this assumes a rewrite pass already
|
|
429
|
+
# prepared the body to contain only what's needed by the aggregates
|
|
430
|
+
exprs = []
|
|
431
|
+
for agg in aggregates:
|
|
432
|
+
# The variables declared in the relational abstraction are the agg's "projection" + "over"
|
|
433
|
+
abs_vars = OrderedSet.from_iterable(agg.projection)
|
|
434
|
+
result = []
|
|
435
|
+
for arg in agg.args:
|
|
436
|
+
if helpers.is_aggregate_input(arg, agg):
|
|
437
|
+
new_arg = arg if isinstance(arg, ir.Var) else self.handle(arg)
|
|
438
|
+
abs_vars.add(new_arg)
|
|
439
|
+
else:
|
|
440
|
+
result.append(self.handle(arg))
|
|
441
|
+
|
|
442
|
+
old_var_map = self.var_map
|
|
443
|
+
self.var_map = {}
|
|
444
|
+
|
|
445
|
+
common_vars = OrderedSet.from_iterable(agg.projection) & agg.group
|
|
446
|
+
abs_body_exprs = []
|
|
447
|
+
for v in common_vars:
|
|
448
|
+
orig_rel_v = self.handle_var(v)
|
|
449
|
+
inner_rel_v = rel.Var("_t" + orig_rel_v.name)
|
|
450
|
+
self.var_map[orig_rel_v] = inner_rel_v
|
|
451
|
+
eq_expr = rel.BinaryExpr(orig_rel_v, "=", inner_rel_v)
|
|
452
|
+
abs_body_exprs.append(eq_expr)
|
|
453
|
+
|
|
454
|
+
abs_head = self.handle_list(tuple(abs_vars))
|
|
455
|
+
abs_body = self.generate_body_expr(other)
|
|
456
|
+
if abs_body_exprs:
|
|
457
|
+
abs_body = rel.create_and([abs_body, *abs_body_exprs])
|
|
458
|
+
rel_abstraction = rel.RelationalAbstraction(abs_head, abs_body)
|
|
459
|
+
|
|
460
|
+
self.var_map = old_var_map
|
|
461
|
+
|
|
462
|
+
exprs.append(rel.atom(
|
|
463
|
+
u.rel_operator(agg.aggregation.name),
|
|
464
|
+
tuple([ rel_abstraction, *result ])
|
|
465
|
+
))
|
|
466
|
+
return exprs[0] if len(exprs) == 1 else rel.create_and(exprs)
|
|
467
|
+
elif ranks:
|
|
468
|
+
# push the body into the aggregates; this assumes a rewrite pass already
|
|
469
|
+
# prepared the body to contain only what's needed by the aggregates
|
|
470
|
+
exprs = []
|
|
471
|
+
for rank in ranks:
|
|
472
|
+
rel_name, has_limit = self.compute_rank_limit_info(rank)
|
|
473
|
+
old_var_map = self.var_map
|
|
474
|
+
self.var_map = {}
|
|
475
|
+
|
|
476
|
+
abs_vars = ordered_set()
|
|
477
|
+
abs_body_exprs = []
|
|
478
|
+
# Rename the sorted vars to avoid conflicts with the result vars.
|
|
479
|
+
# We sort the requested args, augmented with the keys (projection).
|
|
480
|
+
# The keys have to be present to preserve bag semantics, but should
|
|
481
|
+
# not affect the ranking. Thus they have to go at the end of the list.
|
|
482
|
+
# Create a set to deduplicate vars appearing in both.
|
|
483
|
+
raw_args = OrderedSet.from_iterable(rank.args + rank.projection)
|
|
484
|
+
for ir_v in raw_args:
|
|
485
|
+
orig_rel_v = self.handle_var(ir_v)
|
|
486
|
+
if ir_v in rank.projection and ir_v not in rank.group:
|
|
487
|
+
inner_rel_v = rel.Var("_t" + orig_rel_v.name)
|
|
488
|
+
self.var_map[orig_rel_v] = inner_rel_v
|
|
489
|
+
else:
|
|
490
|
+
inner_rel_v = rel.Var("_t" + orig_rel_v.name)
|
|
491
|
+
self.var_map[orig_rel_v] = inner_rel_v
|
|
492
|
+
# inner_rel_v = rel.Var(orig_rel_v.name)
|
|
493
|
+
if ir_v in rank.group:
|
|
494
|
+
eq_expr = rel.BinaryExpr(orig_rel_v, "=", inner_rel_v)
|
|
495
|
+
abs_body_exprs.append(eq_expr)
|
|
496
|
+
abs_vars.add(inner_rel_v)
|
|
497
|
+
|
|
498
|
+
abs_body = self.generate_body_expr(other)
|
|
499
|
+
if abs_body_exprs:
|
|
500
|
+
abs_body = rel.create_and([abs_body, *abs_body_exprs])
|
|
501
|
+
rel_abstraction = rel.RelationalAbstraction(tuple(abs_vars), abs_body)
|
|
502
|
+
|
|
503
|
+
self.var_map = old_var_map
|
|
504
|
+
|
|
505
|
+
out_vars = [self.handle_var(v) for v in raw_args]
|
|
506
|
+
params = [rel_abstraction, self.handle_var(rank.result), *out_vars]
|
|
507
|
+
if has_limit:
|
|
508
|
+
params.insert(0, rank.limit)
|
|
509
|
+
exprs.append(rel.atom(rel_name, tuple(params)))
|
|
510
|
+
|
|
511
|
+
return exprs[0] if len(exprs) == 1 else rel.create_and(exprs)
|
|
512
|
+
else:
|
|
513
|
+
# no aggregates or ranks, just return an expression for the body
|
|
514
|
+
return self.generate_body_expr(other)
|
|
515
|
+
|
|
516
|
+
def compute_rank_limit_info(self, rank: ir.Rank):
|
|
517
|
+
if all(o for o in rank.arg_is_ascending):
|
|
518
|
+
ascending = True
|
|
519
|
+
elif all(not o for o in rank.arg_is_ascending):
|
|
520
|
+
ascending = False
|
|
521
|
+
else:
|
|
522
|
+
raise Exception("Mixed orderings in rank are not supported yet.")
|
|
523
|
+
has_limit = rank.limit != 0
|
|
524
|
+
|
|
525
|
+
if ascending:
|
|
526
|
+
rel_name = "pyrel_top" if has_limit else "pyrel_sort"
|
|
527
|
+
else:
|
|
528
|
+
rel_name = "pyrel_bottom" if has_limit else "pyrel_reverse_sort"
|
|
529
|
+
return rel_name, has_limit
|
|
530
|
+
|
|
531
|
+
def generate_body_expr(self, tasks: list[ir.Task]):
|
|
532
|
+
""" Helper to generate the an expression from the tasks, wrapping in Ands if necessary. """
|
|
533
|
+
if not tasks:
|
|
534
|
+
return rel.true
|
|
535
|
+
elif len(tasks) == 1:
|
|
536
|
+
return self.handle(tasks[0])
|
|
537
|
+
else:
|
|
538
|
+
return rel.create_and([self.handle(b) for b in tasks])
|
|
539
|
+
|
|
540
|
+
#--------------------------------------------------
|
|
541
|
+
# IR handlers
|
|
542
|
+
#--------------------------------------------------
|
|
543
|
+
|
|
544
|
+
def handle(self, n: ir.Node):
|
|
545
|
+
""" Dispatch to the appropriate ir.Node handler. """
|
|
546
|
+
handler = getattr(self, f"handle_{n.kind}", None)
|
|
547
|
+
if handler:
|
|
548
|
+
return handler(n)
|
|
549
|
+
else:
|
|
550
|
+
raise Exception(f"Rel Compiler handler for '{n.kind}' node not implemented.")
|
|
551
|
+
|
|
552
|
+
def handle_list(self, n: Iterable[ir.Node]):
|
|
553
|
+
""" Dispatch each node to the appropriate ir.Node handler. """
|
|
554
|
+
return tuple([self.handle(x) for x in n])
|
|
555
|
+
|
|
556
|
+
def handle_value(self, type: ir.Type|None, value: Any) -> Union[rel.Primitive, rel.RelationalAbstraction, rel.MetaValue, rel.Var]:
|
|
557
|
+
""" Handle the value (Node or Value) and wrap in a Metavalue if the type is Symbol. """
|
|
558
|
+
# only handle if it is a Node (e.g. ir.Var or ir.Literal)
|
|
559
|
+
v = self.handle(value) if isinstance(value, ir.Node) else value
|
|
560
|
+
|
|
561
|
+
# type might be None for these so we have to handle them before the check below.
|
|
562
|
+
if isinstance(v, float) and (math.isinf(v) or math.isnan(v)):
|
|
563
|
+
x = rel.Var("_float")
|
|
564
|
+
rel_name = "::std::common::infinity" if math.isinf(v) else "::std::common::nan"
|
|
565
|
+
return rel.RelationalAbstraction(
|
|
566
|
+
tuple([x]),
|
|
567
|
+
rel.atom(rel_name, tuple([rel.MetaValue(64), x])),
|
|
568
|
+
)
|
|
569
|
+
|
|
570
|
+
if type is None:
|
|
571
|
+
return cast(Union[rel.Primitive, rel.RelationalAbstraction, rel.MetaValue, rel.Var], v)
|
|
572
|
+
|
|
573
|
+
# only wrap if v is a primitive (i.e. not a metavalue or a var, for example).
|
|
574
|
+
base = to_base_primitive(type) or type
|
|
575
|
+
if type == types.Symbol and isinstance(v, (str, int, float, bool)):
|
|
576
|
+
return rel.MetaValue(v)
|
|
577
|
+
elif isinstance(v, PyDecimal):
|
|
578
|
+
if base == types.GenericDecimal:
|
|
579
|
+
# generic decimals arrive here if that's the type of the field in the relation;
|
|
580
|
+
# in that case, the typer made sure that the value is a Literal and the type in
|
|
581
|
+
# the literal is the exact decimal we need. We can clean this up once we remove
|
|
582
|
+
# support for native literals here, since it's not supported in the IR anymore.
|
|
583
|
+
assert isinstance(value, ir.Literal)
|
|
584
|
+
type = value.type
|
|
585
|
+
assert isinstance(type, ir.DecimalType)
|
|
586
|
+
precision = types.digits_to_bits(type.precision)
|
|
587
|
+
else:
|
|
588
|
+
# if it's not an GenericDecimal, it is a specific decimal and we just use it.
|
|
589
|
+
assert isinstance(type, ir.DecimalType)
|
|
590
|
+
precision = types.digits_to_bits(type.precision)
|
|
591
|
+
x = rel.Var("_dec")
|
|
592
|
+
return rel.RelationalAbstraction(
|
|
593
|
+
tuple([x]),
|
|
594
|
+
rel.atom("::std::common::decimal", tuple([rel.MetaValue(precision), rel.MetaValue(type.scale), v, x]))
|
|
595
|
+
)
|
|
596
|
+
|
|
597
|
+
elif base == types.Int128 and isinstance(v, int):
|
|
598
|
+
x = rel.Var("_int")
|
|
599
|
+
return rel.RelationalAbstraction(
|
|
600
|
+
tuple([x]),
|
|
601
|
+
rel.atom("::std::common::int", tuple([128, v, x]))
|
|
602
|
+
)
|
|
603
|
+
elif (base == types.UInt128 or base == types.RowId) and isinstance(v, int):
|
|
604
|
+
x = rel.Var("_uint")
|
|
605
|
+
return rel.RelationalAbstraction(
|
|
606
|
+
tuple([x]),
|
|
607
|
+
rel.atom("::std::common::uint", tuple([128, v, x]))
|
|
608
|
+
)
|
|
609
|
+
else:
|
|
610
|
+
return cast(Union[rel.Primitive, rel.RelationalAbstraction, rel.MetaValue, rel.Var], v)
|
|
611
|
+
|
|
612
|
+
def handle_value_list(self, types, values) -> list[Union[rel.Primitive, rel.MetaValue, rel.RelationalAbstraction, rel.Var]]:
|
|
613
|
+
result = []
|
|
614
|
+
for t, v in zip(types, values):
|
|
615
|
+
# splat values that are "varargs"
|
|
616
|
+
if isinstance(v, tuple) and isinstance(t, ir.ListType):
|
|
617
|
+
for item in v:
|
|
618
|
+
result.append(self.handle_value(t, item))
|
|
619
|
+
else:
|
|
620
|
+
result.append(self.handle_value(t, v))
|
|
621
|
+
return result
|
|
622
|
+
|
|
623
|
+
#
|
|
624
|
+
# DATA MODEL
|
|
625
|
+
#
|
|
626
|
+
def handle_scalartype(self, n: ir.ScalarType):
|
|
627
|
+
return n.name
|
|
628
|
+
# TODO - what to generate for other kinds of types?
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
|
|
633
|
+
#
|
|
634
|
+
# TASKS
|
|
635
|
+
#
|
|
636
|
+
def handle_logical(self, n: ir.Logical) -> rel.Expr:
|
|
637
|
+
# Generate nested expressions for a nested logical
|
|
638
|
+
effects, other, aggregates, ranks = self._split_tasks(n.body)
|
|
639
|
+
if effects:
|
|
640
|
+
raise Exception("Cannot process nested logical with effects.")
|
|
641
|
+
elif aggregates and ranks:
|
|
642
|
+
raise Exception("Cannot process nested logical with both aggregates and ranks.")
|
|
643
|
+
return self.generate_logical_body(other, aggregates, ranks)
|
|
644
|
+
|
|
645
|
+
def handle_union(self, n: ir.Union) -> rel.Expr:
|
|
646
|
+
# Generate nested expressions for a nested logical
|
|
647
|
+
body:list[rel.Expr] = []
|
|
648
|
+
for t in n.tasks:
|
|
649
|
+
body.append(self.handle(t))
|
|
650
|
+
return rel.Or(OrderedSet.from_iterable(body))
|
|
651
|
+
|
|
652
|
+
def handle_rank(self, n: ir.Rank) -> rel.Expr:
|
|
653
|
+
return rel.atom("rank", tuple([self.handle_var(n.result)]))
|
|
654
|
+
|
|
655
|
+
#
|
|
656
|
+
# LOGICAL QUANTIFIERS
|
|
657
|
+
#
|
|
658
|
+
def handle_not(self, n: ir.Not):
|
|
659
|
+
return rel.Not(self.handle(n.task))
|
|
660
|
+
|
|
661
|
+
def handle_exists(self, n: ir.Exists):
|
|
662
|
+
vars = self._remove_wildcards(n.vars)
|
|
663
|
+
if vars:
|
|
664
|
+
return rel.Exists(
|
|
665
|
+
self.handle_vars(vars),
|
|
666
|
+
self.handle(n.task)
|
|
667
|
+
)
|
|
668
|
+
else:
|
|
669
|
+
# all vars are wildcards, no need for exists
|
|
670
|
+
return self.handle(n.task)
|
|
671
|
+
|
|
672
|
+
#
|
|
673
|
+
# ITERATION
|
|
674
|
+
#
|
|
675
|
+
|
|
676
|
+
#
|
|
677
|
+
# RELATIONAL OPERATIONS
|
|
678
|
+
#
|
|
679
|
+
|
|
680
|
+
def handle_vars(self, vars: Tuple[ir.Var, ...]):
|
|
681
|
+
return tuple([self.handle_var(v) for v in vars])
|
|
682
|
+
|
|
683
|
+
def handle_var(self, n: ir.Var):
|
|
684
|
+
name = n.name if (n.name == "_" or n.name.startswith(':')) else f"_{self._var_name(n)}"
|
|
685
|
+
v = rel.Var(name)
|
|
686
|
+
return self.var_map.get(v, v)
|
|
687
|
+
|
|
688
|
+
def handle_literal(self, n: ir.Literal):
|
|
689
|
+
return self.handle_value(n.type, n.value)
|
|
690
|
+
|
|
691
|
+
def handle_data(self, n: ir.Data):
|
|
692
|
+
return rel.Atom(rel.Union(tuple([self.handle_value(None, d) for d in n])), tuple([self.handle(d) for d in n.vars]))
|
|
693
|
+
|
|
694
|
+
def generate_annotations(self, annos: Iterable[ir.Annotation]):
|
|
695
|
+
""" Helper to cast the handling of ir.Annotations into a tuple of rel.Annotations. """
|
|
696
|
+
filtered_annos = list(filter(lambda anno: anno.relation.name in rel_bt.builtin_annotation_names, annos))
|
|
697
|
+
rel_annos = cast(Tuple[rel.Annotation, ...], self.handle_list(filtered_annos))
|
|
698
|
+
return rel_annos
|
|
699
|
+
|
|
700
|
+
# standard handling mistreats the integer arg of ranked `@function(:checked, k)`
|
|
701
|
+
def handle_ranked_function_annotation(self, n: ir.Annotation):
|
|
702
|
+
assert n.relation == bt.function_ranked and len(n.args) == 2
|
|
703
|
+
checked_lit = n.args[0]
|
|
704
|
+
rank_lit = n.args[1]
|
|
705
|
+
assert isinstance(checked_lit, ir.Literal) and isinstance(rank_lit, ir.Literal)
|
|
706
|
+
checked = rel.MetaValue(checked_lit.value)
|
|
707
|
+
rank = rank_lit.value
|
|
708
|
+
return rel.Annotation(
|
|
709
|
+
n.relation.name,
|
|
710
|
+
(checked, rank)
|
|
711
|
+
)
|
|
712
|
+
|
|
713
|
+
def handle_annotation(self, n: ir.Annotation):
|
|
714
|
+
# special treatment for (ranked) @function(:checked, k)
|
|
715
|
+
if n.relation == bt.function_ranked:
|
|
716
|
+
return self.handle_ranked_function_annotation(n)
|
|
717
|
+
|
|
718
|
+
# we know that annotations won't have vars, so we can ignore that type warning
|
|
719
|
+
return rel.Annotation(
|
|
720
|
+
n.relation.name,
|
|
721
|
+
tuple(self.handle_value_list(self._relation_types(n.relation), n.args)) # type:ignore
|
|
722
|
+
)
|
|
723
|
+
|
|
724
|
+
def handle_update(self, n: ir.Update):
|
|
725
|
+
return rel.atom(
|
|
726
|
+
self._relation_name(n.relation),
|
|
727
|
+
tuple(self.handle_value_list(self._relation_types(n.relation), n.args))
|
|
728
|
+
)
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
def handle_lookup(self, n: ir.Lookup):
|
|
732
|
+
# special cases
|
|
733
|
+
if n.relation == bt.cast:
|
|
734
|
+
return self.handle_cast(n)
|
|
735
|
+
if n.relation == bt.parse_decimal:
|
|
736
|
+
return self.handle_parse_decimal(n)
|
|
737
|
+
if n.relation == bt.join:
|
|
738
|
+
return self.handle_join(n)
|
|
739
|
+
# only translate names to Rel operators if the relation is a built-in
|
|
740
|
+
name = self._relation_name(n.relation)
|
|
741
|
+
if bt.is_builtin(n.relation):
|
|
742
|
+
name = u.rel_operator(name)
|
|
743
|
+
types = self._relation_types(n.relation)
|
|
744
|
+
return rel.atom(name, tuple(self.handle_value_list(types, n.args)))
|
|
745
|
+
|
|
746
|
+
def handle_construct(self, n: ir.Construct):
|
|
747
|
+
args = self.handle_value_list([None] * len(n.values), n.values) + [self.handle(n.id_var)]
|
|
748
|
+
return rel.atom("rel_primitive_hash_tuple_uint128", tuple(args))
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
#--------------------------------------------------
|
|
752
|
+
# Built-in special cases
|
|
753
|
+
#--------------------------------------------------
|
|
754
|
+
def handle_cast(self, n: ir.Lookup):
|
|
755
|
+
assert len(n.args) == 3
|
|
756
|
+
(target_type, source, target) = n.args
|
|
757
|
+
assert isinstance(target_type, ir.Type), f"Expected Type, got {type(target_type)}"
|
|
758
|
+
from_type = to_type(source)
|
|
759
|
+
rel_abstraction = self._convert_abs(from_type, target_type)
|
|
760
|
+
types = (from_type, target_type)
|
|
761
|
+
return rel.Atom(rel_abstraction, tuple(self.handle_value_list(types, (source, target))))
|
|
762
|
+
|
|
763
|
+
def handle_parse_decimal(self, n: ir.Lookup):
|
|
764
|
+
# parse_decimal in the metamodel is a binary relation, (value:String, var:DecimalType)
|
|
765
|
+
# but we need to expand the lookup to (bits(var.precision), var.scale, value, var),
|
|
766
|
+
# so we special case it here
|
|
767
|
+
assert len(n.args) == 2
|
|
768
|
+
value, var = n.args
|
|
769
|
+
assert isinstance(value, ir.Node)
|
|
770
|
+
assert isinstance(var, ir.Var)
|
|
771
|
+
typ = var.type
|
|
772
|
+
assert isinstance(typ, ir.DecimalType)
|
|
773
|
+
args = [
|
|
774
|
+
rel.MetaValue(types.digits_to_bits(typ.precision)),
|
|
775
|
+
rel.MetaValue(typ.scale),
|
|
776
|
+
self.handle(value),
|
|
777
|
+
self.handle(var)
|
|
778
|
+
]
|
|
779
|
+
return rel.Atom(rel.Identifier("rel_primitive_parse_decimal"), tuple(args))
|
|
780
|
+
|
|
781
|
+
def handle_join(self, n: ir.Lookup):
|
|
782
|
+
assert len(n.args) == 3
|
|
783
|
+
(strs, separator, target) = n.args
|
|
784
|
+
# prepare binary relation for string_join.
|
|
785
|
+
# string_join example: string_join[", ", {(1, "a"); (2, "b"); (3, "c")}]
|
|
786
|
+
assert isinstance(separator, ir.Node)
|
|
787
|
+
assert isinstance(target, ir.Var)
|
|
788
|
+
assert isinstance(strs, tuple)
|
|
789
|
+
str_args = []
|
|
790
|
+
for i, s in enumerate(strs):
|
|
791
|
+
assert isinstance(s, ir.Node)
|
|
792
|
+
str_args.append(rel.Product((i, self.handle(s))))
|
|
793
|
+
args = [
|
|
794
|
+
self.handle(separator),
|
|
795
|
+
rel.Union(tuple(str_args)),
|
|
796
|
+
self.handle(target)
|
|
797
|
+
]
|
|
798
|
+
return rel.Atom(rel.Identifier("::std::common::string_join"), tuple(args))
|
|
799
|
+
|
|
800
|
+
#--------------------------------------------------
|
|
801
|
+
# Helpers
|
|
802
|
+
#--------------------------------------------------
|
|
803
|
+
|
|
804
|
+
def _relation_types(self, relation: ir.Relation):
|
|
805
|
+
return [f.type for f in relation.fields]
|
|
806
|
+
|
|
807
|
+
def _relation_name(self, relation: ir.Relation):
|
|
808
|
+
if helpers.is_external(relation) or helpers.builtins.is_builtin(relation):
|
|
809
|
+
return relation.name
|
|
810
|
+
return self.relation_name_cache.get_name(relation.id, relation.name, helpers.relation_name_prefix(relation))
|
|
811
|
+
|
|
812
|
+
def _var_name(self, var: ir.Var):
|
|
813
|
+
if var.name == "_":
|
|
814
|
+
return "_"
|
|
815
|
+
return self.rule_name_cache.get_name(var.id, u.sanitize(var.name.lower()))
|
|
816
|
+
|
|
817
|
+
def _remove_wildcards(self, vars: tuple[ir.Var, ...]):
|
|
818
|
+
return tuple(filter(lambda v: v.name != "_", vars))
|
|
819
|
+
|
|
820
|
+
def _register_external_relations(self, model: ir.Model):
|
|
821
|
+
# force all external relations to get a name in the cache, so that internal relations
|
|
822
|
+
# cannot use those names in _relation_name
|
|
823
|
+
for r in model.relations:
|
|
824
|
+
if helpers.is_external(r):
|
|
825
|
+
self.relation_name_cache.get_name(r.id, r.name)
|
|
826
|
+
|
|
827
|
+
def _split_tasks(self, tasks: PySequence[ir.Task]) -> tuple[list[Union[ir.Update, ir.Output]], list[ir.Task], list[ir.Aggregate], list[ir.Rank]]:
|
|
828
|
+
effects = []
|
|
829
|
+
aggregates = []
|
|
830
|
+
other_body = []
|
|
831
|
+
ranks = []
|
|
832
|
+
for task in tasks:
|
|
833
|
+
if isinstance(task, (ir.Update, ir.Output)):
|
|
834
|
+
effects.append(task)
|
|
835
|
+
elif isinstance(task, ir.Aggregate):
|
|
836
|
+
aggregates.append(task)
|
|
837
|
+
elif isinstance(task, ir.Rank):
|
|
838
|
+
ranks.append(task)
|
|
839
|
+
else:
|
|
840
|
+
other_body.append(task)
|
|
841
|
+
return effects, other_body, aggregates, ranks
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
def _effect_name(self, n: ir.Task):
|
|
845
|
+
""" Return the name to be used for the effect (e.g. the relation name, output, etc). """
|
|
846
|
+
if isinstance(n, ir.Output) and bt.export_annotation in n.annotations:
|
|
847
|
+
return "Export_Relation"
|
|
848
|
+
elif isinstance(n, ir.Output):
|
|
849
|
+
return "output"
|
|
850
|
+
elif isinstance(n, ir.Update):
|
|
851
|
+
return self._relation_name(n.relation)
|
|
852
|
+
else:
|
|
853
|
+
raise Exception(f"Cannot retrieve effect name from node {type(n)}")
|
|
854
|
+
|
|
855
|
+
def _effect_args(self, n: ir.Task) -> Tuple[Tuple[Any], list[ir.Task], list[rel.Expr]]:
|
|
856
|
+
"""
|
|
857
|
+
Return the arguments for the head of an effect rule and a list of lookups to add
|
|
858
|
+
to the body of the rule.
|
|
859
|
+
|
|
860
|
+
The lookups may be necessary because Rel does not allow "missing" in the head,
|
|
861
|
+
so we create a new variable, set the variable to missing in the body (the
|
|
862
|
+
lookup) and use the variable in the head.
|
|
863
|
+
|
|
864
|
+
E.g. output(None) becomes output(x): { x = missing }
|
|
865
|
+
"""
|
|
866
|
+
orig_args = []
|
|
867
|
+
handled_args = []
|
|
868
|
+
if isinstance(n, ir.Output):
|
|
869
|
+
args = helpers.output_values(n.aliases)
|
|
870
|
+
orig_args.extend(args)
|
|
871
|
+
handled_args.extend(self.handle_value_list([None] * len(args), args))
|
|
872
|
+
elif isinstance(n, ir.Update):
|
|
873
|
+
orig_args.extend(n.args)
|
|
874
|
+
handled_args.extend(self.handle_value_list(self._relation_types(n.relation), n.args))
|
|
875
|
+
else:
|
|
876
|
+
raise Exception(f"Cannot retrieve effect params from node {type(n)}")
|
|
877
|
+
|
|
878
|
+
assert len(orig_args) == len(handled_args)
|
|
879
|
+
args, lookups, rel_equiv = [], [], []
|
|
880
|
+
for idx, handled in enumerate(handled_args):
|
|
881
|
+
if handled is None:
|
|
882
|
+
var = ir.Var(types.Any, "head")
|
|
883
|
+
args.append(self.handle(var))
|
|
884
|
+
lookups.append(f.lookup(bt.eq, [var, orig_args[idx]]))
|
|
885
|
+
elif isinstance(handled, rel.RelationalAbstraction):
|
|
886
|
+
var = ir.Var(types.Any, "head")
|
|
887
|
+
rel_var = self.handle(var)
|
|
888
|
+
args.append(rel_var)
|
|
889
|
+
rel_equiv.append(rel.create_eq(rel_var, handled))
|
|
890
|
+
elif isinstance(handled, bool):
|
|
891
|
+
# boolean constants need to be bound to a var in the body which is used in the head
|
|
892
|
+
var = ir.Var(types.Any, "head")
|
|
893
|
+
args.append(self.handle(var))
|
|
894
|
+
lookups.append(f.lookup(bt.eq, [var, ir.Literal(types.Bool, handled)]))
|
|
895
|
+
elif not isinstance(handled, rel.Var):
|
|
896
|
+
# other constants
|
|
897
|
+
args.append(handled)
|
|
898
|
+
else:
|
|
899
|
+
orig = orig_args[idx]
|
|
900
|
+
assert isinstance(orig, ir.Var)
|
|
901
|
+
|
|
902
|
+
# Count how many times this argument has been seen before
|
|
903
|
+
cnt = handled_args[:idx].count(handled)
|
|
904
|
+
if cnt == 0:
|
|
905
|
+
arg_type = self._ir_var_to_rel_type(orig)
|
|
906
|
+
args.append(rel.Var(handled.name, False, arg_type) if arg_type else handled)
|
|
907
|
+
continue
|
|
908
|
+
|
|
909
|
+
# Deduplicate variable
|
|
910
|
+
new_var = ir.Var(orig.type, handled.name + "_dup" + str(cnt))
|
|
911
|
+
rel_var = self.handle_var(new_var)
|
|
912
|
+
arg_type = self._ir_var_to_rel_type(orig)
|
|
913
|
+
args.append(rel.Var(rel_var.name, False, arg_type) if arg_type else rel_var)
|
|
914
|
+
rel_equiv.append(rel.create_eq(rel_var, handled))
|
|
915
|
+
return tuple(args), lookups, rel_equiv
|
|
916
|
+
|
|
917
|
+
def _ir_var_to_rel_type(self, v: ir.Var) -> str:
|
|
918
|
+
if isinstance(v.type, ir.DecimalType):
|
|
919
|
+
return u.rel_typename(v.type)
|
|
920
|
+
primitive_type = to_base_primitive(v.type)
|
|
921
|
+
if primitive_type:
|
|
922
|
+
return u.rel_typename(primitive_type)
|
|
923
|
+
elif v.type != types.Any and v.type != types.Enum:
|
|
924
|
+
return "pyrel_ID"
|
|
925
|
+
return ""
|
|
926
|
+
|
|
927
|
+
def _rel_reads(self, root, reads:OrderedSet[str]|None = None) -> OrderedSet[str]:
|
|
928
|
+
if reads is None:
|
|
929
|
+
reads = OrderedSet()
|
|
930
|
+
|
|
931
|
+
if isinstance(root, (tuple, list)):
|
|
932
|
+
for r in root:
|
|
933
|
+
self._rel_reads(r, reads)
|
|
934
|
+
|
|
935
|
+
if isinstance(root, rel.Var):
|
|
936
|
+
if root.type is not None and not root.type.startswith("::std::common::"):
|
|
937
|
+
reads.add(root.type)
|
|
938
|
+
|
|
939
|
+
elif isinstance(root, rel.Declare):
|
|
940
|
+
assert isinstance(root.premise, rel.Atom)
|
|
941
|
+
self._rel_reads(root.premise.args, reads)
|
|
942
|
+
self._rel_reads(root.requires, reads)
|
|
943
|
+
|
|
944
|
+
elif isinstance(root, rel.Def):
|
|
945
|
+
self._rel_reads(root.params, reads)
|
|
946
|
+
self._rel_reads(root.body, reads)
|
|
947
|
+
|
|
948
|
+
elif isinstance(root, rel.Atom):
|
|
949
|
+
if isinstance(root.expr, rel.Identifier):
|
|
950
|
+
reads.add(root.expr.name)
|
|
951
|
+
else:
|
|
952
|
+
self._rel_reads(root.expr, reads)
|
|
953
|
+
self._rel_reads(root.args, reads)
|
|
954
|
+
|
|
955
|
+
elif isinstance(root, rel.RelationalAbstraction):
|
|
956
|
+
self._rel_reads(root.head, reads)
|
|
957
|
+
self._rel_reads(root.body, reads)
|
|
958
|
+
|
|
959
|
+
elif isinstance(root, rel.And):
|
|
960
|
+
for arg in root.body:
|
|
961
|
+
self._rel_reads(arg, reads)
|
|
962
|
+
|
|
963
|
+
elif isinstance(root, rel.Or):
|
|
964
|
+
for arg in root.body:
|
|
965
|
+
self._rel_reads(arg, reads)
|
|
966
|
+
|
|
967
|
+
elif isinstance(root, rel.Exists):
|
|
968
|
+
self._rel_reads(root.body, reads)
|
|
969
|
+
|
|
970
|
+
elif isinstance(root, rel.ForAll):
|
|
971
|
+
self._rel_reads(root.body, reads)
|
|
972
|
+
|
|
973
|
+
elif isinstance(root, rel.Not):
|
|
974
|
+
self._rel_reads(root.body, reads)
|
|
975
|
+
|
|
976
|
+
elif isinstance(root, rel.BinaryExpr):
|
|
977
|
+
self._rel_reads(root.lhs, reads)
|
|
978
|
+
self._rel_reads(root.rhs, reads)
|
|
979
|
+
reads.add(root.op)
|
|
980
|
+
|
|
981
|
+
elif isinstance(root, rel.Product):
|
|
982
|
+
for arg in root.body:
|
|
983
|
+
self._rel_reads(arg, reads)
|
|
984
|
+
|
|
985
|
+
elif isinstance(root, rel.Union):
|
|
986
|
+
for arg in root.body:
|
|
987
|
+
self._rel_reads(arg, reads)
|
|
988
|
+
|
|
989
|
+
return reads
|