(**************************************************************)
(*   Copyright Dominique Larchey-Wendling [*]                 *)
(*                                                            *)
(*                             [*] Affiliation LORIA -- CNRS  *)
(**************************************************************)
(*      This file is distributed under the terms of the       *)
(*         CeCILL v2 FREE SOFTWARE LICENSE AGREEMENT          *)
(**************************************************************)
(** ** Luca's theorem *)
Set Implicit Arguments.
Local Notation power := (mscal mult 1).
Local Notation expo := (mscal mult 1).
Section fact.
Let factorial_cancel n a b : fact n * a = fact n * b -> a = b.
Notation Π := (msum mult 1).
Notation mprod_an := (fun a n => Π n (fun i => i+a)).
Fact mprod_factorial n : fact n = mprod_an 1 n.
Variable (p : nat) (Hp : p <> 0).
Notation "〚 x 〛" := (nat2Zp Hp x).
Let expo_p_cancel n a b : expo n p * a = expo n p * b -> a = b.
Fact mprod_factorial_Zp i n :〚mprod_an (i*p+1) n〛=〚fact n〛.
Notation φ := (fun n r => mprod_an (n*p+1) r).
Notation Ψ := (fun n => Π n (fun i => mprod_an (i*p+1) (p-1))).
Let phi_Zp_eq n r :〚φ n r〛=〚fact r〛.

(* Specifications: *)
Lemma mprod_factorial_euclid n r : fact (n*p+r) = expo n p * fact n * φ n r * Ψ n.
Notation Zp := (Zp_zero Hp).