Module docstring
{"# List duplicates
Main definitions
List.Duplicate x l : Propis an inductive property that holds whenxis a duplicate inl
Implementation details
In this file, x ∈+ l notation is shorthand for List.Duplicate x l.
"}
{"# List duplicates
List.Duplicate x l : Prop is an inductive property that holds when x is a duplicate in lIn this file, x ∈+ l notation is shorthand for List.Duplicate x l.
"}
List.Duplicate
      inductive
     (x : α) : List α → Prop
        
      List.Mem.duplicate_cons_self
      theorem
     (h : x ∈ l) : x ∈+ x :: l
        theorem Mem.duplicate_cons_self (h : x ∈ l) : x ∈+ x :: l :=
  Duplicate.cons_mem h
        List.Duplicate.duplicate_cons
      theorem
     (h : x ∈+ l) (y : α) : x ∈+ y :: l
        theorem Duplicate.duplicate_cons (h : x ∈+ l) (y : α) : x ∈+ y :: l :=
  Duplicate.cons_duplicate h
        List.Duplicate.mem
      theorem
     (h : x ∈+ l) : x ∈ l
        theorem Duplicate.mem (h : x ∈+ l) : x ∈ l := by
  induction h with
  | cons_mem => exact mem_cons_self
  | cons_duplicate _ hm => exact mem_cons_of_mem _ hm
        List.Duplicate.mem_cons_self
      theorem
     (h : x ∈+ x :: l) : x ∈ l
        theorem Duplicate.mem_cons_self (h : x ∈+ x :: l) : x ∈ l := by
  obtain h | h := h
  · exact h
  · exact h.mem
        List.duplicate_cons_self_iff
      theorem
     : x ∈+ x :: l ↔ x ∈ l
        @[simp]
theorem duplicate_cons_self_iff : x ∈+ x :: lx ∈+ x :: l ↔ x ∈ l :=
  ⟨Duplicate.mem_cons_self, Mem.duplicate_cons_self⟩
        List.Duplicate.ne_nil
      theorem
     (h : x ∈+ l) : l ≠ []
        theorem Duplicate.ne_nil (h : x ∈+ l) : l ≠ [] := fun H => (mem_nil_iff x).mp (H ▸ h.mem)
        List.not_duplicate_nil
      theorem
     (x : α) : ¬x ∈+ []
        @[simp]
theorem not_duplicate_nil (x : α) : ¬x ∈+ [] := fun H => H.ne_nil rfl
        List.Duplicate.ne_singleton
      theorem
     (h : x ∈+ l) (y : α) : l ≠ [y]
        theorem Duplicate.ne_singleton (h : x ∈+ l) (y : α) : l ≠ [y] := by
  induction h with
  | cons_mem h => simp [ne_nil_of_mem h]
  | cons_duplicate h => simp [ne_nil_of_mem h.mem]
        List.not_duplicate_singleton
      theorem
     (x y : α) : ¬x ∈+ [y]
        @[simp]
theorem not_duplicate_singleton (x y : α) : ¬x ∈+ [y] := fun H => H.ne_singleton _ rfl
        List.Duplicate.elim_nil
      theorem
     (h : x ∈+ []) : False
        theorem Duplicate.elim_nil (h : x ∈+ []) : False :=
  not_duplicate_nil x h
        List.Duplicate.elim_singleton
      theorem
     {y : α} (h : x ∈+ [y]) : False
        theorem Duplicate.elim_singleton {y : α} (h : x ∈+ [y]) : False :=
  not_duplicate_singleton x y h
        List.duplicate_cons_iff
      theorem
     {y : α} : x ∈+ y :: l ↔ y = x ∧ x ∈ l ∨ x ∈+ l
        theorem duplicate_cons_iff {y : α} : x ∈+ y :: lx ∈+ y :: l ↔ y = x ∧ x ∈ l ∨ x ∈+ l := by
  refine ⟨fun h => ?_, fun h => ?_⟩
  · obtain hm | hm := h
    · exact Or.inl ⟨rfl, hm⟩
    · exact Or.inr hm
  · rcases h with (⟨rfl | h⟩ | h)
    · simpa
    · exact h.cons_duplicate
        List.Duplicate.of_duplicate_cons
      theorem
     {y : α} (h : x ∈+ y :: l) (hx : x ≠ y) : x ∈+ l
        theorem Duplicate.of_duplicate_cons {y : α} (h : x ∈+ y :: l) (hx : x ≠ y) : x ∈+ l := by
  simpa [duplicate_cons_iff, hx.symm] using h
        List.duplicate_cons_iff_of_ne
      theorem
     {y : α} (hne : x ≠ y) : x ∈+ y :: l ↔ x ∈+ l
        theorem duplicate_cons_iff_of_ne {y : α} (hne : x ≠ y) : x ∈+ y :: lx ∈+ y :: l ↔ x ∈+ l := by
  simp [duplicate_cons_iff, hne.symm]
        List.Duplicate.mono_sublist
      theorem
     {l' : List α} (hx : x ∈+ l) (h : l <+ l') : x ∈+ l'
        theorem Duplicate.mono_sublist {l' : List α} (hx : x ∈+ l) (h : l <+ l') : x ∈+ l' := by
  induction h with
  | slnil => exact hx
  | cons y _ IH => exact (IH hx).duplicate_cons _
  | cons₂ y h IH =>
    rw [duplicate_cons_iff] at hx ⊢
    rcases hx with (⟨rfl, hx⟩ | hx)
    · simp [h.subset hx]
    · simp [IH hx]
        List.duplicate_iff_sublist
      theorem
     : x ∈+ l ↔ [x, x] <+ l
        /-- The contrapositive of `List.nodup_iff_sublist`. -/
theorem duplicate_iff_sublist : x ∈+ lx ∈+ l ↔ [x, x] <+ l := by
  induction' l with y l IH
  · simp
  · by_cases hx : x = y
    · simp [hx, cons_sublist_cons, singleton_sublist]
    · rw [duplicate_cons_iff_of_ne hx, IH]
      refine ⟨sublist_cons_of_sublist y, fun h => ?_⟩
      cases h
      · assumption
      · contradiction
        List.nodup_iff_forall_not_duplicate
      theorem
     : Nodup l ↔ ∀ x : α, ¬x ∈+ l
        theorem nodup_iff_forall_not_duplicate : NodupNodup l ↔ ∀ x : α, ¬x ∈+ l := by
  simp_rw [nodup_iff_sublist, duplicate_iff_sublist]
        List.exists_duplicate_iff_not_nodup
      theorem
     : (∃ x : α, x ∈+ l) ↔ ¬Nodup l
        theorem exists_duplicate_iff_not_nodup : (∃ x : α, x ∈+ l) ↔ ¬Nodup l := by
  simp [nodup_iff_forall_not_duplicate]
        List.Duplicate.not_nodup
      theorem
     (h : x ∈+ l) : ¬Nodup l
        theorem Duplicate.not_nodup (h : x ∈+ l) : ¬Nodup l := fun H =>
  nodup_iff_forall_not_duplicate.mp H _ h
        List.duplicate_iff_two_le_count
      theorem
     [DecidableEq α] : x ∈+ l ↔ 2 ≤ count x l
        theorem duplicate_iff_two_le_count [DecidableEq α] : x ∈+ lx ∈+ l ↔ 2 ≤ count x l := by
  simp [replicate_succ, duplicate_iff_sublist, le_count_iff_replicate_sublist]
        List.decidableDuplicate
      instance
     [DecidableEq α] (x : α) : ∀ l : List α, Decidable (x ∈+ l)
        instance decidableDuplicate [DecidableEq α] (x : α) : ∀ l : List α, Decidable (x ∈+ l)
  | [] => isFalse (not_duplicate_nil x)
  | y :: l =>
    match decidableDuplicate x l with
    | isTrue h => isTrue (h.duplicate_cons y)
    | isFalse h =>
      if hx : y = x ∧ x ∈ l then isTrue (hx.left.symm ▸ List.Mem.duplicate_cons_self hx.right)
      else isFalse (by simpa [duplicate_cons_iff, h] using hx)