l3lab/ntp-mathlib huggingface dataset:
/-- If we start with a multiset of primes, take the product and
 then factor it, we get back the original multiset. -/
theorem factorMultiset_prod (v : PrimeMultiset) : v.prod.factorMultiset = v := by
  apply PrimeMultiset.coeNat_injective
  suffices toNatMultiset (PNat.factorMultiset (prod v)) = toNatMultiset v by exact this
  rw [v.prod.coeNat_factorMultiset, PrimeMultiset.coe_prod]
  rcases v with ⟨l⟩
  --unfold_coes
  dsimp [PrimeMultiset.toNatMultiset]
  rw [Multiset.coe_prod]
  let l' := l.map (Coe.coe : Nat.Primes → ℕ)
  have : ∀ p : ℕ, p ∈ l' → p.Prime := fun p hp => by
    

Proof state:
v : PrimeMultiset
l : List Nat.Primes
l' : List ℕ := List.map Coe.coe l
p : ℕ
hp : p ∈ l'
⊢ Nat.Prime p

Next tactic:
rcases List.mem_map.mp hp with ⟨⟨_, hp'⟩, ⟨_, h_eq⟩⟩
/-- If we start with a multiset of primes, take the product and
 then factor it, we get back the original multiset. -/
theorem factorMultiset_prod (v : PrimeMultiset) : v.prod.factorMultiset = v := by
  apply PrimeMultiset.coeNat_injective
  suffices toNatMultiset (PNat.factorMultiset (prod v)) = toNatMultiset v by exact this
  rw [v.prod.coeNat_factorMultiset, PrimeMultiset.coe_prod]
  rcases v with ⟨l⟩
  --unfold_coes
  dsimp [PrimeMultiset.toNatMultiset]
  rw [Multiset.coe_prod]
  let l' := l.map (Coe.coe : Nat.Primes → ℕ)
  have : ∀ p : ℕ, p ∈ l' → p.Prime := fun p hp => by
    rcases List.mem_map.mp hp with ⟨⟨_, hp'⟩, ⟨_, h_eq⟩⟩
    

Proof state:
case intro.mk.intro
v : PrimeMultiset
l : List Nat.Primes
l' : List ℕ := List.map Coe.coe l
p : ℕ
hp : p ∈ l'
val✝ : ℕ
hp' : Nat.Prime val✝
left✝ : { val := val✝, property := hp' } ∈ l
h_eq : Coe.coe { val := val✝, property := hp' } = p
⊢ Nat.Prime p

Next tactic:
exact h_eq ▸ hp'
/-- If we start with a multiset of primes, take the product and
 then factor it, we get back the original multiset. -/
theorem factorMultiset_prod (v : PrimeMultiset) : v.prod.factorMultiset = v := by
  apply PrimeMultiset.coeNat_injective
  suffices toNatMultiset (PNat.factorMultiset (prod v)) = toNatMultiset v by exact this
  rw [v.prod.coeNat_factorMultiset, PrimeMultiset.coe_prod]
  rcases v with ⟨l⟩
  --unfold_coes
  dsimp [PrimeMultiset.toNatMultiset]
  rw [Multiset.coe_prod]
  let l' := l.map (Coe.coe : Nat.Primes → ℕ)
  have : ∀ p : ℕ, p ∈ l' → p.Prime := fun p hp => by
    rcases List.mem_map.mp hp with ⟨⟨_, hp'⟩, ⟨_, h_eq⟩⟩
    exact h_eq ▸ hp'
  

Proof state:
case a.mk
v : PrimeMultiset
l : List Nat.Primes
l' : List ℕ := List.map Coe.coe l
this : ∀ p ∈ l', Nat.Prime p
⊢ ↑(Nat.factors (List.prod (List.map Coe.coe l))) = ↑(List.map Coe.coe l)

Next tactic:
exact Multiset.coe_eq_coe.mpr (@Nat.factors_unique _ l' rfl this).symm
/-- Factoring gives a homomorphism from the multiplicative
 monoid ℕ+ to the additive monoid of multisets. -/
theorem factorMultiset_one : factorMultiset 1 = 0 := by
  

Proof state:
⊢ factorMultiset 1 = 0

Next tactic:
simp [factorMultiset, PrimeMultiset.ofNatList, PrimeMultiset.ofNatMultiset]
theorem factorMultiset_mul (n m : ℕ+) :
    factorMultiset (n * m) = factorMultiset n + factorMultiset m := by
  

Proof state:
n m : ℕ+
⊢ factorMultiset (n * m) = factorMultiset n + factorMultiset m

Next tactic:
let u := factorMultiset n
theorem factorMultiset_mul (n m : ℕ+) :
    factorMultiset (n * m) = factorMultiset n + factorMultiset m := by
  let u := factorMultiset n
  

Proof state:
n m : ℕ+
u : PrimeMultiset := factorMultiset n
⊢ factorMultiset (n * m) = factorMultiset n + factorMultiset m

Next tactic:
let v := factorMultiset m
theorem factorMultiset_mul (n m : ℕ+) :
    factorMultiset (n * m) = factorMultiset n + factorMultiset m := by
  let u := factorMultiset n
  let v := factorMultiset m
  

Proof state:
n m : ℕ+
u : PrimeMultiset := factorMultiset n
v : PrimeMultiset := factorMultiset m
⊢ factorMultiset (n * m) = factorMultiset n + factorMultiset m

Next tactic:
have : n = u.prod := (prod_factorMultiset n).symm
theorem factorMultiset_mul (n m : ℕ+) :
    factorMultiset (n * m) = factorMultiset n + factorMultiset m := by
  let u := factorMultiset n
  let v := factorMultiset m
  have : n = u.prod := (prod_factorMultiset n).symm; 

Proof state:
n m : ℕ+
u : PrimeMultiset := factorMultiset n
v : PrimeMultiset := factorMultiset m
this : n = PrimeMultiset.prod u
⊢ factorMultiset (n * m) = factorMultiset n + factorMultiset m

Next tactic:
rw [this]
theorem factorMultiset_mul (n m : ℕ+) :
    factorMultiset (n * m) = factorMultiset n + factorMultiset m := by
  let u := factorMultiset n
  let v := factorMultiset m
  have : n = u.prod := (prod_factorMultiset n).symm; rw [this]
  

Proof state:
n m : ℕ+
u : PrimeMultiset := factorMultiset n
v : PrimeMultiset := factorMultiset m
this : n = PrimeMultiset.prod u
⊢ factorMultiset (PrimeMultiset.prod u * m) = factorMultiset (PrimeMultiset.prod u) + factorMultiset m

Next tactic:
have : m = v.prod := (prod_factorMultiset m).symm
theorem factorMultiset_mul (n m : ℕ+) :
    factorMultiset (n * m) = factorMultiset n + factorMultiset m := by
  let u := factorMultiset n
  let v := factorMultiset m
  have : n = u.prod := (prod_factorMultiset n).symm; rw [this]
  have : m = v.prod := (prod_factorMultiset m).symm; 

Proof state:
n m : ℕ+
u : PrimeMultiset := factorMultiset n
v : PrimeMultiset := factorMultiset m
this✝ : n = PrimeMultiset.prod u
this : m = PrimeMultiset.prod v
⊢ factorMultiset (PrimeMultiset.prod u * m) = factorMultiset (PrimeMultiset.prod u) + factorMultiset m

Next tactic:
rw [this]
theorem factorMultiset_mul (n m : ℕ+) :
    factorMultiset (n * m) = factorMultiset n + factorMultiset m := by
  let u := factorMultiset n
  let v := factorMultiset m
  have : n = u.prod := (prod_factorMultiset n).symm; rw [this]
  have : m = v.prod := (prod_factorMultiset m).symm; rw [this]
  

Proof state:
n m : ℕ+
u : PrimeMultiset := factorMultiset n
v : PrimeMultiset := factorMultiset m
this✝ : n = PrimeMultiset.prod u
this : m = PrimeMultiset.prod v
⊢ factorMultiset (PrimeMultiset.prod u * PrimeMultiset.prod v) =
    factorMultiset (PrimeMultiset.prod u) + factorMultiset (PrimeMultiset.prod v)

Next tactic:
rw [← PrimeMultiset.prod_add]
theorem factorMultiset_mul (n m : ℕ+) :
    factorMultiset (n * m) = factorMultiset n + factorMultiset m := by
  let u := factorMultiset n
  let v := factorMultiset m
  have : n = u.prod := (prod_factorMultiset n).symm; rw [this]
  have : m = v.prod := (prod_factorMultiset m).symm; rw [this]
  rw [← PrimeMultiset.prod_add]
  

Proof state:
n m : ℕ+
u : PrimeMultiset := factorMultiset n
v : PrimeMultiset := factorMultiset m
this✝ : n = PrimeMultiset.prod u
this : m = PrimeMultiset.prod v
⊢ factorMultiset (PrimeMultiset.prod (u + v)) =
    factorMultiset (PrimeMultiset.prod u) + factorMultiset (PrimeMultiset.prod v)

Next tactic:
repeat' rw [PrimeMultiset.factorMultiset_prod]
theorem factorMultiset_mul (n m : ℕ+) :
    factorMultiset (n * m) = factorMultiset n + factorMultiset m := by
  let u := factorMultiset n
  let v := factorMultiset m
  have : n = u.prod := (prod_factorMultiset n).symm; rw [this]
  have : m = v.prod := (prod_factorMultiset m).symm; rw [this]
  rw [← PrimeMultiset.prod_add]
  repeat' 

Proof state:
n m : ℕ+
u : PrimeMultiset := factorMultiset n
v : PrimeMultiset := factorMultiset m
this✝ : n = PrimeMultiset.prod u
this : m = PrimeMultiset.prod v
⊢ factorMultiset (PrimeMultiset.prod (u + v)) =
    factorMultiset (PrimeMultiset.prod u) + factorMultiset (PrimeMultiset.prod v)

Next tactic:
rw [PrimeMultiset.factorMultiset_prod]
theorem factorMultiset_mul (n m : ℕ+) :
    factorMultiset (n * m) = factorMultiset n + factorMultiset m := by
  let u := factorMultiset n
  let v := factorMultiset m
  have : n = u.prod := (prod_factorMultiset n).symm; rw [this]
  have : m = v.prod := (prod_factorMultiset m).symm; rw [this]
  rw [← PrimeMultiset.prod_add]
  repeat' 

Proof state:
n m : ℕ+
u : PrimeMultiset := factorMultiset n
v : PrimeMultiset := factorMultiset m
this✝ : n = PrimeMultiset.prod u
this : m = PrimeMultiset.prod v
⊢ u + v = factorMultiset (PrimeMultiset.prod u) + factorMultiset (PrimeMultiset.prod v)

Next tactic:
rw [PrimeMultiset.factorMultiset_prod]
theorem factorMultiset_mul (n m : ℕ+) :
    factorMultiset (n * m) = factorMultiset n + factorMultiset m := by
  let u := factorMultiset n
  let v := factorMultiset m
  have : n = u.prod := (prod_factorMultiset n).symm; rw [this]
  have : m = v.prod := (prod_factorMultiset m).symm; rw [this]
  rw [← PrimeMultiset.prod_add]
  repeat' 

Proof state:
n m : ℕ+
u : PrimeMultiset := factorMultiset n
v : PrimeMultiset := factorMultiset m
this✝ : n = PrimeMultiset.prod u
this : m = PrimeMultiset.prod v
⊢ u + v = u + factorMultiset (PrimeMultiset.prod v)

Next tactic:
rw [PrimeMultiset.factorMultiset_prod]
theorem factorMultiset_pow (n : ℕ+) (m : ℕ) :
    factorMultiset (Pow.pow n m) = m • factorMultiset n := by
  

Proof state:
n : ℕ+
m : ℕ
⊢ factorMultiset (Pow.pow n m) = m • factorMultiset n

Next tactic:
let u := factorMultiset n
theorem factorMultiset_pow (n : ℕ+) (m : ℕ) :
    factorMultiset (Pow.pow n m) = m • factorMultiset n := by
  let u := factorMultiset n
  

Proof state:
n : ℕ+
m : ℕ
u : PrimeMultiset := factorMultiset n
⊢ factorMultiset (Pow.pow n m) = m • factorMultiset n

Next tactic:
have : n = u.prod := (prod_factorMultiset n).symm
theorem factorMultiset_pow (n : ℕ+) (m : ℕ) :
    factorMultiset (Pow.pow n m) = m • factorMultiset n := by
  let u := factorMultiset n
  have : n = u.prod := (prod_factorMultiset n).symm
  

Proof state:
n : ℕ+
m : ℕ
u : PrimeMultiset := factorMultiset n
this : n = PrimeMultiset.prod u
⊢ factorMultiset (Pow.pow n m) = m • factorMultiset n

Next tactic:
rw [this, ← PrimeMultiset.prod_smul]
theorem factorMultiset_pow (n : ℕ+) (m : ℕ) :
    factorMultiset (Pow.pow n m) = m • factorMultiset n := by
  let u := factorMultiset n
  have : n = u.prod := (prod_factorMultiset n).symm
  rw [this, ← PrimeMultiset.prod_smul]
  

Proof state:
n : ℕ+
m : ℕ
u : PrimeMultiset := factorMultiset n
this : n = PrimeMultiset.prod u
⊢ factorMultiset (PrimeMultiset.prod (m • u)) = m • factorMultiset (PrimeMultiset.prod u)

Next tactic:
repeat' rw [PrimeMultiset.factorMultiset_prod]
theorem factorMultiset_pow (n : ℕ+) (m : ℕ) :
    factorMultiset (Pow.pow n m) = m • factorMultiset n := by
  let u := factorMultiset n
  have : n = u.prod := (prod_factorMultiset n).symm
  rw [this, ← PrimeMultiset.prod_smul]
  repeat' 

Proof state:
n : ℕ+
m : ℕ
u : PrimeMultiset := factorMultiset n
this : n = PrimeMultiset.prod u
⊢ factorMultiset (PrimeMultiset.prod (m • u)) = m • factorMultiset (PrimeMultiset.prod u)

Next tactic:
rw [PrimeMultiset.factorMultiset_prod]
theorem factorMultiset_pow (n : ℕ+) (m : ℕ) :
    factorMultiset (Pow.pow n m) = m • factorMultiset n := by
  let u := factorMultiset n
  have : n = u.prod := (prod_factorMultiset n).symm
  rw [this, ← PrimeMultiset.prod_smul]
  repeat' 

Proof state:
n : ℕ+
m : ℕ
u : PrimeMultiset := factorMultiset n
this : n = PrimeMultiset.prod u
⊢ m • u = m • factorMultiset (PrimeMultiset.prod u)

Next tactic:
rw [PrimeMultiset.factorMultiset_prod]
/-- Factoring a prime gives the corresponding one-element multiset. -/
theorem factorMultiset_ofPrime (p : Nat.Primes) :
    (p : ℕ+).factorMultiset = PrimeMultiset.ofPrime p := by
  

Proof state:
p : Nat.Primes
⊢ factorMultiset ↑p = PrimeMultiset.ofPrime p

Next tactic:
apply factorMultisetEquiv.symm.injective
/-- Factoring a prime gives the corresponding one-element multiset. -/
theorem factorMultiset_ofPrime (p : Nat.Primes) :
    (p : ℕ+).factorMultiset = PrimeMultiset.ofPrime p := by
  apply factorMultisetEquiv.symm.injective
  

Proof state:
case a
p : Nat.Primes
⊢ factorMultisetEquiv.symm (factorMultiset ↑p) = factorMultisetEquiv.symm (PrimeMultiset.ofPrime p)

Next tactic:
change (p : ℕ+).factorMultiset.prod = (PrimeMultiset.ofPrime p).prod
/-- Factoring a prime gives the corresponding one-element multiset. -/
theorem factorMultiset_ofPrime (p : Nat.Primes) :
    (p : ℕ+).factorMultiset = PrimeMultiset.ofPrime p := by
  apply factorMultisetEquiv.symm.injective
  change (p : ℕ+).factorMultiset.prod = (PrimeMultiset.ofPrime p).prod
  

Proof state:
case a
p : Nat.Primes
⊢ PrimeMultiset.prod (factorMultiset ↑p) = PrimeMultiset.prod (PrimeMultiset.ofPrime p)

Next tactic:
rw [(p : ℕ+).prod_factorMultiset, PrimeMultiset.prod_ofPrime]
/-- We now have four different results that all encode the
 idea that inequality of multisets corresponds to divisibility
 of positive integers. -/
theorem factorMultiset_le_iff {m n : ℕ+} : factorMultiset m ≤ factorMultiset n ↔ m ∣ n := by
  

Proof state:
m n : ℕ+
⊢ factorMultiset m ≤ factorMultiset n ↔ m ∣ n

Next tactic:
constructor
/-- We now have four different results that all encode the
 idea that inequality of multisets corresponds to divisibility
 of positive integers. -/
theorem factorMultiset_le_iff {m n : ℕ+} : factorMultiset m ≤ factorMultiset n ↔ m ∣ n := by
  constructor
  · 

Proof state:
case mp
m n : ℕ+
⊢ factorMultiset m ≤ factorMultiset n → m ∣ n

Next tactic:
intro h
/-- We now have four different results that all encode the
 idea that inequality of multisets corresponds to divisibility
 of positive integers. -/
theorem factorMultiset_le_iff {m n : ℕ+} : factorMultiset m ≤ factorMultiset n ↔ m ∣ n := by
  constructor
  · intro h
    

Proof state:
case mp
m n : ℕ+
h : factorMultiset m ≤ factorMultiset n
⊢ m ∣ n

Next tactic:
rw [← prod_factorMultiset m, ← prod_factorMultiset m]
/-- We now have four different results that all encode the
 idea that inequality of multisets corresponds to divisibility
 of positive integers. -/
theorem factorMultiset_le_iff {m n : ℕ+} : factorMultiset m ≤ factorMultiset n ↔ m ∣ n := by
  constructor
  · intro h
    rw [← prod_factorMultiset m, ← prod_factorMultiset m]
    

Proof state:
case mp
m n : ℕ+
h : factorMultiset m ≤ factorMultiset n
⊢ PrimeMultiset.prod (factorMultiset (PrimeMultiset.prod (factorMultiset m))) ∣ n

Next tactic:
apply Dvd.intro (n.factorMultiset - m.factorMultiset).prod
/-- We now have four different results that all encode the
 idea that inequality of multisets corresponds to divisibility
 of positive integers. -/
theorem factorMultiset_le_iff {m n : ℕ+} : factorMultiset m ≤ factorMultiset n ↔ m ∣ n := by
  constructor
  · intro h
    rw [← prod_factorMultiset m, ← prod_factorMultiset m]
    apply Dvd.intro (n.factorMultiset - m.factorMultiset).prod
    

Proof state:
case mp
m n : ℕ+
h : factorMultiset m ≤ factorMultiset n
⊢ PrimeMultiset.prod (factorMultiset (PrimeMultiset.prod (factorMultiset m))) *
      PrimeMultiset.prod (factorMultiset n - factorMultiset m) =
    n

Next tactic:
rw [← PrimeMultiset.prod_add, PrimeMultiset.factorMultiset_prod, add_tsub_cancel_of_le h,
      prod_factorMultiset]
/-- We now have four different results that all encode the
 idea that inequality of multisets corresponds to divisibility
 of positive integers. -/
theorem factorMultiset_le_iff {m n : ℕ+} : factorMultiset m ≤ factorMultiset n ↔ m ∣ n := by
  constructor
  · intro h
    rw [← prod_factorMultiset m, ← prod_factorMultiset m]
    apply Dvd.intro (n.factorMultiset - m.factorMultiset).prod
    rw [← PrimeMultiset.prod_add, PrimeMultiset.factorMultiset_prod, add_tsub_cancel_of_le h,
      prod_factorMultiset]
  · 

Proof state:
case mpr
m n : ℕ+
⊢ m ∣ n → factorMultiset m ≤ factorMultiset n

Next tactic:
intro h
/-- We now have four different results that all encode the
 idea that inequality of multisets corresponds to divisibility
 of positive integers. -/
theorem factorMultiset_le_iff {m n : ℕ+} : factorMultiset m ≤ factorMultiset n ↔ m ∣ n := by
  constructor
  · intro h
    rw [← prod_factorMultiset m, ← prod_factorMultiset m]
    apply Dvd.intro (n.factorMultiset - m.factorMultiset).prod
    rw [← PrimeMultiset.prod_add, PrimeMultiset.factorMultiset_prod, add_tsub_cancel_of_le h,
      prod_factorMultiset]
  · intro h
    

Proof state:
case mpr
m n : ℕ+
h : m ∣ n
⊢ factorMultiset m ≤ factorMultiset n

Next tactic:
rw [← mul_div_exact h, factorMultiset_mul]
/-- We now have four different results that all encode the
 idea that inequality of multisets corresponds to divisibility
 of positive integers. -/
theorem factorMultiset_le_iff {m n : ℕ+} : factorMultiset m ≤ factorMultiset n ↔ m ∣ n := by
  constructor
  · intro h
    rw [← prod_factorMultiset m, ← prod_factorMultiset m]
    apply Dvd.intro (n.factorMultiset - m.factorMultiset).prod
    rw [← PrimeMultiset.prod_add, PrimeMultiset.factorMultiset_prod, add_tsub_cancel_of_le h,
      prod_factorMultiset]
  · intro h
    rw [← mul_div_exact h, factorMultiset_mul]
    

Proof state:
case mpr
m n : ℕ+
h : m ∣ n
⊢ factorMultiset m ≤ factorMultiset m + factorMultiset (divExact n m)

Next tactic:
exact le_self_add
theorem factorMultiset_le_iff' {m : ℕ+} {v : PrimeMultiset} :
    factorMultiset m ≤ v ↔ m ∣ v.prod := by
  

Proof state:
m : ℕ+
v : PrimeMultiset
⊢ factorMultiset m ≤ v ↔ m ∣ PrimeMultiset.prod v

Next tactic:
let h := @factorMultiset_le_iff m v.prod
theorem factorMultiset_le_iff' {m : ℕ+} {v : PrimeMultiset} :
    factorMultiset m ≤ v ↔ m ∣ v.prod := by
  let h := @factorMultiset_le_iff m v.prod
  

Proof state:
m : ℕ+
v : PrimeMultiset
h : factorMultiset m ≤ factorMultiset (PrimeMultiset.prod v) ↔ m ∣ PrimeMultiset.prod v := factorMultiset_le_iff
⊢ factorMultiset m ≤ v ↔ m ∣ PrimeMultiset.prod v

Next tactic:
rw [v.factorMultiset_prod] at h
theorem factorMultiset_le_iff' {m : ℕ+} {v : PrimeMultiset} :
    factorMultiset m ≤ v ↔ m ∣ v.prod := by
  let h := @factorMultiset_le_iff m v.prod
  rw [v.factorMultiset_prod] at h
  

Proof state:
m : ℕ+
v : PrimeMultiset
h : factorMultiset m ≤ v ↔ m ∣ PrimeMultiset.prod v
⊢ factorMultiset m ≤ v ↔ m ∣ PrimeMultiset.prod v

Next tactic:
exact h
theorem prod_dvd_iff {u v : PrimeMultiset} : u.prod ∣ v.prod ↔ u ≤ v := by
  

Proof state:
u v : PrimeMultiset
⊢ prod u ∣ prod v ↔ u ≤ v

Next tactic:
let h := @PNat.factorMultiset_le_iff' u.prod v
theorem prod_dvd_iff {u v : PrimeMultiset} : u.prod ∣ v.prod ↔ u ≤ v := by
  let h := @PNat.factorMultiset_le_iff' u.prod v
  

Proof state:
u v : PrimeMultiset
h : PNat.factorMultiset (prod u) ≤ v ↔ prod u ∣ prod v := PNat.factorMultiset_le_iff'
⊢ prod u ∣ prod v ↔ u ≤ v

Next tactic:
rw [u.factorMultiset_prod] at h
theorem prod_dvd_iff {u v : PrimeMultiset} : u.prod ∣ v.prod ↔ u ≤ v := by
  let h := @PNat.factorMultiset_le_iff' u.prod v
  rw [u.factorMultiset_prod] at h
  

Proof state:
u v : PrimeMultiset
h : u ≤ v ↔ prod u ∣ prod v
⊢ prod u ∣ prod v ↔ u ≤ v

Next tactic:
exact h.symm
theorem prod_dvd_iff' {u : PrimeMultiset} {n : ℕ+} : u.prod ∣ n ↔ u ≤ n.factorMultiset := by
  

Proof state:
u : PrimeMultiset
n : ℕ+
⊢ prod u ∣ n ↔ u ≤ PNat.factorMultiset n

Next tactic:
let h := @prod_dvd_iff u n.factorMultiset
theorem prod_dvd_iff' {u : PrimeMultiset} {n : ℕ+} : u.prod ∣ n ↔ u ≤ n.factorMultiset := by
  let h := @prod_dvd_iff u n.factorMultiset
  

Proof state:
u : PrimeMultiset
n : ℕ+
h : prod u ∣ prod (PNat.factorMultiset n) ↔ u ≤ PNat.factorMultiset n := prod_dvd_iff
⊢ prod u ∣ n ↔ u ≤ PNat.factorMultiset n

Next tactic:
rw [n.prod_factorMultiset] at h
theorem prod_dvd_iff' {u : PrimeMultiset} {n : ℕ+} : u.prod ∣ n ↔ u ≤ n.factorMultiset := by
  let h := @prod_dvd_iff u n.factorMultiset
  rw [n.prod_factorMultiset] at h
  

Proof state:
u : PrimeMultiset
n : ℕ+
h : prod u ∣ n ↔ u ≤ PNat.factorMultiset n
⊢ prod u ∣ n ↔ u ≤ PNat.factorMultiset n

Next tactic:
exact h
/-- The gcd and lcm operations on positive integers correspond
 to the inf and sup operations on multisets. -/
theorem factorMultiset_gcd (m n : ℕ+) :
    factorMultiset (gcd m n) = factorMultiset m ⊓ factorMultiset n := by
  

Proof state:
m n : ℕ+
⊢ factorMultiset (gcd m n) = factorMultiset m ⊓ factorMultiset n

Next tactic:
apply le_antisymm
/-- The gcd and lcm operations on positive integers correspond
 to the inf and sup operations on multisets. -/
theorem factorMultiset_gcd (m n : ℕ+) :
    factorMultiset (gcd m n) = factorMultiset m ⊓ factorMultiset n := by
  apply le_antisymm
  · 

Proof state:
case a
m n : ℕ+
⊢ factorMultiset (gcd m n) ≤ factorMultiset m ⊓ factorMultiset n

Next tactic:
apply le_inf_iff.mpr
/-- The gcd and lcm operations on positive integers correspond
 to the inf and sup operations on multisets. -/
theorem factorMultiset_gcd (m n : ℕ+) :
    factorMultiset (gcd m n) = factorMultiset m ⊓ factorMultiset n := by
  apply le_antisymm
  · apply le_inf_iff.mpr; 

Proof state:
case a
m n : ℕ+
⊢ factorMultiset (gcd m n) ≤ factorMultiset m ∧ factorMultiset (gcd m n) ≤ factorMultiset n

Next tactic:
constructor
/-- The gcd and lcm operations on positive integers correspond
 to the inf and sup operations on multisets. -/
theorem factorMultiset_gcd (m n : ℕ+) :
    factorMultiset (gcd m n) = factorMultiset m ⊓ factorMultiset n := by
  apply le_antisymm
  · apply le_inf_iff.mpr; constructor <;> 

Proof state:
case a.left
m n : ℕ+
⊢ factorMultiset (gcd m n) ≤ factorMultiset m

Next tactic:
apply factorMultiset_le_iff.mpr
/-- The gcd and lcm operations on positive integers correspond
 to the inf and sup operations on multisets. -/
theorem factorMultiset_gcd (m n : ℕ+) :
    factorMultiset (gcd m n) = factorMultiset m ⊓ factorMultiset n := by
  apply le_antisymm
  · apply le_inf_iff.mpr; constructor <;> 

Proof state:
case a.right
m n : ℕ+
⊢ factorMultiset (gcd m n) ≤ factorMultiset n

Next tactic:
apply factorMultiset_le_iff.mpr
/-- The gcd and lcm operations on positive integers correspond
 to the inf and sup operations on multisets. -/
theorem factorMultiset_gcd (m n : ℕ+) :
    factorMultiset (gcd m n) = factorMultiset m ⊓ factorMultiset n := by
  apply le_antisymm
  · apply le_inf_iff.mpr; constructor <;> apply factorMultiset_le_iff.mpr
    

Proof state:
case a.left
m n : ℕ+
⊢ gcd m n ∣ m
case a.right m n : ℕ+ ⊢ gcd m n ∣ n

Next tactic:
exact gcd_dvd_left m n
/-- The gcd and lcm operations on positive integers correspond
 to the inf and sup operations on multisets. -/
theorem factorMultiset_gcd (m n : ℕ+) :
    factorMultiset (gcd m n) = factorMultiset m ⊓ factorMultiset n := by
  apply le_antisymm
  · apply le_inf_iff.mpr; constructor <;> apply factorMultiset_le_iff.mpr
    exact gcd_dvd_left m n
    

Proof state:
case a.right
m n : ℕ+
⊢ gcd m n ∣ n

Next tactic:
exact gcd_dvd_right m n
/-- The gcd and lcm operations on positive integers correspond
 to the inf and sup operations on multisets. -/
theorem factorMultiset_gcd (m n : ℕ+) :
    factorMultiset (gcd m n) = factorMultiset m ⊓ factorMultiset n := by
  apply le_antisymm
  · apply le_inf_iff.mpr; constructor <;> apply factorMultiset_le_iff.mpr
    exact gcd_dvd_left m n
    exact gcd_dvd_right m n
  · 

Proof state:
case a
m n : ℕ+
⊢ factorMultiset m ⊓ factorMultiset n ≤ factorMultiset (gcd m n)

Next tactic:
rw [← PrimeMultiset.prod_dvd_iff, prod_factorMultiset]
/-- The gcd and lcm operations on positive integers correspond
 to the inf and sup operations on multisets. -/
theorem factorMultiset_gcd (m n : ℕ+) :
    factorMultiset (gcd m n) = factorMultiset m ⊓ factorMultiset n := by
  apply le_antisymm
  · apply le_inf_iff.mpr; constructor <;> apply factorMultiset_le_iff.mpr
    exact gcd_dvd_left m n
    exact gcd_dvd_right m n
  · rw [← PrimeMultiset.prod_dvd_iff, prod_factorMultiset]
    

Proof state:
case a
m n : ℕ+
⊢ PrimeMultiset.prod (factorMultiset m ⊓ factorMultiset n) ∣ gcd m n

Next tactic:
apply dvd_gcd
/-- The gcd and lcm operations on positive integers correspond
 to the inf and sup operations on multisets. -/
theorem factorMultiset_gcd (m n : ℕ+) :
    factorMultiset (gcd m n) = factorMultiset m ⊓ factorMultiset n := by
  apply le_antisymm
  · apply le_inf_iff.mpr; constructor <;> apply factorMultiset_le_iff.mpr
    exact gcd_dvd_left m n
    exact gcd_dvd_right m n
  · rw [← PrimeMultiset.prod_dvd_iff, prod_factorMultiset]
    apply dvd_gcd <;> 

Proof state:
case a.hm
m n : ℕ+
⊢ PrimeMultiset.prod (factorMultiset m ⊓ factorMultiset n) ∣ m

Next tactic:
rw [PrimeMultiset.prod_dvd_iff']