Problems / erdos-849 / spec-12191c69
spec-12191c69 Opn.erdos_849_rows_eq_pairs
proved
Proposed by a contributor.
theorem Opn.erdos_849_rows_eq_pairs : ∀ a : ℕ,
{n : ℕ | ∃ k ≥ 1, 2 * k ≤ n ∧ choose n k = a}.ncard =
{p : ℕ × ℕ | 1 ≤ p.2 ∧ 2 * p.2 ≤ p.1 ∧ choose p.1 p.2 = a}.ncard := by
sorryWhy does it end in sorry?
A statement is written := by sorry: the sorry holds the place of a proof, because a statement file only says what is claimed. A proof the gate checked is its own file, Proof.lean. How to read a proof page →
How it was proved
Proved by Proof.lean, checked by the kernel. Its attestation, 000989, records the gate’s run.
The proof step by step (outline)
Checked by the kernel — an outline of the attested proof below: attestations/000989.json, merge commit 4baed2f107c4.
Outline of Proof.lean, extracted by the gate at be99b4fba02b from the proof’s elaboration: each step is a claim the proof establishes and the goal it leaves. Open a step for what it uses and its Lean lines.
himghaveProd.fst '' {p : ℕ × ℕ | (1 : ℕ) ≤ p.2 ∧ (2 : ℕ) * p.2 ≤ p.1 ∧ p.1.choose p.2 = a} = {n : ℕ | ∃ k ≥ (1 : ℕ), (2 : ℕ) * k ≤ n ∧ n.choose k = a}Leaves
{n : ℕ | ∃ k ≥ (1 : ℕ), (2 : ℕ) * k ≤ n ∧ n.choose k = a}.ncard = {p : ℕ × ℕ | (1 : ℕ) ≤ p.2 ∧ (2 : ℕ) * p.2 ≤ p.1 ∧ p.1.choose p.2 = a}.ncard, withhimg : Prod.fst '' {p : ℕ × ℕ | (1 : ℕ) ≤ p.2 ∧ (2 : ℕ) * p.2 ≤ p.1 ∧ p.1.choose p.2 = a} = {n : ℕ | ∃ k ≥ (1 : ℕ), (2 : ℕ) * k ≤ n ∧ n.choose k = a}.Uses library
Prod.fstThe first element of a pair. ,Nat.choosechoose n kis the number ofk-element subsets in ann-element set. ,Set.mem_image,Set.mem_setOf_eqAlias ofSet.mem_ofPred_eq. ,Prod.exists.Lean, lines 43–51
have himg : (Prod.fst '' {p : ℕ × ℕ | 1 ≤ p.2 ∧ 2 * p.2 ≤ p.1 ∧ choose p.1 p.2 = a}) = {n : ℕ | ∃ k ≥ 1, 2 * k ≤ n ∧ choose n k = a} := by ext n simp only [Set.mem_image, Set.mem_setOf_eq, Prod.exists] constructor · rintro ⟨m, k, ⟨hk, hkm, hc⟩, rfl⟩ exact ⟨k, hk, hkm, hc⟩ · rintro ⟨k, hk, hkn, hc⟩ exact ⟨n, k, ⟨hk, hkn, hc⟩, rfl⟩targets/erdos-849/nodes/spec-12191c69/Proof.lean, lines 43–51 at
4baed2f107c4↗himg.s1caseLeaves
(∃ (a_1 : ℕ) (b : ℕ), ((1 : ℕ) ≤ b ∧ (2 : ℕ) * b ≤ a_1 ∧ a_1.choose b = a) ∧ a_1 = n) → ∃ k ≥ (1 : ℕ), (2 : ℕ) * k ≤ n ∧ n.choose k = a.Uses library
Exists.introExistential introduction. .Lean, lines 48–49
· rintro ⟨m, k, ⟨hk, hkm, hc⟩, rfl⟩ exact ⟨k, hk, hkm, hc⟩targets/erdos-849/nodes/spec-12191c69/Proof.lean, lines 48–49 at
4baed2f107c4↗himg.s2caseLeaves
(∃ k ≥ (1 : ℕ), (2 : ℕ) * k ≤ n ∧ n.choose k = a) → ∃ (a_2 : ℕ) (b : ℕ), ((1 : ℕ) ≤ b ∧ (2 : ℕ) * b ≤ a_2 ∧ a_2.choose b = a) ∧ a_2 = n.Uses library
Exists.introExistential introduction. ,And.introAnd.intro : a → b → a ∧ bis the constructor for the And operation. ,rflrfl : a = ais the unique constructor of the equality type. .Lean, lines 50–51
· rintro ⟨k, hk, hkn, hc⟩ exact ⟨n, k, ⟨hk, hkn, hc⟩, rfl⟩targets/erdos-849/nodes/spec-12191c69/Proof.lean, lines 50–51 at
4baed2f107c4↗
thishavek₁ = k₂Leaves
(n₁, k₁) = (n₁, k₂), withthis : k₁ = k₂.Lean, line 57
have := row_unique n₁ k₁ k₂ hkn₁ hkn₂ (hc₁.trans hc₂.symm)
targets/erdos-849/nodes/spec-12191c69/Proof.lean, line 57 at
4baed2f107c4↗closeterm(n₁, k₁) = (n₁, k₂)Closes the goal.
Lean, lines 58–59
subst this rfl
targets/erdos-849/nodes/spec-12191c69/Proof.lean, lines 58–59 at
4baed2f107c4↗
The proof in Lean (Proof.lean)
Checked by the kernel — these bytes are the ones its attestation names: attestations/000989.json, merge commit 4baed2f107c4.
artifact_hash of the attestation below, so these are the bytes the gate checked. Rendered from targets/erdos-849/nodes/spec-12191c69/Proof.lean, sha256 9f2af1075f5c.import Mathlib
import Nodes.«spec-12191c69».Context
open Nat
private theorem step_lt (n k : ℕ) (h : 2 * (k + 1) ≤ n) : choose n k < choose n (k + 1) := by
have e := Nat.choose_succ_right_eq n k
have hp : 0 < choose n k := Nat.choose_pos (by omega)
have hk : k + 1 < n - k := by omega
by_contra hc
push_neg at hc
have : choose n k * (n - k) ≤ choose n k * (k + 1) := by
calc choose n k * (n - k) = choose n (k + 1) * (k + 1) := e.symm
_ ≤ choose n k * (k + 1) := Nat.mul_le_mul_right _ hc
have := Nat.le_of_mul_le_mul_left this hp
omega
private theorem mono_lt (n : ℕ) : ∀ j i : ℕ, i < j → 2 * j ≤ n → choose n i < choose n j := by
intro j
induction j with
| zero => intro i h; omega
| succ j ih =>
intro i hij hj
have hs := step_lt n j hj
rcases Nat.lt_succ_iff_lt_or_eq.mp hij with h | h
· exact lt_trans (ih i h (by omega)) hs
· subst h; exact hs
private theorem row_unique (n k₁ k₂ : ℕ) (h₁ : 2 * k₁ ≤ n) (h₂ : 2 * k₂ ≤ n)
(h : choose n k₁ = choose n k₂) : k₁ = k₂ := by
rcases lt_trichotomy k₁ k₂ with hl | he | hg
· have := mono_lt n k₂ k₁ hl h₂; omega
· exact he
· have := mono_lt n k₁ k₂ hg h₁; omega
/-- Erdős 849, structure: the root counts rows `n`; the problem counts solutions `(n, k)`.
For every `a` the two counts agree, because `C(n, ·)` is strictly increasing on
`0 ≤ k ≤ n/2`, so a row holds the value `a` at most once in that range. -/
theorem Opn.erdos_849_rows_eq_pairs : ∀ a : ℕ,
{n : ℕ | ∃ k ≥ 1, 2 * k ≤ n ∧ choose n k = a}.ncard =
{p : ℕ × ℕ | 1 ≤ p.2 ∧ 2 * p.2 ≤ p.1 ∧ choose p.1 p.2 = a}.ncard := by
intro a
have himg : (Prod.fst '' {p : ℕ × ℕ | 1 ≤ p.2 ∧ 2 * p.2 ≤ p.1 ∧ choose p.1 p.2 = a}) =
{n : ℕ | ∃ k ≥ 1, 2 * k ≤ n ∧ choose n k = a} := by
ext n
simp only [Set.mem_image, Set.mem_setOf_eq, Prod.exists]
constructor
· rintro ⟨m, k, ⟨hk, hkm, hc⟩, rfl⟩
exact ⟨k, hk, hkm, hc⟩
· rintro ⟨k, hk, hkn, hc⟩
exact ⟨n, k, ⟨hk, hkn, hc⟩, rfl⟩
rw [← himg]
apply Set.ncard_image_of_injOn
rintro ⟨n₁, k₁⟩ ⟨hk₁, hkn₁, hc₁⟩ ⟨n₂, k₂⟩ ⟨hk₂, hkn₂, hc₂⟩ hn
simp only at hn hk₁ hkn₁ hc₁ hk₂ hkn₂ hc₂
subst hn
have := row_unique n₁ k₁ k₂ hkn₁ hkn₂ (hc₁.trans hc₂.symm)
subst this
rflWhat is known
Work on it
No explainer yet. This proof written as a journal would print it, labelled unverified, is the next thing a writer could add, by pull request (D-3, D-36; the guide shows how).
How to contribute → · Pull requests in flight ↗ · See it in the problem’s graph →
Record
Statement: the Lean file and no words yet
Statement not audited — only a problem’s root statement is audited for fidelity (D-9); the kernel checks a proof against this Lean as written.
import Mathlib
import Nodes.«spec-12191c69».Context
open Nat
/-- Erdős 849, structure: the root counts rows `n`; the problem counts solutions `(n, k)`.
For every `a` the two counts agree, because `C(n, ·)` is strictly increasing on
`0 ≤ k ≤ n/2`, so a row holds the value `a` at most once in that range. -/
theorem Opn.erdos_849_rows_eq_pairs : ∀ a : ℕ,
{n : ℕ | ∃ k ≥ 1, 2 * k ≤ n ∧ choose n k = a}.ncard =
{p : ℕ × ℕ | 1 ≤ p.2 ∧ 2 * p.2 ≤ p.1 ∧ choose p.1 p.2 = a}.ncard := by
sorryA statement is written := by sorry: the sorry holds the place of a proof, because a statement file only says what is claimed. A proof the gate checked is its own file, Proof.lean. How to read a proof page →
No gloss yet: no one has written in words what this statement says (D-3 v3.30); the Lean above is the statement. How to write one →
Rendered from targets/erdos-849/nodes/spec-12191c69/Statement.lean. Origin: authored.
Attestation: pass, 7 of 7 checks
Checked by the kernel — the gate’s record of the run: attestations/000989.json, merge commit 4baed2f107c4.
Verdict pass, from attestations/000989.json.
- Submitter
t1026e-c- Toolchain
- leanprover/lean4:v4.33.1 (hash
f54d0bc916bf76a7fae460ce9d078ccd1f74aeb4fd12c4b6546bca28b6aa1c63) - Mathlib
- 0df444a360eaa60ab8c11dca51a86af692955474
- Reviewer
- none needed (intermediate)
| Step | Check | Result |
|---|---|---|
| 1 | toolchain | pass |
| 2 | paths | pass |
| 4 | kernel-replay | pass |
| 5 | axioms | pass |
| 6 | hazards | pass |
| 7 | witness | pass |
| 8 | deps | pass |
Witness
Checked by the kernel — step 7 passed in the run its attestation records: attestations/000989.json, merge commit 4baed2f107c4.
44993bed5e4a.theorem witness : ∃ a : ℕ, True := ⟨0, trivial⟩
No gloss yet: no one has written in words what this witness says (D-3 v3.30); the Lean above is the witness. How to write one →
Acknowledged findings (2)
Untrusted contributor text — the prover’s justification for a finding.
Untrusted: acknowledgment of a off-by-one-range finding at k ≥ 1
Deliberate, as in the root: k = 0 would count the trivial C(n, 0) = 1, which the problem excludes.
Untrusted contributor text — the prover’s justification for a finding.
Untrusted: acknowledgment of a off-by-one-range finding at 1 ≤ p.2
Deliberate: the same range 1 ≤ k as the root, now on the pair (n, k) = (p.1, p.2).