Skip to content

Commit

Permalink
Merge pull request #381 from EvgSkv/ti2023
Browse files Browse the repository at this point in the history
Enable orbit of a recursive predicate.
  • Loading branch information
EvgSkv authored Sep 27, 2024
2 parents 6198f0f + 3bfe0bf commit 579722b
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 4 deletions.
1 change: 1 addition & 0 deletions compiler/dialects.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ def BuiltInFunctions(self):
'Least': 'LEAST(%s)',
'Greatest': 'GREATEST(%s)',
'ToString': 'CAST(%s AS TEXT)',
'ToFloat64': 'CAST(%s AS DOUBLE)',
'DateAddDay': "DATE({0}, {1} || ' days')",
'DateDiffDay': "CAST(JULIANDAY({0}) - JULIANDAY({1}) AS INT64)",
'CurrentTimestamp': 'GET_CURRENT_TIMESTAMP()',
Expand Down
5 changes: 3 additions & 2 deletions compiler/functors.py
Original file line number Diff line number Diff line change
Expand Up @@ -622,8 +622,9 @@ def CountNils(self, node):
# Do not walk into:
# predicate value literals,
# combine expressions because they will be trivially
# null.
taboo=['the_predicate', 'combine'])
# null,
# lists of satelites.
taboo=['the_predicate', 'combine', 'satellites'])
rules_per_predicate[p] = rules_per_predicate.get(p,0) + (
c.nil_count == 0)
is_nothing = set()
Expand Down
26 changes: 24 additions & 2 deletions compiler/universe.py
Original file line number Diff line number Diff line change
Expand Up @@ -635,11 +635,33 @@ def CheckDistinctConsistency(self):
'Either all rules of a predicate must be distinct denoted '
'or none. Predicate {warning}{p}{end} violates it.',
dict(p=p)), r['full_text'])


def InscribeOrbits(self, rules, depth_map):
"""Writes satellites from annotation to a field in the body."""
# Satellites are written to master and master is written to
# satellites. You are responsible for those whom you tamed.
master = {}
for p, args in depth_map.items():
for s in args.get('satellites', []):
master[s['predicate_name']] = p
for r in rules:
p = r['head']['predicate_name']
if p in depth_map:
if 'satellites' not in depth_map[p]:
continue
if 'body' not in r:
r['body'] = {'conjunction': {'conjunct': []}}
r['body']['conjunction']['satellites'] = depth_map[p]['satellites']
if p in master:
if 'body' not in r:
r['body'] = {'conjunction': {'conjunct': []}}
r['body']['conjunction']['satellites'] = [{'predicate_name': master[p]}]

def UnfoldRecursion(self, rules):
annotations = Annotations(rules, {})
f = functors.Functors(rules)
depth_map = annotations.annotations.get('@Recursive', {})
self.InscribeOrbits(rules, depth_map)
f = functors.Functors(rules)
# Annotations are not ready at this point.
# if (self.execution.annotations.Engine() == 'duckdb'):
# for p in depth_map:
Expand Down
35 changes: 35 additions & 0 deletions integration_tests/duckdb_smoothed_winmove_test.l
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

@Engine("duckdb");

Move("a", "b");
Move("b", "a");
Move("b", "c");
Move("c", "d");

Node(x) distinct :- Move(a, b), x in [a, b];

N() += N();
N() += 1;

@Recursive(Win, 101, satellites: [SmoothedWin, N]);
Win(x) :- Move(x, y), ~Win(y);

SmoothedWin(x) += SmoothedWin(x) * (N() - 1) / N();
SmoothedWin(x) += ToFloat64(!~ Win(x)) / N() :- Node(x);

@OrderBy(Test, "col0");
Test(x, SmoothedWin(x));
8 changes: 8 additions & 0 deletions integration_tests/duckdb_smoothed_winmove_test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
+------+--------------------+
| col0 | col1 |
+------+--------------------+
| a | 0.5049504950495048 |
| b | 0.5049504950495048 |
| c | 1.0 |
| d | 0.0 |
+------+--------------------+
2 changes: 2 additions & 0 deletions integration_tests/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ def RunAll(test_presto=False, test_trino=False):
RunTest("sqlite_element_test")
RunTest("sqlite_functor_over_constant_test")

RunTest("duckdb_smoothed_winmove_test",
use_concertina=True)
RunTest("duckdb_iteration_closure_test",
use_concertina=True)
RunTest("duckdb_stop_test",
Expand Down

0 comments on commit 579722b

Please sign in to comment.