(`!n s:A->bool. s 
  MATCH_MP_TAC 
DERANGEMENT_INDUCT THEN REWRITE_TAC[derangements] THEN
  REPEAT CONJ_TAC THENL
   [CONV_TAC(ONCE_DEPTH_CONV HAS_SIZE_CONV) THEN REPEAT STRIP_TAC THEN
    EXISTS_TAC `{}:A#A->bool` THEN
    ASM_REWRITE_TAC[
DERANGEMENT_EMPTY; 
EXTENSION; 
IN_ELIM_THM] THEN
    REWRITE_TAC[
NOT_IN_EMPTY; 
IN_SING] THEN MESON_TAC[
MEMBER_NOT_EMPTY];
    CONV_TAC(ONCE_DEPTH_CONV HAS_SIZE_CONV) THEN REPEAT STRIP_TAC THEN
    ASM_REWRITE_TAC[
DERANGEMENT_SING] THEN SET_TAC[];
    ALL_TAC] THEN
  X_GEN_TAC `n:num` THEN STRIP_TAC THEN X_GEN_TAC `t:A->bool` THEN
  REWRITE_TAC[ARITH_RULE `n + 2 = SUC(n + 1)`; 
HAS_SIZE_CLAUSES] THEN
  REWRITE_TAC[
LEFT_IMP_EXISTS_THM] THEN
  MAP_EVERY X_GEN_TAC [`x:A`; `s:A->bool`] THEN
  STRIP_TAC THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN
  SUBGOAL_THEN
   `{p | p deranges (x:A 
INSERT s)} =
        (
IMAGE (\(y,p). (x,y) 
INSERT (y,x) 
INSERT p)
               {(y,p) | y 
IN s /\ p 
IN {p | p deranges (s 
DELETE y)}}) 
UNION
        (
IMAGE (\(y,p). let z = @z. p(x,z) in
                        (x,y) 
INSERT (y,z) 
INSERT (p 
DELETE (x,z)))
               {(y,p) | y 
IN s /\
                        p 
IN {p | p deranges (x 
INSERT (s 
DELETE y))}})`
  SUBST1_TAC THENL
   [GEN_REWRITE_TAC I [
EXTENSION] THEN
    REWRITE_TAC[TAUT `(a <=> b) <=> (b ==> a) /\ (a ==> b)`] THEN
    REWRITE_TAC[
FORALL_AND_THM] THEN CONJ_TAC THENL
     [REWRITE_TAC[
IN_UNION; TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`;
                  
FORALL_AND_THM; 
FORALL_IN_IMAGE] THEN
      REWRITE_TAC[
FORALL_PAIR_THM; 
PAIR_BETA_THM; 
IN_ELIM_THM; 
PAIR_EQ] THEN
      ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c /\ d <=> c /\ d /\ a /\ b`] THEN
      REWRITE_TAC[
RIGHT_EXISTS_AND_THM; 
UNWIND_THM1] THEN
      CONJ_TAC THEN MAP_EVERY X_GEN_TAC [`y:A`; `p:A#A->bool`] THEN
      STRIP_TAC THENL
       [FIRST_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE
         `y 
IN s ==> s = y 
INSERT (s 
DELETE y)`)) THEN
        MATCH_MP_TAC 
DERANGEMENT_ADD2 THEN ASM_REWRITE_TAC[
IN_DELETE] THEN
        ASM_MESON_TAC[];
        ALL_TAC] THEN
      ABBREV_TAC `z = @z. p(x:A,z:A)` THEN
      SUBGOAL_THEN `(p:A#A->bool)(x:A,z:A)` STRIP_ASSUME_TAC THENL
       [REPEAT(FIRST_X_ASSUM(SUBST1_TAC o SYM)) THEN
        CONV_TAC SELECT_CONV THEN
        REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC;
        ALL_TAC] THEN
      SUBGOAL_THEN `z:A 
IN s` STRIP_ASSUME_TAC THENL
       [REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC; ALL_TAC] THEN
      REWRITE_TAC[
LET_DEF; 
LET_END_DEF] THEN
      SUBGOAL_THEN `(x:A) 
INSERT s = y 
INSERT (x 
INSERT (s 
DELETE y))`
      SUBST1_TAC THENL
       [REPEAT(POP_ASSUM MP_TAC) THEN SET_TAC[]; ALL_TAC] THEN
      MATCH_MP_TAC 
DERANGEMENT_ADD1 THEN ASM_REWRITE_TAC[] THEN
      ASM_REWRITE_TAC[
IN_DELETE; 
IN_INSERT] THEN ASM_MESON_TAC[];
      ALL_TAC] THEN
    X_GEN_TAC `p:A#A->bool` THEN REWRITE_TAC[
IN_ELIM_THM] THEN DISCH_TAC THEN
    SUBGOAL_THEN `?y. y 
IN s /\ p(x:A,y:A)` STRIP_ASSUME_TAC THENL
     [REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC; ALL_TAC] THEN
    REWRITE_TAC[
IN_UNION] THEN ASM_CASES_TAC `(p:A#A->bool)(y,x)` THENL
     [DISJ1_TAC THEN REWRITE_TAC[
IN_IMAGE] THEN
      EXISTS_TAC `y:A,(p 
DELETE (y,x)) 
DELETE (x:A,y:A)` THEN
      CONJ_TAC THENL
       [REWRITE_TAC[
PAIR_BETA_THM] THEN MAP_EVERY UNDISCH_TAC
         [`(p:A#A->bool)(x,y)`; `(p:A#A->bool)(y,x)`] THEN SET_TAC[];
        ALL_TAC] THEN
      REWRITE_TAC[
IN_ELIM_THM; 
PAIR_EQ] THEN
      ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c /\ d <=> c /\ d /\ a /\ b`] THEN
      ASM_REWRITE_TAC[
RIGHT_EXISTS_AND_THM; 
UNWIND_THM1] THEN
      REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC;
      ALL_TAC] THEN
    SUBGOAL_THEN `?z. p(y:A,z:A)` STRIP_ASSUME_TAC THENL
     [REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC; ALL_TAC] THEN
    SUBGOAL_THEN `z:A 
IN s` ASSUME_TAC THENL
     [REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC; ALL_TAC] THEN
    DISJ2_TAC THEN REWRITE_TAC[
IN_IMAGE; 
EXISTS_PAIR_THM; 
PAIR_BETA_THM] THEN
    EXISTS_TAC `y:A` THEN
    EXISTS_TAC `(x:A,z:A) 
INSERT ((p 
DELETE (x,y)) 
DELETE (y,z))` THEN
    SUBGOAL_THEN
     `(@w:A. ((x,z) 
INSERT (p 
DELETE (x,y) 
DELETE (y,z))) (x,w)) = z`
    SUBST1_TAC THENL
     [MATCH_MP_TAC 
SELECT_UNIQUE THEN REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC;
      ALL_TAC] THEN
    REWRITE_TAC[
LET_DEF; 
LET_END_DEF] THEN CONJ_TAC THENL
     [REWRITE_TAC[
EXTENSION; 
FORALL_PAIR_THM; 
PAIR_BETA_THM] THEN
      REWRITE_TAC[
IN; 
INSERT; 
DELETE; 
PAIR_BETA_THM; 
IN_ELIM_THM; 
PAIR_EQ] THEN
      MAP_EVERY X_GEN_TAC [`u:A`; `v:A`] THEN
      ASM_CASES_TAC `u:A = x` THEN ASM_REWRITE_TAC[] THENL
       [ALL_TAC; REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC] THEN
      FIRST_X_ASSUM SUBST_ALL_TAC THEN REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC;
      ALL_TAC] THEN
    REWRITE_TAC[
IN_ELIM_THM; 
PAIR_EQ] THEN
    ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c /\ d <=> c /\ d /\ a /\ b`] THEN
    ASM_REWRITE_TAC[
RIGHT_EXISTS_AND_THM; 
UNWIND_THM1] THEN
    REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC;
    ALL_TAC] THEN
  REWRITE_TAC[
LEFT_ADD_DISTRIB] THEN MATCH_MP_TAC 
HAS_SIZE_UNION THEN
  REPEAT CONJ_TAC THENL
   [MATCH_MP_TAC 
HAS_SIZE_IMAGE_INJ THEN CONJ_TAC THENL
     [REWRITE_TAC[
FORALL_PAIR_THM; 
IN_ELIM_THM; 
PAIR_BETA_THM; 
PAIR_EQ] THEN
      ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c /\ d <=> c /\ d /\ a /\ b`] THEN
      REWRITE_TAC[
RIGHT_EXISTS_AND_THM; 
UNWIND_THM1] THEN
      REWRITE_TAC[
FUN_EQ_THM; 
INSERT; 
IN_ELIM_THM; 
FORALL_PAIR_THM;
                  
PAIR_EQ] THEN
      UNDISCH_TAC `~(x:A 
IN s)` THEN REL_TAC;
      ALL_TAC] THEN
    MATCH_MP_TAC 
HAS_SIZE_PRODUCT_DEPENDENT THEN ASM_REWRITE_TAC[] THEN
    REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
    UNDISCH_TAC `(s:A->bool) 
HAS_SIZE (n + 1)` THEN
    SIMP_TAC[
HAS_SIZE; 
FINITE_DELETE; 
CARD_DELETE] THEN
    ASM_REWRITE_TAC[
ADD_SUB];
    MATCH_MP_TAC 
HAS_SIZE_IMAGE_INJ THEN CONJ_TAC THENL
     [REWRITE_TAC[
FORALL_PAIR_THM; 
IN_ELIM_THM; 
PAIR_BETA_THM; 
PAIR_EQ] THEN
      ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c /\ d <=> c /\ d /\ a /\ b`] THEN
      REWRITE_TAC[
RIGHT_EXISTS_AND_THM; 
UNWIND_THM1] THEN MAP_EVERY X_GEN_TAC
       [`y:A`; `p:(A#A)->bool`; `y':A`; `p':(A#A->bool)`] THEN
      DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
      DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
      MAP_EVERY ABBREV_TAC [`z = @z. p(x:A,z:A)`; `z' = @z. p'(x:A,z:A)`] THEN
      REWRITE_TAC[
LET_DEF; 
LET_END_DEF] THEN
      SUBGOAL_THEN `p(x:A,z:A) /\ p'(x:A,z':A)` STRIP_ASSUME_TAC THENL
       [REPEAT(FIRST_X_ASSUM(SUBST1_TAC o SYM)) THEN
        CONJ_TAC THEN CONV_TAC SELECT_CONV THEN
        REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC;
        ALL_TAC] THEN
      REPEAT(FIRST_X_ASSUM(K ALL_TAC o SYM)) THEN
      SUBGOAL_THEN `z:A 
IN s /\ z':A 
IN s` STRIP_ASSUME_TAC THENL
       [REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC; ALL_TAC] THEN
      DISCH_THEN(fun th -> MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN
                           CONJ_TAC THEN MP_TAC th)
      THENL
       [DISCH_THEN(MP_TAC o C AP_THM `(x:A,y:A)`) THEN
        REWRITE_TAC[
INSERT; 
DELETE; 
IN_ELIM_THM; 
PAIR_BETA_THM; 
PAIR_EQ] THEN
        REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC;
        ALL_TAC] THEN
      ONCE_REWRITE_TAC[TAUT `a ==> b ==> c <=> b ==> a ==> c`] THEN
      DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
      ASM_CASES_TAC `z':A = z` THEN ASM_REWRITE_TAC[] THENL
       [FIRST_X_ASSUM SUBST_ALL_TAC;
        DISCH_THEN(MP_TAC o C AP_THM `(y:A,z:A)`) THEN
        REWRITE_TAC[
INSERT; 
DELETE; 
IN_ELIM_THM; 
PAIR_BETA_THM; 
PAIR_EQ] THEN
        REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC] THEN
      DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
       `a 
INSERT b 
INSERT s = a 
INSERT b 
INSERT t
        ==> ~(a 
IN s) /\ ~(a 
IN t) /\ ~(b 
IN s) /\ ~(b 
IN t) ==> s = t`)) THEN
      REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC;
      ALL_TAC] THEN
    MATCH_MP_TAC 
HAS_SIZE_PRODUCT_DEPENDENT THEN ASM_REWRITE_TAC[] THEN
    REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
    ASM_REWRITE_TAC[] THEN UNDISCH_TAC `(s:A->bool) 
HAS_SIZE n + 1` THEN
    ASM_SIMP_TAC[
HAS_SIZE; 
FINITE_INSERT; 
FINITE_DELETE] THEN
    ASM_SIMP_TAC[
CARD_DELETE; 
CARD_CLAUSES; 
FINITE_DELETE] THEN
    ASM_REWRITE_TAC[
IN_DELETE] THEN ARITH_TAC;
    REWRITE_TAC[
DISJOINT] THEN
    GEN_REWRITE_TAC I [
EXTENSION] THEN
    REWRITE_TAC[
NOT_IN_EMPTY; 
IN_INTER; TAUT `~(a /\ b) <=> a ==> ~b`] THEN
    REWRITE_TAC[
FORALL_IN_IMAGE] THEN REWRITE_TAC[
FORALL_PAIR_THM] THEN
    MAP_EVERY X_GEN_TAC [`y:A`; `p:A#A->bool`] THEN
    REWRITE_TAC[
IN_ELIM_THM; 
PAIR_BETA_THM; 
PAIR_EQ] THEN
    ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c /\ d <=> c /\ d /\ a /\ b`] THEN
    REWRITE_TAC[
RIGHT_EXISTS_AND_THM; 
UNWIND_THM1] THEN
    STRIP_TAC THEN REWRITE_TAC[
IN_IMAGE; 
EXISTS_PAIR_THM; 
NOT_EXISTS_THM] THEN
    MAP_EVERY X_GEN_TAC [`z:A`; `q:A#A->bool`] THEN
    REWRITE_TAC[
PAIR_BETA_THM; 
IN_ELIM_THM; 
PAIR_EQ] THEN
    ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c /\ d <=> c /\ d /\ a /\ b`] THEN
    REWRITE_TAC[
RIGHT_EXISTS_AND_THM; 
UNWIND_THM1] THEN
    DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
    ABBREV_TAC `w = @w. q(x:A,w:A)` THEN
    SUBGOAL_THEN `(q:A#A->bool)(x:A,w:A)` STRIP_ASSUME_TAC THENL
     [REPEAT(FIRST_X_ASSUM(SUBST1_TAC o SYM)) THEN
      CONV_TAC SELECT_CONV THEN
      REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC;
      ALL_TAC] THEN
    SUBGOAL_THEN `w:A 
IN s` STRIP_ASSUME_TAC THENL
     [REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC; ALL_TAC] THEN
    REWRITE_TAC[
LET_DEF; 
LET_END_DEF] THEN FIRST_X_ASSUM(K ALL_TAC o SYM) THEN
    ASM_CASES_TAC `w:A = z` THEN ASM_REWRITE_TAC[] THENL
     [REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC; ALL_TAC] THEN
    ASM_CASES_TAC `w:A = y` THEN ASM_REWRITE_TAC[] THENL
     [FIRST_X_ASSUM SUBST_ALL_TAC THEN
      REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC;
      ALL_TAC] THEN
    ASM_CASES_TAC `y:A = z` THENL
     [FIRST_X_ASSUM SUBST_ALL_TAC; ALL_TAC] THEN
    REPEAT(POP_ASSUM MP_TAC) THEN REL_TAC]);;