Skip to content

Commit 6cc4532

Browse files
committed
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
1 parent 90da7fc commit 6cc4532

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

reduce.pdf

14.7 KB
Binary file not shown.

reduce.tex

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,11 @@ \subsection{Distributive Aggregates}\label{subsec:distributive-aggregates}
214214
By Lemma~1, any pair $(\iota, \oplus)$ with pairwise commutative $\oplus$ is a distributive aggregate in this sense.
215215
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$.
216216

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}.
221+
217222
\subsection{Deltas}
218223

219224
We model updates to collections as deltas.
@@ -386,6 +391,14 @@ \section{Correctness}\label{sec:correctness}
386391
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$.
387392
\end{remark}
388393

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+
389402
\section{Examples}\label{sec:examples}
390403

391404
\subsection{Sum Reducer}
@@ -421,21 +434,45 @@ \subsection{Count Reducer}
421434
a'_k = (3 - 1) + 1 = 3
422435
\]
423436

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.
441+
442+
Define:
443+
\[
444+
R_{\mathsf{avgState}} = \big((0,0),\ \lambda((s,c),v).\, (s+v, c+1),\ \lambda((s,c),v).\, (s-v, c-1)\big)
445+
\]
446+
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+
424454
\subsection{Min Reducer (Partial)}
425455

456+
The min reducer demonstrates why invertibility is essential for incremental updates.
457+
With accumulator $A = \mathbb{R} \cup \{+\infty\}$, the add operation is:
426458
\[
427-
R_{\mathsf{min}} = (+\infty, \lambda(a,v).\, \min(a,v), \bot)
459+
\iota = +\infty, \quad \oplus = \lambda(a,v).\, \min(a,v)
428460
\]
429461

430-
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.
431463
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 \ominus 5) = 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.
434470

435-
The Skip runtime handles such \emph{partial reducers} by either:
471+
In Skip's implementation, min is handled as a \emph{partial reducer}:
436472
\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
439476
\end{itemize}
440477

441478
\section{Complexity}

0 commit comments

Comments
 (0)