Theorem: WfDvdMonoid.of_exists_prime_factors
File: Mathlib/RingTheory/UniqueFactorizationDomain.lean

tactic: rintro a b ⟨ane0, ⟨c, hc, b_eq⟩⟩
state_before: case refine'_2
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
⊢ ∀ {a b : α},
    DvdNotUnit a b →
      (if h : a = 0 then ⊤
        else ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a)))) <
        if h : b = 0 then ⊤
        else ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ b)))

tactic: rw [dif_neg ane0]
state_before: case refine'_2.intro.intro.intro
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
⊢ (if h : a = 0 then ⊤
    else ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a)))) <
    if h : b = 0 then ⊤
    else ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ b)))

tactic: by_cases h : b = 0
state_before: case refine'_2.intro.intro.intro
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
⊢ ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a))) <
    if h : b = 0 then ⊤
    else ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ b)))

tactic: intro a
state_before: case refine'_1
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
⊢ α → ℕ∞

tactic: by_cases h : a = 0
state_before: case refine'_1
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a : α
⊢ ℕ∞

tactic: exact ↑(Multiset.card (Classical.choose (pf a h)))
state_before: case neg
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a : α
h : ¬a = 0
⊢ ℕ∞

tactic: exact ⊤
state_before: case pos
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a : α
h : a = 0
⊢ ℕ∞

tactic: simp [h, lt_top_iff_ne_top]
state_before: case pos
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : b = 0
⊢ ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a))) <
    if h : b = 0 then ⊤
    else ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ b)))

tactic: rw [dif_neg h]
state_before: case neg
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
⊢ ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a))) <
    if h : b = 0 then ⊤
    else ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ b)))

tactic: erw [WithTop.coe_lt_coe]
state_before: case neg
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
⊢ ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a))) <
    ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ b)))

tactic: have cne0 : c ≠ 0 := by
  refine' mt (fun con => _) h
  rw [b_eq, con, MulZeroClass.mul_zero]
state_before: case neg
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
⊢ ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a))) <
    ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ b)))

tactic: calc
  Multiset.card (Classical.choose (pf a ane0)) <
      _ + Multiset.card (Classical.choose (pf c cne0)) :=
    lt_add_of_pos_right _
      (Multiset.card_pos.mpr fun con => hc (associated_one_iff_isUnit.mp ?_))
  _ = Multiset.card (Classical.choose (pf a ane0) + Classical.choose (pf c cne0)) :=
    (Multiset.card_add _ _).symm
  _ = Multiset.card (Classical.choose (pf b h)) :=
    Multiset.card_eq_card_of_rel
    (prime_factors_unique ?_ (Classical.choose_spec (pf _ h)).1 ?_)
state_before: case neg
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
cne0 : c ≠ 0
⊢ ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a))) <
    ↑(↑Multiset.card (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ b)))

tactic: refine' mt (fun con => _) h
state_before: α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
⊢ c ≠ 0

tactic: rw [b_eq, con, MulZeroClass.mul_zero]
state_before: α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
con : c = 0
⊢ b = 0

tactic: convert (Classical.choose_spec (pf c cne0)).2.symm
state_before: case neg.calc_1
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
cne0 : c ≠ 0
con : Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ c) = 0
⊢ c ~ᵤ 1

tactic: rw [con, Multiset.prod_zero]
state_before: case h.e'_4
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
cne0 : c ≠ 0
con : Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ c) = 0
⊢ 1 = Multiset.prod (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ c))

tactic: intro x hadd
state_before: case neg.calc_2
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
cne0 : c ≠ 0
⊢ ∀ (x : α),
    x ∈
        Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a) +
          Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ c) →
      Prime x

tactic: rw [Multiset.mem_add] at hadd
state_before: case neg.calc_2
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
cne0 : c ≠ 0
x : α
hadd :
  x ∈
    Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a) +
      Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ c)
⊢ Prime x

tactic: cases' hadd with h h <;> apply (Classical.choose_spec (pf _ _)).1 _ h <;> assumption
state_before: case neg.calc_2
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
cne0 : c ≠ 0
x : α
hadd :
  x ∈ Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a) ∨
    x ∈ Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ c)
⊢ Prime x

tactic: rw [Multiset.prod_add]
state_before: case neg.calc_3
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
cne0 : c ≠ 0
⊢ Multiset.prod
      (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a) +
        Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ c)) ~ᵤ
    Multiset.prod (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ b))

tactic: trans a * c
state_before: case neg.calc_3
α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
cne0 : c ≠ 0
⊢ Multiset.prod (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a)) *
      Multiset.prod (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ c)) ~ᵤ
    Multiset.prod (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ b))

tactic: apply Associated.mul_mul <;> apply (Classical.choose_spec (pf _ _)).2 <;> assumption
state_before: α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
cne0 : c ≠ 0
⊢ Multiset.prod (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a)) *
      Multiset.prod (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ c)) ~ᵤ
    a * c

tactic: rw [← b_eq]
state_before: α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
cne0 : c ≠ 0
⊢ a * c ~ᵤ Multiset.prod (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ b))

tactic: apply (Classical.choose_spec (pf _ _)).2.symm
state_before: α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
cne0 : c ≠ 0
⊢ b ~ᵤ Multiset.prod (Classical.choose (_ : ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ b))

tactic: assumption
state_before: α : Type u_1
inst✝ : CancelCommMonoidWithZero α
pf : ∀ (a : α), a ≠ 0 → ∃ f, (∀ (b : α), b ∈ f → Prime b) ∧ Multiset.prod f ~ᵤ a
a b : α
ane0 : a ≠ 0
c : α
hc : ¬IsUnit c
b_eq : b = a * c
h : ¬b = 0
cne0 : c ≠ 0
⊢ b ≠ 0