(* ========================================================================= *)
(* Binomial coefficients and relation to number of combinations.             *)
(* ========================================================================= *)
prioritize_num();;
(* ------------------------------------------------------------------------- *)
(* Binomial coefficients.                                                    *)
(* ------------------------------------------------------------------------- *)
let binom = define
  `(!n. binom(n,0) = 1) /\
   (!k. binom(0,SUC(k)) = 0) /\
   (!n k. binom(SUC(n),SUC(k)) = binom(n,SUC(k)) + binom(n,k))`;;
let BINOM_LT = prove
 (`!n k. n < k ==> (binom(n,k) = 0)`,
  INDUCT_TAC THEN INDUCT_TAC THEN REWRITE_TAC[binom; ARITH; 
LT_SUC; 
LT] THEN
  ASM_SIMP_TAC[ARITH_RULE `n < k ==> n < SUC(k)`; ARITH]);;
 
let lemma = prove
 (`~(a 
IN t)
   ==> {u | u 
SUBSET (a:A 
INSERT t) /\ u 
HAS_SIZE (SUC m)} =
       {u | u 
SUBSET t /\ u 
HAS_SIZE (SUC m)} 
UNION
       IMAGE (\u. a 
INSERT u) {u | u 
SUBSET t /\ u 
HAS_SIZE m}`,
  REPEAT STRIP_TAC THEN GEN_REWRITE_TAC I [
EXTENSION] THEN
  REWRITE_TAC[
IN_UNION; 
IN_IMAGE; 
IN_ELIM_THM] THEN X_GEN_TAC `u:A->bool` THEN
  ASM_CASES_TAC `(u:A->bool) 
SUBSET t` THEN ASM_REWRITE_TAC[] THENL
   [ASM_CASES_TAC `(u:A->bool) 
HAS_SIZE (SUC m)` THEN ASM_REWRITE_TAC[] THEN
    ASM SET_TAC[];
    ALL_TAC] THEN
  EQ_TAC THEN STRIP_TAC THENL
   [EXISTS_TAC `u 
DELETE (a:A)`  THEN
    REPEAT (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
HAS_SIZE_SUC]) THEN
    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MATCH_MP_TAC) THEN ASM SET_TAC[];
    CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
    REWRITE_TAC[
HAS_SIZE_CLAUSES] THEN
    EXISTS_TAC `a:A` THEN EXISTS_TAC `x':A->bool` THEN
    ASM SET_TAC[]]);;
 
let BINOM_INDUCT = prove
 (`!P. (!n. P n 0) /\       
       (!k. P 0 (SUC k)) /\                
       (!n k. P n (SUC k) /\ P n k ==> P (SUC n) (SUC k))
       ==> !m n. P m n`,
                                                       
  GEN_TAC THEN STRIP_TAC THEN REPEAT INDUCT_TAC THEN ASM_MESON_TAC[]);;