l3lab/ntp-mathlib huggingface dataset:
theorem IsNilpotent.isUnit_quotient_mk_iff {R : Type*} [CommRing R] {I : Ideal R}
    (hI : IsNilpotent I) {x : R} : IsUnit (Ideal.Quotient.mk I x) ↔ IsUnit x := by
  refine' ⟨_, fun h => h.map <| Ideal.Quotient.mk I⟩
  revert x
  apply Ideal.IsNilpotent.induction_on (R := R) (S := R) I hI <;> clear hI I
  swap
  · introv e h₁ h₂ h₃
    apply h₁
    apply h₂
    exact
      h₃.map
        ((DoubleQuot.quotQuotEquivQuotSup I J).trans
              (Ideal.quotEquivOfEq (sup_eq_right.mpr e))).symm.toRingHom
  · introv e H
    skip
    obtain ⟨y, hy⟩ := Ideal.Quotient.mk_surjective (↑H.unit⁻¹ : S ⧸ I)
    have : Ideal.Quotient.mk I (x * y) = Ideal.Quotient.mk I 1 := by
      rw [map_one, _root_.map_mul, hy, IsUnit.mul_val_inv]
    rw [Ideal.Quotient.eq] at this
    have : (x * y - 1) ^ 2 = 0 := by
      rw [← Ideal.mem_bot, ← e]
      exact Ideal.pow_mem_pow this _
    have : x * (y * (2 - x * y)) = 1 := by
      rw [eq_comm, ← sub_eq_zero, ← this]
      

Proof state:
R✝ : Type u_1
S✝ : Type u_2
inst✝⁴ : CommSemiring R✝
inst✝³ : CommRing S✝
inst✝² : Algebra R✝ S✝
I✝ : Ideal S✝
R : Type u_3
inst✝¹ : CommRing R
S : Type u_3
inst✝ : CommRing S
I : Ideal S
e : I ^ 2 = ⊥
x : S
H : IsUnit ((Ideal.Quotient.mk I) x)
y : S
hy : (Ideal.Quotient.mk I) y = ↑(IsUnit.unit H)⁻¹
this✝ : x * y - 1 ∈ I
this : (x * y - 1) ^ 2 = 0
⊢ 1 - x * (y * (2 - x * y)) = (x * y - 1) ^ 2

Next tactic:
ring
theorem IsNilpotent.isUnit_quotient_mk_iff {R : Type*} [CommRing R] {I : Ideal R}
    (hI : IsNilpotent I) {x : R} : IsUnit (Ideal.Quotient.mk I x) ↔ IsUnit x := by
  refine' ⟨_, fun h => h.map <| Ideal.Quotient.mk I⟩
  revert x
  apply Ideal.IsNilpotent.induction_on (R := R) (S := R) I hI <;> clear hI I
  swap
  · introv e h₁ h₂ h₃
    apply h₁
    apply h₂
    exact
      h₃.map
        ((DoubleQuot.quotQuotEquivQuotSup I J).trans
              (Ideal.quotEquivOfEq (sup_eq_right.mpr e))).symm.toRingHom
  · introv e H
    skip
    obtain ⟨y, hy⟩ := Ideal.Quotient.mk_surjective (↑H.unit⁻¹ : S ⧸ I)
    have : Ideal.Quotient.mk I (x * y) = Ideal.Quotient.mk I 1 := by
      rw [map_one, _root_.map_mul, hy, IsUnit.mul_val_inv]
    rw [Ideal.Quotient.eq] at this
    have : (x * y - 1) ^ 2 = 0 := by
      rw [← Ideal.mem_bot, ← e]
      exact Ideal.pow_mem_pow this _
    have : x * (y * (2 - x * y)) = 1 := by
      rw [eq_comm, ← sub_eq_zero, ← this]
      ring
    

Proof state:
case h₁.intro
R✝ : Type u_1
S✝ : Type u_2
inst✝⁴ : CommSemiring R✝
inst✝³ : CommRing S✝
inst✝² : Algebra R✝ S✝
I✝ : Ideal S✝
R : Type u_3
inst✝¹ : CommRing R
S : Type u_3
inst✝ : CommRing S
I : Ideal S
e : I ^ 2 = ⊥
x : S
H : IsUnit ((Ideal.Quotient.mk I) x)
y : S
hy : (Ideal.Quotient.mk I) y = ↑(IsUnit.unit H)⁻¹
this✝¹ : x * y - 1 ∈ I
this✝ : (x * y - 1) ^ 2 = 0
this : x * (y * (2 - x * y)) = 1
⊢ IsUnit x

Next tactic:
exact isUnit_of_mul_eq_one _ _ this
instance monMonoid (A : Mon_ (Type u)) : Monoid A.X where
  one := A.one PUnit.unit
  mul x y := A.mul (x, y)
  one_mul x := by convert congr_fun A.one_mul (PUnit.unit, x)
  mul_one x := by convert congr_fun A.mul_one (x, PUnit.unit)
  mul_assoc x y z := by 

Proof state:
A : Mon_ (Type u)
x y z : A.X
⊢ x * y * z = x * (y * z)

Next tactic:
convert congr_fun A.mul_assoc ((x, y), z)
instance monMonoid (A : Mon_ (Type u)) : Monoid A.X where
  one := A.one PUnit.unit
  mul x y := A.mul (x, y)
  one_mul x := by 

Proof state:
A : Mon_ (Type u)
x : A.X
⊢ 1 * x = x

Next tactic:
convert congr_fun A.one_mul (PUnit.unit, x)
instance monMonoid (A : Mon_ (Type u)) : Monoid A.X where
  one := A.one PUnit.unit
  mul x y := A.mul (x, y)
  one_mul x := by convert congr_fun A.one_mul (PUnit.unit, x)
  mul_one x := by 

Proof state:
A : Mon_ (Type u)
x : A.X
⊢ x * 1 = x

Next tactic:
convert congr_fun A.mul_one (x, PUnit.unit)
/-- Converting a bundled monoid to a monoid object in `Type`.
-/
noncomputable def inverse : MonCat.{u} ⥤ Mon_ (Type u) where
  obj A :=
    { X := A
      one := fun _ => 1
      mul := fun p => p.1 * p.2
      one_mul := by 

Proof state:
A : MonCat
⊢ (MonoidalCategory.tensorHom (fun x => 1) (𝟙 ↑A) ≫ fun p => p.1 * p.2) = (MonoidalCategory.leftUnitor ↑A).hom

Next tactic:
ext ⟨_, _⟩
/-- Converting a bundled monoid to a monoid object in `Type`.
-/
noncomputable def inverse : MonCat.{u} ⥤ Mon_ (Type u) where
  obj A :=
    { X := A
      one := fun _ => 1
      mul := fun p => p.1 * p.2
      one_mul := by ext ⟨_, _⟩; 

Proof state:
case h.mk
A : MonCat
fst✝ : 𝟙_ (Type u)
snd✝ : ↑A
⊢ (MonoidalCategory.tensorHom (fun x => 1) (𝟙 ↑A) ≫ fun p => p.1 * p.2) (fst✝, snd✝) =
    (MonoidalCategory.leftUnitor ↑A).hom (fst✝, snd✝)

Next tactic:
dsimp
/-- Converting a bundled monoid to a monoid object in `Type`.
-/
noncomputable def inverse : MonCat.{u} ⥤ Mon_ (Type u) where
  obj A :=
    { X := A
      one := fun _ => 1
      mul := fun p => p.1 * p.2
      one_mul := by ext ⟨_, _⟩; dsimp; 

Proof state:
case h.mk
A : MonCat
fst✝ : 𝟙_ (Type u)
snd✝ : ↑A
⊢ 1 * snd✝ = snd✝

Next tactic:
simp
/-- Converting a bundled monoid to a monoid object in `Type`.
-/
noncomputable def inverse : MonCat.{u} ⥤ Mon_ (Type u) where
  obj A :=
    { X := A
      one := fun _ => 1
      mul := fun p => p.1 * p.2
      one_mul := by ext ⟨_, _⟩; dsimp; simp
      mul_one := by 

Proof state:
A : MonCat
⊢ ((MonoidalCategory.tensorHom (𝟙 ↑A) fun x => 1) ≫ fun p => p.1 * p.2) = (MonoidalCategory.rightUnitor ↑A).hom

Next tactic:
ext ⟨_, _⟩
/-- Converting a bundled monoid to a monoid object in `Type`.
-/
noncomputable def inverse : MonCat.{u} ⥤ Mon_ (Type u) where
  obj A :=
    { X := A
      one := fun _ => 1
      mul := fun p => p.1 * p.2
      one_mul := by ext ⟨_, _⟩; dsimp; simp
      mul_one := by ext ⟨_, _⟩; 

Proof state:
case h.mk
A : MonCat
fst✝ : ↑A
snd✝ : 𝟙_ (Type u)
⊢ ((MonoidalCategory.tensorHom (𝟙 ↑A) fun x => 1) ≫ fun p => p.1 * p.2) (fst✝, snd✝) =
    (MonoidalCategory.rightUnitor ↑A).hom (fst✝, snd✝)

Next tactic:
dsimp
/-- Converting a bundled monoid to a monoid object in `Type`.
-/
noncomputable def inverse : MonCat.{u} ⥤ Mon_ (Type u) where
  obj A :=
    { X := A
      one := fun _ => 1
      mul := fun p => p.1 * p.2
      one_mul := by ext ⟨_, _⟩; dsimp; simp
      mul_one := by ext ⟨_, _⟩; dsimp; 

Proof state:
case h.mk
A : MonCat
fst✝ : ↑A
snd✝ : 𝟙_ (Type u)
⊢ fst✝ * 1 = fst✝

Next tactic:
simp
/-- Converting a bundled monoid to a monoid object in `Type`.
-/
noncomputable def inverse : MonCat.{u} ⥤ Mon_ (Type u) where
  obj A :=
    { X := A
      one := fun _ => 1
      mul := fun p => p.1 * p.2
      one_mul := by ext ⟨_, _⟩; dsimp; simp
      mul_one := by ext ⟨_, _⟩; dsimp; simp
      mul_assoc := by 

Proof state:
A : MonCat
⊢ (MonoidalCategory.tensorHom (fun p => p.1 * p.2) (𝟙 ↑A) ≫ fun p => p.1 * p.2) =
    (MonoidalCategory.associator ↑A ↑A ↑A).hom ≫
      (MonoidalCategory.tensorHom (𝟙 ↑A) fun p => p.1 * p.2) ≫ fun p => p.1 * p.2

Next tactic:
ext ⟨⟨x, y⟩, z⟩
/-- Converting a bundled monoid to a monoid object in `Type`.
-/
noncomputable def inverse : MonCat.{u} ⥤ Mon_ (Type u) where
  obj A :=
    { X := A
      one := fun _ => 1
      mul := fun p => p.1 * p.2
      one_mul := by ext ⟨_, _⟩; dsimp; simp
      mul_one := by ext ⟨_, _⟩; dsimp; simp
      mul_assoc := by ext ⟨⟨x, y⟩, z⟩; 

Proof state:
case h.mk.mk
A : MonCat
z x y : ↑A
⊢ (MonoidalCategory.tensorHom (fun p => p.1 * p.2) (𝟙 ↑A) ≫ fun p => p.1 * p.2) ((x, y), z) =
    ((MonoidalCategory.associator ↑A ↑A ↑A).hom ≫
        (MonoidalCategory.tensorHom (𝟙 ↑A) fun p => p.1 * p.2) ≫ fun p => p.1 * p.2)
      ((x, y), z)

Next tactic:
simp [mul_assoc]
/-- The category of internal monoid objects in `Type`
is equivalent to the category of "native" bundled monoids.
-/
noncomputable def monTypeEquivalenceMon : Mon_ (Type u) ≌ MonCat.{u} where
  functor := functor
  inverse := inverse
  unitIso :=
    NatIso.ofComponents
      (fun A =>
        { hom := { hom := 𝟙 _ }
          inv := { hom := 𝟙 _ } })
      (by 

Proof state:
⊢ ∀ {X Y : Mon_ (Type u)} (f : X ⟶ Y),
    (𝟭 (Mon_ (Type u))).map f ≫
        ((fun A =>
              Iso.mk (Mon_.Hom.mk (𝟙 ((𝟭 (Mon_ (Type u))).obj A).X)) (Mon_.Hom.mk (𝟙 ((functor ⋙ inverse).obj A).X)))
            Y).hom =
      ((fun A => Iso.mk (Mon_.Hom.mk (𝟙 ((𝟭 (Mon_ (Type u))).obj A).X)) (Mon_.Hom.mk (𝟙 ((functor ⋙ inverse).obj A).X)))
            X).hom ≫
        (functor ⋙ inverse).map f

Next tactic:
aesop_cat
/-- The category of internal monoid objects in `Type`
is equivalent to the category of "native" bundled monoids.
-/
noncomputable def monTypeEquivalenceMon : Mon_ (Type u) ≌ MonCat.{u} where
  functor := functor
  inverse := inverse
  unitIso :=
    NatIso.ofComponents
      (fun A =>
        { hom := { hom := 𝟙 _ }
          inv := { hom := 𝟙 _ } })
      (by aesop_cat)
  counitIso :=
    NatIso.ofComponents
      (fun A =>
        { hom :=
            { toFun := id
              map_one' := rfl
              map_mul' := fun x y => rfl }
          inv :=
            { toFun := id
              map_one' := rfl
              map_mul' := fun x y => rfl } })
      (by 

Proof state:
⊢ ∀ {X Y : MonCat} (f : X ⟶ Y),
    (inverse ⋙ functor).map f ≫
        ((fun A =>
              Iso.mk
                { toOneHom := { toFun := id, map_one' := (_ : id 1 = id 1) },
                  map_mul' :=
                    (_ :
                      ∀ (x y : ↑((inverse ⋙ functor).obj A)),
                        OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y) =
                          OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y)) }
                { toOneHom := { toFun := id, map_one' := (_ : id 1 = id 1) },
                  map_mul' :=
                    (_ :
                      ∀ (x y : ↑((𝟭 MonCat).obj A)),
                        OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y) =
                          OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y)) })
            Y).hom =
      ((fun A =>
              Iso.mk
                { toOneHom := { toFun := id, map_one' := (_ : id 1 = id 1) },
                  map_mul' :=
                    (_ :
                      ∀ (x y : ↑((inverse ⋙ functor).obj A)),
                        OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y) =
                          OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y)) }
                { toOneHom := { toFun := id, map_one' := (_ : id 1 = id 1) },
                  map_mul' :=
                    (_ :
                      ∀ (x y : ↑((𝟭 MonCat).obj A)),
                        OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y) =
                          OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y)) })
            X).hom ≫
        (𝟭 MonCat).map f

Next tactic:
aesop_cat
/-- The equivalence `Mon_ (Type u) ≌ MonCat.{u}`
is naturally compatible with the forgetful functors to `Type u`.
-/
noncomputable def monTypeEquivalenceMonForget :
    MonTypeEquivalenceMon.functor ⋙ forget MonCat ≅ Mon_.forget (Type u) :=
  NatIso.ofComponents (fun A => Iso.refl _) (by 

Proof state:
⊢ ∀ {X Y : Mon_ (Type u)} (f : X ⟶ Y),
    (functor ⋙ forget MonCat).map f ≫ ((fun A => Iso.refl ((functor ⋙ forget MonCat).obj A)) Y).hom =
      ((fun A => Iso.refl ((functor ⋙ forget MonCat).obj A)) X).hom ≫ (Mon_.forget (Type u)).map f

Next tactic:
aesop_cat
instance commMonCommMonoid (A : CommMon_ (Type u)) : CommMonoid A.X :=
  { MonTypeEquivalenceMon.monMonoid A.toMon_ with
    mul_comm := fun x y => by 

Proof state:
A : CommMon_ (Type u)
src✝ : Monoid A.X := monMonoid A.toMon_
x y : A.X
⊢ x * y = y * x

Next tactic:
convert congr_fun A.mul_comm (y, x)
/-- Converting a bundled commutative monoid to a commutative monoid object in `Type`.
-/
noncomputable def inverse : CommMonCat.{u} ⥤ CommMon_ (Type u) where
  obj A :=
    { MonTypeEquivalenceMon.inverse.obj ((forget₂ CommMonCat MonCat).obj A) with
      mul_comm := by
        

Proof state:
A : CommMonCat
src✝ : Mon_ (Type u) := MonTypeEquivalenceMon.inverse.obj ((forget₂ CommMonCat MonCat).obj A)
⊢ (β_ (Mon_.mk src✝.X src✝.one src✝.mul).X (Mon_.mk src✝.X src✝.one src✝.mul).X).hom ≫
      (Mon_.mk src✝.X src✝.one src✝.mul).mul =
    (Mon_.mk src✝.X src✝.one src✝.mul).mul

Next tactic:
ext ⟨x : A, y : A⟩
/-- Converting a bundled commutative monoid to a commutative monoid object in `Type`.
-/
noncomputable def inverse : CommMonCat.{u} ⥤ CommMon_ (Type u) where
  obj A :=
    { MonTypeEquivalenceMon.inverse.obj ((forget₂ CommMonCat MonCat).obj A) with
      mul_comm := by
        ext ⟨x : A, y : A⟩
        

Proof state:
case h.mk
A : CommMonCat
src✝ : Mon_ (Type u) := MonTypeEquivalenceMon.inverse.obj ((forget₂ CommMonCat MonCat).obj A)
x y : ↑A
⊢ ((β_ (Mon_.mk src✝.X src✝.one src✝.mul).X (Mon_.mk src✝.X src✝.one src✝.mul).X).hom ≫
        (Mon_.mk src✝.X src✝.one src✝.mul).mul)
      (x, y) =
    Mon_.mul (Mon_.mk src✝.X src✝.one src✝.mul) (x, y)

Next tactic:
exact CommMonoid.mul_comm y x
/-- The category of internal commutative monoid objects in `Type`
is equivalent to the category of "native" bundled commutative monoids.
-/
noncomputable def commMonTypeEquivalenceCommMon : CommMon_ (Type u) ≌ CommMonCat.{u} where
  functor := functor
  inverse := inverse
  unitIso :=
    NatIso.ofComponents
      (fun A =>
        { hom := { hom := 𝟙 _ }
          inv := { hom := 𝟙 _ } })
      (by 

Proof state:
⊢ ∀ {X Y : CommMon_ (Type u)} (f : X ⟶ Y),
    (𝟭 (CommMon_ (Type u))).map f ≫
        ((fun A =>
              Iso.mk (Mon_.Hom.mk (𝟙 ((𝟭 (CommMon_ (Type u))).obj A).X))
                (Mon_.Hom.mk
                  (𝟙 ((CommMonTypeEquivalenceCommMon.functor ⋙ CommMonTypeEquivalenceCommMon.inverse).obj A).X)))
            Y).hom =
      ((fun A =>
              Iso.mk (Mon_.Hom.mk (𝟙 ((𝟭 (CommMon_ (Type u))).obj A).X))
                (Mon_.Hom.mk
                  (𝟙 ((CommMonTypeEquivalenceCommMon.functor ⋙ CommMonTypeEquivalenceCommMon.inverse).obj A).X)))
            X).hom ≫
        (CommMonTypeEquivalenceCommMon.functor ⋙ CommMonTypeEquivalenceCommMon.inverse).map f

Next tactic:
aesop_cat
/-- The category of internal commutative monoid objects in `Type`
is equivalent to the category of "native" bundled commutative monoids.
-/
noncomputable def commMonTypeEquivalenceCommMon : CommMon_ (Type u) ≌ CommMonCat.{u} where
  functor := functor
  inverse := inverse
  unitIso :=
    NatIso.ofComponents
      (fun A =>
        { hom := { hom := 𝟙 _ }
          inv := { hom := 𝟙 _ } })
      (by aesop_cat)
  counitIso :=
    NatIso.ofComponents
      (fun A =>
        { hom :=
            { toFun := id
              map_one' := rfl
              map_mul' := fun x y => rfl }
          inv :=
            { toFun := id
              map_one' := rfl
              map_mul' := fun x y => rfl } })
      (by 

Proof state:
⊢ ∀ {X Y : CommMonCat} (f : X ⟶ Y),
    (CommMonTypeEquivalenceCommMon.inverse ⋙ CommMonTypeEquivalenceCommMon.functor).map f ≫
        ((fun A =>
              Iso.mk
                { toOneHom := { toFun := id, map_one' := (_ : id 1 = id 1) },
                  map_mul' :=
                    (_ :
                      ∀
                        (x y :
                          ↑((CommMonTypeEquivalenceCommMon.inverse ⋙ CommMonTypeEquivalenceCommMon.functor).obj A)),
                        OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y) =
                          OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y)) }
                { toOneHom := { toFun := id, map_one' := (_ : id 1 = id 1) },
                  map_mul' :=
                    (_ :
                      ∀ (x y : ↑((𝟭 CommMonCat).obj A)),
                        OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y) =
                          OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y)) })
            Y).hom =
      ((fun A =>
              Iso.mk
                { toOneHom := { toFun := id, map_one' := (_ : id 1 = id 1) },
                  map_mul' :=
                    (_ :
                      ∀
                        (x y :
                          ↑((CommMonTypeEquivalenceCommMon.inverse ⋙ CommMonTypeEquivalenceCommMon.functor).obj A)),
                        OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y) =
                          OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y)) }
                { toOneHom := { toFun := id, map_one' := (_ : id 1 = id 1) },
                  map_mul' :=
                    (_ :
                      ∀ (x y : ↑((𝟭 CommMonCat).obj A)),
                        OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y) =
                          OneHom.toFun { toFun := id, map_one' := (_ : id 1 = id 1) } (x * y)) })
            X).hom ≫
        (𝟭 CommMonCat).map f

Next tactic:
aesop_cat
/-- The equivalences `Mon_ (Type u) ≌ MonCat.{u}` and `CommMon_ (Type u) ≌ CommMonCat.{u}`
are naturally compatible with the forgetful functors to `MonCat` and `Mon_ (Type u)`.
-/
noncomputable def commMonTypeEquivalenceCommMonForget :
    CommMonTypeEquivalenceCommMon.functor ⋙ forget₂ CommMonCat MonCat ≅
      CommMon_.forget₂Mon_ (Type u) ⋙ MonTypeEquivalenceMon.functor :=
  NatIso.ofComponents (fun A => Iso.refl _) (by 

Proof state:
⊢ ∀ {X Y : CommMon_ (Type u)} (f : X ⟶ Y),
    (CommMonTypeEquivalenceCommMon.functor ⋙ forget₂ CommMonCat MonCat).map f ≫
        ((fun A => Iso.refl ((CommMonTypeEquivalenceCommMon.functor ⋙ forget₂ CommMonCat MonCat).obj A)) Y).hom =
      ((fun A => Iso.refl ((CommMonTypeEquivalenceCommMon.functor ⋙ forget₂ CommMonCat MonCat).obj A)) X).hom ≫
        (CommMon_.forget₂Mon_ (Type u) ⋙ MonTypeEquivalenceMon.functor).map f

Next tactic:
aesop_cat
/-- Auxiliary construction to build a rotation by the oriented angle `θ`. -/
def rotationAux (θ : Real.Angle) : V →ₗᵢ[ℝ] V :=
  LinearMap.isometryOfInner
    (Real.Angle.cos θ • LinearMap.id +
      Real.Angle.sin θ • (LinearIsometryEquiv.toLinearEquiv J).toLinearMap)
    (by
      

Proof state:
V : Type u_1
V' : Type u_2
inst✝⁵ : NormedAddCommGroup V
inst✝⁴ : NormedAddCommGroup V'
inst✝³ : InnerProductSpace ℝ V
inst✝² : InnerProductSpace ℝ V'
inst✝¹ : Fact (finrank ℝ V = 2)
inst✝ : Fact (finrank ℝ V' = 2)
o : Orientation ℝ V (Fin 2)
θ : Real.Angle
⊢ ∀ (x y : V),
    inner ((Real.Angle.cos θ • LinearMap.id + Real.Angle.sin θ • ↑(rightAngleRotation o).toLinearEquiv) x)
        ((Real.Angle.cos θ • LinearMap.id + Real.Angle.sin θ • ↑(rightAngleRotation o).toLinearEquiv) y) =
      inner x y

Next tactic:
intro x y
/-- Auxiliary construction to build a rotation by the oriented angle `θ`. -/
def rotationAux (θ : Real.Angle) : V →ₗᵢ[ℝ] V :=
  LinearMap.isometryOfInner
    (Real.Angle.cos θ • LinearMap.id +
      Real.Angle.sin θ • (LinearIsometryEquiv.toLinearEquiv J).toLinearMap)
    (by
      intro x y
      

Proof state:
V : Type u_1
V' : Type u_2
inst✝⁵ : NormedAddCommGroup V
inst✝⁴ : NormedAddCommGroup V'
inst✝³ : InnerProductSpace ℝ V
inst✝² : InnerProductSpace ℝ V'
inst✝¹ : Fact (finrank ℝ V = 2)
inst✝ : Fact (finrank ℝ V' = 2)
o : Orientation ℝ V (Fin 2)
θ : Real.Angle
x y : V
⊢ inner ((Real.Angle.cos θ • LinearMap.id + Real.Angle.sin θ • ↑(rightAngleRotation o).toLinearEquiv) x)
      ((Real.Angle.cos θ • LinearMap.id + Real.Angle.sin θ • ↑(rightAngleRotation o).toLinearEquiv) y) =
    inner x y

Next tactic:
simp only [IsROrC.conj_to_real, id.def, LinearMap.smul_apply, LinearMap.add_apply,
        LinearMap.id_coe, LinearEquiv.coe_coe, LinearIsometryEquiv.coe_toLinearEquiv,
        Orientation.areaForm_rightAngleRotation_left, Orientation.inner_rightAngleRotation_left,
        Orientation.inner_rightAngleRotation_right, inner_add_left, inner_smul_left,
        inner_add_right, inner_smul_right]
/-- Auxiliary construction to build a rotation by the oriented angle `θ`. -/
def rotationAux (θ : Real.Angle) : V →ₗᵢ[ℝ] V :=
  LinearMap.isometryOfInner
    (Real.Angle.cos θ • LinearMap.id +
      Real.Angle.sin θ • (LinearIsometryEquiv.toLinearEquiv J).toLinearMap)
    (by
      intro x y
      simp only [IsROrC.conj_to_real, id.def, LinearMap.smul_apply, LinearMap.add_apply,
        LinearMap.id_coe, LinearEquiv.coe_coe, LinearIsometryEquiv.coe_toLinearEquiv,
        Orientation.areaForm_rightAngleRotation_left, Orientation.inner_rightAngleRotation_left,
        Orientation.inner_rightAngleRotation_right, inner_add_left, inner_smul_left,
        inner_add_right, inner_smul_right]
      

Proof state:
V : Type u_1
V' : Type u_2
inst✝⁵ : NormedAddCommGroup V
inst✝⁴ : NormedAddCommGroup V'
inst✝³ : InnerProductSpace ℝ V
inst✝² : InnerProductSpace ℝ V'
inst✝¹ : Fact (finrank ℝ V = 2)
inst✝ : Fact (finrank ℝ V' = 2)
o : Orientation ℝ V (Fin 2)
θ : Real.Angle
x y : V
⊢ Real.Angle.cos θ * (Real.Angle.cos θ * inner x y + Real.Angle.sin θ * ((areaForm o) x) y) +
      Real.Angle.sin θ * (Real.Angle.cos θ * -((areaForm o) x) y + Real.Angle.sin θ * - -inner x y) =
    inner x y

Next tactic:
linear_combination inner (𝕜 := ℝ) x y * θ.cos_sq_add_sin_sq
/-- A rotation by the oriented angle `θ`. -/
def rotation (θ : Real.Angle) : V ≃ₗᵢ[ℝ] V :=
  LinearIsometryEquiv.ofLinearIsometry (o.rotationAux θ)
    (Real.Angle.cos θ • LinearMap.id -
      Real.Angle.sin θ • (LinearIsometryEquiv.toLinearEquiv J).toLinearMap)
    (by
      

Proof state:
V : Type u_1
V' : Type u_2
inst✝⁵ : NormedAddCommGroup V
inst✝⁴ : NormedAddCommGroup V'
inst✝³ : InnerProductSpace ℝ V
inst✝² : InnerProductSpace ℝ V'
inst✝¹ : Fact (finrank ℝ V = 2)
inst✝ : Fact (finrank ℝ V' = 2)
o : Orientation ℝ V (Fin 2)
θ : Real.Angle
⊢ LinearMap.comp (rotationAux o θ).toLinearMap
      (Real.Angle.cos θ • LinearMap.id - Real.Angle.sin θ • ↑(rightAngleRotation o).toLinearEquiv) =
    LinearMap.id

Next tactic:
ext x
/-- A rotation by the oriented angle `θ`. -/
def rotation (θ : Real.Angle) : V ≃ₗᵢ[ℝ] V :=
  LinearIsometryEquiv.ofLinearIsometry (o.rotationAux θ)
    (Real.Angle.cos θ • LinearMap.id -
      Real.Angle.sin θ • (LinearIsometryEquiv.toLinearEquiv J).toLinearMap)
    (by
      ext x
      

Proof state:
case h
V : Type u_1
V' : Type u_2
inst✝⁵ : NormedAddCommGroup V
inst✝⁴ : NormedAddCommGroup V'
inst✝³ : InnerProductSpace ℝ V
inst✝² : InnerProductSpace ℝ V'
inst✝¹ : Fact (finrank ℝ V = 2)
inst✝ : Fact (finrank ℝ V' = 2)
o : Orientation ℝ V (Fin 2)
θ : Real.Angle
x : V
⊢ (LinearMap.comp (rotationAux o θ).toLinearMap
        (Real.Angle.cos θ • LinearMap.id - Real.Angle.sin θ • ↑(rightAngleRotation o).toLinearEquiv))
      x =
    LinearMap.id x

Next tactic:
convert congr_arg (fun t : ℝ => t • x) θ.cos_sq_add_sin_sq using 1
/-- A rotation by the oriented angle `θ`. -/
def rotation (θ : Real.Angle) : V ≃ₗᵢ[ℝ] V :=
  LinearIsometryEquiv.ofLinearIsometry (o.rotationAux θ)
    (Real.Angle.cos θ • LinearMap.id -
      Real.Angle.sin θ • (LinearIsometryEquiv.toLinearEquiv J).toLinearMap)
    (by
      ext x
      convert congr_arg (fun t : ℝ => t • x) θ.cos_sq_add_sin_sq using 1
      · 

Proof state:
case h.e'_2
V : Type u_1
V' : Type u_2
inst✝⁵ : NormedAddCommGroup V
inst✝⁴ : NormedAddCommGroup V'
inst✝³ : InnerProductSpace ℝ V
inst✝² : InnerProductSpace ℝ V'
inst✝¹ : Fact (finrank ℝ V = 2)
inst✝ : Fact (finrank ℝ V' = 2)
o : Orientation ℝ V (Fin 2)
θ : Real.Angle
x : V
⊢ (LinearMap.comp (rotationAux o θ).toLinearMap
        (Real.Angle.cos θ • LinearMap.id - Real.Angle.sin θ • ↑(rightAngleRotation o).toLinearEquiv))
      x =
    (Real.Angle.cos θ ^ 2 + Real.Angle.sin θ ^ 2) • x

Next tactic:
simp only [o.rightAngleRotation_rightAngleRotation, o.rotationAux_apply,
          Function.comp_apply, id.def, LinearEquiv.coe_coe, LinearIsometry.coe_toLinearMap,
          LinearIsometryEquiv.coe_toLinearEquiv, map_smul, map_sub, LinearMap.coe_comp,
          LinearMap.id_coe, LinearMap.smul_apply, LinearMap.sub_apply, ← mul_smul, add_smul,
          smul_add, smul_neg, smul_sub, mul_comm, sq]