agda-algebras — GitHub Project Roadmap¶
Project Title: agda-algebras 3.0 — Infrastructure, Consolidation, Classical Structures, Applications
Repository: ualib/agda-algebras
Date: 2026-04-19
Summary¶
Modernization of agda-algebras in 10 milestones: tooling upgrade/infra (M1), consolidate Base/Setoid (M2), classical structures (M3), style/naming uniformity (M4), Cubical Agda (M5), FLRP (M6), complexity/CSP module (M7), training corpus/LLM (M8), novel-research apps of Continuous relation API (M9), and post-3.0 polish — rendering pipeline, organization transfer, and Nix packaging (M10).
Description¶
A structured plan to modernize the agda-algebras library. The work is organized into ten milestones: tooling upgrade and infrastructure (M1), consolidation of the Base/Setoid fork (M2), introduction of the long-missing classical structures layer (M3), style and naming uniformity (M4), a Cubical Agda proof-of-concept as the canonical long-term target (M5), prerequisites for work on the Finite Lattice Representation Problem (M6), an extension of the existing algebraic complexity / CSP module for finite templates (M7), publication of a training corpus for language-model work (M8), novel-research applications of the Continuous relation API (M9), and a post-3.0 polish layer — rendering-pipeline modernization, transfer to the official agda GitHub organization, and first-class distribution through nixpkgs (M10). After M1 lands, the remaining milestones run largely in parallel; M10 in particular requires only M1, M2, and M4 to be complete and runs alongside M5–M9 rather than after them.
Note on version numbering¶
agda-algebras was released as v2.0.1 in December 2021 (Zenodo DOI 10.5281/zenodo.5765793) as an archival artifact for the TYPES 2021 submission. The current reconstruction is a major version bump past that release and is planned as v3.0. The planned Cubical-canonical successor, in which src/Cubical/ becomes the default development tree, is planned as v4.0.
Labels¶
milestone-1-infra(0075ca) — Milestone 1: Infrastructure health.milestone-2-consolidation(0075ca) — Milestone 2: Consolidation.milestone-3-classical(0075ca) — Milestone 3: Classical structures layer.milestone-4-style(0075ca) — Milestone 4: Style and naming uniformity.milestone-5-cubical(5319e7) — Milestone 5: Cubical track.milestone-6-flrp(5319e7) — Milestone 6: FLRP prerequisites.milestone-7-csp(5319e7) — Milestone 7: Algebraic complexity / CSP.milestone-8-llm(5319e7) — Milestone 8: LLM readiness.milestone-9-apps(5319e7) — Milestone 9: Applications of continuous relations.milestone-10-polish(5319e7) — Milestone 10: Post-3.0 polish (rendering, organization transfer, packaging).stdlib-bridge(fbca04) — Bridges to the Agda standard library.breaking-change(d93f0b) — Breaking change to the public API.good first issue(7057ff) — Good for newcomers.help-wanted(0e8a16) — Community help wanted.design-discussion(c5def5) — Needs design discussion before implementation.documentation(0e8a16) — Documentation changes.governance(8aea29) — Administration and governanceagda-community(945ca0) — Topics relevant to the Agda community.
Milestones¶
Milestone 1 — Infrastructure health (BLOCKING)¶
Description. Modernize the library's tooling, establish baseline project hygiene, and unblock every subsequent milestone. The library is currently pinned to Agda 2.6.2 / stdlib 1.7; it must move to Agda 2.8.0 / stdlib v2.3 with --cubical-compatible replacing --without-K. Standard community-health files (CONTRIBUTING, CHANGELOG, CODE_OF_CONDUCT, STYLE) must land. GitHub Actions CI must stand up. README and installation docs must be rewritten for the 3.0 line.
Exit criterion. make check passes under GitHub Actions CI against Agda 2.8.0 / stdlib v2.3; CONTRIBUTING.md, docs/STYLE_GUIDE.md, ROADMAP.md, CHANGELOG.md are merged; README documents the new install path.
Milestone 2 — Consolidation¶
Description. Resolve the parallel Base/Setoid fork by freezing Base/ and moving it to Legacy/Base/. Setoid/ is the canonical development tree for 3.0. Within Legacy, consolidate redundant Base.Structures implementations and remove abandoned experimental modules. Designate a single canonical proof of Birkhoff's HSP theorem while preserving the pedagogical demonstration variants.
Exit criterion. src/Base/ is in src/Legacy/Base/ with a deprecation note; Setoid.Varieties.HSP.Birkhoff is designated canonical; ADR-001 (Setoid as canonical) is merged; no duplicate implementations of the same concept remain in Setoid/ or Legacy/Base/.
Milestone 3 — Classical structures layer¶
Description. Introduce the long-missing tower of classical algebraic structures as Σ-typed specific theories over the universal-algebra framework, with record-typed bundle views matching the stdlib Algebra.Bundles idiom. Each structure ships as a Signatures / Theories / Structures / Bundles / Small quintuple. Designed so that the underlying equivalence used in the Setoid-based 3.0 line can be mechanically replaced by a Cubical path type when the 4.0 Cubical track becomes canonical.
Phase 1: Magma, Semigroup, CommutativeSemigroup, Monoid, CommutativeMonoid, Group, AbelianGroup, Semilattice, Lattice.
Phase 2: Ring, CommutativeRing, Field, Module, DistributiveLattice, BooleanAlgebra.
Exit criterion. Phase 1 classical structures are implemented, documented, bridged to stdlib, and exercised by at least one worked example each (e.g. (ℕ, +, 0) as a CommutativeMonoid; (ℤ, +, -, 0) as an AbelianGroup).
Milestone 4 — Style and naming uniformity sweep¶
Description. Apply docs/STYLE_GUIDE.md consistently across Setoid/ and Classical/. Audit naming (one preferred name per concept; synonyms deprecated); audit notation (one canonical symbol table); audit module structure (one concept per module where feasible); ensure every user-facing definition has a prose comment block.
Exit criterion. No undocumented public definitions remain in Setoid/ or Classical/; no synonym pairs (e.g. is-homomorphism + IsHom) exist in the public API; the canonical symbol table in docs/STYLE_GUIDE.md matches the notation actually used in the library.
Milestone 5 — Cubical track (canonical long-term target)¶
Description. Prepare the path for Cubical/ to become the canonical development tree in version 3.0. Port Algebra to cubical Agda, prove the structure identity principle (SIP), prove equivalence of ≅ with path equality, and demonstrate end-to-end workflow by porting at least one classical structure (Monoid is the natural choice).
Exit criterion. Cubical/Algebras/Basic.agda compiles; SIP is proven for the cubical Algebra record; Monoid has a working cubical port that is essentially a mechanical substitution from its Setoid analog; ADR-003 (Cubical as canonical target) is merged.
Milestone 6 — Toward the Finite Lattice Representation Problem¶
Description. Build the specialized universal-algebraic infrastructure needed to tackle the Finite Lattice Representation Problem: "Does every finite lattice occur as the congruence lattice of a finite algebra?" Near-term prerequisites include Con 𝑨 and Sub 𝑨 as complete lattices, subdirect products, subdirectly irreducible algebras, and basic Maltsev conditions relevant to lattice representations. Medium-term. Jónsson's theorem, Day's theorem. Long-term (out of scope for 3.0): tame congruence theory, commutator theory, explicit representations of small lattices.
Exit criterion. Con 𝑨 is a complete lattice; subdirect products and subdirectly irreducible algebras are defined with basic properties proven; at least one Maltsev condition (congruence permutability via the Maltsev term characterization) is proven.
Milestone 7 — Algebraic complexity / CSP extensions (finite templates)¶
Description. Extend the existing Base.Complexity / Exercises.Complexity.FiniteCSP work into a proper algebraic-complexity development of finite-template constraint satisfaction. This is a separate research program from Milestone 6 (the FLRP is about lattice representation theory; finite CSP is about the complexity of constraint satisfaction with a fixed finite template over the algebraic approach of Bulatov, Zhuk, Barto, and others). Candidate content includes polymorphism clones, the Jeavons Galois connection, Post's lattice, and a statement of the Bulatov–Zhuk algebraic dichotomy. The infinite-template / ω-categorical extension is covered separately under Milestone 9.
Exit criterion. At least one substantial algebraic-CSP theorem is formalized (e.g. the Jeavons Galois connection for a fixed finite domain); polymorphism clones are available as a first-class type.
Milestone 8 — LLM readiness and corpus artifacts¶
Description. Make the library maximally useful as a training and retrieval corpus for language models. Extract (theorem statement, proof term) pairs with metadata; publish as a Hugging Face dataset; explore agda-native-air integration; publish a short paper or blog post describing the corpus and its intended uses.
Exit criterion. Initial corpus artifact is published with at least 500 (theorem, proof) pairs; a CI job regenerates the corpus on each release; a public-facing write-up describing the dataset is available.
Milestone 9 — Applications of continuous relations¶
Description. Explore substantive mathematical applications of the Continuous relation API — the generalization of classical relations to arbitrary arity types, developed in Base.Relations.Continuous and carried forward into Setoid/. Three directions are in scope, each intrinsically interesting and independent of the FLRP and finite-CSP programs. M9-1 formalizes Scott-continuous relations on directed-complete partial orders (DCPOs), connecting to domain theory and Escardó's work on searchable sets in the constructive-mathematics tradition. M9-2 formalizes infinitary CSP over ω-categorical templates in the Bodirsky–Pinsker program, where relations of countably infinite arity arise naturally. M9-3 is exploratory rather than deliverable-oriented: a reading-and-writing investigation into whether coalgebraic bisimulation has an under-exploited angle at the intersection with universal algebra in the Birkhoff sense.
Exit criterion. At least one of M9-1 or M9-2 produces a formalized non-trivial example accompanied by a short public write-up (blog post, arXiv note, or similar); M9-3 produces a design-discussion document summarizing what was learned from the reading, with a concrete verdict ("pursue" or "saturated") regardless of whether formalization work follows.
Milestone 10 — Post-3.0 polish (community packaging and presentation)¶
Description. Independent polish items that finalize agda-algebras' presentation as a community-grade library, separated out from the body of the 3.0 modernization work because each is most valuable applied to a library already in production-grade shape, but none of them depends on M5–M9, and M10-1 in particular can begin as soon as M1, M2, and M4 are complete and run in parallel with the rest.
- M10-1: modernize the rendering pipeline by replacing the Jekyll-based
admin/generate-htmlmachinery with a MkDocs site consumed directly from.lagda.mdsources. - M10-2: transfer the repository to the official
agdaGitHub organization to align governance with the rest of the Agda ecosystem. - M10-3: promote the library to a first-class entry under
nixpkgs.agdaPackagesso downstream Nix users can depend on it without vendoring a flake input.
M10-2 and M10-3 are governance/packaging tasks with no hard structural prerequisites inside the milestone tree; they sit in M10 for thematic grouping (post-3.0 community polish) rather than for dependency reasons. Pursuing them prematurely, before the library itself is in 3.0-ready shape, undermines the goals these tasks aim to achieve, which is why they're tagged with this milestone rather than M1 or M2.
Exit criterion. MkDocs site live at https://ualib.org with make site building cleanly under nix develop; the repository is hosted at agda/agda-algebras with HTTP redirects from the old ualib/ URL working transparently; nix-shell -p 'agdaPackages.agda-algebras' produces a working environment in which agda --library agda-algebras resolves correctly.
Milestone Dependencies¶
graph TD
M1["M1 — Infrastructure"]
M2["M2 — Consolidation"]
M3["M3 — Classical structures"]
M4["M4 — Style sweep"]
M5["M5 — Cubical"]
M6["M6 — FLRP prerequisites"]
M7["M7 — CSP (finite templates)"]
M8["M8 — LLM corpus"]
M9["M9 — Continuous-relation apps"]
M10["M10 — Post-3.0 polish"]
M1 --> M2
M1 --> M4
M1 --> M5
M1 --> M10
M2 --> M3
M2 --> M7
M2 --> M9
M2 --> M10
M3 --> M5
M3 --> M6
M3 --> M7
M3 --> M9
M4 --> M8
M4 --> M10
M7 -.-> M9
Issues¶
Below, each issue is tagged with its milestone (M1, M2, etc.), suggested labels, and a full issue body ready for GitHub. Cross-milestone dependencies are noted in the body; see the Mermaid graph at the end of this file for a visual summary.
---¶
Milestone 1 — Infrastructure health¶
Issue M1-1: Upgrade to Agda 2.8.0 and stdlib v2.3; replace --without-K with --cubical-compatible (#250, closed)¶
Labels: milestone-1-infra, breaking-change
Description¶
The library is currently pinned to Agda 2.6.2 / stdlib 1.7. The Agda ecosystem has moved on: the current stable is Agda 2.8.0 (July 2025) and stdlib v2.3. --without-K has been superseded by --cubical-compatible since Agda 2.6.3. This issue tracks the full upgrade. Blocks essentially every other issue in this project.
Tasks¶
- Update
agda-algebras.agda-libtodepend: standard-library-2.3and document the minimum Agda version as 2.8.0. - Replace every
{-# OPTIONS --without-K --exact-split --safe #-}with{-# OPTIONS --cubical-compatible --exact-split --safe #-}. - Fix any regressions from the flag change.
- Update import paths for anything that moved between stdlib 1.7 and 2.3 (expected hotspots:
Function.Bundles,Relation.Binary.*renamings,Data.*reorganizations). - Update CI config to test against Agda 2.8.0 / stdlib 2.3.
- Update
README.mdandINSTALL.mdto reflect the new requirements. - Update the Nix flake.
Acceptance criteria¶
- Library type-checks under Agda 2.8.0 / stdlib v2.3.
-
make checksucceeds locally. - No file still declares
--without-K. - Once 2.0 is stable, consider adding a CI job against Agda 2.9/dev to catch forward-compatibility issues early.
Issue M1-2: Add GitHub Actions CI to type-check the library (#251, closed)¶
Labels: milestone-1-infra, nix, ci
Description¶
The library has no CI. Contributors can break type-checking without maintainers noticing. Add a GitHub Actions workflow that type-checks the library on each push and pull request. Reference workflows: agda-categories and the stdlib itself both have well-maintained CI that can be adapted.
Tasks¶
- Add
.github/workflows/ci.yml. - Install Agda at the pinned version (Agda 2.8.0; see M1-1).
- Install stdlib v2.3.
- Run
make check(or equivalent) on every push tomainand on PRs. - Cache the Agda binary and
.agdaifiles between runs. - Display a CI badge in the README.
Acceptance criteria¶
- CI runs green on
main. - CI triggers on every pull request.
- Average job time < 10 min after caching.
- README shows a green CI badge.
Issue M1-3: Add CONTRIBUTING.md, CHANGELOG.md, CODE_OF_CONDUCT.md (#252, closed)¶
Labels: documentation, milestone-1-infra
Description¶
Standard community-health files are missing. Drafts of CONTRIBUTING.md and docs/STYLE_GUIDE.md may exist from the 3.0 planning cycle and could be merged after review.
Tasks¶
- Add
CONTRIBUTING.md(draft from planning cycle). - Add
CHANGELOG.mdseeded with the 3.0 milestone entry. - Add
CODE_OF_CONDUCT.md(Contributor Covenant 2.1). - Add
.github/ISSUE_TEMPLATE/with bug-report, feature-request, and design-discussion templates. - Add
.github/PULL_REQUEST_TEMPLATE.md.
Acceptance criteria¶
- All four files exist at the repo root (or in
.github/). - GitHub recognizes the community-health files (green checkmarks on the "Insights → Community standards" page).
Issue M1-4: Adopt docs/STYLE_GUIDE.md as the project style guide (#253, closed)¶
Labels: documentation, milestone-1-infra
Description¶
Create docs/STYLE_GUIDE.md documenting file format, module structure, naming conventions, notation, universe-polymorphism practices, record vs Σ guidance, proof style, and library-as-training-corpus considerations. A draft from the planning cycle is ready for review. Applying the style guide across Setoid/ and Classical/ is tracked in M4-1.
Tasks¶
- Merge
docs/STYLE_GUIDE.md(draft from planning cycle). - Link
docs/STYLE_GUIDE.mdfromREADME.mdandCONTRIBUTING.md.
Acceptance criteria¶
-
docs/STYLE_GUIDE.mdis merged. - Links from README and CONTRIBUTING work.
Issue M1-5: Rewrite README and Preface for the 3.0 release (#254, closed)¶
Labels: documentation, milestone-1-infra
Description¶
The current README.md and docs/lagda/Overture/Preface.lagda are 1.x-era: wrong Agda versions, obsolete installation paths, pre-consolidation library structure. They need a rewrite aligned with the 3.0 release. Depends on M1-1 through M1-4 and M2-1.
Tasks¶
- Pin Agda 2.8.0 / stdlib 2.3 in install instructions.
- Describe the Setoid-as-canonical structure and point to
Classical/. - Link
CONTRIBUTING.md,GITHUB_PROJECT.md,docs/STYLE_GUIDE.md. - Concrete quickstart for new users (5-command install →
make check). - Add CI badge (from M1-2) and documentation site link.
- Consider whether to merge
docs/lagda/Overture/Preface.lagdaandsrc/Overture/Preface.agdainto new Markdown-based literate Agda file calledsrc/Overture/Preface.lagda.mdat this stage or put this off to a later milestone/issue/release.
Acceptance criteria¶
- A reviewer can follow the README on a clean machine to a working
make checkwithout asking questions. - All links resolve.
- ~~No references to Agda 2.6.x or stdlib 1.x remain.~~ Current installation/setup guidance no longer instructs users to use Agda 2.6.x or stdlib 1.x; any remaining references are clearly historical or archival rather than normative.
- A decision is made to either merge Preface{.lagda,.agda} files into one Markdown-based literate Agda file, or make a new issue for applying the
.lagda+.agda=>.lagda.mdtransformation across entire code base (e.g., using a script like the one we developed at IO for converting LaTeX-based to Markdown-based literate Agda).
Issue M1-6: Establish docs/adr/ for Architecture Decision Records (#255, closed)¶
Labels: documentation, milestone-1-infra
Description¶
As the library evolves, design decisions (Setoid vs Base canonicality, record vs Σ for classical structures, Cubical track planning) should be recorded so future contributors understand the rationale. Use Michael Nygard's lightweight ADR format (one page per decision).
Tasks¶
- Create
docs/adr/directory. - Add
docs/adr/README.mdexplaining the ADR format. - Add
docs/adr/000-template.md. - Seed with decisions ratified in 2.0:
001-setoid-as-canonical.md(from M2-1);002-classical-layer-design.md(from M3-1);003-cubical-canonical-target.md(from M5-1).
Acceptance criteria¶
-
docs/adr/exists with README and template. - All three seeded ADRs are drafted (full content can land with the associated implementation issues).
Issue M1-8: Consolidate literate and bare-Agda sources into .lagda.md (#280, closed)¶
Labels: documentation, milestone-1-infra, breaking-change
Problem¶
The repository currently maintains literate Agda sources in two formats and two locations.
src/X/Y/Z.agda— minimal module skeletons that the type checker sees (typically just the OPTIONS pragma andmodule ... where).docs/lagda/X/Y/Z.lagda— the corresponding LaTeX-literate Agda content used bymake htmlto generate the rendered documentation at https://ualib.org.
This is a maintenance hazard and directly undermines the library-as-corpus pillar, since prose and proof in two files must be held in sync by hand.
The fix is to migrate to Markdown-literate Agda (.lagda.md), consolidating each module into a single src/X/Y/Z.lagda.md file that is both type-checked by make check and rendered by make html. An existing LaTeX-literate-to-Markdown-literate conversion script developed by @williamdemeo at IOHK is available and could be useful here.
Open design questions¶
A short design discussion is needed before code is written; the resolutions should be recorded in docs/adr/004-lagda-md-canonical.md.
- What happens to
docs/lagda/after migration? Recommend: delete; everything moves tosrc/. Implication: external bookmarks pointing to specificdocs/lagda/X.lagdapaths will break — audit and document the breakage. - Are there files we should keep in LaTeX-literate form? Paper companions under
docs/papers/may be co-built with a LaTeX paper PDF and arguably should stay. Itemize and decide individually. - How does Jekyll site generation change? The current
admin/generate-htmlpipeline type-checks.lagdafiles and post-processes the resulting.texand.htmlfor Jekyll consumption. The replacement runsagda --htmlon.lagda.mdfiles (which produces Markdown with fenced code blocks, suitable for direct Jekyll consumption) and may obviateadmin/generate-texentirely.
Proposal¶
Pre-work and design¶
- Extract and generalize the IOHK conversion script; done (see agda-lagda-migrator).
- Confirm agda-lagda-migrator produces well-formed
.lagda.mdon a representative sample (suggested:Overture/Preface,Setoid/Algebras/Basic,Demos/HSP). - Audit current state: count of
.lagdafiles, count of.agdaskeletons paired with.lagdacontent, count of.agdafiles with substantive content. - Confirm Agda 2.8.0's
.lagda.mdsupport is fully functional under--cubical-compatible --exact-split --safe. - Inventory hard-coded paths to specific
.lagdafiles across the repository (commit messages, BibTeX notes, paper PDFs, README links, internal cross-references, Jekyll templates). - Write ADR
docs/adr/004-lagda-md-canonical.mdresolving the open design questions above.
Build-system changes¶
- Update the Nix flake's
shellHookand the.agda-libinclude-path rules as needed (they should Just Work;.lagda.mdis treated as Agda source by the compiler). - Update
Makefile's Everything.agda generation pattern to pick up*.lagda.mdfiles alongside*.agda(currentlyfind $(SRCDIR) -name '*.agda'matches neither.lagdanor.lagda.md; change tofind src -name '*.lagda.md' -o -name '*.agda'; Agda will handle either, though going forward everything should be.lagda.md). - ~~Consider adding a
make corpustarget that extracts (prose, code-block) pairs into JSONL — first piece of M8 (LLM readiness) landing early.~~ (deferred) - ~~Update
admin/generate-htmlto operate on.lagda.mdfiles; remove or deprecateadmin/generate-texif no longer needed.~~ (deferred) - ~~Update Jekyll configuration to consume the Markdown output of
agda --htmldirectly.~~ (deferred) - Update CI workflow if the new pipeline introduces new dependencies.
File migration¶
- Run the conversion script across
docs/lagda/(excluding any items the ADR earmarks to remain LaTeX-literate). - Move output to the matching
src/path with.lagda.mdextension. - Delete the corresponding
src/X/Y/Z.agdaskeleton files. - ~~Update internal cross-references — link definitions,
[Module.Name][]-style references, BibTeXSource codenotes in module headers.~~ (deferred) - ~~Update
_includes/UALib.Links.md(or equivalent) to reflect new paths.~~ (deferred)
Documentation¶
- Update
docs/STYLE_GUIDE.mdto specify.lagda.mdas the canonical literate-Agda format and document the migration outcome. - Update
CONTRIBUTING.mdexamples that reference.lagdafiles. - Update
README.md's BibTeX notes if any reference.lagdapaths (specifically theDeMeo:2021entry'sSource codeURL). - Add a
CHANGELOG.mdentry under [Unreleased] flagging the file-format change as breaking for external links.
Verification¶
-
make checkpasses after migration. - ~~
make htmlproduces equivalent or improved HTML output; spot-check at least 10 rendered pages against a pre-migration archive.~~ (deferred) - ~~All internal cross-references resolve in the rendered HTML.~~ (deferred)
- Round-trip sanity: a representative sample of converted Agda code blocks type-check identically to their pre-migration
.lagdaoriginals.
Acceptance criteria¶
- No
.lagdafiles remain undersrc/ordocs/lagda/outside of any items the ADR explicitly preserves. - No
src/X/Y/Z.agdaskeleton files remain (those that previously paired with adocs/lagda/X/Y/Z.lagdacontent file). -
make check~~andmake html~~ succeeds under the new pipeline. - ~~Rendered HTML output at https://ualib.org is equivalent or improved.~~ (deferred)
-
docs/STYLE_GUIDE.mdspecifies.lagda.mdas canonical. - ADR
docs/adr/004-lagda-md-canonical.mdis merged.
Non-goals¶
- Changing the mathematical content of any module.
- Reorganizing the module hierarchy.
- Re-litigating the choice of literate Agda as the default presentation format.
Why now¶
Several converging considerations make this worth doing in the 3.0 cycle rather than deferring to 4.0.
- Single source of truth. The dual-file split is a structural source of drift between formal content and prose. Consolidation eliminates the drift class entirely.
- Tooling alignment. Markdown is the universal lingua franca; GitHub renders
.lagda.mdnatively, VSCode previews them, and the modern Agda ecosystem (1Lab being the most visible example) has standardized on the format. - Corpus extraction (M8-1). The training-corpus extractor walks the library to emit
(theorem, prose, proof)records. A uniform format with prose and code in one file is materially easier to extract from than a dual-file split where pairing depends on path correspondence. - Onboarding. New contributors find Markdown easier to author than LaTeX-literate Agda; the friction reduction is real.
- Efficiency. Doing this now saves conversion of new Agda modules later.
Relation to other milestones¶
- Sequenced before: M4-2 (docstring pass) — operates on the new file format directly.
- Benefits: M8-1 (LLM corpus) — uniform format simplifies extraction.
- Independent of: M3, M5, M6, M7, M9.
References¶
- 1Lab — large-scale Agda library written in
.lagda.md. - Agda's literate-programming documentation — language reference for
.lagda.mdand other literate formats.
Issue M1-9: Simplify Nix agda wrapper: drop defensive flags and rely on auto-discovery (#285)¶
Labels: milestone-1-infra, design-discussion, nix
Context¶
The current flake.nix generates a wrapper script at $AGDA_DIR/bin/agda that invokes the Nix-provided Agda with four defensive flags:
exec "$NIX_AGDA" \
--no-default-libraries \
--library-file "$AGDA_DIR/libraries" \
--library standard-library \
--library agda-algebras \
"$@"
Each flag was added to address a specific concern at the time it was introduced:
--no-default-librariessuppresses any entries in the user's~/.config/agda/defaultsthat might otherwise leak in (e.g. a globally-registered stdlib 2.2).--library-fileregisters our project-local stdlib + agda-algebras entries.--library standard-libraryensures stdlib is on the include path.--library agda-algebrasensures our library'ssrc/is on the include path (added in #251 after CI revealed that--no-default-librariessuppresses auto-discovery walk-up).
The defensive posture solves real problems, but it also suppresses Agda's normal library-resolution machinery — which exists for good reasons and is what most Agda users rely on.
Hypothesis¶
With the project-local AGDA_DIR already shadowing the user's ~/.config/agda/, the need for defensive flags is largely obviated. Specifically:
- The user's
~/.config/agda/defaultscannot leak in becauseAGDA_DIRpoints to./agda/(a gitignored project-local directory), not~/.config/agda/. The project-localdefaultsis what Agda reads, and we control its contents. - The walk-up-from-file auto-discovery can find the repo-root
agda-algebras.agda-libon its own if we let it.
Proposal¶
Investigate whether the wrapper can be simplified to just:
exec "$NIX_AGDA" \
--library-file "$AGDA_DIR/libraries" \
"$@"
Combined with a project-local $AGDA_DIR/defaults that lists standard-library. This would:
- Restore standard Agda library-resolution behavior (filename walk-up, include-root inference, etc.).
- Make the wrapper match what a developer would expect from having read the Agda docs.
- Reduce the surface area for future bugs of the kind #251 revealed.
Tasks¶
- Write a minimal test case: a file that imports from stdlib and from agda-algebras, check it with only
--library-fileset. Confirm that auto-discovery works as expected. - Verify that no
~/.config/agda/leakage occurs with the simplified wrapper on a developer machine with a globally-registered stdlib of a different version than the pinned one. - If the simpler wrapper works, update
flake.nixto emit it. - Verify the simplification doesn't break Emacs
agda-modeinteractive use (the mode invokesagdaviaagda --emacs-mode, inheriting our wrapper). - Verify
make checkstill passes in CI. - Document the resolution behavior in a
docs/adr/entry (see M1-6).
Non-goals¶
- Breaking CI to prove a point. If any step above reveals a real need for the defensive flags, document it and keep them.
- Reintroducing the flags one at a time incrementally. The point of this issue is to test the "remove all defensive flags" hypothesis; partial regressions aren't informative.
Acceptance criteria¶
- Decision is recorded: either the wrapper is simplified and the simpler version passes
make checklocally and in CI, or an ADR documents why each defensive flag is load-bearing.
Relation to other milestones¶
- Depends on: #251 (M1-2), which establishes the CI baseline this issue would test against.
- Independent of everything else.
Issue M1-10: Script to generate GITHUB_PROJECT.md from GitHub API (#289, closed)¶
Labels: documentation, milestone-1-infra
Problem¶
docs/GITHUB_PROJECT.md is the single-file master plan of the 3.0 upgrade: milestone prose, exit criteria, dependency graphs, and the full set of issue bodies. It was authored by hand during the initial project-planning cycle and then used as input to scripts/gh_project_populate.py to materialize the GitHub milestones, labels, and issues.
After the initial population, GitHub became the authoritative source for issue state — we edit issues on the web, close them as they complete, file new ones. But the markdown file has no mechanism to follow along. Issues added since the initial cycle are not reflected, and this drift will compound as the project progresses.
The file is too useful to abandon — external readers link to it, gh_project_populate.py consumes it, and a single-file view of the entire plan is the most efficient way to share the project state with collaborators (human and AI). The problem is purely that it isn't regenerated.
Proposal¶
Add scripts/gh_project_render.py, a generator that produces docs/GITHUB_PROJECT.md from two inputs:
- GitHub API — issue bodies, milestone assignments (inferred from
milestone-N-*labels), issue state (open/closed); queried via theghCLI in the same style asgh_project_populate.py. - ~~
docs/project_meta.yml— authored-by-hand narrative content that has no home on GitHub: ordered milestone list with description / exit criterion / mermaid dependency graph per milestone; label palette with hex colors and descriptions; file-level preamble and epilogue.~~ Alternative design ratified: all content in one file with markdown comment markers delimiting what should be regenerated.
The generator is sort of inverse to gh_project_populate.py: the latter pushes markdown to GitHub, the former pulls GitHub state back into markdown. Shared data classes (Milestone, Label, Issue) and the GitHubClient wrapper are factored into a small scripts/_gh_project_lib.py module used by both scripts.
Design decisions to ratify¶
- Issue membership is label-inferred, not listed in a separate outline file. The
milestone-N-*labels already used bygh_project_populate.pydetermine which milestone an issue belongs to; within-milestone ordering comes from the[MN-k]prefix in the issue title. Rationale: adding a new issue requires one human action (label it) instead of two (label it + edit an outline). - Dependency graphs are authored by hand as per-milestone mermaid strings. Machine-generation would require a "Depends on #N" convention nobody has committed to and a parser that doesn't exist; manual mermaid is typically less than ten lines per milestone and changes rarely.
GITHUB_PROJECT.mdremains committed, with a generated-file banner at the top, because external links, issue templates, and the library's documentation page all point at it, and because a textual diff on project-structure changes is a useful PR review aid.- Maintenance is initially manual via
make project-plan; a CI staleness check is a follow-up once CI lands in M1-2.
Tasks¶
- Factor shared data classes and the
GitHubClientwrapper out ofgh_project_populate.pyintoscripts/_gh_project_lib.py. - Add
scripts/gh_project_render.pythat queries the GitHub API and emitsdocs/GITHUB_PROJECT.md. - Add a
project-plantarget to theMakefile. - Add a top-of-file banner to
docs/GITHUB_PROJECT.mdnoting that it is generated. - Regenerate
docs/GITHUB_PROJECT.mdand commit the (now byte-reproducible) version. - Update
scripts/README.mdwith usage for the new generator.
Follow-up (not part of this issue)¶
- Once CI exists (M1-2), add a job that re-runs
gh_project_render.pyin a scratch directory, diffs against the committed file, and fails the PR if they differ. Prevents drift at zero ongoing cost.
Acceptance criteria¶
- Running
make project-planon a clean checkout with a validghauth token produces adocs/GITHUB_PROJECT.mdthat matches the committed file byte-for-byte. - All currently-open issues are listed in their correct milestone sections.
- The mermaid dependency graphs render identically to the current hand-authored versions.
-
scripts/README.mddocuments the new workflow.
Issue M1-11: Add Claude Code agent config for Agda type-checking (#349, closed)¶
Labels: milestone-1-infra, nix
Description¶
Add a .claude/ configuration directory so Claude Code on the web can provision the pinned Agda toolchain and type-check the library exactly as CI does (nix develop --command make check). The web container is ephemeral and ships with neither Nix nor Agda, so a SessionStart hook re-provisions the toolchain at the start of every session.
This adds two files:
.claude/settings.json— registers theSessionStarthook..claude/hooks/session-start.sh— an idempotent, web-only hook that installs single-user Nix, enables flakes, and pre-warms the dev shell so Agda 2.8.0 + standard-library 2.3 (pinned byflake.lock) are realized from the binary cache before the agent runs.
Toolchain pinning stays entirely in flake.nix / flake.lock; the hook only makes nix available and then drives Agda through the existing flake wrapper.
Motivation¶
The library is intended to support AI-assisted formal development (the agda-native-air tooling track) and to serve as a high-quality Agda corpus for ML training and retrieval (M8). An agent that can type-check its own proposed revisions is a prerequisite for both: it closes the loop between suggestion and verification, and it keeps any agent-authored proof terms honest before they enter the corpus. Committing the configuration makes agent onboarding reproducible and reviewable rather than ad hoc per session.
Tasks¶
- Add
.claude/settings.json. - Add
.claude/hooks/session-start.sh(mode0755). - Confirm generated artifacts stay untracked (
/.agda/,src/**/*.agdai, the generatedEverything*.agda). - (Optional) Add the
formalverificationCachix substituter to the hook for CI parity and faster warm-ups. - (Optional) Add or update
CLAUDE.mdso the agent inherits the canonical-path conventions (Setoid/canonical,Legacy/Base/frozen, Σ-type core with record bundle views, deprecation discipline).
Acceptance criteria¶
- In a fresh web session the hook provisions Nix and reports Agda 2.8.0 / standard-library 2.3.
- The agent type-checks at least one representative module through the flake wrapper with exit 0 (e.g.
nix develop --command agda src/Overture.lagda.md). -
makeregenerates the module aggregator andmake checkinvokesagdaunchanged. - No generated interface files or aggregator modules are committed.
- CI behaviour is unaffected; the hook is web-only and local
nix developis untouched.
Notes¶
- The hook is synchronous: the session waits until provisioning finishes, which prevents the agent from invoking
agdabefore it exists. The cost is ~30–80 s on a cold container and near-instant once cached. - Network discovery: the web container uses a host allowlist in which
nixos.organdinstall.determinate.systemsare unreachable butreleases.nixos.organdcache.nixos.orgare reachable; the hook fetches the installer fromreleases.nixos.orgaccordingly. - Chicken-and-egg: the hook only takes effect once it is on the checked-out branch, so the first session after merge — and any session on a branch that contains it — is provisioned automatically.
- Project-specific Claude Code skills (an Agda type-check skill, a
docs/STYLE.md-mirroring style skill) are deferred to a follow-up issue to keep this change focused on the environment.
Issue M1-12: Reorganize docs/: resolve the docs/notes vs docs/Notes case collision (#396, closed)¶
Labels:
Problem¶
docs/ holds two sibling directories whose names differ only in case — docs/notes/ and docs/Notes/. On a case-insensitive filesystem (default macOS APFS, default Windows NTFS) these two paths collide: git tracks them as distinct, but a checkout folds them into one directory, producing phantom modify/delete churn in git status and risking file clobbering on checkout. This is a portability bug, not merely a cosmetic one; it will bite any collaborator or CI runner on a case-insensitive filesystem.
The two directories are also unrelated in content:
docs/notes/holds Markdown working and design notes — currentlymilestone-signature-functors.mdandm4-5d-handoff.md. This is the correct home for prose notes and should keep its lowercase name.docs/Notes/is not notes at all: it is a LIPIcs LaTeX paper draft, "The design space of generalizing universal algebra" (Jacques Carette), together with its build assets (lipics-v2021.cls,cc-by.pdf,orcid.pdf,lipics-logo-bw.pdf). It is paper material misfiled under a "Notes" name.
Proposed structure¶
Move the LaTeX draft under docs/papers/ (where the arXiv paper and TYPES2021/ already live) and keep docs/notes/ for Markdown notes:
docs/
├── adr/ # architecture decision records (unchanged)
├── audits/ # style / quality audits (unchanged)
├── notes/ # Markdown working & design notes (unchanged; canonical home for prose notes)
├── papers/ # all LaTeX papers and their assets
│ ├── designspace/ # ← moved from docs/Notes/ (Carette "design space" LIPIcs draft + assets)
│ ├── TYPES2021/
│ └── … # arXiv paper, shared .cls / .sty / .bib / pdf
├── GITHUB_PROJECT.md
└── STYLE_GUIDE.md
The core move eliminates the docs/Notes path entirely, so the collision is resolved without a case-only rename (which would itself need a two-step git mv on a case-insensitive filesystem).
Tasks¶
-
git mv docs/Notes docs/papers/designspace(movesdesignspace.texand its four assets). - Grep the repo for references to
docs/Notes(any makefile target, link, or build script) and update them. - Record the convention in
docs/STYLE_GUIDE.md:docs/notes/is the home for Markdown notes; LaTeX papers and their assets live underdocs/papers/.
Non-goals¶
- Deduplicating the three
lipics-v2021.clscopies (underdocs/Notes/,docs/papers/, anddocs/papers/TYPES2021/). They have different contents (distinct md5sums), so consolidating them is a separate, careful task and not part of this cleanup. - Any change to
src/, or to theadr/andaudits/trees.
Labeling¶
This is repo-infrastructure and docs-governance hygiene, so it belongs in milestone M1 (home of CI, the STYLE_GUIDE, docs/adr/, and the GITHUB_PROJECT tooling), as M1-12 — the next free M1 number (M1-11 / #349 is the highest used).
Issue M1-13: Tier the type-check: the paper-specific certificates are 44% of a clean build (#515, closed)¶
Labels: enhancement, milestone-1-infra, ci, flrp-research
Description¶
Type-checking the whole library has roughly doubled in wall-clock time, and a large share of the new cost is modules that matter only to the FLRP research track and to the fin-lat-rep manuscript — above all the generated representation certificates under src/FLRP/Certificates/SmallLatticeReps/. A user of the algebra library who does not care about the finite lattice representation problem should not pay for them on every build, and a contributor waiting on make check should not either.
Measurements (this worktree, Agda 2.8.0, agda --profile=modules src/Everything.agda from an empty _build/, -M6G -A128M):
| time | share of build | |
|---|---|---|
| whole clean type-check | 395.2 s (6.6 min, 6.3 GB peak RSS) | 100 % |
FLRP.Certificates.SmallLatticeReps.* (27 modules) |
175.2 s | 44.3 % |
the other two certificates (Pilot, Group) |
3.4 s | 0.9 % |
Legacy.*, pulled in transitively by Examples.Structures and Exercises.Complexity.FiniteCSP (#322, #323) |
24.1 s | 6.1 % |
| core library and everything else | 192.4 s | 48.7 % |
So the census costs as much as the entire rest of the library, and it is concentrated: the four slowest certificates (SLR13 45.2 s, SLR27 29.6 s, SLR09 25.2 s, SLR33 23.6 s) are 71 % of the census total. Two further data points worth recording here, both actionable independently of this issue:
- the slowest single module in the whole library is not a certificate — it is
Classical.Structures.Lattice.Parachuteat 45.4 s (currently in review on #506), just ahead ofSLR13; Setoid.Subalgebras.Subdirect.Finitecosts 22.1 s, which corroborates #439's guess about that module from measurement rather than impression.
For scale on the other axis: the census is 36,095 lines, 39 % of all source under src/, but only 12 % of interface bytes.
Three structural facts make this cheap to fix.
- The census certificates are pure leaves. No module in
src/imports anyFLRP.Certificates.SmallLatticeReps.SLR*module — not even theFLRP.Certificatesbarrel, which contains only the checker assembly. They enter the build solely through the generatedsrc/Everything.agda, so excluding them changes no import graph and no public API. - The Makefile already has the pattern.
EverythingLegacy.agdais a second generated aggregator with its own gate, precisely so the frozenLegacy/tree is checked without being part of the canonical library. A certificate tier is the same move a second time. - Two CI cache bugs are inflating the measured cost independently of any tiering. The
Cache .agdai interface filesstep cachespath: src/**/*.agdai, but Agda 2.7+ writes interfaces to_build/<version>/agda/src/...— there are zero.agdaifiles undersrc/, so the cache saves and restores nothing. Its key also hashessrc/**/*.agda, which misses the.lagda.mdfiles that are ~99 % of the sources. Fixing those two lines is likely a larger win for CI than the tiering itself, and is worth doing first because it is independent.
Options considered¶
A. Tier the aggregator (recommended). Exclude src/FLRP/Certificates/SmallLatticeReps/** from Everything.agda, add a generated EverythingCertificates.agda over exactly that directory, and give it its own make target and its own CI job. Keeps every module in the repository and under CI, needs no file moves, touches no imports, and is trivially reversible. Keep FLRP/Certificates/{Pilot,Group}/** — two modules — in the core tier so the default build still exercises the certificate checker end to end.
A′. Move the certificates out of src/ entirely (say to certificates/), so they are artifacts rather than library modules. Architecturally tidier and the aggregator excludes them for free, but it moves 27 files, rewrites their cross-links and site paths, and needs the .agda-lib include path extended. Worth considering later; not worth it as a first step.
B. Move the certificates to UniversalAlgebra/fin-lat-rep. Cleanest audience separation, and the option to keep in view — but the costs are real and worth writing down before choosing it:
- that repository has been untouched since October 2016; it holds LaTeX, lattice lists, UACalc files, and talks, with no
.github/, no CI, no Nix, and no Agda — so the whole toolchain would have to be stood up there first; - the certificates import the library's checkers (
FLRP.Certificates,Setoid.Congruences.Certificates), so the other repository needs a pinnedagda-algebrasdependency, and version skew becomes a maintenance surface; - cross-repo breakage becomes invisible: a change to a checker's API here would be discovered late, in a repository nobody is watching, instead of by
make checkin the PR that caused it; - it gives up the atomic-PR property that FLRP roadmap § 1 explicitly chose in-repo development for ("a single PR can extend the foundation and use the extension atomically");
- it also gives up M8 corpus value — machine-checked certificates are among the most valuable training artifacts the repository has;
- and the manuscript source is itself vendored here, at
docs/papers/fin-lat-rep/SmallLatticeReps.tex, so moving only the evidence would separate the paper from its checked artifacts rather than co-locating them.
C. Make the certificates cheaper to check (worth doing regardless, and it feeds #439). The per-module profile attached above says where the time actually goes; candidate levers are abstract/opaque boundaries around the big tables so downstream normalization cannot unfold them, replacing compile-time from-yes (… ?) evaluation with tabulated structural proofs, and splitting the largest modules so interface caching is finer-grained. This should be a follow-up issue driven by the profile, not guesswork.
Proposal¶
Do the independent CI cache fix and option A now; open a data-driven follow-up for C; leave B on the table as the answer if the census keeps growing.
Tasks¶
- Fix the CI interface cache:
path: _build/and a key that hashessrc/**/*.lagda.mdas well assrc/**/*.agda. -
Everything.agda: exclude$(SRCDIR)/FLRP/Certificates/SmallLatticeReps/*, with the reason in the target's comment block. - New generated aggregator
EverythingCertificates.agdaover that directory, in the style ofEverythingLegacy.agda. - Targets:
make check(core + Legacy, as now, minus the census),make check-certificates(the new tier),make check-all(both). Update the Makefile header,README.md, andCONTRIBUTING.md, which currently tell contributors thatmake checktype-checks the entire library. - CI: add a
Type-check certificatesjob runningmake check-certificates, in parallel with the existing job and required byall-green. Nothing goes unchecked; core feedback arrives sooner and total wall-clock drops because the jobs run concurrently. -
make htmlandmake agda-mdkeep rendering the certificate tier, so the published site and/classic/do not lose pages. - Attach the per-module profile to #439 and open a follow-up for the worst offenders.
Acceptance criteria¶
-
make checkno longer type-checksFLRP/Certificates/SmallLatticeReps/**, and the measured improvement is reported in the PR. -
make check-allis green, and CI still gates on the certificate tier. - The site still renders every certificate page.
- No core-tier module imports a census certificate (guaranteed today;
make check-allwould catch a regression).
Related: #439 (profile type-checking times), #483 and #485 (the census that produces these certificates), #451 (FLRP program).
Milestone 1 Dependencies¶
M1-5 is the integration node: the new README / Preface needs all the other M1 deliverables to exist before it can refer to them. M1-6 (docs/adr/) is structurally independent but is gated on M1-1 because it references the 3.0 release.
graph TD
M1_1["M1-1: Agda 2.8 / stdlib 2.3"]
M1_2["M1-2: GitHub Actions CI"]
M1_3["M1-3: Community files"]
M1_4["M1-4: STYLE_GUIDE.md"]
M1_5["M1-5: README / Preface"]
M1_6["M1-6: docs/adr/"]
M1_1 --> M1_2
M1_1 --> M1_3
M1_1 --> M1_4
M1_1 --> M1_6
M1_2 --> M1_5
M1_3 --> M1_5
M1_4 --> M1_5
---¶
Milestone 2 — Consolidation¶
Issue M2-1: Freeze Base/, adopt Setoid/ as canonical (#256, closed)¶
Labels: milestone-2-consolidation, breaking-change
Description¶
The decision is ratified: Setoid/ is the canonical development tree for 2.0; Base/ is frozen and moved to Legacy/Base/. Rationale: Setoid/ is fully constructive (no extensionality postulates); it matches the stdlib Algebra.Bundles idiom which simplifies bridges; maintaining two trees indefinitely doubles every theorem's cost; Setoid/ already contains the definitive HSP proof.
Note: Base/ remains in the repo — frozen, not deleted — for posterity and as a reference. Parts may be ported back to Setoid/ or Cubical/ as needed.
This is a breaking change for downstream users of Base/. Announce prominently in the 2.0 CHANGELOG.
Tasks¶
- Move
src/Base/→src/Legacy/Base/. - Update
src/agda-algebras.agdato re-exportLegacy.Basewith a deprecation note. - Add
DEPRECATED.mdinLegacy/Base/explaining the status and pointing users toSetoid/. - Write ADR
docs/adr/001-setoid-as-canonical.md. - Announce in CHANGELOG.
Acceptance criteria¶
-
src/Base/no longer exists at the old path. -
src/Legacy/Base/exists and type-checks. - ADR-001 is merged.
- CHANGELOG entry documents the move prominently.
Issue M2-2: Consolidate parallel implementations within Legacy/Base/Structures (#257, closed)¶
Labels: milestone-2-consolidation
Description¶
Base.Structures.Basic defines multi-sorted structures as records; Base.Structures.Sigma.* does the same thing as Σ-types. They are parallel implementations of the same concept, each with its own Products, Congruences, Homs, Isos. Since Base/ is frozen (see M2-1), scope is limited to Legacy cleanup, but worth doing for clarity.
Tasks¶
- Pick one formulation (record or Σ) as canonical within Legacy.
- Add conversion functions where they don't already exist.
- Update internal uses to the canonical form.
- Keep the non-canonical form under a distinct namespace with a deprecation note.
Acceptance criteria¶
-
Legacy/Base/Structures/has a single canonical implementation of each concept. - The non-canonical namespace is clearly marked deprecated.
Issue M2-3: Remove Base.Structures.Graphs0 (unused experimental duplicate) (#258, closed)¶
Labels: milestone-2-consolidation
Description¶
src/Base/Structures/Graphs0.agda is not exported public from Base/Structures.agda and appears to be an abandoned experimental earlier version of Base/Structures/Graphs.agda.
Tasks¶
- Investigate for any downstream dependency on
Graphs0. - If none, delete the file.
- If still referenced, rename to
Graphs.Alternativewith a comment explaining the distinction.
Acceptance criteria¶
-
Graphs0is either deleted or clearly renamed with documentation. - Library still type-checks.
Issue M2-4: Designate a canonical HSP proof; consolidate the others (#259, closed)¶
Labels: documentation, milestone-2-consolidation
Description¶
The library contains three proofs of Birkhoff's HSP theorem:
Base.Varieties.FreeAlgebras.Birkhoff(original Base-tree proof).Setoid.Varieties.HSP.Birkhoff(definitive setoid proof).Demos.HSP.Birkhoff(self-contained pedagogical version for TYPES 2021).
Tasks¶
- Designate
Setoid.Varieties.HSP.Birkhoffas canonical. - Keep
Demos.HSPas the self-contained pedagogical presentation (it was created for TYPES 2021 and remains valuable as a teaching artifact). - Move
Base.Varieties.FreeAlgebras.Birkhoffinto Legacy (implicit via M2-1, but cross-reference explicitly). - Add cross-references among the three so a reader starting at any of them can find the canonical statement.
- Update paper citations in
docs/papers/.
Acceptance criteria¶
-
Setoid.Varieties.HSP.Birkhoffis marked canonical in its module header. -
Demos.HSPcontains a reference to the canonical version. - The paper citation table is up to date.
Issue M2-5: CI gap: Legacy.Base tree is not type-checked by make check (#301, closed)¶
Labels: milestone-2-consolidation, ci
Description¶
The current Everything.agda target in the Makefile excludes $(SRCDIR)/Legacy/* from the generated Everything.agda file. Consequence: make check does not type-check the Legacy/Base/* tree. This was discovered while reviewing PR #300 (M2-1, freeze Base/ as Legacy/Base/); the freeze itself does not introduce the gap, but it makes the gap operationally significant for the first time, since several Setoid/* modules now import from Legacy.Base/* (per ADR-001 §Consequences and the partial-replacement note in DEPRECATED.md).
The exclusion is correct in spirit: Everything is the canonical library, and Legacy/ is by definition not canonical. Including Legacy modules in Everything would (i) clutter the rendered HTML with import Legacy.Base.Structures.Sigma.Congruences next to import Setoid.Varieties.HSP as if they were peers, and (ii) bind the canonical aggregator's import list to content scheduled for eventual removal.
The fix is a second aggregator, EverythingLegacy.lagda.md, that exists purely as a CI gate over src/Legacy/. It is not part of the canonical library and is not rendered to HTML. This pattern generalizes correctly: when Setoid/ itself becomes Legacy in 4.0 (per ADR-003, to be ratified at M5-1), EverythingLegacy.lagda.md will pick up the demoted Setoid tree without any change to Everything.lagda.md semantics.
Tasks¶
- Add an
EverythingLegacy.lagda.mdtarget to the Makefile that generates an aggregator over$(SRCDIR)/Legacy/. - Wire
EverythingLegacy.lagda.mdintomake checkso that bothEverythingandEverythingLegacyare type-checked on every invocation. - Update
.gitignoreifEverything.lagda.mdis gitignored (treat the legacy aggregator the same way). - Update
.github/workflows/ci.ymlto ensure CI invokes the same target (likely no change needed if CI already callsmake check, but verify). - Add a header comment to the generated
EverythingLegacy.lagda.mdexplaining why it exists and that it is not part of the canonical library. - Add
! -name 'EverythingLegacy.lagda.md'to theEverything.lagda.mdtarget'sfindexclusions (preempts the bootstrap loop where each aggregator tries to import the other). - Document the split in
docs/STYLE_GUIDE.md(one paragraph: "what does Everything mean?") so future contributors understand the convention.
Acceptance criteria¶
-
make checkon a cleannix developshell type-checks every.lagda.mdand.agdafile undersrc/, includingsrc/Legacy/. - CI on a fresh PR fails if any
Legacy/Base/*module fails to type-check. - The rendered HTML at https://ualib.org continues to advertise
Everythingas the canonical library, with noLegacy.Base.*entries cluttering its module list. - STYLE_GUIDE.md documents the convention.
Issue M2-6: Extract Setoid-canonical foundations from Legacy.Base (#303, closed)¶
Labels: milestone-2-consolidation
Description¶
The M2-1 freeze (#256, PR #300) surfaced an unaesthetic structural fact: several Setoid/* modules import basic definitions from what is now Legacy.Base.*. After the freeze these imports are type-correct but contradict the framing of Setoid/ as canonical — the canonical tree should not depend on the legacy tree.
This issue extracts the affected definitions into a self-sufficient location. Should land before M3-1 (#260, Classical/ scaffold) so the new layer builds on a clean Setoid/.
Affected imports (audit at M2-1 merge)¶
From grep -rn 'open import Legacy.Base' src/Setoid after the freeze:
Setoid.Algebras.Congruences←Legacy.Base.Relations(0[_],_|:_,Equivalence)Setoid.Algebras.Products←Legacy.Base.Functions(proj,projIsOnto,IsSurjectiverenamedonto)Setoid.Homomorphisms.Factor←Legacy.Base.Relations(kernelRel)Setoid.Homomorphisms.Kernels←Legacy.Base.Relations(kerRel,kerRelOfEquiv)Setoid.Relations.Quotients←Legacy.Base.Relations([_],Equivalence)Setoid.Subalgebras.Subuniverses←Legacy.Base.Relations(Im_⊆_),Legacy.Base.Terms(Term,ℊ,node)Setoid.Terms.Basic,Setoid.Terms.Operations,Setoid.Terms.Properties←Legacy.Base.Terms(Term)Setoid.Varieties.EquationalLogic,Setoid.Varieties.FreeAlgebras,Setoid.Varieties.Preservation,Setoid.Varieties.Properties,Setoid.Varieties.SoundAndComplete←Legacy.Base.Terms(Term,ℊ)
Tasks¶
- For each imported definition (
Term,Equivalence,kernelRel,kerRel,kerRelOfEquiv,Im_⊆_,[_],0[_],_|:_,proj,projIsOnto,IsSurjective), decide its canonical destination:Overture/(if it's foundational and shared acrossSetoid/andClassical/), or a newSetoid/module (if it's setoid-specific and was simply mis-located inBase/historically).Termis the most consequential decision point: it likely belongs inOverture/because bothSetoid/andClassical/will need it. - Move each definition to its canonical destination. Preserve prose comments.
- Update the affected
Setoid/*imports. - Add a
{-# WARNING_ON_USAGE #-}pragma to the legacy definition pointing at the new home. - Update
Legacy/Base/DEPRECATED.mdto record the relocation under Category A with the new canonical path. -
make checkpasses.
Acceptance criteria¶
-
grep -rn 'open import Legacy.Base' src/Setoidreturns no matches. -
grep -rn 'open import Legacy.Base' src/Classical(when M3-1 lands) returns no matches. -
make checkpasses includingEverythingLegacy.lagda.md. - DEPRECATED.md reflects the relocations.
Why now¶
- M3-1 (#260) introduces
Classical/, which will exerciseSetoid/'s self-sufficiency aggressively. Landing this work first meansClassical/doesn't inherit the Legacy.Base dependency. - Definitions that need to live in
Overture/are easier to relocate before they have many call sites;Termin particular is referenced widely already.
Non-goals¶
- Porting Category-B legacy modules (tracked in #TBD parent).
- Reorganizing
Setoid/more broadly.
References¶
- ADR-001 —
docs/adr/001-setoid-as-canonical.md(Consequences section, "Setoid/ is not yet self-sufficient") - M2-1 — #256
- M3-1 — #260 (depends on this)
Issue M2-7: Port orphan Base modules to canonical paths (#302, closed)¶
Labels: milestone-2-consolidation
Description¶
The M2-1 freeze (#256, PR #300) moved src/Base/ to src/Legacy/Base/ and partitioned the legacy modules into three categories in DEPRECATED.md. This issue was the parent tracking the Category-B ports — modules without a canonical replacement at the freeze point.
Scope (as filed)¶
Only orphans whose canonical destination is a port to Setoid/, Overture/, or Examples/. The two large groups of Category-B content explicitly out of scope:
Legacy.Base.Structures.*(16 modules) — superseded wholesale by theClassical/tree (#260, M3-1). Closed by M3 deliverables; no child issue here.Legacy.Base.Equality.*(4 modules, Category C) — retired by construction inSetoid/, no replacement planned. No child issue.
Resolution¶
All seven children closed. Final dispositions:
- M2-7a (#305) —
Legacy.Base.Adjunction.*(4 modules) →Overture.Adjunction.*. Promoted toOverture/rather thanSetoid/because the abstract order-theoretic content is needed identically acrossSetoid/,Classical/, andCubical/. - M2-7b (#306) —
Legacy.Base.Categories.*(2 modules) →Examples.PolynomialFunctors.*. Relocated toExamples/rather than ported into the canonical universal-algebra core; established the precedent now documented in DEPRECATED.md for Category-A relocations toExamples/. - M2-7c (#307) —
Legacy.Base.Complexity.*(3 modules) →Setoid.Complexity.*. Landed in M2 rather than deferred to M9; M9-2 (#281) and M7-1 (#274) now consume the canonical path directly. - M2-7d (#308) —
Legacy.Base.Relations.Continuous→Setoid.Relations.Continuous, with the arity-many indexed-setoidcongdesign documented in the module header. Landed in M2; M9-1 (#282) and M9-2 (#281) now consume the canonical path directly. - M2-7e (#309) —
Legacy.Base.Relations.Properties→Setoid.Relations.Properties. - M2-7f (#310) —
Legacy.Base.Functions.Transformers→Examples.FunctionTypeBijections. Audit against stdlib'sFunction.*confirmed the content was illustrative bijection-construction material rather than a load-bearing API; sameExamples/precedent as M2-7b. - M2-7g (#311) —
Legacy.Base.Varieties.Invariants→Setoid.Varieties.Invariants.
For each port, the legacy module was retained with a {-# WARNING_ON_USAGE #-} pragma naming the canonical home and the closing-issue number; removal is scheduled for v3.1, giving downstream users one full minor cycle to migrate.
Acceptance criteria¶
- Every orphan listed above has a closed child issue (port complete).
- DEPRECATED.md's Category B table contains no row whose
Tracking issuecolumn reads#TBD. - The only Category-B residual content is the
Structures.*subtree (handled by M3); theEquality.*subtree is Category C (no replacement planned).
References¶
- ADR-001 —
docs/adr/001-setoid-as-canonical.md - DEPRECATED.md —
src/Legacy/Base/DEPRECATED.md - M2-1 — #256
- Children — #305, #306, #307, #308, #309, #310, #311
Issue M2-7a: Port Legacy.Base.Adjunction.* to canonical paths (#305, closed)¶
Labels: milestone-2-consolidation, design-discussion
Description¶
Port the four-module Legacy.Base.Adjunction.* subtree (aggregator + Closure + Galois + Residuation) to canonical paths. Child of #302.
The destination is not yet decided — adjunction / Galois-connection / residuation content sits at an awkward intersection of universal algebra (where it is consumed: closure operators induce algebraic closure systems, congruence-extending Galois connections appear in clone theory) and pure order theory (where the abstract definitions naturally belong). The destination decision is part of this issue.
Destination options¶
Setoid.Adjunction/— keeps the content next to its universal-algebra consumers. Disadvantage: adjunctions are not specifically setoid-flavored; ifClassical/ever grows order-theoretic content (lattices, posets) the same definitions will want to live there too, and we'd have duplication.Classical.Order.Adjunction/— fits if M3-5 (#264, Lattice) and any plannedClassical.Order.*infrastructure absorb the abstract order-theoretic content. Disadvantage: requiresClassical/order infrastructure to land first.Overture/Adjunction/— fits if the content is genuinely foundational and used acrossSetoid/,Classical/, and (eventually)Cubical/. Disadvantage:Overture/is small and intentionally narrow; expanding its scope deserves its own design discussion.
The third option is probably premature; the first two are both defensible. Recommend deciding Setoid.Adjunction/ for v3.0 and reconsidering the location for v4.0 alongside any Classical.Order/ work.
Tasks¶
- Decide the destination. Record briefly in this issue.
- Port
Legacy.Base.Adjunction.Closureto<Destination>.Closure. - Port
Legacy.Base.Adjunction.Galoisto<Destination>.Galois. - Port
Legacy.Base.Adjunction.Residuationto<Destination>.Residuation. - Port the aggregator
Legacy.Base.Adjunctionto<Destination>. - Add
{-# WARNING_ON_USAGE #-}pragmas to each legacy module pointing at the canonical home. - Update
Legacy/Base/DEPRECATED.md: move all four rows from Category B to Category A. - Confirm
make checkandEverythingLegacyboth pass.
Acceptance criteria¶
- Four canonical-path modules exist and type-check.
- Four
Legacy.Base.Adjunction.*modules carryWARNING_ON_USAGEpragmas. - DEPRECATED.md reflects the move; no
#TBDcells remain for the Adjunction rows.
References¶
- Parent — #302
- ADR-001 —
docs/adr/001-setoid-as-canonical.md - DEPRECATED.md —
src/Legacy/Base/DEPRECATED.md - Possible future consumer — #282 (M9-1, Scott-continuous DCPOs). Not a blocker; flagged because the destination decision should keep M9-1's plausible needs in mind (Galois connections between predicates and operations on DCPOs are natural M9-1 territory).
Issue M2-7b: Port Legacy.Base.Categories.* to canonical paths (#306, closed)¶
Labels: milestone-2-consolidation, design-discussion
Description¶
Port the two-module Legacy.Base.Categories.* subtree (aggregator + Functors) to canonical paths. Child of #302.
The destination is not obvious. agda-algebras is a universal-algebra library, not a category-theory library; the Agda ecosystem already has agda-categories as a comprehensive category-theory development. Two questions:
- Do we need this content in agda-algebras, or should it be redirected to
agda-categorieswith a thin shim re-exporting whatever agda-algebras code presently consumes?src/Examples/Categories/Functors.lagda.mdis the only known consumer in this repo. - If kept, where:
Setoid.Categories/, a new top-levelCategories/tree (probably wrong; we don't want to be a category-theory library), or pulled intoOverture/(probably wrong; too narrow there)?
This issue's first deliverable is the destination decision, not the port.
Tasks¶
- Audit the content of
Legacy.Base.Categories.*againstagda-categoriesto determine whether equivalent functionality already exists upstream. - If equivalent functionality exists upstream: file a follow-up to remove
Legacy.Base.Categories.*outright, redirectingsrc/Examples/Categories/Functors.lagda.md(#304) toagda-categoriesinstead of porting. Close this issue with the redirection decision recorded. - If equivalent functionality does not exist upstream: decide on a destination (
Setoid.Categories/, or kept inLegacy.Base.Categories/indefinitely with the Category B rationale clarified to "stays in Legacy because no canonical home exists in the universal-algebra scope of this library"). Port ifSetoid.Categories/; document if "stays in Legacy." - Update
Legacy/Base/DEPRECATED.mdaccordingly: either move both rows to Category A (port landed), or reword the Category B rows to reflect "stays in Legacy" status (no port planned), or move to a new "Category D — relocated upstream" if redirected. - Confirm
make checkandEverythingLegacyboth pass.
Acceptance criteria¶
- A destination decision is recorded in this issue.
- DEPRECATED.md reflects the resolution; no
#TBDcells remain for the Categories rows. - If a port lands, the canonical-path modules type-check; if relocated upstream,
Examples/Categories/Functors.lagda.mdis updated accordingly.
References¶
- Parent — #302
- Examples migration — #304
agda-categories— https://github.com/agda/agda-categories- Adjacent — #283 (M9-3, exploratory coalgebra). M9-3's reading may surface a need for some categorical infrastructure; if so, this issue's destination decision should be reconsidered with M9-3's findings in mind. Not a current blocker — M9-3 is exploratory and may conclude no formalization is warranted.
Issue M2-7c: Port Legacy.Base.Complexity.* to canonical paths (#307, closed)¶
Labels: milestone-2-consolidation, milestone-9-apps
Description¶
Port the three-module Legacy.Base.Complexity.* subtree (aggregator + Basic + CSP) to canonical paths. Child of #302.
Scheduled with M9. Issue #274 (M7-1, "Extend Complexity module beyond Basic and CSP") is the substantive sequel that grows this content significantly; this issue's scope is the canonical-path migration only, not the extension. Order: this issue first, then #274 builds on the canonical-path version.
Destination¶
The natural destination is Setoid.Complexity/, mirroring the existing Legacy.Base.Complexity/ shape. Open question — to be settled in this issue — is whether the eventual home should be Setoid.Complexity/ (consistent with current naming) or a top-level Complexity/ tree (parallel to Classical/, since complexity is a domain rather than a flavor of universal algebra). Recommendation: Setoid.Complexity/ for v3.0 to minimize churn; revisit at the v4.0 Cubical canonicalization moment.
Tasks¶
- Confirm the destination — recommended
Setoid.Complexity/. - Port
Legacy.Base.Complexity.BasictoSetoid.Complexity.Basic. - Port
Legacy.Base.Complexity.CSPtoSetoid.Complexity.CSP. - Port the aggregator
Legacy.Base.ComplexitytoSetoid.Complexity. - Add
{-# WARNING_ON_USAGE #-}pragmas to each legacy module pointing at the canonical home. - Update
Legacy/Base/DEPRECATED.md: move all three rows from Category B to Category A; correct the destination column to the agreed canonical name. - Confirm
make checkandEverythingLegacyboth pass.
Acceptance criteria¶
- Three canonical-path modules exist and type-check.
- Three
Legacy.Base.Complexity.*modules carryWARNING_ON_USAGEpragmas. - DEPRECATED.md reflects the move; no
#TBDcells remain for the Complexity rows.
Why M9 milestone?¶
Setoid.Complexity/ is the foundation for M9-2 (#281, infinitary CSP), which is squarely complexity content built on the existing Base.Complexity development. M7-1 (#274) is the extension of the same content for finite-template CSP; that issue depends on the canonical-path version landing first. M9-1 (#282, Scott-continuous DCPOs) does not depend on this port — its dependencies are on Relations.Continuous (#308) and on the order/lattice infrastructure flowing from M3-5 (#264) — and is listed below only as a sibling M9 issue, not as a consumer.
References¶
- Parent — #302
- M7-1 (extend Complexity) — #274
- M9-2 (infinitary CSP) — #281
- Exercises migration — #304 (depends on this for
FiniteCSP.lagda.md)
Issue M2-7d: Port Legacy.Base.Relations.Continuous to canonical paths (#308, closed)¶
Labels: milestone-2-consolidation, milestone-9-apps
Description¶
Port Legacy.Base.Relations.Continuous to a canonical path. Child of #302.
The Continuous relation API — relations of arbitrary arity type rather than fixed natural-number arity, with arity-many indexed-setoid families — is the foundation of three M9 issues (#281, #282, #283). Until this port lands, M9 work depends on Legacy.Base/, contradicting the framing of Setoid/ as canonical.
Destination question¶
Two options:
Setoid.Relations.Continuous— fits the currentSetoid.Relations.{Discrete,Quotients}naming. Disadvantage: continuous relations are not specifically setoid-flavored; the abstract definition is at the order-theoretic / domain-theoretic level.Overture.Relations.Continuous(or newOverture.Continuous/) — fits if continuous relations are foundational acrossSetoid/,Classical/, andCubical/. Likely the right long-term home, but expandingOverture/deserves its own design moment.
Recommendation: port to Setoid.Relations.Continuous for v3.0 (mechanical, low-friction); revisit Overture/ placement during v4.0 Cubical canonicalization when the same definitions will have to be expressible there too.
The destination decision should harmonize with #303 (M2-6, Extract Setoid-canonical foundations from Legacy.Base), which makes parallel decisions for Term, kerRel, and other foundational definitions. If #303 lands first and routes those to Overture/, this issue should follow suit; if #303 keeps them in Setoid/, the same logic applies here.
Why this is a non-trivial port¶
Unlike most of Category A, where the propositional-equality version maps mechanically onto the setoid version by passing ≡-setoid A, the Continuous API has substantive subtlety: the "respects-the-setoid-equivalence" condition for arity-many arguments needs careful design. The natural setoid version of f : (i : I) → A i → B has a cong that takes a proof of (i : I) → A i ≈ A' i and produces f A ≈ f A', but the indexing makes the standard setoid-function shape not quite right. The port should consult the design used by the underlying stdlib Function.Indexed.* machinery (if any) and harmonize.
Tasks¶
- Decide the destination. Recommended
Setoid.Relations.Continuousfor v3.0. - Design the setoid-respecting interface for indexed continuous relations. Document briefly in the module header.
- Port
Legacy.Base.Relations.Continuousto the chosen destination, with the indexed-setoid design in place. - Add a
{-# WARNING_ON_USAGE #-}pragma to the legacy module. - Update
Legacy/Base/DEPRECATED.md: move the row to Category A. - Confirm
make checkandEverythingLegacyboth pass.
Acceptance criteria¶
- Canonical-path module exists, type-checks, and has a prose comment block documenting the indexed-setoid-respecting design.
-
Legacy.Base.Relations.Continuouscarries aWARNING_ON_USAGEpragma. - DEPRECATED.md reflects the move; no
#TBDcell remains for the Continuous row. - M9-1 (#282) and M9-2 (#281) can import from the canonical path without changes.
References¶
- Parent — #302
- M2-6 (Setoid foundations extraction) — #303. Sibling issue setting precedent for
Overture/vs.Setoid/placement of foundational definitions. - M9-1 — #282
- M9-2 — #281
- M9-3 — #283
- Exercises migration — #304 (depends on this for
FiniteCSP.lagda.md)
Issue M2-7e: Port Legacy.Base.Relations.Properties to Setoid.Relations.Properties (#309, closed)¶
Labels: milestone-2-consolidation
Description¶
Port Legacy.Base.Relations.Properties to Setoid.Relations.Properties. Child of #302.
Smallest of the M2-7 children — a single module port whose canonical destination is unambiguous (the Setoid.Relations.* subtree exists and has matching Discrete / Quotients siblings). Scheduled as an M2 follow-up.
The M2-1 inventory found no consumers of Base.Relations.Properties outside src/Base/ itself — no src/Setoid/, src/Examples/, or src/Exercises/ module imports it. The migration is therefore localized: porting the module and updating the Setoid.Relations aggregator covers it.
Tasks¶
- Port
Legacy.Base.Relations.PropertiestoSetoid.Relations.Properties. Migration is mechanical when content is propositional-equality-based; replace_≡_arguments with the algebra's setoid equivalence as needed. - Update
Setoid.Relations(the aggregator) to re-exportSetoid.Relations.Propertiespublic. - Add a
{-# WARNING_ON_USAGE #-}pragma toLegacy.Base.Relations.Properties. - Update
Legacy/Base/DEPRECATED.md: move the row from Category B to Category A; remove the partial-replacement note from theLegacy.Base.Relationsaggregator row in Category A (now covered). - Confirm
make checkandEverythingLegacyboth pass.
Acceptance criteria¶
-
Setoid.Relations.Propertiesexists and type-checks. -
Legacy.Base.Relations.Propertiescarries aWARNING_ON_USAGEpragma. - DEPRECATED.md no longer flags
Setoid.Relationsas a partial replacement (assumingContinuousis also resolved per #308; otherwise, the partial-replacement note is updated to reference onlyContinuous). - No
#TBDcell remains for the Relations.Properties row.
References¶
- Parent — #302
- Companion — #308 (Relations.Continuous; the other half of why
Setoid.Relationsis currently partial)
Issue M2-7f: Port Legacy.Base.Functions.Transformers to canonical paths (#310, closed)¶
Labels: milestone-2-consolidation, design-discussion
Description¶
Port Legacy.Base.Functions.Transformers to a canonical path. Child of #302.
Single-module port; destination is the design-discussion piece.
Like #309, the M2-1 inventory found no consumers of Base.Functions.Transformers outside src/Base/ itself. This makes the "drop entirely if all definitions have stdlib equivalents" path cheap — no internal call sites need migration.
Destination question¶
Legacy.Base.Functions.Transformers contains function-transformer combinators (currying, uncurrying, point-free composition variants, possibly others — to be confirmed by audit). Two destinations:
Setoid.Functions.Transformers— fits the currentSetoid.Functions.{Injective,Surjective,Inverses}naming. Disadvantage: function transformers are propositional (not setoid-flavored) by nature; the canonical home is probably stdlib'sFunction.Base/Function.Definitions.- Redirect to stdlib — audit the content; if stdlib already provides equivalent combinators, remove the module rather than porting it, and update any consumers to import from stdlib.
Recommendation: audit first; the right answer is likely "stdlib redirect" for most of the module, with Setoid.Functions.Transformers covering whatever residual content has no stdlib analog.
Tasks¶
- Audit
Legacy.Base.Functions.Transformerscontent against stdlib'sFunction.BaseandFunction.Construct.*. - For each definition, decide: stdlib redirect, port to
Setoid.Functions.Transformers, or drop entirely (if an unused experimental). - If any content survives the audit: port to
Setoid.Functions.Transformers; updateSetoid.Functionsaggregator to re-export. - If no content survives: remove
Legacy.Base.Functions.TransformersfromLegacy/Base/DEPRECATED.mdand from the Legacy build (or move to a new "Category D — removed in 3.x" section if the deletion deserves a record). - Add a
{-# WARNING_ON_USAGE #-}pragma to the legacy module pointing at the new home (or at the appropriate stdlib module per definition). - Confirm
make checkandEverythingLegacyboth pass.
Acceptance criteria¶
- Audit results recorded in this issue (per-definition disposition).
- DEPRECATED.md reflects the resolution; no
#TBDcell remains for the Functions.Transformers row. -
make checkpasses.
References¶
- Parent — #302
- stdlib
Function.*— https://agda.github.io/agda-stdlib/master/Function.html
Issue M2-7g: Port Legacy.Base.Varieties.Invariants to Setoid.Varieties.Invariants (#311, closed)¶
Labels: milestone-2-consolidation
Description¶
Port Legacy.Base.Varieties.Invariants to Setoid.Varieties.Invariants. Child of #302.
Single-module port; destination is unambiguous (the Setoid.Varieties.* subtree is already canonical and contains the HSP development).
The M2-1 inventory found no consumers of Base.Varieties.Invariants outside src/Base/ itself. Plausible future consumer: M3-7 (#266, expand Examples/), where varieties-as-invariants results characterizing classical structure classes are natural worked examples.
Tasks¶
- Port
Legacy.Base.Varieties.InvariantstoSetoid.Varieties.Invariants. Migration is mechanical when content reasons up to propositional equality on the algebra carrier; replace with the algebra's setoid equivalence as needed. - Update
Setoid.Varieties(the aggregator) to re-exportSetoid.Varieties.Invariantspublic. - Add a
{-# WARNING_ON_USAGE #-}pragma toLegacy.Base.Varieties.Invariants. - Update
Legacy/Base/DEPRECATED.md: move the row from Category B to Category A. - Confirm
make checkandEverythingLegacyboth pass.
Acceptance criteria¶
-
Setoid.Varieties.Invariantsexists and type-checks. -
Legacy.Base.Varieties.Invariantscarries aWARNING_ON_USAGEpragma. - DEPRECATED.md reflects the move; no
#TBDcell remains for the Varieties.Invariants row.
References¶
- Parent — #302
- Possible future consumer — #266 (M3-7, expand Examples/ with classical structures). Not a current dependency.
Issue M2-8: Migrate src/Examples and src/Exercises imports to canonical paths (#304, closed)¶
Labels: milestone-2-consolidation
Description¶
After the M2-1 freeze (#256, PR #300), three files outside src/Legacy/ still import from Legacy.Base.*:
src/Examples/Structures/Basic.lagda.md— importsLegacy.Base.StructuresandLegacy.Base.Structures.Basic.src/Examples/Structures/Signatures.lagda.md— importsLegacy.Base.Structures.Basic.src/Exercises/Complexity/FiniteCSP.lagda.md— importsLegacy.Base.Structures.Basic,Legacy.Base.Structures.Homs(and, until this PR,Legacy.Base.Relations.Continuous).
These imports are technically correct after the rename, but the example/exercise should exercise the canonical library, not the legacy one. Each needs to migrate to whichever destination its content lands at.
Status¶
- Categories.Functors. Resolved under #306 (M2-7b) by relocation to
Examples.PolynomialFunctors.Functors; the oldsrc/Examples/Categories/directory was removed. The stale\input{../latex/Examples.Categories.Functors}indocs/papers/EverythingFunc.texis fixed by this PR. Setoid.Relations.Continuousimport inFiniteCSP. Landed in this PR (the canonical Continuous destination was finalized under #308 / M2-7d).Legacy.Base.Structures.*imports. Blocked on M3-1 (#260,Classical/scaffold). Tracked in follow-ups M2-8b (Structures examples) and M2-8c (FiniteCSP structures + homs).
Tasks¶
- Migrate the
Continuousimport inExercises/Complexity/FiniteCSP.lagda.md. - Fix the stale
Examples.Categories.FunctorsLaTeX\input. - Decide the fate of
Examples/Structures/{Basic,Signatures}.lagda.mdonce M3-1 lands — migrate toClassical/or fold into the M3-7 (#266) examples. Tracked in M2-8b. - Migrate the two
Legacy.Base.Structures.*imports inExercises/Complexity/FiniteCSP.lagda.mdonce M3-1 lands. Tracked in M2-8c.
Acceptance criteria¶
-
grep -rn 'Examples\.Categories' src/ docs/returns no matches. -
grep -rn 'open import Legacy.Base' src/Examples src/Exercisesreturns no matches (deferred to M2-8b + M2-8c after M3-1). -
make checkpasses.
References¶
- M2-1 — #256
- M2-7b (Categories port) — #306
- M2-7d (Continuous port) — #308
- M3-1 — #260
- M3-7 — #266
- Parent port-tracking issue — #302
Issue M2-8b: Update imports in submodules of Examples.Structures (#322)¶
Labels: milestone-2-consolidation, blocked-upstream
Description¶
The two example modules src/Examples/Structures/Basic.lagda.md and src/Examples/Structures/Signatures.lagda.md still import signature and structure from Legacy.Base.Structures.{Basic,...}. Their canonical home depends on M3-1 (#260, Classical/ scaffold), which has not yet landed.
The pedagogical content here is heterogeneous:
- Finite signatures
S∅,S1,S001,S021, ... inSignatures.lagda.md. These are foundational examples consumed byExercises.Complexity.FiniteCSP. Natural canonical home:Classical.Signatures.*once M3-1 lands. Migration is mechanical. SL(3-element meet-semilattice) inBasic.lagda.md. Naturally re-expressed againstClassical.Structures.Semilattice(M3-5 #264) once that lands. Could fold into the M3-7 (#266) examples program.NAE3SAT(2-element ternary NAE-3-SAT relational structure) inBasic.lagda.md. Genuinely relational — the current M3 plan is algebraic (operations only) — so this content has no natural destination in the plannedClassical/tree. Two options: (a) keep a bare-types relational-structures example, perhaps underExamples/RelationalStructures/; (b) defer to a futureClassical.Relational/extension.
Tasks¶
- Decide the per-example destination once M3-1 lands.
- Migrate signatures examples to
Classical.Signatures.*if M3-1's signature API supports it directly. - Migrate or rewrite
SLagainstClassical.Structures.Semilattice(depends on M3-5). - Resolve
NAE3SAT: relocate, rewrite, or delete. - Update
Exercises/Complexity/FiniteCSP.lagda.md'sExamples.Structures.Signaturesconsumer accordingly (M2-8c is the immediate downstream).
Dependencies¶
- Blocked by M3-1 (#260).
- Benefits from M3-5 (#264) for the semilattice example.
- M3-7 (#266) may subsume the
SLexample.
References¶
- Parent — #304 (M2-8)
- M3-1 — #260
- M3-5 — #264
- M3-7 — #266
Issue M2-8c: Fix imports in Exercises.Complexity.FiniteCSP (#323)¶
Labels: milestone-2-consolidation, blocked-upstream
Description¶
src/Exercises/Complexity/FiniteCSP.lagda.md still imports signature, structure, and hom from Legacy.Base.Structures.{Basic,Homs} after the M2-8a partial closure (#304). These imports are gated on M3-1 (#260, Classical/ scaffold) for the same reasons as M2-8b.
The exercise uses the bare-types relational-structures API (relational signatures S021, the structure 𝐹 𝑅 record with non-trivial rel field, and hom for the resulting relational structures). As noted in M2-8b, the planned Classical/ tree is currently algebraic-only, so this migration depends on either:
- M2-8b resolving the relational-structures destination question, or
- M3 being extended to cover relational structures (a
Classical.Relational/subtree).
Tasks¶
- Coordinate with M2-8b on the destination of relational-structures content.
- Migrate the
signature,structure,homimports inFiniteCSP.lagda.mdto the chosen destination. - Remove the
TODO(#M2-8c)marker added in M2-8a.
Acceptance criteria¶
-
grep -rn 'open import Legacy.Base' src/Exercisesreturns no matches. -
make checkpasses.
References¶
- Parent — #304 (M2-8)
- Sibling — M2-8b
- M3-1 — #260
Milestone 2 Dependencies¶
M2-1 (freeze Base/) is the fork point: everything else in this milestone is internal cleanup within what becomes Legacy/Base/, and all three depend on the move happening first. M1-1 is shown dashed to indicate it's an upstream dependency from a different milestone.
graph TD
M1_1["M1-1: Agda 2.8 / stdlib 2.3"]:::ext
M2_1["M2-1: Freeze Base"]
M2_2["M2-2: Consolidate Base.Structures"]
M2_3["M2-3: Remove Graphs0"]
M2_4["M2-4: Canonical HSP"]
M2_5["M2-5: EverythingLegacy CI"]
M2_6["M2-6: Extract Setoid foundations"]
M2_7["M2-7: Port orphans (parent)"]
M2_7a["M2-7a: Adjunction"]
M2_7b["M2-7b: Categories"]
M2_7c["M2-7c: Complexity"]
M2_7d["M2-7d: Continuous"]
M2_7e["M2-7e: Relations.Properties"]
M2_7f["M2-7f: Functions.Transformers"]
M2_7g["M2-7g: Varieties.Invariants"]
M2_8["M2-8: Examples/Exercises migration"]
M1_1 --> M2_1
M2_1 --> M2_2
M2_1 --> M2_3
M2_1 --> M2_4
M2_1 --> M2_5
M2_1 --> M2_6
M2_1 --> M2_7
M2_7 --> M2_7a
M2_7 --> M2_7b
M2_7 --> M2_7c
M2_7 --> M2_7d
M2_7 --> M2_7e
M2_7 --> M2_7f
M2_7 --> M2_7g
M2_7a --> M2_8
M2_7b --> M2_8
M2_7c --> M2_8
M2_7d --> M2_8
classDef ext fill:#f0f0f0,stroke:#999,stroke-dasharray: 4 3,color:#555
---¶
Milestone 3 — Classical structures layer¶
Issue M3-1: Introduce the Classical/ tree — Signatures, Theories, Structures, Bundles, Small (#260, closed)¶
Labels: milestone-3-classical, design-discussion
Description¶
The library has no formalized classical algebraic structures despite this being a long-stated vision. This issue creates the scaffold; subsequent issues add specific structures.
Ratified design decisions (to be recorded in docs/adr/002-classical-layer.md):
- Each classical structure
Xis Σ-typed at the core:X α ρ = Σ[ 𝑨 ∈ Algebra 𝑆ₓ α ρ ] 𝑨 ⊨ Eₓ. The mathematical reading "X is an algebra equipped with a proof it satisfies the X-theory" motivates Σ over record for classical structures. The coreAlgebratype stays a record. - A parallel record-typed "bundle view" in
Classical/Bundles/Xmatches the stdlibAlgebra.Bundlesidiom for interop. - Built on
Setoid/(notBase/). A helperfromPropEq : Type α → ... → X α αlets users build classical structures from propositional-equality-based definitions without explicit Setoid wrapping. - Designed for Cubical portability. Equations stated purely in terms of
Algebra.Domain's equivalence — never reaching for Setoid-specific features without a Cubical analog. WhenCubical/becomes canonical in 3.0, the port should be mechanical. - Two levels of specificity per structure: polymorphic core (
Classical.Structures.X) and level-fixed veneer (Classical.Small.Structures.X) for the commonℓ₀case.
Tasks¶
- Create the directory skeleton:
src/Classical/
Classical.agda
Signatures/
Theories/
Structures/
Bundles/
Small/Structures/
- Add placeholder modules that type-check.
- Write
Classical.agdathat re-exports everything. - Write
docs/adr/002-classical-layer.mdrecording the design decisions.
Acceptance criteria¶
- Scaffold type-checks.
-
Classical.agdare-exports the empty scaffold cleanly. - ADR-002 is merged.
Issue M3-1a: Scaffold the Classical/ tree — umbrella files for all five subtrees (#326, closed)¶
Labels: documentation, milestone-3-classical
Parent: #260 (M3-1)
Description¶
This issue introduces the directory layout and umbrella files for the Classical/ tree, per the design committed in ADR-002. It is scaffolding only: no concrete structure (Magma, Semigroup, Monoid, …) lands here. Concrete structures are tracked under separate M3-2…N issues, each shipping the five-file quintuple (Signatures + Theories + Structures + Bundles + Small) per ADR-002 for one structure.
Six umbrella files land:
src/Classical.lagda.md— top-level umbrella for theClassicaltreesrc/Classical/Signatures.lagda.md— umbrella for per-structure signaturessrc/Classical/Theories.lagda.md— umbrella for per-structure equational theoriessrc/Classical/Structures.lagda.md— umbrella for per-structure Σ-typed coressrc/Classical/Bundles.lagda.md— umbrella for per-structure stdlib-shaped record bundlessrc/Classical/Small.lagda.md— umbrella for per-structure level-fixed veneers
Each umbrella file gets a standard module header with the canonical "This is the [Classical.X][] module of the Agda Universal Algebra Library" prose preamble, an ADR-002 cross-reference, a prose-schema explanation of what the subtree will contain (so a reader landing on Classical/Signatures.lagda.md knows it's the home of per-structure signature definitions, even before any concrete signature exists), and an empty public re-export block ready to grow as M3-2…N land structures.
The top-level Classical.lagda.md umbrella additionally cross-references the parallel structure of Setoid/ (per ADR-001) so the relationship between the two trees is visible from the entry point.
The library aggregator agda-algebras.lagda.md already mentions Classical/ as a planned tree under ADR-002; that reference is updated from "planned, M3" to active wording with a link to this scaffold, and the existing open import Classical line is uncommented (or added, if currently absent).
The Everything.agda and EverythingFunc.agda generators are updated to walk the new subtree.
Non-goals¶
- No concrete structure (
Magma,Semigroup,Monoid,Group,Lattice,Ring, …) lands here; those are M3-2…N. - No shared infrastructure (
fromPropEq, named projection helpers likeDomain/Signature/equations, generic Classical-flavored equational reasoning) lands here. The right shapes for those helpers emerge from M3-2 (Semigroup) and will be pulled up into shared locations only once they have at least one consumer. Premature abstraction here is the failure mode this issue explicitly avoids. - No bundle-bridge infrastructure to stdlib lands here; that is M3-3.
- No update to
Legacy.Base.Structures.*deprecation notices; the structures-superseded-by-Classical relocation is per-structure and tracked on the M3-2…N issues.
Tasks¶
- Create
src/Classical.lagda.mdwith the top-level module header, ADR-001/ADR-002 cross-references, a brief prose explanation of the five-subtree quintuple pattern, and an empty re-export block. - Create
src/Classical/Signatures.lagda.md,src/Classical/Theories.lagda.md,src/Classical/Structures.lagda.md,src/Classical/Bundles.lagda.md,src/Classical/Small.lagda.md, each with module header + ADR-002 cross-reference + subtree-purpose prose + empty re-export block. - Update
src/agda-algebras.lagda.mdto activate theClassical/mention (replace "planned, M3" with active wording linking to ADR-002 and to this scaffold). - Update the
Everything.agda/EverythingFunc.agdabuild target so the new files are walked bymake check. - Update
README.mdlibrary-structure section to drop "planned, M3" from theClassical/bullet. - Record under
CHANGELOG.md[Unreleased] / Added.
Acceptance criteria¶
- All six umbrella files exist with proper module headers and ADR-002 cross-references.
-
make checkpasses (the empty re-export blocks should type-check trivially). -
agda-algebras.lagda.md,README.md, andCHANGELOG.mdreflect the activation. - No concrete structure or shared helper lands; the diff is pure scaffolding.
References¶
- Parent — #260 (M3-1).
- Design — ADR-002.
- Foundation — ADR-001.
- Long-term portability target — ADR-003.
- Downstream — M3-2 (Semigroup, the first concrete structure landing under the scaffold), M3-3 (stdlib bundle bridges).
Issue M3-2: Classical.Operations and Classical.Equations infrastructure (#330, closed)¶
Labels: milestone-3-classical, design-discussion
Description¶
This issue introduces the two shared-infrastructure modules that every concrete Classical/X structure will depend on: Classical.Operations, holding the per-arity Curry/Uncurry helpers that bridge the foundational tuple-indexed operation form (I → A) → A with the curried user-facing form A → A → A; and the seed of Classical.Equations (or Classical.Identities.lagda.md — name TBD in PR), holding generic equation builders parametric in a signature and operation symbols.
Per ADR-002 v2 §1, tuple-indexed operations live in Setoid.Algebras and downstream meta-theory; curried operations are the user-facing form across Classical/. Per ADR-002 v2 §3, generic equation builders form the syntactic dual of stdlib's Algebra.Definitions and feed the equational-logic substrate (Modᵗ) for every concrete theory.
Landing this infrastructure before any concrete structure means M3-3 (Magma) is purely about signature mechanics, M3-4 (Semigroup) is purely about adding one equation, and so on. Each per-structure issue is a small composition rather than a re-derivation.
This issue is the renumbered predecessor of what was originally M3-2 (Semigroup); the M3-2 issue body was reformulated to M3-4 after the v2 ADR.
Design decisions¶
These are the conventions established here; the same applies to every per-structure file that consumes this infrastructure.
Curry/Uncurryhelpers. One pair per arity:Curry₀/Uncurry₀for nullary,Curry₁/Uncurry₁for unary,Curry₂/Uncurry₂for binary. Higher arities added as needed (Lattice in M3-7 may wantCurry₃for the absorption-law statement; defer the decision until then). Each helper is a two-line definition; the file is short.- Fin n η-bridge containment. The Fin 2 η-failure under
--cubical-compatibleis contained insideUncurry₂andCurry₂— at the use site, an(I → A) → Aoperation appears asA → A → Aand the wrapping/unwrapping is invisible. Per-structure files never writepair-style helpers inline. - Generic equation builders. Parametric in signature
S : Signature 𝓞 𝓥(orSignature ℓ₁ ℓ₂if the abstract over levels is undesirable; finalize during PR) and in operation symbols withinS, with arity-conformance evidence as a≡ Fin nargument. Inventory for M3-2: Associative : (f : OperationSymbolsOf S) → ArityOf f ≡ Fin 2 → ∀ {X} → X → X → X → Term X × Term XCommutative : (f : OperationSymbolsOf S) → ArityOf f ≡ Fin 2 → ∀ {X} → X → X → Term X × Term XLeftIdentity / RightIdentity : binary op + nullary op + their arity proofs → ∀ {X} → X → Term X × Term XLeftInverse / RightInverse : binary op + nullary identity op + unary inverse op + arity proofs → ∀ {X} → X → Term X × Term XIdempotent : (f : OperationSymbolsOf S) → ArityOf f ≡ Fin 2 → ∀ {X} → X → Term X × Term XDistributesOverˡ / DistributesOverʳ : two binary ops + their arity proofs → ∀ {X} → X → X → X → Term X × Term XAbsorbs : two binary ops + their arity proofs → ∀ {X} → X → X → Term X × Term X
This inventory covers every equation in Th-Magma, Th-Semigroup, Th-Monoid, Th-Group, Th-Semilattice, Th-Lattice, Th-Semiring, Th-Ring. Builders for less-uniform equations (e.g., the medial law) deferred until a structure needs them.
+ Self-documenting signature projections. This file also seeds OperationSymbolsOf and ArityOf aliases in Overture.Signatures (per ADR-002 v2 §1). Two-line addition; bracket notation remains everywhere it already appears.
+ Notation rename ̂ → ^ (per ADR-002 v2 §7). Add WARNING_ON_USAGE to the existing ̂ definition in Setoid.Algebras.Basic; introduce ^ as the new canonical infix. Per-tree policy: new Classical/ code uses ^ exclusively; existing Setoid/ code is not retroactively renamed.
Tasks¶
Core infrastructure files¶
-
src/Classical/Operations.lagda.md—Curry₀/Uncurry₀,Curry₁/Uncurry₁,Curry₂/Uncurry₂with prose explaining the design intent. -
src/Classical/Equations.lagda.md— the generic equation builders above, with prose introducing the file as the syntactic dual ofAlgebra.Definitionsand citing Bryant 1982 for the historical motivation that distinguishes syntactic from evaluated equation collections. -
src/Classical.lagda.mdumbrella —open import Classical.Operations publicandopen import Classical.Equations public.
Signature-projection aliases¶
- Update
src/Overture/Signatures.lagda.mdto exportOperationSymbolsOfandArityOf. Definitionally identical to the existing∣ 𝑆 ∣and∥ 𝑆 ∥aliases; no behavioral change.
Notation rename¶
- Update
src/Setoid/Algebras/Basic.lagda.mdto introduce_^_alongside_̂_, with aWARNING_ON_USAGE _̂_pragma announcing v3.1 removal. Add an ADR-002 §7 cross-reference in the module-header prose.
Documentation¶
- Module-header prose in
Classical.OperationsandClassical.Equationsdocumenting the design intent normatively, so M3-3 / M3-4 / M3-5 / M3-6 authors have a single reference for the conventions they're consuming. - Cross-reference
Classical.Equationsindocs/STYLE_GUIDE.mdunder a new section on "Generic equation builders for classical structures." -
CHANGELOG.md[Unreleased] / Addedentry.
Non-goals¶
- No concrete structure (Magma, Semigroup, Monoid, …) lands here. Those are M3-3 onward.
- No bundle-bridge infrastructure beyond what
Curry/Uncurryenables. Per-structure bundle bridges land with their structures. - Higher-arity
Curry/Uncurryhelpers (Curry₃, Curry₄, …) are added only when a concrete structure requires them. - Generic equation builders beyond the inventory above are added per-need.
Acceptance criteria¶
- All three new files (
Classical.Operations,Classical.Equations, and theClassical.lagda.mdumbrella update) type-check undermake check. -
OperationSymbolsOfandArityOfaliases reduce definitionally to the bracket forms —OperationSymbolsOf S ≡ ∣ S ∣andArityOf {S} f ≡ ∥ S ∥ fboth inhabited byrefl. - The
WARNING_ON_USAGE _̂_pragma fires in a test module that imports the old notation, and^is available as the new canonical notation. ExistingSetoid/code continues to type-check (the warning is non-fatal). - Module-header prose in
Classical.OperationsandClassical.Equationsis normative enough that a contributor authoringClassical.Magmafrom scratch can do so without consulting this PR. - CHANGELOG entry under
[Unreleased] / Added.
References¶
- Parent — #260 (M3-1).
- Scaffold predecessor — #326 (M3-1a).
- Design — ADR-002 v2 §1, §3, §7.
- Downstream — M3-3 (Magma, first consumer of this infrastructure), M3-4 (Semigroup, first equation-bearing consumer), M3-5 (stdlib bridges), M3-6/M3-7/M3-8 (Monoid/Group, Lattice, Ring).
- Empirical motivation — the M3-2 (old) Semigroup load-test in branch
261-m3-2-classical-semigroup, whosecong (Interp 𝑨)bridges andassignmentplumbing live as evidence of what this infrastructure exists to remove. - Reference for the syntactic-vs-evaluated equation distinction — R. Bryant, The laws of finite pointed groups, Bull. London Math. Soc. 14 (1982), 119–123.
Issue M3-3: Classical.Magma (#331, closed)¶
Labels: enhancement, milestone-3-classical
Description¶
After [M3-2] (#330) lands, add Magma as the pattern-setting first concrete classical structure under Classical/. Magma is the right starting structure precisely because its equational theory is empty: this isolates the signature mechanics (operation-symbol naming, arity convention, signature assembly, signature-to-algebra interpretation) from the equation mechanics of subsequent structures. Every signature convention established here propagates to Semigroup (M3-4), Monoid (M3-6), Group (M3-6), Lattice (M3-7), Ring (M3-8).
Per ADR-002 v2 §5, a structure with empty equational theory is encoded as Magma α ρ = Algebra α ρ directly — no Σ-wrapping over a trivial ⊤-typed proof obligation. Subsequent structures with equations follow the Σ[ 𝑨 ∈ Algebra α ρ ] 𝑨 ⊨ Th-X pattern.
This issue is the renumbered analog of the pattern-setting role that the original M3-2 (Semigroup) was meant to play. The original M3-2 conflated signature mechanics with equation mechanics; the v2 ADR splits them out.
Design decisions¶
These are normative for every subsequent structure (Semigroup in M3-4, Monoid + Group in M3-6, Lattice in M3-7, Ring in M3-8). Per ADR-002 v2.
- Signature representation. Named operator via a one-constructor data type:
data Op-Magma : Type where ∙-Op : Op-Magma. Constructor-naming convention<symbol>-Op(hyphen-separated, capital O). Reserves the bare symbol for use-site infix sugar overCurry₂ (∙-Op ^ _). - Arity function.
ar-Magma ∙-Op = Fin 2. Naming convention:ar-<Structure>for the arity function of<Structure>'s signature. - Signature value.
Sig-Magma : Signature lzero lzerodefined asSig-Magma = Op-Magma , ar-Magma. Hyphenated long-form name per ADR-002 v2 §7; the original draft's𝑆ₘₐsubscript form is not adopted. - No theory file. Magma has no equations, so no
src/Classical/Theories/Magma.lagda.mdfile is created. The umbrellaClassical.Theoriesdoes not import a Magma theory. Subsequent structures with theories will introduce their ownTheories/X.lagda.mdfiles. - Σ-typed core absent.
Magma α ρ = Algebra α ρ(after openingSetoid.Algebras {𝑆 = Sig-Magma}). No⊨obligation since the theory is empty. This is the only structure in the hierarchy with this property; from Semigroup onward, structures are Σ-typed. - Named accessors next to the core.
Domain,Carrier,_∙_defined alongsideMagma α ρto offset Σ/record-projection ergonomic cost._∙_ : (𝑴 : Magma α ρ) → Carrier 𝑴 → Carrier 𝑴 → Carrier 𝑴defined as𝑴 ∙ a b = Curry₂ (∙-Op ^ 𝑴) a b. Per ADR-002 v2 §1, this surfaces the operation in user-facing curried form; the tuple-indexed∙-Op ^ 𝑴form lives below the user interface. fromOpshape. Per-structure:fromOp : (A : Type α) (_·_ : A → A → A) → Magma α α. No equation arguments because Magma's theory is empty. Subsequent structures'fromOp-family constructors add an equation argument per equation in their theory.- Morphisms. No per-structure invariant required: a magma morphism is definitionally an algebra homomorphism between the underlying
Algebra Sig-Magma-algebras. Per ADR-002 v2 §5, this applies uniformly across the hierarchy. - Worked-example placement. In sibling
src/Examples/Classical/Magma.lagda.md, paralleling ADR-002 v2 §5's policy.
Tasks¶
Core four-file quintuple (no theory file — see design decisions)¶
-
src/Classical/Signatures/Magma.lagda.md—Op-Magma,ar-Magma,Sig-Magma : Signature lzero lzero. -
src/Classical/Structures/Magma.lagda.md: - the type-alias core
Magma α ρ = Algebra α ρinsideopen Setoid.Algebras {𝑆 = Sig-Magma}, - named accessors
Domain,Carrier,_∙_, - the
fromOphelper. -
src/Classical/Bundles/Magma.lagda.md— record matchingAlgebra.Bundles.Magmafrom stdlib 2.3, conversion functions⟨_⟩ₘₐ,⟪_⟫ₘₐ, pointwise round-trip lemma per ADR-002 v2 §6. -
src/Classical/Small/Structures/Magma.lagda.md— level-fixed veneerMagma = Classical.Structures.Magma.Magma lzero lzero, plus the small-casefromOp.
Worked example¶
-
src/Examples/Classical/Magma.lagda.md—(ℕ, _+_)asClassical.Small.Structures.Magma.Magma, constructed viafromOp. File-header prose flags this as the home of all future magma-specific examples. No further example demands beyond this one for M3-3.
Umbrella updates¶
- Update
src/Classical/Signatures.lagda.mdtoopen import Classical.Signatures.Magma public. - Update
src/Classical/Structures.lagda.mdtoopen import Classical.Structures.Magma public. - Update
src/Classical/Bundles.lagda.mdtoopen import Classical.Bundles.Magma public. - Update
src/Classical/Small/Structures.lagda.mdtoopen import Classical.Small.Structures.Magma public. Create this aggregator if it does not exist. - Update
src/Examples/Classical.lagda.mdtoopen import Examples.Classical.Magma. Create this umbrella if it does not exist.
Documentation¶
- Module-header prose in
Classical/Structures/Magma.lagda.mddocuments the conventions established here normatively, so future structures (Semigroup in M3-4, Monoid in M3-6, …) have a single normative reference for signature mechanics. Explicitly: hyphen-separated<symbol>-Opconstructor convention,ar-<Structure>arity-function convention,Sig-<Structure>signature-value convention,_∙_ = Curry₂ (∙-Op ^ _)user-facing curried-accessor convention,fromOp-family constructor convention. -
CHANGELOG.md[Unreleased] / Addedentry.
Non-goals¶
- No equational theory. Magma's defining feature is the empty theory; structures with equations are M3-4 onward.
- No
Classical/Theories/Magma.lagda.md. The umbrellaClassical.Theoriesremains empty after M3-3 lands; first concrete theory file is Semigroup's in M3-4. - No generic equation builders. Those are M3-2.
- No magma homomorphisms beyond the observation that they are definitionally algebra homomorphisms.
- No free magma, magma varieties as a sub-class of varieties of
Sig-Magma-algebras, presentations, term rewriting. All later. - Additional worked examples beyond
(ℕ, +). TheExamples.Classical.Magmafile is the right home for these as they accumulate.
Acceptance criteria¶
- All new files type-check under
make check. - The worked example
ℕ-magmainExamples.Classical.Magmatype-checks. - The interpretation of
∙-Opinℕ-magmareduces definitionally to_+_— no opacity from thefromOpconstruction or from theCurry₂wrapping. Discharged byrefl. - The bridge to
Algebra.Bundles.Magmaround-trips onℕ-magmapointwise: for alla, b : ℕ, the round-tripped operation applied toa, bequalsa + b. Discharged byreflon the curried form. Pointwise round-trip per ADR-002 v2 §6; not propositional≡on the Σ-type. - Module-header prose in
Classical/Structures/Magma.lagda.mddocuments the design conventions clearly enough that a contributor writingClassical/Structures/Semigroup.lagda.md(M3-4) from scratch could do so without consulting this PR's discussion. - CHANGELOG entry under
[Unreleased] / Added.
References¶
- Parent: [M3-1] #260
- Scaffold predecessor: [M3-1a] #326
- Predecessor: [M3-2] #330
- Successor: [M3-4] Semigroup #261 (first equation-bearing structure consuming this signature pattern).
- Sibling: [M3-5] #262 (stdlib bundle bridges)
- Design: ADR-002 v2 §1, §5, §7, §8.
- Stdlib target for the bundle bridge:
Algebra.Bundles.Magmain standard-library 2.3.
Issue M3-4: Classical.Semigroup (#261, closed)¶
Labels: enhancement, milestone-3-classical
Description¶
After [M3-3] #331 (Magma) lands, add Semigroup as the first concrete classical structure with a non-empty equational theory. Following ADR-002 v2 §5, a semigroup is the Σ-typed structure Semigroup α ρ = Σ[ 𝑨 ∈ Algebra α ρ ] 𝑨 ⊨ Th-Semigroup over the same signature Sig-Magma introduced by Magma — semigroups and magmas share a signature; semigroups are precisely those magmas whose binary operation is associative.
This issue is the reformulated body of #261 (originally M3-2). The original body — which positioned Semigroup as the pattern-setting first structure with per-structure SemigroupVar enums and Σ-typed cores — is superseded by the v2 ADR. The original branch 261-m3-2-classical-semigroup is retained in repository history as evidence of the load test that motivated the v2 revisions.
Design decisions¶
These are normative for every subsequent equation-bearing structure (Monoid in M3-6, Group in M3-6, …) and consume the conventions established in M3-2 (infrastructure) and M3-3 (Magma). Per ADR-002 v2.
- Signature reuse. Semigroup uses the magma signature
Sig-Magmadirectly — there is noSig-Semigroup. Subsequent structures that add operations (Monoid adds an identity element, Group adds an inverse) get their own signature; structures that only add equations over a predecessor's signature reuse the predecessor's signature. - Equational theory representation. Indexed form per
Setoid.Varieties.EquationalLogic.Modᵗ:data Eq-Semigroup : Type where assoc : Eq-Semigroup, withTh-Semigroup : Eq-Semigroup → Term (Fin 3) × Term (Fin 3)mappingassocto the associativity term-pair via the generic builderAssociative ∙-Op refl 0F 1F 2FfromClassical.Equations(introduced in M3-2). (OpenClassical.Equationswith the parameters fixed:open Classical.Equations.??? {𝑆 = Sig-Magma} {X = Fin 3}at the top ofClassical/Theories/Semigroup.lagda.md.) - Variable carrier
Fin 3. Per ADR-002 v2 §2. No per-structureSemigroupVar-style enum. Variable patterns at use sites are0F,1F,2FfromData.Fin.Patterns. - Σ-typed core.
Semigroup α ρ = Σ[ 𝑨 ∈ Algebra α ρ ] Modᵗ Th-Semigroup 𝑨insideopen Setoid.Algebras {𝑆 = Sig-Magma}. Local_⊨_alias forModᵗ Th-Semigroupis permitted but should spell out the codomain type explicitly to avoid the meta-resolution pitfall identified in the original M3-2 load test ((Eq-Semigroup → Term (Fin 3) × Term (Fin 3)), not_— the underscore lets Agda's unifier wander into the equational-logic substrate and the resulting error message points atModᵗrather than at the alias). - Named accessors in a
Semigroup-Opmodule. Following the [M3-3] precedent (whereMagma-Ophouses magma's named accessors so thatopen Magma-Op 𝑴bringsa ∙ binto scope at the use site),Semigroup-Op {α ρ} (𝑺 : Semigroup α ρ)is a named parametric module exposing_∙_, andequations. The first is re-exported through the forgetful functor viaopen Magma-Op (semigroup→magma 𝑺) public using (_∙_). This pattern — each<Structure>-Opmodule additively re-exports its predecessor's<Weaker>-Opaccessors through the forgetful projection — is the normative inheritance idiom for the whole hierarchy; subsequentMonoid-Op,Group-Op,Lattice-Op,Ring-Opfollow the same template.equations : Modᵗ Th-Semigroup (semigroup→magma 𝑺)is the new addition exposing the satisfaction proof.DomainandCarrierare not placed inSemigroup-Op; they remain accessible through the foundation's blackboard-bold accessors𝔻[ semigroup→magma 𝑺 ]and𝕌[ semigroup→magma 𝑺 ], which makes name clashes with stdlib bundle fields less likely. fromPropEqshape. Per-structure:fromPropEq : (A : Type α) (_·_ : A → A → A) (·-assoc : ∀ a b c → (a · b) · c ≡ a · (b · c)) → Semigroup α α. Pull-up to a shared location deferred until Monoid (M3-6) confirms the shape generalizes — premature shared abstraction is the failure mode #326's non-goals warn against.fromPropEqfactors throughfromOp.fromPropEq A _·_ ·-assoc = fromOp A _·_ , <Th-Semigroup proof>, reusing M3-3'sfromOprather than rebuilding the underlying algebra. This makes the forgetful acceptance criterion discharge byrefland is the normative shape for every subsequentfromPropEq-family constructor (Monoid's factors through Semigroup's, etc.).semigroup→magmaforgetful.semigroup→magma : Semigroup α ρ → Magma α ρdefined alongside the Σ-typed core, simplyproj₁. Per ADR-002 v2 §5, forgetful projections are how the "a semigroup is a magma" inheritance manifests; subsequent structures define analogous forgetfuls (monoid→semigroup,group→monoid, etc.).- Bundle bridge. Bidirectional
⟨_⟩ˢᵍ/⟪_⟫ˢᵍtoAlgebra.Bundles.Semigroupfrom stdlib 2.3, with a pointwise round-trip lemma per ADR-002 v2 §6. The Fin 2 η-bridge is contained inCurry₂/Uncurry₂fromClassical.Operations; per-structure bridge files do not write inlinepair-style wrappers. The superscript subscript-mnemonicˢᵍreplaces theₛₘform of the original draft; the analogous Magma bridge is renamed⟨_⟩ᵐᵃ/⟪_⟫ᵐᵃ(fromₘₐ) for hierarchy-wide uniformity, since the natural "sg" mnemonic for Semigroup has no subscript-g. - Worked-example placement.
src/Examples/Classical/Semigroup.lagda.md, alongside the Magma example from M3-3.
Tasks¶
Core four-file quintuple¶
-
src/Classical/Theories/Semigroup.lagda.md—Eq-Semigroup,Th-Semigroup(composesAssociative ∙-Op refl 0F 1F 2F). -
src/Classical/Structures/Semigroup.lagda.md: - the Σ-typed core,
- the
semigroup→magmaforgetful projection, - the
Semigroup-Opnamed accessor module exposing_∙_(via the forgetful) andequations, - the
fromPropEqhelper. -
src/Classical/Bundles/Semigroup.lagda.md— bidirectional bridge toAlgebra.Bundles.Semigroupwith pointwise round-trip. -
src/Classical/Small/Structures/Semigroup.lagda.md— level-fixed veneer.
Worked example¶
-
src/Examples/Classical/Semigroup.lagda.md—(ℕ, +)as aClassical.Small.Structures.Semigroup.Semigroup, constructed viafromPropEqfrom stdlib's+-assoc.
Umbrella updates¶
- Update
src/Classical/Theories.lagda.mdtoopen import Classical.Theories.Semigroup public. First concrete theory module. - Update
src/Classical/Structures.lagda.mdtoopen import Classical.Structures.Semigroup public. - Update
src/Classical/Bundles.lagda.mdtoopen import Classical.Bundles.Semigroup public. - Update
src/Classical/Small/Structures.lagda.mdtoopen import Classical.Small.Structures.Semigroup public. - Update
src/Examples/Classical.lagda.mdtoopen import Examples.Classical.Semigroup.
Documentation¶
- Module-header prose in
Classical/Structures/Semigroup.lagda.mddocuments the equation-bearing-structure conventions established here normatively, complementing the signature-mechanics prose inClassical/Structures/Magma.lagda.mdfrom M3-3. -
CHANGELOG.md[Unreleased] / Addedentry.
Non-goals¶
- Pull-up of
fromPropEqto a shared location. Deferred until at least Monoid (M3-6) confirms the shape generalizes. - Pull-up of named accessors and forgetful projections to a shared location. Same policy.
- Generic bundle-bridge infrastructure beyond the per-structure conversion functions. M3-5.
- Semigroup homomorphisms beyond
semigroup→magma-via-Setoid.Homomorphisms. Per ADR-002 v2 §5. - Free semigroups, semigroup varieties as a sub-class of varieties of
Sig-Magma-algebras, presentations, term rewriting, decidability of the word problem. All later. - Additional worked examples beyond
(ℕ, +).
Acceptance criteria¶
- All new files type-check under
make check. - The worked example
ℕ-semigrouptype-checks. - The interpretation of
∙-Opinℕ-semigroupreduces definitionally to_+_. Discharged byreflon the curried form. - The bridge to
Algebra.Bundles.Semigroupround-trips onℕ-semigrouppointwise. Discharged byreflon the curried form per ADR-002 v2 §6. - The forgetful
semigroup→magma (ℕ-semigroup)equalsℕ-magma(from M3-3) propositionally. Discharged byrefl. This holds becausefromPropEqis implemented as(fromOp A _·_) , <proof of Th-Semigroup>, factoring the underlying-algebra construction through M3-3'sfromOpso thatsemigroup→magma ∘ fromPropEq A _·_ _ ≡ fromOp A _·_definitionally. - Module-header prose in
Classical/Structures/Semigroup.lagda.mddocuments the equation-bearing-structure conventions normatively. - CHANGELOG entry under
[Unreleased] / Added.
References¶
- Parent: [M3-1] #260.
- Scaffold predecessor: [M3-1a] #326.
- Predecessors: [M3-2] (infrastructure) #330, [M3-3] (Magma) #331.
- Sibling: [M3-5] (stdlib bundle bridges) #262.
- Design: ADR-002 v2 §2, §3, §4, §5, §6.
- Empirical motivation: the original #261 branch
261-m3-2-classical-semigroup, whose Σ-typed-with-SemigroupVardesign surfaced the issues that the v2 ADR addresses. - Equational-logic substrate:
src/Setoid/Varieties/EquationalLogic.lagda.md(Modᵗ). - Equation builder:
Associativeinsrc/Classical/Equations.lagda.md([M3-2]). - Stdlib target for the bundle bridge:
Algebra.Bundles.Semigroupin standard-library 2.3.
Issue M3-5: Bridges between Classical.Structures and Algebra.Bundles (#262, closed)¶
Labels: milestone-3-classical, stdlib-bridge
v3 amendment (2026-05-21)¶
Following the M3-4 precedent (Magma and Semigroup bridges landed inside #331 and #261), the Monoid, CommutativeMonoid, Group, and AbelianGroup bundle bridges move into [M3-6] #263 alongside their structures. The bridge is a thin record-shuffle once each -Op module exposes its laws in curried form, so it belongs in the same PR as the structure that produces those laws.
Applying that rule uniformly, every remaining bundle bridge lands with its owning structure issue. This issue is consequently reduced to a tracking issue: it records the cross-cutting round-trip policy and the per-structure ownership map, and holds no implementation tasks of its own.
Round-trip policy (normative, applies to every bridge)¶
The pointwise round-trip policy from ADR-002 v2 §6 applies uniformly. No per-structure bundle bridge claims a propositional Σ-equality round-trip; the round-trip is stated pointwise on the carrier in the structure's underlying setoid equivalence. Each bridge ships a roundtrip- lemma to that effect, and a stdlib concrete instance round-trips through the bridge in the owning issue's worked example.
Bridge ownership map¶
- Magma →
Algebra.Bundles.Magma— landed in [M3-3] #331. - Semigroup →
Algebra.Bundles.Semigroup— landed in [M3-4] #261. - CommutativeSemigroup →
Algebra.Bundles.CommutativeSemigroup— UNASSIGNED; fold into [M3-6] #263. - Monoid, CommutativeMonoid, Group, AbelianGroup →
Algebra.Bundles.{Monoid,CommutativeMonoid,Group,AbelianGroup}— [M3-6] #263. - Semilattice, Lattice →
Algebra.Bundles/Algebra.Lattice.Bundles— [M3-7] #264. Lattice bridges to bothAlgebra.Bundles.LatticeandAlgebra.Lattice.Bundles.Lattice. - ~~Semiring~~, Ring, CommutativeRing →
Algebra.Bundles.{~~Semiring~~,Ring,CommutativeRing}— [M3-8] #265. (~~Semiring~~ was never in M3-8's scope and was not implemented; deferred to a later milestone. Ring and CommutativeRing landed in #265.)
Acceptance criteria¶
- This issue carries no code. Each bridge's type-checking and round-trip acceptance is owned by the structure issue listed above.
- The round-trip policy text above is mirrored in ADR-002 v2 §6 so the policy survives even if this tracker is later closed.
Issue M3-6: Classical structures — Monoid, CommutativeMonoid, Group, AbelianGroup (#263, closed)¶
Labels: milestone-3-classical, help-wanted
v2 amendment (2026-05-17)¶
Renumbered [M3-4] → [M3-6] following revision of ADR-002 v2.
Scope adjustment per ADR-002 v2 §5: each structure is self-contained over its own signature, with forgetful projections for inheritance. Concretely:
Sig-Monoidadds a nullary identity-element symbolε-Op(arityFin 0) toSig-Magma.Th-Monoidincludesassoc,id-l,id-r. Forgetfulmonoid→semigroup.Sig-Groupadds a unary inverse symbol⁻¹-Op(arityFin 1) toSig-Monoid.Th-Groupincludesassoc,id-l,id-r,inv-l,inv-r. Forgetfulgroup→monoid(composes downward togroup→semigroup,group→magma).Sig-CommutativeMonoidandSig-AbelianGroupreuseSig-MonoidandSig-Grouprespectively; the only addition iscommto the theory.
All equations come from the generic builders in Classical.Equations [M3-2]. Distinguished elements (the identity, the inverse) are nullary/unary operation symbols of the signature, per ADR-002 v2 §9.
Description¶
Follow the pattern established in [M3-3]/[M3-4] to add the monoid-and-group family, with corresponding signatures, theories, bundle views, and level-fixed veneers.
Tasks¶
-
Classical/Structures/Monoid.lagda.md. -
Classical/Structures/CommutativeMonoid.lagda.md. -
Classical/Structures/CommutativeSemigroup.lagda.md. -
Classical/Structures/Group.lagda.md. -
Classical/Structures/AbelianGroup.lagda.md. - Corresponding signatures, theories, bundles (per [M3-3]), Small veneers.
- Worked examples:
(ℕ, +, 0)as CommutativeMonoid;(ℤ, +, 0, -)as AbelianGroup.
Acceptance criteria¶
- All four structures type-check and round-trip through their bundles.
- Worked examples type-check.
Issue M3-7: Classical.Semilattice and Classical.Lattice (#264, closed)¶
Labels: milestone-3-classical
v2 amendment (2026-05-17)¶
Renumbered M3-5 → M3-7 following revision of ADR-002 v2.
Scope is unchanged. Conventions inherit from M3-2 / M3-3 / M3-4: hyphen-separated ∧-Op, ∨-Op constructors; Sig-Semilattice and Sig-Lattice signatures; equations composed from Associative, Commutative, Idempotent, Absorbs builders in Classical.Equations.
The "two binary ops" vs "one binary op with the other defined" representational question for Lattice — flagged in the original issue — is settled in favor of two binary operation symbols (∧-Op and ∨-Op), consistent with the signature-extension policy: each operation that participates in the variety's equations gets its own signature symbol.
Description¶
Lattices are centrally important because Con 𝑨 and Sub 𝑨 are naturally lattices, and the Finite Lattice Representation Problem (M6) is stated in terms of lattices.
Tasks¶
-
Classical/Signatures/Lattice.agda: two binary operations (∧,∨) or one (meet), depending on formulation. -
Classical/Theories/Lattice.agda: associativity, commutativity, idempotence, absorption. -
Classical/Structures/Semilattice.agda. -
Classical/Structures/Lattice.agda. - Bridge to
Algebra.Lattice.Bundles. - Prove equivalence of algebraic (meet-join) and order-theoretic formulations.
Acceptance criteria¶
- Both structures type-check.
- The meet-join / order-theoretic equivalence theorem is proved.
- Bridge to stdlib round-trips on
𝟚as a Boolean lattice.
Issue M3-8: Classical.Ring and Classical.CommutativeRing (#265, closed)¶
Labels: milestone-3-classical, help-wanted
v2 amendment (2026-05-17)¶
Renumbered M3-6 → M3-8 following this revision of the ADR-002 v2 document.
Scope is unchanged. Conventions inherit from M3-6 (Monoid/Group/AbelianGroup) and from M3-7 (the precedent for multiple binary operations in one signature).
Sig-Ring has signature symbols +-Op (binary), 0-Op (nullary, the additive identity), -Op (unary, the additive inverse), ·-Op (binary), 1-Op (nullary, the multiplicative identity). Th-Ring composes the abelian-group equations on (+-Op, 0-Op, -Op), the monoid equations on (·-Op, 1-Op), and the distributivity equations from DistributesOverˡ/DistributesOverʳ. Forgetful ring→abelianGroup (additive structure) and an additional forgetful ring→monoid (multiplicative structure) defined alongside the core.
Description¶
Rings depend on AbelianGroup for the additive structure, so this issue comes after M3-4.
Tasks¶
-
Classical/Signatures/Ring.agda. -
Classical/Theories/Ring.agda. -
Classical/Structures/Ring.agda. -
Classical/Structures/CommutativeRing.agda. - Bridge to stdlib.
- Worked example:
(ℤ, +, *, 0, 1, -)as CommutativeRing.
Acceptance criteria¶
- Both structures type-check.
- The worked example
ℤ-ringtype-checks. - Bridge to stdlib
CommutativeRinground-trips onℤ.
Issue M3-9: Expand Examples/ with worked classical-structure instances (#266, closed)¶
Labels: documentation, milestone-3-classical
v2 amendment (2026-05-17)¶
Renumbered M3-7 → M3-9 following revision of ADR-002 v2.
Scope is unchanged. Per-structure worked examples land with their structure issues (M3-3 ships ℕ-magma; M3-4 ships ℕ-semigroup; M3-6 ships ℕ-monoid and ℤ-group; etc.). This issue is therefore reduced to cross-structure and richer examples: free magmas, free semigroups, term-rewriting demonstrations, presentations, finite-quotient examples for use as Demos/ companion material, etc.
The reduction in scope reflects the M3-3-onward convention that one canonical worked example per structure ships with the structure itself; this issue exists for the additional examples that wouldn't fit cleanly in any one structure's file.
Description¶
The Examples/ directory is thin. Add worked examples that exercise the Classical/ layer.
Tasks¶
Update (20260531)¶
Missed ask. We forgot to address the following: "Richer examples: free magmas, free semigroups, term-rewriting demonstrations, presentations, finite-quotient examples for use as Demos/ companion material, etc." Let's reopen and add these in a new PR attached to this issue.
-
(ℕ, +, 0)as aCommutativeMonoid, with HSP specialized to it. -
(ℤ, +, 0, -)as anAbelianGroup. -
𝟚with two operations as aDistributiveLattice. - A small finite group (
ℤ/3ℤ) with its congruence lattice computed. - A finite Heyting algebra as a Lattice example.
- An example of a nonabelian group. (I believe the only example of the
Grouptype inExamples.Classicalis the integers. We should add an example of a nonabelian group that does not happen to be abelian as well.) - An example of a "commutative idempotent binar" (that is, a magma with an idempotent commutative binary operation); the operation should be defined by its Cayley table. (I'm not sure how to implement a Cayley table to describe an operation in Agda yet, so this task will be an excellent opportunity for us to figure out the best way to do that.)
Acceptance criteria¶
- At least five new example files in
Examples/Classical/. - Each example type-checks and is documented in a prose header.
Milestone 3 Dependencies¶
The pattern-setters are M3-2 (infrastructure), M3-3 (no-equation pattern), M3-4 (one-equation pattern) — the design choices made there propagate to every other structure. M3-6 (Monoid/Group) and M3-7 (Lattice) are the mid-level hubs; M3-8 (Ring) needs M3-6 because rings are abelian groups with extra structure, and M3-9 (Examples) aggregates from several of the structure issues.
graph TD
M2_1["M2-1: Freeze Base"]:::ext
M2_6["M2-6: Extract Setoid foundations"]:::ext
M3_1["M3-1: Classical/ scaffold"]
M3_2["M3-2: Operations + Equations infra"]
M3_3["M3-3: Magma (no-equation pattern)"]
M3_4["M3-4: Semigroup (one-equation pattern)"]
M3_5["M3-5: Stdlib bridges (continued)"]
M3_6["M3-6: Monoid / Group"]
M3_7["M3-7: Lattice"]
M3_8["M3-8: Ring"]
M3_9["M3-9: Examples"]
M2_1 --> M3_1
M2_6 --> M3_1
M3_1 --> M3_2
M3_2 --> M3_3
M3_3 --> M3_4
M3_4 --> M3_5
M3_4 --> M3_6
M3_5 --> M3_7
M3_6 --> M3_7
M3_6 --> M3_8
M3_4 --> M3_9
M3_6 --> M3_9
M3_7 --> M3_9
classDef ext fill:#f0f0f0,stroke:#999,stroke-dasharray: 4 3,color:#555
---¶
Milestone 4 — Style and naming uniformity sweep¶
Issue M4-1: Mechanical style & notation sweep (umbrella) (#267, closed)¶
Labels: documentation, milestone-4-style
Description¶
Umbrella for the mechanical half of Milestone 4: bring the live trees (Overture/, Setoid/, Classical/, Demos/, Examples/) into docs/STYLE_GUIDE.md conformance for everything that changes compiled code — notation and imports — and reconcile the guide with itself. All prose work (rich module headers, per-definition docstrings, anchor removal) is tracked under M4-2 (#268) and its per-subtree children.
The naming audit is already discharged. grep -rnE 'is-homomorphism|\bHom\b' src/Setoid/ is empty; the only is-hom/is-epi hits are descriptive lemma names (⊙-is-hom, lift-of-epi-is-epi, hom𝔽[_]-is-epic), not synonyms of the IsHom/IsEpi predicates. The Setoid public API is already on IsHom/hom, IsMon/mon, IsEpi/epi. What remains is notation, imports, and the guide.
Children¶
-
367¶
-
368¶
-
369¶
-
370¶
-
372¶
-
384 —
fst/snd→proj₁/proj₂, split out of #367 task 4 (the rename turned out to be a deliberate library-wide convention across ~17 modules, not a dead rename).¶
Residual import hygiene rides along with #368/#369 (which rewrite every import block touching projections/interpretation) and the M4-2 per-subtree PRs; no separate issue.
Exit criterion¶
- All sub-issues closed.
-
make checkpasses;EverythingLegacy.agdastill compiles (warnings fromLegacy/expected). -
grep -rE 'is-homomorphism|\bHom\b' src/Setoid/ src/Classical/is empty. - The Projections and Interpretation tables in
docs/STYLE_GUIDE.mdmatch the live trees.
Issue M4-1a: Migrate ∣_∣ / ∥_∥ → proj₁ / proj₂ (#367, closed)¶
Labels:
Description¶
Remove the bracket projections from the live trees. Generic Σ-projections become stdlib proj₁ / proj₂; signature components become the existing OperationSymbolsOf / ArityOf from Overture.Signatures (already canonical in Classical/). The ∣_∣ / ∥_∥ definitions stay in Overture.Basic with WARNING_ON_USAGE so Legacy/Base/ still compiles. Mechanical but verified by recompilation — execute in Claude Code.
Tasks¶
-
Overture.Basic: decouple∥_∥'s type from∣_∣; addWARNING_ON_USAGEto both. -
Overture.Signatures: rewriteOperationSymbolsOf/ArityOfto useproj₁/proj₂; drop theOverture.Basicbracket import; fix the staleBase.Functionsreference and the per-tree prose. - Sweep all non-
Legacy/callsites:∣ 𝑆 ∣→OperationSymbolsOf 𝑆,∥ 𝑆 ∥→ArityOf 𝑆, all other∣ e ∣/∥ e ∥→proj₁ e/proj₂ e(code fences and inline prose). - Per-file import surgery; collapse the dead
proj₁ to fst ; proj₂ to sndrename inSetoid/Homomorphisms/Properties. - Amend ADR-002 §1 (the unified policy) — or fold into #CCC.
-
make check.
Acceptance criteria¶
-
rg '∣' src --glob '!src/Legacy/**'matches only the∣_∣/∥_∥definitions inOverture.Basic. -
make checkpasses;Legacy/compiles.
Issue M4-1b: Complete the _̂_ → _^_ migration (#368, closed)¶
Labels:
Description¶
_̂_ was deprecated in v3.0 in favour of the ASCII _^_, with a WARNING_ON_USAGE pragma already at the definition site in Setoid.Algebras.Basic (ADR-002 §7). The callsite migration is partial: Setoid.Algebras.Products is on _^_, but Setoid.Algebras.Congruences still imports and uses _̂_ and trips the warning. Finish it across the live trees.
Tasks¶
- Rewrite every non-
Legacy/_̂_callsite and import to_^_(code fences and inline prose). - Update the
### Interpretationtable indocs/STYLE_GUIDE.md(folds into #CCC if landing together). -
make checkwith no_̂_deprecation warnings outsideLegacy/.
Acceptance criteria¶
-
grep -rn '̂' src/ | grep -v src/Legacy/matches only the_̂_definition/deprecation inSetoid.Algebras.Basicand insrc/Demos/HSP.lagda.md; (the latter is frozen for historical continuity since it's cited in the Birkhoff HSP paper). -
make checkpasses.
Issue M4-1c: Reconcile docs/STYLE_GUIDE.md self-contradictions (#369, closed)¶
Labels:
Description¶
The guide contradicts itself in three places; its own meta-rule makes each an M4-1 bug.
+ Docstring form: the "prose comment block" example uses -- | inside a fence, which "Prose belongs in Markdown" forbids. Rewrite to Markdown-prose-before-fence.
+ Hom vs hom: the same example defines a capital Hom, the synonym the Naming section deprecates. Use lowercase hom.
+ Tables: update Projections to reflect #367 and Interpretation to reflect #368.
Tasks¶
- Apply the three edits (drafted in the PR thread).
- Verify no remaining
-- |-style docstring examples in the guide. - Amend ADR-002 §1 and
Overture.Signaturesprose to the unified projection policy; fix the staleBase.Functionscross-reference.
Acceptance criteria¶
- The guide's examples use lowercase
hom,_^_, and Markdown-prose docstrings. - Projections and Interpretation tables match the post-migration trees.
Issue M4-1d: Repo-wide style-guide violation audit (#370, closed)¶
Labels:
Description¶
A scripted sweep of the live trees for STYLE_GUIDE.md violations, producing a checklist that feeds the migration PRs and the M4-2 per-subtree PRs. Run in Claude Code.
Tasks¶
- Notation: residual
∣_∣/∥_∥/_̂_outsideLegacy/. - Imports: bare
open importwithoutusing; cosmeticrenaming; non-alphabetical groups. - Headers: modules whose header is only YAML + the one-line "This is the … module" (feeds M4-2).
- Anchors:
<a id=…>occurrences (feeds M4-1g; ≈ 90 acrossSetoid/). - Naming: any
is-xpredicate forms or synonym pairs (expected: none inSetoid/). - Emit
docs/audits/M4-style-audit.mdwith per-file findings.
Acceptance criteria¶
- Audit committed; every finding fixed or linked to a child PR.
Issue M4-1e: Normalize code-fence whitespace (#372, closed)¶
Labels:
Description¶
The .lagda→.lagda.md migration script left blank lines between the ```agda opener and the first line of code in many blocks. Collapse them so the first code line is adjacent. Live trees only; Legacy/ stays frozen. Pure whitespace, semantically null for both Agda and Markdown.
Tasks¶
-
perl -0pi -e 's/```agda\n\n+/```agda\n/g'acrosssrc/excludingsrc/Legacy/. -
make check.
Acceptance criteria¶
-
rg -U '```agda\n\n' src --glob '!src/Legacy/**'is empty.
Issue M4-1f: Unify fst / snd → proj₁ / proj₂ (#384, closed)¶
Labels:
Description¶
Split out of #367 task 4. That task asked to "collapse the dead proj₁ to fst ; proj₂ to snd rename in Setoid.Homomorphisms.Properties", but the rename is not dead: fst / snd is a deliberate short-hand for proj₁ / proj₂ used across ~17 live modules. Unifying it on the canonical proj₁ / proj₂ (per the STYLE_GUIDE "one canonical form per concept" rule) is therefore its own mechanical sweep, separate from the bracket-projection migration (#367), which is now complete.
Scope¶
The renaming ( proj₁ to fst ; proj₂ to snd ) idiom (or a one-sided variant) appears in:
Overture/Relations,Overture/Functions,Overture/Adjunction/Galois;Setoid/Functions/{Inverses, Surjective};Setoid/Homomorphisms/{HomomorphicImages, Noether, Properties, Factor};Setoid/Subalgebras/{Properties, Subalgebras};Setoid/Varieties/{FreeAlgebras, SoundAndComplete, Preservation, HSP, EquationalLogic}.
Demos/HSP also uses it; consistent with the #367 / #368 decisions, the self-contained demo is exempt by default.
Tasks¶
- Drop the
proj₁ to fst/proj₂ to sndrenames from eachData.Productimport. After #367,proj₁/proj₂are re-exported by theOvertureumbrella, so most modules can drop theData.Productprojection import entirely rather than re-add a plain one. - Rewrite
fst→proj₁andsnd→proj₂at every callsite. - Gotcha: identifiers such as
Lift-hom-fst/Lift-hom-snd(definition names inSetoid.Homomorphisms.Properties) and any other…fst/…snd-suffixed names must not be rewritten. A blinds/\bfst\b/proj₁/corrupts them, since\bmatches inside a hyphenated name. -
make check.
Acceptance criteria¶
-
grep -rn 'proj₁ to fst\|proj₂ to snd' srcmatches onlysrc/Legacy/**(andsrc/Demos/HSP.lagda.mdif exempted). -
make checkpasses;Legacy/compiles.
Part of the M4-1 umbrella (#267).
Issue M4-1g: Remove HTML heading anchors (rely on kramdown auto-slugs) (#387, closed)¶
Labels:
Description¶
Split out of the M4 style audit (docs/audits/M4-style-audit.md, finding 4). The docs/STYLE_GUIDE.md § Section headings rule says headings should be plain ATX, not wrapped in <a id="…">…</a>; the renderer (Jekyll + kramdown) auto-generates a slug id from each heading. The audit found ~300 such anchors across 111 files. Pursue per-subtree, starting with Setoid/ (~93 anchors / 43 files).
Algorithm (per anchor <level> <a id="TAG">TEXT</a>)¶
- Compute
slug = kramdown_generate_id(TEXT). - If
slug == TAG: drop the wrapper →<level> TEXT(the auto-slug reproduces the same id, so any#TAGlink still resolves). - If
slug ≠ TAG: check whetherTAGis used as a cross-reference (#TAGin a link, anywhere insrc/+docs/). - If not referenced: drop the wrapper →
<level> TEXT. - If referenced: keep the id explicitly via the kramdown attribute-list form →
<level> TEXT {#TAG}.
This guarantees no cross-reference breaks while removing the HTML wrappers.
Notes¶
- Cross-references are scanned repo-wide (a
Setoid/anchor can be linked fromOverture/, the paper, etc. — e.g.proof-of-the-hsp-theoremis linked fromOverture.Preface). src/Legacy/**is frozen and excluded from rewriting (but still scanned for references).- Anchor changes are pure prose (outside
agdafences);make checkis unaffected but is run as the gate.
Acceptance criteria¶
-
rg -n '<a id=' src/Setoidis empty (after theSetoid/PR; further subtrees follow). - No cross-reference
#TAGis left dangling. -
make checkpasses.
Part of Milestone 4 (style and naming uniformity sweep); see also the umbrella #267 and the audit #370.
Issue M4-2: Docstring pass for all user-facing definitions (#268)¶
Labels: documentation, milestone-4-style, help-wanted
Description¶
Every record, type family, and top-level function in the public API should have a prose comment block explaining what it is, when to use it, and cross-references to related definitions. Long-tail task; pursued as the per-subtree sub-issues below.
Where it stands¶
Measured by make docstrings (#537) over the live trees: 3226 public definitions in 307 modules, of which 201 sit under a fence carrying no real prose, and 50 modules open with nothing beyond the boilerplate "This is the [X][] module of the …" sentence.
make docstrings is a ratchet pinned at DOCSTRING_MAX_GAPS (201) and DOCSTRING_MAX_WEAK_HEADERS (50), so both counts can only fall. The policy and its reasoning are recorded in ADR-010. Each sub-issue lowers it.
Tasks¶
- #539 — Setoid/Algebras and Setoid/Homomorphisms (25 gaps, 10 headers)
- #540 — Setoid/Subalgebras (23, 5)
- #541 — Setoid/Varieties, Congruences, Terms, Categories (11, 9)
- #542 — Setoid/Functions, Setoid/Relations, Setoid barrels (6, 5)
- #543 — Classical/Structures, root and Lattice (34, 1)
- #544 — Classical/Structures/Group (31, 1)
- #545 — Classical/Bundles, Signatures, rest of Classical (37, 1)
- #546 — Examples (30, 8)
- #547 — Overture, FLRP, Exercises, top-level barrels (4, 10)
Done: #537 (the audit tool, the baseline, the CI ratchet) · #538 (exemplar: Setoid.Algebras.Basic) · #387 (the <a id> anchor sweep).
Acceptance criteria¶
-
make docstringsreports 0 definitions without a prose block, withDOCSTRING_MAX_GAPSat 0. - No module opens with only the boilerplate sentence.
The original criterion said a "grep-based audit". A grep cannot do this — the corpus has no -- | docstrings, prose lives in Markdown outside the fences, and almost every definition is indented inside an anonymous module _ … where. scripts/python/docstring_audit.py parses literate structure and Agda's layout rule instead; it is validated against Agda's own scope checker.
The bar (decided)¶
Settled in ADR-010, and reflected in docs/STYLE_GUIDE.md:
- The bar is per code fence. Every fence is preceded by a real paragraph, and every module opens with prose beyond the boilerplate sentence. 201 definitions and 50 module headers to clear;
make docstringsenforces both, ratcheted. - One definition per fence is rejected as a repository-wide rule. It would enforce layout rather than content — 1952 paragraphs each restating a type signature would satisfy it — and it fragments pages that are meant to read as an exposition of universal algebra.
--strictstays in the tool as a diagnostic for sizing, never as a gate. - A block covering several definitions should name each of them, so a reader, and the corpus extractor of #275, can tell which sentence belongs to which definition. Reported as the
namedcolumn (19% today); tracked, deliberately not gated.
Conventions for a docstring PR¶
Every sub-issue follows these; they are recorded once here rather than repeated nine times.
- The rule is
docs/STYLE_GUIDE.md§ "Every public definition has a prose comment block" and § "Module headers have comment blocks". Prose is Markdown before the code fence, never-- |inside it. A comment that only restates the type signature fails the bar. - The tool:
make docstrings-listnames every gap;python3 scripts/python/docstring_audit.py <path> --list --exit-zeroscopes it to a subtree;--strictshows the other reading. - The exemplar is #538. Copy its shape: what the definition is mathematically, when a reader reaches for it, two or three cross-references.
- Module headers: keep the
This is the [X][] module of the …line and add paragraphs after it, asSetoid.Terms.MonadandClassical.Structures.Lattice.OrdinalSumdo. - Ground the prose or mark it TODO. Write only what is supported by the definition itself, by prose the library already contains, or by a source actually read. Where the mathematics needs the author, leave
<!-- TODO(#268): … -->saying what would be needed. In the PR, name the paragraphs that are the agent's and the ones it is least sure of. A short list of "I could not write this one, and here is why" is a better deliverable than plausible-sounding filler. - Cross-references are reference-style (
[Setoid.Algebras.Products][]); the label must already exist indocs/_links.mdormake check-linksfails. - Style:
+bullets, two spaces after a sentence-ending period, one paragraph per source line, kramdown attribute spans for Agda names. Do not reflow pre-existing wrapped paragraphs. - Verify, do not assert: the Agda extracted from the fences must be byte-identical to
masterfor every file touched; type-check each modified module;make check-linksandmake docstringsgreen. If a prose edit changes compiled code, something is wrong. - Out of scope:
src/Legacy/**, any change to Agda code, reformatting, and editingdocs/STYLE_GUIDE.md.
Issue M4-2a: Docstrings: Setoid/Algebras and Setoid/Homomorphisms (#539, closed)¶
Labels: documentation, milestone-4-style, help-wanted
Scope¶
src/Setoid/Algebras/ src/Setoid/Homomorphisms/
The heart of the Setoid tree and the first thing a new reader meets. Setoid.Algebras.Basic is already done by #538 and is the pattern to follow.
| measure | count |
|---|---|
| modules | 14 |
| public definitions | 116 |
| definitions with no prose on their fence | 25 |
| modules with a boilerplate-only or heading-only header | 10 |
Sized for one PR.
Done when¶
python3 scripts/python/docstring_audit.py src/Setoid/Algebras/ --exit-zeroreports 0 gaps in scope.- Every module in scope opens with prose beyond the boilerplate sentence.
DOCSTRING_MAX_GAPSin theMakefileis lowered by the number cleared.
How¶
Conventions, tooling, grounding discipline and the verification checklist are in #268 — read that first; they are not repeated here. Exemplar: #538.
The bar is per code fence, settled in ADR-010: every fence carries a real paragraph, and every module opens with more than the boilerplate sentence. One definition per fence was considered and rejected, so the
--strictfigure for this subtree (73) sizes a road not taken and is not a backlog.
Sub-issue of #268. Tooling: #537.
Issue M4-2b: Docstrings: Setoid/Subalgebras (#540, closed)¶
Labels: documentation, milestone-4-style, help-wanted
Scope¶
src/Setoid/Subalgebras/
Self-contained and gap-dense: subuniverses, generation, subdirect products. A good second subtree, once the convention from #538 has settled.
| measure | count |
|---|---|
| modules | 10 |
| public definitions | 144 |
| definitions with no prose on their fence | 23 |
| modules with a boilerplate-only or heading-only header | 5 |
Sized for one PR.
Done when¶
python3 scripts/python/docstring_audit.py src/Setoid/Subalgebras/ --exit-zeroreports 0 gaps in scope.- Every module in scope opens with prose beyond the boilerplate sentence.
DOCSTRING_MAX_GAPSin theMakefileis lowered by the number cleared.
How¶
Conventions, tooling, grounding discipline and the verification checklist are in #268 — read that first; they are not repeated here. Exemplar: #538.
The bar is per code fence, settled in ADR-010: every fence carries a real paragraph, and every module opens with more than the boilerplate sentence. One definition per fence was considered and rejected, so the
--strictfigure for this subtree (99) sizes a road not taken and is not a backlog.
Sub-issue of #268. Tooling: #537.
Issue M4-2c: Docstrings: Setoid/Varieties, Congruences, Terms, Categories (#541)¶
Labels: documentation, milestone-4-style, help-wanted
Scope¶
src/Setoid/Varieties/ src/Setoid/Congruences/ src/Setoid/Terms/ src/Setoid/Categories/
Few gaps for their size, because the HSP-adjacent modules already carry good prose. Mostly header work plus a scattering of undocumented fences. Examples/Demos/HSP.lagda.md is a rich source of grounded prose for the Varieties material.
| measure | count |
|---|---|
| modules | 53 |
| public definitions | 632 |
| definitions with no prose on their fence | 11 |
| modules with a boilerplate-only or heading-only header | 9 |
Sized for one PR.
Done when¶
python3 scripts/python/docstring_audit.py src/Setoid/Varieties/ --exit-zeroreports 0 gaps in scope.- Every module in scope opens with prose beyond the boilerplate sentence.
DOCSTRING_MAX_GAPSin theMakefileis lowered by the number cleared.
How¶
Conventions, tooling, grounding discipline and the verification checklist are in #268 — read that first; they are not repeated here. Exemplar: #538.
The bar is per code fence, settled in ADR-010: every fence carries a real paragraph, and every module opens with more than the boilerplate sentence. One definition per fence was considered and rejected, so the
--strictfigure for this subtree (370) sizes a road not taken and is not a backlog.
Sub-issue of #268. Tooling: #537.
Issue M4-2d: Docstrings: Setoid/Functions, Setoid/Relations, and the Setoid barrels (#542)¶
Labels: documentation, milestone-4-style, help-wanted
Scope¶
src/Setoid/Functions/ src/Setoid/Relations/ src/Setoid.lagda.md
Small, and mostly header work. The barrel modules hold no definitions but several open with boilerplate; a barrel's header is the natural place to say what the theme is and which submodule to reach for.
| measure | count |
|---|---|
| modules | 20 |
| public definitions | 104 |
| definitions with no prose on their fence | 6 |
| modules with a boilerplate-only or heading-only header | 5 |
Sized for one PR.
Done when¶
python3 scripts/python/docstring_audit.py src/Setoid/Functions/ --exit-zeroreports 0 gaps in scope.- Every module in scope opens with prose beyond the boilerplate sentence.
DOCSTRING_MAX_GAPSin theMakefileis lowered by the number cleared.
How¶
Conventions, tooling, grounding discipline and the verification checklist are in #268 — read that first; they are not repeated here. Exemplar: #538.
The bar is per code fence, settled in ADR-010: every fence carries a real paragraph, and every module opens with more than the boilerplate sentence. One definition per fence was considered and rejected, so the
--strictfigure for this subtree (66) sizes a road not taken and is not a backlog.
Sub-issue of #268. Tooling: #537.
Issue M4-2e: Docstrings: Classical/Structures (root and Lattice) (#543)¶
Labels: documentation, milestone-4-style, help-wanted
Scope¶
src/Classical/Structures/ (excluding Group/, which is #544)
The quintuple pattern (ADR-002) makes these highly repetitive, so one well-written structure can be adapted across the rest. Do that deliberately: adapt, do not paste.
| measure | count |
|---|---|
| modules | 19 |
| public definitions | 336 |
| definitions with no prose on their fence | 34 |
| modules with a boilerplate-only or heading-only header | 1 |
Sized for one or two PRs; split by directory if the diff runs long.
Done when¶
python3 scripts/python/docstring_audit.py src/Classical/Structures/ --exit-zeroreports 0 gaps in scope.- Every module in scope opens with prose beyond the boilerplate sentence.
DOCSTRING_MAX_GAPSin theMakefileis lowered by the number cleared.
How¶
Conventions, tooling, grounding discipline and the verification checklist are in #268 — read that first; they are not repeated here. Exemplar: #538.
The bar is per code fence, settled in ADR-010: every fence carries a real paragraph, and every module opens with more than the boilerplate sentence. One definition per fence was considered and rejected, so the
--strictfigure for this subtree (240) sizes a road not taken and is not a backlog.
Sub-issue of #268. Tooling: #537.
Issue M4-2f: Docstrings: Classical/Structures/Group (#544)¶
Labels: documentation, milestone-4-style, help-wanted
Scope¶
src/Classical/Structures/Group/
Split from the rest of Classical/Structures purely on size. The group-theoretic material feeds the FLRP research track, so cross-references into FLRP/ are worth getting right.
| measure | count |
|---|---|
| modules | 20 |
| public definitions | 310 |
| definitions with no prose on their fence | 31 |
| modules with a boilerplate-only or heading-only header | 1 |
Sized for one or two PRs; split by directory if the diff runs long.
Done when¶
python3 scripts/python/docstring_audit.py src/Classical/Structures/Group/ --exit-zeroreports 0 gaps in scope.- Every module in scope opens with prose beyond the boilerplate sentence.
DOCSTRING_MAX_GAPSin theMakefileis lowered by the number cleared.
How¶
Conventions, tooling, grounding discipline and the verification checklist are in #268 — read that first; they are not repeated here. Exemplar: #538.
The bar is per code fence, settled in ADR-010: every fence carries a real paragraph, and every module opens with more than the boilerplate sentence. One definition per fence was considered and rejected, so the
--strictfigure for this subtree (202) sizes a road not taken and is not a backlog.
Sub-issue of #268. Tooling: #537.
Issue M4-2g: Docstrings: Classical/Bundles, Signatures, and the rest of Classical (#545)¶
Labels: documentation, milestone-4-style, help-wanted
Scope¶
src/Classical/Bundles/ src/Classical/Signatures/ src/Classical/Theories/ src/Classical/Small/ src/Classical/Categories/ src/Classical/Properties/ src/Classical/Interpretations/ src/Classical.lagda.md
Gap-dense but shallow. Each bundle module is a stdlib-interop view and wants a short paragraph naming the Algebra.Bundles record it matches and why the view exists. Classical/Categories/ is the exception — the categorical framing needs real intent, so mark it TODO rather than guessing.
| measure | count |
|---|---|
| modules | 57 |
| public definitions | 242 |
| definitions with no prose on their fence | 37 |
| modules with a boilerplate-only or heading-only header | 1 |
Sized for one or two PRs; split by directory if the diff runs long.
Done when¶
python3 scripts/python/docstring_audit.py src/Classical/Bundles/ --exit-zeroreports 0 gaps in scope.- Every module in scope opens with prose beyond the boilerplate sentence.
DOCSTRING_MAX_GAPSin theMakefileis lowered by the number cleared.
How¶
Conventions, tooling, grounding discipline and the verification checklist are in #268 — read that first; they are not repeated here. Exemplar: #538.
The bar is per code fence, settled in ADR-010: every fence carries a real paragraph, and every module opens with more than the boilerplate sentence. One definition per fence was considered and rejected, so the
--strictfigure for this subtree (154) sizes a road not taken and is not a backlog.
Sub-issue of #268. Tooling: #537.
Issue M4-2h: Docstrings: Examples (#546)¶
Labels: documentation, milestone-4-style, help-wanted
Scope¶
src/Examples/
Demonstration modules. Prose should say what the example demonstrates and which theorem or definition it exercises, not re-describe the construction. Examples/Demos/HSP.lagda.md is the frozen TYPES 2021 artifact — leave its prose and its <a id> anchors alone (see #387).
| measure | count |
|---|---|
| modules | 41 |
| public definitions | 442 |
| definitions with no prose on their fence | 30 |
| modules with a boilerplate-only or heading-only header | 8 |
Sized for one or two PRs; split by directory if the diff runs long.
Done when¶
python3 scripts/python/docstring_audit.py src/Examples/ --exit-zeroreports 0 gaps in scope.- Every module in scope opens with prose beyond the boilerplate sentence.
DOCSTRING_MAX_GAPSin theMakefileis lowered by the number cleared.
How¶
Conventions, tooling, grounding discipline and the verification checklist are in #268 — read that first; they are not repeated here. Exemplar: #538.
The bar is per code fence, settled in ADR-010: every fence carries a real paragraph, and every module opens with more than the boilerplate sentence. One definition per fence was considered and rejected, so the
--strictfigure for this subtree (272) sizes a road not taken and is not a backlog.
Sub-issue of #268. Tooling: #537.
Issue M4-2i: Docstrings: Overture, FLRP, Exercises, and the top-level barrels (#547)¶
Labels: documentation, milestone-4-style, help-wanted
Scope¶
src/Overture/ src/FLRP/ src/Exercises/ src/agda-algebras.lagda.md
Only 4 gaps but 10 weak headers, so almost entirely module-header work. FLRP/ needs William's research context — the parachute, Kurzweil–Netter and Snow material encodes a live research programme that cannot be reconstructed from the types. Prefer deferring the FLRP headers to a follow-up over guessing.
| measure | count |
|---|---|
| modules | 73 |
| public definitions | 900 |
| definitions with no prose on their fence | 4 |
| modules with a boilerplate-only or heading-only header | 10 |
Sized for one PR.
Done when¶
python3 scripts/python/docstring_audit.py src/Overture/ --exit-zeroreports 0 gaps in scope.- Every module in scope opens with prose beyond the boilerplate sentence.
DOCSTRING_MAX_GAPSin theMakefileis lowered by the number cleared.
How¶
Conventions, tooling, grounding discipline and the verification checklist are in #268 — read that first; they are not repeated here. Exemplar: #538.
The bar is per code fence, settled in ADR-010: every fence carries a real paragraph, and every module opens with more than the boilerplate sentence. One definition per fence was considered and rejected, so the
--strictfigure for this subtree (476) sizes a road not taken and is not a backlog.
Sub-issue of #268. Tooling: #537.
Issue M4-3: Design discussion — scope of 𝓞 and 𝓥 universe variables (#269, closed)¶
Labels: milestone-4-style, design-discussion
Description¶
Overture.Signatures declares variable 𝓞 𝓥 : Level without private. They leak through every downstream module, which is convenient but can be confusing for new contributors shadowing the names.
Tasks¶
- Write up the three options in an ADR or design-discussion issue:
- Keep current behavior; document clearly.
- Make them
privateinOverture.Signatures; downstream modules re-declare. - Move to a dedicated
Overture.UniverseLevelsmodule imported explicitly. - Collect input; pick one.
- Document the decision in STYLE.md.
- Apply consistently.
Acceptance criteria¶
- Decision is recorded (ADR or STYLE.md section).
-
𝓞and𝓥are handled uniformly across the library.
Issue M4-4: Hoist ⟨_⟩ and EqArgs out of Setoid.Algebras.Basic (#337, closed)¶
Labels: enhancement, milestone-4-style, breaking-change, design-discussion
Context¶
Setoid.Algebras.Basic is parameterized by a module-level {𝑆 : Signature 𝓞 𝓥}. Two of its definitions — EqArgs and the polynomial-functor lifting ⟨_⟩ — take their signature as their own explicit argument and do not use the module parameter. When such a name is imported without instantiating the module, Agda still prepends the unused {𝑆} to it. For every other export (Algebra, _^_, 𝔻[_], 𝕌[_], …) the parameter is recovered from context because the name's type mentions 𝑆; but ⟨_⟩ and EqArgs mention it nowhere, so the prepended {𝑆} becomes an unsolvable metavariable the moment either is written by hand at a use site.
This surfaced while implementing Classical.Structures.Monoid: an interp : Func (⟨ Sig-Monoid ⟩ (≡.setoid A)) (≡.setoid A) annotation failed with an UnsolvedConstraints error (_𝑆_ : Signature 0ℓ 0ℓ … blocked), even though every value in scope determined the signature. The current workaround is to avoid hand-writing ⟨_⟩ and rely on copattern inference of the Interp field — which works, but leaves a latent footgun for any future use site that names ⟨_⟩ or EqArgs directly.
The underlying issue is conceptual: the module parameter fixes a fibre Alg(𝑆), which is exactly right for the single-signature meta-theory but wrong for code that ranges over signatures. ⟨_⟩ and EqArgs are signature-generic constructions that happen to live inside the fibre-fixing module.
Proposal¶
Extract EqArgs and ⟨_⟩ (and any other signature-explicit, parameter-unused definitions) into a new non-parameterized module — suggest Setoid/Algebras/Setoid.lagda.md — and have Setoid.Algebras.Basic import them. Their bodies are unchanged (they already take 𝑆 explicitly); only their home changes, so the spurious {𝑆} no longer rides along. Algebra's field Interp : Func (⟨ 𝑆 ⟩ Domain) Domain continues to apply the relocated ⟨_⟩ to the module's 𝑆.
Acceptance criteria¶
-
EqArgsand⟨_⟩live in a non-parameterized module;Setoid.Algebras.Basicre-exports them so existing import sites are unaffected (or, where they must change, the change is mechanical and enumerated in the PR). -
make checkpasses on the wholeSetoid/tree and theDemos/HSPdevelopment. - A throwaway
_ = ⟨ Sig-Monoid ⟩ (≡.setoid ℕ)inClassical/Structures/Monoidelaborates with no unsolved metavariable (then removed). - The copattern workaround in
fromMonoidOps/expand-εstill type-checks (it should be unaffected; this is a regression guard).
Non-goals¶
- Any change to the fibre vs. total-category design of
Algebraitself — that is the separate M11 question (see #). This issue only relocates two signature-generic helpers; it does not touch whether 𝑆is a parameter or an argument ofAlgebra.
Risk¶
Low, but the blast radius is whatever currently imports ⟨_⟩/EqArgs from Basic. Expected to be small (both are nearly internal to Algebra), but the PR should grep for both and re-run make check rather than assume.
Issue M4-5: Signatures as functors — reducts, expansions, and interpretability (#338, closed)¶
Labels: enhancement, milestone-4-style, design-discussion
Summary¶
Make the polynomial-functor / container structure already latent in the foundation first-class, and with it the total-category (∫Alg) view that reducts, expansions, and signature morphisms inherently require — as opposed to the fibre view (Alg(𝑆) for a fixed 𝑆) that the module-parameter convention of Setoid.Algebras.Basic privileges. This is the structural companion to the surgical fix in [M4-4]: where M4-4 relocates the two signature-generic helpers (⟨_⟩, EqArgs) that leak the unused module parameter, [M4-5] builds out the category-theoretic layer that motivates ranging over signatures in the first place. Full design in docs/notes/milestone-signature-functors.md.
Why now¶
The M3-6 (Monoid/Group) work built, by hand, a container-morphism reduct ([Classical.Structures.Reduct][]), an expand-ε dual, and discovered that "reduct-invariance of satisfaction" is what discharges each forgetful projection's theory obligation (the per-structure curried-law pivots in monoid→semigroup and the reindex forgetfuls). It also surfaced that the foundation already is a polynomial-functor formalization without saying so: Signature is a container, ⟨ 𝑆 ⟩ is the polynomial functor P_σ lifted to setoids, Interp is the structure map P_σ(Domain) → Domain, and Term is the initial algebra of A ↦ X ⊎ P_σ(A). M4-5 makes this explicit and reusable, and is the proper home for the Base/Adjunction and Base/Categories orphans currently parked as TBD.
Mathematical core¶
A signature morphism is a container morphism (ι , κ) (ι covariant on symbols, κ contravariant on arities). Signatures and these morphisms form a category Sig. P is a 2-functor Sig → [Setoid,Setoid]; reduct is precomposition with the induced natural transformation; expansion is its copairing dual; reduct-invariance of satisfaction is naturality of the unique fold; reduct has a left adjoint (free expansion); a theory interpretation is a signature morphism into derived operations, with Maltsev conditions as interpretations of small theories.
Subissues¶
- M4-5a Category of signature morphisms; promote
reductto a packaged morphism. (low risk) - M4-5b
⟨_⟩as a functor; induced natural transformations. (low–medium) - M4-5c Reduct as a functor on algebras; upgrade the classical forgetful projections to forgetful functors by supplying the morphism action. (medium)
- M4-5d Free expansion; the
F ⊣ reductadjunction. Distinguish from M3-6's chosenexpand-ε. (high / high-value) - M4-5e Term monad; naturality of the fold; reduct-invariance of satisfaction as a corollary, absorbing M3-6's per-structure pivot proofs. (medium)
- M4-5f Theory interpretations; Maltsev conditions as interpretations; the interpretability quasi-order. (research-grade, exploratory)
- M4-5g Reduct classes of varieties are prevarieties (closed under S, P, not H). (research-grade)
The ordering is a dependency chain: a→b→c→{d,e}, with e gating f and c gating g.
De-risking spikes (before the hard phases)¶
- Spike A (in M4-5c): supply the morphism action for
monoid→semigrouponly and prove it functorial. - Spike B (in M4-5d): construct the free monoid on a semigroup (adjoin a unit) and prove the universal property against
reduct. If this single adjunction is clean with setoid quotients, the general theorem is plausible.
Open questions¶
- Adjunction direction/existence along inclusions that add equations (needs quotients now, cubical HITs later).
- Build on
agda-categoriesvs. stay self-contained (prototype both in M4-5a). - Whether cubical dissolves the M3-5 binary-node-bridge obstruction (an MLTT/
--safeartifact) — a measurable cubical-port (v4.0) payoff if so; M4-5e is the place to measure it. - Keep M4-5f/g on the clone/CSP side (connects to M9-2, Bodirsky–Pinsker), explicitly not the FLRP side.
Relationship to other work¶
Depends on M3 (concrete reduct/expand) and the Setoid.Varieties machinery. Sibling to [M4-4] (the ⟨_⟩/EqArgs parameter-leak fix, which removes friction this milestone would otherwise keep hitting). Connects to M9-2 via interpretability.
Issue M4-5a: Category of signature morphisms (#339, closed)¶
Labels: enhancement, milestone-4-style, category-theory
The current reduct ι κ 𝑨 (Classical.Structures.Reduct) takes the container morphism as two loose arguments. Package the pair (ι , κ) as a first-class SigMorphism 𝑆₁ 𝑆₂ — a record with ι : OperationSymbolsOf 𝑆₁ → OperationSymbolsOf 𝑆₂ (covariant on symbols) and κ : (o : OperationSymbolsOf 𝑆₁) → ArityOf 𝑆₂ (ι o) → ArityOf 𝑆₁ o (contravariant on positions) — and assemble signatures and these morphisms into a category Sig. This is the Abbott–Altenkirch–Ghani container-morphism, specialized to Signature = (OperationSymbolsOf ▷ ArityOf).
The first real subtlety this surfaces is morphism equality: under --safe without funext, two SigMorphisms agreeing pointwise need not be propositionally equal (the same Fin n η-gap that forces the pointwise bundle round-trips), so the category laws may have to be stated against a setoid of morphisms rather than ≡. Settling that is half the value of the issue, since it determines the shape of everything downstream.
Tasks:
+ [ ] Define SigMorphism 𝑆₁ 𝑆₂ (record packaging ι, κ).
+ [ ] Define identity (ι = id, κ = λ _ → id) and composition (ι composes covariantly, κ contravariantly).
+ [ ] Decide the hom-equality (propositional vs. a hom-setoid) and prove the category laws under that choice.
+ [ ] Re-express reduct to consume a SigMorphism, keeping the loose-argument form as a thin wrapper (or deprecating it).
+ [ ] Decision spike: realize Sig both as an agda-categories Category and as a self-contained record; record which to standardize on.
Non-goals: any action on algebras (that is M4-5-3); morphisms into derived operations (that is M4-5-6, where κ's codomain becomes terms rather than symbols).
Acceptance criteria:
+ [ ] reduct (id-morphism) 𝑨 agrees with 𝑨 (definitionally on the carrier; up to the chosen hom-equality on operations).
+ [ ] reduct (ψ ∘ φ) agrees with reduct φ ∘ reduct ψ.
+ [ ] The category laws type-check under the chosen morphism-equality.
References: Abbott, Altenkirch, Ghani, Containers: constructing strictly positive types; ADR-002 v2 §5.
Issue M4-5b: ⟨_⟩ as functor and induced natural transformations (#340, closed)¶
Labels: enhancement, milestone-4-style, category-theory
Make explicit that ⟨ 𝑆 ⟩ : Setoid → Setoid (Setoid.Algebras.Basic) is the polynomial/container functor P_σ and is functorial in the carrier (its action on a setoid map is post-composition on the position function). Then show that a SigMorphism (ι , κ) : 𝑆₁ → 𝑆₂ induces a natural transformation ⟦ι,κ⟧ : ⟨ 𝑆₁ ⟩ ⟹ ⟨ 𝑆₂ ⟩, given on components by (o , args) ↦ (ι o , args ∘ κ o) — which is exactly the data reduct already precomposes into Interp. Finally, show the assignment SigMorphism ↦ natural transformation is itself functorial (identity to identity, composite to vertical composite), i.e. ⟦_⟧ is a functor Sig → [Setoid , Setoid].
This is the issue where the "the foundation already is a polynomial-functor formalization" observation stops being a remark and becomes a checked statement. It is the natural-transformation layer that [M4-5e]'s fold-naturality result will sit on top of.
Tasks:
+ [ ] ⟨ 𝑆 ⟩ functorial in the carrier (map-law + functoriality).
+ [ ] The induced natural transformation ⟦ι,κ⟧; prove its naturality square.
+ [ ] Functoriality of ⟦_⟧ (preserves identity and composition of SigMorphisms).
Acceptance criteria:
+ [ ] The naturality square for ⟦ι,κ⟧ commutes.
+ [ ] ⟦ id-morphism ⟧ is the identity natural transformation; ⟦ ψ ∘ φ ⟧ is the vertical composite, up to the chosen equality.
References: Gambino, Kock, Polynomial functors and polynomial monads.
Issue M4-5c: Reduct as functor on algebras (#341, closed)¶
Labels: enhancement, milestone-4-style, category-theory
For a fixed φ : SigMorphism 𝑆₁ 𝑆₂, promote reduct φ : Alg(𝑆₂) → Alg(𝑆₁) from an object map to a functor: its action on an 𝑆₂-homomorphism is the same underlying setoid map, whose 𝑆₁-homomorphism condition transfers because the reduct's operations are φ-images of 𝑆₂'s (the square commutes by the same κ-reindex). Then resolve the M3-6 note that monoid→semigroup and friends are "object maps of forgetful functors, not yet functors" by supplying the morphism action, packaging each classical forgetful as a genuine functor between the structures' categories.
This requires a category of 𝑆-algebras in the first place. Setoid.Homomorphisms supplies the homs; this issue must assemble Alg(𝑆) as a category (or reuse one if it already exists), and observe that a morphism of Σ-typed classical structures is just an algebra hom (the equational-witness component carries no additional morphism data). That assembly is the main dependency risk and should be scoped explicitly at the top of the PR.
Tasks:
+ [ ] Assemble Alg(𝑆) as a category over Setoid.Homomorphisms (or confirm/reuse an existing one).
+ [ ] reduct φ as a functor: morphism action + functor laws.
+ [ ] Package monoid→semigroup, commutativeMonoid→monoid, commutativeSemigroup→semigroup (and the Sig-Group analogues once they land) as forgetful functors, with the reindex forgetfuls reusing the M4-5-1 identity-ish morphism.
Non-goals: a left adjoint [M4-5d] (#342); the equational-class semantics [M4-5g] (#345)).
Acceptance criteria:
+ [ ] reduct φ satisfies the functor laws.
+ [ ] At least monoid→semigroup type-checks as a functor and its action on a concrete monoid hom reduces correctly.
References: Setoid.Homomorphisms; ADR-002 v2 §5.
Issue M4-5d: Free expansion; the F ⊣ reduct adjunction (#342, closed)¶
Labels: enhancement, milestone-4-style, category-theory, research-exploratory
Construct the left adjoint F : Alg(𝑆₁) → Alg(𝑆₂) to reduct φ along a symbol-adjoining inclusion φ (one that adds operation symbols and no equations), exhibiting the free 𝑆₂-algebra on an 𝑆₁-algebra. The sharpest content of the issue is the contrast with M3-6's expand-ε: expand-ε adjoins ε as a chosen element of the existing magma carrier — a specific section of the reduct, not a universal one — whereas the free expansion freely adjoins a new generator for each added symbol, enlarging the carrier. Making F ⊣ reduct precise is what tells you when "this magma is secretly a monoid" (a section) and "the free monoid on this magma" (the adjoint) are the same and when they diverge.
Inclusions that adjoin equations (not just symbols) need a quotient for the left adjoint — the free algebra modulo the new equations — which wants setoid quotients now and is a candidate cubical-HIT payoff later. Scope this issue to symbol-adjoining inclusions; flag equation-adjoining adjoints as a follow-up.
Spike (do this before the general construction): build F for one concrete symbol-adjoining inclusion — freely adjoin a unit to a semigroup, i.e. the free monoid on a semigroup — and verify the universal property against reduct. If a single adjunction is clean under setoid quotients, the general theorem is plausible; if it is not, that is the signal to re-scope.
Tasks:
+ [ ] Spike: F for the free-unit inclusion; unit, counit, and triangle identities for that one case.
+ [ ] Generalize F to arbitrary symbol-adjoining φ (stretch).
+ [ ] Document precisely how expand-ε relates to F (a section vs. the adjoint), updating the M3-6 prose that currently calls expand-ε "the expand half of the reduct/expand dual."
Non-goals: equation-adjoining left adjoints (deferred; needs quotients/HITs).
Acceptance criteria:
+ [ ] The spike adjunction's triangle identities type-check.
+ [ ] A design note distinguishing expand-ε from F.
Issue M4-5e: Term monad; naturality of the fold; reduct-invariance of satisfaction (#343, closed)¶
Labels: enhancement, milestone-4-style, category-theory
Establish Term 𝑆 : Setoid → Setoid as a monad (unit ℊ, multiplication by substitution) and the environment interpretation ⟦_⟧ as the unique fold out of the term algebra, natural in the carrier. The target theorem is reduct-invariance of satisfaction: for φ : 𝑆₁ → 𝑆₂, an 𝑆₂-algebra 𝑨, and an 𝑆₁-equation s ≈ t, reduct φ 𝑨 ⊧ s ≈ t is equivalent to 𝑨 ⊧ φ✶ s ≈ φ✶ t (the φ-translation of terms), and this is precisely naturality of the fold with respect to the [M4-5b] induced natural transformation.
This is the payoff issue. As a corollary it absorbs the per-structure curried-law pivots written by hand in M3-6 — monoid→semigroup's thm, and the analogous obligations for the reindex forgetfuls — into instances of one lemma. It also bears directly on the M3-5 negative finding: the per-signature interp-nodeₙ families are the manual unfolding that fold-naturality systematizes, and this issue should measure whether the binary-node-bridge obstruction (the refl-match on a neutral ArityOf 𝑆 f ≡ Fin 2, rejected by the without-K unifier) survives at the functorial level or dissolves — the answer is a concrete data point for the cubical-port (v4.0) cost/benefit.
Tasks:
+ [ ] Term 𝑆 monad laws (left/right unit, associativity of substitution).
+ [ ] Fold (⟦_⟧) naturality in the carrier.
+ [ ] The reduct-invariance-of-satisfaction lemma.
+ [ ] Re-derive monoid→semigroup's Th-Semigroup obligation from the lemma as a regression demonstration (do not delete the bespoke proof until the general one lands and type-checks).
+ [ ] Record whether the M3-5 node-bridge obstruction persists functorially.
Acceptance criteria: + [ ] The reduct-invariance lemma type-checks. + [ ] The Monoid forgetful's theory obligation is re-provable through it.
References: the M3-5 finding on interp-node (per-signature, proof-free); ADR-002 v2 §1.
Issue M4-5f: Theory interpretations; Maltsev conditions as interpretations; the interpretability quasi-order (#344, closed)¶
Labels: milestone-4-style, research-exploratory
Scope note: this is a research-tracking issue. The task list below is provisional and deliberately shallow — committing to an internal structure before M4-5-1..5 exist would be premature. The deliverable for this issue is a definition, one or two worked instances, and a design note that lets a later issue commit to the real development.
Generalize the symbol-to-symbol SigMorphism of M4-5-1 to a theory interpretation T₁ → T₂: a signature morphism into the derived (term) operations of T₂ under which every T₁-equation becomes a T₂-theorem. Maltsev conditions — a Maltsev term, a majority term, a near-unanimity term — are then exactly interpretations of small theories (e.g. the one-ternary-symbol theory with the Maltsev equations) into a given variety, and the interpretability relation induces the Garcia–Taylor quasi-order on varieties.
This sits squarely on the clone/CSP side of the library and connects forward to M9-2 (infinitary CSP over ω-categorical templates, the Bodirsky–Pinsker program). It is explicitly not FLRP work — the interpretability/Maltsev/clone material and the Finite Lattice Representation Problem are kept in separate research tracks, and conflating them is an error to flag in review.
Provisional tasks: + [ ] Reading pass: Garcia–Taylor, The Lattice of Interpretability Types of Varieties; standard Maltsev-condition references; Bodirsky for the CSP linkage. + [ ] Define theory interpretation (signature morphism into derived operations + equation-preservation). + [ ] One worked instance (e.g. the Maltsev-term theory interpreted into a concrete congruence-permutable variety, or just the formal statement). + [ ] Design note scoping the real development and its dependence on [M4-5e] (#343).
Acceptance criteria (loose): a checked definition, at least one interpretation instance, and a written scope note. No claim about the full quasi-order is in scope here.
Issue M4-5g: Reduct classes of varieties (prevarieties) (#345, closed)¶
Labels: milestone-4-style, research-exploratory
Scope note: research-tracking, like [M4-5f] (#344). Prove the tractable half (S, P) and document the rest; do not over-specify before the dependencies land.
For a variety 𝒱 of 𝑆₂-algebras and φ : 𝑆₁ → 𝑆₂, the reduct class reduct φ (𝒱) is closed under subalgebras and products but not, in general, homomorphic images — so it is a prevariety, not a variety. The S- and P-closure follow structurally from reduct φ being a functor [M4-5c] (#341) that preserves the relevant subobjects and limits, together with reduct-invariance [M4-5e] (#343); the failure of H-closure is the interesting negative and is best recorded as a concrete counterexample.
Like [M4-5f], this is clone/variety-theoretic and CSP-adjacent, not FLRP.
Provisional tasks:
+ [ ] State the theorem against the Setoid.Varieties S/H/P machinery.
+ [ ] Prove reduct preserves S (subalgebras).
+ [ ] Prove reduct preserves P (products).
+ [ ] Record the ¬H part as a documented counterexample, or defer with a written rationale.
Acceptance criteria (loose): S and P parts type-check; the ¬H situation is documented.
References: Burris, Sankappanavar, A Course in Universal Algebra (reducts; SP-closure).
Issue M4-6: Consolidate the duplicate Op operation type into one canonical declaration (#354, closed)¶
Labels: enhancement, milestone-4-style, breaking-change
Context¶
The library currently carries two declarations of the operation type Op, with identical bodies but opposite parameter order:
Overture.Operations.Op A I = (I → A) → A— carrier first.Classical.Operations.Op I A = (I → A) → A— arity first.
They are the same type up to argument order, so this is a "one canonical form per concept" violation (the M4 exit criterion explicitly targets synonym pairs in the public API). The arity-first order has proved the more useful of the two: Op (Fin 2) partially applies as "binary operation," independent of any carrier, which is the right convention for the Curry/Uncurry/pair family in Classical.Operations.
Why this issue exists (and why it is deferred from #353)¶
This surfaced in #353, which adds Overture.Cayley (a Cayley-table construction for finite operations). That PR deliberately types a binary operation as a bare Fin n → Fin n → Fin n rather than either Op, precisely so as not to spread the unresolved convention clash into a new module before it is settled. A note at the end of Overture.Cayley points here. The consolidation has a wide blast radius (Op is foundational and used throughout Classical/), so it belongs in the M4 style sweep rather than in an examples-focused PR.
Decision to implement¶
Consolidate to a single canonical Op in Overture.Operations, using the arity-first convention Op I A = (I → A) → A, and have Classical.Operations re-export it (deprecating its local copy under the stable-API discipline rather than deleting it outright).
Tasks¶
- Adopt the canonical
Op : Type 𝓥 → Type α → Type _withOp I A = (I → A) → AinOverture.Operations; update that module's prose, and adjustπandarity[_]to the new argument order. - Re-export the canonical
OpfromClassical.Operations; mark the old arity-first local definition with aWARNING_ON_USAGEdeprecation for at least one minor cycle (it already matches the canonical order, so this is mostly a relocation). - Audit every
Opuse site for the carrier-first vs arity-first flip and migrate; the carrier-first uses (whatever currently importsOverture.Operations.Op) are the ones that change. - Decide whether
pair/Curry₂/Uncurry₂(currently inClassical.Operations) move down toOverturealongside the canonicalOp, or stay inClassical.Operations; record the rationale. - Re-express
Overture.Cayley.⟦_⟧and the decidable-law checkers over the canonicalOpif it reads better than the bareFin n → Fin n → Fin n, or record why the finite case keeps the plain function type. - Update the canonical symbol/notation table in
docs/STYLE_GUIDE.mdto record the singleOpand its argument-order convention.
Acceptance criteria¶
- Exactly one
Opdeclaration in the public API; no duplicate/synonym remains. -
make checkpasses across the whole tree. - Any removed/relocated public name goes through a
WARNING_ON_USAGEdeprecation cycle rather than a hard break. - The
docs/STYLE_GUIDE.mdnotation table matches the consolidatedOp.
Risk¶
Low conceptually but wide: Op is foundational, so the PR should grep every use site, flip carrier-first uses, and re-run make check rather than assume the blast radius is small.
Issue M4-7: V exposes eight unconstrained universe-level parameters; provide a common-case specialization (#359, closed)¶
Labels: milestone-4-style
Context¶
Setoid.Varieties.Closure.V is defined in a module parameterized by eight universe levels:
module _ {α ρᵃ β ρᵇ γ ρᶜ δ ρᵈ : Level} where
V : ∀ ℓ ι → Pred(Algebra α ρᵃ) (a ⊔ ov ℓ) → Pred(Algebra δ ρᵈ) (d ⊔ ov(a ⊔ b ⊔ c ⊔ ℓ ⊔ ι))
V ℓ ι 𝒦 = H{γ}{ρᶜ}{δ}{ρᵈ} (a ⊔ b ⊔ ℓ ⊔ ι) (S{β}{ρᵇ} (a ⊔ ℓ ⊔ ι) (P ℓ ι 𝒦))
The four intermediate levels β ρᵇ γ ρᶜ are genuinely internal to the H ∘ S ∘ P composition — they appear in neither the input algebra (α, ρᵃ) nor the output algebra (δ, ρᵈ).
Where it bit¶
Writing a natural type signature for "the variety generated by a concrete algebra" fails with unsolved metavariables, because β ρᵇ γ ρᶜ are not determined by anything in the signature:
ℕ∈V : 𝑨₀ ∈ V 0ℓ (ov 0ℓ) 𝒦₀ -- unsolved metas: β ρᵇ γ ρᶜ
In Examples.Setoid.HSPCommutativeMonoid (PR #358) I had to introduce a 𝕍 alias pinning all eight implicits to 0ℓ positionally:
𝕍 : Pred (Algebra 0ℓ 0ℓ) (ov (ov 0ℓ))
𝕍 = V {0ℓ}{0ℓ}{0ℓ}{0ℓ}{0ℓ}{0ℓ}{0ℓ}{0ℓ} 0ℓ (ov 0ℓ) 𝒦₀
This is a real papercut for anyone instantiating the variety machinery at a fixed algebra.
Suggested fix¶
- Provide a common-case specialization, e.g.
V′ : ∀ ℓ ι → Pred(Algebra α ρᵃ)(a ⊔ ov ℓ) → Pred(Algebra α ρᵃ) _that collapses the intermediate universes to those of the input/output algebra (the overwhelmingly common case where a class and the generated variety live at the same levels). - Alternatively, make
β ρᵇ γ ρᶜcomputed fromα ρᵃ δ ρᵈ ℓ ι(so they are no longer free implicits) rather than independent module parameters, if the H/S/P composition permits. - At minimum, document the eight-parameter shape and the pinning idiom in
docs/STYLE_GUIDE.md, and ship the𝕍-style helper as library API so examples/tests need not re-derive it.
Acceptance criteria¶
- A downstream
𝑨 ∈ V … 𝒦membership at a fixed algebra type-checks without manually pinning intermediate levels. make checkpasses.
Issue M4-8: V-expa cannot infer its class 𝒦 from a membership proof; offer an explicit-argument variant (#360, closed)¶
Labels: milestone-4-style
Context¶
Setoid.Varieties.Closure.V-expa has the _⊆_-based signature
V-expa : ∀ ℓ ι → {𝒦 : Pred (Algebra α ρᵃ)(a ⊔ ov ℓ)} → 𝒦 ⊆ V ℓ ι 𝒦
where 𝒦 ⊆ V ℓ ι 𝒦 unfolds to ∀ {x} → x ∈ 𝒦 → x ∈ V ℓ ι 𝒦. Both the class 𝒦 and the element x are implicit and must be recovered from a single membership argument.
Where it bit¶
Applying V-expa to a membership proof leaves 𝒦 (and x) as a higher-order unification problem _𝒦 _x ≟ (type of the proof), which Agda cannot solve — especially once the class predicate reduces. In Examples.Setoid.HSPCommutativeMonoid (PR #358), V-expa 0ℓ (ov 0ℓ) 𝑨₀∈𝒦₀ failed; I had to both (a) make the singleton class a non-reducing one-constructor data family and (b) pass {𝒦 = 𝒦₀} explicitly:
ℕ∈V = V-expa 0ℓ (ov 0ℓ) {𝒦 = 𝒦₀} 𝑨₀∈𝒦₀
Suggested fix¶
- Add an explicit-argument variant, e.g.
V-expa′ : ∀ ℓ ι (𝒦 : Pred (Algebra α ρᵃ)(a ⊔ ov ℓ)) {𝑨} → 𝑨 ∈ 𝒦 → 𝑨 ∈ V ℓ ι 𝒦
so the class is supplied directly rather than back-inferred through _⊆_.
+ Consider applying the same treatment to the other _⊆_/_⊫_-stated closure lemmas (S-expa, H-expa, P-expa) for consistency.
+ Keep the _⊆_ form as the abstract statement; the explicit variant is the ergonomic entry point.
Acceptance criteria¶
𝑨 ∈ V ℓ ι 𝒦is derivable from𝑨 ∈ 𝒦without manually supplying{𝒦 = …}or reshaping the class to avoid reduction.make checkpasses.
Issue M4-9: V-id1 forces explicit {p}{q} because _⊫_/_⊧_ unfold eagerly during unification (#361, closed)¶
Labels: milestone-4-style
Context¶
Setoid.Varieties.Preservation.V-id1 lifts an identity from a class to the variety it generates:
V-id1 : 𝒦 ⊫ (p ≈̇ q) → V ℓ ι 𝒦 ⊫ (p ≈̇ q)
with p q module-level implicits. The equation (p ≈̇ q) appears, intact, in the type of the argument.
Where it bit¶
When checking V-commutative : 𝕍 ⊫ (x·y ≈̇ y·x) against V-id1 … 𝒦₀⊫comm (PR #358), Agda did not unify the equation at the injective Eq level (_p ≈̇ _q ≟ x·y ≈̇ y·x). Instead it unfolded _⊫_ → _⊧_ → Equal → ⟦_⟧, producing stuck constraints of the form
⟦ 𝑨 ⟧ _p ρ ≈ ⟦ 𝑨 ⟧ (node ∙-Op (λ { 0F → ℊ 0F ; 1F → ℊ 1F })) ρ (blocked on _p)
i.e. the equation's lhs/rhs became metavariables blocked behind the unfolded interpreter. I had to pin them by hand:
V-commutative = V-id1 {ℓ = 0ℓ} {ι = ov 0ℓ} {𝒦 = 𝒦₀} {p = x·y} {q = y·x} 𝒦₀⊫comm
even though p, q, and 𝒦 are all visible in the argument's type.
Suggested fix¶
- Make
_⊧_/Equal(and hence_⊫_) less reduction-happy so the equation unifies as anEq, not as an unfoldedEqual— e.g. wrapEqualin arecord/ make itabstract, or mark the relevant definitions so the unifier prefers theEqconstructor. (This likely helpsV-id2,S-id1,H-id1, and friends too.) - Or restate the preservation lemmas to take the equation
Eqas an explicit argument, so callers never rely on back-inference through_⊫_.
Acceptance criteria¶
V ℓ ι 𝒦 ⊫ (p ≈̇ q)is derivable from𝒦 ⊫ (p ≈̇ q)without manually supplying{p}{q}when they already appear in the argument's type.make checkpasses.
Issue M4-10: Substitution _[_] does not compute through tuple arguments; add a substitution-lemma kit (#362, closed)¶
Labels: milestone-4-style
Context¶
In Setoid.Terms.Basic, term substitution pushes into nodes pointwise:
(node f ts) [ σ ] = node f (λ i → ts i [ σ ])
When ts is a finite tuple built from a pattern-matching lambda (the natural way to write a binary term, s · t = node ∙-Op (λ { 0F → s ; 1F → t })), the result node f (λ i → ts i [ σ ]) is not definitionally equal to a freshly rebuilt term (s [ σ ]) · (t [ σ ]) — a pattern-matching lambda does not reduce under a variable index i, and bridging the two functions needs function extensionality, which is unavailable under --safe/--cubical-compatible.
Where it bit¶
This blocks the obvious way to instantiate an equation at compound terms. In Examples.Setoid.FreeSemigroup (PR #358) the natural statement
assoc▹ : (p q r : Term (Fin 4)) → E ⊢ Fin 4 ▹ ((p · q) · r) ≈ (p · (q · r))
assoc▹ p q r = sub (hyp 0F) σ -- σ 0F = p; 1F = q; 2F = r
fails: sub produces a goal in [ σ ]-form (node ∙-Op (λ i → … [ σ ])) that will not match the readable (p · q) · r. As a result I could not write a clean four-fold reassociation and had to restrict the term-rewriting demo to redexes that match the law literally (no sub).
Suggested fix¶
- Ship a small substitution-lemma kit, proved up to derivable equality
_⊢_▹_≈_(or propositional_≡_where it holds), e.g.: []-node:node f ts [ σ ] ≈ node f (λ i → ts i [ σ ])and a congruence[]-congfor rebuilding tuples;[]-∘(substitution composition) and[]-ℊ.- And/or offer a
Vec-based (or explicitly enumerated) argument representation for fixed finite arities under which substitution commutes definitionally, so(s · t) [ σ ]reduces to(s [ σ ]) · (t [ σ ])on the nose. - Document the idiom (and the funext obstruction) so users do not rediscover it.
Acceptance criteria¶
- An equation can be instantiated at compound terms via
suband the result matches a readable, rebuilt term (definitionally, or via a one-line lemma). - A multi-step reassociation example (e.g.
((a·b)·c)·d ≈ a·(b·(c·d))) type-checks cleanly. make checkpasses.
Issue M4-11: No generic smart-constructor for a concrete Setoid Algebra; add one (#363, closed)¶
Labels: milestone-4-style
Context¶
Building a concrete Setoid.Algebras.Basic.Algebra requires hand-writing the interpretation Func (⟨ 𝑆 ⟩ Domain) Domain, including its cong over the Σ/EqArgs encoding of ⟨ 𝑆 ⟩:
ℕ∸-magma : Algebra 0ℓ 0ℓ
ℕ∸-magma = record { Domain = ≡.setoid ℕ ; Interp = interp }
where
interp : Func (⟨ Sig-Magma ⟩ (≡.setoid ℕ)) (≡.setoid ℕ)
interp ⟨$⟩ (∙-Op , args) = args 0F ∸ args 1F
cong interp {∙-Op , _} {.∙-Op , _} (refl , args≈) = ≡.cong₂ _∸_ (args≈ 0F) (args≈ 1F)
The {∙-Op , _}{.∙-Op , _}(refl , args≈) boilerplate recurs in every concrete algebra (it appears in Examples.Setoid.FreeMagma, Examples.Setoid.FiniteQuotient, and across Classical.Bundles.*).
Where it bit¶
The Classical layer has structure-specific smart-constructors (opsToMagma, eqsToMonoid, eqsToCommutativeMonoid, …), but there is no generic builder at the Setoid layer. Every example/test that needs a one-off concrete algebra re-derives the interp + cong plumbing.
Suggested fix¶
- Add a generic builder in
Setoid.Algebras.Basic, e.g. for a≡-carrier:
mkAlgebraₚ : (A : Type α)
→ (f : (o : ∣ 𝑆 ∣) → (∥ 𝑆 ∥ o → A) → A)
→ Algebra α 0ℓ
deriving Domain = ≡.setoid A and the cong automatically (it is ≡-congruence of f in each argument).
+ Optionally a setoid-general version mkAlgebra taking a carrier Setoid plus a per-operation cong obligation, packaging the (refl , args≈) destructuring once.
+ Re-express a couple of existing concrete algebras through it as a regression demonstration.
Acceptance criteria¶
- A concrete finite/
≡-carrier algebra can be defined without writing the⟨ 𝑆 ⟩-congboilerplate by hand. make checkpasses.
Issue M4-12: Re-export _,_ from Setoid.Algebras to avoid a misleading Σ-constructor scope error (#364, closed)¶
Labels: milestone-4-style
Context¶
The carrier of ⟨ 𝑆 ⟩ ξ is an Agda.Builtin.Sigma.Σ, so an interpretation clause pattern-matches as (o , args). This requires the pair constructor _,_ to be in scope.
Where it bit¶
If _,_ is not imported (easy to forget when you have only imported the signature and algebra machinery), the clause
interp ⟨$⟩ (∙-Op , args) = …
fails with the misleading error
∙-Op is not a constructor of the datatype Agda.Builtin.Sigma.Σ
which points at ∙-Op rather than at the missing _,_, and gives no hint that the fix is open import Data.Product using ( _,_ ). I hit this immediately when writing the first example in PR #358.
Suggested fix¶
- Re-export
_,_(and likelyΣ-syntax) fromSetoid.Algebras(and/orSetoid.Algebras.Basic), since any consumer pattern-matching on⟨ 𝑆 ⟩carriers needs it. This is the smallest change and removes the trap for example/test authors. - Optionally, note the requirement in the
Setoid.Algebras.Basicprose next to the⟨_⟩definition.
Acceptance criteria¶
- Importing
Setoid.Algebrasis sufficient to pattern-match(o , args)on a⟨ 𝑆 ⟩carrier without a separateData.Productimport. make checkpasses.
Issue M4-13: Reorganize modules: top-level Order/ tree and Setoid.Congruences promotion (#377, closed)¶
Labels:
Description¶
Two module-placement corrections that came out of the #373/#375 review discussion. Both are about putting things on the footing the library's own conventions imply.
(a) Promote congruences to a sibling of Setoid.Algebras. The library's child-vs-sibling convention is "the definition of the algebra type is a child of Algebras (Basic, Products); a major construction built on algebras is a sibling" — which is why Homomorphisms, Subalgebras, Relations, Terms, Varieties are all siblings even though they depend crucially on algebras. Congruences are the dual of subalgebras (quotients ↔ subobjects), so by that rule they belong next to Setoid.Subalgebras, not buried under Setoid.Algebras (where they currently sit only by inheritance from legacy Base.Algebras.Congruences).
(b) Move the order-theoretic lattice infrastructure to a new top-level Order/ tree. The CompleteLattice record is pure order theory — it imports only Level and Relation.Binary, with zero dependency on algebras or setoids. A top-level Order/ tree (sibling of Setoid/, Classical/, Overture/) is its honest home, and it makes the tree path self-documenting: Order.* is unmistakably the order-theoretic notion of lattice, fully disambiguated from Classical.*.Lattice, which is the distinct equational-algebra notion (a peer of groups/rings). There is no real redundancy between the two — they are the two classical presentations of "lattice," equivalent only via a theorem.
Target layout¶
src/
├── Order/
│ ├── Order.lagda.md (barrel; prose cross-refs Classical.*.Lattice)
│ └── CompleteLattice.lagda.md (moved from Setoid.Algebras.Lattices.CompleteLattice)
├── Setoid/
│ ├── Algebras/ (Basic, Products)
│ ├── Congruences/ (Basic, Lattice, Generation, CompleteLattice) ← promoted
│ ├── Subalgebras/ (…, CompleteLattice)
│ └── Relations/ Homomorphisms/ Terms/ Varieties/ …
└── Classical/ (… .Lattice modules untouched)
Tasks¶
- Create top-level
Order/tree:git mvSetoid.Algebras.Lattices.CompleteLattice→Order.CompleteLattice; add theOrderbarrel; removeSetoid.Algebras.Lattices(.lagda.md). - Promote
Setoid.Algebras.Congruences.*→Setoid.Congruences.*(Basic,Lattice,Generation,CompleteLattice); add theSetoid.Congruencesbarrel; drop theCongruencesre-export from theSetoid.Algebrasbarrel. - Rewire all imports:
Setoid.Homomorphisms.Kernels, theSetoid.Algebrasbarrel,Setoid.Subalgebras.CompleteLattice(now importsOrder.CompleteLattice), the Congruences submodules' self-references, and the examples (Examples.Setoid.{CongruenceLattice, FiniteQuotient, SubalgebraLattice, SubgroupLattice}). - Update module titles, nav links, and the
Order ↔ Classical.*.Latticecross-reference prose. nix develop --command make checkpasses.
Acceptance criteria¶
- Tree matches the target layout;
Order.CompleteLatticeandSetoid.Congruences.*resolve. - Full library type-checks (exit 0).
- Cross-reference prose added in both directions (
Order↔Classical).
Notes¶
- An algebraic ⇄ order-theoretic lattice bridge (proving the two presentations agree) is a genuinely valuable follow-up, but a theorem, not part of this reorg — track separately.
- Pure module-move + import-rewrite refactor; no proofs change. To be done on branch
377-m4-13-order-reorgafter #375 and #376 merge, so those reviews aren't rebased mid-flight.
Issue M4-14: Free expansion on raw algebra cats: symbol-adjoining left adjoint via term-algebra quotient (#400)¶
Labels: enhancement, milestone-4-style, category-theory, research-exploratory
M4-5d (#342, merged via #399) landed the free-expansion adjunction at the theory-satisfying (bundle) level: adjoinUnit ⊣ forgetUnit between Semigroups and Monoids, where the monoid equations collapse the free expansion to first-order normal forms (Maybe 𝕌[ 𝑺 ]) and no quotient is needed. This issue is the deferred stretch task of #342, plus the follow-up it flagged: construct the left adjoint to reductF φ : Alg(𝑆₂) → Alg(𝑆₁) for an arbitrary symbol-adjoining φ : SigMorphism 𝑆₁ 𝑆₂ on the raw algebra categories (no theories), and, on the same quotient infrastructure, the equation-adjoining left adjoint. The construction plan below is lifted from docs/notes/m4-5d-free-expansion.md, which records why the raw level is where setoid quotients genuinely enter.
Construction plan (raw, symbol-adjoining)¶
With no equations available, nothing collapses formal products involving the new symbols (already for Sig-Magma ↪ Sig-Monoid, a ∙ ε and ε ∙ ε are genuinely new elements), so the free 𝑆₂-algebra on a raw 𝑆₁-algebra 𝑨 is a setoid quotient of the term algebra:
- Carrier.
F 𝑨 = T_{𝑆₂}(𝕌[ 𝑨 ]) / Θ_φ(𝑨), whereΘ_φ(𝑨)is the congruence generated by the𝑆₁-operation graph of𝑨: for each symboloof𝑆₁and each tuplea : ArityOf 𝑆₁ o → 𝕌[ 𝑨 ], identifynode (ι φ o) (λ i → ℊ (a (κ φ o i)))withℊ ((o ^ 𝑨) a)— exactly the identifications that make the unit a homomorphism, and only those.Setoid.Termsprovides the term algebra andSetoid.Congruences.Generationthe generated congruence. - Unit.
ℊinto the quotient, an𝑆₁-homomorphism by the generating relations. - Counit and extension. The fold of
T_{𝑆₂}(𝕌[ 𝑨 ])into an𝑆₂-algebra𝑩along an𝑆₁-homomorphism𝑨 → reduct φ 𝑩, shown to respectΘ_φ(𝑨)(the generators map to instances of the homomorphism's compatibility); uniqueness by induction on terms. - Adjunction. Instantiate the componentwise
Adjunctionrecord ofSetoid.Categories.Adjunction(unit, counit, naturality squares,zig/zag) againstreductF φfromClassical.Categories.Reduct, between the raw categoriesAlg 𝑆₂ α ρandAlg 𝑆₁ α ρofSetoid.Categories.Algebra. Mind the level bookkeeping: the quotient carrier must land back at levels theAlgcategories share, the same constraint that forced the hand-rolled level-ρrelation inClassical.Categories.AdjoinUnit.
De-risk spike-first, as #342 did: build F for Sig-Magma ↪ Sig-Monoid on raw algebras — the free Sig-Monoid-algebra on a raw magma, whose carrier is genuinely bigger than Maybe — before generalizing over φ.
Equation-adjoining stage¶
For an inclusion into a theory (𝑆₂ , Th-X) the left adjoint is the same construction with Th-X's equations, instantiated over T_{𝑆₂}(𝕌[ 𝑨 ]) under all environments, added to the generators of the congruence. This contains the bundle-level adjoinUnit of #342 as the special case in which the quotient happens to have computable normal forms.
Cubical payoff measurement¶
The quotient is a candidate cubical-HIT payoff at v4.0 (ADR-003). Record what the setoid-quotient construction costs — lemma count, whether the proof terms stay transport-free — so the eventual port comparison is quantitative; this is the same measurement hook the milestone note attaches to M4-5e's binary-node-bridge question.
Tasks:
+ [ ] Raw spike: the free Sig-Monoid-algebra on a raw magma; unit, counit, and triangle identities against reductF magma↪monoid between the raw Alg categories.
+ [ ] Generalize F to an arbitrary symbol-adjoining φ : SigMorphism 𝑆₁ 𝑆₂.
+ [ ] Equation-adjoining left adjoint on the same quotient infrastructure (stretch).
+ [ ] Record the cubical-HIT cost-comparison data in docs/notes/m4-5d-free-expansion.md (or a successor note).
Non-goals: re-doing the bundle-level adjunction of #342; theory interpretations and the interpretability quasi-order (M4-5f, #344).
Acceptance criteria:
+ [ ] The raw spike adjunction's triangle identities type-check under --cubical-compatible --exact-split --safe.
+ [ ] The general symbol-adjoining F ⊣ reductF φ type-checks, or a design note documents the precise obstruction and the re-scope decision.
References: #338 (the M4-5 epic), #342 / #399 (the bundle-level spike this defers from), docs/notes/m4-5d-free-expansion.md § "Why the spike lives at the bundle level" and § Follow-ups, ADR-003, ADR-006.
Issue M4-15: Generalize finite op-law deciders to DecSetoid + exhaustive-search witness (#357, closed)¶
Labels: enhancement, milestone-4-style
Summary¶
The decidable equational-law checkers in Overture.Operations.Properties (Associative?, Commutative?, Idempotent?, the identity/inverse laws, and the two-operation Absorbsˡ?/Absorbsʳ?/Distributesˡ?/Distributesʳ?) are currently stated only for a finite carrier Fin n with propositional equality _≡_. Their decidability rests on exactly two ingredients:
Data.Fin.Properties.all?— the carrier is exhaustively searchable; and_≟_— equality on the carrier is decidable.
Neither ingredient is specific to Fin n or to _≡_. This issue proposes generalizing the checkers to an arbitrary DecSetoid (a setoid whose _≈_ is decidable) equipped with an exhaustive-search / finiteness witness for the carrier.
Why¶
-
Reuse. The checkers would then apply to any decidable, exhaustively-searchable carrier — not only
Fin n— so downstream finite-algebra work (CSP templates, the FLRP examples, finite quotients) could decide laws over whatever carrier is natural, without first coercing toFin n. -
A principled home. Stated over a
DecSetoid, the checkers become genuinely setoid-level content and would earn a home in theSetoid/tree (e.g. alongsideSetoid.Relations.*), rather than the≡/Fin-onlyOverture/layer where they live today. (The decision to keep the concrete versions inOverture.Operations.Propertiesfor now is recorded in #356.) -
Connection to M9-1 (Escardó's exhaustive search). The right abstraction for "exhaustively searchable" is precisely the subject of Martín Escardó's work —
Searchable/exhaustibletypes, where even some infinite types (e.g.ℕ∞, the one-point compactification ofℕ) admit a total search functional. Generalizing the deciders against such aSearchable/Exhaustibleinterface (rather than hard-codingFin'sall?) would let the same law-checkers run over those carriers, and would dovetail with the planned M9-1 work. See Escardó, Infinite sets that admit fast exhaustive search (LICS 2007) and Seemingly impossible functional programs.
Sketch¶
Roughly, replace
module _ {n : ℕ} (_·_ : Fin n → Fin n → Fin n) where
Associative? : Dec (∀ a b c → (a · b) · c ≡ a · (b · c))
Associative? = all? (λ a → all? (λ b → all? (λ c → ((a · b) · c) ≟ (a · (b · c)))))
with something parameterized over a DecSetoid S and a search/finiteness witness E for its carrier, where all? is recovered from E and ≟ from S's decidable _≈_. The existing Fin n checkers then fall out by instantiating S := ≡-decSetoid and E := Fin's all?.
Notes¶
- Keep the concrete
Fin nversions (they are what the finite examples use and they reduce well forfrom-yes); the generalized versions would sit alongside, with theFinones recovered as an instance. - This is exploratory and tied to M9-1; it does not block any current milestone.
Spun off from review discussion on #356.
Issue M4-16: Relocate the reduct development from Classical/ to Setoid/ (#403, closed)¶
Labels: milestone-4-style
Follow-up from the review of #402 (M4-5g). The notion of reduct — and the variety-level results built on it — is universal algebra: it quantifies over arbitrary signatures and signature morphisms. It is not classical algebra, where each theory studies one fixed kind of structure (groups, rings, fields) and reducts play little role. So the development belongs in Setoid/ (the universal-algebra foundation), not Classical/.
The current placement under Classical/ is genealogical, not principled. reduct was introduced in ADR-002 §5 as the engine for the classical forgetful projections (monoid→semigroup, group→monoid), so it was born in Classical.Structures; ADR-006 then kept it there ("stays in its current home") and rationalized a "Setoid.* → Classical.* would be a cycle" rule around it.
That rule is circular: the cycle exists only because reduct sits in Classical/. reduct imports only Overture.* and Setoid.Algebras.Basic — nothing from Classical/ — so the whole reduct chain can move down to Setoid/ with no cycle. Doing so also reunifies the M4-5 functorial layer, most of which (Overture.Signatures.Morphisms, Setoid.Signatures.Functor, the Setoid.Categories.* vocabulary, Overture.Terms.Translation, Setoid.Terms.*) already lives in Setoid/ / Overture/; only the reduct-touching modules were stranded in Classical/.
Scope¶
Classical.Structures.Reduct→Setoid.Algebras.Reduct(reduct,reductBy,reduct-id,reduct-∘).Classical.Categories.Reduct→Setoid.Categories.Reduct(reductF).Classical.Varieties.Invariance→Setoid.Varieties.Invariance(reduct-interp,⊧-reduct,⊧-expand).Classical.Varieties.Reducts→Setoid.Varieties.Reducts(the M4-5g module from #402; folded in when the PRs rebase — see below). The now-emptyClassical/Varieties/directory is removed.- Amend ADR-006 to reverse the "reduct stays in
Classical/" placement decision and retire the cycle rationale. - Import sweep of all consumers (
Classical.Structures.{Monoid,Group,Lattice,Ring},Classical.Categories.{AdjoinUnit,Forgetful}) and prose links (Setoid.Terms.*,Overture.Terms.Translation,Overture.Signatures.Morphisms).
Note: the moved modules are inherently two-signature, so they do not fit the single-{𝑆} umbrellas (Setoid.Algebras, Setoid.Varieties); they remain directory-resident and imported directly, as they already are.
Stays in Classical/¶
Classical.Categories.AdjoinUnitandClassical.Categories.Forgetfulare genuinely structure-specific (adjoin-a-unit to a semigroup;monoid→semigroup), so they remain — they importreductF/⊧-reductfrom the newSetoid/homes.
Interaction with #402¶
402 adds Classical.Varieties.Reducts. Whichever of #402 / this PR merges first, the other rebases. Recommended order: #402 first (so its active review is not disrupted by a path change), after which this PR folds in the Reducts → Setoid.Varieties.Reducts move.¶
Acceptance¶
nix develop --command make checkpasses (whole library).
Issue M4-17: style improvements and general clean up of Setoid modules (#434, closed)¶
Labels: milestone-4-style
Description¶
Apply new style conventions uniformly across the Setoid tree.
- clean up syntax/code-style, e.g., using dot patterns, fewer parens, etc.;
- change from one- to two- space indentation convention;
- maybe add more prose describing what the theorems say/mean.
- remove unused imports (rerun "remove unused imports" script)
Acceptance Criteria¶
- no violations of style conventions laid out in the STYLE_GUIDE doc
- any style conventions followed uniformly across modules are documented in STYLE_GUIDE
- any changes in style conventions are reflected in (updates to) the STYLE_GUIDE
Issue M4-18: Move Demos under Examples (#436, closed)¶
Labels: milestone-4-style
(no description on GitHub)
Issue M4-19: Clean up imports post-sweep (#477, closed)¶
Labels:
After the sweep that removed the signature parameter from many module definitions, the line
open import Overture using (𝓞 ; 𝓥 ; Signature ; 𝑆 )
still appears outside the start of the module, which is unnecessary when there's no top-level module parameter. We can now move the import of Overture inside with the other imports, consistent with the repo-wide style convention.
Issue M4-20: Validate kramdown attribute-span classes against Agda's own classification (#553)¶
Labels: documentation, milestone-4-style, ci
The gap¶
Every Agda name in the rendered corpus is marked up with a kramdown attribute span, `Algebra`{.AgdaRecord}, and attr_list turns the class into the CSS class that colours it. mkdocs.yml calls attr_list "THE load-bearing one" for exactly this reason.
Nothing checks that the class is the right one. check_links.py validates reference-style links, docstring_audit.py validates prose coverage, and neither looks at span classes. A span whose class disagrees with what Agda thinks the name is renders with the wrong highlighting, and no gate notices.
This surfaced in review on #552, where Copilot caught `Equivalence`{.AgdaRecord} — Equivalence A {ρ} = Σ[ r ∈ BinaryRel A ρ ] IsEquivalence r is a Σ-type alias, so a function, not a record. Looking for siblings found four more.
Four confirmed defects on master¶
| file | span | actually |
|---|---|---|
Classical/Structures/Lattice/Parachute.lagda.md (4 occurrences: 42, 65, 272, 594) |
`_≤ᵖ_`{.AgdaFunction} |
data _≤ᵖ_ : P → P → Type (α ⊔ ρ) at :261 |
Examples/Setoid/HSPCommutativeMonoid.lagda.md:101 |
`𝒦₀`{.AgdaFunction} |
data 𝒦₀ : Pred (Algebra 0ℓ 0ℓ) 1ℓ at :78 |
FLRP/Problem.lagda.md:121 |
`Lattice-Order`{.AgdaRecord} |
module Lattice-Order … at Classical/Properties/Lattice.lagda.md:58 |
FLRP/Representable.lagda.md:149 |
`Signature`{.AgdaRecord} |
Signature 𝓞 𝓥 = Σ[ F ∈ Type 𝓞 ] (F → Type 𝓥) at Overture/Signatures.lagda.md:91 |
The last is the same error class as the Equivalence one: a Σ-bundle type alias read as a record because it behaves like one.
Scale¶
Measured over src/**/*.lagda.md: 2198 span occurrences, 990 distinct (name, class) pairs, across 11 classes. The distribution is AgdaFunction 1404, AgdaRecord 257, AgdaBound 156, AgdaInductiveConstructor 112, AgdaField 110, AgdaDatatype 79, AgdaModule 73, and single digits of AgdaGeneralizable, AgdaKeyword, AgdaPrimitiveType, AgdaSymbol.
docstring_audit.py --json already emits a kind per public definition — signature (3060), module (72), record (61), data (50), pattern (31) — so ground truth for a large fraction of spans is already computed and needs no new parser.
The naive design does not work, and this is the main finding¶
Matching a span's name against the audit's kind by name alone produces 126 hits, of which only the 4 above are real. The 122 false positives come in two shapes, and both are legitimate markup:
AgdaBound, 94 hits.`N`{.AgdaBound}inside a paragraph refers to a locally bound variable. That a top-level definition namedNexists elsewhere is irrelevant, and marking the bound occurrence.AgdaBoundis correct.AgdaField, 16 hits.`to∘from`{.AgdaField}names a record field, which is not a top-level definition at all — ADR-010 deliberately excludes fields, members and constructors from the audit's inventory — so the audit has no entry to compare against and a same-named function elsewhere produces a spurious hit.
The rest are cross-module name collisions: `Lattice`{.AgdaRecord} in Setoid/Subalgebras/CompleteLattice.lagda.md is stdlib's Relation.Binary.Lattice.Lattice, a genuine record, while Classical/Small/Structures/Lattice defines an unrelated Lattice alias. Same for Group, List, and the generalizable 𝑨.
So a useful checker needs name resolution in the scope of the file the span sits in, not a global name table. A checker without it would emit 30 false positives for every real one and be switched off within a week — which is the outcome ADR-010 already warns about for un-ratcheted gates.
Two designs that could work¶
- Ask Agda.
agda --htmlemits<a class="Agda…">spans with Agda's own classification, per file and per occurrence. Rendering the corpus once and diffing our span classes against the highlighter's is the only approach that is right by construction, including for fields, constructors and bound variables. Cost: an HTML build in CI, and a mapping from source positions to the generated anchors. - Ask
agda-mcp.resolve_nameanswers "what does this name resolve to here", scoped to a file, with provenance. That is exactly the missing ingredient, and it handles the collisions. Cost: it is a live interaction lane, so a whole-corpus sweep is one load per file, and the server is currently single-worktree (arootMismatchguard refuses files from any other checkout).
Design 1 is the better fit for a gate; design 2 is the better fit for a one-off sweep to clear the existing backlog. They are not exclusive.
Done when¶
- A checker under
scripts/python/reports spans whose class disagrees with Agda's classification, with zero false positives on current master. - The four defects above are fixed, plus whatever the sweep adds.
- A
Makefiletarget and a CI job, followingcheck_links/docstring_audit(see thewriting-a-corpus-linterconventions), ratcheted if the backlog cannot be cleared in one pass. - Validated the way #537's audit was: against Agda's own answer, not against the checker's author's expectations.
Notes¶
- Related: #537 (the docstring audit and its ratchet), ADR-010 (which fixes what counts as a public definition, and why fields and constructors are excluded), #275 (the corpus extractor, another consumer of correct span classification).
- There is a second, cheaper unchecked-markup gap worth folding in or splitting out: dangling footnote references.
[^1]with no[^1]:definition renders as literal text and passes every gate. Two exist on master, inOverture/Basic.lagda.mdandClassical/Structures/Group/Complexes.lagda.md. That one is a few lines of regex and needs no Agda at all.
---¶
Milestone 5 — Cubical track¶
Issue M5-1: Cubical track — Cubical/Algebras/Basic with SIP and Monoid port (#270)¶
Labels: milestone-5-cubical
Description¶
Cubical Agda is the canonical long-term target for this library. This issue establishes the path: port the core algebra types, prove the structure identity principle (SIP), and demonstrate end-to-end workflow by porting Monoid from the Setoid-based Classical layer to a Cubical counterpart. The ultimate goal is for Cubical to become the default development track in version 3.0, with Setoid/ moving to Legacy.
Design implication for M3: the Classical layer must be designed so that the Setoid-to-Cubical port is mechanical — equations stated purely in terms of the Algebra record's Domain equivalence, no Setoid-specific gadgets in the definitions of classical structures themselves.
Tasks¶
-
Cubical/Algebras/Basic.agda: cubical counterpart ofSetoid.Algebras.Basic. Carrier is a Type; equality is the path type. -
Cubical/Algebras/SIP.agda: structure identity principle. Port or adapt from thecubicalor1Lablibrary. - Prove:
≅as defined for Cubical algebras is equivalent to path equality (the central "transport does what we want" result). - End-to-end port: take
Classical/Structures/Monoid.agdafrom the Setoid-based version (post M3-4) and produce the Cubical analog. Verify that equations transport by substitution alone. - Write
docs/adr/003-cubical-canonical-target.mdexplicitly planning the 3.0 transition and the criteria for promoting Cubical from experimental to canonical.
Acceptance criteria¶
-
Cubical/Algebras/Basic.agdaandSIP.agdacompile under--cubical. - The
≅-is-path theorem is proved. -
Cubical/Classical/Monoid.agdacompiles and is substitutionally derived from its Setoid analog. - ADR-003 is merged.
Issue M5-2: Monitor agda/agda-stdlib#2967 and finalize cubical-port flag strategy (#279)¶
Labels: agda-stdlib, milestone-5-cubical, stdlib-bridge, cubical, blocked-upstream
Context¶
The agda-stdlib maintainers are considering reverting from --cubical-compatible to --without-K for stdlib v3.0. See agda/agda-stdlib#2967 (opened 2026-03-20 by @Taneb; open, under discussion).
For agda-algebras this has concrete implications:
- Type-checking speed. The Agda 2.6.3 changelog reports ~30% faster type-checking for stdlib under plain
--without-Kvs--cubical-compatible, and ~10% faster even with-WnoUnsupportedIndexedMatchenabled. Across the lifetime of agda-algebras 2.0 this is substantial. - Import firewall. Code that uses only
--without-Kcannot be imported from code that uses--cubical. If stdlib v3.0 lands on--without-K, a futuresrc/Cubical/tree that uses--cubicalcannot import stdlib at all; it would needagda-cubical(or re-derivation) for anything stdlib-shaped. The converse direction (--cubical-compatibleimporting--without-K) is fine. - Warning noise. Under stdlib 2.3 we currently face
UnsupportedIndexedMatchwarnings on many of our own pattern-matching definitions. Either we live with the noise or suppress with-WnoUnsupportedIndexedMatch. A stdlib 3.0 revert makes this go away for stdlib's types but not for agda-algebras-internal definitions, unless we also switch our code to--without-K.
Tasks¶
- Watch agda/agda-stdlib#2967. Track the discussion; note the final decision (reverted as proposed, compromise, or
--without-K-with-opt-in). - Benchmark
--cubical-compatible→--without-Kon our own code. Branch experiment: add{-# OPTIONS --without-K --exact-split --safe #-}pragmas acrossSetoid/andClassical/, measuremake checkwall-clock delta. This is decidable today, independent of upstream. - Decide and document the
src/Cubical/→ agda-cubical strategy. Write up indocs/FLAGS.md(new file) so future contributors understand the firewall and why. The current best guess:Setoid/andClassical/remain--cubical-compatible(or move to--without-Kafter benchmark);Cubical/uses--cubical, importsagda-cubicalinstead of stdlib, and re-derives / imports-from-agda-cubical whatever stdlib types it needs. - (Deferred) Prepare comment for agda/agda-stdlib#2967. agda-algebras is a non-trivial downstream with stated cubical ambitions; the maintainers benefit from knowing our position. Hold until we have hands-on experience with agda-cubical in
src/Cubical/(see M5) — the comment should be factual ("here is what this PR means for us in practice"), not advocacy.
Relation to other milestones¶
- Informs M5 (Cubical port) fundamentally — the flag strategy for
src/Cubical/is decided here. - May inform M4 (style sweep) if a library-wide flag change lands.
- Does not block M2 or M3.
Non-goals¶
- Not blocking any other milestone; this is a monitoring issue.
- Not changing agda-algebras flags in response to a not-yet-merged upstream PR; any change lands via a separate, sweep-style PR when the decision is made.
---¶
Milestone 6 — Toward the Finite Lattice Representation Problem¶
Issue M6-1: Con(A) as a complete lattice (#271, closed)¶
Labels: milestone-6-flrp
Description¶
The current Setoid.Algebras.Congruences defines congruences but does not organize them as a lattice. For the FLRP, commutator theory, and subdirect product theorems, Con 𝑨 as a complete lattice is foundational infrastructure. Likely requires a congruence-generation theorem as a subsidiary result.
Tasks¶
- Define
Con 𝑨as a type (may exist already; promote to a first-class lattice object). - Define the partial order
_≤_(containment). - Define meet:
θ ∧ φ = θ ∩ φ. - Define join:
θ ∨ φ = Cg(θ ∪ φ)(congruence generated by union). -
Con-Lattice : (𝑨 : Algebra α ρ) → Lattice _ _. -
Con-CompleteLatticewith infinite meets and joins. - Zero and total congruences as
0ᴬand1ᴬ. - Subsidiary: congruence-generation theorem.
Acceptance criteria¶
-
Con-Lattice 𝑨type-checks and satisfies the Lattice axioms. - Infinite meets and joins are proved.
- At least one small worked example (e.g.
Conof a 2-element algebra).
Issue M6-2: Subdirect products and subdirectly irreducible algebras (#272, closed)¶
Labels: milestone-6-flrp
Description¶
Subdirect products and subdirect irreducibility are foundational for both the FLRP and for general universal-algebraic theorems (e.g. Birkhoff's subdirect representation theorem).
Tasks¶
-
SubdirectProduct/ subdirect embedding — landed asIsSubdirectEmbedding/SubdirectEmbedding(Setoid.Subalgebras.Subdirect): an injective hom into⨅ 𝒜whose every coordinate projection is surjective (the standard relational presentation of "a subalgebra of⨅ 𝒜meeting every factor", rather than a separately-constructed algebra). -
IsSubdirectlyIrreducible : Algebra α ρ → Type _— landed (Setoid.Congruences.Monolith), defined asNontrivial × HasMonolith. - Birkhoff's subdirect representation theorem — the choice-free core is proved (
SIRep→Representable: a separating SI-family of congruences yields a subdirect embedding into a product of SI algebras);Birkhoff-subdirectproves the full statement relative to an explicit choice principle (SubdirectSIRepexistence), the Zorn step isolated as a module parameter rather than postulated. - SI characterization via monolithic congruences —
monolith⇒cmi(a monolith makes0ᴬcompletely meet-irreducible) and the binary instancemonolith⇒∧-irreducible(0ᴬis meet-irreducible); plusmonolith-unique.
Acceptance criteria¶
- Subdirect product construction type-checks —
Setoid.Subalgebras.Subdirecttype-checks undermake check. - Birkhoff's subdirect representation theorem is proved — constructive core in full; the choice-dependent existence is an explicit module parameter (mirrors M6-3's handling of choice-dependent theorems). See the design note.
- SI characterization is proved — the forward direction (monolith ⟹ completely meet-irreducible) is proved constructively; the converse is predicativity-blocked and recorded as a follow-up.
Status — first pass (PR #418)¶
The constructive core of subdirect representation theory landed in two modules:
Setoid.Congruences.Monolith—Nontrivial/Trivial,Nonzerocongruences, the infinitary meet⋂,IsMonolith/HasMonolith/monolith-unique,IsSubdirectlyIrreducible, and the characterizationmonolith⇒cmi/monolith⇒∧-irreducible.Setoid.Subalgebras.Subdirect—⨅-proj,coord,IsSubdirectEmbedding/SubdirectEmbedding/subdirect→≤; the bridgeseparating→SubdirectEmbedding(withnatmap-injective/natmap-separates, and arefl-checkedIsInjective (proj₁ natmap) ≡ Separates, showing injectivity is definitionally the separation hypothesis "the meet is the diagonal"); andBirkhoff-subdirect, the subdirect representation theorem relative to the choice principleSubdirectSIRep.
The choice/Zorn decision (option (a): explicit module parameter), the constructive-¬¬ reason the parameter is a separating SI-family rather than per-pair maximal congruences, the predicativity wall blocking the cmi-⟹-monolith converse, and the level conventions are recorded in docs/notes/m6-2-subdirect.md. Follow-ups: the constructive finite case (option (b), discharging the parameter by search when ≈ is decidable); the impredicative converse; and linking SI to the absence of a nontrivial subdirect decomposition.
Issue M6-3: Basic Maltsev conditions (CD, CM, CP) (#273, closed)¶
Labels: milestone-6-flrp, design-discussion
Description¶
Maltsev conditions characterize varieties by the existence of terms with specific properties. The three most basic are congruence distributivity (CD), congruence modularity (CM), and congruence permutability (CP). For the FLRP, congruence modularity is particularly relevant because modular congruence lattices are a natural testing ground for representation questions.
Design discussion: how to encode Maltsev conditions uniformly? Options include (a) a record bundling a term and its identities; (b) an inductive type of schemes. Lift from Taylor 1977 where possible.
Tasks¶
-
HasMaltsevTerm : Variety → Term → Type— landed as the interpretation predicateHasMaltsevTerm ℰ = Th-Maltsev ≼ ℰ(Setoid.Varieties.Maltsev). - Specific Maltsev terms: Jónsson terms (CD), Day terms (CM), Maltsev operation (CP) —
Th-Maltsev,Th-Jonsson n,Th-Day n, withHasMaltsevTerm/HasJonssonTerms n/HasDayTerms n(Setoid.Varieties.Maltsev). - Jónsson's theorem: a variety is CD iff Jónsson terms exist — stated (
Jonsson-Statement); proof tracked in #412 (forward) and #413 (converse). - CP iff a Maltsev term exists — forward direction
MaltsevTerm⇒CP/maltsev⇒CP(M6-3, #409); converseCP⇒maltsev(Setoid.Varieties.Maltsev.Permutability, M6-5, #411) inhabitingCP⇒maltsev-Statement, built on the free-algebra bridge (Setoid.Varieties.FreeSubstitution, M6-4, #410). - Day's theorem for CM — stated (
Day-Statement); proof tracked in #412 (forward) and #413 (converse).
Acceptance criteria¶
- At least CP's Maltsev-term characterization is proved —
MaltsevTerm⇒CP/maltsev⇒CPinSetoid.Varieties.Maltsev.Permutability(the concrete "term ⟹ permutable" direction). - Jónsson's theorem and Day's theorem are either proved or have a clear stub indicating what remains — both stated as checked, uninhabited
Types, with construction plans indocs/notes/m6-3-maltsev-conditions.md.
Status — first pass (PR #409)¶
The CP track landed in PR #409:
Setoid.Congruences.Permutability— relation compositionθ ∘ φ, thePermutespredicate (θ ∘ φ ⊆ φ ∘ θ), andCongruencePermutable.Setoid.Congruences.Properties—CongruenceDistributiveandCongruenceModular.Setoid.Varieties.Maltsev.{Basic,Permutability,Distributivity,Modularity}(split from the originalMaltsevConditionsmodule in #428, re-exported bySetoid.Varieties.Maltsev) —term-compatible; the forward Maltsev theoremMaltsevTerm⇒CP/maltsev⇒CP; the Jónsson and Day term theories; and the deferred theorems (CP⇒maltsev-Statement,Jonsson-Statement,Day-Statement) as checkedTypestatements.- Design note:
docs/notes/m6-3-maltsev-conditions.md.
The chosen encoding is the interpretation Th-X ≼ ℰ (preferred over the issue's options (a) record and (b) inductive scheme; see the note).
Deferred proofs are tracked in successor issues: #410 ([M6-4] free-algebra Cg↔derivability bridge — landed, Setoid.Varieties.FreeSubstitution), #411 ([M6-5] CP converse — landed, CP⇒maltsev in Setoid.Varieties.Maltsev.Permutability), #412 ([M6-6] forward Jónsson/Day — landed), #413 ([M6-7] converse Jónsson/Day — landed). See the design note docs/notes/m6-4-free-bridge.md for #410 / #411.
Issue M6-4: Free-algebra congruence/derivability bridge (infrastructure for the Maltsev-condition converses) (#410, closed)¶
Labels: milestone-6-flrp
Description¶
The converse directions of the basic Maltsev conditions (a lattice property of Con 𝑨 ⟹ the existence of terms) are all proved the same way: read equational identities off the congruences of the relatively free algebra 𝔽[ X ]. This issue builds the reusable bridge that all of them need — between the generated congruence Cg R on 𝔽[ X ] and derivability _⊢_▹_≈_ — so the converse issues ([M6-5], [M6-7]) can consume it rather than each re-deriving it.
It is the single biggest lever identified in the M6-3 design note: built once, it unlocks the CP, CD, and CM converses.
Background¶
- M6-3 (#273, PR #409) landed the CP layer and the forward Maltsev theorem, and stated the deferred converses as checked, uninhabited
Types (CP⇒maltsev-Statement,Jonsson-Statement,Day-Statement). - Construction plan and rationale:
docs/notes/m6-3-maltsev-conditions.md, § "The deferred theorems and their construction plans".
Tasks¶
- Substitution-induced homomorphism
𝔽[ X ] → 𝔽[ Y ]from a map of variables (X → Term Y, and the special caseX → Y), with the proof that it is a homomorphism — its action on a term is substitution_[_], which commutes withnodeby definition. - Package the kernel of a homomorphism as a
Con(compatibility isHomKerCompinSetoid.Homomorphisms.Kernels; add the equivalence andreflexivefields). - The bridge lemma: for a relation
Ron𝔽[ X ]cut out by finitely many identified pairs,Cg R ⊆ ker hfor any homhthat collapses those pairs (immediate fromCg-least); hence membership in a principal congruenceCg {(s , t)}yields a derivable equation in the quotient. - The impedance shims between the
Idx → Term × Termtheory shape used by_≼_and theI → Eqshape used by_⊢_▹_≈_/𝔽[_], in both directions, so a witness term extracted in𝔽can be packaged as anInterpretationand discharged via⊧-interp+ soundness.
Dependencies¶
- None beyond what M6-3 (#273, PR #409) landed. This is the prerequisite for [M6-5] and [M6-7].
Acceptance criteria¶
- The bridge lemmas type-check under
--cubical-compatible --exact-split --safe. - At least one smoke-test consumer: recover a single derivable identity from a principal-congruence membership on
𝔽[ X ].
References¶
Setoid.Varieties.SoundAndComplete(𝔽[_],satisfies, soundness/completeness);Setoid.Congruences.Generation(Cg,Cg-least);Setoid.Homomorphisms.Kernels(HomKerComp);Setoid.Varieties.Interpretation(⊧-interp).- Burris and Sankappanavar, A Course in Universal Algebra, Ch. II.
Status — landed¶
The bridge originally landed as Setoid.Varieties.FreeBridge, dissolved in the #428 cleanup; its API now lives in Setoid.Varieties.FreeSubstitution: subhom / renhom (the substitution-induced hom out of 𝔽[ X ], a homomorphism by refl), cg-pair→⊢ / cg-pairs→⊢ (the bridge lemma, one line via Cg-least), and the smoke test recover / recover-gen / recover-swap. Its dependencies were distributed to Setoid.Homomorphisms.Properties (Cg⊆ker, and the re-exported kernel-as-Con kercon), Setoid.Congruences.Generation (the principal relation ❴_,_❵), and Setoid.Varieties.SoundAndComplete (the toEq shim — the two satisfaction predicates _⊨ₑ_ / _⊨_ coincide definitionally, so no conversion function is needed). The term-level companion graft≐[] (identifying _✦_'s graft with _[_]) lives with the other laws of graft in Setoid.Terms.Interpretation. Design note: docs/notes/m6-4-free-bridge.md.
🤖 Generated with Claude Code
https://claude.ai/code/session_01MvPrLTCxKjFgsnTMK8j2qZ
Issue M6-5: Converse of Maltsev's theorem: congruence-permutable ⟹ Maltsev term (#411, closed)¶
Labels: milestone-6-flrp
Description¶
Complete the congruence-permutability characterization by proving the converse of Maltsev's theorem: a congruence-permutable variety has a Maltsev term. Concretely, inhabit CP⇒maltsev-Statement in Setoid.Varieties.Maltsev.Permutability. M6-3 (#273, PR #409) proved the forward direction (MaltsevTerm⇒CP); together they give the iff.
Background¶
Construction (Burris–Sankappanavar, Thm. 12.2), detailed in docs/notes/m6-3-maltsev-conditions.md:
- Work in
𝔽[ Fin 3 ], the relatively free algebra on three generatorsx , y , z; it is a model ofℰ(satisfies), hence congruence-permutable by hypothesis. - Take the principal congruences
θ = Cg(x , y)andφ = Cg(y , z). Fromx θ yandy φ zwe get(x , z) ∈ θ ∘ φ; permutability gives(x , z) ∈ φ ∘ θ, i.e. a witnesswwithx φ wandw θ z. - Since the carrier of
𝔽isTerm (Fin 3),wis literally a termM(x , y , z). Translatingx φ wandw θ zthrough the collapsing-substitution homomorphisms (z ↦ y, resp.x ↦ y) yieldsM(x , y , y) ≈ xandM(x , x , y) ≈ y— the two Maltsev identities. - Package
Mas the interpretationTh-Maltsev ≼ ℰand discharge via⊧-interp+ soundness.
Note: #273's text says "the free algebra on two generators"; the standard construction is on three generators x , y , z, since the Maltsev term has three variables.
Tasks¶
- Build the principal congruences and the
θ ∘ φmembership in𝔽[ Fin 3 ]; apply the CP hypothesis. - Extract the witness
was a term and translate both memberships to the two identities via the [M6-4] bridge (#410). - Assemble the interpretation and inhabit
CP⇒maltsev-Statement.
Dependencies¶
- [M6-4] (#410) — the free-algebra congruence/derivability bridge. This is the smallest client of that bridge and a good first validation of it.
Acceptance criteria¶
CP⇒maltsev-Statementis inhabited; withmaltsev⇒CP, congruence permutability is characterized by the Maltsev term (a complete iff).
References¶
- A. I. Mal'cev, On the general theory of algebraic systems (Russian), Mat. Sb. (N.S.) 35(77) (1954), 3–20; Engl. transl., Amer. Math. Soc. Transl. (2) 27 (1963), 125–142. Math-Net.Ru.
- Burris and Sankappanavar, A Course in Universal Algebra, Thm. II.12.2.
Status — landed¶
CP⇒maltsev (in Setoid.Varieties.Maltsev.Permutability) inhabits CP⇒maltsev-Statement at the levels of 𝔽[ Fin 3 ], for theories with variables X : Type 0ℓ (forced by the single-level free-algebra interface; no restriction for finitary theories). The collapsing substitutions are chosen to coincide with the _✦_ position maps, so the bridge output is definitionally the interpreted Maltsev identity up to one graft≐[] step. With maltsev⇒CP, congruence permutability is now a complete iff. Design note: docs/notes/m6-4-free-bridge.md.
🤖 Generated with Claude Code
https://claude.ai/code/session_01MvPrLTCxKjFgsnTMK8j2qZ
Issue M6-6: Forward Jónsson/Day: Jónsson terms ⟹ CD and Day terms ⟹ CM (#412, closed)¶
Labels: enhancement, milestone-6-flrp
Description¶
Prove the "terms ⟹ lattice property" halves of Jónsson's and Day's theorems: a variety with Jónsson terms is congruence-distributive, and a variety with Day terms is congruence-modular. These are the second projections of Jonsson-Statement and Day-Statement in the Setoid.Varieties.Maltsev subtree (Jonsson-Statement in Maltsev.Distributivity, Day-Statement in Maltsev.Modularity): with P ⇔ Q = (P → Q) × (Q → P) and Jonsson-Statement = CongruenceDistributiveVariety ⇔ (Σ n, HasJonssonTerms n), the term ⟹ CD direction is proj₂ (Q → P), not the first projection. (The original text said "first projections"; corrected here.)
These halves are independent of [M6-4] (#410): they use the chain terms available on every algebra via the interpretation, plus term-compatible and an induction over the join.
Status: COMPLETE (forward Jónsson in PR #428; forward Day in PR #442)¶
Forward Jónsson: DONE — including the featured finitary theorem, unconditionally.
- The former monolithic
MaltsevConditionsmodule was split intoSetoid.Varieties.Maltsev.{Basic,Permutability,Distributivity,Modularity}(re-exported by theSetoid.Varieties.Maltsevumbrella); the Jónsson development lives inMaltsev.Distributivity. - Generalized the curried-term extraction from one ternary symbol to the
Fin (n+1)Jónsson chain (d𝑩/eval-d/d-fst/d-lst/d-mid/d-compat). - The two-part staircase: the horizontal lemma (induction on the chain) and the vertical induction over the rungs (
Data.Fin.Induction.<-weakInduction, whoseinject₁ i → suc istep lines up with the parity-split forkd-fork i). jonsson⇒chainDistributive— the forward inclusionθ ∧ (φ ∨ ψ) ⊆ (θ∧φ) ∨ (θ∧ψ)along every chain, fully general (no finiteness).jonsson⇒CongruenceDistributive/jonsson⇒CongruenceDistributiveVariety— the literalCongruenceDistributive/CongruenceDistributiveVariety(theproj₂direction ofJonsson-Statement), modulo the one isolated hypothesisJoinIsChain.jonsson-finitary⇒CongruenceDistributiveVariety— the featured theorem: a variety over a finitary signature with Jónsson terms is congruence-distributive, with no residual side condition. This is the form a working algebraist applies; universal algebra in practice means finitary algebras.
The Gen-vs-chain obstruction: named once, then discharged for finitary signatures. The library's join is Cg(φ ∪ ψ) = Gen(φ ∪ ψ), the inductively-generated congruence whose comp constructor closes it under the basic operations (necessary and correct for infinitary signatures, whose arities are arbitrary types). The Jónsson-term "sandwich" relation dᵢ(a,u,b) γ dᵢ(a,v,b) is provably not closed under comp, so a direct Gen-induction cannot carry the staircase, and for an infinitary signature the join strictly exceeds the finite-chain closure. The forward theorem is therefore proved against Chain in full generality, the lone missing step Gen(φ ∪ ψ) ⊆ Chain is isolated as the explicit hypothesis JoinIsChain, and that hypothesis is then discharged for finitary signatures in the module Setoid.Congruences.ChainJoin (finitary⇒JoinIsChain): Chain 𝑩 (φ ∪ᵣ ψ) is shown to be a congruence (operation-closed via the one-coordinate-at-a-time fold chain-op over a finite-arity enumeration Finitary 𝑆), hence contains the generated join by Cg-least. The Examples.Setoid.FinitarySignatures module shows the Finitary witness is a hoop-free one-liner (λ _ → _ , ↔-id _).
Forward Day: DONE (PR #442) — by a genuinely different ladder, not a mirror. As predicted, Day's mᵢ(x,y,y,x) ≈ x pinning requires the two middle arguments equal, so the even-fork column mᵢ(a,a,b,b) is not ψ-pinnable and the Jónsson two-column staircase does not transfer. The construction that landed is Day 1969 in the streamlined form of Freese–McKenzie (Commutator Theory for Congruence Modular Varieties, Thm 2.2 and Lemma 2.3), inlined into a single chain-level induction in Setoid.Varieties.Maltsev.Modularity:
m-collect(FM Lemma 2.3), for an arbitrary congruenceμ: givenb μ d, rung-wiseμ-relations between the ladder columnsmᵢ(a,a,c,c)andmᵢ(a,b,d,c)collect intoa μ c. The unpinnable even-fork column is never pinned — it is carried by the hypothesis pair, which is the two-dimensional aspect of Day's construction.Day⇒chainModular— the modular inclusion(θ ∨ ϕ) ∧ ψ ⊆ θ ∨ (ϕ ∧ ψ)(forθ ⊆ ψ) along every θ/ϕ-chain, fully general (no finiteness): an outer induction on the number of ϕ-steps whose decrease comes from fusing the two flanking ϕ-steps of the heada ϕ t₁ θ t₂ ϕ t₃ ⋯into a single two-slotm-compatmove, with the remaining chain pushed through the third slot ofmᵢ(m-push) and the induction hypothesis applied to the ψ-railed pair(mᵢ(a,t₁,t₂,c), mᵢ(a,a,c,c)).Day⇒CongruenceModular(moduloJoinIsChain, applied once, to the hypothesis join),Day+finjoin⇒CM, and the unconditional finitaryDay⇒CM.Day-theorem— the complete iff, assembled with the M6-7 converseCM⇒Day(#413, PR #440), which now takes itsFinitarywitness as an explicit argument, mirroringCD⇒jonsson.
With this, all three classical Maltsev-condition theorems (Maltsev/CP, Jónsson/CD, Day/CM) are proved in both directions.
Remaining tasks¶
None — this issue is complete once PR #442 merges.
Dependencies¶
- None beyond M6-3 (#273, PR #409): reuses
term-compatible, the curried-extraction pattern, and the congruence lattice (Setoid.Congruences.{Lattice,Generation,Properties}). Independent of [M6-4] (#410).
Acceptance criteria¶
- Forward Jónsson type-checks under
--safe; the term ⟹ CD direction of Jónsson's theorem is done, and the finitary version is unconditional. ✅ (PR #428;make checkpasses.) - Forward Day type-checks under
--safe; the term ⟹ CM direction of Day's theorem is done, the finitary version is unconditional, andDay-theoremassembles the complete iff. ✅ (PR #442;make checkpasses.)
Notes¶
- Difficulty: the Jónsson half was moderate as expected; the realized work surfaced two findings — the
Gen-vs-chain (infinitarycomp) obstruction, discharged for finitary signatures, and that Day is not a mechanical mirror of Jónsson. The Day half then required the genuinely two-dimensional FM Lemma 2.3 ladder, with a ϕ-count measure whose decrease is a two-steps-into-one fusion. All of this is recorded indocs/notes/m6-6-forward-jonsson-day.md("Why Day is not a mirror — and the ladder that works").
References¶
- B. Jónsson, Algebras whose congruence lattices are distributive, Math. Scand. 21 (1967), 110–121. doi:10.7146/math.scand.a-10850 (open access).
- A. Day, A characterization of modularity for congruence lattices of algebras, Canad. Math. Bull. 12 (1969), 167–173. doi:10.4153/CMB-1969-016-6.
- R. Freese and R. McKenzie, Commutator Theory for Congruence Modular Varieties, LMS Lecture Note Series 125, Cambridge University Press (1987), Thm 2.2 and Lemma 2.3. Free online edition.
- Burris and Sankappanavar, A Course in Universal Algebra, Thms. II.12.6 (Jónsson) and II.12.4 (Day).
🤖 Generated with Claude Code
https://claude.ai/code/session_011crz6XaiE4uecELazSkJFY
Issue M6-7: Converse Jónsson/Day: CD ⟹ Jónsson terms and CM ⟹ Day terms (#413, closed)¶
Labels: enhancement, milestone-6-flrp, research-exploratory
Description¶
Complete Jónsson's and Day's theorems with the hard "lattice property ⟹ terms" directions: a congruence-distributive variety has Jónsson terms, and a congruence-modular variety has Day terms. These inhabit the converse projections of Jonsson-Statement and Day-Statement (with the orientation P ⇔ Q = (P → Q) × (Q → P) fixed in #412, the CD ⟹ terms direction is the first projection; the original text said "second"), turning both into complete iffs. Following the #428 module split, the statements live in Setoid.Varieties.Maltsev.{Distributivity,Modularity}.
This is the research-grade end of the M6-3 track. Beyond the [M6-4] (#410) bridge, it requires extracting the chain length n and the terms dᵢ / mᵢ from the inductive derivation witnessing a join membership — the source of the Σ[ n ∈ ℕ ] in the statements, and the part with no off-the-shelf analogue in the library.
Background¶
Construction (Burris–Sankappanavar, Thms. 12.6 and 12.4), sketched in docs/notes/m6-3-maltsev-conditions.md:
- Work in
𝔽[ Fin 3 ](Jónsson) /𝔽[ Fin 4 ](Day); set up the principal congruences whose distributive / modular identity forces the chain. - Extract
n : ℕand the parity-correct chain of terms from theGenderivation witnessing the relevant join membership. - Package the chain as an interpretation and discharge via
⊧-interp+ soundness (through the [M6-4] bridge).
Status (PRs #438, #440): COMPLETE¶
Converse Jónsson: DONE — and Jónsson's theorem is a complete iff for finitary signatures. CD⇒jonsson inhabits the CD ⟹ terms direction of Jonsson-Statement, and jonsson-theorem assembles both halves, all in Setoid.Varieties.Maltsev.Distributivity, next to the statement and the M6-6 forward half.
- The crux, realized. The chain-length extraction is
finitary⇒JoinIsChain(M6-6,Setoid.Congruences.ChainJoin) applied in𝔽[ Fin 3 ]to the membership(x , z) ∈ (θ∧φ) ∨ (θ∧ψ)that distributivity produces fromθ = Cg ❴x,z❵,φ = Cg ❴x,y❵,ψ = Cg ❴y,z❵; the chain length is theΣ[ n ∈ ℕ ], and the chain elements — terms, since the carrier of𝔽[ Fin 3 ]isTerm (Fin 3)— are the Jónsson termsd₀ … dₙ. - The one genuinely new piece is parity normalization (
ParityChain/chain→parity): the chain's steps arrive in arbitrary tag order, whileTh-Jonsson's forks demand(θ∧φ)-steps at even and(θ∧ψ)-steps at odd positions. Mismatches are padded with congruence-reflexivity steps;pconsswaps the two relations in its tail, soeven? (suc k) = not (even? k)keeps the parity bookkeeping definitional (no numeric lemmas). - Parity cross-check (third task, Jónsson half): confirmed. Even forks collapse
y ↦ x(the φ-pair), odd forks collapsez ↦ y(the ψ-pair) — exactly the normalized chain's even/odd step relations, matchingTh-Jonsson'seven?split. - Everything else is the
CP⇒maltsevpattern (M6-4/M6-5): the bridgecg-pair→⊢per identity family, collapsing substitutions chosen to be theI ✦position maps (so every collapse condition isrefland onlygraft≐[]shims remain), and⊧-interp+soundto discharge satisfaction in an arbitrary model; the θ-tie of every chain element toxis a<-weakInductionover the rungs. - The
Finitaryhypothesis is inherited from the M6-6 chain collapse, so both directions ofjonsson-theoremcarry the same one-liner witness; the levels are those of the free-algebra construction (𝔽[ Fin 3 ] : Algebra (lsuc 0ℓ) (ι ⊔ lsuc 0ℓ), variable typeX : Type 0ℓ), the same instantiation asCP⇒maltsev. - Design note:
docs/notes/m6-7-reverse-jonsson.md; roadmap updated indocs/GITHUB_PROJECT.md.
Converse Day: DONE (PR #440) — this completes the issue. CM⇒Day (born CM⇒day; renamed, and given an explicit Finitary 𝑆 argument mirroring CD⇒jonsson, in PR #442) inhabits the CM ⟹ terms direction of Day-Statement in Setoid.Varieties.Maltsev.Modularity, the planned mechanical mirror of CD⇒jonsson over 𝔽[ Fin 4 ] (Burris–Sankappanavar II.12.4).
- The congruences are
θ = Cg ❴y,z❵,φ = Cg ❴x,y❵ ∨ Cg ❴z,u❵,ψ = Cg ❴x,u❵ ∨ Cg ❴y,z❵, withθ ⊆ ψthe modular side condition;(x , u)lies in(θ ∨ φ) ∧ ψ, and the modular law read right to left moves it intoθ ∨ (φ ∧ ψ), whencefinitary⇒JoinIsChainextracts the Day chain. - Day's
φandψare joins of two principal congruences, so their collapsing substitutions must kill two generator pairs at once: the two-pair bridgecg-pairs→⊢(added toSetoid.Varieties.FreeSubstitution, next tocg-pair→⊢) is the one new piece of machinery — a single⊎-split over the sameCg⊆kerargument. - Parity cross-check (third task, Day half): confirmed. The modular join carries its θ-steps in the first
∪ᵣtag whileTh-Day's even forks are the φ-collapses, so the normalization is the off-phase passchain→parityᵒ: even forks collapsey ↦ x , z ↦ u(the two φ-pairs), odd forksz ↦ y(the θ-pair), and the middle familymᵢ(x,y,y,x) ≈ xcollapsesz ↦ y , u ↦ xvia the ψ-tie (head-linkedatψ). - Design note:
docs/notes/m6-7-reverse-day.md; roadmap updated indocs/GITHUB_PROJECT.md.
Day's forward half (terms ⟹ CM) was tracked separately on #412 and has since landed (PR #442, closing #412): Day-theorem assembles the complete iff, so Day's theorem now stands as an iff alongside jonsson-theorem, and no Day item remains open anywhere.
Tasks¶
- ~CD ⟹ Jónsson terms: extract the ternary chain
d₀ … dₙand inhabit the converse projection ofJonsson-Statement.~ ✅ PR #438 (CD⇒jonsson,jonsson-theorem). - ~CM ⟹ Day terms: extract the quaternary chain
m₀ … mₙand inhabit the converse projection ofDay-Statement.~ ✅ PR #440 (CM⇒Day,Setoid.Varieties.Maltsev.Modularity; renamed fromCM⇒dayin PR #442). - ~Confirm the extracted identities match the parity convention of
Th-Jonsson/Th-Day(cross-check the even/odd argument patterns when the proof is in hand).~ ✅ both halves (PR #438, PR #440; details in the Status section above).
Dependencies¶
- [M6-4] (#410) — the free-algebra congruence/derivability bridge.
- [M6-6] (#412) — the chain-term extraction and the forward halves (reused for the parity bookkeeping and the curried chain operations).
Acceptance criteria¶
- Both converse implications type-check under
--safe; Jónsson's and Day's theorems are complete iffs. ✅ in full: Jónsson converse PR #438 with the complete iffjonsson-theorem; Day converse PR #440; and the once re-scoped clause — Day's full iff — discharged by PR #442 on #412, which landed the forward half and assembledDay-theorem.
Notes¶
- Difficulty: hard. The derivation-length / chain extraction from an inductively-generated congruence is the crux; budget accordingly and consider landing CD ⟹ Jónsson first, with CM ⟹ Day mirroring it. (Realized as planned: reverse Jónsson landed first; the crux decomposed into the M6-6
finitary⇒JoinIsChainplus the new parity normalization, and reverse Day was the predicted mechanical mirror.) - Close-out: PR #446 reconciles the two M6-7 design notes with the post-#442 state (the
CM⇒Dayrename and the landed forward half) and closes this issue on merge.
References¶
- B. Jónsson, Algebras whose congruence lattices are distributive, Math. Scand. 21 (1967), 110–121. doi:10.7146/math.scand.a-10850.
- A. Day, A characterization of modularity for congruence lattices of algebras, Canad. Math. Bull. 12 (1969), 167–173. doi:10.4153/CMB-1969-016-6.
- S. Burris and H. P. Sankappanavar, A Course in Universal Algebra, Thms. II.12.6 (Jónsson) and II.12.4 (Day).
🤖 Generated with Claude Code
https://claude.ai/code/session_011crz6XaiE4uecELazSkJFY
Issue M6-8: Finite Birkhoff: discharge SubdirectSIRep constructively for finite algebras with decidable equality (#419, closed)¶
Labels: enhancement, milestone-6-flrp
Description¶
[M6-2] (#272, PR #418) proved the choice-free core of Birkhoff's subdirect representation theorem: the bridge separating→SubdirectEmbedding (a family of congruences whose meet is the diagonal embeds 𝑨 subdirectly into the product of its quotients) and the reduction SIRep→Representable. The full theorem Birkhoff-subdirect is stated relative to a module parameter SubdirectSIRep 𝑨 — the existence of a separating family of SI-quotient congruences — because producing it in general is a Zorn's-lemma step (a congruence maximal among those excluding a given pair), incompatible with postulate-free --safe.
For finite algebras with decidable setoid equality that parameter can be discharged constructively: the congruence lattice is finite and searchable, so for each pair a ≢ b one finds a congruence maximal among those not relating a , b by search. Such a congruence is completely meet-irreducible, hence its quotient is subdirectly irreducible (via the monolith characterization in Setoid.Congruences.Monolith), and the family over all distinct pairs separates points. This turns Birkhoff-subdirect into an unconditional theorem on finite algebras — and finiteness is exactly the FLRP setting, so this is the payoff direction.
This is option (b) of the M6-2 design note (docs/notes/m6-2-subdirect.md).
Tasks¶
- Fix the finiteness/decidability interface: a decidable setoid equality on
𝕌[ 𝑨 ]and a finiteness/enumerability witness for the relevant congruences at the working level. Decide the cleanest encoding (reuse any existingFin/Setoid-based finiteness already in the tree). - For a distinct pair
a , b, search the (finite) set of congruences not relatinga , bfor a maximal one, and prove its maximality. - Show a maximal-separating congruence is completely meet-irreducible and that its quotient is
IsSubdirectlyIrreducible. Note the subtlety the design note flags: with decidable≈the¬¬-gap that blocks the general construction disappears, so the family's meet is exactly the diagonal. - Assemble
SubdirectSIRep 𝑨(index = distinct pairs) and instantiateBirkhoff-subdirectto obtain the unconditional finite statement.
Dependencies¶
- [M6-2] (#272, PR #418) —
Setoid.Subalgebras.Subdirect(the bridge,SubdirectSIRep,Birkhoff-subdirect) andSetoid.Congruences.Monolith(SI via monolith,monolith⇒cmi).
Acceptance criteria¶
- A constructive
SubdirectSIRep 𝑨for finite algebras with decidable equality, andBirkhoff-subdirectinstantiated to an unconditional subdirect-representation theorem on that class, type-checking under--cubical-compatible --exact-split --safe.
References¶
- Burris and Sankappanavar, A Course in Universal Algebra, Thm. II.8.6 (Birkhoff's subdirect representation theorem).
- Design note:
docs/notes/m6-2-subdirect.md(option (b)).
🤖 Generated with Claude Code
https://claude.ai/code/session_01B9q9aP34sakGdPgZVaXU2s
Issue M6-9: The completely-meet-irreducible ⟹ monolith converse (needs an impredicative/resized congruence meet) (#420)¶
Labels: enhancement, milestone-6-flrp, design-discussion
Description¶
Setoid.Congruences.Monolith (from [M6-2] (#272, PR #418)) proves the useful direction of the subdirect-irreducibility characterization: a monolith makes 0ᴬ completely meet-irreducible (monolith⇒cmi, in the constructive contrapositive form "every member of a family nonzero ⟹ the meet is nonzero").
The converse — 0ᴬ completely meet-irreducible ⟹ a monolith exists — is not proved, for a predicativity reason. The natural construction takes the monolith to be μ = ⋀ { θ : Nonzero θ }, the meet of all nonzero congruences; but that family is indexed by Σ[ θ ∈ Con 𝑨 ℓ ] Nonzero θ, which lives one universe up, so the meet lands at a level ℓ′ > ℓ and is not a monolith at level ℓ. This is the same predicativity wall the complete-lattice construction meets (completeness only for ℓ₀-small families).
Tasks¶
- Decide the resolution: (i) a level-polymorphic monolith /
IsSubdirectlyIrreducibleallowing the monolith one level up; (ii) an impredicative or resized congruence meet, taken as an explicit parameter (mirroring the M6-2 choice-principle discipline, so nothing is postulated under--safe); or (iii) restrict to a setting where the nonzero congruences areℓ-small (e.g. finite, dovetailing with [M6-8]). - Prove the converse under the chosen resolution: from completely-meet-irreducible
0ᴬ(and nontriviality) construct the least nonzero congruence and showIsMonolith. - Record the assumption / level cost explicitly.
Dependencies¶
- [M6-2] (#272, PR #418) —
Setoid.Congruences.Monolith(IsMonolith,Nonzero,⋂,monolith⇒cmi).
Acceptance criteria¶
cmi ⟹ HasMonolithproved (at the appropriate level / under the stated resizing assumption), completing the SI ⟺ completely-meet-irreducible characterization, type-checking under--safe.
References¶
- Design note:
docs/notes/m6-2-subdirect.md(§ "The monolith characterization and its converse").
🤖 Generated with Claude Code
https://claude.ai/code/session_01B9q9aP34sakGdPgZVaXU2s
Issue M6-10: Subdirectly irreducible ⟺ no nontrivial subdirect decomposition (the structural characterization) (#421, closed)¶
Labels: enhancement, milestone-6-flrp
Description¶
Setoid.Congruences.Monolith (from [M6-2] (#272, PR #418)) defines subdirect irreducibility order-theoretically: IsSubdirectlyIrreducible 𝑨 = Nontrivial 𝑨 × HasMonolith 𝑨. What makes the name apt is the structural characterization: 𝑨 is subdirectly irreducible iff it has no nontrivial subdirect decomposition — i.e. in every subdirect embedding 𝑨 ↪ ⨅ 𝒜, some coordinate projection projᵢ ∘ h is an isomorphism. This issue proves that equivalence, tying Setoid.Congruences.Monolith to Setoid.Subalgebras.Subdirect.
Tasks¶
- State "no nontrivial subdirect decomposition": in every subdirect embedding
h : 𝑨 ↪ ⨅ 𝒜, some coordinate map is an isomorphism. Pick the cleanest constructive phrasing — via the kernels, a subdirect embedding corresponds to a separating familyθ(⋂ θthe diagonal), and "some projection is iso" ⟺ "someθ i ≑ 0ᴬ". - Prove monolith ⟹ structural irreducibility: if
⋂ θis the diagonal and𝑨has a monolithμ, then someθ i ≑ 0ᴬ(elseμ ⊆ θ ifor alli, soμ ⊆ ⋂ θ ≑ 0ᴬ, contradictingNonzero μ) —monolith⇒cmitransported across the kernel/subdirect correspondence. Extracting the specificiconstructively may need the index decidable/finite (coordinate with [M6-8]); otherwise state the contrapositive. - Prove the converse (structural ⟹ monolith), or document its level/choice cost if it mirrors [M6-9].
Dependencies¶
- [M6-2] (#272, PR #418) —
Setoid.Subalgebras.SubdirectandSetoid.Congruences.Monolith. - Likely interacts with [M6-8] (finite/decidable extraction) and [M6-9] (the converse's predicativity).
Acceptance criteria¶
- The equivalence (at least the constructive direction, with the converse proved or its cost documented) type-checks under
--safe, connectingIsSubdirectlyIrreducibleto subdirect decompositions.
References¶
- Burris and Sankappanavar, A Course in Universal Algebra, Def. II.8.3 and Thm. II.8.4.
- Design note:
docs/notes/m6-2-subdirect.md.
🤖 Generated with Claude Code
https://claude.ai/code/session_01B9q9aP34sakGdPgZVaXU2s
Issue M6-11: Sub(A) as a complete lattice (next Setoid.Algebras.Lattices instance) (#373, closed)¶
Labels: milestone-6-flrp
Description¶
With the congruence lattice now in place (#271, modules Setoid.Algebras.Congruences.{Lattice,Generation,CompleteLattice} plus the general Setoid.Algebras.Lattices.CompleteLattice record), the natural companion is the subalgebra lattice: the subuniverses of a setoid algebra 𝑨, ordered by inclusion, form a complete lattice Sub 𝑨. This is the second motivating instance of the CompleteLattice record and is foundational for the FLRP (every finite lattice question is, after all, about lattices of the form Con 𝑨 / Sub 𝑨).
Most of the hard work already exists in Setoid.Subalgebras.Subuniverses:
Subuniverses 𝑨— the predicate "is a subuniverse" (closed under the basic operations);Sg 𝑨 G— the inductively generated subuniverse, withsgIsSub(it is a subuniverse) andsgIsSmallest(the generation theorem / universal property);⋂s— an arbitrary intersection of subuniverses is a subuniverse (the infinitary meet).
So assembling the lattice is a "step-3"-style task, closely parallel to the congruence-lattice assembly.
Tasks¶
- Define
Sub 𝑨(the type of subuniverses, as a Σ of a predicate with its subuniverse proof) and the inclusion order_≤_(=_⊆_). - Meet
B ∧ C = B ∩ C, joinB ∨ C = Sg(B ∪ C). -
Sub-Lattice : (𝑨 : Algebra α ρ)(ℓ₀ : Level) → Lattice _ _ _, at the absorbing levelL = 𝓞 ⊔ 𝓥 ⊔ α ⊔ ℓ₀(whereSgstays atL). - Bounds: bottom
Sg ∅(smallest subuniverse) and topU(the whole carrier);Sub-BoundedLattice. - Infinitary meet
⋂(via⋂s) and joinSg(⋃ …);Sub-CompleteLatticeinstantiating theCompleteLatticerecord. - A small worked example.
Acceptance criteria¶
-
Sub-Lattice 𝑨/Sub-CompleteLattice 𝑨type-check and satisfy the (complete-)lattice axioms. - Bounds proved as
⊥/⊤. - At least one small worked example.
Notes¶
- Placement, mirroring the congruence case (
Setoid.Algebras.Congruences.CompleteLattice): the instance goes inSetoid.Subalgebras.CompleteLattice, instantiating the general record inSetoid.Algebras.Lattices.CompleteLattice. - A richer worked example — the subgroup lattice of a concrete finite group — is appealing but a sizeable undertaking (defining the group over a signature, classifying its subgroups); it is tracked as a separate follow-up so this PR can stay focused.
Issue M6-12: Worked example: the subgroup lattice of a concrete finite group (#374, closed)¶
Labels: milestone-6-flrp
Description¶
Follow-up to the subalgebra-lattice infrastructure (#373). Once Sub 𝑨 is available as a complete lattice, a compelling worked example is the subgroup lattice of a concrete finite group — e.g. ℤ/4ℤ (the 3-element chain 0 < ⟨2⟩ < ℤ/4ℤ), the Klein four-group V₄ (the diamond M₃-minus, i.e. 2³-style with three order-2 subgroups), or S₃ (the well-known six-subgroup lattice).
This is separated from #373 because it is a sizeable undertaking on its own:
- realize the group concretely as a setoid algebra over a group signature (the
Classical/tree has group machinery to draw on); - identify the subuniverses (= subgroups, since the signature includes inverse and identity);
- classify them and exhibit the lattice order, ideally matching a known finite lattice.
Acceptance criteria¶
- A concrete finite group built as a
Setoidalgebra. - Its subgroups exhibited as elements of
Sub 𝑨, with the lattice order between them. - Prose identifying the resulting lattice (chain / diamond /
S₃lattice).
Notes¶
- Subuniverses of a group algebra are exactly its subgroups precisely because the signature carries the unary inverse and the nullary identity, so closure under the operations forces the subgroup axioms — worth stating explicitly in the example.
Issue M6-13: FLRP research program — tracking issue (#451)¶
Labels: milestone-6-flrp, research-exploratory, flrp-research
Description¶
Umbrella issue for the research program on the Finite Lattice Representation Problem. The roadmap is docs/notes/flrp-research-roadmap.md (added in #450), and the interval-enforceable-properties note it builds on is vendored at docs/papers/flrp/ieprops/ (arXiv:1205.1927, v4).
The program is organized as six PR-sized work packages (WP-1…WP-6) building the formal infrastructure, and four research phases (RP-1…RP-4) pursuing the interval-enforceable-properties attack described in roadmap § 4. The critical path to RP-1 is WP-1 → WP-2 → WP-3 → WP-4.
This program is a separate research track from the M7 algebraic-complexity / CSP work and from the M6 infrastructure milestone; do not conflate them (see CLAUDE.md).
Structure¶
- WP-1…WP-6 — infrastructure and formalization steps, each intended to land as one focused PR; tracked as sub-issues.
- RP-1…RP-4 — open-ended research phases with the success/kill criteria of roadmap § 4; tracked as sub-issues and reviewed quarterly.
Acceptance criteria¶
- All WP sub-issues are closed.
- Each RP phase has either produced results or hit its documented kill criterion.
Issue M6-13a: FLRP WP-1: FLRP.Problem — formal statement and representability predicate (#452, closed)¶
Labels: research-exploratory, flrp-research
Description¶
Create the new top-level tree src/FLRP/ (barrel plus first submodule FLRP.Problem) containing the formal core of the problem: a Representable predicate — "there exists a finite algebra whose congruence lattice is isomorphic to L" — and the FLRP statement as a type, together with at least one worked instance. Design guidance: roadmap §§ 6–7 (docs/notes/flrp-research-roadmap.md). Reuse the FiniteAlgebra interface from Setoid.Subalgebras.Subdirect.Finite and the congruence lattice from Setoid.Congruences.CompleteLattice.
Part of #451.
Tasks¶
-
src/FLRP.lagda.mdbarrel andsrc/FLRP/Problem.lagda.md, scaffolded per house conventions. -
Representable Lfor a finite latticeL; choose and document the lattice-presentation and isomorphism notions, preferring existing library or stdlib infrastructure. - The FLRP statement as a type, with prose making clear that it is stated, not asserted.
- One worked instance wired to existing examples (e.g. the two-element chain as
Conof a two-element algebra with no operations), withL7referenced in prose as the distinguished open instance.
Acceptance criteria¶
- New modules type-check under
--cubical-compatible --exact-split --safe. - Every public definition has an explicit type signature and a prose comment.
- Changes to existing modules are limited to what promotion of
FiniteAlgebra(if needed) strictly requires.
Issue M6-13b: FLRP WP-2: group-action infrastructure — subgroups, core, cosets, G-sets, Sub(G), intervals (#453, closed)¶
Labels: research-exploratory, flrp-research
Description¶
Reusable group-theoretic infrastructure needed by the Pálfy–Pudlák bridge (WP-3) and the enforceability framework (WP-4): subgroups as subalgebras with Sub(G) as a complete lattice (generalizing the Klein-four worked example Examples.Setoid.SubgroupLattice), conjugation/normality and the normal core Core_G(H), cosets with the transitive coset G-set as a unary algebra, and upper intervals [H, G] as bounded lattices. Per roadmap § 6 this lands in the Classical/ and Setoid/ trees, not in FLRP/, so the library gains value independently of the research program.
Part of #451.
Tasks¶
- Subgroups of a
Groupas subuniverses/subalgebras;Sub(G)viaSetoid.Subalgebras.CompleteLattice. - Conjugation, normal subgroups, and
Core_G(H)(largest normal subgroup ofGbelowH). - Cosets
G/Hand the coset G-set as a unary algebra (one operation per group element). - Upper intervals
[H, G]inSub(G)as bounded lattices. - Dedekind's rule
A ≤ B → A(C ∩ B) = AC ∩ Bat least stated (its proof may land here or in RP-1).
Acceptance criteria¶
- New modules type-check under the standard pragma; changes are additive.
- The Klein-four subgroup-lattice example still type-checks.
Scope note: this is the largest WP; splitting into WP-2a (subgroups/core) and WP-2b (cosets/G-sets/intervals) at PR time is acceptable and expected if the diff grows.
Issue M6-13c: FLRP WP-3: Pálfy–Pudlák bridge, easy direction — Con(G ↷ G/H) ≅ [H, G] (#454, closed)¶
Labels: research-exploratory, flrp-research
Description¶
The first substantive FLRP theorem in the library: the congruence lattice of the transitive G-set on the cosets G/H is isomorphic to the upper interval [H, G] in Sub(G). Classical references: McKenzie–McNulty–Taylor (Lemma 4.20) and Dixon–Mortimer (Theorem 1.5A); see roadmap § 2 and the introduction of the vendored note docs/papers/flrp/ieprops/. Corollary, wired into FLRP.Problem: every group-representable lattice is representable as the congruence lattice of a finite algebra.
Depends on WP-1 and WP-2. Part of #451.
Scope update — 2026-07-12 (ADR-008)¶
Per the ratified two-layer congruence discipline (docs/adr/008-two-layer-congruence-discipline.md; design note docs/notes/flrp-two-layer-congruences.md on #462), this theorem is to be stated at Layer D: for a finite group G carrying the standard finiteness data (surjective enumeration plus decidable equality) and a decidable subgroup H, the isomorphism is between the DecCon poset of the coset algebra and the interval [H, G] in Sub(G), both of which are finite lattices with decidable order. The Layer S version follows from the registered classical bridge if ever needed. Consequently this issue now also depends on WP-7 (#466), which lands first per the ratified ordering; the corollary targets Representableᵈ.
Tasks¶
- Congruences of the coset G-set correspond to intermediate subgroups (both directions as separate named lemmas), at Layer D.
- The order/lattice isomorphism
Con (G ↷ G/H) ≅ [H, G], assembled from small lemmas. - Corollary: group representable implies
Representableᵈ, inFLRP.Problem/FLRP.ProblemDecterms.
Acceptance criteria¶
- Type-checks under
--safewith no classical assumptions; each direction of the correspondence is its own lemma; every public definition carries prose.
Issue M6-13d: FLRP WP-4: FLRP.Enforceable — IE, cf-IE, min-IE, and the no-go lemmas (#455, closed)¶
Labels: research-exploratory, flrp-research
Description¶
Formalize § 2 of the vendored note (docs/papers/flrp/ieprops/): the definitions of interval enforceable (IE), core-free interval enforceable (cf-IE), min-IE, and group representable, with the vacuity subtlety handled by tracking group representability of the enforcing lattice explicitly. Then the first structural results of its § 3: Lemma 3.1 (if the complementary class is closed under homomorphic images, cf-IE upgrades to IE), the fattening remark ([H × K, G × K] ≅ [H, G], so solvability is not IE), and Lemma 3.2 (a property and its negation cannot both be IE via group-representable lattices). This machine-checks why the program lives at the core-free level (roadmap § 4).
Depends on WP-2 (WP-3 is helpful but not required). Part of #451.
Tasks¶
-
FLRP/Enforceable.lagda.mdwith the four definitions and representability tracking. - Fattening lemma
[H × K, G × K] ≅ [H, G](needs direct products of groups). - Lemma 3.1 and Lemma 3.2, with names traceable to the note.
- Statement (hypotheses named, proof deferred to RP-1) of the parachute meta-theorem.
Acceptance criteria¶
- Type-checks under
--safe; no postulates; deferred results appear only as explicit hypotheses.
Issue M6-13e: FLRP WP-5: closure toolkit — products, ordinal sums, Kurzweil–Netter duality (#456, closed)¶
Labels: milestone-6-flrp, research-exploratory, flrp-research
Description¶
Formalize closure of the class of representable lattices under finite direct products and ordinal sums, and establish the FLRP.Assumptions registry pattern by recording duality (Kurzweil 1985, Netter 1986) as its first entry — a precise statement with citation, imported as an explicit hypothesis, keeping --safe. Stretch goal: reprove Netter's duality construction formally; the content is finite and combinatorial, plausibly tractable, and Netter's proof may never have been published, so a formal reproof is independently valuable (roadmap § 7).
Depends on WP-1. Part of #451.
Tasks¶
- Product closure of
Representable. - Ordinal-sum closure of
Representable. -
FLRP/Assumptions.lagda.mdwith the duality entry (statement, source, citation discipline documented). - Stretch: formal proof of duality closure via the Kurzweil–Netter construction.
Acceptance criteria¶
- Type-checks under
--safe; the assumptions registry documents every imported statement with its citation.
Issue M6-13f: FLRP WP-6: certificate pipeline — schema, Agda checker, GAP/SAT emitters (#457, closed)¶
Labels: research-exploratory, flrp-research
Description¶
External searches (GAP, UACalc, SAT/model finders) must never be trusted directly: they emit finite certificate data which Agda re-checks, in the style of Examples.Classical.Lattices.L7. Build the certificate schema, the generic Agda checker, at least one emitter, and a pilot re-verification of one thesis-era small-lattice representation end-to-end. Search scripts and raw logs live outside src/ (roadmap § 6; they move to a companion repo if they grow).
Depends on WP-1. Part of #451.
Design — fixed 2026-07-13 (Freese traces)¶
Full design: docs/notes/flrp-wp6-freese-certificates.md. Guiding principle: the checker never searches — all fixpoint iteration happens in the external engine, and Agda verifies a linear-size witness.
- Per-congruence certificate for
θ ≑ Cg(fromPairs P): the claimed partition as a parent vector in Freese normal form, plus the Freese trace — the justified merge list of theCgworklist algorithm of R. Freese, Computing congruences efficiently (https://math.hawaii.edu/~ralph/Preprints/cg2.pdf), which is literally aGen-derivation skeleton (seeds ↦base, translate applications ↦ operation compatibility). - Checker obligations, each linear and search-free: C1 trace soundness (every merge derivable); C2 claimed ⊆ generated (forest edges covered by the trace); C3 generated ⊆ claimed (contains
P; compatibility checked on the≤ n − 1forest edges only, extended by symmetry/transitivity through roots). - Whole-lattice certificates (
FiniteCongruencesᵈinstances,Representableᵈtargets): the congruence list plus, for every carrier pair, a pointer to its principal congruence with trace; order/meet/join verified definitionally by root lookups. The union-find join and root-pair-hashing meet of R. Freese, Partition algorithms (https://math.hawaii.edu/~ralph/Notes/Partitions/partitions.pdf, Algorithm 4) are the engine-side devices for producing these tables;cg2supersedes that note for generation only, so the 3-pager remains the lattice-structure reference. - Engine: UACalc instrumented to emit its merge trace, or a ~100-line reimplementation of the
cg2worklist algorithm in the scripts layer. - Non-goal (parked): a verified in-Agda union-find. The Layer-D abstraction boundary (
Cg-decisDec-valued with anabstractimplementation, #467) makes a fast decider a drop-in later if a concrete consumer ever needs in-Agda computation at scale. - Background: Tarjan, Efficiency of a good but not linear set union algorithm, J. ACM 22 (1975) — the
O(m·α(m,n))union-find analysis both notes rest on.
Tasks¶
- Certificate schema: normal-form parent vectors + Freese traces (per-congruence), plus the whole-lattice pointer structure (design note § 4).
- Generic checker discharging obligations C1–C3 and the whole-lattice verifications, with no fixpoint iteration or search.
- One emitter producing traces (instrumented UACalc or standalone
cg2reimplementation). - Pilot: re-verify one small-lattice representation from the thesis era end-to-end through the pipeline.
Acceptance criteria¶
- A certificate produced by an external tool round-trips to a type-checked Agda proof with no manual editing beyond file placement.
- Checking cost is linear in trace + table size (no
Cg-decexecution in the checking path).
Issue M6-13g: FLRP RP-1: formalize the IE framework end-to-end (parachute theorems) (#458, closed)¶
Labels: milestone-6-flrp, research-exploratory, flrp-research
Description¶
Research phase continuing from WP-4 through § 3 of the vendored note (docs/papers/flrp/ieprops/): Dedekind's rule and the antichain corollary (Corollary 3.5), the parachute construction 𝒫(L₁, …, Lₙ), Theorem 3.6 ((B) ⟺ (C)), Lemma 3.7 (a core-free parachute representation forces G subdirectly irreducible, nonsolvable, with NH = G and C_G(N) = 1 for all nontrivial N ⊴ G), and Corollary 3.8 (cf-IE properties are closed under finite conjunction). The phase is capped by the machine-checked strategy meta-theorem: finitely many cf-IE classes with empty intersection imply the corresponding parachute is not group representable, hence — with Pálfy–Pudlák imported as an explicit hypothesis — the FLRP has a negative answer. The wreath Lemma 3.3 (requires wreath products and the double Kurzweil construction) either closes this phase or moves to RP-4.
Depends on WP-2 and WP-4. Part of #451; roadmap § 4.
Exit criterion¶
- The strategy meta-theorem type-checks under
--safewith an explicit, auditable assumption registry. - A short design note in
docs/notes/records the formalization decisions and any divergences from the note's paper proofs.
Issue M6-13h: FLRP RP-2: the enforcement catalog (#459, closed)¶
Labels: milestone-6-flrp, research-exploratory, flrp-research
Description¶
Build the machine-readable catalog of "interval shape forces group structure" theorems, each recast as a precise (cf-/min-)IE statement with an Agda statement — assumption-parameterized wherever the proof stays on paper. Seed entries, per roadmap § 4: the note's classes 𝒢₀ (nonsolvable; IE), 𝒢₁ (neither alternating nor symmetric; IE), 𝒢₂ (subdirectly irreducible), 𝒢₃ (no nontrivial abelian normal subgroup), 𝒢₄ (C_G(M) = 1 for all nontrivial normal M) — the last three cf-IE via parachutes. External entries: Pálfy's solvable-exclusion lattices; Köhler/Feit M₇ and Pálfy's minimality analysis of Feit's examples (min-IE); Baddeley–Lucchini reductions; Börner; Aschbacher's D∆/signalizer theorems specialized to parachutes (whose interiors are disconnected); Lucchini–Moscatiello–Palcoux–Spiga Boolean overgroup lattices.
Depends on WP-4; grows alongside RP-1. Part of #451.
Exit criterion¶
- A catalog module plus survey note exists, with at least the note's five classes and two external entries formalized as statements.
- Each entry records its source, its enforcing lattice(s), and whether the proof is formalized or imported as a hypothesis.
Issue M6-13i: FLRP RP-3: hunt for an empty intersection of cf-IE classes (#460)¶
Labels: milestone-6-flrp, research-exploratory, flrp-research
Description¶
The kill shot, per Theorem 3.6 of the vendored note: exhibit finitely many cf-IE classes whose intersection is empty, and the FLRP has a negative answer (a property and its negation is the special case n = 2). The wreath no-go (Lemma 3.3) constrains the hunt: every cf-IE-by-group-representable class contains wreath products S ≀ Ū for every finite nonabelian simple S, so every member of a candidate family is wreath-rich, and the joint tension must come from finer invariants — the structure of the unique minimal normal subgroup forced by Lemma 3.7, its centralizer and complement behavior, and the permutation action on it.
Method discipline: use computation as cheap falsification. Before investing in a non-representability proof for a candidate parachute, search for representations of it over the small-groups and primitive-groups libraries (Hulpke's intermediate-subgroup algorithms), and attempt UA-side representations of small candidates directly; certificates flow through the WP-6 pipeline.
Depends on RP-1 and RP-2. Part of #451; success/kill criteria in roadmap § 4.
Exit criterion¶
- Success: a finite lattice with a machine-checked non-representability proof (modulo the explicit assumption registry).
- Kill: two consecutive quarterly reviews with no viable candidate family, documented in the tracking issue.
Issue M6-13j: FLRP RP-4: dead-end branch — can a property and its negation both be cf-IE? (#461)¶
Labels: milestone-6-flrp, research-exploratory, flrp-research
Description¶
Prove or refute the implicit conjecture of the vendored note: a group property and its negation cannot both be core-free interval enforceable by group-representable lattices. The wreath no-go (Lemma 3.3, via the double Kurzweil construction) is the prototype tool and already excludes the classes omitting wreath products S ≀ Ū (solvable, alternating/symmetric, almost simple); the phase extends it toward a structure theory of the cf-IE class, and more generally characterizes what an empty-intersection family (RP-3) would have to look like.
Either outcome is valuable. A proof is the honorable dead end for the n = 2 case and independently a publishable structure theorem about intervals in subgroup lattices; a refutation is a concrete path toward a negative FLRP answer. A sobering asymmetry to keep in view: the existence of empty-intersection families cannot be ruled out without proving statement (B) itself, so the realistic aim is structure theorems constraining the families we can actually construct.
Depends on RP-1 (wreath products, Kurzweil construction). Part of #451; roadmap § 4.
Exit criterion¶
- A theorem (formalized, or paper-proved with a formal statement) settling the
n = 2conjecture in either direction, or a documented reduction of it to named open questions.
Issue M6-13k: FLRP WP-7: the decidable layer — presented congruences, FiniteAlgebraᵈ, Representableᵈ (#466, closed)¶
Labels: flrp-research
Description¶
Implement Layer D of the two-layer congruence discipline ratified in ADR-008 (docs/adr/008-two-layer-congruence-discipline.md; design note docs/notes/flrp-two-layer-congruences.md, PR #462): finitely presented congruences with decidable membership on finite finitary algebras, the reconstruction theorem, a constructive completeness theorem yielding FiniteCongruencesᵈ, the single registered classical bridge, and Representableᵈ as the FLRP program's working notion. Per the ratified ordering this lands before WP-3 (#454), which will be stated at Layer D.
Interface update: #465 has since split the old interface into the bare carrier record FiniteAlgebra (Setoid.Algebras.Finite, no classical content) and the congruence-side FiniteCongruences (Setoid.Congruences.Finite, home of DecCon and the classical complete field), so Layer D's constructive completeness record is the congruence-side counterpart, working name FiniteCongruencesᵈ.
Part of #451.
Tasks (three PR-sized slices)¶
- Slice (i) — L1 + L2:
Cgof a finite pair list on a finite finitary algebra has decidable membership (congruence-closure computation), and everyDecConis≑toCgof its related-pairs list; includes fixing the Agda packaging of finite finitary signatures (audit A3). (merged #467) - Slice (ii) — L3 + audits: constructive completeness for
DecConvia enumeration of Bool-valued tables; theFiniteCongruencesᵈinterface; audit A1 (which m6-8 consumers, in particular finite Birkhoff, survive onFiniteAlgebra+FiniteCongruencesᵈalone) and audit A2 (WP-2 group modules are Layer-D ready). (merged #468) - Slice (iii) — L4 + L5. Constructive core merged in #479; the classical-bridge parts remain — see the status update below.
-
Representableᵈ,FLRP-Statementᵈ, the decidable-congruence poset order (_⊆ᵈ_,_≑ᵈ_,ConIsoᵈ), and the constructivechain₂instancechain₂-Representableᵈ, all--safewith no postulates (src/FLRP/Representable.lagda.md, #479). -
FLRP.Assumptionsregistry with the classical bridge (completeofFiniteCongruences) as its first entry, strength documented (between WLEM and LEM at the working level). - Under that bridge,
Representable 𝑳 ↔ Representableᵈ 𝑳. - The
DecConposet as a finite lattice with decidable order (meets, joins) — deferred to WP-6 (#457) certificate tooling; #479 provides only theOrderIsotarget that representability needs.
Status update — 2026-07-20 (slice iii core merged)¶
Slices (i) and (ii) merged in #467 and #468. The constructive core of slice (iii) merged in #479 (src/FLRP/Representable.lagda.md): Representableᵈ, FLRP-Statementᵈ, the decidable-congruence poset order (ConIsoᵈ), and the postulate-free two-element-chain representation chain₂-Representableᵈ — the object the WP-1 no-go theorem forbids at Layer S, now attained constructively at Layer D.
Remaining to close this issue (narrowed scope):
src/FLRP/Assumptions.lagda.md— the--saferegistry naming the classical bridge (FiniteCongruences.complete : ∀ φ → Σ[ d ∈ DecCon 𝑨 _ ] (d ∈ cons) × (φ ≑ proj₁ d)) as an explicit hypothesis, never a postulate; strength documented between WLEM and LEM (ADR-008 L4).- Under that bridge, the cross-layer equivalence
Representable 𝑳 ↔ Representableᵈ 𝑳— theConandDecConposets of a finite finitary algebra coincide oncecompleteholds;Representable/Representableᵈdiffer exactly byConIsovsConIsoᵈplus thefinsigfield. - Wiring the now-unblocked Layer-D corollary of WP-3 (#454):
FLRP.Bridge.interval-Con-representablecan targetRepresentableᵈ(may land here or as a sibling PR).
Coordination: WP-5 (#456) also plans FLRP.Assumptions with the Kurzweil–Netter duality as "its first entry." This issue creates the module with the classical complete bridge as entry 1; WP-5 appends the duality entry.
Acceptance criteria¶
- All new modules type-check under
--cubical-compatible --exact-split --safe; no postulates; the bridge appears only as an explicit hypothesis. (FLRP.Representable satisfies this in #479; completes when FLRP.Assumptions lands.) -
Representableᵈ (toLattice chain₂)is inhabited with no classical assumptions. (chain₂-Representableᵈ, #479.) - The m6-8 note gains an addendum recording the A1 audit outcome. (
docs/notes/m6-8-finite-birkhoff.md§ "Update (WP-7 A1)"; full findings indocs/notes/flrp-wp7-audits.md.)
Issue M6-14: FLRP computational campaign: small-lattice certificates and the L7 hunt — tracking issue (#483)¶
Labels: milestone-6-flrp, research-exploratory, flrp-research
Description¶
This tracking issue registers the computational campaign of roadmap § 5, Avenue A (docs/notes/flrp-research-roadmap.md): systematic small-lattice representation work under the certificate discipline, now that the WP-6 pipeline (#457, PR #482) provides the certificate schema, the search-free Agda checker, and the cg2 emitter. Three inputs converge here.
- The WP-6 certificate pipeline (PR #482): external engines emit Freese-trace certificates and Agda re-checks them into
Representableᵈwitnesses; nothing enterssrc/on the authority of an external tool. - The DeMeo–Freese–Jipsen manuscript Representing Finite Lattices as Congruence Lattices of Finite Algebras (
article/SmallLatticeReps.texin https://github.com/UniversalAlgebra/fin-lat-rep), whose § 6 catalogs 35 nondistributive, non-ordinal-sum latticesL1–L35of size ≤ 7 together with explicit minimal unary algebrasB1–B35for most of them, and whose lone open caseL10is this library'sL7. - A 2026-07-22 working session on
L7that produced its minimal sublattice-of-Eq(6)representation and machine-checked closure obstructions on 6 and 7 points (recorded in #484).
Naming. The lattice this library calls L7 (Examples.Classical.Lattices.L7) is L10 in the manuscript's numbering, and the manuscript's L7 is a different lattice. Every module, note, and issue in this family must state which numbering it uses; #485 includes a dictionary task.
Sub-issues¶
Dependency sketch¶
-
486 is infrastructure for #484 (the Eq(8) sweep) and produces candidate algebras that the #485 pipeline certifies.¶
-
487 feeds both #484 (minimal representations must be transitive, by the manuscript's § 5 theorem, so transitive-degree scans settle the frontier degree by degree) and #485 (the group-representation entries
L11,L14,L16,L20); its Agda import route is the WP-3 bridge (#454).¶ - Everything follows roadmap § 6: search scripts and raw logs live outside
src/, and external results enter only as re-checked certificates.
Acceptance criteria¶
- Each sub-issue is closed or explicitly re-scoped, with its artifacts (scripts, certificates, notes) merged.
- A census status note in
docs/notes/records, for all 35 catalog entries plusL7, whether an Agda-checked certificate exists and by which route.
Issue M6-14a: L7 (= L10 of SmallLatticeReps): Eq(6) sublattice representation, closure obstructions on ≤ 7 points, and the Eq(8) frontier (#484, closed)¶
Labels: research-exploratory, flrp-research
Description¶
L7 (this library's name; L10 in the SmallLatticeReps manuscript — see the naming note on #483) is the smallest lattice not known to be representable as the congruence lattice of a finite algebra (Examples.Classical.Lattices.L7, roadmap § 5.A.1). A 2026-07-22 working session established the results below by exhaustive machine search; this issue records them and drives the next steps. Part of #483.
Session results (2026-07-22)¶
Element names follow the module's grid labeling: carrier ⊥, (1,0), (0,1), x, (1,1), (0,2), ⊤, with x the doubly irreducible atom-and-coatom. Partitions are written in bar notation on {0,…,5} with singleton blocks suppressed.
- Minimal sublattice representation.
L7embeds inEq(6)and in noEq(n)withn ≤ 5(bounds normalize toΔ/∇: quotient by the bottom partition; simplicity ofL7handles the top). An explicit embedding:⊥ ↦ Δ,x ↦ |0,4|1,3|2,5|,(1,0) ↦ |0,2|3,4|,(0,1) ↦ |0,1|4,5|,(1,1) ↦ |0,1,2|3,4,5|,(0,2) ↦ |0,1|2,3|4,5|,⊤ ↦ ∇. - Classification.
Eq(6)contains 1080 labelled copies ofL7, and exactly two up to relabeling of the six points: the copy above, which is invariant under the involution(0 4)(1 5)(2 3), and a rigid copy obtained from it by replacingx ↦ |0,3|1,4|2,5|. - Closure fails on 6 points. For both classes, the monoid of unary maps preserving the five nontrivial relations consists of the stabilizer group plus the constants — there is no non-bijective non-constant preserving map — so
Inv(M)has 31 (symmetric class) resp. 203 (rigid class) members instead of 7. Since the congruence lattice of an arbitrary algebra is determined by its unary polynomials, no algebra on 6 elements hasCon ≅ L7. - Closure fails on 7 points.
Eq(7)contains 55,440 labelled copies in 12 classes (2 with aℤ₂stabilizer, 10 rigid); again no class admits any non-bijective non-constant preserving map, andInv(M)has 59 resp. 877 members. Hence no algebra on at most 7 elements has congruence latticeL7. - Combined with the manuscript's § 5 theorem that a minimal representation of
L10 = L7must come from a transitive permutation group: a minimal representation, if one exists, is a transitiveG-set on at least 8 points.
Tasks¶
- Record the session computation as a docs note (proposed:
docs/notes/flrp-l7-eq6.md) with the partitions, the two-class classification, the closure data, and reproduction instructions via the #486 tooling. - Formalize the positive fact in Agda: the seven listed partitions form a sublattice of
Eq(6)isomorphic toL7, verified by decision over the finite carrier in the style ofExamples.Classical.Lattices.L7; this is the library's explicit Pudlák–Tůma witness forL7, on a base set of provably minimal size. - Eq(8) closure sweep with the vectorized #486 tooling: enumerate the relabeling classes of copies of
L7inEq(8)(bounds atΔ/∇) and closure-test each. A closed class yields a finite algebra withCon ≅ L7— feed it directly to the PR #482 emitter for a certificate; if all classes fail, the negative census extends to|A| ≤ 8. - Group-side cross-check with #487: for each
TransitiveGroup(n, k)with point stabilizerH, starting at degreen = 8, test[H, G] ≅ L7; by the transitivity theorem this settles existence of minimal representations degree by degree and cross-validates the Eq(8) sweep. - Decide how much of the negative sweep is certifiable in Agda (the per-class
Inv(M)computations are plain finite checks; exhaustiveness of the embedding enumeration is the hard part) and record the decision in the docs note.
Acceptance criteria¶
- The Eq(6) representation and its classification are stated in a committed note and reproducible from committed scripts.
- The Agda module with the Eq(6) sublattice witness type-checks under the standard pragma set.
- The 8-point frontier is resolved: either a closed class is found and certified, or the census extends to
|A| ≤ 8with the transitive-degree-8 cross-check recorded.
Issue M6-14b: Certificates of representability for the SmallLatticeReps catalog (L1–L35) (#485, closed)¶
Labels: research-exploratory, flrp-research
Description¶
Run the WP-6 pipeline (#457, PR #482) over the small-lattice catalog of the SmallLatticeReps manuscript (DeMeo–Freese–Jipsen, article/SmallLatticeReps.tex in https://github.com/UniversalAlgebra/fin-lat-rep; orientation here is from the 2016-06-10 draft). Manuscript § 6 lists 35 nondistributive, non-ordinal-sum lattices L1–L35 of size ≤ 7, most with explicit minimal unary algebras B1–B35 given as value tables on {0,…,n−1} — exactly the input format of scripts/flrp/cg2.py, and all unary, matching the v1 renderer. Target: each catalog entry becomes a generated module under src/FLRP/Certificates/SmallLatticeReps/ proving Representableᵈ, with no manual editing beyond file placement, plus a census note recording status. This also machine-audits every Con(Bᵢ) ≅ Lᵢ claim in the manuscript, so discrepancies feed back as errata. Part of #483.
Naming. The manuscript numbering clashes with ours: manuscript L10 is this library's L7, and manuscript L7 is a different lattice. Certificate modules use the manuscript numbering, with the dictionary task below resolving the clash explicitly.
Coverage plan¶
- Immediately emittable (unary, carrier ≤ 10, inside the v1 renderer's
0F–9Flimit):B1–B4,B6–B8,B12,B15,B19,B21,B23–B26,B29–B32,B34,B35— about 21 entries. NoteB2is the regularV4action, so manuscriptL2 = M3is already certified by the pilotFLRP.Certificates.Pilot.V4RegularM3up to naming and placement. - Needs the renderer extension (carrier > 10):
B5(12),B9(16),B13(19),B17(12),B33(16); the engine is size-agnostic, onlyFin-literal rendering must grow past9F. - Group-representation entries:
L11(108-element coset algebra fromSmallGroup(216,153)),L14(upper interval inSub(A6), size 90),L16(Sub(C2.A6), size 180),L20(filter-ideal inSmallGroup(216,153)). Route: the WP-3 bridge (#454) when available, or direct big-carrier certificates if checking cost stays acceptable; concrete group data comes from #487. - Duals without explicit algebras:
L18(dual ofL19) andL22(dual ofL23) carry no explicit small algebra in the manuscript; they follow from Kurzweil–Netter duality, which is a registered assumption per WP-5 (#456). Either find explicit algebras (searches via #486/#487, or the mechanized overalgebra route of roadmap § 5.C) or record them as assumption-conditional. - The open case: manuscript
L10(ourL7) is #484's subject and is excluded here.
Tasks¶
- Naming dictionary: a docs note mapping manuscript
L1–L35to existing agda-algebras names (M3,N5, the hexagon, ourL7, …), linked from every certificate module header. - Batch-emit the ~21 immediately emittable entries; commit engine inputs (
scripts/flrp/inputs/), audit JSONs, and the generated modules; wire them into the barrels andmake check. - Extend the renderer past
9F(carriers up to at least 19) and emitB5,B9,B13,B17,B33. - Decide and implement the route for
L11,L14,L16,L20(WP-3 bridge vs direct big-carrier certificates), coordinating with #454 and #487. - Resolve
L18andL22: explicit algebras found by search, or assumption-conditional statements through the WP-5 duality registration. - Census note in
docs/notes/(entry ↦ certified / pending renderer / pending bridge / assumption-conditional / open), updated as batches land; consider feeding the table back to the manuscript repo. - Report any discrepancy the pipeline finds in a manuscript table as an erratum to https://github.com/UniversalAlgebra/fin-lat-rep.
Acceptance criteria¶
- Every unary catalog entry with carrier ≤ 19 has a type-checked certificate module produced by the emitter with no manual editing beyond file placement.
- The census note states the status of all 35 entries and is regenerable from committed artifacts.
Issue M6-14c: FLRP search tooling: generalized Eq(n) sublattice search and Snow closure tests in scripts/flrp (#486, closed)¶
Labels: research-exploratory, flrp-research
Description¶
Fold the 2026-07-22 session's search programs into scripts/flrp/ (the directory established by PR #482) as first-class, generalized tools. The session versions live outside the repository and are hard-coded to L7; the campaign needs them for arbitrary finite target lattices. Part of #483.
What exists and how it fits together¶
- From PR #482 (
scripts/flrp/):cg2.py(Freese worklist with trace recording),lattice.py,emit_agda.py,test_flrp.py, and the JSON conventions ofREADME.md. Direction: given an algebra, compute its congruence lattice with traces and emit an Agda certificate. - From the session (currently outside the repo): exhaustive
Eq(n)sublattice search for a target lattice with bounds atΔ/∇(restricted-growth-string partitions, precomputed meet/join tables),Sₙ-orbit classification of the copies, and the Snow-style closure test — backtracking enumeration of the monoidMof relation-preserving unary maps, then progressive filtering toInv(M). Direction: given a lattice, find candidate representations and decide whether each is a congruence lattice on that base set. - The two directions are complementary, with a small overlap in partition utilities. When a closure test succeeds, the unary algebra
⟨X, M⟩is exactly acg2.pyinput, closing the loop: lattice ⇒ search ⇒ algebra ⇒ certificate ⇒Representableᵈ.
Tasks¶
- Generalize the search from the hard-coded
L7constraint schedule to an arbitrary finite target lattice (input: covers or meet/join tables in a JSON format shared withlattice.py; derive the generator-driven pruning order automatically). - Unify partition representations: adopt the Freese normal-form parent vectors already used by
cg2.pyas the shared type, in one utilities module, so union-find and canonical forms are not duplicated. - Vectorize for
Eq(8): numpyint16meet/join tables (2 × 4140² entries ≈ 69 MB), mask-based candidate enumeration, and an invariant-bucketed orbit sweep, so the #484 Eq(8) run completes in minutes to hours rather than days. - Port the session's checks into the test suite: Bell-number counts,
M3inEq(4), theEq(6)results (1080 copies, 2 classes, closure verdicts), and theEq(7)results (55,440 copies, 12 classes, closure verdicts). - Output discipline: deterministic JSON artifacts under the
inputs/andout/conventions of PR #482, so sweeps are citable and re-runs are byte-identical no-ops. - SAT/model-finder encoder, first step per roadmap § 5.A.3: encode
Con(𝑨) ≅ Lfor operation tables on ≤ n elements; a small working prototype that documents the encoding suffices at this stage.
Acceptance criteria¶
-
scripts/flrp/contains the generalized search and closure tools, tests are green, and the README documents the formats and workflows. - The
Eq(6)andEq(7)session results are reproduced by the committed tools from a clean checkout. - An end-to-end demo exists: the search finds a closed class for some small lattice (for instance
N5on 4 points), and its⟨X, M⟩flows throughcg2.pyandemit_agda.pyto a type-checked certificate with no manual editing.
Issue M6-14d: GAP subgroup-interval search: Hulpke intermediate-subgroup routines over the small-groups libraries (#487, closed)¶
Labels: milestone-6-flrp, research-exploratory, flrp-research
Description¶
Build GAP scripts that hunt for a given finite lattice as an upper interval [H, G] in subgroup lattices across the GAP group libraries — SmallGroups first, then the perfect- and primitive-groups libraries per roadmap § 5.A.1 — using A. Hulpke's intermediate-subgroup machinery (IntermediateSubgroups and his latest interval routines). The SmallLatticeReps manuscript already ran such searches by hand (SmallGroup(216,153) for the minimal pentagonal upper interval and for the L11/L20 constructions); this issue makes them systematic, scripted, and repo-resident, with outputs both the certificate pipeline and the manuscript can consume. Part of #483.
Tasks¶
- Scripted search: given a target lattice (JSON format shared with #486), scan a configurable slice of the SmallGroups library for upper intervals
[H, G]isomorphic to it, with core-free normalization ofHand lattice-isomorphism testing on the interval; record(G, H, interval, isomorphism witness)as JSON artifacts under thescripts/flrp/conventions, raw logs outsidesrc/per roadmap § 6. - Transitive-degree scan for
L7(with #484): for eachTransitiveGroup(n, k)with point stabilizerH, starting at degreen = 8, test[H, G] ≅ L7; by the manuscript's § 5 transitivity theorem, a degree-by-degree exhaustion settles existence of minimal representations of that size. - Reproduce and script the manuscript's concrete claims:
SmallGroup(216,153)as the smallest group with a pentagonal upper interval (the manuscript's TODO appendix), theL11filter-ideal construction, and the interval data behindL14,L16,L20for #485. - Import route into Agda: coordinate with the WP-3 bridge (#454) so a found interval becomes
RepresentableᵈviaCon(G ↷ G/H) ≅ [H, G]; for small indices, alternatively dump the coset algebra's operation tables intocg2.pyfor a direct certificate. - Environment: GAP is not in the flake; document a pinned GAP setup, and provide it by specifying a new nix devshell in flake.nix that provides GAP and the SmallGroups library, so runs are reproducible; note the library versions in every emitted artifact.
Acceptance criteria¶
- A clean-checkout run reproduces the
SmallGroup(216,153)pentagon-minimality claim and emits its JSON artifact. - The degree-8 transitive scan for
L7is complete with a recorded verdict. - At least one found interval flows into an Agda-checked
Representableᵈwitness, by the bridge or by direct certificate.
Issue M6-14e: eqsearch --group-rep: restrict the Eq(n) sweep to uniform (coset-block) copies (#494, closed)¶
Labels: milestone-6-flrp, research-exploratory, flrp-research
Description¶
Extend the #486 search tooling (eqsearch.py / eqfast.py, PR #493) with a --group-rep flag that restricts the sublattice sweep to copies all of whose members are uniform partitions: for each relation r in the copy there is a k (necessarily dividing n) such that every block of r has exactly k elements. This mechanizes remark iv of the manuscript's closure-algorithm discussion (SmallLatticeReps § 6.1): "If it can be shown that the algebra of a minimal representation of L has a transitive permutation group for its nonconstant unary polynomials, then we can restrict our search in Eq(k) to uniform equivalence relations." Congruences of a transitive G-set are its systems of imprimitivity — the blocks are cosets of intermediate subgroups, hence all of equal size — so every congruence lattice of a transitive group action occurs among uniform copies.
Naming (per #483): the library's L7 (Examples.Classical.Lattices.L7) is the manuscript's L10; the dictionary is docs/notes/flrp-slr-naming.md.
Why this is the right restriction for the L7 hunt¶
- By the manuscript's § 5 analysis of intransitive group actions (its Theorem on the orbit congruence
τand the intervals it pins) a minimal representation of libraryL7cannot come from an intransitive action, and the machine-checked closure obstructions through eight points (#484,docs/notes/flrp-l7-eq6.md§ 6) push the frontier to nine; so a minimal representation, if one exists, is the congruence lattice of a transitiveG-set on at least nine points — and every congruence of such an algebra is a uniform partition. - Positive verdicts keep exactly their current meaning: the Snow closure test (the preserving monoid
Mover all unary maps, andInv(M)) is unchanged, so a closed uniform class still yields the honest witness algebra⟨X, M⟩and a ready-made claim file for the WP-6 certificate pipeline. - Negative verdicts weaken, and the README must say so explicitly: "no closed uniform class on
npoints" rules out algebras whose congruence lattices consist of uniform partitions — in particular every transitive group action — rather than all algebras; for libraryL7at the minimal frontier that is exactly the statement needed.
Why this is fast¶
Nontrivial uniform partitions are vanishingly rare among all partitions:
n |
Bell(n) |
nontrivial uniform | by block size |
|---|---|---|---|
| 6 | 203 | 25 | 15 of shape 2³, 10 of shape 3² |
| 7 | 877 | 0 | (7 is prime) |
| 8 | 4,140 | 140 | 105 of shape 2⁴, 35 of shape 4² |
| 9 | 21,147 | 280 | 280 of shape 3³ |
| 10 | 115,975 | 1,071 | 945 of shape 2⁵, 126 of shape 5² |
| 12 | 4,213,597 | 32,032 | 10,395 + 15,400 + 5,775 + 462 (shapes 2⁶, 3⁴, 4³, 6²) |
- At nine points the candidate pool collapses from 21,145 nontrivial partitions to 280, and the ~1.8 GB
Eq(9)meet/join tables that currently block the unrestricted sweep (#486 follow-up) shrink to a282 × 282table — the table problem disappears entirely rather than needing the blocked build. - The prefix ballooning that made the committed unrestricted
Eq(8)run take about three hours acts on a pool two orders of magnitude smaller; a uniformEq(9)sweep should take minutes even in the pure engine, andEq(10)andEq(12)come into range — sizes the unrestricted table-driven design cannot touch at all. - Prime degrees degenerate gracefully and correctly:
Eq(7)andEq(11)have no nontrivial uniform partitions, matching the group fact that a transitive action of prime degree is primitive, so its congruence lattice is the two-element chain; the sweep can skip primenand the enumerator's empty pool there is a wired-correctly cross-check.
Implementation sketch¶
- Enumerate the uniform pool directly, one divisor
kofnat a time (never through the fullBell(n)enumeration), in the engines' canonical min-rooted parent-vector order. - A copy is closed under the target's meets and joins by definition, so the assignment plan only ever needs meet/join of pool members followed by a membership test in the pool: compute them on the fly with the existing pure kernels or precompute pool² tables — both trivial at these pool sizes. A meet or join of two uniform partitions need not be uniform; that case simply fails the placement, which is the pruning doing its work.
- Classification and orbit generation are unchanged: relabeling points preserves uniformity, so class representatives, stabilizers, and orbit sizes work exactly as today.
- The closure test is unchanged (the full unary-map monoid). Remark iv's second sentence — restricting the polymorph search to permutations — is a separable optimization with different verdict semantics (
Invof the permutation group alone) and should stay out of this flag, or land later as its own flag with its own documentation. - Reports keep the
flrp-eqsearch v1format with a field recording the restriction, so uniform censuses are never mistaken for full ones.
Tests¶
- Parity with the unrestricted engine: for
n ≤ 7, filter the full census's classes to those whose members are all uniform and require the--group-repsweep to produce exactly those classes; behindFLRP_EQSEARCH_SLOW=1, apply the same filter to the committedEq(8)report (out/l7_eq8_report.json). ForL7/Eq(6)both known classes contain non-uniform members (the grid element(1,0)is|0,2|3,4|with singleton blocks), so the uniform census there is empty — pin it. - Pool pins: the uniform counts in the table above for
n = 6, 8, 9, 10as unit tests of the enumerator. - Fast/pure backend parity, as for the existing
--fasttests.
The headline runs¶
- The
--group-repsweep ofEq(9)for libraryL7(manuscriptL10), with the verdict — a closed class and hence a witness algebra flowing into the certificate pipeline, or a machine-checked "no transitive representation on nine points" — recorded indocs/notes/flrp-l7-eq6.mdand #484. - Then
Eq(10)andEq(12)as budget permits (Eq(11)is prime and skips itself). - Cross-validation with #487's transitive-degree scan: the GAP side enumerates transitive groups of degree
nand tests intermediate-subgroup intervals[H, G] ≅ L7; a closed uniform class found here must be visible there and vice versa, so disagreement in either direction is a bug or a discovery.
Acceptance criteria¶
-
--group-replands in both engines with byte-identical reports, a recorded restriction field, and documented negative-verdict semantics in the README. - The pool enumerator's counts and the filter-parity tests (including the empty
L7/Eq(6)uniform census) are pinned inmake flrp-test. - The
Eq(9)uniform sweep for libraryL7is run and its outcome recorded in theL7note and #484.
Part of #483; extends #486 (search tooling); serves #484 (the L7 hunt) and cross-validates #487 (the GAP transitive-degree scan).
Issue M6-14f: eqsearch --group-rep: bring the Eq(12) uniform sweep within reach (orbit–stabilizer classification, blocked pool tables) (#499, closed)¶
Labels: milestone-6-flrp, research-exploratory, flrp-research
Description¶
Extend the #494 uniform restriction (--group-rep, PR #498) so the Eq(12) sweep runs to a verdict. Twelve is now the frontier: the Eq(9) and Eq(10) uniform censuses are empty and eleven is prime (docs/notes/flrp-l7-eq6.md § 8), so a minimal representation of library L7 (manuscript L10; dictionary docs/notes/flrp-slr-naming.md), if one exists, has at least twelve elements — and n = 12 is the first ground-set size whose uniform pool contains comparable nontrivial partitions (divisor chains 2 | 4, 2 | 6, 3 | 6), hence the first where a uniform copy of L7 is even conceivable.
Why Eq(12) is decisive¶
- A closed uniform class at twelve is a candidate minimal representation of the open lattice, flowing directly into the WP-6 certificate pipeline (carrier 12 is well inside the renderer's literal cap of 32).
- An empty or unclosed census pushes the frontier from twelve to sixteen in one step: thirteen is prime, and fourteen (
2 ∤ 7) and fifteen (3 ∤ 5) have antichain pools by the divisor argument of theL7note § 8, so with the manuscript's § 5 transitivity theorem the next size where a uniform copy is conceivable is16 = 2⁴(chains2 | 4 | 8). - Cross-validation with #487 (the GAP transitive-degree scan,
scripts/gap/flrp/): degree 12 is the first degree where both attacks probe genuinely new ground; a closed class found here must be visible there and vice versa, so disagreement in either direction is a bug or a discovery.
What breaks at twelve, and the known fixes¶
The #494 engines were sized for pools of a few hundred to a thousand; at twelve the nontrivial pool is 32,032 (shapes 2⁶: 10,395, 3⁴: 15,400, 4³: 5,775, 6²: 462).
- Tables. Eager pool² meet/join at
int16is ~4.1 GB; replace with a blocked (row-band) build or with on-the-fly membership — per-prefixmeet_rows/join_rowsagainst the pool matrix plus binary search over the sorted pool codes, memoized by prefix index. The 2026-07-24Eq(10)measurements (pure 6 m 59 s versus fast 24 m 12 s: the constant per-prefix mask cost dominates at narrow pools) say to benchmark both engines rather than assume vectorization wins. - Classification. Materialized orbits are
12! ≈ 4.79 × 10⁸relabelings per class — hours apiece even with #494's chunking. Replace with orbit–stabilizer: backtrack for the stabilizer of the relation set, report orbit size12!/|stab|, keep the first-found-representative order, and keep a conservation cross-check (Σ 12!/|stab|equals the number of distinct relation sets) so reports stay byte-identical wherever the materialized classifier also runs. - Closure universe.
Inv(M)must still range over all ofEq(12)(Bell(12) = 4,213,597): the tuple-of-tuples universe costs on the order of a gigabyte and a progressive filter pass is seconds per map, so either accept that, pack the universe as anint8matrix with a vectorized invariance filter, or stream the filter — decided by measurement, without changinginvariant_partitionssemantics. - Sweep order. The prefix ballooning of the generic height-ordered assignment plan (#486's known follow-up) may finally bite once the pool has real chains; the constraint-density-guided order is the fix if it does.
Tests¶
- Pool pins at twelve: 32,032 nontrivial members with the shape split 10,395 + 15,400 + 5,775 + 462, plus the structural facts at 13, 14, 15 (empty or antichain pools) as cheap cross-checks.
- Byte-parity of the orbit–stabilizer classifier against the materialized one on every existing census (
M3on 4 and 6 points, the uniformL7censuses through ten, and the committed unrestricted reports). - The committed
Eq(12)report re-derived underFLRP_EQSEARCH_SLOW=1, with fast/pure cross-validation of whatever engine variants land.
The headline run¶
- The
--group-repsweep ofEq(12)for libraryL7, with the verdict — a closed class and hence a witness algebra flowing into the certificate pipeline, or a machine-checked "no transitive representation on twelve points", which by the chaining above moves the frontier to sixteen — recorded indocs/notes/flrp-l7-eq6.mdand #484.
Acceptance criteria¶
- The
Eq(12)uniform sweep completes on one core with recorded wall-clock, byte-deterministic output, and a committed report. - The classification and table costs are brought down as sketched, with parity pinned against the existing engines on all committed censuses in
make flrp-test. - The verdict is recorded in the
L7note and #484; if a class closes, the witness flows throughclaim_input/emit_agda.pyto an Agda-checked certificate.
Part of #483; extends #494 (PR #498) and #486; serves #484 (the L7 hunt); cross-validates #487 (the GAP transitive-degree scan).
Issue M6-15: FLRP: formalize the unary-reduction theorem Con 𝑨 = Con ⟨A, Pol₁(𝑨)⟩ (#501)¶
Labels: milestone-6-flrp, research-exploratory, flrp-research
Description¶
Formalize the unary-reduction theorem for congruence lattices: the congruences of an algebra are exactly the equivalence relations compatible with its unary polynomial operations, so Con 𝑨 = Con ⟨A, Pol₁(𝑨)⟩ (McKenzie–McNulty–Taylor, Algebras, Lattices, Varieties I, Theorem 4.18). The manuscript docs/papers/fin-lat-rep/SmallLatticeReps.tex invokes this reduction at the start of its Kurzweil–Netter duality proof ("we can assume that F consists of unary operations"), and the closure method of its § Concrete Representations (the λ(L) operator, the filter–ideal lemma) lives entirely in the unary world, so this theorem is the bridge from the library's general signatures to those arguments.
Context: the WP-5 closure toolkit (#456) deliberately avoided this reduction — the product and ordinal-sum witness constructions carry general signatures directly — but the planned formal proof of Kurzweil–Netter duality (#502) needs it, and it is independently useful infrastructure for the FLRP program (#451).
Tasks¶
- Unary polynomial operations of a setoid algebra: terms in one variable with constants from the carrier, or the inductive closure of the basic operations under composition and point substitution; pick one canonical presentation and prove it closed under composition.
- The reduction theorem at Layer S: an equivalence relation is a congruence of
𝑨iff it is compatible with every unary polynomial; henceCon 𝑨andConof the unary reduct are equal as posets (mutual≑, order preserved). - The Layer-D corollary for finite finitary algebras: the unary reduct is again finite finitary (unary polynomials of a finite algebra are finitely many up to extensional equality, which is decidable on a finite carrier), and
DecContransports across the reduction. - Placement per roadmap § 6: the polynomial machinery is reusable mathematics and belongs in the
Setoid/tree (e.g. besideSetoid.Terms), not underFLRP/.
Acceptance criteria¶
- Type-checks under
--safewith no postulates; the reduction is stated and proved at Layer S with the Layer-D transport for finite finitary algebras.
Issue M6-16: FLRP WP-5 stretch: formal Kurzweil–Netter duality proof, retiring Assumptions Entry 2 (#502)¶
Labels: milestone-6-flrp, research-exploratory, flrp-research
Description¶
Prove Kurzweil–Netter duality closure formally, retiring Entry 2 of FLRP.Assumptions: if a finite lattice is decidably representable then so is its dual, with no hypothesis. This is the stretch goal of WP-5 (#456), split out so the closure-toolkit PR could land without it; roadmap § 7 flags the payoff explicitly — the content is finite and combinatorial, and Netter's 1986 proof may never have been published, so a machine-checked reproof is independently valuable (a standalone paper).
The target argument is the one presented in docs/papers/fin-lat-rep/SmallLatticeReps.tex § "Lattice duals: the theorem of Kurzweil and Netter" (after Pálfy's 2009 lectures): the idempotent-contraction lattice IC(n) ≅ Eq(n); the dual isomorphism f ↦ f̂[Sⁿ] from Eq(n) onto the interval [D, Sⁿ] of the subgroup lattice of a power of a finite nonabelian simple group S (Lemma lem:latt-duals); the transitive-G-set bridge Con ⟨Sⁿ/D, Sⁿ⟩ ≅ [D, Sⁿ]; and the expansion of the coset algebra by the lifted operations F̂, cutting the congruences down to the F-invariant partitions.
On completion, KurzweilNetterDuality becomes a proved theorem, dual-Representableᵈ of FLRP.Closure drops its hypothesis, and the census's assumption-conditional entries L18/L22 (#485) become unconditional.
Prerequisites¶
- The WP-3 bridge
Con (G ↷ G/H) ≅ [H, G]at Layer D on the needed scale (#454), plus WP-2 group infrastructure for the powerSⁿ, its diagonal subgroupD, and the interval[D, Sⁿ]. - The unary-reduction theorem
Con 𝑨 = Con ⟨A, Pol₁(𝑨)⟩(#501), or a reworked argument that lifts general-arity operations through the construction directly. - A finite nonabelian simple group in the library to instantiate
S: either formalize simplicity ofA₅(a substantial task in itself), or state the closure theorem parameterized by such anSand track theA₅instantiation separately.
Tasks¶
-
Eq(n) ≅ IC(n)and the dual isomorphism onto[D, Sⁿ](the manuscript's Lemma lem:latt-duals). - The expansion step: congruences of the expanded coset algebra correspond to
F-invariant partitions, i.e. to the congruences of the original algebra, dually ordered. - Assemble
(𝑳 : Lattice) → Representableᵈ 𝑳 → Representableᵈ (dualLattice 𝑳)and retire Entry 2 per the registry's documented retirement path (deprecate the assumption, rewiredual-Representableᵈ).
Acceptance criteria¶
- Type-checks under
--safewith no postulates and no registry hypothesis;FLRP.AssumptionsEntry 2 is retired with its documentation updated to point at the theorem.
Issue M6-17: Retire the degenerate minIE in favour of MinimallyIE (#509)¶
Labels: bug, milestone-6-flrp, flrp-research
Description¶
minIE of FLRP.Enforceable (WP-4) does not define minimal interval enforceability. It quantifies minimality against a single other representation:
minIE P 𝑳 = ∀ 𝒢 𝒬 H J H-sg J-sg → (fin : FiniteAlgebra …) → IntervalIso 𝒢 H H-sg 𝑳
→ (fin' : FiniteAlgebra …) → IntervalIso 𝒬 J J-sg 𝑳 → fin .card ≤ⁿ fin' .card → P 𝒢
Instantiating 𝒬 := 𝒢 and fin' := fin makes the cardinality premise card ≤ card, so minIE P 𝑳 implies P of every finitely presented representation of 𝑳. It is therefore plain interval enforceability restricted to finite groups, not min-IE. minIE-degenerate in FLRP.Reductions (#507) proves the collapse in one line, and the RP-2 catalog states its min-IE entry (Köhler, Pálfy–Pudlák on minimal representations of Mₙ) over the repaired notion MinimallyIE instead, in which minimality is quantified over all finite representations.
This was left unfixed on #507 deliberately, to keep that branch additive while #506 was in review.
Tasks¶
- Move
MinimallyIE,IE→MinimallyIE, andMinimallyIE-∧fromFLRP.ReductionsintoFLRP.Enforceable, replacingminIEunder that name (one canonical form per concept — no synonym pair). - Keep
minIE-degenerateas a regression witness, restated against whatever the replacement is called, or record the defect in the module prose if the old definition disappears entirely. - Update
FLRP.ReductionsEntry 6 anddocs/notes/flrp-rp2-catalog.md§ 4.7 to point at the canonical definition. - While there: consider whether the exactness caveat on
card(it bounds the carrier from above, so this is minimality of certified cardinalities) deserves aFiniteAlgebrawith an exact enumeration, or stays a documented approximation.
Acceptance criteria¶
-
make checkgreen; no definition in the tree has the degenerate quantifier shape. - Blocked until #506 and #507 land, so the edit does not collide with review fixes.
Follow-up to #459 / #507. Part of #451.
Issue M6-18: Minimal normal subgroups exist in finite groups (well-founded descent) (#510)¶
Labels: enhancement, milestone-6-flrp, flrp-research
Description¶
Prove that every nontrivial normal subgroup of a finite group contains a minimal one, by well-founded descent on order, and discharge the hypothesis it currently stands in for.
This single fact is the last finiteness gap in the parachute structure theory. It is assumed twice today, both times as an explicit argument and never as a postulate:
- RP-1 (#506) threads it as the
Mparameter ofGroupParachute.Structure.Minimal— the minimal normal subgroup whose centralizer Lemma 3.7 (i) computes (docs/notes/flrp-rp1-parachutes.md§ 4, fourth assumption); - RP-2 (#507) threads it as
MinimalNormalDescent, the antecedent of the enforced property in catalog Entries 1–3, so that the quantifier over normal subgroups in𝒢₃and𝒢₄is not silently narrowed (docs/notes/flrp-rp2-catalog.md§ 4.2).
Discharging it turns those entries into the note's statements verbatim.
Tasks¶
- Decide the finiteness interface:
FiniteAlgebraon the underlying algebra gives a decidable setoid equality and a surjective enumeration, from which a measure on equality-respecting subgroups (the number of enumerated elements satisfying a decidable membership predicate) is computable — note this needs the Layer-D presentation of the subgroup (decidable membership), exactly asIntervalᵈdoes; a semantic-only subgroup has no computable order. - Well-founded descent: a strictly decreasing chain of nontrivial normal subgroups terminates, using
Data.Nat.Induction's<-well-foundedness on the measure. - Conclude
MinimalNormalDescentfor a finite group with decidably presented normal subgroups, and instantiate RP-1'sMinimalmodule from it. - Update the two design notes and drop the antecedent from catalog Entries 1–3.
Acceptance criteria¶
- Type-checks under
--safe, no postulates; the Layer-D requirement (if any) is stated explicitly per ADR-008 rather than smuggled in. -
FLRP.ReductionsEntries 1–3 readcfIE 𝒢ᵢ ⊕ᵖ-Latticewith no conditional antecedent, for finite groups.
Follow-up to #458 / #459. Part of #451.
Issue M6-19: Certify M₆ as an interval: discharge Entry 5 vacuity by computation (#511)¶
Labels: enhancement, milestone-6-flrp, flrp-research
Description¶
Discharge the group representability of M₆ by computation instead of importing it, so that the non-vacuity of RP-2's Entry 5 becomes a theorem.
The vacuity discipline of the enforcement catalog (#507) requires every entry to track whether its enforcing lattice is known to be group representable, since a lattice that is no interval enforces everything (not-representable→IE). Entry 5 (𝒢₁, neither alternating nor symmetric, IE via M₆) currently imports its witness as the hypothesis M₆-representable, justified by the folklore construction quoted in docs/notes/flrp-rp2-catalog.md § 3: for a prime power q, M_{q+1} is the subspace lattice of a two-dimensional space V over F_q, realized as the interval [K , V ⋊ K] where K ≅ F_q^* acts by scalars.
For q = 5 the witness group has order 25 · 4 = 100 and the interval has 8 elements — small enough for the WP-6 certificate pipeline, and it would be the first group-side certificate in the catalog.
Tasks¶
- GAP side (
scripts/gap/flrp/): emitV ⋊ F₅^*of order 100 with the scalar action, the subgroupK, and the interval[K , G]; check[K , G] ≅ M₆there first. - Certificate side: the interval is a congruence lattice by
FLRP.Bridge(Con (𝒢 ↷ 𝒢/K) ≅ [K , 𝒢]), so the existing algebra-side certificate schema applies to the coset action on the 25 cosets; alternatively certify the interval directly if that is cheaper. - Agda side: check the emitted certificate and derive
GroupRepresentable M[ 6 ], then instantiateEntry-𝒢₁.nongiant-nonvacuouswith it in place of the hypothesis. - Record in the survey note that Entry 5's vacuity datum is discharged, and note that Entry 4's (
M₇inA₃₁, index30!/10) is out of computational reach and stays an import.
Acceptance criteria¶
-
GroupRepresentable M[ 6 ]is inhabited in the library with no new assumption, and Entry 5's non-vacuity no longer takesM₆-representableas an argument. - The emitter and its golden test live under
scripts/with a Makefile target, perCLAUDE.md.
Follow-up to #459 / #507; uses the WP-6 pipeline (#457) and the WP-3 bridge. Part of #451.
Issue M6-20: Solvability and the alternating/symmetric predicates (#512)¶
Labels: enhancement, milestone-6-flrp, flrp-research
Description¶
Define solvability and being an alternating or symmetric group in the library, turning four RP-2 catalog entries from schemas into statements.
FLRP.Reductions (#507) parameterizes Entries 4, 5, 7, and 8 by an abstract group predicate together with the facts their sources supply about it, because neither notion is definable in the library today (docs/notes/flrp-rp2-catalog.md § 4.8). The schemas instantiate unchanged once the predicates exist, and the exercise made explicit which properties are actually used: for solvability, only H-closure and the Mₙ exclusion.
Solvability additionally closes an RP-1 open item: the second half of the note's Lemma 3.7 (ii), "a group with a nonabelian minimal normal subgroup is nonsolvable" — the sharper structural fact (Minimal.nonabelian) is already proved (#506).
Tasks¶
- Solvability: the derived series (commutator subgroups iterated) or a subnormal abelian series; prove the class closed under homomorphic images (this is exactly
Entry-𝒢₀.SolvableHClosed), and that a group with a nonabelian minimal normal subgroup is nonsolvable. -
AₙandSₙ: the symmetric group onFin nexists in embryo (Examples.Classical.Groups.SymmetricGroup3); generalize toSym (Fin n)and the alternating subgroup, and defineAltOrSym 𝒢as "isomorphic toAₙorSₙfor somen". Prove H-closure (Entry-𝒢₁.AltSymHClosed): the quotients ofAₙ/Sₙare again alternating or symmetric. - Instantiate the four catalog schemas at the new predicates and simplify the survey note § 4.8.
- Close the degree-
≤ 4gap of Entry 5 (survey note § 3): Basile's Theorem D assumes degree at least 5, and the small cases were checked by hand, not machine-checked. Note that the check is not vacuous —[V₄ , S₄] ≅ M₄, soM₄does occur in a symmetric group and onlyM₆(and higher counts outside{1,2,3,5,7,11}) is safe. Either decide the small cases by computation overFin-presentedAₘ/Sₘform ≤ 4, or restrict the imported hypothesis to degree≥ 5and compose Entry 5 with Entry 4 through "every alternating or symmetric group of degree≤ 4is solvable".
Acceptance criteria¶
- Both predicates are defined in
Classical/(reusable mathematics, roadmap § 6), not underFLRP/. - The two H-closure hypotheses of
FLRP.Reductionsare proved rather than assumed, and the entries no longer take an abstract predicate.
Follow-up to #459 / #507; also closes an open item of #458. Part of #451.
Issue M6-21: Aschbacher's D∆ and signalizer theorems, specialized to parachutes (#513)¶
Labels: milestone-6-flrp, blocked-upstream, research-exploratory, flrp-research
Description¶
Obtain Aschbacher's D∆ and signalizer-lattice papers and work out what they say about minimal parachute representations, then add the resulting entries to the RP-2 catalog.
This is roadmap avenue B and the highest-value external entry still missing. Parachutes have disconnected interiors, which is exactly the domain of Aschbacher's class D∆, so his reductions plausibly apply to them directly — but RP-2 rejected the entry rather than guess it (docs/notes/flrp-rp2-catalog.md § 5): the statements are inseparable from his own apparatus (O_G(H)'', M_G(H), signalizer lattices), and transcribing them from secondary descriptions would produce exactly the plausible-sounding non-theorem the phase's discipline exists to prevent. Specializing them to parachutes is research, not transcription.
Sources needed (none reachable in the current environment; all paywalled, no preprints located):
- M. Aschbacher, On intervals in subgroup lattices of finite groups, J. Amer. Math. Soc. 21 (2008), 809–830.
- M. Aschbacher, Signalizer lattices in finite groups, Michigan Math. J. 58 (2009), 79–103.
- M. Aschbacher, Lower signalizer lattices in alternating and symmetric groups, J. Group Theory 15 (2012), 151–225.
- M. Aschbacher, Overgroup lattices in finite groups of Lie type containing a parabolic, J. Algebra 382 (2013), 71–99.
- M. Aschbacher and J. Shareshian, Restrictions on the structure of subgroup lattices of finite alternating and symmetric groups, J. Algebra 322 (2009), 2449–2463 — cited by the note beside Basile for
𝒢₁, currently named but not consumed by the catalog.
One usable lead: §§ 2 of arXiv:1911.04516 (Lucchini–Moscatiello–Palcoux–Spiga) is a careful secondary presentation of Aschbacher's notation and of the overgroup results his program supplies, and is a reasonable entry point while the primary texts are being obtained. This is also the avenue most likely to benefit from expert correspondence (roadmap § 5 B).
Tasks¶
- Obtain the primary texts (library access or correspondence).
- State the
D∆hypothesis and the minimal-representation conclusion precisely enough to write down, in the vocabulary ofFLRP.Enforceable; expect a min-IE disjunction ("Galmost simple, or a signalizer lattice arises"). - Decide what it says when the lattice is a parachute with two big canopies, where RP-1 already forces a unique nonabelian minimal normal subgroup with trivial centralizer and
NH = G(Lemma 3.7) — the two structure theories should either compose or conflict, and either outcome is informative. - Add the resulting entries to
FLRP.Reductionswith their citations, and record verification status in the survey note § 3. If a claim cannot be pinned down from the primary text, leave it rejected in § 5 rather than approximating it. - Same treatment for Aschbacher–Shareshian, which would give Entry 5 a second independent source.
Acceptance criteria¶
- Either new catalog entries whose statements are verified against the primary texts, or an updated § 5 explaining precisely which statement resisted formalization and why.
Follow-up to #459 / #507. Part of #451; roadmap avenue B.
Issue M6-22: Normal subgroups and congruences of a group: the missing correspondence (#508, closed)¶
Labels: enhancement, milestone-6-flrp, flrp-research
Description¶
Formalize the correspondence between normal subgroups of a group and congruences of it, and use it to identify the group-side monolith notion with the library's congruence-side one.
Classical.Structures.Group.MinimalNormal (added by #507) defines HasMonolithᵍ — a least nontrivial normal subgroup — because the library has no way to say "this group is subdirectly irreducible" in the sense of Setoid.Congruences.Monolith.IsSubdirectlyIrreducible, which is a statement about Con 𝑨. The RP-2 catalog's Entry 1 (𝒢₂) is therefore stated group-side, with the divergence recorded in docs/notes/flrp-rp2-catalog.md § 4.1. This issue retires that divergence.
The work is ordinary — no obstruction and no classical input — and it is reusable mathematics, so per roadmap § 6 it belongs in Classical/Structures/Group/, beside FLRP.Bridge's Pálfy–Pudlák correspondence, not under FLRP/.
Tasks¶
- From a normal subgroup
N, the relationx θ y ⟺ x y⁻¹ ∈ Nis a congruence of the group algebra: reflexivity, symmetry, transitivity,≈-respect, and compatibility with the three operations ofSig-Group. - From a congruence
θ, the class{x : x θ ε}is an equality-respecting normal subgroup. - The two maps are monotone and mutually inverse (up to
≑on congruences and mutual inclusion on subgroups), hence an order isomorphismCon 𝑮 ≅ Normal(𝑮); nontriviality of the subgroup corresponds toNonzeroof the congruence. - Transport
HasMonolithᵍtoHasMonolith, givingIsSubdirectlyIrreducibleᵍ 𝒢 → IsSubdirectlyIrreducible (proj₁ 𝒢); the least-element form needed formono-leastis already available asminimal-meets→least. - Retire the
ᵍsuperscript inMinimalNormal(FLRP modules are exempt from the deprecation cycle, roadmap § 1, so the rename can be direct) and update the𝒢₂entry ofFLRP.Reductionsplus § 4.1 of the survey note.
Acceptance criteria¶
- Type-checks under
--cubical-compatible --exact-split --safewith no postulates. -
𝒢₂ofFLRP.Reductionsis stated with the library'sIsSubdirectlyIrreducible, and the survey note's § 4.1 divergence is replaced by a pointer to the bridge.
Follow-up to #459 / #507. Part of #451.
Issue M6-23: Powers, diagonals, and the interval [D , Sⁿ] (#521, closed)¶
Labels: enhancement, milestone-6-flrp, flrp-research
Description¶
Build the group infrastructure that Kurzweil's construction needs — the power Sⁿ of a group, its diagonal subgroup D, and the interval [D , Sⁿ] — once, in Classical/, so that both FLRP consumers import the same definitions: RP-4's wreath no-go (#461, Lemma 3.3 of the vendored note docs/papers/flrp/ieprops/) and the Kurzweil–Netter duality proof (#502, WP-5 stretch). Reusable mathematics lands in the Classical/ tree per roadmap § 6; the FLRP-facing interval packaging composes with FLRP.Enforceable's UpperInterval / IntervalIso, the interval presentation everything downstream expects.
The mathematical target is Kurzweil's lemma (lem:latt-duals of docs/papers/fin-lat-rep/SmallLatticeReps.tex, discussed in DeMeo's thesis § 2.2): for S a finite nonabelian simple group, the interval [D , Sⁿ] in Sub(Sⁿ) is isomorphic to Eq(n)′, the dual of the partition lattice of an n-element set. Both written sources prove only the order-reversing embedding π ↦ K_π = { y ∣ ker π ≤ ker y }; the surjectivity half — every subgroup between D and Sⁿ is such a K_π, the step where nonabelian simplicity enters — is cited to Kurzweil's 1985 article and not reproved. The formal treatment mirrors that split honestly:
- everything the sources actually prove is formalized unconditionally — the power, the diagonal, the partition subgroups with their membership characterizations, the partition lattice
Eq(n)itself as a level-0 equationalLattice(on the Freese normal-form parent vectors ofSetoid.Congruences.Certificates.Schema, which are exactly the idempotent decreasing mapsIC(n)the sources use), and the dual order-embeddingEq(n) → [D , Sⁿ]; - surjectivity is registered as
FLRP.AssumptionsEntry 4 in the established per-entry style (statement, source and citation, status, layer, retirement path), stated so that it hands the consumer the partition witness; the assembledIntervalIso [D , Sⁿ] ≅ Eq(n)′is then a proved theorem conditional on the entry, and retiring the entry (a follow-up issue: the normal-subgroup structure of powers of a nonabelian simple group, plus the induction over blocks) upgrades it with no change to consumers.
Tasks¶
- The indexed product
⨅ᵍof groups and the power_^ᵍ_(carrierFin n → S, pointwise operations), generalizing the binary_×ᵍ_ofClassical.Structures.Group.Productrather than duplicating it; satisfaction transfers by⊧-P-invarofSetoid.Varieties.Properties. Coordinate projections and pointwise descriptions of the curried operations. - The diagonal
D = { (s , … , s) }as an equality-respecting subgroup ofSⁿ, with its membership characterization. - The partition lattice
Eq(n)as aClassical.Small.Structures.Lattice, order-first on normal-form parent vectors: kernel-inclusion order, computable meet and join, lattice laws derived from the order, and thedualLatticeinstance. - Partition subgroups
K_πwithD ≤ K_π ≤ Sⁿ, the membership characterizationy ∈ K_π ⟺ ker π ⊆ ker y, and the dual order-embedding (order-reversal in both directions; the reflection direction consumes nontriviality ofS). - The interval
[D , Sⁿ]as anUpperIntervalinstance, and the conditional theorem assemblingIntervalIso (Sⁿ) D (dualLattice (Eq n))from Entry 4. -
FLRP.AssumptionsEntry 4: Kurzweil interval surjectivity, per-entry documentation and retirement path. - Consumer interface sanity check: state (as type definitions, not proofs) the signatures RP-4 (#461) and Kurzweil–Netter (#502) will call, and confirm they typecheck against what was built.
Acceptance criteria¶
- Type-checks under
--cubical-compatible --exact-split --safewith no postulates; classical inputs enter only through the named Entry 4 hypothesis. -
make check,make unused-imports, andmake check-links(aftermake gen-links) are green.
Consumers: #461, #502. Part of #451; roadmap §§ 2, 6.
Issue M6-24: Kurzweil surjectivity: every subgroup in [D , Sⁿ] is a partition subgroup (retire Assumptions Entry 4) (#522)¶
Labels: enhancement, milestone-6-flrp, flrp-research
Description¶
Prove Kurzweil surjectivity — for a finite nonabelian simple group S, every subgroup of Sⁿ containing the diagonal D is a partition subgroup K_π — and retire Entry 4 of FLRP.Assumptions per its documented retirement path. This is the onto half of Kurzweil's lemma [D , Sⁿ] ≅ Eq(n)′; the dual order embedding and the conditional isomorphism kurzweilIntervalIso landed with #521, so discharging this entry upgrades the isomorphism to an unconditional theorem at simple instantiations, with no change to consumers (#461, #502).
The missing mathematics is the normal-subgroup structure theory of powers of a nonabelian simple group. The classical argument (Kurzweil 1985; Pálfy's 2009 lectures): the kernel meet π of a subgroup U ∈ [D , Sⁿ] satisfies U = K_π, by showing each block column { c_B(s) ∣ s ∈ S } lies in U — the set N_B = { s ∣ c_B(s) ∈ U } is normal in S by conjugating with diagonal elements, so by simplicity it is trivial or everything, and nontriviality of N_B is where nonabelianness enters (normal subgroups of Sᵐ are partial products, so a surjection Sᵐ → S is a coordinate followed by an automorphism, which the diagonal forces to be the identity).
Prerequisites¶
- A simplicity predicate for groups (issue #512 owns the alternating/symmetric and solvability predicates; simplicity in the "every normal subgroup is trivial or full" form can land there or here).
Classical.Structures.Group.{Power, Diagonal, PartitionSubgroup}andFLRP.KurzweilIntervalfrom #521.
Tasks¶
- Normal subgroups of a finite power
Sⁿof a nonabelian simple group are the partial products (the commutator argument: a normal subgroup with a nontriviali-th coordinate contains the fulli-th factor). - A subgroup of
Sⁿcontaining the diagonal collapses blockwise: withπits kernel meet, each block column lies in it. - Assemble
KurzweilSurjectivityAt 𝒮 nfor𝒮simple nonabelian, at Layer S; derive the Layer-D reading over decidable interval elements. - Retire Entry 4: deprecate
KurzweilSurjectivityAtas a hypothesis, rewirekurzweilIntervalIsoandeqDual-groupRepresentable, and update the registry documentation.
Acceptance criteria¶
- Type-checks under
--cubical-compatible --exact-split --safewith no postulates; the nonabelian-simple side condition of Entry 4 becomes a formal hypothesis rather than prose.
Follow-up to #521. Feeds #461 and #502; part of #451.
Issue M6-25: L16 erratum: the printed Sub(C2.A6) interval does not reproduce — and three parked census entries are duals of certified ones (#529)¶
Labels: milestone-6-flrp, research-exploratory, flrp-research
Description¶
Two findings about the L16 entry of the SmallLatticeReps § 6 catalog, one negative and one positive. The negative one extends erratum E2 of docs/notes/flrp-slr-census.md; the positive one settles L16's census status outright and, in passing, two other parked entries. All numbering is the manuscript's (docs/papers/fin-lat-rep/SmallLatticeReps.tex, 2016-06-10 draft); the dictionary is docs/notes/flrp-slr-naming.md.
1. The printed group representation does not reproduce (E2, extended)¶
The manuscript prints, for L16 (covers 0 ≺ 1, 2; 1 ≺ 3, 4, 5; 2, 3, 4, 5 ≺ 6):
Upper interval in Sub(
C_2.A_6), algebra of size 180
That asserts a subgroup H ≤ C2.A6 of index 180 — so |H| = 4 in a group of order 720 — with [H, C2.A6] ≅ L16. Both readings of C2.A6 fail, and the failure is not a near miss:
C2.A6 = 2.A6 = SL(2,9)(the ATLAS double cover, the reading of E2). A single conjugacy class of index-180 subgroups; its interval has 38 elements.C2 × A6(the split reading, checked here for the first time). Index-180 classes give intervals of sizes 16, 28, 38 — no seven-element interval at all.
Stronger, and independent of which group was meant: no finite group has an upper interval ≅ L16 of index ≤ 16. The transitive-groups scan settles every index it covers, because a counterexample of index n can be taken core-free (if N = Core_G(H) ≠ 1 then [H/N, G/N] ≅ [H, G] at the same index), hence is a faithful transitive action of degree n; degrees 4, 6, 8, 9, 10, 12, 14, 15, 16 were scanned exhaustively — 2340 transitive groups, 1954 of them at degree 16 — and every prime degree is a free negative (transitive of prime degree ⇒ primitive ⇒ two-element interval). The Eq(n) uniform-partition filter (#494) agrees independently: L16 has no uniform copy in Eq(n) for n ≤ 10, so no transitive G-set of those degrees can have it as a congruence lattice.
Either the group or the index is wrong in the printed entry; this issue does not guess which.
2. L16 is the dual of L17 — and so are two other parked entries¶
L16 ≅ dual(L17), verified by exhaustive order-isomorphism search over the committed stanzas (L16 is not self-dual). L17 is certified in this library (FLRP.Certificates.SmallLatticeReps.SLR17, from the manuscript's own 12-element algebra B17), so L16 is representable through dual-Representableᵈ of FLRP.Closure.Basic, conditional on FLRP.Assumptions Entry 2 (Kurzweil–Netter) — exactly the route the census already uses for L18 and L22. L16 therefore needs no group representation at all to leave the parked list; the erratum above concerns only the manuscript's stated construction.
Sweeping the same test across every parked entry turns up two more:
| parked entry | dual is | census status today |
|---|---|---|
L14 |
L15 (certified, SLR15) |
group representation, Sub(A6) index 90 — reproduced, but parked on the WP-3 bridge |
L16 |
L17 (certified, SLR17) |
group representation, Sub(C2.A6) — does not reproduce |
L20 |
L21 (certified, SLR21) |
filter-ideal in SmallGroup(216,153); the draft prints no explicit construction |
L18 |
L19 (certified) |
already recorded as a dual |
L22 |
L23 (certified) |
already recorded as a dual |
L10, L11, L28 |
self-dual | duality gives nothing new |
The manuscript lists dual pairs adjacently (14/15, 16/17, 18/19, 20/21, 22/23), so the pairing looks deliberate; the census and FLRP.Closure.Basic simply track it for only two of the five pairs.
Tasks¶
- Extend erratum E2 in
docs/notes/flrp-slr-census.mdwith theC2 × A6result, the index-≤-16 non-existence, and theEq(n)uniform-filter cross-check; commit the GAP artifacts underscripts/gap/flrp/out/. - Record the duality finding in the census: reclassify
L14,L16,L20as assumption-conditional duals ofSLR15,SLR17,SLR21, keeping the group-representation notes as the (independent) second route forL14. - Update the payoff prose in
src/FLRP/Closure/Basic.lagda.md, which names onlyL18andL22as the census's dual entries — five of the seven parked entries are duals of certified ones. - Consider a
bin/sweep_smallgroups.gdriver:FLRP_ScanSmallGroupsexists inlib/search.gwith no command-line front end, which is why the searches above had to go throughfind_interval.gandscan_transitive.g. - Optional, if cheap: push the transitive scan past degree 16 to sharpen the non-existence bound (degree 18 has 983 groups, 20 has 1117, 24 has 25000 — the last is likely out of reach), and note that
scan_transitive.ghard-codesL7naming and output paths while its prescreen (interval size 7) serves any seven-element target — worth parameterizing. - Report the erratum upstream to https://github.com/UniversalAlgebra/fin-lat-rep alongside E1, with the suggested repair: cite duality with
L17(as the draft already does forL18andL22), or supply a corrected group and index.
Acceptance criteria¶
- The census records
L16's status as settled-by-duality, with the failed group representation logged as an erratum rather than a pending search. - Every claim above is reproducible from committed artifacts and documented commands.
Part of #483; follows up the census of #485 and the GAP engine of #487. The duality route retires unconditionally when #502 discharges Entry 2.
Issue M6-25: Instantiate Kurzweil–Netter duality at a concrete simple group (A₅) (#527)¶
Labels:
Description¶
The formal Kurzweil–Netter duality proof of #502 (FLRP.KurzweilNetter.Duality) is deliberately parameterized by the base group rather than instantiated: KurzweilNetterProof takes a group 𝒮 together with exactly the properties the argument uses — a FiniteAlgebra witness (finite carrier, decidable equality), a nontriviality witness s₀ with ¬ (s₀ ≈ ε), and the Kurzweil-surjectivity family (n : ℕ) → KurzweilSurjectivityAt 𝒮 n (Assumptions Entry 4). Nonabelianness and simplicity of 𝒮 enter the mathematics only through Entry 4, so no simplicity predicate occurs in the formal development.
This issue tracks the instantiation at a concrete finite nonabelian simple group, canonically A₅, so that kurzweilNetterDuality (and dual-Representableᵈ of FLRP.Closure) can be consumed with no group-shaped parameter at all.
Tasks¶
- Construct
A₅as aGroup 0ℓ 0ℓwith aFiniteAlgebrawitness (a Cayley-table presentation onFin 60, or the even permutations ofFin 5), and exhibit a nontrivial element. - Either supply Entry 4 for
A₅— blocked on #522 in general form, or provable directly for the specific group — or thread the per-group hypothesis to the census consumers explicitly. - Provide the specialized corollary
kurzweilNetterDuality-A₅ : ((n : ℕ) → KurzweilSurjectivityAt A₅ n) → KurzweilNetterDuality, collapsing to the unconditional theorem once #522 lands.
Relations¶
-
502 provides the parameterized theorem this issue instantiates.¶
-
522 retires Entry 4, the surjectivity family the instantiation must supply.¶
-
512 owns the solvability and alternating/symmetric predicates; simplicity of
A₅as a stated property belongs there, but is not needed for this instantiation — only Entry 4 is.¶
Acceptance criteria¶
- A concrete group value instantiates
KurzweilNetterProofunder--safewith no postulate, with any remaining hypothesis being exactly Entry 4 at that group.
Issue M6-26: Formalize Snow's filter-ideal lemma, and use it to represent L11 and L16 unconditionally (#530)¶
Labels: enhancement, milestone-6-flrp, research-exploratory, flrp-research
Description¶
Formalize the union-of-a-filter-and-an-ideal closure lemma — Snow's theorem, in the direct form the manuscript proves — and apply it to the two census entries whose manuscript representations are filter-ideal constructions. The payoff is that L11 and L16 become representable unconditionally: no Kurzweil–Netter assumption (Entry 2, needed for the duality route of #529) and no emitted certificate at carrier 60 or 216.
The lemma (lemma:union-filter-ideal of docs/papers/fin-lat-rep/SmallLatticeReps.tex § "Union of a filter and ideal"; Snow, Algebra Universalis 43 (2000), reproved there directly rather than via primitive positive formulas):
Let
Xbe a finite set. IfL ≤ Eq(X)is representable andL₀ ≤ Lis a sublattice with universeα↑ ∪ β↓, thenL₀is representable.
Its proof is four lines and entirely constructive, which is what makes this worth formalizing. Writing λ(L) = { f ∈ Xˣ ∣ f respects every θ ∈ L }, representability of L means L = Con ⟨X , λ(L)⟩. Given θ ∈ L \ L₀, pick (a,b) ∈ α \ θ and (u,v) ∈ θ \ β, and define the two-valued map h(x) = a if x ∈ u/β, else b. Then β ≤ ker h, so h respects everything below β; and (a,b) ∈ γ for every γ ≥ α, so h respects everything above α. Hence h ∈ λ(L₀) violates θ. Since λ(L) ⊆ λ(L₀), every θ ∉ L₀ is violated by something in λ(L₀), i.e. L₀ = Con ⟨X , λ(L₀)⟩.
No search, no enumeration, no fixpoint — the same "witness, not decision" shape as the WP-6 checkers, and a good fit for --safe Agda.
The concrete witnesses¶
L16— found by a search over all groups of order ≤ 100 (the only configuration in that range). InSub(A5)takeH = C3(index 20):
[C3 , A5] = { C3 , S3 , A4 , A4′ , A5 } ≅ M3
(the two A4s are the alternating subgroups containing that C3, the S3 is its normalizer; GAP's IntermediateSubgroups reports exactly three middles with no containments among them). Take K = C5: it lies in none of the three middles, meets each trivially, and joins each to A5. So
L16 ≅ [C3 , A5] ∪ [1 , C5] inside Sub(A5),
a filter-ideal union, with ambient set X = A5 — an algebra of size 60, against the erroneous 180 of the printed entry (#529).
+ L11 — the manuscript's own construction, already reproduced by the #487 engine (scripts/gap/flrp/out/l11_filter_ideal_216_153.json): the pentagon filter [H , G] ≅ N5 in SmallGroup(216,153) together with the order-3 minimal subgroup K below β but below neither α nor γ. Ambient set of size 216.
Why the ambient lattice is closed, without waiting on #501¶
The lemma needs the ambient L ≤ Eq(X) to satisfy L = Con ⟨X , λ(L)⟩. In general that follows from the unary-reduction theorem (#501, open), but both instances here avoid it: the ambient is Sub(G) presented as the left-coset partitions of X = G, and Con ⟨G , right translations⟩ ≅ Sub(G) is the WP-3 bridge (#454, merged) at H = 1. So Inv(λ(L)) ⊆ Inv({right translations}) = Sub(G) = L, and closedness is immediate. Recording this because it decides the dependency order: this issue does not block on #501.
Tasks¶
- The
λoperator and the concrete representability predicate for a set of equivalence relations on a finite set — the "closed" notionL = Con ⟨X , λ(L)⟩(this is exactly whateqsearch.py's closure test computes engine-side, so the naming should match the tooling's). - Filters and ideals of a lattice, and the fact that
α↑ ∪ β↓is always a sublattice (one line each way:x ∧ y ≤ y ≤ βandx ∨ y ≥ x ≥ α). - The lemma itself, following the manuscript's proof; the
hconstruction is a two-valued map defined by a decidableβ-class membership test, so it should be smooth over a finite carrier. - Bridge to
Representableᵈ: a closedL₀ ≤ Eq(X)yields the unary algebra⟨X , λ(L₀)⟩withCon ≅ L₀. Check whetherClassical.Structures.Unary(from the WP-6 pilot) already provides the algebra side. - The
Sub(G)ambient: instantiate the WP-3 bridge atH = 1to getSub(G)as a closed sublattice ofEq(G); state it as a reusable lemma inClassical/, not underFLRP/. - Apply to
L16(theA5data above) andL11(the committedSmallGroup(216,153)data), producingRepresentableᵈwitnesses; updatedocs/notes/flrp-slr-census.mdand the tally. - GAP side: promote the ad-hoc probe into
bin/find_filter_ideal.g— given a target filter shape and an ideal length, hunt for(G, H, K)— and commit theA5artifact in theflrp-gap-filter-ideal v1format thatbin/filter_ideal_216.galready uses. - Cross-check with the manuscript's derivation: it obtains adjoined ordinal sums as a corollary of this lemma (
α = β = 1_{L₁} × 0_{L₂}insideL₁ × L₂).FLRP.Closureproves ordinal-sum closure directly (#456), so deriving it a second way is a free consistency check on both.
Scope note¶
An alternative route is to emit a 60-element certificate for ⟨A5 , λ(L₀)⟩ through the WP-6 pipeline, but that needs the renderer's Fin-literal cap lifted past 31 and the type-check cost at carrier 60 is untested (27.9 s at carrier 19, growing with the n² trace tables). The abstract route above avoids both, and is the reason to prefer formalizing the lemma over brute-forcing the instance.
Acceptance criteria¶
- The lemma type-checks under
--cubical-compatible --exact-split --safewith no postulates and no registry assumption. -
L11andL16areRepresentableᵈin the library without Entry 2, and the census records them as certified by the filter-ideal route.
Part of #483; relates to #529 (which currently parks L16 on the conditional duality route) and to the manuscript's L17/L20 entries, which use the same method.
Milestone 6 Dependencies¶
M6-1 (Con(A) as a lattice) is the foundation: both subdirect products and Maltsev conditions need congruences-as-a-lattice to be phrasable in the form the classical proofs use.
graph TD
M3_5["M3-5: Lattice"]:::ext
M6_1["M6-1: Con(A) lattice"]
M6_2["M6-2: Subdirect products"]
M6_3["M6-3: Maltsev conditions"]
M3_5 --> M6_1
M6_1 --> M6_2
M6_1 --> M6_3
classDef ext fill:#f0f0f0,stroke:#999,stroke-dasharray: 4 3,color:#555
---¶
Milestone 7 — Algebraic complexity / CSP extensions (finite templates)¶
Issue M7-1: Extend Complexity module beyond Basic and CSP (#274)¶
Labels: milestone-7-csp, design-discussion
Description¶
The current Base.Complexity module has only two submodules (Basic and CSP). The CSP module is little more than a bare definition with no theorems. This is a separate research track from the FLRP (M6): the FLRP is about which lattices arise as congruence lattices of finite algebras, while finite-template algebraic CSP is about the complexity of constraint satisfaction problems as a function of the polymorphism clone of the underlying finite relational structure. Both use universal algebra, but they are different questions. Infinite-template extensions (ω-categorical, Bodirsky–Pinsker) are covered separately under M9-2.
This issue is research-flavored and best decomposed after discussion.
Tasks¶
Candidate content, to be prioritized:
- Polymorphism clones:
Pol(A, Γ)as a first-class type. - The Jeavons Galois connection between invariant relations and polymorphism clones.
- Post's lattice (for Boolean clones).
- Specific CSP tractability classes as worked examples (Horn-SAT, 2-SAT, linear systems over finite fields).
- Statement (not necessarily proof) of the Bulatov–Zhuk algebraic dichotomy.
Acceptance criteria¶
- Polymorphism clones available as a type with basic operations.
- Jeavons Galois connection is proved for a fixed finite domain, OR a clear research-plan issue is filed continuing the work.
Milestone 7 Dependencies¶
M7-1 (#274) depends on M2-7c (#307) for the canonical-path Complexity content. Sequencing: #307 ports the existing module; this issue extends it.
---¶
Milestone 8 — LLM readiness and corpus artifacts¶
Issue M8-1: Publish (theorem, proof) corpus for LLM training (#275)¶
Labels: documentation, milestone-8-llm
Description¶
Once Setoid/ and Classical/ are stable post-M4, publish a training and retrieval corpus for language models.
Tasks¶
- Design a schema for corpus records: module path, theorem statement, proof term, dependencies, prose summary, keywords.
- Implement an extractor that walks the library and emits records.
- Publish as a Hugging Face dataset.
- Add a CI job that regenerates the corpus on each release.
- Write a short paper or blog post describing the dataset.
Acceptance criteria¶
- Dataset published with ≥ 500 (theorem, proof) records.
- CI regenerates on release.
- Write-up is public.
Issue M8-2: Explore integration with agda-native-air (#276)¶
Labels: milestone-8-llm, design-discussion
Description¶
agda-native-air (a parallel project on AI-assisted formal proof) is a natural consumer of the agda-algebras corpus. This issue tracks the integration. Exploratory; low-priority until agda-native-air stabilizes.
Tasks¶
- Document what API / metadata / annotations agda-native-air needs from agda-algebras.
- Identify any agda-algebras design choices that help or hinder agda-native-air consumption.
- Write an integration report.
Acceptance criteria¶
- Integration report exists in
docs/integration-agda-native-air.md. - Any design changes required are filed as separate issues.
---¶
Milestone 9 — Applications of continuous relations¶
Issue M9-1: Scott-continuous relations on DCPOs using Relations.Continuous (#282)¶
Labels: design-discussion, milestone-9-apps
Description¶
The Base.Relations.Continuous formalization generalizes classical relations: the arity is an arbitrary type rather than a natural number, and compatibility with an operation is stated pointwise over that arity. That shape turns out to be the right one for a notion with a distinguished mathematical pedigree: Scott-continuous relations on directed-complete partial orders (DCPOs).
A relation R ⊆ X × Y between DCPOs is Scott-continuous when, for every directed family {(xᵢ, yᵢ)}ᵢ∈I in R, the supremum (⊔ xᵢ, ⊔ yᵢ) is again in R. This is a statement about arbitrary-arity suprema — the index set I is genuinely arbitrary — and factors through the continuous-relation API naturally.
The broader context is domain theory in the Scott sense, which underlies the denotational semantics of typed lambda calculi, topologically-enriched model theory and partial-function spaces, and constructive analysis via Escardó's work on exhaustively searchable sets. The Escardó connection is worth flagging: his LICS 2007 result "Infinite sets that admit fast exhaustive search" characterizes searchable sets via a topological continuity condition on their decision procedures, and provides a computability-flavored reason to care about Scott-continuous relations on specific DCPOs such as the Cantor space.
Tasks¶
-
Classical/Order/DCPO.agda(orSetoid/Order/DCPO.agdaif it will be adapted for Cubical later): DCPO as a record bundle — a poset with directed suprema. -
Classical/Order/ScottContinuous.agda: aScottContinuouspredicate on pairs of aContinuousrelation and a DCPO structure on its carriers. - Basic closure properties: Scott-continuous relations are closed under composition, intersection, and directed unions of Scott-continuous families.
- At least one non-trivial example: the graph of a Scott-continuous function is Scott-continuous as a relation; conversely, a single-valued Scott-continuous relation is the graph of a Scott-continuous function.
- Optional stretch goal: a path to Escardó's characterization of searchable sets, formalized as far as tractable. If
TypeTopologyis the cleanest source, import from there rather than re-derive.
Acceptance criteria¶
- DCPO record and ScottContinuous predicate type-check.
- The graph-of-continuous-function ↔ single-valued-continuous-relation characterization is proved.
- At least one closure property (composition or directed union) is proved.
- A short public write-up (blog post or arXiv note) connects the formalization to domain theory.
Why this belongs in agda-algebras¶
Universal algebra and order theory have a long shared history: every algebra with a compatible order gives an ordered algebra; Birkhoff's theorem has order-enriched variants; congruence lattices (the central FLRP object) are themselves DCPOs. Housing the Scott-continuous-relation material in agda-algebras keeps related abstractions together and gives them a shared foundation in the continuous-relation API.
Relation to other milestones¶
- Depends on: M2 (Setoid/ canonical), M3-1 (Classical/ scaffold).
- Independent of: M6 (FLRP), M7 (finite-template CSP).
- Informs: M5 (Cubical port) — Scott-continuous relations have a natural cubical-friendly statement using paths.
Issue M9-2: Infinitary CSP over ω-categorical templates via continuous relations (#281)¶
Labels: design-discussion, milestone-9-apps
Description¶
The CSP module under M7 targets finite-template CSPs with finite-arity relations. A rich body of contemporary work — most visibly the Bodirsky–Pinsker program — studies CSPs whose template is an ω-categorical structure with a countable domain and potentially infinitary relations. The central tools there include:
- Polymorphism clones of ω-categorical structures, which control CSP complexity via a topological-dynamical analog of the finite-domain algebraic approach.
- Canonical functions in a polymorphism clone: functions whose behavior on all "types" is determined by their behavior on finitely many representatives. See Michael Pinsker's recent work (e.g. arXiv:2502.06621).
- Birkhoff-style theorems for topological clones, generalizing the classical HSP theorem from varieties to polymorphism clones with a topological structure.
The Base.Relations.Continuous formalization in agda-algebras happens to be exactly the right abstraction for this setting. An ω-categorical template has relations whose natural arity is a countable index set; a continuous-in-our-sense relation drops in unchanged.
This is a design-discussion issue, not an implementation plan.
Tasks¶
- Which definitions port over unchanged from
Setoid/Complexity/CSP(post M7-1), and which need generalization? - What is the minimal API for a "template" in the ω-categorical setting (base structure, automorphism group, topological structure)?
- Is there a natural "Birkhoff for topological clones" result whose formalization is tractable with current tooling? Bodirsky, Pinsker, and collaborators have published multiple variants; select the one with the cleanest statement.
- Can a small but genuinely infinitary example be formalized end-to-end — e.g. the template
(ℚ, <)for temporal constraint satisfaction, which is ω-categorical and has a well-understood polymorphism clone?
Deliverables (if pursued)¶
- A new subtree
Classical/Complexity/Infinitary/(or similar) with the generalized definitions. - A single formalized example (suggestion: the template
(ℚ, <)). - A short write-up — blog post or arXiv note — connecting the formalization to the Bodirsky–Pinsker literature.
Non-goals¶
- Formalizing the full Bodirsky–Pinsker dichotomy conjecture.
- Matching the generality of any existing implementation.
- Engaging with decidability or tractability results (those are downstream; the first task is having the definitions).
Relation to other milestones¶
- Depends on: M2 (Setoid/ canonical), M3-1 (Classical/ scaffold).
- Benefits from: M7-1 (finite-template CSP infrastructure — polymorphism clones, Galois connection machinery).
- Independent of: M5 (Cubical), M6 (FLRP).
Issue M9-3: Exploratory: coalgebraic bisimulation as a continuous relation (#283)¶
Labels: design-discussion, milestone-9-apps
Description¶
An exploratory issue, not a deliverable. The goal is to read, think, and write up findings about whether the Continuous relation API has novel applications in coalgebra, particularly for bisimulation of non-finitary coalgebras.
A bisimulation between F-coalgebras (c : A → F A, d : B → F B) is classically a relation R ⊆ A × B that lifts along F: if (a, b) ∈ R then there is a witness (F R) (c a) (d b). When F is a finitary polynomial functor (e.g. finite-branching trees), R is naturally a finite-arity relation. When F is continuous — for example, the stream functor F X = X × A, or the unbounded-branching tree functor F X = X ^ ℕ — the natural witness type for a bisimilarity step is an arbitrary-arity relation. This is where the Continuous API might fit.
The intersection of coalgebra and classical universal algebra has many smart people (Rutten, Jacobs, Kurz, Adámek, Pattinson, et al.), but most of that work targets theoretical-CS applications (automata, regular languages, process calculi). It is much less developed on the universal-algebra-in-the-Birkhoff-sense side. It is plausible that low-hanging fruit remains at the intersection, but finding it requires sustained reading, not speculation.
Progress on this issue is measured in paragraphs written, not in type-checked Agda.
Tasks¶
- Read Rutten, "Universal coalgebra: a theory of systems," TCS 2000 (the standard introduction).
- Read one or two recent survey articles on coalgebraic bisimulation for continuous functors.
- Write up (in
docs/exploration/coalgebra.md) what the natural coalgebra-with-continuous-arity examples look like, and whether theContinuousAPI fits them without modification. - Identify at least one concrete formalization candidate, even if small (e.g. a bisimulation characterization of stream equality using the
ContinuousAPI). If no such candidate emerges, document why. - Optional: formalize the candidate, or file a follow-up M9-3a issue.
Acceptance criteria¶
-
docs/exploration/coalgebra.mdexists and is at least 2000 words. - The document contains a concrete verdict: either "there is a formalization project worth pursuing" (in which case a follow-up issue is filed) or "the area is saturated / the fit is not natural" (in which case this issue is closed).
Non-goals¶
- Producing a polished, publishable result. This is scoping work.
- Committing to a specific subarea of coalgebra. The reading should be broad enough to spot the low-hanging fruit, whatever it turns out to be.
Relation to other milestones¶
- Completely independent of every other milestone. This is a long-tail exploratory investigation.
Milestone 9 Dependencies¶
M9-1 and M9-2 depend on M2 (Setoid/ canonical) and M3-1 (Classical/ scaffold). M9-2 additionally benefits from M7-1's CSP infrastructure but does not strictly require it — the infinitary definitions can be developed in parallel and harmonized later. M9-3 is independent of every other milestone.
graph TD
M2_1["M2-1: Freeze Base"]:::ext
M2_7c["M2-7c: Port Complexity"]:::ext
M2_7d["M2-7d: Port Continuous"]:::ext
M3_1["M3-1: Classical/ scaffold"]:::ext
M3_5["M3-5: Lattice"]:::ext
M7_1["M7-1: Finite CSP"]:::ext
M9_1["M9-1: Scott-continuous relations"]
M9_2["M9-2: Infinitary CSP"]
M9_3["M9-3: Coalgebra exploration"]
M2_1 --> M9_1
M2_1 --> M9_2
M2_7d --> M9_1
M2_7d --> M9_2
M2_7d -.-> M9_3
M2_7c --> M9_2
M3_1 --> M9_1
M3_5 --> M9_1
M3_1 --> M9_2
M7_1 -.-> M9_2
classDef ext fill:#f0f0f0,stroke:#999,stroke-dasharray: 4 3,color:#555
M2-7d → M9-1, M9-2added as solid edges;M2-7d -.-> M9-3added as dashed (M9-3 only consumes if it produces a formalization candidate, per its own body).M2-7c → M9-2added as solid (per the audit; M9-1 explicitly does not depend on Complexity).M3-5 → M9-1added — this is technically a pre-existing dependency that the original graph missed. M9-1's body explicitly invokes "DCPO as a record bundle — a poset with directed suprema," which depends on lattice/order infrastructure that M3-5 produces. Worth flagging since the audit surfaced it.
---¶
Milestone 10 — Post-3.0 polish¶
Issue M10-1: doc rendering-pipeline modernization (mkdocs) (#295, closed)¶
Labels: documentation, breaking-change, milestone-10-polish
Context¶
M1-8 / PR #294 proposes consolidating the current dual-tree literate-Agda layout into single-file .lagda.md modules under src/. This issue tracks the rendering-pipeline modernization that should follow once that migration lands.
The shared root cause is the same: if the source tree is migrated to Markdown-literate .lagda.md files, the current Jekyll-based admin/generate-html + admin/generate-tex pipeline will no longer be the natural fit. In that post-migration layout, agda --html --html-highlight=code on a .lagda.md file already produces Markdown with fenced code blocks and (when paired with kramdown attribute spans, per ADR-004 and agda-lagda-migrator#14) inline-highlighted Agda terms. A modern static-site generator that reads Markdown directly would then be the right shape for the rendering pipeline; the Agda community's de facto choice for that role is MkDocs with the Material theme.
Open design questions¶
A short discussion is needed before code is written. The resolutions should be recorded in docs/adr/005-mkdocs-rendering-pipeline.md.
- Domain. Recommendation: keep https://ualib.org. It is the existing public URL of the rendered library; preserving it avoids breaking every external link to a
Module.Submodule.htmlpage. Alternatives are out of scope here (see "Non-goals" below). - agda-html integration. Two viable architectures — (a) preprocess
.lagda.mdfiles by runningagda --html --html-highlight=codeand pointing MkDocs at the generated Markdown, vs. (b) point MkDocs directly at.lagda.mdand rely on kramdown attribute spans + a custom CSS for highlighting (noagda --htmlstep in the rendering pipeline). Recommendation: (b), because it eliminates a build-time dependency and matches what 1Lab andagda-lagda-migratoralready produce. The trade-off is that whole-token-by-token Agda highlighting (the kindagda --htmlproduces) is sacrificed in favor of class-tagged inline references; in practice the latter is what readers actually use. - MkDocs plugins. Baseline:
material,search(built-in),mkdocs-macros-plugin(for the equivalent of Jekyll's{% include %}directive),mkdocs-redirects(to absorb the small set of post-3.0 URL changes). Open: whether to add a Mermaid plugin for the dependency graphs indocs/GITHUB_PROJECT.mdonce they're rendered there too. - Custom CSS. Recommendation: adapt the formal-ledger-specifications
custom.css(referenced fromagda-lagda-migrator#14's PR description) for kramdown-attribute-span styling. Light and dark themes; per-Agda-class colors (AgdaFunction,AgdaBound,AgdaRecord,AgdaSymbol,AgdaArgument).
Proposal¶
Pre-work¶
- Write
docs/adr/005-mkdocs-rendering-pipeline.mdresolving the open questions above. - Confirm that the existing
_includes/UALib.Links.mdcontent is reproducible under MkDocs' macros plugin (or under a simple Markdown reference-link include scheme).
Tooling¶
- Add
mkdocs.ymlat the repo root withtheme: material, navigation tabs configured to mirror the existingdocs/GITHUB_PROJECT.mdordering, and theagda-algebraslibrary section linking to thesrc/tree. - Add
docs/stylesheets/custom.csswith kramdown-attribute-span styling for the five Agda classes. - Add
docs/javascripts/only if a specific JS dependency is required (e.g., a search hook); avoid by default. - Add a top-level
make sitetarget that runsmkdocs build, withmake servefor local preview (mkdocs serve). - Add a Nix shell input for MkDocs + Material so the rendering pipeline is reproducible under
nix develop.
Content migration¶
- Move the shared link definitions to a dedicated
docs/_links.mdreferenced from each module (or provide the equivalent undermkdocs-macros-plugin). - Rewrite
docs/_links.md's entries: strip thedocs/lagda/paths, point each entry at the newsrc/X/Y/Z.lagda.mdpath. - Rebrand legacy prose for the post-M2-1 module names. Across
src/Legacy/Base/**/*.lagda.md: front-mattertitle:fields still say "Base.X.Y module"; reference-style links of the form[Base.X.Y][]in prose comments don't resolve; bottom-of-page nav links targetBase.htmlfiles that no longer exist after the rename toLegacy.Base/. This was deliberately deferred from PR #300 (the freeze rewrote onlymodule,import,open importlines — the syntactic positions Agda's type checker reads — leaving prose untouched). Rebranding piecemeal would create inconsistency; doing it as part of the rendering-pipeline migration is the natural moment because the Markdown reference targets and nav scheme are themselves changing here. - Audit the
src/**/*.lagda.mdcorpus for any surviving\href{...}{...}LaTeX-link macros (theagda-lagda-migrator#14rewrite catches these but a sweep is cheap insurance) and any surviving raw@@AgdaTerm@@...@@placeholders.
CI / deploy¶
- Add a GitHub Actions workflow
.github/workflows/docs.ymlthat builds the MkDocs site on every push tomasterand deploys togh-pages(usingmkdocs gh-deploy --forceorpeaceiris/actions-gh-pages). - Configure GitHub Pages to serve from
gh-pageswith custom domainualib.org. - Configure DNS at the registrar to point
ualib.org(andwww.ualib.org) at GitHub Pages' IPs. - Spot-check at least 10 rendered pages against the pre-migration archive at the current
https://ualib.org.
Tooling cleanup¶
- Delete
admin/generate-html,admin/generate-tex,admin/illiterator/. - Delete
_layouts/,_config.yml, and any other Jekyll-only files at the repo root or underdocs/. - Remove the
make htmltarget and replace it withmake site; updateMakefile,README.md, andINSTALL.mdaccordingly.
Acceptance criteria¶
-
make sitebuilds the full library atsite/(or wherever MkDocs writes output) without errors. - Spot-checked rendered pages match the pre-migration archive in content; minor styling differences are acceptable.
-
https://ualib.orgserves the new MkDocs site; existingModule.Submodule.htmlURLs continue to resolve (withmkdocs-redirectscovering any path that legitimately moved). -
admin/generate-html/,admin/generate-tex/, andadmin/illiterator/no longer exist in the tree. -
docs/adr/005-mkdocs-rendering-pipeline.mdis merged. -
CHANGELOG.mdrecords the rendering-pipeline change under[Unreleased] / Changed.
Non-goals¶
- Moving the documentation to a different domain.
formalverification.organdagda-algebras.orgare tracked as separate considerations if at all; this issue does the obvious-and-stable thing and keepsualib.org. - Re-litigating the choice of MkDocs over alternatives (Hugo, Zola, Quarto, etc.). MkDocs is the de facto standard in the Agda ecosystem and the choice tracks ecosystem convention.
- Restructuring the module hierarchy or renaming any
.lagda.mdfile.
Related¶
- PR #294 — M1-8: migrate to Markdown-literate Agda.
- ADR-004 — Markdown-literate Agda as the canonical literate format.
agda-lagda-migrator#14— kramdown attribute spans (the convention this pipeline relies on).- Issue #280 — original M1-8 issue (closed by #294).
Why now¶
The rendering pipeline is the last piece of the M1-8 story. Deferring it indefinitely leaves admin/generate-html and the Jekyll machinery as dead code in the tree, ages the deferred-CHANGELOG entries, and blocks the make corpus target from M8 (LLM readiness) which wants the same .lagda.md walker MkDocs will exercise. The work is bounded: MkDocs configuration is small, the kramdown-attribute-span scheme is already proven against the agda-algebras corpus by agda-lagda-migrator#14, and the deploy step is a known-good Actions-to-Pages flow.
Issue M10-2: offer to transfer agda-algebras to the agda organization (#298)¶
Labels: milestone-10-polish, governance, agda-community
Motivation¶
Agda's umbrella organization, github.com/agda, already hosts the language itself, the standard library, the categorical-foundations library agda-categories, and other community-maintained core libraries. agda-algebras' current home at github.com/ualib reflects an earlier era; folding it into the umbrella agda org would
- signal community-curated rather than personal-project status,
- make discovery easier for users browsing Agda's GitHub presence,
- align the library's governance with the same patterns the rest of the ecosystem uses.
Pre-conditions¶
The transfer should happen after the library is in good shape. Concretely:
- 3.0 has shipped (M1–M5 complete, classical structures landed, CI green, documentation site live).
- CONTRIBUTING.md, CODE_OF_CONDUCT.md, governance model are stable.
- Maintainership beyond a single primary author is realistic — at least one additional reviewer with commit rights to the core tree.
The case for transfer rests on the library being something an org-level audience can rely on; transferring during a half-finished reconstruction would be premature.
Process¶
GitHub's "Transfer ownership" feature (Settings → General → Danger zone → Transfer) preserves stars, forks, watchers, issues, PRs, releases, and — critically — installs HTTP redirects from the old ualib/agda-algebras URLs to the new agda/agda-algebras URLs at the GitHub level. External links don't need to be rewritten on day one.
Tasks¶
- Approach the agda-org maintainers (Andreas Abel, Nils Anders Danielsson, etc.) informally first. Confirm they're amenable to hosting the library and what their org-level expectations are (CI, code of conduct, license, responsiveness on issues).
- File a tracking issue in
agda/agda-algebras(or wherever the discussion lives) for cross-referencing. - Execute the GitHub transfer.
- Update
README.md,INSTALL.md,CONTRIBUTING.md,CHANGELOG.md, the MkDocs site'smkdocs.yml, and any CI badge URLs to point atagda/agda-algebrasdirectly (the redirects work, but explicit URLs are more durable). - Update the
agda-algebras.cabal-style metadata (or whatever the equivalent is for an Agda library) to reflect the new home. - Announce on the Agda Zulip and the agda-algebras CHANGELOG.
Non-goals¶
- Renaming the repository.
agda-algebrasstaysagda-algebras. - Changing the library's API or any source content as part of the move.
- Migrating off the existing
ualib.orgdocumentation domain. That decision is independent and tracked separately.
Issue M10-3: Type-on-hover tooltips for Agda tokens (1Lab-style), with a toggle (#429, closed)¶
Labels: documentation, milestone-10-polish
Context¶
M10-1 (#295, PR #427) brought full agda --html token highlighting with per-token hyperlinks to definitions into the MkDocs site, plus the classic clickable-HTML site at /classic/. Tokens are now classed and linked; the natural next step — deferred from the #295 review — is type-on-hover tooltips (like 1lab.dev, and the less polished Ledger formal spec and Leios formal spec): hover a token, see a small popover with its definition, without leaving the page.
Goal¶
- Hovering any highlighted Agda token shows a popover containing its type signature (and, where available, its definition snippet / docstring).
- A "Tooltips on/off" toggle in the page header, persisted across pages (e.g.
localStorage), so readers who find them distracting can switch them off. - Light + dark styling consistent with the site theme.
Approach (proposed)¶
This builds directly on the make agda-md output already produced for #3a — no new Agda dependency:
- The
agda --html --html-highlight=codeoutput already contains every definition's type signature as highlighted code, anchored by char-offset id (the same ids the hyperlinks target). A small build step (agen-filespass or a hook) extracts{anchor → type-signature HTML}into a JSON index emitted into the site. - A small script under
docs/javascripts/attaches a popover on hover over any linked token, looking up the target anchor in the index (cross-page lookups resolve because the index is global). - A header button toggles a
localStorageflag that shows/hides the popovers (a Material header/announceoverride or a tiny custom element).
Scope¶
- MVP (this issue). Signature-on-hover from the existing
agda --htmloutput + the toggle. No new tooling beyond a JSON-index build step and a small JS/CSS bundle. - Stretch (separate issue if pursued). Fully normalised types / docstrings as 1Lab renders them — this needs the Agda API (a Shake/Haskell-style extractor), a materially larger effort.
Non-goals¶
- Re-deriving the highlighting or hyperlinks (done in #295 / PR #427).
- Agda-API type extraction (the stretch goal above).
References¶
-
295 — M10-1 rendering-pipeline modernization; PR #427 — its implementation.¶
- ADR-007 — the rendering pipeline this extends.
- 1lab.dev — the reference implementation of type-on-hover.
Issue M10-3: Distribute agda-algebras through nixpkgs as an Agda library (#299)¶
Labels: nix, milestone-10-polish, agda-community
Motivation¶
The repo's flake.nix provides a development environment — nix develop gives a contributor a pinned Agda + stdlib shell. It does not provide a consumer Nix package: a downstream Nix user who wants to depend on agda-algebras as a library has to vendor a flake input or rebuild the package themselves. Promoting agda-algebras to a first-class entry under nixpkgs.agdaPackages solves this and tracks how the rest of the Agda ecosystem is distributed (agdaPackages.standard-library, agdaPackages.agda-categories, agdaPackages.cubical, etc.).
Tasks¶
- Audit
nixpkgs/pkgs/build-support/agdaand the existingagdaPackages.*entries to confirm the packaging contract (build inputs,everythingFile, library-name conventions, version pinning). - Add a
pkgs/agda-modules/agda-algebras.nix(or whatever the current nixpkgs path is) defining the package: source from a tagged release onmaster, depend onstandard-library≥ 2.3, buildEverything.agda. - Open a PR against
nixpkgsadding the entry; coordinate with the nixpkgs Agda maintainers (look at recentagdaPackagesPRs for the right reviewer set). - Once accepted, update agda-algebras' own
flake.nixto expose the same library derivation as a flake output (so flake-based downstream users don't have to wait for the nixpkgs channel cycle). - Document the consumer-side usage pattern in
INSTALL.md:agdaPackages.agda-algebrasfor nixpkgs users;inputs.agda-algebras.lib.Xfor flake users. - Coordinate with each subsequent agda-algebras release: tag, update the nixpkgs entry's source hash, bump the package version.
Acceptance criteria¶
-
nix-shell -p 'agdaPackages.agda-algebras'produces a working environment in whichagda --library agda-algebrasresolves correctly. - The flake also exposes the library derivation:
nix build github:ualib/agda-algebras#lib(or the post-transferagda/agda-algebrasURL). -
INSTALL.mddocuments the nixpkgs consumer path alongside the existing development-environment path.
Non-goals¶
- Replacing the existing development flake. The development flake (
nix develop) is a different artifact and stays in place. - Distributing through any package manager other than nix. Agda libraries don't have a strong tradition of cross-package-manager distribution; the agda-stdlib is the closest thing to a canonical distribution channel and it's nixpkgs-anchored.
Issue M10-4: Retire and park the legacy ualib.org site; cut over to the MkDocs site (#430, closed)¶
Labels: documentation, milestone-10-polish
Context¶
PR #427 (closing #295) builds the new MkDocs (Material) site from the .lagda.md sources and deploys it to the gh-pages branch on every push to master.
By deliberate decision in ADR-007 (docs/adr/007-mkdocs-rendering-pipeline.md), the cutover — pointing GitHub Pages at gh-pages, attaching the ~~ualib.org~~ agda-algebras.universalalgebra.org custom domain, and the registrar DNS change — was left as a manual maintainer step so that merging the PR does not disturb the currently-live site.
This issue tracks that cutover and the parking + deprecation of the existing (Jekyll-rendered) ualib.org content.
Goal¶
ualib.org ~~serves the new site~~ continues to serve the old, deprecated site; the old site is preserved ("parked") and carries a prominent banner marking it deprecated and linking forward to the new site; legacy Module.Submodule.html URLs redirect to the new directory URLs.
agda-algebras.universalalgebra.org serves the new site.
Plan¶
Park the old site¶
-
Decide where to park the current live content.
Decision: keep it parked at its original and current location
ualib.org. -
Add a prominent deprecation banner to the top of the old landing page (ideally every old page): a dated notice that the site is deprecated, with a link to the new site at
agda-algebras.universalalgebra.org. A sticky<div>with a contrasting background is enough.Done in
d921a44(ongh-pages): a dated, full-bleed banner on the landing page, all 147 Jekyll content pages (via a new_includes/deprecation-banner.htmlreferenced from both page layouts), and the 198 root-levelagda --htmlcode fragments (a self-contained inline-styled bar, since those files have no<body>).
Cut over to the new site¶
- Point GitHub Pages at the
gh-pagesbranch (Settings → Pages → Deploy from a branch →gh-pages/ root). Done on the new-home repouniversalalgebra/agda-algebras. - Attach the custom domain: set
cname: agda-algebras.universalalgebra.orgin.github/workflows/docs.yml(written into theCNAMEon every deploy). - Update registrar DNS: point
agda-algebras.universalalgebra.orgat GitHub Pages, per GitHub's custom-domain docs. - ~~Populate the
mkdocs-redirectsmap (currently empty inmkdocs.yml) with the legacy flatModule.Submodule.html→ new/Module/Submodule/URLs, so external links survive.~~ Dropped — satisfied by parking: legacy URLs resolve to their original content atualib.org, and the oldBase.*tree has no equivalent on the newSetoid.*-centric site, so a redirect map would send those URLs to 404s.
Verify¶
- Spot-check at least 10 pages on the live
agda-algebras.universalalgebra.orgagainst the parked archive: content, search, inline cross-links, the/classic/agda-html mirror, and the module constellation. - Confirm HTTPS (GitHub-provisioned certificate) is active on the apex and
www. - Confirm a sample of legacy
….htmlURLs resolve — directly now (parked atualib.org), rather than via a redirect.
Acceptance criteria¶
-
https://agda-algebras.universalalgebra.orgserves the new MkDocs site over HTTPS. - The old site is parked at its original URL (
ualib.org) and shows a dated deprecation banner linking to the new site. - Legacy
Module.Submodule.htmlURLs resolve (directly or via redirect). - No regression in the currently-live content during the transition: the old site stays reachable until the new one is verified.
Related¶
- PR #427 — the new MkDocs pipeline (closes #295).
- ADR-007 (
docs/adr/007-mkdocs-rendering-pipeline.md) — records the deferred-cutover decision and the checklist this issue executes. -
295 — M10-1 rendering-pipeline modernization.¶
Notes¶
- This is the last remaining item from ADR-007's deferred-cutover checklist. It is intentionally an ops issue (Pages config + DNS + a banner), not a code change, so it can land independently once PR #427 is merged.
- The "park + banner" step is what makes the transition safe: nothing about the old content is destroyed, and visitors to stale links are routed forward.
Issue M10-5: Improve how module imports are presented on the documentation pages (#431, closed)¶
Labels: documentation, milestone-10-polish
Context¶
Every rendered module page opens with the module's full import block (open import …), plus the OPTIONS pragma and the module header, shown verbatim with no framing — no comment or heading telling the reader "these are the module's imports." To anyone who knows Agda this is obvious, but for a documentation reader (as opposed to someone reading source) it is noise up front: it pushes the actual content down the page and reads as undocumented boilerplate.
This issue is to weigh ways to make the import/scaffolding blocks less obtrusive for the casual reader without losing them for readers who want the full source (which is always available in the /classic/ agda-html mirror and on GitHub).
Options to consider¶
- (a) Always hide the scaffolding on doc pages. Strip or collapse the leading import/OPTIONS/module blocks during
mkdocs_gen_library.py(or hide them with CSS), keeping them only in/classic/and the GitHub source. Most aggressive; least reversible for a reader who does want to see them inline. - (b) Collapsible admonition. Wrap the imports in a
pymdownx.detailsblock (??? note "Module imports"), collapsed by default. Pure-Markdown, no JS — but needs each import block marked. Could be automated in gen-files (wrap the leading<pre class="Agda">blocks up to the module header in a<details>) so the 283 source files are not touched. - (c) A "Show / hide Agda" toggle, à la formal-ledger-specifications. A small JS control at the top of each page that flips "Show more Agda" / "Show less Agda", hiding/showing the scaffolding (and optionally all code) globally, with the choice persisted in
localStoragelike the theme toggle. Least lossy (reader opts in) and most flexible (can hide more than imports).
Things to work out¶
- Reliable identification of the "scaffolding" blocks. In the agda-html output these are the leading
<pre class="Agda">blocks containing theOPTIONSpragma, themodule … whereheader, and theopen import/importlines (and arguably theprivate variabledeclarations). A heuristic in gen-files or in JS can tag them. - Granularity. Just the imports, or all scaffolding (pragma + module line + private variables)? formal-ledger's toggle hides more than imports.
- Scope of the preference. Per-page state vs. a global, persisted preference.
- Interaction with existing features. The copy button (
agda-copy.js) and the token highlighting must keep working on whatever remains visible. - Nothing is lost.
/classic/and the GitHub source always show everything, so any of these is safe.
Leaning¶
Option (c) seems the best fit — it is the least lossy and the most flexible, and it matches a pattern the team already maintains on the formal-ledger site (so there is prior art to adapt). Option (b), automated in gen-files, is the simplest to ship without per-file edits and could be a good first step. Option (a) is a fallback if a toggle proves more trouble than it is worth.
Acceptance (to be refined after discussion)¶
- A casual reader's first screenful of a module page is content/prose, not a wall of imports.
- Readers who want the full source can still reach it inline (toggle) or via
/classic/and GitHub. - Highlighting and the copy button continue to work.
Related¶
- PR #427 — the MkDocs rendering pipeline.
- ADR-007 (
docs/adr/007-mkdocs-rendering-pipeline.md). - formal-ledger-specifications — the "Show more/less Agda" toggle this borrows from.
Issue M10-6: Explore definition-level dependency graphs for the documentation site (#432)¶
Labels: documentation, milestone-10-polish
Context (exploratory)¶
The site has a module-level constellation (the import graph, as a d3 force-directed graph; see docs/constellation.md). A finer-grained, definition/lemma-level dependency view — "what does Birkhoff's HSP theorem actually rest on?" — would be valuable for a proof-engineering audience in a way the module graph is not.
This is deliberately an open-ended, exploratory issue: the aim is to investigate, prototype, and discuss approaches, with loosely defined targets. No fixed deliverable is committed up front.
Candidate tooling¶
- omelkonian/agda-dependencies (
agda-deps) — a Haskell/cabal tool that emits a Graphviz (DOT) dependency graph between Agda definitions. Its cabal bounds requireAgda >= 2.8, which matches our pinned 2.8.0; it also pulls ingraphvizandfgl. - Derive it ourselves from data we already produce. The
agda --htmlpass already emits per-token hyperlinks (each identifier links to its defining site); a definition-level dependency graph might be extractable from that cross-reference data without adding a second Haskell toolchain. Worth comparing againstagda-deps. - Agda's own
--dependency-graph(module-level only — already covered by the constellation, noted for completeness).
Questions and approaches to explore¶
- Build integration. If we use
agda-deps: add it to the Nix flake (callCabal2nix, or a flake input), ideally reusing nixpkgs' Agda 2.8 Haskell library so we don't rebuild Agda-the-library from source; add thegraphvizbinary. How much does this add to CI wall-clock, and what caches it? - Granularity and legibility. A definition-level graph over 283 modules / 38k lines is a hairball as a single global picture. More legible units to try: per-theorem (an "anatomy of a proof" — e.g. the dependency cone of Birkhoff's HSP), per-module, or an interactive/filterable graph.
- Presentation. Static SVG embedded on a page? An interactive graph (like the constellation, fed from
agda-deps' DOT/JSON)? A dedicated "anatomy of a proof" page for a few flagship results, rather than a global tab? - Relationship to the constellation. These are complementary — the module forest vs. the definition trees inside one proof. Keep both? Share a visual language?
- Maintenance cost. A second pinned Haskell toolchain next to Agda is a real ongoing cost; the "derive from agda-html" route may avoid it.
Suggested first spike¶
Wire agda-deps (or the agda-html-derived approach) into the dev environment, run it over one module/theorem (Birkhoff's HSP), render the result to SVG, and eyeball whether it is illuminating at that scope. Decide next steps from there.
Loose targets / acceptance¶
- A working prototype graph for at least one flagship result.
- A short written recommendation: whether/how to integrate (global tab vs. per-page vs. a curated "anatomy of a proof" page), the build and CI cost, and the maintenance tradeoff — enough to decide whether this becomes a real feature.
Non-goals (for now)¶
- A global, all-library definition graph (the hairball).
- Committing to a specific UI before the spike.
Related¶
- The module constellation (
docs/constellation.md), PR #427, ADR-007. - omelkonian/agda-dependencies.
Issue M10-7: Self-host the remaining webfonts, and three colour tokens that miss WCAG AA (#531)¶
Labels: documentation, milestone-10-polish
Two findings from reading stylesheets/custom.css and the page source, while choosing a visual system for williamdemeo.github.io. That site is also MkDocs Material, so the fixes are the same shape in both places. Happy to open PRs for either.
1. Three external font requests, two of which the site's own CSS overrides¶
Every page currently emits, from Material's default theme.font:
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Inter";--md-code-font:"Roboto Mono"}</style>
and custom.css line 31:
@import url("https://cdn.jsdelivr.net/gh/cormullion/juliamono/webfonts/juliamono.css");
But custom.css then overrides both variables (lines 73–75):
--md-code-font: "JuliaMono", "JetBrains Mono", "Fira Code", "Cascadia Code", …
--md-text-font: "InterVar", "Inter", -apple-system, BlinkMacSystemFont, …
So Roboto Mono is never selected, and Inter is served from Google while inter-latin-wght-normal.woff2 is already self-hosted under assets/fonts/. Space Grotesk, Geist (four weights) and Sora are self-hosted too — the site is most of the way there. What is left is:
theme.font: falseinmkdocs.yml, which removes the preconnect and the Google Fonts stylesheet. The--md-text-font/--md-code-fontvalues incustom.cssalready cover what those lines were providing.- Self-host JuliaMono rather than
@import-ing it from jsDelivr.
JuliaMono is the one that matters. It is the only face in that stack with the Mathematical Alphanumeric Symbols block, so it is the only one that can render 𝑨 𝓤 𝑆 𝔸 𝕏 𝒦 𝓞 𝓥. Measured against the 1,952 non-ASCII characters agda-input.el names, and a 44-character probe drawn from real Agda:
| Face | Glyphs | agda-input | Probe |
|---|---|---|---|
| JuliaMono v0.63.2 | 11,191 | 92.8% | 44/44 |
| Cascadia Code | 2,426 | 17.0% | 14/44 |
| Fira Code | 1,551 | 19.3% | 24/44 |
| JetBrains Mono | 976 | 14.7% | 21/44 |
If jsDelivr is unreachable — blocked network, corporate proxy, or the CDN simply going away — the fallbacks silently take over and every universe level and bold-script letter on the site renders in a substitute face, mid-line. The precedent is uncomfortably close to hand: williamdemeo.org loads Fira Code from cdn.rawgit.com, which shut down in 2019, so its intended monospace font has not rendered for years and nobody noticed, because nothing fails loudly.
If it is useful, scripts/python/build_fonts.py in williamdemeo/williamdemeo.github.io#70 does exactly this job and would port over nearly unchanged. It pins sources by SHA-256, subsets by Unicode block rather than by an enumerated character list, splits JuliaMono three ways by unicode-range (56 KB text / 253 KB symbols / 154 KB mathematical alphanumerics, so a page pays only for the notation it shows), and emits deterministic WOFF2.
One warning from writing it, since it would bite anyone doing this by hand: subsetting against the characters agda-input-translations names is not enough. The Agda input method inherits from Emacs' TeX method for everything it does not redefine, so ℓ, Π and the subscript digits are absent from that list and fall back mid-line. Only a browser catches it — CSS.getPlatformFontsForNode reports which face actually rasterised each run of text.
2. Three colour tokens do not clear WCAG AA as text¶
Contrast ratios computed from custom.css's own values:
| Token | Value | Ratio | Against |
|---|---|---|---|
--md-default-fg-color--lighter (light) |
#818bab |
3.29:1 | #fbfcff |
--md-default-fg-color--lighter (dark) |
#6a7197 |
3.70:1 | #15172e |
--md-accent-fg-color (light) |
#fb6a00 |
2.86:1 | #fbfcff |
AA is 4.5:1 for body text and 3:1 for large text. Material uses --md-default-fg-color--lighter for real text in several places — the footer copyright line and search-result metadata among them — and --md-accent-fg-color is the link hover colour, so it carries link text at the moment a reader is looking straight at it.
The coral needs no change in dark, where it is 7.34:1 on #0c0e1d. It is only on paper that a saturated orange cannot carry text.
Values that keep the hue and clear AA:
| Token | Now | Suggested | After |
|---|---|---|---|
--md-default-fg-color--lighter light |
#818bab |
#626b88 |
5.15:1 |
--md-default-fg-color--lighter dark |
#6a7197 |
#8189af |
5.14:1 |
--md-accent-fg-color light |
#fb6a00 |
#b34b00 |
5.22:1 |
These are the values that palette is running under on williamdemeo.github.io, where it is kept as a switchable alternative system — so the adjusted set is already checked on every build by an audit that walks every text element in both themes and composites the background up the ancestor chain.
Everything above comes from stylesheets/custom.css and the served HTML as of 2026-08-02; I was not able to run a network trace against the live site from my environment, so the request-level claims are read from the source rather than measured.
Milestone 10 Dependencies¶
M10-1 (MkDocs rendering) is the only one of the three with concrete structural prerequisites — it consumes the .lagda.md corpus produced by M1-8, the stable file tree from M2, and the prose-comment uniformity from M4. M10-2 (organization transfer) and M10-3 (nixpkgs distribution) are governance/packaging tasks with no hard upstream dependencies; their position in this milestone is thematic rather than structural.
graph TD
M1_8["M1-8: `.lagda.md` migration"]:::ext
M2_1["M2-1: Freeze Base"]:::ext
M4_1["M4-1: Style audit"]:::ext
M10_1["M10-1: MkDocs rendering"]
M10_2["M10-2: agda org transfer"]
M10_3["M10-3: nixpkgs distribution"]
M1_8 --> M10_1
M2_1 --> M10_1
M4_1 --> M10_1
classDef ext fill:#f0f0f0,stroke:#999,stroke-dasharray: 4 3,color:#555
---¶
Dependency Graph (Mermaid)¶
graph TD
subgraph "M1 — Infrastructure"
M1_1["M1-1: Agda 2.8 / stdlib 2.3"]
M1_2["M1-2: GitHub Actions CI"]
M1_3["M1-3: Community files"]
M1_4["M1-4: STYLE_GUIDE.md"]
M1_5["M1-5: README / Preface"]
M1_6["M1-6: docs/adr/"]
M1_8["M1-8: .lagda.md migration"]
end
subgraph "M2 — Consolidation"
M2_1["M2-1: Freeze Base"]
M2_2["M2-2: Consolidate Base.Structures"]
M2_3["M2-3: Remove Graphs0"]
M2_4["M2-4: Canonical HSP"]
end
subgraph "M3 — Classical structures"
M3_1["M3-1: Classical/ scaffold"]
M3_2["M3-2: Semigroup"]
M3_3["M3-3: Stdlib bridges"]
M3_4["M3-4: Monoid / Group"]
M3_5["M3-5: Lattice"]
M3_6["M3-6: Ring"]
M3_7["M3-7: Examples"]
end
subgraph "M4 — Style sweep"
M4_1["M4-1: Style audit"]
M4_2["M4-2: Docstrings"]
M4_3["M4-3: 𝓞/𝓥 scope"]
end
subgraph "M5 — Cubical"
M5_1["M5-1: Cubical Algebra + SIP + Monoid"]
end
subgraph "M6 — FLRP"
M6_1["M6-1: Con(A) lattice"]
M6_2["M6-2: Subdirect products"]
M6_3["M6-3: Maltsev conditions"]
end
subgraph "M7 — CSP (finite)"
M7_1["M7-1: Complexity / CSP"]
end
subgraph "M8 — LLM corpus"
M8_1["M8-1: Corpus artifact"]
M8_2["M8-2: agda-native-air"]
end
subgraph "M9 — Continuous-relation apps"
M9_1["M9-1: Scott-continuous relations"]
M9_2["M9-2: Infinitary CSP"]
M9_3["M9-3: Coalgebra exploration"]
end
subgraph "M10 — Post-3.0 polish"
M10_1["M10-1: MkDocs rendering"]
M10_2["M10-2: agda org transfer"]
M10_3["M10-3: nixpkgs distribution"]
end
%% M1 internal
M1_1 --> M1_2
M1_1 --> M1_3
M1_1 --> M1_4
M1_1 --> M1_6
M1_1 --> M1_5
M1_2 --> M1_5
M1_3 --> M1_5
M1_4 --> M1_5
%% M2 depends on M1
M1_1 --> M2_1
M2_1 --> M2_2
M2_1 --> M2_3
M2_1 --> M2_4
M2_1 --> M1_5
%% M3 depends on M2
M2_1 --> M3_1
M3_1 --> M3_2
M3_2 --> M3_3
M3_2 --> M3_4
M3_3 --> M3_5
M3_4 --> M3_5
M3_4 --> M3_6
M3_2 --> M3_7
M3_4 --> M3_7
M3_5 --> M3_7
%% M4 depends on M1-4
M1_4 --> M4_1
M1_4 --> M4_2
M1_4 --> M4_3
%% M5 depends on M1 and M3-4
M1_1 --> M5_1
M3_4 --> M5_1
%% M6 depends on M3-5
M3_5 --> M6_1
M6_1 --> M6_2
M6_1 --> M6_3
%% M7 depends on M2-1 and M3-5
M2_1 --> M7_1
M3_5 --> M7_1
%% M8 depends on M4
M4_1 --> M8_1
M4_2 --> M8_1
M8_1 --> M8_2
%% M9 depends on M2-1 and M3-1; M9-2 benefits from M7-1
M2_1 --> M9_1
M2_1 --> M9_2
M3_1 --> M9_1
M3_1 --> M9_2
M7_1 -.-> M9_2
%% M10 depends on M1-8, M2-1, M4-1 (M10-1 specifically; M10-2 and M10-3 are independent)
M1_8 --> M10_1
M2_1 --> M10_1
M4_1 --> M10_1
How to Create This Project on GitHub¶
Use the companion script gh_project_populate.py (patched as described in the project planning notes to read labels from the ## Labels section above).
Prerequisites¶
- Python 3.8+.
ghCLI installed and authenticated.- The
ualib/agda-algebrasrepo must already exist.
Quick start¶
# 1. Dry run — see what would be created:
python3 scripts/python/gh_project_populate.py docs/GITHUB_PROJECT.md --repo ualib/agda-algebras --dry-run
# 2. Create everything (will prompt for confirmation):
python3 scripts/python/gh_project_populate.py docs/GITHUB_PROJECT.md --repo ualib/agda-algebras
# 3. Or create in stages:
python3 scripts/python/gh_project_populate.py docs/GITHUB_PROJECT.md --repo ualib/agda-algebras --labels-only
python3 scripts/python/gh_project_populate.py docs/GITHUB_PROJECT.md --repo ualib/agda-algebras --milestones-only
python3 scripts/python/gh_project_populate.py docs/GITHUB_PROJECT.md --repo ualib/agda-algebras --issues-only
# 4. Resume if interrupted (e.g. start from M3-2):
python3 scripts/python/gh_project_populate.py docs/GITHUB_PROJECT.md --repo ualib/agda-algebras --issues-only --start-from M3-2
Notes¶
- The patched
_parse_labelsreads from the## Labelssection of this file. See the companion patch file for the small diff. - Labels and milestones are idempotent — re-running skips existing ones.
- Issue titles are prefixed with
[M1-1],[M2-3], etc. for easy identification and ordering. - A 1.5-second delay between API calls avoids GitHub rate limiting (adjustable with
--delay).