(** [list_equiv l1 l2] holds iff the lists [l1] and [l2] contain the same elements. *)

Definition list_equiv (A : Type) (l1 l2: list A) : Prop :=
  forall x, In x l1 <-> In x l2.(** [list_norepet l] holds iff the list [l] contains no repetitions,
  i.e. no element occurs twice. *)

Inductive list_norepet (A: Type) : list A -> Prop :=
  | list_norepet_nil:
      list_norepet nil
  | list_norepet_cons:
      forall hd tl,
      ~(In hd tl) -> list_norepet tl -> list_norepet (hd :: tl).(** [list_norepet l] holds iff the list [l] contains no repetitions,
  i.e. no element occurs twice. *)

Inductive list_norepet (A: Type) : list A -> Prop :=
  | list_norepet_nil:
      list_norepet nil
  | list_norepet_cons:
      forall hd tl,
      ~(In hd tl) -> list_norepet tl -> list_norepet (hd :: tl).(** [list_norepet l] holds iff the list [l] contains no repetitions,
  i.e. no element occurs twice. *)

Inductive list_norepet (A: Type) : list A -> Prop :=
  | list_norepet_nil:
      list_norepet nil
  | list_norepet_cons:
      forall hd tl,
      ~(In hd tl) -> list_norepet tl -> list_norepet (hd :: tl).

(* Specifications: *)
Lemma list_norepet_dec: forall (A: Type) (eqA_dec: forall (x y: A), {x=y} + {x<>y}) (l: list A), {list_norepet l} + {~list_norepet l}.
Lemma list_map_norepet: forall (A B: Type) (f: A -> B) (l: list A), list_norepet l -> (forall x y, In x l -> In y l -> x <> y -> f x <> f y) -> list_norepet (List.map f l).
Lemma list_norepet_dec: forall (A: Type) (eqA_dec: forall (x y: A), {x=y} + {x<>y}) (l: list A), {list_norepet l} + {~list_norepet l}.
Lemma list_map_norepet: forall (A B: Type) (f: A -> B) (l: list A), list_norepet l -> (forall x y, In x l -> In y l -> x <> y -> f x <> f y) -> list_norepet (List.map f l).