l3lab/ntp-mathlib huggingface dataset:
/-- The inversion of Ore fractions for a ring without zero divisors, satisying `0⁻¹ = 0` and
`(r /ₒ r')⁻¹ = r' /ₒ r` for `r ≠ 0`. -/
protected def inv : R[R⁰⁻¹] → R[R⁰⁻¹] :=
  liftExpand
    (fun r s =>
      if hr : r = (0 : R) then (0 : R[R⁰⁻¹])
      else s /ₒ ⟨r, fun _ => eq_zero_of_ne_zero_of_mul_right_eq_zero hr⟩)
    (by
      intro r t s hst
      by_cases hr : r = 0
      · 

Proof state:
case pos
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
r t : R
s : ↥R⁰
hst : ↑s * t ∈ R⁰
hr : r = 0
⊢ (fun r s => if hr : r = 0 then 0 else ↑s /ₒ { val := r, property := (_ : ∀ (x : R), x * r = 0 → x = 0) }) r s =
    (fun r s => if hr : r = 0 then 0 else ↑s /ₒ { val := r, property := (_ : ∀ (x : R), x * r = 0 → x = 0) }) (r * t)
      { val := ↑s * t, property := hst }

Next tactic:
simp [hr]
/-- The inversion of Ore fractions for a ring without zero divisors, satisying `0⁻¹ = 0` and
`(r /ₒ r')⁻¹ = r' /ₒ r` for `r ≠ 0`. -/
protected def inv : R[R⁰⁻¹] → R[R⁰⁻¹] :=
  liftExpand
    (fun r s =>
      if hr : r = (0 : R) then (0 : R[R⁰⁻¹])
      else s /ₒ ⟨r, fun _ => eq_zero_of_ne_zero_of_mul_right_eq_zero hr⟩)
    (by
      intro r t s hst
      by_cases hr : r = 0
      · simp [hr]
      · 

Proof state:
case neg
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
r t : R
s : ↥R⁰
hst : ↑s * t ∈ R⁰
hr : ¬r = 0
⊢ (fun r s => if hr : r = 0 then 0 else ↑s /ₒ { val := r, property := (_ : ∀ (x : R), x * r = 0 → x = 0) }) r s =
    (fun r s => if hr : r = 0 then 0 else ↑s /ₒ { val := r, property := (_ : ∀ (x : R), x * r = 0 → x = 0) }) (r * t)
      { val := ↑s * t, property := hst }

Next tactic:
by_cases ht : t = 0
/-- The inversion of Ore fractions for a ring without zero divisors, satisying `0⁻¹ = 0` and
`(r /ₒ r')⁻¹ = r' /ₒ r` for `r ≠ 0`. -/
protected def inv : R[R⁰⁻¹] → R[R⁰⁻¹] :=
  liftExpand
    (fun r s =>
      if hr : r = (0 : R) then (0 : R[R⁰⁻¹])
      else s /ₒ ⟨r, fun _ => eq_zero_of_ne_zero_of_mul_right_eq_zero hr⟩)
    (by
      intro r t s hst
      by_cases hr : r = 0
      · simp [hr]
      · by_cases ht : t = 0
        · 

Proof state:
case pos
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
r t : R
s : ↥R⁰
hst : ↑s * t ∈ R⁰
hr : ¬r = 0
ht : t = 0
⊢ (fun r s => if hr : r = 0 then 0 else ↑s /ₒ { val := r, property := (_ : ∀ (x : R), x * r = 0 → x = 0) }) r s =
    (fun r s => if hr : r = 0 then 0 else ↑s /ₒ { val := r, property := (_ : ∀ (x : R), x * r = 0 → x = 0) }) (r * t)
      { val := ↑s * t, property := hst }

Next tactic:
exfalso
/-- The inversion of Ore fractions for a ring without zero divisors, satisying `0⁻¹ = 0` and
`(r /ₒ r')⁻¹ = r' /ₒ r` for `r ≠ 0`. -/
protected def inv : R[R⁰⁻¹] → R[R⁰⁻¹] :=
  liftExpand
    (fun r s =>
      if hr : r = (0 : R) then (0 : R[R⁰⁻¹])
      else s /ₒ ⟨r, fun _ => eq_zero_of_ne_zero_of_mul_right_eq_zero hr⟩)
    (by
      intro r t s hst
      by_cases hr : r = 0
      · simp [hr]
      · by_cases ht : t = 0
        · exfalso
          

Proof state:
case pos.h
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
r t : R
s : ↥R⁰
hst : ↑s * t ∈ R⁰
hr : ¬r = 0
ht : t = 0
⊢ False

Next tactic:
apply nonZeroDivisors.coe_ne_zero ⟨_, hst⟩
/-- The inversion of Ore fractions for a ring without zero divisors, satisying `0⁻¹ = 0` and
`(r /ₒ r')⁻¹ = r' /ₒ r` for `r ≠ 0`. -/
protected def inv : R[R⁰⁻¹] → R[R⁰⁻¹] :=
  liftExpand
    (fun r s =>
      if hr : r = (0 : R) then (0 : R[R⁰⁻¹])
      else s /ₒ ⟨r, fun _ => eq_zero_of_ne_zero_of_mul_right_eq_zero hr⟩)
    (by
      intro r t s hst
      by_cases hr : r = 0
      · simp [hr]
      · by_cases ht : t = 0
        · exfalso
          apply nonZeroDivisors.coe_ne_zero ⟨_, hst⟩
          

Proof state:
case pos.h
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
r t : R
s : ↥R⁰
hst : ↑s * t ∈ R⁰
hr : ¬r = 0
ht : t = 0
⊢ ↑{ val := ↑s * t, property := hst } = 0

Next tactic:
simp [ht, mul_zero]
/-- The inversion of Ore fractions for a ring without zero divisors, satisying `0⁻¹ = 0` and
`(r /ₒ r')⁻¹ = r' /ₒ r` for `r ≠ 0`. -/
protected def inv : R[R⁰⁻¹] → R[R⁰⁻¹] :=
  liftExpand
    (fun r s =>
      if hr : r = (0 : R) then (0 : R[R⁰⁻¹])
      else s /ₒ ⟨r, fun _ => eq_zero_of_ne_zero_of_mul_right_eq_zero hr⟩)
    (by
      intro r t s hst
      by_cases hr : r = 0
      · simp [hr]
      · by_cases ht : t = 0
        · exfalso
          apply nonZeroDivisors.coe_ne_zero ⟨_, hst⟩
          simp [ht, mul_zero]
        · 

Proof state:
case neg
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
r t : R
s : ↥R⁰
hst : ↑s * t ∈ R⁰
hr : ¬r = 0
ht : ¬t = 0
⊢ (fun r s => if hr : r = 0 then 0 else ↑s /ₒ { val := r, property := (_ : ∀ (x : R), x * r = 0 → x = 0) }) r s =
    (fun r s => if hr : r = 0 then 0 else ↑s /ₒ { val := r, property := (_ : ∀ (x : R), x * r = 0 → x = 0) }) (r * t)
      { val := ↑s * t, property := hst }

Next tactic:
simp only [hr, ht, dif_neg, not_false_iff, or_self_iff, mul_eq_zero]
/-- The inversion of Ore fractions for a ring without zero divisors, satisying `0⁻¹ = 0` and
`(r /ₒ r')⁻¹ = r' /ₒ r` for `r ≠ 0`. -/
protected def inv : R[R⁰⁻¹] → R[R⁰⁻¹] :=
  liftExpand
    (fun r s =>
      if hr : r = (0 : R) then (0 : R[R⁰⁻¹])
      else s /ₒ ⟨r, fun _ => eq_zero_of_ne_zero_of_mul_right_eq_zero hr⟩)
    (by
      intro r t s hst
      by_cases hr : r = 0
      · simp [hr]
      · by_cases ht : t = 0
        · exfalso
          apply nonZeroDivisors.coe_ne_zero ⟨_, hst⟩
          simp [ht, mul_zero]
        · simp only [hr, ht, dif_neg, not_false_iff, or_self_iff, mul_eq_zero]
          

Proof state:
case neg
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
r t : R
s : ↥R⁰
hst : ↑s * t ∈ R⁰
hr : ¬r = 0
ht : ¬t = 0
⊢ ↑s /ₒ { val := r, property := (_ : ∀ (x : R), x * r = 0 → x = 0) } =
    ↑s * t /ₒ { val := r * t, property := (_ : ∀ (x : R), x * (r * t) = 0 → x = 0) }

Next tactic:
apply OreLocalization.expand
protected theorem mul_inv_cancel (x : R[R⁰⁻¹]) (h : x ≠ 0) : x * x⁻¹ = 1 := by
  

Proof state:
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
x : OreLocalization R R⁰
h : x ≠ 0
⊢ x * x⁻¹ = 1

Next tactic:
induction' x using OreLocalization.ind with r s
protected theorem mul_inv_cancel (x : R[R⁰⁻¹]) (h : x ≠ 0) : x * x⁻¹ = 1 := by
  induction' x using OreLocalization.ind with r s
  

Proof state:
case c
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
r : R
s : ↥R⁰
h : r /ₒ s ≠ 0
⊢ r /ₒ s * (r /ₒ s)⁻¹ = 1

Next tactic:
rw [OreLocalization.inv_def, OreLocalization.one_def]
protected theorem mul_inv_cancel (x : R[R⁰⁻¹]) (h : x ≠ 0) : x * x⁻¹ = 1 := by
  induction' x using OreLocalization.ind with r s
  rw [OreLocalization.inv_def, OreLocalization.one_def]
  

Proof state:
case c
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
r : R
s : ↥R⁰
h : r /ₒ s ≠ 0
⊢ (r /ₒ s * if hr : r = 0 then 0 else ↑s /ₒ { val := r, property := (_ : ∀ (x : R), x * r = 0 → x = 0) }) = 1 /ₒ 1

Next tactic:
by_cases hr : r = 0
protected theorem mul_inv_cancel (x : R[R⁰⁻¹]) (h : x ≠ 0) : x * x⁻¹ = 1 := by
  induction' x using OreLocalization.ind with r s
  rw [OreLocalization.inv_def, OreLocalization.one_def]
  by_cases hr : r = 0
  · 

Proof state:
case pos
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
r : R
s : ↥R⁰
h : r /ₒ s ≠ 0
hr : r = 0
⊢ (r /ₒ s * if hr : r = 0 then 0 else ↑s /ₒ { val := r, property := (_ : ∀ (x : R), x * r = 0 → x = 0) }) = 1 /ₒ 1

Next tactic:
exfalso
protected theorem mul_inv_cancel (x : R[R⁰⁻¹]) (h : x ≠ 0) : x * x⁻¹ = 1 := by
  induction' x using OreLocalization.ind with r s
  rw [OreLocalization.inv_def, OreLocalization.one_def]
  by_cases hr : r = 0
  · exfalso
    

Proof state:
case pos.h
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
r : R
s : ↥R⁰
h : r /ₒ s ≠ 0
hr : r = 0
⊢ False

Next tactic:
apply h
protected theorem mul_inv_cancel (x : R[R⁰⁻¹]) (h : x ≠ 0) : x * x⁻¹ = 1 := by
  induction' x using OreLocalization.ind with r s
  rw [OreLocalization.inv_def, OreLocalization.one_def]
  by_cases hr : r = 0
  · exfalso
    apply h
    

Proof state:
case pos.h
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
r : R
s : ↥R⁰
h : r /ₒ s ≠ 0
hr : r = 0
⊢ r /ₒ s = 0

Next tactic:
simp [hr]
protected theorem mul_inv_cancel (x : R[R⁰⁻¹]) (h : x ≠ 0) : x * x⁻¹ = 1 := by
  induction' x using OreLocalization.ind with r s
  rw [OreLocalization.inv_def, OreLocalization.one_def]
  by_cases hr : r = 0
  · exfalso
    apply h
    simp [hr]
  · 

Proof state:
case neg
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
r : R
s : ↥R⁰
h : r /ₒ s ≠ 0
hr : ¬r = 0
⊢ (r /ₒ s * if hr : r = 0 then 0 else ↑s /ₒ { val := r, property := (_ : ∀ (x : R), x * r = 0 → x = 0) }) = 1 /ₒ 1

Next tactic:
simp [hr]
protected theorem mul_inv_cancel (x : R[R⁰⁻¹]) (h : x ≠ 0) : x * x⁻¹ = 1 := by
  induction' x using OreLocalization.ind with r s
  rw [OreLocalization.inv_def, OreLocalization.one_def]
  by_cases hr : r = 0
  · exfalso
    apply h
    simp [hr]
  · simp [hr]
    

Proof state:
case neg
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
r : R
s : ↥R⁰
h : r /ₒ s ≠ 0
hr : ¬r = 0
⊢ 1 = 1 /ₒ 1

Next tactic:
apply OreLocalization.div_eq_one'
protected theorem inv_zero : (0 : R[R⁰⁻¹])⁻¹ = 0 := by
  

Proof state:
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
⊢ 0⁻¹ = 0

Next tactic:
rw [OreLocalization.zero_def, OreLocalization.inv_def]
protected theorem inv_zero : (0 : R[R⁰⁻¹])⁻¹ = 0 := by
  rw [OreLocalization.zero_def, OreLocalization.inv_def]
  

Proof state:
R : Type u_1
inst✝³ : Ring R
inst✝² : Nontrivial R
inst✝¹ : OreSet R⁰
inst✝ : NoZeroDivisors R
⊢ (if hr : 0 = 0 then 0 else ↑1 /ₒ { val := 0, property := (_ : ∀ (x : R), x * 0 = 0 → x = 0) }) = 0 /ₒ 1

Next tactic:
simp
theorem prod_unique (f : R →ₙ+* S × T) : ((fst S T).comp f).prod ((snd S T).comp f) = f :=
  ext fun x => by 

Proof state:
α : Type u_1
β : Type u_2
R : Type u_3
R' : Type u_4
S : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
inst✝² : NonUnitalNonAssocSemiring R
inst✝¹ : NonUnitalNonAssocSemiring S
inst✝ : NonUnitalNonAssocSemiring T
f✝ : R →ₙ+* S
g : R →ₙ+* T
f : R →ₙ+* S × T
x : R
⊢ (NonUnitalRingHom.prod (comp (fst S T) f) (comp (snd S T) f)) x = f x

Next tactic:
simp only [prod_apply, coe_fst, coe_snd, comp_apply]
theorem prod_unique (f : R →+* S × T) : ((fst S T).comp f).prod ((snd S T).comp f) = f :=
  ext fun x => by 

Proof state:
α : Type u_1
β : Type u_2
R : Type u_3
R' : Type u_4
S : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
inst✝² : NonAssocSemiring R
inst✝¹ : NonAssocSemiring S
inst✝ : NonAssocSemiring T
f✝ : R →+* S
g : R →+* T
f : R →+* S × T
x : R
⊢ (RingHom.prod (comp (fst S T) f) (comp (snd S T) f)) x = f x

Next tactic:
simp only [prod_apply, coe_fst, coe_snd, comp_apply]
/-- A ring `R` is isomorphic to `R × S` when `S` is the zero ring -/
@[simps]
def prodZeroRing : R ≃+* R × S where
  toFun x := (x, 0)
  invFun := Prod.fst
  map_add' := by simp
  map_mul' := by simp
  left_inv x := rfl
  right_inv x := by 

Proof state:
α : Type u_1
β : Type u_2
R : Type u_3
R' : Type u_4
S : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
inst✝⁴ : NonAssocSemiring R
inst✝³ : NonAssocSemiring S
inst✝² : NonAssocSemiring R'
inst✝¹ : NonAssocSemiring S'
inst✝ : Subsingleton S
x : R × S
⊢ (fun x => (x, 0)) x.1 = x

Next tactic:
cases x
/-- A ring `R` is isomorphic to `R × S` when `S` is the zero ring -/
@[simps]
def prodZeroRing : R ≃+* R × S where
  toFun x := (x, 0)
  invFun := Prod.fst
  map_add' := by simp
  map_mul' := by simp
  left_inv x := rfl
  right_inv x := by cases x; 

Proof state:
case mk
α : Type u_1
β : Type u_2
R : Type u_3
R' : Type u_4
S : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
inst✝⁴ : NonAssocSemiring R
inst✝³ : NonAssocSemiring S
inst✝² : NonAssocSemiring R'
inst✝¹ : NonAssocSemiring S'
inst✝ : Subsingleton S
fst✝ : R
snd✝ : S
⊢ (fun x => (x, 0)) (fst✝, snd✝).1 = (fst✝, snd✝)

Next tactic:
simp [eq_iff_true_of_subsingleton]
/-- A ring `R` is isomorphic to `R × S` when `S` is the zero ring -/
@[simps]
def prodZeroRing : R ≃+* R × S where
  toFun x := (x, 0)
  invFun := Prod.fst
  map_add' := by simp
  map_mul' := by 

Proof state:
α : Type u_1
β : Type u_2
R : Type u_3
R' : Type u_4
S : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
inst✝⁴ : NonAssocSemiring R
inst✝³ : NonAssocSemiring S
inst✝² : NonAssocSemiring R'
inst✝¹ : NonAssocSemiring S'
inst✝ : Subsingleton S
⊢ ∀ (x y : R),
    Equiv.toFun
        { toFun := fun x => (x, 0), invFun := Prod.fst,
          left_inv := (_ : ∀ (x : R), ((fun x => (x, 0)) x).1 = ((fun x => (x, 0)) x).1),
          right_inv := (_ : ∀ (x : R × S), (fun x => (x, 0)) x.1 = x) }
        (x * y) =
      Equiv.toFun
          { toFun := fun x => (x, 0), invFun := Prod.fst,
            left_inv := (_ : ∀ (x : R), ((fun x => (x, 0)) x).1 = ((fun x => (x, 0)) x).1),
            right_inv := (_ : ∀ (x : R × S), (fun x => (x, 0)) x.1 = x) }
          x *
        Equiv.toFun
          { toFun := fun x => (x, 0), invFun := Prod.fst,
            left_inv := (_ : ∀ (x : R), ((fun x => (x, 0)) x).1 = ((fun x => (x, 0)) x).1),
            right_inv := (_ : ∀ (x : R × S), (fun x => (x, 0)) x.1 = x) }
          y

Next tactic:
simp
/-- A ring `R` is isomorphic to `R × S` when `S` is the zero ring -/
@[simps]
def prodZeroRing : R ≃+* R × S where
  toFun x := (x, 0)
  invFun := Prod.fst
  map_add' := by 

Proof state:
α : Type u_1
β : Type u_2
R : Type u_3
R' : Type u_4
S : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
inst✝⁴ : NonAssocSemiring R
inst✝³ : NonAssocSemiring S
inst✝² : NonAssocSemiring R'
inst✝¹ : NonAssocSemiring S'
inst✝ : Subsingleton S
⊢ ∀ (x y : R),
    Equiv.toFun
        { toFun := fun x => (x, 0), invFun := Prod.fst,
          left_inv := (_ : ∀ (x : R), ((fun x => (x, 0)) x).1 = ((fun x => (x, 0)) x).1),
          right_inv := (_ : ∀ (x : R × S), (fun x => (x, 0)) x.1 = x) }
        (x + y) =
      Equiv.toFun
          { toFun := fun x => (x, 0), invFun := Prod.fst,
            left_inv := (_ : ∀ (x : R), ((fun x => (x, 0)) x).1 = ((fun x => (x, 0)) x).1),
            right_inv := (_ : ∀ (x : R × S), (fun x => (x, 0)) x.1 = x) }
          x +
        Equiv.toFun
          { toFun := fun x => (x, 0), invFun := Prod.fst,
            left_inv := (_ : ∀ (x : R), ((fun x => (x, 0)) x).1 = ((fun x => (x, 0)) x).1),
            right_inv := (_ : ∀ (x : R × S), (fun x => (x, 0)) x.1 = x) }
          y

Next tactic:
simp
/-- A ring `R` is isomorphic to `S × R` when `S` is the zero ring -/
@[simps]
def zeroRingProd : R ≃+* S × R where
  toFun x := (0, x)
  invFun := Prod.snd
  map_add' := by simp
  map_mul' := by simp
  left_inv x := rfl
  right_inv x := by 

Proof state:
α : Type u_1
β : Type u_2
R : Type u_3
R' : Type u_4
S : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
inst✝⁴ : NonAssocSemiring R
inst✝³ : NonAssocSemiring S
inst✝² : NonAssocSemiring R'
inst✝¹ : NonAssocSemiring S'
inst✝ : Subsingleton S
x : S × R
⊢ (fun x => (0, x)) x.2 = x

Next tactic:
cases x
/-- A ring `R` is isomorphic to `S × R` when `S` is the zero ring -/
@[simps]
def zeroRingProd : R ≃+* S × R where
  toFun x := (0, x)
  invFun := Prod.snd
  map_add' := by simp
  map_mul' := by simp
  left_inv x := rfl
  right_inv x := by cases x; 

Proof state:
case mk
α : Type u_1
β : Type u_2
R : Type u_3
R' : Type u_4
S : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
inst✝⁴ : NonAssocSemiring R
inst✝³ : NonAssocSemiring S
inst✝² : NonAssocSemiring R'
inst✝¹ : NonAssocSemiring S'
inst✝ : Subsingleton S
fst✝ : S
snd✝ : R
⊢ (fun x => (0, x)) (fst✝, snd✝).2 = (fst✝, snd✝)

Next tactic:
simp [eq_iff_true_of_subsingleton]
/-- A ring `R` is isomorphic to `S × R` when `S` is the zero ring -/
@[simps]
def zeroRingProd : R ≃+* S × R where
  toFun x := (0, x)
  invFun := Prod.snd
  map_add' := by simp
  map_mul' := by 

Proof state:
α : Type u_1
β : Type u_2
R : Type u_3
R' : Type u_4
S : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
inst✝⁴ : NonAssocSemiring R
inst✝³ : NonAssocSemiring S
inst✝² : NonAssocSemiring R'
inst✝¹ : NonAssocSemiring S'
inst✝ : Subsingleton S
⊢ ∀ (x y : R),
    Equiv.toFun
        { toFun := fun x => (0, x), invFun := Prod.snd,
          left_inv := (_ : ∀ (x : R), ((fun x => (0, x)) x).2 = ((fun x => (0, x)) x).2),
          right_inv := (_ : ∀ (x : S × R), (fun x => (0, x)) x.2 = x) }
        (x * y) =
      Equiv.toFun
          { toFun := fun x => (0, x), invFun := Prod.snd,
            left_inv := (_ : ∀ (x : R), ((fun x => (0, x)) x).2 = ((fun x => (0, x)) x).2),
            right_inv := (_ : ∀ (x : S × R), (fun x => (0, x)) x.2 = x) }
          x *
        Equiv.toFun
          { toFun := fun x => (0, x), invFun := Prod.snd,
            left_inv := (_ : ∀ (x : R), ((fun x => (0, x)) x).2 = ((fun x => (0, x)) x).2),
            right_inv := (_ : ∀ (x : S × R), (fun x => (0, x)) x.2 = x) }
          y

Next tactic:
simp
/-- A ring `R` is isomorphic to `S × R` when `S` is the zero ring -/
@[simps]
def zeroRingProd : R ≃+* S × R where
  toFun x := (0, x)
  invFun := Prod.snd
  map_add' := by 

Proof state:
α : Type u_1
β : Type u_2
R : Type u_3
R' : Type u_4
S : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
inst✝⁴ : NonAssocSemiring R
inst✝³ : NonAssocSemiring S
inst✝² : NonAssocSemiring R'
inst✝¹ : NonAssocSemiring S'
inst✝ : Subsingleton S
⊢ ∀ (x y : R),
    Equiv.toFun
        { toFun := fun x => (0, x), invFun := Prod.snd,
          left_inv := (_ : ∀ (x : R), ((fun x => (0, x)) x).2 = ((fun x => (0, x)) x).2),
          right_inv := (_ : ∀ (x : S × R), (fun x => (0, x)) x.2 = x) }
        (x + y) =
      Equiv.toFun
          { toFun := fun x => (0, x), invFun := Prod.snd,
            left_inv := (_ : ∀ (x : R), ((fun x => (0, x)) x).2 = ((fun x => (0, x)) x).2),
            right_inv := (_ : ∀ (x : S × R), (fun x => (0, x)) x.2 = x) }
          x +
        Equiv.toFun
          { toFun := fun x => (0, x), invFun := Prod.snd,
            left_inv := (_ : ∀ (x : R), ((fun x => (0, x)) x).2 = ((fun x => (0, x)) x).2),
            right_inv := (_ : ∀ (x : S × R), (fun x => (0, x)) x.2 = x) }
          y

Next tactic:
simp
/-- The product of two nontrivial rings is not a domain -/
theorem false_of_nontrivial_of_product_domain (R S : Type*) [Ring R] [Ring S] [IsDomain (R × S)]
    [Nontrivial R] [Nontrivial S] : False := by
  

Proof state:
α : Type u_1
β : Type u_2
R✝ : Type u_3
R' : Type u_4
S✝ : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
R : Type u_9
S : Type u_10
inst✝⁴ : Ring R
inst✝³ : Ring S
inst✝² : IsDomain (R × S)
inst✝¹ : Nontrivial R
inst✝ : Nontrivial S
⊢ False

Next tactic:
have :=
    NoZeroDivisors.eq_zero_or_eq_zero_of_mul_eq_zero (show ((0 : R), (1 : S)) * (1, 0) = 0 by simp)
/-- The product of two nontrivial rings is not a domain -/
theorem false_of_nontrivial_of_product_domain (R S : Type*) [Ring R] [Ring S] [IsDomain (R × S)]
    [Nontrivial R] [Nontrivial S] : False := by
  have :=
    NoZeroDivisors.eq_zero_or_eq_zero_of_mul_eq_zero (show ((0 : R), (1 : S)) * (1, 0) = 0 by 

Proof state:
α : Type u_1
β : Type u_2
R✝ : Type u_3
R' : Type u_4
S✝ : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
R : Type u_9
S : Type u_10
inst✝⁴ : Ring R
inst✝³ : Ring S
inst✝² : IsDomain (R × S)
inst✝¹ : Nontrivial R
inst✝ : Nontrivial S
⊢ (0, 1) * (1, 0) = 0

Next tactic:
simp
/-- The product of two nontrivial rings is not a domain -/
theorem false_of_nontrivial_of_product_domain (R S : Type*) [Ring R] [Ring S] [IsDomain (R × S)]
    [Nontrivial R] [Nontrivial S] : False := by
  have :=
    NoZeroDivisors.eq_zero_or_eq_zero_of_mul_eq_zero (show ((0 : R), (1 : S)) * (1, 0) = 0 by simp)
  

Proof state:
α : Type u_1
β : Type u_2
R✝ : Type u_3
R' : Type u_4
S✝ : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
R : Type u_9
S : Type u_10
inst✝⁴ : Ring R
inst✝³ : Ring S
inst✝² : IsDomain (R × S)
inst✝¹ : Nontrivial R
inst✝ : Nontrivial S
this : (0, 1) = 0 ∨ (1, 0) = 0
⊢ False

Next tactic:
rw [Prod.mk_eq_zero, Prod.mk_eq_zero] at this
/-- The product of two nontrivial rings is not a domain -/
theorem false_of_nontrivial_of_product_domain (R S : Type*) [Ring R] [Ring S] [IsDomain (R × S)]
    [Nontrivial R] [Nontrivial S] : False := by
  have :=
    NoZeroDivisors.eq_zero_or_eq_zero_of_mul_eq_zero (show ((0 : R), (1 : S)) * (1, 0) = 0 by simp)
  rw [Prod.mk_eq_zero, Prod.mk_eq_zero] at this
  

Proof state:
α : Type u_1
β : Type u_2
R✝ : Type u_3
R' : Type u_4
S✝ : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
R : Type u_9
S : Type u_10
inst✝⁴ : Ring R
inst✝³ : Ring S
inst✝² : IsDomain (R × S)
inst✝¹ : Nontrivial R
inst✝ : Nontrivial S
this : 0 = 0 ∧ 1 = 0 ∨ 1 = 0 ∧ 0 = 0
⊢ False

Next tactic:
rcases this with (⟨_, h⟩ | ⟨h, _⟩)
/-- The product of two nontrivial rings is not a domain -/
theorem false_of_nontrivial_of_product_domain (R S : Type*) [Ring R] [Ring S] [IsDomain (R × S)]
    [Nontrivial R] [Nontrivial S] : False := by
  have :=
    NoZeroDivisors.eq_zero_or_eq_zero_of_mul_eq_zero (show ((0 : R), (1 : S)) * (1, 0) = 0 by simp)
  rw [Prod.mk_eq_zero, Prod.mk_eq_zero] at this
  rcases this with (⟨_, h⟩ | ⟨h, _⟩)
  · 

Proof state:
case inl.intro
α : Type u_1
β : Type u_2
R✝ : Type u_3
R' : Type u_4
S✝ : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
R : Type u_9
S : Type u_10
inst✝⁴ : Ring R
inst✝³ : Ring S
inst✝² : IsDomain (R × S)
inst✝¹ : Nontrivial R
inst✝ : Nontrivial S
left✝ : 0 = 0
h : 1 = 0
⊢ False

Next tactic:
exact zero_ne_one h.symm
/-- The product of two nontrivial rings is not a domain -/
theorem false_of_nontrivial_of_product_domain (R S : Type*) [Ring R] [Ring S] [IsDomain (R × S)]
    [Nontrivial R] [Nontrivial S] : False := by
  have :=
    NoZeroDivisors.eq_zero_or_eq_zero_of_mul_eq_zero (show ((0 : R), (1 : S)) * (1, 0) = 0 by simp)
  rw [Prod.mk_eq_zero, Prod.mk_eq_zero] at this
  rcases this with (⟨_, h⟩ | ⟨h, _⟩)
  · exact zero_ne_one h.symm
  · 

Proof state:
case inr.intro
α : Type u_1
β : Type u_2
R✝ : Type u_3
R' : Type u_4
S✝ : Type u_5
S' : Type u_6
T : Type u_7
T' : Type u_8
R : Type u_9
S : Type u_10
inst✝⁴ : Ring R
inst✝³ : Ring S
inst✝² : IsDomain (R × S)
inst✝¹ : Nontrivial R
inst✝ : Nontrivial S
h : 1 = 0
right✝ : 0 = 0
⊢ False

Next tactic:
exact zero_ne_one h.symm
/-- Since the vector space is empty the ring is commutative. -/
instance : CommRing (CliffordAlgebra (0 : QuadraticForm R Unit)) :=
  { CliffordAlgebra.instRing _ with
    mul_comm := fun x y => by
      

Proof state:
R : Type u_1
inst✝ : CommRing R
src✝ : Ring (CliffordAlgebra 0) := instRing 0
x y : CliffordAlgebra 0
⊢ x * y = y * x

Next tactic:
induction x using CliffordAlgebra.induction
/-- Since the vector space is empty the ring is commutative. -/
instance : CommRing (CliffordAlgebra (0 : QuadraticForm R Unit)) :=
  { CliffordAlgebra.instRing _ with
    mul_comm := fun x y => by
      induction x using CliffordAlgebra.induction
      

Proof state:
case h_grade0
R : Type u_1
inst✝ : CommRing R
src✝ : Ring (CliffordAlgebra 0) := instRing 0
y : CliffordAlgebra 0
r✝ : R
⊢ (algebraMap R (CliffordAlgebra 0)) r✝ * y = y * (algebraMap R (CliffordAlgebra 0)) r✝
case h_grade1
R : Type u_1
inst✝ : CommRing R
src✝ : Ring (CliffordAlgebra 0) := instRing 0
y : CliffordAlgebra 0
x✝ : Unit
⊢ (ι 0) x✝ * y = y * (ι 0) x✝
case h_mul
R : Type u_1
inst✝ : CommRing R
src✝ : Ring (CliffordAlgebra 0) := instRing 0
y a✝² b✝ : CliffordAlgebra 0
a✝¹ : a✝² * y = y * a✝²
a✝ : b✝ * y = y * b✝
⊢ a✝² * b✝ * y = y * (a✝² * b✝)
case h_add
R : Type u_1
inst✝ : CommRing R
src✝ : Ring (CliffordAlgebra 0) := instRing 0
y a✝² b✝ : CliffordAlgebra 0
a✝¹ : a✝² * y = y * a✝²
a✝ : b✝ * y = y * b✝
⊢ (a✝² + b✝) * y = y * (a✝² + b✝)

Next tactic:
case h_grade0 r => apply Algebra.commutes