-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Datalog query with leapjoin #51
Comments
I'm in a similar situation to you, having figured out what leapjoins do but not how to use them. For your rules the best I could come up with uses two joins: let mut iteration = Iteration::new();
let pages: Relation<(u32, &str)> = vec![
(1, "super.com"),
(2, "page.com"),
(3, "subpage.com"),
(4, "minpage.com"),
]
.into();
let edges: Relation<(u32, u32)> = vec![(1, 2), (2, 3), (3, 1), (1, 4)].into();
let pages_source_var: Variable<(u32, &str)> = iteration.variable("pages_source_var");
pages_source_var.insert(pages.clone());
let intermediate_page_edge_var: Variable<(&str, u32)> =
iteration.variable("intermediate_page_edge_var");
let depth_two_var: Variable<(&str, &str)> = iteration.variable("depth_two");
while iteration.changed() {
intermediate_page_edge_var.from_leapjoin(
&pages_source_var,
edges.extend_with(|&(edge_start, _)| edge_start),
|&(_, initial_page_name), &edge_end| (initial_page_name, edge_end),
);
depth_two_var.from_leapjoin(
&intermediate_page_edge_var,
pages.extend_with(|&(_, edge_end)| edge_end),
|&(start_name, _), &end_name| (start_name, end_name),
);
}
println!("{:?}", depth_two_var.complete().elements); |
I've thought a bit more about it and here's the explanation I could come up with. Looking at the API for fn from_leapjoin(
&self: &Variable<Tuple>,
source: &Variable<SourceTuple>,
leapers: impl Leapers<SourceTuple, Val>,
logic: impl FnMut(&SourceTuple, &Val) -> Tuple
)
Without
For every tuple from the source variable, each leaper proposes a set (or restricts an already-proposed set) of depth_two_var.from_leapjoin(
&edges_var,
(
todo!("something proposing all pairs of pages"),
edges.filter_with(|&(start, _)| (start, todo!("not sure what goes here"))),
edges_rev.filter_with(|&(_, end)| (end, todo!("not sure what goes here")))
),
|_src, ((_, start_name), (_, end_name))| (start_name, end_name)
); The biggest difficulty might be proposing fn function_name(
&self: &Relation<(Key, Val)>,
key_func: Fn(&SourceTuple) -> Key
) -> impl Leaper<SourceTuple, Val> You can see there's only one input relation, More succinctly, any data that constructs the tuple on the left-hand-side of the rule has to either come from your chosen source variable, or needs to be from a set enumerated by at least one leaper. If we choose Anyway, doing a cross join felt inefficient compared to the two leapjoins in my other comment. |
Hey, I'm just playing around with datafrog and trying to translate some basic datalog queries to the equivalent Rust code. I am wondering what something like the following snippet looks like in datafrog?
I'm mostly interested in
leapjoin
and have tried something like:But I can't quite wrap my head around how the leapers work even after reading the comment given in the source code of the repo. Any pointers would be appreciated!
The text was updated successfully, but these errors were encountered: