relationalai 0.12.3__py3-none-any.whl → 0.12.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. relationalai/__init__.py +4 -0
  2. relationalai/clients/snowflake.py +129 -28
  3. relationalai/clients/use_index_poller.py +3 -0
  4. relationalai/{semantics/reasoners/graph → experimental}/paths/README.md +2 -2
  5. relationalai/experimental/paths/__init__.py +14 -309
  6. relationalai/{semantics/reasoners/graph → experimental}/paths/examples/basic_example.py +2 -2
  7. relationalai/{semantics/reasoners/graph → experimental}/paths/examples/paths_benchmark.py +2 -2
  8. relationalai/{semantics/reasoners/graph → experimental}/paths/examples/paths_example.py +2 -2
  9. relationalai/{semantics/reasoners/graph → experimental}/paths/examples/pattern_to_automaton.py +1 -1
  10. relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/one_sided_ball_repetition.py +1 -1
  11. relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/single.py +3 -3
  12. relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/two_sided_balls_repetition.py +1 -1
  13. relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/two_sided_balls_upto.py +2 -2
  14. relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/usp-old.py +3 -3
  15. relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/usp-tuple.py +3 -3
  16. relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/usp.py +3 -3
  17. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_limit_sp_max_length.py +2 -2
  18. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_limit_sp_multiple.py +2 -2
  19. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_limit_sp_single.py +2 -2
  20. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_limit_walks_multiple.py +2 -2
  21. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_limit_walks_single.py +2 -2
  22. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_one_sided_ball_repetition_multiple.py +2 -2
  23. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_one_sided_ball_repetition_single.py +2 -2
  24. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_one_sided_ball_upto_multiple.py +2 -2
  25. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_one_sided_ball_upto_single.py +2 -2
  26. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_single_paths.py +2 -2
  27. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_single_walks.py +2 -2
  28. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_single_walks_undirected.py +2 -2
  29. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_two_sided_balls_repetition_multiple.py +2 -2
  30. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_two_sided_balls_repetition_single.py +2 -2
  31. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_two_sided_balls_upto_multiple.py +2 -2
  32. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_two_sided_balls_upto_single.py +2 -2
  33. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_usp_nsp_multiple.py +2 -2
  34. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_usp_nsp_single.py +2 -2
  35. relationalai/semantics/__init__.py +4 -0
  36. relationalai/semantics/internal/annotations.py +1 -0
  37. relationalai/semantics/internal/internal.py +2 -0
  38. relationalai/semantics/internal/snowflake.py +2 -3
  39. relationalai/semantics/lqp/builtins.py +1 -0
  40. relationalai/semantics/lqp/executor.py +15 -10
  41. relationalai/semantics/lqp/model2lqp.py +96 -4
  42. relationalai/semantics/lqp/primitives.py +3 -0
  43. relationalai/semantics/lqp/rewrite/extract_common.py +26 -6
  44. relationalai/semantics/metamodel/builtins.py +50 -1
  45. relationalai/semantics/metamodel/dependency.py +14 -11
  46. relationalai/semantics/metamodel/rewrite/flatten.py +1 -13
  47. relationalai/semantics/metamodel/typer/typer.py +3 -0
  48. relationalai/semantics/reasoners/__init__.py +4 -0
  49. relationalai/semantics/reasoners/experimental/__init__.py +7 -0
  50. relationalai/semantics/reasoners/graph/core.py +1226 -148
  51. relationalai/semantics/rel/builtins.py +3 -1
  52. relationalai/semantics/rel/executor.py +13 -6
  53. relationalai/semantics/rel/rel_utils.py +5 -0
  54. relationalai/semantics/sql/compiler.py +6 -0
  55. relationalai/semantics/sql/executor/snowflake.py +2 -2
  56. {relationalai-0.12.3.dist-info → relationalai-0.12.6.dist-info}/METADATA +1 -1
  57. {relationalai-0.12.3.dist-info → relationalai-0.12.6.dist-info}/RECORD +92 -108
  58. {relationalai-0.12.3.dist-info → relationalai-0.12.6.dist-info}/WHEEL +1 -1
  59. relationalai/early_access/paths/__init__.py +0 -22
  60. relationalai/early_access/paths/api/__init__.py +0 -12
  61. relationalai/early_access/paths/benchmarks/__init__.py +0 -13
  62. relationalai/early_access/paths/graph/__init__.py +0 -12
  63. relationalai/early_access/paths/path_algorithms/find_paths/__init__.py +0 -12
  64. relationalai/early_access/paths/path_algorithms/one_sided_ball_repetition/__init__.py +0 -12
  65. relationalai/early_access/paths/path_algorithms/one_sided_ball_upto/__init__.py +0 -12
  66. relationalai/early_access/paths/path_algorithms/single/__init__.py +0 -12
  67. relationalai/early_access/paths/path_algorithms/two_sided_balls_repetition/__init__.py +0 -12
  68. relationalai/early_access/paths/path_algorithms/two_sided_balls_upto/__init__.py +0 -12
  69. relationalai/early_access/paths/path_algorithms/usp/__init__.py +0 -12
  70. relationalai/early_access/paths/rpq/__init__.py +0 -13
  71. relationalai/early_access/paths/utilities/iterators/__init__.py +0 -12
  72. relationalai/experimental/paths/pathfinder.rel +0 -2560
  73. relationalai/semantics/reasoners/graph/paths/__init__.py +0 -16
  74. relationalai/semantics/reasoners/graph/paths/path_algorithms/__init__.py +0 -3
  75. relationalai/semantics/reasoners/graph/paths/utilities/__init__.py +0 -3
  76. /relationalai/{semantics/reasoners/graph → experimental}/paths/api.py +0 -0
  77. /relationalai/{semantics/reasoners/graph → experimental}/paths/benchmarks/__init__.py +0 -0
  78. /relationalai/{semantics/reasoners/graph → experimental}/paths/benchmarks/grid_graph.py +0 -0
  79. /relationalai/{semantics/reasoners/graph → experimental}/paths/code_organization.md +0 -0
  80. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/Movies.ipynb +0 -0
  81. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/minimal_engine_warmup.py +0 -0
  82. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movie_example.py +0 -0
  83. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/actedin.csv +0 -0
  84. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/directed.csv +0 -0
  85. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/follows.csv +0 -0
  86. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/movies.csv +0 -0
  87. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/person.csv +0 -0
  88. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/produced.csv +0 -0
  89. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/ratings.csv +0 -0
  90. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/wrote.csv +0 -0
  91. /relationalai/{semantics/reasoners/graph → experimental}/paths/find_paths_via_automaton.py +0 -0
  92. /relationalai/{semantics/reasoners/graph → experimental}/paths/graph.py +0 -0
  93. /relationalai/{early_access → experimental}/paths/path_algorithms/__init__.py +0 -0
  94. /relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/find_paths.py +0 -0
  95. /relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/one_sided_ball_upto.py +0 -0
  96. /relationalai/{semantics/reasoners/graph → experimental}/paths/product_graph.py +0 -0
  97. /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/__init__.py +0 -0
  98. /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/automaton.py +0 -0
  99. /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/diagnostics.py +0 -0
  100. /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/filter.py +0 -0
  101. /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/glushkov.py +0 -0
  102. /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/rpq.py +0 -0
  103. /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/transition.py +0 -0
  104. /relationalai/{early_access → experimental}/paths/utilities/__init__.py +0 -0
  105. /relationalai/{semantics/reasoners/graph → experimental}/paths/utilities/iterators.py +0 -0
  106. /relationalai/{semantics/reasoners/graph → experimental}/paths/utilities/prefix_sum.py +0 -0
  107. /relationalai/{semantics/reasoners/graph → experimental}/paths/utilities/utilities.py +0 -0
  108. {relationalai-0.12.3.dist-info → relationalai-0.12.6.dist-info}/entry_points.txt +0 -0
  109. {relationalai-0.12.3.dist-info → relationalai-0.12.6.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, select, String, define
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.api import path, star, match
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.api import path, star, match
4
4
 
5
5
  # Create an automaton that matches paths with pattern: A(A*)B:
6
6
  pattern = path("A", star("A"), "B")
@@ -4,8 +4,8 @@ Example usage of automaton-based pathfinding.
4
4
 
5
5
  import time
6
6
  from relationalai.semantics import Model, Integer, select, String, define
7
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
8
- from relationalai.semantics.reasoners.graph.paths.api import node, path, match
7
+ from relationalai.experimental.paths.graph import Graph
8
+ from relationalai.experimental.paths.api import node, path, match
9
9
 
10
10
  import argparse
11
11
 
@@ -4,8 +4,8 @@ Example usage of automaton-based pathfinding.
4
4
 
5
5
  import time
6
6
  from relationalai.semantics import Model, Integer, select, String, define
7
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
8
- from relationalai.semantics.reasoners.graph.paths.api import node, path, match
7
+ from relationalai.experimental.paths.graph import Graph
8
+ from relationalai.experimental.paths.api import node, path, match
9
9
 
10
10
  import argparse
11
11
 
@@ -1,4 +1,4 @@
1
- from relationalai.semantics.reasoners.graph.paths.api import path, union
1
+ from relationalai.experimental.paths.api import path, union
2
2
  from relationalai.semantics import Concept
3
3
 
4
4
  Node = Concept('Node')
@@ -1,6 +1,6 @@
1
1
  # For builder components.
2
2
  from relationalai.semantics import Integer, define
3
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
+ from relationalai.experimental.paths.graph import Graph
4
4
 
5
5
 
6
6
  def ball_with_repetition(g:Graph, Source, max_length):
@@ -1,8 +1,8 @@
1
1
  # For builder components.
2
2
  from relationalai.semantics import Integer, where, define, select, min
3
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
4
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.one_sided_ball_repetition import ball_with_repetition
5
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.one_sided_ball_upto import ball_upto
3
+ from relationalai.experimental.paths.graph import Graph
4
+ from relationalai.experimental.paths.path_algorithms.one_sided_ball_repetition import ball_with_repetition
5
+ from relationalai.experimental.paths.path_algorithms.one_sided_ball_upto import ball_upto
6
6
 
7
7
  # find a (deterministic) path from src to dst inside the given ball
8
8
  # where dst is at distance radius from src
@@ -1,6 +1,6 @@
1
1
  # For builder components.
2
2
  from relationalai.semantics import Integer, define
3
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
+ from relationalai.experimental.paths.graph import Graph
4
4
 
5
5
 
6
6
  def two_balls_repetition(g:Graph, Source, Target, max_length):
@@ -1,7 +1,7 @@
1
1
  # For builder components.
2
2
  from relationalai.semantics import Integer, define, not_, count
3
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
4
- from relationalai.semantics.reasoners.graph.paths.utilities.iterators import setup_iteration
3
+ from relationalai.experimental.paths.graph import Graph
4
+ from relationalai.experimental.paths.utilities.iterators import setup_iteration
5
5
 
6
6
 
7
7
  def two_balls_upto(g:Graph, Source, Target, max_length=None):
@@ -1,8 +1,8 @@
1
1
  # For builder components.
2
2
  from relationalai.semantics import Integer, define, max, sum, not_
3
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
4
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.one_sided_ball_upto import ball_upto
5
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.one_sided_ball_repetition import ball_with_repetition
3
+ from relationalai.experimental.paths.graph import Graph
4
+ from relationalai.experimental.paths.path_algorithms.one_sided_ball_upto import ball_upto
5
+ from relationalai.experimental.paths.path_algorithms.one_sided_ball_repetition import ball_with_repetition
6
6
 
7
7
 
8
8
  def compute_usp(g: Graph, Source, Target, max_length = None):
@@ -1,8 +1,8 @@
1
1
  # For builder components.
2
2
  from relationalai.semantics import Model, Integer, define, max, sum, select, not_
3
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
4
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.one_sided_ball_upto import ball_upto
5
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.one_sided_ball_repetition import ball_with_repetition
3
+ from relationalai.experimental.paths.graph import Graph
4
+ from relationalai.experimental.paths.path_algorithms.one_sided_ball_upto import ball_upto
5
+ from relationalai.experimental.paths.path_algorithms.one_sided_ball_repetition import ball_with_repetition
6
6
 
7
7
 
8
8
  def compute_usp(g: Graph, Source, Target, max_length = None):
@@ -1,8 +1,8 @@
1
1
  # For builder components.
2
2
  from relationalai.semantics import Integer, define, sum, not_
3
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
4
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.one_sided_ball_upto import ball_upto
5
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.one_sided_ball_repetition import ball_with_repetition
3
+ from relationalai.experimental.paths.graph import Graph
4
+ from relationalai.experimental.paths.path_algorithms.one_sided_ball_upto import ball_upto
5
+ from relationalai.experimental.paths.path_algorithms.one_sided_ball_repetition import ball_with_repetition
6
6
 
7
7
 
8
8
  def compute_usp(g: Graph, Source, Target, max_length=None):
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select, count
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.find_paths import find_shortest_paths
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.find_paths import find_shortest_paths
4
4
 
5
5
 
6
6
  # First test with grid graph
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select, count
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.find_paths import find_shortest_paths
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.find_paths import find_shortest_paths
4
4
 
5
5
 
6
6
  # First test with grid graph
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select, count
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.find_paths import find_shortest_paths
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.find_paths import find_shortest_paths
4
4
 
5
5
 
6
6
  # First test with grid graph
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select, count
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.find_paths import find_walks
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.find_paths import find_walks
4
4
 
5
5
 
6
6
  # First test with grid graph
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select, count
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.find_paths import find_walks
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.find_paths import find_walks
4
4
 
5
5
 
6
6
  # First test with grid graph
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.one_sided_ball_repetition import ball_with_repetition
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.one_sided_ball_repetition import ball_with_repetition
4
4
 
5
5
 
6
6
  # Test with grid graph
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.one_sided_ball_repetition import ball_with_repetition
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.one_sided_ball_repetition import ball_with_repetition
4
4
 
5
5
 
6
6
  # Test with grid graph
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.one_sided_ball_upto import ball_upto
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.one_sided_ball_upto import ball_upto
4
4
 
5
5
 
6
6
  # First test with grid graph and multiple source and target nodes
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.one_sided_ball_upto import ball_upto
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.one_sided_ball_upto import ball_upto
4
4
 
5
5
 
6
6
  # First test with grid graph
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.single import single_shortest_path
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.single import single_shortest_path
4
4
 
5
5
 
6
6
  model = Model("test_single_paths", dry_run=False)
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.single import single_walk
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.single import single_walk
4
4
 
5
5
 
6
6
  model = Model("test_single_paths", dry_run=False)
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.single import single_walk
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.single import single_walk
4
4
 
5
5
 
6
6
  model = Model("test_single_paths", dry_run=False)
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.two_sided_balls_repetition import two_balls_repetition
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.two_sided_balls_repetition import two_balls_repetition
4
4
 
5
5
 
6
6
  # Test with diamond graph
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.two_sided_balls_repetition import two_balls_repetition
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.two_sided_balls_repetition import two_balls_repetition
4
4
 
5
5
 
6
6
  # Test with diamond graph
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.two_sided_balls_upto import two_balls_upto
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.two_sided_balls_upto import two_balls_upto
4
4
 
5
5
 
6
6
  # Test with grid graph
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.two_sided_balls_upto import two_balls_upto
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.two_sided_balls_upto import two_balls_upto
4
4
 
5
5
 
6
6
  # Test with grid graph
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.usp import compute_usp, compute_nsp
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.usp import compute_usp, compute_nsp
4
4
 
5
5
 
6
6
  # First test for usp with grid graph
@@ -1,6 +1,6 @@
1
1
  from relationalai.semantics import Model, Integer, define, select
2
- from relationalai.semantics.reasoners.graph.paths.graph import Graph
3
- from relationalai.semantics.reasoners.graph.paths.path_algorithms.usp import compute_usp, compute_nsp
2
+ from relationalai.experimental.paths.graph import Graph
3
+ from relationalai.experimental.paths.path_algorithms.usp import compute_usp, compute_nsp
4
4
 
5
5
 
6
6
  # First test for usp with grid graph
@@ -1,3 +1,7 @@
1
+ """
2
+ The RelationalAI Semantics Module.
3
+ """
4
+
1
5
  # Mark this package's docstrings for inclusion
2
6
  # in automatically generated web documentation.
3
7
  __include_in_docs__ = True
@@ -6,3 +6,4 @@ concept_population = Relationship.builtins["concept_population"]
6
6
  function = Relationship.builtins["function"]
7
7
  from_cdc = Relationship.builtins["from_cdc"]
8
8
  track = Relationship.builtins["track"]
9
+ recursion_config = Relationship.builtins["recursion_config"]
@@ -3419,6 +3419,8 @@ class Compiler():
3419
3419
  return out
3420
3420
 
3421
3421
  elif isinstance(item, TypeRef):
3422
+ if isinstance(item._thing, Relationship):
3423
+ return self.to_relation(item._thing)
3422
3424
  concept = to_type(item)
3423
3425
  if not concept:
3424
3426
  raise ValueError(f"Cannot find concept for {item}, {type(item)}")
@@ -264,12 +264,11 @@ class Table():
264
264
  else:
265
265
  me = self._rel._field_refs[0]
266
266
  b.where(self).define(concept(me))
267
- # if there are no keys all the fields must be properties
268
- rel_func = b.Relationship if keys else b.Property
267
+ # All the fields are treated as properties
269
268
  for field in self._rel._fields[1:]:
270
269
  field_name = sanitize_identifier(field.name.lower())
271
270
  if field_name not in key_dict:
272
- r = rel_func(
271
+ r = b.Property(
273
272
  f"{{{concept}}} has {{{field_name}:{field.type_str}}}",
274
273
  parent=concept,
275
274
  short_name=field_name,
@@ -12,4 +12,5 @@ annotations_to_emit = FrozenOrderedSet([
12
12
  adhoc.name,
13
13
  builtins.function.name,
14
14
  builtins.track.name,
15
+ builtins.recursion_config.name,
15
16
  ])
@@ -56,7 +56,15 @@ class LQPExecutor(e.Executor):
56
56
  resource_class = rai.clients.snowflake.Resources
57
57
  if self.config.get("use_direct_access", USE_DIRECT_ACCESS):
58
58
  resource_class = rai.clients.snowflake.DirectAccessResources
59
- self._resources = resource_class(dry_run=self.dry_run, config=self.config, generation=rai.Generation.QB, connection=self.connection)
59
+ # NOTE: language="lqp" is not strictly required for LQP execution, but it
60
+ # will significantly improve performance.
61
+ self._resources = resource_class(
62
+ dry_run=self.dry_run,
63
+ config=self.config,
64
+ generation=rai.Generation.QB,
65
+ connection=self.connection,
66
+ language="lqp",
67
+ )
60
68
  if not self.dry_run:
61
69
  self.engine = self._resources.get_default_engine_name()
62
70
  if not self.keep_model:
@@ -88,13 +96,12 @@ class LQPExecutor(e.Executor):
88
96
  assert self.engine is not None
89
97
 
90
98
  with debugging.span("poll_use_index", sources=sources, model=model, engine=engine_name):
91
- resources.poll_use_index(
99
+ resources.maybe_poll_use_index(
92
100
  app_name=app_name,
93
101
  sources=sources,
94
102
  model=model,
95
103
  engine_name=self.engine,
96
104
  engine_size=engine_size,
97
- language="lqp",
98
105
  program_span_id=program_span_id,
99
106
  )
100
107
 
@@ -280,6 +287,8 @@ class LQPExecutor(e.Executor):
280
287
  """Construct an epoch that defines a number of built-in definitions used by the
281
288
  emitter."""
282
289
  with debugging.span("compile_intrinsics") as span:
290
+ span["compile_type"] = "intrinsics"
291
+
283
292
  debug_info = lqp_ir.DebugInfo(id_to_orig_name={}, meta=None)
284
293
  intrinsics_fragment = lqp_ir.Fragment(
285
294
  id = lqp_ir.FragmentId(id=b"__pyrel_lqp_intrinsics", meta=None),
@@ -290,7 +299,7 @@ class LQPExecutor(e.Executor):
290
299
  meta = None,
291
300
  )
292
301
 
293
- span["compile_type"] = "intrinsics"
302
+
294
303
  span["lqp"] = lqp_print.to_string(intrinsics_fragment, {"print_names": True, "print_debug": False, "print_csv_filename": False})
295
304
 
296
305
  return lqp_ir.Epoch(
@@ -327,13 +336,14 @@ class LQPExecutor(e.Executor):
327
336
  model_txn = None
328
337
  if self._last_model != model:
329
338
  with debugging.span("compile", metamodel=model) as install_span:
339
+ install_span["compile_type"] = "model"
330
340
  _, model_txn = self.compiler.compile(model, {"fragment_id": b"model"})
331
341
  model_txn = txn_with_configure(model_txn, configure)
332
- install_span["compile_type"] = "model"
333
342
  install_span["lqp"] = lqp_print.to_string(model_txn, {"print_names": True, "print_debug": False, "print_csv_filename": False})
334
343
  self._last_model = model
335
344
 
336
345
  with debugging.span("compile", metamodel=task) as compile_span:
346
+ compile_span["compile_type"] = "query"
337
347
  query = f.compute_model(f.logical([task]))
338
348
  options = {
339
349
  "wide_outputs": self.wide_outputs,
@@ -342,7 +352,6 @@ class LQPExecutor(e.Executor):
342
352
  result, final_model = self.compiler.compile_inner(query, options)
343
353
  export_info, query_txn = result
344
354
  query_txn = txn_with_configure(query_txn, configure)
345
- compile_span["compile_type"] = "query"
346
355
  compile_span["lqp"] = lqp_print.to_string(query_txn, {"print_names": True, "print_debug": False, "print_csv_filename": False})
347
356
 
348
357
  # Merge the epochs into a single transactions. Long term the query bits should all
@@ -356,14 +365,10 @@ class LQPExecutor(e.Executor):
356
365
  epochs.append(model_txn.epochs[0])
357
366
 
358
367
  query_txn_epoch = query_txn.epochs[0]
359
-
360
368
  epochs.append(query_txn_epoch)
361
-
362
369
  epochs.append(self._compile_undefine_query(query_txn_epoch))
363
370
 
364
371
  txn = lqp_ir.Transaction(epochs=epochs, configure=configure, meta=None)
365
-
366
- # Revalidate now that we've joined all the epochs.
367
372
  validate_lqp(txn)
368
373
 
369
374
  txn_proto = convert_transaction(txn)
@@ -62,7 +62,6 @@ def to_lqp(model: ir.Model, fragment_name: bytes, ctx: TranslationCtx) -> tuple[
62
62
  meta=None,
63
63
  )
64
64
 
65
- lqp.validate_lqp(txn)
66
65
  return (export_info, txn)
67
66
 
68
67
  def _effect_bindings(effect: Union[ir.Output, ir.Update]) -> list[ir.Value]:
@@ -254,7 +253,7 @@ def _translate_rank(ctx: TranslationCtx, rank: ir.Rank, body: lqp.Formula) -> lq
254
253
  # to convert it to Int128.
255
254
  result_var, _ = _translate_term(ctx, rank.result)
256
255
  # The primitive will return an Int64 result, so we need a var to hold the intermediary.
257
- result_64_var = gen_unique_var(ctx, "result_64")
256
+ result_64_var = gen_unique_var(ctx, "rank_result_64")
258
257
  result_64_type = mk_type(lqp.TypeName.INT)
259
258
 
260
259
  cast = lqp.Cast(input=result_64_var, result=result_var, meta=None)
@@ -274,7 +273,7 @@ def _translate_descending_rank(ctx: TranslationCtx, limit: int, result: lqp.Var,
274
273
  result_type = mk_type(lqp.TypeName.INT)
275
274
 
276
275
  # Rename abstracted args in the body to new variable names
277
- var_map = {var.name: gen_unique_var(ctx, var.name) for (var, _) in abstr_args}
276
+ var_map = {var.name: gen_unique_var(ctx, 't_' + var.name) for (var, _) in abstr_args}
278
277
  body = utils.rename_vars_formula(body, var_map)
279
278
  new_abstr_args = [(var_map[var.name], typ) for (var, typ) in abstr_args]
280
279
 
@@ -341,7 +340,7 @@ def _translate_ascending_rank(ctx: TranslationCtx, limit: int, result_var: lqp.V
341
340
  terms = [result_var] + [v[0] for v in abstr_args]
342
341
 
343
342
  # Rename abstracted args in the body to new variable names
344
- var_map = {var.name: gen_unique_var(ctx, var.name) for (var, _) in abstr_args}
343
+ var_map = {var.name: gen_unique_var(ctx, 't_' + var.name) for (var, _) in abstr_args}
345
344
  body = utils.rename_vars_formula(body, var_map)
346
345
  new_abstr_args = [(var_map[var.name], typ) for (var, typ) in abstr_args]
347
346
  sort_abstr = mk_abstraction(new_abstr_args, body)
@@ -462,6 +461,7 @@ def _translate_aggregate(ctx: TranslationCtx, aggr: ir.Aggregate, body: lqp.Form
462
461
  # `input_args`` hold the types of the input arguments, but they may have been modified
463
462
  # if we're dealing with a count, so we use `abstr_args` to find the type.
464
463
  (aggr_arg, aggr_arg_type) = abstr_args[-1]
464
+
465
465
  # Group-bys do not need to be handled at all, since they are introduced outside already
466
466
  reduce = lqp.Reduce(
467
467
  op=lqp_operator(ctx.var_names, aggr.aggregation.name, aggr_arg.name, aggr_arg_type),
@@ -543,6 +543,12 @@ def _translate_to_atom(ctx: TranslationCtx, task: ir.Lookup) -> lqp.Formula:
543
543
 
544
544
  if task.relation == builtins.join:
545
545
  return _translate_join(ctx, task)
546
+ elif task.relation == builtins.infomap:
547
+ return _translate_infomap(ctx, task)
548
+ elif task.relation == builtins.louvain:
549
+ return _translate_louvain(ctx, task)
550
+ elif task.relation == builtins.label_propagation:
551
+ return _translate_label_propagation(ctx, task)
546
552
 
547
553
  terms = []
548
554
  term_types = []
@@ -668,6 +674,92 @@ def _extract_pyrel_error_ids(ctx: TranslationCtx, model: ir.Model) -> list[Tuple
668
674
 
669
675
  return pyrel_error_attrs
670
676
 
677
+ # Translate a relation reference into an abstraction over its fields.
678
+ def _translate_relation_ref(ctx: TranslationCtx, relation: ir.Relation) -> lqp.Abstraction:
679
+ projection = []
680
+ for field in relation.fields:
681
+ var = gen_unique_var(ctx, field.name)
682
+ typ = meta_type_to_lqp(field.type)
683
+ projection.append((var, typ))
684
+
685
+ rid = get_relation_id(ctx, relation, projection)
686
+ atom = lqp.Atom(name=rid, terms=[var for (var, _) in projection], meta=None)
687
+ return mk_abstraction(projection, atom)
688
+
689
+ # Common translation logic for graph algorithms.
690
+ # task.args[0] : normalized weight list (int64, int64, float)
691
+ # task.args[1] : normalized node count (relation or constant int64)
692
+ # task.args[2] : normalized edge count (relation or constant int64)
693
+ # task.args[3:-3] : algorithm parameters (var or constant)
694
+ # task.args[-3] : diagnostic info
695
+ # task.args[-2] : node index
696
+ # task.args[-1] : community ident
697
+ def _translate_graph_common(name: str, ctx: TranslationCtx, task: ir.Lookup):
698
+ abstractions = []
699
+
700
+ assert isinstance(task.args[0], ir.Relation), \
701
+ f"Expected relation as first arg to {name}, got {task.args[0]}:{type(task.args[0])}"
702
+ abstractions.append(_translate_relation_ref(ctx, task.args[0]))
703
+
704
+ # Allow constant args for node and edge count
705
+ for arg in task.args[1:3]:
706
+ if isinstance(arg, ir.Relation):
707
+ abst = _translate_relation_ref(ctx, arg)
708
+ typ = abst.vars[0][1]
709
+ assert typ.type_name == lqp.TypeName.INT, \
710
+ f"Expected Int64 types for node and edge counts, got type {typ.type_name}"
711
+ abstractions.append(abst)
712
+ else:
713
+ var, typ, eq = binding_to_lqp_var(ctx, arg)
714
+ assert eq is not None, \
715
+ f"Expected equality formula for {name} arg {arg}:{type(arg)}"
716
+ abstractions.append(mk_abstraction([(var, typ)], mk_and([eq])))
717
+
718
+ for arg in task.args[3:-3]:
719
+ var, typ, eq = binding_to_lqp_var(ctx, arg)
720
+ if eq:
721
+ abstractions.append(mk_abstraction([(var, typ)], mk_and([eq])))
722
+ else:
723
+ print(f"Primitive graph algorithm arg without eq:\n var:{var}, typ:{typ}\n arg:{arg}:{type(arg)}")
724
+ abstractions.append(mk_abstraction([(var, typ)], mk_and([])))
725
+
726
+ terms = []
727
+ for arg in task.args[-3:]:
728
+ term, _ = _translate_relterm(ctx, arg)
729
+ terms.append(term)
730
+
731
+ return (abstractions, terms)
732
+
733
+ def _translate_infomap(ctx: TranslationCtx, task: ir.Lookup) -> lqp.Formula:
734
+ abstractions, terms = _translate_graph_common("infomap", ctx, task)
735
+
736
+ return lqp.FFI(
737
+ meta=None,
738
+ name="rel_primitive_infomap",
739
+ args=abstractions,
740
+ terms=terms,
741
+ )
742
+
743
+ def _translate_louvain(ctx: TranslationCtx, task: ir.Lookup) -> lqp.Formula:
744
+ abstractions, terms = _translate_graph_common("louvain", ctx, task)
745
+
746
+ return lqp.FFI(
747
+ meta=None,
748
+ name="rel_primitive_louvain",
749
+ args=abstractions,
750
+ terms=terms,
751
+ )
752
+
753
+ def _translate_label_propagation(ctx: TranslationCtx, task: ir.Lookup) -> lqp.Formula:
754
+ abstractions, terms = _translate_graph_common("label_propagation", ctx, task)
755
+
756
+ return lqp.FFI(
757
+ meta=None,
758
+ name="rel_primitive_async_label_propagation",
759
+ args=abstractions,
760
+ terms=terms,
761
+ )
762
+
671
763
  # Hard-coded implementation of Rel's string_join
672
764
  def _translate_join(ctx: TranslationCtx, task: ir.Lookup) -> lqp.Formula:
673
765
  assert len(task.args) == 3
@@ -96,6 +96,9 @@ rel_to_lqp = {
96
96
  "split": "rel_primitive_string_split",
97
97
  "split_part": "rel_primitive_string_split",
98
98
  "regex_match": "rel_primitive_regex_match",
99
+ "infomap": "rel_primitive_infomap",
100
+ "louvain": "rel_primitive_louvain",
101
+ "label_propagation": "rel_primitive_async_label_propagation",
99
102
  }
100
103
 
101
104
  primitive_type_reorderings = {