l3lab/ntp-mathlib huggingface dataset:
/-- There is no surjection from `α : Type u` into `Type (max u v)`. This theorem
  demonstrates why `Type : Type` would be inconsistent in Lean. -/
theorem not_surjective_Type {α : Type u} (f : α → Type max u v) : ¬Surjective f := by
  intro hf
  let T : Type max u v := Sigma f
  cases hf (Set T) with | intro U hU =>
  let g : Set T → T := fun s ↦ ⟨U, cast hU.symm s⟩
  have hg : Injective g := by
    intro s t h
    

Proof state:
α✝ : Sort ?u.9034
β : Sort ?u.9037
γ : Sort ?u.9040
f✝ : α✝ → β
α : Type u
f : α → Type (max u v)
hf : Surjective f
T : Type (max u v) := Sigma f
U : α
hU : f U = Set T
g : Set T → T := fun s => { fst := U, snd := cast (_ : Set T = f U) s }
s t : Set T
h : g s = g t
⊢ s = t

Next tactic:
suffices cast hU (g s).2 = cast hU (g t).2 by
      simp only [cast_cast, cast_eq] at this
      assumption
/-- There is no surjection from `α : Type u` into `Type (max u v)`. This theorem
  demonstrates why `Type : Type` would be inconsistent in Lean. -/
theorem not_surjective_Type {α : Type u} (f : α → Type max u v) : ¬Surjective f := by
  intro hf
  let T : Type max u v := Sigma f
  cases hf (Set T) with | intro U hU =>
  let g : Set T → T := fun s ↦ ⟨U, cast hU.symm s⟩
  have hg : Injective g := by
    intro s t h
    suffices cast hU (g s).2 = cast hU (g t).2 by
      

Proof state:
α✝ : Sort ?u.9034
β : Sort ?u.9037
γ : Sort ?u.9040
f✝ : α✝ → β
α : Type u
f : α → Type (max u v)
hf : Surjective f
T : Type (max u v) := Sigma f
U : α
hU : f U = Set T
g : Set T → T := fun s => { fst := U, snd := cast (_ : Set T = f U) s }
s t : Set T
h : g s = g t
this : cast hU (g s).snd = cast hU (g t).snd
⊢ s = t

Next tactic:
simp only [cast_cast, cast_eq] at this
/-- There is no surjection from `α : Type u` into `Type (max u v)`. This theorem
  demonstrates why `Type : Type` would be inconsistent in Lean. -/
theorem not_surjective_Type {α : Type u} (f : α → Type max u v) : ¬Surjective f := by
  intro hf
  let T : Type max u v := Sigma f
  cases hf (Set T) with | intro U hU =>
  let g : Set T → T := fun s ↦ ⟨U, cast hU.symm s⟩
  have hg : Injective g := by
    intro s t h
    suffices cast hU (g s).2 = cast hU (g t).2 by
      simp only [cast_cast, cast_eq] at this
      

Proof state:
α✝ : Sort ?u.9034
β : Sort ?u.9037
γ : Sort ?u.9040
f✝ : α✝ → β
α : Type u
f : α → Type (max u v)
hf : Surjective f
T : Type (max u v) := Sigma f
U : α
hU : f U = Set T
g : Set T → T := fun s => { fst := U, snd := cast (_ : Set T = f U) s }
s t : Set T
h : g s = g t
this : s = t
⊢ s = t

Next tactic:
assumption
/-- There is no surjection from `α : Type u` into `Type (max u v)`. This theorem
  demonstrates why `Type : Type` would be inconsistent in Lean. -/
theorem not_surjective_Type {α : Type u} (f : α → Type max u v) : ¬Surjective f := by
  intro hf
  let T : Type max u v := Sigma f
  cases hf (Set T) with | intro U hU =>
  let g : Set T → T := fun s ↦ ⟨U, cast hU.symm s⟩
  have hg : Injective g := by
    intro s t h
    suffices cast hU (g s).2 = cast hU (g t).2 by
      simp only [cast_cast, cast_eq] at this
      assumption
    · 

Proof state:
α✝ : Sort ?u.9034
β : Sort ?u.9037
γ : Sort ?u.9040
f✝ : α✝ → β
α : Type u
f : α → Type (max u v)
hf : Surjective f
T : Type (max u v) := Sigma f
U : α
hU : f U = Set T
g : Set T → T := fun s => { fst := U, snd := cast (_ : Set T = f U) s }
s t : Set T
h : g s = g t
⊢ cast hU (g s).snd = cast hU (g t).snd

Next tactic:
congr
/-- There is no surjection from `α : Type u` into `Type (max u v)`. This theorem
  demonstrates why `Type : Type` would be inconsistent in Lean. -/
theorem not_surjective_Type {α : Type u} (f : α → Type max u v) : ¬Surjective f := by
  intro hf
  let T : Type max u v := Sigma f
  cases hf (Set T) with | intro U hU =>
  let g : Set T → T := fun s ↦ ⟨U, cast hU.symm s⟩
  have hg : Injective g := by
    intro s t h
    suffices cast hU (g s).2 = cast hU (g t).2 by
      simp only [cast_cast, cast_eq] at this
      assumption
    · congr
  

Proof state:
case intro
α✝ : Sort ?u.9034
β : Sort ?u.9037
γ : Sort ?u.9040
f✝ : α✝ → β
α : Type u
f : α → Type (max u v)
hf : Surjective f
T : Type (max u v) := Sigma f
U : α
hU : f U = Set T
g : Set T → T := fun s => { fst := U, snd := cast (_ : Set T = f U) s }
hg : Injective g
⊢ False

Next tactic:
exact cantor_injective g hg
theorem LeftInverse.comp {f : α → β} {g : β → α} {h : β → γ} {i : γ → β} (hf : LeftInverse f g)
    (hh : LeftInverse h i) : LeftInverse (h ∘ f) (g ∘ i) :=
  fun a ↦ show h (f (g (i a))) = a by 

Proof state:
α : Sort u_2
β : Sort u_1
γ : Sort u_3
f✝ f : α → β
g : β → α
h : β → γ
i : γ → β
hf : LeftInverse f g
hh : LeftInverse h i
a : γ
⊢ h (f (g (i a))) = a

Next tactic:
rw [hf (i a), hh a]
theorem LeftInverse.eq_rightInverse {f : α → β} {g₁ g₂ : β → α} (h₁ : LeftInverse g₁ f)
    (h₂ : RightInverse g₂ f) : g₁ = g₂ :=
  calc
    g₁ = g₁ ∘ f ∘ g₂ := by 

Proof state:
α : Sort u_1
β : Sort u_2
γ : Sort ?u.11583
f✝ f : α → β
g₁ g₂ : β → α
h₁ : LeftInverse g₁ f
h₂ : RightInverse g₂ f
⊢ g₁ = g₁ ∘ f ∘ g₂

Next tactic:
rw [h₂.comp_eq_id, comp.right_id]
theorem LeftInverse.eq_rightInverse {f : α → β} {g₁ g₂ : β → α} (h₁ : LeftInverse g₁ f)
    (h₂ : RightInverse g₂ f) : g₁ = g₂ :=
  calc
    g₁ = g₁ ∘ f ∘ g₂ := by rw [h₂.comp_eq_id, comp.right_id]
     _ = g₂ := by 

Proof state:
α : Sort u_1
β : Sort u_2
γ : Sort ?u.11583
f✝ f : α → β
g₁ g₂ : β → α
h₁ : LeftInverse g₁ f
h₂ : RightInverse g₂ f
⊢ g₁ ∘ f ∘ g₂ = g₂

Next tactic:
rw [← comp.assoc, h₁.comp_eq_id, comp.left_id]
theorem partialInv_of_injective {α β} {f : α → β} (I : Injective f) : IsPartialInv f (partialInv f)
  | a, b =>
  ⟨fun h =>
    have hpi : partialInv f b = if h : ∃ a, f a = b then some (Classical.choose h) else none :=
      rfl
    if h' : ∃ a, f a = b
    then by 

Proof state:
α✝ : Sort ?u.12049
β✝ : Sort ?u.12052
γ : Sort ?u.12055
f✝ : α✝ → β✝
α : Type u_1
β : Sort u_2
f : α → β
I : Injective f
a : α
b : β
h : partialInv f b = some a
hpi : partialInv f b = if h : ∃ a, f a = b then some (Classical.choose h) else none
h' : ∃ a, f a = b
⊢ f a = b

Next tactic:
rw [hpi, dif_pos h'] at h
theorem partialInv_of_injective {α β} {f : α → β} (I : Injective f) : IsPartialInv f (partialInv f)
  | a, b =>
  ⟨fun h =>
    have hpi : partialInv f b = if h : ∃ a, f a = b then some (Classical.choose h) else none :=
      rfl
    if h' : ∃ a, f a = b
    then by rw [hpi, dif_pos h'] at h
            

Proof state:
α✝ : Sort ?u.12049
β✝ : Sort ?u.12052
γ : Sort ?u.12055
f✝ : α✝ → β✝
α : Type u_1
β : Sort u_2
f : α → β
I : Injective f
a : α
b : β
hpi : partialInv f b = if h : ∃ a, f a = b then some (Classical.choose h) else none
h' : ∃ a, f a = b
h : some (Classical.choose h') = some a
⊢ f a = b

Next tactic:
injection h with h
theorem partialInv_of_injective {α β} {f : α → β} (I : Injective f) : IsPartialInv f (partialInv f)
  | a, b =>
  ⟨fun h =>
    have hpi : partialInv f b = if h : ∃ a, f a = b then some (Classical.choose h) else none :=
      rfl
    if h' : ∃ a, f a = b
    then by rw [hpi, dif_pos h'] at h
            injection h with h
            

Proof state:
α✝ : Sort ?u.12049
β✝ : Sort ?u.12052
γ : Sort ?u.12055
f✝ : α✝ → β✝
α : Type u_1
β : Sort u_2
f : α → β
I : Injective f
a : α
b : β
hpi : partialInv f b = if h : ∃ a, f a = b then some (Classical.choose h) else none
h' : ∃ a, f a = b
h : Classical.choose h' = a
⊢ f a = b

Next tactic:
subst h
theorem partialInv_of_injective {α β} {f : α → β} (I : Injective f) : IsPartialInv f (partialInv f)
  | a, b =>
  ⟨fun h =>
    have hpi : partialInv f b = if h : ∃ a, f a = b then some (Classical.choose h) else none :=
      rfl
    if h' : ∃ a, f a = b
    then by rw [hpi, dif_pos h'] at h
            injection h with h
            subst h
            

Proof state:
α✝ : Sort ?u.12049
β✝ : Sort ?u.12052
γ : Sort ?u.12055
f✝ : α✝ → β✝
α : Type u_1
β : Sort u_2
f : α → β
I : Injective f
b : β
hpi : partialInv f b = if h : ∃ a, f a = b then some (Classical.choose h) else none
h' : ∃ a, f a = b
⊢ f (Classical.choose h') = b

Next tactic:
apply Classical.choose_spec h'
theorem partialInv_of_injective {α β} {f : α → β} (I : Injective f) : IsPartialInv f (partialInv f)
  | a, b =>
  ⟨fun h =>
    have hpi : partialInv f b = if h : ∃ a, f a = b then some (Classical.choose h) else none :=
      rfl
    if h' : ∃ a, f a = b
    then by rw [hpi, dif_pos h'] at h
            injection h with h
            subst h
            apply Classical.choose_spec h'
    else by 

Proof state:
α✝ : Sort ?u.12049
β✝ : Sort ?u.12052
γ : Sort ?u.12055
f✝ : α✝ → β✝
α : Type u_1
β : Sort u_2
f : α → β
I : Injective f
a : α
b : β
h : partialInv f b = some a
hpi : partialInv f b = if h : ∃ a, f a = b then some (Classical.choose h) else none
h' : ¬∃ a, f a = b
⊢ f a = b

Next tactic:
rw [hpi, dif_neg h'] at h
theorem partialInv_of_injective {α β} {f : α → β} (I : Injective f) : IsPartialInv f (partialInv f)
  | a, b =>
  ⟨fun h =>
    have hpi : partialInv f b = if h : ∃ a, f a = b then some (Classical.choose h) else none :=
      rfl
    if h' : ∃ a, f a = b
    then by rw [hpi, dif_pos h'] at h
            injection h with h
            subst h
            apply Classical.choose_spec h'
    else by rw [hpi, dif_neg h'] at h; 

Proof state:
α✝ : Sort ?u.12049
β✝ : Sort ?u.12052
γ : Sort ?u.12055
f✝ : α✝ → β✝
α : Type u_1
β : Sort u_2
f : α → β
I : Injective f
a : α
b : β
h : none = some a
hpi : partialInv f b = if h : ∃ a, f a = b then some (Classical.choose h) else none
h' : ¬∃ a, f a = b
⊢ f a = b

Next tactic:
contradiction
theorem invFun_eq (h : ∃ a, f a = b) : f (invFun f b) = b :=
  by 

Proof state:
α : Sort u_1
β : Sort u_2
inst✝ : Nonempty α
f : α → β
a : α
b : β
h : ∃ a, f a = b
⊢ f (invFun f b) = b

Next tactic:
simp only [invFun, dif_pos h, h.choose_spec]
theorem invFun_eq_of_injective_of_rightInverse {g : β → α} (hf : Injective f)
    (hg : RightInverse g f) : invFun f = g :=
  funext fun b ↦
    hf
      (by
        

Proof state:
α : Sort u_1
β : Sort u_2
inst✝ : Nonempty α
f : α → β
a : α
b✝ : β
g : β → α
hf : Injective f
hg : RightInverse g f
b : β
⊢ f (invFun f b) = f (g b)

Next tactic:
rw [hg b]
theorem invFun_eq_of_injective_of_rightInverse {g : β → α} (hf : Injective f)
    (hg : RightInverse g f) : invFun f = g :=
  funext fun b ↦
    hf
      (by
        rw [hg b]
        

Proof state:
α : Sort u_1
β : Sort u_2
inst✝ : Nonempty α
f : α → β
a : α
b✝ : β
g : β → α
hf : Injective f
hg : RightInverse g f
b : β
⊢ f (invFun f b) = b

Next tactic:
exact invFun_eq ⟨g b, hg b⟩
/-- On non-dependent functions, `Function.update` can be expressed as an `ite` -/
theorem update_apply {β : Sort*} (f : α → β) (a' : α) (b : β) (a : α) :
    update f a' b a = if a = a' then b else f a := by
  

Proof state:
α : Sort u
β✝ : α → Sort v
α' : Sort w
inst✝¹ : DecidableEq α
inst✝ : DecidableEq α'
f✝ g : (a : α) → β✝ a
a✝ : α
b✝ : β✝ a✝
β : Sort u_1
f : α → β
a' : α
b : β
a : α
⊢ update f a' b a = if a = a' then b else f a

Next tactic:
rcases Decidable.eq_or_ne a a' with rfl | hne
/-- On non-dependent functions, `Function.update` can be expressed as an `ite` -/
theorem update_apply {β : Sort*} (f : α → β) (a' : α) (b : β) (a : α) :
    update f a' b a = if a = a' then b else f a := by
  rcases Decidable.eq_or_ne a a' with rfl | hne <;> 

Proof state:
case inl
α : Sort u
β✝ : α → Sort v
α' : Sort w
inst✝¹ : DecidableEq α
inst✝ : DecidableEq α'
f✝ g : (a : α) → β✝ a
a✝ : α
b✝ : β✝ a✝
β : Sort u_1
f : α → β
b : β
a : α
⊢ update f a b a = if a = a then b else f a

Next tactic:
simp [*]
/-- On non-dependent functions, `Function.update` can be expressed as an `ite` -/
theorem update_apply {β : Sort*} (f : α → β) (a' : α) (b : β) (a : α) :
    update f a' b a = if a = a' then b else f a := by
  rcases Decidable.eq_or_ne a a' with rfl | hne <;> 

Proof state:
case inr
α : Sort u
β✝ : α → Sort v
α' : Sort w
inst✝¹ : DecidableEq α
inst✝ : DecidableEq α'
f✝ g : (a : α) → β✝ a
a✝ : α
b✝ : β✝ a✝
β : Sort u_1
f : α → β
a' : α
b : β
a : α
hne : a ≠ a'
⊢ update f a' b a = if a = a' then b else f a

Next tactic:
simp [*]
theorem update_injective (f : ∀ a, β a) (a' : α) : Injective (update f a') := fun v v' h ↦ by
  

Proof state:
α : Sort u
β : α → Sort v
α' : Sort w
inst✝¹ : DecidableEq α
inst✝ : DecidableEq α'
f✝ g : (a : α) → β a
a : α
b : β a
f : (a : α) → β a
a' : α
v v' : β a'
h : update f a' v = update f a' v'
⊢ v = v'

Next tactic:
have := congr_fun h a'
theorem update_injective (f : ∀ a, β a) (a' : α) : Injective (update f a') := fun v v' h ↦ by
  have := congr_fun h a'
  

Proof state:
α : Sort u
β : α → Sort v
α' : Sort w
inst✝¹ : DecidableEq α
inst✝ : DecidableEq α'
f✝ g : (a : α) → β a
a : α
b : β a
f : (a : α) → β a
a' : α
v v' : β a'
h : update f a' v = update f a' v'
this : update f a' v a' = update f a' v' a'
⊢ v = v'

Next tactic:
rwa [update_same, update_same] at this
lemma forall_update_iff (f : ∀a, β a) {a : α} {b : β a} (p : ∀a, β a → Prop) :
    (∀ x, p x (update f a b x)) ↔ p a b ∧ ∀ x, x ≠ a → p x (f x) := by
  

Proof state:
α : Sort u
β : α → Sort v
α' : Sort w
inst✝¹ : DecidableEq α
inst✝ : DecidableEq α'
f✝ g : (a : α) → β a
a✝ : α
b✝ : β a✝
f : (a : α) → β a
a : α
b : β a
p : (a : α) → β a → Prop
⊢ (∀ (x : α), p x (update f a b x)) ↔ p a b ∧ ∀ (x : α), x ≠ a → p x (f x)

Next tactic:
rw [← and_forall_ne a, update_same]
lemma forall_update_iff (f : ∀a, β a) {a : α} {b : β a} (p : ∀a, β a → Prop) :
    (∀ x, p x (update f a b x)) ↔ p a b ∧ ∀ x, x ≠ a → p x (f x) := by
  rw [← and_forall_ne a, update_same]
  

Proof state:
α : Sort u
β : α → Sort v
α' : Sort w
inst✝¹ : DecidableEq α
inst✝ : DecidableEq α'
f✝ g : (a : α) → β a
a✝ : α
b✝ : β a✝
f : (a : α) → β a
a : α
b : β a
p : (a : α) → β a → Prop
⊢ (p a b ∧ ∀ (b_1 : α), b_1 ≠ a → p b_1 (update f a b b_1)) ↔ p a b ∧ ∀ (x : α), x ≠ a → p x (f x)

Next tactic:
simp (config := { contextual := true })
theorem exists_update_iff (f : ∀ a, β a) {a : α} {b : β a} (p : ∀ a, β a → Prop) :
    (∃ x, p x (update f a b x)) ↔ p a b ∨ ∃ (x : _) (_ : x ≠ a), p x (f x) := by
  

Proof state:
α : Sort u
β : α → Sort v
α' : Sort w
inst✝¹ : DecidableEq α
inst✝ : DecidableEq α'
f✝ g : (a : α) → β a
a✝ : α
b✝ : β a✝
f : (a : α) → β a
a : α
b : β a
p : (a : α) → β a → Prop
⊢ (∃ x, p x (update f a b x)) ↔ p a b ∨ ∃ x x_1, p x (f x)

Next tactic:
rw [← not_forall_not, forall_update_iff f fun a b ↦ ¬p a b]
theorem exists_update_iff (f : ∀ a, β a) {a : α} {b : β a} (p : ∀ a, β a → Prop) :
    (∃ x, p x (update f a b x)) ↔ p a b ∨ ∃ (x : _) (_ : x ≠ a), p x (f x) := by
  rw [← not_forall_not, forall_update_iff f fun a b ↦ ¬p a b]
  

Proof state:
α : Sort u
β : α → Sort v
α' : Sort w
inst✝¹ : DecidableEq α
inst✝ : DecidableEq α'
f✝ g : (a : α) → β a
a✝ : α
b✝ : β a✝
f : (a : α) → β a
a : α
b : β a
p : (a : α) → β a → Prop
⊢ ¬(¬p a b ∧ ∀ (x : α), x ≠ a → ¬p x (f x)) ↔ p a b ∨ ∃ x x_1, p x (f x)

Next tactic:
simp [-not_and, not_and_or]
@[simp] lemma update_eq_self_iff : update f a b = f ↔ b = f a := by 

Proof state:
α : Sort u
β : α → Sort v
α' : Sort w
inst✝¹ : DecidableEq α
inst✝ : DecidableEq α'
f g : (a : α) → β a
a : α
b : β a
⊢ update f a b = f ↔ b = f a

Next tactic:
simp [update_eq_iff]
@[simp] lemma eq_update_self_iff : f = update f a b ↔ f a = b := by 

Proof state:
α : Sort u
β : α → Sort v
α' : Sort w
inst✝¹ : DecidableEq α
inst✝ : DecidableEq α'
f g : (a : α) → β a
a : α
b : β a
⊢ f = update f a b ↔ f a = b

Next tactic:
simp [eq_update_iff]
theorem apply_update {ι : Sort*} [DecidableEq ι] {α β : ι → Sort*} (f : ∀ i, α i → β i)
    (g : ∀ i, α i) (i : ι) (v : α i) (j : ι) :
    f j (update g i v j) = update (fun k ↦ f k (g k)) i (f i v) j := by
  

Proof state:
α✝ : Sort u
β✝ : α✝ → Sort v
α' : Sort w
inst✝² : DecidableEq α✝
inst✝¹ : DecidableEq α'
f✝ g✝ : (a : α✝) → β✝ a
a : α✝
b : β✝ a
ι : Sort u_1
inst✝ : DecidableEq ι
α : ι → Sort u_2
β : ι → Sort u_3
f : (i : ι) → α i → β i
g : (i : ι) → α i
i : ι
v : α i
j : ι
⊢ f j (update g i v j) = update (fun k => f k (g k)) i (f i v) j

Next tactic:
by_cases h:j = i
theorem apply_update {ι : Sort*} [DecidableEq ι] {α β : ι → Sort*} (f : ∀ i, α i → β i)
    (g : ∀ i, α i) (i : ι) (v : α i) (j : ι) :
    f j (update g i v j) = update (fun k ↦ f k (g k)) i (f i v) j := by
  by_cases h:j = i
  · 

Proof state:
case pos
α✝ : Sort u
β✝ : α✝ → Sort v
α' : Sort w
inst✝² : DecidableEq α✝
inst✝¹ : DecidableEq α'
f✝ g✝ : (a : α✝) → β✝ a
a : α✝
b : β✝ a
ι : Sort u_1
inst✝ : DecidableEq ι
α : ι → Sort u_2
β : ι → Sort u_3
f : (i : ι) → α i → β i
g : (i : ι) → α i
i : ι
v : α i
j : ι
h : j = i
⊢ f j (update g i v j) = update (fun k => f k (g k)) i (f i v) j

Next tactic:
subst j
theorem apply_update {ι : Sort*} [DecidableEq ι] {α β : ι → Sort*} (f : ∀ i, α i → β i)
    (g : ∀ i, α i) (i : ι) (v : α i) (j : ι) :
    f j (update g i v j) = update (fun k ↦ f k (g k)) i (f i v) j := by
  by_cases h:j = i
  · subst j
    

Proof state:
case pos
α✝ : Sort u
β✝ : α✝ → Sort v
α' : Sort w
inst✝² : DecidableEq α✝
inst✝¹ : DecidableEq α'
f✝ g✝ : (a : α✝) → β✝ a
a : α✝
b : β✝ a
ι : Sort u_1
inst✝ : DecidableEq ι
α : ι → Sort u_2
β : ι → Sort u_3
f : (i : ι) → α i → β i
g : (i : ι) → α i
i : ι
v : α i
⊢ f i (update g i v i) = update (fun k => f k (g k)) i (f i v) i

Next tactic:
simp
theorem apply_update {ι : Sort*} [DecidableEq ι] {α β : ι → Sort*} (f : ∀ i, α i → β i)
    (g : ∀ i, α i) (i : ι) (v : α i) (j : ι) :
    f j (update g i v j) = update (fun k ↦ f k (g k)) i (f i v) j := by
  by_cases h:j = i
  · subst j
    simp
  · 

Proof state:
case neg
α✝ : Sort u
β✝ : α✝ → Sort v
α' : Sort w
inst✝² : DecidableEq α✝
inst✝¹ : DecidableEq α'
f✝ g✝ : (a : α✝) → β✝ a
a : α✝
b : β✝ a
ι : Sort u_1
inst✝ : DecidableEq ι
α : ι → Sort u_2
β : ι → Sort u_3
f : (i : ι) → α i → β i
g : (i : ι) → α i
i : ι
v : α i
j : ι
h : ¬j = i
⊢ f j (update g i v j) = update (fun k => f k (g k)) i (f i v) j

Next tactic:
simp [h]
theorem apply_update₂ {ι : Sort*} [DecidableEq ι] {α β γ : ι → Sort*} (f : ∀ i, α i → β i → γ i)
    (g : ∀ i, α i) (h : ∀ i, β i) (i : ι) (v : α i) (w : β i) (j : ι) :
    f j (update g i v j) (update h i w j) = update (fun k ↦ f k (g k) (h k)) i (f i v w) j := by
  

Proof state:
α✝ : Sort u
β✝ : α✝ → Sort v
α' : Sort w
inst✝² : DecidableEq α✝
inst✝¹ : DecidableEq α'
f✝ g✝ : (a : α✝) → β✝ a
a : α✝
b : β✝ a
ι : Sort u_1
inst✝ : DecidableEq ι
α : ι → Sort u_2
β : ι → Sort u_3
γ : ι → Sort u_4
f : (i : ι) → α i → β i → γ i
g : (i : ι) → α i
h : (i : ι) → β i
i : ι
v : α i
w : β i
j : ι
⊢ f j (update g i v j) (update h i w j) = update (fun k => f k (g k) (h k)) i (f i v w) j

Next tactic:
by_cases h:j = i
theorem apply_update₂ {ι : Sort*} [DecidableEq ι] {α β γ : ι → Sort*} (f : ∀ i, α i → β i → γ i)
    (g : ∀ i, α i) (h : ∀ i, β i) (i : ι) (v : α i) (w : β i) (j : ι) :
    f j (update g i v j) (update h i w j) = update (fun k ↦ f k (g k) (h k)) i (f i v w) j := by
  by_cases h:j = i
  · 

Proof state:
case pos
α✝ : Sort u
β✝ : α✝ → Sort v
α' : Sort w
inst✝² : DecidableEq α✝
inst✝¹ : DecidableEq α'
f✝ g✝ : (a : α✝) → β✝ a
a : α✝
b : β✝ a
ι : Sort u_1
inst✝ : DecidableEq ι
α : ι → Sort u_2
β : ι → Sort u_3
γ : ι → Sort u_4
f : (i : ι) → α i → β i → γ i
g : (i : ι) → α i
h✝ : (i : ι) → β i
i : ι
v : α i
w : β i
j : ι
h : j = i
⊢ f j (update g i v j) (update h✝ i w j) = update (fun k => f k (g k) (h✝ k)) i (f i v w) j

Next tactic:
subst j
theorem apply_update₂ {ι : Sort*} [DecidableEq ι] {α β γ : ι → Sort*} (f : ∀ i, α i → β i → γ i)
    (g : ∀ i, α i) (h : ∀ i, β i) (i : ι) (v : α i) (w : β i) (j : ι) :
    f j (update g i v j) (update h i w j) = update (fun k ↦ f k (g k) (h k)) i (f i v w) j := by
  by_cases h:j = i
  · subst j
    

Proof state:
case pos
α✝ : Sort u
β✝ : α✝ → Sort v
α' : Sort w
inst✝² : DecidableEq α✝
inst✝¹ : DecidableEq α'
f✝ g✝ : (a : α✝) → β✝ a
a : α✝
b : β✝ a
ι : Sort u_1
inst✝ : DecidableEq ι
α : ι → Sort u_2
β : ι → Sort u_3
γ : ι → Sort u_4
f : (i : ι) → α i → β i → γ i
g : (i : ι) → α i
h : (i : ι) → β i
i : ι
v : α i
w : β i
⊢ f i (update g i v i) (update h i w i) = update (fun k => f k (g k) (h k)) i (f i v w) i

Next tactic:
simp
theorem apply_update₂ {ι : Sort*} [DecidableEq ι] {α β γ : ι → Sort*} (f : ∀ i, α i → β i → γ i)
    (g : ∀ i, α i) (h : ∀ i, β i) (i : ι) (v : α i) (w : β i) (j : ι) :
    f j (update g i v j) (update h i w j) = update (fun k ↦ f k (g k) (h k)) i (f i v w) j := by
  by_cases h:j = i
  · subst j
    simp
  · 

Proof state:
case neg
α✝ : Sort u
β✝ : α✝ → Sort v
α' : Sort w
inst✝² : DecidableEq α✝
inst✝¹ : DecidableEq α'
f✝ g✝ : (a : α✝) → β✝ a
a : α✝
b : β✝ a
ι : Sort u_1
inst✝ : DecidableEq ι
α : ι → Sort u_2
β : ι → Sort u_3
γ : ι → Sort u_4
f : (i : ι) → α i → β i → γ i
g : (i : ι) → α i
h✝ : (i : ι) → β i
i : ι
v : α i
w : β i
j : ι
h : ¬j = i
⊢ f j (update g i v j) (update h✝ i w j) = update (fun k => f k (g k) (h✝ k)) i (f i v w) j

Next tactic:
simp [h]
theorem pred_update (P : ∀ ⦃a⦄, β a → Prop) (f : ∀ a, β a) (a' : α) (v : β a') (a : α) :
    P (update f a' v a) ↔ a = a' ∧ P v ∨ a ≠ a' ∧ P (f a) := by
  

Proof state:
α : Sort u
β : α → Sort v
α' : Sort w
inst✝¹ : DecidableEq α
inst✝ : DecidableEq α'
f✝ g : (a : α) → β a
a✝ : α
b : β a✝
P : ⦃a : α⦄ → β a → Prop
f : (a : α) → β a
a' : α
v : β a'
a : α
⊢ P (update f a' v a) ↔ a = a' ∧ P v ∨ a ≠ a' ∧ P (f a)

Next tactic:
rw [apply_update P, update_apply, ite_prop_iff_or]
theorem update_comm {α} [DecidableEq α] {β : α → Sort*} {a b : α} (h : a ≠ b) (v : β a) (w : β b)
    (f : ∀ a, β a) : update (update f a v) b w = update (update f b w) a v := by
  

Proof state:
α✝ : Sort u
β✝ : α✝ → Sort v
α' : Sort w
inst✝² : DecidableEq α✝
inst✝¹ : DecidableEq α'
f✝ g : (a : α✝) → β✝ a
a✝ : α✝
b✝ : β✝ a✝
α : Sort u_2
inst✝ : DecidableEq α
β : α → Sort u_1
a b : α
h : a ≠ b
v : β a
w : β b
f : (a : α) → β a
⊢ update (update f a v) b w = update (update f b w) a v

Next tactic:
funext c
theorem update_comm {α} [DecidableEq α] {β : α → Sort*} {a b : α} (h : a ≠ b) (v : β a) (w : β b)
    (f : ∀ a, β a) : update (update f a v) b w = update (update f b w) a v := by
  funext c
  

Proof state:
case h
α✝ : Sort u
β✝ : α✝ → Sort v
α' : Sort w
inst✝² : DecidableEq α✝
inst✝¹ : DecidableEq α'
f✝ g : (a : α✝) → β✝ a
a✝ : α✝
b✝ : β✝ a✝
α : Sort u_2
inst✝ : DecidableEq α
β : α → Sort u_1
a b : α
h : a ≠ b
v : β a
w : β b
f : (a : α) → β a
c : α
⊢ update (update f a v) b w c = update (update f b w) a v c

Next tactic:
simp only [update]
theorem update_comm {α} [DecidableEq α] {β : α → Sort*} {a b : α} (h : a ≠ b) (v : β a) (w : β b)
    (f : ∀ a, β a) : update (update f a v) b w = update (update f b w) a v := by
  funext c
  simp only [update]
  

Proof state:
case h
α✝ : Sort u
β✝ : α✝ → Sort v
α' : Sort w
inst✝² : DecidableEq α✝
inst✝¹ : DecidableEq α'
f✝ g : (a : α✝) → β✝ a
a✝ : α✝
b✝ : β✝ a✝
α : Sort u_2
inst✝ : DecidableEq α
β : α → Sort u_1
a b : α
h : a ≠ b
v : β a
w : β b
f : (a : α) → β a
c : α
⊢ (if h : c = b then (_ : b = c) ▸ w else if h : c = a then (_ : a = c) ▸ v else f c) =
    if h : c = a then (_ : a = c) ▸ v else if h : c = b then (_ : b = c) ▸ w else f c

Next tactic:
by_cases h₁ : c = b
theorem update_comm {α} [DecidableEq α] {β : α → Sort*} {a b : α} (h : a ≠ b) (v : β a) (w : β b)
    (f : ∀ a, β a) : update (update f a v) b w = update (update f b w) a v := by
  funext c
  simp only [update]
  by_cases h₁ : c = b <;> 

Proof state:
case pos
α✝ : Sort u
β✝ : α✝ → Sort v
α' : Sort w
inst✝² : DecidableEq α✝
inst✝¹ : DecidableEq α'
f✝ g : (a : α✝) → β✝ a
a✝ : α✝
b✝ : β✝ a✝
α : Sort u_2
inst✝ : DecidableEq α
β : α → Sort u_1
a b : α
h : a ≠ b
v : β a
w : β b
f : (a : α) → β a
c : α
h₁ : c = b
⊢ (if h : c = b then (_ : b = c) ▸ w else if h : c = a then (_ : a = c) ▸ v else f c) =
    if h : c = a then (_ : a = c) ▸ v else if h : c = b then (_ : b = c) ▸ w else f c

Next tactic:
by_cases h₂ : c = a
theorem update_comm {α} [DecidableEq α] {β : α → Sort*} {a b : α} (h : a ≠ b) (v : β a) (w : β b)
    (f : ∀ a, β a) : update (update f a v) b w = update (update f b w) a v := by
  funext c
  simp only [update]
  by_cases h₁ : c = b <;> 

Proof state:
case neg
α✝ : Sort u
β✝ : α✝ → Sort v
α' : Sort w
inst✝² : DecidableEq α✝
inst✝¹ : DecidableEq α'
f✝ g : (a : α✝) → β✝ a
a✝ : α✝
b✝ : β✝ a✝
α : Sort u_2
inst✝ : DecidableEq α
β : α → Sort u_1
a b : α
h : a ≠ b
v : β a
w : β b
f : (a : α) → β a
c : α
h₁ : ¬c = b
⊢ (if h : c = b then (_ : b = c) ▸ w else if h : c = a then (_ : a = c) ▸ v else f c) =
    if h : c = a then (_ : a = c) ▸ v else if h : c = b then (_ : b = c) ▸ w else f c

Next tactic:
by_cases h₂ : c = a