(`!p. 2 <= p /\ llseq (2
REPEAT STRIP_TAC THEN
ONCE_REWRITE_TAC[
PRIME_PRIME_FACTOR_SQRT] THEN
SUBGOAL_THEN `2 <= 2
EXP p - 1` ASSUME_TAC THENL
[MATCH_MP_TAC(ARITH_RULE `2
EXP 2 <= x ==> 2 <= x - 1`) THEN
REWRITE_TAC[
LE_EXP] THEN ASM_ARITH_TAC;
ALL_TAC] THEN
REPEAT(MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN
CONJ_TAC THENL [ASM_ARITH_TAC; DISCH_TAC]) THEN
DISCH_THEN(X_CHOOSE_THEN `q:num` STRIP_ASSUME_TAC) THEN
FIRST_ASSUM(ASSUME_TAC o MATCH_MP
PRIME_GE_2) THEN
FIRST_ASSUM(ASSUME_TAC o MATCH_MP
PRIME_IMP_NZ) THEN
ABBREV_TAC
`equiv =
\x y. ?a b. integer a /\ integer b /\
x - y = (a + b * sqrt(&3)) * &q` THEN
SUBGOAL_THEN `!x:real. (x == x) equiv` ASSUME_TAC THENL
[REWRITE_TAC[cong] THEN EXPAND_TAC "equiv" THEN
GEN_TAC THEN REPEAT(EXISTS_TAC `&0`) THEN
REWRITE_TAC[
INTEGER_CLOSED] THEN REAL_ARITH_TAC;
ALL_TAC] THEN
SUBGOAL_THEN
`!x y:real. (x == y) equiv <=> (y == x) equiv`
ASSUME_TAC THENL
[MATCH_MP_TAC(MESON[]
`(!x y. P x y ==> P y x) ==> (!x y. P x y <=> P y x)`) THEN
REWRITE_TAC[cong] THEN EXPAND_TAC "equiv" THEN
MESON_TAC[
INTEGER_CLOSED; REAL_ARITH
`x - y:real = (a + b * s) * q ==> y - x = (--a + --b * s) * q`];
ALL_TAC] THEN
SUBGOAL_THEN
`!x y z:real. (x == y) equiv /\ (y == z) equiv ==> (x == z) equiv`
ASSUME_TAC THENL
[REWRITE_TAC[cong] THEN EXPAND_TAC "equiv" THEN
MESON_TAC[
INTEGER_CLOSED; REAL_ARITH
`x - y = (a + b * s) * q /\
y - z = (a' + b' * s) * q
==> x - z:real = ((a + a') + (b + b') * s) * q`];
ALL_TAC] THEN
SUBGOAL_THEN
`!k. ?a b. (&2 + sqrt(&3)) pow k = &a + &b * sqrt(&3)`
STRIP_ASSUME_TAC THENL
[INDUCT_TAC THENL
[MAP_EVERY EXISTS_TAC [`1`; `0`] THEN REAL_ARITH_TAC;
FIRST_X_ASSUM(X_CHOOSE_THEN `a:num` MP_TAC) THEN
REWRITE_TAC[
real_pow;
LEFT_IMP_EXISTS_THM] THEN
X_GEN_TAC `b:num` THEN DISCH_THEN SUBST1_TAC THEN
MAP_EVERY EXISTS_TAC [`2 * a + 3 * b`; `2 * b + a`] THEN
REWRITE_TAC[GSYM REAL_OF_NUM_MUL; GSYM REAL_OF_NUM_ADD] THEN
MP_TAC(SPEC `&3`
SQRT_POW_2) THEN REWRITE_TAC[
REAL_POS] THEN
CONV_TAC REAL_RING];
ALL_TAC] THEN
SUBGOAL_THEN
`!x y. ((&2 + sqrt(&3)) * x == (&2 + sqrt(&3)) * y) equiv <=>
(x == y) equiv`
ASSUME_TAC THENL
[SUBGOAL_THEN
`!x y:real. (x == y) equiv <=> (x - y == &0) equiv`
(fun th -> ONCE_REWRITE_TAC[th])
THENL
[REWRITE_TAC[cong] THEN EXPAND_TAC "equiv" THEN SIMP_TAC[
REAL_SUB_RZERO];
REWRITE_TAC[GSYM
REAL_SUB_LDISTRIB]] THEN
REPEAT GEN_TAC THEN SPEC_TAC(`x - y:real`,`x:real`) THEN
X_GEN_TAC `x:real` THEN REWRITE_TAC[cong] THEN EXPAND_TAC "equiv" THEN
REWRITE_TAC[
REAL_SUB_RZERO] THEN EQ_TAC THEN
REWRITE_TAC[
LEFT_IMP_EXISTS_THM] THEN
MAP_EVERY X_GEN_TAC [`u:real`; `v:real`] THEN
REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
REWRITE_TAC[
REAL_SUB_RZERO] THEN DISCH_TAC THENL
[MAP_EVERY EXISTS_TAC [`&2 * u - &3 * v`; `&2 * v - u`];
MAP_EVERY EXISTS_TAC [`&2 * u + &3 * v`; `&2 * v + u`]] THEN
ASM_SIMP_TAC[
INTEGER_CLOSED] THEN
FIRST_X_ASSUM(MP_TAC o SYM) THEN
MP_TAC(SPEC `&3`
SQRT_POW_2) THEN REWRITE_TAC[
REAL_POS] THEN
CONV_TAC REAL_RING;
ALL_TAC] THEN
SUBGOAL_THEN
`((&2 + sqrt(&3)) pow (2
EXP (p - 1)) == -- &1) equiv`
ASSUME_TAC THENL
[UNDISCH_THEN `!x y:real. (x == y) equiv <=> (y == x) equiv`
(K ALL_TAC) THEN
MP_TAC(ISPECL [`2
EXP p - 1`; `p - 2`]
LLSEQ_CLOSEDFORM) THEN
ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[
EQ_SYM_EQ] THEN
ASM_SIMP_TAC[
MOD_EQ_0;
LEFT_AND_EXISTS_THM] THEN
ONCE_REWRITE_TAC[
SWAP_EXISTS_THM] THEN REWRITE_TAC[
UNWIND_THM2] THEN
DISCH_THEN(X_CHOOSE_THEN `r:num` (MP_TAC o
AP_TERM `(*) ((&2 + sqrt(&3)) pow (2 EXP (p - 2)))`)) THEN
REWRITE_TAC[] THEN ONCE_REWRITE_TAC[REAL_ADD_LDISTRIB] THEN
REWRITE_TAC[GSYM REAL_POW_MUL; GSYM REAL_POW_2; REAL_POW_POW] THEN
REWRITE_TAC[REAL_ARITH `(&2 + s) * (&2 - s) = &4 - s pow 2`] THEN
REWRITE_TAC[REAL_SQRT_POW_2; REAL_ABS_NUM] THEN
CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[REAL_POW_ONE] THEN
REWRITE_TAC[GSYM(CONJUNCT2 EXP)] THEN
ASM_SIMP_TAC[ARITH_RULE `2 <= p ==> SUC(p - 2) = p - 1`] THEN
SUBGOAL_THEN
`?a b. (&2 + sqrt(&3)) pow (2 EXP (p - 2)) = &a + &b * sqrt(&3)`
STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
REWRITE_TAC[cong] THEN EXPAND_TAC "equiv" THEN
REWRITE_TAC[REAL_SUB_RNEG] THEN DISCH_THEN SUBST1_TAC THEN
ASM_REWRITE_TAC[] THEN
FIRST_X_ASSUM(X_CHOOSE_THEN `s:num` SUBST1_TAC o
REWRITE_RULE[divides]) THEN
MAP_EVERY EXISTS_TAC [`&a * &r * &s`; `&b * &r * &s`] THEN
SIMP_TAC[INTEGER_CLOSED; GSYM REAL_OF_NUM_MUL] THEN REAL_ARITH_TAC;
ALL_TAC] THEN
SUBGOAL_THEN
`((&2 + sqrt(&3)) pow (2 EXP p) == &1) equiv`
ASSUME_TAC THENL
[FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [cong]) THEN
REWRITE_TAC[cong] THEN EXPAND_TAC "equiv" THEN
REWRITE_TAC[LEFT_IMP_EXISTS_THM; REAL_ARITH
`a - -- &1 = b <=> a = b - &1`] THEN
MAP_EVERY X_GEN_TAC [`a:real`; `b:real`] THEN STRIP_TAC THEN
SUBGOAL_THEN `p = (p - 1) + 1` SUBST1_TAC THENL
[UNDISCH_TAC `2 <= p` THEN ARITH_TAC; ALL_TAC] THEN
ASM_REWRITE_TAC[EXP_ADD; GSYM REAL_POW_POW] THEN
EXISTS_TAC `&q * (a pow 2 + &3 * b pow 2) - &2 * a` THEN
EXISTS_TAC `&2 * a * b * &q - &2 * b` THEN
REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[INTEGER_CLOSED]; ALL_TAC]) THEN
CONV_TAC NUM_REDUCE_CONV THEN
MP_TAC(SPEC `&3` SQRT_POW_2) THEN REWRITE_TAC[REAL_POS] THEN
CONV_TAC REAL_RING;
ALL_TAC] THEN
SUBGOAL_THEN
`?k. 0 < k /\ k <= 2 EXP p - 1 /\
!n. ((&2 + sqrt(&3)) pow n == &1) equiv <=> k divides n`
STRIP_ASSUME_TAC THENL
[MP_TAC(ISPEC `\x y:real. (x == y) equiv` ORDER_EXISTENCE_CARD) THEN
REWRITE_TAC[REAL_POW_ITER] THEN DISCH_THEN MATCH_MP_TAC THEN
ASM_REWRITE_TAC[] THEN MATCH_MP_TAC
(MESON[CARD_SUBSET; FINITE_SUBSET; LE_TRANS; CARD_IMAGE_LE; FINITE_IMAGE]
`!f:num#num->A t. s SUBSET IMAGE f t /\ FINITE t /\ CARD t <= n
==> FINITE s /\ CARD s <= n`) THEN
EXISTS_TAC `\(a,b) y. (y == &a + &b * sqrt(&3)) equiv` THEN
EXISTS_TAC `(0..q-1) CROSS (0..q-1)` THEN
SIMP_TAC[CARD_CROSS; FINITE_CROSS; FINITE_NUMSEG; CARD_NUMSEG] THEN
ASM_SIMP_TAC[SUB_ADD; SUB_0; LE_1; GSYM EXP_2; SUBSET] THEN
REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV; IN_IMAGE; EXISTS_PAIR_THM] THEN
X_GEN_TAC `n:num` THEN REWRITE_TAC[IN_CROSS; GSYM REAL_POW_ITER] THEN
FIRST_X_ASSUM(X_CHOOSE_THEN `a:num` MP_TAC o SPEC `n:num`) THEN
DISCH_THEN(X_CHOOSE_TAC `b:num`) THEN
MAP_EVERY EXISTS_TAC [`a MOD q`; `b MOD q`] THEN
ASM_SIMP_TAC[IN_NUMSEG; LE_0; DIVISION; FUN_EQ_THM;
ARITH_RULE `a <= q - 1 <=> a = 0 \/ a < q`] THEN
MATCH_MP_TAC(MESON[]
`(a == b) equiv /\
((a == b) equiv ==> !x. (x == a) equiv <=> (x == b) equiv)
==> !x. (x == a) equiv <=> (x == b) equiv`) THEN
CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
REWRITE_TAC[cong] THEN EXPAND_TAC "equiv" THEN
MAP_EVERY EXISTS_TAC [`&(a DIV q)`; `&(b DIV q)`] THEN
REWRITE_TAC[INTEGER_CLOSED; REAL_RING
`(a + b * s) - (a' + b' * s):real = (a'' + b'' * s) * q <=>
a + b * s = (a'' * q + a') + (b'' * q + b') * s`] THEN
REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_MUL] THEN
ASM_SIMP_TAC[GSYM DIVISION];
SUBGOAL_THEN `k divides 2 EXP p` MP_TAC THENL
[ASM_MESON_TAC[]; SIMP_TAC[DIVIDES_PRIMEPOW; PRIME_2]] THEN
REWRITE_TAC[LE_LT; RIGHT_OR_DISTRIB; EXISTS_OR_THM; UNWIND_THM2] THEN
ASM_SIMP_TAC[ARITH_RULE `k <= p - 1 ==> (k = p <=> p = 0)`] THEN
REWRITE_TAC[EXP_EQ_0; ARITH_EQ] THEN
DISCH_THEN(X_CHOOSE_THEN `i:num` STRIP_ASSUME_TAC) THEN
SUBGOAL_THEN
`((&2 + sqrt (&3)) pow (2 EXP (p - 1)) == &1) (equiv)`
ASSUME_TAC THENL
[ASM_REWRITE_TAC[] THEN SIMP_TAC[DIVIDES_EXP_LE; LE_REFL] THEN
ASM_SIMP_TAC[ARITH_RULE `i < p ==> i <= p - 1`];
ALL_TAC] THEN
SUBGOAL_THEN `(&1 == -- &1) (equiv)` MP_TAC THENL
[ASM_MESON_TAC[]; ALL_TAC] THEN
REWRITE_TAC[cong] THEN EXPAND_TAC "equiv" THEN
REWRITE_TAC[NOT_EXISTS_THM] THEN
MAP_EVERY X_GEN_TAC [`a:real`; `b:real`] THEN
REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
REWRITE_TAC[REAL_ARITH `&1 - -- &1 = &2`] THEN
ASM_CASES_TAC `b = &0` THENL
[ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_ADD_RID] THEN
DISCH_THEN(MP_TAC o AP_TERM `abs`) THEN REWRITE_TAC[REAL_ABS_MUL] THEN
SUBGOAL_THEN `?q. abs a = &q` (CHOOSE_THEN SUBST1_TAC)
THENL [ASM_MESON_TAC[integer]; REWRITE_TAC[REAL_ABS_NUM]] THEN
REWRITE_TAC[REAL_OF_NUM_MUL; REAL_OF_NUM_EQ] THEN
DISCH_THEN(ASSUME_TAC o SYM) THEN
MP_TAC PRIME_2 THEN REWRITE_TAC[prime; ARITH_EQ] THEN
DISCH_THEN(MP_TAC o SPEC `q:num`) THEN ANTS_TAC THENL
[REWRITE_TAC[divides] THEN ASM_MESON_TAC[MULT_SYM]; ALL_TAC] THEN
DISCH_THEN(DISJ_CASES_THEN SUBST_ALL_TAC) THENL
[ASM_MESON_TAC[NUM_REDUCE_CONV `2 <= 1`]; ALL_TAC] THEN
SUBGOAL_THEN `2 divides (2 EXP p - 1) + 2` MP_TAC THENL
[MATCH_MP_TAC DIVIDES_ADD THEN ASM_REWRITE_TAC[DIVIDES_REFL];
ASM_SIMP_TAC[ARITH_RULE `~(n - 1 = 0) ==> n - 1 + 2 = n + 1`]] THEN
REWRITE_TAC[DIVIDES_2; EVEN_ADD; EVEN_EXP; ARITH] THEN
UNDISCH_TAC `2 <= p` THEN ARITH_TAC;
DISCH_THEN(MP_TAC o MATCH_MP (REAL_FIELD
`&2 = (a + b * x) * q
==> ~(b = &0) ==> x = (&2 - a * q) / (b * q)`)) THEN
ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o AP_TERM `rational`) THEN
SIMP_TAC[IRRATIONAL_SQRT_PRIME; PRIME_CONV `prime 3`] THEN
ASM_MESON_TAC[RATIONAL_CLOSED; INTEGER_CLOSED]]]);;
(* ------------------------------------------------------------------------- *)
(* Actual evaluation of the LL sequence. *)
(* ------------------------------------------------------------------------- *)
let ll_verbose = ref false;;