l3lab/ntp-mathlib huggingface dataset:
theorem HasGroupoid.comp
    (H : ∀ e ∈ G₂, LiftPropOn (IsLocalStructomorphWithinAt G₁) (e : H₂ → H₂) e.source) :
    @HasGroupoid H₁ _ H₃ _ (ChartedSpace.comp H₁ H₂ H₃) G₁ :=
  let _ := ChartedSpace.comp H₁ H₂ H₃ -- Porting note: need this to synthesize `ChartedSpace H₁ H₃`
  { compatible := by
      rintro _ _ ⟨e, f, he, hf, rfl⟩ ⟨e', f', he', hf', rfl⟩
      apply G₁.locality
      intro x hx
      simp only [mfld_simps] at hx
      

Proof state:
case intro.intro.intro.intro.intro.intro.intro.intro
H✝ : Type u_1
M : Type u_2
H' : Type u_3
M' : Type u_4
X : Type u_5
inst✝¹⁴ : TopologicalSpace H✝
inst✝¹³ : TopologicalSpace M
inst✝¹² : ChartedSpace H✝ M
inst✝¹¹ : TopologicalSpace H'
inst✝¹⁰ : TopologicalSpace M'
inst✝⁹ : ChartedSpace H' M'
inst✝⁸ : TopologicalSpace X
G : StructureGroupoid H✝
G' : StructureGroupoid H'
e✝ e'✝ : PartialHomeomorph M H✝
f✝ f'✝ : PartialHomeomorph M' H'
P : (H✝ → H') → Set H✝ → H✝ → Prop
g g' : M → M'
s t : Set M
x✝¹ : M
Q : (H✝ → H✝) → Set H✝ → H✝ → Prop
H₁ : Type u_6
inst✝⁷ : TopologicalSpace H₁
H₂ : Type u_7
inst✝⁶ : TopologicalSpace H₂
H₃ : Type u_8
inst✝⁵ : TopologicalSpace H₃
inst✝⁴ : ChartedSpace H₁ H₂
inst✝³ : ChartedSpace H₂ H₃
G₁ : StructureGroupoid H₁
inst✝² : HasGroupoid H₂ G₁
inst✝¹ : ClosedUnderRestriction G₁
G₂ : StructureGroupoid H₂
inst✝ : HasGroupoid H₃ G₂
H : ∀ e ∈ G₂, LiftPropOn (IsLocalStructomorphWithinAt G₁) (↑e) e.source
x✝ : ChartedSpace H₁ H₃ := ChartedSpace.comp H₁ H₂ H₃
e : PartialHomeomorph H₃ H₂
f : PartialHomeomorph H₂ H₁
he : e ∈ atlas H₂ H₃
hf : f ∈ atlas H₁ H₂
e' : PartialHomeomorph H₃ H₂
f' : PartialHomeomorph H₂ H₁
he' : e' ∈ atlas H₂ H₃
hf' : f' ∈ atlas H₁ H₂
x : H₁
hx :
  (x ∈ f.target ∧ ↑(PartialHomeomorph.symm f) x ∈ e.target) ∧
    ↑(PartialHomeomorph.symm e) (↑(PartialHomeomorph.symm f) x) ∈ e'.source ∧
      ↑e' (↑(PartialHomeomorph.symm e) (↑(PartialHomeomorph.symm f) x)) ∈ f'.source
⊢ ∃ s, IsOpen s ∧ x ∈ s ∧ PartialHomeomorph.restr (PartialHomeomorph.symm (e ≫ₕ f) ≫ₕ e' ≫ₕ f') s ∈ G₁

Next tactic:
have hxs : x ∈ f.symm ⁻¹' (e.symm ≫ₕ e').source := by simp only [hx, mfld_simps]
theorem HasGroupoid.comp
    (H : ∀ e ∈ G₂, LiftPropOn (IsLocalStructomorphWithinAt G₁) (e : H₂ → H₂) e.source) :
    @HasGroupoid H₁ _ H₃ _ (ChartedSpace.comp H₁ H₂ H₃) G₁ :=
  let _ := ChartedSpace.comp H₁ H₂ H₃ -- Porting note: need this to synthesize `ChartedSpace H₁ H₃`
  { compatible := by
      rintro _ _ ⟨e, f, he, hf, rfl⟩ ⟨e', f', he', hf', rfl⟩
      apply G₁.locality
      intro x hx
      simp only [mfld_simps] at hx
      have hxs : x ∈ f.symm ⁻¹' (e.symm ≫ₕ e').source := by 

Proof state:
H✝ : Type u_1
M : Type u_2
H' : Type u_3
M' : Type u_4
X : Type u_5
inst✝¹⁴ : TopologicalSpace H✝
inst✝¹³ : TopologicalSpace M
inst✝¹² : ChartedSpace H✝ M
inst✝¹¹ : TopologicalSpace H'
inst✝¹⁰ : TopologicalSpace M'
inst✝⁹ : ChartedSpace H' M'
inst✝⁸ : TopologicalSpace X
G : StructureGroupoid H✝
G' : StructureGroupoid H'
e✝ e'✝ : PartialHomeomorph M H✝
f✝ f'✝ : PartialHomeomorph M' H'
P : (H✝ → H') → Set H✝ → H✝ → Prop
g g' : M → M'
s t : Set M
x✝¹ : M
Q : (H✝ → H✝) → Set H✝ → H✝ → Prop
H₁ : Type u_6
inst✝⁷ : TopologicalSpace H₁
H₂ : Type u_7
inst✝⁶ : TopologicalSpace H₂
H₃ : Type u_8
inst✝⁵ : TopologicalSpace H₃
inst✝⁴ : ChartedSpace H₁ H₂
inst✝³ : ChartedSpace H₂ H₃
G₁ : StructureGroupoid H₁
inst✝² : HasGroupoid H₂ G₁
inst✝¹ : ClosedUnderRestriction G₁
G₂ : StructureGroupoid H₂
inst✝ : HasGroupoid H₃ G₂
H : ∀ e ∈ G₂, LiftPropOn (IsLocalStructomorphWithinAt G₁) (↑e) e.source
x✝ : ChartedSpace H₁ H₃ := ChartedSpace.comp H₁ H₂ H₃
e : PartialHomeomorph H₃ H₂
f : PartialHomeomorph H₂ H₁
he : e ∈ atlas H₂ H₃
hf : f ∈ atlas H₁ H₂
e' : PartialHomeomorph H₃ H₂
f' : PartialHomeomorph H₂ H₁
he' : e' ∈ atlas H₂ H₃
hf' : f' ∈ atlas H₁ H₂
x : H₁
hx :
  (x ∈ f.target ∧ ↑(PartialHomeomorph.symm f) x ∈ e.target) ∧
    ↑(PartialHomeomorph.symm e) (↑(PartialHomeomorph.symm f) x) ∈ e'.source ∧
      ↑e' (↑(PartialHomeomorph.symm e) (↑(PartialHomeomorph.symm f) x)) ∈ f'.source
⊢ x ∈ ↑(PartialHomeomorph.symm f) ⁻¹' (PartialHomeomorph.symm e ≫ₕ e').toPartialEquiv.source

Next tactic:
simp only [hx, mfld_simps]
theorem HasGroupoid.comp
    (H : ∀ e ∈ G₂, LiftPropOn (IsLocalStructomorphWithinAt G₁) (e : H₂ → H₂) e.source) :
    @HasGroupoid H₁ _ H₃ _ (ChartedSpace.comp H₁ H₂ H₃) G₁ :=
  let _ := ChartedSpace.comp H₁ H₂ H₃ -- Porting note: need this to synthesize `ChartedSpace H₁ H₃`
  { compatible := by
      rintro _ _ ⟨e, f, he, hf, rfl⟩ ⟨e', f', he', hf', rfl⟩
      apply G₁.locality
      intro x hx
      simp only [mfld_simps] at hx
      have hxs : x ∈ f.symm ⁻¹' (e.symm ≫ₕ e').source := by simp only [hx, mfld_simps]
      

Proof state:
case intro.intro.intro.intro.intro.intro.intro.intro
H✝ : Type u_1
M : Type u_2
H' : Type u_3
M' : Type u_4
X : Type u_5
inst✝¹⁴ : TopologicalSpace H✝
inst✝¹³ : TopologicalSpace M
inst✝¹² : ChartedSpace H✝ M
inst✝¹¹ : TopologicalSpace H'
inst✝¹⁰ : TopologicalSpace M'
inst✝⁹ : ChartedSpace H' M'
inst✝⁸ : TopologicalSpace X
G : StructureGroupoid H✝
G' : StructureGroupoid H'
e✝ e'✝ : PartialHomeomorph M H✝
f✝ f'✝ : PartialHomeomorph M' H'
P : (H✝ → H') → Set H✝ → H✝ → Prop
g g' : M → M'
s t : Set M
x✝¹ : M
Q : (H✝ → H✝) → Set H✝ → H✝ → Prop
H₁ : Type u_6
inst✝⁷ : TopologicalSpace H₁
H₂ : Type u_7
inst✝⁶ : TopologicalSpace H₂
H₃ : Type u_8
inst✝⁵ : TopologicalSpace H₃
inst✝⁴ : ChartedSpace H₁ H₂
inst✝³ : ChartedSpace H₂ H₃
G₁ : StructureGroupoid H₁
inst✝² : HasGroupoid H₂ G₁
inst✝¹ : ClosedUnderRestriction G₁
G₂ : StructureGroupoid H₂
inst✝ : HasGroupoid H₃ G₂
H : ∀ e ∈ G₂, LiftPropOn (IsLocalStructomorphWithinAt G₁) (↑e) e.source
x✝ : ChartedSpace H₁ H₃ := ChartedSpace.comp H₁ H₂ H₃
e : PartialHomeomorph H₃ H₂
f : PartialHomeomorph H₂ H₁
he : e ∈ atlas H₂ H₃
hf : f ∈ atlas H₁ H₂
e' : PartialHomeomorph H₃ H₂
f' : PartialHomeomorph H₂ H₁
he' : e' ∈ atlas H₂ H₃
hf' : f' ∈ atlas H₁ H₂
x : H₁
hx :
  (x ∈ f.target ∧ ↑(PartialHomeomorph.symm f) x ∈ e.target) ∧
    ↑(PartialHomeomorph.symm e) (↑(PartialHomeomorph.symm f) x) ∈ e'.source ∧
      ↑e' (↑(PartialHomeomorph.symm e) (↑(PartialHomeomorph.symm f) x)) ∈ f'.source
hxs : x ∈ ↑(PartialHomeomorph.symm f) ⁻¹' (PartialHomeomorph.symm e ≫ₕ e').toPartialEquiv.source
⊢ ∃ s, IsOpen s ∧ x ∈ s ∧ PartialHomeomorph.restr (PartialHomeomorph.symm (e ≫ₕ f) ≫ₕ e' ≫ₕ f') s ∈ G₁

Next tactic:
have hxs' : x ∈ f.target ∩ f.symm ⁻¹' ((e.symm ≫ₕ e').source ∩ e.symm ≫ₕ e' ⁻¹' f'.source) :=
        by simp only [hx, mfld_simps]
theorem HasGroupoid.comp
    (H : ∀ e ∈ G₂, LiftPropOn (IsLocalStructomorphWithinAt G₁) (e : H₂ → H₂) e.source) :
    @HasGroupoid H₁ _ H₃ _ (ChartedSpace.comp H₁ H₂ H₃) G₁ :=
  let _ := ChartedSpace.comp H₁ H₂ H₃ -- Porting note: need this to synthesize `ChartedSpace H₁ H₃`
  { compatible := by
      rintro _ _ ⟨e, f, he, hf, rfl⟩ ⟨e', f', he', hf', rfl⟩
      apply G₁.locality
      intro x hx
      simp only [mfld_simps] at hx
      have hxs : x ∈ f.symm ⁻¹' (e.symm ≫ₕ e').source := by simp only [hx, mfld_simps]
      have hxs' : x ∈ f.target ∩ f.symm ⁻¹' ((e.symm ≫ₕ e').source ∩ e.symm ≫ₕ e' ⁻¹' f'.source) :=
        by 

Proof state:
H✝ : Type u_1
M : Type u_2
H' : Type u_3
M' : Type u_4
X : Type u_5
inst✝¹⁴ : TopologicalSpace H✝
inst✝¹³ : TopologicalSpace M
inst✝¹² : ChartedSpace H✝ M
inst✝¹¹ : TopologicalSpace H'
inst✝¹⁰ : TopologicalSpace M'
inst✝⁹ : ChartedSpace H' M'
inst✝⁸ : TopologicalSpace X
G : StructureGroupoid H✝
G' : StructureGroupoid H'
e✝ e'✝ : PartialHomeomorph M H✝
f✝ f'✝ : PartialHomeomorph M' H'
P : (H✝ → H') → Set H✝ → H✝ → Prop
g g' : M → M'
s t : Set M
x✝¹ : M
Q : (H✝ → H✝) → Set H✝ → H✝ → Prop
H₁ : Type u_6
inst✝⁷ : TopologicalSpace H₁
H₂ : Type u_7
inst✝⁶ : TopologicalSpace H₂
H₃ : Type u_8
inst✝⁵ : TopologicalSpace H₃
inst✝⁴ : ChartedSpace H₁ H₂
inst✝³ : ChartedSpace H₂ H₃
G₁ : StructureGroupoid H₁
inst✝² : HasGroupoid H₂ G₁
inst✝¹ : ClosedUnderRestriction G₁
G₂ : StructureGroupoid H₂
inst✝ : HasGroupoid H₃ G₂
H : ∀ e ∈ G₂, LiftPropOn (IsLocalStructomorphWithinAt G₁) (↑e) e.source
x✝ : ChartedSpace H₁ H₃ := ChartedSpace.comp H₁ H₂ H₃
e : PartialHomeomorph H₃ H₂
f : PartialHomeomorph H₂ H₁
he : e ∈ atlas H₂ H₃
hf : f ∈ atlas H₁ H₂
e' : PartialHomeomorph H₃ H₂
f' : PartialHomeomorph H₂ H₁
he' : e' ∈ atlas H₂ H₃
hf' : f' ∈ atlas H₁ H₂
x : H₁
hx :
  (x ∈ f.target ∧ ↑(PartialHomeomorph.symm f) x ∈ e.target) ∧
    ↑(PartialHomeomorph.symm e) (↑(PartialHomeomorph.symm f) x) ∈ e'.source ∧
      ↑e' (↑(PartialHomeomorph.symm e) (↑(PartialHomeomorph.symm f) x)) ∈ f'.source
hxs : x ∈ ↑(PartialHomeomorph.symm f) ⁻¹' (PartialHomeomorph.symm e ≫ₕ e').toPartialEquiv.source
⊢ x ∈
    f.target ∩
      ↑(PartialHomeomorph.symm f) ⁻¹'
        ((PartialHomeomorph.symm e ≫ₕ e').toPartialEquiv.source ∩ ↑(PartialHomeomorph.symm e ≫ₕ e') ⁻¹' f'.source)

Next tactic:
simp only [hx, mfld_simps]
theorem HasGroupoid.comp
    (H : ∀ e ∈ G₂, LiftPropOn (IsLocalStructomorphWithinAt G₁) (e : H₂ → H₂) e.source) :
    @HasGroupoid H₁ _ H₃ _ (ChartedSpace.comp H₁ H₂ H₃) G₁ :=
  let _ := ChartedSpace.comp H₁ H₂ H₃ -- Porting note: need this to synthesize `ChartedSpace H₁ H₃`
  { compatible := by
      rintro _ _ ⟨e, f, he, hf, rfl⟩ ⟨e', f', he', hf', rfl⟩
      apply G₁.locality
      intro x hx
      simp only [mfld_simps] at hx
      have hxs : x ∈ f.symm ⁻¹' (e.symm ≫ₕ e').source := by simp only [hx, mfld_simps]
      have hxs' : x ∈ f.target ∩ f.symm ⁻¹' ((e.symm ≫ₕ e').source ∩ e.symm ≫ₕ e' ⁻¹' f'.source) :=
        by simp only [hx, mfld_simps]
      

Proof state:
case intro.intro.intro.intro.intro.intro.intro.intro
H✝ : Type u_1
M : Type u_2
H' : Type u_3
M' : Type u_4
X : Type u_5
inst✝¹⁴ : TopologicalSpace H✝
inst✝¹³ : TopologicalSpace M
inst✝¹² : ChartedSpace H✝ M
inst✝¹¹ : TopologicalSpace H'
inst✝¹⁰ : TopologicalSpace M'
inst✝⁹ : ChartedSpace H' M'
inst✝⁸ : TopologicalSpace X
G : StructureGroupoid H✝
G' : StructureGroupoid H'
e✝ e'✝ : PartialHomeomorph M H✝
f✝ f'✝ : PartialHomeomorph M' H'
P : (H✝ → H') → Set H✝ → H✝ → Prop
g g' : M → M'
s t : Set M
x✝¹ : M
Q : (H✝ → H✝) → Set H✝ → H✝ → Prop
H₁ : Type u_6
inst✝⁷ : TopologicalSpace H₁
H₂ : Type u_7
inst✝⁶ : TopologicalSpace H₂
H₃ : Type u_8
inst✝⁵ : TopologicalSpace H₃
inst✝⁴ : ChartedSpace H₁ H₂
inst✝³ : ChartedSpace H₂ H₃
G₁ : StructureGroupoid H₁
inst✝² : HasGroupoid H₂ G₁
inst✝¹ : ClosedUnderRestriction G₁
G₂ : StructureGroupoid H₂
inst✝ : HasGroupoid H₃ G₂
H : ∀ e ∈ G₂, LiftPropOn (IsLocalStructomorphWithinAt G₁) (↑e) e.source
x✝ : ChartedSpace H₁ H₃ := ChartedSpace.comp H₁ H₂ H₃
e : PartialHomeomorph H₃ H₂
f : PartialHomeomorph H₂ H₁
he : e ∈ atlas H₂ H₃
hf : f ∈ atlas H₁ H₂
e' : PartialHomeomorph H₃ H₂
f' : PartialHomeomorph H₂ H₁
he' : e' ∈ atlas H₂ H₃
hf' : f' ∈ atlas H₁ H₂
x : H₁
hx :
  (x ∈ f.target ∧ ↑(PartialHomeomorph.symm f) x ∈ e.target) ∧
    ↑(PartialHomeomorph.symm e) (↑(PartialHomeomorph.symm f) x) ∈ e'.source ∧
      ↑e' (↑(PartialHomeomorph.symm e) (↑(PartialHomeomorph.symm f) x)) ∈ f'.source
hxs : x ∈ ↑(PartialHomeomorph.symm f) ⁻¹' (PartialHomeomorph.symm e ≫ₕ e').toPartialEquiv.source
hxs' :
  x ∈
    f.target ∩
      ↑(PartialHomeomorph.symm f) ⁻¹'
        ((PartialHomeomorph.symm e ≫ₕ e').toPartialEquiv.source ∩ ↑(PartialHomeomorph.symm e ≫ₕ e') ⁻¹' f'.source)
⊢ ∃ s, IsOpen s ∧ x ∈ s ∧ PartialHomeomorph.restr (PartialHomeomorph.symm (e ≫ₕ f) ≫ₕ e' ≫ₕ f') s ∈ G₁

Next tactic:
obtain ⟨φ, hφG₁, hφ, hφ_dom⟩ := LocalInvariantProp.liftPropOn_indep_chart
        (isLocalStructomorphWithinAt_localInvariantProp G₁) (G₁.subset_maximalAtlas hf)
        (G₁.subset_maximalAtlas hf') (H _ (G₂.compatible he he')) hxs' hxs
theorem HasGroupoid.comp
    (H : ∀ e ∈ G₂, LiftPropOn (IsLocalStructomorphWithinAt G₁) (e : H₂ → H₂) e.source) :
    @HasGroupoid H₁ _ H₃ _ (ChartedSpace.comp H₁ H₂ H₃) G₁ :=
  let _ := ChartedSpace.comp H₁ H₂ H₃ -- Porting note: need this to synthesize `ChartedSpace H₁ H₃`
  { compatible := by
      rintro _ _ ⟨e, f, he, hf, rfl⟩ ⟨e', f', he', hf', rfl⟩
      apply G₁.locality
      intro x hx
      simp only [mfld_simps] at hx
      have hxs : x ∈ f.symm ⁻¹' (e.symm ≫ₕ e').source := by simp only [hx, mfld_simps]
      have hxs' : x ∈ f.target ∩ f.symm ⁻¹' ((e.symm ≫ₕ e').source ∩ e.symm ≫ₕ e' ⁻¹' f'.source) :=
        by simp only [hx, mfld_simps]
      obtain ⟨φ, hφG₁, hφ, hφ_dom⟩ := LocalInvariantProp.liftPropOn_indep_chart
        (isLocalStructomorphWithinAt_localInvariantProp G₁) (G₁.subset_maximalAtlas hf)
        (G₁.subset_maximalAtlas hf') (H _ (G₂.compatible he he')) hxs' hxs
      

Proof state:
case intro.intro.intro.intro.intro.intro.intro.intro.intro.intro.intro
H✝ : Type u_1
M : Type u_2
H' : Type u_3
M' : Type u_4
X : Type u_5
inst✝¹⁴ : TopologicalSpace H✝
inst✝¹³ : TopologicalSpace M
inst✝¹² : ChartedSpace H✝ M
inst✝¹¹ : TopologicalSpace H'
inst✝¹⁰ : TopologicalSpace M'
inst✝⁹ : ChartedSpace H' M'
inst✝⁸ : TopologicalSpace X
G : StructureGroupoid H✝
G' : StructureGroupoid H'
e✝ e'✝ : PartialHomeomorph M H✝
f✝ f'✝ : PartialHomeomorph M' H'
P : (H✝ → H') → Set H✝ → H✝ → Prop
g g' : M → M'
s t : Set M
x✝¹ : M
Q : (H✝ → H✝) → Set H✝ → H✝ → Prop
H₁ : Type u_6
inst✝⁷ : TopologicalSpace H₁
H₂ : Type u_7
inst✝⁶ : TopologicalSpace H₂
H₃ : Type u_8
inst✝⁵ : TopologicalSpace H₃
inst✝⁴ : ChartedSpace H₁ H₂
inst✝³ : ChartedSpace H₂ H₃
G₁ : StructureGroupoid H₁
inst✝² : HasGroupoid H₂ G₁
inst✝¹ : ClosedUnderRestriction G₁
G₂ : StructureGroupoid H₂
inst✝ : HasGroupoid H₃ G₂
H : ∀ e ∈ G₂, LiftPropOn (IsLocalStructomorphWithinAt G₁) (↑e) e.source
x✝ : ChartedSpace H₁ H₃ := ChartedSpace.comp H₁ H₂ H₃
e : PartialHomeomorph H₃ H₂
f : PartialHomeomorph H₂ H₁
he : e ∈ atlas H₂ H₃
hf : f ∈ atlas H₁ H₂
e' : PartialHomeomorph H₃ H₂
f' : PartialHomeomorph H₂ H₁
he' : e' ∈ atlas H₂ H₃
hf' : f' ∈ atlas H₁ H₂
x : H₁
hx :
  (x ∈ f.target ∧ ↑(PartialHomeomorph.symm f) x ∈ e.target) ∧
    ↑(PartialHomeomorph.symm e) (↑(PartialHomeomorph.symm f) x) ∈ e'.source ∧
      ↑e' (↑(PartialHomeomorph.symm e) (↑(PartialHomeomorph.symm f) x)) ∈ f'.source
hxs : x ∈ ↑(PartialHomeomorph.symm f) ⁻¹' (PartialHomeomorph.symm e ≫ₕ e').toPartialEquiv.source
hxs' :
  x ∈
    f.target ∩
      ↑(PartialHomeomorph.symm f) ⁻¹'
        ((PartialHomeomorph.symm e ≫ₕ e').toPartialEquiv.source ∩ ↑(PartialHomeomorph.symm e ≫ₕ e') ⁻¹' f'.source)
φ : PartialHomeomorph H₁ H₁
hφG₁ : φ ∈ G₁
hφ :
  EqOn (↑f' ∘ ↑(PartialHomeomorph.symm e ≫ₕ e') ∘ ↑(PartialHomeomorph.symm f)) (↑φ.toPartialEquiv)
    (↑(PartialHomeomorph.symm f) ⁻¹' (PartialHomeomorph.symm e ≫ₕ e').toPartialEquiv.source ∩ φ.source)
hφ_dom : x ∈ φ.source
⊢ ∃ s, IsOpen s ∧ x ∈ s ∧ PartialHomeomorph.restr (PartialHomeomorph.symm (e ≫ₕ f) ≫ₕ e' ≫ₕ f') s ∈ G₁

Next tactic:
simp_rw [← PartialHomeomorph.coe_trans, PartialHomeomorph.trans_assoc] at hφ
/-- The equivalence between a quaternion algebra over `R` and `Fin 4 → R`. -/
@[simps symm_apply]
def equivTuple {R : Type*} (c₁ c₂ : R) : ℍ[R,c₁,c₂] ≃ (Fin 4 → R) where
  toFun a := ![a.1, a.2, a.3, a.4]
  invFun a := ⟨a 0, a 1, a 2, a 3⟩
  left_inv _ := rfl
  right_inv f := by 

Proof state:
R : Type u_1
c₁ c₂ : R
f : Fin 4 → R
⊢ (fun a => ![a.re, a.imI, a.imJ, a.imK]) ((fun a => { re := a 0, imI := a 1, imJ := a 2, imK := a 3 }) f) = f

Next tactic:
ext ⟨_, _ | _ | _ | _ | _ | ⟨⟩⟩
/-- The equivalence between a quaternion algebra over `R` and `Fin 4 → R`. -/
@[simps symm_apply]
def equivTuple {R : Type*} (c₁ c₂ : R) : ℍ[R,c₁,c₂] ≃ (Fin 4 → R) where
  toFun a := ![a.1, a.2, a.3, a.4]
  invFun a := ⟨a 0, a 1, a 2, a 3⟩
  left_inv _ := rfl
  right_inv f := by ext ⟨_, _ | _ | _ | _ | _ | ⟨⟩⟩ <;> 

Proof state:
case h.mk.refl
R : Type u_1
c₁ c₂ : R
f : Fin 4 → R
⊢ (fun a => ![a.re, a.imI, a.imJ, a.imK]) ((fun a => { re := a 0, imI := a 1, imJ := a 2, imK := a 3 }) f)
      { val := 3, isLt := (_ : Nat.le (Nat.succ 3) (Nat.succ 3)) } =
    f { val := 3, isLt := (_ : Nat.le (Nat.succ 3) (Nat.succ 3)) }

Next tactic:
rfl
/-- The equivalence between a quaternion algebra over `R` and `Fin 4 → R`. -/
@[simps symm_apply]
def equivTuple {R : Type*} (c₁ c₂ : R) : ℍ[R,c₁,c₂] ≃ (Fin 4 → R) where
  toFun a := ![a.1, a.2, a.3, a.4]
  invFun a := ⟨a 0, a 1, a 2, a 3⟩
  left_inv _ := rfl
  right_inv f := by ext ⟨_, _ | _ | _ | _ | _ | ⟨⟩⟩ <;> 

Proof state:
case h.mk.step.refl
R : Type u_1
c₁ c₂ : R
f : Fin 4 → R
⊢ (fun a => ![a.re, a.imI, a.imJ, a.imK]) ((fun a => { re := a 0, imI := a 1, imJ := a 2, imK := a 3 }) f)
      { val := 2, isLt := (_ : Nat.le (Nat.succ 2) (Nat.succ 3)) } =
    f { val := 2, isLt := (_ : Nat.le (Nat.succ 2) (Nat.succ 3)) }

Next tactic:
rfl
/-- The equivalence between a quaternion algebra over `R` and `Fin 4 → R`. -/
@[simps symm_apply]
def equivTuple {R : Type*} (c₁ c₂ : R) : ℍ[R,c₁,c₂] ≃ (Fin 4 → R) where
  toFun a := ![a.1, a.2, a.3, a.4]
  invFun a := ⟨a 0, a 1, a 2, a 3⟩
  left_inv _ := rfl
  right_inv f := by ext ⟨_, _ | _ | _ | _ | _ | ⟨⟩⟩ <;> 

Proof state:
case h.mk.step.step.refl
R : Type u_1
c₁ c₂ : R
f : Fin 4 → R
⊢ (fun a => ![a.re, a.imI, a.imJ, a.imK]) ((fun a => { re := a 0, imI := a 1, imJ := a 2, imK := a 3 }) f)
      { val := 1, isLt := (_ : Nat.le (Nat.succ 1) (Nat.succ 3)) } =
    f { val := 1, isLt := (_ : Nat.le (Nat.succ 1) (Nat.succ 3)) }

Next tactic:
rfl
/-- The equivalence between a quaternion algebra over `R` and `Fin 4 → R`. -/
@[simps symm_apply]
def equivTuple {R : Type*} (c₁ c₂ : R) : ℍ[R,c₁,c₂] ≃ (Fin 4 → R) where
  toFun a := ![a.1, a.2, a.3, a.4]
  invFun a := ⟨a 0, a 1, a 2, a 3⟩
  left_inv _ := rfl
  right_inv f := by ext ⟨_, _ | _ | _ | _ | _ | ⟨⟩⟩ <;> 

Proof state:
case h.mk.step.step.step.refl
R : Type u_1
c₁ c₂ : R
f : Fin 4 → R
⊢ (fun a => ![a.re, a.imI, a.imJ, a.imK]) ((fun a => { re := a 0, imI := a 1, imJ := a 2, imK := a 3 }) f)
      { val := 0, isLt := (_ : Nat.le (Nat.succ 0) (Nat.succ 3)) } =
    f { val := 0, isLt := (_ : Nat.le (Nat.succ 0) (Nat.succ 3)) }

Next tactic:
rfl
@[simp, norm_cast]
theorem coe_add : ((x + y : R) : ℍ[R,c₁,c₂]) = x + y := by 

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
c₁ c₂ r x y z : R
a b c : ℍ[R,c₁,c₂]
⊢ ↑(x + y) = ↑x + ↑y

Next tactic:
ext
@[simp, norm_cast]
theorem coe_add : ((x + y : R) : ℍ[R,c₁,c₂]) = x + y := by ext <;> 

Proof state:
case re
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
c₁ c₂ r x y z : R
a b c : ℍ[R,c₁,c₂]
⊢ (↑(x + y)).re = (↑x + ↑y).re

Next tactic:
simp
@[simp, norm_cast]
theorem coe_add : ((x + y : R) : ℍ[R,c₁,c₂]) = x + y := by ext <;> 

Proof state:
case imI
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
c₁ c₂ r x y z : R
a b c : ℍ[R,c₁,c₂]
⊢ (↑(x + y)).imI = (↑x + ↑y).imI

Next tactic:
simp
@[simp, norm_cast]
theorem coe_add : ((x + y : R) : ℍ[R,c₁,c₂]) = x + y := by ext <;> 

Proof state:
case imJ
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
c₁ c₂ r x y z : R
a b c : ℍ[R,c₁,c₂]
⊢ (↑(x + y)).imJ = (↑x + ↑y).imJ

Next tactic:
simp
@[simp, norm_cast]
theorem coe_add : ((x + y : R) : ℍ[R,c₁,c₂]) = x + y := by ext <;> 

Proof state:
case imK
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
c₁ c₂ r x y z : R
a b c : ℍ[R,c₁,c₂]
⊢ (↑(x + y)).imK = (↑x + ↑y).imK

Next tactic:
simp
@[simp, norm_cast]
theorem coe_neg : ((-x : R) : ℍ[R,c₁,c₂]) = -x := by 

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
c₁ c₂ r x y z : R
a b c : ℍ[R,c₁,c₂]
⊢ ↑(-x) = -↑x

Next tactic:
ext
@[simp, norm_cast]
theorem coe_neg : ((-x : R) : ℍ[R,c₁,c₂]) = -x := by ext <;> 

Proof state:
case re
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
c₁ c₂ r x y z : R
a b c : ℍ[R,c₁,c₂]
⊢ (↑(-x)).re = (-↑x).re

Next tactic:
simp
@[simp, norm_cast]
theorem coe_neg : ((-x : R) : ℍ[R,c₁,c₂]) = -x := by ext <;> 

Proof state:
case imI
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
c₁ c₂ r x y z : R
a b c : ℍ[R,c₁,c₂]
⊢ (↑(-x)).imI = (-↑x).imI

Next tactic:
simp
@[simp, norm_cast]
theorem coe_neg : ((-x : R) : ℍ[R,c₁,c₂]) = -x := by ext <;> 

Proof state:
case imJ
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
c₁ c₂ r x y z : R
a b c : ℍ[R,c₁,c₂]
⊢ (↑(-x)).imJ = (-↑x).imJ

Next tactic:
simp
@[simp, norm_cast]
theorem coe_neg : ((-x : R) : ℍ[R,c₁,c₂]) = -x := by ext <;> 

Proof state:
case imK
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
c₁ c₂ r x y z : R
a b c : ℍ[R,c₁,c₂]
⊢ (↑(-x)).imK = (-↑x).imK

Next tactic:
simp
instance [SMul S T] [IsScalarTower S T R] : IsScalarTower S T ℍ[R,c₁,c₂] where
  smul_assoc s t x := by 

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝⁴ : CommRing R
c₁ c₂ r x✝ y z : R
a b c : ℍ[R,c₁,c₂]
inst✝³ : SMul S R
inst✝² : SMul T R
s✝ : S
inst✝¹ : SMul S T
inst✝ : IsScalarTower S T R
s : S
t : T
x : ℍ[R,c₁,c₂]
⊢ (s • t) • x = s • t • x

Next tactic:
ext
instance [SMul S T] [IsScalarTower S T R] : IsScalarTower S T ℍ[R,c₁,c₂] where
  smul_assoc s t x := by ext <;> 

Proof state:
case re
S : Type u_1
T : Type u_2
R : Type u_3
inst✝⁴ : CommRing R
c₁ c₂ r x✝ y z : R
a b c : ℍ[R,c₁,c₂]
inst✝³ : SMul S R
inst✝² : SMul T R
s✝ : S
inst✝¹ : SMul S T
inst✝ : IsScalarTower S T R
s : S
t : T
x : ℍ[R,c₁,c₂]
⊢ ((s • t) • x).re = (s • t • x).re

Next tactic:
exact smul_assoc _ _ _
instance [SMul S T] [IsScalarTower S T R] : IsScalarTower S T ℍ[R,c₁,c₂] where
  smul_assoc s t x := by ext <;> 

Proof state:
case imI
S : Type u_1
T : Type u_2
R : Type u_3
inst✝⁴ : CommRing R
c₁ c₂ r x✝ y z : R
a b c : ℍ[R,c₁,c₂]
inst✝³ : SMul S R
inst✝² : SMul T R
s✝ : S
inst✝¹ : SMul S T
inst✝ : IsScalarTower S T R
s : S
t : T
x : ℍ[R,c₁,c₂]
⊢ ((s • t) • x).imI = (s • t • x).imI

Next tactic:
exact smul_assoc _ _ _
instance [SMul S T] [IsScalarTower S T R] : IsScalarTower S T ℍ[R,c₁,c₂] where
  smul_assoc s t x := by ext <;> 

Proof state:
case imJ
S : Type u_1
T : Type u_2
R : Type u_3
inst✝⁴ : CommRing R
c₁ c₂ r x✝ y z : R
a b c : ℍ[R,c₁,c₂]
inst✝³ : SMul S R
inst✝² : SMul T R
s✝ : S
inst✝¹ : SMul S T
inst✝ : IsScalarTower S T R
s : S
t : T
x : ℍ[R,c₁,c₂]
⊢ ((s • t) • x).imJ = (s • t • x).imJ

Next tactic:
exact smul_assoc _ _ _
instance [SMul S T] [IsScalarTower S T R] : IsScalarTower S T ℍ[R,c₁,c₂] where
  smul_assoc s t x := by ext <;> 

Proof state:
case imK
S : Type u_1
T : Type u_2
R : Type u_3
inst✝⁴ : CommRing R
c₁ c₂ r x✝ y z : R
a b c : ℍ[R,c₁,c₂]
inst✝³ : SMul S R
inst✝² : SMul T R
s✝ : S
inst✝¹ : SMul S T
inst✝ : IsScalarTower S T R
s : S
t : T
x : ℍ[R,c₁,c₂]
⊢ ((s • t) • x).imK = (s • t • x).imK

Next tactic:
exact smul_assoc _ _ _
instance [SMulCommClass S T R] : SMulCommClass S T ℍ[R,c₁,c₂] where
  smul_comm s t x := by 

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝³ : CommRing R
c₁ c₂ r x✝ y z : R
a b c : ℍ[R,c₁,c₂]
inst✝² : SMul S R
inst✝¹ : SMul T R
s✝ : S
inst✝ : SMulCommClass S T R
s : S
t : T
x : ℍ[R,c₁,c₂]
⊢ s • t • x = t • s • x

Next tactic:
ext
instance [SMulCommClass S T R] : SMulCommClass S T ℍ[R,c₁,c₂] where
  smul_comm s t x := by ext <;> 

Proof state:
case re
S : Type u_1
T : Type u_2
R : Type u_3
inst✝³ : CommRing R
c₁ c₂ r x✝ y z : R
a b c : ℍ[R,c₁,c₂]
inst✝² : SMul S R
inst✝¹ : SMul T R
s✝ : S
inst✝ : SMulCommClass S T R
s : S
t : T
x : ℍ[R,c₁,c₂]
⊢ (s • t • x).re = (t • s • x).re

Next tactic:
exact smul_comm _ _ _
instance [SMulCommClass S T R] : SMulCommClass S T ℍ[R,c₁,c₂] where
  smul_comm s t x := by ext <;> 

Proof state:
case imI
S : Type u_1
T : Type u_2
R : Type u_3
inst✝³ : CommRing R
c₁ c₂ r x✝ y z : R
a b c : ℍ[R,c₁,c₂]
inst✝² : SMul S R
inst✝¹ : SMul T R
s✝ : S
inst✝ : SMulCommClass S T R
s : S
t : T
x : ℍ[R,c₁,c₂]
⊢ (s • t • x).imI = (t • s • x).imI

Next tactic:
exact smul_comm _ _ _
instance [SMulCommClass S T R] : SMulCommClass S T ℍ[R,c₁,c₂] where
  smul_comm s t x := by ext <;> 

Proof state:
case imJ
S : Type u_1
T : Type u_2
R : Type u_3
inst✝³ : CommRing R
c₁ c₂ r x✝ y z : R
a b c : ℍ[R,c₁,c₂]
inst✝² : SMul S R
inst✝¹ : SMul T R
s✝ : S
inst✝ : SMulCommClass S T R
s : S
t : T
x : ℍ[R,c₁,c₂]
⊢ (s • t • x).imJ = (t • s • x).imJ

Next tactic:
exact smul_comm _ _ _
instance [SMulCommClass S T R] : SMulCommClass S T ℍ[R,c₁,c₂] where
  smul_comm s t x := by ext <;> 

Proof state:
case imK
S : Type u_1
T : Type u_2
R : Type u_3
inst✝³ : CommRing R
c₁ c₂ r x✝ y z : R
a b c : ℍ[R,c₁,c₂]
inst✝² : SMul S R
inst✝¹ : SMul T R
s✝ : S
inst✝ : SMulCommClass S T R
s : S
t : T
x : ℍ[R,c₁,c₂]
⊢ (s • t • x).imK = (t • s • x).imK

Next tactic:
exact smul_comm _ _ _
instance : AddCommGroupWithOne ℍ[R,c₁,c₂] where
  natCast n := ((n : R) : ℍ[R,c₁,c₂])
  natCast_zero := by 

Proof state:
S : Type u_1
T : Type u_2
R : Type u_3
inst✝ : CommRing R
c₁ c₂ r x y z : R
a b c : ℍ[R,c₁,c₂]
⊢ NatCast.natCast 0 = 0

Next tactic:
simp