l3lab/ntp-mathlib huggingface dataset:
theorem nodup_permsOfList : ∀ {l : List α} (_ : l.Nodup), (permsOfList l).Nodup
  | [], _ => by simp [permsOfList]
  | a :: l, hl => by
    have hl' : l.Nodup := hl.of_cons
    have hln' : (permsOfList l).Nodup := nodup_permsOfList hl'
    have hmeml : ∀ {f : Perm α}, f ∈ permsOfList l → f a = a := fun {f} hf =>
      not_not.1 (mt (mem_of_mem_permsOfList hf _) (nodup_cons.1 hl).1)
    rw [permsOfList, List.nodup_append, List.nodup_bind, pairwise_iff_get]
    refine ⟨?_, ⟨⟨?_,?_ ⟩, ?_⟩⟩
    · exact hln'
    · exact fun _ _ => hln'.map fun _ _ => mul_left_cancel
    · intros i j hij x hx₁ hx₂
      let ⟨f, hf⟩ := List.mem_map.1 hx₁
      let ⟨g, hg⟩ := List.mem_map.1 hx₂
      have hix : x a = List.get l i := by
        

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
l : List α
hl : Nodup (a :: l)
hl' : Nodup l
hln' : Nodup (permsOfList l)
hmeml : ∀ {f : Equiv.Perm α}, f ∈ permsOfList l → f a = a
i j : Fin (length l)
hij : i < j
x : Equiv.Perm α
hx₁ : x ∈ List.map (fun f => Equiv.swap a (List.get l i) * f) (permsOfList l)
hx₂ : x ∈ List.map (fun f => Equiv.swap a (List.get l j) * f) (permsOfList l)
f : Equiv.Perm α
hf : f ∈ permsOfList l ∧ Equiv.swap a (List.get l i) * f = x
g : Equiv.Perm α
hg : g ∈ permsOfList l ∧ Equiv.swap a (List.get l j) * g = x
⊢ x a = List.get l i

Next tactic:
rw [← hf.2, mul_apply, hmeml hf.1, swap_apply_left]
theorem nodup_permsOfList : ∀ {l : List α} (_ : l.Nodup), (permsOfList l).Nodup
  | [], _ => by simp [permsOfList]
  | a :: l, hl => by
    have hl' : l.Nodup := hl.of_cons
    have hln' : (permsOfList l).Nodup := nodup_permsOfList hl'
    have hmeml : ∀ {f : Perm α}, f ∈ permsOfList l → f a = a := fun {f} hf =>
      not_not.1 (mt (mem_of_mem_permsOfList hf _) (nodup_cons.1 hl).1)
    rw [permsOfList, List.nodup_append, List.nodup_bind, pairwise_iff_get]
    refine ⟨?_, ⟨⟨?_,?_ ⟩, ?_⟩⟩
    · exact hln'
    · exact fun _ _ => hln'.map fun _ _ => mul_left_cancel
    · intros i j hij x hx₁ hx₂
      let ⟨f, hf⟩ := List.mem_map.1 hx₁
      let ⟨g, hg⟩ := List.mem_map.1 hx₂
      have hix : x a = List.get l i := by
        rw [← hf.2, mul_apply, hmeml hf.1, swap_apply_left]
      

Proof state:
case refine_3
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
l : List α
hl : Nodup (a :: l)
hl' : Nodup l
hln' : Nodup (permsOfList l)
hmeml : ∀ {f : Equiv.Perm α}, f ∈ permsOfList l → f a = a
i j : Fin (length l)
hij : i < j
x : Equiv.Perm α
hx₁ : x ∈ List.map (fun f => Equiv.swap a (List.get l i) * f) (permsOfList l)
hx₂ : x ∈ List.map (fun f => Equiv.swap a (List.get l j) * f) (permsOfList l)
f : Equiv.Perm α
hf : f ∈ permsOfList l ∧ Equiv.swap a (List.get l i) * f = x
g : Equiv.Perm α
hg : g ∈ permsOfList l ∧ Equiv.swap a (List.get l j) * g = x
hix : x a = List.get l i
⊢ False

Next tactic:
have hiy : x a = List.get l j := by
        rw [← hg.2, mul_apply, hmeml hg.1, swap_apply_left]
theorem nodup_permsOfList : ∀ {l : List α} (_ : l.Nodup), (permsOfList l).Nodup
  | [], _ => by simp [permsOfList]
  | a :: l, hl => by
    have hl' : l.Nodup := hl.of_cons
    have hln' : (permsOfList l).Nodup := nodup_permsOfList hl'
    have hmeml : ∀ {f : Perm α}, f ∈ permsOfList l → f a = a := fun {f} hf =>
      not_not.1 (mt (mem_of_mem_permsOfList hf _) (nodup_cons.1 hl).1)
    rw [permsOfList, List.nodup_append, List.nodup_bind, pairwise_iff_get]
    refine ⟨?_, ⟨⟨?_,?_ ⟩, ?_⟩⟩
    · exact hln'
    · exact fun _ _ => hln'.map fun _ _ => mul_left_cancel
    · intros i j hij x hx₁ hx₂
      let ⟨f, hf⟩ := List.mem_map.1 hx₁
      let ⟨g, hg⟩ := List.mem_map.1 hx₂
      have hix : x a = List.get l i := by
        rw [← hf.2, mul_apply, hmeml hf.1, swap_apply_left]
      have hiy : x a = List.get l j := by
        

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
l : List α
hl : Nodup (a :: l)
hl' : Nodup l
hln' : Nodup (permsOfList l)
hmeml : ∀ {f : Equiv.Perm α}, f ∈ permsOfList l → f a = a
i j : Fin (length l)
hij : i < j
x : Equiv.Perm α
hx₁ : x ∈ List.map (fun f => Equiv.swap a (List.get l i) * f) (permsOfList l)
hx₂ : x ∈ List.map (fun f => Equiv.swap a (List.get l j) * f) (permsOfList l)
f : Equiv.Perm α
hf : f ∈ permsOfList l ∧ Equiv.swap a (List.get l i) * f = x
g : Equiv.Perm α
hg : g ∈ permsOfList l ∧ Equiv.swap a (List.get l j) * g = x
hix : x a = List.get l i
⊢ x a = List.get l j

Next tactic:
rw [← hg.2, mul_apply, hmeml hg.1, swap_apply_left]
theorem nodup_permsOfList : ∀ {l : List α} (_ : l.Nodup), (permsOfList l).Nodup
  | [], _ => by simp [permsOfList]
  | a :: l, hl => by
    have hl' : l.Nodup := hl.of_cons
    have hln' : (permsOfList l).Nodup := nodup_permsOfList hl'
    have hmeml : ∀ {f : Perm α}, f ∈ permsOfList l → f a = a := fun {f} hf =>
      not_not.1 (mt (mem_of_mem_permsOfList hf _) (nodup_cons.1 hl).1)
    rw [permsOfList, List.nodup_append, List.nodup_bind, pairwise_iff_get]
    refine ⟨?_, ⟨⟨?_,?_ ⟩, ?_⟩⟩
    · exact hln'
    · exact fun _ _ => hln'.map fun _ _ => mul_left_cancel
    · intros i j hij x hx₁ hx₂
      let ⟨f, hf⟩ := List.mem_map.1 hx₁
      let ⟨g, hg⟩ := List.mem_map.1 hx₂
      have hix : x a = List.get l i := by
        rw [← hf.2, mul_apply, hmeml hf.1, swap_apply_left]
      have hiy : x a = List.get l j := by
        rw [← hg.2, mul_apply, hmeml hg.1, swap_apply_left]
      

Proof state:
case refine_3
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
l : List α
hl : Nodup (a :: l)
hl' : Nodup l
hln' : Nodup (permsOfList l)
hmeml : ∀ {f : Equiv.Perm α}, f ∈ permsOfList l → f a = a
i j : Fin (length l)
hij : i < j
x : Equiv.Perm α
hx₁ : x ∈ List.map (fun f => Equiv.swap a (List.get l i) * f) (permsOfList l)
hx₂ : x ∈ List.map (fun f => Equiv.swap a (List.get l j) * f) (permsOfList l)
f : Equiv.Perm α
hf : f ∈ permsOfList l ∧ Equiv.swap a (List.get l i) * f = x
g : Equiv.Perm α
hg : g ∈ permsOfList l ∧ Equiv.swap a (List.get l j) * g = x
hix : x a = List.get l i
hiy : x a = List.get l j
⊢ False

Next tactic:
have hieqj : i = j := nodup_iff_injective_get.1 hl' (hix.symm.trans hiy)
theorem nodup_permsOfList : ∀ {l : List α} (_ : l.Nodup), (permsOfList l).Nodup
  | [], _ => by simp [permsOfList]
  | a :: l, hl => by
    have hl' : l.Nodup := hl.of_cons
    have hln' : (permsOfList l).Nodup := nodup_permsOfList hl'
    have hmeml : ∀ {f : Perm α}, f ∈ permsOfList l → f a = a := fun {f} hf =>
      not_not.1 (mt (mem_of_mem_permsOfList hf _) (nodup_cons.1 hl).1)
    rw [permsOfList, List.nodup_append, List.nodup_bind, pairwise_iff_get]
    refine ⟨?_, ⟨⟨?_,?_ ⟩, ?_⟩⟩
    · exact hln'
    · exact fun _ _ => hln'.map fun _ _ => mul_left_cancel
    · intros i j hij x hx₁ hx₂
      let ⟨f, hf⟩ := List.mem_map.1 hx₁
      let ⟨g, hg⟩ := List.mem_map.1 hx₂
      have hix : x a = List.get l i := by
        rw [← hf.2, mul_apply, hmeml hf.1, swap_apply_left]
      have hiy : x a = List.get l j := by
        rw [← hg.2, mul_apply, hmeml hg.1, swap_apply_left]
      have hieqj : i = j := nodup_iff_injective_get.1 hl' (hix.symm.trans hiy)
      

Proof state:
case refine_3
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
l : List α
hl : Nodup (a :: l)
hl' : Nodup l
hln' : Nodup (permsOfList l)
hmeml : ∀ {f : Equiv.Perm α}, f ∈ permsOfList l → f a = a
i j : Fin (length l)
hij : i < j
x : Equiv.Perm α
hx₁ : x ∈ List.map (fun f => Equiv.swap a (List.get l i) * f) (permsOfList l)
hx₂ : x ∈ List.map (fun f => Equiv.swap a (List.get l j) * f) (permsOfList l)
f : Equiv.Perm α
hf : f ∈ permsOfList l ∧ Equiv.swap a (List.get l i) * f = x
g : Equiv.Perm α
hg : g ∈ permsOfList l ∧ Equiv.swap a (List.get l j) * g = x
hix : x a = List.get l i
hiy : x a = List.get l j
hieqj : i = j
⊢ False

Next tactic:
exact absurd hieqj (_root_.ne_of_lt hij)
theorem nodup_permsOfList : ∀ {l : List α} (_ : l.Nodup), (permsOfList l).Nodup
  | [], _ => by simp [permsOfList]
  | a :: l, hl => by
    have hl' : l.Nodup := hl.of_cons
    have hln' : (permsOfList l).Nodup := nodup_permsOfList hl'
    have hmeml : ∀ {f : Perm α}, f ∈ permsOfList l → f a = a := fun {f} hf =>
      not_not.1 (mt (mem_of_mem_permsOfList hf _) (nodup_cons.1 hl).1)
    rw [permsOfList, List.nodup_append, List.nodup_bind, pairwise_iff_get]
    refine ⟨?_, ⟨⟨?_,?_ ⟩, ?_⟩⟩
    · exact hln'
    · exact fun _ _ => hln'.map fun _ _ => mul_left_cancel
    · intros i j hij x hx₁ hx₂
      let ⟨f, hf⟩ := List.mem_map.1 hx₁
      let ⟨g, hg⟩ := List.mem_map.1 hx₂
      have hix : x a = List.get l i := by
        rw [← hf.2, mul_apply, hmeml hf.1, swap_apply_left]
      have hiy : x a = List.get l j := by
        rw [← hg.2, mul_apply, hmeml hg.1, swap_apply_left]
      have hieqj : i = j := nodup_iff_injective_get.1 hl' (hix.symm.trans hiy)
      exact absurd hieqj (_root_.ne_of_lt hij)
    · 

Proof state:
case refine_4
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
l : List α
hl : Nodup (a :: l)
hl' : Nodup l
hln' : Nodup (permsOfList l)
hmeml : ∀ {f : Equiv.Perm α}, f ∈ permsOfList l → f a = a
⊢ List.Disjoint (permsOfList l) (List.bind l fun b => List.map (fun f => Equiv.swap a b * f) (permsOfList l))

Next tactic:
intros f hf₁ hf₂
theorem nodup_permsOfList : ∀ {l : List α} (_ : l.Nodup), (permsOfList l).Nodup
  | [], _ => by simp [permsOfList]
  | a :: l, hl => by
    have hl' : l.Nodup := hl.of_cons
    have hln' : (permsOfList l).Nodup := nodup_permsOfList hl'
    have hmeml : ∀ {f : Perm α}, f ∈ permsOfList l → f a = a := fun {f} hf =>
      not_not.1 (mt (mem_of_mem_permsOfList hf _) (nodup_cons.1 hl).1)
    rw [permsOfList, List.nodup_append, List.nodup_bind, pairwise_iff_get]
    refine ⟨?_, ⟨⟨?_,?_ ⟩, ?_⟩⟩
    · exact hln'
    · exact fun _ _ => hln'.map fun _ _ => mul_left_cancel
    · intros i j hij x hx₁ hx₂
      let ⟨f, hf⟩ := List.mem_map.1 hx₁
      let ⟨g, hg⟩ := List.mem_map.1 hx₂
      have hix : x a = List.get l i := by
        rw [← hf.2, mul_apply, hmeml hf.1, swap_apply_left]
      have hiy : x a = List.get l j := by
        rw [← hg.2, mul_apply, hmeml hg.1, swap_apply_left]
      have hieqj : i = j := nodup_iff_injective_get.1 hl' (hix.symm.trans hiy)
      exact absurd hieqj (_root_.ne_of_lt hij)
    · intros f hf₁ hf₂
      

Proof state:
case refine_4
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
l : List α
hl : Nodup (a :: l)
hl' : Nodup l
hln' : Nodup (permsOfList l)
hmeml : ∀ {f : Equiv.Perm α}, f ∈ permsOfList l → f a = a
f : Equiv.Perm α
hf₁ : f ∈ permsOfList l
hf₂ : f ∈ List.bind l fun b => List.map (fun f => Equiv.swap a b * f) (permsOfList l)
⊢ False

Next tactic:
let ⟨x, hx, hx'⟩ := List.mem_bind.1 hf₂
theorem nodup_permsOfList : ∀ {l : List α} (_ : l.Nodup), (permsOfList l).Nodup
  | [], _ => by simp [permsOfList]
  | a :: l, hl => by
    have hl' : l.Nodup := hl.of_cons
    have hln' : (permsOfList l).Nodup := nodup_permsOfList hl'
    have hmeml : ∀ {f : Perm α}, f ∈ permsOfList l → f a = a := fun {f} hf =>
      not_not.1 (mt (mem_of_mem_permsOfList hf _) (nodup_cons.1 hl).1)
    rw [permsOfList, List.nodup_append, List.nodup_bind, pairwise_iff_get]
    refine ⟨?_, ⟨⟨?_,?_ ⟩, ?_⟩⟩
    · exact hln'
    · exact fun _ _ => hln'.map fun _ _ => mul_left_cancel
    · intros i j hij x hx₁ hx₂
      let ⟨f, hf⟩ := List.mem_map.1 hx₁
      let ⟨g, hg⟩ := List.mem_map.1 hx₂
      have hix : x a = List.get l i := by
        rw [← hf.2, mul_apply, hmeml hf.1, swap_apply_left]
      have hiy : x a = List.get l j := by
        rw [← hg.2, mul_apply, hmeml hg.1, swap_apply_left]
      have hieqj : i = j := nodup_iff_injective_get.1 hl' (hix.symm.trans hiy)
      exact absurd hieqj (_root_.ne_of_lt hij)
    · intros f hf₁ hf₂
      let ⟨x, hx, hx'⟩ := List.mem_bind.1 hf₂
      

Proof state:
case refine_4
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
l : List α
hl : Nodup (a :: l)
hl' : Nodup l
hln' : Nodup (permsOfList l)
hmeml : ∀ {f : Equiv.Perm α}, f ∈ permsOfList l → f a = a
f : Equiv.Perm α
hf₁ : f ∈ permsOfList l
hf₂ : f ∈ List.bind l fun b => List.map (fun f => Equiv.swap a b * f) (permsOfList l)
x : α
hx : x ∈ l
hx' : f ∈ List.map (fun f => Equiv.swap a x * f) (permsOfList l)
⊢ False

Next tactic:
let ⟨g, hg⟩ := List.mem_map.1 hx'
theorem nodup_permsOfList : ∀ {l : List α} (_ : l.Nodup), (permsOfList l).Nodup
  | [], _ => by simp [permsOfList]
  | a :: l, hl => by
    have hl' : l.Nodup := hl.of_cons
    have hln' : (permsOfList l).Nodup := nodup_permsOfList hl'
    have hmeml : ∀ {f : Perm α}, f ∈ permsOfList l → f a = a := fun {f} hf =>
      not_not.1 (mt (mem_of_mem_permsOfList hf _) (nodup_cons.1 hl).1)
    rw [permsOfList, List.nodup_append, List.nodup_bind, pairwise_iff_get]
    refine ⟨?_, ⟨⟨?_,?_ ⟩, ?_⟩⟩
    · exact hln'
    · exact fun _ _ => hln'.map fun _ _ => mul_left_cancel
    · intros i j hij x hx₁ hx₂
      let ⟨f, hf⟩ := List.mem_map.1 hx₁
      let ⟨g, hg⟩ := List.mem_map.1 hx₂
      have hix : x a = List.get l i := by
        rw [← hf.2, mul_apply, hmeml hf.1, swap_apply_left]
      have hiy : x a = List.get l j := by
        rw [← hg.2, mul_apply, hmeml hg.1, swap_apply_left]
      have hieqj : i = j := nodup_iff_injective_get.1 hl' (hix.symm.trans hiy)
      exact absurd hieqj (_root_.ne_of_lt hij)
    · intros f hf₁ hf₂
      let ⟨x, hx, hx'⟩ := List.mem_bind.1 hf₂
      let ⟨g, hg⟩ := List.mem_map.1 hx'
      

Proof state:
case refine_4
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
l : List α
hl : Nodup (a :: l)
hl' : Nodup l
hln' : Nodup (permsOfList l)
hmeml : ∀ {f : Equiv.Perm α}, f ∈ permsOfList l → f a = a
f : Equiv.Perm α
hf₁ : f ∈ permsOfList l
hf₂ : f ∈ List.bind l fun b => List.map (fun f => Equiv.swap a b * f) (permsOfList l)
x : α
hx : x ∈ l
hx' : f ∈ List.map (fun f => Equiv.swap a x * f) (permsOfList l)
g : Equiv.Perm α
hg : g ∈ permsOfList l ∧ Equiv.swap a x * g = f
⊢ False

Next tactic:
have hgxa : g⁻¹ x = a := f.injective <| by rw [hmeml hf₁, ← hg.2]; simp
theorem nodup_permsOfList : ∀ {l : List α} (_ : l.Nodup), (permsOfList l).Nodup
  | [], _ => by simp [permsOfList]
  | a :: l, hl => by
    have hl' : l.Nodup := hl.of_cons
    have hln' : (permsOfList l).Nodup := nodup_permsOfList hl'
    have hmeml : ∀ {f : Perm α}, f ∈ permsOfList l → f a = a := fun {f} hf =>
      not_not.1 (mt (mem_of_mem_permsOfList hf _) (nodup_cons.1 hl).1)
    rw [permsOfList, List.nodup_append, List.nodup_bind, pairwise_iff_get]
    refine ⟨?_, ⟨⟨?_,?_ ⟩, ?_⟩⟩
    · exact hln'
    · exact fun _ _ => hln'.map fun _ _ => mul_left_cancel
    · intros i j hij x hx₁ hx₂
      let ⟨f, hf⟩ := List.mem_map.1 hx₁
      let ⟨g, hg⟩ := List.mem_map.1 hx₂
      have hix : x a = List.get l i := by
        rw [← hf.2, mul_apply, hmeml hf.1, swap_apply_left]
      have hiy : x a = List.get l j := by
        rw [← hg.2, mul_apply, hmeml hg.1, swap_apply_left]
      have hieqj : i = j := nodup_iff_injective_get.1 hl' (hix.symm.trans hiy)
      exact absurd hieqj (_root_.ne_of_lt hij)
    · intros f hf₁ hf₂
      let ⟨x, hx, hx'⟩ := List.mem_bind.1 hf₂
      let ⟨g, hg⟩ := List.mem_map.1 hx'
      have hgxa : g⁻¹ x = a := f.injective <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
l : List α
hl : Nodup (a :: l)
hl' : Nodup l
hln' : Nodup (permsOfList l)
hmeml : ∀ {f : Equiv.Perm α}, f ∈ permsOfList l → f a = a
f : Equiv.Perm α
hf₁ : f ∈ permsOfList l
hf₂ : f ∈ List.bind l fun b => List.map (fun f => Equiv.swap a b * f) (permsOfList l)
x : α
hx : x ∈ l
hx' : f ∈ List.map (fun f => Equiv.swap a x * f) (permsOfList l)
g : Equiv.Perm α
hg : g ∈ permsOfList l ∧ Equiv.swap a x * g = f
⊢ f (g⁻¹ x) = f a

Next tactic:
rw [hmeml hf₁, ← hg.2]
theorem nodup_permsOfList : ∀ {l : List α} (_ : l.Nodup), (permsOfList l).Nodup
  | [], _ => by simp [permsOfList]
  | a :: l, hl => by
    have hl' : l.Nodup := hl.of_cons
    have hln' : (permsOfList l).Nodup := nodup_permsOfList hl'
    have hmeml : ∀ {f : Perm α}, f ∈ permsOfList l → f a = a := fun {f} hf =>
      not_not.1 (mt (mem_of_mem_permsOfList hf _) (nodup_cons.1 hl).1)
    rw [permsOfList, List.nodup_append, List.nodup_bind, pairwise_iff_get]
    refine ⟨?_, ⟨⟨?_,?_ ⟩, ?_⟩⟩
    · exact hln'
    · exact fun _ _ => hln'.map fun _ _ => mul_left_cancel
    · intros i j hij x hx₁ hx₂
      let ⟨f, hf⟩ := List.mem_map.1 hx₁
      let ⟨g, hg⟩ := List.mem_map.1 hx₂
      have hix : x a = List.get l i := by
        rw [← hf.2, mul_apply, hmeml hf.1, swap_apply_left]
      have hiy : x a = List.get l j := by
        rw [← hg.2, mul_apply, hmeml hg.1, swap_apply_left]
      have hieqj : i = j := nodup_iff_injective_get.1 hl' (hix.symm.trans hiy)
      exact absurd hieqj (_root_.ne_of_lt hij)
    · intros f hf₁ hf₂
      let ⟨x, hx, hx'⟩ := List.mem_bind.1 hf₂
      let ⟨g, hg⟩ := List.mem_map.1 hx'
      have hgxa : g⁻¹ x = a := f.injective <| by rw [hmeml hf₁, ← hg.2]; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
l : List α
hl : Nodup (a :: l)
hl' : Nodup l
hln' : Nodup (permsOfList l)
hmeml : ∀ {f : Equiv.Perm α}, f ∈ permsOfList l → f a = a
f : Equiv.Perm α
hf₁ : f ∈ permsOfList l
hf₂ : f ∈ List.bind l fun b => List.map (fun f => Equiv.swap a b * f) (permsOfList l)
x : α
hx : x ∈ l
hx' : f ∈ List.map (fun f => Equiv.swap a x * f) (permsOfList l)
g : Equiv.Perm α
hg : g ∈ permsOfList l ∧ Equiv.swap a x * g = f
⊢ (Equiv.swap a x * g) (g⁻¹ x) = a

Next tactic:
simp
theorem nodup_permsOfList : ∀ {l : List α} (_ : l.Nodup), (permsOfList l).Nodup
  | [], _ => by simp [permsOfList]
  | a :: l, hl => by
    have hl' : l.Nodup := hl.of_cons
    have hln' : (permsOfList l).Nodup := nodup_permsOfList hl'
    have hmeml : ∀ {f : Perm α}, f ∈ permsOfList l → f a = a := fun {f} hf =>
      not_not.1 (mt (mem_of_mem_permsOfList hf _) (nodup_cons.1 hl).1)
    rw [permsOfList, List.nodup_append, List.nodup_bind, pairwise_iff_get]
    refine ⟨?_, ⟨⟨?_,?_ ⟩, ?_⟩⟩
    · exact hln'
    · exact fun _ _ => hln'.map fun _ _ => mul_left_cancel
    · intros i j hij x hx₁ hx₂
      let ⟨f, hf⟩ := List.mem_map.1 hx₁
      let ⟨g, hg⟩ := List.mem_map.1 hx₂
      have hix : x a = List.get l i := by
        rw [← hf.2, mul_apply, hmeml hf.1, swap_apply_left]
      have hiy : x a = List.get l j := by
        rw [← hg.2, mul_apply, hmeml hg.1, swap_apply_left]
      have hieqj : i = j := nodup_iff_injective_get.1 hl' (hix.symm.trans hiy)
      exact absurd hieqj (_root_.ne_of_lt hij)
    · intros f hf₁ hf₂
      let ⟨x, hx, hx'⟩ := List.mem_bind.1 hf₂
      let ⟨g, hg⟩ := List.mem_map.1 hx'
      have hgxa : g⁻¹ x = a := f.injective <| by rw [hmeml hf₁, ← hg.2]; simp
      

Proof state:
case refine_4
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
l : List α
hl : Nodup (a :: l)
hl' : Nodup l
hln' : Nodup (permsOfList l)
hmeml : ∀ {f : Equiv.Perm α}, f ∈ permsOfList l → f a = a
f : Equiv.Perm α
hf₁ : f ∈ permsOfList l
hf₂ : f ∈ List.bind l fun b => List.map (fun f => Equiv.swap a b * f) (permsOfList l)
x : α
hx : x ∈ l
hx' : f ∈ List.map (fun f => Equiv.swap a x * f) (permsOfList l)
g : Equiv.Perm α
hg : g ∈ permsOfList l ∧ Equiv.swap a x * g = f
hgxa : g⁻¹ x = a
⊢ False

Next tactic:
have hxa : x ≠ a := fun h => (List.nodup_cons.1 hl).1 (h ▸ hx)
theorem nodup_permsOfList : ∀ {l : List α} (_ : l.Nodup), (permsOfList l).Nodup
  | [], _ => by simp [permsOfList]
  | a :: l, hl => by
    have hl' : l.Nodup := hl.of_cons
    have hln' : (permsOfList l).Nodup := nodup_permsOfList hl'
    have hmeml : ∀ {f : Perm α}, f ∈ permsOfList l → f a = a := fun {f} hf =>
      not_not.1 (mt (mem_of_mem_permsOfList hf _) (nodup_cons.1 hl).1)
    rw [permsOfList, List.nodup_append, List.nodup_bind, pairwise_iff_get]
    refine ⟨?_, ⟨⟨?_,?_ ⟩, ?_⟩⟩
    · exact hln'
    · exact fun _ _ => hln'.map fun _ _ => mul_left_cancel
    · intros i j hij x hx₁ hx₂
      let ⟨f, hf⟩ := List.mem_map.1 hx₁
      let ⟨g, hg⟩ := List.mem_map.1 hx₂
      have hix : x a = List.get l i := by
        rw [← hf.2, mul_apply, hmeml hf.1, swap_apply_left]
      have hiy : x a = List.get l j := by
        rw [← hg.2, mul_apply, hmeml hg.1, swap_apply_left]
      have hieqj : i = j := nodup_iff_injective_get.1 hl' (hix.symm.trans hiy)
      exact absurd hieqj (_root_.ne_of_lt hij)
    · intros f hf₁ hf₂
      let ⟨x, hx, hx'⟩ := List.mem_bind.1 hf₂
      let ⟨g, hg⟩ := List.mem_map.1 hx'
      have hgxa : g⁻¹ x = a := f.injective <| by rw [hmeml hf₁, ← hg.2]; simp
      have hxa : x ≠ a := fun h => (List.nodup_cons.1 hl).1 (h ▸ hx)
      

Proof state:
case refine_4
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
l : List α
hl : Nodup (a :: l)
hl' : Nodup l
hln' : Nodup (permsOfList l)
hmeml : ∀ {f : Equiv.Perm α}, f ∈ permsOfList l → f a = a
f : Equiv.Perm α
hf₁ : f ∈ permsOfList l
hf₂ : f ∈ List.bind l fun b => List.map (fun f => Equiv.swap a b * f) (permsOfList l)
x : α
hx : x ∈ l
hx' : f ∈ List.map (fun f => Equiv.swap a x * f) (permsOfList l)
g : Equiv.Perm α
hg : g ∈ permsOfList l ∧ Equiv.swap a x * g = f
hgxa : g⁻¹ x = a
hxa : x ≠ a
⊢ False

Next tactic:
exact (List.nodup_cons.1 hl).1 <|
          hgxa ▸ mem_of_mem_permsOfList hg.1 _ (by rwa [apply_inv_self, hgxa])
theorem nodup_permsOfList : ∀ {l : List α} (_ : l.Nodup), (permsOfList l).Nodup
  | [], _ => by simp [permsOfList]
  | a :: l, hl => by
    have hl' : l.Nodup := hl.of_cons
    have hln' : (permsOfList l).Nodup := nodup_permsOfList hl'
    have hmeml : ∀ {f : Perm α}, f ∈ permsOfList l → f a = a := fun {f} hf =>
      not_not.1 (mt (mem_of_mem_permsOfList hf _) (nodup_cons.1 hl).1)
    rw [permsOfList, List.nodup_append, List.nodup_bind, pairwise_iff_get]
    refine ⟨?_, ⟨⟨?_,?_ ⟩, ?_⟩⟩
    · exact hln'
    · exact fun _ _ => hln'.map fun _ _ => mul_left_cancel
    · intros i j hij x hx₁ hx₂
      let ⟨f, hf⟩ := List.mem_map.1 hx₁
      let ⟨g, hg⟩ := List.mem_map.1 hx₂
      have hix : x a = List.get l i := by
        rw [← hf.2, mul_apply, hmeml hf.1, swap_apply_left]
      have hiy : x a = List.get l j := by
        rw [← hg.2, mul_apply, hmeml hg.1, swap_apply_left]
      have hieqj : i = j := nodup_iff_injective_get.1 hl' (hix.symm.trans hiy)
      exact absurd hieqj (_root_.ne_of_lt hij)
    · intros f hf₁ hf₂
      let ⟨x, hx, hx'⟩ := List.mem_bind.1 hf₂
      let ⟨g, hg⟩ := List.mem_map.1 hx'
      have hgxa : g⁻¹ x = a := f.injective <| by rw [hmeml hf₁, ← hg.2]; simp
      have hxa : x ≠ a := fun h => (List.nodup_cons.1 hl).1 (h ▸ hx)
      exact (List.nodup_cons.1 hl).1 <|
          hgxa ▸ mem_of_mem_permsOfList hg.1 _ (by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
a : α
l : List α
hl : Nodup (a :: l)
hl' : Nodup l
hln' : Nodup (permsOfList l)
hmeml : ∀ {f : Equiv.Perm α}, f ∈ permsOfList l → f a = a
f : Equiv.Perm α
hf₁ : f ∈ permsOfList l
hf₂ : f ∈ List.bind l fun b => List.map (fun f => Equiv.swap a b * f) (permsOfList l)
x : α
hx : x ∈ l
hx' : f ∈ List.map (fun f => Equiv.swap a x * f) (permsOfList l)
g : Equiv.Perm α
hg : g ∈ permsOfList l ∧ Equiv.swap a x * g = f
hgxa : g⁻¹ x = a
hxa : x ≠ a
⊢ g (g⁻¹ x) ≠ g⁻¹ x

Next tactic:
rwa [apply_inv_self, hgxa]
/-- Given a finset, produce the finset of all permutations of its elements. -/
def permsOfFinset (s : Finset α) : Finset (Perm α) :=
  Quotient.hrecOn s.1 (fun l hl => ⟨permsOfList l, nodup_permsOfList hl⟩)
    (fun a b hab =>
      hfunext (congr_arg _ (Quotient.sound hab)) fun ha hb _ =>
        heq_of_eq <| Finset.ext <| by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
s : Finset α
a b : List α
hab : a ≈ b
ha : Multiset.Nodup ⟦a⟧
hb : Multiset.Nodup ⟦b⟧
x✝ : HEq ha hb
⊢ ∀ (a_1 : Equiv.Perm α),
    a_1 ∈ { val := ↑(permsOfList a), nodup := (_ : Nodup (permsOfList a)) } ↔
      a_1 ∈ { val := ↑(permsOfList b), nodup := (_ : Nodup (permsOfList b)) }

Next tactic:
simp [mem_permsOfList_iff, hab.mem_iff]
theorem mem_perms_of_finset_iff :
    ∀ {s : Finset α} {f : Perm α}, f ∈ permsOfFinset s ↔ ∀ {x}, f x ≠ x → x ∈ s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : DecidableEq α
inst✝ : DecidableEq β
⊢ ∀ {s : Finset α} {f : Equiv.Perm α}, f ∈ permsOfFinset s ↔ ∀ {x : α}, f x ≠ x → x ∈ s

Next tactic:
rintro ⟨⟨l⟩, hs⟩ f