l3lab/ntp-mathlib huggingface dataset:
/-- The map from the third isomorphism theorem for modules: `(M / S) / (T / S) → M / T`. -/
def quotientQuotientEquivQuotientAux (h : S ≤ T) : (M ⧸ S) ⧸ T.map S.mkQ →ₗ[R] M ⧸ T :=
  liftQ _ (mapQ S T LinearMap.id h)
    (by
      rintro _ ⟨x, hx, rfl⟩
      rw [LinearMap.mem_ker, mkQ_apply, mapQ_apply]
      

Proof state:
case intro.intro
R : Type u_1
M : Type u_2
M₂ : Type u_3
M₃ : Type u_4
inst✝⁶ : Ring R
inst✝⁵ : AddCommGroup M
inst✝⁴ : AddCommGroup M₂
inst✝³ : AddCommGroup M₃
inst✝² : Module R M
inst✝¹ : Module R M₂
inst✝ : Module R M₃
f : M →ₗ[R] M₂
S T : Submodule R M
h✝ h : S ≤ T
x : M
hx : x ∈ ↑T
⊢ Quotient.mk (LinearMap.id x) = 0

Next tactic:
exact (Quotient.mk_eq_zero _).mpr hx
theorem quotientQuotientEquivQuotientAux_mk_mk (x : M) :
    quotientQuotientEquivQuotientAux S T h (Quotient.mk (Quotient.mk x)) = Quotient.mk x := by 

Proof state:
R : Type u_1
M : Type u_2
M₂ : Type u_3
M₃ : Type u_4
inst✝⁶ : Ring R
inst✝⁵ : AddCommGroup M
inst✝⁴ : AddCommGroup M₂
inst✝³ : AddCommGroup M₃
inst✝² : Module R M
inst✝¹ : Module R M₂
inst✝ : Module R M₃
f : M →ₗ[R] M₂
S T : Submodule R M
h : S ≤ T
x : M
⊢ (quotientQuotientEquivQuotientAux S T h) (Quotient.mk (Quotient.mk x)) = Quotient.mk x

Next tactic:
simp
/-- **Noether's third isomorphism theorem** for modules: `(M / S) / (T / S) ≃ M / T`. -/
def quotientQuotientEquivQuotient : ((M ⧸ S) ⧸ T.map S.mkQ) ≃ₗ[R] M ⧸ T :=
  { quotientQuotientEquivQuotientAux S T h with
    toFun := quotientQuotientEquivQuotientAux S T h
    invFun := mapQ _ _ (mkQ S) (le_comap_map _ _)
    left_inv := fun x => Quotient.inductionOn' x fun x => Quotient.inductionOn' x fun x => by 

Proof state:
R : Type u_1
M : Type u_2
M₂ : Type u_3
M₃ : Type u_4
inst✝⁶ : Ring R
inst✝⁵ : AddCommGroup M
inst✝⁴ : AddCommGroup M₂
inst✝³ : AddCommGroup M₃
inst✝² : Module R M
inst✝¹ : Module R M₂
inst✝ : Module R M₃
f : M →ₗ[R] M₂
S T : Submodule R M
h : S ≤ T
src✝ : (M ⧸ S) ⧸ map (mkQ S) T →ₗ[R] M ⧸ T := quotientQuotientEquivQuotientAux S T h
x✝¹ : (M ⧸ S) ⧸ map (mkQ S) T
x✝ : M ⧸ S
x : M
⊢ (mapQ T (map (mkQ S) T) (mkQ S) (_ : T ≤ comap (mkQ S) (map (mkQ S) T)))
      (AddHom.toFun
        {
            toAddHom :=
              { toFun := ⇑(quotientQuotientEquivQuotientAux S T h),
                map_add' :=
                  (_ :
                    ∀ (x y : (M ⧸ S) ⧸ map (mkQ S) T),
                      AddHom.toFun src✝.toAddHom (x + y) =
                        AddHom.toFun src✝.toAddHom x + AddHom.toFun src✝.toAddHom y) },
            map_smul' :=
              (_ :
                ∀ (r : R) (x : (M ⧸ S) ⧸ map (mkQ S) T),
                  AddHom.toFun src✝.toAddHom (r • x) = (RingHom.id R) r • AddHom.toFun src✝.toAddHom x) }.toAddHom
        (Quotient.mk'' (Quotient.mk'' x))) =
    Quotient.mk'' (Quotient.mk'' x)

Next tactic:
simp
/-- **Noether's third isomorphism theorem** for modules: `(M / S) / (T / S) ≃ M / T`. -/
def quotientQuotientEquivQuotient : ((M ⧸ S) ⧸ T.map S.mkQ) ≃ₗ[R] M ⧸ T :=
  { quotientQuotientEquivQuotientAux S T h with
    toFun := quotientQuotientEquivQuotientAux S T h
    invFun := mapQ _ _ (mkQ S) (le_comap_map _ _)
    left_inv := fun x => Quotient.inductionOn' x fun x => Quotient.inductionOn' x fun x => by simp
    right_inv := fun x => Quotient.inductionOn' x fun x => by 

Proof state:
R : Type u_1
M : Type u_2
M₂ : Type u_3
M₃ : Type u_4
inst✝⁶ : Ring R
inst✝⁵ : AddCommGroup M
inst✝⁴ : AddCommGroup M₂
inst✝³ : AddCommGroup M₃
inst✝² : Module R M
inst✝¹ : Module R M₂
inst✝ : Module R M₃
f : M →ₗ[R] M₂
S T : Submodule R M
h : S ≤ T
src✝ : (M ⧸ S) ⧸ map (mkQ S) T →ₗ[R] M ⧸ T := quotientQuotientEquivQuotientAux S T h
x✝ : M ⧸ T
x : M
⊢ AddHom.toFun
      {
          toAddHom :=
            { toFun := ⇑(quotientQuotientEquivQuotientAux S T h),
              map_add' :=
                (_ :
                  ∀ (x y : (M ⧸ S) ⧸ map (mkQ S) T),
                    AddHom.toFun src✝.toAddHom (x + y) = AddHom.toFun src✝.toAddHom x + AddHom.toFun src✝.toAddHom y) },
          map_smul' :=
            (_ :
              ∀ (r : R) (x : (M ⧸ S) ⧸ map (mkQ S) T),
                AddHom.toFun src✝.toAddHom (r • x) = (RingHom.id R) r • AddHom.toFun src✝.toAddHom x) }.toAddHom
      ((mapQ T (map (mkQ S) T) (mkQ S) (_ : T ≤ comap (mkQ S) (map (mkQ S) T))) (Quotient.mk'' x)) =
    Quotient.mk'' x

Next tactic:
simp
/-- Corollary of the third isomorphism theorem: `[S : T] [M : S] = [M : T]` -/
theorem card_quotient_mul_card_quotient (S T : Submodule R M) (hST : T ≤ S)
    [DecidablePred fun x => x ∈ S.map T.mkQ] [Fintype (M ⧸ S)] [Fintype (M ⧸ T)] :
    Fintype.card (S.map T.mkQ) * Fintype.card (M ⧸ S) = Fintype.card (M ⧸ T) := by
  

Proof state:
R : Type u_1
M : Type u_2
M₂ : Type u_3
M₃ : Type u_4
inst✝⁹ : Ring R
inst✝⁸ : AddCommGroup M
inst✝⁷ : AddCommGroup M₂
inst✝⁶ : AddCommGroup M₃
inst✝⁵ : Module R M
inst✝⁴ : Module R M₂
inst✝³ : Module R M₃
f : M →ₗ[R] M₂
S✝ T✝ : Submodule R M
h : S✝ ≤ T✝
S T : Submodule R M
hST : T ≤ S
inst✝² : DecidablePred fun x => x ∈ map (mkQ T) S
inst✝¹ : Fintype (M ⧸ S)
inst✝ : Fintype (M ⧸ T)
⊢ Fintype.card ↥(map (mkQ T) S) * Fintype.card (M ⧸ S) = Fintype.card (M ⧸ T)

Next tactic:
rw [Submodule.card_eq_card_quotient_mul_card (map T.mkQ S),
    Fintype.card_eq.mpr ⟨(quotientQuotientEquivQuotient T S hST).toEquiv⟩]
instance self (R : Type u) [CommRing R] : Flat R R :=
  ⟨by
    

Proof state:
R✝ : Type u
inst✝¹ : CommRing R✝
R : Type u
inst✝ : CommRing R
⊢ ∀ ⦃I : Ideal R⦄, Ideal.FG I → Injective ⇑(lift (lsmul R R ∘ₗ Submodule.subtype I))

Next tactic:
intro I _
instance self (R : Type u) [CommRing R] : Flat R R :=
  ⟨by
    intro I _
    

Proof state:
R✝ : Type u
inst✝¹ : CommRing R✝
R : Type u
inst✝ : CommRing R
I : Ideal R
x✝ : Ideal.FG I
⊢ Injective ⇑(lift (lsmul R R ∘ₗ Submodule.subtype I))

Next tactic:
rw [← Equiv.injective_comp (TensorProduct.rid R I).symm.toEquiv]
instance self (R : Type u) [CommRing R] : Flat R R :=
  ⟨by
    intro I _
    rw [← Equiv.injective_comp (TensorProduct.rid R I).symm.toEquiv]
    

Proof state:
R✝ : Type u
inst✝¹ : CommRing R✝
R : Type u
inst✝ : CommRing R
I : Ideal R
x✝ : Ideal.FG I
⊢ Injective
    (⇑(lift (lsmul R R ∘ₗ Submodule.subtype I)) ∘ ⇑(LinearEquiv.toEquiv (LinearEquiv.symm (TensorProduct.rid R ↥I))))

Next tactic:
convert Subtype.coe_injective using 1
instance self (R : Type u) [CommRing R] : Flat R R :=
  ⟨by
    intro I _
    rw [← Equiv.injective_comp (TensorProduct.rid R I).symm.toEquiv]
    convert Subtype.coe_injective using 1
    

Proof state:
case h.e'_3
R✝ : Type u
inst✝¹ : CommRing R✝
R : Type u
inst✝ : CommRing R
I : Ideal R
x✝ : Ideal.FG I
⊢ ⇑(lift (lsmul R R ∘ₗ Submodule.subtype I)) ∘ ⇑(LinearEquiv.toEquiv (LinearEquiv.symm (TensorProduct.rid R ↥I))) =
    fun a => ↑a

Next tactic:
ext x
instance self (R : Type u) [CommRing R] : Flat R R :=
  ⟨by
    intro I _
    rw [← Equiv.injective_comp (TensorProduct.rid R I).symm.toEquiv]
    convert Subtype.coe_injective using 1
    ext x
    

Proof state:
case h.e'_3.h
R✝ : Type u
inst✝¹ : CommRing R✝
R : Type u
inst✝ : CommRing R
I : Ideal R
x✝ : Ideal.FG I
x : ↥I
⊢ (⇑(lift (lsmul R R ∘ₗ Submodule.subtype I)) ∘ ⇑(LinearEquiv.toEquiv (LinearEquiv.symm (TensorProduct.rid R ↥I)))) x =
    ↑x

Next tactic:
simp only [Function.comp_apply, LinearEquiv.coe_toEquiv, rid_symm_apply, comp_apply, mul_one,
      lift.tmul, Submodule.subtype_apply, Algebra.id.smul_eq_mul, lsmul_apply]
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  

Proof state:
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
⊢ Flat R M ↔ ∀ ⦃I : Ideal R⦄, Ideal.FG I → Injective ⇑(rTensor M (Submodule.subtype I))

Next tactic:
have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    intro I; apply TensorProduct.ext'; intro x y; simp
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    

Proof state:
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
⊢ ∀ (I : Ideal R), ↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I) = lift (lsmul R M ∘ₗ Submodule.subtype I)

Next tactic:
intro I
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    intro I; 

Proof state:
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
⊢ ↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I) = lift (lsmul R M ∘ₗ Submodule.subtype I)

Next tactic:
apply TensorProduct.ext'
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    intro I; apply TensorProduct.ext'; 

Proof state:
case H
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
⊢ ∀ (x : ↥I) (y : M),
    (↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I)) (x ⊗ₜ[R] y) =
      (lift (lsmul R M ∘ₗ Submodule.subtype I)) (x ⊗ₜ[R] y)

Next tactic:
intro x y
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    intro I; apply TensorProduct.ext'; intro x y; 

Proof state:
case H
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
I : Ideal R
x : ↥I
y : M
⊢ (↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I)) (x ⊗ₜ[R] y) =
    (lift (lsmul R M ∘ₗ Submodule.subtype I)) (x ⊗ₜ[R] y)

Next tactic:
simp
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    intro I; apply TensorProduct.ext'; intro x y; simp
  

Proof state:
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
aux :
  ∀ (I : Ideal R), ↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I) = lift (lsmul R M ∘ₗ Submodule.subtype I)
⊢ Flat R M ↔ ∀ ⦃I : Ideal R⦄, Ideal.FG I → Injective ⇑(rTensor M (Submodule.subtype I))

Next tactic:
constructor
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    intro I; apply TensorProduct.ext'; intro x y; simp
  constructor
  · 

Proof state:
case mp
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
aux :
  ∀ (I : Ideal R), ↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I) = lift (lsmul R M ∘ₗ Submodule.subtype I)
⊢ Flat R M → ∀ ⦃I : Ideal R⦄, Ideal.FG I → Injective ⇑(rTensor M (Submodule.subtype I))

Next tactic:
intro F I hI
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    intro I; apply TensorProduct.ext'; intro x y; simp
  constructor
  · intro F I hI
    

Proof state:
case mp
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
aux :
  ∀ (I : Ideal R), ↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I) = lift (lsmul R M ∘ₗ Submodule.subtype I)
F : Flat R M
I : Ideal R
hI : Ideal.FG I
⊢ Injective ⇑(rTensor M (Submodule.subtype I))

Next tactic:
erw [← Equiv.comp_injective _ (TensorProduct.lid R M).toEquiv]
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    intro I; apply TensorProduct.ext'; intro x y; simp
  constructor
  · intro F I hI
    erw [← Equiv.comp_injective _ (TensorProduct.lid R M).toEquiv]
    

Proof state:
case mp
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
aux :
  ∀ (I : Ideal R), ↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I) = lift (lsmul R M ∘ₗ Submodule.subtype I)
F : Flat R M
I : Ideal R
hI : Ideal.FG I
⊢ Injective (⇑(LinearEquiv.toEquiv (TensorProduct.lid R M)) ∘ ⇑(rTensor M (Submodule.subtype I)))

Next tactic:
have h₁ := F.out hI
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    intro I; apply TensorProduct.ext'; intro x y; simp
  constructor
  · intro F I hI
    erw [← Equiv.comp_injective _ (TensorProduct.lid R M).toEquiv]
    have h₁ := F.out hI
    

Proof state:
case mp
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
aux :
  ∀ (I : Ideal R), ↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I) = lift (lsmul R M ∘ₗ Submodule.subtype I)
F : Flat R M
I : Ideal R
hI : Ideal.FG I
h₁ : Injective ⇑(lift (lsmul R M ∘ₗ Submodule.subtype I))
⊢ Injective (⇑(LinearEquiv.toEquiv (TensorProduct.lid R M)) ∘ ⇑(rTensor M (Submodule.subtype I)))

Next tactic:
rw [← aux] at h₁
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    intro I; apply TensorProduct.ext'; intro x y; simp
  constructor
  · intro F I hI
    erw [← Equiv.comp_injective _ (TensorProduct.lid R M).toEquiv]
    have h₁ := F.out hI
    rw [← aux] at h₁
    

Proof state:
case mp
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
aux :
  ∀ (I : Ideal R), ↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I) = lift (lsmul R M ∘ₗ Submodule.subtype I)
F : Flat R M
I : Ideal R
hI : Ideal.FG I
h₁ : Injective ⇑(↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I))
⊢ Injective (⇑(LinearEquiv.toEquiv (TensorProduct.lid R M)) ∘ ⇑(rTensor M (Submodule.subtype I)))

Next tactic:
refine h₁
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    intro I; apply TensorProduct.ext'; intro x y; simp
  constructor
  · intro F I hI
    erw [← Equiv.comp_injective _ (TensorProduct.lid R M).toEquiv]
    have h₁ := F.out hI
    rw [← aux] at h₁
    refine h₁
  · 

Proof state:
case mpr
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
aux :
  ∀ (I : Ideal R), ↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I) = lift (lsmul R M ∘ₗ Submodule.subtype I)
⊢ (∀ ⦃I : Ideal R⦄, Ideal.FG I → Injective ⇑(rTensor M (Submodule.subtype I))) → Flat R M

Next tactic:
intro h₁
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    intro I; apply TensorProduct.ext'; intro x y; simp
  constructor
  · intro F I hI
    erw [← Equiv.comp_injective _ (TensorProduct.lid R M).toEquiv]
    have h₁ := F.out hI
    rw [← aux] at h₁
    refine h₁
  · intro h₁
    

Proof state:
case mpr
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
aux :
  ∀ (I : Ideal R), ↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I) = lift (lsmul R M ∘ₗ Submodule.subtype I)
h₁ : ∀ ⦃I : Ideal R⦄, Ideal.FG I → Injective ⇑(rTensor M (Submodule.subtype I))
⊢ Flat R M

Next tactic:
constructor
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    intro I; apply TensorProduct.ext'; intro x y; simp
  constructor
  · intro F I hI
    erw [← Equiv.comp_injective _ (TensorProduct.lid R M).toEquiv]
    have h₁ := F.out hI
    rw [← aux] at h₁
    refine h₁
  · intro h₁
    constructor
    

Proof state:
case mpr.out
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
aux :
  ∀ (I : Ideal R), ↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I) = lift (lsmul R M ∘ₗ Submodule.subtype I)
h₁ : ∀ ⦃I : Ideal R⦄, Ideal.FG I → Injective ⇑(rTensor M (Submodule.subtype I))
⊢ ∀ ⦃I : Ideal R⦄, Ideal.FG I → Injective ⇑(lift (lsmul R M ∘ₗ Submodule.subtype I))

Next tactic:
intro I hI
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    intro I; apply TensorProduct.ext'; intro x y; simp
  constructor
  · intro F I hI
    erw [← Equiv.comp_injective _ (TensorProduct.lid R M).toEquiv]
    have h₁ := F.out hI
    rw [← aux] at h₁
    refine h₁
  · intro h₁
    constructor
    intro I hI
    

Proof state:
case mpr.out
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
aux :
  ∀ (I : Ideal R), ↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I) = lift (lsmul R M ∘ₗ Submodule.subtype I)
h₁ : ∀ ⦃I : Ideal R⦄, Ideal.FG I → Injective ⇑(rTensor M (Submodule.subtype I))
I : Ideal R
hI : Ideal.FG I
⊢ Injective ⇑(lift (lsmul R M ∘ₗ Submodule.subtype I))

Next tactic:
rw [← aux]
/-- An `R`-module `M` is flat iff for all finitely generated ideals `I` of `R`, the
tensor product of the inclusion `I → R` and the identity `M → M` is injective. See
`iff_rTensor_injective'` to extend to all ideals `I`. --/
lemma iff_rTensor_injective :
    Flat R M ↔ ∀ ⦃I : Ideal R⦄ (_ : I.FG), Injective (rTensor M I.subtype) := by
  have aux : ∀ I : Ideal R, (TensorProduct.lid R M).comp (rTensor M I.subtype) =
      TensorProduct.lift ((lsmul R M).comp I.subtype) := by
    intro I; apply TensorProduct.ext'; intro x y; simp
  constructor
  · intro F I hI
    erw [← Equiv.comp_injective _ (TensorProduct.lid R M).toEquiv]
    have h₁ := F.out hI
    rw [← aux] at h₁
    refine h₁
  · intro h₁
    constructor
    intro I hI
    rw [← aux]
    

Proof state:
case mpr.out
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
aux :
  ∀ (I : Ideal R), ↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I) = lift (lsmul R M ∘ₗ Submodule.subtype I)
h₁ : ∀ ⦃I : Ideal R⦄, Ideal.FG I → Injective ⇑(rTensor M (Submodule.subtype I))
I : Ideal R
hI : Ideal.FG I
⊢ Injective ⇑(↑(TensorProduct.lid R M) ∘ₗ rTensor M (Submodule.subtype I))

Next tactic:
simp [h₁ hI]
/-- An `R`-module `M` is flat iff for all ideals `I` of `R`, the tensor product of the
inclusion `I → R` and the identity `M → M` is injective. See `iff_rTensor_injective` to
restrict to finitely generated ideals `I`. --/
theorem iff_rTensor_injective' :
    Flat R M ↔ ∀ I : Ideal R, Injective (rTensor M I.subtype) := by
  

Proof state:
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
⊢ Flat R M ↔ ∀ (I : Ideal R), Injective ⇑(rTensor M (Submodule.subtype I))

Next tactic:
rewrite [Flat.iff_rTensor_injective]
/-- An `R`-module `M` is flat iff for all ideals `I` of `R`, the tensor product of the
inclusion `I → R` and the identity `M → M` is injective. See `iff_rTensor_injective` to
restrict to finitely generated ideals `I`. --/
theorem iff_rTensor_injective' :
    Flat R M ↔ ∀ I : Ideal R, Injective (rTensor M I.subtype) := by
  rewrite [Flat.iff_rTensor_injective]
  

Proof state:
R : Type u
inst✝² : CommRing R
M : Type v
inst✝¹ : AddCommGroup M
inst✝ : Module R M
⊢ (∀ ⦃I : Ideal R⦄, Ideal.FG I → Injective ⇑(rTensor M (Submodule.subtype I))) ↔
    ∀ (I : Ideal R), Injective ⇑(rTensor M (Submodule.subtype I))

Next tactic:
refine ⟨fun h I => ?_, fun h I _ => h I⟩