(* pi- parts *)
(* Testing for membership in set of prime factors. *)
Coercion nat_pred_of_nat (p : nat) : nat_pred := pred1 p.
Section NatPreds.
Variables (n : nat) (pi : nat_pred).
Definition negn : nat_pred := [predC pi].
Definition pnat : pred nat := fun m => (m > 0) && all (mem pi) (primes m).
Definition partn := \prod_(0 <= p < n.+1 | p \in pi) p ^ logn p n.
End NatPreds.
Notation "pi ^'" := (negn pi) (at level 2, format "pi ^'") : nat_scope.
Notation "pi .-nat" := (pnat pi) (at level 2, format "pi .-nat") : nat_scope.
Notation "n `_ pi" := (partn n pi) : nat_scope.
Section PnatTheory.
Implicit Types (n p : nat) (pi rho : nat_pred).

(* Specifications: *)
Lemma negnK pi : pi^'^' =i pi.
Lemma part_gt0 pi n : 0 < n`_pi.
Lemma eq_in_partn pi1 pi2 n : {in \pi(n), pi1 =i pi2} -> n`_pi1 = n`_pi2.
Lemma eq_partn pi1 pi2 n : pi1 =i pi2 -> n`_pi1 = n`_pi2.
Lemma partn0 pi : 0`_pi = 1.
Lemma partnX pi m n : (m ^ n)`_pi = m`_pi ^ n.
Lemma partn_dvd pi m n : n > 0 -> m %| n -> m`_pi %| n`_pi.
Lemma p_part p n : n`_p = p ^ logn p n.
Lemma p_part_eq1 p n : (n`_p == 1) = (p \notin \pi(n)).
Lemma p_part_gt1 p n : (n`_p > 1) = (p \in \pi(n)).
Lemma filter_pi_of n m : n < m -> filter \pi(n) (index_iota 0 m) = primes n.
Lemma partn_pi n : n > 0 -> n`_\pi(n) = n.
Lemma partnT n : n > 0 -> n`_predT = n.
Lemma partnC pi n : n > 0 -> n`_pi * n`_pi^' = n.
Lemma dvdn_part pi n : n`_pi %| n.
Lemma partn_lcm pi m n : m > 0 -> n > 0 -> (lcmn m n)`_pi = lcmn m`_pi n`_pi.
Lemma partn_gcd pi m n : m > 0 -> n > 0 -> (gcdn m n)`_pi = gcdn m`_pi n`_pi.
Lemma partn_biglcm (I : finType) (P : pred I) F pi :
(forall i, P i -> F i > 0) ->
(\big[lcmn/1%N]_(i | P i) F i)`_pi = \big[lcmn/1%N]_(i | P i) (F i)`_pi.
Lemma partn_biggcd (I : finType) (P : pred I) F pi :
#|SimplPred P| > 0 -> (forall i, P i -> F i > 0) ->
(\big[gcdn/0]_(i | P i) F i)`_pi = \big[gcdn/0]_(i | P i) (F i)`_pi.
Lemma sub_in_pnat pi rho n :
{in \pi(n), {subset pi <= rho}} -> pi.-nat n -> rho.-nat n.
Lemma eq_in_pnat pi rho n : {in \pi(n), pi =i rho} -> pi.-nat n = rho.-nat n.
Lemma pnat_exp pi m n : pi.-nat (m ^ n) = pi.-nat m || (n == 0).
Lemma pnatE pi p : prime p -> pi.-nat p = (p \in pi).
Lemma pnat_pi n : n > 0 -> \pi(n).-nat n.
Lemma pi_ofM m n : m > 0 -> n > 0 -> \pi(m * n) =i [predU \pi(m) & \pi(n)].
Lemma pnatPpi pi n p : pi.-nat n -> p \in \pi(n) -> p \in pi.
Lemma pnat_coprime pi m n : pi.-nat m -> pi^'.-nat n -> coprime m n.
Lemma p'nat_coprime pi m n : pi^'.-nat m -> pi.-nat n -> coprime m n.
Lemma coprime_partC pi m n : coprime m`_pi n`_pi^'.
Lemma part_pnat_id pi n : pi.-nat n -> n`_pi = n.
Lemma part_p'nat pi n : pi^'.-nat n -> n`_pi = 1.
Lemma partn_eq1 pi n : n > 0 -> (n`_pi == 1) = pi^'.-nat n.
Lemma pnatP pi n :
n > 0 -> reflect (forall p, prime p -> p %| n -> p \in pi) (pi.-nat n).
Lemma pi_pnat pi p n : p.-nat n -> p \in pi -> pi.-nat n.
Lemma p_natP p n : p.-nat n -> {k | n = p ^ k}.
Lemma pi_p'nat p pi n : pi.-nat n -> p \in pi^' -> p^'.-nat n.
Lemma partnI pi rho n : n`_[predI pi & rho] = n`_pi`_rho.
Lemma odd_2'nat n : odd n = 2^'.-nat n.
Lemma sorted_divisors n : sorted leq (divisors n).
Lemma modn_partP n a b : 0 < n ->
reflect (forall p : nat, p \in \pi(n) -> a = b %[mod n`_p]) (a == b %[mod n]).