l3lab/ntp-mathlib huggingface dataset:
theorem Ici_iSup (f : ι → α) : Ici (⨆ i, f i) = ⋂ i, Ici (f i) :=
  ext fun _ => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
inst✝ : CompleteLattice α
f : ι → α
x✝ : α
⊢ x✝ ∈ Ici (⨆ i, f i) ↔ x✝ ∈ ⋂ i, Ici (f i)

Next tactic:
simp only [mem_Ici, iSup_le_iff, mem_iInter]
theorem Iic_iInf (f : ι → α) : Iic (⨅ i, f i) = ⋂ i, Iic (f i) :=
  ext fun _ => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
inst✝ : CompleteLattice α
f : ι → α
x✝ : α
⊢ x✝ ∈ Iic (⨅ i, f i) ↔ x✝ ∈ ⋂ i, Iic (f i)

Next tactic:
simp only [mem_Iic, le_iInf_iff, mem_iInter]
theorem Ici_iSup₂ (f : ∀ i, κ i → α) : Ici (⨆ (i) (j), f i j) = ⋂ (i) (j), Ici (f i j) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
inst✝ : CompleteLattice α
f : (i : ι) → κ i → α
⊢ Ici (⨆ i, ⨆ j, f i j) = ⋂ i, ⋂ j, Ici (f i j)

Next tactic:
simp_rw [Ici_iSup]
theorem Iic_iInf₂ (f : ∀ i, κ i → α) : Iic (⨅ (i) (j), f i j) = ⋂ (i) (j), Iic (f i j) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
inst✝ : CompleteLattice α
f : (i : ι) → κ i → α
⊢ Iic (⨅ i, ⨅ j, f i j) = ⋂ i, ⋂ j, Iic (f i j)

Next tactic:
simp_rw [Iic_iInf]
theorem Ici_sSup (s : Set α) : Ici (sSup s) = ⋂ a ∈ s, Ici a := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
inst✝ : CompleteLattice α
s : Set α
⊢ Ici (sSup s) = ⋂ a ∈ s, Ici a

Next tactic:
rw [sSup_eq_iSup, Ici_iSup₂]
theorem Iic_sInf (s : Set α) : Iic (sInf s) = ⋂ a ∈ s, Iic a := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
inst✝ : CompleteLattice α
s : Set α
⊢ Iic (sInf s) = ⋂ a ∈ s, Iic a

Next tactic:
rw [sInf_eq_iInf, Iic_iInf₂]
theorem biUnion_diff_biUnion_subset (s₁ s₂ : Set α) :
    ((⋃ x ∈ s₁, t x) \ ⋃ x ∈ s₂, t x) ⊆ ⋃ x ∈ s₁ \ s₂, t x := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
t : α → Set β
s₁ s₂ : Set α
⊢ (⋃ x ∈ s₁, t x) \ ⋃ x ∈ s₂, t x ⊆ ⋃ x ∈ s₁ \ s₂, t x

Next tactic:
simp only [diff_subset_iff, ← biUnion_union]
theorem biUnion_diff_biUnion_subset (s₁ s₂ : Set α) :
    ((⋃ x ∈ s₁, t x) \ ⋃ x ∈ s₂, t x) ⊆ ⋃ x ∈ s₁ \ s₂, t x := by
  simp only [diff_subset_iff, ← biUnion_union]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
t : α → Set β
s₁ s₂ : Set α
⊢ ⋃ x ∈ s₁, t x ⊆ ⋃ x ∈ s₂ ∪ s₁ \ s₂, t x

Next tactic:
apply biUnion_subset_biUnion_left
theorem biUnion_diff_biUnion_subset (s₁ s₂ : Set α) :
    ((⋃ x ∈ s₁, t x) \ ⋃ x ∈ s₂, t x) ⊆ ⋃ x ∈ s₁ \ s₂, t x := by
  simp only [diff_subset_iff, ← biUnion_union]
  apply biUnion_subset_biUnion_left
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
t : α → Set β
s₁ s₂ : Set α
⊢ s₁ ⊆ s₂ ∪ s₁ \ s₂

Next tactic:
rw [union_diff_self]
theorem biUnion_diff_biUnion_subset (s₁ s₂ : Set α) :
    ((⋃ x ∈ s₁, t x) \ ⋃ x ∈ s₂, t x) ⊆ ⋃ x ∈ s₁ \ s₂, t x := by
  simp only [diff_subset_iff, ← biUnion_union]
  apply biUnion_subset_biUnion_left
  rw [union_diff_self]
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
t : α → Set β
s₁ s₂ : Set α
⊢ s₁ ⊆ s₂ ∪ s₁

Next tactic:
apply subset_union_right
theorem sigmaToiUnion_surjective : Surjective (sigmaToiUnion t)
  | ⟨b, hb⟩ =>
    have : ∃ a, b ∈ t a := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
t : α → Set β
b : β
hb : b ∈ ⋃ i, t i
⊢ ∃ a, b ∈ t a

Next tactic:
simpa using hb
theorem sigmaToiUnion_injective (h : ∀ i j, i ≠ j → Disjoint (t i) (t j)) :
    Injective (sigmaToiUnion t)
  | ⟨a₁, b₁, h₁⟩, ⟨a₂, b₂, h₂⟩, eq =>
    have b_eq : b₁ = b₂ := congr_arg Subtype.val eq
    have a_eq : a₁ = a₂ :=
      by_contradiction fun ne =>
        have : b₁ ∈ t a₁ ∩ t a₂ := ⟨h₁, b_eq.symm ▸ h₂⟩
        (h _ _ ne).le_bot this
    Sigma.eq a_eq <| Subtype.eq <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
t : α → Set β
h : ∀ (i j : α), i ≠ j → Disjoint (t i) (t j)
a₁ : α
b₁ : β
h₁ : b₁ ∈ t a₁
a₂ : α
b₂ : β
h₂ : b₂ ∈ t a₂
eq :
  sigmaToiUnion t { fst := a₁, snd := { val := b₁, property := h₁ } } =
    sigmaToiUnion t { fst := a₂, snd := { val := b₂, property := h₂ } }
b_eq : b₁ = b₂
a_eq : a₁ = a₂
⊢ ↑(Eq.recOn a_eq { fst := a₁, snd := { val := b₁, property := h₁ } }.snd) =
    ↑{ fst := a₂, snd := { val := b₂, property := h₂ } }.snd

Next tactic:
subst b_eq
theorem sigmaToiUnion_injective (h : ∀ i j, i ≠ j → Disjoint (t i) (t j)) :
    Injective (sigmaToiUnion t)
  | ⟨a₁, b₁, h₁⟩, ⟨a₂, b₂, h₂⟩, eq =>
    have b_eq : b₁ = b₂ := congr_arg Subtype.val eq
    have a_eq : a₁ = a₂ :=
      by_contradiction fun ne =>
        have : b₁ ∈ t a₁ ∩ t a₂ := ⟨h₁, b_eq.symm ▸ h₂⟩
        (h _ _ ne).le_bot this
    Sigma.eq a_eq <| Subtype.eq <| by subst b_eq; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
t : α → Set β
h : ∀ (i j : α), i ≠ j → Disjoint (t i) (t j)
a₁ : α
b₁ : β
h₁ : b₁ ∈ t a₁
a₂ : α
a_eq : a₁ = a₂
h₂ : b₁ ∈ t a₂
eq :
  sigmaToiUnion t { fst := a₁, snd := { val := b₁, property := h₁ } } =
    sigmaToiUnion t { fst := a₂, snd := { val := b₁, property := h₂ } }
⊢ ↑(Eq.recOn a_eq { fst := a₁, snd := { val := b₁, property := h₁ } }.snd) =
    ↑{ fst := a₂, snd := { val := b₁, property := h₂ } }.snd

Next tactic:
subst a_eq
theorem sigmaToiUnion_injective (h : ∀ i j, i ≠ j → Disjoint (t i) (t j)) :
    Injective (sigmaToiUnion t)
  | ⟨a₁, b₁, h₁⟩, ⟨a₂, b₂, h₂⟩, eq =>
    have b_eq : b₁ = b₂ := congr_arg Subtype.val eq
    have a_eq : a₁ = a₂ :=
      by_contradiction fun ne =>
        have : b₁ ∈ t a₁ ∩ t a₂ := ⟨h₁, b_eq.symm ▸ h₂⟩
        (h _ _ ne).le_bot this
    Sigma.eq a_eq <| Subtype.eq <| by subst b_eq; subst a_eq; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
t : α → Set β
h : ∀ (i j : α), i ≠ j → Disjoint (t i) (t j)
a₁ : α
b₁ : β
h₁ h₂ : b₁ ∈ t a₁
eq :
  sigmaToiUnion t { fst := a₁, snd := { val := b₁, property := h₁ } } =
    sigmaToiUnion t { fst := a₁, snd := { val := b₁, property := h₂ } }
⊢ ↑(Eq.recOn (_ : a₁ = a₁) { fst := a₁, snd := { val := b₁, property := h₁ } }.snd) =
    ↑{ fst := a₁, snd := { val := b₁, property := h₂ } }.snd

Next tactic:
rfl
theorem iSup_iUnion (s : ι → Set α) (f : α → β) : ⨆ a ∈ ⋃ i, s i, f a = ⨆ (i) (a ∈ s i), f a := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
inst✝ : CompleteLattice β
s : ι → Set α
f : α → β
⊢ ⨆ a ∈ ⋃ i, s i, f a = ⨆ i, ⨆ a ∈ s i, f a

Next tactic:
rw [iSup_comm]
theorem iSup_iUnion (s : ι → Set α) (f : α → β) : ⨆ a ∈ ⋃ i, s i, f a = ⨆ (i) (a ∈ s i), f a := by
  rw [iSup_comm]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
inst✝ : CompleteLattice β
s : ι → Set α
f : α → β
⊢ ⨆ a ∈ ⋃ i, s i, f a = ⨆ j, ⨆ i, ⨆ (_ : j ∈ s i), f j

Next tactic:
simp_rw [mem_iUnion, iSup_exists]
theorem sSup_sUnion (s : Set (Set β)) : sSup (⋃₀ s) = ⨆ t ∈ s, sSup t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
inst✝ : CompleteLattice β
s : Set (Set β)
⊢ sSup (⋃₀ s) = ⨆ t ∈ s, sSup t

Next tactic:
simp only [sUnion_eq_biUnion, sSup_eq_iSup, iSup_iUnion]
lemma iSup_sUnion (S : Set (Set α)) (f : α → β) :
    (⨆ x ∈ ⋃₀ S, f x) = ⨆ (s ∈ S) (x ∈ s), f x := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
inst✝ : CompleteLattice β
S : Set (Set α)
f : α → β
⊢ ⨆ x ∈ ⋃₀ S, f x = ⨆ s ∈ S, ⨆ x ∈ s, f x

Next tactic:
rw [sUnion_eq_iUnion, iSup_iUnion, ← iSup_subtype'']
lemma iInf_sUnion (S : Set (Set α)) (f : α → β) :
    (⨅ x ∈ ⋃₀ S, f x) = ⨅ (s ∈ S) (x ∈ s), f x := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
inst✝ : CompleteLattice β
S : Set (Set α)
f : α → β
⊢ ⨅ x ∈ ⋃₀ S, f x = ⨅ s ∈ S, ⨅ x ∈ s, f x

Next tactic:
rw [sUnion_eq_iUnion, iInf_iUnion, ← iInf_subtype'']
lemma forall_sUnion {p : α → Prop} :
    (∀ x ∈ ⋃₀ S, p x) ↔ ∀ s ∈ S, ∀ x ∈ s, p x := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
inst✝ : CompleteLattice β
S : Set (Set α)
p : α → Prop
⊢ (∀ x ∈ ⋃₀ S, p x) ↔ ∀ s ∈ S, ∀ x ∈ s, p x

Next tactic:
simp_rw [← iInf_Prop_eq, iInf_sUnion]
lemma exists_sUnion {p : α → Prop} :
    (∃ x ∈ ⋃₀ S, p x) ↔ ∃ s ∈ S, ∃ x ∈ s, p x := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Sort u_4
ι' : Sort u_5
ι₂ : Sort u_6
κ : ι → Sort u_7
κ₁ : ι → Sort u_8
κ₂ : ι → Sort u_9
κ' : ι' → Sort u_10
inst✝ : CompleteLattice β
S : Set (Set α)
p : α → Prop
⊢ (∃ x ∈ ⋃₀ S, p x) ↔ ∃ s ∈ S, ∃ x ∈ s, p x

Next tactic:
simp_rw [← exists_prop, ← iSup_Prop_eq, iSup_sUnion]
/-- Rotating triangles gives an endofunctor on the category of triangles in `C`.
-/
@[simps]
def rotate : Triangle C ⥤ Triangle C
    where
  obj := Triangle.rotate
  map f :=
  { hom₁ := f.hom₂
    hom₂ := f.hom₃
    hom₃ := f.hom₁⟦1⟧'
    comm₃ := by
      

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
inst✝ : HasShift C ℤ
X : C
X✝ Y✝ : Triangle C
f : X✝ ⟶ Y✝
⊢ (Triangle.rotate X✝).mor₃ ≫ (shiftFunctor C 1).map f.hom₂ = (shiftFunctor C 1).map f.hom₁ ≫ (Triangle.rotate Y✝).mor₃

Next tactic:
dsimp
/-- Rotating triangles gives an endofunctor on the category of triangles in `C`.
-/
@[simps]
def rotate : Triangle C ⥤ Triangle C
    where
  obj := Triangle.rotate
  map f :=
  { hom₁ := f.hom₂
    hom₂ := f.hom₃
    hom₃ := f.hom₁⟦1⟧'
    comm₃ := by
      dsimp
      

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
inst✝ : HasShift C ℤ
X : C
X✝ Y✝ : Triangle C
f : X✝ ⟶ Y✝
⊢ (-(shiftFunctor C 1).map X✝.mor₁) ≫ (shiftFunctor C 1).map f.hom₂ =
    (shiftFunctor C 1).map f.hom₁ ≫ (-(shiftFunctor C 1).map Y✝.mor₁)

Next tactic:
simp only [comp_neg, neg_comp, ← Functor.map_comp, f.comm₁]
/-- The inverse rotation of triangles gives an endofunctor on the category of triangles in `C`.
-/
@[simps]
def invRotate : Triangle C ⥤ Triangle C
    where
  obj := Triangle.invRotate
  map f :=
  { hom₁ := f.hom₃⟦-1⟧'
    hom₂ := f.hom₁
    hom₃ := f.hom₂
    comm₁ := by
      

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
inst✝ : HasShift C ℤ
X : C
X✝ Y✝ : Triangle C
f : X✝ ⟶ Y✝
⊢ (Triangle.invRotate X✝).mor₁ ≫ f.hom₁ = (shiftFunctor C (-1)).map f.hom₃ ≫ (Triangle.invRotate Y✝).mor₁

Next tactic:
dsimp
/-- The inverse rotation of triangles gives an endofunctor on the category of triangles in `C`.
-/
@[simps]
def invRotate : Triangle C ⥤ Triangle C
    where
  obj := Triangle.invRotate
  map f :=
  { hom₁ := f.hom₃⟦-1⟧'
    hom₂ := f.hom₁
    hom₃ := f.hom₂
    comm₁ := by
      dsimp
      

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
inst✝ : HasShift C ℤ
X : C
X✝ Y✝ : Triangle C
f : X✝ ⟶ Y✝
⊢ (-(shiftFunctor C (-1)).map X✝.mor₃ ≫ (shiftFunctorCompIsoId C 1 (-1) (_ : 1 + -1 = 0)).hom.app X✝.obj₁) ≫ f.hom₁ =
    (shiftFunctor C (-1)).map f.hom₃ ≫
      (-(shiftFunctor C (-1)).map Y✝.mor₃ ≫ (shiftFunctorCompIsoId C 1 (-1) (_ : 1 + -1 = 0)).hom.app Y✝.obj₁)

Next tactic:
simp only [neg_comp, assoc, comp_neg, neg_inj, ← Functor.map_comp_assoc, ← f.comm₃]
/-- The inverse rotation of triangles gives an endofunctor on the category of triangles in `C`.
-/
@[simps]
def invRotate : Triangle C ⥤ Triangle C
    where
  obj := Triangle.invRotate
  map f :=
  { hom₁ := f.hom₃⟦-1⟧'
    hom₂ := f.hom₁
    hom₃ := f.hom₂
    comm₁ := by
      dsimp
      simp only [neg_comp, assoc, comp_neg, neg_inj, ← Functor.map_comp_assoc, ← f.comm₃]
      

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
inst✝ : HasShift C ℤ
X : C
X✝ Y✝ : Triangle C
f : X✝ ⟶ Y✝
⊢ (shiftFunctor C (-1)).map X✝.mor₃ ≫ (shiftFunctorCompIsoId C 1 (-1) (_ : 1 + -1 = 0)).hom.app X✝.obj₁ ≫ f.hom₁ =
    (shiftFunctor C (-1)).map (X✝.mor₃ ≫ (shiftFunctor C 1).map f.hom₁) ≫
      (shiftFunctorCompIsoId C 1 (-1) (_ : 1 + -1 = 0)).hom.app Y✝.obj₁

Next tactic:
rw [Functor.map_comp, assoc]
/-- The inverse rotation of triangles gives an endofunctor on the category of triangles in `C`.
-/
@[simps]
def invRotate : Triangle C ⥤ Triangle C
    where
  obj := Triangle.invRotate
  map f :=
  { hom₁ := f.hom₃⟦-1⟧'
    hom₂ := f.hom₁
    hom₃ := f.hom₂
    comm₁ := by
      dsimp
      simp only [neg_comp, assoc, comp_neg, neg_inj, ← Functor.map_comp_assoc, ← f.comm₃]
      rw [Functor.map_comp, assoc]
      

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
inst✝ : HasShift C ℤ
X : C
X✝ Y✝ : Triangle C
f : X✝ ⟶ Y✝
⊢ (shiftFunctor C (-1)).map X✝.mor₃ ≫ (shiftFunctorCompIsoId C 1 (-1) (_ : 1 + -1 = 0)).hom.app X✝.obj₁ ≫ f.hom₁ =
    (shiftFunctor C (-1)).map X✝.mor₃ ≫
      (shiftFunctor C (-1)).map ((shiftFunctor C 1).map f.hom₁) ≫
        (shiftFunctorCompIsoId C 1 (-1) (_ : 1 + -1 = 0)).hom.app Y✝.obj₁

Next tactic:
erw [← NatTrans.naturality]
/-- The inverse rotation of triangles gives an endofunctor on the category of triangles in `C`.
-/
@[simps]
def invRotate : Triangle C ⥤ Triangle C
    where
  obj := Triangle.invRotate
  map f :=
  { hom₁ := f.hom₃⟦-1⟧'
    hom₂ := f.hom₁
    hom₃ := f.hom₂
    comm₁ := by
      dsimp
      simp only [neg_comp, assoc, comp_neg, neg_inj, ← Functor.map_comp_assoc, ← f.comm₃]
      rw [Functor.map_comp, assoc]
      erw [← NatTrans.naturality]
      

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
inst✝ : HasShift C ℤ
X : C
X✝ Y✝ : Triangle C
f : X✝ ⟶ Y✝
⊢ (shiftFunctor C (-1)).map X✝.mor₃ ≫
      (shiftFunctor C 1 ⋙ shiftFunctor C (-1)).map f.1 ≫
        (shiftFunctorCompIsoId C 1 (-1) (_ : 1 + -1 = 0)).hom.app Y✝.obj₁ =
    (shiftFunctor C (-1)).map X✝.mor₃ ≫
      (shiftFunctor C (-1)).map ((shiftFunctor C 1).map f.hom₁) ≫
        (shiftFunctorCompIsoId C 1 (-1) (_ : 1 + -1 = 0)).hom.app Y✝.obj₁

Next tactic:
rfl
/-- The inverse rotation of triangles gives an endofunctor on the category of triangles in `C`.
-/
@[simps]
def invRotate : Triangle C ⥤ Triangle C
    where
  obj := Triangle.invRotate
  map f :=
  { hom₁ := f.hom₃⟦-1⟧'
    hom₂ := f.hom₁
    hom₃ := f.hom₂
    comm₁ := by
      dsimp
      simp only [neg_comp, assoc, comp_neg, neg_inj, ← Functor.map_comp_assoc, ← f.comm₃]
      rw [Functor.map_comp, assoc]
      erw [← NatTrans.naturality]
      rfl
    comm₃ := by
      

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
inst✝ : HasShift C ℤ
X : C
X✝ Y✝ : Triangle C
f : X✝ ⟶ Y✝
⊢ (Triangle.invRotate X✝).mor₃ ≫ (shiftFunctor C 1).map ((shiftFunctor C (-1)).map f.hom₃) =
    f.hom₂ ≫ (Triangle.invRotate Y✝).mor₃

Next tactic:
erw [← reassoc_of% f.comm₂, Category.assoc, ← NatTrans.naturality]
/-- The inverse rotation of triangles gives an endofunctor on the category of triangles in `C`.
-/
@[simps]
def invRotate : Triangle C ⥤ Triangle C
    where
  obj := Triangle.invRotate
  map f :=
  { hom₁ := f.hom₃⟦-1⟧'
    hom₂ := f.hom₁
    hom₃ := f.hom₂
    comm₁ := by
      dsimp
      simp only [neg_comp, assoc, comp_neg, neg_inj, ← Functor.map_comp_assoc, ← f.comm₃]
      rw [Functor.map_comp, assoc]
      erw [← NatTrans.naturality]
      rfl
    comm₃ := by
      erw [← reassoc_of% f.comm₂, Category.assoc, ← NatTrans.naturality]
      

Proof state:
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : Preadditive C
inst✝ : HasShift C ℤ
X : C
X✝ Y✝ : Triangle C
f : X✝ ⟶ Y✝
⊢ X✝.mor₂ ≫ (𝟭 C).map f.hom₃ ≫ (shiftEquiv C 1).counitIso.inv.app Y✝.obj₃ =
    X✝.mor₂ ≫ f.hom₃ ≫ (shiftEquiv C 1).counitIso.inv.app Y✝.3

Next tactic:
rfl
instance : IsEquivalence (rotate C) := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
inst✝¹ : HasShift C ℤ
X : C
inst✝ : ∀ (n : ℤ), Functor.Additive (shiftFunctor C n)
⊢ IsEquivalence (rotate C)

Next tactic:
change IsEquivalence (triangleRotation C).functor
instance : IsEquivalence (rotate C) := by
  change IsEquivalence (triangleRotation C).functor
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
inst✝¹ : HasShift C ℤ
X : C
inst✝ : ∀ (n : ℤ), Functor.Additive (shiftFunctor C n)
⊢ IsEquivalence (triangleRotation C).functor

Next tactic:
infer_instance
instance : IsEquivalence (invRotate C) := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
inst✝¹ : HasShift C ℤ
X : C
inst✝ : ∀ (n : ℤ), Functor.Additive (shiftFunctor C n)
⊢ IsEquivalence (invRotate C)

Next tactic:
change IsEquivalence (triangleRotation C).inverse
instance : IsEquivalence (invRotate C) := by
  change IsEquivalence (triangleRotation C).inverse
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
inst✝² : Preadditive C
inst✝¹ : HasShift C ℤ
X : C
inst✝ : ∀ (n : ℤ), Functor.Additive (shiftFunctor C n)
⊢ IsEquivalence (triangleRotation C).inverse

Next tactic:
infer_instance
@[to_additive]
private lemma devosMulRel_iff :
    DevosMulRel x y ↔
      (x.1 * x.2).card < (y.1 * y.2).card ∨
        (x.1 * x.2).card = (y.1 * y.2).card ∧ y.1.card + y.2.card < x.1.card + x.2.card ∨
          (x.1 * x.2).card = (y.1 * y.2).card ∧
            x.1.card + x.2.card = y.1.card + y.2.card ∧ x.1.card < y.1.card := by
  

Proof state:
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
x y : Finset α × Finset α
s t : Finset α
⊢ DevosMulRel x y ↔
    card (x.1 * x.2) < card (y.1 * y.2) ∨
      card (x.1 * x.2) = card (y.1 * y.2) ∧ card y.1 + card y.2 < card x.1 + card x.2 ∨
        card (x.1 * x.2) = card (y.1 * y.2) ∧ card x.1 + card x.2 = card y.1 + card y.2 ∧ card x.1 < card y.1

Next tactic:
simp [DevosMulRel, Prod.lex_iff, and_or_left]
@[to_additive]
private lemma wellFoundedOn_devosMulRel :
    {x : Finset α × Finset α | x.1.Nonempty ∧ x.2.Nonempty}.WellFoundedOn
      (DevosMulRel : Finset α × Finset α → Finset α × Finset α → Prop) := by
  

Proof state:
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
x y : Finset α × Finset α
s t : Finset α
⊢ Set.WellFoundedOn {x | Finset.Nonempty x.1 ∧ Finset.Nonempty x.2} DevosMulRel

Next tactic:
refine wellFounded_lt.onFun.wellFoundedOn.prod_lex_of_wellFoundedOn_fiber fun n ↦
    Set.WellFoundedOn.prod_lex_of_wellFoundedOn_fiber ?_ fun n ↦
      wellFounded_lt.onFun.wellFoundedOn
@[to_additive]
private lemma wellFoundedOn_devosMulRel :
    {x : Finset α × Finset α | x.1.Nonempty ∧ x.2.Nonempty}.WellFoundedOn
      (DevosMulRel : Finset α × Finset α → Finset α × Finset α → Prop) := by
  refine wellFounded_lt.onFun.wellFoundedOn.prod_lex_of_wellFoundedOn_fiber fun n ↦
    Set.WellFoundedOn.prod_lex_of_wellFoundedOn_fiber ?_ fun n ↦
      wellFounded_lt.onFun.wellFoundedOn
  

Proof state:
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
x y : Finset α × Finset α
s t : Finset α
n : ℕ
⊢ Set.WellFoundedOn ({x | Finset.Nonempty x.1 ∧ Finset.Nonempty x.2} ∩ (fun x => card (x.1 * x.2)) ⁻¹' {n})
    ((fun x x_1 => x > x_1) on fun x => card x.1 + card x.2)

Next tactic:
exact wellFounded_lt.onFun.wellFoundedOn.mono' fun x hx y _ ↦ tsub_lt_tsub_left_of_le <|
    add_le_add ((card_le_card_mul_right _ hx.1.2).trans_eq hx.2) <|
      (card_le_card_mul_left _ hx.1.1).trans_eq hx.2
/-- A generalisation of the **Cauchy-Davenport theorem** to arbitrary groups. The size of `s * t` is
lower-bounded by `|s| + |t| - 1` unless this quantity is greater than the size of the smallest
subgroup. -/
@[to_additive "A generalisation of the **Cauchy-Davenport theorem** to arbitrary groups. The size of
`s + t` is lower-bounded by `|s| + |t| - 1` unless this quantity is greater than the size of the
smallest subgroup."]
lemma Finset.min_le_card_mul (hs : s.Nonempty) (ht : t.Nonempty) :
    min (minOrder α) ↑(s.card + t.card - 1) ≤ (s * t).card := by
  -- Set up the induction on `x := (s, t)` along the `DevosMulRel` relation.
  

Proof state:
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
x y : Finset α × Finset α
s t : Finset α
hs : Finset.Nonempty s
ht : Finset.Nonempty t
⊢ min (minOrder α) ↑(card s + card t - 1) ≤ ↑(card (s * t))

Next tactic:
set x := (s, t) with hx
/-- A generalisation of the **Cauchy-Davenport theorem** to arbitrary groups. The size of `s * t` is
lower-bounded by `|s| + |t| - 1` unless this quantity is greater than the size of the smallest
subgroup. -/
@[to_additive "A generalisation of the **Cauchy-Davenport theorem** to arbitrary groups. The size of
`s + t` is lower-bounded by `|s| + |t| - 1` unless this quantity is greater than the size of the
smallest subgroup."]
lemma Finset.min_le_card_mul (hs : s.Nonempty) (ht : t.Nonempty) :
    min (minOrder α) ↑(s.card + t.card - 1) ≤ (s * t).card := by
  -- Set up the induction on `x := (s, t)` along the `DevosMulRel` relation.
  set x := (s, t) with hx
  

Proof state:
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
x✝ y : Finset α × Finset α
s t : Finset α
hs : Finset.Nonempty s
ht : Finset.Nonempty t
x : Finset α × Finset α := (s, t)
hx : x = (s, t)
⊢ min (minOrder α) ↑(card s + card t - 1) ≤ ↑(card (s * t))

Next tactic:
clear_value x
/-- A generalisation of the **Cauchy-Davenport theorem** to arbitrary groups. The size of `s * t` is
lower-bounded by `|s| + |t| - 1` unless this quantity is greater than the size of the smallest
subgroup. -/
@[to_additive "A generalisation of the **Cauchy-Davenport theorem** to arbitrary groups. The size of
`s + t` is lower-bounded by `|s| + |t| - 1` unless this quantity is greater than the size of the
smallest subgroup."]
lemma Finset.min_le_card_mul (hs : s.Nonempty) (ht : t.Nonempty) :
    min (minOrder α) ↑(s.card + t.card - 1) ≤ (s * t).card := by
  -- Set up the induction on `x := (s, t)` along the `DevosMulRel` relation.
  set x := (s, t) with hx
  clear_value x
  

Proof state:
α : Type u_1
inst✝¹ : Group α
inst✝ : DecidableEq α
x✝ y : Finset α × Finset α
s t : Finset α
hs : Finset.Nonempty s
ht : Finset.Nonempty t
x : Finset α × Finset α
hx : x = (s, t)
⊢ min (minOrder α) ↑(card s + card t - 1) ≤ ↑(card (s * t))

Next tactic:
simp only [Prod.ext_iff] at hx