l3lab/ntp-mathlib huggingface dataset:
set_option linter.deprecated false in
theorem support_formPerm_of_nodup' (l : List α) (h : Nodup l) (h' : ∀ x : α, l ≠ [x]) :
    { x | formPerm l x ≠ x } = l.toFinset := by
  apply _root_.le_antisymm
  · exact support_formPerm_le' l
  · intro x hx
    simp only [Finset.mem_coe, mem_toFinset] at hx
    obtain ⟨n, hn, rfl⟩ := nthLe_of_mem hx
    rw [Set.mem_setOf_eq, formPerm_apply_nthLe _ h]
    intro H
    rw [nodup_iff_nthLe_inj] at h
    specialize h _ _ _ _ H
    rcases (Nat.succ_le_of_lt hn).eq_or_lt with hn' | hn'
    · simp only [← hn', Nat.mod_self] at h
      refine' not_exists.mpr h' _
      rw [← length_eq_one]
      

Proof state:
case a.intro.intro.inl
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h' : ∀ (x : α), l ≠ [x]
n : ℕ
hn : n < length l
hx : nthLe l n hn ∈ l
H : nthLe l ((n + 1) % length l) (_ : (n + 1) % length l < length l) = nthLe l n hn
hn' : Nat.succ n = length l
h : 0 = n
⊢ length l = 1

Next tactic:
simpa [← h, eq_comm] using hn'
set_option linter.deprecated false in
theorem support_formPerm_of_nodup' (l : List α) (h : Nodup l) (h' : ∀ x : α, l ≠ [x]) :
    { x | formPerm l x ≠ x } = l.toFinset := by
  apply _root_.le_antisymm
  · exact support_formPerm_le' l
  · intro x hx
    simp only [Finset.mem_coe, mem_toFinset] at hx
    obtain ⟨n, hn, rfl⟩ := nthLe_of_mem hx
    rw [Set.mem_setOf_eq, formPerm_apply_nthLe _ h]
    intro H
    rw [nodup_iff_nthLe_inj] at h
    specialize h _ _ _ _ H
    rcases (Nat.succ_le_of_lt hn).eq_or_lt with hn' | hn'
    · simp only [← hn', Nat.mod_self] at h
      refine' not_exists.mpr h' _
      rw [← length_eq_one]
      simpa [← h, eq_comm] using hn'
    · 

Proof state:
case a.intro.intro.inr
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h' : ∀ (x : α), l ≠ [x]
n : ℕ
hn : n < length l
hx : nthLe l n hn ∈ l
H : nthLe l ((n + 1) % length l) (_ : (n + 1) % length l < length l) = nthLe l n hn
h : (n + 1) % length l = n
hn' : Nat.succ n < length l
⊢ False

Next tactic:
simp [Nat.mod_eq_of_lt hn'] at h
theorem support_formPerm_of_nodup [Fintype α] (l : List α) (h : Nodup l) (h' : ∀ x : α, l ≠ [x]) :
    support (formPerm l) = l.toFinset := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : DecidableEq α
l✝ : List α
x : α
inst✝ : Fintype α
l : List α
h : Nodup l
h' : ∀ (x : α), l ≠ [x]
⊢ support (formPerm l) = toFinset l

Next tactic:
rw [← Finset.coe_inj]
theorem support_formPerm_of_nodup [Fintype α] (l : List α) (h : Nodup l) (h' : ∀ x : α, l ≠ [x]) :
    support (formPerm l) = l.toFinset := by
  rw [← Finset.coe_inj]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : DecidableEq α
l✝ : List α
x : α
inst✝ : Fintype α
l : List α
h : Nodup l
h' : ∀ (x : α), l ≠ [x]
⊢ ↑(support (formPerm l)) = ↑(toFinset l)

Next tactic:
convert support_formPerm_of_nodup' _ h h'
theorem support_formPerm_of_nodup [Fintype α] (l : List α) (h : Nodup l) (h' : ∀ x : α, l ≠ [x]) :
    support (formPerm l) = l.toFinset := by
  rw [← Finset.coe_inj]
  convert support_formPerm_of_nodup' _ h h'
  

Proof state:
case h.e'_2
α : Type u_1
β : Type u_2
inst✝¹ : DecidableEq α
l✝ : List α
x : α
inst✝ : Fintype α
l : List α
h : Nodup l
h' : ∀ (x : α), l ≠ [x]
⊢ ↑(support (formPerm l)) = {x | (formPerm l) x ≠ x}

Next tactic:
simp [Set.ext_iff]
set_option linter.deprecated false in
theorem formPerm_rotate_one (l : List α) (h : Nodup l) : formPerm (l.rotate 1) = formPerm l := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
⊢ formPerm (rotate l 1) = formPerm l

Next tactic:
have h' : Nodup (l.rotate 1) := by simpa using h
set_option linter.deprecated false in
theorem formPerm_rotate_one (l : List α) (h : Nodup l) : formPerm (l.rotate 1) = formPerm l := by
  have h' : Nodup (l.rotate 1) := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
⊢ Nodup (rotate l 1)

Next tactic:
simpa using h
set_option linter.deprecated false in
theorem formPerm_rotate_one (l : List α) (h : Nodup l) : formPerm (l.rotate 1) = formPerm l := by
  have h' : Nodup (l.rotate 1) := by simpa using h
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
h' : Nodup (rotate l 1)
⊢ formPerm (rotate l 1) = formPerm l

Next tactic:
ext x
set_option linter.deprecated false in
theorem formPerm_rotate_one (l : List α) (h : Nodup l) : formPerm (l.rotate 1) = formPerm l := by
  have h' : Nodup (l.rotate 1) := by simpa using h
  ext x
  

Proof state:
case H
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ : α
l : List α
h : Nodup l
h' : Nodup (rotate l 1)
x : α
⊢ (formPerm (rotate l 1)) x = (formPerm l) x

Next tactic:
by_cases hx : x ∈ l.rotate 1
set_option linter.deprecated false in
theorem formPerm_rotate_one (l : List α) (h : Nodup l) : formPerm (l.rotate 1) = formPerm l := by
  have h' : Nodup (l.rotate 1) := by simpa using h
  ext x
  by_cases hx : x ∈ l.rotate 1
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ : α
l : List α
h : Nodup l
h' : Nodup (rotate l 1)
x : α
hx : x ∈ rotate l 1
⊢ (formPerm (rotate l 1)) x = (formPerm l) x

Next tactic:
obtain ⟨k, hk, rfl⟩ := nthLe_of_mem hx
set_option linter.deprecated false in
theorem formPerm_rotate_one (l : List α) (h : Nodup l) : formPerm (l.rotate 1) = formPerm l := by
  have h' : Nodup (l.rotate 1) := by simpa using h
  ext x
  by_cases hx : x ∈ l.rotate 1
  · obtain ⟨k, hk, rfl⟩ := nthLe_of_mem hx
    

Proof state:
case pos.intro.intro
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
h' : Nodup (rotate l 1)
k : ℕ
hk : k < length (rotate l 1)
hx : nthLe (rotate l 1) k hk ∈ rotate l 1
⊢ (formPerm (rotate l 1)) (nthLe (rotate l 1) k hk) = (formPerm l) (nthLe (rotate l 1) k hk)

Next tactic:
rw [formPerm_apply_nthLe _ h', nthLe_rotate l, nthLe_rotate l, formPerm_apply_nthLe _ h]
set_option linter.deprecated false in
theorem formPerm_rotate_one (l : List α) (h : Nodup l) : formPerm (l.rotate 1) = formPerm l := by
  have h' : Nodup (l.rotate 1) := by simpa using h
  ext x
  by_cases hx : x ∈ l.rotate 1
  · obtain ⟨k, hk, rfl⟩ := nthLe_of_mem hx
    rw [formPerm_apply_nthLe _ h', nthLe_rotate l, nthLe_rotate l, formPerm_apply_nthLe _ h]
    

Proof state:
case pos.intro.intro
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
h' : Nodup (rotate l 1)
k : ℕ
hk : k < length (rotate l 1)
hx : nthLe (rotate l 1) k hk ∈ rotate l 1
⊢ nthLe l (((k + 1) % length (rotate l 1) + 1) % length l)
      (_ : ((k + 1) % length (rotate l 1) + 1) % length l < length l) =
    nthLe l (((k + 1) % length l + 1) % length l) (_ : ((k + 1) % length l + 1) % length l < length l)

Next tactic:
simp
set_option linter.deprecated false in
theorem formPerm_rotate_one (l : List α) (h : Nodup l) : formPerm (l.rotate 1) = formPerm l := by
  have h' : Nodup (l.rotate 1) := by simpa using h
  ext x
  by_cases hx : x ∈ l.rotate 1
  · obtain ⟨k, hk, rfl⟩ := nthLe_of_mem hx
    rw [formPerm_apply_nthLe _ h', nthLe_rotate l, nthLe_rotate l, formPerm_apply_nthLe _ h]
    simp
  · 

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ : α
l : List α
h : Nodup l
h' : Nodup (rotate l 1)
x : α
hx : x ∉ rotate l 1
⊢ (formPerm (rotate l 1)) x = (formPerm l) x

Next tactic:
rw [formPerm_apply_of_not_mem _ _ hx, formPerm_apply_of_not_mem]
set_option linter.deprecated false in
theorem formPerm_rotate_one (l : List α) (h : Nodup l) : formPerm (l.rotate 1) = formPerm l := by
  have h' : Nodup (l.rotate 1) := by simpa using h
  ext x
  by_cases hx : x ∈ l.rotate 1
  · obtain ⟨k, hk, rfl⟩ := nthLe_of_mem hx
    rw [formPerm_apply_nthLe _ h', nthLe_rotate l, nthLe_rotate l, formPerm_apply_nthLe _ h]
    simp
  · rw [formPerm_apply_of_not_mem _ _ hx, formPerm_apply_of_not_mem]
    

Proof state:
case neg.h
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ : α
l : List α
h : Nodup l
h' : Nodup (rotate l 1)
x : α
hx : x ∉ rotate l 1
⊢ x ∉ l

Next tactic:
simpa using hx
theorem formPerm_rotate (l : List α) (h : Nodup l) (n : ℕ) :
    formPerm (l.rotate n) = formPerm l := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
n : ℕ
⊢ formPerm (rotate l n) = formPerm l

Next tactic:
induction' n with n hn
theorem formPerm_rotate (l : List α) (h : Nodup l) (n : ℕ) :
    formPerm (l.rotate n) = formPerm l := by
  induction' n with n hn
  · 

Proof state:
case zero
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
⊢ formPerm (rotate l Nat.zero) = formPerm l

Next tactic:
simp
theorem formPerm_rotate (l : List α) (h : Nodup l) (n : ℕ) :
    formPerm (l.rotate n) = formPerm l := by
  induction' n with n hn
  · simp
  · 

Proof state:
case succ
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
n : ℕ
hn : formPerm (rotate l n) = formPerm l
⊢ formPerm (rotate l (Nat.succ n)) = formPerm l

Next tactic:
rw [Nat.succ_eq_add_one, ← rotate_rotate, formPerm_rotate_one, hn]
theorem formPerm_rotate (l : List α) (h : Nodup l) (n : ℕ) :
    formPerm (l.rotate n) = formPerm l := by
  induction' n with n hn
  · simp
  · rw [Nat.succ_eq_add_one, ← rotate_rotate, formPerm_rotate_one, hn]
    

Proof state:
case succ.h
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
n : ℕ
hn : formPerm (rotate l n) = formPerm l
⊢ Nodup (rotate l n)

Next tactic:
rwa [IsRotated.nodup_iff]
theorem formPerm_rotate (l : List α) (h : Nodup l) (n : ℕ) :
    formPerm (l.rotate n) = formPerm l := by
  induction' n with n hn
  · simp
  · rw [Nat.succ_eq_add_one, ← rotate_rotate, formPerm_rotate_one, hn]
    rwa [IsRotated.nodup_iff]
    

Proof state:
case succ.h
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
n : ℕ
hn : formPerm (rotate l n) = formPerm l
⊢ rotate l n ~r l

Next tactic:
exact IsRotated.forall l n
theorem formPerm_eq_of_isRotated {l l' : List α} (hd : Nodup l) (h : l ~r l') :
    formPerm l = formPerm l' := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l l' : List α
hd : Nodup l
h : l ~r l'
⊢ formPerm l = formPerm l'

Next tactic:
obtain ⟨n, rfl⟩ := h
theorem formPerm_eq_of_isRotated {l l' : List α} (hd : Nodup l) (h : l ~r l') :
    formPerm l = formPerm l' := by
  obtain ⟨n, rfl⟩ := h
  

Proof state:
case intro
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
hd : Nodup l
n : ℕ
⊢ formPerm l = formPerm (rotate l n)

Next tactic:
exact (formPerm_rotate l hd n).symm
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
⊢ formPerm (reverse l) = (formPerm l)⁻¹

Next tactic:
rw [eq_comm, inv_eq_iff_mul_eq_one]
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  rw [eq_comm, inv_eq_iff_mul_eq_one]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
⊢ formPerm l * formPerm (reverse l) = 1

Next tactic:
ext x
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  rw [eq_comm, inv_eq_iff_mul_eq_one]
  ext x
  -- We only have to check for `x ∈ l` that `formPerm l (formPerm l.reverse x)`
  

Proof state:
case H
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ : α
l : List α
h : Nodup l
x : α
⊢ (formPerm l * formPerm (reverse l)) x = 1 x

Next tactic:
rw [mul_apply, one_apply]
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  rw [eq_comm, inv_eq_iff_mul_eq_one]
  ext x
  -- We only have to check for `x ∈ l` that `formPerm l (formPerm l.reverse x)`
  rw [mul_apply, one_apply]
  

Proof state:
case H
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ : α
l : List α
h : Nodup l
x : α
⊢ (formPerm l) ((formPerm (reverse l)) x) = x

Next tactic:
cases' Classical.em (x ∈ l) with hx hx
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  rw [eq_comm, inv_eq_iff_mul_eq_one]
  ext x
  -- We only have to check for `x ∈ l` that `formPerm l (formPerm l.reverse x)`
  rw [mul_apply, one_apply]
  cases' Classical.em (x ∈ l) with hx hx
  · 

Proof state:
case H.inl
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ : α
l : List α
h : Nodup l
x : α
hx : x ∈ l
⊢ (formPerm l) ((formPerm (reverse l)) x) = x

Next tactic:
obtain ⟨k, hk, rfl⟩ := nthLe_of_mem (mem_reverse.mpr hx)
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  rw [eq_comm, inv_eq_iff_mul_eq_one]
  ext x
  -- We only have to check for `x ∈ l` that `formPerm l (formPerm l.reverse x)`
  rw [mul_apply, one_apply]
  cases' Classical.em (x ∈ l) with hx hx
  · obtain ⟨k, hk, rfl⟩ := nthLe_of_mem (mem_reverse.mpr hx)
    

Proof state:
case H.inl.intro.intro
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
k : ℕ
hk : k < length (reverse l)
hx : nthLe (reverse l) k hk ∈ l
⊢ (formPerm l) ((formPerm (reverse l)) (nthLe (reverse l) k hk)) = nthLe (reverse l) k hk

Next tactic:
have h1 : l.length - 1 - k < l.length := by
      rw [Nat.sub_sub, add_comm]
      exact Nat.sub_lt_self (Nat.succ_pos _) (Nat.succ_le_of_lt (by simpa using hk))
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  rw [eq_comm, inv_eq_iff_mul_eq_one]
  ext x
  -- We only have to check for `x ∈ l` that `formPerm l (formPerm l.reverse x)`
  rw [mul_apply, one_apply]
  cases' Classical.em (x ∈ l) with hx hx
  · obtain ⟨k, hk, rfl⟩ := nthLe_of_mem (mem_reverse.mpr hx)
    have h1 : l.length - 1 - k < l.length := by
      

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
k : ℕ
hk : k < length (reverse l)
hx : nthLe (reverse l) k hk ∈ l
⊢ length l - 1 - k < length l

Next tactic:
rw [Nat.sub_sub, add_comm]
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  rw [eq_comm, inv_eq_iff_mul_eq_one]
  ext x
  -- We only have to check for `x ∈ l` that `formPerm l (formPerm l.reverse x)`
  rw [mul_apply, one_apply]
  cases' Classical.em (x ∈ l) with hx hx
  · obtain ⟨k, hk, rfl⟩ := nthLe_of_mem (mem_reverse.mpr hx)
    have h1 : l.length - 1 - k < l.length := by
      rw [Nat.sub_sub, add_comm]
      

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
k : ℕ
hk : k < length (reverse l)
hx : nthLe (reverse l) k hk ∈ l
⊢ length l - (k + 1) < length l

Next tactic:
exact Nat.sub_lt_self (Nat.succ_pos _) (Nat.succ_le_of_lt (by simpa using hk))
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  rw [eq_comm, inv_eq_iff_mul_eq_one]
  ext x
  -- We only have to check for `x ∈ l` that `formPerm l (formPerm l.reverse x)`
  rw [mul_apply, one_apply]
  cases' Classical.em (x ∈ l) with hx hx
  · obtain ⟨k, hk, rfl⟩ := nthLe_of_mem (mem_reverse.mpr hx)
    have h1 : l.length - 1 - k < l.length := by
      rw [Nat.sub_sub, add_comm]
      exact Nat.sub_lt_self (Nat.succ_pos _) (Nat.succ_le_of_lt (by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
k : ℕ
hk : k < length (reverse l)
hx : nthLe (reverse l) k hk ∈ l
⊢ k < length l

Next tactic:
simpa using hk
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  rw [eq_comm, inv_eq_iff_mul_eq_one]
  ext x
  -- We only have to check for `x ∈ l` that `formPerm l (formPerm l.reverse x)`
  rw [mul_apply, one_apply]
  cases' Classical.em (x ∈ l) with hx hx
  · obtain ⟨k, hk, rfl⟩ := nthLe_of_mem (mem_reverse.mpr hx)
    have h1 : l.length - 1 - k < l.length := by
      rw [Nat.sub_sub, add_comm]
      exact Nat.sub_lt_self (Nat.succ_pos _) (Nat.succ_le_of_lt (by simpa using hk))
    

Proof state:
case H.inl.intro.intro
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
k : ℕ
hk : k < length (reverse l)
hx : nthLe (reverse l) k hk ∈ l
h1 : length l - 1 - k < length l
⊢ (formPerm l) ((formPerm (reverse l)) (nthLe (reverse l) k hk)) = nthLe (reverse l) k hk

Next tactic:
have h2 : length l - 1 - (k + 1) % length (reverse l) < length l := by
      rw [Nat.sub_sub, length_reverse];
      exact Nat.sub_lt_self (by rw [add_comm]; exact Nat.succ_pos _)
        (by rw [add_comm]; exact Nat.succ_le_of_lt (Nat.mod_lt _ (length_pos_of_mem hx)))
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  rw [eq_comm, inv_eq_iff_mul_eq_one]
  ext x
  -- We only have to check for `x ∈ l` that `formPerm l (formPerm l.reverse x)`
  rw [mul_apply, one_apply]
  cases' Classical.em (x ∈ l) with hx hx
  · obtain ⟨k, hk, rfl⟩ := nthLe_of_mem (mem_reverse.mpr hx)
    have h1 : l.length - 1 - k < l.length := by
      rw [Nat.sub_sub, add_comm]
      exact Nat.sub_lt_self (Nat.succ_pos _) (Nat.succ_le_of_lt (by simpa using hk))
    have h2 : length l - 1 - (k + 1) % length (reverse l) < length l := by
      

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
k : ℕ
hk : k < length (reverse l)
hx : nthLe (reverse l) k hk ∈ l
h1 : length l - 1 - k < length l
⊢ length l - 1 - (k + 1) % length (reverse l) < length l

Next tactic:
rw [Nat.sub_sub, length_reverse]
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  rw [eq_comm, inv_eq_iff_mul_eq_one]
  ext x
  -- We only have to check for `x ∈ l` that `formPerm l (formPerm l.reverse x)`
  rw [mul_apply, one_apply]
  cases' Classical.em (x ∈ l) with hx hx
  · obtain ⟨k, hk, rfl⟩ := nthLe_of_mem (mem_reverse.mpr hx)
    have h1 : l.length - 1 - k < l.length := by
      rw [Nat.sub_sub, add_comm]
      exact Nat.sub_lt_self (Nat.succ_pos _) (Nat.succ_le_of_lt (by simpa using hk))
    have h2 : length l - 1 - (k + 1) % length (reverse l) < length l := by
      rw [Nat.sub_sub, length_reverse];
      

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
k : ℕ
hk : k < length (reverse l)
hx : nthLe (reverse l) k hk ∈ l
h1 : length l - 1 - k < length l
⊢ length l - (1 + (k + 1) % length l) < length l

Next tactic:
exact Nat.sub_lt_self (by rw [add_comm]; exact Nat.succ_pos _)
        (by rw [add_comm]; exact Nat.succ_le_of_lt (Nat.mod_lt _ (length_pos_of_mem hx)))
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  rw [eq_comm, inv_eq_iff_mul_eq_one]
  ext x
  -- We only have to check for `x ∈ l` that `formPerm l (formPerm l.reverse x)`
  rw [mul_apply, one_apply]
  cases' Classical.em (x ∈ l) with hx hx
  · obtain ⟨k, hk, rfl⟩ := nthLe_of_mem (mem_reverse.mpr hx)
    have h1 : l.length - 1 - k < l.length := by
      rw [Nat.sub_sub, add_comm]
      exact Nat.sub_lt_self (Nat.succ_pos _) (Nat.succ_le_of_lt (by simpa using hk))
    have h2 : length l - 1 - (k + 1) % length (reverse l) < length l := by
      rw [Nat.sub_sub, length_reverse];
      exact Nat.sub_lt_self (by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
k : ℕ
hk : k < length (reverse l)
hx : nthLe (reverse l) k hk ∈ l
h1 : length l - 1 - k < length l
⊢ 0 < 1 + (k + 1) % length l

Next tactic:
rw [add_comm]
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  rw [eq_comm, inv_eq_iff_mul_eq_one]
  ext x
  -- We only have to check for `x ∈ l` that `formPerm l (formPerm l.reverse x)`
  rw [mul_apply, one_apply]
  cases' Classical.em (x ∈ l) with hx hx
  · obtain ⟨k, hk, rfl⟩ := nthLe_of_mem (mem_reverse.mpr hx)
    have h1 : l.length - 1 - k < l.length := by
      rw [Nat.sub_sub, add_comm]
      exact Nat.sub_lt_self (Nat.succ_pos _) (Nat.succ_le_of_lt (by simpa using hk))
    have h2 : length l - 1 - (k + 1) % length (reverse l) < length l := by
      rw [Nat.sub_sub, length_reverse];
      exact Nat.sub_lt_self (by rw [add_comm]; 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
k : ℕ
hk : k < length (reverse l)
hx : nthLe (reverse l) k hk ∈ l
h1 : length l - 1 - k < length l
⊢ 0 < (k + 1) % length l + 1

Next tactic:
exact Nat.succ_pos _
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  rw [eq_comm, inv_eq_iff_mul_eq_one]
  ext x
  -- We only have to check for `x ∈ l` that `formPerm l (formPerm l.reverse x)`
  rw [mul_apply, one_apply]
  cases' Classical.em (x ∈ l) with hx hx
  · obtain ⟨k, hk, rfl⟩ := nthLe_of_mem (mem_reverse.mpr hx)
    have h1 : l.length - 1 - k < l.length := by
      rw [Nat.sub_sub, add_comm]
      exact Nat.sub_lt_self (Nat.succ_pos _) (Nat.succ_le_of_lt (by simpa using hk))
    have h2 : length l - 1 - (k + 1) % length (reverse l) < length l := by
      rw [Nat.sub_sub, length_reverse];
      exact Nat.sub_lt_self (by rw [add_comm]; exact Nat.succ_pos _)
        (by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
k : ℕ
hk : k < length (reverse l)
hx : nthLe (reverse l) k hk ∈ l
h1 : length l - 1 - k < length l
⊢ 1 + (k + 1) % length l ≤ length l

Next tactic:
rw [add_comm]
set_option linter.deprecated false in
theorem formPerm_reverse (l : List α) (h : Nodup l) : formPerm l.reverse = (formPerm l)⁻¹ := by
  -- Let's show `formPerm l` is an inverse to `formPerm l.reverse`.
  rw [eq_comm, inv_eq_iff_mul_eq_one]
  ext x
  -- We only have to check for `x ∈ l` that `formPerm l (formPerm l.reverse x)`
  rw [mul_apply, one_apply]
  cases' Classical.em (x ∈ l) with hx hx
  · obtain ⟨k, hk, rfl⟩ := nthLe_of_mem (mem_reverse.mpr hx)
    have h1 : l.length - 1 - k < l.length := by
      rw [Nat.sub_sub, add_comm]
      exact Nat.sub_lt_self (Nat.succ_pos _) (Nat.succ_le_of_lt (by simpa using hk))
    have h2 : length l - 1 - (k + 1) % length (reverse l) < length l := by
      rw [Nat.sub_sub, length_reverse];
      exact Nat.sub_lt_self (by rw [add_comm]; exact Nat.succ_pos _)
        (by rw [add_comm]; 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x : α
l : List α
h : Nodup l
k : ℕ
hk : k < length (reverse l)
hx : nthLe (reverse l) k hk ∈ l
h1 : length l - 1 - k < length l
⊢ (k + 1) % length l + 1 ≤ length l

Next tactic:
exact Nat.succ_le_of_lt (Nat.mod_lt _ (length_pos_of_mem hx))