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