(* listRepeat is used to show some interesting properties of rel_map and pred_count. *)
Fixpoint listRepeat(A : Type)(a : A) n :=
  match n with
    | 0 => nil
    | S n' => a :: (listRepeat a n')
  end.

(* Specifications: *)
Lemma listRepeat_length : forall n (A : Type) (a : A), length (listRepeat a n) = n.
Lemma pred_count_listRepeat_eq_inv : forall n (A : Type)(a : A) count, pred_count (eq a) (listRepeat a n) count -> count = n.
Lemma pred_count_listRepeat_ne_inv : forall n (A : Type)(a1 a2 : A) count, a1 <> a2 -> pred_count (eq a1) (listRepeat a2 n) count -> count = O.
Lemma pred_count_func : forall (A : Type)(P : A -> Prop)(ls : list A) n1 n2, pred_count P ls n1 -> pred_count P ls n2 -> n1 = n2.
Lemma pred_count_eq_all_inv : forall (A : Type)(ls : list A)(P : A -> Prop) c, pred_count P ls c -> (forall a, In a ls -> P a) -> c = length ls.
Lemma pred_count_first_skip : forall (A : Type)(P : A -> Prop)(ls : list A)(c : nat), pred_count P ls c -> forall n, exists c1 c2, pred_count P (firstn n ls) c1 /\ pred_count P (skipn n ls) c2 /\ (c1 + c2 = c)%nat.
Lemma pred_count_eq_all : forall (A : Type)(P : A -> Prop)(ls : list A) n, (forall a, In a ls -> P a) -> n = length ls -> pred_count P ls n.
Lemma pred_count_eq_none : forall (A : Type)(P : A -> Prop)(ls : list A), (forall a, In a ls -> ~P a) -> pred_count P ls 0.
Lemma in_listRepeat_inv : forall n (A : Type)(a1 a2 : A), In a1 (listRepeat a2 n) -> a1 = a2.
Lemma pred_count_app : forall (A : Type)(P : A -> Prop)(ls1 ls2 : list A) n1 n2, pred_count P ls1 n1 -> pred_count P ls2 n2 -> pred_count P (ls1 ++ ls2) (n1 + n2).
Lemma pred_count_permutation : forall (A : Set)(P : A -> Prop)(ls1 ls2 : list A), Permutation ls1 ls2 -> forall c, pred_count P ls1 c -> pred_count P ls2 c.
Lemma pred_count_eq_none_inv : forall (A : Set)(P : A -> Prop)(ls : list A) c, pred_count P ls c -> (forall a, In a ls -> ~P a) -> c = O.
Lemma pred_count_eq_1_inv : forall (A : Set)(eqd : eq_dec A)(P : A -> Prop)(ls : list A) c a, pred_count P ls c -> NoDup ls -> P a -> In a ls -> (forall a', In a' ls -> a <> a' -> ~P a') -> c = (S O).
Lemma pred_count_left_total : forall (A : Type)(P : A -> Prop)(ls : list A), (forall a, P a \/ ~P a) -> exists c, pred_count P ls c.