l3lab/ntp-mathlib huggingface dataset:
theorem getD_append_right (l l' : List α) (d : α) (n : ℕ) (h : l.length ≤ n) :
    (l ++ l').getD n d = l'.getD (n - l.length) d := by
  cases lt_or_le n (l ++ l').length with
  | inl h' =>
    rw [getD_eq_get (l ++ l') d h', get_append_right, getD_eq_get]
    · 

Proof state:
case inl.hn
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l✝ : List α
x : α
xs : List α
d✝ : α
n✝ : ℕ
l l' : List α
d : α
n : ℕ
h : length l ≤ n
h' : n < length (l ++ l')
⊢ n - length l < length l'

Next tactic:
rw [length_append] at h'
theorem getD_append_right (l l' : List α) (d : α) (n : ℕ) (h : l.length ≤ n) :
    (l ++ l').getD n d = l'.getD (n - l.length) d := by
  cases lt_or_le n (l ++ l').length with
  | inl h' =>
    rw [getD_eq_get (l ++ l') d h', get_append_right, getD_eq_get]
    · rw [length_append] at h'
      

Proof state:
case inl.hn
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l✝ : List α
x : α
xs : List α
d✝ : α
n✝ : ℕ
l l' : List α
d : α
n : ℕ
h : length l ≤ n
h' : n < length l + length l'
⊢ n - length l < length l'

Next tactic:
exact Nat.sub_lt_left_of_lt_add h h'
theorem getD_append_right (l l' : List α) (d : α) (n : ℕ) (h : l.length ≤ n) :
    (l ++ l').getD n d = l'.getD (n - l.length) d := by
  cases lt_or_le n (l ++ l').length with
  | inl h' =>
    rw [getD_eq_get (l ++ l') d h', get_append_right, getD_eq_get]
    · rw [length_append] at h'
      exact Nat.sub_lt_left_of_lt_add h h'
    · 

Proof state:
case inl.h
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l✝ : List α
x : α
xs : List α
d✝ : α
n✝ : ℕ
l l' : List α
d : α
n : ℕ
h : length l ≤ n
h' : n < length (l ++ l')
⊢ ¬n < length l

Next tactic:
exact not_lt_of_le h
theorem getD_append_right (l l' : List α) (d : α) (n : ℕ) (h : l.length ≤ n) :
    (l ++ l').getD n d = l'.getD (n - l.length) d := by
  cases lt_or_le n (l ++ l').length with
  | inl h' =>
    rw [getD_eq_get (l ++ l') d h', get_append_right, getD_eq_get]
    · rw [length_append] at h'
      exact Nat.sub_lt_left_of_lt_add h h'
    · exact not_lt_of_le h
  

Proof state:
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l✝ : List α
x : α
xs : List α
d✝ : α
n✝ : ℕ
l l' : List α
d : α
n : ℕ
h : length l ≤ n
h' : length (l ++ l') ≤ n
⊢ getD (l ++ l') n d = getD l' (n - length l) d

Next tactic:
| inr h' =>
    rw [getD_eq_default _ _ h', getD_eq_default]
    rwa [le_tsub_iff_left h, ← length_append]
theorem getD_append_right (l l' : List α) (d : α) (n : ℕ) (h : l.length ≤ n) :
    (l ++ l').getD n d = l'.getD (n - l.length) d := by
  cases lt_or_le n (l ++ l').length with
  | inl h' =>
    rw [getD_eq_get (l ++ l') d h', get_append_right, getD_eq_get]
    · rw [length_append] at h'
      exact Nat.sub_lt_left_of_lt_add h h'
    · exact not_lt_of_le h
  | inr h' =>
    

Proof state:
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l✝ : List α
x : α
xs : List α
d✝ : α
n✝ : ℕ
l l' : List α
d : α
n : ℕ
h : length l ≤ n
h' : length (l ++ l') ≤ n
⊢ getD (l ++ l') n d = getD l' (n - length l) d

Next tactic:
rw [getD_eq_default _ _ h', getD_eq_default]
theorem getD_append_right (l l' : List α) (d : α) (n : ℕ) (h : l.length ≤ n) :
    (l ++ l').getD n d = l'.getD (n - l.length) d := by
  cases lt_or_le n (l ++ l').length with
  | inl h' =>
    rw [getD_eq_get (l ++ l') d h', get_append_right, getD_eq_get]
    · rw [length_append] at h'
      exact Nat.sub_lt_left_of_lt_add h h'
    · exact not_lt_of_le h
  | inr h' =>
    rw [getD_eq_default _ _ h', getD_eq_default]
    

Proof state:
case inr.hn
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l✝ : List α
x : α
xs : List α
d✝ : α
n✝ : ℕ
l l' : List α
d : α
n : ℕ
h : length l ≤ n
h' : length (l ++ l') ≤ n
⊢ length l' ≤ n - length l

Next tactic:
rwa [le_tsub_iff_left h, ← length_append]
theorem getD_eq_getD_get? (n : ℕ) : l.getD n d = (l.get? n).getD d := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ n : ℕ
⊢ getD l n d = Option.getD (get? l n) d

Next tactic:
cases lt_or_le n l.length with
  | inl h => rw [getD_eq_get _ _ h, get?_eq_get h, Option.getD_some]
  | inr h => rw [getD_eq_default _ _ h, get?_eq_none.mpr h, Option.getD_none]
theorem getD_eq_getD_get? (n : ℕ) : l.getD n d = (l.get? n).getD d := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ n : ℕ
x✝ : n < length l ∨ length l ≤ n
⊢ getD l n d = Option.getD (get? l n) d

Next tactic:
cases lt_or_le n l.length with
  | inl h => rw [getD_eq_get _ _ h, get?_eq_get h, Option.getD_some]
  | inr h => rw [getD_eq_default _ _ h, get?_eq_none.mpr h, Option.getD_none]
theorem getD_eq_getD_get? (n : ℕ) : l.getD n d = (l.get? n).getD d := by
  cases lt_or_le n l.length with
  

Proof state:
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ n : ℕ
h : n < length l
⊢ getD l n d = Option.getD (get? l n) d

Next tactic:
| inl h => rw [getD_eq_get _ _ h, get?_eq_get h, Option.getD_some]
theorem getD_eq_getD_get? (n : ℕ) : l.getD n d = (l.get? n).getD d := by
  cases lt_or_le n l.length with
  | inl h => 

Proof state:
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ n : ℕ
h : n < length l
⊢ getD l n d = Option.getD (get? l n) d

Next tactic:
rw [getD_eq_get _ _ h, get?_eq_get h, Option.getD_some]
theorem getD_eq_getD_get? (n : ℕ) : l.getD n d = (l.get? n).getD d := by
  cases lt_or_le n l.length with
  | inl h => rw [getD_eq_get _ _ h, get?_eq_get h, Option.getD_some]
  

Proof state:
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ n : ℕ
h : length l ≤ n
⊢ getD l n d = Option.getD (get? l n) d

Next tactic:
| inr h => rw [getD_eq_default _ _ h, get?_eq_none.mpr h, Option.getD_none]
theorem getD_eq_getD_get? (n : ℕ) : l.getD n d = (l.get? n).getD d := by
  cases lt_or_le n l.length with
  | inl h => rw [getD_eq_get _ _ h, get?_eq_get h, Option.getD_some]
  | inr h => 

Proof state:
case inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ l : List α
x : α
xs : List α
d : α
n✝ n : ℕ
h : length l ≤ n
⊢ getD l n d = Option.getD (get? l n) d

Next tactic:
rw [getD_eq_default _ _ h, get?_eq_none.mpr h, Option.getD_none]
theorem getI_eq_iget_get? (n : ℕ) : l.getI n = (l.get? n).iget := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : Inhabited α
l : List α
x : α
xs : List α
n✝ n : ℕ
⊢ getI l n = Option.iget (get? l n)

Next tactic:
rw [← getD_default_eq_getI, getD_eq_getD_get?, Option.getD_default_eq_iget]
theorem getI_zero_eq_headI : l.getI 0 = l.headI := by 

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : Inhabited α
l : List α
x : α
xs : List α
n : ℕ
⊢ getI l 0 = headI l

Next tactic:
cases l
theorem getI_zero_eq_headI : l.getI 0 = l.headI := by cases l <;> 

Proof state:
case nil
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : Inhabited α
x : α
xs : List α
n : ℕ
⊢ getI [] 0 = headI []

Next tactic:
rfl
theorem getI_zero_eq_headI : l.getI 0 = l.headI := by cases l <;> 

Proof state:
case cons
ι : Type u_1
α : Type u
β : Type v
γ : Type w
l₁ l₂ : List α
inst✝ : Inhabited α
x : α
xs : List α
n : ℕ
head✝ : α
tail✝ : List α
⊢ getI (head✝ :: tail✝) 0 = headI (head✝ :: tail✝)

Next tactic:
rfl
/-- The images of disjoint lists under an injective map are disjoint -/
theorem disjoint_map {f : α → β} {s t : List α} (hf : Function.Injective f)
    (h : Disjoint s t) : Disjoint (s.map f) (t.map f) := by
  

Proof state:
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
s t : List α
hf : Injective f
h : Disjoint s t
⊢ Disjoint (map f s) (map f t)

Next tactic:
simp only [Disjoint]
/-- The images of disjoint lists under an injective map are disjoint -/
theorem disjoint_map {f : α → β} {s t : List α} (hf : Function.Injective f)
    (h : Disjoint s t) : Disjoint (s.map f) (t.map f) := by
  simp only [Disjoint]
  

Proof state:
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
s t : List α
hf : Injective f
h : Disjoint s t
⊢ ∀ ⦃a : β⦄, a ∈ map f s → a ∈ map f t → False

Next tactic:
intro b hbs hbt
/-- The images of disjoint lists under an injective map are disjoint -/
theorem disjoint_map {f : α → β} {s t : List α} (hf : Function.Injective f)
    (h : Disjoint s t) : Disjoint (s.map f) (t.map f) := by
  simp only [Disjoint]
  intro b hbs hbt
  

Proof state:
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
s t : List α
hf : Injective f
h : Disjoint s t
b : β
hbs : b ∈ map f s
hbt : b ∈ map f t
⊢ False

Next tactic:
rw [mem_map] at hbs hbt
/-- The images of disjoint lists under an injective map are disjoint -/
theorem disjoint_map {f : α → β} {s t : List α} (hf : Function.Injective f)
    (h : Disjoint s t) : Disjoint (s.map f) (t.map f) := by
  simp only [Disjoint]
  intro b hbs hbt
  rw [mem_map] at hbs hbt
  

Proof state:
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
s t : List α
hf : Injective f
h : Disjoint s t
b : β
hbs : ∃ a, a ∈ s ∧ f a = b
hbt : ∃ a, a ∈ t ∧ f a = b
⊢ False

Next tactic:
obtain ⟨a, ha, rfl⟩ := hbs
/-- The images of disjoint lists under an injective map are disjoint -/
theorem disjoint_map {f : α → β} {s t : List α} (hf : Function.Injective f)
    (h : Disjoint s t) : Disjoint (s.map f) (t.map f) := by
  simp only [Disjoint]
  intro b hbs hbt
  rw [mem_map] at hbs hbt
  obtain ⟨a, ha, rfl⟩ := hbs
  

Proof state:
case intro.intro
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
s t : List α
hf : Injective f
h : Disjoint s t
a : α
ha : a ∈ s
hbt : ∃ a_1, a_1 ∈ t ∧ f a_1 = f a
⊢ False

Next tactic:
apply h ha
/-- The images of disjoint lists under an injective map are disjoint -/
theorem disjoint_map {f : α → β} {s t : List α} (hf : Function.Injective f)
    (h : Disjoint s t) : Disjoint (s.map f) (t.map f) := by
  simp only [Disjoint]
  intro b hbs hbt
  rw [mem_map] at hbs hbt
  obtain ⟨a, ha, rfl⟩ := hbs
  apply h ha
  

Proof state:
case intro.intro
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
s t : List α
hf : Injective f
h : Disjoint s t
a : α
ha : a ∈ s
hbt : ∃ a_1, a_1 ∈ t ∧ f a_1 = f a
⊢ a ∈ t

Next tactic:
obtain ⟨a', ha', ha''⟩ := hbt
/-- The images of disjoint lists under an injective map are disjoint -/
theorem disjoint_map {f : α → β} {s t : List α} (hf : Function.Injective f)
    (h : Disjoint s t) : Disjoint (s.map f) (t.map f) := by
  simp only [Disjoint]
  intro b hbs hbt
  rw [mem_map] at hbs hbt
  obtain ⟨a, ha, rfl⟩ := hbs
  apply h ha
  obtain ⟨a', ha', ha''⟩ := hbt
  

Proof state:
case intro.intro.intro.intro
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
s t : List α
hf : Injective f
h : Disjoint s t
a : α
ha : a ∈ s
a' : α
ha' : a' ∈ t
ha'' : f a' = f a
⊢ a ∈ t

Next tactic:
rw [hf ha''.symm]
/-- The images of disjoint lists under an injective map are disjoint -/
theorem disjoint_map {f : α → β} {s t : List α} (hf : Function.Injective f)
    (h : Disjoint s t) : Disjoint (s.map f) (t.map f) := by
  simp only [Disjoint]
  intro b hbs hbt
  rw [mem_map] at hbs hbt
  obtain ⟨a, ha, rfl⟩ := hbs
  apply h ha
  obtain ⟨a', ha', ha''⟩ := hbt
  rw [hf ha''.symm]; 

Proof state:
case intro.intro.intro.intro
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
f : α → β
s t : List α
hf : Injective f
h : Disjoint s t
a : α
ha : a ∈ s
a' : α
ha' : a' ∈ t
ha'' : f a' = f a
⊢ a' ∈ t

Next tactic:
exact ha'
/-- The images of disjoint lists under a partially defined map are disjoint -/
theorem disjoint_pmap {p : α → Prop} {f : ∀ a : α, p a → β} {s t : List α}
    (hs : ∀ a ∈ s, p a) (ht : ∀ a ∈ t, p a)
    (hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a')
    (h : Disjoint s t) :
    Disjoint (s.pmap f hs) (t.pmap f ht) := by
  

Proof state:
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
p : α → Prop
f : (a : α) → p a → β
s t : List α
hs : ∀ (a : α), a ∈ s → p a
ht : ∀ (a : α), a ∈ t → p a
hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a'
h : Disjoint s t
⊢ Disjoint (pmap f s hs) (pmap f t ht)

Next tactic:
simp only [Disjoint]
/-- The images of disjoint lists under a partially defined map are disjoint -/
theorem disjoint_pmap {p : α → Prop} {f : ∀ a : α, p a → β} {s t : List α}
    (hs : ∀ a ∈ s, p a) (ht : ∀ a ∈ t, p a)
    (hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a')
    (h : Disjoint s t) :
    Disjoint (s.pmap f hs) (t.pmap f ht) := by
  simp only [Disjoint]
  

Proof state:
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
p : α → Prop
f : (a : α) → p a → β
s t : List α
hs : ∀ (a : α), a ∈ s → p a
ht : ∀ (a : α), a ∈ t → p a
hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a'
h : Disjoint s t
⊢ ∀ ⦃a : β⦄, a ∈ pmap f s hs → a ∈ pmap f t ht → False

Next tactic:
intro b hbs hbt
/-- The images of disjoint lists under a partially defined map are disjoint -/
theorem disjoint_pmap {p : α → Prop} {f : ∀ a : α, p a → β} {s t : List α}
    (hs : ∀ a ∈ s, p a) (ht : ∀ a ∈ t, p a)
    (hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a')
    (h : Disjoint s t) :
    Disjoint (s.pmap f hs) (t.pmap f ht) := by
  simp only [Disjoint]
  intro b hbs hbt
  

Proof state:
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
p : α → Prop
f : (a : α) → p a → β
s t : List α
hs : ∀ (a : α), a ∈ s → p a
ht : ∀ (a : α), a ∈ t → p a
hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a'
h : Disjoint s t
b : β
hbs : b ∈ pmap f s hs
hbt : b ∈ pmap f t ht
⊢ False

Next tactic:
rw [mem_pmap] at hbs hbt
/-- The images of disjoint lists under a partially defined map are disjoint -/
theorem disjoint_pmap {p : α → Prop} {f : ∀ a : α, p a → β} {s t : List α}
    (hs : ∀ a ∈ s, p a) (ht : ∀ a ∈ t, p a)
    (hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a')
    (h : Disjoint s t) :
    Disjoint (s.pmap f hs) (t.pmap f ht) := by
  simp only [Disjoint]
  intro b hbs hbt
  rw [mem_pmap] at hbs hbt
  

Proof state:
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
p : α → Prop
f : (a : α) → p a → β
s t : List α
hs : ∀ (a : α), a ∈ s → p a
ht : ∀ (a : α), a ∈ t → p a
hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a'
h : Disjoint s t
b : β
hbs : ∃ a h, f a (_ : p a) = b
hbt : ∃ a h, f a (_ : p a) = b
⊢ False

Next tactic:
obtain ⟨a, ha, rfl⟩ := hbs
/-- The images of disjoint lists under a partially defined map are disjoint -/
theorem disjoint_pmap {p : α → Prop} {f : ∀ a : α, p a → β} {s t : List α}
    (hs : ∀ a ∈ s, p a) (ht : ∀ a ∈ t, p a)
    (hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a')
    (h : Disjoint s t) :
    Disjoint (s.pmap f hs) (t.pmap f ht) := by
  simp only [Disjoint]
  intro b hbs hbt
  rw [mem_pmap] at hbs hbt
  obtain ⟨a, ha, rfl⟩ := hbs
  

Proof state:
case intro.intro
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
p : α → Prop
f : (a : α) → p a → β
s t : List α
hs : ∀ (a : α), a ∈ s → p a
ht : ∀ (a : α), a ∈ t → p a
hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a'
h : Disjoint s t
a : α
ha : a ∈ s
hbt : ∃ a_1 h, f a_1 (_ : p a_1) = f a (_ : p a)
⊢ False

Next tactic:
apply h ha
/-- The images of disjoint lists under a partially defined map are disjoint -/
theorem disjoint_pmap {p : α → Prop} {f : ∀ a : α, p a → β} {s t : List α}
    (hs : ∀ a ∈ s, p a) (ht : ∀ a ∈ t, p a)
    (hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a')
    (h : Disjoint s t) :
    Disjoint (s.pmap f hs) (t.pmap f ht) := by
  simp only [Disjoint]
  intro b hbs hbt
  rw [mem_pmap] at hbs hbt
  obtain ⟨a, ha, rfl⟩ := hbs
  apply h ha
  

Proof state:
case intro.intro
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
p : α → Prop
f : (a : α) → p a → β
s t : List α
hs : ∀ (a : α), a ∈ s → p a
ht : ∀ (a : α), a ∈ t → p a
hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a'
h : Disjoint s t
a : α
ha : a ∈ s
hbt : ∃ a_1 h, f a_1 (_ : p a_1) = f a (_ : p a)
⊢ a ∈ t

Next tactic:
obtain ⟨a', ha', ha''⟩ := hbt
/-- The images of disjoint lists under a partially defined map are disjoint -/
theorem disjoint_pmap {p : α → Prop} {f : ∀ a : α, p a → β} {s t : List α}
    (hs : ∀ a ∈ s, p a) (ht : ∀ a ∈ t, p a)
    (hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a')
    (h : Disjoint s t) :
    Disjoint (s.pmap f hs) (t.pmap f ht) := by
  simp only [Disjoint]
  intro b hbs hbt
  rw [mem_pmap] at hbs hbt
  obtain ⟨a, ha, rfl⟩ := hbs
  apply h ha
  obtain ⟨a', ha', ha''⟩ := hbt
  

Proof state:
case intro.intro.intro.intro
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
p : α → Prop
f : (a : α) → p a → β
s t : List α
hs : ∀ (a : α), a ∈ s → p a
ht : ∀ (a : α), a ∈ t → p a
hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a'
h : Disjoint s t
a : α
ha : a ∈ s
a' : α
ha' : a' ∈ t
ha'' : f a' (_ : p a') = f a (_ : p a)
⊢ a ∈ t

Next tactic:
rw [hf a a' (hs a ha) (ht a' ha') ha''.symm]
/-- The images of disjoint lists under a partially defined map are disjoint -/
theorem disjoint_pmap {p : α → Prop} {f : ∀ a : α, p a → β} {s t : List α}
    (hs : ∀ a ∈ s, p a) (ht : ∀ a ∈ t, p a)
    (hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a')
    (h : Disjoint s t) :
    Disjoint (s.pmap f hs) (t.pmap f ht) := by
  simp only [Disjoint]
  intro b hbs hbt
  rw [mem_pmap] at hbs hbt
  obtain ⟨a, ha, rfl⟩ := hbs
  apply h ha
  obtain ⟨a', ha', ha''⟩ := hbt
  rw [hf a a' (hs a ha) (ht a' ha') ha''.symm]
  

Proof state:
case intro.intro.intro.intro
ι : Type u_1
α✝ : Type u
β✝ : Type v
γ : Type w
l₁ l₂ : List α✝
α : Type u_2
β : Type u_3
p : α → Prop
f : (a : α) → p a → β
s t : List α
hs : ∀ (a : α), a ∈ s → p a
ht : ∀ (a : α), a ∈ t → p a
hf : ∀ (a a' : α) (ha : p a) (ha' : p a'), f a ha = f a' ha' → a = a'
h : Disjoint s t
a : α
ha : a ∈ s
a' : α
ha' : a' ∈ t
ha'' : f a' (_ : p a') = f a (_ : p a)
⊢ a' ∈ t

Next tactic:
exact ha'
@[to_additive]
instance monoidObj (F : J ⥤ MonCatMax.{u,v} ) (j) : Monoid ((F ⋙ forget MonCat).obj j) := by
  

Proof state:
J : Type v
inst✝ : SmallCategory J
F : J ⥤ MonCatMax
j : J
⊢ Monoid ((F ⋙ forget MonCat).obj j)

Next tactic:
change Monoid (F.obj j)
@[to_additive]
instance monoidObj (F : J ⥤ MonCatMax.{u,v} ) (j) : Monoid ((F ⋙ forget MonCat).obj j) := by
  change Monoid (F.obj j)
  

Proof state:
J : Type v
inst✝ : SmallCategory J
F : J ⥤ MonCatMax
j : J
⊢ Monoid ↑(F.obj j)

Next tactic:
infer_instance
/-- The flat sections of a functor into `MonCat` form a submonoid of all sections.
-/
@[to_additive
      "The flat sections of a functor into `AddMonCat` form an additive submonoid of all sections."]
def sectionsSubmonoid (F : J ⥤ MonCatMax.{u,v}) : Submonoid (∀ j, F.obj j) where
  carrier := (F ⋙ forget MonCat).sections
  one_mem' {j} {j'} f := by simp
  mul_mem' {a} {b} ah bh {j} {j'} f := by
    

Proof state:
J : Type v
inst✝ : SmallCategory J
F : J ⥤ MonCatMax
a b : (j : J) → ↑(F.obj j)
ah : a ∈ Functor.sections (F ⋙ forget MonCat)
bh : b ∈ Functor.sections (F ⋙ forget MonCat)
j j' : J
f : j ⟶ j'
⊢ (F ⋙ forget MonCat).map f ((a * b) j) = (a * b) j'

Next tactic:
simp only [Functor.comp_map, MonoidHom.map_mul, Pi.mul_apply]
/-- The flat sections of a functor into `MonCat` form a submonoid of all sections.
-/
@[to_additive
      "The flat sections of a functor into `AddMonCat` form an additive submonoid of all sections."]
def sectionsSubmonoid (F : J ⥤ MonCatMax.{u,v}) : Submonoid (∀ j, F.obj j) where
  carrier := (F ⋙ forget MonCat).sections
  one_mem' {j} {j'} f := by simp
  mul_mem' {a} {b} ah bh {j} {j'} f := by
    simp only [Functor.comp_map, MonoidHom.map_mul, Pi.mul_apply]
    

Proof state:
J : Type v
inst✝ : SmallCategory J
F : J ⥤ MonCatMax
a b : (j : J) → ↑(F.obj j)
ah : a ∈ Functor.sections (F ⋙ forget MonCat)
bh : b ∈ Functor.sections (F ⋙ forget MonCat)
j j' : J
f : j ⟶ j'
⊢ (forget MonCat).map (F.map f) (a j * b j) = a j' * b j'

Next tactic:
dsimp [Functor.sections] at ah bh
/-- The flat sections of a functor into `MonCat` form a submonoid of all sections.
-/
@[to_additive
      "The flat sections of a functor into `AddMonCat` form an additive submonoid of all sections."]
def sectionsSubmonoid (F : J ⥤ MonCatMax.{u,v}) : Submonoid (∀ j, F.obj j) where
  carrier := (F ⋙ forget MonCat).sections
  one_mem' {j} {j'} f := by simp
  mul_mem' {a} {b} ah bh {j} {j'} f := by
    simp only [Functor.comp_map, MonoidHom.map_mul, Pi.mul_apply]
    dsimp [Functor.sections] at ah bh
    

Proof state:
J : Type v
inst✝ : SmallCategory J
F : J ⥤ MonCatMax
a b : (j : J) → ↑(F.obj j)
ah : a ∈ {u | ∀ {j j' : J} (f : j ⟶ j'), (F.map f) (u j) = u j'}
bh : b ∈ {u | ∀ {j j' : J} (f : j ⟶ j'), (F.map f) (u j) = u j'}
j j' : J
f : j ⟶ j'
⊢ (forget MonCat).map (F.map f) (a j * b j) = a j' * b j'

Next tactic:
rw [← ah f, ← bh f, forget_map, map_mul]
/-- The flat sections of a functor into `MonCat` form a submonoid of all sections.
-/
@[to_additive
      "The flat sections of a functor into `AddMonCat` form an additive submonoid of all sections."]
def sectionsSubmonoid (F : J ⥤ MonCatMax.{u,v}) : Submonoid (∀ j, F.obj j) where
  carrier := (F ⋙ forget MonCat).sections
  one_mem' {j} {j'} f := by 

Proof state:
J : Type v
inst✝ : SmallCategory J
F : J ⥤ MonCatMax
j j' : J
f : j ⟶ j'
⊢ (F ⋙ forget MonCat).map f (OfNat.ofNat 1 j) = OfNat.ofNat 1 j'

Next tactic:
simp
/-- Witness that the limit cone in `MonCat` is a limit cone.
(Internal use only; use the limits API.)
-/
@[to_additive "(Internal use only; use the limits API.)"]
noncomputable def limitConeIsLimit (F : J ⥤ MonCatMax.{u,v}) : IsLimit (limitCone F) := by
  

Proof state:
J : Type v
inst✝ : SmallCategory J
F : J ⥤ MonCatMax
⊢ IsLimit (limitCone F)

Next tactic:
refine IsLimit.ofFaithful (forget MonCatMax) (Types.limitConeIsLimit.{v,u} _)
    (fun s => { toFun := _, map_one' := ?_, map_mul' := ?_ }) (fun s => rfl)
/-- Witness that the limit cone in `MonCat` is a limit cone.
(Internal use only; use the limits API.)
-/
@[to_additive "(Internal use only; use the limits API.)"]
noncomputable def limitConeIsLimit (F : J ⥤ MonCatMax.{u,v}) : IsLimit (limitCone F) := by
  refine IsLimit.ofFaithful (forget MonCatMax) (Types.limitConeIsLimit.{v,u} _)
    (fun s => { toFun := _, map_one' := ?_, map_mul' := ?_ }) (fun s => rfl) <;>
  

Proof state:
case refine_1
J : Type v
inst✝ : SmallCategory J
F : J ⥤ MonCatMax
s : Cone F
⊢ { val := fun j => ((forget MonCatMax).mapCone s).π.app j 1,
      property :=
        (_ :
          ∀ {j j' : J} (f : j ⟶ j'),
            (((forget MonCatMax).mapCone s).π.app j ≫ (F ⋙ forget MonCatMax).map f) 1 =
              ((forget MonCatMax).mapCone s).π.app j' 1) } =
    1

Next tactic:
aesop_cat