Theory Wieferich_Kempner

(*  Author:      Jamie Chen
    License:     LGPL      *)

theory "Wieferich_Kempner"
  imports  
  "HOL-Number_Theory.Cong"
  "HOL.Real"
  "HOL.NthRoot"
  "HOL.Transcendental"
  "HOL-Library.Code_Target_Nat"
  "Three_Squares.Three_Squares"
  Main
begin

fun sumpow :: "nat  nat list  nat" where [code_computation_unfold, coercion_enabled]:
  "sumpow p l = fold (+) (map (λx. x^p) l) 0"
declare sumpow.simps[code]

definition is_sumpow :: "nat  nat  nat  bool"
  where "is_sumpow p n m   l. length l = n  m = sumpow p l"

section ‹Technical Lemmas›
text‹We show four lemmas used in the main theorem.›
subsection ‹ Lemma 2.1 in \cite{nathanson1996}›

lemma sum_of_6_cubes:
  fixes A m :: nat
  assumes mLessASq: "m  A2"
  assumes mIsSum3Sq: "is_sumpow 2 3 m"
  shows "is_sumpow 3 6 (6 * A * (A2 + m))"
proof -
  from mIsSum3Sq obtain l where "length l = 3" and " m = sumpow 2 l"
    using is_sumpow_def by blast
  then obtain m1 m2 m3 where "l = [m1, m2, m3]"
    by (smt (verit, best) Suc_length_conv length_0_conv numeral_3_eq_3)

  obtain il where "il = map (int) l" by auto
  obtain iA where "iA = (int A)" by auto
  obtain im where "im = (int m)" by auto

  have "fold (+) (map power2 l) 0 = m12 + m22 + m32"
    using l = [m1, m2, m3] by simp
  hence "m = m12 + m22 + m32"
    using length l = 3 m = sumpow 2 l sumpow.simps by presburger
  obtain im1 im2 im3 where "il = [im1, im2, im3]"
    by (simp add: il = map int l l = [m1, m2, m3])
  hence "im1 = int m1" and "im2 = int m2" and "im3 = int m3"
    using il = map int l l = [m1, m2, m3] by auto

  obtain x1 x2 x3 where "[x1,x2,x3] = map (λx. A+x) l"
    by (simp add: l =[m1,m2,m3])
  obtain x4 x5 x6 where "[x4,x5,x6] = map (λx. A-x) l"
    by (simp add: l =[m1,m2,m3])
  obtain ns where "ns =  [x1, x2, x3, x4, x5, x6]" by auto

  have " x  set l. x  0"
    by auto
  hence " x  set l. x2  m"
    usingl = [m1, m2, m3] m = m12 + m22 + m32 power2_nat_le_imp_le by auto
  have " x  set il. x  0"
    by (simp add: il = map int l)
  hence " x  set il. x2  im"
    usingim = int m il = map int ll = [m1, m2, m3] m = m12 + m22 + m32 power2_nat_le_imp_le 
    by auto

  have " x  set il. iA + x  0"
    using iA = int A il = map int l by auto
  have "int (x1) = iA + im1"
    using [x1, x2, x3] = map ((+) A) l iA = int A il = [im1, im2, im3] il = map int l by force
  have "int (x2) = iA + im2"
    using [x1, x2, x3] = map ((+) A) l iA = int A il = [im1, im2, im3] il = map int l by force
  have "int (x3) = iA + im3"
    using [x1, x2, x3] = map ((+) A) l iA = int A il = [im1, im2, im3] il = map int l by force
  have "A  m1"
    by (metis m = m12 + m22 + m32 add_leE mLessASq power2_nat_le_eq_le)
  hence "iA - im1  0"
    using iA = int A il = [im1, im2, im3] il = map int l l = [m1, m2, m3] by auto
  hence "int x4 = iA - im1"
    using [x4, x5, x6] = map ((-) A) l iA = int A im1 = int m1 l = [m1, m2, m3] by auto
  have "A  m2"
    by (metis m = m12 + m22 + m32 add_leE mLessASq power2_nat_le_eq_le)
  hence "iA - im2  0"
    using iA = int A il = [im1, im2, im3] il = map int l l = [m1, m2, m3] by auto
  hence "int x5 = iA - im2"
    using [x4, x5, x6] = map ((-) A) l iA = int A im2 = int m2l = [m1, m2, m3] by auto
  have "A  m3"
    by (metis m = m12 + m22 + m32 add_leE mLessASq power2_nat_le_eq_le)
  hence "iA - im3  0"
    using iA = int A il = [im1, im2, im3] il = map int l l = [m1, m2, m3] by auto
  hence "int x6 = iA - im3"
    using [x4, x5, x6] = map ((-) A) l iA = int A im3 = int m3 l = [m1, m2, m3] by auto

  have "6*A*(A2+m) = 6*A*(A2 + sumpow 2 l)"
    by (simp add:m = sumpow 2 l)
  have distr: " = 6*A^3 +6*A*(sumpow 2 l)"
    by (simp add: distrib_left power2_eq_square power3_eq_cube) 
  have " = 6*A*(A2 + m12 + m22 + m32)"
    using m = m12 + m22 + m32 m = sumpow 2 l by (metis distr group_cancel.add1)
  hence expanded: "int  = 6*iA*(iA2 +  im12 +im22 + im32)"
    using iA = int A im1 = int m1 im2 = int m2 im3 = int m3 by simp
  have sixcubes: " = (iA + im1)^3 + (iA - im1)^3 +
                       (iA + im2)^3 + (iA - im2)^3 +
                       (iA + im3)^3 + (iA - im3)^3"
    by Groebner_Basis.algebra
  have " = int x1^3 + int x2^3 + int x3^3 + int x4^3 + int x5^3 + int x6^3"
    using int x1 = iA + im1 int x2 = iA + im2 int x3 = iA + im3 
          int x4 = iA - im1 int x5 = iA - im2 int x6 = iA - im3 by simp
  hence "6*A*(A2+m) = x1^3 + x2^3 + x3^3 + x4^3 + x5^3 + x6^3"
    using distr m = sumpow 2 l m = m12 + m22 + m32 expanded of_nat_eq_iff sixcubes 
    by (smt (verit) of_nat_add of_nat_power)
  have "map (λx. x^3) ns = [x1^3, x2^3, x3^3, x4^3, x5^3, x6^3]"
    by (simp add: ns = [x1, x2, x3, x4, x5, x6])
  hence "sumpow 3 ns = x1^3 + x2^3 + x3^3 + x4^3 + x5^3 + x6^3"
    by (simp add: ns = [x1, x2, x3, x4, x5, x6])
  hence "6*A*(A2+m) = sumpow 3 ns"
    using 6 * A * (A2 + m) = x1 ^ 3 + x2 ^ 3 + x3 ^ 3 + x4 ^ 3 + x5 ^ 3 + x6 ^ 3 by presburger
  hence "length ns = 6  6*A*(A2+m) = sumpow 3 ns"
    by (simp add: ns = [x1, x2, x3, x4, x5, x6])
  then show ?thesis
    using is_sumpow_def by blast
qed

subsection ‹ Lemma 2.2 in \cite{nathanson1996}›

lemma if_cube_cong_then_cong:
  fixes t :: nat
  fixes b1 b2 :: int
  assumes odd: "odd b1  odd b2"
  assumes "b1 > 0  b2 > 0"
  assumes tGeq1: "t  1"
  assumes "[b1^3 = b2^3] (mod 2^t)"
  shows "[b1  b2] (mod 2^t)  [b1^3  b2^3] (mod 2^t)"
proof -
  have "[b2^3 - b1^3 = 0] (mod 2^t)"
    using [b1 ^ 3 = b2 ^ 3] (mod 2 ^ t) cong_diff_iff_cong_0 cong_sym_eq by blast
  have "(b2 - b1)*(b22 + b2*b1 + b12) = b2^3 - b1^3"
    by Groebner_Basis.algebra
  hence "[(b2-b1)*(b22 + b2*b1 + b12) = 0] (mod 2^t)"
    using [b2 ^ 3 - b1 ^ 3 = 0] (mod 2 ^ t) by auto
  have "coprime (b22 + b2*b1 + b12) (2^t)"
    by (simp add: odd)
  hence "[b2 - b1 = 0] (mod 2^t)"
    by (metis [(b2 - b1) * (b22 + b2 * b1 + b12) = 0] (mod 2 ^ t) cong_mult_rcancel mult_zero_left)
  hence "[b1 = b2] (mod 2^t)"
    using cong_diff_iff_cong_0 cong_sym_eq by blast
  assume "[b1  b2] (mod 2^t)"
  then show ?thesis
    using [b1 = b2] (mod 2^t) by auto
qed

lemma every_odd_nat_cong_cube:
  fixes t w :: nat
  assumes tPositive: "t  1"
  assumes wOdd: "odd w"
  shows "b. odd b  [w = b^3] (mod 2^t)"
proof (rule ccontr)
  assume "¬?thesis"
  hence "b. odd b  [w  b^3] (mod 2^t)"
    by blast
  obtain b::nat where "odd b"
    using odd_numeral by blast
  hence "[w  b^3] (mod 2^t)"
    by (simp add: b. odd b  [w  b ^ 3] (mod 2 ^ t))
  obtain bSet::"nat set" where bSet_def: "bSet = {x. odd x  x < 2^t}"
    by auto
  obtain w' where w'_def: "w' = w mod 2^t"
    by auto
  hence "odd w'"
    by (metis dvd_mod_imp_dvd dvd_power order_less_le_trans tPositive wOdd zero_less_one)
  have "w' < 2^t"
    by (simp add: w' = w mod 2^t)
  hence "w'  bSet"
    by (simp add: bSet = {x. odd x  x < 2 ^ t} odd w')
  define bSetMinusW'::"nat set" where "bSetMinusW' = {x. x  bSet  x  w'}"

  have "x  bSet. [w  x^3] (mod 2^t)"
    using b. odd b  [w  b ^ 3] (mod 2 ^ t) bSet = {x. odd x  x < 2 ^ t} by blast
  have "x  bSet. odd (x^3)"
    using bSet_def by simp
  have "even (2^t)"
    using tPositive by fastforce
  hence "x  bSet. odd (x^3 mod 2^t)"
    using xbSet. odd (x^3) dvd_mod_iff by blast
  hence " x  bSet. (x^3 mod 2^t)  bSet"
    by (simp add: bSet = {x. odd x  x < 2 ^ t})
  hence " x  bSet. (x^3 mod 2^t)  bSetMinusW'"
    using xbSet. [w  x ^ 3] (mod 2 ^ t) bSetMinusW'_def w'_def cong_def
    by (metis (mono_tags, lifting) mem_Collect_eq unique_euclidean_semiring_class.cong_def)
  hence " x  bSet.  y  bSetMinusW'. [y = x^3] (mod 2^t)"
    using cong_mod_right cong_refl by blast
  hence " x  bSet. ∃! y  bSetMinusW'. [y = x^3] (mod 2^t)"
    by (metis (no_types, lifting) bSet_def bSetMinusW'_def unique_euclidean_semiring_class.cong_def 
        mem_Collect_eq mod_less)
  have " x1  bSet. x2  bSet. odd x1  odd x2"
    using bSet_def by auto

  hence " x1  bSet.  x2  bSet. [x1  x2] (mod 2^t)  [x1^3  x2^3] (mod 2^t)"
    by (metis (mono_tags) cong_int_iff even_of_nat if_cube_cong_then_cong odd_pos of_nat_0_less_iff 
        of_nat_numeral of_nat_power tPositive)
  hence " x1  bSet.  x2  bSet. x1  x2  [x1^3  x2^3] (mod 2^t)"
    using bSet_def cong_less_modulus_unique_nat by blast
  hence "inj_on (λ x. x^3 mod 2^t) bSet"
    by (meson inj_onI unique_euclidean_semiring_class.cong_def)

  have "bSetMinusW'  bSet"
    using bSetMinusW'_def w'  bSet by blast 
  moreover hence "card bSetMinusW' < card bSet"
    by (simp add: bSet_def psubset_card_mono)
  moreover have "(λ x. x^3 mod 2^t) ` bSet  bSetMinusW'"
    using xbSet. x ^ 3 mod 2 ^ t  bSetMinusW' by blast
  ultimately have "card ((λ x. x^3 mod 2^t) ` bSet) < card bSet"
    by (metis card.infinite less_zeroE psubset_card_mono subset_psubset_trans)
  hence "¬inj_on (λ x. x^3 mod 2^t) bSet"
    using pigeonhole by auto
  thus False
    using inj_on (λx. x ^ 3 mod 2 ^ t) bSet by blast
qed

subsection ‹ Lemma 2.3 in \cite{nathanson1996}›
text‹It is this section in which we use the Three Squares Theorem AFP Entry \cite{Three_Squares-AFP}.›

lemma sum_of_3_squares_exceptions:
  fixes m::nat
  assumes notSum3Sq: "¬is_sumpow 2 3 m"
  shows "6*m mod 96  {0,72,42,90}"
proof -
  have "¬( l. length l = 3  m = sumpow 2 l)"
    using is_sumpow_def notSum3Sq by blast
  hence "¬( a b c. m = sumpow 2 [a,b,c])"
    by (metis length_Cons list.size(3) numeral_3_eq_3)
  hence "¬( a b c. m = fold (+) (map power2 [a,b,c]) 0)"
    by auto
  hence "¬( a b c. m = fold (+) [a2,b2,c2] 0)"
    by auto
  hence "¬( a b c. m = a2 + b2 + c2)"
    by (simp add: add.commute)
  then obtain s t where "(m = 4^s*(8*t + 7))"
    using three_squares_iff by auto
  obtain h'::"nat set" where "h' = {0,72,42,90}" 
    by auto
  consider (s0) "s = 0"| (s1) "s = 1" | (s2) "s2"
    by arith
  hence "6*4^s*(8*t + 7) mod 96  h'"
  proof cases
    case s0
    consider (even) "even t" | (odd) "odd t"
      by auto
    thus "6*4^s*(8*t + 7) mod 96  h'"
    proof cases
      case even
      obtain t' where "t' =  t div 2"
        by simp
      hence "6*4^s*(8*t+7) = 96*t' + 42"
        using s0 even by fastforce
      hence "6*4^s*(8*t+7) mod 96 = 42"
        by (simp add: cong_0_iff cong_add_rcancel_0_nat)
      have "42  h'"
        by (simp add: h' = {0, 72, 42, 90})
      thus "6*4^s*(8*t + 7) mod 96  h'"
        by (simp add: 6 * 4 ^ s * (8 * t + 7) mod 96 = 42)
    next
      case odd
      obtain t' where "t' =  (t-1) div 2"
        by simp
      hence "6*4^s*(8*t+7) = 6*(8*(2*t'+1)+7)"
        by (simp add: s0 odd)
      hence "6*4^s*(8*t+7) mod 96 = 90"
        using cong_le_nat by auto
      have "90  h'"
        by (simp add: h' = {0, 72, 42, 90})
      thus "6*4^s*(8*t + 7) mod 96  h'"
        by (simp add: 6 * 4 ^ s * (8 * t + 7) mod 96 = 90)
    qed
  next
    case s1
    have "6*4^s*(8*t+7) = 96*(2*t + 1) + 72"
      using s1 by auto
    hence "[6*4^s*(8*t+7) = 72] (mod 96)"
    by (metis cong_add_rcancel_0_nat cong_mult_self_left)
  hence "6*4^s*(8*t+7) mod 96 = 72 mod 96"
    using unique_euclidean_semiring_class.cong_def by blast
    hence "6*4^s*(8*t+7) mod 96 = 72"
      by auto
    have "72  h'"
      by (simp add: h' = {0, 72, 42, 90})
    thus "6*4^s*(8*t + 7) mod 96  h'"
      by (simp add:6 * 4 ^ s * (8 * t + 7) mod 96 = 72)
  next
    case s2
    obtain s' where "s' = s-2"
      by simp
    have "6*4^s*(8*t+7) = 6*4^2*4^s'*(8*t+7)"
      by (metis s' = s - 2 le_add_diff_inverse mult.assoc power_add s2)
    have " = 96*4^s'*(8*t+7)"
      by auto
    hence "[6*4^s*(8*t+7) = 0] (mod 96)"
      by (metis 6*4^s*(8*t + 7) = 6*42*4^s'*(8*t + 7) cong_modulus_mult_nat cong_mult_self_left)
    hence "6*4^s*(8*t+7) mod 96 = 0 mod 96"
    using unique_euclidean_semiring_class.cong_def by blast
    hence "6*4^s*(8*t+7) mod 96 = 0"
      by auto
    have "0  h'"
      by (simp add: h' = {0, 72, 42, 90})
    thus "6*4^s*(8*t + 7) mod 96  h'"
      by (simp add: 6 * 4 ^ s * (8 * t + 7) mod 96 = 0)
  qed
  thus ?thesis
     by (metis h' = {0, 72, 42, 90} m = 4 ^ s * (8 * t + 7) mult.assoc)
qed

lemma values_geq_22_cubed_can_be_normalised:
  fixes r :: nat
  assumes rLarge: " r  10648" (*10648 = 223*)
  obtains d m where "d  0" and "d  22" and "r = d^3 + 6*m" and "is_sumpow 2 3 m"
proof -
  define MultiplesOf6LessThan96::"nat set" where 
    "MultiplesOf6LessThan96 = {0,6,12,18,24,30,36,42,48,54,60,66,72,78,84,90}"
  have "m'   MultiplesOf6LessThan96. m' < 96"
    unfolding MultiplesOf6LessThan96_def by auto
  have " m'  MultiplesOf6LessThan96. m' mod 6 = 0"
    unfolding MultiplesOf6LessThan96_def by auto
  hence "m  MultiplesOf6LessThan96. n. m = 6*n"
     by fastforce
  have "m'  MultiplesOf6LessThan96. m' mod 96 = m'"
    by (simp add: m'MultiplesOf6LessThan96. m' < 96)

  define H'::"nat set" where "H' = {0,42,72,90}"

  have "m'. 6*m' mod 96  H'  is_sumpow 2 3 m'"
    unfolding H'_def using sum_of_3_squares_exceptions by blast
  hence "m'. (6*m' mod 96  MultiplesOf6LessThan96 - H')  is_sumpow 2 3 m'"
    by fastforce

  define H::"nat set" where "H = {6, 12, 18, 24, 30, 36, 48, 54, 60, 66, 78, 84}"
  have "H =  MultiplesOf6LessThan96 - H'"
    unfolding H_def MultiplesOf6LessThan96_def H'_def by auto
  hence "m'. 6*m' mod 96  H  is_sumpow 2 3 m'"
    using m'. 6 * m' mod 96  MultiplesOf6LessThan96 - H'  is_sumpow 2 3 m' by blast

  define D::"nat set" where "D = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22}"
  have "d  D. d  0  d  22"
    using D_def by auto
  define residue::"nat set" where "residue = {x.  h  H.  d  D. x = (d^3 + h) mod 96}"
(*for some reason Isabelle doesn't like it when you do this in steps larger than 10*)
  have "x<10. x  residue"
    unfolding residue_def H_def D_def by auto
  moreover have "x 10. x < 19  x  residue"
    unfolding residue_def H_def D_def by auto
  moreover have "x 19. x < 28  x  residue"
    unfolding residue_def H_def D_def by auto
  moreover have "x 28. x < 37  x  residue"
    unfolding residue_def H_def D_def by auto
  moreover have "x 37. x < 46  x  residue"
    unfolding residue_def H_def D_def by auto
  moreover have "x 46. x < 55  x  residue"
    unfolding residue_def H_def D_def by auto
  moreover have "x 55. x < 64  x  residue"
    unfolding residue_def H_def D_def by auto
  moreover have "x 64. x < 73  x  residue"
    unfolding residue_def H_def D_def by auto
  moreover have "x 73. x < 82  x  residue"
    unfolding residue_def H_def D_def by auto
  moreover have "x 82. x < 91  x  residue"
    unfolding residue_def H_def D_def by auto
  moreover have "x 91. x < 96  x  residue"
    unfolding residue_def H_def D_def by auto
  ultimately have "x < 96. x  residue"
    by (metis leI)

  have " r  residue.  h  H.  d  D. r = (d^3 + h) mod 96"
    unfolding residue_def by auto
  have " h  H.  d  D. (d^3 + h) mod 96  residue"
    by (simp add: x<96. x  residue)
  have "r mod 96  residue"
    by (simp add: x<96. x  residue)
  have "d  D. r  d^3"
    unfolding D_def using rLarge by auto
  hence " h  H.  d  D. [d^3 + h = r] (mod 96)"
    using r mod 96  residue
    by (metis rresidue. hH. dD. r = (d ^ 3 + h) mod 96 unique_euclidean_semiring_class.cong_def)
  hence " h  H.  d  D. [r - d^3 = h] (mod 96)"
    by (smt (z3) dD. d^3  r add.commute add_diff_cancel_right' cong_diff_nat cong_refl le_add2)
  then obtain h d where "h  H" and "d  D" and "[r - d^3 = h] (mod 96)"
    by auto
  then obtain h' where "h' mod 96 = h" and "r - d^3 = h'"
    using H = MultiplesOf6LessThan96 - H' m'MultiplesOf6LessThan96. m' mod 96 = m' 
    by (simp add: unique_euclidean_semiring_class.cong_def)
  have "[h = 0] (mod 6)"
    using H = MultiplesOf6LessThan96 - H' mMultiplesOf6LessThan96. n. m = 6*n h  H 
      cong_mult_self_left by fastforce
  hence "[h' = 0] (mod 6)"
    using [r-d^3 = h] (mod 96) r-d^3 = h' unique_euclidean_semiring_class.cong_def
    by (metis cong_dvd_modulus_nat dvd_triv_right num_double numeral_mult)
  then obtain m where "6*m = h'"
    by (metis cong_0_iff dvd_def)
  moreover hence "is_sumpow 2 3 m"
    using m'. 6 * m' mod 96  H  is_sumpow 2 3 m' by (simp add:h  H h' mod 96 = h)
  moreover have "d  0" 
    by auto
  moreover have "d  22"
    by (simp add: dD. 0  d  d  22 d  D)
  ultimately show "?thesis"
    by (metis dD. d ^ 3  r d  Dr - d ^ 3 = h' le_add_diff_inverse that)
qed

subsection ‹Lemma 2.4 in \cite{nathanson1996}›

partial_function(tailrec) list_builder :: "nat  nat  nat list  nat list" 
  where [code_computation_unfold, coercion_enabled]:
    "list_builder m n l = (if n = 0 then l else (list_builder m (n-1) (m#l)))"
declare list_builder.simps[code]

partial_function(tailrec) dec_list :: "nat  nat list  nat list" 
  where [code_computation_unfold, coercion_enabled]:
    "dec_list depth l = (if (tl l) = [] then list_builder (hd l + 1) (depth+1) [] else 
    if hd l  hd (tl l) + 1 then dec_list (depth+1) ((hd (tl l) + 1)#(tl (tl l))) else
    list_builder (hd (tl l) + 1) (depth + 2) (tl (tl l)))"
declare dec_list.simps[code]

partial_function(tailrec) sumcubepow_finder ::"nat  nat list  nat list" 
  where [code_computation_unfold, coercion_enabled]:
    "sumcubepow_finder n l = (if (sumpow 3 l < n) then 
    (sumcubepow_finder n ((Suc (hd l))#(tl l)))
    else if (sumpow 3 l) = n then l else sumcubepow_finder n  (dec_list 0 l))"
declare sumcubepow_finder.simps[code]

lemma leq_40000_is_sum_of_9_cubes:
  fixes n :: nat
  assumes "n  40000"
  shows "is_sumpow 3 9 n" and "n > 8042  is_sumpow 3 6 n"
proof -
  (* split computation into chunks so that computation is done in parallel *)
  let ?A1 = "[8043 ..< 15000]" 
  let ?A2 = "[15000 ..< 23000]" 
  let ?A3 = "[23000 ..< 29000]" 
  let ?A4 = "[29000 ..< 35000]" 
  let ?A5 = "[35000 ..< 40001]" 
  (* let expression to avoid duplicate computation of result *)
  let ?test = "λ n. let result = sumcubepow_finder n [0,0,0,0,0,0] in
     sumpow 3 result = n  length result = 6" 
  have split: " n. n  40000  n > 8042  
    n  set ?A1  n  set ?A2  n  set ?A3  n  set ?A4  n  set ?A5" 
    unfolding set_upt by simp linarith
  have " n  set ?A1. ?test n"
    by eval (*takes a while to compute*)
  moreover have "n  set ?A2. ?test n"
    by eval (*takes a while to compute*)
  moreover have "n  set ?A3. ?test n"
    by eval (*takes a while to compute*)
  moreover have "n  set ?A4. ?test n"
    by eval (*takes a while to compute*)
  moreover have "n  set ?A5. ?test n"
    by eval (*takes a while to compute*)
  ultimately have "n  40000. n > 8042  ?test n" using split by blast
  then have "n40000. n > 8042  is_sumpow 3 6 n"
    using is_sumpow_def by metis
  then show "n > 8042  is_sumpow 3 6 n"
    using n  40000 by simp
  have "n40000. n > 8042  ( l. length l = 6  n = sumpow 3 l)"
    using is_sumpow_def n40000. n > 8042  is_sumpow 3 6 n by simp
  then have "n40000. n > 8042  ( l. length (l@[0,0,0]) = 9  n = sumpow 3 (l@[0,0,0]))"
    by simp
  then have "n40000. n > 8042  is_sumpow 3 9 n"
    using is_sumpow_def by blast
  have "n  8042. let res = sumcubepow_finder n [0,0,0,0,0,0,0,0,0] in 
      sumpow 3 res = n  length res = 9"
    by eval
  then have "n8042. is_sumpow 3 9 n"
    using is_sumpow_def by metis
  then have "n  40000. is_sumpow 3 9 n"
    using n40000. n > 8042  is_sumpow 3 9 n by auto
  then show "is_sumpow 3 9 n"
    using n  40000 by simp
qed

section ‹Wieferich--Kempner Theorem›
text‹Theorem 2.1 in \cite{nathanson1996}›

theorem Wieferich_Kempner:
  fixes N :: nat
  shows "is_sumpow 3 9 N"
proof cases
  consider (ge8pow10) "N > 8^10" | (leq8pow10) "N  8^10"
    by arith
  thus ?thesis
  proof cases
    case ge8pow10
    define n::int where "n = root 3 N"
    hence "n  root 3 (8^10)"
      by (meson floor_mono ge8pow10 less_imp_le_nat numeral_power_le_of_nat_cancel_iff 
          real_root_le_iff zero_less_numeral)
    have "(2::nat)^3 = 8"
      by simp
    hence "8^10 = ((2::nat)^10)^3"
      by simp
    have "root 3 ((2::nat)^10)^3 = (2::nat)^10"
      by simp
    hence "n  (2::nat)^10"
      by (metis 8^10 = (2^10)^3 root 3 (8^10)  n of_nat_numeral of_nat_power power3_eq_cube 
          real_root_mult)
    hence ngeq2pow10: " n  (2::nat)^10"
      by auto
    obtain k::int where "k = (log 8 (N/8))/3-1"
      by simp
    hence "3*k < (log 8 (N/8))"
      by linarith
    hence "8*(8 powr (3*k)) < N"
      using ge8pow10 less_log_iff by simp
    have "k+1  (log 8 (N/8))/3"
      by (simp add: k = log 8 (real N / 8) / 3 - 1)
    hence "8 powr (3*(k+1))  8 powr (log 8 (N/8))"
      by simp
    hence "8*(8 powr (3*(k+1)))  N"
      using ge8pow10 by simp
    have "(N/8) > 8^9"
      using ge8pow10 by simp
    hence "(log 8 (N/8)) > 9"
      by (metis less_log_of_power numeral_One numeral_less_iff of_nat_numeral semiring_norm(76))
    hence "(log 8 (N/8))/3 > 3"
      by simp
    hence "k  3"
      using k = (log 8 (N/8))/3-1 by simp

    define i::int where "i = root 3 (N - (8*(8 powr (3*k))))"
    hence "i  root 3 (N - (8*(8 powr (3*k))))"
      by fastforce
    have "root 3 (N - (8*(8 powr (3*k))))  0"
      using 8*(8 powr (3 * k)) < N by force
    hence "i  0"
      by (simp add: i_def)
    hence "i^3  (root 3 (N - (8*(8 powr (3*k)))))^3"
      using i  root 3 (N - 8 * 8 powr (3*k)) power_mono by fastforce    
    hence "i^3  N - (8*(8 powr (3*k)))"
      using 8 * 8 powr (3*k) < N by force
    hence exp01:"8*(8 powr (3*k))  N - i^3"
      by simp
    have "i+1 > root 3 (N - (8*(8 powr (3*k))))"
      by (simp add: i_def)
    hence "(i+1)^3 > (root 3 (N - (8*(8 powr (3*k)))))^3"
      by (metis 0  root 3 (N - 8 * 8 powr (3*k)) of_int_power power_strict_mono zero_less_numeral)
    hence "(i+1)^3 > (N - (8*(8 powr (3*k))))"
      using 8 * 8 powr (3*k) < N by force
    hence exp02:"8*(8 powr (3*k)) > N - (i+1)^3"
      by simp

    have "i  1"
    proof (rule ccontr)
      assume "¬ i 1"
      hence "i = 0"
        using i  0 by simp
      hence "8*(8 powr (3*k))  N"
        using 8*(8 powr (3*k))  N - i^3 by simp
      moreover have "8*(8 powr (3*k)) + 1 > N"
        using i = 0 (N - (i+1)^3) < 8*(8 powr (3*k)) ge8pow10 by auto
      moreover have " x. x  N  x + 1 > N  x = N"
        by linarith
      have "8*8^(nat(3*k)) = 8*(8 powr (3*k))"
        by (smt (verit, ccfv_SIG) 3  k powr_real_of_int)
      ultimately have "8*(8 powr (3*k)) = N"
        by (metis nat_le_real_less nle_le of_nat_le_iff of_nat_numeral of_nat_power power.simps(2))
      thus False
        using 8 * 8 powr (3 * k) < N by simp
    qed
    
    have "8 powr (3*(k+1)) = (8 powr (k+1))^3"
      by (metis of_int_mult of_int_numeral powr_ge_pzero powr_numeral powr_powr powr_powr_swap) 
    have "(x::int)1. x^3 - (x-1)^3  = 3*x^2 - 3*x +1"
      by Groebner_Basis.algebra
    hence "(x::int)1. x^3 - (x-1)^3  < 3*x^2"
      by auto
    have exp03:"(x::int)1. x  n  3*x^2  3*(root 3 N)^2"
      using n_def by (simp add: le_floor_iff)
    have "root 3 N  root 3 (8*(8 powr (3*(k+1))))"
      using N  8 * 8 powr (3 * (k + 1)) by force
    moreover have " = (root 3 8)*(root 3 ((8 powr ((k+1)))^3))"
      using 8 powr (3*(k+1)) = (8 powr (k+1))^3 real_root_mult by simp
    moreover have " = 2*(8 powr ((k+1)))"
      using odd_real_root_power_cancel by simp
    ultimately have exp04:"(root 3 N)^2  (2*(8 powr (k+1)))^2"
      by (metis of_nat_0_le_iff power_mono real_root_pos_pos_le)
    moreover hence exp05: " = (4*(8 powr ((k+1)))^2)"
      using four_x_squared by presburger
    moreover hence exp06:" = (4*(8 powr (2*(k+1))))"
      by (smt (verit) of_int_add power2_eq_square powr_add)
    moreover hence " = (8*(8 powr (2*k + 2))/2)"
      by simp
    moreover hence exp07:" = (8 powr (2*k + 3)/2)"
      by (simp add: add.commute powr_mult_base)
    ultimately have exp08:"3*(root 3 N)^2  (3*8 powr (2*k + 3))/2"
      by linarith
    have exp09:" x  1. x  n  real_of_int (x^3 - (x-1)^3) < real_of_int (3*x^2)"
      using (x::int)1. x^3 - (x-1)^3  < 3*x^2 by presburger 
    hence " x  1. x  n x^3 - (x-1)^3 < 3*(root 3 N)^2"
      using exp03 less_le_trans 
      by fastforce
    hence exp10:" x  1. x  n x^3 - (x-1)^3  (3*8 powr (2*k + 3))/2"
      using exp08 by fastforce

    have "(root 3 N)^3 = N"
      by simp
    have "root 3 N < n+1"
      using n_def by linarith
    hence "(root 3 N)^3 < (n+1)^3"
      by (metis of_int_power of_nat_0_le_iff real_root_pos_pos_le zero_less_numeral power_strict_mono)
   
    text‹The following few lines have been slightly modified from the original proof to simplify 
formalisation.  This does not affect the proof in any meaningful way.›
    hence exp11:"N - n^3 < (n+1)^3 - n^3"
      using (root 3 N)^3 = N by linarith
    have exp12:" = 3*n^2 + 3*n + 1"
      by Groebner_Basis.algebra
    have exp13:"  6*n^2 + 1"
      using n  (2::nat)^10 power_strict_mono by (simp add: self_le_power)
    have "  6*(root 3 N)^2 + 1"
      using n_def by auto
    have "  (3*8 powr (2*k + 3))+1"
      using 3*(root 3 N)^2  (3*8 powr (2*k + 3))/2 by auto
    hence exp14:"  4*8 powr (2*k + 3)"
      using 3  k ge_one_powr_ge_zero by auto
    hence exp15:"  8*8 powr(3*k)"
      by (smt (verit, best) 3  k of_int_le_iff powr_mono)

    have "6*n^2 3*8 powr (2*k + 3)"
      using 6*(root 3 N)2 + 1  3*8 powr (2*k + 3)+1 (6*n2 + 1)  6*(root 3 N)2 + 1 by linarith
    hence "i  n-1"
      using exp12 exp14 exp13 exp01 i_def n_def exp11 exp15
      by (smt (verit, ccfv_SIG) floor_mono of_int_less_iff real_root_le_iff zero_less_numeral)
    hence "N - (i+1)^3  8*8 powr (3*k)"
      using (int N - (i + 1) ^ 3) < 8 * 8 powr (3*k) by linarith
    hence "N  (i+1)^3"
      using exp04 exp06 exp15 exp07 exp01 exp03 exp09 i  n - 1 0  i 
      by (smt (verit, ccfv_threshold) divide_cancel_right exp05 of_int_0_le_iff of_int_diff)
    have exp16:"((i+1)^3 - i^3)  3*8 powr (2*k + 3)"
      using exp10 exp05 exp04 exp06 exp07 exp03 exp09 i  n-1 0i
      by (smt (verit, ccfv_SIG)  divide_cancel_right powr_non_neg)
    have "(i^3 - (i-1)^3)  3*8 powr (2*k + 3)"
      using exp10 exp05 exp04 exp06 exp07 exp03 exp09 i  n-1 1i
      by (smt (verit, ccfv_SIG) divide_cancel_right powr_non_neg)
    have "i^3 > (i-1)^3"
      by (smt (verit, best) power_minus_Bit1 power_mono_iff zero_less_numeral)
    have "N - (i-1)^3 = ((N - (i-1)^3)-(N-i^3)) + ((N-i^3) - (N-(i+1)^3)) + (N-(i+1)^3)"
      by simp
    have " = (i^3 - (i-1)^3) + ((i+1)^3 - i^3) + (N-(i+1)^3)"
      by simp
    have exp17: " < 3*8 powr (2*k + 3) + 8*8 powr (3*k)"              
      using N - (i+1)^3  8*8 powr (3*k) i  n-1 1i 0  i exp08 exp10 exp03 exp09
      by (smt (verit) field_sum_of_halves of_int_add of_int_diff power_strict_mono zero_less_numeral)
    have exp18:"  11*(8 powr (3*k))"
      by (simp add: 3  k)
    have "(even (i^3)  odd ((i-1)^3))  (even ((i-1)^3)  odd (i^3))"
      by simp
    hence "(even (N - i^3)  odd (N - (i-1)^3))  (even (N - (i-1)^3)  odd (N - i^3))"
      by auto
    hence "(even (N-(i-1)^3))  odd (N-i^3)"
      by blast 
    obtain a::nat where a_def: "if odd (N-(i-1)^3) then a = i-1 else a = i"
      by (metis 0  i 1  i diff_ge_0_iff_ge nonneg_int_cases)
    have "a = int a"
      by simp
    consider (odd) "odd (N - (i-1)^3)" | (even) "even (N - (i-1)^3)"
      by blast
    hence "odd (N - a^3)"
    proof cases
      case odd
      have "int a = i-1"
        using a_def odd by simp
      have "odd (N - (i-1)^3)"
        using odd by simp
      hence "odd (N - (int a)^3)"
        using a = i-1 by simp
      have "a^3  N"
        using N  (i+1)^3 int a = i-1 power_mono i  1
        by (smt (verit, ccfv_SIG) of_nat_le_of_nat_power_cancel_iff)
      hence "N - a^3 = N - (int a)^3"
        by (simp add: of_nat_diff)
      thus ?thesis
        using odd (N - (int a)^3) by presburger
    next
      case even
      have "a = i"
        using a_def even by simp
      have "odd (N - i^3)"
        using (even (N-(i-1)^3))  odd (N-i^3) even by simp
      hence "odd (N - (int a)^3)"
        using a = i by simp
      have "a^3  N"
        using N  (i+1)^3 int a = i power_mono i  1
        by (smt (verit, ccfv_SIG) of_nat_le_of_nat_power_cancel_iff)
      hence "N - a^3 = N - (int a)^3"
        by (simp add: of_nat_diff)
      thus ?thesis 
        using odd (N - (int a)^3) by presburger
    qed
    hence "odd (nat (N - a^3))"
      using nat_int by presburger
    moreover have "3*(nat k)  1"
      using 3  k by auto
    ultimately have "b. odd b  [(nat (N - a^3)) = b^3] (mod 2^(3*(nat k)))"
      using every_odd_nat_cong_cube by presburger
    then obtain b'::nat where "odd b'" and "[(nat (N - a^3)) = b'^3] (mod 2^(3*(nat k)))"
      by auto
    define b::nat where "b = b' mod (8^(nat k))"
    have "[nat (N - a^3)  0] (mod 2^(3*(nat k)))"
      by (meson 1  3 * nat k odd (nat (int (N - a ^ 3))) cong_0_iff even_power 
          cong_dvd_modulus_nat dvd_refl order_less_le_trans zero_less_one)
    hence "b > 0"
      by (metis 1  3 * nat k 2 ^ 3 = 8 b_def odd b' dvd_power gcd_nat.trans 
          mod_greater_zero_iff_not_dvd order_less_le_trans power_mult zero_less_one)
    hence "b^3 > 0"
      by simp

    have "b < 8 powr k"
      by (simp add: b_def powr_int)
    hence "b^3 < (8 powr (k))^3"
      using power_strict_mono by fastforce
    hence "b^3 < 8 powr (3*k)"
      by (metis mult.commute of_int_mult of_int_numeral powr_ge_pzero powr_numeral powr_powr)
    have "N - a^3  8*8 powr (3*k)"
      using (i - 1)^3 < i^3 8 * 8 powr (3*k)  N - i^3
      by (smt (verit, best)  a_def int_ops(6) of_int_less_iff of_int_of_nat_eq of_nat_power)
    
    have exp19:"7*8 powr (3*k) = 8*8 powr (3*k) - 8 powr (3*k)"
      by simp
    have exp20:" < (N - a^3) - b^3"
      using N - a^3  8*8 powr (3*k) b^3 < 8 powr (3*k) by linarith
    hence " < N - a^3"
      using 0 < b ^ 3 (b ^ 3) < 8 powr (3 * k) by linarith
    have exp21: " < 11*8 powr (3*k)"
      using a_def (i-1)^3 < i^3 exp16 exp01 exp17 exp18 exp02
      by (smt(verit) of_int_less_iff of_int_of_nat_eq of_nat_diff of_nat_le_of_nat_power_cancel_iff 
          of_nat_power)

    have "[N - a^3 - b^3 = 0] (mod (8^(nat k)))"
      by (smt (verit, del_insts) 2^3 = 8 [nat (N - a^3) = b'^3] (mod 2^(3*nat k)) b_def
          unique_euclidean_semiring_class.cong_def cong_diff_iff_cong_0_nat diff_is_0_eq' nat_int 
          nle_le power_mod power_mult)
    define q::real where "q = (N - a^3 - b^3)/((8 powr k))"
    have "(N - a^3 - b^3)/(8 powr k)  1"
      by (smt (verit, ccfv_SIG) 1  3 * nat k exp20 le_divide_eq_1_pos less_numeral_extra(1) 
          nat_0_less_mult_iff of_int_less_iff order_less_le_trans powr_gt_zero powr_less_cancel_iff 
          zero_less_nat_eq)
    hence "q  0"
      using q_def by auto
    moreover have "(N - a^3 - b^3)  0"
      using exp20 by auto

    moreover have "(8 powr k)  0"
      using power_not_zero by auto
    ultimately have exp22: "q*((8 powr k)) = (N - a^3 - b^3)"
      using q_def by auto

    have exp23: "(8::nat)^(nat k) = 8 powr k"
      using 1  3 * nat k powr_int by auto
    hence "q = q"
      using [N - a^3 - b^3 = 0] (mod (8::nat)^(nat k)) q_def
      by (metis cong_0_iff floor_of_nat of_int_of_nat_eq real_of_nat_div)
    have "7*8 powr (3*k) < q*8 powr (k)"
      using exp19 exp20 exp22
      by presburger
    hence "q > 7*8 powr (3*k)/(8 powr k)"
      by (simp add: divide_less_eq)
    hence " > 7*(8 powr (3*k - k))"
      using powr_diff by (metis of_int_diff times_divide_eq_right)
    hence " > 7 * 8 powr (2*k)"
      by simp

    have "q*8 powr k < 11*8 powr (3*k)"
      using exp22 exp21 by linarith
    hence "q < 11*8 powr (3*k) / 8 powr k"
      by (simp add: pos_less_divide_eq)
    hence "q < 11*8 powr (3*k - k)"
      using powr_diff by (metis of_int_diff times_divide_eq_right) 
    hence "q < 11*8 powr (2*k)"
      by simp
    have exp24:"(8::nat)^(2*(nat k)) = 8 powr (2*k)"
      using 3  k powr_int
      by (metis exp23 of_int_mult of_int_numeral of_nat_power power_even_eq powr_ge_pzero 
          powr_numeral powr_powr powr_powr_swap) 
    hence "6*(8::nat)^(2*(nat k)) = 6*8 powr (2*k)"
      by simp
    have "6*(8 powr (2* k)) < 7*(8 powr (2*k))"
      by simp
    hence "q - 6*(8 ^ (2*(nat k))) > 0"
      using 7 * 8 powr (2 * k) < q q = q
    proof -
      have  "6 * 8 powr (2*k) < 7 * 8 powr (2*k)"
        by simp
      have "7 * 8 powr (2 * k) < q"
        using 7 * 8 powr (2 * k) < q by fastforce
      hence "6 * 8 powr (2 * k) < q"
        using 6 * 8 powr (2*k) < 7 * 8 powr (2*k) by linarith
      thus  ?thesis
        by (metis (no_types) q = q exp24 of_int_0_less_iff of_int_diff of_int_eq_numeral_power_cancel_iff
            of_int_mult of_int_numeral real_of_nat_eq_numeral_power_cancel_iff diff_gt_0_iff_gt)
    qed
    then obtain r::nat where "r = q - 6*(8 ^ (2*(nat k)))"
      by (metis zero_less_imp_eq_int)
    hence "r = q - 6*(8 powr (2*k))"
      by (metis q = q exp24 of_int_diff of_int_mult of_int_numeral of_int_of_nat_eq 
          real_of_nat_eq_numeral_power_cancel_iff)
    have "(22::nat)^3 < 8^6"
      using power_mono by simp
    have "  8^(nat (k*2))"
      by (smt (verit, best) k  3  nat_mono nat_numeral numeral_Bit0 numeral_Bit1 
          numeral_eq_one_iff numeral_less_iff power_increasing_iff)
    have " = 8 powr (2*k)"
      by (smt (verit, best) 3  k numeral_Bit0 numeral_One of_nat_1 of_nat_numeral of_nat_power powr_int)
    have " < r"
      using r = q - 6*(8 powr (2*k)) q > 7*8 powr (2*k) by auto
    have " < 5*(8 powr (2*k))"
      using q < 11*8 powr (2*k) r = q - 6*(8 powr (2*k)) by auto

    have "r > 22^3"
      using (22::nat)^3 < 8^6 8^6  8^(nat (k*2)) real (8^(nat (k*2))) = 8 powr (2*k) 8 powr (2*k) < r 
      by linarith
    hence " r  10648"
      by simp
    then obtain d m where "d  0" and "d  22" and "r = d^3 + 6*m" and "is_sumpow 2 3 m"
      using values_geq_22_cubed_can_be_normalised by auto

    define A::nat where "A = 8^(nat k)"
    have "m  r/6"
      using r = d^3 + 6*m d  0 by linarith 
    have " < (5*8^(nat (2*k)))/6"
      by (smt (verit, ccfv_SIG) 3  k r < 5*(8 powr (2*k)) divide_strict_right_mono powr_int)
    have " < 8^(nat (2*k))"
      by simp
    have " = A2"
      by (metis A_def real (8^(2*nat k)) = 8 powr (2*k) real (8 ^ nat(k*2)) = 8 powr (2*k) 
          mult.commute power_mult real_of_nat_eq_numeral_power_cancel_iff)

    define c::nat where "c = d*2^(nat k)"
    have "N = a^3 + b^3 + (8^(nat k))*q"
      by (smt (verit, del_insts) 1  3 * nat k N - a^3 - b^3  0 exp22
          diff_is_0_eq' mult.commute nat_0_iff nat_0_less_mult_iff nat_int nle_le of_nat_add 
          of_nat_diff powr_int zero_less_nat_eq zero_less_one)
    moreover have " = a^3 + b^3 + 8^(nat k)*(6*8 powr (2*k) + r)"
      using r = q - 6*(8 powr (2*k)) by simp
    moreover have " = a^3 + b^3 + 8^(nat k)*(6*8^(nat(2*k)) + r)"
    proof -
      have "8 powr (int 2 * k) = (8 ^ nat (k * int 2))"
        using real (8 ^ nat (k * 2)) = 8 powr (2 * k) by auto
      thus ?thesis
        by simp
    qed
    moreover have " = a^3 + b^3 + (8^(nat k)*d^3) + 8^(nat k)*(6*8^(nat(2*k)) + 6*m)"
      by (simp add: r = d^3 + 6*m add_mult_distrib2)
    moreover have " = a^3 + b^3 + ((2^(nat k))*d)^3 + 8^(nat k)*(6*8^(nat(2*k)) + 6*m)"
      by (smt (verit) 2 ^ 3 = 8 mult.commute power_mult power_mult_distrib)
    moreover have " = a^3 + b^3 + c^3 + 6*A*(A2 + m)"
      by (smt (z3) A_def c_def exp24 real (8 ^ nat(k*2)) = 8 powr (2*k) add_mult_distrib2
          mult.assoc mult.commute of_nat_eq_iff power_even_eq)
    ultimately have "N = a^3 + b^3 + c^3 + 6*A*(A2 + m)"
      using of_nat_eq_iff by metis
    have "is_sumpow 3 6 (6*A*(A2 + m))"
    proof -
      have "m  A2"
        using 8 ^ nat (2*k) = real (A2) m  r/6 real r / 6 < 5*8^nat (2 * k)/6 by linarith
      thus ?thesis
        using sum_of_6_cubes is_sumpow 2 3 m by simp
    qed
    then obtain l::"nat list" where "length l = 6" and "6*A*(A2 + m) = sumpow 3 l"
      using is_sumpow_def by blast
    have "a^3 + b^3 + c^3 + sumpow 3 l = sumpow 3 (a#b#c#l)"
      by (simp add: fold_plus_sum_list_rev)
    hence " = N"
      using 6 * A * (A2 + m) = sumpow 3 l N = a^3 + b^3 + c^3 + 6*A*(A2 + m) by presburger
    have "length (a#b#c#l) = 9"
      using length l = 6 by simp
    thus ?thesis
      using sumpow 3 (a#b#c#l) = N is_sumpow_def by blast
  next
    case leq8pow10
    consider (leq40000) "N  40000" | (ge40000) "N > 40000"
      by arith
    thus ?thesis
    proof (cases)
      case ge40000
      define a::int where "a = (N - 10000) powr (1/3)"

      text‹The following inequalities differ from those in \cite{nathanson1996}, which erroneously result in
the false statement a > 31, we have corrected these mistakes.  This does not affect the rest of the proof.›
      have "(N - 10000) > 30000"
        using ge40000 by linarith
      hence "(N - 10000) powr (1/3)  (30000) powr (1/3)"
        using powr_mono2 by simp
      hence "a  (30000::int) powr (1/3)"
        using a_def floor_mono by simp
      have "(30000::nat) > (31)^3"
        by simp
      hence "(30000::nat) powr (1/3) > (31^3) powr (1/3)"
        by (metis numeral_less_iff numeral_pow of_nat_numeral powr_less_mono2 zero_le_numeral 
            zero_less_divide_1_iff zero_less_numeral)
      hence " > 31"
        by auto
      hence "(30000::nat) powr (1/3)  31"
        by linarith
      hence "a  31"
        using a  (30000::int) powr (1/3)
        by (metis nle_le of_int_numeral of_nat_numeral order_trans)
      hence "nat a = a"
        by simp
      have "(x::int) > 4. x*(x - 3) > 1"
        by (simp add: less_1_mult)
      hence "(x::int) > 4. x^2 - 3*x -1 > 0"
        by (simp add: mult.commute power2_eq_square right_diff_distrib')
      define d::int where "d = (a+1)^3 - a^3"
      moreover have " =3*a^2 + 3*a + 1"
        by Groebner_Basis.algebra
      moreover hence "a^2 - 3*a -1 > 0"
        using a  31 (x::int) > 4. x^2 - 3*x -1 > 0 by simp
      moreover hence "4*a^2 > 3*a^2 + 3*a + 1"
        by simp
      ultimately have "4*a^2 > d"
        by presburger
      have "a < (N powr (1/3))"
        by (smt (verit, best) a_def diff_less floor_eq_iff ge40000 of_nat_0_le_iff of_nat_less_iff 
            powr_less_mono2 zero_less_divide_1_iff zero_less_numeral)
      hence "a powr 2 < (N powr (1/3))powr 2"
        using 31  a order_less_le by fastforce
      hence "4*a^2 < 4*(N powr (2/3))"
        using a_def powr_powr by fastforce
      have "N - (N - 10000)  10000"
        by simp
      hence "N - ((N - 10000) powr (1/3)) powr 3  10000"
        using powr_powr powr_one_gt_zero_iff ge40000 by force
      hence "N - (N-10000) powr (1/3) + 1 powr 3 < 10000"
        by (smt (verit, best) powr_ge_pzero powr_less_mono2 real_of_int_floor_add_one_gt)
      hence "N - (a+1) powr 3 < 10000"
        using a_def one_add_floor by simp
      have "(a+1) powr 3 = (a+1)^3"
        using a_def by auto
      hence "N - (a+1)^3 < 10000"
        using N - (a+1) powr 3 < 10000 by linarith
      have "  N - (N - 10000)"
        using ge40000 by auto 
      moreover have " = N - ((N - 10000) powr (1/3)) powr 3"
        using powr_powr by simp
      moreover have "  N - ((N - 10000) powr (1/3)) powr 3"
        by simp
      moreover have " = N - a^3"
        using a_def by simp
      ultimately have "10000  N - a^3"
        by linarith
      have " = N - (a+1)^3 + d"
        using d_def by simp
      moreover have " < 10000 + 4*(N powr (2/3))"
        using N - (a+1)^3 < 10000 4*a^2 > d 4*a^2 < 4*(N powr (2/3)) le_less_trans by linarith
      ultimately have "N - a^3 < 10000 + 4*(N powr (2/3))"
        by presburger
      hence "int (N - (nat a)^3) < 10000 + 4*(N powr (2/3))"
        using nat a = a
        by (smt (verit, best) 10000  int N - a^3 int_ops(6) of_int_of_nat_eq of_nat_power)

      consider (N_min_a_cube_leq40000) "N-(nat a)^3  40000" | (N_min_a_cube_ge40000) "N - (nat a)^3 > 40000"
        by arith
      thus ?thesis
      proof (cases)
        case N_min_a_cube_leq40000
        have "N - (nat a)^3  10000"
          using 10000  N - a^3 int_nat_eq a  31
          by (smt (verit) int_ops(6) numeral_Bit0 numeral_Bit1 numeral_One of_nat_1 of_nat_le_iff 
              of_nat_numeral of_nat_power) 
        hence "is_sumpow 3 6 (N-(nat a)^3)"
          using leq_40000_is_sum_of_9_cubes N_min_a_cube_leq40000 by force

        then obtain l::"nat list" where "length l = 6" and "N - (nat a)^3 = sumpow 3 l"
          using is_sumpow_def by blast
        have "0 + 0 + (nat a)^3 + sumpow 3 l = sumpow 3 ((nat a)#0#0#l)"
          by (simp add: fold_plus_sum_list_rev)
        hence " = N"
          using N - (nat a)^3 = sumpow 3 l 10000  N - nat a ^ 3 by presburger 
        have "length ((nat a)#0#0#l) = 9"
          using length l = 6 by simp
        thus ?thesis
          using sumpow 3 ((nat a)#0#0#l) = N is_sumpow_def by blast
      next
        case N_min_a_cube_ge40000
        define N'::nat where "N' = N - (nat a)^3"
        hence "N' > 40000"
          using N_min_a_cube_ge40000 by simp

        define b::int where "b = (N' - 10000) powr (1/3)"
        text‹The same mistake as above crops up, and we have corrected it in the same way.›
        have "  31"
          by (smt (verit) 31  real 30000 powr (1 / 3) 40000 < N' floor_mono floor_of_nat 
              int_ops(2) int_ops(6) less_imp_of_nat_less numeral_Bit0 numeral_Bit1 numeral_One 
              of_nat_numeral powr_mono2 zero_le_divide_1_iff)
        hence "b  31"
          using b_def by simp
        hence "nat b = b"
          by simp

        define d'::int where "d' = (b+1)^3 - b^3"
        moreover have " =3*b^2 + 3*b + 1"
          by Groebner_Basis.algebra 
        moreover have "b^2 - 3*b -1 > 0"
          using b  31 (x::int) > 4. x^2 - 3*x -1 > 0 by simp
        moreover hence "4*b^2 > 3*b^2 + 3*b + 1"
          by simp
        ultimately have "4*b^2 > d'"        
          by presburger

        have "b < (N' powr (1/3))"
          using b_def
          by (smt (verit, best) N_min_a_cube_ge40000 N'_def diff_less floor_eq_iff of_nat_0_le_iff
              of_nat_less_iff powr_less_mono2 zero_less_divide_1_iff zero_less_numeral)
        hence "b powr 2 < (N' powr (1/3))powr 2"
          using 31  b order_less_le by fastforce
        hence "4*b^2 < 4*(N' powr (2/3))"
          using b_def powr_powr by fastforce
        have "N' - (N' - 10000)  10000"
          by simp
        hence "N' - ((N' - 10000) powr (1/3)) powr 3  10000"
          using powr_powr powr_one_gt_zero_iff N' > 40000 by force
        hence "N' - (N'-10000) powr (1/3) + 1 powr 3 < 10000"
          by (smt (verit, best) powr_ge_pzero powr_less_mono2 real_of_int_floor_add_one_gt)
        hence "N' - (b+1) powr 3 < 10000"
          using b_def one_add_floor by simp
        have "(b+1) powr 3 = (b+1)^3"
          using b_def by auto
        hence "N' - (b+1)^3 < 10000"
          using  N' - (b+1) powr 3 < 10000 by linarith
        have "  N' - (N' - 10000)"
          using N' > 40000 by auto
        moreover have " = N' - ( (N' - 10000) powr (1/3)) powr 3"
          using powr_powr by simp
        moreover have "  N' - ((N' - 10000) powr (1/3)) powr 3"
          by simp
        moreover have " = N' - b^3"
          using b_def by simp
        ultimately have "10000  N' - b^3"
          by linarith
        have " = N' - (b+1)^3 + d'"
          using d'_def by simp
        moreover have " < 10000 + 4*(N' powr (2/3))"
          using N' - (b+1)^3 < 10000 4*b^2 > d' 4*b^2 < 4*(N' powr (2/3)) le_less_trans 
          by linarith
        ultimately have "N' - b^3 < 10000 + 4*(N' powr (2/3))"
          by presburger
        hence "int (N' - (nat b)^3) < 10000 + 4*(N' powr (2/3))"
          using nat b = b
          by (smt (verit, best) 10000  int N' - b ^ 3 int_ops(6) of_int_of_nat_eq of_nat_power)

        consider (N'_min_b_cube_leq40000) "N'-(nat b)^3  40000" | (N'_min_b_cube_ge40000) "N' - (nat b)^3 > 40000"
          by arith
        thus ?thesis
        proof (cases)
          case N'_min_b_cube_leq40000
          have "N' - (nat b)^3  10000"
            using 10000  N' - b^3 int_nat_eq b  31
            by (smt (verit) int_ops(6) numeral_Bit0 numeral_Bit1 numeral_One of_nat_1 of_nat_le_iff 
                of_nat_numeral of_nat_power) 
          hence "N - (nat a)^3 - (nat b)^3  10000"
            using N'_def by simp
          hence "is_sumpow 3 6 (N - (nat a)^3 - (nat b)^3)"
            using leq_40000_is_sum_of_9_cubes N'_min_b_cube_leq40000 N'_def by force
          then obtain l::"nat list" where "length l = 6" and "N - (nat a)^3 - (nat b)^3 = sumpow 3 l"
            using is_sumpow_def by blast
          have "0 + (nat b)^3 + (nat a)^3 + sumpow 3 l = sumpow 3 ((nat a)#(nat b)#0#l)"
            by (simp add: fold_plus_sum_list_rev)
          hence " = N"
            using N - (nat a)^3 - (nat b)^3 = sumpow 3 l 10000  N - nat a^3 - nat b^3 
            by presburger 
          have "length ((nat a)#(nat b)#0#l) = 9"
            using length l = 6 by simp
          thus ?thesis 
            using sumpow 3 (nat a # nat b # 0 # l) = N is_sumpow_def by blast
        next
          case N'_min_b_cube_ge40000

          define N''::nat where "N'' = N - (nat a)^3 - (nat b)^3"
          hence "N'' > 40000"
            using N'_min_b_cube_ge40000 N'_def by simp

          define c::int where "c = (N'' - 10000) powr (1/3)"
          text‹We correct the same mistake as above.›
          have "  31"
            by (smt (verit) 31  real 30000 powr (1 / 3) 40000 < N'' floor_mono floor_of_nat 
                int_ops(2) int_ops(6) less_imp_of_nat_less numeral_Bit0 numeral_Bit1 numeral_One 
                of_nat_numeral powr_mono2 zero_le_divide_1_iff)
          hence "c  31"
            using c_def by simp
          hence cnotneg: "nat c = c"
            using int_nat_eq by simp 

          define d''::int where "d'' = (c+1)^3 - c^3"
          moreover have " =3*c^2 + 3*c + 1"
            by Groebner_Basis.algebra 
          moreover have "c^2 - 3*c -1 > 0"
            using c  31 (x::int) > 4. x^2 - 3*x -1 > 0 by simp
          moreover hence "4*c^2 > 3*c^2 + 3*c + 1"
            by simp
          ultimately have "4*c^2 > d''"        
            by presburger
      
          have "c < (N'' powr (1/3))"
            using c_def N'_min_b_cube_ge40000 N'_def N''_def
            by (smt (verit, ccfv_SIG) diff_less floor_eq_iff of_nat_0_le_iff of_nat_less_iff 
                powr_less_mono2 zero_less_divide_1_iff zero_less_numeral)
          hence "c powr 2 < (N'' powr (1/3))powr 2"
            using 31  c order_less_le by fastforce
          hence "4*c^2 < 4*(N'' powr (2/3))"
            using c_def powr_powr by fastforce

          have "N'' - (N'' - 10000)  10000"
            by simp
          hence "N'' - ((N'' - 10000) powr (1/3)) powr 3  10000"
            using powr_powr powr_one_gt_zero_iff N' > 40000 by force
          hence "N'' - (N''-10000) powr (1/3) + 1 powr 3 < 10000"
            by (smt (verit, best) powr_ge_pzero powr_less_mono2 real_of_int_floor_add_one_gt)
          hence "N'' - (c+1) powr 3 < 10000"
            using c_def one_add_floor by simp
          have "(c+1) powr 3 = (c+1)^3"
            using c_def by auto
          hence "N'' - (c+1)^3 < 10000"
            using  N'' - (c+1) powr 3 < 10000 by linarith
          have "  N'' - (N'' - 10000)"
            using N'' > 40000 by auto
          moreover have " = N'' - ( (N'' - 10000) powr (1/3)) powr 3"
            using powr_powr by simp
          moreover have "  N'' - ((N'' - 10000) powr (1/3)) powr 3"
            by simp
          moreover have " = N'' - c^3"
            using c_def by simp
          ultimately have "10000  N'' - c^3"
            by linarith
          moreover have " = N'' - (c+1)^3 + d''"
            using d''_def by simp
          moreover have " < 10000 + 4*(N'' powr (2/3))"
            using N'' - (c+1)^3 < 10000 4*c^2 > d'' 4*c^2 < 4*(N'' powr (2/3)) le_less_trans 
            by linarith
          ultimately have "N'' - c^3 < 10000 + 4*(N'' powr (2/3))"
            by presburger
          hence "int (N'' - (nat c)^3) < 10000 + 4*(N'' powr (2/3))"
            using cnotneg
            by (smt (verit, best) 10000  int N'' - c ^ 3 int_ops(6) of_int_of_nat_eq of_nat_power) 
      
          have "N - (nat a)^3 - (nat b)^3 - (c+1)^3 < 10000"
            using N'' - (c+1)^3 < 10000 N''_def by simp
          have "  N'' - (nat c)^3"
            by (smt (verit, del_insts) 10000  int N'' - c ^ 3 cnotneg int_ops(6) of_nat_power)
          have " < 10000 + 4*((N - (nat a)^3 - (nat b)^3) powr (2/3))"
            using N''_def int (N'' - (nat c)^3) < 10000 + 4*(N'' powr (2/3)) by simp
          moreover have " < 10000 + 4*((10000 + 4*((N - (nat a)^3) powr (2/3))) powr (2/3))" 
            using int (N' - (nat b)^3) < 10000 + 4*(N' powr (2/3)) powr_less_mono2 N'_def by simp
          moreover have " < 10000 + 4*((10000 + 4*((10000 + 4*(N powr (2/3))) powr (2/3))) powr (2/3))"
            using int (N - (nat a)^3) < 10000 + 4*(N powr (2/3)) powr_less_mono2 by simp
          moreover have "  10000 + 4*((10000 + 4*((10000 + 4*((int 8^10) powr (2/3))) powr (2/3))) powr (2/3))"
            using leq8pow10 powr_less_mono2 nle_le
            by (smt (verit, best) numeral_power_le_of_nat_cancel_iff of_int_of_nat_eq of_nat_0_le_iff 
                of_nat_power powr_ge_pzero zero_less_divide_iff)
          moreover have " = 10000 + 4*((10000 + 4*((4204304) powr (2/3))) powr (2/3))"
            using powr_powr by simp
          (*4251528 is the next lowest cube number after 4204304*)
          moreover have "  10000 + 4*((10000 + 4*((4251528) powr (2/3))) powr (2/3))" 
            by (smt (verit, best) powr_ge_pzero powr_less_mono2 zero_less_divide_iff)
          moreover have " = 10000 + 4*((114976) powr (2/3))"
            by auto
          (*117649 is the next lowest cube number after 114976*)
          moreover have "  10000 + 4*((117649) powr (2/3))" 
            by (smt (verit, best) powr_ge_pzero powr_less_mono2 zero_less_divide_iff)
          moreover have "  20000"
            by auto
          ultimately have "N - (nat a)^3 - (nat b)^3 - (nat c)^3  20000"
            by (smt (verit, del_insts) N''_def numeral_Bit0 numeral_Bit1 numerals(1) of_int_of_nat_eq 
                of_nat_1 of_nat_le_iff of_nat_numeral)

          hence "is_sumpow 3 6 (N - (nat a)^3 - (nat b)^3 - (nat c)^3)"
            using leq_40000_is_sum_of_9_cubes 10000  N'' - c^3 N''_def cnotneg 
            by (smt (verit) 10000  int (N'' - nat c ^ 3) int_ops(2) numeral_Bit0 numeral_Bit1 
                numeral_One of_nat_le_iff of_nat_numeral order_less_le) 
          then obtain l::"nat list" where "length l = 6" and 
            "N - (nat a)^3 - (nat b)^3 - (nat c)^3 = sumpow 3 l"
            using is_sumpow_def by blast
          moreover have "(nat c)^3 + (nat b)^3 + (nat a)^3 + sumpow 3 l = sumpow 3 ((nat a)#(nat b)#(nat c)#l)"
            by (simp add: fold_plus_sum_list_rev)
          ultimately have  " = N"
            using 10000  int N'' - c^3 N''_def cnotneg 
            by (smt (verit, del_insts) diff_diff_left of_nat_power of_nat_le_iff le_add_diff_inverse 
                add.commute int_ops(6))
          moreover have "length ((nat a)#(nat b)#(nat c)#l) = 9"
            using length l = 6 by simp
          ultimately show ?thesis 
            using is_sumpow_def by blast
        qed
      qed
    next
      case leq40000
      thus ?thesis 
        using leq_40000_is_sum_of_9_cubes by blast
    qed
  qed
  thus ?thesis
    by simp
qed
end