Theorem: perm_of_prod_eq_prod
File: Mathlib/Data/List/Prime.lean

tactic: classical
  have hl₁' : ∀ p ∈ l₁, Prime p := fun p hp => hl₁ p (mem_cons_of_mem _ hp)
  have hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p := fun p hp => hl₂ p (mem_of_mem_erase hp)
  have ha : a ∈ b :: l₂ :=
    mem_list_primes_of_dvd_prod (hl₁ a (mem_cons_self _ _)) hl₂
      (h ▸ by rw [prod_cons]; exact dvd_mul_right _ _)
  have hb : b :: l₂ ~ a :: (b :: l₂).erase a := perm_cons_erase ha
  have hl : prod l₁ = prod ((b :: l₂).erase a) :=
    (mul_right_inj' (hl₁ a (mem_cons_self _ _)).ne_zero).1 <| by
      rwa [← prod_cons, ← prod_cons, ← hb.prod_eq]
  exact Perm.trans ((perm_of_prod_eq_prod hl hl₁' hl₂').cons _) hb.symm
state_before: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
⊢ a :: l₁ ~ b :: l₂
state_after: no goals

tactic: have hl₁' : ∀ p ∈ l₁, Prime p := fun p hp => hl₁ p (mem_cons_of_mem _ hp)
state_before: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
⊢ a :: l₁ ~ b :: l₂
state_after: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
⊢ a :: l₁ ~ b :: l₂

tactic: have hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p := fun p hp => hl₂ p (mem_of_mem_erase hp)
state_before: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
⊢ a :: l₁ ~ b :: l₂
state_after: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p
⊢ a :: l₁ ~ b :: l₂

tactic: have ha : a ∈ b :: l₂ :=
  mem_list_primes_of_dvd_prod (hl₁ a (mem_cons_self _ _)) hl₂
    (h ▸ by rw [prod_cons]; exact dvd_mul_right _ _)
state_before: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p
⊢ a :: l₁ ~ b :: l₂
state_after: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p
ha : a ∈ b :: l₂
⊢ a :: l₁ ~ b :: l₂

tactic: have hb : b :: l₂ ~ a :: (b :: l₂).erase a := perm_cons_erase ha
state_before: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p
ha : a ∈ b :: l₂
⊢ a :: l₁ ~ b :: l₂
state_after: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p
ha : a ∈ b :: l₂
hb : b :: l₂ ~ a :: (b :: l₂).erase a
⊢ a :: l₁ ~ b :: l₂

tactic: have hl : prod l₁ = prod ((b :: l₂).erase a) :=
  (mul_right_inj' (hl₁ a (mem_cons_self _ _)).ne_zero).1 <| by
    rwa [← prod_cons, ← prod_cons, ← hb.prod_eq]
state_before: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p
ha : a ∈ b :: l₂
hb : b :: l₂ ~ a :: (b :: l₂).erase a
⊢ a :: l₁ ~ b :: l₂
state_after: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p
ha : a ∈ b :: l₂
hb : b :: l₂ ~ a :: (b :: l₂).erase a
hl : l₁.prod = ((b :: l₂).erase a).prod
⊢ a :: l₁ ~ b :: l₂

tactic: exact Perm.trans ((perm_of_prod_eq_prod hl hl₁' hl₂').cons _) hb.symm
state_before: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p
ha : a ∈ b :: l₂
hb : b :: l₂ ~ a :: (b :: l₂).erase a
hl : l₁.prod = ((b :: l₂).erase a).prod
⊢ a :: l₁ ~ b :: l₂
state_after: no goals

tactic: rw [prod_cons]
state_before: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p
⊢ a ∣ (a :: l₁).prod
state_after: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p
⊢ a ∣ a * l₁.prod

tactic: exact dvd_mul_right _ _
state_before: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p
⊢ a ∣ a * l₁.prod
state_after: no goals

tactic: rwa [← prod_cons, ← prod_cons, ← hb.prod_eq]
state_before: M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : (a :: l₁).prod = (b :: l₂).prod
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p
ha : a ∈ b :: l₂
hb : b :: l₂ ~ a :: (b :: l₂).erase a
⊢ a * l₁.prod = a * ((b :: l₂).erase a).prod
state_after: no goals