Theory Polygonal_Number_Theorem_Gauss
section ‹ Polygonal Number Theorem ›
subsection ‹ Gauss's Theorem on Triangular Numbers›
text ‹We show Gauss's theorem which states that every non-negative integer is the sum of three triangles, using the Three Squares Theorem AFP entry \cite{Three_Squares-AFP}. This corresponds to Theorem 1.8 in \cite{nathanson1996}.›
theory Polygonal_Number_Theorem_Gauss
imports Polygonal_Number_Theorem_Lemmas
begin
text‹The following is the formula for the $k$-th polygonal number of order $m+2$.›
definition polygonal_number :: "nat ⇒ nat ⇒ nat"
where "polygonal_number m k = m*k*(k-1) div 2 + k"
text‹When $m = 1$, the polygonal numbers have order 3 and the formula represents triangular numbers.
Gauss showed that all natural numbers can be written as the sum of three triangular numbers.
In other words, the triangular numbers form an additive basis of order 3 of the natural numbers.›
theorem Gauss_Sum_of_Three_Triangles:
fixes n :: nat
shows "∃ x y z. n = polygonal_number 1 x + polygonal_number 1 y + polygonal_number 1 z"
proof -
have "(8 * n + 3) mod 8 = 3" by auto
then obtain a b c where 0: "odd a ∧ odd b ∧ odd c ∧ 8 * n + 3 = a^2 + b^2 + c^2"
using odd_three_squares_using_mod_eight by presburger
then obtain x y z where "a = 2 * x + 1 ∧ b = 2 * y + 1 ∧ c = 2 * z + 1" by (meson oddE)
hence "8 * n + 3 = (2 * x + 1)^2 + (2 * y + 1)^2 + (2 * z + 1)^2"
using 0 by auto
hence "n = (x * x + x + y * y + y + z * z + z) div 2"
by (auto simp add: power2_eq_square)
hence n_expr:"n = (x * (x + 1) + y * (y + 1) + z * (z + 1)) div 2"
by (metis (no_types, lifting) arithmetic_simps(79) nat_arith.add1 nat_distrib(2))
have triangle_identity: "polygonal_number 1 k = k*(k+1) div 2" for k
proof -
have "k*(k-1)+2*k = k*k+k" by (simp add: right_diff_distrib')
hence "k*(k-1) div 2 + k = (k*k+k) div 2"
by (metis Groups.add_ac(2) bot_nat_0.not_eq_extremum div_mult_self2 pos2)
thus ?thesis using polygonal_number_def by simp
qed
from n_expr triangle_identity show ?thesis
by (metis div_plus_div_distrib_dvd_right even_mult_iff odd_even_add odd_one)
qed
end