/- Copyright 2025 The Formal Conjectures Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -/ import FormalConjecturesUtil

Kurepa's conjecture

Reference: On the left factorial function !N, by Đuro Kurepa Math. Balkanica 1, p. 147-153, 1971

namespace Kurepa open BigOperators Nat Finset

Left factorial of n $$!n = 0! + 1! + 2! + \dots + (n-1)!$$

def left_factorial (n : ) := m Finset.range n, m ! local notation "!" n => left_factorial n

Kurepa's conjecture

For all $n$, $$!n\not\equiv 0 \mod n$$

This appears as B44 "Sums of factorials." in Unsolved Problems in Number Theory by Richard K. Guy

@[category research open, AMS 11] theorem declaration uses 'sorry'kurepa_conjecture (n : ) (h_n : 2 < n) : (!n : ) % n 0 := n:h_n:2 < n(!n) % n 0 All goals completed! 🐙

This statement can be reduced to the prime case only.

@[category research open, AMS 11] theorem declaration uses 'sorry'kurepa_conjecture.variants.prime (p : ) (h_p : 2 < p) : p.Prime (!p : ) % p 0 := p:h_p:2 < pNat.Prime p (!p) % p 0 All goals completed! 🐙

Kurepa's conjecture for all integers greater than 2 is equivalent to the conjecture restricted to primes greater than 2.

@[category textbook, AMS 11] theorem kurepa_conjecture.prime_reduction : ( n, 2 < n (!n : ) % n 0) ( p, 2 < p p.Prime (!p : ) % p 0) := (∀ (n : ), 2 < n (!n) % n 0) (p : ), 2 < p Nat.Prime p (!p) % p 0 h: (p : ), 2 < p Nat.Prime p (!p) % p 0n:hn:2 < nh_mod:(!n) % n = 0False have : n.primeFactorsList.prod n := (∀ (n : ), 2 < n (!n) % n 0) (p : ), 2 < p Nat.Prime p (!p) % p 0 have (p : ) (h_mem : p n.primeFactorsList) : p = 2 := (∀ (n : ), 2 < n (!n) % n 0) (p : ), 2 < p Nat.Prime p (!p) % p 0 h: (p : ), 2 < p Nat.Prime p (!p) % p 0n:hn:2 < nh_mod:(!n) % n = 0p:h_mem:p n.primeFactorsListhp:Nat.Prime p := prime_of_mem_primeFactorsList h_memp = 2 h: (p : ), 2 < p Nat.Prime p (!p) % p 0n:hn:2 < nh_mod:(!n) % n = 0p:h_mem:p n.primeFactorsListhp:Nat.Prime p := prime_of_mem_primeFactorsList h_memx✝:p % 2 = 1False have : p a range n, (a)! := .trans (h: (p : ), 2 < p Nat.Prime p (!p) % p 0n:hn:2 < nh_mod:(!n) % n = 0p:h_mem:p n.primeFactorsListhp:Nat.Prime p := prime_of_mem_primeFactorsList h_memx✝:p % 2 = 1p p All goals completed! 🐙) (dvd_of_mem_primeFactorsList h_mem |>.trans (dvd_of_mod_eq_zero h_mod)) have hxp : range p range n := (∀ (n : ), 2 < n (!n) % n 0) (p : ), 2 < p Nat.Prime p (!p) % p 0 h: (p : ), 2 < p Nat.Prime p (!p) % p 0n:hn:2 < nh_mod:(!n) % n = 0p:h_mem:p n.primeFactorsListhp:Nat.Prime p := prime_of_mem_primeFactorsList h_memx✝:p % 2 = 1this:p a range n, a ! := Dvd.dvd.trans (of_eq_true (dvd_refl._simp_1 p)) (Dvd.dvd.trans (dvd_of_mem_primeFactorsList h_mem) (dvd_of_mod_eq_zero h_mod))p n All goals completed! 🐙 h: (p : ), 2 < p Nat.Prime p (!p) % p 0n:hn:2 < nh_mod:(!n) % n = 0p:h_mem:p n.primeFactorsListhp:Nat.Prime p := prime_of_mem_primeFactorsList h_memx✝:p % 2 = 1this:p x range p, x !hxp:range p range nFalse exact h p (hp.two_le.lt_of_ne (h: (p : ), 2 < p Nat.Prime p (!p) % p 0n:hn:2 < nh_mod:(!n) % n = 0p:h_mem:p n.primeFactorsListhp:Nat.Prime p := prime_of_mem_primeFactorsList h_memx✝:p % 2 = 1this:p x range p, x !hxp:range p range n2 p All goals completed! 🐙)) hp <| mod_eq_zero_of_dvd this h: (p : ), 2 < p Nat.Prime p (!p) % p 0n:hn:2 < nh_mod:(!n) % n = 0this: p n.primeFactorsList, p = 2 := fun p h_mem => have hp := prime_of_mem_primeFactorsList h_mem; Or.resolve_right (Prime.eq_two_or_odd hp) fun x => have this := Dvd.dvd.trans (of_eq_true (dvd_refl._simp_1 p)) (Dvd.dvd.trans (dvd_of_mem_primeFactorsList h_mem) (dvd_of_mod_eq_zero h_mod)); have hxp := Eq.mpr (id prime_reduction._simp_1) (le_of_mem_primeFactorsList h_mem); h p (LE.le.lt_of_ne (Prime.two_le hp) fun a => prime_reduction._proof_2 n p x a) hp (mod_eq_zero_of_dvd (Eq.mp (congrArg (fun _a => _a) (propext (CharP.cast_eq_zero_iff (ZMod p) p (∑ x range p, x !)))) (Eq.mp (congrArg (fun _a => _a = 0) (Eq.symm (cast_sum (range p) factorial))) (Eq.mp (congrArg (fun _a => _a = 0) (Eq.symm (sum_subset hxp fun x x_1 x_2 => (CharP.cast_eq_zero_iff (ZMod p) p x !).mpr ((Prime.dvd_factorial hp).mpr (id (Eq.mp (Eq.trans (congrArg Not mem_range._simp_1) not_lt._simp_1) x_2)))))) (Eq.mp (congrArg (fun _a => _a = 0) (cast_sum (range n) factorial)) (Eq.mp (congrArg (fun _a => _a) (Eq.symm (propext (CharP.cast_eq_zero_iff (ZMod p) p (∑ a range n, a !))))) this))))))2 ^ n.primeFactorsList.length n h✝: (p : ), 2 < p Nat.Prime p (!p) % p 0n:hn:2 < nh_mod:(!n) % n = 0this: p n.primeFactorsList, p = 2 := fun p h_mem => have hp := prime_of_mem_primeFactorsList h_mem; Or.resolve_right (Prime.eq_two_or_odd hp) fun x => have this := Dvd.dvd.trans (of_eq_true (dvd_refl._simp_1 p)) (Dvd.dvd.trans (dvd_of_mem_primeFactorsList h_mem) (dvd_of_mod_eq_zero h_mod)); have hxp := Eq.mpr (id prime_reduction._simp_1) (le_of_mem_primeFactorsList h_mem); h p (LE.le.lt_of_ne (Prime.two_le hp) fun a => prime_reduction._proof_2 n p x a) hp (mod_eq_zero_of_dvd (Eq.mp (congrArg (fun _a => _a) (propext (CharP.cast_eq_zero_iff (ZMod p) p (∑ x range p, x !)))) (Eq.mp (congrArg (fun _a => _a = 0) (Eq.symm (cast_sum (range p) factorial))) (Eq.mp (congrArg (fun _a => _a = 0) (Eq.symm (sum_subset hxp fun x x_1 x_2 => (CharP.cast_eq_zero_iff (ZMod p) p x !).mpr ((Prime.dvd_factorial hp).mpr (id (Eq.mp (Eq.trans (congrArg Not mem_range._simp_1) not_lt._simp_1) x_2)))))) (Eq.mp (congrArg (fun _a => _a = 0) (cast_sum (range n) factorial)) (Eq.mp (congrArg (fun _a => _a) (Eq.symm (propext (CharP.cast_eq_zero_iff (ZMod p) p (∑ a range n, a !))))) this))))))h:2 ^ n.primeFactorsList.length = nFalse have : 4 n := h pow_dvd_pow 2 ((Nat.pow_lt_pow_iff_right (n := 1) one_lt_two).1 (h✝: (p : ), 2 < p Nat.Prime p (!p) % p 0n:hn:2 < nh_mod:(!n) % n = 0this: p n.primeFactorsList, p = 2 := fun p h_mem => have hp := prime_of_mem_primeFactorsList h_mem; Or.resolve_right (Prime.eq_two_or_odd hp) fun x => have this := Dvd.dvd.trans (of_eq_true (dvd_refl._simp_1 p)) (Dvd.dvd.trans (dvd_of_mem_primeFactorsList h_mem) (dvd_of_mod_eq_zero h_mod)); have hxp := Eq.mpr (id prime_reduction._simp_1) (le_of_mem_primeFactorsList h_mem); h✝ p (LE.le.lt_of_ne (Prime.two_le hp) fun a => prime_reduction._proof_2 n p x a) hp (mod_eq_zero_of_dvd (Eq.mp (congrArg (fun _a => _a) (propext (CharP.cast_eq_zero_iff (ZMod p) p (∑ x range p, x !)))) (Eq.mp (congrArg (fun _a => _a = 0) (Eq.symm (cast_sum (range p) factorial))) (Eq.mp (congrArg (fun _a => _a = 0) (Eq.symm (sum_subset hxp fun x x_1 x_2 => (CharP.cast_eq_zero_iff (ZMod p) p x !).mpr ((Prime.dvd_factorial hp).mpr (id (Eq.mp (Eq.trans (congrArg Not mem_range._simp_1) not_lt._simp_1) x_2)))))) (Eq.mp (congrArg (fun _a => _a = 0) (cast_sum (range n) factorial)) (Eq.mp (congrArg (fun _a => _a) (Eq.symm (propext (CharP.cast_eq_zero_iff (ZMod p) p (∑ a range n, a !))))) this))))))h:2 ^ n.primeFactorsList.length = n2 ^ 1 < 2 ^ n.primeFactorsList.length All goals completed! 🐙)) h✝: (p : ), 2 < p Nat.Prime p (!p) % p 0n:hn:2 < nh_mod:(!n) % n = 0this✝¹: p n.primeFactorsList, p = 2 := fun p h_mem => have hp := prime_of_mem_primeFactorsList h_mem; Or.resolve_right (Prime.eq_two_or_odd hp) fun x => have this := Dvd.dvd.trans (of_eq_true (dvd_refl._simp_1 p)) (Dvd.dvd.trans (dvd_of_mem_primeFactorsList h_mem) (dvd_of_mod_eq_zero h_mod)); have hxp := Eq.mpr (id prime_reduction._simp_1) (le_of_mem_primeFactorsList h_mem); h p (LE.le.lt_of_ne (Prime.two_le hp) fun a => prime_reduction._proof_2 n p x a) hp (mod_eq_zero_of_dvd (Eq.mp (congrArg (fun _a => _a) (propext (CharP.cast_eq_zero_iff (ZMod p) p (∑ x range p, x !)))) (Eq.mp (congrArg (fun _a => _a = 0) (Eq.symm (cast_sum (range p) factorial))) (Eq.mp (congrArg (fun _a => _a = 0) (Eq.symm (sum_subset hxp fun x x_1 x_2 => (CharP.cast_eq_zero_iff (ZMod p) p x !).mpr ((Prime.dvd_factorial hp).mpr (id (Eq.mp (Eq.trans (congrArg Not mem_range._simp_1) not_lt._simp_1) x_2)))))) (Eq.mp (congrArg (fun _a => _a = 0) (cast_sum (range n) factorial)) (Eq.mp (congrArg (fun _a => _a) (Eq.symm (propext (CharP.cast_eq_zero_iff (ZMod p) p (∑ a range n, a !))))) this))))))h:2 ^ n.primeFactorsList.length = nthis✝:4 n := h pow_dvd_pow 2 ((Nat.pow_lt_pow_iff_right one_lt_two).mp (lt_of_not_ge fun a => Mathlib.Tactic.Linarith.lt_irrefl (Eq.mp (congrArg (fun _a => _a < 0) (Mathlib.Tactic.Ring.of_eq (Mathlib.Tactic.Ring.add_congr (Mathlib.Tactic.Ring.add_congr (Mathlib.Tactic.Ring.add_congr (Mathlib.Tactic.Ring.neg_congr (Mathlib.Tactic.Ring.cast_pos (Mathlib.Meta.NormNum.isNat_ofNat (Eq.refl 1))) (Mathlib.Tactic.Ring.neg_add (Mathlib.Tactic.Ring.neg_one_mul (Mathlib.Meta.NormNum.IsInt.to_raw_eq (Mathlib.Meta.NormNum.isInt_mul (Eq.refl HMul.hMul) (Mathlib.Meta.NormNum.IsInt.of_raw (Int.negOfNat 1)) (Mathlib.Meta.NormNum.IsNat.to_isInt (Mathlib.Meta.NormNum.IsNat.of_raw 1)) (Eq.refl (Int.negOfNat 1))))) Mathlib.Tactic.Ring.neg_zero)) (Mathlib.Tactic.Ring.sub_congr (Mathlib.Tactic.Ring.add_congr (Mathlib.Tactic.Ring.cast_pos (Mathlib.Meta.NormNum.isNat_ofNat (Eq.refl 2))) (Mathlib.Tactic.Ring.cast_pos (Mathlib.Meta.NormNum.isNat_ofNat (Eq.refl 1))) (Mathlib.Tactic.Ring.add_pf_add_overlap (Mathlib.Meta.NormNum.IsNat.to_raw_eq (Mathlib.Meta.NormNum.isNat_add (Eq.refl HAdd.hAdd) (Mathlib.Meta.NormNum.IsNat.of_raw 2) (Mathlib.Meta.NormNum.IsNat.of_raw 1) (Eq.refl 3))) (Mathlib.Tactic.Ring.add_pf_zero_add 0))) (Mathlib.Tactic.Ring.atom_pf n) (Mathlib.Tactic.Ring.sub_pf (Mathlib.Tactic.Ring.neg_add (Mathlib.Tactic.Ring.neg_mul (↑n) (rawCast 1) (Mathlib.Tactic.Ring.neg_one_mul (Mathlib.Meta.NormNum.IsInt.to_raw_eq (Mathlib.Meta.NormNum.isInt_mul (Eq.refl HMul.hMul) (Mathlib.Meta.NormNum.IsInt.of_raw (Int.negOfNat 1)) (Mathlib.Meta.NormNum.IsNat.to_isInt (Mathlib.Meta.NormNum.IsNat.of_raw 1)) (Eq.refl (Int.negOfNat 1)))))) Mathlib.Tactic.Ring.neg_zero) (Mathlib.Tactic.Ring.add_pf_add_lt (rawCast 3) (Mathlib.Tactic.Ring.add_pf_zero_add (n ^ rawCast 1 * (Int.negOfNat 1).rawCast + 0))))) (Mathlib.Tactic.Ring.add_pf_add_overlap (Mathlib.Meta.NormNum.IsNat.to_raw_eq (Mathlib.Meta.NormNum.IsInt.to_isNat (Mathlib.Meta.NormNum.isInt_add (Eq.refl HAdd.hAdd) (Mathlib.Meta.NormNum.IsInt.of_raw (Int.negOfNat 1)) (Mathlib.Meta.NormNum.IsNat.to_isInt (Mathlib.Meta.NormNum.IsNat.of_raw 3)) (Eq.refl (Int.ofNat 2))))) (Mathlib.Tactic.Ring.add_pf_zero_add (n ^ rawCast 1 * (Int.negOfNat 1).rawCast + 0)))) (Mathlib.Tactic.Ring.neg_congr (Mathlib.Tactic.Ring.sub_congr (Mathlib.Tactic.Ring.pow_congr (Mathlib.Tactic.Ring.cast_pos (Mathlib.Meta.NormNum.isNat_ofNat (Eq.refl 2))) (Mathlib.Tactic.Ring.atom_pf n.primeFactorsList.length) (Mathlib.Tactic.Ring.pow_add (Mathlib.Tactic.Ring.single_pow (Mathlib.Tactic.Ring.pow_prod_atom (rawCast 2) (n.primeFactorsList.length ^ rawCast 1 * rawCast 1))) (Mathlib.Tactic.Ring.pow_zero (rawCast 2 + 0)) (Mathlib.Tactic.Ring.add_mul (Mathlib.Tactic.Ring.mul_add (Mathlib.Tactic.Ring.mul_pf_left (rawCast 2 + 0) (n.primeFactorsList.length ^ rawCast 1 * rawCast 1) (Mathlib.Tactic.Ring.one_mul (rawCast 1))) (Mathlib.Tactic.Ring.mul_zero ((rawCast 2 + 0) ^ (n.primeFactorsList.length ^ rawCast 1 * rawCast 1) * rawCast 1)) (Mathlib.Tactic.Ring.add_pf_add_zero ((rawCast 2 + 0) ^ (n.primeFactorsList.length ^ rawCast 1 * rawCast 1) * rawCast 1 + 0))) (Mathlib.Tactic.Ring.zero_mul (rawCast 1 + 0)) (Mathlib.Tactic.Ring.add_pf_add_zero ((rawCast 2 + 0) ^ (n.primeFactorsList.length ^ rawCast 1 * rawCast 1) * rawCast 1 + 0))))) (Mathlib.Tactic.Ring.atom_pf n) (Mathlib.Tactic.Ring.sub_pf (Mathlib.Tactic.Ring.neg_add (Mathlib.Tactic.Ring.neg_mul (↑n) (rawCast 1) (Mathlib.Tactic.Ring.neg_one_mul (Mathlib.Meta.NormNum.IsInt.to_raw_eq (Mathlib.Meta.NormNum.isInt_mul (Eq.refl HMul.hMul) (Mathlib.Meta.NormNum.IsInt.of_raw (Int.negOfNat 1)) (Mathlib.Meta.NormNum.IsNat.to_isInt (Mathlib.Meta.NormNum.IsNat.of_raw 1)) (Eq.refl (Int.negOfNat 1)))))) Mathlib.Tactic.Ring.neg_zero) (Mathlib.Tactic.Ring.add_pf_add_gt (n ^ rawCast 1 * (Int.negOfNat 1).rawCast) (Mathlib.Tactic.Ring.add_pf_add_zero ((rawCast 2 + 0) ^ (n.primeFactorsList.length ^ rawCast 1 * rawCast 1) * rawCast 1 + 0))))) (Mathlib.Tactic.Ring.neg_add (Mathlib.Tactic.Ring.neg_mul (↑n) (rawCast 1) (Mathlib.Tactic.Ring.neg_one_mul (Mathlib.Meta.NormNum.IsNat.to_raw_eq (Mathlib.Meta.NormNum.IsInt.to_isNat (Mathlib.Meta.NormNum.isInt_mul (Eq.refl HMul.hMul) (Mathlib.Meta.NormNum.IsInt.of_raw (Int.negOfNat 1)) (Mathlib.Meta.NormNum.IsInt.of_raw (Int.negOfNat 1)) (Eq.refl (Int.ofNat 1))))))) (Mathlib.Tactic.Ring.neg_add (Mathlib.Tactic.Ring.neg_mul (rawCast 2 + 0) (n.primeFactorsList.length ^ rawCast 1 * rawCast 1) (Mathlib.Tactic.Ring.neg_one_mul (Mathlib.Meta.NormNum.IsInt.to_raw_eq (Mathlib.Meta.NormNum.isInt_mul (Eq.refl HMul.hMul) (Mathlib.Meta.NormNum.IsInt.of_raw (Int.negOfNat 1)) (Mathlib.Meta.NormNum.IsNat.to_isInt (Mathlib.Meta.NormNum.IsNat.of_raw 1)) (Eq.refl (Int.negOfNat 1)))))) Mathlib.Tactic.Ring.neg_zero))) (Mathlib.Tactic.Ring.add_pf_add_lt (rawCast 2) (Mathlib.Tactic.Ring.add_pf_add_overlap_zero (Mathlib.Tactic.Ring.add_overlap_pf_zero (↑n) (rawCast 1) (Mathlib.Meta.NormNum.IsInt.to_isNat (Mathlib.Meta.NormNum.isInt_add (Eq.refl HAdd.hAdd) (Mathlib.Meta.NormNum.IsInt.of_raw (Int.negOfNat 1)) (Mathlib.Meta.NormNum.IsNat.to_isInt (Mathlib.Meta.NormNum.IsNat.of_raw 1)) (Eq.refl (Int.ofNat 0))))) (Mathlib.Tactic.Ring.add_pf_zero_add ((rawCast 2 + 0) ^ (n.primeFactorsList.length ^ rawCast 1 * rawCast 1) * (Int.negOfNat 1).rawCast + 0))))) (Mathlib.Tactic.Ring.sub_congr (Mathlib.Tactic.Ring.pow_congr (Mathlib.Tactic.Ring.cast_pos (Mathlib.Meta.NormNum.isNat_ofNat (Eq.refl 2))) (Mathlib.Tactic.Ring.atom_pf n.primeFactorsList.length) (Mathlib.Tactic.Ring.pow_add (Mathlib.Tactic.Ring.single_pow (Mathlib.Tactic.Ring.pow_prod_atom (rawCast 2) (n.primeFactorsList.length ^ rawCast 1 * rawCast 1))) (Mathlib.Tactic.Ring.pow_zero (rawCast 2 + 0)) (Mathlib.Tactic.Ring.add_mul (Mathlib.Tactic.Ring.mul_add (Mathlib.Tactic.Ring.mul_pf_left (rawCast 2 + 0) (n.primeFactorsList.length ^ rawCast 1 * rawCast 1) (Mathlib.Tactic.Ring.one_mul (rawCast 1))) (Mathlib.Tactic.Ring.mul_zero ((rawCast 2 + 0) ^ (n.primeFactorsList.length ^ rawCast 1 * rawCast 1) * rawCast 1)) (Mathlib.Tactic.Ring.add_pf_add_zero ((rawCast 2 + 0) ^ (n.primeFactorsList.length ^ rawCast 1 * rawCast 1) * rawCast 1 + 0))) (Mathlib.Tactic.Ring.zero_mul (rawCast 1 + 0)) (Mathlib.Tactic.Ring.add_pf_add_zero ((rawCast 2 + 0) ^ (n.primeFactorsList.length ^ rawCast 1 * rawCast 1) * rawCast 1 + 0))))) (Mathlib.Tactic.Ring.pow_congr (Mathlib.Tactic.Ring.cast_pos (Mathlib.Meta.NormNum.isNat_ofNat (Eq.refl 2))) (Mathlib.Tactic.Ring.cast_pos (Mathlib.Meta.NormNum.isNat_ofNat (Eq.refl 1))) (Mathlib.Tactic.Ring.pow_add (Mathlib.Tactic.Ring.pow_one_cast (rawCast 2 + 0)) (Mathlib.Tactic.Ring.pow_zero (rawCast 2 + 0)) (Mathlib.Tactic.Ring.add_mul (Mathlib.Tactic.Ring.mul_add (Mathlib.Tactic.Ring.mul_one (rawCast 2)) (Mathlib.Tactic.Ring.mul_zero (rawCast 2)) (Mathlib.Tactic.Ring.add_pf_add_zero (rawCast 2 + 0))) (Mathlib.Tactic.Ring.zero_mul (rawCast 1 + 0)) (Mathlib.Tactic.Ring.add_pf_add_zero (rawCast 2 + 0))))) (Mathlib.Tactic.Ring.sub_pf (Mathlib.Tactic.Ring.neg_add (Mathlib.Tactic.Ring.neg_one_mul (Mathlib.Meta.NormNum.IsInt.to_raw_eq (Mathlib.Meta.NormNum.isInt_mul (Eq.refl HMul.hMul) (Mathlib.Meta.NormNum.IsInt.of_raw (Int.negOfNat 1)) (Mathlib.Meta.NormNum.IsNat.to_isInt (Mathlib.Meta.NormNum.IsNat.of_raw 2)) (Eq.refl (Int.negOfNat 2))))) Mathlib.Tactic.Ring.neg_zero) (Mathlib.Tactic.Ring.add_pf_add_gt (Int.negOfNat 2).rawCast (Mathlib.Tactic.Ring.add_pf_add_zero ((rawCast 2 + 0) ^ (n.primeFactorsList.length ^ rawCast 1 * rawCast 1) * rawCast 1 + 0))))) (Mathlib.Tactic.Ring.add_pf_add_overlap_zero (Mathlib.Meta.NormNum.IsInt.to_isNat (Mathlib.Meta.NormNum.isInt_add (Eq.refl HAdd.hAdd) (Mathlib.Meta.NormNum.IsNat.to_isInt (Mathlib.Meta.NormNum.IsNat.of_raw 2)) (Mathlib.Meta.NormNum.IsInt.of_raw (Int.negOfNat 2)) (Eq.refl (Int.ofNat 0)))) (Mathlib.Tactic.Ring.add_pf_add_overlap_zero (Mathlib.Tactic.Ring.add_overlap_pf_zero (rawCast 2 + 0) (n.primeFactorsList.length ^ rawCast 1 * rawCast 1) (Mathlib.Meta.NormNum.IsInt.to_isNat (Mathlib.Meta.NormNum.isInt_add (Eq.refl HAdd.hAdd) (Mathlib.Meta.NormNum.IsInt.of_raw (Int.negOfNat 1)) (Mathlib.Meta.NormNum.IsNat.to_isInt (Mathlib.Meta.NormNum.IsNat.of_raw 1)) (Eq.refl (Int.ofNat 0))))) (Mathlib.Tactic.Ring.add_pf_zero_add 0)))) (Mathlib.Tactic.Ring.cast_zero (Mathlib.Meta.NormNum.isNat_ofNat (Eq.refl 0))))) (Mathlib.Tactic.Linarith.add_lt_of_neg_of_le (Mathlib.Tactic.Linarith.lt_of_lt_of_eq (Mathlib.Tactic.Linarith.add_lt_of_neg_of_le (neg_neg_of_pos Mathlib.Tactic.Linarith.zero_lt_one) (Mathlib.Tactic.Linarith.sub_nonpos_of_le (Int.add_one_le_iff.mpr (id (Eq.mp (Mathlib.Tactic.Zify.natCast_lt._simp_1 2 n) hn))))) (neg_eq_zero.mpr (sub_eq_zero_of_eq (id (Eq.mp (Eq.trans (Mathlib.Tactic.Zify.natCast_eq._simp_1 (2 ^ n.primeFactorsList.length) n) (congrArg (fun x => x = n) (cast_pow 2 n.primeFactorsList.length))) h))))) (Mathlib.Tactic.Linarith.sub_nonpos_of_le (id (Eq.mp (Eq.trans (Mathlib.Tactic.Zify.natCast_le._simp_1 (2 ^ n.primeFactorsList.length) (2 ^ 1)) (congr (congrArg LE.le (cast_pow 2 n.primeFactorsList.length)) (cast_pow 2 1))) a)))))))this:4 !n := Dvd.dvd.trans this✝ (dvd_of_mod_eq_zero h_mod)False match n with h✝: (p : ), 2 < p Nat.Prime p (!p) % p 0n:S:hn:2 < S + 4h_mod:(!S + 4) % (S + 4) = 0this✝¹: p (S + 4).primeFactorsList, p = 2h:2 ^ (S + 4).primeFactorsList.length = S + 4this✝:4 S + 4this:4 !S + 4False All goals completed! 🐙 All goals completed! 🐙

An equivalent formulation in terms of the gcd of $n!$ and $!n$.

@[category research open, AMS 11] theorem declaration uses 'sorry'kurepa_conjecture.variants.gcd (n : ) : 2 < n (n !).gcd (! n) = 2 := n:2 < n n !.gcd (!n) = 2 All goals completed! 🐙

Kurepa's conjecture for all integers greater than 2 is equivalent to the statement that $\gcd(n!, !n) = 2$ for all integers greater than 2.

@[category textbook, AMS 11] theorem kurepa_conjecture.gcd_reduction : ( n, 2 < n (!n : ) % n 0) ( n, 2 < n (n)!.gcd (!n) = 2) := (∀ (n : ), 2 < n (!n) % n 0) (n : ), 2 < n n !.gcd (!n) = 2 refine fun h n hn match n with | S + 1 => gcd_eq_iff.2 ?_, fun h n hn _ Nat.not_dvd_of_pos_of_lt (h: (n : ), 2 < n n !.gcd (!n) = 2n:hn:2 < nx✝:(!n) % n = 00 < 2 All goals completed! 🐙) hn <| h n hn n.dvd_gcd (n.dvd_factorial hn.pos le_rfl) (dvd_of_mod_eq_zero _) h: (n : ), 2 < n (!n) % n 0n:S:hn:2 < S + 12 !S + 1h: (n : ), 2 < n (!n) % n 0n:S:hn:2 < S + 1c:hc:c (S + 1)!h_dvd:c !S + 1c 2 h: (n : ), 2 < n (!n) % n 0n:S:hn:2 < S + 12 !S + 1 match S with h: (n : ), 2 < n (!n) % n 0n:S✝:S:hn:2 < S + 1 + 12 !S + 1 + 1 All goals completed! 🐙 h: (n : ), 2 < n (!n) % n 0n:S:hn:2 < S + 1c:hc:c (S + 1)!h_dvd:c !S + 1c 2 have hc' : c S + 1 := (∀ (n : ), 2 < n (!n) % n 0) (n : ), 2 < n n !.gcd (!n) = 2 h: (n : ), 2 < n (!n) % n 0n:S:hn:2 < S + 1c:hc:c (S + 1)!h_dvd:c !S + 1this:¬c S + 1False apply h c (h: (n : ), 2 < n (!n) % n 0n:S:hn:2 < S + 1c:hc:c (S + 1)!h_dvd:c !S + 1this:¬c S + 12 < c All goals completed! 🐙) (c.mod_eq_zero_of_dvd ?_) exact (sum_range_add_sum_Ico _ (le_of_not_ge _)).subst (h_dvd.add (dvd_sum fun _ h => hc.trans <| Nat.factorial_dvd_factorial (h✝: (n : ), 2 < n (!n) % n 0n:S:hn:2 < S + 1c:hc:c (S + 1)!h_dvd:c !S + 1this:¬c S + 1x✝:h:x✝ Ico (S + 1) cS + 1 x✝ All goals completed! 🐙))) h: (n : ), 2 < n (!n) % n 0n:S:hn:2 < S + 1c:hc:c (S + 1)!h_dvd:(∑ x range c, x ! % c) % c = 0hc':c S + 1c 2 h: (n : ), 2 < n (!n) % n 0n:S:hn:2 < S + 1c:hc:c (S + 1)!h_dvd:(∑ x range c, x ! % c) % c = 0hc':c S + 1x✝:¬c 22 < c match c with h: (n : ), 2 < n (!n) % n 0n:S:hn:2 < S + 1c:hc:0 (S + 1)!h_dvd:(∑ x range 0, x ! % 0) % 0 = 0hc':0 S + 1x✝:¬0 22 < 0 h: (n : ), 2 < n (!n) % n 0n:S:hn:2 < S + 1c:h_dvd:(∑ x range 0, x ! % 0) % 0 = 0hc':0 S + 1x✝:¬0 2hc:0 2¬0 (S + 1)! h: (n : ), 2 < n (!n) % n 0n:S:hn:2 < S + 1c:h_dvd:(∑ x range 0, x ! % 0) % 0 = 0hc':0 S + 1x✝:¬0 2hc:0 2¬(S + 1)! = 0 All goals completed! 🐙 h: (n : ), 2 < n (!n) % n 0n:S:hn:2 < S + 1c:hc:1 (S + 1)!h_dvd:(∑ x range 1, x ! % 1) % 1 = 0hc':1 S + 1x✝:¬1 22 < 1 All goals completed! 🐙 h: (n : ), 2 < n (!n) % n 0n:S✝:hn:2 < S + 1c:S:hc:S + 3 (S✝ + 1)!h_dvd:(∑ x range (S + 3), x ! % (S + 3)) % (S + 3) = 0hc':S + 3 S✝ + 1x✝:¬S + 3 22 < S + 3 All goals completed! 🐙

Sanity check: for small values we can just compute that the conjecture is true

@[category test, AMS 11] theorem kurepa_conjecture.variants.first_cases (n : ) (h_n : 2 < n) (h_n_upper : n < 50) : (!n : ) % n 0 := n:h_n:2 < nh_n_upper:n < 50(!n) % n 0 n:h_n:2 < 3h_n_upper:3 < 50(!3) % 3 0n:h_n:2 < 4h_n_upper:4 < 50(!4) % 4 0n:h_n:2 < 5h_n_upper:5 < 50(!5) % 5 0n:h_n:2 < 6h_n_upper:6 < 50(!6) % 6 0n:h_n:2 < 7h_n_upper:7 < 50(!7) % 7 0n:h_n:2 < 8h_n_upper:8 < 50(!8) % 8 0n:h_n:2 < 9h_n_upper:9 < 50(!9) % 9 0n:h_n:2 < 10h_n_upper:10 < 50(!10) % 10 0n:h_n:2 < 11h_n_upper:11 < 50(!11) % 11 0n:h_n:2 < 12h_n_upper:12 < 50(!12) % 12 0n:h_n:2 < 13h_n_upper:13 < 50(!13) % 13 0n:h_n:2 < 14h_n_upper:14 < 50(!14) % 14 0n:h_n:2 < 15h_n_upper:15 < 50(!15) % 15 0n:h_n:2 < 16h_n_upper:16 < 50(!16) % 16 0n:h_n:2 < 17h_n_upper:17 < 50(!17) % 17 0n:h_n:2 < 18h_n_upper:18 < 50(!18) % 18 0n:h_n:2 < 19h_n_upper:19 < 50(!19) % 19 0n:h_n:2 < 20h_n_upper:20 < 50(!20) % 20 0n:h_n:2 < 21h_n_upper:21 < 50(!21) % 21 0n:h_n:2 < 22h_n_upper:22 < 50(!22) % 22 0n:h_n:2 < 23h_n_upper:23 < 50(!23) % 23 0n:h_n:2 < 24h_n_upper:24 < 50(!24) % 24 0n:h_n:2 < 25h_n_upper:25 < 50(!25) % 25 0n:h_n:2 < 26h_n_upper:26 < 50(!26) % 26 0n:h_n:2 < 27h_n_upper:27 < 50(!27) % 27 0n:h_n:2 < 28h_n_upper:28 < 50(!28) % 28 0n:h_n:2 < 29h_n_upper:29 < 50(!29) % 29 0n:h_n:2 < 30h_n_upper:30 < 50(!30) % 30 0n:h_n:2 < 31h_n_upper:31 < 50(!31) % 31 0n:h_n:2 < 32h_n_upper:32 < 50(!32) % 32 0n:h_n:2 < 33h_n_upper:33 < 50(!33) % 33 0n:h_n:2 < 34h_n_upper:34 < 50(!34) % 34 0n:h_n:2 < 35h_n_upper:35 < 50(!35) % 35 0n:h_n:2 < 36h_n_upper:36 < 50(!36) % 36 0n:h_n:2 < 37h_n_upper:37 < 50(!37) % 37 0n:h_n:2 < 38h_n_upper:38 < 50(!38) % 38 0n:h_n:2 < 39h_n_upper:39 < 50(!39) % 39 0n:h_n:2 < 40h_n_upper:40 < 50(!40) % 40 0n:h_n:2 < 41h_n_upper:41 < 50(!41) % 41 0n:h_n:2 < 42h_n_upper:42 < 50(!42) % 42 0n:h_n:2 < 43h_n_upper:43 < 50(!43) % 43 0n:h_n:2 < 44h_n_upper:44 < 50(!44) % 44 0n:h_n:2 < 45h_n_upper:45 < 50(!45) % 45 0n:h_n:2 < 46h_n_upper:46 < 50(!46) % 46 0n:h_n:2 < 47h_n_upper:47 < 50(!47) % 47 0n:h_n:2 < 48h_n_upper:48 < 50(!48) % 48 0n:h_n:2 < 49h_n_upper:49 < 50(!49) % 49 0 n:h_n:2 < 3h_n_upper:3 < 50(!3) % 3 0n:h_n:2 < 4h_n_upper:4 < 50(!4) % 4 0n:h_n:2 < 5h_n_upper:5 < 50(!5) % 5 0n:h_n:2 < 6h_n_upper:6 < 50(!6) % 6 0n:h_n:2 < 7h_n_upper:7 < 50(!7) % 7 0n:h_n:2 < 8h_n_upper:8 < 50(!8) % 8 0n:h_n:2 < 9h_n_upper:9 < 50(!9) % 9 0n:h_n:2 < 10h_n_upper:10 < 50(!10) % 10 0n:h_n:2 < 11h_n_upper:11 < 50(!11) % 11 0n:h_n:2 < 12h_n_upper:12 < 50(!12) % 12 0n:h_n:2 < 13h_n_upper:13 < 50(!13) % 13 0n:h_n:2 < 14h_n_upper:14 < 50(!14) % 14 0n:h_n:2 < 15h_n_upper:15 < 50(!15) % 15 0n:h_n:2 < 16h_n_upper:16 < 50(!16) % 16 0n:h_n:2 < 17h_n_upper:17 < 50(!17) % 17 0n:h_n:2 < 18h_n_upper:18 < 50(!18) % 18 0n:h_n:2 < 19h_n_upper:19 < 50(!19) % 19 0n:h_n:2 < 20h_n_upper:20 < 50(!20) % 20 0n:h_n:2 < 21h_n_upper:21 < 50(!21) % 21 0n:h_n:2 < 22h_n_upper:22 < 50(!22) % 22 0n:h_n:2 < 23h_n_upper:23 < 50(!23) % 23 0n:h_n:2 < 24h_n_upper:24 < 50(!24) % 24 0n:h_n:2 < 25h_n_upper:25 < 50(!25) % 25 0n:h_n:2 < 26h_n_upper:26 < 50(!26) % 26 0n:h_n:2 < 27h_n_upper:27 < 50(!27) % 27 0n:h_n:2 < 28h_n_upper:28 < 50(!28) % 28 0n:h_n:2 < 29h_n_upper:29 < 50(!29) % 29 0n:h_n:2 < 30h_n_upper:30 < 50(!30) % 30 0n:h_n:2 < 31h_n_upper:31 < 50(!31) % 31 0n:h_n:2 < 32h_n_upper:32 < 50(!32) % 32 0n:h_n:2 < 33h_n_upper:33 < 50(!33) % 33 0n:h_n:2 < 34h_n_upper:34 < 50(!34) % 34 0n:h_n:2 < 35h_n_upper:35 < 50(!35) % 35 0n:h_n:2 < 36h_n_upper:36 < 50(!36) % 36 0n:h_n:2 < 37h_n_upper:37 < 50(!37) % 37 0n:h_n:2 < 38h_n_upper:38 < 50(!38) % 38 0n:h_n:2 < 39h_n_upper:39 < 50(!39) % 39 0n:h_n:2 < 40h_n_upper:40 < 50(!40) % 40 0n:h_n:2 < 41h_n_upper:41 < 50(!41) % 41 0n:h_n:2 < 42h_n_upper:42 < 50(!42) % 42 0n:h_n:2 < 43h_n_upper:43 < 50(!43) % 43 0n:h_n:2 < 44h_n_upper:44 < 50(!44) % 44 0n:h_n:2 < 45h_n_upper:45 < 50(!45) % 45 0n:h_n:2 < 46h_n_upper:46 < 50(!46) % 46 0n:h_n:2 < 47h_n_upper:47 < 50(!47) % 47 0n:h_n:2 < 48h_n_upper:48 < 50(!48) % 48 0n:h_n:2 < 49h_n_upper:49 < 50(!49) % 49 0 All goals completed! 🐙

Sanity check: for small values we can just compute that the conjecture is true.

@[category test, AMS 11] theorem kurepa_conjecture.variants.gcd.first_cases (n : ) (h_n : 2 < n) (h_n_upper : n < 50) : (n !).gcd (! n) = 2 := n:h_n:2 < nh_n_upper:n < 50n !.gcd (!n) = 2 n:h_n:2 < 3h_n_upper:3 < 503!.gcd (!3) = 2n:h_n:2 < 4h_n_upper:4 < 504!.gcd (!4) = 2n:h_n:2 < 5h_n_upper:5 < 505!.gcd (!5) = 2n:h_n:2 < 6h_n_upper:6 < 506!.gcd (!6) = 2n:h_n:2 < 7h_n_upper:7 < 507!.gcd (!7) = 2n:h_n:2 < 8h_n_upper:8 < 508!.gcd (!8) = 2n:h_n:2 < 9h_n_upper:9 < 509!.gcd (!9) = 2n:h_n:2 < 10h_n_upper:10 < 5010!.gcd (!10) = 2n:h_n:2 < 11h_n_upper:11 < 5011!.gcd (!11) = 2n:h_n:2 < 12h_n_upper:12 < 5012!.gcd (!12) = 2n:h_n:2 < 13h_n_upper:13 < 5013!.gcd (!13) = 2n:h_n:2 < 14h_n_upper:14 < 5014!.gcd (!14) = 2n:h_n:2 < 15h_n_upper:15 < 5015!.gcd (!15) = 2n:h_n:2 < 16h_n_upper:16 < 5016!.gcd (!16) = 2n:h_n:2 < 17h_n_upper:17 < 5017!.gcd (!17) = 2n:h_n:2 < 18h_n_upper:18 < 5018!.gcd (!18) = 2n:h_n:2 < 19h_n_upper:19 < 5019!.gcd (!19) = 2n:h_n:2 < 20h_n_upper:20 < 5020!.gcd (!20) = 2n:h_n:2 < 21h_n_upper:21 < 5021!.gcd (!21) = 2n:h_n:2 < 22h_n_upper:22 < 5022!.gcd (!22) = 2n:h_n:2 < 23h_n_upper:23 < 5023!.gcd (!23) = 2n:h_n:2 < 24h_n_upper:24 < 5024!.gcd (!24) = 2n:h_n:2 < 25h_n_upper:25 < 5025!.gcd (!25) = 2n:h_n:2 < 26h_n_upper:26 < 5026!.gcd (!26) = 2n:h_n:2 < 27h_n_upper:27 < 5027!.gcd (!27) = 2n:h_n:2 < 28h_n_upper:28 < 5028!.gcd (!28) = 2n:h_n:2 < 29h_n_upper:29 < 5029!.gcd (!29) = 2n:h_n:2 < 30h_n_upper:30 < 5030!.gcd (!30) = 2n:h_n:2 < 31h_n_upper:31 < 5031!.gcd (!31) = 2n:h_n:2 < 32h_n_upper:32 < 5032!.gcd (!32) = 2n:h_n:2 < 33h_n_upper:33 < 5033!.gcd (!33) = 2n:h_n:2 < 34h_n_upper:34 < 5034!.gcd (!34) = 2n:h_n:2 < 35h_n_upper:35 < 5035!.gcd (!35) = 2n:h_n:2 < 36h_n_upper:36 < 5036!.gcd (!36) = 2n:h_n:2 < 37h_n_upper:37 < 5037!.gcd (!37) = 2n:h_n:2 < 38h_n_upper:38 < 5038!.gcd (!38) = 2n:h_n:2 < 39h_n_upper:39 < 5039!.gcd (!39) = 2n:h_n:2 < 40h_n_upper:40 < 5040!.gcd (!40) = 2n:h_n:2 < 41h_n_upper:41 < 5041!.gcd (!41) = 2n:h_n:2 < 42h_n_upper:42 < 5042!.gcd (!42) = 2n:h_n:2 < 43h_n_upper:43 < 5043!.gcd (!43) = 2n:h_n:2 < 44h_n_upper:44 < 5044!.gcd (!44) = 2n:h_n:2 < 45h_n_upper:45 < 5045!.gcd (!45) = 2n:h_n:2 < 46h_n_upper:46 < 5046!.gcd (!46) = 2n:h_n:2 < 47h_n_upper:47 < 5047!.gcd (!47) = 2n:h_n:2 < 48h_n_upper:48 < 5048!.gcd (!48) = 2n:h_n:2 < 49h_n_upper:49 < 5049!.gcd (!49) = 2 n:h_n:2 < 3h_n_upper:3 < 503!.gcd (!3) = 2n:h_n:2 < 4h_n_upper:4 < 504!.gcd (!4) = 2n:h_n:2 < 5h_n_upper:5 < 505!.gcd (!5) = 2n:h_n:2 < 6h_n_upper:6 < 506!.gcd (!6) = 2n:h_n:2 < 7h_n_upper:7 < 507!.gcd (!7) = 2n:h_n:2 < 8h_n_upper:8 < 508!.gcd (!8) = 2n:h_n:2 < 9h_n_upper:9 < 509!.gcd (!9) = 2n:h_n:2 < 10h_n_upper:10 < 5010!.gcd (!10) = 2n:h_n:2 < 11h_n_upper:11 < 5011!.gcd (!11) = 2n:h_n:2 < 12h_n_upper:12 < 5012!.gcd (!12) = 2n:h_n:2 < 13h_n_upper:13 < 5013!.gcd (!13) = 2n:h_n:2 < 14h_n_upper:14 < 5014!.gcd (!14) = 2n:h_n:2 < 15h_n_upper:15 < 5015!.gcd (!15) = 2n:h_n:2 < 16h_n_upper:16 < 5016!.gcd (!16) = 2n:h_n:2 < 17h_n_upper:17 < 5017!.gcd (!17) = 2n:h_n:2 < 18h_n_upper:18 < 5018!.gcd (!18) = 2n:h_n:2 < 19h_n_upper:19 < 5019!.gcd (!19) = 2n:h_n:2 < 20h_n_upper:20 < 5020!.gcd (!20) = 2n:h_n:2 < 21h_n_upper:21 < 5021!.gcd (!21) = 2n:h_n:2 < 22h_n_upper:22 < 5022!.gcd (!22) = 2n:h_n:2 < 23h_n_upper:23 < 5023!.gcd (!23) = 2n:h_n:2 < 24h_n_upper:24 < 5024!.gcd (!24) = 2n:h_n:2 < 25h_n_upper:25 < 5025!.gcd (!25) = 2n:h_n:2 < 26h_n_upper:26 < 5026!.gcd (!26) = 2n:h_n:2 < 27h_n_upper:27 < 5027!.gcd (!27) = 2n:h_n:2 < 28h_n_upper:28 < 5028!.gcd (!28) = 2n:h_n:2 < 29h_n_upper:29 < 5029!.gcd (!29) = 2n:h_n:2 < 30h_n_upper:30 < 5030!.gcd (!30) = 2n:h_n:2 < 31h_n_upper:31 < 5031!.gcd (!31) = 2n:h_n:2 < 32h_n_upper:32 < 5032!.gcd (!32) = 2n:h_n:2 < 33h_n_upper:33 < 5033!.gcd (!33) = 2n:h_n:2 < 34h_n_upper:34 < 5034!.gcd (!34) = 2n:h_n:2 < 35h_n_upper:35 < 5035!.gcd (!35) = 2n:h_n:2 < 36h_n_upper:36 < 5036!.gcd (!36) = 2n:h_n:2 < 37h_n_upper:37 < 5037!.gcd (!37) = 2n:h_n:2 < 38h_n_upper:38 < 5038!.gcd (!38) = 2n:h_n:2 < 39h_n_upper:39 < 5039!.gcd (!39) = 2n:h_n:2 < 40h_n_upper:40 < 5040!.gcd (!40) = 2n:h_n:2 < 41h_n_upper:41 < 5041!.gcd (!41) = 2n:h_n:2 < 42h_n_upper:42 < 5042!.gcd (!42) = 2n:h_n:2 < 43h_n_upper:43 < 5043!.gcd (!43) = 2n:h_n:2 < 44h_n_upper:44 < 5044!.gcd (!44) = 2n:h_n:2 < 45h_n_upper:45 < 5045!.gcd (!45) = 2n:h_n:2 < 46h_n_upper:46 < 5046!.gcd (!46) = 2n:h_n:2 < 47h_n_upper:47 < 5047!.gcd (!47) = 2n:h_n:2 < 48h_n_upper:48 < 5048!.gcd (!48) = 2n:h_n:2 < 49h_n_upper:49 < 5049!.gcd (!49) = 2 All goals completed! 🐙 end Kurepa