relationalai 0.12.4__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 (101) hide show
  1. relationalai/__init__.py +4 -0
  2. relationalai/clients/snowflake.py +23 -11
  3. relationalai/{semantics/reasoners/graph → experimental}/paths/README.md +2 -2
  4. relationalai/experimental/paths/__init__.py +14 -309
  5. relationalai/{semantics/reasoners/graph → experimental}/paths/examples/basic_example.py +2 -2
  6. relationalai/{semantics/reasoners/graph → experimental}/paths/examples/paths_benchmark.py +2 -2
  7. relationalai/{semantics/reasoners/graph → experimental}/paths/examples/paths_example.py +2 -2
  8. relationalai/{semantics/reasoners/graph → experimental}/paths/examples/pattern_to_automaton.py +1 -1
  9. relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/one_sided_ball_repetition.py +1 -1
  10. relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/single.py +3 -3
  11. relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/two_sided_balls_repetition.py +1 -1
  12. relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/two_sided_balls_upto.py +2 -2
  13. relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/usp-old.py +3 -3
  14. relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/usp-tuple.py +3 -3
  15. relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/usp.py +3 -3
  16. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_limit_sp_max_length.py +2 -2
  17. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_limit_sp_multiple.py +2 -2
  18. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_limit_sp_single.py +2 -2
  19. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_limit_walks_multiple.py +2 -2
  20. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_limit_walks_single.py +2 -2
  21. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_one_sided_ball_repetition_multiple.py +2 -2
  22. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_one_sided_ball_repetition_single.py +2 -2
  23. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_one_sided_ball_upto_multiple.py +2 -2
  24. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_one_sided_ball_upto_single.py +2 -2
  25. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_single_paths.py +2 -2
  26. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_single_walks.py +2 -2
  27. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_single_walks_undirected.py +2 -2
  28. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_two_sided_balls_repetition_multiple.py +2 -2
  29. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_two_sided_balls_repetition_single.py +2 -2
  30. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_two_sided_balls_upto_multiple.py +2 -2
  31. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_two_sided_balls_upto_single.py +2 -2
  32. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_usp_nsp_multiple.py +2 -2
  33. relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_usp_nsp_single.py +2 -2
  34. relationalai/semantics/__init__.py +4 -0
  35. relationalai/semantics/internal/annotations.py +1 -0
  36. relationalai/semantics/internal/internal.py +2 -0
  37. relationalai/semantics/lqp/builtins.py +1 -0
  38. relationalai/semantics/lqp/model2lqp.py +96 -3
  39. relationalai/semantics/lqp/primitives.py +3 -0
  40. relationalai/semantics/metamodel/builtins.py +50 -1
  41. relationalai/semantics/metamodel/typer/typer.py +3 -0
  42. relationalai/semantics/reasoners/__init__.py +4 -0
  43. relationalai/semantics/reasoners/experimental/__init__.py +7 -0
  44. relationalai/semantics/reasoners/graph/core.py +1154 -122
  45. relationalai/semantics/rel/builtins.py +3 -1
  46. relationalai/semantics/rel/rel_utils.py +5 -0
  47. relationalai/semantics/sql/compiler.py +6 -0
  48. {relationalai-0.12.4.dist-info → relationalai-0.12.6.dist-info}/METADATA +1 -1
  49. {relationalai-0.12.4.dist-info → relationalai-0.12.6.dist-info}/RECORD +84 -100
  50. {relationalai-0.12.4.dist-info → relationalai-0.12.6.dist-info}/WHEEL +1 -1
  51. relationalai/early_access/paths/__init__.py +0 -22
  52. relationalai/early_access/paths/api/__init__.py +0 -12
  53. relationalai/early_access/paths/benchmarks/__init__.py +0 -13
  54. relationalai/early_access/paths/graph/__init__.py +0 -12
  55. relationalai/early_access/paths/path_algorithms/find_paths/__init__.py +0 -12
  56. relationalai/early_access/paths/path_algorithms/one_sided_ball_repetition/__init__.py +0 -12
  57. relationalai/early_access/paths/path_algorithms/one_sided_ball_upto/__init__.py +0 -12
  58. relationalai/early_access/paths/path_algorithms/single/__init__.py +0 -12
  59. relationalai/early_access/paths/path_algorithms/two_sided_balls_repetition/__init__.py +0 -12
  60. relationalai/early_access/paths/path_algorithms/two_sided_balls_upto/__init__.py +0 -12
  61. relationalai/early_access/paths/path_algorithms/usp/__init__.py +0 -12
  62. relationalai/early_access/paths/rpq/__init__.py +0 -13
  63. relationalai/early_access/paths/utilities/iterators/__init__.py +0 -12
  64. relationalai/experimental/paths/pathfinder.rel +0 -2560
  65. relationalai/semantics/reasoners/graph/paths/__init__.py +0 -16
  66. relationalai/semantics/reasoners/graph/paths/path_algorithms/__init__.py +0 -3
  67. relationalai/semantics/reasoners/graph/paths/utilities/__init__.py +0 -3
  68. /relationalai/{semantics/reasoners/graph → experimental}/paths/api.py +0 -0
  69. /relationalai/{semantics/reasoners/graph → experimental}/paths/benchmarks/__init__.py +0 -0
  70. /relationalai/{semantics/reasoners/graph → experimental}/paths/benchmarks/grid_graph.py +0 -0
  71. /relationalai/{semantics/reasoners/graph → experimental}/paths/code_organization.md +0 -0
  72. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/Movies.ipynb +0 -0
  73. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/minimal_engine_warmup.py +0 -0
  74. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movie_example.py +0 -0
  75. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/actedin.csv +0 -0
  76. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/directed.csv +0 -0
  77. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/follows.csv +0 -0
  78. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/movies.csv +0 -0
  79. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/person.csv +0 -0
  80. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/produced.csv +0 -0
  81. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/ratings.csv +0 -0
  82. /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/wrote.csv +0 -0
  83. /relationalai/{semantics/reasoners/graph → experimental}/paths/find_paths_via_automaton.py +0 -0
  84. /relationalai/{semantics/reasoners/graph → experimental}/paths/graph.py +0 -0
  85. /relationalai/{early_access → experimental}/paths/path_algorithms/__init__.py +0 -0
  86. /relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/find_paths.py +0 -0
  87. /relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/one_sided_ball_upto.py +0 -0
  88. /relationalai/{semantics/reasoners/graph → experimental}/paths/product_graph.py +0 -0
  89. /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/__init__.py +0 -0
  90. /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/automaton.py +0 -0
  91. /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/diagnostics.py +0 -0
  92. /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/filter.py +0 -0
  93. /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/glushkov.py +0 -0
  94. /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/rpq.py +0 -0
  95. /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/transition.py +0 -0
  96. /relationalai/{early_access → experimental}/paths/utilities/__init__.py +0 -0
  97. /relationalai/{semantics/reasoners/graph → experimental}/paths/utilities/iterators.py +0 -0
  98. /relationalai/{semantics/reasoners/graph → experimental}/paths/utilities/prefix_sum.py +0 -0
  99. /relationalai/{semantics/reasoners/graph → experimental}/paths/utilities/utilities.py +0 -0
  100. {relationalai-0.12.4.dist-info → relationalai-0.12.6.dist-info}/entry_points.txt +0 -0
  101. {relationalai-0.12.4.dist-info → relationalai-0.12.6.dist-info}/licenses/LICENSE +0 -0
@@ -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)}")
@@ -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
  ])
@@ -253,7 +253,7 @@ def _translate_rank(ctx: TranslationCtx, rank: ir.Rank, body: lqp.Formula) -> lq
253
253
  # to convert it to Int128.
254
254
  result_var, _ = _translate_term(ctx, rank.result)
255
255
  # The primitive will return an Int64 result, so we need a var to hold the intermediary.
256
- result_64_var = gen_unique_var(ctx, "result_64")
256
+ result_64_var = gen_unique_var(ctx, "rank_result_64")
257
257
  result_64_type = mk_type(lqp.TypeName.INT)
258
258
 
259
259
  cast = lqp.Cast(input=result_64_var, result=result_var, meta=None)
@@ -273,7 +273,7 @@ def _translate_descending_rank(ctx: TranslationCtx, limit: int, result: lqp.Var,
273
273
  result_type = mk_type(lqp.TypeName.INT)
274
274
 
275
275
  # Rename abstracted args in the body to new variable names
276
- 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}
277
277
  body = utils.rename_vars_formula(body, var_map)
278
278
  new_abstr_args = [(var_map[var.name], typ) for (var, typ) in abstr_args]
279
279
 
@@ -340,7 +340,7 @@ def _translate_ascending_rank(ctx: TranslationCtx, limit: int, result_var: lqp.V
340
340
  terms = [result_var] + [v[0] for v in abstr_args]
341
341
 
342
342
  # Rename abstracted args in the body to new variable names
343
- 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}
344
344
  body = utils.rename_vars_formula(body, var_map)
345
345
  new_abstr_args = [(var_map[var.name], typ) for (var, typ) in abstr_args]
346
346
  sort_abstr = mk_abstraction(new_abstr_args, body)
@@ -461,6 +461,7 @@ def _translate_aggregate(ctx: TranslationCtx, aggr: ir.Aggregate, body: lqp.Form
461
461
  # `input_args`` hold the types of the input arguments, but they may have been modified
462
462
  # if we're dealing with a count, so we use `abstr_args` to find the type.
463
463
  (aggr_arg, aggr_arg_type) = abstr_args[-1]
464
+
464
465
  # Group-bys do not need to be handled at all, since they are introduced outside already
465
466
  reduce = lqp.Reduce(
466
467
  op=lqp_operator(ctx.var_names, aggr.aggregation.name, aggr_arg.name, aggr_arg_type),
@@ -542,6 +543,12 @@ def _translate_to_atom(ctx: TranslationCtx, task: ir.Lookup) -> lqp.Formula:
542
543
 
543
544
  if task.relation == builtins.join:
544
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)
545
552
 
546
553
  terms = []
547
554
  term_types = []
@@ -667,6 +674,92 @@ def _extract_pyrel_error_ids(ctx: TranslationCtx, model: ir.Model) -> list[Tuple
667
674
 
668
675
  return pyrel_error_attrs
669
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
+
670
763
  # Hard-coded implementation of Rel's string_join
671
764
  def _translate_join(ctx: TranslationCtx, task: ir.Lookup) -> lqp.Formula:
672
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 = {
@@ -507,6 +507,13 @@ track = f.relation("track", [
507
507
  ])
508
508
  track_annotation = f.annotation(track, [])
509
509
 
510
+ # Enables config used by raicode/src/Recursion. Supported for Relationships and queries.
511
+ recursion_config = f.relation("recursion_config", [
512
+ f.input_field("config_key", types.Symbol),
513
+ f.input_field("config_value", types.Int64)
514
+ ])
515
+ recursion_config_annotation = f.annotation(recursion_config, [])
516
+
510
517
  # All ir nodes marked by this annotation will be removed from the final metamodel before compilation.
511
518
  # Specifically it happens in `Flatten` pass when rewrites for `require` happen
512
519
  discharged = f.relation("discharged", [])
@@ -648,6 +655,48 @@ rel_primitive_solverlib_ho_appl = aggregation("rel_primitive_solverlib_ho_appl",
648
655
  implies = f.relation("implies", [f.input_field("a", types.Bool), f.input_field("b", types.Bool)])
649
656
  all_different = aggregation("all_different", [f.input_field("over", types.Any)])
650
657
 
658
+ # graph primitive algorithm helpers
659
+ infomap = aggregation("infomap", [
660
+ f.input_field("weights", types.AnyList),
661
+ f.input_field("node_count", types.Any),
662
+ f.input_field("edge_count", types.Any),
663
+ f.input_field("teleportation_rate", types.Float),
664
+ f.input_field("visit_rate_tolerance", types.Float),
665
+ f.input_field("level_tolerance", types.Float),
666
+ f.input_field("sweep_tolerance", types.Float),
667
+ f.input_field("max_levels", types.Int64),
668
+ f.input_field("max_sweeps", types.Int64),
669
+ f.input_field("randomization_seed", types.Int64),
670
+ f.field("termination_info", types.String),
671
+ f.field("node_index", types.Int64),
672
+ f.field("community", types.Int64)
673
+ ])
674
+
675
+ louvain = aggregation("louvain", [
676
+ f.input_field("weights", types.AnyList),
677
+ f.input_field("node_count", types.Any),
678
+ f.input_field("edge_count", types.Any),
679
+ f.input_field("level_tolerance", types.Float),
680
+ f.input_field("sweep_tolerance", types.Float),
681
+ f.input_field("max_levels", types.Int64),
682
+ f.input_field("max_sweeps", types.Int64),
683
+ f.input_field("randomization_seed", types.Int64),
684
+ f.field("termination_info", types.String),
685
+ f.field("node_index", types.Int64),
686
+ f.field("community", types.Int64)
687
+ ])
688
+
689
+ label_propagation = aggregation("label_propagation", [
690
+ f.input_field("weights", types.AnyList),
691
+ f.input_field("node_count", types.Any),
692
+ f.input_field("edge_count", types.Any),
693
+ f.input_field("max_sweeps", types.Int64),
694
+ f.input_field("randomization_seed", types.Int64),
695
+ f.field("termination_info", types.String),
696
+ f.field("node_index", types.Int64),
697
+ f.field("community", types.Int64)
698
+ ])
699
+
651
700
  #
652
701
  # Public access to built-in relations
653
702
  #
@@ -683,7 +732,7 @@ def _compute_builtin_overloads() -> list[ir.Relation]:
683
732
  return overloads
684
733
 
685
734
  # manually maintain the list of relations that are actually annotations
686
- builtin_annotations = [external, export, concept_population, from_cdc, from_cast, track]
735
+ builtin_annotations = [external, export, concept_population, from_cdc, from_cast, track, recursion_config]
687
736
  builtin_annotations_by_name = dict((r.name, r) for r in builtin_annotations)
688
737
 
689
738
  builtin_relations = _compute_builtin_relations()
@@ -137,6 +137,9 @@ def to_type(value: ir.Value|ir.Field) -> ir.Type:
137
137
  if isinstance(value, tuple):
138
138
  return types.AnyList
139
139
 
140
+ if isinstance(value, ir.Relation):
141
+ return types.AnyList
142
+
140
143
  raise TypeError(f"Cannot determine IR type for value: {value} of type {type(value).__name__}")
141
144
 
142
145
  def type_matches(actual:ir.Type, expected:ir.Type, allow_expected_parents=False) -> bool:
@@ -1,3 +1,7 @@
1
+ """
2
+ The RelationalAI Semantics Reasoners Module.
3
+ """
4
+
1
5
  # Mark this package's docstrings for inclusion
2
6
  # in automatically generated web documentation,
3
7
  # by default as early access.
@@ -0,0 +1,7 @@
1
+ """
2
+ Experimental reasoners and algorithms.
3
+
4
+ This namespace contains experimental features that may change in future versions.
5
+ """
6
+
7
+ __all__ = []