From elpi Require Import elpi.
From HB Require Import structures.
From mathcomp Require Import all_ssreflect.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
(**
----------------------------------------------------------
#
#
** Roadmap of the second lesson
Playing with basic arithmetics
- Order
- Division
- Primality
#
#
----------------------------------------------------------
*)
(**
----------------------------------------------------------
##
** Reminder
Natural numbers
#
#
*)
Check nat.
(* nat : Set *)
Print nat.
(* Inductive nat : Set :=
O : nat | S : nat -> nat *)
Check O.
(* 0 : nat *)
Check S O.
(* 1 : nat *)
Check S (S O).
(* 2 : nat *)
Check 2.+1.
(* 3 : nat *)
Set Printing All.
Check 4.
(* S (S (S O)) : nat *)
Unset Printing All.
Check 5.
(* 5 : nat *)
(**
#
#
----------------------------------------------------------
*)
(**
----------------------------------------------------------
##
** Reminder
Proof by case
#
#
*)
Goal forall (P : pred nat),
P 0 -> (forall n, P n.+1) -> forall n, P n.
Proof.
move=> P HP0 HPS n.
case: n => [|n].
exact: HP0.
by apply: HPS.
Qed.
(**
----------------------------------------------------------
#
#
#
#
*)
(**
----------------------------------------------------------
##
** Reminder
Proof by induction
#
#
*)
Goal forall (P : pred nat),
P 0 -> (forall n, P n -> P n.+1) -> forall n, P n.
Proof.
move=> P HP0 HPS n.
elim: n => [|n IH].
exact: HP0.
by apply: HPS.
Qed.
(**
----------------------------------------------------------
#
#
#
#
*)
(**
----------------------------------------------------------
##
** Reminder
Eq type
#
#
*)
Check eqn.
(* eqn : nat -> nat -> bool *)
Print eqn.
(* fix eqn (m n : nat) {struct m} : bool :=
match m with ... end. *)
Compute 1 == 1.
(* true : bool *)
Compute 2 == 3.
(* false : bool *)
Goal forall m n, m.+1 == n.+1 -> m == n.
Proof.
move=> m n mEn.
exact: mEn.
Qed.
(**
----------------------------------------------------------
#
#
#
#
*)
(**
----------------------------------------------------------
##
** Natural numbers
Addition
#
#
*)
Check addn.
(* addn : nat -> nat -> nat *)
Check addn 2 3.
(* 2 + 3 : nat *)
Compute 2 + 3.
(* 5 : nat *)
Goal forall m n, m.+1 + n = (m + n).+1.
Proof.
move=> m n.
by [].
Qed.
Search (_.+1 + _ = _.+1) in ssrnat.
(*
add1n: forall n : nat, 1 + n = n.+1
addSn: forall m n : nat, m.+1 + n = (m + n).+1
add2n: forall m : nat, 2 + m = m.+2
add3n: forall m : nat, 3 + m = m.+3
add4n: forall m : nat, 4 + m = m.+4
*)
Goal forall m n, m + n.+1 = (m + n).+1.
Proof.
move=> m n.
elim: m => [|m IH].
by [].
rewrite !addSn.
rewrite IH.
by [].
Qed.
Search (_ + _.+1 = _.+1) in ssrnat.
(*
addn1: forall n : nat, n + 1 = n.+1
addnS: forall m n : nat, m + n.+1 = (m + n).+1
addn2: forall m : nat, m + 2 = m.+2
addn3: forall m : nat, m + 3 = m.+3
addn4: forall m : nat, m + 4 = m.+4
*)
Search (_.+1 + _ = _ + _.+1) in ssrnat.
(* addSnnS: forall m n : nat, m.+1 + n = m + n.+1*)
(**
----------------------------------------------------------
#
#
#
#
*)
(**
----------------------------------------------------------
##
** Natural Numbers
Subtraction
#
#
*)
Check subn.
(* subn : nat -> nat -> nat *)
Check subn 3 2.
(* 3 - 2 : nat *)
Compute 3 - 2.
(* 1 : nat *)
Compute 3 - 4.
(* 0 : nat *)
Goal forall n, 0 - n = 0.
Proof.
move=> n.
by [].
Qed.
Search left_zero subn in ssrnat.
(* sub0n: left_zero 0 subn *)
Goal forall n, n - 0 = n.
Proof.
case => [|n].
- by [].
by [].
Qed.
Search (_.+1 - _.+1 = _) in ssrnat.
(* sub0n: left_zero 0 subn *)
(**
----------------------------------------------------------
#
#
#
#
*)
(**
----------------------------------------------------------
##
** Natural Numbers
Order
#
#
*)
Check leq.
(* nat -> nat -> bool *)
Check 0 <= 2.
(* 0 <= 2 : bool *)
Compute (0 <= 2).
(* true : bool *)
Print leq.
(* leq = fun m n : nat => m - n == 0
: nat -> nat -> bool
*)
(**
#
#
One definition several notations
#
#
*)
Goal forall m n, m >= n -> n <= m.
Proof.
by [].
Qed.
Goal forall m n, m.+1 <= n -> m < n.
Proof.
by [].
Qed.
Goal forall n, n <= n.+1.
Proof.
elim=> [|n IH].
by [].
exact: IH.
Qed.
Search (?_1 <= ?_1.+1) in ssrnat.
(* eqnSn: forall n : nat, n <= n.+1 *)
(**
#
#
Reflexivity
#
#
*)
Search (?_1 <= ?_1) in ssrnat.
(*
leqnn: forall n : nat, n <= n
ltnSn: forall n : nat, n < n.+1
*)
(**
#
#
Antisymmetry
#
#
*)
Search (~~ _) (_ <= _) in ssrnat.
(*#
ltnNge: forall m n : nat, (m < n) = ~~ (n <= m)
leqNgt: forall m n : nat, (m <= n) = ~~ (n < m)
lt0n_neq0: forall [n : nat], 0 < n -> n != 0
ltnNleqif: forall [x y : nat] [C : bool], x <= y ?= iff ~~ C -> (x < y) = C
ltn_leqif: forall [a b : nat] [C : bool], a <= b ?= iff C -> (a < b) = ~~ C
lt0n: forall n : nat, (0 < n) = (n != 0)
eqn0Ngt: forall n : nat_eqType, (n == 0) = ~~ (0 < n)
contraNleq: forall [b : bool] [m n : nat], (n < m -> b) -> ~~ b -> m <= n
contra_leqT: forall [b : bool] [m n : nat], (~~ b -> m < n) -> n <= m -> b
contra_ltnT: forall [b : bool] [m n : nat], (~~ b -> m <= n) -> n < m -> b
contraTleq: forall [b : bool] [m n : nat], (n < m -> ~~ b) -> b -> m <= n
contraNltn: forall [b : bool] [m n : nat], (n <= m -> b) -> ~~ b -> m < n
contra_ltnN: forall [b : bool] [m n : nat], (b -> m <= n) -> n < m -> ~~ b
contraTltn: forall [b : bool] [m n : nat], (n <= m -> ~~ b) -> b -> m < n
contra_leqN: forall [b : bool] [m n : nat], (b -> m < n) -> n <= m -> ~~ b
#*)
Search (_ == _ = _) (_ <= _) in ssrnat.
(*#
subn_eq0: forall m n : nat, (m - n == 0) = (m <= n)
eqn0Ngt: forall n : nat_eqType, (n == 0) = ~~ (0 < n)
eqn_leq: forall m n : nat_eqType, (m == n) = (m <= n <= m)
ltn_eqF: forall [m n : nat], m < n -> (m == n) = false
gtn_eqF: forall [m n : nat], m < n -> (n == m) = false
neq0_lt0n: forall [n : nat_eqType], (n == 0) = false -> 0 < n
expn_eq0: forall m e : nat, (m ^ e == 0) = (m == 0) && (0 < e)
eqn_pmul2l: forall [m n1 n2 : nat], 0 < m -> (m * n1 == m * n2) = (n1 == n2)
eqn_exp2r: forall (m n : nat) [e : nat], 0 < e -> (m ^ e == n ^ e) = (m == n)
eqn_pmul2r: forall [m n1 n2 : nat], 0 < m -> (n1 * m == n2 * m) = (n1 == n2)
eqn_exp2l:
forall [m : nat] (n1 n2 : nat), 1 < m -> (m ^ n1 == m ^ n2) = (n1 == n2)
#*)
(**
#
#
Transitivity
#
#
*)
Search nat "trans" in ssrnat.
(*#
leq_trans: forall [n m p : nat], m <= n -> n <= p -> m <= p
leqif_trans:
forall [m1 m2 m3 : nat] [C12 C23 : bool],
m1 <= m2 ?= iff C12 -> m2 <= m3 ?= iff C23 -> m1 <= m3 ?= iff C12 && C23
leq_ltn_trans: forall [n m p : nat], m <= n -> n < p -> m < p
ltn_trans: forall [n m p : nat], m < n -> n < p -> m < p
#*)
Goal forall m n p, m < n -> n <= p -> m < p.
Proof.
move=> m n p.
have trans := leq_trans.
have trans_Sm_n := leq_trans (_ : m < n) (_ : n <= p).
by [].
Qed.
Goal forall (P : pred nat),
P 0 ->
(forall m, (forall n, n <= m -> P n) -> P m.+1) ->
(forall m, P m).
Proof.
move=> P HC IHs m.
move: (leqnn m).
move: {-2}m.
elim: m => [|m IH].
by case.
case=> // n nLm.
apply: IHs => k kLn.
apply: IH.
apply: leq_trans kLn nLm.
Qed.
Goal forall a b c,
a < b -> b < c -> a <= c.
Proof.
move=> a b c aLb bLc.
apply: leq_trans (_ : b <= _).
by apply: ltnW.
by apply: ltnW.
Qed.
(**
#
#
Proof by case
#
#
*)
Goal forall (m : nat) (n : nat) (P : nat -> bool),
(n <= m -> P n) -> (m < n -> P n) -> P n.
Proof.
move=> m n P LP GP.
case: (leqP n m).
by apply: LP.
by apply: GP.
Qed.
Goal forall (m : nat) (n : nat) (P : nat -> bool),
(n < m -> P n) -> (m < n -> P n) -> (n = m -> P n) -> P n.
Proof.
move=> m n P LP GP EP.
case: (ltngtP n m).
- by apply: LP.
- by apply: GP.
by apply: EP.
Qed.
Check leq_eqVlt.
(* leq_eqVlt
: forall m n : nat, (m <= n) = (m == n) || (m < n)
*)
Goal forall (P : pred nat) m n, P n ->
(m < n -> P m) -> m <= n -> P m.
Proof.
move=> P m n Pn PL.
rewrite leq_eqVlt.
move=> /orP[|].
move/eqP->.
by [].
exact: PL.
Qed.
Goal forall (P : pred nat) m n, P n ->
(m < n -> P m) -> m <= n -> P m.
Proof.
move=> P m n Pn GP.
case: ltngtP.
- move=> mLn _.
by apply: GP.
- by [].
move=> -> _.
exact: Pn.
Qed.
(**
#
#
Addition
#
#
*)
Search (_ <= _ + _) in ssrnat.
(*#
leq_addr: forall m n : nat, n <= n + m
leq_addl: forall m n : nat, n <= m + n
leq_add2r: forall p m n : nat, (m + p <= n + p) = (m <= n)
leq_add2l: forall p m n : nat, (p + m <= p + n) = (m <= n)
ltn_addl: forall [m n : nat] (p : nat), m < n -> m < p + n
leq_subLR: forall m n p : nat, (m - n <= p) = (m <= n + p)
ltn_addr: forall [m n : nat] (p : nat), m < n -> m < n + p
ltn_add2r: forall p m n : nat, (m + p < n + p) = (m < n)
ltn_add2l: forall p m n : nat, (p + m < p + n) = (m < n)
leq_add:
forall [m1 m2 n1 n2 : nat], m1 <= n1 -> m2 <= n2 -> m1 + m2 <= n1 + n2
addn_gt0: forall m n : nat, (0 < m + n) = (0 < m) || (0 < n)
ltn_subLR: forall [m n : nat] (p : nat), n <= m -> (m - n < p) = (m < n + p)
ltn_psubLR: forall (m n : nat) [p : nat], 0 < p -> (m - n < p) = (m < n + p)
#*)
Goal forall m n, n <= m -> n.*2 <= m + n.
Proof.
move=> m n nLm.
rewrite -addnn.
rewrite leq_add2r.
by [].
Qed.
(**
#
#
Multiplication
#
#
*)
Search _ (_ <= _ * _) in ssrnat.
(*#
leq_pmulr: forall (m : nat) [n : nat], 0 < n -> m <= m * n
leq_pmull: forall (m : nat) [n : nat], 0 < n -> m <= n * m
leq_mul:
forall [m1 m2 n1 n2 : nat], m1 <= n1 -> m2 <= n2 -> m1 * m2 <= n1 * n2
ltn_Pmull: forall [m n : nat], 1 < n -> 0 < m -> m < n * m
ltn_Pmulr: forall [m n : nat], 1 < n -> 0 < m -> m < m * n
muln_gt0: forall m n : nat, (0 < m * n) = (0 < m) && (0 < n)
ltn_mul: forall [m1 m2 n1 n2 : nat], m1 < n1 -> m2 < n2 -> m1 * m2 < n1 * n2
leq_pmul2l: forall [m n1 n2 : nat], 0 < m -> (m * n1 <= m * n2) = (n1 <= n2)
leq_pmul2r: forall [m n1 n2 : nat], 0 < m -> (n1 * m <= n2 * m) = (n1 <= n2)
leq_mul2r: forall m n1 n2 : nat, (n1 * m <= n2 * m) = (m == 0) || (n1 <= n2)
leq_mul2l: forall m n1 n2 : nat, (m * n1 <= m * n2) = (m == 0) || (n1 <= n2)
ltn_mul2l: forall m n1 n2 : nat, (m * n1 < m * n2) = (0 < m) && (n1 < n2)
ltn_mul2r: forall m n1 n2 : nat, (n1 * m < n2 * m) = (0 < m) && (n1 < n2)
ltn_pmul2r: forall [m n1 n2 : nat], 0 < m -> (n1 * m < n2 * m) = (n1 < n2)
ltn_pmul2l: forall [m n1 n2 : nat], 0 < m -> (m * n1 < m * n2) = (n1 < n2)
#*)
Goal forall m n, n <= m -> n ^ 2 <= m * n.
Proof.
move=> m n nLm.
rewrite -mulnn.
rewrite leq_mul2r.
rewrite nLm.
rewrite orbT.
by [].
Qed.
(** Conditional comparison **)
Search (_ <= _ ?= iff _) (_ && _) in ssrnat.
(*#
eqif_trans:
forall [m1 m2 m3 : nat] [C12 C23 : bool],
m1 <= m2 ?= iff C12 -> m2 <= m3 ?= iff C23 -> m1 <= m3 ?= iff C12 && C23
leqif_add:
forall [m1 n1 : nat] [C1 : bool] [m2 n2 : nat] [C2 : bool],
m1 <= n1 ?= iff C1 ->
m2 <= n2 ?= iff C2 -> m1 + m2 <= n1 + n2 ?= iff C1 && C2
leqif_mul:
forall [m1 n1 : nat] [C1 : bool] [m2 n2 : nat] [C2 : bool],
m1 <= n1 ?= iff C1 ->
m2 <= n2 ?= iff C2 -> m1 * m2 <= n1 * n2 ?= iff (n1 * n2 == 0) || C1 && C2
#*)
(**
----------------------------------------------------------
#
#
#
#
*)
(**
----------------------------------------------------------
##
** Natural Numbers
Division
#
#
*)
Check (modn 21 2).
(* 21 %% 2 : nat *)
Compute 21 %% 2.
(* 1 : nat *)
Check (divn 21 2).
(* 21 %/ 2 : nat *)
Compute 21 %/ 2.
(* 10 : nat *)
Check (dvdn 2 21).
Compute 2 %| 21.
Print dvdn.
(*#
dvdn = fun d m : nat => m %% d == 0
: nat -> nat -> bool
#*)
Search (_ %| _ + _) in div.
(*#
dvdn_add: forall [d m n : nat], d %| m -> d %| n -> d %| m + n
dvdn_add_eq: forall [d m n : nat], d %| m + n -> (d %| m) = (d %| n)
dvdn_addl: forall [n d : nat] (m : nat), d %| n -> (d %| m + n) = (d %| m)
dvdn_addr: forall [m d : nat] (n : nat), d %| m -> (d %| m + n) = (d %| n)
Bezoutl:
forall [m : nat] (n : nat),
0 < m -> {a : nat | a < m & m %| gcdn m n + a * n}
Bezoutr:
forall (m : nat) [n : nat],
0 < n -> {a : nat | a < n & n %| gcdn m n + a * m}
#*)
Search ((_ + _) %/ _) in div.
(*#
divnDr:
forall (m : nat) [n d : nat], d %| n -> (m + n) %/ d = m %/ d + n %/ d
divnDl:
forall [m : nat] (n : nat) [d : nat],
d %| m -> (m + n) %/ d = m %/ d + n %/ d
leq_divDl: forall p m n : nat, (m + n) %/ p <= m %/ p + n %/ p + 1
divnDMl: forall (q m : nat) [d : nat], 0 < d -> (m + q * d) %/ d = m %/ d + q
divnMDl: forall (q m : nat) [d : nat], 0 < d -> (q * d + m) %/ d = q + m %/ d
divnD:
forall (m n : nat) [d : nat],
0 < d -> (m + n) %/ d = m %/ d + n %/ d + (d <= m %% d + n %% d)
#*)
Search (?_1 %/ ?_1) in div.
(*# divnn: forall d : nat, d %/ d = (0 < d) #*)
Compute 0 %/ 0.
(*# 0 : nat #*)
Search (_ %| _ * _) in div.
(*#
dvdn_mulr: forall [d m : nat] (n : nat), d %| m -> d %| m * n
dvdn_mull: forall [d : nat] (m : nat) [n : nat], d %| n -> d %| m * n
dvdn_mul:
forall [d1 d2 m1 m2 : nat], d1 %| m1 -> d2 %| m2 -> d1 * d2 %| m1 * m2
Gauss_dvdl:
forall [m : nat] (n : nat) [p : nat],
coprime m p -> (m %| n * p) = (m %| n)
Gauss_dvdr:
forall [m n : nat] (p : nat), coprime m n -> (m %| n * p) = (m %| p)
dvdn_pmul2l: forall [p d m : nat], 0 < p -> (p * d %| p * m) = (d %| m)
dvdn_pmul2r: forall [p d m : nat], 0 < p -> (d * p %| m * p) = (d %| m)
dvdn_divLR:
forall [p d : nat] (m : nat),
0 < p -> p %| d -> (d %/ p %| m) = (d %| m * p)
#*)
Search ((_ * _) %/ _) in div.
(*#
divnA: forall (m : nat) [n p : nat], p %| n -> m %/ (n %/ p) = (m * p) %/ n
muln_divA:
forall [d : nat] (m : nat) [n : nat], d %| n -> m * (n %/ d) = (m * n) %/ d
divn_mulAC: forall [d m : nat] (n : nat), d %| m -> m %/ d * n = (m * n) %/ d
mulKn: forall (m : nat) [d : nat], 0 < d -> (d * m) %/ d = m
mulnK: forall (m : nat) [d : nat], 0 < d -> (m * d) %/ d = m
divnMl: forall [p m d : nat], 0 < p -> (p * m) %/ (p * d) = m %/ d
divnMr: forall [p m d : nat], 0 < p -> (m * p) %/ (d * p) = m %/ d
#*)
(**
----------------------------------------------------------
#
#
#
#
*)
(**
----------------------------------------------------------
##
** Natural Numbers
Odd
#
#
*)
Compute odd 4.
(* false : bool *)
Compute odd 5.
(* true : bool *)
Print odd.
(*
odd =
fix odd (n : nat) : bool :=
match n with
| 0 => false
| n'.+1 => ~~ odd n'
end
: nat -> bool
*)
Search odd (_ %% _) in div.
(*#
modn2: forall m : nat, m %% 2 = odd m
odd_mod: forall (m : nat) [d : nat], odd d = false -> odd (m %% d) = odd m
#*)
(**
----------------------------------------------------------
#
#
#
#
*)
(**
----------------------------------------------------------
##
** Natural Numbers
Gcd and Lcm
#
#
*)
Compute gcdn 42 49.
(* 7 : nat *)
Compute lcmn 42 49.
(* 294 : nat *)
Search gcdn lcmn in div.
(*
muln_lcm_gcd: forall m n : nat, lcmn m n * gcdn m n = m * n
*)
Search gcdn (_ * _) in div.
(*#
gcdnMr: forall n m : nat, gcdn n (n * m) = n
gcdnMl: forall n m : nat, gcdn n (m * n) = n
muln_lcm_gcd: forall m n : nat, lcmn m n * gcdn m n = m * n
gcdnMDl: forall k m n : nat, gcdn m (k * m + n) = gcdn m n
muln_divCA_gcd: forall n m : nat, n * (m %/ gcdn n m) = m * (n %/ gcdn n m)
Gauss_gcdl:
forall [p : nat] (m : nat) [n : nat],
coprime p n -> gcdn p (m * n) = gcdn p m
Gauss_gcdr:
forall [p m : nat] (n : nat), coprime p m -> gcdn p (m * n) = gcdn p n
Bezoutl:
forall [m : nat] (n : nat),
0 < m -> {a : nat | a < m & m %| gcdn m n + a * n}
Bezoutr:
forall (m : nat) [n : nat],
0 < n -> {a : nat | a < n & n %| gcdn m n + a * m}
EgcdnSpec:
forall [m n km kn : nat],
km * m = kn * n + gcdn m n -> kn * gcdn m n < m -> egcdn_spec m n (km, kn)
#*)
(**
----------------------------------------------------------
#
#
#
#
*)
(**
----------------------------------------------------------
##
** Natural Numbers
Coprime & Prime
#
#
*)
Check coprime.
(* coprime : nat -> nat -> bool *)
Compute coprime 3 5.
(* true : bool *)
Compute coprime 21 7.
(* false : true *)
Print coprime.
(*
coprime = fun m n : nat => gcdn m n == 1
: nat -> nat -> bool
*)
Search coprime (_ %| _) in div prime.
(*#
coprime_dvdr: forall [m n p : nat], m %| n -> coprime p n -> coprime p m
coprime_dvdl: forall [m n p : nat], m %| n -> coprime n p -> coprime m p
prime_coprime:
forall [p : nat] (m : nat), prime p -> coprime p m = ~~ (p %| m)
Gauss_dvdr:
forall [m n : nat] (p : nat), coprime m n -> (m %| n * p) = (m %| p)
Gauss_dvdl:
forall [m : nat] (n : nat) [p : nat],
coprime m p -> (m %| n * p) = (m %| n)
Gauss_dvd:
forall [m n : nat] (p : nat),
coprime m n -> (m * n %| p) = (m %| p) && (n %| p)
#*)
Check prime.
(* prime : nat -> bool *)
Compute prime 21.
(* false : bool *)
Compute prime 22.
(* false : bool *)
Compute prime 23.
(* true : bool *)
Print prime.
(*#
prime =
fun p : nat =>
match prime_decomp p with
| [:: (_, 1)] => true
| _ => false
end : nat -> bool
#*)
Compute primes 21.
(*# [:: 3, 7] : seq nat #*)
Compute primes 22.
(*# [:: 2; 11] : seq nat #*)
Compute primes 23.
(*# [:: 23] : seq nat #*)
Check primeP.
(*#
primeP
: reflect (1 < ?p /\ (forall d : nat, d %| ?p -> (d == 1) || (d == ?p)))
(prime ?p)
#*)
Goal prime 2.
Proof.
apply/primeP.
split.
by [].
move=> d.
case: d.
by [].
case.
by [].
by case.
Qed.
Search prime (_ %| _) in div prime.
(*#
Euclid_dvd1: forall [p : nat], prime p -> (p %| 1) = false
prime_coprime:
forall [p : nat] (m : nat), prime p -> coprime p m = ~~ (p %| m)
dvdn_prime2: forall [p q : nat], prime p -> prime q -> (p %| q) = (p == q)
pdivP: forall [n : nat], 1 < n -> {p : nat | prime p & p %| n}
Euclid_dvdM:
forall (m n : nat) [p : nat],
prime p -> (p %| m * n) = (p %| m) || (p %| n)
p'natE: forall [p : nat] (n : nat), prime p -> (p^').-nat n = ~~ (p %| n)
Euclid_dvdX:
forall (m n : nat) [p : nat], prime p -> (p %| m ^ n) = (p %| m) && (0 < n)
dvdn_pfactor:
forall [p : nat] (d n : nat),
prime p -> reflect (exists2 m : nat, m <= n & d = p ^ m) (d %| p ^ n)
lognE:
forall p m : nat,
logn p m =
(if [&& prime p, 0 < m & p %| m] then (logn p (m %/ p)).+1 else 0)
pfactor_dvdn:
forall [p : nat] (n : nat) [m : nat],
prime p -> 0 < m -> (p ^ n %| m) = (n <= logn p m)
prime_nt_dvdP:
forall [d : nat_eqType] [p : nat],
prime p -> d != 1 -> reflect (d = p) (d %| p)
pnatP:
forall (pi : nat_pred) [n : nat],
0 < n ->
reflect (forall p : nat, prime p -> p %| n -> p \in pi) (pi.-nat n)
mem_primes:
forall (p : nat_eqType) (n : nat),
(p \in primes n) = [&& prime p, 0 < n & p %| n]
primePn:
forall {n : nat},
reflect (n < 2 \/ (exists2 d : nat, 1 < d < n & d %| n)) (~~ prime n)
logn_count_dvd:
forall [p : nat] (n : nat),
prime p -> logn p n = \sum_(1 <= k < n) (p ^ k %| n)
primePns:
forall {n : nat},
reflect (n < 2 \/ (exists p : nat, [/\ prime p, p ^ 2 <= n & p %| n]))
(~~ prime n)
primeP:
forall {p : nat},
reflect (1 < p /\ (forall d : nat, d %| p -> xpred2 1 p d)) (prime p)
Euclid_dvd_prod:
forall [I : Type] (r : seq I) (P : pred I) (f : I -> nat) [p : nat],
prime p ->
(p %| \prod_(i <- r | P i) f i) = \big[orb/false]_(i <- r | P i) (p %| f i)
mem_prime_decomp:
forall [n : nat] [p e : nat_eqType],
(p, e) \in prime_decomp n -> [/\ prime p, 0 < e & p ^ e %| n]
#*)
Check logn.
(* logn : nat -> nat -> nat*)
Compute logn 3 8.
(* 0 : nat *)
Compute logn 3 9.
(* 2 : nat *)
Search logn in prime.
(*#
logn0: forall p : nat, logn p 0 = 0
logn1: forall p : nat, logn p 1 = 0
pfactor_dvdnn: forall p n : nat, p ^ logn p n %| n
logn_part: forall p m : nat, logn p m`_p = logn p m
logn_coprime: forall [p m : nat], coprime p m -> logn p m = 0
lognX: forall p m n : nat, logn p (m ^ n) = n * logn p m
p_part: forall p n : nat, n`_p = p ^ logn p n
pfactorK: forall [p : nat] (n : nat), prime p -> logn p (p ^ n) = n
pfactor_gt0: forall p n : nat, 0 < p ^ logn p n
ltn_logl: forall (p : nat) [n : nat], 0 < n -> logn p n < n
ltn_log0: forall [p n : nat], n < p -> logn p n = 0
logn_Gauss:
forall [p m : nat] (n : nat), coprime p m -> logn p (m * n) = logn p n
pfactorKpdiv:
forall [p : nat] (n : nat), prime p -> logn (pdiv (p ^ n)) (p ^ n) = n
logn_prime: forall (p : nat) [q : nat], prime q -> logn p q = (p == q)
logn_div:
forall (p : nat) [m n : nat],
m %| n -> logn p (n %/ m) = logn p n - logn p m
dvdn_leq_log:
forall (p : nat) [m n : nat], 0 < n -> m %| n -> logn p m <= logn p n
prime_decompE:
forall n : nat, prime_decomp n = [seq (p, logn p n) | p <- primes n]
eqn_from_log:
forall [m n : nat], 0 < m -> 0 < n -> logn^~ m =1 logn^~ n -> m = n
logn_gt0: forall p n : nat, (0 < logn p n) = (p \in primes n)
lognE:
forall p m : nat,
logn p m =
(if [&& prime p, 0 < m & p %| m] then (logn p (m %/ p)).+1 else 0)
logn_lcm:
forall (p : nat) [m n : nat],
0 < m -> 0 < n -> logn p (lcmn m n) = maxn (logn p m) (logn p n)
lognM:
forall (p : nat) [m n : nat],
0 < m -> 0 < n -> logn p (m * n) = logn p m + logn p n
logn_gcd:
forall (p : nat) [m n : nat],
0 < m -> 0 < n -> logn p (gcdn m n) = minn (logn p m) (logn p n)
pfactor_dvdn:
forall [p : nat] (n : nat) [m : nat],
prime p -> 0 < m -> (p ^ n %| m) = (n <= logn p m)
pfactor_coprime:
forall [p n : nat],
prime p -> 0 < n -> {m : nat | coprime p m & n = m * p ^ logn p n}
logn_count_dvd:
forall [p : nat] (n : nat),
prime p -> logn p n = \sum_(1 <= k < n) (p ^ k %| n)
totientE:
forall [n : nat],
0 < n -> totient n = \prod_(p <- primes n) (p.-1 * p ^ (logn p n).-1)
widen_partn:
forall [m : nat] (pi : nat_pred) [n : nat],
n <= m -> n`_pi = \prod_(0 <= p < m.+1 | p \in pi) p ^ logn p n
eq_partn_from_log:
forall [m n : nat] [pi : nat_pred],
0 < m -> 0 < n -> {in pi, logn^~ m =1 logn^~ n} -> m`_pi = n`_pi
#*)
(**
----------------------------------------------------------
#
#
#
#
*)