l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem inv_iff {f : Perm α} : IsThreeCycle f⁻¹ ↔ IsThreeCycle f :=
  ⟨by
    rw [← inv_inv f]
    

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ f : Perm α
⊢ IsThreeCycle f⁻¹⁻¹⁻¹ → IsThreeCycle f⁻¹⁻¹

Next tactic:
apply inv
theorem orderOf {g : Perm α} (ht : IsThreeCycle g) : orderOf g = 3 := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ g : Perm α
ht : IsThreeCycle g
⊢ _root_.orderOf g = 3

Next tactic:
rw [← lcm_cycleType, ht.cycleType, Multiset.lcm_singleton, normalize_eq]
theorem isThreeCycle_sq {g : Perm α} (ht : IsThreeCycle g) : IsThreeCycle (g * g) := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ g : Perm α
ht : IsThreeCycle g
⊢ IsThreeCycle (g * g)

Next tactic:
rw [← pow_two, ← card_support_eq_three_iff, support_pow_coprime, ht.card_support]
theorem isThreeCycle_sq {g : Perm α} (ht : IsThreeCycle g) : IsThreeCycle (g * g) := by
  rw [← pow_two, ← card_support_eq_three_iff, support_pow_coprime, ht.card_support]
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ g : Perm α
ht : IsThreeCycle g
⊢ Nat.Coprime 2 (_root_.orderOf g)

Next tactic:
rw [ht.orderOf]
theorem isThreeCycle_sq {g : Perm α} (ht : IsThreeCycle g) : IsThreeCycle (g * g) := by
  rw [← pow_two, ← card_support_eq_three_iff, support_pow_coprime, ht.card_support]
  rw [ht.orderOf]
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ g : Perm α
ht : IsThreeCycle g
⊢ Nat.Coprime 2 3

Next tactic:
norm_num
theorem isThreeCycle_swap_mul_swap_same {a b c : α} (ab : a ≠ b) (ac : a ≠ c) (bc : b ≠ c) :
    IsThreeCycle (swap a b * swap a c) := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b c : α
ab : a ≠ b
ac : a ≠ c
bc : b ≠ c
⊢ IsThreeCycle (swap a b * swap a c)

Next tactic:
suffices h : support (swap a b * swap a c) = {a, b, c}
theorem isThreeCycle_swap_mul_swap_same {a b c : α} (ab : a ≠ b) (ac : a ≠ c) (bc : b ≠ c) :
    IsThreeCycle (swap a b * swap a c) := by
  suffices h : support (swap a b * swap a c) = {a, b, c}
  · 

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b c : α
ab : a ≠ b
ac : a ≠ c
bc : b ≠ c
h : support (swap a b * swap a c) = {a, b, c}
⊢ IsThreeCycle (swap a b * swap a c)

Next tactic:
rw [← card_support_eq_three_iff, h]
theorem isThreeCycle_swap_mul_swap_same {a b c : α} (ab : a ≠ b) (ac : a ≠ c) (bc : b ≠ c) :
    IsThreeCycle (swap a b * swap a c) := by
  suffices h : support (swap a b * swap a c) = {a, b, c}
  · rw [← card_support_eq_three_iff, h]
    

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b c : α
ab : a ≠ b
ac : a ≠ c
bc : b ≠ c
h : support (swap a b * swap a c) = {a, b, c}
⊢ Finset.card {a, b, c} = 3

Next tactic:
simp [ab, ac, bc]
theorem isThreeCycle_swap_mul_swap_same {a b c : α} (ab : a ≠ b) (ac : a ≠ c) (bc : b ≠ c) :
    IsThreeCycle (swap a b * swap a c) := by
  suffices h : support (swap a b * swap a c) = {a, b, c}
  · rw [← card_support_eq_three_iff, h]
    simp [ab, ac, bc]
  

Proof state:
case h
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b c : α
ab : a ≠ b
ac : a ≠ c
bc : b ≠ c
⊢ support (swap a b * swap a c) = {a, b, c}

Next tactic:
apply le_antisymm ((support_mul_le _ _).trans fun x => _) fun x hx => ?_
theorem isThreeCycle_swap_mul_swap_same {a b c : α} (ab : a ≠ b) (ac : a ≠ c) (bc : b ≠ c) :
    IsThreeCycle (swap a b * swap a c) := by
  suffices h : support (swap a b * swap a c) = {a, b, c}
  · rw [← card_support_eq_three_iff, h]
    simp [ab, ac, bc]
  apply le_antisymm ((support_mul_le _ _).trans fun x => _) fun x hx => ?_
  · 

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b c : α
ab : a ≠ b
ac : a ≠ c
bc : b ≠ c
⊢ ∀ x ∈ support (swap a b) ⊔ support (swap a c), x ∈ {a, b, c}

Next tactic:
simp [ab, ac, bc]
theorem isThreeCycle_swap_mul_swap_same {a b c : α} (ab : a ≠ b) (ac : a ≠ c) (bc : b ≠ c) :
    IsThreeCycle (swap a b * swap a c) := by
  suffices h : support (swap a b * swap a c) = {a, b, c}
  · rw [← card_support_eq_three_iff, h]
    simp [ab, ac, bc]
  apply le_antisymm ((support_mul_le _ _).trans fun x => _) fun x hx => ?_
  · simp [ab, ac, bc]
  · 

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b c : α
ab : a ≠ b
ac : a ≠ c
bc : b ≠ c
x : α
hx : x ∈ {a, b, c}
⊢ x ∈ support (swap a b * swap a c)

Next tactic:
simp only [Finset.mem_insert, Finset.mem_singleton] at hx
theorem isThreeCycle_swap_mul_swap_same {a b c : α} (ab : a ≠ b) (ac : a ≠ c) (bc : b ≠ c) :
    IsThreeCycle (swap a b * swap a c) := by
  suffices h : support (swap a b * swap a c) = {a, b, c}
  · rw [← card_support_eq_three_iff, h]
    simp [ab, ac, bc]
  apply le_antisymm ((support_mul_le _ _).trans fun x => _) fun x hx => ?_
  · simp [ab, ac, bc]
  · simp only [Finset.mem_insert, Finset.mem_singleton] at hx
    

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b c : α
ab : a ≠ b
ac : a ≠ c
bc : b ≠ c
x : α
hx : x = a ∨ x = b ∨ x = c
⊢ x ∈ support (swap a b * swap a c)

Next tactic:
rw [mem_support]
theorem isThreeCycle_swap_mul_swap_same {a b c : α} (ab : a ≠ b) (ac : a ≠ c) (bc : b ≠ c) :
    IsThreeCycle (swap a b * swap a c) := by
  suffices h : support (swap a b * swap a c) = {a, b, c}
  · rw [← card_support_eq_three_iff, h]
    simp [ab, ac, bc]
  apply le_antisymm ((support_mul_le _ _).trans fun x => _) fun x hx => ?_
  · simp [ab, ac, bc]
  · simp only [Finset.mem_insert, Finset.mem_singleton] at hx
    rw [mem_support]
    

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b c : α
ab : a ≠ b
ac : a ≠ c
bc : b ≠ c
x : α
hx : x = a ∨ x = b ∨ x = c
⊢ (swap a b * swap a c) x ≠ x

Next tactic:
simp only [Perm.coe_mul, Function.comp_apply, Ne.def]
theorem isThreeCycle_swap_mul_swap_same {a b c : α} (ab : a ≠ b) (ac : a ≠ c) (bc : b ≠ c) :
    IsThreeCycle (swap a b * swap a c) := by
  suffices h : support (swap a b * swap a c) = {a, b, c}
  · rw [← card_support_eq_three_iff, h]
    simp [ab, ac, bc]
  apply le_antisymm ((support_mul_le _ _).trans fun x => _) fun x hx => ?_
  · simp [ab, ac, bc]
  · simp only [Finset.mem_insert, Finset.mem_singleton] at hx
    rw [mem_support]
    simp only [Perm.coe_mul, Function.comp_apply, Ne.def]
    

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b c : α
ab : a ≠ b
ac : a ≠ c
bc : b ≠ c
x : α
hx : x = a ∨ x = b ∨ x = c
⊢ ¬(swap a b) ((swap a c) x) = x

Next tactic:
obtain rfl | rfl | rfl := hx
theorem isThreeCycle_swap_mul_swap_same {a b c : α} (ab : a ≠ b) (ac : a ≠ c) (bc : b ≠ c) :
    IsThreeCycle (swap a b * swap a c) := by
  suffices h : support (swap a b * swap a c) = {a, b, c}
  · rw [← card_support_eq_three_iff, h]
    simp [ab, ac, bc]
  apply le_antisymm ((support_mul_le _ _).trans fun x => _) fun x hx => ?_
  · simp [ab, ac, bc]
  · simp only [Finset.mem_insert, Finset.mem_singleton] at hx
    rw [mem_support]
    simp only [Perm.coe_mul, Function.comp_apply, Ne.def]
    obtain rfl | rfl | rfl := hx
    · 

Proof state:
case inl
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
b c : α
bc : b ≠ c
x : α
ab : x ≠ b
ac : x ≠ c
⊢ ¬(swap x b) ((swap x c) x) = x

Next tactic:
rw [swap_apply_left, swap_apply_of_ne_of_ne ac.symm bc.symm]
theorem isThreeCycle_swap_mul_swap_same {a b c : α} (ab : a ≠ b) (ac : a ≠ c) (bc : b ≠ c) :
    IsThreeCycle (swap a b * swap a c) := by
  suffices h : support (swap a b * swap a c) = {a, b, c}
  · rw [← card_support_eq_three_iff, h]
    simp [ab, ac, bc]
  apply le_antisymm ((support_mul_le _ _).trans fun x => _) fun x hx => ?_
  · simp [ab, ac, bc]
  · simp only [Finset.mem_insert, Finset.mem_singleton] at hx
    rw [mem_support]
    simp only [Perm.coe_mul, Function.comp_apply, Ne.def]
    obtain rfl | rfl | rfl := hx
    · rw [swap_apply_left, swap_apply_of_ne_of_ne ac.symm bc.symm]
      

Proof state:
case inl
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
b c : α
bc : b ≠ c
x : α
ab : x ≠ b
ac : x ≠ c
⊢ ¬c = x

Next tactic:
exact ac.symm
theorem isThreeCycle_swap_mul_swap_same {a b c : α} (ab : a ≠ b) (ac : a ≠ c) (bc : b ≠ c) :
    IsThreeCycle (swap a b * swap a c) := by
  suffices h : support (swap a b * swap a c) = {a, b, c}
  · rw [← card_support_eq_three_iff, h]
    simp [ab, ac, bc]
  apply le_antisymm ((support_mul_le _ _).trans fun x => _) fun x hx => ?_
  · simp [ab, ac, bc]
  · simp only [Finset.mem_insert, Finset.mem_singleton] at hx
    rw [mem_support]
    simp only [Perm.coe_mul, Function.comp_apply, Ne.def]
    obtain rfl | rfl | rfl := hx
    · rw [swap_apply_left, swap_apply_of_ne_of_ne ac.symm bc.symm]
      exact ac.symm
    · 

Proof state:
case inr.inl
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a c : α
ac : a ≠ c
x : α
ab : a ≠ x
bc : x ≠ c
⊢ ¬(swap a x) ((swap a c) x) = x

Next tactic:
rw [swap_apply_of_ne_of_ne ab.symm bc, swap_apply_right]
theorem isThreeCycle_swap_mul_swap_same {a b c : α} (ab : a ≠ b) (ac : a ≠ c) (bc : b ≠ c) :
    IsThreeCycle (swap a b * swap a c) := by
  suffices h : support (swap a b * swap a c) = {a, b, c}
  · rw [← card_support_eq_three_iff, h]
    simp [ab, ac, bc]
  apply le_antisymm ((support_mul_le _ _).trans fun x => _) fun x hx => ?_
  · simp [ab, ac, bc]
  · simp only [Finset.mem_insert, Finset.mem_singleton] at hx
    rw [mem_support]
    simp only [Perm.coe_mul, Function.comp_apply, Ne.def]
    obtain rfl | rfl | rfl := hx
    · rw [swap_apply_left, swap_apply_of_ne_of_ne ac.symm bc.symm]
      exact ac.symm
    · rw [swap_apply_of_ne_of_ne ab.symm bc, swap_apply_right]
      

Proof state:
case inr.inl
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a c : α
ac : a ≠ c
x : α
ab : a ≠ x
bc : x ≠ c
⊢ ¬a = x

Next tactic:
exact ab
theorem isThreeCycle_swap_mul_swap_same {a b c : α} (ab : a ≠ b) (ac : a ≠ c) (bc : b ≠ c) :
    IsThreeCycle (swap a b * swap a c) := by
  suffices h : support (swap a b * swap a c) = {a, b, c}
  · rw [← card_support_eq_three_iff, h]
    simp [ab, ac, bc]
  apply le_antisymm ((support_mul_le _ _).trans fun x => _) fun x hx => ?_
  · simp [ab, ac, bc]
  · simp only [Finset.mem_insert, Finset.mem_singleton] at hx
    rw [mem_support]
    simp only [Perm.coe_mul, Function.comp_apply, Ne.def]
    obtain rfl | rfl | rfl := hx
    · rw [swap_apply_left, swap_apply_of_ne_of_ne ac.symm bc.symm]
      exact ac.symm
    · rw [swap_apply_of_ne_of_ne ab.symm bc, swap_apply_right]
      exact ab
    · 

Proof state:
case inr.inr
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b : α
ab : a ≠ b
x : α
ac : a ≠ x
bc : b ≠ x
⊢ ¬(swap a b) ((swap a x) x) = x

Next tactic:
rw [swap_apply_right, swap_apply_left]
theorem isThreeCycle_swap_mul_swap_same {a b c : α} (ab : a ≠ b) (ac : a ≠ c) (bc : b ≠ c) :
    IsThreeCycle (swap a b * swap a c) := by
  suffices h : support (swap a b * swap a c) = {a, b, c}
  · rw [← card_support_eq_three_iff, h]
    simp [ab, ac, bc]
  apply le_antisymm ((support_mul_le _ _).trans fun x => _) fun x hx => ?_
  · simp [ab, ac, bc]
  · simp only [Finset.mem_insert, Finset.mem_singleton] at hx
    rw [mem_support]
    simp only [Perm.coe_mul, Function.comp_apply, Ne.def]
    obtain rfl | rfl | rfl := hx
    · rw [swap_apply_left, swap_apply_of_ne_of_ne ac.symm bc.symm]
      exact ac.symm
    · rw [swap_apply_of_ne_of_ne ab.symm bc, swap_apply_right]
      exact ab
    · rw [swap_apply_right, swap_apply_left]
      

Proof state:
case inr.inr
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b : α
ab : a ≠ b
x : α
ac : a ≠ x
bc : b ≠ x
⊢ ¬b = x

Next tactic:
exact bc
theorem swap_mul_swap_same_mem_closure_three_cycles {a b c : α} (ab : a ≠ b) (ac : a ≠ c) :
    swap a b * swap a c ∈ closure { σ : Perm α | IsThreeCycle σ } := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b c : α
ab : a ≠ b
ac : a ≠ c
⊢ swap a b * swap a c ∈ closure {σ | IsThreeCycle σ}

Next tactic:
by_cases bc : b = c
theorem swap_mul_swap_same_mem_closure_three_cycles {a b c : α} (ab : a ≠ b) (ac : a ≠ c) :
    swap a b * swap a c ∈ closure { σ : Perm α | IsThreeCycle σ } := by
  by_cases bc : b = c
  · 

Proof state:
case pos
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b c : α
ab : a ≠ b
ac : a ≠ c
bc : b = c
⊢ swap a b * swap a c ∈ closure {σ | IsThreeCycle σ}

Next tactic:
subst bc
theorem swap_mul_swap_same_mem_closure_three_cycles {a b c : α} (ab : a ≠ b) (ac : a ≠ c) :
    swap a b * swap a c ∈ closure { σ : Perm α | IsThreeCycle σ } := by
  by_cases bc : b = c
  · subst bc
    

Proof state:
case pos
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b : α
ab ac : a ≠ b
⊢ swap a b * swap a b ∈ closure {σ | IsThreeCycle σ}

Next tactic:
simp [one_mem]
theorem swap_mul_swap_same_mem_closure_three_cycles {a b c : α} (ab : a ≠ b) (ac : a ≠ c) :
    swap a b * swap a c ∈ closure { σ : Perm α | IsThreeCycle σ } := by
  by_cases bc : b = c
  · subst bc
    simp [one_mem]
  

Proof state:
case neg
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b c : α
ab : a ≠ b
ac : a ≠ c
bc : ¬b = c
⊢ swap a b * swap a c ∈ closure {σ | IsThreeCycle σ}

Next tactic:
exact subset_closure (isThreeCycle_swap_mul_swap_same ab ac bc)
theorem IsSwap.mul_mem_closure_three_cycles {σ τ : Perm α} (hσ : IsSwap σ) (hτ : IsSwap τ) :
    σ * τ ∈ closure { σ : Perm α | IsThreeCycle σ } := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
σ τ : Perm α
hσ : IsSwap σ
hτ : IsSwap τ
⊢ σ * τ ∈ closure {σ | IsThreeCycle σ}

Next tactic:
obtain ⟨a, b, ab, rfl⟩ := hσ
theorem IsSwap.mul_mem_closure_three_cycles {σ τ : Perm α} (hσ : IsSwap σ) (hτ : IsSwap τ) :
    σ * τ ∈ closure { σ : Perm α | IsThreeCycle σ } := by
  obtain ⟨a, b, ab, rfl⟩ := hσ
  

Proof state:
case intro.intro.intro
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
τ : Perm α
hτ : IsSwap τ
a b : α
ab : a ≠ b
⊢ swap a b * τ ∈ closure {σ | IsThreeCycle σ}

Next tactic:
obtain ⟨c, d, cd, rfl⟩ := hτ
theorem IsSwap.mul_mem_closure_three_cycles {σ τ : Perm α} (hσ : IsSwap σ) (hτ : IsSwap τ) :
    σ * τ ∈ closure { σ : Perm α | IsThreeCycle σ } := by
  obtain ⟨a, b, ab, rfl⟩ := hσ
  obtain ⟨c, d, cd, rfl⟩ := hτ
  

Proof state:
case intro.intro.intro.intro.intro.intro
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b : α
ab : a ≠ b
c d : α
cd : c ≠ d
⊢ swap a b * swap c d ∈ closure {σ | IsThreeCycle σ}

Next tactic:
by_cases ac : a = c
theorem IsSwap.mul_mem_closure_three_cycles {σ τ : Perm α} (hσ : IsSwap σ) (hτ : IsSwap τ) :
    σ * τ ∈ closure { σ : Perm α | IsThreeCycle σ } := by
  obtain ⟨a, b, ab, rfl⟩ := hσ
  obtain ⟨c, d, cd, rfl⟩ := hτ
  by_cases ac : a = c
  · 

Proof state:
case pos
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b : α
ab : a ≠ b
c d : α
cd : c ≠ d
ac : a = c
⊢ swap a b * swap c d ∈ closure {σ | IsThreeCycle σ}

Next tactic:
subst ac
theorem IsSwap.mul_mem_closure_three_cycles {σ τ : Perm α} (hσ : IsSwap σ) (hτ : IsSwap τ) :
    σ * τ ∈ closure { σ : Perm α | IsThreeCycle σ } := by
  obtain ⟨a, b, ab, rfl⟩ := hσ
  obtain ⟨c, d, cd, rfl⟩ := hτ
  by_cases ac : a = c
  · subst ac
    

Proof state:
case pos
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b : α
ab : a ≠ b
d : α
cd : a ≠ d
⊢ swap a b * swap a d ∈ closure {σ | IsThreeCycle σ}

Next tactic:
exact swap_mul_swap_same_mem_closure_three_cycles ab cd
theorem IsSwap.mul_mem_closure_three_cycles {σ τ : Perm α} (hσ : IsSwap σ) (hτ : IsSwap τ) :
    σ * τ ∈ closure { σ : Perm α | IsThreeCycle σ } := by
  obtain ⟨a, b, ab, rfl⟩ := hσ
  obtain ⟨c, d, cd, rfl⟩ := hτ
  by_cases ac : a = c
  · subst ac
    exact swap_mul_swap_same_mem_closure_three_cycles ab cd
  

Proof state:
case neg
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b : α
ab : a ≠ b
c d : α
cd : c ≠ d
ac : ¬a = c
⊢ swap a b * swap c d ∈ closure {σ | IsThreeCycle σ}

Next tactic:
have h' : swap a b * swap c d = swap a b * swap a c * (swap c a * swap c d) := by
    simp [swap_comm c a, mul_assoc]
theorem IsSwap.mul_mem_closure_three_cycles {σ τ : Perm α} (hσ : IsSwap σ) (hτ : IsSwap τ) :
    σ * τ ∈ closure { σ : Perm α | IsThreeCycle σ } := by
  obtain ⟨a, b, ab, rfl⟩ := hσ
  obtain ⟨c, d, cd, rfl⟩ := hτ
  by_cases ac : a = c
  · subst ac
    exact swap_mul_swap_same_mem_closure_three_cycles ab cd
  have h' : swap a b * swap c d = swap a b * swap a c * (swap c a * swap c d) := by
    

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b : α
ab : a ≠ b
c d : α
cd : c ≠ d
ac : ¬a = c
⊢ swap a b * swap c d = swap a b * swap a c * (swap c a * swap c d)

Next tactic:
simp [swap_comm c a, mul_assoc]
theorem IsSwap.mul_mem_closure_three_cycles {σ τ : Perm α} (hσ : IsSwap σ) (hτ : IsSwap τ) :
    σ * τ ∈ closure { σ : Perm α | IsThreeCycle σ } := by
  obtain ⟨a, b, ab, rfl⟩ := hσ
  obtain ⟨c, d, cd, rfl⟩ := hτ
  by_cases ac : a = c
  · subst ac
    exact swap_mul_swap_same_mem_closure_three_cycles ab cd
  have h' : swap a b * swap c d = swap a b * swap a c * (swap c a * swap c d) := by
    simp [swap_comm c a, mul_assoc]
  

Proof state:
case neg
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b : α
ab : a ≠ b
c d : α
cd : c ≠ d
ac : ¬a = c
h' : swap a b * swap c d = swap a b * swap a c * (swap c a * swap c d)
⊢ swap a b * swap c d ∈ closure {σ | IsThreeCycle σ}

Next tactic:
rw [h']
theorem IsSwap.mul_mem_closure_three_cycles {σ τ : Perm α} (hσ : IsSwap σ) (hτ : IsSwap τ) :
    σ * τ ∈ closure { σ : Perm α | IsThreeCycle σ } := by
  obtain ⟨a, b, ab, rfl⟩ := hσ
  obtain ⟨c, d, cd, rfl⟩ := hτ
  by_cases ac : a = c
  · subst ac
    exact swap_mul_swap_same_mem_closure_three_cycles ab cd
  have h' : swap a b * swap c d = swap a b * swap a c * (swap c a * swap c d) := by
    simp [swap_comm c a, mul_assoc]
  rw [h']
  

Proof state:
case neg
α : Type u_1
inst✝¹ : Fintype α
inst✝ : DecidableEq α
a b : α
ab : a ≠ b
c d : α
cd : c ≠ d
ac : ¬a = c
h' : swap a b * swap c d = swap a b * swap a c * (swap c a * swap c d)
⊢ swap a b * swap a c * (swap c a * swap c d) ∈ closure {σ | IsThreeCycle σ}

Next tactic:
exact
    mul_mem (swap_mul_swap_same_mem_closure_three_cycles ab ac)
      (swap_mul_swap_same_mem_closure_three_cycles (Ne.symm ac) cd)
/-- The order on `DFinsupp`s over a partial order embeds into the order on functions -/
def orderEmbeddingToFun : (Π₀ i, α i) ↪o ∀ i, α i where
  toFun := FunLike.coe
  inj' := FunLike.coe_injective
  map_rel_iff' := by 

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝¹ : (i : ι) → Zero (α i)
inst✝ : (i : ι) → LE (α i)
f g : Π₀ (i : ι), α i
⊢ ∀ {a b : Π₀ (i : ι), α i},
    { toFun := FunLike.coe, inj' := (_ : Function.Injective fun f => ⇑f) } a ≤
        { toFun := FunLike.coe, inj' := (_ : Function.Injective fun f => ⇑f) } b ↔
      a ≤ b

Next tactic:
rfl
theorem support_inf_union_support_sup : (f ⊓ g).support ∪ (f ⊔ g).support = f.support ∪ g.support :=
  coe_injective $ compl_injective $ by 

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝³ : (i : ι) → Zero (α i)
inst✝² : (i : ι) → Lattice (α i)
f g : Π₀ (i : ι), α i
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → (x : α i) → Decidable (x ≠ 0)
⊢ (↑(support (f ⊓ g) ∪ support (f ⊔ g)))ᶜ = (↑(support f ∪ support g))ᶜ

Next tactic:
ext
theorem support_inf_union_support_sup : (f ⊓ g).support ∪ (f ⊔ g).support = f.support ∪ g.support :=
  coe_injective $ compl_injective $ by ext; 

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
inst✝³ : (i : ι) → Zero (α i)
inst✝² : (i : ι) → Lattice (α i)
f g : Π₀ (i : ι), α i
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → (x : α i) → Decidable (x ≠ 0)
x✝ : ι
⊢ x✝ ∈ (↑(support (f ⊓ g) ∪ support (f ⊔ g)))ᶜ ↔ x✝ ∈ (↑(support f ∪ support g))ᶜ

Next tactic:
simp [inf_eq_and_sup_eq_iff]
instance : OrderBot (Π₀ i, α i) where
  bot := 0
  bot_le := by 

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → CanonicallyOrderedAddCommMonoid (α i)
⊢ ∀ (a : Π₀ (i : ι), α i), ⊥ ≤ a

Next tactic:
simp only [le_def, coe_zero, Pi.zero_apply, imp_true_iff, zero_le]
@[simp]
theorem add_eq_zero_iff (f g : Π₀ i, α i) : f + g = 0 ↔ f = 0 ∧ g = 0 := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝ : (i : ι) → CanonicallyOrderedAddCommMonoid (α i)
f g : Π₀ (i : ι), α i
⊢ f + g = 0 ↔ f = 0 ∧ g = 0

Next tactic:
simp [FunLike.ext_iff, forall_and]
lemma support_monotone : Monotone (support (ι := ι) (β := α)) :=
  fun f g h a ha ↦ by 

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝² : (i : ι) → CanonicallyOrderedAddCommMonoid (α i)
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → (x : α i) → Decidable (x ≠ 0)
f✝ g✝ : Π₀ (i : ι), α i
s : Finset ι
f g : Π₀ (i : ι), α i
h : f ≤ g
a : ι
ha : a ∈ support f
⊢ a ∈ support g

Next tactic:
rw [mem_support_iff, ← pos_iff_ne_zero] at ha ⊢
lemma support_monotone : Monotone (support (ι := ι) (β := α)) :=
  fun f g h a ha ↦ by rw [mem_support_iff, ← pos_iff_ne_zero] at ha ⊢; 

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝² : (i : ι) → CanonicallyOrderedAddCommMonoid (α i)
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → (x : α i) → Decidable (x ≠ 0)
f✝ g✝ : Π₀ (i : ι), α i
s : Finset ι
f g : Π₀ (i : ι), α i
h : f ≤ g
a : ι
ha : 0 < f a
⊢ 0 < g a

Next tactic:
exact ha.trans_le (h _)
@[simp]
theorem single_le_iff {i : ι} {a : α i} : single i a ≤ f ↔ a ≤ f i :=
  (le_iff' support_single_subset).trans <| by 

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝² : (i : ι) → CanonicallyOrderedAddCommMonoid (α i)
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → (x : α i) → Decidable (x ≠ 0)
f g : Π₀ (i : ι), α i
s : Finset ι
i : ι
a : α i
⊢ (∀ i_1 ∈ {i}, (single i a) i_1 ≤ f i_1) ↔ a ≤ f i

Next tactic:
simp
@[simp, norm_cast]
theorem coe_tsub (f g : Π₀ i, α i) : ⇑(f - g) = f - g := by
  

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝² : (i : ι) → CanonicallyOrderedAddCommMonoid (α i)
inst✝¹ : (i : ι) → Sub (α i)
inst✝ : ∀ (i : ι), OrderedSub (α i)
f✝ g✝ : Π₀ (i : ι), α i
i : ι
a b : α i
f g : Π₀ (i : ι), α i
⊢ ⇑(f - g) = ⇑f - ⇑g

Next tactic:
ext i
@[simp, norm_cast]
theorem coe_tsub (f g : Π₀ i, α i) : ⇑(f - g) = f - g := by
  ext i
  

Proof state:
case h
ι : Type u_1
α : ι → Type u_2
inst✝² : (i : ι) → CanonicallyOrderedAddCommMonoid (α i)
inst✝¹ : (i : ι) → Sub (α i)
inst✝ : ∀ (i : ι), OrderedSub (α i)
f✝ g✝ : Π₀ (i : ι), α i
i✝ : ι
a b : α i✝
f g : Π₀ (i : ι), α i
i : ι
⊢ (f - g) i = (⇑f - ⇑g) i

Next tactic:
exact tsub_apply f g i
instance : CanonicallyOrderedAddCommMonoid (Π₀ i, α i) :=
  { (inferInstance : OrderBot (DFinsupp α)),
    (inferInstance : OrderedAddCommMonoid (DFinsupp α)) with
    exists_add_of_le := by
      

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝² : (i : ι) → CanonicallyOrderedAddCommMonoid (α i)
inst✝¹ : (i : ι) → Sub (α i)
inst✝ : ∀ (i : ι), OrderedSub (α i)
f g : Π₀ (i : ι), α i
i : ι
a b : α i
src✝¹ : OrderBot (DFinsupp α) := inferInstance
src✝ : OrderedAddCommMonoid (DFinsupp α) := inferInstance
⊢ ∀ {a b : Π₀ (i : ι), α i}, a ≤ b → ∃ c, b = a + c

Next tactic:
intro f g h
instance : CanonicallyOrderedAddCommMonoid (Π₀ i, α i) :=
  { (inferInstance : OrderBot (DFinsupp α)),
    (inferInstance : OrderedAddCommMonoid (DFinsupp α)) with
    exists_add_of_le := by
      intro f g h
      

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝² : (i : ι) → CanonicallyOrderedAddCommMonoid (α i)
inst✝¹ : (i : ι) → Sub (α i)
inst✝ : ∀ (i : ι), OrderedSub (α i)
f✝ g✝ : Π₀ (i : ι), α i
i : ι
a b : α i
src✝¹ : OrderBot (DFinsupp α) := inferInstance
src✝ : OrderedAddCommMonoid (DFinsupp α) := inferInstance
f g : Π₀ (i : ι), α i
h : f ≤ g
⊢ ∃ c, g = f + c

Next tactic:
exists g - f
instance : CanonicallyOrderedAddCommMonoid (Π₀ i, α i) :=
  { (inferInstance : OrderBot (DFinsupp α)),
    (inferInstance : OrderedAddCommMonoid (DFinsupp α)) with
    exists_add_of_le := by
      intro f g h
      exists g - f
      

Proof state:
ι : Type u_1
α : ι → Type u_2
inst✝² : (i : ι) → CanonicallyOrderedAddCommMonoid (α i)
inst✝¹ : (i : ι) → Sub (α i)
inst✝ : ∀ (i : ι), OrderedSub (α i)
f✝ g✝ : Π₀ (i : ι), α i
i : ι
a b : α i
src✝¹ : OrderBot (DFinsupp α) := inferInstance
src✝ : OrderedAddCommMonoid (DFinsupp α) := inferInstance
f g : Π₀ (i : ι), α i
h : f ≤ g
⊢ g = f + (g - f)

Next tactic:
ext i