You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Improve exposition of partial reducers and algebraic aggregates
- Move 'Partial Reducers' remark to after Theorem 4 (was prematurely placed)
- Add proper definition of algebraic aggregates in Section 3.2
- Remove incoherent 'partial average reducer' paragraph - you cannot maintain
average incrementally with only the average value (need count too)
- Clarify min reducer as canonical example of non-invertible aggregate
- Explain Skip's strategies for handling partial reducers
By Lemma~1, any pair $(\iota, \oplus)$ with pairwise commutative $\oplus$ is a distributive aggregate in this sense.
215
215
Moreover, a well-formed reducer $R = (\iota, \oplus, \ominus)$ (Definition~\ref{def:well-formed-reducer}) is precisely an \emph{invertible distributive aggregate}: the aggregate is distributive over partitions of the multiset, and individual contributions can be removed using $\ominus$.
216
216
217
+
The database literature also defines \emph{algebraic} aggregates~\cite{viewmaintenance}: aggregates that can be computed by maintaining a fixed number of distributive aggregates and post-processing their results.
218
+
For example, average is algebraic because it can be computed from the distributive aggregates sum and count via division.
219
+
In Skip, this corresponds to using a well-formed reducer with richer accumulator state (e.g., $(sum, count)$ pairs) followed by a pointwise mapper to extract the final value.
220
+
We illustrate this pattern in Section~\ref{sec:examples}.
In many practical reducers (for example sum over integers or product over rationals), every accumulator value is reachable as $\mathsf{fold}_\oplus(\iota, M)$ for some multiset $M$, so the definition of well-formedness above coincides with the simpler global inverse law $(a \oplus v) \ominus v = a$ for all $a \in A$, $v \in V$.
387
392
\end{remark}
388
393
394
+
\begin{remark}[Partial Reducers in Skip]
395
+
Theorem~\ref{thm:equivalence} characterizes when incremental updates are correct for well-formed reducers.
396
+
In Skip's concrete API, the remove operation is allowed to be \emph{partial}: a reducer's remove function can signal ``recompute from scratch'' (by returning \texttt{None} in the ReScript bindings) instead of producing an updated accumulator.
397
+
Such partial reducers handle cases where $\ominus$ cannot efficiently invert $\oplus$---for example, computing the minimum without maintaining auxiliary state.
398
+
The runtime responds by recomputing the fold from scratch for that key.
399
+
Examples of partial reducers appear in Section~\ref{sec:examples}.
400
+
\end{remark}
401
+
389
402
\section{Examples}\label{sec:examples}
390
403
391
404
\subsection{Sum Reducer}
@@ -421,21 +434,45 @@ \subsection{Count Reducer}
421
434
a'_k = (3 - 1) + 1 = 3
422
435
\]
423
436
437
+
\subsection{Average Reducer (Algebraic)}
438
+
439
+
The average is a classic example of an \emph{algebraic} aggregate~\cite{viewmaintenance}: it can be expressed as a post-processing of a distributive aggregate over richer state.
440
+
A standard encoding uses accumulator state $A = \mathbb{R} \times\mathbb{N}$ to track sum and count.
with accumulator state $A = \mathbb{R} \times\mathbb{N}$ tracking (sum, count).
447
+
On reachable states with $c > 0$, the corresponding average is $\mathsf{avg} = s / c$.
448
+
This reducer is well-formed: addition and subtraction on sum and increment/decrement on count satisfy the inverse law on all reachable accumulator states, so Theorem~\ref{thm:equivalence} applies.
449
+
In Skip, the average view can be implemented by first using $\mathsf{reduce}_{R_{\mathsf{avgState}}}$ and then applying a pointwise mapper that divides sum by count for each key.
450
+
451
+
Note that maintaining \emph{only} the average (without count) is insufficient: to update the average when adding a value, one needs to know how many values contributed to the current average.
452
+
Thus, average is genuinely an algebraic aggregate requiring auxiliary state, unlike sum or count which can be maintained with a single accumulator value.
453
+
424
454
\subsection{Min Reducer (Partial)}
425
455
456
+
The min reducer demonstrates why invertibility is essential for incremental updates.
457
+
With accumulator $A = \mathbb{R} \cup\{+\infty\}$, the add operation is:
The min reducer does not have a well-defined remove operation $\ominus$in general, so $R_{\mathsf{min}}$ is not a reducer in the strict sense of Definition~\ref{def:well-formed-reducer}.
462
+
However, there is no inverse operation $\ominus$that works in general.
431
463
Consider $C(k) = \{3, 5\}$ with $a_k = 3$.
432
-
If we remove $5$, we need $a'_k = 3$, which is correct.
433
-
But if we remove $3$, we need $a'_k = 5$---yet from $a_k = 3$ alone, we cannot recover that $5$ was the second-smallest value.
464
+
\begin{itemize}
465
+
\item If we remove $5$: we need $a'_k = 3$. We could define $(3\ominus5) = 3$ (removing a non-minimum has no effect).
466
+
\item If we remove $3$: we need $a'_k = 5$. But from $a_k = 3$ alone, we cannot know that $5$ was the second-smallest value!
467
+
\end{itemize}
468
+
469
+
This shows min is \emph{not} an invertible distributive aggregate: knowing only the accumulated minimum is insufficient to update the result when the minimum itself is removed.
434
470
435
-
The Skip runtime handles such \emph{partial reducers} by either:
471
+
In Skip's implementation, min is handled as a \emph{partial reducer}:
436
472
\begin{itemize}
437
-
\item Recomputing from scratch when values are removed, or
438
-
\item Maintaining additional state (e.g., a sorted structure of all values).
473
+
\item The remove function signals ``cannot update incrementally'' (e.g., returns \texttt{None})
474
+
\item The runtime responds by recomputing from scratch: $\mathsf{fold}_{\min}(\iota, C'(k))$
475
+
\item Alternatively, one can maintain richer state (e.g., a sorted multiset of all values), making the remove operation invertible on that richer state---but this is no longer a constant-space reducer
0 commit comments