relationalai 0.12.4__py3-none-any.whl → 0.12.7__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.
- relationalai/__init__.py +4 -0
- relationalai/clients/snowflake.py +34 -13
- relationalai/early_access/lqp/constructors/__init__.py +2 -2
- relationalai/early_access/metamodel/rewrite/__init__.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/README.md +2 -2
- relationalai/experimental/paths/__init__.py +14 -309
- relationalai/{semantics/reasoners/graph → experimental}/paths/examples/basic_example.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/examples/paths_benchmark.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/examples/paths_example.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/examples/pattern_to_automaton.py +1 -1
- relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/one_sided_ball_repetition.py +1 -1
- relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/single.py +3 -3
- relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/two_sided_balls_repetition.py +1 -1
- relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/two_sided_balls_upto.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/usp-old.py +3 -3
- relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/usp-tuple.py +3 -3
- relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/usp.py +3 -3
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_limit_sp_max_length.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_limit_sp_multiple.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_limit_sp_single.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_limit_walks_multiple.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_limit_walks_single.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_one_sided_ball_repetition_multiple.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_one_sided_ball_repetition_single.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_one_sided_ball_upto_multiple.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_one_sided_ball_upto_single.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_single_paths.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_single_walks.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_single_walks_undirected.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_two_sided_balls_repetition_multiple.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_two_sided_balls_repetition_single.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_two_sided_balls_upto_multiple.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_two_sided_balls_upto_single.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_usp_nsp_multiple.py +2 -2
- relationalai/{semantics/reasoners/graph → experimental}/paths/tests/tests_usp_nsp_single.py +2 -2
- relationalai/semantics/__init__.py +4 -0
- relationalai/semantics/internal/annotations.py +1 -0
- relationalai/semantics/internal/internal.py +3 -4
- relationalai/semantics/internal/snowflake.py +14 -1
- relationalai/semantics/lqp/builtins.py +1 -0
- relationalai/semantics/lqp/constructors.py +0 -5
- relationalai/semantics/lqp/executor.py +34 -10
- relationalai/semantics/lqp/intrinsics.py +2 -2
- relationalai/semantics/lqp/model2lqp.py +105 -9
- relationalai/semantics/lqp/passes.py +27 -8
- relationalai/semantics/lqp/primitives.py +18 -15
- relationalai/semantics/lqp/rewrite/__init__.py +2 -2
- relationalai/semantics/lqp/rewrite/{fd_constraints.py → function_annotations.py} +4 -4
- relationalai/semantics/lqp/utils.py +17 -13
- relationalai/semantics/metamodel/builtins.py +50 -1
- relationalai/semantics/metamodel/typer/typer.py +3 -0
- relationalai/semantics/reasoners/__init__.py +4 -0
- relationalai/semantics/reasoners/experimental/__init__.py +7 -0
- relationalai/semantics/reasoners/graph/core.py +1154 -122
- relationalai/semantics/rel/builtins.py +3 -1
- relationalai/semantics/rel/compiler.py +2 -2
- relationalai/semantics/rel/executor.py +30 -8
- relationalai/semantics/rel/rel_utils.py +5 -0
- relationalai/semantics/snowflake/__init__.py +2 -2
- relationalai/semantics/sql/compiler.py +6 -0
- relationalai/semantics/sql/executor/snowflake.py +6 -2
- relationalai/semantics/tests/test_snapshot_abstract.py +5 -4
- {relationalai-0.12.4.dist-info → relationalai-0.12.7.dist-info}/METADATA +2 -2
- {relationalai-0.12.4.dist-info → relationalai-0.12.7.dist-info}/RECORD +99 -115
- {relationalai-0.12.4.dist-info → relationalai-0.12.7.dist-info}/WHEEL +1 -1
- relationalai/early_access/paths/__init__.py +0 -22
- relationalai/early_access/paths/api/__init__.py +0 -12
- relationalai/early_access/paths/benchmarks/__init__.py +0 -13
- relationalai/early_access/paths/graph/__init__.py +0 -12
- relationalai/early_access/paths/path_algorithms/find_paths/__init__.py +0 -12
- relationalai/early_access/paths/path_algorithms/one_sided_ball_repetition/__init__.py +0 -12
- relationalai/early_access/paths/path_algorithms/one_sided_ball_upto/__init__.py +0 -12
- relationalai/early_access/paths/path_algorithms/single/__init__.py +0 -12
- relationalai/early_access/paths/path_algorithms/two_sided_balls_repetition/__init__.py +0 -12
- relationalai/early_access/paths/path_algorithms/two_sided_balls_upto/__init__.py +0 -12
- relationalai/early_access/paths/path_algorithms/usp/__init__.py +0 -12
- relationalai/early_access/paths/rpq/__init__.py +0 -13
- relationalai/early_access/paths/utilities/iterators/__init__.py +0 -12
- relationalai/experimental/paths/pathfinder.rel +0 -2560
- relationalai/semantics/reasoners/graph/paths/__init__.py +0 -16
- relationalai/semantics/reasoners/graph/paths/path_algorithms/__init__.py +0 -3
- relationalai/semantics/reasoners/graph/paths/utilities/__init__.py +0 -3
- /relationalai/{semantics/reasoners/graph → experimental}/paths/api.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/benchmarks/__init__.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/benchmarks/grid_graph.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/code_organization.md +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/Movies.ipynb +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/minimal_engine_warmup.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movie_example.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/actedin.csv +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/directed.csv +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/follows.csv +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/movies.csv +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/person.csv +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/produced.csv +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/ratings.csv +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/examples/movies_data/wrote.csv +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/find_paths_via_automaton.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/graph.py +0 -0
- /relationalai/{early_access → experimental}/paths/path_algorithms/__init__.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/find_paths.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/path_algorithms/one_sided_ball_upto.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/product_graph.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/__init__.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/automaton.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/diagnostics.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/filter.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/glushkov.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/rpq.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/rpq/transition.py +0 -0
- /relationalai/{early_access → experimental}/paths/utilities/__init__.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/utilities/iterators.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/utilities/prefix_sum.py +0 -0
- /relationalai/{semantics/reasoners/graph → experimental}/paths/utilities/utilities.py +0 -0
- {relationalai-0.12.4.dist-info → relationalai-0.12.7.dist-info}/entry_points.txt +0 -0
- {relationalai-0.12.4.dist-info → relationalai-0.12.7.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from relationalai.semantics.metamodel.types import digits_to_bits
|
|
2
2
|
from relationalai.semantics.lqp import ir as lqp
|
|
3
3
|
from relationalai.semantics.lqp.types import is_numeric
|
|
4
|
-
from relationalai.semantics.lqp.utils import
|
|
5
|
-
from relationalai.semantics.lqp.constructors import mk_primitive, mk_specialized_value, mk_type, mk_value
|
|
4
|
+
from relationalai.semantics.lqp.utils import TranslationCtx, gen_unique_var, lqp_hash
|
|
5
|
+
from relationalai.semantics.lqp.constructors import mk_primitive, mk_specialized_value, mk_type, mk_value
|
|
6
6
|
|
|
7
7
|
rel_to_lqp = {
|
|
8
8
|
"=": "rel_primitive_eq",
|
|
@@ -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 = {
|
|
@@ -202,15 +205,15 @@ def is_monotype(name: str) -> bool:
|
|
|
202
205
|
|
|
203
206
|
# We take the name and type of the variable that we're summing over, so that we can generate
|
|
204
207
|
# recognizable names for the variables in the reduce operation and preserve the type.
|
|
205
|
-
def lqp_avg_op(
|
|
208
|
+
def lqp_avg_op(ctx: TranslationCtx, op_name: str, sum_name: str, sum_type: lqp.Type) -> lqp.Abstraction:
|
|
206
209
|
count_type = mk_type(lqp.TypeName.INT)
|
|
207
210
|
vars = [
|
|
208
|
-
(
|
|
209
|
-
(
|
|
210
|
-
(
|
|
211
|
-
(
|
|
212
|
-
(
|
|
213
|
-
(
|
|
211
|
+
(gen_unique_var(ctx, sum_name), sum_type),
|
|
212
|
+
(gen_unique_var(ctx, "counter"), count_type),
|
|
213
|
+
(gen_unique_var(ctx, sum_name), sum_type),
|
|
214
|
+
(gen_unique_var(ctx, "one"), count_type),
|
|
215
|
+
(gen_unique_var(ctx, "sum"), sum_type),
|
|
216
|
+
(gen_unique_var(ctx, "count"), count_type),
|
|
214
217
|
]
|
|
215
218
|
|
|
216
219
|
x1 = vars[0][0]
|
|
@@ -230,10 +233,10 @@ def lqp_avg_op(names: UniqueNames, op_name: str, sum_name: str, sum_type: lqp.Ty
|
|
|
230
233
|
return lqp.Abstraction(vars=vars, value=body, meta=None)
|
|
231
234
|
|
|
232
235
|
# Default handler for aggregation operations in LQP.
|
|
233
|
-
def lqp_agg_op(
|
|
234
|
-
x =
|
|
235
|
-
y =
|
|
236
|
-
z =
|
|
236
|
+
def lqp_agg_op(ctx: TranslationCtx, op_name: str, aggr_arg_name: str, aggr_arg_type: lqp.Type) -> lqp.Abstraction:
|
|
237
|
+
x = gen_unique_var(ctx, f"x_{aggr_arg_name}")
|
|
238
|
+
y = gen_unique_var(ctx, f"y_{aggr_arg_name}")
|
|
239
|
+
z = gen_unique_var(ctx, f"z_{aggr_arg_name}")
|
|
237
240
|
ts = [(x, aggr_arg_type), (y, aggr_arg_type), (z, aggr_arg_type)]
|
|
238
241
|
|
|
239
242
|
name = agg_to_lqp.get(op_name, op_name)
|
|
@@ -241,9 +244,9 @@ def lqp_agg_op(names: UniqueNames, op_name: str, aggr_arg_name: str, aggr_arg_ty
|
|
|
241
244
|
|
|
242
245
|
return lqp.Abstraction(vars=ts, value=body, meta=None)
|
|
243
246
|
|
|
244
|
-
def lqp_operator(
|
|
247
|
+
def lqp_operator(ctx: TranslationCtx, op_name: str, aggr_arg_name: str, aggr_arg_type: lqp.Type) -> lqp.Abstraction:
|
|
245
248
|
# TODO: Can we just pass through unknown operations?
|
|
246
249
|
if op_name not in agg_to_lqp:
|
|
247
250
|
raise NotImplementedError(f"Unsupported aggregation: {op_name}")
|
|
248
251
|
|
|
249
|
-
return lqp_agg_op(
|
|
252
|
+
return lqp_agg_op(ctx, op_name, aggr_arg_name, aggr_arg_type)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from .cdc import CDC
|
|
2
2
|
from .extract_common import ExtractCommon
|
|
3
3
|
from .extract_keys import ExtractKeys
|
|
4
|
-
from .
|
|
4
|
+
from .function_annotations import FunctionAnnotations
|
|
5
5
|
from .quantify_vars import QuantifyVars
|
|
6
6
|
from .splinter import Splinter
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@ __all__ = [
|
|
|
9
9
|
"CDC",
|
|
10
10
|
"ExtractCommon",
|
|
11
11
|
"ExtractKeys",
|
|
12
|
-
"
|
|
12
|
+
"FunctionAnnotations",
|
|
13
13
|
"QuantifyVars",
|
|
14
14
|
"Splinter",
|
|
15
15
|
]
|
|
@@ -5,7 +5,7 @@ from relationalai.semantics.metamodel import ir, compiler as c, visitor as v, bu
|
|
|
5
5
|
from relationalai.semantics.metamodel.util import OrderedSet, ordered_set
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class
|
|
8
|
+
class FunctionAnnotations(c.Pass):
|
|
9
9
|
"""
|
|
10
10
|
Pass marks all appropriate relations with `function` annotation.
|
|
11
11
|
Criteria:
|
|
@@ -17,7 +17,7 @@ class FDConstraints(c.Pass):
|
|
|
17
17
|
collect_fd = CollectFunctionalRelationsVisitor()
|
|
18
18
|
new_model = collect_fd.walk(model)
|
|
19
19
|
# mark relations collected by previous visitor with `@function` annotation
|
|
20
|
-
return
|
|
20
|
+
return FunctionalAnnotationsVisitor(collect_fd.functional_relations).walk(new_model)
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
@dataclass
|
|
@@ -57,9 +57,9 @@ class CollectFunctionalRelationsVisitor(v.Rewriter):
|
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
@dataclass
|
|
60
|
-
class
|
|
60
|
+
class FunctionalAnnotationsVisitor(v.Rewriter):
|
|
61
61
|
"""
|
|
62
|
-
This visitor marks functional_relations with `
|
|
62
|
+
This visitor marks functional_relations with `function` annotation.
|
|
63
63
|
"""
|
|
64
64
|
|
|
65
65
|
def __init__(self, functional_relations: OrderedSet):
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from relationalai.semantics.lqp import ir as lqp
|
|
2
2
|
from relationalai.semantics.metamodel import ir
|
|
3
|
+
from relationalai.semantics.metamodel.helpers import sanitize
|
|
3
4
|
from relationalai.semantics.metamodel.util import FrozenOrderedSet
|
|
4
5
|
|
|
5
6
|
from hashlib import sha256
|
|
@@ -13,21 +14,24 @@ class UniqueNames:
|
|
|
13
14
|
self.id_to_name = dict[int,str]()
|
|
14
15
|
|
|
15
16
|
def get_name(self, name: str) -> str:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
# so test the new name.
|
|
21
|
-
while f"{name}_{id}" in self.seen:
|
|
22
|
-
id += 1
|
|
23
|
-
self.seen[name] = id
|
|
24
|
-
new_name = f"{name}_{id}"
|
|
25
|
-
self.seen[new_name] = 1
|
|
26
|
-
return new_name
|
|
27
|
-
else:
|
|
17
|
+
# Names will eventually be sanitized, which could cause collisions, so we
|
|
18
|
+
# do the sanitization here.
|
|
19
|
+
name = '_' if name == '_' else sanitize(name)
|
|
20
|
+
if name not in self.seen:
|
|
28
21
|
self.seen[name] = 1
|
|
29
22
|
return f"{name}"
|
|
30
23
|
|
|
24
|
+
self.seen[name] += 1
|
|
25
|
+
id = self.seen[name]
|
|
26
|
+
# If the original name has a suffix we can get collisions with generated names,
|
|
27
|
+
# so test the new name.
|
|
28
|
+
while f"{name}_{id}" in self.seen:
|
|
29
|
+
id += 1
|
|
30
|
+
self.seen[name] = id
|
|
31
|
+
new_name = f"{name}_{id}"
|
|
32
|
+
self.seen[new_name] = 1
|
|
33
|
+
return new_name
|
|
34
|
+
|
|
31
35
|
# Get a unique name for the given id. If the id is already in the map, return the
|
|
32
36
|
# existing name. Otherwise, generate a new name using the suggested_name and
|
|
33
37
|
# store it in the map.
|
|
@@ -55,7 +59,7 @@ def gen_rel_id(ctx: TranslationCtx, orig_name: str, suffix: str = "") -> lqp.Rel
|
|
|
55
59
|
ctx.rel_id_to_orig_name[relation_id] = orig_name
|
|
56
60
|
return relation_id
|
|
57
61
|
|
|
58
|
-
def gen_unique_var(ctx: TranslationCtx, name_hint: str):
|
|
62
|
+
def gen_unique_var(ctx: TranslationCtx, name_hint: str) -> lqp.Var:
|
|
59
63
|
"""
|
|
60
64
|
Generate a new variable with a unique name based on the provided hint.
|
|
61
65
|
"""
|
|
@@ -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:
|