[System] You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Data.Sum.Basic).

[User]
Prove the following theorem. The retrieved context below may help.

```lean
lemma elim_update_left {γ : Sort*} [DecidableEq α] [DecidableEq β]
    (f : α → γ) (g : β → γ) (a : α) (x : γ) :
    Sum.elim (update f a x) g = update (Sum.elim f g) (.inl a) x
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Data.Sum.Basic.not_isLeft_and_isRight (L24-L27)
lemma not_isLeft_and_isRight {x : α ⊕ β} : ¬(x.isLeft ∧ x.isRight) := by simp
namespace Sum
```

-- snippet 2
```lean
-- Mathlib.Data.Sum.Basic.elim_swap (L29-L33)
theorem elim_swap {α β γ : Type*} {f : α → γ} {g : β → γ} :
    Sum.elim f g ∘ Sum.swap = Sum.elim g f := by
grind

-- Lean has removed the `@[simp]` attribute on these. For now Mathlib adds it back.
```

-- snippet 3
```lean
-- Mathlib.Data.Sum.Basic.exists_sum (L36-L40)
theorem exists_sum {γ : α ⊕ β → Sort*} (p : (∀ ab, γ ab) → Prop) :
    (∃ fab, p fab) ↔ (∃ fa fb, p (Sum.rec fa fb)) := by
rw [← not_forall_not, forall_sum]
  simp
```

-- snippet 4
```lean
-- Mathlib.Data.Sum.Basic.inl_injective (L41-L42)
theorem inl_injective : Function.Injective (inl : α → α ⊕ β) := fun _ _ ↦ inl.inj
```

-- snippet 5
```lean
-- Mathlib.Data.Sum.Basic.inr_injective (L43-L44)
theorem inr_injective : Function.Injective (inr : β → α ⊕ β) := fun _ _ ↦ inr.inj
```

-- snippet 6
```lean
-- Mathlib.Data.Sum.Basic.sum_rec_congr (L45-L52)
theorem sum_rec_congr (P : α ⊕ β → Sort*) (f : ∀ i, P (inl i)) (g : ∀ i, P (inr i))
    {x y : α ⊕ β} (h : x = y) :
    @Sum.rec _ _ _ f g x = cast (congr_arg P h.symm) (@Sum.rec _ _ _ f g y) := by cases h; rfl
section get

variable {x : α ⊕ β}
```

-- snippet 7
```lean
-- Mathlib.Data.Sum.Basic.eq_left_iff_getLeft_eq (L53-L55)
theorem eq_left_iff_getLeft_eq {a : α} : x = inl a ↔ ∃ h, x.getLeft h = a := by
cases x <;> simp
```

-- snippet 8
```lean
-- Mathlib.Data.Sum.Basic.eq_right_iff_getRight_eq (L56-L58)
theorem eq_right_iff_getRight_eq {b : β} : x = inr b ↔ ∃ h, x.getRight h = b := by
cases x <;> simp
```

-- snippet 9
```lean
-- Mathlib.Data.Sum.Basic.getLeft_eq_getLeft (L59-L61)
theorem getLeft_eq_getLeft? (h₁ : x.isLeft) (h₂ : x.getLeft?.isSome) :
    x.getLeft h₁ = x.getLeft?.get h₂ := by grind
```

-- snippet 10
```lean
-- Mathlib.Data.Sum.Basic.getRight_eq_getRight (L62-L64)
theorem getRight_eq_getRight? (h₁ : x.isRight) (h₂ : x.getRight?.isSome) :
    x.getRight h₁ = x.getRight?.get h₂ := by grind
```

-- snippet 11
```lean
-- Mathlib.Data.Sum.Basic.update_elim_inl (L76-L79)
theorem update_elim_inl [DecidableEq α] [DecidableEq (α ⊕ β)] {f : α → γ} {g : β → γ} {i : α}
    {x : γ} : update (Sum.elim f g) (inl i) x = Sum.elim (update f i x) g :=
update_eq_iff.2 ⟨by simp, by simp +contextual⟩
```

-- snippet 12
```lean
-- Mathlib.Data.Sum.Basic.update_elim_inr (L81-L84)
theorem update_elim_inr [DecidableEq β] [DecidableEq (α ⊕ β)] {f : α → γ} {g : β → γ} {i : β}
    {x : γ} : update (Sum.elim f g) (inr i) x = Sum.elim f (update g i x) :=
update_eq_iff.2 ⟨by simp, by simp +contextual⟩
```

-- snippet 13
```lean
-- Mathlib.Data.Sum.Basic.update_inl_comp_inl (L86-L89)
theorem update_inl_comp_inl [DecidableEq α] [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i : α}
    {x : γ} : update f (inl i) x ∘ inl = update (f ∘ inl) i x :=
update_comp_eq_of_injective _ inl_injective _ _
```

-- snippet 14
```lean
-- Mathlib.Data.Sum.Basic.update_inl_apply_inl (L91-L94)
theorem update_inl_apply_inl [DecidableEq α] [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i j : α}
    {x : γ} : update f (inl i) x (inl j) = update (f ∘ inl) i x j := by
grind
```

-- snippet 15
```lean
-- Mathlib.Data.Sum.Basic.update_inl_comp_inr (L96-L99)
theorem update_inl_comp_inr [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i : α} {x : γ} :
    update f (inl i) x ∘ inr = f ∘ inr :=
(update_comp_eq_of_forall_ne _ _) fun _ ↦ inr_ne_inl
```

-- snippet 16
```lean
-- Mathlib.Data.Sum.Basic.update_inl_apply_inr (L100-L103)
theorem update_inl_apply_inr [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i : α} {j : β} {x : γ} :
    update f (inl i) x (inr j) = f (inr j) :=
Function.update_of_ne inr_ne_inl ..
```

-- snippet 17
```lean
-- Mathlib.Data.Sum.Basic.update_inr_comp_inl (L105-L108)
theorem update_inr_comp_inl [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i : β} {x : γ} :
    update f (inr i) x ∘ inl = f ∘ inl :=
(update_comp_eq_of_forall_ne _ _) fun _ ↦ inl_ne_inr
```

-- snippet 18
```lean
-- Mathlib.Data.Sum.Basic.update_inr_apply_inl (L109-L112)
theorem update_inr_apply_inl [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i : α} {j : β} {x : γ} :
    update f (inr j) x (inl i) = f (inl i) :=
Function.update_of_ne inl_ne_inr ..
```

-- snippet 19
```lean
-- Mathlib.Data.Sum.Basic.update_inr_comp_inr (L114-L117)
theorem update_inr_comp_inr [DecidableEq β] [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i : β}
    {x : γ} : update f (inr i) x ∘ inr = update (f ∘ inr) i x :=
update_comp_eq_of_injective _ inr_injective _ _
```

-- snippet 20
```lean
-- Mathlib.Data.Sum.Basic.update_inr_apply_inr (L119-L122)
theorem update_inr_apply_inr [DecidableEq β] [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i j : β}
    {x : γ} : update f (inr i) x (inr j) = update (f ∘ inr) i x j := by
rw [← update_inr_comp_inr, Function.comp_apply]
```

-- snippet 21
```lean
-- Mathlib.Data.Sum.Basic.update_inl_apply_inl' (L124-L128)
theorem update_inl_apply_inl' {γ : α ⊕ β → Type*} [DecidableEq α] [DecidableEq (α ⊕ β)]
    {f : (i : α ⊕ β) → γ i} {i : α} {x : γ (.inl i)} (j : α) :
    update f (.inl i) x (Sum.inl j) = update (fun j ↦ f (.inl j)) i x j :=
Function.update_apply_of_injective f Sum.inl_injective i x j
```

-- snippet 22
```lean
-- Mathlib.Data.Sum.Basic.update_inr_apply_inr' (L130-L134)
theorem update_inr_apply_inr' {γ : α ⊕ β → Type*} [DecidableEq β] [DecidableEq (α ⊕ β)]
    {f : (i : α ⊕ β) → γ i} {i : β} {x : γ (.inr i)} (j : β) :
    update f (.inr i) x (Sum.inr j) = update (fun j ↦ f (.inr j)) i x j :=
Function.update_apply_of_injective f Sum.inr_injective i x j
```

-- snippet 23
```lean
-- Mathlib.Data.Sum.Basic.rec_update_left (L136-L142)
lemma rec_update_left {γ : α ⊕ β → Sort*} [DecidableEq α] [DecidableEq β]
    (f : ∀ a, γ (.inl a)) (g : ∀ b, γ (.inr b)) (a : α) (x : γ (.inl a)) :
    Sum.rec (update f a x) g = update (Sum.rec f g) (.inl a) x :=
Function.rec_update Sum.inl_injective (Sum.rec · g) (fun _ _ => rfl) (fun
    | _, _, .inl _, h => (h _ rfl).elim
    | _, _, .inr _, _ => rfl) _ _ _
```

-- snippet 24
```lean
-- Mathlib.Data.Sum.Basic.rec_update_right (L144-L150)
lemma rec_update_right {γ : α ⊕ β → Sort*} [DecidableEq α] [DecidableEq β]
    (f : ∀ a, γ (.inl a)) (g : ∀ b, γ (.inr b)) (b : β) (x : γ (.inr b)) :
    Sum.rec f (update g b x) = update (Sum.rec f g) (.inr b) x :=
Function.rec_update Sum.inr_injective (Sum.rec f) (fun _ _ => rfl) (fun
    | _, _, .inr _, h => (h _ rfl).elim
    | _, _, .inl _, _ => rfl) _ _ _
```

-- snippet 25
```lean
-- Mathlib.Data.Sum.Basic.elim_update_right (L158-L162)
lemma elim_update_right {γ : Sort*} [DecidableEq α] [DecidableEq β]
    (f : α → γ) (g : β → γ) (b : β) (x : γ) :
    Sum.elim f (update g b x) = update (Sum.elim f g) (.inr b) x :=
rec_update_right _ _ _ _
```

-- snippet 26
```lean
-- Mathlib.Data.Sum.Order.swap_lt_swap_iff (L263-L278)
theorem swap_lt_swap_iff [LT α] [LT β] {a b : α ⊕ β} : a.swap < b.swap ↔ a < b :=
liftRel_swap_iff

end Disjoint

/-! ### Linear sum of two orders -/

namespace Lex

/-- The linear sum of two orders -/
notation:30 α " ⊕ₗ " β:29 => _root_.Lex (α ⊕ β)

--TODO: Can we make `inlₗ`, `inrₗ` `local notation`?
/-- Lexicographical `Sum.inl`. Only used for pattern matching. -/
```

-- snippet 27
```lean
-- Mathlib.Data.Sum.Lattice.inrLatticeHom (L103-L109)
def inrLatticeHom : LatticeHom β (α ⊕ₗ β) where
  toFun := inrₗ
map_sup' _ _ := rfl
  map_inf' _ _ := rfl

end Lattice
```

-- snippet 28
```lean
-- Mathlib.Data.Sum.Interval.Iic_inl (L298-L298)
theorem Iic_inl : Iic (inl a : α ⊕ β) = (Iic a).map Embedding.inl := rfl
```

-- snippet 29
```lean
-- Mathlib.Data.Sum.Order.not_inr_le_inl (L149-L151)
theorem not_inr_le_inl [LE α] [LE β] {a : α} {b : β} : ¬inr b ≤ inl a :=
not_liftRel_inr_inl
```

-- snippet 30
```lean
-- Mathlib.Data.Sum.Order.inl_strictMono (L177-L178)
theorem inl_strictMono : StrictMono (inl : α → α ⊕ β) := fun _ _ => LiftRel.inl
```

-- snippet 31
```lean
-- Mathlib.Data.Sum.Order.toLexRelIsoLT (L337-L342)
def toLexRelIsoLT [LT α] [LT β] :
    Sum.Lex (· < · : α → α → Prop) (· < · : β → β → Prop) ≃r (· < · : α ⊕ₗ β → _ → _) where
  toFun := toLex
invFun := ofLex
  map_rel_iff' := .rfl
```

-- snippet 32
```lean
-- Mathlib.Data.Sum.Interval.Ici_inl (L316-L316)
theorem Ici_inl : Ici (inl a : α ⊕ β) = (Ici a).map Embedding.inl := rfl
```

-- snippet 33
```lean
-- Mathlib.Data.Sum.Interval.sumLift₂_nonempty (L88-L93)
theorem sumLift₂_nonempty :
    (sumLift₂ f g a b).Nonempty ↔
      (∃ a₁ b₁, a = inl a₁ ∧ b = inl b₁ ∧ (f a₁ b₁).Nonempty) ∨
        ∃ a₂ b₂, a = inr a₂ ∧ b = inr b₂ ∧ (g a₂ b₂).Nonempty := by
simp only [nonempty_iff_ne_empty, Ne, sumLift₂_eq_empty, not_and_or, not_forall, exists_prop]
```

-- snippet 34
```lean
-- Mathlib.Data.Sum.Interval.Ioi_inl (L318-L318)
theorem Ioi_inl : Ioi (inl a : α ⊕ β) = (Ioi a).map Embedding.inl := rfl
```

-- snippet 35
```lean
-- Mathlib.Data.Sum.Order.noMaxOrder_iff (L221-L232)
theorem noMaxOrder_iff [LT α] [LT β] : NoMaxOrder (α ⊕ β) ↔ NoMaxOrder α ∧ NoMaxOrder β :=
⟨fun _ =>
    ⟨⟨fun a => by
        obtain ⟨b | b, h⟩ := exists_gt (inl a : α ⊕ β)
        · exact ⟨b, inl_lt_inl_iff.1 h⟩
        · exact (not_inl_lt_inr h).elim⟩,
      ⟨fun a => by
        obtain ⟨b | b, h⟩ := exists_gt (inr a : α ⊕ β)
        · exact (not_inr_lt_inl h).elim
        · exact ⟨b, inr_lt_inr_iff.1 h⟩⟩⟩,
    fun h => @Sum.noMaxOrder _ _ _ _ h.1 h.2⟩
```

-- snippet 36
```lean
-- Mathlib.Data.Sum.Order.not_inl_lt_inr (L145-L147)
theorem not_inl_lt_inr [LT α] [LT β] {a : α} {b : β} : ¬inl b < inr a :=
not_liftRel_inl_inr
```

-- snippet 37
```lean
-- Mathlib.Data.Sum.Interval.Iio_inl (L300-L300)
theorem Iio_inl : Iio (inl a : α ⊕ β) = (Iio a).map Embedding.inl := rfl
```

-- snippet 38
```lean
-- Mathlib.Data.Sum.Order.inl_le_inr (L324-L326)
theorem inl_le_inr [LE α] [LE β] (a : α) (b : β) : toLex (inl a) ≤ toLex (inr b) :=
Lex.sep _ _
```

-- snippet 39
```lean
-- Mathlib.Data.Sum.Order.le_def (L118-L120)
theorem le_def [LE α] [LE β] {a b : α ⊕ β} : a ≤ b ↔ LiftRel (· ≤ ·) (· ≤ ·) a b :=
Iff.rfl
```

-- snippet 40
```lean
-- Mathlib.Data.Sum.Interval.Ici_inr (L317-L317)
theorem Ici_inr : Ici (inr b : α ⊕ β) = (Ici b).map Embedding.inr := rfl
```

-- snippet 41
```lean
-- Mathlib.Data.Sum.Interval.inr_mem_sumLift₂ (L67-L73)
theorem inr_mem_sumLift₂ {c₂ : γ₂} :
    inr c₂ ∈ sumLift₂ f g a b ↔ ∃ a₂ b₂, a = inr a₂ ∧ b = inr b₂ ∧ c₂ ∈ g a₂ b₂ := by
rw [mem_sumLift₂, or_iff_right]
  · simp only [inr.injEq, exists_and_left, exists_eq_left']
  rintro ⟨_, _, c₂, _, _, h, _⟩
  exact inr_ne_inl h
```

-- snippet 42
```lean
-- Mathlib.Data.Sum.Order.inr_le_inr_iff (L129-L131)
theorem inr_le_inr_iff [LE α] [LE β] {a b : β} : (inr a : α ⊕ β) ≤ inr b ↔ a ≤ b :=
liftRel_inr_inr
```

-- snippet 43
```lean
-- Mathlib.Data.Sum.Order.not_inr_lt_inl (L153-L159)
theorem not_inr_lt_inl [LT α] [LT β] {a : α} {b : β} : ¬inr b < inl a :=
not_liftRel_inr_inl

section Preorder

variable [Preorder α] [Preorder β]
```

-- snippet 44
```lean
-- Mathlib.Data.Sum.Order.inl_mono (L173-L174)
theorem inl_mono : Monotone (inl : α → α ⊕ β) := fun _ _ => LiftRel.inl
```

-- snippet 45
```lean
-- Mathlib.Data.Sum.Interval.Ioo_inr_inl (L270-L272)
theorem Ioo_inr_inl : Ioo (inr b₁) (inl a₂) = ∅ :=
rfl
```

-- snippet 46
```lean
-- Mathlib.Data.Sum.Order.noMinOrder_iff (L208-L219)
theorem noMinOrder_iff [LT α] [LT β] : NoMinOrder (α ⊕ β) ↔ NoMinOrder α ∧ NoMinOrder β :=
⟨fun _ =>
    ⟨⟨fun a => by
        obtain ⟨b | b, h⟩ := exists_lt (inl a : α ⊕ β)
        · exact ⟨b, inl_lt_inl_iff.1 h⟩
        · exact (not_inr_lt_inl h).elim⟩,
      ⟨fun a => by
        obtain ⟨b | b, h⟩ := exists_lt (inr a : α ⊕ β)
        · exact (not_inl_lt_inr h).elim
        · exact ⟨b, inr_lt_inr_iff.1 h⟩⟩⟩,
    fun h => @Sum.noMinOrder _ _ _ _ h.1 h.2⟩
```

-- snippet 47
```lean
-- Mathlib.Data.Sum.Order.inr_lt_inr_iff (L137-L139)
theorem inr_lt_inr_iff [LT α] [LT β] {a b : β} : (inr a : α ⊕ β) < inr b ↔ a < b :=
liftRel_inr_inr
```

-- snippet 48
```lean
-- Mathlib.Data.Sum.Interval.inl_mem_sumLexLift (L160-L165)
lemma inl_mem_sumLexLift {c₁ : γ₁} :
    inl c₁ ∈ sumLexLift f₁ f₂ g₁ g₂ a b ↔
      (∃ a₁ b₁, a = inl a₁ ∧ b = inl b₁ ∧ c₁ ∈ f₁ a₁ b₁) ∨
        ∃ a₁ b₂, a = inl a₁ ∧ b = inr b₂ ∧ c₁ ∈ g₁ a₁ b₂ := by
simp [mem_sumLexLift]
```

-- snippet 49
```lean
-- Mathlib.Data.Sum.Interval.mem_sumLift₂ (L44-L59)
theorem mem_sumLift₂ :
    c ∈ sumLift₂ f g a b ↔
      (∃ a₁ b₁ c₁, a = inl a₁ ∧ b = inl b₁ ∧ c = inl c₁ ∧ c₁ ∈ f a₁ b₁) ∨
        ∃ a₂ b₂ c₂, a = inr a₂ ∧ b = inr b₂ ∧ c = inr c₂ ∧ c₂ ∈ g a₂ b₂ := by
constructor
  · rcases a with a | a <;> rcases b with b | b
    · rw [sumLift₂, mem_map]
      rintro ⟨c, hc, rfl⟩
      exact Or.inl ⟨a, b, c, rfl, rfl, rfl, hc⟩
    · refine fun h ↦ (notMem_empty _ h).elim
    · refine fun h ↦ (notMem_empty _ h).elim
    · rw [sumLift₂, mem_map]
      rintro ⟨c, hc, rfl⟩
      exact Or.inr ⟨a, b, c, rfl, rfl, rfl, hc⟩
  · rintro (⟨a, b, c, rfl, rfl, rfl, h⟩ | ⟨a, b, c, rfl, rfl, rfl, h⟩) <;> exact mem_map_of_mem _ h
```

-- snippet 50
```lean
-- Mathlib.Data.Sum.Order.inl_lt_inl_iff (L133-L135)
theorem inl_lt_inl_iff [LT α] [LT β] {a b : α} : (inl a : α ⊕ β) < inl b ↔ a < b :=
liftRel_inl_inl
```

-- snippet 51
```lean
-- Mathlib.Data.Sum.Interval.Icc_inr_inl (L258-L260)
theorem Icc_inr_inl : Icc (inr b₁) (inl a₂) = ∅ :=
rfl
```

-- snippet 52
```lean
-- Mathlib.Data.Sum.Order.toLexRelIsoLE (L352-L357)
def toLexRelIsoLE [LE α] [LE β] :
    Sum.Lex (· ≤ · : α → α → Prop) (· ≤ · : β → β → Prop) ≃r (· ≤ · : α ⊕ₗ β → _ → _) where
  toFun := toLex
invFun := ofLex
  map_rel_iff' := .rfl
```

-- snippet 53
```lean
-- Mathlib.Data.Sum.Interval.sumLift₂_eq_empty (L74-L87)
theorem sumLift₂_eq_empty :
    sumLift₂ f g a b = ∅ ↔
      (∀ a₁ b₁, a = inl a₁ → b = inl b₁ → f a₁ b₁ = ∅) ∧
        ∀ a₂ b₂, a = inr a₂ → b = inr b₂ → g a₂ b₂ = ∅ := by
refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩
  · constructor <;>
    · rintro a b rfl rfl
      exact map_eq_empty.1 h
  cases a <;> cases b
  · exact map_eq_empty.2 (h.1 _ _ rfl rfl)
  · rfl
  · rfl
  · exact map_eq_empty.2 (h.2 _ _ rfl rfl)
```

-- snippet 54
```lean
-- Mathlib.Data.Sum.Interval.sumLexLift_inr_inl (L125-L126)
lemma sumLexLift_inr_inl (a : α₂) (b : β₁) : sumLexLift f₁ f₂ g₁ g₂ (inr a) (inl b) = ∅ := rfl
```

-- snippet 55
```lean
-- Mathlib.Data.Sum.Interval.Ico_inr_inr (L276-L278)
theorem Ico_inr_inr : Ico (inr b₁ : α ⊕ β) (inr b₂) = (Ico b₁ b₂).map Embedding.inr :=
rfl
```

-- snippet 56
```lean
-- Mathlib.Data.Sum.Interval.Ioc_inr_inl (L266-L268)
theorem Ioc_inr_inl : Ioc (inr b₁) (inl a₂) = ∅ :=
rfl
```

-- snippet 57
```lean
-- Mathlib.Data.Sum.Order.noMinOrder (L187-L196)
instance noMinOrder [LT α] [LT β] [NoMinOrder α] [NoMinOrder β] : NoMinOrder (α ⊕ β) :=
⟨fun a =>
    match a with
    | inl a =>
      let ⟨b, h⟩ := exists_lt a
      ⟨inl b, inl_lt_inl_iff.2 h⟩
    | inr a =>
      let ⟨b, h⟩ := exists_lt a
      ⟨inr b, inr_lt_inr_iff.2 h⟩⟩
```

-- snippet 58
```lean
-- Mathlib.Data.Sum.Order.denselyOrdered_iff (L245-L257)
theorem denselyOrdered_iff [LT α] [LT β] :
    DenselyOrdered (α ⊕ β) ↔ DenselyOrdered α ∧ DenselyOrdered β :=
⟨fun _ =>
    ⟨⟨fun a b h => by
        obtain ⟨c | c, ha, hb⟩ := @exists_between (α ⊕ β) _ _ _ _ (inl_lt_inl_iff.2 h)
        · exact ⟨c, inl_lt_inl_iff.1 ha, inl_lt_inl_iff.1 hb⟩
        · exact (not_inl_lt_inr ha).elim⟩,
      ⟨fun a b h => by
        obtain ⟨c | c, ha, hb⟩ := @exists_between (α ⊕ β) _ _ _ _ (inr_lt_inr_iff.2 h)
        · exact (not_inl_lt_inr hb).elim
        · exact ⟨c, inr_lt_inr_iff.1 ha, inr_lt_inr_iff.1 hb⟩⟩⟩,
    fun h => @Sum.denselyOrdered _ _ _ _ h.1 h.2⟩
```

-- snippet 59
```lean
-- Mathlib.Data.Sum.Interval.sumLexLift_nonempty (L193-L216)
lemma sumLexLift_nonempty :
    (sumLexLift f₁ f₂ g₁ g₂ a b).Nonempty ↔
      (∃ a₁ b₁, a = inl a₁ ∧ b = inl b₁ ∧ (f₁ a₁ b₁).Nonempty) ∨
        (∃ a₁ b₂, a = inl a₁ ∧ b = inr b₂ ∧ ((g₁ a₁ b₂).Nonempty ∨ (g₂ a₁ b₂).Nonempty)) ∨
          ∃ a₂ b₂, a = inr a₂ ∧ b = inr b₂ ∧ (f₂ a₂ b₂).Nonempty := by
simp only [nonempty_iff_ne_empty, Ne, sumLexLift_eq_empty, not_and_or, exists_prop, not_forall]

end SumLexLift
end Finset

open Finset

namespace Sum

variable {α β : Type*}

/-! ### Disjoint sum of orders -/

section Disjoint

section LocallyFiniteOrder
variable [Preorder α] [Preorder β] [LocallyFiniteOrder α] [LocallyFiniteOrder β]
```

-- snippet 60
```lean
-- Mathlib.Data.Sum.Order.inl_lt_inr (L327-L329)
theorem inl_lt_inr [LT α] [LT β] (a : α) (b : β) : toLex (inl a) < toLex (inr b) :=
Lex.sep _ _
```

-- snippet 61
```lean
-- Mathlib.Data.Sum.Order.instPreorderSum (L160-L172)
instance instPreorderSum : Preorder (α ⊕ β) :=
{ instLESum, instLTSum with
    le_refl := fun _ => LiftRel.refl _ _ _,
    le_trans := fun _ _ _ => LiftRel.trans _ _,
    lt_iff_le_not_ge := fun a b => by
      refine ⟨fun hab => ⟨hab.mono (fun _ _ => le_of_lt) fun _ _ => le_of_lt, ?_⟩, ?_⟩
      · rintro (⟨hba⟩ | ⟨hba⟩)
        · exact hba.not_gt (inl_lt_inl_iff.1 hab)
        · exact hba.not_gt (inr_lt_inr_iff.1 hab)
      · rintro ⟨⟨hab⟩ | ⟨hab⟩, hba⟩
        · exact LiftRel.inl (hab.lt_of_not_ge fun h => hba <| LiftRel.inl h)
        · exact LiftRel.inr (hab.lt_of_not_ge fun h => hba <| LiftRel.inr h) }
```

-- snippet 62
```lean
-- Mathlib.Data.Sum.Interval.Ioc_inl_inr (L250-L252)
theorem Ioc_inl_inr : Ioc (inl a₁) (inr b₂) = ∅ :=
rfl
```

-- snippet 63
```lean
-- Mathlib.Data.Sum.Interval.Icc_inl_inl (L229-L231)
theorem Icc_inl_inl : Icc (inl a₁ : α ⊕ β) (inl a₂) = (Icc a₁ a₂).map Embedding.inl :=
rfl
```

-- snippet 64
```lean
-- Mathlib.Data.Sum.Lattice.instDistribLattice (L110-L117)
instance instDistribLattice [DistribLattice α] [DistribLattice β] : DistribLattice (α ⊕ₗ β) where
  le_sup_inf := by
simp only [Lex.forall, Sum.forall, inr_le_inr_iff,
      le_sup_left, inl_le_inr, sup_of_le_right, and_self,
      inf_of_le_left, implies_true, inf_of_le_right, sup_of_le_left, ← inl_sup,
      ← inr_sup, ← inl_inf, ← inr_inf, sup_inf_left, le_rfl]

end Sum.Lex
```

-- snippet 65
```lean
-- Mathlib.Data.Sum.Interval.Ico_inr_inl (L262-L264)
theorem Ico_inr_inl : Ico (inr b₁) (inl a₂) = ∅ :=
rfl
```

-- snippet 66
```lean
-- Mathlib.Data.Sum.Order.toLex_le_toLex (L297-L300)
theorem toLex_le_toLex [LE α] [LE β] {a b : α ⊕ β} :
    toLex a ≤ toLex b ↔ Lex (· ≤ ·) (· ≤ ·) a b :=
Iff.rfl
```

-- snippet 67
```lean
-- Mathlib.Data.Sum.Interval.sumLexLift_inl_inr (L121-L123)
lemma sumLexLift_inl_inr (a : α₁) (b : β₂) :
    sumLexLift f₁ f₂ g₁ g₂ (inl a) (inr b) = (g₁ a b).disjSum (g₂ a b) := rfl
```

-- snippet 68
```lean
-- Mathlib.Data.Sum.Interval.Icc_inl_inr (L242-L244)
theorem Icc_inl_inr : Icc (inl a₁) (inr b₂) = ∅ :=
rfl
```

-- snippet 69
```lean
-- Mathlib.Data.Sum.Interval.instLocallyFiniteOrderTop (L442-L453)
instance instLocallyFiniteOrderTop : LocallyFiniteOrderTop (α ⊕ₗ β) where
  finsetIci := Sum.elim
(fun x => (Ici x).disjSum Finset.univ |>.map toLex.toEmbedding)
    (Ici · |>.map (.trans .inr toLex.toEmbedding)) ∘ ofLex
  finsetIoi := Sum.elim
    (fun x => (Ioi x).disjSum Finset.univ |>.map toLex.toEmbedding)
    (Ioi · |>.map (.trans .inr toLex.toEmbedding)) ∘ ofLex
  finset_mem_Ici := by simp
  finset_mem_Ioi := by simp

variable (a : α) (b : β)
```

-- snippet 70
```lean
-- Mathlib.Data.Sum.Interval.sumLexLift_inr_inr (L128-L132)
lemma sumLexLift_inr_inr (a : α₂) (b : β₂) :
    sumLexLift f₁ f₂ g₁ g₂ (inr a) (inr b) = (f₂ a b).map ⟨_, inr_injective⟩ := rfl
variable {f₁ g₁ f₂ g₂ f₁' g₁' f₂' g₂'} {a : α₁ ⊕ α₂} {b : β₁ ⊕ β₂} {c : γ₁ ⊕ γ₂}
```

-- snippet 71
```lean
-- Mathlib.Data.Sum.Interval.Icc_inr_inr (L273-L275)
theorem Icc_inr_inr : Icc (inr b₁ : α ⊕ β) (inr b₂) = (Icc b₁ b₂).map Embedding.inr :=
rfl
```

-- snippet 72
```lean
-- Mathlib.Data.Sum.Interval.Ioc_inr_inr (L279-L281)
theorem Ioc_inr_inr : Ioc (inr b₁ : α ⊕ β) (inr b₂) = (Ioc b₁ b₂).map Embedding.inr :=
rfl
```

-- snippet 73
```lean
-- Mathlib.Data.Sum.Order.lt_def (L121-L123)
theorem lt_def [LT α] [LT β] {a b : α ⊕ β} : a < b ↔ LiftRel (· < ·) (· < ·) a b :=
Iff.rfl
```

-- snippet 74
```lean
-- Mathlib.Data.Sum.Interval.Ioo_inr_inr (L282-L289)
theorem Ioo_inr_inr : Ioo (inr b₁ : α ⊕ β) (inr b₂) = (Ioo b₁ b₂).map Embedding.inr :=
rfl

end LocallyFiniteOrder

section LocallyFiniteOrderBot
variable [Preorder α] [Preorder β] [LocallyFiniteOrderBot α] [LocallyFiniteOrderBot β]
```

-- snippet 75
```lean
-- Mathlib.Data.Sum.Interval.sumLexLift_inl_inl (L117-L119)
lemma sumLexLift_inl_inl (a : α₁) (b : β₁) :
    sumLexLift f₁ f₂ g₁ g₂ (inl a) (inl b) = (f₁ a b).map Embedding.inl := rfl
```

-- snippet 76
```lean
-- Mathlib.Data.Sum.Interval.mem_sumLexLift (L133-L159)
lemma mem_sumLexLift :
    c ∈ sumLexLift f₁ f₂ g₁ g₂ a b ↔
      (∃ a₁ b₁ c₁, a = inl a₁ ∧ b = inl b₁ ∧ c = inl c₁ ∧ c₁ ∈ f₁ a₁ b₁) ∨
        (∃ a₁ b₂ c₁, a = inl a₁ ∧ b = inr b₂ ∧ c = inl c₁ ∧ c₁ ∈ g₁ a₁ b₂) ∨
          (∃ a₁ b₂ c₂, a = inl a₁ ∧ b = inr b₂ ∧ c = inr c₂ ∧ c₂ ∈ g₂ a₁ b₂) ∨
            ∃ a₂ b₂ c₂, a = inr a₂ ∧ b = inr b₂ ∧ c = inr c₂ ∧ c₂ ∈ f₂ a₂ b₂ := by
constructor
  · obtain a | a := a <;> obtain b | b := b
    · rw [sumLexLift, mem_map]
      rintro ⟨c, hc, rfl⟩
      exact Or.inl ⟨a, b, c, rfl, rfl, rfl, hc⟩
    · refine fun h ↦ (mem_disjSum.1 h).elim ?_ ?_
      · rintro ⟨c, hc, rfl⟩
        exact Or.inr (Or.inl ⟨a, b, c, rfl, rfl, rfl, hc⟩)
      · rintro ⟨c, hc, rfl⟩
        exact Or.inr (Or.inr <| Or.inl ⟨a, b, c, rfl, rfl, rfl, hc⟩)
    · exact fun h ↦ (notMem_empty _ h).elim
    · rw [sumLexLift, mem_map]
      rintro ⟨c, hc, rfl⟩
      exact Or.inr (Or.inr <| Or.inr <| ⟨a, b, c, rfl, rfl, rfl, hc⟩)
  · rintro (⟨a, b, c, rfl, rfl, rfl, hc⟩ | ⟨a, b, c, rfl, rfl, rfl, hc⟩ |
      ⟨a, b, c, rfl, rfl, rfl, hc⟩ | ⟨a, b, c, rfl, rfl, rfl, hc⟩)
    · exact mem_map_of_mem _ hc
    · exact inl_mem_disjSum.2 hc
    · exact inr_mem_disjSum.2 hc
    · exact mem_map_of_mem _ hc
```

-- snippet 77
```lean
-- Mathlib.Data.Sum.Order.noMaxOrder (L197-L206)
instance noMaxOrder [LT α] [LT β] [NoMaxOrder α] [NoMaxOrder β] : NoMaxOrder (α ⊕ β) :=
⟨fun a =>
    match a with
    | inl a =>
      let ⟨b, h⟩ := exists_gt a
      ⟨inl b, inl_lt_inl_iff.2 h⟩
    | inr a =>
      let ⟨b, h⟩ := exists_gt a
      ⟨inr b, inr_lt_inr_iff.2 h⟩⟩
```

-- snippet 78
```lean
-- Mathlib.Data.Sum.Order.denselyOrdered (L233-L243)
instance denselyOrdered [LT α] [LT β] [DenselyOrdered α] [DenselyOrdered β] :
    DenselyOrdered (α ⊕ β) :=
⟨fun a b h =>
    match a, b, h with
    | inl _, inl _, LiftRel.inl h =>
      let ⟨c, ha, hb⟩ := exists_between h
      ⟨toLex (inl c), LiftRel.inl ha, LiftRel.inl hb⟩
    | inr _, inr _, LiftRel.inr h =>
      let ⟨c, ha, hb⟩ := exists_between h
      ⟨toLex (inr c), LiftRel.inr ha, LiftRel.inr hb⟩⟩
```

-- snippet 79
```lean
-- Mathlib.Data.Sum.Interval.Ioi_inr (L319-L332)
theorem Ioi_inr : Ioi (inr b : α ⊕ β) = (Ioi b).map Embedding.inr := rfl
end LocallyFiniteOrderTop

end Disjoint

/-! ### Lexicographical sum of orders -/

namespace Lex

section LocallyFiniteOrder
variable [Preorder α] [Preorder β] [LocallyFiniteOrder α] [LocallyFiniteOrder β]
variable [LocallyFiniteOrderTop α] [LocallyFiniteOrderBot β]
```

-- snippet 80
```lean
-- Mathlib.Data.Sum.Order.inl_le_inl_iff (L125-L127)
theorem inl_le_inl_iff [LE α] [LE β] {a b : α} : (inl a : α ⊕ β) ≤ inl b ↔ a ≤ b :=
liftRel_inl_inl
```

-- snippet 81
```lean
-- Mathlib.Data.Sum.Order.instLTSum (L115-L117)
instance instLTSum [LT α] [LT β] : LT (α ⊕ β) :=
⟨LiftRel (· < ·) (· < ·)⟩
```

-- snippet 82
```lean
-- Mathlib.Data.Sum.Interval.Ioo_inl_inr (L254-L256)
theorem Ioo_inl_inr : Ioo (inl a₁) (inr b₂) = ∅ :=
rfl
```

-- snippet 83
```lean
-- Mathlib.Data.Sum.Order.inr_strictMono (L179-L182)
theorem inr_strictMono : StrictMono (inr : β → α ⊕ β) := fun _ _ => LiftRel.inr
end Preorder
```

-- snippet 84
```lean
-- Mathlib.Data.Sum.Interval.inl_mem_sumLift₂ (L60-L66)
theorem inl_mem_sumLift₂ {c₁ : γ₁} :
    inl c₁ ∈ sumLift₂ f g a b ↔ ∃ a₁ b₁, a = inl a₁ ∧ b = inl b₁ ∧ c₁ ∈ f a₁ b₁ := by
rw [mem_sumLift₂, or_iff_left]
  · simp only [inl.injEq, exists_and_left, exists_eq_left']
  rintro ⟨_, _, c₂, _, _, h, _⟩
  exact inl_ne_inr h
```

-- snippet 85
```lean
-- Mathlib.Data.Sum.Order.swap_le_swap_iff (L259-L261)
theorem swap_le_swap_iff [LE α] [LE β] {a b : α ⊕ β} : a.swap ≤ b.swap ↔ a ≤ b :=
liftRel_swap_iff
```

-- snippet 86
```lean
-- Mathlib.Data.Sum.Interval.instLocallyFiniteOrder (L217-L228)
instance instLocallyFiniteOrder : LocallyFiniteOrder (α ⊕ β) where
  finsetIcc := sumLift₂ Icc Icc
finsetIco := sumLift₂ Ico Ico
  finsetIoc := sumLift₂ Ioc Ioc
  finsetIoo := sumLift₂ Ioo Ioo
  finset_mem_Icc := by simp
  finset_mem_Ico := by simp
  finset_mem_Ioc := by simp
  finset_mem_Ioo := by simp

variable (a₁ a₂ : α) (b₁ b₂ : β)
```

-- snippet 87
```lean
-- Mathlib.Data.Sum.Order.toLexRelIsoLT_coe (L344-L346)
theorem toLexRelIsoLT_coe [LT α] [LT β] : ⇑(toLexRelIsoLT (α := α) (β := β)) = toLex :=
rfl
```

-- snippet 88
```lean
-- Mathlib.Data.Sum.Interval.Iic_inr (L299-L299)
theorem Iic_inr : Iic (inr b : α ⊕ β) = (Iic b).map Embedding.inr := rfl
```

-- snippet 89
```lean
-- Mathlib.Data.Sum.Lattice.instLattice (L94-L96)
instance instLattice : Lattice (α ⊕ₗ β) := { instSemilatticeSup, instSemilatticeInf with }
/-- `Sum.Lex.inlₗ` as a lattice homomorphism. -/
```

-- snippet 90
```lean
-- Mathlib.Data.Sum.Interval.Ico_inl_inl (L232-L234)
theorem Ico_inl_inl : Ico (inl a₁ : α ⊕ β) (inl a₂) = (Ico a₁ a₂).map Embedding.inl :=
rfl
```

-- snippet 91
```lean
-- Mathlib.Data.Sum.Interval.locallyFiniteOrder (L333-L348)
instance locallyFiniteOrder : LocallyFiniteOrder (α ⊕ₗ β) where
  finsetIcc a b :=
(sumLexLift Icc Icc (fun a _ => Ici a) (fun _ => Iic) (ofLex a) (ofLex b)).map toLex.toEmbedding
  finsetIco a b :=
    (sumLexLift Ico Ico (fun a _ => Ici a) (fun _ => Iio) (ofLex a) (ofLex b)).map toLex.toEmbedding
  finsetIoc a b :=
    (sumLexLift Ioc Ioc (fun a _ => Ioi a) (fun _ => Iic) (ofLex a) (ofLex b)).map toLex.toEmbedding
  finsetIoo a b :=
    (sumLexLift Ioo Ioo (fun a _ => Ioi a) (fun _ => Iio) (ofLex a) (ofLex b)).map toLex.toEmbedding
  finset_mem_Icc := by simp
  finset_mem_Ico := by simp
  finset_mem_Ioc := by simp
  finset_mem_Ioo := by simp

variable (a a₁ a₂ : α) (b b₁ b₂ : β)
```

-- snippet 92
```lean
-- Mathlib.Data.Sum.Order.instLESum (L112-L114)
instance instLESum [LE α] [LE β] : LE (α ⊕ β) :=
⟨LiftRel (· ≤ ·) (· ≤ ·)⟩
```

-- snippet 93
```lean
-- Mathlib.Data.Sum.Interval.instLocallyFiniteOrderBot (L410-L421)
instance instLocallyFiniteOrderBot : LocallyFiniteOrderBot (α ⊕ₗ β) where
  finsetIic := Sum.elim
(Iic · |>.map (.trans .inl toLex.toEmbedding))
    (fun x => Finset.univ.disjSum (Iic x) |>.map toLex.toEmbedding) ∘ ofLex
  finsetIio := Sum.elim
    (Iio · |>.map (.trans .inl toLex.toEmbedding))
    (fun x => Finset.univ.disjSum (Iio x) |>.map toLex.toEmbedding) ∘ ofLex
  finset_mem_Iic := by simp
  finset_mem_Iio := by simp

variable (a : α) (b : β)
```

-- snippet 94
```lean
-- Mathlib.Data.Sum.Interval.sumLexLift_eq_empty (L179-L192)
lemma sumLexLift_eq_empty :
    sumLexLift f₁ f₂ g₁ g₂ a b = ∅ ↔
      (∀ a₁ b₁, a = inl a₁ → b = inl b₁ → f₁ a₁ b₁ = ∅) ∧
        (∀ a₁ b₂, a = inl a₁ → b = inr b₂ → g₁ a₁ b₂ = ∅ ∧ g₂ a₁ b₂ = ∅) ∧
          ∀ a₂ b₂, a = inr a₂ → b = inr b₂ → f₂ a₂ b₂ = ∅ := by
refine ⟨fun h ↦ ⟨?_, ?_, ?_⟩, fun h ↦ ?_⟩
  any_goals rintro a b rfl rfl; exact map_eq_empty.1 h
  · rintro a b rfl rfl; exact disjSum_eq_empty.1 h
  cases a <;> cases b
  · exact map_eq_empty.2 (h.1 _ _ rfl rfl)
  · simp [h.2.1 _ _ rfl rfl]
  · rfl
  · exact map_eq_empty.2 (h.2.2 _ _ rfl rfl)
```

-- snippet 95
```lean
-- Mathlib.Data.Sum.Interval.Ioc_inl_inl (L235-L237)
theorem Ioc_inl_inl : Ioc (inl a₁ : α ⊕ β) (inl a₂) = (Ioc a₁ a₂).map Embedding.inl :=
rfl
```

-- snippet 96
```lean
-- Mathlib.Data.Sum.Interval.inr_mem_sumLexLift (L166-L171)
lemma inr_mem_sumLexLift {c₂ : γ₂} :
    inr c₂ ∈ sumLexLift f₁ f₂ g₁ g₂ a b ↔
      (∃ a₁ b₂, a = inl a₁ ∧ b = inr b₂ ∧ c₂ ∈ g₂ a₁ b₂) ∨
        ∃ a₂ b₂, a = inr a₂ ∧ b = inr b₂ ∧ c₂ ∈ f₂ a₂ b₂ := by
simp [mem_sumLexLift]
```

-- snippet 97
```lean
-- Mathlib.Data.Sum.Interval.Ioo_inl_inl (L238-L240)
theorem Ioo_inl_inl : Ioo (inl a₁ : α ⊕ β) (inl a₂) = (Ioo a₁ a₂).map Embedding.inl :=
rfl
```

-- snippet 98
```lean
-- Mathlib.Data.Sum.Interval.Iio_inr (L301-L307)
theorem Iio_inr : Iio (inr b : α ⊕ β) = (Iio b).map Embedding.inr := rfl
end LocallyFiniteOrderBot

section LocallyFiniteOrderTop
variable [Preorder α] [Preorder β] [LocallyFiniteOrderTop α] [LocallyFiniteOrderTop β]
```

-- snippet 99
```lean
-- Mathlib.Data.Sum.Interval.sumLexLift_mono (L172-L178)
lemma sumLexLift_mono (hf₁ : ∀ a b, f₁ a b ⊆ f₁' a b) (hf₂ : ∀ a b, f₂ a b ⊆ f₂' a b)
    (hg₁ : ∀ a b, g₁ a b ⊆ g₁' a b) (hg₂ : ∀ a b, g₂ a b ⊆ g₂' a b) (a : α₁ ⊕ α₂)
    (b : β₁ ⊕ β₂) : sumLexLift f₁ f₂ g₁ g₂ a b ⊆ sumLexLift f₁' f₂' g₁' g₂' a b := by
cases a <;> cases b
  exacts [map_subset_map.2 (hf₁ _ _), disjSum_mono (hg₁ _ _) (hg₂ _ _), Subset.rfl,
    map_subset_map.2 (hf₂ _ _)]
```

-- snippet 100
```lean
-- Mathlib.Data.Sum.Order.toLex_lt_toLex (L302-L305)
theorem toLex_lt_toLex [LT α] [LT β] {a b : α ⊕ β} :
    toLex a < toLex b ↔ Lex (· < ·) (· < ·) a b :=
Iff.rfl
```

-- snippet 101
```lean
-- Mathlib.Data.Sum.Order.not_inl_le_inr (L141-L143)
theorem not_inl_le_inr [LE α] [LE β] {a : α} {b : β} : ¬inl b ≤ inr a :=
not_liftRel_inl_inr
```

-- snippet 102
```lean
-- Mathlib.Data.Sum.Order.toLexRelIsoLT_symm_coe (L348-L351)
theorem toLexRelIsoLT_symm_coe [LT α] [LT β] : ⇑(toLexRelIsoLT (α := α) (β := β)).symm = ofLex :=
rfl

/-- `toLex` promoted to a `RelIso` between `≤` relations. -/
```

-- snippet 103
```lean
-- Mathlib.Data.Sum.Lattice.inlLatticeHom (L97-L102)
def inlLatticeHom : LatticeHom α (α ⊕ₗ β) where
  toFun := inlₗ
map_sup' _ _ := rfl
  map_inf' _ _ := rfl

/-- `Sum.Lex.inrₗ` as a lattice homomorphism. -/
```

-- snippet 104
```lean
-- Mathlib.Data.Sum.Interval.Ico_inl_inr (L246-L248)
theorem Ico_inl_inr : Ico (inl a₁) (inr b₂) = ∅ :=
rfl
```

-- snippet 105
```lean
-- Mathlib.Data.Sum.Order.inr_mono (L175-L176)
theorem inr_mono : Monotone (inr : β → α ⊕ β) := fun _ _ => LiftRel.inr
```

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Data.Sum.Basic).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Prove the following theorem. The retrieved context below may help.

```lean
lemma elim_update_left {γ : Sort*} [DecidableEq α] [DecidableEq β]
    (f : α → γ) (g : β → γ) (a : α) (x : γ) :
    Sum.elim (update f a x) g = update (Sum.elim f g) (.inl a) x
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Data.Sum.Basic.not_isLeft_and_isRight (L24-L27)
lemma not_isLeft_and_isRight {x : α ⊕ β} : ¬(x.isLeft ∧ x.isRight) := by simp
namespace Sum
```

-- snippet 2
```lean
-- Mathlib.Data.Sum.Basic.elim_swap (L29-L33)
theorem elim_swap {α β γ : Type*} {f : α → γ} {g : β → γ} :
    Sum.elim f g ∘ Sum.swap = Sum.elim g f := by
grind

-- Lean has removed the `@[simp]` attribute on these. For now Mathlib adds it back.
```

-- snippet 3
```lean
-- Mathlib.Data.Sum.Basic.exists_sum (L36-L40)
theorem exists_sum {γ : α ⊕ β → Sort*} (p : (∀ ab, γ ab) → Prop) :
    (∃ fab, p fab) ↔ (∃ fa fb, p (Sum.rec fa fb)) := by
rw [← not_forall_not, forall_sum]
  simp
```

-- snippet 4
```lean
-- Mathlib.Data.Sum.Basic.inl_injective (L41-L42)
theorem inl_injective : Function.Injective (inl : α → α ⊕ β) := fun _ _ ↦ inl.inj
```

-- snippet 5
```lean
-- Mathlib.Data.Sum.Basic.inr_injective (L43-L44)
theorem inr_injective : Function.Injective (inr : β → α ⊕ β) := fun _ _ ↦ inr.inj
```

-- snippet 6
```lean
-- Mathlib.Data.Sum.Basic.sum_rec_congr (L45-L52)
theorem sum_rec_congr (P : α ⊕ β → Sort*) (f : ∀ i, P (inl i)) (g : ∀ i, P (inr i))
    {x y : α ⊕ β} (h : x = y) :
    @Sum.rec _ _ _ f g x = cast (congr_arg P h.symm) (@Sum.rec _ _ _ f g y) := by cases h; rfl
section get

variable {x : α ⊕ β}
```

-- snippet 7
```lean
-- Mathlib.Data.Sum.Basic.eq_left_iff_getLeft_eq (L53-L55)
theorem eq_left_iff_getLeft_eq {a : α} : x = inl a ↔ ∃ h, x.getLeft h = a := by
cases x <;> simp
```

-- snippet 8
```lean
-- Mathlib.Data.Sum.Basic.eq_right_iff_getRight_eq (L56-L58)
theorem eq_right_iff_getRight_eq {b : β} : x = inr b ↔ ∃ h, x.getRight h = b := by
cases x <;> simp
```

-- snippet 9
```lean
-- Mathlib.Data.Sum.Basic.getLeft_eq_getLeft (L59-L61)
theorem getLeft_eq_getLeft? (h₁ : x.isLeft) (h₂ : x.getLeft?.isSome) :
    x.getLeft h₁ = x.getLeft?.get h₂ := by grind
```

-- snippet 10
```lean
-- Mathlib.Data.Sum.Basic.getRight_eq_getRight (L62-L64)
theorem getRight_eq_getRight? (h₁ : x.isRight) (h₂ : x.getRight?.isSome) :
    x.getRight h₁ = x.getRight?.get h₂ := by grind
```

-- snippet 11
```lean
-- Mathlib.Data.Sum.Basic.update_elim_inl (L76-L79)
theorem update_elim_inl [DecidableEq α] [DecidableEq (α ⊕ β)] {f : α → γ} {g : β → γ} {i : α}
    {x : γ} : update (Sum.elim f g) (inl i) x = Sum.elim (update f i x) g :=
update_eq_iff.2 ⟨by simp, by simp +contextual⟩
```

-- snippet 12
```lean
-- Mathlib.Data.Sum.Basic.update_elim_inr (L81-L84)
theorem update_elim_inr [DecidableEq β] [DecidableEq (α ⊕ β)] {f : α → γ} {g : β → γ} {i : β}
    {x : γ} : update (Sum.elim f g) (inr i) x = Sum.elim f (update g i x) :=
update_eq_iff.2 ⟨by simp, by simp +contextual⟩
```

-- snippet 13
```lean
-- Mathlib.Data.Sum.Basic.update_inl_comp_inl (L86-L89)
theorem update_inl_comp_inl [DecidableEq α] [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i : α}
    {x : γ} : update f (inl i) x ∘ inl = update (f ∘ inl) i x :=
update_comp_eq_of_injective _ inl_injective _ _
```

-- snippet 14
```lean
-- Mathlib.Data.Sum.Basic.update_inl_apply_inl (L91-L94)
theorem update_inl_apply_inl [DecidableEq α] [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i j : α}
    {x : γ} : update f (inl i) x (inl j) = update (f ∘ inl) i x j := by
grind
```

-- snippet 15
```lean
-- Mathlib.Data.Sum.Basic.update_inl_comp_inr (L96-L99)
theorem update_inl_comp_inr [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i : α} {x : γ} :
    update f (inl i) x ∘ inr = f ∘ inr :=
(update_comp_eq_of_forall_ne _ _) fun _ ↦ inr_ne_inl
```

-- snippet 16
```lean
-- Mathlib.Data.Sum.Basic.update_inl_apply_inr (L100-L103)
theorem update_inl_apply_inr [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i : α} {j : β} {x : γ} :
    update f (inl i) x (inr j) = f (inr j) :=
Function.update_of_ne inr_ne_inl ..
```

-- snippet 17
```lean
-- Mathlib.Data.Sum.Basic.update_inr_comp_inl (L105-L108)
theorem update_inr_comp_inl [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i : β} {x : γ} :
    update f (inr i) x ∘ inl = f ∘ inl :=
(update_comp_eq_of_forall_ne _ _) fun _ ↦ inl_ne_inr
```

-- snippet 18
```lean
-- Mathlib.Data.Sum.Basic.update_inr_apply_inl (L109-L112)
theorem update_inr_apply_inl [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i : α} {j : β} {x : γ} :
    update f (inr j) x (inl i) = f (inl i) :=
Function.update_of_ne inl_ne_inr ..
```

-- snippet 19
```lean
-- Mathlib.Data.Sum.Basic.update_inr_comp_inr (L114-L117)
theorem update_inr_comp_inr [DecidableEq β] [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i : β}
    {x : γ} : update f (inr i) x ∘ inr = update (f ∘ inr) i x :=
update_comp_eq_of_injective _ inr_injective _ _
```

-- snippet 20
```lean
-- Mathlib.Data.Sum.Basic.update_inr_apply_inr (L119-L122)
theorem update_inr_apply_inr [DecidableEq β] [DecidableEq (α ⊕ β)] {f : α ⊕ β → γ} {i j : β}
    {x : γ} : update f (inr i) x (inr j) = update (f ∘ inr) i x j := by
rw [← update_inr_comp_inr, Function.comp_apply]
```

-- snippet 21
```lean
-- Mathlib.Data.Sum.Basic.update_inl_apply_inl' (L124-L128)
theorem update_inl_apply_inl' {γ : α ⊕ β → Type*} [DecidableEq α] [DecidableEq (α ⊕ β)]
    {f : (i : α ⊕ β) → γ i} {i : α} {x : γ (.inl i)} (j : α) :
    update f (.inl i) x (Sum.inl j) = update (fun j ↦ f (.inl j)) i x j :=
Function.update_apply_of_injective f Sum.inl_injective i x j
```

-- snippet 22
```lean
-- Mathlib.Data.Sum.Basic.update_inr_apply_inr' (L130-L134)
theorem update_inr_apply_inr' {γ : α ⊕ β → Type*} [DecidableEq β] [DecidableEq (α ⊕ β)]
    {f : (i : α ⊕ β) → γ i} {i : β} {x : γ (.inr i)} (j : β) :
    update f (.inr i) x (Sum.inr j) = update (fun j ↦ f (.inr j)) i x j :=
Function.update_apply_of_injective f Sum.inr_injective i x j
```

-- snippet 23
```lean
-- Mathlib.Data.Sum.Basic.rec_update_left (L136-L142)
lemma rec_update_left {γ : α ⊕ β → Sort*} [DecidableEq α] [DecidableEq β]
    (f : ∀ a, γ (.inl a)) (g : ∀ b, γ (.inr b)) (a : α) (x : γ (.inl a)) :
    Sum.rec (update f a x) g = update (Sum.rec f g) (.inl a) x :=
Function.rec_update Sum.inl_injective (Sum.rec · g) (fun _ _ => rfl) (fun
    | _, _, .inl _, h => (h _ rfl).elim
    | _, _, .inr _, _ => rfl) _ _ _
```

-- snippet 24
```lean
-- Mathlib.Data.Sum.Basic.rec_update_right (L144-L150)
lemma rec_update_right {γ : α ⊕ β → Sort*} [DecidableEq α] [DecidableEq β]
    (f : ∀ a, γ (.inl a)) (g : ∀ b, γ (.inr b)) (b : β) (x : γ (.inr b)) :
    Sum.rec f (update g b x) = update (Sum.rec f g) (.inr b) x :=
Function.rec_update Sum.inr_injective (Sum.rec f) (fun _ _ => rfl) (fun
    | _, _, .inr _, h => (h _ rfl).elim
    | _, _, .inl _, _ => rfl) _ _ _
```

-- snippet 25
```lean
-- Mathlib.Data.Sum.Basic.elim_update_right (L158-L162)
lemma elim_update_right {γ : Sort*} [DecidableEq α] [DecidableEq β]
    (f : α → γ) (g : β → γ) (b : β) (x : γ) :
    Sum.elim f (update g b x) = update (Sum.elim f g) (.inr b) x :=
rec_update_right _ _ _ _
```

-- snippet 26
```lean
-- Mathlib.Data.Sum.Order.swap_lt_swap_iff (L263-L278)
theorem swap_lt_swap_iff [LT α] [LT β] {a b : α ⊕ β} : a.swap < b.swap ↔ a < b :=
liftRel_swap_iff

end Disjoint

/-! ### Linear sum of two orders -/

namespace Lex

/-- The linear sum of two orders -/
notation:30 α " ⊕ₗ " β:29 => _root_.Lex (α ⊕ β)

--TODO: Can we make `inlₗ`, `inrₗ` `local notation`?
/-- Lexicographical `Sum.inl`. Only used for pattern matching. -/
```

-- snippet 27
```lean
-- Mathlib.Data.Sum.Lattice.inrLatticeHom (L103-L109)
def inrLatticeHom : LatticeHom β (α ⊕ₗ β) where
  toFun := inrₗ
map_sup' _ _ := rfl
  map_inf' _ _ := rfl

end Lattice
```

-- snippet 28
```lean
-- Mathlib.Data.Sum.Interval.Iic_inl (L298-L298)
theorem Iic_inl : Iic (inl a : α ⊕ β) = (Iic a).map Embedding.inl := rfl
```

-- snippet 29
```lean
-- Mathlib.Data.Sum.Order.not_inr_le_inl (L149-L151)
theorem not_inr_le_inl [LE α] [LE β] {a : α} {b : β} : ¬inr b ≤ inl a :=
not_liftRel_inr_inl
```

-- snippet 30
```lean
-- Mathlib.Data.Sum.Order.inl_strictMono (L177-L178)
theorem inl_strictMono : StrictMono (inl : α → α ⊕ β) := fun _ _ => LiftRel.inl
```

-- snippet 31
```lean
-- Mathlib.Data.Sum.Order.toLexRelIsoLT (L337-L342)
def toLexRelIsoLT [LT α] [LT β] :
    Sum.Lex (· < · : α → α → Prop) (· < · : β → β → Prop) ≃r (· < · : α ⊕ₗ β → _ → _) where
  toFun := toLex
invFun := ofLex
  map_rel_iff' := .rfl
```

-- snippet 32
```lean
-- Mathlib.Data.Sum.Interval.Ici_inl (L316-L316)
theorem Ici_inl : Ici (inl a : α ⊕ β) = (Ici a).map Embedding.inl := rfl
```

-- snippet 33
```lean
-- Mathlib.Data.Sum.Interval.sumLift₂_nonempty (L88-L93)
theorem sumLift₂_nonempty :
    (sumLift₂ f g a b).Nonempty ↔
      (∃ a₁ b₁, a = inl a₁ ∧ b = inl b₁ ∧ (f a₁ b₁).Nonempty) ∨
        ∃ a₂ b₂, a = inr a₂ ∧ b = inr b₂ ∧ (g a₂ b₂).Nonempty := by
simp only [nonempty_iff_ne_empty, Ne, sumLift₂_eq_empty, not_and_or, not_forall, exists_prop]
```

-- snippet 34
```lean
-- Mathlib.Data.Sum.Interval.Ioi_inl (L318-L318)
theorem Ioi_inl : Ioi (inl a : α ⊕ β) = (Ioi a).map Embedding.inl := rfl
```

-- snippet 35
```lean
-- Mathlib.Data.Sum.Order.noMaxOrder_iff (L221-L232)
theorem noMaxOrder_iff [LT α] [LT β] : NoMaxOrder (α ⊕ β) ↔ NoMaxOrder α ∧ NoMaxOrder β :=
⟨fun _ =>
    ⟨⟨fun a => by
        obtain ⟨b | b, h⟩ := exists_gt (inl a : α ⊕ β)
        · exact ⟨b, inl_lt_inl_iff.1 h⟩
        · exact (not_inl_lt_inr h).elim⟩,
      ⟨fun a => by
        obtain ⟨b | b, h⟩ := exists_gt (inr a : α ⊕ β)
        · exact (not_inr_lt_inl h).elim
        · exact ⟨b, inr_lt_inr_iff.1 h⟩⟩⟩,
    fun h => @Sum.noMaxOrder _ _ _ _ h.1 h.2⟩
```

-- snippet 36
```lean
-- Mathlib.Data.Sum.Order.not_inl_lt_inr (L145-L147)
theorem not_inl_lt_inr [LT α] [LT β] {a : α} {b : β} : ¬inl b < inr a :=
not_liftRel_inl_inr
```

-- snippet 37
```lean
-- Mathlib.Data.Sum.Interval.Iio_inl (L300-L300)
theorem Iio_inl : Iio (inl a : α ⊕ β) = (Iio a).map Embedding.inl := rfl
```

-- snippet 38
```lean
-- Mathlib.Data.Sum.Order.inl_le_inr (L324-L326)
theorem inl_le_inr [LE α] [LE β] (a : α) (b : β) : toLex (inl a) ≤ toLex (inr b) :=
Lex.sep _ _
```

-- snippet 39
```lean
-- Mathlib.Data.Sum.Order.le_def (L118-L120)
theorem le_def [LE α] [LE β] {a b : α ⊕ β} : a ≤ b ↔ LiftRel (· ≤ ·) (· ≤ ·) a b :=
Iff.rfl
```

-- snippet 40
```lean
-- Mathlib.Data.Sum.Interval.Ici_inr (L317-L317)
theorem Ici_inr : Ici (inr b : α ⊕ β) = (Ici b).map Embedding.inr := rfl
```

-- snippet 41
```lean
-- Mathlib.Data.Sum.Interval.inr_mem_sumLift₂ (L67-L73)
theorem inr_mem_sumLift₂ {c₂ : γ₂} :
    inr c₂ ∈ sumLift₂ f g a b ↔ ∃ a₂ b₂, a = inr a₂ ∧ b = inr b₂ ∧ c₂ ∈ g a₂ b₂ := by
rw [mem_sumLift₂, or_iff_right]
  · simp only [inr.injEq, exists_and_left, exists_eq_left']
  rintro ⟨_, _, c₂, _, _, h, _⟩
  exact inr_ne_inl h
```

-- snippet 42
```lean
-- Mathlib.Data.Sum.Order.inr_le_inr_iff (L129-L131)
theorem inr_le_inr_iff [LE α] [LE β] {a b : β} : (inr a : α ⊕ β) ≤ inr b ↔ a ≤ b :=
liftRel_inr_inr
```

-- snippet 43
```lean
-- Mathlib.Data.Sum.Order.not_inr_lt_inl (L153-L159)
theorem not_inr_lt_inl [LT α] [LT β] {a : α} {b : β} : ¬inr b < inl a :=
not_liftRel_inr_inl

section Preorder

variable [Preorder α] [Preorder β]
```

-- snippet 44
```lean
-- Mathlib.Data.Sum.Order.inl_mono (L173-L174)
theorem inl_mono : Monotone (inl : α → α ⊕ β) := fun _ _ => LiftRel.inl
```

-- snippet 45
```lean
-- Mathlib.Data.Sum.Interval.Ioo_inr_inl (L270-L272)
theorem Ioo_inr_inl : Ioo (inr b₁) (inl a₂) = ∅ :=
rfl
```

-- snippet 46
```lean
-- Mathlib.Data.Sum.Order.noMinOrder_iff (L208-L219)
theorem noMinOrder_iff [LT α] [LT β] : NoMinOrder (α ⊕ β) ↔ NoMinOrder α ∧ NoMinOrder β :=
⟨fun _ =>
    ⟨⟨fun a => by
        obtain ⟨b | b, h⟩ := exists_lt (inl a : α ⊕ β)
        · exact ⟨b, inl_lt_inl_iff.1 h⟩
        · exact (not_inr_lt_inl h).elim⟩,
      ⟨fun a => by
        obtain ⟨b | b, h⟩ := exists_lt (inr a : α ⊕ β)
        · exact (not_inl_lt_inr h).elim
        · exact ⟨b, inr_lt_inr_iff.1 h⟩⟩⟩,
    fun h => @Sum.noMinOrder _ _ _ _ h.1 h.2⟩
```

-- snippet 47
```lean
-- Mathlib.Data.Sum.Order.inr_lt_inr_iff (L137-L139)
theorem inr_lt_inr_iff [LT α] [LT β] {a b : β} : (inr a : α ⊕ β) < inr b ↔ a < b :=
liftRel_inr_inr
```

-- snippet 48
```lean
-- Mathlib.Data.Sum.Interval.inl_mem_sumLexLift (L160-L165)
lemma inl_mem_sumLexLift {c₁ : γ₁} :
    inl c₁ ∈ sumLexLift f₁ f₂ g₁ g₂ a b ↔
      (∃ a₁ b₁, a = inl a₁ ∧ b = inl b₁ ∧ c₁ ∈ f₁ a₁ b₁) ∨
        ∃ a₁ b₂, a = inl a₁ ∧ b = inr b₂ ∧ c₁ ∈ g₁ a₁ b₂ := by
simp [mem_sumLexLift]
```

-- snippet 49
```lean
-- Mathlib.Data.Sum.Interval.mem_sumLift₂ (L44-L59)
theorem mem_sumLift₂ :
    c ∈ sumLift₂ f g a b ↔
      (∃ a₁ b₁ c₁, a = inl a₁ ∧ b = inl b₁ ∧ c = inl c₁ ∧ c₁ ∈ f a₁ b₁) ∨
        ∃ a₂ b₂ c₂, a = inr a₂ ∧ b = inr b₂ ∧ c = inr c₂ ∧ c₂ ∈ g a₂ b₂ := by
constructor
  · rcases a with a | a <;> rcases b with b | b
    · rw [sumLift₂, mem_map]
      rintro ⟨c, hc, rfl⟩
      exact Or.inl ⟨a, b, c, rfl, rfl, rfl, hc⟩
    · refine fun h ↦ (notMem_empty _ h).elim
    · refine fun h ↦ (notMem_empty _ h).elim
    · rw [sumLift₂, mem_map]
      rintro ⟨c, hc, rfl⟩
      exact Or.inr ⟨a, b, c, rfl, rfl, rfl, hc⟩
  · rintro (⟨a, b, c, rfl, rfl, rfl, h⟩ | ⟨a, b, c, rfl, rfl, rfl, h⟩) <;> exact mem_map_of_mem _ h
```

-- snippet 50
```lean
-- Mathlib.Data.Sum.Order.inl_lt_inl_iff (L133-L135)
theorem inl_lt_inl_iff [LT α] [LT β] {a b : α} : (inl a : α ⊕ β) < inl b ↔ a < b :=
liftRel_inl_inl
```

-- snippet 51
```lean
-- Mathlib.Data.Sum.Interval.Icc_inr_inl (L258-L260)
theorem Icc_inr_inl : Icc (inr b₁) (inl a₂) = ∅ :=
rfl
```

-- snippet 52
```lean
-- Mathlib.Data.Sum.Order.toLexRelIsoLE (L352-L357)
def toLexRelIsoLE [LE α] [LE β] :
    Sum.Lex (· ≤ · : α → α → Prop) (· ≤ · : β → β → Prop) ≃r (· ≤ · : α ⊕ₗ β → _ → _) where
  toFun := toLex
invFun := ofLex
  map_rel_iff' := .rfl
```

-- snippet 53
```lean
-- Mathlib.Data.Sum.Interval.sumLift₂_eq_empty (L74-L87)
theorem sumLift₂_eq_empty :
    sumLift₂ f g a b = ∅ ↔
      (∀ a₁ b₁, a = inl a₁ → b = inl b₁ → f a₁ b₁ = ∅) ∧
        ∀ a₂ b₂, a = inr a₂ → b = inr b₂ → g a₂ b₂ = ∅ := by
refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩
  · constructor <;>
    · rintro a b rfl rfl
      exact map_eq_empty.1 h
  cases a <;> cases b
  · exact map_eq_empty.2 (h.1 _ _ rfl rfl)
  · rfl
  · rfl
  · exact map_eq_empty.2 (h.2 _ _ rfl rfl)
```

-- snippet 54
```lean
-- Mathlib.Data.Sum.Interval.sumLexLift_inr_inl (L125-L126)
lemma sumLexLift_inr_inl (a : α₂) (b : β₁) : sumLexLift f₁ f₂ g₁ g₂ (inr a) (inl b) = ∅ := rfl
```

-- snippet 55
```lean
-- Mathlib.Data.Sum.Interval.Ico_inr_inr (L276-L278)
theorem Ico_inr_inr : Ico (inr b₁ : α ⊕ β) (inr b₂) = (Ico b₁ b₂).map Embedding.inr :=
rfl
```

-- snippet 56
```lean
-- Mathlib.Data.Sum.Interval.Ioc_inr_inl (L266-L268)
theorem Ioc_inr_inl : Ioc (inr b₁) (inl a₂) = ∅ :=
rfl
```

-- snippet 57
```lean
-- Mathlib.Data.Sum.Order.noMinOrder (L187-L196)
instance noMinOrder [LT α] [LT β] [NoMinOrder α] [NoMinOrder β] : NoMinOrder (α ⊕ β) :=
⟨fun a =>
    match a with
    | inl a =>
      let ⟨b, h⟩ := exists_lt a
      ⟨inl b, inl_lt_inl_iff.2 h⟩
    | inr a =>
      let ⟨b, h⟩ := exists_lt a
      ⟨inr b, inr_lt_inr_iff.2 h⟩⟩
```

-- snippet 58
```lean
-- Mathlib.Data.Sum.Order.denselyOrdered_iff (L245-L257)
theorem denselyOrdered_iff [LT α] [LT β] :
    DenselyOrdered (α ⊕ β) ↔ DenselyOrdered α ∧ DenselyOrdered β :=
⟨fun _ =>
    ⟨⟨fun a b h => by
        obtain ⟨c | c, ha, hb⟩ := @exists_between (α ⊕ β) _ _ _ _ (inl_lt_inl_iff.2 h)
        · exact ⟨c, inl_lt_inl_iff.1 ha, inl_lt_inl_iff.1 hb⟩
        · exact (not_inl_lt_inr ha).elim⟩,
      ⟨fun a b h => by
        obtain ⟨c | c, ha, hb⟩ := @exists_between (α ⊕ β) _ _ _ _ (inr_lt_inr_iff.2 h)
        · exact (not_inl_lt_inr hb).elim
        · exact ⟨c, inr_lt_inr_iff.1 ha, inr_lt_inr_iff.1 hb⟩⟩⟩,
    fun h => @Sum.denselyOrdered _ _ _ _ h.1 h.2⟩
```

-- snippet 59
```lean
-- Mathlib.Data.Sum.Interval.sumLexLift_nonempty (L193-L216)
lemma sumLexLift_nonempty :
    (sumLexLift f₁ f₂ g₁ g₂ a b).Nonempty ↔
      (∃ a₁ b₁, a = inl a₁ ∧ b = inl b₁ ∧ (f₁ a₁ b₁).Nonempty) ∨
        (∃ a₁ b₂, a = inl a₁ ∧ b = inr b₂ ∧ ((g₁ a₁ b₂).Nonempty ∨ (g₂ a₁ b₂).Nonempty)) ∨
          ∃ a₂ b₂, a = inr a₂ ∧ b = inr b₂ ∧ (f₂ a₂ b₂).Nonempty := by
simp only [nonempty_iff_ne_empty, Ne, sumLexLift_eq_empty, not_and_or, exists_prop, not_forall]

end SumLexLift
end Finset

open Finset

namespace Sum

variable {α β : Type*}

/-! ### Disjoint sum of orders -/

section Disjoint

section LocallyFiniteOrder
variable [Preorder α] [Preorder β] [LocallyFiniteOrder α] [LocallyFiniteOrder β]
```

-- snippet 60
```lean
-- Mathlib.Data.Sum.Order.inl_lt_inr (L327-L329)
theorem inl_lt_inr [LT α] [LT β] (a : α) (b : β) : toLex (inl a) < toLex (inr b) :=
Lex.sep _ _
```

-- snippet 61
```lean
-- Mathlib.Data.Sum.Order.instPreorderSum (L160-L172)
instance instPreorderSum : Preorder (α ⊕ β) :=
{ instLESum, instLTSum with
    le_refl := fun _ => LiftRel.refl _ _ _,
    le_trans := fun _ _ _ => LiftRel.trans _ _,
    lt_iff_le_not_ge := fun a b => by
      refine ⟨fun hab => ⟨hab.mono (fun _ _ => le_of_lt) fun _ _ => le_of_lt, ?_⟩, ?_⟩
      · rintro (⟨hba⟩ | ⟨hba⟩)
        · exact hba.not_gt (inl_lt_inl_iff.1 hab)
        · exact hba.not_gt (inr_lt_inr_iff.1 hab)
      · rintro ⟨⟨hab⟩ | ⟨hab⟩, hba⟩
        · exact LiftRel.inl (hab.lt_of_not_ge fun h => hba <| LiftRel.inl h)
        · exact LiftRel.inr (hab.lt_of_not_ge fun h => hba <| LiftRel.inr h) }
```

-- snippet 62
```lean
-- Mathlib.Data.Sum.Interval.Ioc_inl_inr (L250-L252)
theorem Ioc_inl_inr : Ioc (inl a₁) (inr b₂) = ∅ :=
rfl
```

-- snippet 63
```lean
-- Mathlib.Data.Sum.Interval.Icc_inl_inl (L229-L231)
theorem Icc_inl_inl : Icc (inl a₁ : α ⊕ β) (inl a₂) = (Icc a₁ a₂).map Embedding.inl :=
rfl
```

-- snippet 64
```lean
-- Mathlib.Data.Sum.Lattice.instDistribLattice (L110-L117)
instance instDistribLattice [DistribLattice α] [DistribLattice β] : DistribLattice (α ⊕ₗ β) where
  le_sup_inf := by
simp only [Lex.forall, Sum.forall, inr_le_inr_iff,
      le_sup_left, inl_le_inr, sup_of_le_right, and_self,
      inf_of_le_left, implies_true, inf_of_le_right, sup_of_le_left, ← inl_sup,
      ← inr_sup, ← inl_inf, ← inr_inf, sup_inf_left, le_rfl]

end Sum.Lex
```

-- snippet 65
```lean
-- Mathlib.Data.Sum.Interval.Ico_inr_inl (L262-L264)
theorem Ico_inr_inl : Ico (inr b₁) (inl a₂) = ∅ :=
rfl
```

-- snippet 66
```lean
-- Mathlib.Data.Sum.Order.toLex_le_toLex (L297-L300)
theorem toLex_le_toLex [LE α] [LE β] {a b : α ⊕ β} :
    toLex a ≤ toLex b ↔ Lex (· ≤ ·) (· ≤ ·) a b :=
Iff.rfl
```

-- snippet 67
```lean
-- Mathlib.Data.Sum.Interval.sumLexLift_inl_inr (L121-L123)
lemma sumLexLift_inl_inr (a : α₁) (b : β₂) :
    sumLexLift f₁ f₂ g₁ g₂ (inl a) (inr b) = (g₁ a b).disjSum (g₂ a b) := rfl
```

-- snippet 68
```lean
-- Mathlib.Data.Sum.Interval.Icc_inl_inr (L242-L244)
theorem Icc_inl_inr : Icc (inl a₁) (inr b₂) = ∅ :=
rfl
```

-- snippet 69
```lean
-- Mathlib.Data.Sum.Interval.instLocallyFiniteOrderTop (L442-L453)
instance instLocallyFiniteOrderTop : LocallyFiniteOrderTop (α ⊕ₗ β) where
  finsetIci := Sum.elim
(fun x => (Ici x).disjSum Finset.univ |>.map toLex.toEmbedding)
    (Ici · |>.map (.trans .inr toLex.toEmbedding)) ∘ ofLex
  finsetIoi := Sum.elim
    (fun x => (Ioi x).disjSum Finset.univ |>.map toLex.toEmbedding)
    (Ioi · |>.map (.trans .inr toLex.toEmbedding)) ∘ ofLex
  finset_mem_Ici := by simp
  finset_mem_Ioi := by simp

variable (a : α) (b : β)
```

-- snippet 70
```lean
-- Mathlib.Data.Sum.Interval.sumLexLift_inr_inr (L128-L132)
lemma sumLexLift_inr_inr (a : α₂) (b : β₂) :
    sumLexLift f₁ f₂ g₁ g₂ (inr a) (inr b) = (f₂ a b).map ⟨_, inr_injective⟩ := rfl
variable {f₁ g₁ f₂ g₂ f₁' g₁' f₂' g₂'} {a : α₁ ⊕ α₂} {b : β₁ ⊕ β₂} {c : γ₁ ⊕ γ₂}
```

-- snippet 71
```lean
-- Mathlib.Data.Sum.Interval.Icc_inr_inr (L273-L275)
theorem Icc_inr_inr : Icc (inr b₁ : α ⊕ β) (inr b₂) = (Icc b₁ b₂).map Embedding.inr :=
rfl
```

-- snippet 72
```lean
-- Mathlib.Data.Sum.Interval.Ioc_inr_inr (L279-L281)
theorem Ioc_inr_inr : Ioc (inr b₁ : α ⊕ β) (inr b₂) = (Ioc b₁ b₂).map Embedding.inr :=
rfl
```

-- snippet 73
```lean
-- Mathlib.Data.Sum.Order.lt_def (L121-L123)
theorem lt_def [LT α] [LT β] {a b : α ⊕ β} : a < b ↔ LiftRel (· < ·) (· < ·) a b :=
Iff.rfl
```

-- snippet 74
```lean
-- Mathlib.Data.Sum.Interval.Ioo_inr_inr (L282-L289)
theorem Ioo_inr_inr : Ioo (inr b₁ : α ⊕ β) (inr b₂) = (Ioo b₁ b₂).map Embedding.inr :=
rfl

end LocallyFiniteOrder

section LocallyFiniteOrderBot
variable [Preorder α] [Preorder β] [LocallyFiniteOrderBot α] [LocallyFiniteOrderBot β]
```

-- snippet 75
```lean
-- Mathlib.Data.Sum.Interval.sumLexLift_inl_inl (L117-L119)
lemma sumLexLift_inl_inl (a : α₁) (b : β₁) :
    sumLexLift f₁ f₂ g₁ g₂ (inl a) (inl b) = (f₁ a b).map Embedding.inl := rfl
```

-- snippet 76
```lean
-- Mathlib.Data.Sum.Interval.mem_sumLexLift (L133-L159)
lemma mem_sumLexLift :
    c ∈ sumLexLift f₁ f₂ g₁ g₂ a b ↔
      (∃ a₁ b₁ c₁, a = inl a₁ ∧ b = inl b₁ ∧ c = inl c₁ ∧ c₁ ∈ f₁ a₁ b₁) ∨
        (∃ a₁ b₂ c₁, a = inl a₁ ∧ b = inr b₂ ∧ c = inl c₁ ∧ c₁ ∈ g₁ a₁ b₂) ∨
          (∃ a₁ b₂ c₂, a = inl a₁ ∧ b = inr b₂ ∧ c = inr c₂ ∧ c₂ ∈ g₂ a₁ b₂) ∨
            ∃ a₂ b₂ c₂, a = inr a₂ ∧ b = inr b₂ ∧ c = inr c₂ ∧ c₂ ∈ f₂ a₂ b₂ := by
constructor
  · obtain a | a := a <;> obtain b | b := b
    · rw [sumLexLift, mem_map]
      rintro ⟨c, hc, rfl⟩
      exact Or.inl ⟨a, b, c, rfl, rfl, rfl, hc⟩
    · refine fun h ↦ (mem_disjSum.1 h).elim ?_ ?_
      · rintro ⟨c, hc, rfl⟩
        exact Or.inr (Or.inl ⟨a, b, c, rfl, rfl, rfl, hc⟩)
      · rintro ⟨c, hc, rfl⟩
        exact Or.inr (Or.inr <| Or.inl ⟨a, b, c, rfl, rfl, rfl, hc⟩)
    · exact fun h ↦ (notMem_empty _ h).elim
    · rw [sumLexLift, mem_map]
      rintro ⟨c, hc, rfl⟩
      exact Or.inr (Or.inr <| Or.inr <| ⟨a, b, c, rfl, rfl, rfl, hc⟩)
  · rintro (⟨a, b, c, rfl, rfl, rfl, hc⟩ | ⟨a, b, c, rfl, rfl, rfl, hc⟩ |
      ⟨a, b, c, rfl, rfl, rfl, hc⟩ | ⟨a, b, c, rfl, rfl, rfl, hc⟩)
    · exact mem_map_of_mem _ hc
    · exact inl_mem_disjSum.2 hc
    · exact inr_mem_disjSum.2 hc
    · exact mem_map_of_mem _ hc
```

-- snippet 77
```lean
-- Mathlib.Data.Sum.Order.noMaxOrder (L197-L206)
instance noMaxOrder [LT α] [LT β] [NoMaxOrder α] [NoMaxOrder β] : NoMaxOrder (α ⊕ β) :=
⟨fun a =>
    match a with
    | inl a =>
      let ⟨b, h⟩ := exists_gt a
      ⟨inl b, inl_lt_inl_iff.2 h⟩
    | inr a =>
      let ⟨b, h⟩ := exists_gt a
      ⟨inr b, inr_lt_inr_iff.2 h⟩⟩
```

-- snippet 78
```lean
-- Mathlib.Data.Sum.Order.denselyOrdered (L233-L243)
instance denselyOrdered [LT α] [LT β] [DenselyOrdered α] [DenselyOrdered β] :
    DenselyOrdered (α ⊕ β) :=
⟨fun a b h =>
    match a, b, h with
    | inl _, inl _, LiftRel.inl h =>
      let ⟨c, ha, hb⟩ := exists_between h
      ⟨toLex (inl c), LiftRel.inl ha, LiftRel.inl hb⟩
    | inr _, inr _, LiftRel.inr h =>
      let ⟨c, ha, hb⟩ := exists_between h
      ⟨toLex (inr c), LiftRel.inr ha, LiftRel.inr hb⟩⟩
```

-- snippet 79
```lean
-- Mathlib.Data.Sum.Interval.Ioi_inr (L319-L332)
theorem Ioi_inr : Ioi (inr b : α ⊕ β) = (Ioi b).map Embedding.inr := rfl
end LocallyFiniteOrderTop

end Disjoint

/-! ### Lexicographical sum of orders -/

namespace Lex

section LocallyFiniteOrder
variable [Preorder α] [Preorder β] [LocallyFiniteOrder α] [LocallyFiniteOrder β]
variable [LocallyFiniteOrderTop α] [LocallyFiniteOrderBot β]
```

-- snippet 80
```lean
-- Mathlib.Data.Sum.Order.inl_le_inl_iff (L125-L127)
theorem inl_le_inl_iff [LE α] [LE β] {a b : α} : (inl a : α ⊕ β) ≤ inl b ↔ a ≤ b :=
liftRel_inl_inl
```

-- snippet 81
```lean
-- Mathlib.Data.Sum.Order.instLTSum (L115-L117)
instance instLTSum [LT α] [LT β] : LT (α ⊕ β) :=
⟨LiftRel (· < ·) (· < ·)⟩
```

-- snippet 82
```lean
-- Mathlib.Data.Sum.Interval.Ioo_inl_inr (L254-L256)
theorem Ioo_inl_inr : Ioo (inl a₁) (inr b₂) = ∅ :=
rfl
```

-- snippet 83
```lean
-- Mathlib.Data.Sum.Order.inr_strictMono (L179-L182)
theorem inr_strictMono : StrictMono (inr : β → α ⊕ β) := fun _ _ => LiftRel.inr
end Preorder
```

-- snippet 84
```lean
-- Mathlib.Data.Sum.Interval.inl_mem_sumLift₂ (L60-L66)
theorem inl_mem_sumLift₂ {c₁ : γ₁} :
    inl c₁ ∈ sumLift₂ f g a b ↔ ∃ a₁ b₁, a = inl a₁ ∧ b = inl b₁ ∧ c₁ ∈ f a₁ b₁ := by
rw [mem_sumLift₂, or_iff_left]
  · simp only [inl.injEq, exists_and_left, exists_eq_left']
  rintro ⟨_, _, c₂, _, _, h, _⟩
  exact inl_ne_inr h
```

-- snippet 85
```lean
-- Mathlib.Data.Sum.Order.swap_le_swap_iff (L259-L261)
theorem swap_le_swap_iff [LE α] [LE β] {a b : α ⊕ β} : a.swap ≤ b.swap ↔ a ≤ b :=
liftRel_swap_iff
```

-- snippet 86
```lean
-- Mathlib.Data.Sum.Interval.instLocallyFiniteOrder (L217-L228)
instance instLocallyFiniteOrder : LocallyFiniteOrder (α ⊕ β) where
  finsetIcc := sumLift₂ Icc Icc
finsetIco := sumLift₂ Ico Ico
  finsetIoc := sumLift₂ Ioc Ioc
  finsetIoo := sumLift₂ Ioo Ioo
  finset_mem_Icc := by simp
  finset_mem_Ico := by simp
  finset_mem_Ioc := by simp
  finset_mem_Ioo := by simp

variable (a₁ a₂ : α) (b₁ b₂ : β)
```

-- snippet 87
```lean
-- Mathlib.Data.Sum.Order.toLexRelIsoLT_coe (L344-L346)
theorem toLexRelIsoLT_coe [LT α] [LT β] : ⇑(toLexRelIsoLT (α := α) (β := β)) = toLex :=
rfl
```

-- snippet 88
```lean
-- Mathlib.Data.Sum.Interval.Iic_inr (L299-L299)
theorem Iic_inr : Iic (inr b : α ⊕ β) = (Iic b).map Embedding.inr := rfl
```

-- snippet 89
```lean
-- Mathlib.Data.Sum.Lattice.instLattice (L94-L96)
instance instLattice : Lattice (α ⊕ₗ β) := { instSemilatticeSup, instSemilatticeInf with }
/-- `Sum.Lex.inlₗ` as a lattice homomorphism. -/
```

-- snippet 90
```lean
-- Mathlib.Data.Sum.Interval.Ico_inl_inl (L232-L234)
theorem Ico_inl_inl : Ico (inl a₁ : α ⊕ β) (inl a₂) = (Ico a₁ a₂).map Embedding.inl :=
rfl
```

-- snippet 91
```lean
-- Mathlib.Data.Sum.Interval.locallyFiniteOrder (L333-L348)
instance locallyFiniteOrder : LocallyFiniteOrder (α ⊕ₗ β) where
  finsetIcc a b :=
(sumLexLift Icc Icc (fun a _ => Ici a) (fun _ => Iic) (ofLex a) (ofLex b)).map toLex.toEmbedding
  finsetIco a b :=
    (sumLexLift Ico Ico (fun a _ => Ici a) (fun _ => Iio) (ofLex a) (ofLex b)).map toLex.toEmbedding
  finsetIoc a b :=
    (sumLexLift Ioc Ioc (fun a _ => Ioi a) (fun _ => Iic) (ofLex a) (ofLex b)).map toLex.toEmbedding
  finsetIoo a b :=
    (sumLexLift Ioo Ioo (fun a _ => Ioi a) (fun _ => Iio) (ofLex a) (ofLex b)).map toLex.toEmbedding
  finset_mem_Icc := by simp
  finset_mem_Ico := by simp
  finset_mem_Ioc := by simp
  finset_mem_Ioo := by simp

variable (a a₁ a₂ : α) (b b₁ b₂ : β)
```

-- snippet 92
```lean
-- Mathlib.Data.Sum.Order.instLESum (L112-L114)
instance instLESum [LE α] [LE β] : LE (α ⊕ β) :=
⟨LiftRel (· ≤ ·) (· ≤ ·)⟩
```

-- snippet 93
```lean
-- Mathlib.Data.Sum.Interval.instLocallyFiniteOrderBot (L410-L421)
instance instLocallyFiniteOrderBot : LocallyFiniteOrderBot (α ⊕ₗ β) where
  finsetIic := Sum.elim
(Iic · |>.map (.trans .inl toLex.toEmbedding))
    (fun x => Finset.univ.disjSum (Iic x) |>.map toLex.toEmbedding) ∘ ofLex
  finsetIio := Sum.elim
    (Iio · |>.map (.trans .inl toLex.toEmbedding))
    (fun x => Finset.univ.disjSum (Iio x) |>.map toLex.toEmbedding) ∘ ofLex
  finset_mem_Iic := by simp
  finset_mem_Iio := by simp

variable (a : α) (b : β)
```

-- snippet 94
```lean
-- Mathlib.Data.Sum.Interval.sumLexLift_eq_empty (L179-L192)
lemma sumLexLift_eq_empty :
    sumLexLift f₁ f₂ g₁ g₂ a b = ∅ ↔
      (∀ a₁ b₁, a = inl a₁ → b = inl b₁ → f₁ a₁ b₁ = ∅) ∧
        (∀ a₁ b₂, a = inl a₁ → b = inr b₂ → g₁ a₁ b₂ = ∅ ∧ g₂ a₁ b₂ = ∅) ∧
          ∀ a₂ b₂, a = inr a₂ → b = inr b₂ → f₂ a₂ b₂ = ∅ := by
refine ⟨fun h ↦ ⟨?_, ?_, ?_⟩, fun h ↦ ?_⟩
  any_goals rintro a b rfl rfl; exact map_eq_empty.1 h
  · rintro a b rfl rfl; exact disjSum_eq_empty.1 h
  cases a <;> cases b
  · exact map_eq_empty.2 (h.1 _ _ rfl rfl)
  · simp [h.2.1 _ _ rfl rfl]
  · rfl
  · exact map_eq_empty.2 (h.2.2 _ _ rfl rfl)
```

-- snippet 95
```lean
-- Mathlib.Data.Sum.Interval.Ioc_inl_inl (L235-L237)
theorem Ioc_inl_inl : Ioc (inl a₁ : α ⊕ β) (inl a₂) = (Ioc a₁ a₂).map Embedding.inl :=
rfl
```

-- snippet 96
```lean
-- Mathlib.Data.Sum.Interval.inr_mem_sumLexLift (L166-L171)
lemma inr_mem_sumLexLift {c₂ : γ₂} :
    inr c₂ ∈ sumLexLift f₁ f₂ g₁ g₂ a b ↔
      (∃ a₁ b₂, a = inl a₁ ∧ b = inr b₂ ∧ c₂ ∈ g₂ a₁ b₂) ∨
        ∃ a₂ b₂, a = inr a₂ ∧ b = inr b₂ ∧ c₂ ∈ f₂ a₂ b₂ := by
simp [mem_sumLexLift]
```

-- snippet 97
```lean
-- Mathlib.Data.Sum.Interval.Ioo_inl_inl (L238-L240)
theorem Ioo_inl_inl : Ioo (inl a₁ : α ⊕ β) (inl a₂) = (Ioo a₁ a₂).map Embedding.inl :=
rfl
```

-- snippet 98
```lean
-- Mathlib.Data.Sum.Interval.Iio_inr (L301-L307)
theorem Iio_inr : Iio (inr b : α ⊕ β) = (Iio b).map Embedding.inr := rfl
end LocallyFiniteOrderBot

section LocallyFiniteOrderTop
variable [Preorder α] [Preorder β] [LocallyFiniteOrderTop α] [LocallyFiniteOrderTop β]
```

-- snippet 99
```lean
-- Mathlib.Data.Sum.Interval.sumLexLift_mono (L172-L178)
lemma sumLexLift_mono (hf₁ : ∀ a b, f₁ a b ⊆ f₁' a b) (hf₂ : ∀ a b, f₂ a b ⊆ f₂' a b)
    (hg₁ : ∀ a b, g₁ a b ⊆ g₁' a b) (hg₂ : ∀ a b, g₂ a b ⊆ g₂' a b) (a : α₁ ⊕ α₂)
    (b : β₁ ⊕ β₂) : sumLexLift f₁ f₂ g₁ g₂ a b ⊆ sumLexLift f₁' f₂' g₁' g₂' a b := by
cases a <;> cases b
  exacts [map_subset_map.2 (hf₁ _ _), disjSum_mono (hg₁ _ _) (hg₂ _ _), Subset.rfl,
    map_subset_map.2 (hf₂ _ _)]
```

-- snippet 100
```lean
-- Mathlib.Data.Sum.Order.toLex_lt_toLex (L302-L305)
theorem toLex_lt_toLex [LT α] [LT β] {a b : α ⊕ β} :
    toLex a < toLex b ↔ Lex (· < ·) (· < ·) a b :=
Iff.rfl
```

-- snippet 101
```lean
-- Mathlib.Data.Sum.Order.not_inl_le_inr (L141-L143)
theorem not_inl_le_inr [LE α] [LE β] {a : α} {b : β} : ¬inl b ≤ inr a :=
not_liftRel_inl_inr
```

-- snippet 102
```lean
-- Mathlib.Data.Sum.Order.toLexRelIsoLT_symm_coe (L348-L351)
theorem toLexRelIsoLT_symm_coe [LT α] [LT β] : ⇑(toLexRelIsoLT (α := α) (β := β)).symm = ofLex :=
rfl

/-- `toLex` promoted to a `RelIso` between `≤` relations. -/
```

-- snippet 103
```lean
-- Mathlib.Data.Sum.Lattice.inlLatticeHom (L97-L102)
def inlLatticeHom : LatticeHom α (α ⊕ₗ β) where
  toFun := inlₗ
map_sup' _ _ := rfl
  map_inf' _ _ := rfl

/-- `Sum.Lex.inrₗ` as a lattice homomorphism. -/
```

-- snippet 104
```lean
-- Mathlib.Data.Sum.Interval.Ico_inl_inr (L246-L248)
theorem Ico_inl_inr : Ico (inl a₁) (inr b₂) = ∅ :=
rfl
```

-- snippet 105
```lean
-- Mathlib.Data.Sum.Order.inr_mono (L175-L176)
theorem inr_mono : Monotone (inr : β → α ⊕ β) := fun _ _ => LiftRel.inr
```
[/INST]


[System] You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.RingTheory.AdjoinRoot).

[User]
Prove the following theorem. The retrieved context below may help.

```lean
lemma liftAlgHom_of (i : R →ₐ[S] T) (x : T) (h) (r : R) : liftAlgHom p i x h (of p r) = i r
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.RingTheory.AdjoinRoot.AdjoinRoot (L62-L72)
def AdjoinRoot [CommRing R] (f : R[X]) : Type _ :=
Polynomial R ⧸ (span {f} : Ideal R[X])

namespace AdjoinRoot

section CommRing

variable [CommRing R] (f g : R[X])

deriving instance CommRing, Inhabited for AdjoinRoot
```

-- snippet 2
```lean
-- Mathlib.RingTheory.AdjoinRoot.mk (L83-L85)
def mk : R[X] →+* AdjoinRoot f :=
Ideal.Quotient.mk _
```

-- snippet 3
```lean
-- Mathlib.RingTheory.AdjoinRoot.induction_on (L87-L91)
theorem induction_on {C : AdjoinRoot f → Prop} (x : AdjoinRoot f) (ih : ∀ p : R[X], C (mk f p)) :
    C x :=
Quotient.inductionOn' x ih

/-- Embedding of the original ring `R` into `AdjoinRoot f`. -/
```

-- snippet 4
```lean
-- Mathlib.RingTheory.AdjoinRoot.of (L92-L94)
def of : R →+* AdjoinRoot f :=
(mk f).comp C
```

-- snippet 5
```lean
-- Mathlib.RingTheory.AdjoinRoot.instSMulAdjoinRoot (L95-L97)
instance instSMulAdjoinRoot [DistribSMul S R] [IsScalarTower S R R] : SMul S (AdjoinRoot f) :=
inferInstanceAs <| SMul S (_ ⧸ _)
```

-- snippet 6
```lean
-- Mathlib.RingTheory.AdjoinRoot.smul_mk (L102-L105)
theorem smul_mk [DistribSMul S R] [IsScalarTower S R R] (a : S) (x : R[X]) :
    a • mk f x = mk f (a • x) :=
rfl
```

-- snippet 7
```lean
-- Mathlib.RingTheory.AdjoinRoot.smul_of (L106-L108)
theorem smul_of [DistribSMul S R] [IsScalarTower S R R] (a : S) (x : R) :
    a • of f x = of f (a • x) := by rw [of, RingHom.comp_apply, RingHom.comp_apply, smul_mk, smul_C]
```

-- snippet 8
```lean
-- Mathlib.RingTheory.AdjoinRoot.isScalarTower_right (L119-L122)
instance isScalarTower_right [DistribSMul S R] [IsScalarTower S R R] :
    IsScalarTower S (AdjoinRoot f) (AdjoinRoot f) :=
inferInstanceAs <| IsScalarTower S (_ ⧸ _) (_ ⧸ _)
```

-- snippet 9
```lean
-- Mathlib.RingTheory.AdjoinRoot.mkₐ (L134-L136)
def mkₐ : R[X] →ₐ[R] AdjoinRoot f :=
Ideal.Quotient.mkₐ R _
```

-- snippet 10
```lean
-- Mathlib.RingTheory.AdjoinRoot.algebraMap_eq (L142-L145)
theorem algebraMap_eq : algebraMap R (AdjoinRoot f) = of f :=
rfl

variable (S) in
```

-- snippet 11
```lean
-- Mathlib.RingTheory.AdjoinRoot.algebraMap_eq' (L146-L149)
theorem algebraMap_eq' [CommSemiring S] [Algebra S R] :
    algebraMap S (AdjoinRoot f) = (of f).comp (algebraMap S R) :=
rfl
```

-- snippet 12
```lean
-- Mathlib.RingTheory.AdjoinRoot.finiteType (L150-L153)
instance finiteType [CommSemiring S] [Algebra S R] [FiniteType S R] :
    FiniteType S (AdjoinRoot f) :=
inferInstanceAs <| FiniteType S (_ ⧸ (_ : Ideal R[X]))
```

-- snippet 13
```lean
-- Mathlib.RingTheory.AdjoinRoot.finitePresentation (L154-L158)
instance finitePresentation [CommRing S] [Algebra S R] [FinitePresentation S R] :
    FinitePresentation S (AdjoinRoot f) :=
.quotient (Submodule.fg_span_singleton f)

/-- The adjoined root. -/
```

-- snippet 14
```lean
-- Mathlib.RingTheory.AdjoinRoot.root (L159-L166)
def root : AdjoinRoot f :=
mk f X

section Algebra
variable [CommSemiring S] [Semiring T] [Algebra S R] [Algebra S T] (p : R[X])

variable (S) in
/-- Embedding of the original ring `R` into `AdjoinRoot p`. -/
```

-- snippet 15
```lean
-- Mathlib.RingTheory.AdjoinRoot.ofAlgHom (L167-L168)
abbrev ofAlgHom : R →ₐ[S] AdjoinRoot p := Algebra.algHom S R <| AdjoinRoot p
```

-- snippet 16
```lean
-- Mathlib.RingTheory.AdjoinRoot.ringHom_ext (L176-L182)
lemma ringHom_ext {f g : AdjoinRoot p →+* T} (hAlg : f.comp (of p) = g.comp (of p))
    (hRoot : f (root p) = g (root p)) : f = g := by
apply Ideal.Quotient.ringHom_ext
  ext x
  · simpa using congr($(hAlg) x)
  · simpa
```

-- snippet 17
```lean
-- Mathlib.RingTheory.AdjoinRoot.algHom_ext' (L184-L192)
lemma algHom_ext' {f g : AdjoinRoot p →ₐ[S] T}
    (hAlg : f.comp (ofAlgHom S p) = g.comp (ofAlgHom S p))
    (hRoot : f (root p) = g (root p)) : f = g := by
apply AlgHom.coe_ringHom_injective; exact ringHom_ext congr(($hAlg).toRingHom) hRoot

end Algebra

variable {f g}
```

-- snippet 18
```lean
-- Mathlib.RingTheory.AdjoinRoot.hasCoeT (L193-L197)
instance hasCoeT : CoeTC R (AdjoinRoot f) :=
⟨of f⟩

/-- Two `R`-`AlgHom` from `AdjoinRoot f` to the same `R`-algebra are the same iff
they agree on `root f`. -/
```

-- snippet 19
```lean
-- Mathlib.RingTheory.AdjoinRoot.algHom_ext (L199-L202)
theorem algHom_ext [Semiring S] [Algebra R S] {g₁ g₂ : AdjoinRoot f →ₐ[R] S}
    (h : g₁ (root f) = g₂ (root f)) : g₁ = g₂ :=
Ideal.Quotient.algHom_ext R <| Polynomial.algHom_ext h
```

-- snippet 20
```lean
-- Mathlib.RingTheory.AdjoinRoot.mk_eq_mk (L204-L206)
theorem mk_eq_mk {g h : R[X]} : mk f g = mk f h ↔ f ∣ g - h :=
Ideal.Quotient.eq.trans Ideal.mem_span_singleton
```

-- snippet 21
```lean
-- Mathlib.RingTheory.AdjoinRoot.mk_eq_zero (L208-L210)
theorem mk_eq_zero {g : R[X]} : mk f g = 0 ↔ f ∣ g :=
mk_eq_mk.trans <| by rw [sub_zero]
```

-- snippet 22
```lean
-- Mathlib.RingTheory.AdjoinRoot.mk_self (L212-L214)
theorem mk_self : mk f f = 0 :=
Quotient.sound' <| QuotientAddGroup.leftRel_apply.mpr (mem_span_singleton.2 <| by simp)
```

-- snippet 23
```lean
-- Mathlib.RingTheory.AdjoinRoot.mk_C (L216-L218)
theorem mk_C (x : R) : mk f (C x) = x :=
rfl
```

-- snippet 24
```lean
-- Mathlib.RingTheory.AdjoinRoot.mk_X (L220-L222)
theorem mk_X : mk f X = root f :=
rfl
```

-- snippet 25
```lean
-- Mathlib.RingTheory.AdjoinRoot.mk_ne_zero_of_degree_lt (L223-L226)
theorem mk_ne_zero_of_degree_lt (hf : Monic f) {g : R[X]} (h0 : g ≠ 0) (hd : degree g < degree f) :
    mk f g ≠ 0 :=
mk_eq_zero.not.2 <| hf.not_dvd_of_degree_lt h0 hd
```

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.RingTheory.AdjoinRoot).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Prove the following theorem. The retrieved context below may help.

```lean
lemma liftAlgHom_of (i : R →ₐ[S] T) (x : T) (h) (r : R) : liftAlgHom p i x h (of p r) = i r
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.RingTheory.AdjoinRoot.AdjoinRoot (L62-L72)
def AdjoinRoot [CommRing R] (f : R[X]) : Type _ :=
Polynomial R ⧸ (span {f} : Ideal R[X])

namespace AdjoinRoot

section CommRing

variable [CommRing R] (f g : R[X])

deriving instance CommRing, Inhabited for AdjoinRoot
```

-- snippet 2
```lean
-- Mathlib.RingTheory.AdjoinRoot.mk (L83-L85)
def mk : R[X] →+* AdjoinRoot f :=
Ideal.Quotient.mk _
```

-- snippet 3
```lean
-- Mathlib.RingTheory.AdjoinRoot.induction_on (L87-L91)
theorem induction_on {C : AdjoinRoot f → Prop} (x : AdjoinRoot f) (ih : ∀ p : R[X], C (mk f p)) :
    C x :=
Quotient.inductionOn' x ih

/-- Embedding of the original ring `R` into `AdjoinRoot f`. -/
```

-- snippet 4
```lean
-- Mathlib.RingTheory.AdjoinRoot.of (L92-L94)
def of : R →+* AdjoinRoot f :=
(mk f).comp C
```

-- snippet 5
```lean
-- Mathlib.RingTheory.AdjoinRoot.instSMulAdjoinRoot (L95-L97)
instance instSMulAdjoinRoot [DistribSMul S R] [IsScalarTower S R R] : SMul S (AdjoinRoot f) :=
inferInstanceAs <| SMul S (_ ⧸ _)
```

-- snippet 6
```lean
-- Mathlib.RingTheory.AdjoinRoot.smul_mk (L102-L105)
theorem smul_mk [DistribSMul S R] [IsScalarTower S R R] (a : S) (x : R[X]) :
    a • mk f x = mk f (a • x) :=
rfl
```

-- snippet 7
```lean
-- Mathlib.RingTheory.AdjoinRoot.smul_of (L106-L108)
theorem smul_of [DistribSMul S R] [IsScalarTower S R R] (a : S) (x : R) :
    a • of f x = of f (a • x) := by rw [of, RingHom.comp_apply, RingHom.comp_apply, smul_mk, smul_C]
```

-- snippet 8
```lean
-- Mathlib.RingTheory.AdjoinRoot.isScalarTower_right (L119-L122)
instance isScalarTower_right [DistribSMul S R] [IsScalarTower S R R] :
    IsScalarTower S (AdjoinRoot f) (AdjoinRoot f) :=
inferInstanceAs <| IsScalarTower S (_ ⧸ _) (_ ⧸ _)
```

-- snippet 9
```lean
-- Mathlib.RingTheory.AdjoinRoot.mkₐ (L134-L136)
def mkₐ : R[X] →ₐ[R] AdjoinRoot f :=
Ideal.Quotient.mkₐ R _
```

-- snippet 10
```lean
-- Mathlib.RingTheory.AdjoinRoot.algebraMap_eq (L142-L145)
theorem algebraMap_eq : algebraMap R (AdjoinRoot f) = of f :=
rfl

variable (S) in
```

-- snippet 11
```lean
-- Mathlib.RingTheory.AdjoinRoot.algebraMap_eq' (L146-L149)
theorem algebraMap_eq' [CommSemiring S] [Algebra S R] :
    algebraMap S (AdjoinRoot f) = (of f).comp (algebraMap S R) :=
rfl
```

-- snippet 12
```lean
-- Mathlib.RingTheory.AdjoinRoot.finiteType (L150-L153)
instance finiteType [CommSemiring S] [Algebra S R] [FiniteType S R] :
    FiniteType S (AdjoinRoot f) :=
inferInstanceAs <| FiniteType S (_ ⧸ (_ : Ideal R[X]))
```

-- snippet 13
```lean
-- Mathlib.RingTheory.AdjoinRoot.finitePresentation (L154-L158)
instance finitePresentation [CommRing S] [Algebra S R] [FinitePresentation S R] :
    FinitePresentation S (AdjoinRoot f) :=
.quotient (Submodule.fg_span_singleton f)

/-- The adjoined root. -/
```

-- snippet 14
```lean
-- Mathlib.RingTheory.AdjoinRoot.root (L159-L166)
def root : AdjoinRoot f :=
mk f X

section Algebra
variable [CommSemiring S] [Semiring T] [Algebra S R] [Algebra S T] (p : R[X])

variable (S) in
/-- Embedding of the original ring `R` into `AdjoinRoot p`. -/
```

-- snippet 15
```lean
-- Mathlib.RingTheory.AdjoinRoot.ofAlgHom (L167-L168)
abbrev ofAlgHom : R →ₐ[S] AdjoinRoot p := Algebra.algHom S R <| AdjoinRoot p
```

-- snippet 16
```lean
-- Mathlib.RingTheory.AdjoinRoot.ringHom_ext (L176-L182)
lemma ringHom_ext {f g : AdjoinRoot p →+* T} (hAlg : f.comp (of p) = g.comp (of p))
    (hRoot : f (root p) = g (root p)) : f = g := by
apply Ideal.Quotient.ringHom_ext
  ext x
  · simpa using congr($(hAlg) x)
  · simpa
```

-- snippet 17
```lean
-- Mathlib.RingTheory.AdjoinRoot.algHom_ext' (L184-L192)
lemma algHom_ext' {f g : AdjoinRoot p →ₐ[S] T}
    (hAlg : f.comp (ofAlgHom S p) = g.comp (ofAlgHom S p))
    (hRoot : f (root p) = g (root p)) : f = g := by
apply AlgHom.coe_ringHom_injective; exact ringHom_ext congr(($hAlg).toRingHom) hRoot

end Algebra

variable {f g}
```

-- snippet 18
```lean
-- Mathlib.RingTheory.AdjoinRoot.hasCoeT (L193-L197)
instance hasCoeT : CoeTC R (AdjoinRoot f) :=
⟨of f⟩

/-- Two `R`-`AlgHom` from `AdjoinRoot f` to the same `R`-algebra are the same iff
they agree on `root f`. -/
```

-- snippet 19
```lean
-- Mathlib.RingTheory.AdjoinRoot.algHom_ext (L199-L202)
theorem algHom_ext [Semiring S] [Algebra R S] {g₁ g₂ : AdjoinRoot f →ₐ[R] S}
    (h : g₁ (root f) = g₂ (root f)) : g₁ = g₂ :=
Ideal.Quotient.algHom_ext R <| Polynomial.algHom_ext h
```

-- snippet 20
```lean
-- Mathlib.RingTheory.AdjoinRoot.mk_eq_mk (L204-L206)
theorem mk_eq_mk {g h : R[X]} : mk f g = mk f h ↔ f ∣ g - h :=
Ideal.Quotient.eq.trans Ideal.mem_span_singleton
```

-- snippet 21
```lean
-- Mathlib.RingTheory.AdjoinRoot.mk_eq_zero (L208-L210)
theorem mk_eq_zero {g : R[X]} : mk f g = 0 ↔ f ∣ g :=
mk_eq_mk.trans <| by rw [sub_zero]
```

-- snippet 22
```lean
-- Mathlib.RingTheory.AdjoinRoot.mk_self (L212-L214)
theorem mk_self : mk f f = 0 :=
Quotient.sound' <| QuotientAddGroup.leftRel_apply.mpr (mem_span_singleton.2 <| by simp)
```

-- snippet 23
```lean
-- Mathlib.RingTheory.AdjoinRoot.mk_C (L216-L218)
theorem mk_C (x : R) : mk f (C x) = x :=
rfl
```

-- snippet 24
```lean
-- Mathlib.RingTheory.AdjoinRoot.mk_X (L220-L222)
theorem mk_X : mk f X = root f :=
rfl
```

-- snippet 25
```lean
-- Mathlib.RingTheory.AdjoinRoot.mk_ne_zero_of_degree_lt (L223-L226)
theorem mk_ne_zero_of_degree_lt (hf : Monic f) {g : R[X]} (h0 : g ≠ 0) (hd : degree g < degree f) :
    mk f g ≠ 0 :=
mk_eq_zero.not.2 <| hf.not_dvd_of_degree_lt h0 hd
```
[/INST]

mistral-common:Tekken v15 (Mistral chat template, [INST]/[SYSTEM_PROMPT])