Repository navigation
Add EchoAggregation module — Monoid + GroupAggregator carriers for SQL aggregation-as-fold (consumer: affinescript db-theory #3) #175
Description
Context (consumer)
AffineScript ships db-theory #3 in the next PR — a new stdlib/Aggregate.affine module exposing SQL group-by + aggregation primitives (count / sum / min / max / avg) plus a db_group_by convenience returning the grouped result-set as JSON. The proof-relevant property is the classical aggregation-as-monoid-homomorphism claim (Green / Karvounarakis / Tannen, provenance semirings): each aggregator is a commutative monoid; group-by is the indexed sum.
Sibling to echo-types#174 (Transaction safety / no-section-of-collapsing-map).
Audit summary (2026-06-01)
Echo-types currently carries no reusable monoid/semiring infrastructure. The closest scaffolding:
EchoCost.CostAlgebra— left-identity + monotonicity, no composition law. Reusable as aMonoidinstance onceMonoidexists.Ordinal/Brouwer/OmegaPow.agda#additive-principal— exactly the monoid closure property for ω^n exponents.EchoDecorationStructure.agda— observer-level lattice, not data-level algebra.
docs/adjacency/provenance-semirings.adoc already names the relevant distinctness story (echo adds types; semirings add scalars; this module bridges both).
Proposed module shape
module EchoAggregation where
open import Level using (Level; suc)
open import Relation.Binary.PropositionalEquality using (_≡_)
record Monoid (ℓ : Level) : Set (suc ℓ) where
field
Elem : Set ℓ
ε : Elem
_⊕_ : Elem → Elem → Elem
assoc : ∀ a b c → (a ⊕ b) ⊕ c ≡ a ⊕ (b ⊕ c)
identity-l : ∀ a → ε ⊕ a ≡ a
identity-r : ∀ a → a ⊕ ε ≡ a
-- A GroupAggregator over keys K, values V, monoid M is the data of:
-- an aggregator agg : V → M.Elem
-- that lifts to a fold over rows, indexed by their K-key.
record GroupAggregator {ℓ} (K V : Set) (M : Monoid ℓ) : Set ℓ where
open Monoid M
field
agg : V → Elem
-- Headline lemma (proof TBD upstream; consumer references):
-- aggregation-as-fold :
-- (rows : List (K × V)) →
-- aggregate-by-key (partition rows by .fst)
-- (λ vs → foldr (λ v acc → agg v ⊕ acc) ε vs)
-- ≡ the actual SQL GROUP-BY semantics.
-- Concrete instances:
-- countMonoid : Monoid ℓ-zero (ℕ, 0, +)
-- sumMonoid : Monoid ℓ-zero (ℕ, 0, +)
-- minMonoid : Monoid ℓ-zero (ℕ ∪ {∞}, ∞, min)
-- maxMonoid : Monoid ℓ-zero (ℕ ∪ {-∞}, -∞, max)
-- -- avg is NOT a monoid (no identity); express as sum / count.Why this matters
- Bridge between the existing
EchoCostordered-monoid sketch (now formalisable as aMonoidinstance) and theprovenance-semirings.adocadjacency. - Foundation for downstream proof obligations: db-theory E3 CNF trichotomy + E4 pedagogical psi least-gap #4 (selection / filtered projection — distributivity of agg over filter), db-theory E5: make ν operational and add Buchholz example/smoke modules #6 (B+ tree / hash indices — agg over indexed scans), and db-theory Add partial _<ᵇ_ order on Buchholz terms (WF-0, partial) #9 (CRDTs — OR-Set / GCounter are monoid instances with convergence).
- Acceptance criteria: zero new axioms (
Print Assumptionsclean); concretecountMonoid/sumMonoid/minMonoid/maxMonoidinstances; signature foraggregation-as-fold(the proof itself may follow in a stacked PR).
Cross-doc
- Consumer cross-doc lands at
affinescript/docs/academic/proofs/db-theory-3-aggregation-as-fold.mdand back-links this issue. - Sibling: echo-types#174 (Transaction safety / no-section-of-collapsing-map).
Activity
feat(stdlib): Aggregate.affine — SQL group-by + aggregation primitive…
feat(stdlib): Aggregate.affine — SQL group-by + aggregation primitive…
feat(aggregation): general EchoAggregation monoid/group form (#175) +…
Generalize EchoAggregation to monoid/group form (#175); CC-BY-SA-4.0 …
docs(wiki): refresh status to 2026-06-21 + add developer/maintainer/e…
docs(6a2): refresh STATE.a2ml currency to 2026-06-21 (ordinal track R…
docs(handoffs): EchoTypes.jl EchoAggregation-mirror next-Claude brief (…
hyperpolymath commentedon Jun 27, 2026
The general monoid/group
EchoAggregationhas landed onmain(proofs/agda/EchoAggregation.agda):record Monoid(Elem/ε/_⊕_/assoc/identity-l/identity-r);⊕-fold+ the⊕-fold-++fold-is-a-monoid-homomorphism law over_++_;record GroupAggregator+aggregate-values+ the provedaggregation-as-fold;sumMonoid/countMonoid/maxMonoidover ℕ andminMonoidoverMaybe ℕ(nothing= ∞) — pluscountAggregator;no-canonical-disaggregation-of(=no-section-of-collapsing-map);module Example-PairSum(the macroℕ×ℕ→ℕreading as an instance —pairSumis thesumMonoidfold).Builds
--safe --without-K, zero postulates; wired intoAll.agda, pinned inSmoke.agda,kernel-guard.shPASS. All acceptance criteria are met (concrete instances + a provedaggregation-as-fold;avgcorrectly omitted as a non-monoid — express assum / count).Honest scope:
aggregation-as-foldis the fold's monoid-homomorphism law, not full SQL GROUP-BY operational semantics;no-canonical-disaggregation-ofrefutes a section (left inverse), not a representative choice.The sibling #174 is already closed (
EchoTransaction). The executable EchoTypes.jl finite-domain mirror is tracked separately. Closing as completed.Generated by Claude Code