Section Uniq.
Variable A: Type.
Inductive uniq: list A -> Prop :=
uniq_nil: uniq nil
| uniq_cons: forall a l, ~ In a l -> uniq l -> uniq (a::l).
End Uniq.
destruct l as [|a l]; simpl; auto.
right; intros HH; discriminate.
Qed.
Arguments uniq[A].
(* Georges' trick for easy case analysis *)
Inductive eq_Spec (A: Type) (x y: A): bool -> Prop :=
|eq_Spect:  x = y -> eq_Spec A x y true
|eq_Specf: x <> y -> eq_Spec A x y false.
Arguments eq_Spec[A].
(** Binomial Coefficient defined using Pascal's triangle *)
Fixpoint bin (a b : nat) {struct a} : nat :=
match a, b with
_, O => 1
| O, S b' => 0
| S a', S b' => bin a' (S b') + bin a' b'
end.
intros n; induction n; auto.
Qed.
intros; induction n as [|n IH]; simpl; auto.
rewrite bin_0, IH, Plus.plus_comm; auto.
Qed.
intros n; induction n as [| n IH]; simpl; auto.
intros m; case m; simpl; auto.
intros H'; inversion H'; auto.
intros m; case m; simpl; auto.
intros H'0; contradict H'0; auto with arith.
intros n1 H'0; rewrite !IH; auto with arith.
Qed.
intros n; induction n as [| n IH]; intros; simpl; auto.
rewrite (bin_more n (S n)); auto.
Qed.
simpl; auto.
Qed.
Fixpoint iter {A: Type} (f: A -> A) (n: nat) (x: A) :=
match n with
| O => x
| S n1 => f (iter f n1 x)
end.
(* A bit of ssreflect *)
Coercion b2Prop (x : bool) := x = true.
(* Some facts about div2 *)
Fixpoint eq_nat (m n: nat) :=
match m, n with (S m), (S n) => eq_nat m n | 0, 0 => true | _, _ => false end.
Notation "m ?= n" := (eq_nat m n) (at level 70): nat_scope.
Inductive eq_nat_spec: nat -> nat -> bool -> Type :=
eq_nat_spect: forall m, eq_nat_spec m m true
| eq_nat_specb: forall m n, m <> n -> eq_nat_spec m n false.

Lemma eq_natP m n: eq_nat_spec m n (m ?= n).