Theorem: Finset.prod_involution
File: Mathlib/Algebra/BigOperators/Basic.lean

tactic: haveI := Classical.decEq α
state_before: ι : Type ?u.714761
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
⊢ ∀ (g : (a : α) → a ∈ s → α),
    (∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1) →
      (∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a) →
        ∀ (g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s),
          (∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a) → ∏ x in s, f x = 1

tactic: haveI := Classical.decEq β
state_before: ι : Type ?u.714761
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
this : DecidableEq α
⊢ ∀ (g : (a : α) → a ∈ s → α),
    (∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1) →
      (∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a) →
        ∀ (g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s),
          (∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a) → ∏ x in s, f x = 1

tactic: exact
  Finset.strongInductionOn s fun s ih g h g_ne g_mem g_inv =>
    s.eq_empty_or_nonempty.elim (fun hs => hs.symm ▸ rfl) fun ⟨x, hx⟩ =>
      have hmem : ∀ y ∈ (s.erase x).erase (g x hx), y ∈ s := fun y hy =>
        mem_of_mem_erase (mem_of_mem_erase hy)
      have g_inj : ∀ {x hx y hy}, g x hx = g y hy → x = y := fun {x hx y hy} h => by
        rw [← g_inv x hx, ← g_inv y hy]; simp [h]
      have ih' : (∏ y in erase (erase s x) (g x hx), f y) = (1 : β) :=
        ih ((s.erase x).erase (g x hx))
          ⟨Subset.trans (erase_subset _ _) (erase_subset _ _), fun h =>
            not_mem_erase (g x hx) (s.erase x) (h (g_mem x hx))⟩
          (fun y hy => g y (hmem y hy)) (fun y hy => h y (hmem y hy))
          (fun y hy => g_ne y (hmem y hy))
          (fun y hy =>
            mem_erase.2
              ⟨fun h : g y _ = g x hx => by simp [g_inj h] at hy,
                mem_erase.2
                  ⟨fun h : g y _ = x => by
                    have : y = g x hx := g_inv y (hmem y hy) ▸ by simp [h]
                    simp [this] at hy, g_mem y (hmem y hy)⟩⟩)
          fun y hy => g_inv y (hmem y hy)
      if hx1 : f x = 1 then
        ih' ▸
          Eq.symm
            (prod_subset hmem fun y hy hy₁ =>
              have : y = x ∨ y = g x hx := by
                simpa [hy, -not_and, mem_erase, not_and_or, or_comm] using hy₁
              this.elim (fun hy => hy.symm ▸ hx1) fun hy =>
                h x hx ▸ hy ▸ hx1.symm ▸ (one_mul _).symm)
      else by
        rw [← insert_erase hx, prod_insert (not_mem_erase _ _), ←
          insert_erase (mem_erase.2 ⟨g_ne x hx hx1, g_mem x hx⟩),
          prod_insert (not_mem_erase _ _), ih', mul_one, h x hx]
state_before: ι : Type ?u.714761
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
⊢ ∀ (g : (a : α) → a ∈ s → α),
    (∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1) →
      (∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a) →
        ∀ (g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s),
          (∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a) → ∏ x in s, f x = 1

tactic: rw [← g_inv x hx, ← g_inv y hy]
state_before: ι : Type ?u.714761
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h✝ : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝¹ : Finset.Nonempty s
x✝ : α
hx✝ : x✝ ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x✝) (g x✝ hx✝) → y ∈ s
x : α
hx : x ∈ s
y : α
hy : y ∈ s
h : g x hx = g y hy
⊢ x = y

tactic: simp [h]
state_before: ι : Type ?u.714761
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h✝ : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝¹ : Finset.Nonempty s
x✝ : α
hx✝ : x✝ ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x✝) (g x✝ hx✝) → y ∈ s
x : α
hx : x ∈ s
y : α
hy : y ∈ s
h : g x hx = g y hy
⊢ g (g x hx) (_ : g x hx ∈ s) = g (g y hy) (_ : g y hy ∈ s)

tactic: simp [g_inj h] at hy
state_before: ι : Type ?u.714761
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h✝ : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝ : Finset.Nonempty s
x : α
hx : x ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x) (g x hx) → y ∈ s
g_inj : ∀ {x : α} {hx : x ∈ s} {y : α} {hy : y ∈ s}, g x hx = g y hy → x = y
y : α
hy : y ∈ erase (erase s x) (g x hx)
h : g y (_ : y ∈ s) = g x hx
⊢ False

tactic: have : y = g x hx := g_inv y (hmem y hy) ▸ by simp [h]
state_before: ι : Type ?u.714761
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h✝ : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝ : Finset.Nonempty s
x : α
hx : x ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x) (g x hx) → y ∈ s
g_inj : ∀ {x : α} {hx : x ∈ s} {y : α} {hy : y ∈ s}, g x hx = g y hy → x = y
y : α
hy : y ∈ erase (erase s x) (g x hx)
h : g y (_ : y ∈ s) = x
⊢ False

tactic: simp [this] at hy
state_before: ι : Type ?u.714761
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝¹ : DecidableEq α
this✝ : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h✝ : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝ : Finset.Nonempty s
x : α
hx : x ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x) (g x hx) → y ∈ s
g_inj : ∀ {x : α} {hx : x ∈ s} {y : α} {hy : y ∈ s}, g x hx = g y hy → x = y
y : α
hy : y ∈ erase (erase s x) (g x hx)
h : g y (_ : y ∈ s) = x
this : y = g x hx
⊢ False

tactic: simp [h]
state_before: ι : Type ?u.714761
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h✝ : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝ : Finset.Nonempty s
x : α
hx : x ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x) (g x hx) → y ∈ s
g_inj : ∀ {x : α} {hx : x ∈ s} {y : α} {hy : y ∈ s}, g x hx = g y hy → x = y
y : α
hy : y ∈ erase (erase s x) (g x hx)
h : g y (_ : y ∈ s) = x
⊢ g (g y (_ : y ∈ s)) (_ : g y (_ : y ∈ s) ∈ s) = g x hx

tactic: simpa [hy, -not_and, mem_erase, not_and_or, or_comm] using hy₁
state_before: ι : Type ?u.714761
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝ : Finset.Nonempty s
x : α
hx : x ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x) (g x hx) → y ∈ s
g_inj : ∀ {x : α} {hx : x ∈ s} {y : α} {hy : y ∈ s}, g x hx = g y hy → x = y
ih' : ∏ y in erase (erase s x) (g x hx), f y = 1
hx1 : f x = 1
y : α
hy : y ∈ s
hy₁ : ¬y ∈ erase (erase s x) (g x hx)
⊢ y = x ∨ y = g x hx

tactic: rw [← insert_erase hx, prod_insert (not_mem_erase _ _), ←
  insert_erase (mem_erase.2 ⟨g_ne x hx hx1, g_mem x hx⟩),
  prod_insert (not_mem_erase _ _), ih', mul_one, h x hx]
state_before: ι : Type ?u.714761
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝ : Finset.Nonempty s
x : α
hx : x ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x) (g x hx) → y ∈ s
g_inj : ∀ {x : α} {hx : x ∈ s} {y : α} {hy : y ∈ s}, g x hx = g y hy → x = y
ih' : ∏ y in erase (erase s x) (g x hx), f y = 1
hx1 : ¬f x = 1
⊢ ∏ x in s, f x = 1