l3lab/ntp-mathlib huggingface dataset:
/-- Taking the product of two maps with the same domain is equivalent to taking the product of
their codomains.

See note [bundled maps over different rings] for why separate `R` and `S` semirings are used. -/
@[simps]
def prodEquiv [Module S M₂] [Module S M₃] [SMulCommClass R S M₂] [SMulCommClass R S M₃] :
    ((M →ₗ[R] M₂) × (M →ₗ[R] M₃)) ≃ₗ[S] M →ₗ[R] M₂ × M₃ where
  toFun f := f.1.prod f.2
  invFun f := ((fst _ _ _).comp f, (snd _ _ _).comp f)
  left_inv f := by ext <;> 

Proof state:
case a.h
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹⁷ : Semiring R
inst✝¹⁶ : Semiring S
inst✝¹⁵ : AddCommMonoid M
inst✝¹⁴ : AddCommMonoid M₂
inst✝¹³ : AddCommMonoid M₃
inst✝¹² : AddCommMonoid M₄
inst✝¹¹ : AddCommMonoid M₅
inst✝¹⁰ : AddCommMonoid M₆
inst✝⁹ : Module R M
inst✝⁸ : Module R M₂
inst✝⁷ : Module R M₃
inst✝⁶ : Module R M₄
inst✝⁵ : Module R M₅
inst✝⁴ : Module R M₆
f✝ : M →ₗ[R] M₂
inst✝³ : Module S M₂
inst✝² : Module S M₃
inst✝¹ : SMulCommClass R S M₂
inst✝ : SMulCommClass R S M₃
f : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)
x✝ : M
⊢ ((fun f => (fst R M₂ M₃ ∘ₗ f, snd R M₂ M₃ ∘ₗ f))
          (AddHom.toFun
            {
                toAddHom :=
                  { toFun := fun f => prod f.1 f.2,
                    map_add' :=
                      (_ :
                        ∀ (a b : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                          (fun f => prod f.1 f.2) (a + b) = (fun f => prod f.1 f.2) (a + b)) },
                map_smul' :=
                  (_ :
                    ∀ (r : S) (a : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                      AddHom.toFun
                          { toFun := fun f => prod f.1 f.2,
                            map_add' :=
                              (_ :
                                ∀ (a b : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                                  (fun f => prod f.1 f.2) (a + b) = (fun f => prod f.1 f.2) (a + b)) }
                          (r • a) =
                        AddHom.toFun
                          { toFun := fun f => prod f.1 f.2,
                            map_add' :=
                              (_ :
                                ∀ (a b : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                                  (fun f => prod f.1 f.2) (a + b) = (fun f => prod f.1 f.2) (a + b)) }
                          (r • a)) }.toAddHom
            f)).1
      x✝ =
    f.1 x✝

Next tactic:
rfl
/-- Taking the product of two maps with the same domain is equivalent to taking the product of
their codomains.

See note [bundled maps over different rings] for why separate `R` and `S` semirings are used. -/
@[simps]
def prodEquiv [Module S M₂] [Module S M₃] [SMulCommClass R S M₂] [SMulCommClass R S M₃] :
    ((M →ₗ[R] M₂) × (M →ₗ[R] M₃)) ≃ₗ[S] M →ₗ[R] M₂ × M₃ where
  toFun f := f.1.prod f.2
  invFun f := ((fst _ _ _).comp f, (snd _ _ _).comp f)
  left_inv f := by ext <;> 

Proof state:
case a.h
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹⁷ : Semiring R
inst✝¹⁶ : Semiring S
inst✝¹⁵ : AddCommMonoid M
inst✝¹⁴ : AddCommMonoid M₂
inst✝¹³ : AddCommMonoid M₃
inst✝¹² : AddCommMonoid M₄
inst✝¹¹ : AddCommMonoid M₅
inst✝¹⁰ : AddCommMonoid M₆
inst✝⁹ : Module R M
inst✝⁸ : Module R M₂
inst✝⁷ : Module R M₃
inst✝⁶ : Module R M₄
inst✝⁵ : Module R M₅
inst✝⁴ : Module R M₆
f✝ : M →ₗ[R] M₂
inst✝³ : Module S M₂
inst✝² : Module S M₃
inst✝¹ : SMulCommClass R S M₂
inst✝ : SMulCommClass R S M₃
f : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)
x✝ : M
⊢ ((fun f => (fst R M₂ M₃ ∘ₗ f, snd R M₂ M₃ ∘ₗ f))
          (AddHom.toFun
            {
                toAddHom :=
                  { toFun := fun f => prod f.1 f.2,
                    map_add' :=
                      (_ :
                        ∀ (a b : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                          (fun f => prod f.1 f.2) (a + b) = (fun f => prod f.1 f.2) (a + b)) },
                map_smul' :=
                  (_ :
                    ∀ (r : S) (a : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                      AddHom.toFun
                          { toFun := fun f => prod f.1 f.2,
                            map_add' :=
                              (_ :
                                ∀ (a b : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                                  (fun f => prod f.1 f.2) (a + b) = (fun f => prod f.1 f.2) (a + b)) }
                          (r • a) =
                        AddHom.toFun
                          { toFun := fun f => prod f.1 f.2,
                            map_add' :=
                              (_ :
                                ∀ (a b : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                                  (fun f => prod f.1 f.2) (a + b) = (fun f => prod f.1 f.2) (a + b)) }
                          (r • a)) }.toAddHom
            f)).2
      x✝ =
    f.2 x✝

Next tactic:
rfl
/-- Taking the product of two maps with the same domain is equivalent to taking the product of
their codomains.

See note [bundled maps over different rings] for why separate `R` and `S` semirings are used. -/
@[simps]
def prodEquiv [Module S M₂] [Module S M₃] [SMulCommClass R S M₂] [SMulCommClass R S M₃] :
    ((M →ₗ[R] M₂) × (M →ₗ[R] M₃)) ≃ₗ[S] M →ₗ[R] M₂ × M₃ where
  toFun f := f.1.prod f.2
  invFun f := ((fst _ _ _).comp f, (snd _ _ _).comp f)
  left_inv f := by ext <;> rfl
  right_inv f := by 

Proof state:
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹⁷ : Semiring R
inst✝¹⁶ : Semiring S
inst✝¹⁵ : AddCommMonoid M
inst✝¹⁴ : AddCommMonoid M₂
inst✝¹³ : AddCommMonoid M₃
inst✝¹² : AddCommMonoid M₄
inst✝¹¹ : AddCommMonoid M₅
inst✝¹⁰ : AddCommMonoid M₆
inst✝⁹ : Module R M
inst✝⁸ : Module R M₂
inst✝⁷ : Module R M₃
inst✝⁶ : Module R M₄
inst✝⁵ : Module R M₅
inst✝⁴ : Module R M₆
f✝ : M →ₗ[R] M₂
inst✝³ : Module S M₂
inst✝² : Module S M₃
inst✝¹ : SMulCommClass R S M₂
inst✝ : SMulCommClass R S M₃
f : M →ₗ[R] M₂ × M₃
⊢ AddHom.toFun
      {
          toAddHom :=
            { toFun := fun f => prod f.1 f.2,
              map_add' :=
                (_ :
                  ∀ (a b : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                    (fun f => prod f.1 f.2) (a + b) = (fun f => prod f.1 f.2) (a + b)) },
          map_smul' :=
            (_ :
              ∀ (r : S) (a : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                AddHom.toFun
                    { toFun := fun f => prod f.1 f.2,
                      map_add' :=
                        (_ :
                          ∀ (a b : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                            (fun f => prod f.1 f.2) (a + b) = (fun f => prod f.1 f.2) (a + b)) }
                    (r • a) =
                  AddHom.toFun
                    { toFun := fun f => prod f.1 f.2,
                      map_add' :=
                        (_ :
                          ∀ (a b : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                            (fun f => prod f.1 f.2) (a + b) = (fun f => prod f.1 f.2) (a + b)) }
                    (r • a)) }.toAddHom
      ((fun f => (fst R M₂ M₃ ∘ₗ f, snd R M₂ M₃ ∘ₗ f)) f) =
    f

Next tactic:
ext
/-- Taking the product of two maps with the same domain is equivalent to taking the product of
their codomains.

See note [bundled maps over different rings] for why separate `R` and `S` semirings are used. -/
@[simps]
def prodEquiv [Module S M₂] [Module S M₃] [SMulCommClass R S M₂] [SMulCommClass R S M₃] :
    ((M →ₗ[R] M₂) × (M →ₗ[R] M₃)) ≃ₗ[S] M →ₗ[R] M₂ × M₃ where
  toFun f := f.1.prod f.2
  invFun f := ((fst _ _ _).comp f, (snd _ _ _).comp f)
  left_inv f := by ext <;> rfl
  right_inv f := by ext <;> 

Proof state:
case h.a
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹⁷ : Semiring R
inst✝¹⁶ : Semiring S
inst✝¹⁵ : AddCommMonoid M
inst✝¹⁴ : AddCommMonoid M₂
inst✝¹³ : AddCommMonoid M₃
inst✝¹² : AddCommMonoid M₄
inst✝¹¹ : AddCommMonoid M₅
inst✝¹⁰ : AddCommMonoid M₆
inst✝⁹ : Module R M
inst✝⁸ : Module R M₂
inst✝⁷ : Module R M₃
inst✝⁶ : Module R M₄
inst✝⁵ : Module R M₅
inst✝⁴ : Module R M₆
f✝ : M →ₗ[R] M₂
inst✝³ : Module S M₂
inst✝² : Module S M₃
inst✝¹ : SMulCommClass R S M₂
inst✝ : SMulCommClass R S M₃
f : M →ₗ[R] M₂ × M₃
x✝ : M
⊢ ((AddHom.toFun
          {
              toAddHom :=
                { toFun := fun f => prod f.1 f.2,
                  map_add' :=
                    (_ :
                      ∀ (a b : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                        (fun f => prod f.1 f.2) (a + b) = (fun f => prod f.1 f.2) (a + b)) },
              map_smul' :=
                (_ :
                  ∀ (r : S) (a : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                    AddHom.toFun
                        { toFun := fun f => prod f.1 f.2,
                          map_add' :=
                            (_ :
                              ∀ (a b : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                                (fun f => prod f.1 f.2) (a + b) = (fun f => prod f.1 f.2) (a + b)) }
                        (r • a) =
                      AddHom.toFun
                        { toFun := fun f => prod f.1 f.2,
                          map_add' :=
                            (_ :
                              ∀ (a b : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                                (fun f => prod f.1 f.2) (a + b) = (fun f => prod f.1 f.2) (a + b)) }
                        (r • a)) }.toAddHom
          ((fun f => (fst R M₂ M₃ ∘ₗ f, snd R M₂ M₃ ∘ₗ f)) f))
        x✝).1 =
    (f x✝).1

Next tactic:
rfl
/-- Taking the product of two maps with the same domain is equivalent to taking the product of
their codomains.

See note [bundled maps over different rings] for why separate `R` and `S` semirings are used. -/
@[simps]
def prodEquiv [Module S M₂] [Module S M₃] [SMulCommClass R S M₂] [SMulCommClass R S M₃] :
    ((M →ₗ[R] M₂) × (M →ₗ[R] M₃)) ≃ₗ[S] M →ₗ[R] M₂ × M₃ where
  toFun f := f.1.prod f.2
  invFun f := ((fst _ _ _).comp f, (snd _ _ _).comp f)
  left_inv f := by ext <;> rfl
  right_inv f := by ext <;> 

Proof state:
case h.a
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹⁷ : Semiring R
inst✝¹⁶ : Semiring S
inst✝¹⁵ : AddCommMonoid M
inst✝¹⁴ : AddCommMonoid M₂
inst✝¹³ : AddCommMonoid M₃
inst✝¹² : AddCommMonoid M₄
inst✝¹¹ : AddCommMonoid M₅
inst✝¹⁰ : AddCommMonoid M₆
inst✝⁹ : Module R M
inst✝⁸ : Module R M₂
inst✝⁷ : Module R M₃
inst✝⁶ : Module R M₄
inst✝⁵ : Module R M₅
inst✝⁴ : Module R M₆
f✝ : M →ₗ[R] M₂
inst✝³ : Module S M₂
inst✝² : Module S M₃
inst✝¹ : SMulCommClass R S M₂
inst✝ : SMulCommClass R S M₃
f : M →ₗ[R] M₂ × M₃
x✝ : M
⊢ ((AddHom.toFun
          {
              toAddHom :=
                { toFun := fun f => prod f.1 f.2,
                  map_add' :=
                    (_ :
                      ∀ (a b : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                        (fun f => prod f.1 f.2) (a + b) = (fun f => prod f.1 f.2) (a + b)) },
              map_smul' :=
                (_ :
                  ∀ (r : S) (a : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                    AddHom.toFun
                        { toFun := fun f => prod f.1 f.2,
                          map_add' :=
                            (_ :
                              ∀ (a b : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                                (fun f => prod f.1 f.2) (a + b) = (fun f => prod f.1 f.2) (a + b)) }
                        (r • a) =
                      AddHom.toFun
                        { toFun := fun f => prod f.1 f.2,
                          map_add' :=
                            (_ :
                              ∀ (a b : (M →ₗ[R] M₂) × (M →ₗ[R] M₃)),
                                (fun f => prod f.1 f.2) (a + b) = (fun f => prod f.1 f.2) (a + b)) }
                        (r • a)) }.toAddHom
          ((fun f => (fst R M₂ M₃ ∘ₗ f, snd R M₂ M₃ ∘ₗ f)) f))
        x✝).2 =
    (f x✝).2

Next tactic:
rfl
theorem range_inl : range (inl R M M₂) = ker (snd R M M₂) := by
  

Proof state:
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
⊢ range (inl R M M₂) = ker (snd R M M₂)

Next tactic:
ext x
theorem range_inl : range (inl R M M₂) = ker (snd R M M₂) := by
  ext x
  

Proof state:
case h
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
x : M × M₂
⊢ x ∈ range (inl R M M₂) ↔ x ∈ ker (snd R M M₂)

Next tactic:
simp only [mem_ker, mem_range]
theorem range_inl : range (inl R M M₂) = ker (snd R M M₂) := by
  ext x
  simp only [mem_ker, mem_range]
  

Proof state:
case h
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
x : M × M₂
⊢ (∃ y, (inl R M M₂) y = x) ↔ (snd R M M₂) x = 0

Next tactic:
constructor
theorem range_inl : range (inl R M M₂) = ker (snd R M M₂) := by
  ext x
  simp only [mem_ker, mem_range]
  constructor
  · 

Proof state:
case h.mp
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
x : M × M₂
⊢ (∃ y, (inl R M M₂) y = x) → (snd R M M₂) x = 0

Next tactic:
rintro ⟨y, rfl⟩
theorem range_inl : range (inl R M M₂) = ker (snd R M M₂) := by
  ext x
  simp only [mem_ker, mem_range]
  constructor
  · rintro ⟨y, rfl⟩
    

Proof state:
case h.mp.intro
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
y : M
⊢ (snd R M M₂) ((inl R M M₂) y) = 0

Next tactic:
rfl
theorem range_inl : range (inl R M M₂) = ker (snd R M M₂) := by
  ext x
  simp only [mem_ker, mem_range]
  constructor
  · rintro ⟨y, rfl⟩
    rfl
  · 

Proof state:
case h.mpr
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
x : M × M₂
⊢ (snd R M M₂) x = 0 → ∃ y, (inl R M M₂) y = x

Next tactic:
intro h
theorem range_inl : range (inl R M M₂) = ker (snd R M M₂) := by
  ext x
  simp only [mem_ker, mem_range]
  constructor
  · rintro ⟨y, rfl⟩
    rfl
  · intro h
    

Proof state:
case h.mpr
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
x : M × M₂
h : (snd R M M₂) x = 0
⊢ ∃ y, (inl R M M₂) y = x

Next tactic:
exact ⟨x.fst, Prod.ext rfl h.symm⟩
theorem range_inr : range (inr R M M₂) = ker (fst R M M₂) := by
  

Proof state:
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
⊢ range (inr R M M₂) = ker (fst R M M₂)

Next tactic:
ext x
theorem range_inr : range (inr R M M₂) = ker (fst R M M₂) := by
  ext x
  

Proof state:
case h
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
x : M × M₂
⊢ x ∈ range (inr R M M₂) ↔ x ∈ ker (fst R M M₂)

Next tactic:
simp only [mem_ker, mem_range]
theorem range_inr : range (inr R M M₂) = ker (fst R M M₂) := by
  ext x
  simp only [mem_ker, mem_range]
  

Proof state:
case h
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
x : M × M₂
⊢ (∃ y, (inr R M M₂) y = x) ↔ (fst R M M₂) x = 0

Next tactic:
constructor
theorem range_inr : range (inr R M M₂) = ker (fst R M M₂) := by
  ext x
  simp only [mem_ker, mem_range]
  constructor
  · 

Proof state:
case h.mp
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
x : M × M₂
⊢ (∃ y, (inr R M M₂) y = x) → (fst R M M₂) x = 0

Next tactic:
rintro ⟨y, rfl⟩
theorem range_inr : range (inr R M M₂) = ker (fst R M M₂) := by
  ext x
  simp only [mem_ker, mem_range]
  constructor
  · rintro ⟨y, rfl⟩
    

Proof state:
case h.mp.intro
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
y : M₂
⊢ (fst R M M₂) ((inr R M M₂) y) = 0

Next tactic:
rfl
theorem range_inr : range (inr R M M₂) = ker (fst R M M₂) := by
  ext x
  simp only [mem_ker, mem_range]
  constructor
  · rintro ⟨y, rfl⟩
    rfl
  · 

Proof state:
case h.mpr
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
x : M × M₂
⊢ (fst R M M₂) x = 0 → ∃ y, (inr R M M₂) y = x

Next tactic:
intro h
theorem range_inr : range (inr R M M₂) = ker (fst R M M₂) := by
  ext x
  simp only [mem_ker, mem_range]
  constructor
  · rintro ⟨y, rfl⟩
    rfl
  · intro h
    

Proof state:
case h.mpr
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
x : M × M₂
h : (fst R M M₂) x = 0
⊢ ∃ y, (inr R M M₂) y = x

Next tactic:
exact ⟨x.snd, Prod.ext h.symm rfl⟩
theorem inl_injective : Function.Injective (inl R M M₂) := fun _ => by 

Proof state:
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
x✝ : M
⊢ ∀ ⦃a₂ : M⦄, (inl R M M₂) x✝ = (inl R M M₂) a₂ → x✝ = a₂

Next tactic:
simp
theorem inr_injective : Function.Injective (inr R M M₂) := fun _ => by 

Proof state:
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f : M →ₗ[R] M₂
x✝ : M₂
⊢ ∀ ⦃a₂ : M₂⦄, (inr R M M₂) x✝ = (inr R M M₂) a₂ → x✝ = a₂

Next tactic:
simp
@[simp]
theorem coprod_inl (f : M →ₗ[R] M₃) (g : M₂ →ₗ[R] M₃) : (coprod f g).comp (inl R M M₂) = f := by
  

Proof state:
R : Type u
K : Type u'
M : Type v
V : Type v'
M₂ : Type w
V₂ : Type w'
M₃ : Type y
V₃ : Type y'
M₄ : Type z
ι : Type x
M₅ : Type u_1
M₆ : Type u_2
S : Type u_3
inst✝¹³ : Semiring R
inst✝¹² : Semiring S
inst✝¹¹ : AddCommMonoid M
inst✝¹⁰ : AddCommMonoid M₂
inst✝⁹ : AddCommMonoid M₃
inst✝⁸ : AddCommMonoid M₄
inst✝⁷ : AddCommMonoid M₅
inst✝⁶ : AddCommMonoid M₆
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
inst✝² : Module R M₄
inst✝¹ : Module R M₅
inst✝ : Module R M₆
f✝ : M →ₗ[R] M₂
f : M →ₗ[R] M₃
g : M₂ →ₗ[R] M₃
⊢ coprod f g ∘ₗ inl R M M₂ = f

Next tactic:
ext