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).

Lemma NoDup_concat A (l: list (list A)): NoDupL l -> NoDup (concat l).