mirror of
https://github.com/ModernRelay/omnigraph.git
synced 2026-07-12 03:12:11 +02:00
feat(engine): execute Direction::Both on both Expand arms
CSR arm: an undirected hop chains csr(edge).neighbors with
csc(edge).neighbors under the existing visited/seen_dst gates, so
both-direction pairs and self-loops dedup for free (set semantics),
including per-hop in variable-length BFS. Indexed arm: endpoint_probes
returns both (src,dst) and (dst,src) orientations for Both; the per-hop
scan runs once per orientation into one neighbor_map, deduped by the
existing per-source seen_dst sets. Bulk anti-join: "no edge in EITHER
direction" (csr || csc has_neighbors).
Also fixes a lowering gap the anti-join test caught red: negation
inners are typechecked into a discarded context clone, so the
ResolvedTraversal direction lookup silently fell back to Out inside
not{} — undirectedness now travels on the AST node itself (the syntax
is the source of truth), immune to context-propagation gaps.
Tests: traversal.rs (out ∪ in vs the directional miss, both-ways dedup,
var-length from an incoming-only node, undirected anti-join vs
directional), traversal_indexed.rs both_modes equivalence, and the
proptest arm-equivalence property widened with <knows>{1,3}.
This commit is contained in:
parent
d4b21ce4eb
commit
9460f097d9
5 changed files with 254 additions and 40 deletions
|
|
@ -267,14 +267,24 @@ fn lower_clauses(
|
|||
))
|
||||
})?;
|
||||
|
||||
let direction = type_ctx
|
||||
.traversals
|
||||
.iter()
|
||||
.find(|rt| {
|
||||
rt.src == traversal.src && rt.dst == traversal.dst && rt.edge_type == edge.name
|
||||
})
|
||||
.map(|rt| rt.direction)
|
||||
.unwrap_or(Direction::Out);
|
||||
// Undirected is carried on the AST node itself — negation inners
|
||||
// are typechecked into a discarded context clone, so the
|
||||
// ResolvedTraversal lookup below cannot see their direction; the
|
||||
// syntax is the source of truth for Both.
|
||||
let direction = if traversal.undirected {
|
||||
Direction::Both
|
||||
} else {
|
||||
type_ctx
|
||||
.traversals
|
||||
.iter()
|
||||
.find(|rt| {
|
||||
rt.src == traversal.src
|
||||
&& rt.dst == traversal.dst
|
||||
&& rt.edge_type == edge.name
|
||||
})
|
||||
.map(|rt| rt.direction)
|
||||
.unwrap_or(Direction::Out)
|
||||
};
|
||||
|
||||
let dst_type = match direction {
|
||||
Direction::Out => edge.to_type.clone(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue