-- Mathlib/Data/Sigma/Basic.lean
theorem Sigma.curry_update {γ : ∀ a, β a → Type*} [DecidableEq α] [∀ a, DecidableEq (β a)]
    (i : Σ a, β a) (f : (i : Σ a, β a) → γ i.1 i.2) (x : γ i.1 i.2) :
    Sigma.curry (Function.update f i x) =
      Function.update (Sigma.curry f) i.1 (Function.update (Sigma.curry f i.1) i.2 x)

Proof state:
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
jb : β ia
hb : ib ≠ jb
⊢ ⟨ia, jb⟩ = ⟨ia, ib⟩ → jb = ib

Tactic:
rintro h

Result:
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
jb : β ia
hb : ib ≠ jb
h : ⟨ia, jb⟩ = ⟨ia, ib⟩
⊢ jb = ib

Proof state:
case mk.h.h.inr.h
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
ja : α
jb : β ja
ha : ia ≠ ja
⊢ ja ≠ ⟨ia, ib⟩.fst

Tactic:
exact ha.symm

Result:
no goals

Proof state:
case mk.h.h
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
ja : α
jb : β ja
⊢ update f ⟨ia, ib⟩ x ⟨ja, jb⟩ =
    update (fun x y => f ⟨x, y⟩) ⟨ia, ib⟩.fst (update (fun y => f ⟨⟨ia, ib⟩.fst, y⟩) ⟨ia, ib⟩.snd x) ja jb

Tactic:
obtain rfl | ha := eq_or_ne ia ja

Result:
case mk.h.h.inl
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
jb : β ia
⊢ update f ⟨ia, ib⟩ x ⟨ia, jb⟩ =
    update (fun x y => f ⟨x, y⟩) ⟨ia, ib⟩.fst (update (fun y => f ⟨⟨ia, ib⟩.fst, y⟩) ⟨ia, ib⟩.snd x) ia jb

case mk.h.h.inr
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
ja : α
jb : β ja
ha : ia ≠ ja
⊢ update f ⟨ia, ib⟩ x ⟨ja, jb⟩ =
    update (fun x y => f ⟨x, y⟩) ⟨ia, ib⟩.fst (update (fun y => f ⟨⟨ia, ib⟩.fst, y⟩) ⟨ia, ib⟩.snd x) ja jb

Proof state:
case mk.h.h.inl.inr
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
jb : β ia
hb : ib ≠ jb
⊢ update f ⟨ia, ib⟩ x ⟨ia, jb⟩ =
    update (fun x y => f ⟨x, y⟩) ⟨ia, ib⟩.fst (update (fun y => f ⟨⟨ia, ib⟩.fst, y⟩) ⟨ia, ib⟩.snd x) ia jb

Tactic:
simp only [update_self]

Result:
case mk.h.h.inl.inr
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
jb : β ia
hb : ib ≠ jb
⊢ update f ⟨ia, ib⟩ x ⟨ia, jb⟩ = update (fun y => f ⟨ia, y⟩) ib x jb

Proof state:
case mk.h.h.inl.inr
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
jb : β ia
hb : ib ≠ jb
⊢ update f ⟨ia, ib⟩ x ⟨ia, jb⟩ = update (fun y => f ⟨ia, y⟩) ib x jb

Tactic:
rw [Function.update_of_ne (mt _ hb.symm), Function.update_of_ne hb.symm]

Result:
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
jb : β ia
hb : ib ≠ jb
⊢ ⟨ia, jb⟩ = ⟨ia, ib⟩ → jb = ib

Proof state:
case mk.h.h
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
ja : α
jb : β ja
⊢ curry (update f ⟨ia, ib⟩ x) ja jb = update (curry f) ⟨ia, ib⟩.fst (update (curry f ⟨ia, ib⟩.fst) ⟨ia, ib⟩.snd x) ja jb

Tactic:
unfold Sigma.curry

Result:
case mk.h.h
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
ja : α
jb : β ja
⊢ update f ⟨ia, ib⟩ x ⟨ja, jb⟩ =
    update (fun x y => f ⟨x, y⟩) ⟨ia, ib⟩.fst (update (fun y => f ⟨⟨ia, ib⟩.fst, y⟩) ⟨ia, ib⟩.snd x) ja jb

Proof state:
case mk.h.h.inl.inl
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
⊢ update f ⟨ia, ib⟩ x ⟨ia, ib⟩ =
    update (fun x y => f ⟨x, y⟩) ⟨ia, ib⟩.fst (update (fun y => f ⟨⟨ia, ib⟩.fst, y⟩) ⟨ia, ib⟩.snd x) ia ib

Tactic:
simp

Result:
no goals

Proof state:
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
i : (a : α) × β a
f : (i : (a : α) × β a) → γ i.fst i.snd
x : γ i.fst i.snd
⊢ curry (update f i x) = update (curry f) i.fst (update (curry f i.fst) i.snd x)

Tactic:
obtain ⟨ia, ib⟩ := i

Result:
case mk
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
⊢ curry (update f ⟨ia, ib⟩ x) = update (curry f) ⟨ia, ib⟩.fst (update (curry f ⟨ia, ib⟩.fst) ⟨ia, ib⟩.snd x)

Proof state:
case mk
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
⊢ curry (update f ⟨ia, ib⟩ x) = update (curry f) ⟨ia, ib⟩.fst (update (curry f ⟨ia, ib⟩.fst) ⟨ia, ib⟩.snd x)

Tactic:
ext ja jb

Result:
case mk.h.h
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
ja : α
jb : β ja
⊢ curry (update f ⟨ia, ib⟩ x) ja jb = update (curry f) ⟨ia, ib⟩.fst (update (curry f ⟨ia, ib⟩.fst) ⟨ia, ib⟩.snd x) ja jb

Proof state:
case mk.h.h.inl
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
jb : β ia
⊢ update f ⟨ia, ib⟩ x ⟨ia, jb⟩ =
    update (fun x y => f ⟨x, y⟩) ⟨ia, ib⟩.fst (update (fun y => f ⟨⟨ia, ib⟩.fst, y⟩) ⟨ia, ib⟩.snd x) ia jb

Tactic:
obtain rfl | hb := eq_or_ne ib jb

Result:
case mk.h.h.inl.inl
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
⊢ update f ⟨ia, ib⟩ x ⟨ia, ib⟩ =
    update (fun x y => f ⟨x, y⟩) ⟨ia, ib⟩.fst (update (fun y => f ⟨⟨ia, ib⟩.fst, y⟩) ⟨ia, ib⟩.snd x) ia ib

case mk.h.h.inl.inr
α : Type u_1
β : α → Type u_4
γ : (a : α) → β a → Type u_7
inst✝¹ : DecidableEq α
inst✝ : (a : α) → DecidableEq (β a)
f : (i : (a : α) × β a) → γ i.fst i.snd
ia : α
ib : β ia
x : γ ⟨ia, ib⟩.fst ⟨ia, ib⟩.snd
jb : β ia
hb : ib ≠ jb
⊢ update f ⟨ia, ib⟩ x ⟨ia, jb⟩ =
    update (fun x y => f ⟨x, y⟩) ⟨ia, ib⟩.fst (update (fun y => f ⟨⟨ia, ib⟩.fst, y⟩) ⟨ia, ib⟩.snd x) ia jb