l3lab/ntp-mathlib huggingface dataset:
theorem mem_sections {L : List (List α)} {f} : f ∈ sections L ↔ Forall₂ (· ∈ ·) f L := by
  refine' ⟨fun h => _, fun h => _⟩
  · induction L generalizing f
    · cases mem_singleton.1 h
      exact Forall₂.nil
    simp only [sections, bind_eq_bind, mem_bind, mem_map] at h
    rcases h with ⟨_, _, _, _, rfl⟩
    simp only [*, forall₂_cons, true_and_iff]
  · induction' h with a l f L al fL fs
    · simp only [sections, mem_singleton]
    

Proof state:
case refine'_2.cons
α : Type u_1
β : Type u_2
L✝ : List (List α)
f✝ : List α
a : α
l f : List α
L : List (List α)
al : a ∈ l
fL : Forall₂ (fun x x_1 => x ∈ x_1) f L
fs : f ∈ sections L
⊢ a :: f ∈ sections (l :: L)

Next tactic:
simp only [sections, bind_eq_bind, mem_bind, mem_map]
theorem mem_sections {L : List (List α)} {f} : f ∈ sections L ↔ Forall₂ (· ∈ ·) f L := by
  refine' ⟨fun h => _, fun h => _⟩
  · induction L generalizing f
    · cases mem_singleton.1 h
      exact Forall₂.nil
    simp only [sections, bind_eq_bind, mem_bind, mem_map] at h
    rcases h with ⟨_, _, _, _, rfl⟩
    simp only [*, forall₂_cons, true_and_iff]
  · induction' h with a l f L al fL fs
    · simp only [sections, mem_singleton]
    simp only [sections, bind_eq_bind, mem_bind, mem_map]
    

Proof state:
case refine'_2.cons
α : Type u_1
β : Type u_2
L✝ : List (List α)
f✝ : List α
a : α
l f : List α
L : List (List α)
al : a ∈ l
fL : Forall₂ (fun x x_1 => x ∈ x_1) f L
fs : f ∈ sections L
⊢ ∃ a_1, a_1 ∈ sections L ∧ ∃ a_2, a_2 ∈ l ∧ a_2 :: a_1 = a :: f

Next tactic:
exact ⟨f, fs, a, al, rfl⟩
theorem _root_.Decidable.List.eq_or_ne_mem_of_mem [DecidableEq α]
    {a b : α} {l : List α} (h : a ∈ b :: l) : a = b ∨ a ≠ b ∧ a ∈ l := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
h : a ∈ b :: l
⊢ a = b ∨ a ≠ b ∧ a ∈ l

Next tactic:
by_cases hab : a = b
theorem _root_.Decidable.List.eq_or_ne_mem_of_mem [DecidableEq α]
    {a b : α} {l : List α} (h : a ∈ b :: l) : a = b ∨ a ≠ b ∧ a ∈ l := by
  by_cases hab : a = b
  · 

Proof state:
case pos
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
h : a ∈ b :: l
hab : a = b
⊢ a = b ∨ a ≠ b ∧ a ∈ l

Next tactic:
exact Or.inl hab
theorem _root_.Decidable.List.eq_or_ne_mem_of_mem [DecidableEq α]
    {a b : α} {l : List α} (h : a ∈ b :: l) : a = b ∨ a ≠ b ∧ a ∈ l := by
  by_cases hab : a = b
  · exact Or.inl hab
  · 

Proof state:
case neg
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
a b : α
l : List α
h : a ∈ b :: l
hab : ¬a = b
⊢ a = b ∨ a ≠ b ∧ a ∈ l

Next tactic:
exact ((List.mem_cons.1 h).elim Or.inl (fun h => Or.inr ⟨hab, h⟩))
lemma mem_pair {a b c : α} : a ∈ [b, c] ↔ a = b ∨ a = c := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a b c : α
⊢ a ∈ [b, c] ↔ a = b ∨ a = c

Next tactic:
rw [mem_cons, mem_singleton]
theorem mem_split {a : α} {l : List α} (h : a ∈ l) : ∃ s t : List α, l = s ++ a :: t := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
l : List α
h : a ∈ l
⊢ ∃ s t, l = s ++ a :: t

Next tactic:
induction' l with b l ih
theorem mem_split {a : α} {l : List α} (h : a ∈ l) : ∃ s t : List α, l = s ++ a :: t := by
  induction' l with b l ih; 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
h : a ∈ []
⊢ ∃ s t, [] = s ++ a :: t
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a b : α
l : List α
ih : a ∈ l → ∃ s t, l = s ++ a :: t
h : a ∈ b :: l
⊢ ∃ s t, b :: l = s ++ a :: t

Next tactic:
{cases h}
theorem mem_split {a : α} {l : List α} (h : a ∈ l) : ∃ s t : List α, l = s ++ a :: t := by
  induction' l with b l ih; {

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
h : a ∈ []
⊢ ∃ s t, [] = s ++ a :: t

Next tactic:
cases h
theorem mem_split {a : α} {l : List α} (h : a ∈ l) : ∃ s t : List α, l = s ++ a :: t := by
  induction' l with b l ih; {cases h}; 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a b : α
l : List α
ih : a ∈ l → ∃ s t, l = s ++ a :: t
h : a ∈ b :: l
⊢ ∃ s t, b :: l = s ++ a :: t

Next tactic:
rcases h with (_ | ⟨_, h⟩)
theorem mem_split {a : α} {l : List α} (h : a ∈ l) : ∃ s t : List α, l = s ++ a :: t := by
  induction' l with b l ih; {cases h}; rcases h with (_ | ⟨_, h⟩)
  · 

Proof state:
case cons.head
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
l : List α
ih : a ∈ l → ∃ s t, l = s ++ a :: t
⊢ ∃ s t, a :: l = s ++ a :: t

Next tactic:
exact ⟨[], l, rfl⟩
theorem mem_split {a : α} {l : List α} (h : a ∈ l) : ∃ s t : List α, l = s ++ a :: t := by
  induction' l with b l ih; {cases h}; rcases h with (_ | ⟨_, h⟩)
  · exact ⟨[], l, rfl⟩
  · 

Proof state:
case cons.tail
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a b : α
l : List α
ih : a ∈ l → ∃ s t, l = s ++ a :: t
h : Mem a l
⊢ ∃ s t, b :: l = s ++ a :: t

Next tactic:
rcases ih h with ⟨s, t, rfl⟩
theorem mem_split {a : α} {l : List α} (h : a ∈ l) : ∃ s t : List α, l = s ++ a :: t := by
  induction' l with b l ih; {cases h}; rcases h with (_ | ⟨_, h⟩)
  · exact ⟨[], l, rfl⟩
  · rcases ih h with ⟨s, t, rfl⟩
    

Proof state:
case cons.tail.intro.intro
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a b : α
s t : List α
ih : a ∈ s ++ a :: t → ∃ s_1 t_1, s ++ a :: t = s_1 ++ a :: t_1
h : Mem a (s ++ a :: t)
⊢ ∃ s_1 t_1, b :: (s ++ a :: t) = s_1 ++ a :: t_1

Next tactic:
exact ⟨b :: s, t, rfl⟩
@[simp]
theorem _root_.Function.Involutive.exists_mem_and_apply_eq_iff {f : α → α}
    (hf : Function.Involutive f) (x : α) (l : List α) : (∃ y : α, y ∈ l ∧ f y = x) ↔ f x ∈ l :=
  ⟨by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → α
hf : Involutive f
x : α
l : List α
⊢ (∃ y, y ∈ l ∧ f y = x) → f x ∈ l

Next tactic:
rintro ⟨y, h, rfl⟩
@[simp]
theorem _root_.Function.Involutive.exists_mem_and_apply_eq_iff {f : α → α}
    (hf : Function.Involutive f) (x : α) (l : List α) : (∃ y : α, y ∈ l ∧ f y = x) ↔ f x ∈ l :=
  ⟨by rintro ⟨y, h, rfl⟩; 

Proof state:
case intro.intro
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → α
hf : Involutive f
l : List α
y : α
h : y ∈ l
⊢ f (f y) ∈ l

Next tactic:
rwa [hf y]
theorem mem_map_of_involutive {f : α → α} (hf : Involutive f) {a : α} {l : List α} :
    a ∈ map f l ↔ f a ∈ l := by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → α
hf : Involutive f
a : α
l : List α
⊢ a ∈ map f l ↔ f a ∈ l

Next tactic:
rw [mem_map, hf.exists_mem_and_apply_eq_iff]
theorem map_bind (g : β → List γ) (f : α → β) :
    ∀ l : List α, (List.map f l).bind g = l.bind fun a => g (f a)
  | [] => rfl
  | a :: l => by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
g : β → List γ
f : α → β
a : α
l : List α
⊢ List.bind (map f (a :: l)) g = List.bind (a :: l) fun a => g (f a)

Next tactic:
simp only [cons_bind, map_cons, map_bind _ _ l]
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
⊢ Injective length ↔ Subsingleton α

Next tactic:
constructor
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · 

Proof state:
case mp
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
⊢ Injective length → Subsingleton α

Next tactic:
intro h
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; 

Proof state:
case mp
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
h : Injective length
⊢ Subsingleton α

Next tactic:
refine ⟨fun x y => ?_⟩
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (

Proof state:
case mp
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
h : Injective length
x y : α
⊢ x = y

Next tactic:
suffices [x] = [y] by simpa using this
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
h : Injective length
x y : α
this : [x] = [y]
⊢ x = y

Next tactic:
simpa using this
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by simpa using this); 

Proof state:
case mp
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
h : Injective length
x y : α
⊢ [x] = [y]

Next tactic:
apply h
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by simpa using this); apply h; 

Proof state:
case mp.a
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
h : Injective length
x y : α
⊢ length [x] = length [y]

Next tactic:
rfl
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by simpa using this); apply h; rfl
  · 

Proof state:
case mpr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
⊢ Subsingleton α → Injective length

Next tactic:
intros hα l1 l2 hl
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by simpa using this); apply h; rfl
  · intros hα l1 l2 hl
    

Proof state:
case mpr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hα : Subsingleton α
l1 l2 : List α
hl : length l1 = length l2
⊢ l1 = l2

Next tactic:
induction l1 generalizing l2
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by simpa using this); apply h; rfl
  · intros hα l1 l2 hl
    induction l1 generalizing l2 <;> 

Proof state:
case mpr.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hα : Subsingleton α
l2 : List α
hl : length [] = length l2
⊢ [] = l2

Next tactic:
cases l2
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by simpa using this); apply h; rfl
  · intros hα l1 l2 hl
    induction l1 generalizing l2 <;> 

Proof state:
case mpr.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hα : Subsingleton α
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ ⦃l2 : List α⦄, length tail✝ = length l2 → tail✝ = l2
l2 : List α
hl : length (head✝ :: tail✝) = length l2
⊢ head✝ :: tail✝ = l2

Next tactic:
cases l2
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by simpa using this); apply h; rfl
  · intros hα l1 l2 hl
    induction l1 generalizing l2 <;> cases l2
    · 

Proof state:
case mpr.nil.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hα : Subsingleton α
hl : length [] = length []
⊢ [] = []

Next tactic:
rfl
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by simpa using this); apply h; rfl
  · intros hα l1 l2 hl
    induction l1 generalizing l2 <;> cases l2
    · rfl
    · 

Proof state:
case mpr.nil.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hα : Subsingleton α
head✝ : α
tail✝ : List α
hl : length [] = length (head✝ :: tail✝)
⊢ [] = head✝ :: tail✝

Next tactic:
cases hl
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by simpa using this); apply h; rfl
  · intros hα l1 l2 hl
    induction l1 generalizing l2 <;> cases l2
    · rfl
    · cases hl
    · 

Proof state:
case mpr.cons.nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hα : Subsingleton α
head✝ : α
tail✝ : List α
tail_ih✝ : ∀ ⦃l2 : List α⦄, length tail✝ = length l2 → tail✝ = l2
hl : length (head✝ :: tail✝) = length []
⊢ head✝ :: tail✝ = []

Next tactic:
cases hl
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by simpa using this); apply h; rfl
  · intros hα l1 l2 hl
    induction l1 generalizing l2 <;> cases l2
    · rfl
    · cases hl
    · cases hl
    · 

Proof state:
case mpr.cons.cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hα : Subsingleton α
head✝¹ : α
tail✝¹ : List α
tail_ih✝ : ∀ ⦃l2 : List α⦄, length tail✝¹ = length l2 → tail✝¹ = l2
head✝ : α
tail✝ : List α
hl : length (head✝¹ :: tail✝¹) = length (head✝ :: tail✝)
⊢ head✝¹ :: tail✝¹ = head✝ :: tail✝

Next tactic:
next ih _ _ =>
      congr
      · exact Subsingleton.elim _ _
      · apply ih; simpa using hl
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by simpa using this); apply h; rfl
  · intros hα l1 l2 hl
    induction l1 generalizing l2 <;> cases l2
    · rfl
    · cases hl
    · cases hl
    · next ih _ _ =>
      

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hα : Subsingleton α
head✝¹ : α
tail✝¹ : List α
ih : ∀ ⦃l2 : List α⦄, length tail✝¹ = length l2 → tail✝¹ = l2
head✝ : α
tail✝ : List α
hl : length (head✝¹ :: tail✝¹) = length (head✝ :: tail✝)
⊢ head✝¹ :: tail✝¹ = head✝ :: tail✝

Next tactic:
congr
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by simpa using this); apply h; rfl
  · intros hα l1 l2 hl
    induction l1 generalizing l2 <;> cases l2
    · rfl
    · cases hl
    · cases hl
    · next ih _ _ =>
      congr
      · 

Proof state:
case e_head
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hα : Subsingleton α
head✝¹ : α
tail✝¹ : List α
ih : ∀ ⦃l2 : List α⦄, length tail✝¹ = length l2 → tail✝¹ = l2
head✝ : α
tail✝ : List α
hl : length (head✝¹ :: tail✝¹) = length (head✝ :: tail✝)
⊢ head✝¹ = head✝

Next tactic:
exact Subsingleton.elim _ _
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by simpa using this); apply h; rfl
  · intros hα l1 l2 hl
    induction l1 generalizing l2 <;> cases l2
    · rfl
    · cases hl
    · cases hl
    · next ih _ _ =>
      congr
      · exact Subsingleton.elim _ _
      · 

Proof state:
case e_tail
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hα : Subsingleton α
head✝¹ : α
tail✝¹ : List α
ih : ∀ ⦃l2 : List α⦄, length tail✝¹ = length l2 → tail✝¹ = l2
head✝ : α
tail✝ : List α
hl : length (head✝¹ :: tail✝¹) = length (head✝ :: tail✝)
⊢ tail✝¹ = tail✝

Next tactic:
apply ih
@[simp] lemma length_injective_iff : Injective (List.length : List α → ℕ) ↔ Subsingleton α := by
  constructor
  · intro h; refine ⟨fun x y => ?_⟩; (suffices [x] = [y] by simpa using this); apply h; rfl
  · intros hα l1 l2 hl
    induction l1 generalizing l2 <;> cases l2
    · rfl
    · cases hl
    · cases hl
    · next ih _ _ =>
      congr
      · exact Subsingleton.elim _ _
      · apply ih; 

Proof state:
case e_tail.hl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
hα : Subsingleton α
head✝¹ : α
tail✝¹ : List α
ih : ∀ ⦃l2 : List α⦄, length tail✝¹ = length l2 → tail✝¹ = l2
head✝ : α
tail✝ : List α
hl : length (head✝¹ :: tail✝¹) = length (head✝ :: tail✝)
⊢ length tail✝¹ = length tail✝

Next tactic:
simpa using hl
theorem doubleton_eq [DecidableEq α] {x y : α} (h : x ≠ y) : ({x, y} : List α) = [x, y] := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
x y : α
h : x ≠ y
⊢ {x, y} = [x, y]

Next tactic:
rw [insert_neg, singleton_eq]
theorem doubleton_eq [DecidableEq α] {x y : α} (h : x ≠ y) : ({x, y} : List α) = [x, y] := by
  rw [insert_neg, singleton_eq]
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : DecidableEq α
x y : α
h : x ≠ y
⊢ ¬x ∈ {y}

Next tactic:
rwa [singleton_eq, mem_singleton]
theorem or_exists_of_exists_mem_cons {p : α → Prop} {a : α} {l : List α} : (∃ x ∈ a :: l, p x) →
    p a ∨ ∃ x ∈ l, p x :=
  fun ⟨x, xal, px⟩ =>
    Or.elim (eq_or_mem_of_mem_cons xal) (fun h : x = a => by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Prop
a : α
l : List α
x✝ : ∃ x, x ∈ a :: l ∧ p x
x : α
xal : x ∈ a :: l
px : p x
h : x = a
⊢ p a ∨ ∃ x, x ∈ l ∧ p x

Next tactic:
rw [← h]
theorem or_exists_of_exists_mem_cons {p : α → Prop} {a : α} {l : List α} : (∃ x ∈ a :: l, p x) →
    p a ∨ ∃ x ∈ l, p x :=
  fun ⟨x, xal, px⟩ =>
    Or.elim (eq_or_mem_of_mem_cons xal) (fun h : x = a => by rw [← h]; 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Prop
a : α
l : List α
x✝ : ∃ x, x ∈ a :: l ∧ p x
x : α
xal : x ∈ a :: l
px : p x
h : x = a
⊢ p x ∨ ∃ x, x ∈ l ∧ p x

Next tactic:
left
theorem or_exists_of_exists_mem_cons {p : α → Prop} {a : α} {l : List α} : (∃ x ∈ a :: l, p x) →
    p a ∨ ∃ x ∈ l, p x :=
  fun ⟨x, xal, px⟩ =>
    Or.elim (eq_or_mem_of_mem_cons xal) (fun h : x = a => by rw [← h]; left; 

Proof state:
case h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
p : α → Prop
a : α
l : List α
x✝ : ∃ x, x ∈ a :: l ∧ p x
x : α
xal : x ∈ a :: l
px : p x
h : x = a
⊢ p x

Next tactic:
exact px
theorem map_subset_iff {l₁ l₂ : List α} (f : α → β) (h : Injective f) :
    map f l₁ ⊆ map f l₂ ↔ l₁ ⊆ l₂ := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁✝ l₂✝ l₁ l₂ : List α
f : α → β
h : Injective f
⊢ map f l₁ ⊆ map f l₂ ↔ l₁ ⊆ l₂

Next tactic:
refine' ⟨_, map_subset f⟩
theorem map_subset_iff {l₁ l₂ : List α} (f : α → β) (h : Injective f) :
    map f l₁ ⊆ map f l₂ ↔ l₁ ⊆ l₂ := by
  refine' ⟨_, map_subset f⟩; 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁✝ l₂✝ l₁ l₂ : List α
f : α → β
h : Injective f
⊢ map f l₁ ⊆ map f l₂ → l₁ ⊆ l₂

Next tactic:
intro h2 x hx
theorem map_subset_iff {l₁ l₂ : List α} (f : α → β) (h : Injective f) :
    map f l₁ ⊆ map f l₂ ↔ l₁ ⊆ l₂ := by
  refine' ⟨_, map_subset f⟩; intro h2 x hx
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁✝ l₂✝ l₁ l₂ : List α
f : α → β
h : Injective f
h2 : map f l₁ ⊆ map f l₂
x : α
hx : x ∈ l₁
⊢ x ∈ l₂

Next tactic:
rcases mem_map.1 (h2 (mem_map_of_mem f hx)) with ⟨x', hx', hxx'⟩
theorem map_subset_iff {l₁ l₂ : List α} (f : α → β) (h : Injective f) :
    map f l₁ ⊆ map f l₂ ↔ l₁ ⊆ l₂ := by
  refine' ⟨_, map_subset f⟩; intro h2 x hx
  rcases mem_map.1 (h2 (mem_map_of_mem f hx)) with ⟨x', hx', hxx'⟩
  

Proof state:
case intro.intro
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁✝ l₂✝ l₁ l₂ : List α
f : α → β
h : Injective f
h2 : map f l₁ ⊆ map f l₂
x : α
hx : x ∈ l₁
x' : α
hx' : x' ∈ l₂
hxx' : f x' = f x
⊢ x ∈ l₂

Next tactic:
cases h hxx'
theorem map_subset_iff {l₁ l₂ : List α} (f : α → β) (h : Injective f) :
    map f l₁ ⊆ map f l₂ ↔ l₁ ⊆ l₂ := by
  refine' ⟨_, map_subset f⟩; intro h2 x hx
  rcases mem_map.1 (h2 (mem_map_of_mem f hx)) with ⟨x', hx', hxx'⟩
  cases h hxx'; 

Proof state:
case intro.intro.refl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁✝ l₂✝ l₁ l₂ : List α
f : α → β
h : Injective f
h2 : map f l₁ ⊆ map f l₂
x : α
hx : x ∈ l₁
hx' : x ∈ l₂
hxx' : f x = f x
⊢ x ∈ l₂

Next tactic:
exact hx'
theorem append_eq_cons_iff {a b c : List α} {x : α} :
    a ++ b = x :: c ↔ a = [] ∧ b = x :: c ∨ ∃ a', a = x :: a' ∧ c = a' ++ b := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ a b c : List α
x : α
⊢ a ++ b = x :: c ↔ a = [] ∧ b = x :: c ∨ ∃ a', a = x :: a' ∧ c = a' ++ b

Next tactic:
cases a
theorem append_eq_cons_iff {a b c : List α} {x : α} :
    a ++ b = x :: c ↔ a = [] ∧ b = x :: c ∨ ∃ a', a = x :: a' ∧ c = a' ++ b := by
  cases a <;>
    

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ b c : List α
x : α
⊢ [] ++ b = x :: c ↔ [] = [] ∧ b = x :: c ∨ ∃ a', [] = x :: a' ∧ c = a' ++ b

Next tactic:
simp only [and_assoc, @eq_comm _ c, nil_append, cons_append, cons.injEq, true_and_iff,
      false_and_iff, exists_false, false_or_iff, or_false_iff, exists_and_left, exists_eq_left']
theorem append_eq_cons_iff {a b c : List α} {x : α} :
    a ++ b = x :: c ↔ a = [] ∧ b = x :: c ∨ ∃ a', a = x :: a' ∧ c = a' ++ b := by
  cases a <;>
    

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ b c : List α
x head✝ : α
tail✝ : List α
⊢ head✝ :: tail✝ ++ b = x :: c ↔ head✝ :: tail✝ = [] ∧ b = x :: c ∨ ∃ a', head✝ :: tail✝ = x :: a' ∧ c = a' ++ b

Next tactic:
simp only [and_assoc, @eq_comm _ c, nil_append, cons_append, cons.injEq, true_and_iff,
      false_and_iff, exists_false, false_or_iff, or_false_iff, exists_and_left, exists_eq_left']
theorem cons_eq_append_iff {a b c : List α} {x : α} :
    (x :: c : List α) = a ++ b ↔ a = [] ∧ b = x :: c ∨ ∃ a', a = x :: a' ∧ c = a' ++ b := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ a b c : List α
x : α
⊢ x :: c = a ++ b ↔ a = [] ∧ b = x :: c ∨ ∃ a', a = x :: a' ∧ c = a' ++ b

Next tactic:
rw [eq_comm, append_eq_cons_iff]
theorem eq_replicate_length {a : α} : ∀ {l : List α}, l = replicate l.length a ↔ ∀ b ∈ l, b = a
  | [] => by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
⊢ [] = replicate (length []) a ↔ ∀ (b : α), b ∈ [] → b = a

Next tactic:
simp
theorem eq_replicate_length {a : α} : ∀ {l : List α}, l = replicate l.length a ↔ ∀ b ∈ l, b = a
  | [] => by simp
  | (b :: l) => by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a b : α
l : List α
⊢ b :: l = replicate (length (b :: l)) a ↔ ∀ (b_1 : α), b_1 ∈ b :: l → b_1 = a

Next tactic:
simp [eq_replicate_length]
theorem replicate_add (m n) (a : α) : replicate (m + n) a = replicate m a ++ replicate n a := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
m n : ℕ
a : α
⊢ replicate (m + n) a = replicate m a ++ replicate n a

Next tactic:
induction m
theorem replicate_add (m n) (a : α) : replicate (m + n) a = replicate m a ++ replicate n a := by
  induction m <;> 

Proof state:
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
n : ℕ
a : α
⊢ replicate (zero + n) a = replicate zero a ++ replicate n a

Next tactic:
simp [*, zero_add, succ_add, replicate]
theorem replicate_add (m n) (a : α) : replicate (m + n) a = replicate m a ++ replicate n a := by
  induction m <;> 

Proof state:
case succ
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
n : ℕ
a : α
n✝ : ℕ
n_ih✝ : replicate (n✝ + n) a = replicate n✝ a ++ replicate n a
⊢ replicate (succ n✝ + n) a = replicate (succ n✝) a ++ replicate n a

Next tactic:
simp [*, zero_add, succ_add, replicate]
theorem subset_singleton_iff {a : α} {L : List α} : L ⊆ [a] ↔ ∃ n, L = replicate n a := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
a : α
L : List α
⊢ L ⊆ [a] ↔ ∃ n, L = replicate n a

Next tactic:
simp only [eq_replicate, subset_def, mem_singleton, exists_eq_left']
@[simp] theorem map_replicate (f : α → β) (n) (a : α) :
    map f (replicate n a) = replicate n (f a) := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → β
n : ℕ
a : α
⊢ map f (replicate n a) = replicate n (f a)

Next tactic:
induction n <;> [rfl; simp only [*, replicate, map]]
@[simp] theorem map_replicate (f : α → β) (n) (a : α) :
    map f (replicate n a) = replicate n (f a) := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → β
n : ℕ
a : α
⊢ map f (replicate n a) = replicate n (f a)

Next tactic:
induction n
@[simp] theorem map_replicate (f : α → β) (n) (a : α) :
    map f (replicate n a) = replicate n (f a) := by
  induction n <;> [

Proof state:
case zero
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
f : α → β
a : α
⊢ map f (replicate zero a) = replicate zero (f a)

Next tactic:
rfl