Initial version - #1
Closed
roed314 wants to merge 3 commits into
Closed
Conversation
- docs/FAMILIES.md: prioritized enumeration of ~60 families of Diophantine
equations (forms, status, methods, software, references, specialization
DAG, undecidability boundary), per the LuCaNT 2 vision talk
- diophantine_classifier/: Sage-based package
- data/families.yaml: machine-readable registry (DAG, priorities, status,
software pointers, fillable code templates)
- parsing: term model with parameters, variable exponents (2^n, y^q),
unit fractions, denominator-clearing with tracked conditions
- matchers: ~45 structural recognizers + genus-based routing for plane
curves; reducible equations split into components
- classify: DAG-ranked classification with explain() and JSON as_dict()
- solvers: linear, Pell (continued fractions), generalized Pell and Thue
(PARI), quadratic-form isotropy with local obstructions, 2/3/4 squares,
BinaryQF, Weierstrass integral points, plus literature-complete answers
(Catalan, Fermat, Ramanujan-Nagell)
- cli: dioclassify entry point (text and JSON)
- tests: 86 tests incl. a 54-equation corpus of famous examples
- docs/DESIGN.md: architecture + transformation-ladder roadmap (waves 2-4)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…stry files Responding to review: 1. Sage-convention docstrings (INPUT/OUTPUT/EXAMPLES) on every function and dataclass, private helpers included; 410 doctests pass under 'sage -t'; 'sage --coverage' reports 100% on all seven modules (make doctest/coverage). 2. SolutionSet is now iterable with true enumeration of infinite solution sets: Pell by powers of the fundamental unit, generalized Pell by walking automorph orbits, linear equations by lattice-coset shells, primitive Pythagorean triples, and the Markov/Hurwitz Vieta tree (heap order). Finite representation problems are enumerated completely instead of witnessed (2/3/4 squares, definite BinaryQF, unit fractions), with explicit complete/kind semantics. 3. All dataclasses (Family, Term, ParsedEquation, Match, Classification, SolutionSet) document every attribute. 4. References upgraded: data/references.bib (122 entries; DOIs where verified, urls only to legally free copies), families cite by BibTeX key with per-use 'why' annotations, and tools/check_references.py validates structure, resolves DOIs/URLs (--online), and checks locally downloaded PDFs (references/pdf/<key>.pdf) against their entries; report at references/REPORT.md. 5. Registry split into data/families/<slug>.yaml (one file per family, merge-friendly; loader enforces slug == filename). 105 unit tests + 410 doctests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- tools/check_references.py now records successes (PDF verified, DOI/URL resolved) write-once in the committed ledger references/status.yaml: a run on a machine without a file reports 'missing locally' but never downgrades a recorded verification, and a local mismatch warns without erasing the ledger (your copy may simply be the wrong file). Ledger verifications also drop entries from the download TODO list. Tests cover upgrade-only, mismatch-keeps-verification, and recording. - All 115 docstrings reformatted to the Sage convention: the summary starts on the line after the opening triple quote. Doctests (410) and coverage (100% on all modules) unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Aug 8, 2026
roed-math
pushed a commit
that referenced
this pull request
Aug 8, 2026
The parser: equation string to `ParsedEquation`. Recognizes the term model the rest of the classifier works with: polynomial terms, `2^n`-style exponential terms and `y^q` power terms, with parameters living in the coefficient ring. Denominators are cleared and the resulting nonvanishing conditions are recorded in `conditions`, so the original problem is never silently replaced by a cleared one. No family data is involved: the parser is exercised entirely by its own doctests (`make doctest`). Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 8, 2026
The family registry: `data/families/<slug>.yaml`, one file per family. - `registry.py` loads the directory, validates it (parents resolve, priorities and statuses come from fixed vocabularies, the DAG is acyclic, every reference key resolves in `references.bib` with a nonempty `why`), and exposes `depth`/`ancestors` — the specificity order used to rank matches. - `tools/check_references.py` plus `references/`: the reference pipeline and its monotone verification ledger. `make references` regenerates `references/REPORT.md`; that generated file is committed by the last PR of the series, when the registry is complete. - `docs/FAMILIES.md`: the prose enumeration. Its section headings are all here; the per-family entries arrive with their families. Three seed families are included so that the layers that follow have something to classify: `general-polynomial` (the root of the DAG), `linear` and `univariate`. Every other family gets its own PR later in the series. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 8, 2026
The shape matchers: `matchers.run(parsed)` returns `Match(slug, data)` records. This is the file where a human eye is most useful on the mathematics: the degree/genus tests, the reductions to standard forms, and the data each match extracts (`D` for Pell, a-invariants for Weierstrass, the regime of a generalized Fermat equation, ...). Matchers never mutate the parsed equation; any normalization is described in `Match.transform`. The recognizers cover 44 families, most of which are not registered yet. That is deliberate and safe: a recognizer whose family has not landed is inert, because the classifier (next PR) ranks matches through the registry and drops slugs it does not know. `tests/test_registry.py` checks the flags of the registered ones; `99-polish` tightens that to *every* emitted slug once the registry is complete. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 8, 2026
The classification pipeline. `classify()` parses, splits reducible equations into components, runs the matchers, and ranks the results by depth in the family DAG, so the most specific family wins. `Classification.explain()` is the human report and `as_dict()` is the JSON contract for the future website backend. `tests/test_classify.py` starts the classification corpus (famous equation to expected family); each family PR adds its own rows. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 8, 2026
The solver layer. `SolutionSet` is the result type: a finite complete list, an empty set with a reason, or an infinite family that streams (`iter(S)`, `S.first(n)`). When no solver is wired up, `SolverUnavailable` carries the registry's software pointers and filled code templates, so an equation page can always offer runnable code. `solve()` dispatches on the primary family and then walks up the lineage. The two seed solvers (linear, univariate) are here; every other solver arrives with its family, which is what makes those PRs independent. The module-level enumeration bounds and the Sage imports are the union used by those solvers. `cli.py` (`dioclassify 'x^2 - 61*y^2 = 1' --solve`) also lands here, since it needs both halves: classification for `--json`, solving for `--solve`. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 8, 2026
The first layer of the family DAG: the root families and their immediate specializations. These are the parents that the individual family PRs hang off, so they land first as a group. Each entry is a YAML file, its `docs/FAMILIES.md` section, its classification-corpus rows and, where standard software is definitive, its solver. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 8, 2026
The second layer of the family DAG. Same shape as the previous PR: parent families only, so that the 38 one-family PRs at the end of the series can be reviewed and merged in any order. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 8, 2026
The last layer of parent families: the deepest interior nodes of the DAG. After this PR every remaining family is a leaf, and each one gets its own PR that touches nothing but its own data, prose, tests and (where applicable) solver. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
Packaging and documentation skeleton plus the bibliography layer. - `pyproject.toml`, `Makefile`, `.gitignore`: the project runs under Sage's Python (`make test`, `make doctest`, `make coverage`, `make references`). - `.github/workflows/ci.yml`: those same four checks on every pull request, inside the official `sagemath/sagemath` container (that image has no `make`, so the steps spell the commands out and name the target they mirror). - `CLAUDE.md`, `docs/DESIGN.md`: how the classifier is put together. They describe the finished system, i.e. the state at the end of this series. `README.md` waits for `03-registry`, the PR that brings the files it links to. - `references.py` and `data/references.bib`: the annotated bibliography and the BibTeX parser/formatter that renders entries for display. Every family in this series cites into that file by key. Reviewing the bibliography: entries are checked mechanically (required fields, DOI/arXiv/URL syntax) by the tool that arrives in `03-registry`; `url` fields point at legally free copies only. What each reference is *for* is recorded per family, in the family's own PR. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The parser: equation string to `ParsedEquation`. Recognizes the term model the rest of the classifier works with: polynomial terms, `2^n`-style exponential terms and `y^q` power terms, with parameters living in the coefficient ring. Denominators are cleared and the resulting nonvanishing conditions are recorded in `conditions`, so the original problem is never silently replaced by a cleared one. No family data is involved: the parser is exercised entirely by its own doctests (`make doctest`). Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The family registry: `data/families/<slug>.yaml`, one file per family. - `registry.py` loads the directory, validates it (parents resolve, priorities and statuses come from fixed vocabularies, the DAG is acyclic, every reference key resolves in `references.bib` with a nonempty `why`), and exposes `depth`/`ancestors` — the specificity order used to rank matches. - `tools/check_references.py` plus `references/`: the reference pipeline and its monotone verification ledger. The committed `references/REPORT.md` is the output of `make references` against the registry as it stands here; the closing PR regenerates it once every family has landed (regenerating it in each family PR would collide in every one of them). - `README.md`, which links to the family enumeration, the registry directory and the reference report — all of them present as of this PR. - `docs/FAMILIES.md`: the prose enumeration. Its section headings are all here; the per-family entries arrive with their families. Three seed families are included so that the layers that follow have something to classify: `general-polynomial` (the root of the DAG), `linear` and `univariate`. Every other family gets its own PR later in the series. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The shape matchers: `matchers.run(parsed)` returns `Match(slug, data)` records. This is the file where a human eye is most useful on the mathematics: the degree/genus tests, the reductions to standard forms, and the data each match extracts (`D` for Pell, a-invariants for Weierstrass, the regime of a generalized Fermat equation, ...). Matchers never mutate the parsed equation; any normalization is described in `Match.transform`. The recognizers cover 44 families, most of which are not registered yet. That is deliberate and safe: a recognizer whose family has not landed is inert, because the classifier (next PR) ranks matches through the registry and drops slugs it does not know. `tests/test_registry.py` checks the flags of the registered ones; `99-polish` tightens that to *every* emitted slug once the registry is complete. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The classification pipeline. `classify()` parses, splits reducible equations into components, runs the matchers, and ranks the results by depth in the family DAG, so the most specific family wins. `Classification.explain()` is the human report and `as_dict()` is the JSON contract for the future website backend. `tests/test_classify.py` starts the classification corpus (famous equation to expected family); each family PR adds its own rows. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The solver layer. `SolutionSet` is the result type: a finite complete list, an empty set with a reason, or an infinite family that streams (`iter(S)`, `S.first(n)`). When no solver is wired up, `SolverUnavailable` carries the registry's software pointers and filled code templates, so an equation page can always offer runnable code. `solve()` dispatches on the primary family and then walks up the lineage. The two seed solvers (linear, univariate) are here; every other solver arrives with its family, which is what makes those PRs independent. The module-level enumeration bounds and the Sage imports are the union used by those solvers. `cli.py` (`dioclassify 'x^2 - 61*y^2 = 1' --solve`) also lands here, since it needs both halves: classification for `--json`, solving for `--solve`. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The first layer of the family DAG: the root families and their immediate specializations. These are the parents that the individual family PRs hang off, so they land first as a group. Each entry is a YAML file, its `docs/FAMILIES.md` section, its classification-corpus rows and, where standard software is definitive, its solver. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The second layer of the family DAG. Same shape as the previous PR: parent families only, so that the 38 one-family PRs at the end of the series can be reviewed and merged in any order. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The last layer of parent families: the deepest interior nodes of the DAG. After this PR every remaining family is a leaf, and each one gets its own PR that touches nothing but its own data, prose, tests and (where applicable) solver. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
Packaging and documentation skeleton plus the bibliography layer. - `pyproject.toml`, `Makefile`, `.gitignore`: the project runs under Sage's Python (`make test`, `make doctest`, `make coverage`, `make references`). - `.github/workflows/ci.yml`: those same four checks on every pull request, inside the official `sagemath/sagemath` container (that image has no `make`, so the steps spell the commands out and name the target they mirror). - `CLAUDE.md`, `docs/DESIGN.md`: how the classifier is put together. They describe the finished system, i.e. the state at the end of this series. `README.md` waits for `03-registry`, the PR that brings the files it links to. - `references.py` and `data/references.bib`: the annotated bibliography and the BibTeX parser/formatter that renders entries for display. Every family in this series cites into that file by key. Reviewing the bibliography: entries are checked mechanically (required fields, DOI/arXiv/URL syntax) by the tool that arrives in `03-registry`; `url` fields point at legally free copies only. What each reference is *for* is recorded per family, in the family's own PR. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The parser: equation string to `ParsedEquation`. Recognizes the term model the rest of the classifier works with: polynomial terms, `2^n`-style exponential terms and `y^q` power terms, with parameters living in the coefficient ring. Denominators are cleared and the resulting nonvanishing conditions are recorded in `conditions`, so the original problem is never silently replaced by a cleared one. No family data is involved: the parser is exercised entirely by its own doctests (`make doctest`). Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The family registry: `data/families/<slug>.yaml`, one file per family. - `registry.py` loads the directory, validates it (parents resolve, priorities and statuses come from fixed vocabularies, the DAG is acyclic, every reference key resolves in `references.bib` with a nonempty `why`), and exposes `depth`/`ancestors` — the specificity order used to rank matches. - `tools/check_references.py` plus `references/`: the reference pipeline and its monotone verification ledger. The committed `references/REPORT.md` is the output of `make references` against the registry as it stands here; the closing PR regenerates it once every family has landed (regenerating it in each family PR would collide in every one of them). - `README.md`, which links to the family enumeration, the registry directory and the reference report — all of them present as of this PR. - `docs/FAMILIES.md`: the prose enumeration. Its section headings are all here; the per-family entries arrive with their families. Three seed families are included so that the layers that follow have something to classify: `general-polynomial` (the root of the DAG), `linear` and `univariate`. Every other family gets its own PR later in the series. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The shape matchers: `matchers.run(parsed)` returns `Match(slug, data)` records. This is the file where a human eye is most useful on the mathematics: the degree/genus tests, the reductions to standard forms, and the data each match extracts (`D` for Pell, a-invariants for Weierstrass, the regime of a generalized Fermat equation, ...). Matchers never mutate the parsed equation; any normalization is described in `Match.transform`. The recognizers cover 44 families, most of which are not registered yet. That is deliberate and safe: a recognizer whose family has not landed is inert, because the classifier (next PR) ranks matches through the registry and drops slugs it does not know. `tests/test_registry.py` checks the flags of the registered ones; `99-polish` tightens that to *every* emitted slug once the registry is complete. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The classification pipeline. `classify()` parses, splits reducible equations into components, runs the matchers, and ranks the results by depth in the family DAG, so the most specific family wins. `Classification.explain()` is the human report and `as_dict()` is the JSON contract for the future website backend. `tests/test_classify.py` starts the classification corpus (famous equation to expected family); each family PR adds its own rows. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The solver layer. `SolutionSet` is the result type: a finite complete list, an empty set with a reason, or an infinite family that streams (`iter(S)`, `S.first(n)`). When no solver is wired up, `SolverUnavailable` carries the registry's software pointers and filled code templates, so an equation page can always offer runnable code. `solve()` dispatches on the primary family and then walks up the lineage. The two seed solvers (linear, univariate) are here; every other solver arrives with its family, which is what makes those PRs independent. The module-level enumeration bounds and the Sage imports are the union used by those solvers. `cli.py` (`dioclassify 'x^2 - 61*y^2 = 1' --solve`) also lands here, since it needs both halves: classification for `--json`, solving for `--solve`. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The first layer of the family DAG: the root families and their immediate specializations. These are the parents that the individual family PRs hang off, so they land first as a group. Each entry is a YAML file, its `docs/FAMILIES.md` section, its classification-corpus rows and, where standard software is definitive, its solver. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The second layer of the family DAG. Same shape as the previous PR: parent families only, so that the 38 one-family PRs at the end of the series can be reviewed and merged in any order. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The last layer of parent families: the deepest interior nodes of the DAG. After this PR every remaining family is a leaf, and each one gets its own PR that touches nothing but its own data, prose, tests and (where applicable) solver. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
Packaging and documentation skeleton plus the bibliography layer. - `pyproject.toml`, `Makefile`, `.gitignore`: the project runs under Sage's Python (`make test`, `make doctest`, `make coverage`, `make references`). - `.github/workflows/ci.yml`: those same four checks on every pull request, inside the official `sagemath/sagemath` container (that image has no `make`, so the steps spell the commands out and name the target they mirror). - `CLAUDE.md`, `docs/DESIGN.md`: how the classifier is put together. They describe the finished system, i.e. the state at the end of this series. `README.md` waits for `03-registry`, the PR that brings the files it links to. - `references.py` and `data/references.bib`: the annotated bibliography and the BibTeX parser/formatter that renders entries for display. Every family in this series cites into that file by key. Reviewing the bibliography: entries are checked mechanically (required fields, DOI/arXiv/URL syntax) by the tool that arrives in `03-registry`; `url` fields point at legally free copies only. What each reference is *for* is recorded per family, in the family's own PR. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The parser: equation string to `ParsedEquation`. Recognizes the term model the rest of the classifier works with: polynomial terms, `2^n`-style exponential terms and `y^q` power terms, with parameters living in the coefficient ring. Denominators are cleared and the resulting nonvanishing conditions are recorded in `conditions`, so the original problem is never silently replaced by a cleared one. No family data is involved: the parser is exercised entirely by its own doctests (`make doctest`). Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The family registry: `data/families/<slug>.yaml`, one file per family. - `registry.py` loads the directory, validates it (parents resolve, priorities and statuses come from fixed vocabularies, the DAG is acyclic, every reference key resolves in `references.bib` with a nonempty `why`), and exposes `depth`/`ancestors` — the specificity order used to rank matches. - `tools/check_references.py` plus `references/`: the reference pipeline and its monotone verification ledger. The committed `references/REPORT.md` is the output of `make references` against the registry as it stands here; the closing PR regenerates it once every family has landed (regenerating it in each family PR would collide in every one of them). - `README.md`, which links to the family enumeration, the registry directory and the reference report — all of them present as of this PR. - `docs/FAMILIES.md`: the prose enumeration. Its section headings are all here; the per-family entries arrive with their families. Three seed families are included so that the layers that follow have something to classify: `general-polynomial` (the root of the DAG), `linear` and `univariate`. Every other family gets its own PR later in the series. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
roed-math
pushed a commit
that referenced
this pull request
Aug 9, 2026
The shape matchers: `matchers.run(parsed)` returns `Match(slug, data)` records. This is the file where a human eye is most useful on the mathematics: the degree/genus tests, the reductions to standard forms, and the data each match extracts (`D` for Pell, a-invariants for Weierstrass, the regime of a generalized Fermat equation, ...). Matchers never mutate the parsed equation; any normalization is described in `Match.transform`. The recognizers cover 44 families, most of which are not registered yet. That is deliberate and safe: a recognizer whose family has not landed is inert, because the classifier (next PR) ranks matches through the registry and drops slugs it does not know. `tests/test_registry.py` checks the flags of the registered ones; `99-polish` tightens that to *every* emitted slug once the registry is complete. Part of the series that splits #1 into reviewable pieces: 1. `01-bibliography` — packaging, docs, annotated bibliography 2. `02-parsing` — equation strings to a term model 3. `03-registry` — the YAML family registry (3 seed families) 4. `04-matchers` — shape recognizers 5. `05-classify` — the classification pipeline 6. `06-solvers` — solver framework, two seed solvers, and the CLI 7. `07..09-backbone` — the 23 parent families of the DAG, by depth 8. one PR per remaining family (38 of them, mutually independent) 9. `99-polish` — restore the full doctests and tighten the invariants
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implemented by Claude, with feedback from @roed314 and GPT.