l3lab/ntp-mathlib huggingface dataset:
/--
If `F` preserves a particular product, then it `IsSheafFor` the corresponging presieve of arrows.
-/
theorem isSheafFor_of_preservesProduct [PreservesLimit (Discrete.functor (fun x ↦ op (X x))) F] :
    (ofArrows X c.inj).IsSheafFor F := by
  rw [Equalizer.Presieve.Arrows.sheaf_condition, Limits.Types.type_equalizer_iff_unique]
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  have hi : IsIso (piComparison F (fun x ↦ op (X x))) := inferInstance
  rw [piComparison_fac (hc := hc), isIso_iff_bijective, Function.bijective_iff_existsUnique] at hi
  intro b _
  obtain ⟨t, ht₁, ht₂⟩ := hi b
  refine ⟨F.map ((opCoproductIsoProduct' hc (productIsProduct _)).inv) t, ht₁, fun y hy ↦ ?_⟩
  apply_fun F.map ((opCoproductIsoProduct' hc (productIsProduct _)).hom) using injective_of_mono _
  simp only [← FunctorToTypes.map_comp_apply, Iso.op, Category.assoc]
  rw [ht₂ (F.map ((opCoproductIsoProduct' hc (productIsProduct _)).hom) y) (by simp [← hy])]
  

Proof state:
case intro.intro
C : Type u
inst✝⁴ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝³ : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝² : HasInitial C
inst✝¹ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
inst✝ : PreservesLimit (Discrete.functor fun x => op (X x)) F
this : HasCoproduct X
hi :
  ∀ (b : ∏ fun b => F.obj (op (X b))),
    ∃! a,
      (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
            Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))
          a =
        b
b : Equalizer.Presieve.Arrows.FirstObj F X
a✝ : Equalizer.Presieve.Arrows.firstMap F X (Cofan.inj c) b = Equalizer.Presieve.Arrows.secondMap F X (Cofan.inj c) b
t : F.obj (∏ fun x => op (X x))
ht₁ :
  (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
        Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))
      t =
    b
ht₂ :
  ∀ (y : F.obj (∏ fun x => op (X x))),
    (fun a =>
          (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
                Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))
              a =
            b)
        y →
      y = t
y : F.obj (op c.pt)
hy : (fun x => Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c) x = b) y
⊢ t =
    F.map
      ((opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
        (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).hom)
      t

Next tactic:
change (𝟙 (F.obj (∏ fun x ↦ op (X x)))) t = _
/--
If `F` preserves a particular product, then it `IsSheafFor` the corresponging presieve of arrows.
-/
theorem isSheafFor_of_preservesProduct [PreservesLimit (Discrete.functor (fun x ↦ op (X x))) F] :
    (ofArrows X c.inj).IsSheafFor F := by
  rw [Equalizer.Presieve.Arrows.sheaf_condition, Limits.Types.type_equalizer_iff_unique]
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  have hi : IsIso (piComparison F (fun x ↦ op (X x))) := inferInstance
  rw [piComparison_fac (hc := hc), isIso_iff_bijective, Function.bijective_iff_existsUnique] at hi
  intro b _
  obtain ⟨t, ht₁, ht₂⟩ := hi b
  refine ⟨F.map ((opCoproductIsoProduct' hc (productIsProduct _)).inv) t, ht₁, fun y hy ↦ ?_⟩
  apply_fun F.map ((opCoproductIsoProduct' hc (productIsProduct _)).hom) using injective_of_mono _
  simp only [← FunctorToTypes.map_comp_apply, Iso.op, Category.assoc]
  rw [ht₂ (F.map ((opCoproductIsoProduct' hc (productIsProduct _)).hom) y) (by simp [← hy])]
  change (𝟙 (F.obj (∏ fun x ↦ op (X x)))) t = _
  

Proof state:
case intro.intro
C : Type u
inst✝⁴ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝³ : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝² : HasInitial C
inst✝¹ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
inst✝ : PreservesLimit (Discrete.functor fun x => op (X x)) F
this : HasCoproduct X
hi :
  ∀ (b : ∏ fun b => F.obj (op (X b))),
    ∃! a,
      (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
            Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))
          a =
        b
b : Equalizer.Presieve.Arrows.FirstObj F X
a✝ : Equalizer.Presieve.Arrows.firstMap F X (Cofan.inj c) b = Equalizer.Presieve.Arrows.secondMap F X (Cofan.inj c) b
t : F.obj (∏ fun x => op (X x))
ht₁ :
  (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
        Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))
      t =
    b
ht₂ :
  ∀ (y : F.obj (∏ fun x => op (X x))),
    (fun a =>
          (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
                Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))
              a =
            b)
        y →
      y = t
y : F.obj (op c.pt)
hy : (fun x => Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c) x = b) y
⊢ 𝟙 (F.obj (∏ fun x => op (X x))) t =
    F.map
      ((opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
        (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).hom)
      t

Next tactic:
rw [← Functor.map_id]
/--
If `F` preserves a particular product, then it `IsSheafFor` the corresponging presieve of arrows.
-/
theorem isSheafFor_of_preservesProduct [PreservesLimit (Discrete.functor (fun x ↦ op (X x))) F] :
    (ofArrows X c.inj).IsSheafFor F := by
  rw [Equalizer.Presieve.Arrows.sheaf_condition, Limits.Types.type_equalizer_iff_unique]
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  have hi : IsIso (piComparison F (fun x ↦ op (X x))) := inferInstance
  rw [piComparison_fac (hc := hc), isIso_iff_bijective, Function.bijective_iff_existsUnique] at hi
  intro b _
  obtain ⟨t, ht₁, ht₂⟩ := hi b
  refine ⟨F.map ((opCoproductIsoProduct' hc (productIsProduct _)).inv) t, ht₁, fun y hy ↦ ?_⟩
  apply_fun F.map ((opCoproductIsoProduct' hc (productIsProduct _)).hom) using injective_of_mono _
  simp only [← FunctorToTypes.map_comp_apply, Iso.op, Category.assoc]
  rw [ht₂ (F.map ((opCoproductIsoProduct' hc (productIsProduct _)).hom) y) (by simp [← hy])]
  change (𝟙 (F.obj (∏ fun x ↦ op (X x)))) t = _
  rw [← Functor.map_id]
  

Proof state:
case intro.intro
C : Type u
inst✝⁴ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝³ : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝² : HasInitial C
inst✝¹ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
inst✝ : PreservesLimit (Discrete.functor fun x => op (X x)) F
this : HasCoproduct X
hi :
  ∀ (b : ∏ fun b => F.obj (op (X b))),
    ∃! a,
      (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
            Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))
          a =
        b
b : Equalizer.Presieve.Arrows.FirstObj F X
a✝ : Equalizer.Presieve.Arrows.firstMap F X (Cofan.inj c) b = Equalizer.Presieve.Arrows.secondMap F X (Cofan.inj c) b
t : F.obj (∏ fun x => op (X x))
ht₁ :
  (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
        Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))
      t =
    b
ht₂ :
  ∀ (y : F.obj (∏ fun x => op (X x))),
    (fun a =>
          (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
                Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))
              a =
            b)
        y →
      y = t
y : F.obj (op c.pt)
hy : (fun x => Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c) x = b) y
⊢ F.map (𝟙 (∏ fun x => op (X x))) t =
    F.map
      ((opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
        (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).hom)
      t

Next tactic:
refine congrFun ?_ t
/--
If `F` preserves a particular product, then it `IsSheafFor` the corresponging presieve of arrows.
-/
theorem isSheafFor_of_preservesProduct [PreservesLimit (Discrete.functor (fun x ↦ op (X x))) F] :
    (ofArrows X c.inj).IsSheafFor F := by
  rw [Equalizer.Presieve.Arrows.sheaf_condition, Limits.Types.type_equalizer_iff_unique]
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  have hi : IsIso (piComparison F (fun x ↦ op (X x))) := inferInstance
  rw [piComparison_fac (hc := hc), isIso_iff_bijective, Function.bijective_iff_existsUnique] at hi
  intro b _
  obtain ⟨t, ht₁, ht₂⟩ := hi b
  refine ⟨F.map ((opCoproductIsoProduct' hc (productIsProduct _)).inv) t, ht₁, fun y hy ↦ ?_⟩
  apply_fun F.map ((opCoproductIsoProduct' hc (productIsProduct _)).hom) using injective_of_mono _
  simp only [← FunctorToTypes.map_comp_apply, Iso.op, Category.assoc]
  rw [ht₂ (F.map ((opCoproductIsoProduct' hc (productIsProduct _)).hom) y) (by simp [← hy])]
  change (𝟙 (F.obj (∏ fun x ↦ op (X x)))) t = _
  rw [← Functor.map_id]
  refine congrFun ?_ t
  

Proof state:
case intro.intro
C : Type u
inst✝⁴ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝³ : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝² : HasInitial C
inst✝¹ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
inst✝ : PreservesLimit (Discrete.functor fun x => op (X x)) F
this : HasCoproduct X
hi :
  ∀ (b : ∏ fun b => F.obj (op (X b))),
    ∃! a,
      (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
            Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))
          a =
        b
b : Equalizer.Presieve.Arrows.FirstObj F X
a✝ : Equalizer.Presieve.Arrows.firstMap F X (Cofan.inj c) b = Equalizer.Presieve.Arrows.secondMap F X (Cofan.inj c) b
t : F.obj (∏ fun x => op (X x))
ht₁ :
  (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
        Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))
      t =
    b
ht₂ :
  ∀ (y : F.obj (∏ fun x => op (X x))),
    (fun a =>
          (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
                Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))
              a =
            b)
        y →
      y = t
y : F.obj (op c.pt)
hy : (fun x => Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c) x = b) y
⊢ F.map (𝟙 (∏ fun x => op (X x))) =
    F.map
      ((opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
        (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).hom)

Next tactic:
congr
/--
If `F` preserves a particular product, then it `IsSheafFor` the corresponging presieve of arrows.
-/
theorem isSheafFor_of_preservesProduct [PreservesLimit (Discrete.functor (fun x ↦ op (X x))) F] :
    (ofArrows X c.inj).IsSheafFor F := by
  rw [Equalizer.Presieve.Arrows.sheaf_condition, Limits.Types.type_equalizer_iff_unique]
  have : HasCoproduct X := ⟨⟨c, hc⟩⟩
  have hi : IsIso (piComparison F (fun x ↦ op (X x))) := inferInstance
  rw [piComparison_fac (hc := hc), isIso_iff_bijective, Function.bijective_iff_existsUnique] at hi
  intro b _
  obtain ⟨t, ht₁, ht₂⟩ := hi b
  refine ⟨F.map ((opCoproductIsoProduct' hc (productIsProduct _)).inv) t, ht₁, fun y hy ↦ ?_⟩
  apply_fun F.map ((opCoproductIsoProduct' hc (productIsProduct _)).hom) using injective_of_mono _
  simp only [← FunctorToTypes.map_comp_apply, Iso.op, Category.assoc]
  rw [ht₂ (F.map ((opCoproductIsoProduct' hc (productIsProduct _)).hom) y) (by simp [← hy])]
  change (𝟙 (F.obj (∏ fun x ↦ op (X x)))) t = _
  rw [← Functor.map_id]
  refine congrFun ?_ t
  congr
  

Proof state:
case intro.intro.e_a
C : Type u
inst✝⁴ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝³ : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝² : HasInitial C
inst✝¹ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
inst✝ : PreservesLimit (Discrete.functor fun x => op (X x)) F
this : HasCoproduct X
hi :
  ∀ (b : ∏ fun b => F.obj (op (X b))),
    ∃! a,
      (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
            Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))
          a =
        b
b : Equalizer.Presieve.Arrows.FirstObj F X
a✝ : Equalizer.Presieve.Arrows.firstMap F X (Cofan.inj c) b = Equalizer.Presieve.Arrows.secondMap F X (Cofan.inj c) b
t : F.obj (∏ fun x => op (X x))
ht₁ :
  (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
        Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))
      t =
    b
ht₂ :
  ∀ (y : F.obj (∏ fun x => op (X x))),
    (fun a =>
          (F.map (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
                Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c))
              a =
            b)
        y →
      y = t
y : F.obj (op c.pt)
hy : (fun x => Equalizer.Presieve.Arrows.forkMap F X (Cofan.inj c) x = b) y
⊢ 𝟙 (∏ fun x => op (X x)) =
    (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).inv ≫
      (opCoproductIsoProduct' hc (productIsProduct fun x => op (X x))).hom

Next tactic:
simp [Iso.eq_inv_comp, ← Category.assoc, ← op_comp, eq_comm, ← Iso.eq_comp_inv]
theorem isSheafFor_iff_preservesProduct : (ofArrows X c.inj).IsSheafFor F ↔
    Nonempty (PreservesLimit (Discrete.functor (fun x ↦ op (X x))) F) := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
⊢ IsSheafFor F (ofArrows X (Cofan.inj c)) ↔ Nonempty (PreservesLimit (Discrete.functor fun x => op (X x)) F)

Next tactic:
refine ⟨fun hF' ↦ ⟨preservesProductOfIsSheafFor _ hF hI c hc hd hF'⟩, fun hF' ↦ ?_⟩
theorem isSheafFor_iff_preservesProduct : (ofArrows X c.inj).IsSheafFor F ↔
    Nonempty (PreservesLimit (Discrete.functor (fun x ↦ op (X x))) F) := by
  refine ⟨fun hF' ↦ ⟨preservesProductOfIsSheafFor _ hF hI c hc hd hF'⟩, fun hF' ↦ ?_⟩
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
hF' : Nonempty (PreservesLimit (Discrete.functor fun x => op (X x)) F)
⊢ IsSheafFor F (ofArrows X (Cofan.inj c))

Next tactic:
let _ := hF'.some
theorem isSheafFor_iff_preservesProduct : (ofArrows X c.inj).IsSheafFor F ↔
    Nonempty (PreservesLimit (Discrete.functor (fun x ↦ op (X x))) F) := by
  refine ⟨fun hF' ↦ ⟨preservesProductOfIsSheafFor _ hF hI c hc hd hF'⟩, fun hF' ↦ ?_⟩
  let _ := hF'.some
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
I : C
F : Cᵒᵖ ⥤ Type (max u v)
hF : IsSheafFor F (ofArrows Empty.elim fun a => IsEmpty.elim instIsEmptyEmpty a)
hI : IsInitial I
α : Type
X : α → C
c : Cofan X
hc : IsColimit c
inst✝² : hasPullbacks (ofArrows X (Cofan.inj c))
inst✝¹ : HasInitial C
inst✝ : ∀ (i : α), Mono (Cofan.inj c i)
hd : ∀ (i j : α), i ≠ j → IsPullback (initial.to (X i)) (initial.to (X j)) (Cofan.inj c i) (Cofan.inj c j)
hF' : Nonempty (PreservesLimit (Discrete.functor fun x => op (X x)) F)
x✝ : PreservesLimit (Discrete.functor fun x => op (X x)) F := Nonempty.some hF'
⊢ IsSheafFor F (ofArrows X (Cofan.inj c))

Next tactic:
exact isSheafFor_of_preservesProduct F c hc
/-- Define a `Ring` structure on a Type by proving a minimized set of axioms.
Note that this uses the default definitions for `npow`, `nsmul`, `zsmul` and `sub`
See note [reducible non-instances]. -/
@[reducible]
def Ring.ofMinimalAxioms {R : Type u}
    [Add R] [Mul R] [Neg R] [Zero R] [One R]
    (add_assoc : ∀ a b c : R, a + b + c = a + (b + c))
    (zero_add : ∀ a : R, 0 + a = a)
    (add_left_neg : ∀ a : R, -a + a = 0)
    (mul_assoc : ∀ a b c : R, a * b * c = a * (b * c))
    (one_mul : ∀ a : R, 1 * a = a)
    (mul_one : ∀ a : R, a * 1 = a)
    (left_distrib : ∀ a b c : R, a * (b + c) = a * b + a * c)
    (right_distrib : ∀ a b c : R, (a + b) * c = a * c + b * c) : Ring R :=
  letI := AddGroup.ofLeftAxioms add_assoc zero_add add_left_neg
  haveI add_comm : ∀ a b, a + b = b + a := by
    

Proof state:
R : Type u
inst✝⁴ : Add R
inst✝³ : Mul R
inst✝² : Neg R
inst✝¹ : Zero R
inst✝ : One R
add_assoc : ∀ (a b c : R), a + b + c = a + (b + c)
zero_add : ∀ (a : R), 0 + a = a
add_left_neg : ∀ (a : R), -a + a = 0
mul_assoc : ∀ (a b c : R), a * b * c = a * (b * c)
one_mul : ∀ (a : R), 1 * a = a
mul_one : ∀ (a : R), a * 1 = a
left_distrib : ∀ (a b c : R), a * (b + c) = a * b + a * c
right_distrib : ∀ (a b c : R), (a + b) * c = a * c + b * c
this : AddGroup R := AddGroup.ofLeftAxioms add_assoc zero_add add_left_neg
⊢ ∀ (a b : R), a + b = b + a

Next tactic:
intro a b
/-- Define a `Ring` structure on a Type by proving a minimized set of axioms.
Note that this uses the default definitions for `npow`, `nsmul`, `zsmul` and `sub`
See note [reducible non-instances]. -/
@[reducible]
def Ring.ofMinimalAxioms {R : Type u}
    [Add R] [Mul R] [Neg R] [Zero R] [One R]
    (add_assoc : ∀ a b c : R, a + b + c = a + (b + c))
    (zero_add : ∀ a : R, 0 + a = a)
    (add_left_neg : ∀ a : R, -a + a = 0)
    (mul_assoc : ∀ a b c : R, a * b * c = a * (b * c))
    (one_mul : ∀ a : R, 1 * a = a)
    (mul_one : ∀ a : R, a * 1 = a)
    (left_distrib : ∀ a b c : R, a * (b + c) = a * b + a * c)
    (right_distrib : ∀ a b c : R, (a + b) * c = a * c + b * c) : Ring R :=
  letI := AddGroup.ofLeftAxioms add_assoc zero_add add_left_neg
  haveI add_comm : ∀ a b, a + b = b + a := by
    intro a b
    

Proof state:
R : Type u
inst✝⁴ : Add R
inst✝³ : Mul R
inst✝² : Neg R
inst✝¹ : Zero R
inst✝ : One R
add_assoc : ∀ (a b c : R), a + b + c = a + (b + c)
zero_add : ∀ (a : R), 0 + a = a
add_left_neg : ∀ (a : R), -a + a = 0
mul_assoc : ∀ (a b c : R), a * b * c = a * (b * c)
one_mul : ∀ (a : R), 1 * a = a
mul_one : ∀ (a : R), a * 1 = a
left_distrib : ∀ (a b c : R), a * (b + c) = a * b + a * c
right_distrib : ∀ (a b c : R), (a + b) * c = a * c + b * c
this : AddGroup R := AddGroup.ofLeftAxioms add_assoc zero_add add_left_neg
a b : R
⊢ a + b = b + a

Next tactic:
have h₁ : (1 + 1 : R) * (a + b) = a + (a + b) + b := by
      rw [left_distrib]
      simp only [right_distrib, one_mul, add_assoc]
/-- Define a `Ring` structure on a Type by proving a minimized set of axioms.
Note that this uses the default definitions for `npow`, `nsmul`, `zsmul` and `sub`
See note [reducible non-instances]. -/
@[reducible]
def Ring.ofMinimalAxioms {R : Type u}
    [Add R] [Mul R] [Neg R] [Zero R] [One R]
    (add_assoc : ∀ a b c : R, a + b + c = a + (b + c))
    (zero_add : ∀ a : R, 0 + a = a)
    (add_left_neg : ∀ a : R, -a + a = 0)
    (mul_assoc : ∀ a b c : R, a * b * c = a * (b * c))
    (one_mul : ∀ a : R, 1 * a = a)
    (mul_one : ∀ a : R, a * 1 = a)
    (left_distrib : ∀ a b c : R, a * (b + c) = a * b + a * c)
    (right_distrib : ∀ a b c : R, (a + b) * c = a * c + b * c) : Ring R :=
  letI := AddGroup.ofLeftAxioms add_assoc zero_add add_left_neg
  haveI add_comm : ∀ a b, a + b = b + a := by
    intro a b
    have h₁ : (1 + 1 : R) * (a + b) = a + (a + b) + b := by
      

Proof state:
R : Type u
inst✝⁴ : Add R
inst✝³ : Mul R
inst✝² : Neg R
inst✝¹ : Zero R
inst✝ : One R
add_assoc : ∀ (a b c : R), a + b + c = a + (b + c)
zero_add : ∀ (a : R), 0 + a = a
add_left_neg : ∀ (a : R), -a + a = 0
mul_assoc : ∀ (a b c : R), a * b * c = a * (b * c)
one_mul : ∀ (a : R), 1 * a = a
mul_one : ∀ (a : R), a * 1 = a
left_distrib : ∀ (a b c : R), a * (b + c) = a * b + a * c
right_distrib : ∀ (a b c : R), (a + b) * c = a * c + b * c
this : AddGroup R := AddGroup.ofLeftAxioms add_assoc zero_add add_left_neg
a b : R
⊢ (1 + 1) * (a + b) = a + (a + b) + b

Next tactic:
rw [left_distrib]
/-- Define a `Ring` structure on a Type by proving a minimized set of axioms.
Note that this uses the default definitions for `npow`, `nsmul`, `zsmul` and `sub`
See note [reducible non-instances]. -/
@[reducible]
def Ring.ofMinimalAxioms {R : Type u}
    [Add R] [Mul R] [Neg R] [Zero R] [One R]
    (add_assoc : ∀ a b c : R, a + b + c = a + (b + c))
    (zero_add : ∀ a : R, 0 + a = a)
    (add_left_neg : ∀ a : R, -a + a = 0)
    (mul_assoc : ∀ a b c : R, a * b * c = a * (b * c))
    (one_mul : ∀ a : R, 1 * a = a)
    (mul_one : ∀ a : R, a * 1 = a)
    (left_distrib : ∀ a b c : R, a * (b + c) = a * b + a * c)
    (right_distrib : ∀ a b c : R, (a + b) * c = a * c + b * c) : Ring R :=
  letI := AddGroup.ofLeftAxioms add_assoc zero_add add_left_neg
  haveI add_comm : ∀ a b, a + b = b + a := by
    intro a b
    have h₁ : (1 + 1 : R) * (a + b) = a + (a + b) + b := by
      rw [left_distrib]
      

Proof state:
R : Type u
inst✝⁴ : Add R
inst✝³ : Mul R
inst✝² : Neg R
inst✝¹ : Zero R
inst✝ : One R
add_assoc : ∀ (a b c : R), a + b + c = a + (b + c)
zero_add : ∀ (a : R), 0 + a = a
add_left_neg : ∀ (a : R), -a + a = 0
mul_assoc : ∀ (a b c : R), a * b * c = a * (b * c)
one_mul : ∀ (a : R), 1 * a = a
mul_one : ∀ (a : R), a * 1 = a
left_distrib : ∀ (a b c : R), a * (b + c) = a * b + a * c
right_distrib : ∀ (a b c : R), (a + b) * c = a * c + b * c
this : AddGroup R := AddGroup.ofLeftAxioms add_assoc zero_add add_left_neg
a b : R
⊢ (1 + 1) * a + (1 + 1) * b = a + (a + b) + b

Next tactic:
simp only [right_distrib, one_mul, add_assoc]
/-- Define a `Ring` structure on a Type by proving a minimized set of axioms.
Note that this uses the default definitions for `npow`, `nsmul`, `zsmul` and `sub`
See note [reducible non-instances]. -/
@[reducible]
def Ring.ofMinimalAxioms {R : Type u}
    [Add R] [Mul R] [Neg R] [Zero R] [One R]
    (add_assoc : ∀ a b c : R, a + b + c = a + (b + c))
    (zero_add : ∀ a : R, 0 + a = a)
    (add_left_neg : ∀ a : R, -a + a = 0)
    (mul_assoc : ∀ a b c : R, a * b * c = a * (b * c))
    (one_mul : ∀ a : R, 1 * a = a)
    (mul_one : ∀ a : R, a * 1 = a)
    (left_distrib : ∀ a b c : R, a * (b + c) = a * b + a * c)
    (right_distrib : ∀ a b c : R, (a + b) * c = a * c + b * c) : Ring R :=
  letI := AddGroup.ofLeftAxioms add_assoc zero_add add_left_neg
  haveI add_comm : ∀ a b, a + b = b + a := by
    intro a b
    have h₁ : (1 + 1 : R) * (a + b) = a + (a + b) + b := by
      rw [left_distrib]
      simp only [right_distrib, one_mul, add_assoc]
    

Proof state:
R : Type u
inst✝⁴ : Add R
inst✝³ : Mul R
inst✝² : Neg R
inst✝¹ : Zero R
inst✝ : One R
add_assoc : ∀ (a b c : R), a + b + c = a + (b + c)
zero_add : ∀ (a : R), 0 + a = a
add_left_neg : ∀ (a : R), -a + a = 0
mul_assoc : ∀ (a b c : R), a * b * c = a * (b * c)
one_mul : ∀ (a : R), 1 * a = a
mul_one : ∀ (a : R), a * 1 = a
left_distrib : ∀ (a b c : R), a * (b + c) = a * b + a * c
right_distrib : ∀ (a b c : R), (a + b) * c = a * c + b * c
this : AddGroup R := AddGroup.ofLeftAxioms add_assoc zero_add add_left_neg
a b : R
h₁ : (1 + 1) * (a + b) = a + (a + b) + b
⊢ a + b = b + a

Next tactic:
have h₂ : (1 + 1 : R) * (a + b) = a + (b + a) + b := by
      rw [right_distrib]
      simp only [left_distrib, one_mul, add_assoc]