Open Proof Network

Problems / erdos-402 / variant-6bb50ad7

Graham's bound for |A| = 8

variant-6bb50ad7

proved

A partial route to the problem.

$\displaystyle \forall A \subset \mathbb{N}\ \text{finite}:\ 0 \notin A,\ |A| = 8 \Rightarrow \exists\, a, b \in A:\ \gcd(a,b) \le \frac{a}{|A|}$

Every set A of exactly eight positive integers has a, b ∈ A (possibly equal) with gcd(a, b) ≤ a/|A|. The division is in ℚ.

unverified · history

Lean
theorem Opn.erdos_402_card_eight :
    ∀ (A : Finset ℕ), 0 ∉ A → A.card = 8 → ∃ a ∈ A, ∃ b ∈ A, a.gcd b ≤ (a / A.card : ℚ) := by
  sorry
Why 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, 000218, records the gate’s run.

The proof step by step (outline)

Checked by the kernel — an outline of the attested proof below: attestations/000218.json, merge commit b9e7eed20f11.

Outline of Proof.lean, extracted by the gate at 82834c4684b8 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.

  1. hpos have (0 : ℕ) < A.card routine: omega

    Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ), with hpos : (0 : ℕ) < A.card.

    Lean, line 12
      have hpos : 0 < A.card := by omega

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 12 at b9e7eed20f11 ↗

  2. hne have A.Nonempty

    Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ), with hne : A.Nonempty.

    Uses library Finset.card_pos.

    Lean, line 13
      have hne : A.Nonempty := Finset.card_pos.mp hpos

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 13 at b9e7eed20f11 ↗

  3. key have ∀ (a b : ℕ), a.gcd b * A.card ≤ a → (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ)

    Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ), with key : ∀ (a b : ℕ), a.gcd b * A.card ≤ a → (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ).

    Uses library le_div_iff₀ See le_div_iff₀' for a version with multiplication on the other side. .

    Lean, lines 14–17
      have key : ∀ a b : ℕ, a.gcd b * A.card ≤ a → (a.gcd b : ℚ) ≤ (a / A.card : ℚ) := by
        intro a b h
        rw [le_div_iff₀ (by exact_mod_cast hpos)]
        exact_mod_cast h

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, lines 14–17 at b9e7eed20f11 ↗

  4. hM have A.max' hne ∈ A

    Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ), with hM : A.max' hne ∈ A.

    Uses library Finset.max'_mem.

    Lean, line 18
      have hM : A.max' hne ∈ A := Finset.max'_mem A hne

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 18 at b9e7eed20f11 ↗

  5. hMpos have (0 : ℕ) < A.max' hne

    Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ), with hMpos : (0 : ℕ) < A.max' hne.

    Uses library Nat.pos_of_ne_zero.

    Lean, line 19
      have hMpos : 0 < A.max' hne := Nat.pos_of_ne_zero (fun h => hA (h ▸ hM))

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 19 at b9e7eed20f11 ↗

  6. s6 case

    Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ).

    Uses library Exists.intro Existential introduction. .

    Lean, lines 21–22
      · obtain ⟨x, hx, h⟩ := hw
        exact ⟨_, hM, x, hx, key _ x (by rw [hn]; exact h)⟩

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, lines 21–22 at b9e7eed20f11 ↗

    1. s6.s1 obtain ∃ x ∈ A, (A.max' hne).gcd x * (8 : ℕ) ≤ A.max' hne

      Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ), with x : ℕ, hx : x ∈ A, h : (A.max' hne).gcd x * (8 : ℕ) ≤ A.max' hne.

      Lean, line 21
        · obtain ⟨x, hx, h⟩ := hw

      targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 21 at b9e7eed20f11 ↗

  7. forms have printed form did not read back: shown as its Lean lines only
      have forms : ∀ x ∈ A.erase (A.max' hne), ∃ a ∈ ({60, 70, 84, 105, 120, 140, 168, 180, 210, 240, 252, 280, 300, 315, 336, 350, 360} : Finset ℕ), 420 * x = a * A.max' hne := by
        intro x hx
        rw [Finset.mem_erase] at hx
        have hxpos : 0 < x := Nat.pos_of_ne_zero (fun h => hA (h ▸ hx.2))
        have hlt : x < A.max' hne := lt_of_le_of_ne (Finset.le_max' A x hx.2) hx.1
        have hg := hw x hx.2
        obtain ⟨k, hk⟩ := Nat.gcd_dvd_left (A.max' hne) x
        obtain ⟨j, hj⟩ := Nat.gcd_dvd_right (A.max' hne) x
        have hgpos : 0 < (A.max' hne).gcd x := Nat.gcd_pos_of_pos_right _ hxpos
        have hkN : k < 8 := by
          by_contra hh
          push_neg at hh
          have := Nat.mul_le_mul_left ((A.max' hne).gcd x) hh
          omega
        have hjk : j < k := by
          by_contra hh
          push_neg at hh
          have := Nat.mul_le_mul_left ((A.max' hne).gcd x) hh
          omega
        have hj1 : 1 ≤ j := by
          rcases Nat.eq_zero_or_pos j with h | h
          · subst h
            omega
          · exact h
        refine ⟨420 * j / k, ?_, ?_⟩
        · interval_cases k <;> interval_cases j <;> decide
        · interval_cases k <;> interval_cases j <;> omega

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, lines 24–50 at b9e7eed20f11 ↗

    1. forms.hxpos have printed form did not read back: shown as its Lean lines only
          have hxpos : 0 < x := Nat.pos_of_ne_zero (fun h => hA (h ▸ hx.2))

      targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 27 at b9e7eed20f11 ↗

    2. forms.hlt have printed form did not read back: shown as its Lean lines only
          have hlt : x < A.max' hne := lt_of_le_of_ne (Finset.le_max' A x hx.2) hx.1

      targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 28 at b9e7eed20f11 ↗

    3. forms.hg have printed form did not read back: shown as its Lean lines only
    4. forms.s4 obtain printed form did not read back: shown as its Lean lines only
          obtain ⟨k, hk⟩ := Nat.gcd_dvd_left (A.max' hne) x

      targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 30 at b9e7eed20f11 ↗

    5. forms.s5 obtain printed form did not read back: shown as its Lean lines only
          obtain ⟨j, hj⟩ := Nat.gcd_dvd_right (A.max' hne) x

      targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 31 at b9e7eed20f11 ↗

    6. forms.hgpos have printed form did not read back: shown as its Lean lines only
          have hgpos : 0 < (A.max' hne).gcd x := Nat.gcd_pos_of_pos_right _ hxpos

      targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 32 at b9e7eed20f11 ↗

    7. forms.hkN have printed form did not read back: shown as its Lean lines only
          have hkN : k < 8 := by
            by_contra hh
            push_neg at hh
            have := Nat.mul_le_mul_left ((A.max' hne).gcd x) hh
            omega

      targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, lines 33–37 at b9e7eed20f11 ↗

      1. forms.hkN.this have (A.max' hne).gcd x * (8 : ℕ) ≤ (A.max' hne).gcd x * k

        Leaves False, with this : (A.max' hne).gcd x * (8 : ℕ) ≤ (A.max' hne).gcd x * k.

        Uses library Nat.mul_le_mul_left.

        Lean, line 36
              have := Nat.mul_le_mul_left ((A.max' hne).gcd x) hh

        targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 36 at b9e7eed20f11 ↗

    8. forms.hjk have printed form did not read back: shown as its Lean lines only
          have hjk : j < k := by
            by_contra hh
            push_neg at hh
            have := Nat.mul_le_mul_left ((A.max' hne).gcd x) hh
            omega

      targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, lines 38–42 at b9e7eed20f11 ↗

      1. forms.hjk.this have (A.max' hne).gcd x * k ≤ (A.max' hne).gcd x * j

        Leaves False, with this : (A.max' hne).gcd x * k ≤ (A.max' hne).gcd x * j.

        Uses library Nat.mul_le_mul_left.

        Lean, line 41
              have := Nat.mul_le_mul_left ((A.max' hne).gcd x) hh

        targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 41 at b9e7eed20f11 ↗

    9. forms.hj1 have printed form did not read back: shown as its Lean lines only
          have hj1 : 1 ≤ j := by
            rcases Nat.eq_zero_or_pos j with h | h
            · subst h
              omega
            · exact h

      targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, lines 43–47 at b9e7eed20f11 ↗

      1. forms.hj1.s1 case

        Leaves (1 : ℕ) ≤ j.

        Lean, lines 45–46
              · subst h
                omega

        targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, lines 45–46 at b9e7eed20f11 ↗

      2. forms.hj1.s2 case
    10. forms.s10 case printed form did not read back: shown as its Lean lines only
    11. forms.s11 case

      Leaves (420 : ℕ) * x = (420 : ℕ) * j / k * A.max' hne.

      Lean, line 50
          · interval_cases k <;> interval_cases j <;> omega

      targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 50 at b9e7eed20f11 ↗

  8. hcard have (A.erase (A.max' hne)).card = (7 : ℕ)

    Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ), with hcard : (A.erase (A.max' hne)).card = (7 : ℕ).

    Uses library Finset.card_erase_of_mem $\#(s \setminus \{a\}) = \#s - 1$ if $a \in s$. .

    Lean, lines 51–52
      have hcard : (A.erase (A.max' hne)).card = 7 := by
        rw [Finset.card_erase_of_mem hM, hn]

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, lines 51–52 at b9e7eed20f11 ↗

  9. hS have printed form did not read back: shown as its Lean lines only
      have hS : ∀ a ∈ ({60, 70, 84, 105, 120, 140, 168, 180, 210, 240, 252, 280, 300, 315, 336, 350, 360} : Finset ℕ), (fun a : ℕ => if a = 60 then 0 else if a = 70 then 1 else if a = 84 then 2 else if a = 105 then 3 else if a = 120 then 1 else if a = 140 then 4 else if a = 168 then 0 else if a = 180 then 2 else if a = 210 then 5 else if a = 240 then 3 else if a = 252 then 1 else if a = 280 then 2 else if a = 300 then 4 else if a = 315 then 0 else if a = 336 then 4 else if a = 350 then 0 else if a = 360 then 5 else 0) a < 6 := by decide

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 53 at b9e7eed20f11 ↗

  10. hmaps have ∀ x ∈ A.erase (A.max' hne), (fun (a : ℕ) => if a = (60 : ℕ) then (0 : ℕ) else if a = (70 : ℕ) then (1 : ℕ) else if a = (84 : ℕ) then (2 : ℕ) else if a = (105 : ℕ) then (3 : ℕ) else if a = (120 : ℕ) then (1 : ℕ) else if a = (140 : ℕ) then (4 : ℕ) else if a = (168 : ℕ) then (0 : ℕ) else if a = (180 : ℕ) then (2 : ℕ) else if a = (210 : ℕ) then (5 : ℕ) else if a = (240 : ℕ) then (3 : ℕ) else if a = (252 : ℕ) then (1 : ℕ) else if a = (280 : ℕ) then (2 : ℕ) else if a = (300 : ℕ) then (4 : ℕ) else if a = (315 : ℕ) then (0 : ℕ) else if a = (336 : ℕ) then (4 : ℕ) else if a = (350 : ℕ) then (0 : ℕ) else if a = (360 : ℕ) then (5 : ℕ) else (0 : ℕ)) ((420 : ℕ) * x / A.max' hne) ∈ Finset.range (6 : ℕ)

    Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ), with hmaps : ∀ x ∈ A.erase (A.max' hne), (fun (a : ℕ) => if a = (60 : ℕ) then (0 : ℕ) else if a = (70 : ℕ) then (1 : ℕ) else if a = (84 : ℕ) then (2 : ℕ) else if a = (105 : ℕ) then (3 : ℕ) else if a = (120 : ℕ) then (1 : ℕ) else if a = (140 : ℕ) then (4 : ℕ) else if a = (168 : ℕ) then (0 : ℕ) else if a = (180 : ℕ) then (2 : ℕ) else if a = (210 : ℕ) then (5 : ℕ) else if a = (240 : ℕ) then (3 : ℕ) else if a = (252 : ℕ) then (1 : ℕ) else if a = (280 : ℕ) then (2 : ℕ) else if a = (300 : ℕ) then (4 : ℕ) else if a = (315 : ℕ) then (0 : ℕ) else if a = (336 : ℕ) then (4 : ℕ) else if a = (350 : ℕ) then (0 : ℕ) else if a = (360 : ℕ) then (5 : ℕ) else (0 : ℕ)) ((420 : ℕ) * x / A.max' hne) ∈ Finset.range (6 : ℕ).

    Uses library Finset.range range n is the set of natural numbers less than n. , Finset.mem_range, Nat.mul_div_cancel.

    Lean, lines 54–58
      have hmaps : ∀ x ∈ A.erase (A.max' hne), (fun a : ℕ => if a = 60 then 0 else if a = 70 then 1 else if a = 84 then 2 else if a = 105 then 3 else if a = 120 then 1 else if a = 140 then 4 else if a = 168 then 0 else if a = 180 then 2 else if a = 210 then 5 else if a = 240 then 3 else if a = 252 then 1 else if a = 280 then 2 else if a = 300 then 4 else if a = 315 then 0 else if a = 336 then 4 else if a = 350 then 0 else if a = 360 then 5 else 0) (420 * x / A.max' hne) ∈ Finset.range 6 := by
        intro x hx
        obtain ⟨a, ha, hax⟩ := forms x hx
        rw [Finset.mem_range, hax, Nat.mul_div_cancel _ hMpos]
        exact hS a ha

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, lines 54–58 at b9e7eed20f11 ↗

    1. hmaps.s1 obtain printed form did not read back: shown as its Lean lines only
  11. s11 obtain ∃ x ∈ A.erase (A.max' hne), ∃ y ∈ A.erase (A.max' hne), x ≠ y ∧ (fun (a : ℕ) => if a = (60 : ℕ) then (0 : ℕ) else if a = (70 : ℕ) then (1 : ℕ) else if a = (84 : ℕ) then (2 : ℕ) else if a = (105 : ℕ) then (3 : ℕ) else if a = (120 : ℕ) then (1 : ℕ) else if a = (140 : ℕ) then (4 : ℕ) else if a = (168 : ℕ) then (0 : ℕ) else if a = (180 : ℕ) then (2 : ℕ) else if a = (210 : ℕ) then (5 : ℕ) else if a = (240 : ℕ) then (3 : ℕ) else if a = (252 : ℕ) then (1 : ℕ) else if a = (280 : ℕ) then (2 : ℕ) else if a = (300 : ℕ) then (4 : ℕ) else if a = (315 : ℕ) then (0 : ℕ) else if a = (336 : ℕ) then (4 : ℕ) else if a = (350 : ℕ) then (0 : ℕ) else if a = (360 : ℕ) then (5 : ℕ) else (0 : ℕ)) ((420 : ℕ) * x / A.max' hne) = (fun (a : ℕ) => if a = (60 : ℕ) then (0 : ℕ) else if a = (70 : ℕ) then (1 : ℕ) else if a = (84 : ℕ) then (2 : ℕ) else if a = (105 : ℕ) then (3 : ℕ) else if a = (120 : ℕ) then (1 : ℕ) else if a = (140 : ℕ) then (4 : ℕ) else (truncated)

    Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ), with x : ℕ, hx : x ∈ A.erase (A.max' hne), y : ℕ, hy : y ∈ A.erase (A.max' hne), hxy : x ≠ y, hc : (fun (a : ℕ) => if a = (60 : ℕ) then (0 : ℕ) else if a = (70 : ℕ) then (1 : ℕ) else if a = (84 : ℕ) then (2 : ℕ) else if a = (105 : ℕ) then (3 : ℕ) else if a = (120 : ℕ) then (1 : ℕ) else if a = (140 : ℕ) then (4 : ℕ) else if a = (168 : ℕ) then (0 : ℕ) else if a = (180 : ℕ) then (2 : ℕ) else if a = (210 : ℕ) then (5 : ℕ) else if a = (240 : ℕ) then (3 : ℕ) else if a = (252 : ℕ) then (1 : ℕ) else if a = (280 : ℕ) then (2 : ℕ) else if a = (300 : ℕ) then (4 : ℕ) else if a = (315 : ℕ) then (0 : ℕ) else if a = (336 : ℕ) then (4 : ℕ) else if a = (350 : ℕ) then (0 : ℕ) else if a = (360 : ℕ) then (5 : ℕ) else (0 : ℕ)) ((420 : ℕ) * x / A.max' hne) = (fun (a : ℕ) => if a = (60 : ℕ) then (0 : ℕ) else if a = (70 : ℕ) then (1 : ℕ) else if a = (84 : ℕ) then (2 : ℕ) else if a = (105 : ℕ) then (3 : ℕ) else if a = (120 : ℕ) then (1 : ℕ) else if a = (140 : ℕ) then (4 : ℕ) else if a = (168 : ℕ) then (0 : ℕ) else if a = (180 : ℕ) then (2 : ℕ) else if a = (210 : ℕ) then (5 : ℕ) else if a = (240 : ℕ) then (3 : ℕ) else if a = (252 : ℕ) then (1 : ℕ) e (truncated).

    Uses library Finset.exists_ne_map_eq_of_card_lt_of_maps_to If there are more pigeons than pigeonholes, then there are two pigeons in the same pigeonhole. , Finset.card_range.

    Lean, lines 59–60
      obtain ⟨x, hx, y, hy, hxy, hc⟩ :=
        Finset.exists_ne_map_eq_of_card_lt_of_maps_to (by rw [hcard, Finset.card_range]; norm_num) hmaps

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, lines 59–60 at b9e7eed20f11 ↗

  12. s12 obtain printed form did not read back: shown as its Lean lines only
  13. s13 obtain printed form did not read back: shown as its Lean lines only
  14. hab have a ≠ b

    Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ), with hab : a ≠ b.

    Lean, lines 64–68
      have hab : a ≠ b := by
        intro h
        subst h
        apply hxy
        omega

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, lines 64–68 at b9e7eed20f11 ↗

  15. hpair have printed form did not read back: shown as its Lean lines only
      have hpair : ∀ a ∈ ({60, 70, 84, 105, 120, 140, 168, 180, 210, 240, 252, 280, 300, 315, 336, 350, 360} : Finset ℕ), ∀ b ∈ ({60, 70, 84, 105, 120, 140, 168, 180, 210, 240, 252, 280, 300, 315, 336, 350, 360} : Finset ℕ), a ≠ b → (fun a : ℕ => if a = 60 then 0 else if a = 70 then 1 else if a = 84 then 2 else if a = 105 then 3 else if a = 120 then 1 else if a = 140 then 4 else if a = 168 then 0 else if a = 180 then 2 else if a = 210 then 5 else if a = 240 then 3 else if a = 252 then 1 else if a = 280 then 2 else if a = 300 then 4 else if a = 315 then 0 else if a = 336 then 4 else if a = 350 then 0 else if a = 360 then 5 else 0) a = (fun a : ℕ => if a = 60 then 0 else if a = 70 then 1 else if a = 84 then 2 else if a = 105 then 3 else if a = 120 then 1 else if a = 140 then 4 else if a = 168 then 0 else if a = 180 then 2 else if a = 210 then 5 else if a = 240 then 3 else if a = 252 then 1 else if a = 280 then 2 else if a = 300 then 4 else if a = 315 then 0 else if a = 336 then 4 else if a = 350 then 0 else if a = 360 then 5 else 0) b →
          8 * a.gcd b ≤ a ∨ 8 * a.gcd b ≤ b := by decide

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, lines 69–70 at b9e7eed20f11 ↗

  16. hgcd have a.gcd b * A.max' hne = (420 : ℕ) * x.gcd y

    Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ), with hgcd : a.gcd b * A.max' hne = (420 : ℕ) * x.gcd y.

    Uses library Nat.gcd_mul_right.

    Lean, lines 71–74
      have hgcd : a.gcd b * A.max' hne = 420 * x.gcd y := by
        have h1 : Nat.gcd (420 * x) (420 * y) = 420 * x.gcd y := Nat.gcd_mul_left 420 x y
        rw [hax, hby, Nat.gcd_mul_right] at h1
        exact h1

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, lines 71–74 at b9e7eed20f11 ↗

    1. hgcd.h1 have ((420 : ℕ) * x).gcd ((420 : ℕ) * y) = (420 : ℕ) * x.gcd y

      Leaves a.gcd b * A.max' hne = (420 : ℕ) * x.gcd y, with h1 : ((420 : ℕ) * x).gcd ((420 : ℕ) * y) = (420 : ℕ) * x.gcd y.

      Uses library Nat.gcd Computes the greatest common divisor of two natural numbers. , Nat.gcd_mul_left.

      Lean, line 72
          have h1 : Nat.gcd (420 * x) (420 * y) = 420 * x.gcd y := Nat.gcd_mul_left 420 x y

      targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 72 at b9e7eed20f11 ↗

  17. hxA have x ∈ A

    Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ), with hxA : x ∈ A.

    Uses library Finset.mem_erase.

    Lean, line 75
      have hxA := (Finset.mem_erase.mp hx).2

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 75 at b9e7eed20f11 ↗

  18. hyA have y ∈ A

    Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ), with hyA : y ∈ A.

    Uses library Finset.mem_erase.

    Lean, line 76
      have hyA := (Finset.mem_erase.mp hy).2

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 76 at b9e7eed20f11 ↗

  19. s19 case

    Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ).

    Uses library Exists.intro Existential introduction. , Nat.le_of_mul_le_mul_right.

    Lean, lines 78–82
      · refine ⟨x, hxA, y, hyA, key x y ?_⟩
        rw [hn]
        have h2 := Nat.mul_le_mul_right (A.max' hne) h
        have h3 : x.gcd y * 8 * 420 ≤ x * 420 := by nlinarith
        exact Nat.le_of_mul_le_mul_right h3 (by norm_num)

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, lines 78–82 at b9e7eed20f11 ↗

    1. s19.h2 have (8 : ℕ) * a.gcd b * A.max' hne ≤ a * A.max' hne

      Leaves x.gcd y * (8 : ℕ) ≤ x, with h2 : (8 : ℕ) * a.gcd b * A.max' hne ≤ a * A.max' hne.

      Uses library Nat.mul_le_mul_right.

      Lean, line 80
          have h2 := Nat.mul_le_mul_right (A.max' hne) h

      targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 80 at b9e7eed20f11 ↗

    2. s19.h3 have x.gcd y * (8 : ℕ) * (420 : ℕ) ≤ x * (420 : ℕ) routine: nlinarith

      Leaves x.gcd y * (8 : ℕ) ≤ x, with h3 : x.gcd y * (8 : ℕ) * (420 : ℕ) ≤ x * (420 : ℕ).

      Lean, line 81
          have h3 : x.gcd y * 8 * 420 ≤ x * 420 := by nlinarith

      targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 81 at b9e7eed20f11 ↗

  20. s20 case

    Leaves ∃ a ∈ A, ∃ b ∈ A, (↑(a.gcd b) : ℚ) ≤ (↑a : ℚ) / (↑A.card : ℚ).

    Uses library Exists.intro Existential introduction. , Nat.gcd_comm, Nat.le_of_mul_le_mul_right.

    Lean, lines 83–87
      · refine ⟨y, hyA, x, hxA, key y x ?_⟩
        rw [hn, Nat.gcd_comm]
        have h2 := Nat.mul_le_mul_right (A.max' hne) h
        have h3 : x.gcd y * 8 * 420 ≤ y * 420 := by nlinarith
        exact Nat.le_of_mul_le_mul_right h3 (by norm_num)

    targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, lines 83–87 at b9e7eed20f11 ↗

    1. s20.h2 have (8 : ℕ) * a.gcd b * A.max' hne ≤ b * A.max' hne

      Leaves x.gcd y * (8 : ℕ) ≤ y, with h2 : (8 : ℕ) * a.gcd b * A.max' hne ≤ b * A.max' hne.

      Uses library Nat.mul_le_mul_right.

      Lean, line 85
          have h2 := Nat.mul_le_mul_right (A.max' hne) h

      targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 85 at b9e7eed20f11 ↗

    2. s20.h3 have x.gcd y * (8 : ℕ) * (420 : ℕ) ≤ y * (420 : ℕ) routine: nlinarith

      Leaves x.gcd y * (8 : ℕ) ≤ y, with h3 : x.gcd y * (8 : ℕ) * (420 : ℕ) ≤ y * (420 : ℕ).

      Lean, line 86
          have h3 : x.gcd y * 8 * 420 ≤ y * 420 := by nlinarith

      targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, line 86 at b9e7eed20f11 ↗

The proof in Lean (Proof.lean)

Checked by the kernel — these bytes are the ones its attestation names: attestations/000218.json, merge commit b9e7eed20f11.

Proof.lean — its sha256 is the artifact_hash of the attestation below, so these are the bytes the gate checked. Rendered from targets/erdos-402/nodes/variant-6bb50ad7/Proof.lean, sha256 30eaefbbd55c.
import Mathlib
import Nodes.«variant-6bb50ad7».Context

/-! Graham's gcd conjecture (Erdős problem 402) for eight-element sets. With M the largest
element, if gcd(M, b) > M/8 for every b then every other b is (j/k)M with j < k ≤ 7: one of
seventeen values. Among those, no seven avoid a pair x, y with x / gcd(x, y) ≥ 8 (a finite
case split on which values occur), so the seven other elements cannot all be distinct values. -/

theorem Opn.erdos_402_card_eight :
    ∀ (A : Finset ℕ), 0 ∉ A → A.card = 8 → ∃ a ∈ A, ∃ b ∈ A, a.gcd b ≤ (a / A.card : ℚ) := by
  intro A hA hn
  have hpos : 0 < A.card := by omega
  have hne : A.Nonempty := Finset.card_pos.mp hpos
  have key : ∀ a b : ℕ, a.gcd b * A.card ≤ a → (a.gcd b : ℚ) ≤ (a / A.card : ℚ) := by
    intro a b h
    rw [le_div_iff₀ (by exact_mod_cast hpos)]
    exact_mod_cast h
  have hM : A.max' hne ∈ A := Finset.max'_mem A hne
  have hMpos : 0 < A.max' hne := Nat.pos_of_ne_zero (fun h => hA (h ▸ hM))
  by_cases hw : ∃ x ∈ A, (A.max' hne).gcd x * 8 ≤ A.max' hne
  · obtain ⟨x, hx, h⟩ := hw
    exact ⟨_, hM, x, hx, key _ x (by rw [hn]; exact h)⟩
  push_neg at hw
  have forms : ∀ x ∈ A.erase (A.max' hne), ∃ a ∈ ({60, 70, 84, 105, 120, 140, 168, 180, 210, 240, 252, 280, 300, 315, 336, 350, 360} : Finset ℕ), 420 * x = a * A.max' hne := by
    intro x hx
    rw [Finset.mem_erase] at hx
    have hxpos : 0 < x := Nat.pos_of_ne_zero (fun h => hA (h ▸ hx.2))
    have hlt : x < A.max' hne := lt_of_le_of_ne (Finset.le_max' A x hx.2) hx.1
    have hg := hw x hx.2
    obtain ⟨k, hk⟩ := Nat.gcd_dvd_left (A.max' hne) x
    obtain ⟨j, hj⟩ := Nat.gcd_dvd_right (A.max' hne) x
    have hgpos : 0 < (A.max' hne).gcd x := Nat.gcd_pos_of_pos_right _ hxpos
    have hkN : k < 8 := by
      by_contra hh
      push_neg at hh
      have := Nat.mul_le_mul_left ((A.max' hne).gcd x) hh
      omega
    have hjk : j < k := by
      by_contra hh
      push_neg at hh
      have := Nat.mul_le_mul_left ((A.max' hne).gcd x) hh
      omega
    have hj1 : 1 ≤ j := by
      rcases Nat.eq_zero_or_pos j with h | h
      · subst h
        omega
      · exact h
    refine ⟨420 * j / k, ?_, ?_⟩
    · interval_cases k <;> interval_cases j <;> decide
    · interval_cases k <;> interval_cases j <;> omega
  have hcard : (A.erase (A.max' hne)).card = 7 := by
    rw [Finset.card_erase_of_mem hM, hn]
  have hS : ∀ a ∈ ({60, 70, 84, 105, 120, 140, 168, 180, 210, 240, 252, 280, 300, 315, 336, 350, 360} : Finset ℕ), (fun a : ℕ => if a = 60 then 0 else if a = 70 then 1 else if a = 84 then 2 else if a = 105 then 3 else if a = 120 then 1 else if a = 140 then 4 else if a = 168 then 0 else if a = 180 then 2 else if a = 210 then 5 else if a = 240 then 3 else if a = 252 then 1 else if a = 280 then 2 else if a = 300 then 4 else if a = 315 then 0 else if a = 336 then 4 else if a = 350 then 0 else if a = 360 then 5 else 0) a < 6 := by decide
  have hmaps : ∀ x ∈ A.erase (A.max' hne), (fun a : ℕ => if a = 60 then 0 else if a = 70 then 1 else if a = 84 then 2 else if a = 105 then 3 else if a = 120 then 1 else if a = 140 then 4 else if a = 168 then 0 else if a = 180 then 2 else if a = 210 then 5 else if a = 240 then 3 else if a = 252 then 1 else if a = 280 then 2 else if a = 300 then 4 else if a = 315 then 0 else if a = 336 then 4 else if a = 350 then 0 else if a = 360 then 5 else 0) (420 * x / A.max' hne) ∈ Finset.range 6 := by
    intro x hx
    obtain ⟨a, ha, hax⟩ := forms x hx
    rw [Finset.mem_range, hax, Nat.mul_div_cancel _ hMpos]
    exact hS a ha
  obtain ⟨x, hx, y, hy, hxy, hc⟩ :=
    Finset.exists_ne_map_eq_of_card_lt_of_maps_to (by rw [hcard, Finset.card_range]; norm_num) hmaps
  obtain ⟨a, ha, hax⟩ := forms x hx
  obtain ⟨b, hb, hby⟩ := forms y hy
  rw [hax, hby, Nat.mul_div_cancel _ hMpos, Nat.mul_div_cancel _ hMpos] at hc
  have hab : a ≠ b := by
    intro h
    subst h
    apply hxy
    omega
  have hpair : ∀ a ∈ ({60, 70, 84, 105, 120, 140, 168, 180, 210, 240, 252, 280, 300, 315, 336, 350, 360} : Finset ℕ), ∀ b ∈ ({60, 70, 84, 105, 120, 140, 168, 180, 210, 240, 252, 280, 300, 315, 336, 350, 360} : Finset ℕ), a ≠ b → (fun a : ℕ => if a = 60 then 0 else if a = 70 then 1 else if a = 84 then 2 else if a = 105 then 3 else if a = 120 then 1 else if a = 140 then 4 else if a = 168 then 0 else if a = 180 then 2 else if a = 210 then 5 else if a = 240 then 3 else if a = 252 then 1 else if a = 280 then 2 else if a = 300 then 4 else if a = 315 then 0 else if a = 336 then 4 else if a = 350 then 0 else if a = 360 then 5 else 0) a = (fun a : ℕ => if a = 60 then 0 else if a = 70 then 1 else if a = 84 then 2 else if a = 105 then 3 else if a = 120 then 1 else if a = 140 then 4 else if a = 168 then 0 else if a = 180 then 2 else if a = 210 then 5 else if a = 240 then 3 else if a = 252 then 1 else if a = 280 then 2 else if a = 300 then 4 else if a = 315 then 0 else if a = 336 then 4 else if a = 350 then 0 else if a = 360 then 5 else 0) b →
      8 * a.gcd b ≤ a ∨ 8 * a.gcd b ≤ b := by decide
  have hgcd : a.gcd b * A.max' hne = 420 * x.gcd y := by
    have h1 : Nat.gcd (420 * x) (420 * y) = 420 * x.gcd y := Nat.gcd_mul_left 420 x y
    rw [hax, hby, Nat.gcd_mul_right] at h1
    exact h1
  have hxA := (Finset.mem_erase.mp hx).2
  have hyA := (Finset.mem_erase.mp hy).2
  rcases hpair a ha b hb hab hc with h | h
  · refine ⟨x, hxA, y, hyA, key x y ?_⟩
    rw [hn]
    have h2 := Nat.mul_le_mul_right (A.max' hne) h
    have h3 : x.gcd y * 8 * 420 ≤ x * 420 := by nlinarith
    exact Nat.le_of_mul_le_mul_right h3 (by norm_num)
  · refine ⟨y, hyA, x, hxA, key y x ?_⟩
    rw [hn, Nat.gcd_comm]
    have h2 := Nat.mul_le_mul_right (A.max' hne) h
    have h3 : x.gcd y * 8 * 420 ≤ y * 420 := by nlinarith
    exact Nat.le_of_mul_le_mul_right h3 (by norm_num)

What 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).

Write the explainer →

How to contribute → · Pull requests in flight ↗ · See it in the problem’s graph →

Record

Statement: the Lean file and its words (1 version)

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.«variant-6bb50ad7».Context

/-! Graham's gcd conjecture (Erdős problem 402) for eight-element sets. With M the largest
element, if gcd(M, b) > M/8 for every b then every other b is (j/k)M with j < k ≤ 7: one of
seventeen values. Among those, no seven avoid a pair x, y with x / gcd(x, y) ≥ 8 (a finite
case split on which values occur), so the seven other elements cannot all be distinct values. -/

theorem Opn.erdos_402_card_eight :
    ∀ (A : Finset ℕ), 0 ∉ A → A.card = 8 → ∃ a ∈ A, ∃ b ∈ A, a.gcd b ≤ (a / A.card : ℚ) := by
  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 →

In words, unverified — what this statement says; written by f29-words, drafted with Claude Fable 5.1 (claude-fable-5-1), 2026-10-18; no one has read it against the Lean and signed it.

Draft · drafted, by the model named above

$\displaystyle \forall A \subset \mathbb{N}\ \text{finite}:\ 0 \notin A,\ |A| = 8 \Rightarrow \exists\, a, b \in A:\ \gcd(a,b) \le \frac{a}{|A|}$

Every set A of exactly eight positive integers has a, b ∈ A (possibly equal) with gcd(a, b) ≤ a/|A|. The division is in ℚ.

Rendered from gloss/277f1f2d2241….md · Improve these words →

Rendered from targets/erdos-402/nodes/variant-6bb50ad7/Statement.lean. Origin: variant (partial).

Attestation: pass, 7 of 7 checks

Checked by the kernel — the gate’s record of the run: attestations/000218.json, merge commit b9e7eed20f11.

Verdict pass, from attestations/000218.json.

Submitter
graham-gcd-http
Toolchain
leanprover/lean4:v4.33.1 (hash f54d0bc916bf76a7fae460ce9d078ccd1f74aeb4fd12c4b6546bca28b6aa1c63)
Mathlib
0df444a360eaa60ab8c11dca51a86af692955474
Reviewer
none needed (calibration)
StepCheckResult
1toolchainpass
2pathspass
4kernel-replaypass
5axiomspass
6hazardspass
7witnesspass
8depspass
Witness

Checked by the kernel — step 7 passed in the run its attestation records: attestations/000218.json, merge commit b9e7eed20f11.

Witness.lean — checked at step 7 of the run recorded below: pass. Rendered from targets/erdos-402/nodes/variant-6bb50ad7/Witness.lean, sha256 4f5252e2b14f.
import Mathlib

theorem witness : ∃ A : Finset ℕ, 0 ∉ A ∧ A.card = 8 :=
  ⟨{1, 2, 3, 4, 5, 6, 7, 8}, by decide, by decide⟩

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 →

Relation to the problem’s statement

Checked by the kernel — checked at admission (D-30); no proof of the node is implied.

Relation.lean — the implication between this variant and the problem’s statement, checked by the gate when the variant was admitted and immutable after (D-30). Rendered from targets/erdos-402/nodes/variant-6bb50ad7/Relation.lean, sha256 181a824e2ac6.
-- relation: partial
import Mathlib

theorem relation :
    (∀ (A : Finset ℕ), 0 ∉ A → A.Nonempty → ∃ᵉ (a ∈ A) (b ∈ A), a.gcd b ≤ (a / A.card : ℚ)) →
    (∀ (A : Finset ℕ), 0 ∉ A → A.card = 8 → ∃ a ∈ A, ∃ b ∈ A, a.gcd b ≤ (a / A.card : ℚ)) := by
  intro h A h0 hc
  exact h A h0 (Finset.card_pos.mp (by omega))

No gloss yet: no one has written in words what this relation says (D-3 v3.30); the Lean above is the relation. How to write one →

Acknowledged findings (1)

Untrusted contributor text — the prover’s justification for a finding.

Untrusted: acknowledgment of a div-zero finding at ↑a / ↑A.card

A.card = 8 is a hypothesis, so the rational division is by 8.

How to read this page