l3lab/ntp-mathlib huggingface dataset:
/-- In an integral domain, a sum indexed by a nontrivial homomorphism from a finite group is zero.
-/
theorem sum_hom_units_eq_zero (f : G →* R) (hf : f ≠ 1) : ∑ g : G, f g = 0 := by
  classical
    obtain ⟨x, hx⟩ :
      ∃ x : MonoidHom.range f.toHomUnits,
        ∀ y : MonoidHom.range f.toHomUnits, y ∈ Submonoid.powers x
    exact IsCyclic.exists_monoid_generator
    have hx1 : x ≠ 1 := by
      rintro rfl
      apply hf
      ext g
      rw [MonoidHom.one_apply]
      cases' hx ⟨f.toHomUnits g, g, rfl⟩ with n hn
      rwa [Subtype.ext_iff, Units.ext_iff, Subtype.coe_mk, MonoidHom.coe_toHomUnits, one_pow,
        eq_comm] at hn
    replace hx1 : (x.val : R) - 1 ≠ 0  -- porting note: was `(x : R)`
    exact fun h => hx1 (Subtype.eq (Units.ext (sub_eq_zero.1 h)))
    let c := (univ.filter fun g => f.toHomUnits g = 1).card
    calc
      ∑ g : G, f g = ∑ g : G, (f.toHomUnits g : R) := rfl
      _ = ∑ u : Rˣ in univ.image f.toHomUnits,
            (univ.filter fun g => f.toHomUnits g = u).card • (u : R) :=
        (sum_comp ((↑) : Rˣ → R) f.toHomUnits)
      _ = ∑ u : Rˣ in univ.image f.toHomUnits, c • (u : R) :=
        (sum_congr rfl fun u hu => congr_arg₂ _ ?_ rfl)
      -- remaining goal 1, proven below
      -- Porting note: have to change `(b : R)` into `((b : Rˣ) : R)`
      _ = ∑ b : MonoidHom.range f.toHomUnits, c • ((b : Rˣ) : R) :=
        (Finset.sum_subtype _ (by simp) _)
      _ = c • ∑ b : MonoidHom.range f.toHomUnits, ((b : Rˣ) : R) := smul_sum.symm
      _ = c • (0 : R) := (congr_arg₂ _ rfl ?_)
      -- remaining goal 2, proven below
      _ = (0 : R) := smul_zero _
    · -- remaining goal 1
      show (univ.filter fun g : G => f.toHomUnits g = u).card = c
      apply card_fiber_eq_of_mem_range f.toHomUnits
      · simpa only [mem_image, mem_univ, true_and, Set.mem_range] using hu
      · exact ⟨1, f.toHomUnits.map_one⟩
    -- remaining goal 2
    show (∑ b : MonoidHom.range f.toHomUnits, ((b : Rˣ) : R)) = 0
    calc
      (∑ b : MonoidHom.range f.toHomUnits, ((b : Rˣ) : R))
        = ∑ n in range (orderOf x), ((x : Rˣ) : R) ^ n :=
        Eq.symm <|
          sum_bij (fun n _ => x ^ n) (by simp only [mem_univ, forall_true_iff])
            (by simp only [imp_true_iff, eq_self_iff_true, Subgroup.coe_pow,
                Units.val_pow_eq_pow_val])
            (fun m n hm hn => pow_injOn_Iio_orderOf (by simpa only [mem_range] using hm)
                (by simpa only [mem_range] using hn))
            (fun b _ => let ⟨n, hn⟩ := hx b
              ⟨n % orderOf x, mem_range.2 (Nat.mod_lt _ (orderOf_pos _)),
               -- Porting note: have to use `dsimp` to apply the function
               by dsimp at hn ⊢; 

Proof state:
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥(MonoidHom.range (MonoidHom.toHomUnits f))
hx : ∀ (y : ↥(MonoidHom.range (MonoidHom.toHomUnits f))), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := card (filter (fun g => (MonoidHom.toHomUnits f) g = 1) univ)
b : ↥(MonoidHom.range (MonoidHom.toHomUnits f))
x✝ : b ∈ univ
n : ℕ
hn : x ^ n = b
⊢ b = x ^ (n % orderOf x)

Next tactic:
rw [pow_mod_orderOf, hn]
/-- In an integral domain, a sum indexed by a nontrivial homomorphism from a finite group is zero.
-/
theorem sum_hom_units_eq_zero (f : G →* R) (hf : f ≠ 1) : ∑ g : G, f g = 0 := by
  classical
    obtain ⟨x, hx⟩ :
      ∃ x : MonoidHom.range f.toHomUnits,
        ∀ y : MonoidHom.range f.toHomUnits, y ∈ Submonoid.powers x
    exact IsCyclic.exists_monoid_generator
    have hx1 : x ≠ 1 := by
      rintro rfl
      apply hf
      ext g
      rw [MonoidHom.one_apply]
      cases' hx ⟨f.toHomUnits g, g, rfl⟩ with n hn
      rwa [Subtype.ext_iff, Units.ext_iff, Subtype.coe_mk, MonoidHom.coe_toHomUnits, one_pow,
        eq_comm] at hn
    replace hx1 : (x.val : R) - 1 ≠ 0  -- porting note: was `(x : R)`
    exact fun h => hx1 (Subtype.eq (Units.ext (sub_eq_zero.1 h)))
    let c := (univ.filter fun g => f.toHomUnits g = 1).card
    calc
      ∑ g : G, f g = ∑ g : G, (f.toHomUnits g : R) := rfl
      _ = ∑ u : Rˣ in univ.image f.toHomUnits,
            (univ.filter fun g => f.toHomUnits g = u).card • (u : R) :=
        (sum_comp ((↑) : Rˣ → R) f.toHomUnits)
      _ = ∑ u : Rˣ in univ.image f.toHomUnits, c • (u : R) :=
        (sum_congr rfl fun u hu => congr_arg₂ _ ?_ rfl)
      -- remaining goal 1, proven below
      -- Porting note: have to change `(b : R)` into `((b : Rˣ) : R)`
      _ = ∑ b : MonoidHom.range f.toHomUnits, c • ((b : Rˣ) : R) :=
        (Finset.sum_subtype _ (by simp) _)
      _ = c • ∑ b : MonoidHom.range f.toHomUnits, ((b : Rˣ) : R) := smul_sum.symm
      _ = c • (0 : R) := (congr_arg₂ _ rfl ?_)
      -- remaining goal 2, proven below
      _ = (0 : R) := smul_zero _
    · -- remaining goal 1
      show (univ.filter fun g : G => f.toHomUnits g = u).card = c
      apply card_fiber_eq_of_mem_range f.toHomUnits
      · simpa only [mem_image, mem_univ, true_and, Set.mem_range] using hu
      · exact ⟨1, f.toHomUnits.map_one⟩
    -- remaining goal 2
    show (∑ b : MonoidHom.range f.toHomUnits, ((b : Rˣ) : R)) = 0
    calc
      (∑ b : MonoidHom.range f.toHomUnits, ((b : Rˣ) : R))
        = ∑ n in range (orderOf x), ((x : Rˣ) : R) ^ n :=
        Eq.symm <|
          sum_bij (fun n _ => x ^ n) (by simp only [mem_univ, forall_true_iff])
            (by simp only [imp_true_iff, eq_self_iff_true, Subgroup.coe_pow,
                Units.val_pow_eq_pow_val])
            (fun m n hm hn => pow_injOn_Iio_orderOf (by simpa only [mem_range] using hm)
                (by simpa only [mem_range] using hn))
            (fun b _ => let ⟨n, hn⟩ := hx b
              ⟨n % orderOf x, mem_range.2 (Nat.mod_lt _ (orderOf_pos _)),
               -- Porting note: have to use `dsimp` to apply the function
               by dsimp at hn ⊢; rw [pow_mod_orderOf, hn]⟩)
      _ = 0 := ?_

    

Proof state:
case intro.calc_2
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥(MonoidHom.range (MonoidHom.toHomUnits f))
hx : ∀ (y : ↥(MonoidHom.range (MonoidHom.toHomUnits f))), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := card (filter (fun g => (MonoidHom.toHomUnits f) g = 1) univ)
⊢ ∑ n in range (orderOf x), ↑↑x ^ n = 0

Next tactic:
rw [← mul_left_inj' hx1, zero_mul, geom_sum_mul]
/-- In an integral domain, a sum indexed by a nontrivial homomorphism from a finite group is zero.
-/
theorem sum_hom_units_eq_zero (f : G →* R) (hf : f ≠ 1) : ∑ g : G, f g = 0 := by
  classical
    obtain ⟨x, hx⟩ :
      ∃ x : MonoidHom.range f.toHomUnits,
        ∀ y : MonoidHom.range f.toHomUnits, y ∈ Submonoid.powers x
    exact IsCyclic.exists_monoid_generator
    have hx1 : x ≠ 1 := by
      rintro rfl
      apply hf
      ext g
      rw [MonoidHom.one_apply]
      cases' hx ⟨f.toHomUnits g, g, rfl⟩ with n hn
      rwa [Subtype.ext_iff, Units.ext_iff, Subtype.coe_mk, MonoidHom.coe_toHomUnits, one_pow,
        eq_comm] at hn
    replace hx1 : (x.val : R) - 1 ≠ 0  -- porting note: was `(x : R)`
    exact fun h => hx1 (Subtype.eq (Units.ext (sub_eq_zero.1 h)))
    let c := (univ.filter fun g => f.toHomUnits g = 1).card
    calc
      ∑ g : G, f g = ∑ g : G, (f.toHomUnits g : R) := rfl
      _ = ∑ u : Rˣ in univ.image f.toHomUnits,
            (univ.filter fun g => f.toHomUnits g = u).card • (u : R) :=
        (sum_comp ((↑) : Rˣ → R) f.toHomUnits)
      _ = ∑ u : Rˣ in univ.image f.toHomUnits, c • (u : R) :=
        (sum_congr rfl fun u hu => congr_arg₂ _ ?_ rfl)
      -- remaining goal 1, proven below
      -- Porting note: have to change `(b : R)` into `((b : Rˣ) : R)`
      _ = ∑ b : MonoidHom.range f.toHomUnits, c • ((b : Rˣ) : R) :=
        (Finset.sum_subtype _ (by simp) _)
      _ = c • ∑ b : MonoidHom.range f.toHomUnits, ((b : Rˣ) : R) := smul_sum.symm
      _ = c • (0 : R) := (congr_arg₂ _ rfl ?_)
      -- remaining goal 2, proven below
      _ = (0 : R) := smul_zero _
    · -- remaining goal 1
      show (univ.filter fun g : G => f.toHomUnits g = u).card = c
      apply card_fiber_eq_of_mem_range f.toHomUnits
      · simpa only [mem_image, mem_univ, true_and, Set.mem_range] using hu
      · exact ⟨1, f.toHomUnits.map_one⟩
    -- remaining goal 2
    show (∑ b : MonoidHom.range f.toHomUnits, ((b : Rˣ) : R)) = 0
    calc
      (∑ b : MonoidHom.range f.toHomUnits, ((b : Rˣ) : R))
        = ∑ n in range (orderOf x), ((x : Rˣ) : R) ^ n :=
        Eq.symm <|
          sum_bij (fun n _ => x ^ n) (by simp only [mem_univ, forall_true_iff])
            (by simp only [imp_true_iff, eq_self_iff_true, Subgroup.coe_pow,
                Units.val_pow_eq_pow_val])
            (fun m n hm hn => pow_injOn_Iio_orderOf (by simpa only [mem_range] using hm)
                (by simpa only [mem_range] using hn))
            (fun b _ => let ⟨n, hn⟩ := hx b
              ⟨n % orderOf x, mem_range.2 (Nat.mod_lt _ (orderOf_pos _)),
               -- Porting note: have to use `dsimp` to apply the function
               by dsimp at hn ⊢; rw [pow_mod_orderOf, hn]⟩)
      _ = 0 := ?_

    rw [← mul_left_inj' hx1, zero_mul, geom_sum_mul]
    

Proof state:
case intro.calc_2
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥(MonoidHom.range (MonoidHom.toHomUnits f))
hx : ∀ (y : ↥(MonoidHom.range (MonoidHom.toHomUnits f))), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := card (filter (fun g => (MonoidHom.toHomUnits f) g = 1) univ)
⊢ ↑↑x ^ orderOf x - 1 = 0

Next tactic:
norm_cast
/-- In an integral domain, a sum indexed by a homomorphism from a finite group is zero,
unless the homomorphism is trivial, in which case the sum is equal to the cardinality of the group.
-/
theorem sum_hom_units (f : G →* R) [Decidable (f = 1)] :
    ∑ g : G, f g = if f = 1 then Fintype.card G else 0 := by
  

Proof state:
R : Type u_1
G : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : Group G
inst✝¹ : Fintype G
f : G →* R
inst✝ : Decidable (f = 1)
⊢ ∑ g : G, f g = ↑(if f = 1 then Fintype.card G else 0)

Next tactic:
split_ifs with h
/-- In an integral domain, a sum indexed by a homomorphism from a finite group is zero,
unless the homomorphism is trivial, in which case the sum is equal to the cardinality of the group.
-/
theorem sum_hom_units (f : G →* R) [Decidable (f = 1)] :
    ∑ g : G, f g = if f = 1 then Fintype.card G else 0 := by
  split_ifs with h
  · 

Proof state:
case pos
R : Type u_1
G : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : Group G
inst✝¹ : Fintype G
f : G →* R
inst✝ : Decidable (f = 1)
h : f = 1
⊢ ∑ g : G, f g = ↑(Fintype.card G)

Next tactic:
simp [h, card_univ]
/-- In an integral domain, a sum indexed by a homomorphism from a finite group is zero,
unless the homomorphism is trivial, in which case the sum is equal to the cardinality of the group.
-/
theorem sum_hom_units (f : G →* R) [Decidable (f = 1)] :
    ∑ g : G, f g = if f = 1 then Fintype.card G else 0 := by
  split_ifs with h
  · simp [h, card_univ]
  · 

Proof state:
case neg
R : Type u_1
G : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : Group G
inst✝¹ : Fintype G
f : G →* R
inst✝ : Decidable (f = 1)
h : ¬f = 1
⊢ ∑ g : G, f g = ↑0

Next tactic:
rw [cast_zero]
/-- In an integral domain, a sum indexed by a homomorphism from a finite group is zero,
unless the homomorphism is trivial, in which case the sum is equal to the cardinality of the group.
-/
theorem sum_hom_units (f : G →* R) [Decidable (f = 1)] :
    ∑ g : G, f g = if f = 1 then Fintype.card G else 0 := by
  split_ifs with h
  · simp [h, card_univ]
  · rw [cast_zero] -- porting note: added
    

Proof state:
case neg
R : Type u_1
G : Type u_2
inst✝⁴ : CommRing R
inst✝³ : IsDomain R
inst✝² : Group G
inst✝¹ : Fintype G
f : G →* R
inst✝ : Decidable (f = 1)
h : ¬f = 1
⊢ ∑ g : G, f g = 0

Next tactic:
exact sum_hom_units_eq_zero f h
theorem formPerm_apply_of_not_mem (x : α) (l : List α) (h : x ∉ l) : formPerm l x = x := by
  

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

Next tactic:
cases' l with y l
theorem formPerm_apply_of_not_mem (x : α) (l : List α) (h : x ∉ l) : formPerm l x = x := by
  cases' l with y l
  · 

Proof state:
case nil
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l : List α
x✝ x : α
h : x ∉ []
⊢ (formPerm []) x = x

Next tactic:
simp
theorem formPerm_apply_of_not_mem (x : α) (l : List α) (h : x ∉ l) : formPerm l x = x := by
  cases' l with y l
  · simp
  

Proof state:
case cons
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
h : x ∉ y :: l
⊢ (formPerm (y :: l)) x = x

Next tactic:
induction' l with z l IH generalizing x y
theorem formPerm_apply_of_not_mem (x : α) (l : List α) (h : x ∉ l) : formPerm l x = x := by
  cases' l with y l
  · simp
  induction' l with z l IH generalizing x y
  · 

Proof state:
case cons.nil
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l : List α
x✝ x y : α
h : x ∉ [y]
⊢ (formPerm [y]) x = x

Next tactic:
simp
theorem formPerm_apply_of_not_mem (x : α) (l : List α) (h : x ∉ l) : formPerm l x = x := by
  cases' l with y l
  · simp
  induction' l with z l IH generalizing x y
  · simp
  · 

Proof state:
case cons.cons
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ z : α
l : List α
IH : ∀ (x y : α), x ∉ y :: l → (formPerm (y :: l)) x = x
x y : α
h : x ∉ y :: z :: l
⊢ (formPerm (y :: z :: l)) x = x

Next tactic:
specialize IH x z (mt (mem_cons_of_mem y) h)
theorem formPerm_apply_of_not_mem (x : α) (l : List α) (h : x ∉ l) : formPerm l x = x := by
  cases' l with y l
  · simp
  induction' l with z l IH generalizing x y
  · simp
  · specialize IH x z (mt (mem_cons_of_mem y) h)
    

Proof state:
case cons.cons
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ z : α
l : List α
x y : α
h : x ∉ y :: z :: l
IH : (formPerm (z :: l)) x = x
⊢ (formPerm (y :: z :: l)) x = x

Next tactic:
simp only [not_or, mem_cons] at h
theorem formPerm_apply_of_not_mem (x : α) (l : List α) (h : x ∉ l) : formPerm l x = x := by
  cases' l with y l
  · simp
  induction' l with z l IH generalizing x y
  · simp
  · specialize IH x z (mt (mem_cons_of_mem y) h)
    simp only [not_or, mem_cons] at h
    

Proof state:
case cons.cons
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ z : α
l : List α
x y : α
IH : (formPerm (z :: l)) x = x
h : ¬x = y ∧ ¬x = z ∧ x ∉ l
⊢ (formPerm (y :: z :: l)) x = x

Next tactic:
simp [IH, swap_apply_of_ne_of_ne, h]
theorem formPerm_apply_mem_of_mem (x : α) (l : List α) (h : x ∈ l) : formPerm l x ∈ l := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ x : α
l : List α
h : x ∈ l
⊢ (formPerm l) x ∈ l

Next tactic:
cases' l with y l
theorem formPerm_apply_mem_of_mem (x : α) (l : List α) (h : x ∈ l) : formPerm l x ∈ l := by
  cases' l with y l
  · 

Proof state:
case nil
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l : List α
x✝ x : α
h : x ∈ []
⊢ (formPerm []) x ∈ []

Next tactic:
simp at h
theorem formPerm_apply_mem_of_mem (x : α) (l : List α) (h : x ∈ l) : formPerm l x ∈ l := by
  cases' l with y l
  · simp at h
  

Proof state:
case cons
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
h : x ∈ y :: l
⊢ (formPerm (y :: l)) x ∈ y :: l

Next tactic:
induction' l with z l IH generalizing x y
theorem formPerm_apply_mem_of_mem (x : α) (l : List α) (h : x ∈ l) : formPerm l x ∈ l := by
  cases' l with y l
  · simp at h
  induction' l with z l IH generalizing x y
  · 

Proof state:
case cons.nil
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l : List α
x✝ x y : α
h : x ∈ [y]
⊢ (formPerm [y]) x ∈ [y]

Next tactic:
simpa using h
theorem formPerm_apply_mem_of_mem (x : α) (l : List α) (h : x ∈ l) : formPerm l x ∈ l := by
  cases' l with y l
  · simp at h
  induction' l with z l IH generalizing x y
  · simpa using h
  · 

Proof state:
case cons.cons
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ z : α
l : List α
IH : ∀ (x y : α), x ∈ y :: l → (formPerm (y :: l)) x ∈ y :: l
x y : α
h : x ∈ y :: z :: l
⊢ (formPerm (y :: z :: l)) x ∈ y :: z :: l

Next tactic:
by_cases hx : x ∈ z :: l
theorem formPerm_apply_mem_of_mem (x : α) (l : List α) (h : x ∈ l) : formPerm l x ∈ l := by
  cases' l with y l
  · simp at h
  induction' l with z l IH generalizing x y
  · simpa using h
  · by_cases hx : x ∈ z :: l
    · 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ z : α
l : List α
IH : ∀ (x y : α), x ∈ y :: l → (formPerm (y :: l)) x ∈ y :: l
x y : α
h : x ∈ y :: z :: l
hx : x ∈ z :: l
⊢ (formPerm (y :: z :: l)) x ∈ y :: z :: l

Next tactic:
rw [formPerm_cons_cons, mul_apply, swap_apply_def]
theorem formPerm_apply_mem_of_mem (x : α) (l : List α) (h : x ∈ l) : formPerm l x ∈ l := by
  cases' l with y l
  · simp at h
  induction' l with z l IH generalizing x y
  · simpa using h
  · by_cases hx : x ∈ z :: l
    · rw [formPerm_cons_cons, mul_apply, swap_apply_def]
      

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ z : α
l : List α
IH : ∀ (x y : α), x ∈ y :: l → (formPerm (y :: l)) x ∈ y :: l
x y : α
h : x ∈ y :: z :: l
hx : x ∈ z :: l
⊢ (if (formPerm (z :: l)) x = y then z else if (formPerm (z :: l)) x = z then y else (formPerm (z :: l)) x) ∈
    y :: z :: l

Next tactic:
split_ifs
theorem formPerm_apply_mem_of_mem (x : α) (l : List α) (h : x ∈ l) : formPerm l x ∈ l := by
  cases' l with y l
  · simp at h
  induction' l with z l IH generalizing x y
  · simpa using h
  · by_cases hx : x ∈ z :: l
    · rw [formPerm_cons_cons, mul_apply, swap_apply_def]
      split_ifs
      · 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ z : α
l : List α
IH : ∀ (x y : α), x ∈ y :: l → (formPerm (y :: l)) x ∈ y :: l
x y : α
h : x ∈ y :: z :: l
hx : x ∈ z :: l
h✝ : (formPerm (z :: l)) x = y
⊢ z ∈ y :: z :: l

Next tactic:
simp [IH _ _ hx]
theorem formPerm_apply_mem_of_mem (x : α) (l : List α) (h : x ∈ l) : formPerm l x ∈ l := by
  cases' l with y l
  · simp at h
  induction' l with z l IH generalizing x y
  · simpa using h
  · by_cases hx : x ∈ z :: l
    · rw [formPerm_cons_cons, mul_apply, swap_apply_def]
      split_ifs
      · simp [IH _ _ hx]
      · 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ z : α
l : List α
IH : ∀ (x y : α), x ∈ y :: l → (formPerm (y :: l)) x ∈ y :: l
x y : α
h : x ∈ y :: z :: l
hx : x ∈ z :: l
h✝¹ : ¬(formPerm (z :: l)) x = y
h✝ : (formPerm (z :: l)) x = z
⊢ y ∈ y :: z :: l

Next tactic:
simp
theorem formPerm_apply_mem_of_mem (x : α) (l : List α) (h : x ∈ l) : formPerm l x ∈ l := by
  cases' l with y l
  · simp at h
  induction' l with z l IH generalizing x y
  · simpa using h
  · by_cases hx : x ∈ z :: l
    · rw [formPerm_cons_cons, mul_apply, swap_apply_def]
      split_ifs
      · simp [IH _ _ hx]
      · simp
      · 

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ z : α
l : List α
IH : ∀ (x y : α), x ∈ y :: l → (formPerm (y :: l)) x ∈ y :: l
x y : α
h : x ∈ y :: z :: l
hx : x ∈ z :: l
h✝¹ : ¬(formPerm (z :: l)) x = y
h✝ : ¬(formPerm (z :: l)) x = z
⊢ (formPerm (z :: l)) x ∈ y :: z :: l

Next tactic:
simpa [*] using IH _ _ hx
theorem formPerm_apply_mem_of_mem (x : α) (l : List α) (h : x ∈ l) : formPerm l x ∈ l := by
  cases' l with y l
  · simp at h
  induction' l with z l IH generalizing x y
  · simpa using h
  · by_cases hx : x ∈ z :: l
    · rw [formPerm_cons_cons, mul_apply, swap_apply_def]
      split_ifs
      · simp [IH _ _ hx]
      · simp
      · simpa [*] using IH _ _ hx
    · 

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ z : α
l : List α
IH : ∀ (x y : α), x ∈ y :: l → (formPerm (y :: l)) x ∈ y :: l
x y : α
h : x ∈ y :: z :: l
hx : x ∉ z :: l
⊢ (formPerm (y :: z :: l)) x ∈ y :: z :: l

Next tactic:
replace h : x = y := Or.resolve_right (mem_cons.1 h) hx
theorem formPerm_apply_mem_of_mem (x : α) (l : List α) (h : x ∈ l) : formPerm l x ∈ l := by
  cases' l with y l
  · simp at h
  induction' l with z l IH generalizing x y
  · simpa using h
  · by_cases hx : x ∈ z :: l
    · rw [formPerm_cons_cons, mul_apply, swap_apply_def]
      split_ifs
      · simp [IH _ _ hx]
      · simp
      · simpa [*] using IH _ _ hx
    · replace h : x = y := Or.resolve_right (mem_cons.1 h) hx
      

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ z : α
l : List α
IH : ∀ (x y : α), x ∈ y :: l → (formPerm (y :: l)) x ∈ y :: l
x y : α
hx : x ∉ z :: l
h : x = y
⊢ (formPerm (y :: z :: l)) x ∈ y :: z :: l

Next tactic:
simp [formPerm_apply_of_not_mem _ _ hx, ← h]
theorem mem_of_formPerm_apply_mem (x : α) (l : List α) (h : l.formPerm x ∈ l) : x ∈ l := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ x : α
l : List α
h : (formPerm l) x ∈ l
⊢ x ∈ l

Next tactic:
cases' l with y l
theorem mem_of_formPerm_apply_mem (x : α) (l : List α) (h : l.formPerm x ∈ l) : x ∈ l := by
  cases' l with y l
  · 

Proof state:
case nil
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l : List α
x✝ x : α
h : (formPerm []) x ∈ []
⊢ x ∈ []

Next tactic:
simp at h
theorem mem_of_formPerm_apply_mem (x : α) (l : List α) (h : l.formPerm x ∈ l) : x ∈ l := by
  cases' l with y l
  · simp at h
  

Proof state:
case cons
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ x y : α
l : List α
h : (formPerm (y :: l)) x ∈ y :: l
⊢ x ∈ y :: l

Next tactic:
induction' l with z l IH generalizing x y
theorem mem_of_formPerm_apply_mem (x : α) (l : List α) (h : l.formPerm x ∈ l) : x ∈ l := by
  cases' l with y l
  · simp at h
  induction' l with z l IH generalizing x y
  · 

Proof state:
case cons.nil
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l : List α
x✝ x y : α
h : (formPerm [y]) x ∈ [y]
⊢ x ∈ [y]

Next tactic:
simpa using h
theorem mem_of_formPerm_apply_mem (x : α) (l : List α) (h : l.formPerm x ∈ l) : x ∈ l := by
  cases' l with y l
  · simp at h
  induction' l with z l IH generalizing x y
  · simpa using h
  · 

Proof state:
case cons.cons
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ z : α
l : List α
IH : ∀ (x y : α), (formPerm (y :: l)) x ∈ y :: l → x ∈ y :: l
x y : α
h : (formPerm (y :: z :: l)) x ∈ y :: z :: l
⊢ x ∈ y :: z :: l

Next tactic:
by_cases hx : (z :: l).formPerm x ∈ z :: l
theorem mem_of_formPerm_apply_mem (x : α) (l : List α) (h : l.formPerm x ∈ l) : x ∈ l := by
  cases' l with y l
  · simp at h
  induction' l with z l IH generalizing x y
  · simpa using h
  · by_cases hx : (z :: l).formPerm x ∈ z :: l
    · 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ z : α
l : List α
IH : ∀ (x y : α), (formPerm (y :: l)) x ∈ y :: l → x ∈ y :: l
x y : α
h : (formPerm (y :: z :: l)) x ∈ y :: z :: l
hx : (formPerm (z :: l)) x ∈ z :: l
⊢ x ∈ y :: z :: l

Next tactic:
rw [List.formPerm_cons_cons, mul_apply, swap_apply_def] at h
theorem mem_of_formPerm_apply_mem (x : α) (l : List α) (h : l.formPerm x ∈ l) : x ∈ l := by
  cases' l with y l
  · simp at h
  induction' l with z l IH generalizing x y
  · simpa using h
  · by_cases hx : (z :: l).formPerm x ∈ z :: l
    · rw [List.formPerm_cons_cons, mul_apply, swap_apply_def] at h
      

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ z : α
l : List α
IH : ∀ (x y : α), (formPerm (y :: l)) x ∈ y :: l → x ∈ y :: l
x y : α
h :
  (if (formPerm (z :: l)) x = y then z else if (formPerm (z :: l)) x = z then y else (formPerm (z :: l)) x) ∈
    y :: z :: l
hx : (formPerm (z :: l)) x ∈ z :: l
⊢ x ∈ y :: z :: l

Next tactic:
split_ifs at h
theorem mem_of_formPerm_apply_mem (x : α) (l : List α) (h : l.formPerm x ∈ l) : x ∈ l := by
  cases' l with y l
  · simp at h
  induction' l with z l IH generalizing x y
  · simpa using h
  · by_cases hx : (z :: l).formPerm x ∈ z :: l
    · rw [List.formPerm_cons_cons, mul_apply, swap_apply_def] at h
      split_ifs at h <;> 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝ : DecidableEq α
l✝ : List α
x✝ z : α
l : List α
IH : ∀ (x y : α), (formPerm (y :: l)) x ∈ y :: l → x ∈ y :: l
x y : α
hx : (formPerm (z :: l)) x ∈ z :: l
h✝ : (formPerm (z :: l)) x = y
h : z ∈ y :: z :: l
⊢ x ∈ y :: z :: l

Next tactic:
aesop