(* The traditional functional zip and unzip. *)
(* TODO: get rid of these and replace with combine and split *)
Definition unzip(A B : Set)(ls : list (A * B)) :=
  (map (@fst _ _) ls, map (@snd _ _) ls).Fixpoint zip(A B : Set)(lsa : list A)(lsb : list B) :=
  match lsa with
    | nil => nil
    | a :: lsa' =>
      match lsb with
        | nil => nil
        | b :: lsb' =>
          (a, b) :: (zip lsa' lsb')
      end
  end.Ltac pairInv := 
  match goal with
    | [H : (_, _) = (_, _) |- _] => 
      inversion H; clear H; subst
  end.Fixpoint removeDups(ls : list A) :=
    match ls with
      | nil => nil
      | a' :: ls' =>
        if (in_dec (EqDec_dec _) a' ls') then (removeDups ls') else (a' :: (removeDups ls'))
    end.

(* Specifications: *)
Theorem removeDups_in : forall (ls : list A) a, In a (removeDups ls) -> In a ls.
Theorem removeDups_NoDup : forall (ls : list A), NoDup (removeDups ls).
Lemma in_removeDups : forall (ls : list A) a, In a ls -> In a (removeDups ls).