(* ========================================================================= *)
(* Ballot problem.                                                           *)
(* ========================================================================= *)
needs "Library/binomial.ml";;
prioritize_num();;
(* ------------------------------------------------------------------------- *)
(* Restricted function space.                                                *)
(* ------------------------------------------------------------------------- *)
parse_as_infix("-->",(13,"right"));;
(* ------------------------------------------------------------------------- *)
(* Definition of the problem.                                                *)
(* ------------------------------------------------------------------------- *)
;
(* ------------------------------------------------------------------------- *)
(* Various lemmas.                                                           *)
(* ------------------------------------------------------------------------- *)
let vote_CASES = cases "vote"
and vote_DISTINCT = distinctness "vote";;
let FORALL_RANGE_SUC = prove
 (`(!i. 1 <= i /\ i <= n + 1 ==> P i) <=>
      P(n + 1) /\ (!i. 1 <= i /\ i <= n ==> P i)`,
  REWRITE_TAC[ARITH_RULE `i <= n + 1 <=> i <= n \/ i = n + 1`] THEN
  MESON_TAC[ARITH_RULE `1 <= n + 1`]);;
 
let VOTE_NOT_EQ = prove
 (`(!x. ~(x = A) <=> x = B) /\
   (!x. ~(x = B) <=> x = A)`,
  MESON_TAC[vote_CASES; vote_DISTINCT]);;
 
let FUNSPACE_FIXED = prove
 (`{f | f 
IN (s --> t) /\ (!i. i 
IN s ==> f i = a)} =
   if s = {} \/ a 
IN t then {(\i. if i 
IN s then a else @x. T)} else {}`,
 
let COUNTING_LEMMA = prove
 (`
CARD {f | f 
IN (1..(n+1) --> {A,B}) /\ P f} =
   
CARD {f | f 
IN (1..n --> {A,B}) /\ P (\i. if i = n + 1 then A else f i)} +
   
CARD {f | f 
IN (1..n --> {A,B}) /\ P (\i. if i = n + 1 then B else f i)}`,