Inductive InP (X: Type) (P: X -> Prop): list X -> Prop :=
  | InP_head x t: P x -> InP P (x :: t)
  | InP_tail x t: InP P t -> InP P (x :: t).Inductive InP (X: Type) (P: X -> Prop): list X -> Prop :=
  | InP_head x t: P x -> InP P (x :: t)
  | InP_tail x t: InP P t -> InP P (x :: t).Inductive InP (X: Type) (P: X -> Prop): list X -> Prop :=
  | InP_head x t: P x -> InP P (x :: t)
  | InP_tail x t: InP P t -> InP P (x :: t).Inductive NoDupL (A: Type): list (list A) -> Prop :=
  | NoDupL_nil: NoDupL nil
  | NoDupL_cons (l: list A) (ll: list (list A)): NoDup l ->
      (forall x, In x l -> ~ InP (In x) ll) -> NoDupL ll -> NoDupL (l :: ll).Inductive NoDupL (A: Type): list (list A) -> Prop :=
  | NoDupL_nil: NoDupL nil
  | NoDupL_cons (l: list A) (ll: list (list A)): NoDup l ->
      (forall x, In x l -> ~ InP (In x) ll) -> NoDupL ll -> NoDupL (l :: ll).Inductive NoDupL (A: Type): list (list A) -> Prop :=
  | NoDupL_nil: NoDupL nil
  | NoDupL_cons (l: list A) (ll: list (list A)): NoDup l ->
      (forall x, In x l -> ~ InP (In x) ll) -> NoDupL ll -> NoDupL (l :: ll).

(* Specifications: *)
Lemma InP_In (X: Type) (l: list X) (ll: list (list X)): In l ll -> forall x, In x l -> InP (In x) ll.
Lemma InP_In_inv X (x: X) (ll: list (list X)): InP (In x) ll -> exists l, In x l /\ In l ll.
Lemma NoDup_concat A (l: list (list A)): NoDupL l -> NoDup (concat l).
Lemma In_filter_inv A (f: A -> bool) (x: A) (l: list A): In x (filter f l) -> In x l /\ f x = true.