pub struct HypergraphRule {
pub head_predicate: String,
pub vertices: Vec<Vertex>,
pub hyperedges: Vec<Hyperedge>,
pub head_has_aggregation: bool,
pub has_negation: bool,
pub has_is_expr: bool,
pub comparison_count: usize,
pub is_fact: bool,
}Expand description
A rule body represented as a hypergraph.
Vertices are body variables (named only — anonymous wildcards do
not participate in the graph). Hyperedges are positive body atoms.
Negated, Comparison, and IsExpr body literals are NOT
hyperedges; their presence is recorded in
HypergraphRule::has_negation / HypergraphRule::has_is_expr
so the eligibility analyzer can flag them as boundaries without
the IR pretending they’re join structure.
Construction is total: every Rule produces a
HypergraphRule. Whether the rule is eligible for multiway
planning is a separate question handled by
crate::hypergraph::eligibility::analyze.
Fields§
§head_predicate: StringPredicate name of the rule head.
vertices: Vec<Vertex>Variables in first-appearance order across the body. Empty for ground facts and bodies that contain only constants.
hyperedges: Vec<Hyperedge>Positive body atoms in source order.
head_has_aggregation: boolTrue if the head contains an crate::ast::AggExpr.
has_negation: boolTrue if any body literal is BodyLiteral::Negated.
has_is_expr: boolTrue if any body literal is BodyLiteral::IsExpr.
comparison_count: usizeNumber of body BodyLiteral::Comparison literals (filters).
Comparisons do NOT block multiway eligibility — they are
applied as filters on top of the join — but the count is
recorded so the explain output can show them and so future
PRs can reason about filter selectivity.
is_fact: boolTrue if the rule is a ground fact (body.is_empty()).
Implementations§
Source§impl HypergraphRule
impl HypergraphRule
Sourcepub fn from_rule(rule: &Rule) -> Self
pub fn from_rule(rule: &Rule) -> Self
Build a HypergraphRule from an AST Rule. Total: never
fails. Anonymous wildcards (Term::Anonymous) and constants
(Term::Integer / Float / String / Symbol) leave the
hyperedge position as None. Aggregate terms in body atoms
are not allowed by the parser (aggregates appear only in rule
heads), but if one is encountered it is treated as a constant
position — the head-aggregation flag captures the eligibility
boundary regardless.
Sourcepub fn vertex_count(&self) -> usize
pub fn vertex_count(&self) -> usize
Number of distinct variables referenced by the body. Equals
self.vertices.len().
Sourcepub fn hyperedge_count(&self) -> usize
pub fn hyperedge_count(&self) -> usize
Number of positive body atoms.
Sourcepub fn vertex(&self, id: VertexId) -> &Vertex
pub fn vertex(&self, id: VertexId) -> &Vertex
Look up a vertex by id. Panics if id is out of range —
VertexIds are only allocated by Self::from_rule, so an
out-of-range id is a programmer error, not a data error.
Sourcepub fn vertex_ids(&self) -> impl Iterator<Item = VertexId> + '_
pub fn vertex_ids(&self) -> impl Iterator<Item = VertexId> + '_
Iterate over vertex ids in allocation (first-appearance) order.
Trait Implementations§
Source§impl Clone for HypergraphRule
impl Clone for HypergraphRule
Source§fn clone(&self) -> HypergraphRule
fn clone(&self) -> HypergraphRule
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more