(`!a n. coprime(a,n) ==> (a
REPEAT GEN_TAC THEN
ASM_CASES_TAC `n = 0` THEN
ASM_SIMP_TAC[
COPRIME_0;
PHI_0;
CONG_MOD_0] THEN CONV_TAC NUM_REDUCE_CONV THEN
ASM_CASES_TAC `n = 1` THEN ASM_REWRITE_TAC[
CONG_MOD_1] THEN DISCH_TAC THEN
SUBGOAL_THEN
`{ c | ?b. 0 < b /\ b < n /\ coprime(b,n) /\ (c = (a * b) MOD n) } =
{ b | 0 < b /\ b < n /\ coprime(b,n) }`
MP_TAC THENL
[REWRITE_TAC[
EXTENSION;
IN_ELIM_THM] THEN
X_GEN_TAC `c:num` THEN EQ_TAC THENL
[DISCH_THEN(X_CHOOSE_THEN `b:num` MP_TAC) THEN
REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
DISCH_THEN SUBST1_TAC THEN ASM_SIMP_TAC[
DIVISION] THEN
MATCH_MP_TAC(TAUT `b /\ (~a ==> ~b) ==> a /\ b`) THEN
SIMP_TAC[ARITH_RULE `~(0 < n) <=> (n = 0)`] THEN
ONCE_REWRITE_TAC[
COPRIME_SYM] THEN ASM_SIMP_TAC[
COPRIME_0] THEN
SUBGOAL_THEN `coprime(n,a * b)` MP_TAC THENL
[MATCH_MP_TAC
COPRIME_MUL THEN
ONCE_REWRITE_TAC[
COPRIME_SYM] THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN
SUBGOAL_THEN `a * b = (a * b) DIV n * n + (a * b) MOD n`
(fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [th])
THENL [ASM_SIMP_TAC[
DIVISION]; ALL_TAC] THEN
REWRITE_TAC[coprime] THEN REPEAT STRIP_TAC THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
ASM_SIMP_TAC[
DIVIDES_ADD;
DIVIDES_LMUL;
DIVIDES_REFL]; ALL_TAC] THEN
STRIP_TAC THEN MP_TAC(SPECL [`a:num`; `n:num`]
BEZOUT) THEN
DISCH_THEN(X_CHOOSE_THEN `d:num`
(X_CHOOSE_THEN `x:num` (X_CHOOSE_THEN `y:num`
(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC)))) THEN
SUBGOAL_THEN `d = 1` SUBST_ALL_TAC THENL
[ASM_MESON_TAC[coprime]; ALL_TAC] THEN
STRIP_TAC THENL
[EXISTS_TAC `(c * x) MOD n` THEN
MATCH_MP_TAC(TAUT `(~a ==> ~c) /\ b /\ c /\ d ==> a /\ b /\ c /\ d`) THEN
CONJ_TAC THENL
[SIMP_TAC[ARITH_RULE `~(0 < n) <=> (n = 0)`] THEN
ONCE_REWRITE_TAC[
COPRIME_SYM] THEN ASM_SIMP_TAC[
COPRIME_0];
ALL_TAC] THEN
ASM_SIMP_TAC[
DIVISION] THEN CONJ_TAC THENL
[SUBGOAL_THEN `coprime(n,c * x)` MP_TAC THENL
[MATCH_MP_TAC
COPRIME_MUL THEN
ONCE_REWRITE_TAC[
COPRIME_SYM] THEN ASM_REWRITE_TAC[] THEN
REWRITE_TAC[coprime; GSYM
DIVIDES_ONE] THEN
FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
SIMP_TAC[
DIVIDES_SUB;
DIVIDES_LMUL;
DIVIDES_RMUL;
DIVIDES_REFL];
ALL_TAC] THEN
SUBGOAL_THEN `c * x = (c * x) DIV n * n + (c * x) MOD n`
(fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [th])
THENL [ASM_SIMP_TAC[
DIVISION]; ALL_TAC] THEN
REWRITE_TAC[coprime] THEN REPEAT STRIP_TAC THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
ASM_SIMP_TAC[
DIVIDES_ADD;
DIVIDES_LMUL;
DIVIDES_REFL]; ALL_TAC] THEN
ASM_SIMP_TAC[
MOD_MULT_RMOD] THEN CONV_TAC SYM_CONV THEN
MATCH_MP_TAC
MOD_UNIQ THEN EXISTS_TAC `c * y:num` THEN
ASM_REWRITE_TAC[GSYM
MULT_ASSOC] THEN
ONCE_REWRITE_TAC[ARITH_RULE
`(a * c * x = b:num) <=> (c * a * x = b)`] THEN
FIRST_ASSUM(SUBST1_TAC o MATCH_MP (ARITH_RULE
`(a - b = 1) ==> (a = b + 1)`)) THEN
REWRITE_TAC[
LEFT_ADD_DISTRIB;
MULT_CLAUSES;
MULT_AC];
EXISTS_TAC `(c * (n - y MOD n)) MOD n` THEN
MATCH_MP_TAC(TAUT `(~a ==> ~c) /\ b /\ c /\ d ==> a /\ b /\ c /\ d`) THEN
CONJ_TAC THENL
[SIMP_TAC[ARITH_RULE `~(0 < n) <=> (n = 0)`] THEN
ONCE_REWRITE_TAC[
COPRIME_SYM] THEN ASM_SIMP_TAC[
COPRIME_0];
ALL_TAC] THEN
ASM_SIMP_TAC[
DIVISION] THEN CONJ_TAC THENL
[SUBGOAL_THEN `coprime(n,c * (n - y MOD n))` MP_TAC THENL
[MATCH_MP_TAC
COPRIME_MUL THEN
ONCE_REWRITE_TAC[
COPRIME_SYM] THEN ASM_REWRITE_TAC[] THEN
REWRITE_TAC[coprime; GSYM
DIVIDES_ONE] THEN
FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
X_GEN_TAC `e:num` THEN STRIP_TAC THEN MATCH_MP_TAC
DIVIDES_SUB THEN
ASM_SIMP_TAC[
DIVIDES_RMUL;
DIVIDES_REFL] THEN
MATCH_MP_TAC
DIVIDES_LMUL THEN
SUBGOAL_THEN `y = (y DIV n) * n + y MOD n` SUBST1_TAC THENL
[ASM_SIMP_TAC[
DIVISION]; ALL_TAC] THEN
MATCH_MP_TAC
DIVIDES_ADD THEN
ASM_SIMP_TAC[
DIVIDES_LMUL;
DIVIDES_REFL] THEN
MATCH_MP_TAC
DIVIDES_ADD_REVR THEN
EXISTS_TAC `n - y MOD n` THEN ASM_REWRITE_TAC[] THEN
ASM_SIMP_TAC[ARITH_RULE `m < n ==> ((n - m) + m = n:num)`;
DIVISION];
ALL_TAC] THEN
SUBGOAL_THEN `!x. c * x = (c * x) DIV n * n + (c * x) MOD n`
(fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [th])
THENL [ASM_SIMP_TAC[
DIVISION]; ALL_TAC] THEN
REWRITE_TAC[coprime] THEN REPEAT STRIP_TAC THEN
FIRST_X_ASSUM MATCH_MP_TAC THEN
ASM_SIMP_TAC[
DIVIDES_ADD;
DIVIDES_LMUL;
DIVIDES_REFL]; ALL_TAC] THEN
ASM_SIMP_TAC[
MOD_MULT_RMOD] THEN
CONV_TAC SYM_CONV THEN MATCH_MP_TAC
MOD_UNIQ THEN
ASM_REWRITE_TAC[] THEN MATCH_MP_TAC
DIFFERENCE_POS_LEMMA THEN
CONJ_TAC THENL
[ONCE_REWRITE_TAC[ARITH_RULE
`c <= a * c * x <=> c * 1 <= c * a * x`] THEN
REWRITE_TAC[
LE_MULT_LCANCEL] THEN DISJ2_TAC THEN
REWRITE_TAC[ARITH_RULE `1 <= n <=> ~(n = 0)`;
MULT_EQ_0;
SUB_EQ_0; DE_MORGAN_THM] THEN
UNDISCH_TAC `coprime(a,n)` THEN ONCE_REWRITE_TAC[
COPRIME_SYM] THEN
ASM_CASES_TAC `a = 0` THEN ASM_REWRITE_TAC[
COPRIME_0] THEN
DISCH_TAC THEN ASM_SIMP_TAC[
DIVISION;
NOT_LE]; ALL_TAC] THEN
MAP_EVERY EXISTS_TAC [`c * x`; `c * a * (1 + y DIV n)`] THEN
REWRITE_TAC[
LEFT_ADD_DISTRIB;
LEFT_SUB_DISTRIB] THEN
MATCH_MP_TAC(ARITH_RULE
`y <= n /\ (a + n = x + y) ==> (a + (n - y) = x)`) THEN
CONJ_TAC THENL
[REWRITE_TAC[
MULT_ASSOC] THEN REWRITE_TAC[
LE_MULT_LCANCEL] THEN
ASM_SIMP_TAC[
LT_IMP_LE;
DIVISION]; ALL_TAC] THEN
REWRITE_TAC[
LEFT_ADD_DISTRIB;
RIGHT_ADD_DISTRIB;
MULT_CLAUSES] THEN
REWRITE_TAC[GSYM
ADD_ASSOC; GSYM
MULT_ASSOC] THEN
REWRITE_TAC[ARITH_RULE
`(x + a * c * n = c * a * n + y) <=> (x = y)`] THEN
FIRST_ASSUM(SUBST1_TAC o MATCH_MP (ARITH_RULE
`(n * x - a * y = 1) ==> (x * n = a * y + 1)`)) THEN
SUBGOAL_THEN `y = (y DIV n) * n + y MOD n`
(fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [th])
THENL [ASM_SIMP_TAC[
DIVISION]; ALL_TAC] THEN
REWRITE_TAC[
LEFT_ADD_DISTRIB;
RIGHT_ADD_DISTRIB;
MULT_CLAUSES] THEN
REWRITE_TAC[
MULT_AC;
ADD_AC]];
ALL_TAC] THEN
SUBGOAL_THEN
`{c | ?b. 0 < b /\ b < n /\ coprime (b,n) /\ (c = (a * b) MOD n)} =
IMAGE (\b. (a * b) MOD n) {b | 0 < b /\ b < n /\ coprime (b,n)}`
SUBST1_TAC THENL
[REWRITE_TAC[
IMAGE;
EXTENSION;
IN_ELIM_THM;
CONJ_ASSOC]; ALL_TAC] THEN
DISCH_THEN(MP_TAC o AP_TERM `
ITSET (\x y. (x * y) MOD n)`) THEN
DISCH_THEN(MP_TAC o C AP_THM `1`) THEN
SUBGOAL_THEN `
FINITE {b | 0 < b /\ b < n /\ coprime (b,n)} /\
!b. b
IN {b | 0 < b /\ b < n /\ coprime (b,n)} ==> b < n`
ASSUME_TAC THENL
[CONJ_TAC THENL [ALL_TAC; SIMP_TAC[
IN_ELIM_THM]] THEN
MATCH_MP_TAC
FINITE_SUBSET THEN EXISTS_TAC `{b | 0 < b /\ b < n}` THEN
REWRITE_TAC[REWRITE_RULE[
HAS_SIZE]
FINITE_NUMBER_SEGMENT] THEN
SIMP_TAC[
SUBSET;
IN_ELIM_THM]; ALL_TAC] THEN
ASM_SIMP_TAC[REWRITE_RULE[IMP_IMP]
ITSET_MODMULT] THEN
ASM_SIMP_TAC[GSYM
PHI_ANOTHER] THEN
DISCH_THEN(MP_TAC o AP_TERM `(MOD)`) THEN
DISCH_THEN(MP_TAC o C AP_THM `n:num`) THEN
ASM_SIMP_TAC[
MOD_MOD_REFL] THEN ASM_SIMP_TAC[GSYM
CONG] THEN
GEN_REWRITE_TAC (LAND_CONV o RATOR_CONV o RAND_CONV)
[ARITH_RULE `x = x * 1`] THEN
GEN_REWRITE_TAC (LAND_CONV o RATOR_CONV o LAND_CONV) [
MULT_SYM] THEN
DISCH_TAC THEN MATCH_MP_TAC
CONG_MULT_LCANCEL THEN
EXISTS_TAC `
ITSET (\x y. (x * y) MOD n)
{b | 0 < b /\ b < n /\ coprime (b,n)} 1` THEN
ASM_REWRITE_TAC[] THEN
ASM_SIMP_TAC[
ITSET_MODMULT_COPRIME;
IN_ELIM_THM]);;