pub struct AggregateBody {
pub result_var: VariableSymbol,
pub aggregator: Aggregator,
pub input_var: VariableSymbol,
pub group_by: Vec<VariableSymbol>,
pub inner_body: Vec<Literal>,
}Expand description
An aggregation sub-query inside a rule body.
Semantically equivalent to a SPARQL Group { ... } over { ... }
projection: evaluate inner_body as a sub-query, group the
results by group_by, fold each group’s input_var values
with aggregator, and bind the per-group result to
result_var. The aggregate then participates in the outer
rule body as if result_var were produced by a positive
atom that ranges over the per-group results.
§Variable scoping
inner_body is its own scope: positive atoms and BIND
outputs inside the inner body bind variables that are visible
only within the aggregation. The three sets of variables that
leak out are group_by, input_var, and (after the
aggregation fires) result_var. Concretely:
group_byandinput_varMUST be bound by some positive atom orBINDinsideinner_body.result_varMUST be fresh — it must not appear anywhere else in the outer rule (head or body).
§Inner-body literal kinds
inner_body accepts the same four literal kinds the outer
rule body accepts — Literal::Positive, Literal::Negative,
Literal::Filter, and Literal::Bind — under the usual
safety rules (negated atoms and filter expressions reference
only inner-body-bound variables; BIND expressions reference
only earlier inner positives / binds and bind a fresh variable).
Nested aggregates inside an aggregate’s inner body are rejected
at validation time as
super::error::ProgramValidationError::NestedAggregateInInnerBody.
Fields§
§result_var: VariableSymbolThe variable that receives the per-group aggregate result.
aggregator: AggregatorWhich aggregator to apply.
input_var: VariableSymbolThe variable whose values are folded into the aggregate (the “input expression” in SPARQL terms).
group_by: Vec<VariableSymbol>Group-by keys. The aggregator runs once per distinct
tuple of group_by values; an empty group_by
collapses every inner-body binding into a single group.
inner_body: Vec<Literal>Literals forming the aggregation’s inner sub-query.
Accepts Literal::Positive, Literal::Negative,
Literal::Filter, and Literal::Bind under the
per-kind safety rules. Nested
Literal::Aggregate is rejected at validation time.
Implementations§
Source§impl AggregateBody
impl AggregateBody
Sourcepub fn inner_bound_variables(&self) -> BTreeSet<VariableSymbol>
pub fn inner_bound_variables(&self) -> BTreeSet<VariableSymbol>
Variables bound by the inner body — every variable a
positive inner atom binds, plus every BIND’s output
variable. Used by safety analysis to verify that
input_var and group_by are sourced from the inner
body and that inner negation / filter / bind references
stay within the inner scope.
Sourcepub fn exported_variables(&self) -> BTreeSet<VariableSymbol>
pub fn exported_variables(&self) -> BTreeSet<VariableSymbol>
Variables this aggregate exposes to the outer rule body:
the freshly-bound result_var plus every key the
outer rule groups by. The outer-scope view of an
aggregate body literal.
Sourcepub fn contains_nested_aggregate(&self) -> bool
pub fn contains_nested_aggregate(&self) -> bool
Returns true when the inner body contains a nested
Literal::Aggregate. Nested aggregates are rejected as
super::error::ProgramValidationError::NestedAggregateInInnerBody.