schema.expr
The serializable expression AST behind the lambda-bound operations in com.eignex.kumulant.schema. When an operation needs a projection or a predicate that must travel on the wire rather than as a live Kotlin lambda, it carries one of these trees instead. The whole tree is serializable, so a filter or a transform round-trips as data and rebuilds an identical closure on the far side.
The three trees
There are three sealed hierarchies, one per result shape. ScalarExpr evaluates to a single number from an update's value, its paired second component, and the current vector. VectorExpr evaluates to a whole vector and backs the per-feature projection and scaling operations. BoolExpr evaluates to a boolean and drives filter predicates and the guards on conditional nodes. Each hierarchy is sealed, so serialization is closed and exhaustive: every node carries a discriminator and decoding can never land on an unknown shape.
Leaves and operators
The scalar leaves are the update value X, the paired second component Y, a vector coordinate V, and a literal Const. Arithmetic composes them with the ordinary operators and with dedicated nodes for the transcendental functions: powers, logs, exponentials, square roots, and absolute value. Comparisons between scalars produce a BoolExpr, and the boolean combinators join several predicates into one.
Sugar nodes
Common shapes have dedicated nodes so a serialized tree stays readable rather than ballooning into nested arithmetic. Standardizing, min-max scaling, centering, and range tests each have their own node, as does the multi-branch Switch and the conditional IfExpr. Vector projection has nodes for dot products, element selection, single-coordinate access, and a fold whose operator picks sum, min, max, or mean.
Anything that cannot be expressed as one of these nodes stays a live-only lambda on the com.eignex.kumulant.core.Stat side and is not wire-expressible. Reach for the lambda overloads of the filter and transform operations in com.eignex.kumulant.operation when that happens.
Types
Wire-serialisable AST for boolean predicates over the same input environment as ScalarExpr. Consumed by every spec-side filter operator and by IfExpr's condition slot.
Reads the center field of the feedback primary's snapshot. Requires the primary's result to implement HasCenterScale; raises IllegalStateException when evaluated without a primary, or when the primary's result does not expose a center.
Wire spec for a constant scalar.
Reads the max field of the feedback primary's snapshot. Requires the primary's result to implement HasMinMax; raises IllegalStateException when evaluated without such a primary.
Wire spec for a ternary if (cond) then else otherwise.
Reads the min field of the feedback primary's snapshot. Requires the primary's result to implement HasMinMax; raises IllegalStateException when evaluated without such a primary.
Min-max projection mapping X from [primary.min, primary.max] to [targetLow, targetHigh], emitting targetLow while the running range is still degenerate. Reusable AST sugar for the min-max-scaler pattern; requires a HasMinMax primary.
Wire-serialisable AST for scalar expressions over the per-update input environment. The library uses these wherever a stat needs to apply a caller-supplied projection / weight / threshold expression that has to round-trip on the wire; weightBy, transform, the per-bin scaler projections, the WithFeedback op, the loss / pinball / quantile configurations.
Reads the scale field of the feedback primary's snapshot. Requires the primary's result to implement HasCenterScale; raises IllegalStateException when evaluated without a primary, or when the primary's result does not expose a scale.
Z-score projection: (X - Center) / Scale, emitting 0 when Scale is still zero. Reusable AST sugar for the standard-scaler pattern; requires a HasCenterScale primary.
Multi-way branch on a scalar key. Replaces nested IfExpr cascades. The first case whose SwitchCase.value equals on.eval(...) exactly wins; if none match, otherwise is returned.
v[index] - out-of-bounds throws at eval time.
Wire-serialisable AST for vector-valued expressions over the same input environment as ScalarExpr / BoolExpr. Used by the spec-side transformVector(VectorExpr) operator when the output is a fresh vector rather than a per-element transform.
In element-wise feedback contexts (vector / regression / paired), returns the coordinate index of the currently evaluating element as a Double. Outside such contexts (primary is not an IndexedResult), raises IllegalStateException.
Refers to the primary scalar input x.
Refers to the secondary scalar input y (paired stats only).
Functions
Absolute value of this expression.
Build Div of two expressions.
Divide this expression by a literal rhs.
Divide a literal receiver by an expression.
Exact equality (no tolerance).
Exact equality against a literal (no tolerance).
e raised to this expression. Overflows to +Infinity well before Double runs out of range.
Greater-or-equal comparison.
Greater-or-equal against a literal.
Strictly-greater-than comparison.
Strictly-greater-than against a literal.
True when this expression evaluates to a finite number: not NaN, and not an infinity.
True when this expression evaluates to NaN.
Less-or-equal comparison.
Less-or-equal against a literal.
Natural logarithm of this expression. ln(0) is -Infinity and a negative input gives NaN.
Strictly-less-than comparison.
Strictly-less-than against a literal.
Build Sub of two expressions.
Subtract a literal rhs from this expression.
Subtract an expression from a literal receiver.
Build Add of two expressions.
Add a literal rhs to this expression.
Add an expression to a literal receiver.
Square root of this expression. A negative input gives NaN.
Build Mul of two expressions.
Multiply this expression by a literal rhs.
Multiply a literal receiver by an expression.
Unary minus: wraps in Neg.
Weighted sum of the feature vector. weights must match the vector length at evaluation time.
Weighted sum of the feature vector, varargs form.
Build an output vector by evaluating each expression in order; output length is exprs.size.
Build an output vector from expressions in order, varargs form.
Reduce the whole feature vector to one scalar with op.