Repairing a Refuted Claim
From the refuted Pythagorean claim to candidate repairs with explicit semantic deltas: satisfiability checks, overfitting control, and trade-offs with no automatic winner.
Start from the claim refuted in Chapter 25:
pythagorean-all-triangles-2d@1.0.0
d²(B,C) = d²(A,B) + d²(A,C) for every three real points A, B, C
Its witness is $A=(0,0)$, $B=(1,0)$, $C=(1,1)$, with residual $-2$. The tempting move is to patch the claim until that witness stops being a counterexample. The engine tests three patches, and one of them is a fix in name only.
Given a claim already refuted by a validated counterexample (Chapter 5), the engine can record proposed repairs as new claims with an explicit record of what changed, test whether each repair’s premise can be satisfied, test a patch for overfitting, and compare the results as a set of trade-offs with no automatic winner. This chapter builds on the negative control of Chapter 25 and the kernel evidence of Chapter 20.
What the refutation says
The refutation is not just “false”. It says why:
- Narrow the assumptions. Require the cross term to vanish.
- Correct the conclusion. Put the cross term in.
- Make the hypothesis impossible. (The dishonest one.)
Repair is not delete-and-replace. The refuted claim stays in history; the diagnosis constrains the candidates; non-vacuity rejects the empty repair and a second witness rejects the overfitted one.
Three candidate repairs
All three are project-authored candidates. None of them repairs Euclid, Heath or any external publication.
| Candidate | Claim and version | Repair kind | Statement |
|---|---|---|---|
| A | pythagorean-coordinate-2d@1.0.0 |
assumption_narrowing |
Add orthogonality: $AB\cdot AC=0$ implies the original equality |
| B | squared-distance-decomposition-2d@1.0.0 |
conclusion_correction |
For all points, $d^2(B,C) = d^2(A,B) + d^2(A,C) - 2\,(AB\cdot AC)$ |
| C | pythagorean-vacuous-premise-2d@1.0.0 |
vacuous_premise |
If $0=1$, then the original equality |
Candidate A reuses the P6 modern claim unchanged. The repair work (the P7 phase) adds the orthogonality premise only in the proposal and its record of what changed, so the claim being cited is the same object P6 verified. A repair is a new claim version with a declared change; the original refuted claim stays in the history with its counterexample.
That record of the change (the semantic delta) says what actually moved. A leaves the bindings and the conclusion alone and adds a hypothesis. B leaves the hypotheses alone and changes the conclusion. C adds the hypothesis $0=1$, and the record marks the premise as vacuous.
Candidate B is the algebra of the diagnosis, stated as a theorem. Both kernels
prove it with ring:
theorem squaredDistanceDecomposition
(a_x a_y b_x b_y c_x c_y : ℝ) :
(c_x - b_x) ^ 2 + (c_y - b_y) ^ 2 =
(b_x - a_x) ^ 2 + (b_y - a_y) ^ 2
+ ((c_x - a_x) ^ 2 + (c_y - a_y) ^ 2)
- 2 * (((b_x - a_x) * (c_x - a_x))
+ ((b_y - a_y) * (c_y - a_y))) := by
ring
Candidate C is also a theorem. The Lean proof is two lines:
theorem pythagoreanVacuousImplication
(a_x a_y b_x b_y c_x c_y : ℝ)
(h : (0 : ℝ) = 1) :
(c_x - b_x) ^ 2 + (c_y - b_y) ^ 2 =
(b_x - a_x) ^ 2 + (b_y - a_y) ^ 2
+ ((c_x - a_x) ^ 2 + (c_y - a_y) ^ 2) := by
exfalso
exact zero_ne_one h
From a false hypothesis anything follows. The kernel is not wrong to accept this: the proposition is valid, and its validity is the problem.
Can the premise be satisfied?
Before a repair is eligible, the engine asks whether its premise can be satisfied at all.
| Candidate | Premise check | Result |
|---|---|---|
| A | Z3 finds a model; witness $A=(0,0)$, $B=(1,0)$, $C=(0,1)$, dot $0$, residual $0$ | satisfiable |
| B | No premise beyond the real domain; the seed witness satisfies the corrected identity (dot $1$, residual $0$) | not applicable |
| C | Z3: $0=1$ is unsat |
unsatisfiable |
Candidate C is recorded as rejected_vacuous. It has a kernel-accepted proof in
Lean and in Rocq, and its dossier even reads formal_statement_verified. The
repair evaluator still rejects it. Kernel acceptance is not repair
eligibility.
Does the patch only remove the known witness?
A different bad patch removes only the known counterexample. The claim
pythagorean-dot-not-one-overfit-2d requires $0 < (\text{dot}-1)^2$, which
excludes exactly the witness whose dot product is $1$. It sounds like progress.
The engine tries a second witness: $A=(0,0)$, $B=(1,0)$, $C=(2,1)$. Its dot
product is $2$, so the patch’s condition holds, and the original equality still
fails, with residual $-4$. The overfitting control is
rejected_by_counterexample, and Z3 re-evaluates it exactly.
This refutes that specific patch. It is not a proof that no exclusion patch can work, and the record says so.
No automatic winner
| Candidate | Premise | Non-vacuity | Eligibility |
|---|---|---|---|
| A | satisfiable | satisfied | mathematically_qualified_candidate |
| B | not applicable | satisfied | mathematically_qualified_candidate |
| C | unsatisfiable | failed | rejected_vacuous |
A and B are both mathematically qualified, and they are different kinds of
repair. A keeps the original conclusion and shrinks the domain; B keeps the
domain and changes the conclusion. Neither dominates. The engine’s comparison
record lists their properties side by side, and the decision is
not_decided: the selected candidate is null, and project, author and
publisher acceptance are all not_claimed. The record does not count proofs:
three proofs of B in different tools are not a reason to prefer B.
What this establishes
The chapter shows that a counterexample can be turned into a diagnosis, that a diagnosis can generate more than one repair, and that a check on the premise catches repairs the kernel cannot.
It does not show:
- that the repairs fix Euclid or Heath; the refuted claim here is a project-authored negative control;
- that A or B is better;
- that one satisfying witness makes a premise meaningful: being satisfiable is necessary, not sufficient;
- that the overfitting control generalizes to every exclusion patch;
- anything about searching for counterexamples. The repair starts from one hand-seeded witness. A real search campaign (finite search, symbolic families, certificates) is still to do.
A repair is a separate claim. Adopting A or B would not mean that the original author, a publisher or peer review approved anything, and the engine records no adoption. Credit for finding the defect (the validated counterexample) and for proposing repairs belongs in a contributor-credit record kept separate from correctness. The book’s conventions require one; this edition did not check what P7 stored.
The ring identities can be checked by expanding the squares, as
Chapter 25 does. Human review: not evaluated. No reviewer has
recorded checking the repair records or the overfitting control. The Lean and Rocq
statements for B and C are structurally_aligned with verified axiom baselines,
and cross-kernel semantic equivalence stays not_established.
Try it yourself
The repair commands are math-engine repair validate, repair build and
repair verify, each taking the plan at
experiments/repairs/pythagorean-negative-control/qualification-plan.json. (The
P7 record lists these subcommands; confirm the flags before relying on them.)
Seeded error. Change Candidate B’s cross-term factor from 2 to 1. Both
kernels should reject it, and Z3’s negation should become sat.
Exercise. Find another witness that defeats the overfitted patch, with $A=(0,0)$ and $B=(1,0)$. What is the residual? (Answer: any $C=(c_x,c_y)$ with $c_x\neq0$ and $c_x\neq1$; for example $C=(3,0)$ has dot product $3$ and residual $-6$.)
Open questions.
- Is there an exclusion patch that is not overfitted? What would distinguish it from A or B?
- Candidate C is an extreme case. What about a premise that is satisfiable, but only on a set of measure zero? The engine checks satisfiability, not usefulness.
- If a reader prefers A over B, what record should capture that preference without turning it into evidence?
Evidence record
| Tool | Candidate A | Candidate B | Candidate C | Overfit |
|---|---|---|---|---|
| SymPy 1.14.0 | exact witness, residual 0 |
corrected residual expands to 0 |
second witness residual −4 |
|
| Z3 5.3.1 | premise sat |
negated identity unsat |
premise unsat |
patched witness sat, residual −4 |
| Lean 4.35.0 | reuses P6 | accepted | accepted | |
| Rocq 9.0.1 | reuses P6 | accepted | accepted |
Axioms: B in Lean uses Classical.choice, Quot.sound and propext; in Rocq it
uses sig_forall_dec and functional_extensionality_dep. C in Rocq uses only
sig_forall_dec, one fewer than B. The P7 mathematical executions in the P2 phase
numbered 11 (3 SymPy, 4 Z3, 2 Lean, 2 Rocq); the dossiers, the kernel audits and
the notebook ran none.
The kernel statement audits are p7-kernel-statement-audit-fe475caf… for B and
…d8f09872… for C. The Lean header parser normalizes numeric type ascriptions
such as (0 : ℝ); the kernel-elaborated type remains authoritative.
Citation identifiers: P7 index
p7-qualification-index-51a24537bc3e8a8e18d463b8555406cfebf3c8eaba873c6cb36c5c8d7543b954;
canonical executed notebook
3d782d4ac399f86af44769f4e98276990d450003c7c486a4983d0f7a529639e0; target
reference p7-target-reference-2a16ae3f…; plan p7-repair-plan-0267d61f….
Post-merge main run 40470483277 succeeded, according to the P8 baseline
record. The local P7 record reports 360 passed, 1 skipped for the full suite and
27 passed for the P7 tests.
Sources
No literature is cited; prior work on non-vacuity checks and
counterexample-guided repair is not yet in the bibliography. In the repository:
formal/lean/PythagoreanRepair.lean and formal/rocq/PythagoreanRepair.v (kernel
proofs of B and C), and experiments/repairs/pythagorean-negative-control/
(claims, proposals, plans).