l3lab/ntp-mathlib huggingface dataset:
/-- This is the infinitary Erdős–Szekeres theorem, and an important lemma in the usual proof of
    Bolzano-Weierstrass for `ℝ`. -/
theorem exists_increasing_or_nonincreasing_subseq (r : α → α → Prop) [IsTrans α r] (f : ℕ → α) :
    ∃ g : ℕ ↪o ℕ,
      (∀ m n : ℕ, m < n → r (f (g m)) (f (g n))) ∨ ∀ m n : ℕ, m < n → ¬r (f (g m)) (f (g n)) := by
  obtain ⟨g, hr | hnr⟩ := exists_increasing_or_nonincreasing_subseq' r f
  · refine' ⟨g, Or.intro_left _ fun m n mn => _⟩
    obtain ⟨x, rfl⟩ := exists_add_of_le (Nat.succ_le_iff.2 mn)
    induction' x with x ih
    · apply hr
    · 

Proof state:
case intro.inl.intro.succ
α : Type u_1
r : α → α → Prop
inst✝ : IsTrans α r
f : ℕ → α
g : ℕ ↪o ℕ
hr : ∀ (n : ℕ), r (f (g n)) (f (g (n + 1)))
m x : ℕ
ih : m < Nat.succ m + x → r (f (g m)) (f (g (Nat.succ m + x)))
mn : m < Nat.succ m + Nat.succ x
⊢ r (f (g m)) (f (g (Nat.succ m + Nat.succ x)))

Next tactic:
apply IsTrans.trans _ _ _ _ (hr _)
/-- This is the infinitary Erdős–Szekeres theorem, and an important lemma in the usual proof of
    Bolzano-Weierstrass for `ℝ`. -/
theorem exists_increasing_or_nonincreasing_subseq (r : α → α → Prop) [IsTrans α r] (f : ℕ → α) :
    ∃ g : ℕ ↪o ℕ,
      (∀ m n : ℕ, m < n → r (f (g m)) (f (g n))) ∨ ∀ m n : ℕ, m < n → ¬r (f (g m)) (f (g n)) := by
  obtain ⟨g, hr | hnr⟩ := exists_increasing_or_nonincreasing_subseq' r f
  · refine' ⟨g, Or.intro_left _ fun m n mn => _⟩
    obtain ⟨x, rfl⟩ := exists_add_of_le (Nat.succ_le_iff.2 mn)
    induction' x with x ih
    · apply hr
    · apply IsTrans.trans _ _ _ _ (hr _)
      

Proof state:
α : Type u_1
r : α → α → Prop
inst✝ : IsTrans α r
f : ℕ → α
g : ℕ ↪o ℕ
hr : ∀ (n : ℕ), r (f (g n)) (f (g (n + 1)))
m x : ℕ
ih : m < Nat.succ m + x → r (f (g m)) (f (g (Nat.succ m + x)))
mn : m < Nat.succ m + Nat.succ x
⊢ r (f (g m)) (f (g (Nat.add (Nat.succ m) x)))

Next tactic:
exact ih (lt_of_lt_of_le m.lt_succ_self (Nat.le_add_right _ _))
/-- This is the infinitary Erdős–Szekeres theorem, and an important lemma in the usual proof of
    Bolzano-Weierstrass for `ℝ`. -/
theorem exists_increasing_or_nonincreasing_subseq (r : α → α → Prop) [IsTrans α r] (f : ℕ → α) :
    ∃ g : ℕ ↪o ℕ,
      (∀ m n : ℕ, m < n → r (f (g m)) (f (g n))) ∨ ∀ m n : ℕ, m < n → ¬r (f (g m)) (f (g n)) := by
  obtain ⟨g, hr | hnr⟩ := exists_increasing_or_nonincreasing_subseq' r f
  · refine' ⟨g, Or.intro_left _ fun m n mn => _⟩
    obtain ⟨x, rfl⟩ := exists_add_of_le (Nat.succ_le_iff.2 mn)
    induction' x with x ih
    · apply hr
    · apply IsTrans.trans _ _ _ _ (hr _)
      exact ih (lt_of_lt_of_le m.lt_succ_self (Nat.le_add_right _ _))
  · 

Proof state:
case intro.inr
α : Type u_1
r : α → α → Prop
inst✝ : IsTrans α r
f : ℕ → α
g : ℕ ↪o ℕ
hnr : ∀ (m n : ℕ), m < n → ¬r (f (g m)) (f (g n))
⊢ ∃ g, (∀ (m n : ℕ), m < n → r (f (g m)) (f (g n))) ∨ ∀ (m n : ℕ), m < n → ¬r (f (g m)) (f (g n))

Next tactic:
exact ⟨g, Or.intro_right _ hnr⟩
theorem WellFounded.monotone_chain_condition' [Preorder α] :
    WellFounded ((· > ·) : α → α → Prop) ↔ ∀ a : ℕ →o α, ∃ n, ∀ m, n ≤ m → ¬a n < a m := by
  

Proof state:
α : Type u_1
inst✝ : Preorder α
⊢ (WellFounded fun x x_1 => x > x_1) ↔ ∀ (a : ℕ →o α), ∃ n, ∀ (m : ℕ), n ≤ m → ¬a n < a m

Next tactic:
refine' ⟨fun h a => _, fun h => _⟩
theorem WellFounded.monotone_chain_condition' [Preorder α] :
    WellFounded ((· > ·) : α → α → Prop) ↔ ∀ a : ℕ →o α, ∃ n, ∀ m, n ≤ m → ¬a n < a m := by
  refine' ⟨fun h a => _, fun h => _⟩
  · 

Proof state:
case refine'_1
α : Type u_1
inst✝ : Preorder α
h : WellFounded fun x x_1 => x > x_1
a : ℕ →o α
⊢ ∃ n, ∀ (m : ℕ), n ≤ m → ¬a n < a m

Next tactic:
have hne : (Set.range a).Nonempty := ⟨a 0, by simp⟩
theorem WellFounded.monotone_chain_condition' [Preorder α] :
    WellFounded ((· > ·) : α → α → Prop) ↔ ∀ a : ℕ →o α, ∃ n, ∀ m, n ≤ m → ¬a n < a m := by
  refine' ⟨fun h a => _, fun h => _⟩
  · have hne : (Set.range a).Nonempty := ⟨a 0, by 

Proof state:
α : Type u_1
inst✝ : Preorder α
h : WellFounded fun x x_1 => x > x_1
a : ℕ →o α
⊢ a 0 ∈ Set.range ⇑a

Next tactic:
simp
theorem WellFounded.monotone_chain_condition' [Preorder α] :
    WellFounded ((· > ·) : α → α → Prop) ↔ ∀ a : ℕ →o α, ∃ n, ∀ m, n ≤ m → ¬a n < a m := by
  refine' ⟨fun h a => _, fun h => _⟩
  · have hne : (Set.range a).Nonempty := ⟨a 0, by simp⟩
    

Proof state:
case refine'_1
α : Type u_1
inst✝ : Preorder α
h : WellFounded fun x x_1 => x > x_1
a : ℕ →o α
hne : Set.Nonempty (Set.range ⇑a)
⊢ ∃ n, ∀ (m : ℕ), n ≤ m → ¬a n < a m

Next tactic:
obtain ⟨x, ⟨n, rfl⟩, H⟩ := h.has_min _ hne
theorem WellFounded.monotone_chain_condition' [Preorder α] :
    WellFounded ((· > ·) : α → α → Prop) ↔ ∀ a : ℕ →o α, ∃ n, ∀ m, n ≤ m → ¬a n < a m := by
  refine' ⟨fun h a => _, fun h => _⟩
  · have hne : (Set.range a).Nonempty := ⟨a 0, by simp⟩
    obtain ⟨x, ⟨n, rfl⟩, H⟩ := h.has_min _ hne
    

Proof state:
case refine'_1.intro.intro.intro
α : Type u_1
inst✝ : Preorder α
h : WellFounded fun x x_1 => x > x_1
a : ℕ →o α
hne : Set.Nonempty (Set.range ⇑a)
n : ℕ
H : ∀ x ∈ Set.range ⇑a, ¬x > a n
⊢ ∃ n, ∀ (m : ℕ), n ≤ m → ¬a n < a m

Next tactic:
exact ⟨n, fun m _ => H _ (Set.mem_range_self _)⟩
theorem WellFounded.monotone_chain_condition' [Preorder α] :
    WellFounded ((· > ·) : α → α → Prop) ↔ ∀ a : ℕ →o α, ∃ n, ∀ m, n ≤ m → ¬a n < a m := by
  refine' ⟨fun h a => _, fun h => _⟩
  · have hne : (Set.range a).Nonempty := ⟨a 0, by simp⟩
    obtain ⟨x, ⟨n, rfl⟩, H⟩ := h.has_min _ hne
    exact ⟨n, fun m _ => H _ (Set.mem_range_self _)⟩
  · 

Proof state:
case refine'_2
α : Type u_1
inst✝ : Preorder α
h : ∀ (a : ℕ →o α), ∃ n, ∀ (m : ℕ), n ≤ m → ¬a n < a m
⊢ WellFounded fun x x_1 => x > x_1

Next tactic:
refine' RelEmbedding.wellFounded_iff_no_descending_seq.2 ⟨fun a => _⟩
theorem WellFounded.monotone_chain_condition' [Preorder α] :
    WellFounded ((· > ·) : α → α → Prop) ↔ ∀ a : ℕ →o α, ∃ n, ∀ m, n ≤ m → ¬a n < a m := by
  refine' ⟨fun h a => _, fun h => _⟩
  · have hne : (Set.range a).Nonempty := ⟨a 0, by simp⟩
    obtain ⟨x, ⟨n, rfl⟩, H⟩ := h.has_min _ hne
    exact ⟨n, fun m _ => H _ (Set.mem_range_self _)⟩
  · refine' RelEmbedding.wellFounded_iff_no_descending_seq.2 ⟨fun a => _⟩
    

Proof state:
case refine'_2
α : Type u_1
inst✝ : Preorder α
h : ∀ (a : ℕ →o α), ∃ n, ∀ (m : ℕ), n ≤ m → ¬a n < a m
a : (fun x x_1 => x > x_1) ↪r fun x x_1 => x > x_1
⊢ False

Next tactic:
obtain ⟨n, hn⟩ := h (a.swap : ((· < ·) : ℕ → ℕ → Prop) →r ((· < ·) : α → α → Prop)).toOrderHom
theorem WellFounded.monotone_chain_condition' [Preorder α] :
    WellFounded ((· > ·) : α → α → Prop) ↔ ∀ a : ℕ →o α, ∃ n, ∀ m, n ≤ m → ¬a n < a m := by
  refine' ⟨fun h a => _, fun h => _⟩
  · have hne : (Set.range a).Nonempty := ⟨a 0, by simp⟩
    obtain ⟨x, ⟨n, rfl⟩, H⟩ := h.has_min _ hne
    exact ⟨n, fun m _ => H _ (Set.mem_range_self _)⟩
  · refine' RelEmbedding.wellFounded_iff_no_descending_seq.2 ⟨fun a => _⟩
    obtain ⟨n, hn⟩ := h (a.swap : ((· < ·) : ℕ → ℕ → Prop) →r ((· < ·) : α → α → Prop)).toOrderHom
    

Proof state:
case refine'_2.intro
α : Type u_1
inst✝ : Preorder α
h : ∀ (a : ℕ →o α), ∃ n, ∀ (m : ℕ), n ≤ m → ¬a n < a m
a : (fun x x_1 => x > x_1) ↪r fun x x_1 => x > x_1
n : ℕ
hn :
  ∀ (m : ℕ),
    n ≤ m →
      ¬(RelHom.toOrderHom (RelEmbedding.toRelHom (RelEmbedding.swap a))) n <
          (RelHom.toOrderHom (RelEmbedding.toRelHom (RelEmbedding.swap a))) m
⊢ False

Next tactic:
exact hn n.succ n.lt_succ_self.le ((RelEmbedding.map_rel_iff _).2 n.lt_succ_self)
/-- The "monotone chain condition" below is sometimes a convenient form of well foundedness. -/
theorem WellFounded.monotone_chain_condition [PartialOrder α] :
    WellFounded ((· > ·) : α → α → Prop) ↔ ∀ a : ℕ →o α, ∃ n, ∀ m, n ≤ m → a n = a m :=
  WellFounded.monotone_chain_condition'.trans <| by
  

Proof state:
α : Type u_1
inst✝ : PartialOrder α
⊢ (∀ (a : ℕ →o α), ∃ n, ∀ (m : ℕ), n ≤ m → ¬a n < a m) ↔ ∀ (a : ℕ →o α), ∃ n, ∀ (m : ℕ), n ≤ m → a n = a m

Next tactic:
congrm ∀ a, ∃ n, ∀ m h, ?_
/-- The "monotone chain condition" below is sometimes a convenient form of well foundedness. -/
theorem WellFounded.monotone_chain_condition [PartialOrder α] :
    WellFounded ((· > ·) : α → α → Prop) ↔ ∀ a : ℕ →o α, ∃ n, ∀ m, n ≤ m → a n = a m :=
  WellFounded.monotone_chain_condition'.trans <| by
  congrm ∀ a, ∃ n, ∀ m h, ?_
  

Proof state:
case a
α : Type u_1
inst✝ : PartialOrder α
a : ℕ →o α
n m : ℕ
h : n ≤ m
⊢ ¬a n < a m ↔ a n = a m

Next tactic:
rw [lt_iff_le_and_ne]
/-- The "monotone chain condition" below is sometimes a convenient form of well foundedness. -/
theorem WellFounded.monotone_chain_condition [PartialOrder α] :
    WellFounded ((· > ·) : α → α → Prop) ↔ ∀ a : ℕ →o α, ∃ n, ∀ m, n ≤ m → a n = a m :=
  WellFounded.monotone_chain_condition'.trans <| by
  congrm ∀ a, ∃ n, ∀ m h, ?_
  rw [lt_iff_le_and_ne]
  

Proof state:
case a
α : Type u_1
inst✝ : PartialOrder α
a : ℕ →o α
n m : ℕ
h : n ≤ m
⊢ ¬(a n ≤ a m ∧ a n ≠ a m) ↔ a n = a m

Next tactic:
simp [a.mono h]
theorem WellFounded.iSup_eq_monotonicSequenceLimit [CompleteLattice α]
    (h : WellFounded ((· > ·) : α → α → Prop)) (a : ℕ →o α) :
    iSup a = monotonicSequenceLimit a := by
  

Proof state:
α : Type u_1
inst✝ : CompleteLattice α
h : WellFounded fun x x_1 => x > x_1
a : ℕ →o α
⊢ iSup ⇑a = monotonicSequenceLimit a

Next tactic:
refine' (iSup_le fun m => _).antisymm (le_iSup a _)
theorem WellFounded.iSup_eq_monotonicSequenceLimit [CompleteLattice α]
    (h : WellFounded ((· > ·) : α → α → Prop)) (a : ℕ →o α) :
    iSup a = monotonicSequenceLimit a := by
  refine' (iSup_le fun m => _).antisymm (le_iSup a _)
  

Proof state:
α : Type u_1
inst✝ : CompleteLattice α
h : WellFounded fun x x_1 => x > x_1
a : ℕ →o α
m : ℕ
⊢ a m ≤ monotonicSequenceLimit a

Next tactic:
rcases le_or_lt m (monotonicSequenceLimitIndex a) with hm | hm
theorem WellFounded.iSup_eq_monotonicSequenceLimit [CompleteLattice α]
    (h : WellFounded ((· > ·) : α → α → Prop)) (a : ℕ →o α) :
    iSup a = monotonicSequenceLimit a := by
  refine' (iSup_le fun m => _).antisymm (le_iSup a _)
  rcases le_or_lt m (monotonicSequenceLimitIndex a) with hm | hm
  · 

Proof state:
case inl
α : Type u_1
inst✝ : CompleteLattice α
h : WellFounded fun x x_1 => x > x_1
a : ℕ →o α
m : ℕ
hm : m ≤ monotonicSequenceLimitIndex a
⊢ a m ≤ monotonicSequenceLimit a

Next tactic:
exact a.monotone hm
theorem WellFounded.iSup_eq_monotonicSequenceLimit [CompleteLattice α]
    (h : WellFounded ((· > ·) : α → α → Prop)) (a : ℕ →o α) :
    iSup a = monotonicSequenceLimit a := by
  refine' (iSup_le fun m => _).antisymm (le_iSup a _)
  rcases le_or_lt m (monotonicSequenceLimitIndex a) with hm | hm
  · exact a.monotone hm
  · 

Proof state:
case inr
α : Type u_1
inst✝ : CompleteLattice α
h : WellFounded fun x x_1 => x > x_1
a : ℕ →o α
m : ℕ
hm : monotonicSequenceLimitIndex a < m
⊢ a m ≤ monotonicSequenceLimit a

Next tactic:
cases' WellFounded.monotone_chain_condition'.1 h a with n hn
theorem WellFounded.iSup_eq_monotonicSequenceLimit [CompleteLattice α]
    (h : WellFounded ((· > ·) : α → α → Prop)) (a : ℕ →o α) :
    iSup a = monotonicSequenceLimit a := by
  refine' (iSup_le fun m => _).antisymm (le_iSup a _)
  rcases le_or_lt m (monotonicSequenceLimitIndex a) with hm | hm
  · exact a.monotone hm
  · cases' WellFounded.monotone_chain_condition'.1 h a with n hn
    

Proof state:
case inr.intro
α : Type u_1
inst✝ : CompleteLattice α
h : WellFounded fun x x_1 => x > x_1
a : ℕ →o α
m : ℕ
hm : monotonicSequenceLimitIndex a < m
n : ℕ
hn : ∀ (m : ℕ), n ≤ m → ¬a n < a m
⊢ a m ≤ monotonicSequenceLimit a

Next tactic:
have : n ∈ {n | ∀ m, n ≤ m → a n = a m} := fun k hk => (a.mono hk).eq_of_not_lt (hn k hk)
theorem WellFounded.iSup_eq_monotonicSequenceLimit [CompleteLattice α]
    (h : WellFounded ((· > ·) : α → α → Prop)) (a : ℕ →o α) :
    iSup a = monotonicSequenceLimit a := by
  refine' (iSup_le fun m => _).antisymm (le_iSup a _)
  rcases le_or_lt m (monotonicSequenceLimitIndex a) with hm | hm
  · exact a.monotone hm
  · cases' WellFounded.monotone_chain_condition'.1 h a with n hn
    have : n ∈ {n | ∀ m, n ≤ m → a n = a m} := fun k hk => (a.mono hk).eq_of_not_lt (hn k hk)
    

Proof state:
case inr.intro
α : Type u_1
inst✝ : CompleteLattice α
h : WellFounded fun x x_1 => x > x_1
a : ℕ →o α
m : ℕ
hm : monotonicSequenceLimitIndex a < m
n : ℕ
hn : ∀ (m : ℕ), n ≤ m → ¬a n < a m
this : n ∈ {n | ∀ (m : ℕ), n ≤ m → a n = a m}
⊢ a m ≤ monotonicSequenceLimit a

Next tactic:
exact (Nat.sInf_mem ⟨n, this⟩ m hm.le).ge
/-- The `DFinsupp` version of `Finsupp.lsum`.

See note [bundled maps over different rings] for why separate `R` and `S` semirings are used. -/
@[simps]
def lsum [Semiring S] [Module S N] [SMulCommClass R S N] :
    (∀ i, M i →ₗ[R] N) ≃ₗ[S] (Π₀ i, M i) →ₗ[R] N where
  toFun F :=
    { toFun := sumAddHom fun i => (F i).toAddMonoidHom
      -- Porting note: needed to (β := M) hint below
      map_add' := (DFinsupp.liftAddHom (β := M) (fun (i : ι) => (F i).toAddMonoidHom)).map_add
      map_smul' := fun c f => by
        

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
M : ι → Type u_4
N : Type u_5
dec_ι : DecidableEq ι
inst✝⁷ : Semiring R
inst✝⁶ : (i : ι) → AddCommMonoid (M i)
inst✝⁵ : (i : ι) → Module R (M i)
inst✝⁴ : AddCommMonoid N
inst✝³ : Module R N
inst✝² : Semiring S
inst✝¹ : Module S N
inst✝ : SMulCommClass R S N
F : (i : ι) → M i →ₗ[R] N
c : R
f : Π₀ (i : ι), M i
⊢ AddHom.toFun
      { toFun := ⇑(sumAddHom fun i => LinearMap.toAddMonoidHom (F i)),
        map_add' :=
          (_ :
            ∀ (a b : Π₀ (i : ι), M i),
              (liftAddHom fun i => LinearMap.toAddMonoidHom (F i)) (a + b) =
                (liftAddHom fun i => LinearMap.toAddMonoidHom (F i)) a +
                  (liftAddHom fun i => LinearMap.toAddMonoidHom (F i)) b) }
      (c • f) =
    (RingHom.id R) c •
      AddHom.toFun
        { toFun := ⇑(sumAddHom fun i => LinearMap.toAddMonoidHom (F i)),
          map_add' :=
            (_ :
              ∀ (a b : Π₀ (i : ι), M i),
                (liftAddHom fun i => LinearMap.toAddMonoidHom (F i)) (a + b) =
                  (liftAddHom fun i => LinearMap.toAddMonoidHom (F i)) a +
                    (liftAddHom fun i => LinearMap.toAddMonoidHom (F i)) b) }
        f

Next tactic:
dsimp
/-- The `DFinsupp` version of `Finsupp.lsum`.

See note [bundled maps over different rings] for why separate `R` and `S` semirings are used. -/
@[simps]
def lsum [Semiring S] [Module S N] [SMulCommClass R S N] :
    (∀ i, M i →ₗ[R] N) ≃ₗ[S] (Π₀ i, M i) →ₗ[R] N where
  toFun F :=
    { toFun := sumAddHom fun i => (F i).toAddMonoidHom
      -- Porting note: needed to (β := M) hint below
      map_add' := (DFinsupp.liftAddHom (β := M) (fun (i : ι) => (F i).toAddMonoidHom)).map_add
      map_smul' := fun c f => by
        dsimp
        

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
M : ι → Type u_4
N : Type u_5
dec_ι : DecidableEq ι
inst✝⁷ : Semiring R
inst✝⁶ : (i : ι) → AddCommMonoid (M i)
inst✝⁵ : (i : ι) → Module R (M i)
inst✝⁴ : AddCommMonoid N
inst✝³ : Module R N
inst✝² : Semiring S
inst✝¹ : Module S N
inst✝ : SMulCommClass R S N
F : (i : ι) → M i →ₗ[R] N
c : R
f : Π₀ (i : ι), M i
⊢ (sumAddHom fun i => LinearMap.toAddMonoidHom (F i)) (c • f) =
    c • (sumAddHom fun i => LinearMap.toAddMonoidHom (F i)) f

Next tactic:
apply DFinsupp.induction f
/-- The `DFinsupp` version of `Finsupp.lsum`.

See note [bundled maps over different rings] for why separate `R` and `S` semirings are used. -/
@[simps]
def lsum [Semiring S] [Module S N] [SMulCommClass R S N] :
    (∀ i, M i →ₗ[R] N) ≃ₗ[S] (Π₀ i, M i) →ₗ[R] N where
  toFun F :=
    { toFun := sumAddHom fun i => (F i).toAddMonoidHom
      -- Porting note: needed to (β := M) hint below
      map_add' := (DFinsupp.liftAddHom (β := M) (fun (i : ι) => (F i).toAddMonoidHom)).map_add
      map_smul' := fun c f => by
        dsimp
        apply DFinsupp.induction f
        · 

Proof state:
case h0
ι : Type u_1
R : Type u_2
S : Type u_3
M : ι → Type u_4
N : Type u_5
dec_ι : DecidableEq ι
inst✝⁷ : Semiring R
inst✝⁶ : (i : ι) → AddCommMonoid (M i)
inst✝⁵ : (i : ι) → Module R (M i)
inst✝⁴ : AddCommMonoid N
inst✝³ : Module R N
inst✝² : Semiring S
inst✝¹ : Module S N
inst✝ : SMulCommClass R S N
F : (i : ι) → M i →ₗ[R] N
c : R
f : Π₀ (i : ι), M i
⊢ (sumAddHom fun i => LinearMap.toAddMonoidHom (F i)) (c • 0) =
    c • (sumAddHom fun i => LinearMap.toAddMonoidHom (F i)) 0

Next tactic:
rw [smul_zero, AddMonoidHom.map_zero, smul_zero]
/-- The `DFinsupp` version of `Finsupp.lsum`.

See note [bundled maps over different rings] for why separate `R` and `S` semirings are used. -/
@[simps]
def lsum [Semiring S] [Module S N] [SMulCommClass R S N] :
    (∀ i, M i →ₗ[R] N) ≃ₗ[S] (Π₀ i, M i) →ₗ[R] N where
  toFun F :=
    { toFun := sumAddHom fun i => (F i).toAddMonoidHom
      -- Porting note: needed to (β := M) hint below
      map_add' := (DFinsupp.liftAddHom (β := M) (fun (i : ι) => (F i).toAddMonoidHom)).map_add
      map_smul' := fun c f => by
        dsimp
        apply DFinsupp.induction f
        · rw [smul_zero, AddMonoidHom.map_zero, smul_zero]
        · 

Proof state:
case ha
ι : Type u_1
R : Type u_2
S : Type u_3
M : ι → Type u_4
N : Type u_5
dec_ι : DecidableEq ι
inst✝⁷ : Semiring R
inst✝⁶ : (i : ι) → AddCommMonoid (M i)
inst✝⁵ : (i : ι) → Module R (M i)
inst✝⁴ : AddCommMonoid N
inst✝³ : Module R N
inst✝² : Semiring S
inst✝¹ : Module S N
inst✝ : SMulCommClass R S N
F : (i : ι) → M i →ₗ[R] N
c : R
f : Π₀ (i : ι), M i
⊢ ∀ (i : ι) (b : M i) (f : Π₀ (i : ι), M i),
    f i = 0 →
      b ≠ 0 →
        (sumAddHom fun i => LinearMap.toAddMonoidHom (F i)) (c • f) =
            c • (sumAddHom fun i => LinearMap.toAddMonoidHom (F i)) f →
          (sumAddHom fun i => LinearMap.toAddMonoidHom (F i)) (c • (single i b + f)) =
            c • (sumAddHom fun i => LinearMap.toAddMonoidHom (F i)) (single i b + f)

Next tactic:
intro a b f _ _ hf
/-- The `DFinsupp` version of `Finsupp.lsum`.

See note [bundled maps over different rings] for why separate `R` and `S` semirings are used. -/
@[simps]
def lsum [Semiring S] [Module S N] [SMulCommClass R S N] :
    (∀ i, M i →ₗ[R] N) ≃ₗ[S] (Π₀ i, M i) →ₗ[R] N where
  toFun F :=
    { toFun := sumAddHom fun i => (F i).toAddMonoidHom
      -- Porting note: needed to (β := M) hint below
      map_add' := (DFinsupp.liftAddHom (β := M) (fun (i : ι) => (F i).toAddMonoidHom)).map_add
      map_smul' := fun c f => by
        dsimp
        apply DFinsupp.induction f
        · rw [smul_zero, AddMonoidHom.map_zero, smul_zero]
        · intro a b f _ _ hf
          

Proof state:
case ha
ι : Type u_1
R : Type u_2
S : Type u_3
M : ι → Type u_4
N : Type u_5
dec_ι : DecidableEq ι
inst✝⁷ : Semiring R
inst✝⁶ : (i : ι) → AddCommMonoid (M i)
inst✝⁵ : (i : ι) → Module R (M i)
inst✝⁴ : AddCommMonoid N
inst✝³ : Module R N
inst✝² : Semiring S
inst✝¹ : Module S N
inst✝ : SMulCommClass R S N
F : (i : ι) → M i →ₗ[R] N
c : R
f✝ : Π₀ (i : ι), M i
a : ι
b : M a
f : Π₀ (i : ι), M i
a✝¹ : f a = 0
a✝ : b ≠ 0
hf :
  (sumAddHom fun i => LinearMap.toAddMonoidHom (F i)) (c • f) =
    c • (sumAddHom fun i => LinearMap.toAddMonoidHom (F i)) f
⊢ (sumAddHom fun i => LinearMap.toAddMonoidHom (F i)) (c • (single a b + f)) =
    c • (sumAddHom fun i => LinearMap.toAddMonoidHom (F i)) (single a b + f)

Next tactic:
rw [smul_add, AddMonoidHom.map_add, AddMonoidHom.map_add, smul_add, hf, ← single_smul,
            sumAddHom_single, sumAddHom_single, LinearMap.toAddMonoidHom_coe,
            LinearMap.map_smul]
/-- While `simp` can prove this, it is often convenient to avoid unfolding `lsum` into `sumAddHom`
with `DFinsupp.lsum_apply_apply`. -/
theorem lsum_single [Semiring S] [Module S N] [SMulCommClass R S N] (F : ∀ i, M i →ₗ[R] N) (i)
    (x : M i) : lsum S (M := M) F (single i x) = F i x := by
  

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
M : ι → Type u_4
N : Type u_5
dec_ι : DecidableEq ι
inst✝⁷ : Semiring R
inst✝⁶ : (i : ι) → AddCommMonoid (M i)
inst✝⁵ : (i : ι) → Module R (M i)
inst✝⁴ : AddCommMonoid N
inst✝³ : Module R N
inst✝² : Semiring S
inst✝¹ : Module S N
inst✝ : SMulCommClass R S N
F : (i : ι) → M i →ₗ[R] N
i : ι
x : M i
⊢ ((lsum S) F) (single i x) = (F i) x

Next tactic:
simp
theorem mapRange_smul (f : ∀ i, β₁ i → β₂ i) (hf : ∀ i, f i 0 = 0) (r : R)
    (hf' : ∀ i x, f i (r • x) = r • f i x) (g : Π₀ i, β₁ i) :
    mapRange f hf (r • g) = r • mapRange f hf g := by
  

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
M : ι → Type u_4
N : Type u_5
dec_ι : DecidableEq ι
inst✝¹⁰ : Semiring R
inst✝⁹ : (i : ι) → AddCommMonoid (M i)
inst✝⁸ : (i : ι) → Module R (M i)
inst✝⁷ : AddCommMonoid N
inst✝⁶ : Module R N
β : ι → Type u_6
β₁ : ι → Type u_7
β₂ : ι → Type u_8
inst✝⁵ : (i : ι) → AddCommMonoid (β i)
inst✝⁴ : (i : ι) → AddCommMonoid (β₁ i)
inst✝³ : (i : ι) → AddCommMonoid (β₂ i)
inst✝² : (i : ι) → Module R (β i)
inst✝¹ : (i : ι) → Module R (β₁ i)
inst✝ : (i : ι) → Module R (β₂ i)
f : (i : ι) → β₁ i → β₂ i
hf : ∀ (i : ι), f i 0 = 0
r : R
hf' : ∀ (i : ι) (x : β₁ i), f i (r • x) = r • f i x
g : Π₀ (i : ι), β₁ i
⊢ mapRange f hf (r • g) = r • mapRange f hf g

Next tactic:
ext
theorem mapRange_smul (f : ∀ i, β₁ i → β₂ i) (hf : ∀ i, f i 0 = 0) (r : R)
    (hf' : ∀ i x, f i (r • x) = r • f i x) (g : Π₀ i, β₁ i) :
    mapRange f hf (r • g) = r • mapRange f hf g := by
  ext
  

Proof state:
case h
ι : Type u_1
R : Type u_2
S : Type u_3
M : ι → Type u_4
N : Type u_5
dec_ι : DecidableEq ι
inst✝¹⁰ : Semiring R
inst✝⁹ : (i : ι) → AddCommMonoid (M i)
inst✝⁸ : (i : ι) → Module R (M i)
inst✝⁷ : AddCommMonoid N
inst✝⁶ : Module R N
β : ι → Type u_6
β₁ : ι → Type u_7
β₂ : ι → Type u_8
inst✝⁵ : (i : ι) → AddCommMonoid (β i)
inst✝⁴ : (i : ι) → AddCommMonoid (β₁ i)
inst✝³ : (i : ι) → AddCommMonoid (β₂ i)
inst✝² : (i : ι) → Module R (β i)
inst✝¹ : (i : ι) → Module R (β₁ i)
inst✝ : (i : ι) → Module R (β₂ i)
f : (i : ι) → β₁ i → β₂ i
hf : ∀ (i : ι), f i 0 = 0
r : R
hf' : ∀ (i : ι) (x : β₁ i), f i (r • x) = r • f i x
g : Π₀ (i : ι), β₁ i
i✝ : ι
⊢ (mapRange f hf (r • g)) i✝ = (r • mapRange f hf g) i✝

Next tactic:
simp only [mapRange_apply f, coe_smul, Pi.smul_apply, hf']
@[simp]
theorem mapRange.linearMap_id :
    (mapRange.linearMap fun i => (LinearMap.id : β₂ i →ₗ[R] _)) = LinearMap.id := by
  

Proof state:
ι : Type u_1
R : Type u_2
S : Type u_3
M : ι → Type u_4
N : Type u_5
dec_ι : DecidableEq ι
inst✝¹⁰ : Semiring R
inst✝⁹ : (i : ι) → AddCommMonoid (M i)
inst✝⁸ : (i : ι) → Module R (M i)
inst✝⁷ : AddCommMonoid N
inst✝⁶ : Module R N
β : ι → Type u_6
β₁ : ι → Type u_7
β₂ : ι → Type u_8
inst✝⁵ : (i : ι) → AddCommMonoid (β i)
inst✝⁴ : (i : ι) → AddCommMonoid (β₁ i)
inst✝³ : (i : ι) → AddCommMonoid (β₂ i)
inst✝² : (i : ι) → Module R (β i)
inst✝¹ : (i : ι) → Module R (β₁ i)
inst✝ : (i : ι) → Module R (β₂ i)
⊢ (linearMap fun i => LinearMap.id) = LinearMap.id

Next tactic:
ext
@[simp]
theorem mapRange.linearMap_id :
    (mapRange.linearMap fun i => (LinearMap.id : β₂ i →ₗ[R] _)) = LinearMap.id := by
  ext
  

Proof state:
case h.h.h
ι : Type u_1
R : Type u_2
S : Type u_3
M : ι → Type u_4
N : Type u_5
dec_ι : DecidableEq ι
inst✝¹⁰ : Semiring R
inst✝⁹ : (i : ι) → AddCommMonoid (M i)
inst✝⁸ : (i : ι) → Module R (M i)
inst✝⁷ : AddCommMonoid N
inst✝⁶ : Module R N
β : ι → Type u_6
β₁ : ι → Type u_7
β₂ : ι → Type u_8
inst✝⁵ : (i : ι) → AddCommMonoid (β i)
inst✝⁴ : (i : ι) → AddCommMonoid (β₁ i)
inst✝³ : (i : ι) → AddCommMonoid (β₂ i)
inst✝² : (i : ι) → Module R (β i)
inst✝¹ : (i : ι) → Module R (β₁ i)
inst✝ : (i : ι) → Module R (β₂ i)
i✝¹ : ι
x✝ : β₂ i✝¹
i✝ : ι
⊢ (((linearMap fun i => LinearMap.id) ∘ₗ lsingle i✝¹) x✝) i✝ = ((LinearMap.id ∘ₗ lsingle i✝¹) x✝) i✝

Next tactic:
simp [linearMap]