(`!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]);;