(* ========================================================================= *)
(* Perfect number theorems. *)
(* ========================================================================= *)
needs "Library/prime.ml";;
prioritize_num();;
(* ------------------------------------------------------------------------- *)
(* The sum-of-divisors function. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Definition of perfection. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Various number-theoretic lemmas. *)
(* ------------------------------------------------------------------------- *)
let EVEN_ODD_DECOMP = prove
(`!n. ~(n = 0) ==> ?r s.
ODD s /\ n = 2
EXP r * s`,
MATCH_MP_TAC
num_WF THEN X_GEN_TAC `n:num` THEN
MP_TAC(SPEC `n:num`
EVEN_OR_ODD) THEN
REWRITE_TAC[
EVEN_EXISTS;
ODD_EXISTS] THEN
DISCH_THEN(DISJ_CASES_THEN (X_CHOOSE_THEN `m:num` SUBST_ALL_TAC)) THENL
[DISCH_THEN(MP_TAC o SPEC `m:num`) THEN
REWRITE_TAC[
MULT_EQ_0; ARITH; ARITH_RULE `m < 2 * m <=> ~(m = 0)`] THEN
ASM_CASES_TAC `m = 0` THEN ASM_REWRITE_TAC[] THEN
ONCE_REWRITE_TAC[
SWAP_EXISTS_THM] THEN MATCH_MP_TAC
MONO_EXISTS THEN
X_GEN_TAC `s:num` THEN DISCH_THEN(X_CHOOSE_TAC `r:num`) THEN
EXISTS_TAC `SUC r` THEN ASM_REWRITE_TAC[
EXP; GSYM
MULT_ASSOC];
REPEAT(DISCH_THEN(K ALL_TAC)) THEN EXISTS_TAC `0` THEN
REWRITE_TAC[
EXP;
MULT_CLAUSES] THEN MESON_TAC[]]);;
let MULT_EQ_COPRIME = prove
(`!a b x y. a * b = x * y /\ coprime(a,x)
==> ?d. y = a * d /\ b = x * d`,
REPEAT STRIP_TAC THEN
MP_TAC(SPECL [`a:num`; `x:num`; `y:num`]
COPRIME_DIVPROD) THEN
MP_TAC(SPECL [`x:num`; `a:num`; `b:num`]
COPRIME_DIVPROD) THEN
REPEAT(ANTS_TAC THENL
[ASM_MESON_TAC[
DIVIDES_REFL;
DIVIDES_RMUL;
COPRIME_SYM];
REWRITE_TAC[divides] THEN STRIP_TAC]) THEN
UNDISCH_TAC `a * b = x * y` THEN ASM_REWRITE_TAC[] THEN
REWRITE_TAC[ARITH_RULE
`(a * x * u = x * a * v) <=> (a * x) * u = (a * x) * v`] THEN
REWRITE_TAC[
EQ_MULT_LCANCEL;
MULT_EQ_0] THEN ASM_MESON_TAC[]);;
(* ------------------------------------------------------------------------- *)
(* Some elementary properties of the sigma function. *)
(* ------------------------------------------------------------------------- *)
let SIGMA_PRIME_EQ = prove
(`!p. prime(p) <=> sigma(p) = p + 1`,
GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[
SIGMA_PRIME] THEN
ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
REWRITE_TAC[prime; DE_MORGAN_THM] THEN
ASM_CASES_TAC `p = 1` THEN ASM_REWRITE_TAC[
SIGMA_1; ARITH] THEN
REWRITE_TAC[
NOT_FORALL_THM; NOT_IMP; divides; DE_MORGAN_THM] THEN
DISCH_THEN(X_CHOOSE_THEN `a:num` (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN
DISCH_THEN(X_CHOOSE_THEN `b:num` SUBST_ALL_TAC) THEN
MP_TAC(SPECL [`a:num`; `b:num`]
SIGMA_MULT) THEN
ASM_CASES_TAC `a = 0` THEN ASM_REWRITE_TAC[
MULT_CLAUSES;
SIGMA_0; ARITH] THEN
ASM_CASES_TAC `b = 0` THEN ASM_REWRITE_TAC[
MULT_CLAUSES;
SIGMA_0; ARITH] THEN
REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[
MULT_EQ_1] THEN
ONCE_REWRITE_TAC[ARITH_RULE `a = a * b <=> a * b = a * 1`] THEN
REWRITE_TAC[
EQ_MULT_LCANCEL] THEN ARITH_TAC);;
(* ------------------------------------------------------------------------- *)
(* Multiplicativity of sigma, the most interesting property. *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Hence the main theorems. *)
(* ------------------------------------------------------------------------- *)
let PERFECT_EULER = prove
(`!n.
EVEN(n) /\ perfect(n)
==> ?k. prime(2
EXP k - 1) /\ n = 2
EXP (k - 1) * (2
EXP k - 1)`,
GEN_TAC THEN MP_TAC(SPEC `n:num`
EVEN_ODD_DECOMP) THEN
ASM_CASES_TAC `n = 0` THENL
[ASM_REWRITE_TAC[perfect]; ASM_REWRITE_TAC[]] THEN
REWRITE_TAC[
LEFT_IMP_EXISTS_THM; GSYM
NOT_EVEN] THEN
MAP_EVERY X_GEN_TAC [`r:num`; `s:num`] THEN
DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC) THEN
ASM_REWRITE_TAC[
EVEN_EXP;
EVEN_MULT; ARITH] THEN
DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
REWRITE_TAC[perfect] THEN
ASM_SIMP_TAC[
SIGMA_MULTIPLICATIVE;
SIGMA_POW2;
COPRIME_ODD_POW2; GSYM
NOT_EVEN] THEN
DISCH_TAC THEN EXISTS_TAC `r + 1` THEN
REWRITE_TAC[
ADD_SUB;
EQ_MULT_LCANCEL] THEN REWRITE_TAC[
EXP_EQ_0; ARITH] THEN
FIRST_X_ASSUM(MP_TAC o check(is_eq o concl)) THEN
REWRITE_TAC[
MULT_ASSOC; GSYM(CONJUNCT2
EXP);
ADD1] THEN
DISCH_THEN(MP_TAC o MATCH_MP
(REWRITE_RULE[
IMP_CONJ]
MULT_EQ_COPRIME)) THEN
ANTS_TAC THENL
[ONCE_REWRITE_TAC[
COPRIME_SYM] THEN MATCH_MP_TAC
COPRIME_ODD_POW2 THEN
SIMP_TAC[
ODD_POW2_MINUS1;
ADD_EQ_0;
ARITH_EQ];
ALL_TAC] THEN
DISCH_THEN(X_CHOOSE_THEN `d:num` MP_TAC) THEN
ASM_CASES_TAC `d = 0` THEN ASM_REWRITE_TAC[
MULT_CLAUSES] THENL
[ASM_MESON_TAC[
EVEN]; ALL_TAC] THEN
ASM_CASES_TAC `d = 1` THENL
[ASM_REWRITE_TAC[
MULT_CLAUSES;
SIGMA_PRIME_EQ] THEN
DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o SYM) ASSUME_TAC) THEN
ASM_REWRITE_TAC[] THEN EXPAND_TAC "s" THEN
MATCH_MP_TAC(GSYM
SUB_ADD) THEN
REWRITE_TAC[ARITH_RULE `1 <= n <=> ~(n = 0)`;
EXP_EQ_0; ARITH];
ALL_TAC] THEN
DISCH_THEN(CONJUNCTS_THEN2 (ASSUME_TAC o SYM) ASSUME_TAC) THEN
MP_TAC(SPECL [`2
EXP (r + 1) - 1`; `d:num`]
SIGMA_MULT) THEN
ASM_REWRITE_TAC[] THEN
MATCH_MP_TAC(TAUT `a /\ ~b ==> (a ==> b) ==> c`) THEN
REPEAT CONJ_TAC THENL
[MATCH_MP_TAC(ARITH_RULE `2
EXP 1 < a ==> 1 < a - 1`) THEN
REWRITE_TAC[
LT_EXP; ARITH] THEN
UNDISCH_TAC `~(r = 0)` THEN ARITH_TAC;
MAP_EVERY UNDISCH_TAC [`~(d = 0)`; `~(d = 1)`] THEN ARITH_TAC;
REWRITE_TAC[
NOT_LE] THEN EXPAND_TAC "s" THEN
REWRITE_TAC[
RIGHT_SUB_DISTRIB;
MULT_CLAUSES] THEN
MATCH_MP_TAC(ARITH_RULE `1 * d < x * d ==> x * d < 1 + d + x * d - d`) THEN
ASM_REWRITE_TAC[
LT_MULT_RCANCEL] THEN
MATCH_MP_TAC(ARITH_RULE `2
EXP 0 < a ==> 1 < a`) THEN
REWRITE_TAC[
LT_EXP] THEN UNDISCH_TAC `~(r = 0)` THEN ARITH_TAC]);;