Skip to main content

enumerate_tuples

Function enumerate_tuples 

Source
pub fn enumerate_tuples<F>(
    canonical: &Arc<PolydatKernel>,
    parent: &Arc<PolydatKernel>,
    clauses: &[Clause],
    filter: Option<&str>,
    on_empty_clause: F,
) -> Result<Vec<Vec<(String, Value)>>, String>
where F: FnMut(&Clause) -> Result<(), String>,
Expand description

Enumerate the typed tuples a Cartesian comprehension produces.

Walks the dependent-tuple tree depth-first using fresh per-branch kernels. Each branch installs the prior clauses’ typed values as inputs on a fresh subscope kernel (PolydatKernel::materialize_subscope), then evaluates the next clause’s spec against that kernel. This is the kernel-per-logical-subspace rule from SRD-18b §“Dependent Tuple Iteration”.

filter, when provided, is evaluated against each fully-bound tuple — the predicate text is interpolated against a kernel with all clause values installed, then eval_const_expr_for (charged to the scope’s ledger) runs it to a Value::Bool. Tuples where the predicate is false are skipped. Predicate evaluation errors (non-Bool result, unresolved name, etc.) abort enumeration. See Comprehension::filter.

Empty-clause handling is delegated to on_empty_clause: the caller decides whether to propagate as a hard error (strict mode) or warn-and-skip (relaxed mode). The callback receives the offending Clause (which carries both single-var and parallel-iter shapes) and returns Result<(), String> — returning Err aborts enumeration, Ok(()) skips the branch.