certo-math 0.11.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. certo_math-0.11.1/LICENSE +21 -0
  2. certo_math-0.11.1/PKG-INFO +317 -0
  3. certo_math-0.11.1/README.md +286 -0
  4. certo_math-0.11.1/pyproject.toml +60 -0
  5. certo_math-0.11.1/setup.cfg +4 -0
  6. certo_math-0.11.1/src/certo/__init__.py +45 -0
  7. certo_math-0.11.1/src/certo/asymptotics.py +233 -0
  8. certo_math-0.11.1/src/certo/audit.py +299 -0
  9. certo_math-0.11.1/src/certo/binding.py +137 -0
  10. certo_math-0.11.1/src/certo/catalogue.py +136 -0
  11. certo_math-0.11.1/src/certo/cdcl.py +276 -0
  12. certo_math-0.11.1/src/certo/certificate.py +4427 -0
  13. certo_math-0.11.1/src/certo/cli.py +2375 -0
  14. certo_math-0.11.1/src/certo/cnf.py +231 -0
  15. certo_math-0.11.1/src/certo/cover.py +129 -0
  16. certo_math-0.11.1/src/certo/cycles.py +196 -0
  17. certo_math-0.11.1/src/certo/dataspec.py +130 -0
  18. certo_math-0.11.1/src/certo/doctor.py +341 -0
  19. certo_math-0.11.1/src/certo/drup.py +245 -0
  20. certo_math-0.11.1/src/certo/engines/__init__.py +1 -0
  21. certo_math-0.11.1/src/certo/engines/algebra.py +1084 -0
  22. certo_math-0.11.1/src/certo/engines/bb.py +256 -0
  23. certo_math-0.11.1/src/certo/engines/bisect.py +128 -0
  24. certo_math-0.11.1/src/certo/engines/bounds.py +116 -0
  25. certo_math-0.11.1/src/certo/engines/cegis.py +180 -0
  26. certo_math-0.11.1/src/certo/engines/compose.py +186 -0
  27. certo_math-0.11.1/src/certo/engines/domain.py +207 -0
  28. certo_math-0.11.1/src/certo/engines/farkas.py +175 -0
  29. certo_math-0.11.1/src/certo/engines/graphsearch.py +308 -0
  30. certo_math-0.11.1/src/certo/engines/induct.py +151 -0
  31. certo_math-0.11.1/src/certo/engines/lp.py +341 -0
  32. certo_math-0.11.1/src/certo/engines/mixed.py +244 -0
  33. certo_math-0.11.1/src/certo/engines/order.py +106 -0
  34. certo_math-0.11.1/src/certo/engines/sat.py +166 -0
  35. certo_math-0.11.1/src/certo/engines/shrink.py +343 -0
  36. certo_math-0.11.1/src/certo/engines/smt.py +433 -0
  37. certo_math-0.11.1/src/certo/entry.py +132 -0
  38. certo_math-0.11.1/src/certo/equitable.py +277 -0
  39. certo_math-0.11.1/src/certo/exact.py +327 -0
  40. certo_math-0.11.1/src/certo/existence.py +124 -0
  41. certo_math-0.11.1/src/certo/family.py +171 -0
  42. certo_math-0.11.1/src/certo/graphs.py +341 -0
  43. certo_math-0.11.1/src/certo/growth.py +130 -0
  44. certo_math-0.11.1/src/certo/i18n.py +69 -0
  45. certo_math-0.11.1/src/certo/interchange.py +159 -0
  46. certo_math-0.11.1/src/certo/lattice.py +447 -0
  47. certo_math-0.11.1/src/certo/lean.py +114 -0
  48. certo_math-0.11.1/src/certo/leancheck.py +238 -0
  49. certo_math-0.11.1/src/certo/leanexport.py +359 -0
  50. certo_math-0.11.1/src/certo/ledger.py +124 -0
  51. certo_math-0.11.1/src/certo/limits.py +31 -0
  52. certo_math-0.11.1/src/certo/linarith.py +288 -0
  53. certo_math-0.11.1/src/certo/linsolve.py +229 -0
  54. certo_math-0.11.1/src/certo/lint.py +707 -0
  55. certo_math-0.11.1/src/certo/locales/en.json +1342 -0
  56. certo_math-0.11.1/src/certo/locales/es.json +1342 -0
  57. certo_math-0.11.1/src/certo/mcp_server.py +1794 -0
  58. certo_math-0.11.1/src/certo/moment.py +116 -0
  59. certo_math-0.11.1/src/certo/numbers.py +192 -0
  60. certo_math-0.11.1/src/certo/numerics.py +295 -0
  61. certo_math-0.11.1/src/certo/orbits.py +362 -0
  62. certo_math-0.11.1/src/certo/orderinfer.py +241 -0
  63. certo_math-0.11.1/src/certo/packing.py +289 -0
  64. certo_math-0.11.1/src/certo/parametric.py +328 -0
  65. certo_math-0.11.1/src/certo/paramsym.py +425 -0
  66. certo_math-0.11.1/src/certo/peak.py +151 -0
  67. certo_math-0.11.1/src/certo/polynomials.py +297 -0
  68. certo_math-0.11.1/src/certo/propositional.py +174 -0
  69. certo_math-0.11.1/src/certo/rangebound.py +228 -0
  70. certo_math-0.11.1/src/certo/ratio.py +120 -0
  71. certo_math-0.11.1/src/certo/reducers.py +135 -0
  72. certo_math-0.11.1/src/certo/repro.py +178 -0
  73. certo_math-0.11.1/src/certo/resultants.py +225 -0
  74. certo_math-0.11.1/src/certo/routing.py +269 -0
  75. certo_math-0.11.1/src/certo/simplex.py +168 -0
  76. certo_math-0.11.1/src/certo/sos.py +236 -0
  77. certo_math-0.11.1/src/certo/spec.py +1541 -0
  78. certo_math-0.11.1/src/certo/status.py +89 -0
  79. certo_math-0.11.1/src/certo/status_report.py +315 -0
  80. certo_math-0.11.1/src/certo/structures.py +290 -0
  81. certo_math-0.11.1/src/certo/symmetry.py +169 -0
  82. certo_math-0.11.1/src/certo/toric.py +276 -0
  83. certo_math-0.11.1/src/certo/tree.py +95 -0
  84. certo_math-0.11.1/src/certo/z3util.py +82 -0
  85. certo_math-0.11.1/src/certo_math.egg-info/PKG-INFO +317 -0
  86. certo_math-0.11.1/src/certo_math.egg-info/SOURCES.txt +94 -0
  87. certo_math-0.11.1/src/certo_math.egg-info/dependency_links.txt +1 -0
  88. certo_math-0.11.1/src/certo_math.egg-info/entry_points.txt +3 -0
  89. certo_math-0.11.1/src/certo_math.egg-info/requires.txt +10 -0
  90. certo_math-0.11.1/src/certo_math.egg-info/top_level.txt +1 -0
  91. certo_math-0.11.1/tests/test_adversarial.py +480 -0
  92. certo_math-0.11.1/tests/test_determinism.py +248 -0
  93. certo_math-0.11.1/tests/test_extras.py +8524 -0
  94. certo_math-0.11.1/tests/test_i18n.py +235 -0
  95. certo_math-0.11.1/tests/test_mcp.py +664 -0
  96. certo_math-0.11.1/tests/test_smoke.py +663 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Juan Pablo Traverso
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,317 @@
1
+ Metadata-Version: 2.4
2
+ Name: certo-math
3
+ Version: 0.11.1
4
+ Summary: Certificates for the work before the proof: decide, enumerate, optimise, reduce and certify -- and re-check it all without trusting the tool. CLI + MCP.
5
+ Author: Juan Pablo Traverso
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://jtraverso.github.io/certo-math/
8
+ Project-URL: Repository, https://github.com/jtraverso/certo-math
9
+ Project-URL: Changelog, https://github.com/jtraverso/certo-math/blob/main/CHANGELOG.md
10
+ Project-URL: Documentation, https://github.com/jtraverso/certo-math/blob/main/docs/COMMANDS.md
11
+ Keywords: proof,certificate,smt,z3,linear-programming,combinatorics,lean,mcp,formalisation
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Operating System :: OS Independent
19
+ Requires-Python: >=3.11
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: z3-solver>=4.12
23
+ Requires-Dist: pulp>=2.7
24
+ Provides-Extra: mcp
25
+ Requires-Dist: mcp>=2.0; extra == "mcp"
26
+ Provides-Extra: numerics
27
+ Requires-Dist: python-flint>=0.6; extra == "numerics"
28
+ Requires-Dist: mpmath>=1.3; extra == "numerics"
29
+ Requires-Dist: numpy>=1.24; extra == "numerics"
30
+ Dynamic: license-file
31
+
32
+ # certo
33
+
34
+ **Between having a mathematical idea and having a proof of it there is a lot
35
+ of work that is not proving.** certo does that work — find the object, break
36
+ the claims that are false, measure what survives, reduce it to what it really
37
+ is, and assemble the rest — and every step comes back with a **certificate
38
+ anyone can re-check without trusting certo.**
39
+
40
+ CLI and MCP. Forty-six commands. Runs in milliseconds where a formalisation
41
+ costs hours.
42
+
43
+ *Español: [README.es.md](README.es.md) · run any command with `--lang es`.*
44
+
45
+ | | |
46
+ |---|---|
47
+ | **[Project page →](https://jtraverso.github.io/certo-math/)** | the didactic introduction: what certo is for, in one page, in both languages |
48
+ | **[Commands](docs/COMMANDS.md)** | all forty-six, one entry each: the question, the spec, the certificate, and what it does not establish |
49
+ | **[Specs](docs/SPECS.md)** | the DSL: every spec type with a minimal working example, shared options, exit codes |
50
+ | **[Certificates](docs/CERTIFICATES.md)** | why they are the centre, the forty-seven kinds, which re-check without a solver |
51
+ | **[Worked cases](docs/CASES.md)** | real problems end to end: symmetry, sweeps, parametric bounds, packings, toric data |
52
+ | **[Limits](docs/LIMITS.md)** | what it does not do, and the FAQ |
53
+ | **[Walkthrough](examples/WALKTHROUGH.md)** | one problem, seven commands, fifteen seconds |
54
+
55
+ ---
56
+
57
+ ## What it is
58
+
59
+ The lab instrument: find a contradiction fast, learn which hypotheses are
60
+ redundant, exhaustively validate a finite case, bracket a constant with a
61
+ certificate, synthesise a candidate over a bounded domain.
62
+
63
+ It is **not** a proof assistant — that is Lean, Rocq or Isabelle — nor a
64
+ computer algebra catalogue. [What it does not do](docs/LIMITS.md) matters as
65
+ much as the command list.
66
+
67
+ The division of labour, in a user's words after a real session: certo finds
68
+ and certifies the small trades; the human proof explains why they assemble
69
+ globally without double-counting.
70
+
71
+ | Phase | What you ask | What comes back |
72
+ |---|---|---|
73
+ | **Find** | Is there an object like this? What is the best one? | the object itself — and with `mixed --prove-optimal`, a proof that it *is* the best |
74
+ | **Break** | Is this claim actually true? | a counterexample **with concrete values**, in milliseconds |
75
+ | **Measure** | Not *whether* it fails — how much, and where is it worst? | exact min, max and mean, and the extreme instances by name |
76
+ | **Reduce** | Ninety counterexamples. How many objects is that really? | orbits under your symmetry, and one minimal witness per orbit |
77
+ | **Establish** | Is it true for every case, every `n`, exactly? | DRAT proofs, induction with the chain checked, Farkas multipliers, Gröbner cofactors, sums of squares, rigorous enclosures |
78
+ | **Assemble** | What does my whole project rest on, and what do I still owe? | the proof with every **bridge named**, and a report of what is still assumed |
79
+
80
+ A verdict you cannot re-check is a rumour. Everything here produces an
81
+ artefact, and most of them check without a solver at all.
82
+
83
+ ## Install
84
+
85
+ Requires Python 3.11+.
86
+
87
+ ```bash
88
+ pip install "certo-math[mcp,numerics]"
89
+ ```
90
+
91
+ The import package and the commands are `certo`, not `certo-math`:
92
+ `from certo import Spec`, `certo prove spec.py`. Only the distribution
93
+ carries the longer name, because `certo` alone is a crowded word.
94
+
95
+ From a checkout instead:
96
+
97
+ ```bash
98
+ git clone https://github.com/jtraverso/certo-math
99
+ cd certo-math
100
+ pip install -e ".[mcp,numerics]"
101
+ ```
102
+
103
+ Dependencies: `z3-solver` and `pulp`, both of which ship their binaries. The
104
+ extras are `mcp` for the MCP server and `numerics` for `bounds` and `sos`
105
+ (`python-flint`, `mpmath` and `numpy`); without them you get the CLI, minus
106
+ rigorous numerics and sums of squares.
107
+
108
+ Check it works:
109
+
110
+ ```bash
111
+ certo doctor
112
+ ```
113
+
114
+ Optional tools, none installed automatically and none needed to start:
115
+
116
+ | Tool | What for | Without it |
117
+ |---|---|---|
118
+ | [`nauty`](https://pallini.di.uniroma1.it/) (`geng` on `PATH`) | enumerating graphs | Python engine, comfortable to n=8 |
119
+ | `cadical` or `kissat` | `cases` on large instances | our own CDCL, correct but slow |
120
+ | `drat-trim` | second opinion on DRAT proofs | the built-in Python checker suffices |
121
+ | `python-flint` (Arb) | `bounds` with special functions | `mpmath.iv`, for the elementary ones |
122
+ | `numpy` | the Gram search behind `sos` | **nothing** — `sos` cannot run without it |
123
+
124
+ `certo doctor` says which of these you have and **what each gap costs**, which
125
+ is the part a checklist of red crosses leaves out.
126
+
127
+ ## Two minutes in
128
+
129
+ ```bash
130
+ certo core examples/amgm.py
131
+ ```
132
+
133
+ ```
134
+ PROVED -- symbolic and universal under the hypotheses [unsat]
135
+ hypotheses needed: a_pos, b_pos, c_pos | redundant: noise
136
+ ```
137
+
138
+ Every file in [`examples/`](examples/) carries in its docstring what it does
139
+ and what to expect. Lost? `certo commands` prints the routing table below in
140
+ your terminal, in your language.
141
+
142
+ ## The three cross-cutting rules
143
+
144
+ 1. **Every command returns a certificate, or says explicitly why not.**
145
+ Never a bare "yes".
146
+ 2. **Six result states:** `unsat`, `sat`, `unknown_solver`, `timeout`,
147
+ `resource_exhausted`, `out_of_theory`. Only the first two are conclusive.
148
+ The other four all mean "no answer", but for different reasons, and
149
+ collapsing them is expensive: an LLM that reads "unknown" writes "no
150
+ solution exists".
151
+ 3. **Determinism by work budget, not by clock:** `rlimit` in Z3 and
152
+ `conflict_budget` in SAT. *This covers our engines, not your predicate:* if
153
+ your `sweep` predicate calls scipy or CBC, that part is outside the
154
+ guarantee.
155
+
156
+ ## If you are an LLM being asked to use this
157
+
158
+ 1. Read [`docs/SPECS.md`](docs/SPECS.md), or call the `dsl_guide` MCP tool,
159
+ before writing a spec.
160
+ 2. Find the command by the **question**, not the name:
161
+ [`docs/COMMANDS.md`](docs/COMMANDS.md), or `certo commands`.
162
+ 3. Run [`certo lint`](docs/COMMANDS.md#certo-lint) on every spec before
163
+ running it. It is the cheapest thing in the tool and it catches the
164
+ contradictory regime, the empty family and the 10⁹ domain.
165
+ 4. Read the verdict, not the exit status. `unknown_solver` is **not**
166
+ "does not exist".
167
+ 5. Certificates are written to disk and do not travel in an MCP response.
168
+ Call `verify` with the path you are given.
169
+
170
+ ## The forty-six commands
171
+
172
+ Grouped as [`certo commands`](docs/COMMANDS.md) groups them. Full entries,
173
+ with what each one does **not** establish, in
174
+ [`docs/COMMANDS.md`](docs/COMMANDS.md).
175
+
176
+ | Command | What it does | Engine | Certificate |
177
+ |---|---|---|---|
178
+ | `prove` | Negate the claim, look for `unsat` | Z3 | unsat core, or counterexample |
179
+ | `check` | Satisfiability; `--hypotheses-only` asks if the regime is non-empty | Z3 | model, or core |
180
+ | `core` | MUS: which hypotheses are needed | Z3 | minimal core |
181
+ | `audit` | Does every hypothesis earn its place, or is the theorem overstated? | Z3 | **verdict per hypothesis, each with the assignment that breaks it** |
182
+ | `farkas` | `linarith` / `nlinarith`, with the multipliers | exact LP | **Farkas certificate**, solver-free |
183
+ | `compose` | Assemble lemmas into one proof, checking the join | Z3 | **proof**: every lemma, its certificate, and the link |
184
+ | `induct` | Base cases + a step, and the check that the chain joins | Z3 | **induction**: both halves, and the two numbers that matter |
185
+ | `synth` | CEGIS: ∃obj ∀input ∃aux | CEGIS/Z3 | object + the counterexamples that forced it |
186
+ | `opt` | LP/ILP, or a packing | CBC | **dual in exact rationals** = the load certificate |
187
+ | `mixed` | A discrete skeleton searched, the continuous part certified | CBC + exact LP | **mixed design**: assignment, exact dual, and a bound |
188
+ | `order` | The exponent of `n` once magnitudes are substituted: decays, or Θ(1)? | exact Laurent | **the exponent**, solver-free |
189
+ | `bounds` | A numeric inequality, rigorously (`e`, `log`, `π`, `ζ`) | Arb or mpmath | **enclosure in exact rationals** |
190
+ | `ideal` | Polynomial systems: refute them, or certify what follows | Gröbner, ours | **cofactors**, checked by expanding |
191
+ | `eliminate` | Remove a variable from two polynomials; keep the condition on the rest | Sylvester + Bareiss | **Res = A·f + B·g**, solver-free |
192
+ | `parametric` | A bound for EVERY value of a parameter, from a dual you already have | weak duality, symbolic | **y and the shifted residuals**, solver-free |
193
+ | `peak` | The best INTEGER choice for a family of concave quadratics, and the value there | exact, no search | **the maximiser and two step inequalities**, solver-free |
194
+ | `reduce` | "By symmetry": the three hypotheses of the averaging argument, checked | exact, no search | **generators, orbits and the quotient**, solver-free |
195
+ | `matrix` | Exact integer linear algebra: rank, determinant, Hermite and Smith | unimodular transforms | **U, V and their inverses**, checked by multiplication, solver-free |
196
+ | `solve` | `A x = b` exactly, over ℚ or ℤ | exact elimination, Smith | **the solution and the system**, one product to check; an obstruction when there is none |
197
+ | `quotient` | A partition of a program, and the equivalence it induces | exact counting | **the class data and both regularities**, solver-free |
198
+ | `cone` | Local toric data: primitivity, multiplicity, the height functional, discrepancies | exact det and solve | **the numbers two geometric theorems consume**, solver-free |
199
+ | `family` | The largest of ten thousand linear programs, and why nothing beats it | exact LP | **the winner and a dual for the rest**, solver-free |
200
+ | `ratio` | A fraction inequality for EVERY n | exact polynomials | **the cleared numerator and the sign of the denominator**, solver-free |
201
+ | `moment` | Is the expected number of bad events below one, so a good object exists? | exact rationals | **the moment and the mass it leaves over**, solver-free |
202
+ | `entry` | Where a sequence first crosses a line, and by how little | exact rationals | **the prefix and the two terms that bracket it**, solver-free |
203
+ | `exists` | Does one exist at all, and the refutation when it does not | own CDCL | model, or DRAT proof |
204
+ | `cover` | Is this an exact cover? A clique partition is one case | counting | **the universe and the parts**, solver-free |
205
+ | `sos` | A polynomial is non-negative, as a sum of squares | numeric + exact rounding | **rational squares**, solver-free |
206
+ | `number` | Primality, or a factorisation | Pratt | **modular-exponentiation tree** |
207
+ | `cases` | SAT with a verified DRAT proof | own CDCL or external binary | DRAT proof |
208
+ | `enum` | Non-isomorphic graphs with filters | nauty or Python | canonical list + hash |
209
+ | `sweep` | Predicate and/or value over a family or ANY finite domain | nauty or Python | family **+ predicate certificates** |
210
+ | `shrink` | Minimise a counterexample (graph or MUS) | CDCL / reduction | minimality witness |
211
+ | `bisect` | A constant's threshold | prove or cases | the pair that brackets it |
212
+ | `range` | The admissible interval of one variable over the regime, not one point of it | exact LP dual | **a Farkas combination at each end**, solver-free |
213
+ | `cycle` | A parameter that depends on itself: compose the growth classes and close the loop | growth ladder | **the chain, its classes and the one comparison**, solver-free |
214
+ | `bind` | Tie a certificate to the Lean declaration meant to justify it, and check it does | Z3 entailment | **the hypothesis, the statement, and whether one covers the other** |
215
+ | `lint` | Check a spec before spending the compute on it | — | — |
216
+ | `status` | Where a proof stands: proved, owed, hollow, stale | — | — |
217
+ | `doctor` | What this install can do, and what each gap costs | — | — |
218
+ | `ask` | One entry point: load a spec and run whatever it asks for (`what` is the same command) | — | whatever the command produces |
219
+ | `commands` | Which command answers which question | — | — |
220
+ | `repro` | Bundle spec, certificates, versions and hashes for a referee | — | the bundle |
221
+ | `verify` | Re-verify a stored certificate | — | — |
222
+ | `export` | Spec to SMT-LIB2/DIMACS, or a linear Farkas certificate to Lean | — | — |
223
+ | `ledger` | Audit log of what was run | — | — |
224
+
225
+ Common options, **after** the subcommand: `--json`, `--cert FILE`, `--lang`,
226
+ `--timeout-ms`, `--rlimit`, `--max-memory-mb`, `--seed`.
227
+
228
+ Exit codes: `0` conclusive, `2` inconclusive, `1` invalid certificate,
229
+ `3` error.
230
+
231
+ ## What it does not do
232
+
233
+ The hard limit is **asymptotic statements with quantifiers over `n`**. "There
234
+ exists `N` such that for every `n ≥ N`, every graph…, the loss is `≤ εn²`" is
235
+ not decided by this tool.
236
+
237
+ | Question | `certo`? |
238
+ |---|---|
239
+ | Is R(3,3) ≤ 6? | **Yes.** `cases`, a 23-line DRAT proof, verified |
240
+ | Is R(3,3) = 6? | **Yes.** `bisect`, threshold certified on both sides |
241
+ | Is R(5,5) ≤ 48? | **Not in practice.** Finite, but the space is 2^903 |
242
+ | Does R(k,k)^(1/k) converge? | **No, in principle.** Asymptotic: not expressible |
243
+
244
+ The full list, and the FAQ, in [`docs/LIMITS.md`](docs/LIMITS.md).
245
+
246
+ ## MCP server
247
+
248
+ Every command exposed to the LLM, with no copy-pasting. The project ships a
249
+ ready [`.mcp.json`](.mcp.json); to register it by hand in Claude Code:
250
+
251
+ ```bash
252
+ claude mcp add certo --env CERTO_WORKSPACE=. -- certo-mcp
253
+ ```
254
+
255
+ `CERTO_WORKSPACE` (the current directory by default) holds `specs/` and
256
+ `certs/`. **Every path is confined there.**
257
+
258
+ Three design decisions:
259
+
260
+ 1. **Certificates do not come back in the response.** A MUS takes 18× more on
261
+ disk than the whole response, and the model cannot verify it by reading it.
262
+ They are written to disk and the path, kind and digest come back.
263
+ 2. **Errors come back as data, not as exceptions.** The SDK turns any
264
+ exception into `Error executing tool X` and swallows the reason; a model
265
+ reading that cannot fix its spec. Here it gets what happened and what to
266
+ correct.
267
+ 3. **`dsl_guide` first.** Both a tool and a resource (`certo://dsl`).
268
+
269
+ > **Specs are Python code and they get executed when loaded.** That is
270
+ > inherent to the DSL and it is the same level of trust an agent with file
271
+ > access already has. The server confines paths, but it **is not a sandbox**:
272
+ > do not point it at third-party specs.
273
+
274
+ `certo doctor --register-mcp` adds certo to `.mcp.json` in the current
275
+ directory, **merging** with whatever is already registered rather than
276
+ replacing it, refusing to touch a file that is not valid JSON, and checking
277
+ that the server actually starts — a different question from whether it is
278
+ registered, and the one people mean.
279
+
280
+ ## Languages
281
+
282
+ English is the default and the source of truth. Spanish ships as an overlay:
283
+
284
+ ```bash
285
+ certo core examples/amgm.py --lang es # or CERTO_LANG=es
286
+ ```
287
+
288
+ Translations live in [`src/certo/locales/`](src/certo/locales/) as JSON. A
289
+ missing key falls back to English, so a partial translation degrades instead
290
+ of breaking. To add a language, copy `en.json`, translate the values and keep
291
+ the `{placeholders}` — there is a test that enforces both invariants.
292
+
293
+ Two things deliberately stay English whatever `--lang` says, because they are
294
+ API surface rather than prose: **command names and flags**, and **MCP tool
295
+ names and descriptions**. Certificates store note **keys**, not rendered text,
296
+ so one issued in Spanish reads correctly for an English reader.
297
+
298
+ ## Tests
299
+
300
+ Over five hundred, no test framework required. The count is deliberately not
301
+ given exactly: the previous README said 253 when there were twice that, and a
302
+ number nobody recomputes goes stale.
303
+
304
+ ```bash
305
+ for t in smoke mcp i18n extras adversarial determinism; do python tests/test_$t.py; done
306
+ ```
307
+
308
+ `python tests/run_examples.py` runs all 65 example specs and verifies every
309
+ certificate they produce.
310
+
311
+ Release notes in [CHANGELOG.md](CHANGELOG.md); what is planned, blocked and
312
+ deliberately refused in [BACKLOG.md](BACKLOG.md).
313
+
314
+ ## Licence
315
+
316
+ MIT. The synthesis engine is a reimplementation of the CEGIS algorithm from
317
+ [marcelwa/CEGIS](https://github.com/marcelwa/CEGIS) (MIT), not of its code.
@@ -0,0 +1,286 @@
1
+ # certo
2
+
3
+ **Between having a mathematical idea and having a proof of it there is a lot
4
+ of work that is not proving.** certo does that work — find the object, break
5
+ the claims that are false, measure what survives, reduce it to what it really
6
+ is, and assemble the rest — and every step comes back with a **certificate
7
+ anyone can re-check without trusting certo.**
8
+
9
+ CLI and MCP. Forty-six commands. Runs in milliseconds where a formalisation
10
+ costs hours.
11
+
12
+ *Español: [README.es.md](README.es.md) · run any command with `--lang es`.*
13
+
14
+ | | |
15
+ |---|---|
16
+ | **[Project page →](https://jtraverso.github.io/certo-math/)** | the didactic introduction: what certo is for, in one page, in both languages |
17
+ | **[Commands](docs/COMMANDS.md)** | all forty-six, one entry each: the question, the spec, the certificate, and what it does not establish |
18
+ | **[Specs](docs/SPECS.md)** | the DSL: every spec type with a minimal working example, shared options, exit codes |
19
+ | **[Certificates](docs/CERTIFICATES.md)** | why they are the centre, the forty-seven kinds, which re-check without a solver |
20
+ | **[Worked cases](docs/CASES.md)** | real problems end to end: symmetry, sweeps, parametric bounds, packings, toric data |
21
+ | **[Limits](docs/LIMITS.md)** | what it does not do, and the FAQ |
22
+ | **[Walkthrough](examples/WALKTHROUGH.md)** | one problem, seven commands, fifteen seconds |
23
+
24
+ ---
25
+
26
+ ## What it is
27
+
28
+ The lab instrument: find a contradiction fast, learn which hypotheses are
29
+ redundant, exhaustively validate a finite case, bracket a constant with a
30
+ certificate, synthesise a candidate over a bounded domain.
31
+
32
+ It is **not** a proof assistant — that is Lean, Rocq or Isabelle — nor a
33
+ computer algebra catalogue. [What it does not do](docs/LIMITS.md) matters as
34
+ much as the command list.
35
+
36
+ The division of labour, in a user's words after a real session: certo finds
37
+ and certifies the small trades; the human proof explains why they assemble
38
+ globally without double-counting.
39
+
40
+ | Phase | What you ask | What comes back |
41
+ |---|---|---|
42
+ | **Find** | Is there an object like this? What is the best one? | the object itself — and with `mixed --prove-optimal`, a proof that it *is* the best |
43
+ | **Break** | Is this claim actually true? | a counterexample **with concrete values**, in milliseconds |
44
+ | **Measure** | Not *whether* it fails — how much, and where is it worst? | exact min, max and mean, and the extreme instances by name |
45
+ | **Reduce** | Ninety counterexamples. How many objects is that really? | orbits under your symmetry, and one minimal witness per orbit |
46
+ | **Establish** | Is it true for every case, every `n`, exactly? | DRAT proofs, induction with the chain checked, Farkas multipliers, Gröbner cofactors, sums of squares, rigorous enclosures |
47
+ | **Assemble** | What does my whole project rest on, and what do I still owe? | the proof with every **bridge named**, and a report of what is still assumed |
48
+
49
+ A verdict you cannot re-check is a rumour. Everything here produces an
50
+ artefact, and most of them check without a solver at all.
51
+
52
+ ## Install
53
+
54
+ Requires Python 3.11+.
55
+
56
+ ```bash
57
+ pip install "certo-math[mcp,numerics]"
58
+ ```
59
+
60
+ The import package and the commands are `certo`, not `certo-math`:
61
+ `from certo import Spec`, `certo prove spec.py`. Only the distribution
62
+ carries the longer name, because `certo` alone is a crowded word.
63
+
64
+ From a checkout instead:
65
+
66
+ ```bash
67
+ git clone https://github.com/jtraverso/certo-math
68
+ cd certo-math
69
+ pip install -e ".[mcp,numerics]"
70
+ ```
71
+
72
+ Dependencies: `z3-solver` and `pulp`, both of which ship their binaries. The
73
+ extras are `mcp` for the MCP server and `numerics` for `bounds` and `sos`
74
+ (`python-flint`, `mpmath` and `numpy`); without them you get the CLI, minus
75
+ rigorous numerics and sums of squares.
76
+
77
+ Check it works:
78
+
79
+ ```bash
80
+ certo doctor
81
+ ```
82
+
83
+ Optional tools, none installed automatically and none needed to start:
84
+
85
+ | Tool | What for | Without it |
86
+ |---|---|---|
87
+ | [`nauty`](https://pallini.di.uniroma1.it/) (`geng` on `PATH`) | enumerating graphs | Python engine, comfortable to n=8 |
88
+ | `cadical` or `kissat` | `cases` on large instances | our own CDCL, correct but slow |
89
+ | `drat-trim` | second opinion on DRAT proofs | the built-in Python checker suffices |
90
+ | `python-flint` (Arb) | `bounds` with special functions | `mpmath.iv`, for the elementary ones |
91
+ | `numpy` | the Gram search behind `sos` | **nothing** — `sos` cannot run without it |
92
+
93
+ `certo doctor` says which of these you have and **what each gap costs**, which
94
+ is the part a checklist of red crosses leaves out.
95
+
96
+ ## Two minutes in
97
+
98
+ ```bash
99
+ certo core examples/amgm.py
100
+ ```
101
+
102
+ ```
103
+ PROVED -- symbolic and universal under the hypotheses [unsat]
104
+ hypotheses needed: a_pos, b_pos, c_pos | redundant: noise
105
+ ```
106
+
107
+ Every file in [`examples/`](examples/) carries in its docstring what it does
108
+ and what to expect. Lost? `certo commands` prints the routing table below in
109
+ your terminal, in your language.
110
+
111
+ ## The three cross-cutting rules
112
+
113
+ 1. **Every command returns a certificate, or says explicitly why not.**
114
+ Never a bare "yes".
115
+ 2. **Six result states:** `unsat`, `sat`, `unknown_solver`, `timeout`,
116
+ `resource_exhausted`, `out_of_theory`. Only the first two are conclusive.
117
+ The other four all mean "no answer", but for different reasons, and
118
+ collapsing them is expensive: an LLM that reads "unknown" writes "no
119
+ solution exists".
120
+ 3. **Determinism by work budget, not by clock:** `rlimit` in Z3 and
121
+ `conflict_budget` in SAT. *This covers our engines, not your predicate:* if
122
+ your `sweep` predicate calls scipy or CBC, that part is outside the
123
+ guarantee.
124
+
125
+ ## If you are an LLM being asked to use this
126
+
127
+ 1. Read [`docs/SPECS.md`](docs/SPECS.md), or call the `dsl_guide` MCP tool,
128
+ before writing a spec.
129
+ 2. Find the command by the **question**, not the name:
130
+ [`docs/COMMANDS.md`](docs/COMMANDS.md), or `certo commands`.
131
+ 3. Run [`certo lint`](docs/COMMANDS.md#certo-lint) on every spec before
132
+ running it. It is the cheapest thing in the tool and it catches the
133
+ contradictory regime, the empty family and the 10⁹ domain.
134
+ 4. Read the verdict, not the exit status. `unknown_solver` is **not**
135
+ "does not exist".
136
+ 5. Certificates are written to disk and do not travel in an MCP response.
137
+ Call `verify` with the path you are given.
138
+
139
+ ## The forty-six commands
140
+
141
+ Grouped as [`certo commands`](docs/COMMANDS.md) groups them. Full entries,
142
+ with what each one does **not** establish, in
143
+ [`docs/COMMANDS.md`](docs/COMMANDS.md).
144
+
145
+ | Command | What it does | Engine | Certificate |
146
+ |---|---|---|---|
147
+ | `prove` | Negate the claim, look for `unsat` | Z3 | unsat core, or counterexample |
148
+ | `check` | Satisfiability; `--hypotheses-only` asks if the regime is non-empty | Z3 | model, or core |
149
+ | `core` | MUS: which hypotheses are needed | Z3 | minimal core |
150
+ | `audit` | Does every hypothesis earn its place, or is the theorem overstated? | Z3 | **verdict per hypothesis, each with the assignment that breaks it** |
151
+ | `farkas` | `linarith` / `nlinarith`, with the multipliers | exact LP | **Farkas certificate**, solver-free |
152
+ | `compose` | Assemble lemmas into one proof, checking the join | Z3 | **proof**: every lemma, its certificate, and the link |
153
+ | `induct` | Base cases + a step, and the check that the chain joins | Z3 | **induction**: both halves, and the two numbers that matter |
154
+ | `synth` | CEGIS: ∃obj ∀input ∃aux | CEGIS/Z3 | object + the counterexamples that forced it |
155
+ | `opt` | LP/ILP, or a packing | CBC | **dual in exact rationals** = the load certificate |
156
+ | `mixed` | A discrete skeleton searched, the continuous part certified | CBC + exact LP | **mixed design**: assignment, exact dual, and a bound |
157
+ | `order` | The exponent of `n` once magnitudes are substituted: decays, or Θ(1)? | exact Laurent | **the exponent**, solver-free |
158
+ | `bounds` | A numeric inequality, rigorously (`e`, `log`, `π`, `ζ`) | Arb or mpmath | **enclosure in exact rationals** |
159
+ | `ideal` | Polynomial systems: refute them, or certify what follows | Gröbner, ours | **cofactors**, checked by expanding |
160
+ | `eliminate` | Remove a variable from two polynomials; keep the condition on the rest | Sylvester + Bareiss | **Res = A·f + B·g**, solver-free |
161
+ | `parametric` | A bound for EVERY value of a parameter, from a dual you already have | weak duality, symbolic | **y and the shifted residuals**, solver-free |
162
+ | `peak` | The best INTEGER choice for a family of concave quadratics, and the value there | exact, no search | **the maximiser and two step inequalities**, solver-free |
163
+ | `reduce` | "By symmetry": the three hypotheses of the averaging argument, checked | exact, no search | **generators, orbits and the quotient**, solver-free |
164
+ | `matrix` | Exact integer linear algebra: rank, determinant, Hermite and Smith | unimodular transforms | **U, V and their inverses**, checked by multiplication, solver-free |
165
+ | `solve` | `A x = b` exactly, over ℚ or ℤ | exact elimination, Smith | **the solution and the system**, one product to check; an obstruction when there is none |
166
+ | `quotient` | A partition of a program, and the equivalence it induces | exact counting | **the class data and both regularities**, solver-free |
167
+ | `cone` | Local toric data: primitivity, multiplicity, the height functional, discrepancies | exact det and solve | **the numbers two geometric theorems consume**, solver-free |
168
+ | `family` | The largest of ten thousand linear programs, and why nothing beats it | exact LP | **the winner and a dual for the rest**, solver-free |
169
+ | `ratio` | A fraction inequality for EVERY n | exact polynomials | **the cleared numerator and the sign of the denominator**, solver-free |
170
+ | `moment` | Is the expected number of bad events below one, so a good object exists? | exact rationals | **the moment and the mass it leaves over**, solver-free |
171
+ | `entry` | Where a sequence first crosses a line, and by how little | exact rationals | **the prefix and the two terms that bracket it**, solver-free |
172
+ | `exists` | Does one exist at all, and the refutation when it does not | own CDCL | model, or DRAT proof |
173
+ | `cover` | Is this an exact cover? A clique partition is one case | counting | **the universe and the parts**, solver-free |
174
+ | `sos` | A polynomial is non-negative, as a sum of squares | numeric + exact rounding | **rational squares**, solver-free |
175
+ | `number` | Primality, or a factorisation | Pratt | **modular-exponentiation tree** |
176
+ | `cases` | SAT with a verified DRAT proof | own CDCL or external binary | DRAT proof |
177
+ | `enum` | Non-isomorphic graphs with filters | nauty or Python | canonical list + hash |
178
+ | `sweep` | Predicate and/or value over a family or ANY finite domain | nauty or Python | family **+ predicate certificates** |
179
+ | `shrink` | Minimise a counterexample (graph or MUS) | CDCL / reduction | minimality witness |
180
+ | `bisect` | A constant's threshold | prove or cases | the pair that brackets it |
181
+ | `range` | The admissible interval of one variable over the regime, not one point of it | exact LP dual | **a Farkas combination at each end**, solver-free |
182
+ | `cycle` | A parameter that depends on itself: compose the growth classes and close the loop | growth ladder | **the chain, its classes and the one comparison**, solver-free |
183
+ | `bind` | Tie a certificate to the Lean declaration meant to justify it, and check it does | Z3 entailment | **the hypothesis, the statement, and whether one covers the other** |
184
+ | `lint` | Check a spec before spending the compute on it | — | — |
185
+ | `status` | Where a proof stands: proved, owed, hollow, stale | — | — |
186
+ | `doctor` | What this install can do, and what each gap costs | — | — |
187
+ | `ask` | One entry point: load a spec and run whatever it asks for (`what` is the same command) | — | whatever the command produces |
188
+ | `commands` | Which command answers which question | — | — |
189
+ | `repro` | Bundle spec, certificates, versions and hashes for a referee | — | the bundle |
190
+ | `verify` | Re-verify a stored certificate | — | — |
191
+ | `export` | Spec to SMT-LIB2/DIMACS, or a linear Farkas certificate to Lean | — | — |
192
+ | `ledger` | Audit log of what was run | — | — |
193
+
194
+ Common options, **after** the subcommand: `--json`, `--cert FILE`, `--lang`,
195
+ `--timeout-ms`, `--rlimit`, `--max-memory-mb`, `--seed`.
196
+
197
+ Exit codes: `0` conclusive, `2` inconclusive, `1` invalid certificate,
198
+ `3` error.
199
+
200
+ ## What it does not do
201
+
202
+ The hard limit is **asymptotic statements with quantifiers over `n`**. "There
203
+ exists `N` such that for every `n ≥ N`, every graph…, the loss is `≤ εn²`" is
204
+ not decided by this tool.
205
+
206
+ | Question | `certo`? |
207
+ |---|---|
208
+ | Is R(3,3) ≤ 6? | **Yes.** `cases`, a 23-line DRAT proof, verified |
209
+ | Is R(3,3) = 6? | **Yes.** `bisect`, threshold certified on both sides |
210
+ | Is R(5,5) ≤ 48? | **Not in practice.** Finite, but the space is 2^903 |
211
+ | Does R(k,k)^(1/k) converge? | **No, in principle.** Asymptotic: not expressible |
212
+
213
+ The full list, and the FAQ, in [`docs/LIMITS.md`](docs/LIMITS.md).
214
+
215
+ ## MCP server
216
+
217
+ Every command exposed to the LLM, with no copy-pasting. The project ships a
218
+ ready [`.mcp.json`](.mcp.json); to register it by hand in Claude Code:
219
+
220
+ ```bash
221
+ claude mcp add certo --env CERTO_WORKSPACE=. -- certo-mcp
222
+ ```
223
+
224
+ `CERTO_WORKSPACE` (the current directory by default) holds `specs/` and
225
+ `certs/`. **Every path is confined there.**
226
+
227
+ Three design decisions:
228
+
229
+ 1. **Certificates do not come back in the response.** A MUS takes 18× more on
230
+ disk than the whole response, and the model cannot verify it by reading it.
231
+ They are written to disk and the path, kind and digest come back.
232
+ 2. **Errors come back as data, not as exceptions.** The SDK turns any
233
+ exception into `Error executing tool X` and swallows the reason; a model
234
+ reading that cannot fix its spec. Here it gets what happened and what to
235
+ correct.
236
+ 3. **`dsl_guide` first.** Both a tool and a resource (`certo://dsl`).
237
+
238
+ > **Specs are Python code and they get executed when loaded.** That is
239
+ > inherent to the DSL and it is the same level of trust an agent with file
240
+ > access already has. The server confines paths, but it **is not a sandbox**:
241
+ > do not point it at third-party specs.
242
+
243
+ `certo doctor --register-mcp` adds certo to `.mcp.json` in the current
244
+ directory, **merging** with whatever is already registered rather than
245
+ replacing it, refusing to touch a file that is not valid JSON, and checking
246
+ that the server actually starts — a different question from whether it is
247
+ registered, and the one people mean.
248
+
249
+ ## Languages
250
+
251
+ English is the default and the source of truth. Spanish ships as an overlay:
252
+
253
+ ```bash
254
+ certo core examples/amgm.py --lang es # or CERTO_LANG=es
255
+ ```
256
+
257
+ Translations live in [`src/certo/locales/`](src/certo/locales/) as JSON. A
258
+ missing key falls back to English, so a partial translation degrades instead
259
+ of breaking. To add a language, copy `en.json`, translate the values and keep
260
+ the `{placeholders}` — there is a test that enforces both invariants.
261
+
262
+ Two things deliberately stay English whatever `--lang` says, because they are
263
+ API surface rather than prose: **command names and flags**, and **MCP tool
264
+ names and descriptions**. Certificates store note **keys**, not rendered text,
265
+ so one issued in Spanish reads correctly for an English reader.
266
+
267
+ ## Tests
268
+
269
+ Over five hundred, no test framework required. The count is deliberately not
270
+ given exactly: the previous README said 253 when there were twice that, and a
271
+ number nobody recomputes goes stale.
272
+
273
+ ```bash
274
+ for t in smoke mcp i18n extras adversarial determinism; do python tests/test_$t.py; done
275
+ ```
276
+
277
+ `python tests/run_examples.py` runs all 65 example specs and verifies every
278
+ certificate they produce.
279
+
280
+ Release notes in [CHANGELOG.md](CHANGELOG.md); what is planned, blocked and
281
+ deliberately refused in [BACKLOG.md](BACKLOG.md).
282
+
283
+ ## Licence
284
+
285
+ MIT. The synthesis engine is a reimplementation of the CEGIS algorithm from
286
+ [marcelwa/CEGIS](https://github.com/marcelwa/CEGIS) (MIT), not of its code.