(** [list_disjoint l1 l2] holds iff [l1] and [l2] have no elements in common. *)
Definition list_disjoint (A: Type) (l1 l2: list A) : Prop :=
forall (x y: A), In x l1 -> In y l2 -> x <> y.

(* Specifications: *)
Lemma list_disjoint_cons_l:
forall (A: Type) (a: A) (l1 l2: list A),
list_disjoint l1 l2 -> ~In a l2 -> list_disjoint (a :: l1) l2.
Lemma list_disjoint_cons_r:
forall (A: Type) (a: A) (l1 l2: list A),
list_disjoint l1 l2 -> ~In a l1 -> list_disjoint l1 (a :: l2).
Lemma list_disjoint_cons_left:
forall (A: Type) (a: A) (l1 l2: list A),
list_disjoint (a :: l1) l2 -> list_disjoint l1 l2.
Lemma list_disjoint_cons_right:
forall (A: Type) (a: A) (l1 l2: list A),
list_disjoint l1 (a :: l2) -> list_disjoint l1 l2.
Lemma list_disjoint_notin:
forall (A: Type) (l1 l2: list A) (a: A),
list_disjoint l1 l2 -> In a l1 -> ~(In a l2).
Lemma list_disjoint_sym:
forall (A: Type) (l1 l2: list A),
list_disjoint l1 l2 -> list_disjoint l2 l1.
Lemma list_disjoint_dec:
forall (A: Type) (eqA_dec: forall (x y: A), {x=y} + {x<>y}) (l1 l2: list A),
{list_disjoint l1 l2} + {~list_disjoint l1 l2}.
Lemma list_disjoint_cons_l:
forall (A: Type) (a: A) (l1 l2: list A),
list_disjoint l1 l2 -> ~In a l2 -> list_disjoint (a :: l1) l2.
Lemma list_disjoint_cons_r:
forall (A: Type) (a: A) (l1 l2: list A),
list_disjoint l1 l2 -> ~In a l1 -> list_disjoint l1 (a :: l2).
Lemma list_disjoint_cons_left:
forall (A: Type) (a: A) (l1 l2: list A),
list_disjoint (a :: l1) l2 -> list_disjoint l1 l2.
Lemma list_disjoint_cons_right:
forall (A: Type) (a: A) (l1 l2: list A),
list_disjoint l1 (a :: l2) -> list_disjoint l1 l2.
Lemma list_disjoint_notin:
forall (A: Type) (l1 l2: list A) (a: A),
list_disjoint l1 l2 -> In a l1 -> ~(In a l2).
Lemma list_disjoint_sym:
forall (A: Type) (l1 l2: list A),
list_disjoint l1 l2 -> list_disjoint l2 l1.
Lemma list_disjoint_dec:
forall (A: Type) (eqA_dec: forall (x y: A), {x=y} + {x<>y}) (l1 l2: list A),
{list_disjoint l1 l2} + {~list_disjoint l1 l2}.