File: Mathlib/Data/PNat/Factors.lean

full_name: PrimeMultiset
code: /-- The type of multisets of prime numbers.  Unique factorization
 gives an equivalence between this set and ℕ+, as we will formalize
 below. -/
def PrimeMultiset 
goal: Type

full_name: instOrderBotPrimeMultiset
code: instance : OrderBot PrimeMultiset 
goal: OrderBot PrimeMultiset

full_name: instOrderedSubPrimeMultiset
code: instance : OrderedSub PrimeMultiset 
goal: OrderedSub PrimeMultiset

full_name: PrimeMultiset.instRepr
code: unsafe instance : Repr PrimeMultiset 
goal: Repr PrimeMultiset

full_name: PrimeMultiset.ofPrime
code: /-- The multiset consisting of a single prime -/
def ofPrime (p : Nat.Primes) : PrimeMultiset 
goal: PrimeMultiset

full_name: PrimeMultiset.card_ofPrime
code: theorem card_ofPrime (p : Nat.Primes) : Multiset.card (ofPrime p) = 1 
goal: Multiset.card (PrimeMultiset.ofPrime p) = 1

full_name: PrimeMultiset.toNatMultiset
code: /-- We can forget the primality property and regard a multiset
 of primes as just a multiset of positive integers, or a multiset
 of natural numbers.  In the opposite direction, if we have a
 multiset of positive integers or natural numbers, together with
 a proof that all the elements are prime, then we can regard it
 as a multiset of primes.  The next block of results records
 obvious properties of these coercions.
-/
def toNatMultiset : PrimeMultiset → Multiset ℕ 
goal: PrimeMultiset → Multiset ℕ

full_name: PrimeMultiset.coeNat
code: instance coeNat : Coe PrimeMultiset (Multiset ℕ) 
goal: Coe PrimeMultiset (Multiset ℕ)

full_name: PrimeMultiset.coeNatMonoidHom
code: /-- `PrimeMultiset.coe`, the coercion from a multiset of primes to a multiset of
naturals, promoted to an `AddMonoidHom`. -/
def coeNatMonoidHom : PrimeMultiset →+ Multiset ℕ 
goal: PrimeMultiset →+ Multiset ℕ

full_name: PrimeMultiset.coe_coeNatMonoidHom
code: @[simp]
theorem coe_coeNatMonoidHom : (coeNatMonoidHom : PrimeMultiset → Multiset ℕ) = Coe.coe 
goal: ⇑PrimeMultiset.coeNatMonoidHom = Coe.coe

full_name: PrimeMultiset.coeNat_injective
code: theorem coeNat_injective : Function.Injective (Coe.coe : PrimeMultiset → Multiset ℕ) 
goal: Function.Injective Coe.coe

full_name: PrimeMultiset.coeNat_ofPrime
code: theorem coeNat_ofPrime (p : Nat.Primes) : (ofPrime p : Multiset ℕ) = {(p : ℕ)} 
goal: (PrimeMultiset.ofPrime p).toNatMultiset = {↑p}

full_name: PrimeMultiset.coeNat_prime
code: theorem coeNat_prime (v : PrimeMultiset) (p : ℕ) (h : p ∈ (v : Multiset ℕ)) : p.Prime 
goal: Nat.Prime p

full_name: PrimeMultiset.toPNatMultiset
code: /-- Converts a `PrimeMultiset` to a `Multiset ℕ+`. -/
def toPNatMultiset : PrimeMultiset → Multiset ℕ+ 
goal: PrimeMultiset → Multiset ℕ+

full_name: PrimeMultiset.coePNat
code: instance coePNat : Coe PrimeMultiset (Multiset ℕ+) 
goal: Coe PrimeMultiset (Multiset ℕ+)

full_name: PrimeMultiset.coePNatMonoidHom
code: /-- `coePNat`, the coercion from a multiset of primes to a multiset of positive
naturals, regarded as an `AddMonoidHom`. -/
def coePNatMonoidHom : PrimeMultiset →+ Multiset ℕ+ 
goal: PrimeMultiset →+ Multiset ℕ+

full_name: PrimeMultiset.coe_coePNatMonoidHom
code: @[simp]
theorem coe_coePNatMonoidHom : (coePNatMonoidHom : PrimeMultiset → Multiset ℕ+) = Coe.coe 
goal: ⇑PrimeMultiset.coePNatMonoidHom = Coe.coe

full_name: PrimeMultiset.coePNat_injective
code: theorem coePNat_injective : Function.Injective (Coe.coe : PrimeMultiset → Multiset ℕ+) 
goal: Function.Injective Coe.coe

full_name: PrimeMultiset.coePNat_ofPrime
code: theorem coePNat_ofPrime (p : Nat.Primes) : (ofPrime p : Multiset ℕ+) = {(p : ℕ+)} 
goal: (PrimeMultiset.ofPrime p).toPNatMultiset = {↑p}

full_name: PrimeMultiset.coePNat_prime
code: theorem coePNat_prime (v : PrimeMultiset) (p : ℕ+) (h : p ∈ (v : Multiset ℕ+)) : p.Prime 
goal: p.Prime

full_name: PrimeMultiset.coeMultisetPNatNat
code: instance coeMultisetPNatNat : Coe (Multiset ℕ+) (Multiset ℕ) 
goal: Coe (Multiset ℕ+) (Multiset ℕ)

full_name: PrimeMultiset.coePNat_nat
code: theorem coePNat_nat (v : PrimeMultiset) : ((v : Multiset ℕ+) : Multiset ℕ) = (v : Multiset ℕ) 
goal: Multiset.map PNat.val v.toPNatMultiset = v.toNatMultiset

full_name: PrimeMultiset.prod
code: /-- The product of a `PrimeMultiset`, as a `ℕ+`. -/
def prod (v : PrimeMultiset) : ℕ+ 
goal: ℕ+

full_name: PrimeMultiset.coe_prod
code: theorem coe_prod (v : PrimeMultiset) : (v.prod : ℕ) = (v : Multiset ℕ).prod 
goal: ↑v.prod = v.toNatMultiset.prod

full_name: PrimeMultiset.prod_ofPrime
code: theorem prod_ofPrime (p : Nat.Primes) : (ofPrime p).prod = (p : ℕ+) 
goal: (PrimeMultiset.ofPrime p).prod = ↑p

full_name: PrimeMultiset.ofNatMultiset
code: /-- If a `Multiset ℕ` consists only of primes, it can be recast as a `PrimeMultiset`. -/
def ofNatMultiset (v : Multiset ℕ) (h : ∀ p : ℕ, p ∈ v → p.Prime) : PrimeMultiset 
goal: PrimeMultiset

full_name: PrimeMultiset.to_ofNatMultiset
code: theorem to_ofNatMultiset (v : Multiset ℕ) (h) : (ofNatMultiset v h : Multiset ℕ) = v 
goal: (PrimeMultiset.ofNatMultiset v h).toNatMultiset = v

full_name: PrimeMultiset.prod_ofNatMultiset
code: theorem prod_ofNatMultiset (v : Multiset ℕ) (h) :
    ((ofNatMultiset v h).prod : ℕ) = (v.prod : ℕ) 
goal: ↑(PrimeMultiset.ofNatMultiset v h).prod = v.prod

full_name: PrimeMultiset.ofPNatMultiset
code: /-- If a `Multiset ℕ+` consists only of primes, it can be recast as a `PrimeMultiset`. -/
def ofPNatMultiset (v : Multiset ℕ+) (h : ∀ p : ℕ+, p ∈ v → p.Prime) : PrimeMultiset 
goal: PrimeMultiset

full_name: PrimeMultiset.to_ofPNatMultiset
code: theorem to_ofPNatMultiset (v : Multiset ℕ+) (h) : (ofPNatMultiset v h : Multiset ℕ+) = v 
goal: (PrimeMultiset.ofPNatMultiset v h).toPNatMultiset = v

full_name: PrimeMultiset.prod_ofPNatMultiset
code: theorem prod_ofPNatMultiset (v : Multiset ℕ+) (h) : ((ofPNatMultiset v h).prod : ℕ+) = v.prod 
goal: (PrimeMultiset.ofPNatMultiset v h).prod = v.prod

full_name: PrimeMultiset.ofNatList
code: /-- Lists can be coerced to multisets; here we have some results
about how this interacts with our constructions on multisets. -/
def ofNatList (l : List ℕ) (h : ∀ p : ℕ, p ∈ l → p.Prime) : PrimeMultiset 
goal: PrimeMultiset

full_name: PrimeMultiset.prod_ofNatList
code: theorem prod_ofNatList (l : List ℕ) (h) : ((ofNatList l h).prod : ℕ) = l.prod 
goal: ↑(PrimeMultiset.ofNatList l h).prod = l.prod

full_name: PrimeMultiset.ofPNatList
code: /-- If a `List ℕ+` consists only of primes, it can be recast as a `PrimeMultiset` with
the coercion from lists to multisets. -/
def ofPNatList (l : List ℕ+) (h : ∀ p : ℕ+, p ∈ l → p.Prime) : PrimeMultiset 
goal: PrimeMultiset

full_name: PrimeMultiset.prod_ofPNatList
code: theorem prod_ofPNatList (l : List ℕ+) (h) : (ofPNatList l h).prod = l.prod 
goal: (PrimeMultiset.ofPNatList l h).prod = l.prod

full_name: PrimeMultiset.prod_zero
code: /-- The product map gives a homomorphism from the additive monoid
of multisets to the multiplicative monoid ℕ+. -/
theorem prod_zero : (0 : PrimeMultiset).prod = 1 
goal: PrimeMultiset.prod 0 = 1

full_name: PrimeMultiset.prod_add
code: theorem prod_add (u v : PrimeMultiset) : (u + v).prod = u.prod * v.prod 
goal: (u + v).prod = u.prod * v.prod

full_name: PrimeMultiset.prod_smul
code: theorem prod_smul (d : ℕ) (u : PrimeMultiset) : (d • u).prod = u.prod ^ d 
goal: (d • u).prod = u.prod ^ d

full_name: PNat.factorMultiset
code: /-- The prime factors of n, regarded as a multiset -/
def factorMultiset (n : ℕ+) : PrimeMultiset 
goal: PrimeMultiset

full_name: PNat.prod_factorMultiset
code: /-- The product of the factors is the original number -/
theorem prod_factorMultiset (n : ℕ+) : (factorMultiset n).prod = n 
goal: n.factorMultiset.prod = n

full_name: PNat.coeNat_factorMultiset
code: theorem coeNat_factorMultiset (n : ℕ+) :
    (factorMultiset n : Multiset ℕ) = (Nat.primeFactorsList n : Multiset ℕ) 
goal: n.factorMultiset.toNatMultiset = ↑(↑n).primeFactorsList

full_name: PrimeMultiset.factorMultiset_prod
code: /-- 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 
goal: v.prod.factorMultiset = v

full_name: PNat.factorMultisetEquiv
code: /-- Positive integers biject with multisets of primes. -/
def factorMultisetEquiv : ℕ+ ≃ PrimeMultiset 
goal: ℕ+ ≃ PrimeMultiset

full_name: PNat.factorMultiset_one
code: /-- Factoring gives a homomorphism from the multiplicative
 monoid ℕ+ to the additive monoid of multisets. -/
theorem factorMultiset_one : factorMultiset 1 = 0 
goal: PNat.factorMultiset 1 = 0

full_name: PNat.factorMultiset_mul
code: theorem factorMultiset_mul (n m : ℕ+) :
    factorMultiset (n * m) = factorMultiset n + factorMultiset m 
goal: (n * m).factorMultiset = n.factorMultiset + m.factorMultiset

full_name: PNat.factorMultiset_pow
code: theorem factorMultiset_pow (n : ℕ+) (m : ℕ) :
    factorMultiset (n ^ m) = m • factorMultiset n 
goal: (n ^ m).factorMultiset = m • n.factorMultiset

full_name: PNat.factorMultiset_ofPrime
code: /-- Factoring a prime gives the corresponding one-element multiset. -/
theorem factorMultiset_ofPrime (p : Nat.Primes) :
    (p : ℕ+).factorMultiset = PrimeMultiset.ofPrime p 
goal: (↑p).factorMultiset = PrimeMultiset.ofPrime p

full_name: PNat.factorMultiset_le_iff
code: /-- 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 
goal: m.factorMultiset ≤ n.factorMultiset ↔ m ∣ n

full_name: PNat.factorMultiset_le_iff'
code: theorem factorMultiset_le_iff' {m : ℕ+} {v : PrimeMultiset} :
    factorMultiset m ≤ v ↔ m ∣ v.prod 
goal: m.factorMultiset ≤ v ↔ m ∣ v.prod

full_name: PrimeMultiset.prod_dvd_iff
code: theorem prod_dvd_iff {u v : PrimeMultiset} : u.prod ∣ v.prod ↔ u ≤ v 
goal: u.prod ∣ v.prod ↔ u ≤ v

full_name: PrimeMultiset.prod_dvd_iff'
code: theorem prod_dvd_iff' {u : PrimeMultiset} {n : ℕ+} : u.prod ∣ n ↔ u ≤ n.factorMultiset 
goal: u.prod ∣ n ↔ u ≤ n.factorMultiset

full_name: PNat.factorMultiset_gcd
code: /-- 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 
goal: (m.gcd n).factorMultiset = m.factorMultiset ⊓ n.factorMultiset

full_name: PNat.factorMultiset_lcm
code: theorem factorMultiset_lcm (m n : ℕ+) :
    factorMultiset (lcm m n) = factorMultiset m ⊔ factorMultiset n 
goal: (m.lcm n).factorMultiset = m.factorMultiset ⊔ n.factorMultiset

full_name: PNat.count_factorMultiset
code: /-- The number of occurrences of p in the factor multiset of m
 is the same as the p-adic valuation of m. -/
theorem count_factorMultiset (m : ℕ+) (p : Nat.Primes) (k : ℕ) :
    (p : ℕ+) ^ k ∣ m ↔ k ≤ m.factorMultiset.count p 
goal: ↑p ^ k ∣ m ↔ k ≤ Multiset.count p m.factorMultiset

full_name: PrimeMultiset.prod_inf
code: theorem prod_inf (u v : PrimeMultiset) : (u ⊓ v).prod = PNat.gcd u.prod v.prod 
goal: (u ⊓ v).prod = u.prod.gcd v.prod

full_name: PrimeMultiset.prod_sup
code: theorem prod_sup (u v : PrimeMultiset) : (u ⊔ v).prod = PNat.lcm u.prod v.prod 
goal: (u ⊔ v).prod = u.prod.lcm v.prod