l3lab/ntp-mathlib huggingface dataset:
theorem ext' [T : TopologicalSpace α] {σ : Type*} {F : Ctop α σ}
    (H : ∀ a s, s ∈ 𝓝 a ↔ ∃ b, a ∈ F b ∧ F b ⊆ s) : F.toTopsp = T := by
  refine' eq_of_nhds_eq_nhds fun x ↦ _
  ext s
  

Proof state:
case a
α : Type u_1
β : Type u_2
σ✝ : Type u_3
τ : Type u_4
T : TopologicalSpace α
σ : Type u_5
F : Ctop α σ
H : ∀ (a : α) (s : Set α), s ∈ 𝓝 a ↔ ∃ b, a ∈ f F b ∧ f F b ⊆ s
x : α
s : Set α
⊢ s ∈ 𝓝 x ↔ s ∈ 𝓝 x

Next tactic:
rw [mem_nhds_toTopsp, H]
/-- Replace the representation type of a `Ctop` realizer. -/
def ofEquiv (F : Realizer α) (E : F.σ ≃ τ) : Realizer α :=
  ⟨τ, F.F.ofEquiv E,
    ext' fun a s ↦
      F.mem_nhds.trans <|
        ⟨fun ⟨s, h⟩ ↦ ⟨E s, by 

Proof state:
α : Type u_1
β : Type u_2
σ : Type u_3
τ : Type u_4
inst✝ : TopologicalSpace α
F : Realizer α
E : F.σ ≃ τ
a : α
s✝ : Set α
x✝ : ∃ b, a ∈ f F.F b ∧ f F.F b ⊆ s✝
s : F.σ
h : a ∈ f F.F s ∧ f F.F s ⊆ s✝
⊢ a ∈ f (Ctop.ofEquiv E F.F) (E s) ∧ f (Ctop.ofEquiv E F.F) (E s) ⊆ s✝

Next tactic:
simpa using h
/-- Replace the representation type of a `Ctop` realizer. -/
def ofEquiv (F : Realizer α) (E : F.σ ≃ τ) : Realizer α :=
  ⟨τ, F.F.ofEquiv E,
    ext' fun a s ↦
      F.mem_nhds.trans <|
        ⟨fun ⟨s, h⟩ ↦ ⟨E s, by simpa using h⟩, fun ⟨t, h⟩ ↦ ⟨E.symm t, by 

Proof state:
α : Type u_1
β : Type u_2
σ : Type u_3
τ : Type u_4
inst✝ : TopologicalSpace α
F : Realizer α
E : F.σ ≃ τ
a : α
s : Set α
x✝ : ∃ b, a ∈ f (Ctop.ofEquiv E F.F) b ∧ f (Ctop.ofEquiv E F.F) b ⊆ s
t : τ
h : a ∈ f (Ctop.ofEquiv E F.F) t ∧ f (Ctop.ofEquiv E F.F) t ⊆ s
⊢ a ∈ f F.F (E.symm t) ∧ f F.F (E.symm t) ⊆ s

Next tactic:
simpa using h
@[simp]
theorem ofEquiv_F (F : Realizer α) (E : F.σ ≃ τ) (s : τ) : (F.ofEquiv E).F s = F.F (E.symm s) := by
  

Proof state:
α : Type u_1
β : Type u_2
σ : Type u_3
τ : Type u_4
inst✝ : TopologicalSpace α
F : Realizer α
E : F.σ ≃ τ
s : τ
⊢ f (ofEquiv F E).F s = f F.F (E.symm s)

Next tactic:
delta ofEquiv
@[simp]
theorem ofEquiv_F (F : Realizer α) (E : F.σ ≃ τ) (s : τ) : (F.ofEquiv E).F s = F.F (E.symm s) := by
  delta ofEquiv; 

Proof state:
α : Type u_1
β : Type u_2
σ : Type u_3
τ : Type u_4
inst✝ : TopologicalSpace α
F : Realizer α
E : F.σ ≃ τ
s : τ
⊢ f { σ := τ, F := Ctop.ofEquiv E F.F, eq := (_ : toTopsp (Ctop.ofEquiv E F.F) = inst✝) }.F s = f F.F (E.symm s)

Next tactic:
simp
instance [TopologicalSpace α] : Inhabited (Compact.Realizer (∅ : Set α)) :=
  ⟨fun {f} F x h hF ↦ by
    

Proof state:
α : Type u_1
β : Type u_2
σ : Type u_3
τ : Type u_4
inst✝ : TopologicalSpace α
f : Filter α
F : Filter.Realizer f
x : F.σ
h : f ≠ ⊥
hF : CFilter.f F.F x ⊆ ∅
⊢ { a // a ∈ ∅ ∧ 𝓝 a ⊓ f ≠ ⊥ }

Next tactic:
suffices : f = ⊥
instance [TopologicalSpace α] : Inhabited (Compact.Realizer (∅ : Set α)) :=
  ⟨fun {f} F x h hF ↦ by
    suffices : f = ⊥; 

Proof state:
α : Type u_1
β : Type u_2
σ : Type u_3
τ : Type u_4
inst✝ : TopologicalSpace α
f : Filter α
F : Filter.Realizer f
x : F.σ
h : f ≠ ⊥
hF : CFilter.f F.F x ⊆ ∅
this : f = ⊥
⊢ { a // a ∈ ∅ ∧ 𝓝 a ⊓ f ≠ ⊥ }
case this
α : Type u_1
β : Type u_2
σ : Type u_3
τ : Type u_4
inst✝ : TopologicalSpace α
f : Filter α
F : Filter.Realizer f
x : F.σ
h : f ≠ ⊥
hF : CFilter.f F.F x ⊆ ∅
⊢ f = ⊥

Next tactic:
exact absurd this h
instance [TopologicalSpace α] : Inhabited (Compact.Realizer (∅ : Set α)) :=
  ⟨fun {f} F x h hF ↦ by
    suffices : f = ⊥; exact absurd this h
    

Proof state:
case this
α : Type u_1
β : Type u_2
σ : Type u_3
τ : Type u_4
inst✝ : TopologicalSpace α
f : Filter α
F : Filter.Realizer f
x : F.σ
h : f ≠ ⊥
hF : CFilter.f F.F x ⊆ ∅
⊢ f = ⊥

Next tactic:
rw [← F.eq, eq_bot_iff]
instance [TopologicalSpace α] : Inhabited (Compact.Realizer (∅ : Set α)) :=
  ⟨fun {f} F x h hF ↦ by
    suffices : f = ⊥; exact absurd this h
    rw [← F.eq, eq_bot_iff]
    

Proof state:
case this
α : Type u_1
β : Type u_2
σ : Type u_3
τ : Type u_4
inst✝ : TopologicalSpace α
f : Filter α
F : Filter.Realizer f
x : F.σ
h : f ≠ ⊥
hF : CFilter.f F.F x ⊆ ∅
⊢ CFilter.toFilter F.F ≤ ⊥

Next tactic:
exact λ s _ ↦ ⟨x, hF.trans s.empty_subset⟩
@[simp]
theorem LinearMap.toMatrix_transpose (u : V₁ →ₗ[K] V₂) :
    LinearMap.toMatrix B₂.dualBasis B₁.dualBasis (Module.Dual.transpose (R := K) u) =
      (LinearMap.toMatrix B₁ B₂ u)ᵀ := by
  

Proof state:
K : Type u_1
V₁ : Type u_2
V₂ : Type u_3
ι₁ : Type u_4
ι₂ : Type u_5
inst✝⁸ : Field K
inst✝⁷ : AddCommGroup V₁
inst✝⁶ : Module K V₁
inst✝⁵ : AddCommGroup V₂
inst✝⁴ : Module K V₂
inst✝³ : Fintype ι₁
inst✝² : Fintype ι₂
inst✝¹ : DecidableEq ι₁
inst✝ : DecidableEq ι₂
B₁ : Basis ι₁ K V₁
B₂ : Basis ι₂ K V₂
u : V₁ →ₗ[K] V₂
⊢ (toMatrix (Basis.dualBasis B₂) (Basis.dualBasis B₁)) (Module.Dual.transpose u) = ((toMatrix B₁ B₂) u)ᵀ

Next tactic:
ext i j
@[simp]
theorem LinearMap.toMatrix_transpose (u : V₁ →ₗ[K] V₂) :
    LinearMap.toMatrix B₂.dualBasis B₁.dualBasis (Module.Dual.transpose (R := K) u) =
      (LinearMap.toMatrix B₁ B₂ u)ᵀ := by
  ext i j
  

Proof state:
case a.h
K : Type u_1
V₁ : Type u_2
V₂ : Type u_3
ι₁ : Type u_4
ι₂ : Type u_5
inst✝⁸ : Field K
inst✝⁷ : AddCommGroup V₁
inst✝⁶ : Module K V₁
inst✝⁵ : AddCommGroup V₂
inst✝⁴ : Module K V₂
inst✝³ : Fintype ι₁
inst✝² : Fintype ι₂
inst✝¹ : DecidableEq ι₁
inst✝ : DecidableEq ι₂
B₁ : Basis ι₁ K V₁
B₂ : Basis ι₂ K V₂
u : V₁ →ₗ[K] V₂
i : ι₁
j : ι₂
⊢ (toMatrix (Basis.dualBasis B₂) (Basis.dualBasis B₁)) (Module.Dual.transpose u) i j = ((toMatrix B₁ B₂) u)ᵀ i j

Next tactic:
simp only [LinearMap.toMatrix_apply, Module.Dual.transpose_apply, B₁.dualBasis_repr,
    B₂.dualBasis_apply, Matrix.transpose_apply, LinearMap.comp_apply]
@[simp]
theorem Matrix.toLin_transpose (M : Matrix ι₁ ι₂ K) : Matrix.toLin B₁.dualBasis B₂.dualBasis Mᵀ =
    Module.Dual.transpose (R := K) (Matrix.toLin B₂ B₁ M) := by
  

Proof state:
K : Type u_1
V₁ : Type u_2
V₂ : Type u_3
ι₁ : Type u_4
ι₂ : Type u_5
inst✝⁸ : Field K
inst✝⁷ : AddCommGroup V₁
inst✝⁶ : Module K V₁
inst✝⁵ : AddCommGroup V₂
inst✝⁴ : Module K V₂
inst✝³ : Fintype ι₁
inst✝² : Fintype ι₂
inst✝¹ : DecidableEq ι₁
inst✝ : DecidableEq ι₂
B₁ : Basis ι₁ K V₁
B₂ : Basis ι₂ K V₂
M : Matrix ι₁ ι₂ K
⊢ (toLin (Basis.dualBasis B₁) (Basis.dualBasis B₂)) Mᵀ = Module.Dual.transpose ((toLin B₂ B₁) M)

Next tactic:
apply (LinearMap.toMatrix B₁.dualBasis B₂.dualBasis).injective
@[simp]
theorem Matrix.toLin_transpose (M : Matrix ι₁ ι₂ K) : Matrix.toLin B₁.dualBasis B₂.dualBasis Mᵀ =
    Module.Dual.transpose (R := K) (Matrix.toLin B₂ B₁ M) := by
  apply (LinearMap.toMatrix B₁.dualBasis B₂.dualBasis).injective
  

Proof state:
case a
K : Type u_1
V₁ : Type u_2
V₂ : Type u_3
ι₁ : Type u_4
ι₂ : Type u_5
inst✝⁸ : Field K
inst✝⁷ : AddCommGroup V₁
inst✝⁶ : Module K V₁
inst✝⁵ : AddCommGroup V₂
inst✝⁴ : Module K V₂
inst✝³ : Fintype ι₁
inst✝² : Fintype ι₂
inst✝¹ : DecidableEq ι₁
inst✝ : DecidableEq ι₂
B₁ : Basis ι₁ K V₁
B₂ : Basis ι₂ K V₂
M : Matrix ι₁ ι₂ K
⊢ (LinearMap.toMatrix (Basis.dualBasis B₁) (Basis.dualBasis B₂))
      ((toLin (Basis.dualBasis B₁) (Basis.dualBasis B₂)) Mᵀ) =
    (LinearMap.toMatrix (Basis.dualBasis B₁) (Basis.dualBasis B₂)) (Module.Dual.transpose ((toLin B₂ B₁) M))

Next tactic:
rw [LinearMap.toMatrix_toLin, LinearMap.toMatrix_transpose, LinearMap.toMatrix_toLin]
@[to_additive]
instance SemigroupPEmpty : Semigroup PEmpty.{u + 1} where
  mul x _ := by 

Proof state:
x x✝ : PEmpty.{u + 1}
⊢ PEmpty.{u + 1}

Next tactic:
cases x
@[to_additive]
instance SemigroupPEmpty : Semigroup PEmpty.{u + 1} where
  mul x _ := by cases x
  mul_assoc x y z := by 

Proof state:
x y z : PEmpty.{u + 1}
⊢ x * y * z = x * (y * z)

Next tactic:
cases x
/-- The multicospan associated to a cover `S : J.Cover X` and a presheaf of the form `P ⋙ F`
is isomorphic to the composition of the multicospan associated to `S` and `P`,
composed with `F`. -/
def multicospanComp : (S.index (P ⋙ F)).multicospan ≅ (S.index P).multicospan ⋙ F :=
  NatIso.ofComponents
    (fun t =>
      match t with
      | WalkingMulticospan.left a => eqToIso rfl
      | WalkingMulticospan.right b => eqToIso rfl)
    (by
      

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁴ : Category.{v₂, u₂} A
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
F G H : A ⥤ B
η : F ⟶ G
γ : G ⟶ H
inst✝² : HasSheafCompose J F
inst✝¹ : HasSheafCompose J G
inst✝ : HasSheafCompose J H
P : Cᵒᵖ ⥤ A
X : C
S : Cover J X
⊢ ∀ {X_1 Y : WalkingMulticospan (index S (P ⋙ F)).fstTo (index S (P ⋙ F)).sndTo} (f : X_1 ⟶ Y),
    (MulticospanIndex.multicospan (index S (P ⋙ F))).map f ≫
        ((fun t =>
              match t with
              | WalkingMulticospan.left a =>
                eqToIso
                  (_ :
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a) =
                      (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a))
              | WalkingMulticospan.right b =>
                eqToIso
                  (_ :
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b) =
                      (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b)))
            Y).hom =
      ((fun t =>
              match t with
              | WalkingMulticospan.left a =>
                eqToIso
                  (_ :
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a) =
                      (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a))
              | WalkingMulticospan.right b =>
                eqToIso
                  (_ :
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b) =
                      (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b)))
            X_1).hom ≫
        (MulticospanIndex.multicospan (index S P) ⋙ F).map f

Next tactic:
rintro (a | b) (a | b) (f | f | f)
/-- The multicospan associated to a cover `S : J.Cover X` and a presheaf of the form `P ⋙ F`
is isomorphic to the composition of the multicospan associated to `S` and `P`,
composed with `F`. -/
def multicospanComp : (S.index (P ⋙ F)).multicospan ≅ (S.index P).multicospan ⋙ F :=
  NatIso.ofComponents
    (fun t =>
      match t with
      | WalkingMulticospan.left a => eqToIso rfl
      | WalkingMulticospan.right b => eqToIso rfl)
    (by
      rintro (a | b) (a | b) (f | f | f)
      all_goals 

Proof state:
case left.left.id
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁴ : Category.{v₂, u₂} A
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
F G H : A ⥤ B
η : F ⟶ G
γ : G ⟶ H
inst✝² : HasSheafCompose J F
inst✝¹ : HasSheafCompose J G
inst✝ : HasSheafCompose J H
P : Cᵒᵖ ⥤ A
X : C
S : Cover J X
a : (index S (P ⋙ F)).L
⊢ (MulticospanIndex.multicospan (index S (P ⋙ F))).map (WalkingMulticospan.Hom.id (WalkingMulticospan.left a)) ≫
      ((fun t =>
            match t with
            | WalkingMulticospan.left a =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a))
            | WalkingMulticospan.right b =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b)))
          (WalkingMulticospan.left a)).hom =
    ((fun t =>
            match t with
            | WalkingMulticospan.left a =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a))
            | WalkingMulticospan.right b =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b)))
          (WalkingMulticospan.left a)).hom ≫
      (MulticospanIndex.multicospan (index S P) ⋙ F).map (WalkingMulticospan.Hom.id (WalkingMulticospan.left a))

Next tactic:
aesop_cat
/-- The multicospan associated to a cover `S : J.Cover X` and a presheaf of the form `P ⋙ F`
is isomorphic to the composition of the multicospan associated to `S` and `P`,
composed with `F`. -/
def multicospanComp : (S.index (P ⋙ F)).multicospan ≅ (S.index P).multicospan ⋙ F :=
  NatIso.ofComponents
    (fun t =>
      match t with
      | WalkingMulticospan.left a => eqToIso rfl
      | WalkingMulticospan.right b => eqToIso rfl)
    (by
      rintro (a | b) (a | b) (f | f | f)
      all_goals 

Proof state:
case left.right.fst
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁴ : Category.{v₂, u₂} A
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
F G H : A ⥤ B
η : F ⟶ G
γ : G ⟶ H
inst✝² : HasSheafCompose J F
inst✝¹ : HasSheafCompose J G
inst✝ : HasSheafCompose J H
P : Cᵒᵖ ⥤ A
X : C
S : Cover J X
b : (index S (P ⋙ F)).R
⊢ (MulticospanIndex.multicospan (index S (P ⋙ F))).map (WalkingMulticospan.Hom.fst b) ≫
      ((fun t =>
            match t with
            | WalkingMulticospan.left a =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a))
            | WalkingMulticospan.right b =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b)))
          (WalkingMulticospan.right b)).hom =
    ((fun t =>
            match t with
            | WalkingMulticospan.left a =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a))
            | WalkingMulticospan.right b =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b)))
          (WalkingMulticospan.left (MulticospanIndex.fstTo (index S (P ⋙ F)) b))).hom ≫
      (MulticospanIndex.multicospan (index S P) ⋙ F).map (WalkingMulticospan.Hom.fst b)

Next tactic:
aesop_cat
/-- The multicospan associated to a cover `S : J.Cover X` and a presheaf of the form `P ⋙ F`
is isomorphic to the composition of the multicospan associated to `S` and `P`,
composed with `F`. -/
def multicospanComp : (S.index (P ⋙ F)).multicospan ≅ (S.index P).multicospan ⋙ F :=
  NatIso.ofComponents
    (fun t =>
      match t with
      | WalkingMulticospan.left a => eqToIso rfl
      | WalkingMulticospan.right b => eqToIso rfl)
    (by
      rintro (a | b) (a | b) (f | f | f)
      all_goals 

Proof state:
case left.right.snd
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁴ : Category.{v₂, u₂} A
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
F G H : A ⥤ B
η : F ⟶ G
γ : G ⟶ H
inst✝² : HasSheafCompose J F
inst✝¹ : HasSheafCompose J G
inst✝ : HasSheafCompose J H
P : Cᵒᵖ ⥤ A
X : C
S : Cover J X
b : (index S (P ⋙ F)).R
⊢ (MulticospanIndex.multicospan (index S (P ⋙ F))).map (WalkingMulticospan.Hom.snd b) ≫
      ((fun t =>
            match t with
            | WalkingMulticospan.left a =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a))
            | WalkingMulticospan.right b =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b)))
          (WalkingMulticospan.right b)).hom =
    ((fun t =>
            match t with
            | WalkingMulticospan.left a =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a))
            | WalkingMulticospan.right b =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b)))
          (WalkingMulticospan.left (MulticospanIndex.sndTo (index S (P ⋙ F)) b))).hom ≫
      (MulticospanIndex.multicospan (index S P) ⋙ F).map (WalkingMulticospan.Hom.snd b)

Next tactic:
aesop_cat
/-- The multicospan associated to a cover `S : J.Cover X` and a presheaf of the form `P ⋙ F`
is isomorphic to the composition of the multicospan associated to `S` and `P`,
composed with `F`. -/
def multicospanComp : (S.index (P ⋙ F)).multicospan ≅ (S.index P).multicospan ⋙ F :=
  NatIso.ofComponents
    (fun t =>
      match t with
      | WalkingMulticospan.left a => eqToIso rfl
      | WalkingMulticospan.right b => eqToIso rfl)
    (by
      rintro (a | b) (a | b) (f | f | f)
      all_goals 

Proof state:
case right.right.id
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁴ : Category.{v₂, u₂} A
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
F G H : A ⥤ B
η : F ⟶ G
γ : G ⟶ H
inst✝² : HasSheafCompose J F
inst✝¹ : HasSheafCompose J G
inst✝ : HasSheafCompose J H
P : Cᵒᵖ ⥤ A
X : C
S : Cover J X
b : (index S (P ⋙ F)).R
⊢ (MulticospanIndex.multicospan (index S (P ⋙ F))).map (WalkingMulticospan.Hom.id (WalkingMulticospan.right b)) ≫
      ((fun t =>
            match t with
            | WalkingMulticospan.left a =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a))
            | WalkingMulticospan.right b =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b)))
          (WalkingMulticospan.right b)).hom =
    ((fun t =>
            match t with
            | WalkingMulticospan.left a =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.left a))
            | WalkingMulticospan.right b =>
              eqToIso
                (_ :
                  (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b) =
                    (MulticospanIndex.multicospan (index S (P ⋙ F))).obj (WalkingMulticospan.right b)))
          (WalkingMulticospan.right b)).hom ≫
      (MulticospanIndex.multicospan (index S P) ⋙ F).map (WalkingMulticospan.Hom.id (WalkingMulticospan.right b))

Next tactic:
aesop_cat
/-- Mapping the multifork associated to a cover `S : J.Cover X` and a presheaf `P` with
respect to a functor `F` is isomorphic (upto a natural isomorphism of the underlying functors)
to the multifork associated to `S` and `P ⋙ F`. -/
def mapMultifork :
    F.mapCone (S.multifork P) ≅
      (Limits.Cones.postcompose (S.multicospanComp F P).hom).obj (S.multifork (P ⋙ F)) :=
  Cones.ext (eqToIso rfl)
    (by
      

Proof state:
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁴ : Category.{v₂, u₂} A
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
F G H : A ⥤ B
η : F ⟶ G
γ : G ⟶ H
inst✝² : HasSheafCompose J F
inst✝¹ : HasSheafCompose J G
inst✝ : HasSheafCompose J H
P : Cᵒᵖ ⥤ A
X : C
S : Cover J X
⊢ ∀ (j : WalkingMulticospan (index S P).fstTo (index S P).sndTo),
    (F.mapCone (multifork S P)).π.app j =
      (eqToIso (_ : (F.mapCone (multifork S P)).pt = (F.mapCone (multifork S P)).pt)).hom ≫
        ((Cones.postcompose (multicospanComp F P S).hom).obj (multifork S (P ⋙ F))).π.app j

Next tactic:
rintro (a | b)
/-- Mapping the multifork associated to a cover `S : J.Cover X` and a presheaf `P` with
respect to a functor `F` is isomorphic (upto a natural isomorphism of the underlying functors)
to the multifork associated to `S` and `P ⋙ F`. -/
def mapMultifork :
    F.mapCone (S.multifork P) ≅
      (Limits.Cones.postcompose (S.multicospanComp F P).hom).obj (S.multifork (P ⋙ F)) :=
  Cones.ext (eqToIso rfl)
    (by
      rintro (a | b)
      · 

Proof state:
case left
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁴ : Category.{v₂, u₂} A
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
F G H : A ⥤ B
η : F ⟶ G
γ : G ⟶ H
inst✝² : HasSheafCompose J F
inst✝¹ : HasSheafCompose J G
inst✝ : HasSheafCompose J H
P : Cᵒᵖ ⥤ A
X : C
S : Cover J X
a : (index S P).L
⊢ (F.mapCone (multifork S P)).π.app (WalkingMulticospan.left a) =
    (eqToIso (_ : (F.mapCone (multifork S P)).pt = (F.mapCone (multifork S P)).pt)).hom ≫
      ((Cones.postcompose (multicospanComp F P S).hom).obj (multifork S (P ⋙ F))).π.app (WalkingMulticospan.left a)

Next tactic:
dsimp
/-- Mapping the multifork associated to a cover `S : J.Cover X` and a presheaf `P` with
respect to a functor `F` is isomorphic (upto a natural isomorphism of the underlying functors)
to the multifork associated to `S` and `P ⋙ F`. -/
def mapMultifork :
    F.mapCone (S.multifork P) ≅
      (Limits.Cones.postcompose (S.multicospanComp F P).hom).obj (S.multifork (P ⋙ F)) :=
  Cones.ext (eqToIso rfl)
    (by
      rintro (a | b)
      · dsimp
        

Proof state:
case left
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁴ : Category.{v₂, u₂} A
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
F G H : A ⥤ B
η : F ⟶ G
γ : G ⟶ H
inst✝² : HasSheafCompose J F
inst✝¹ : HasSheafCompose J G
inst✝ : HasSheafCompose J H
P : Cᵒᵖ ⥤ A
X : C
S : Cover J X
a : (index S P).L
⊢ F.map (P.map a.f.op) =
    𝟙 (F.obj (P.obj (Opposite.op X))) ≫
      F.map (P.map a.f.op) ≫ (multicospanComp F P S).hom.app (WalkingMulticospan.left a)

Next tactic:
erw [Category.id_comp, multicospanComp_hom_app_left, eqToHom_refl, Category.comp_id]
/-- Mapping the multifork associated to a cover `S : J.Cover X` and a presheaf `P` with
respect to a functor `F` is isomorphic (upto a natural isomorphism of the underlying functors)
to the multifork associated to `S` and `P ⋙ F`. -/
def mapMultifork :
    F.mapCone (S.multifork P) ≅
      (Limits.Cones.postcompose (S.multicospanComp F P).hom).obj (S.multifork (P ⋙ F)) :=
  Cones.ext (eqToIso rfl)
    (by
      rintro (a | b)
      · dsimp
        erw [Category.id_comp, multicospanComp_hom_app_left, eqToHom_refl, Category.comp_id]
      · 

Proof state:
case right
C : Type u₁
inst✝⁵ : Category.{v₁, u₁} C
A : Type u₂
inst✝⁴ : Category.{v₂, u₂} A
B : Type u₃
inst✝³ : Category.{v₃, u₃} B
J : GrothendieckTopology C
U : C
R : Presieve U
F G H : A ⥤ B
η : F ⟶ G
γ : G ⟶ H
inst✝² : HasSheafCompose J F
inst✝¹ : HasSheafCompose J G
inst✝ : HasSheafCompose J H
P : Cᵒᵖ ⥤ A
X : C
S : Cover J X
b : (index S P).R
⊢ (F.mapCone (multifork S P)).π.app (WalkingMulticospan.right b) =
    (eqToIso (_ : (F.mapCone (multifork S P)).pt = (F.mapCone (multifork S P)).pt)).hom ≫
      ((Cones.postcompose (multicospanComp F P S).hom).obj (multifork S (P ⋙ F))).π.app (WalkingMulticospan.right b)

Next tactic:
dsimp