Notation Op := (Zp_one Hp).
Notation "∸" := (Zp_opp Hp).
Infix "⊗" := (Zp_mult Hp) (at level 40, left associativity).
Notation expoZp := (mscal (Zp_mult Hp) (Zp_one Hp)).
Hint Resolve Nat_mult_monoid.
Let Psi_Zp_eq n :〚Ψ n〛= expoZp n〚fact (p-1)〛.
Hypothesis (Hprime : prime p).
Let phi_Zp_invertible n r : r < p -> Zp_invertible Hp 〚φ n r〛.
Let Psi_Zp_invertible n : Zp_invertible Hp 〚Ψ n〛.
(** rewrite the binomial theorem  fact k * fact (n-k) * binomial n k = fact n  when  k = K*p + k0 n = N*p + n0  with  1)  K <= N & k0 <= n0  we get n-k = (N-K)*p + (n0-k0) and  expo K     p * fact K     * φ K      k0     * Ψ K .* expo (N-K) p * fact (N-K) * φ (N-K) (n0-k0) * Ψ (N-K) .* binomial n k = expo N p     * fact N     * φ N      n0     * Ψ N.  hence, simplifying by expo N p  we get  fact K * fact (N-K) * φ K k0 * Ψ K * φ (N-K) (n0-k0) * Ψ (N-K) * binomial n k = fact N * φ N n0 * Ψ N.  then in Z/Zp we derive (modulo Wilson's theorem, unnecessary here〚fact (p-1)〛=〚-1〛)  〚fact K〛⊗〚fact (N-K)〛⊗〚fact k0〛⊗〚-1〛^K⊗〚fact (n0-k0)〛⊗〚-1〛^(N-K)⊗〚binomial n k〛 =〚fact N〛⊗〚fact n0〛⊗〚-1〛^N  that we combine with 〚fact K〛⊗〚fact (N-K)〛⊗〚binomial N K〛=〚fact N〛 and  〚fact k0〛⊗〚fact (n0-k0)〛⊗〚binomial n0 k0〛=〚fact n0〛  to derive the result:〚binomial n k 〛=〚binomial N K〛⊗〚binomial n0 k0〛  with  2) K < N & n0 < k0  we have n-k = (N-(K+1))*p + (p-(k0-n0)) and  expo K         p * fact K         * φ K          k0         * Ψ K .* expo (N-(K+1)) p * fact (N-(K+1)) * φ (N-(K+1)) (p-(k0-n0)) * Ψ (N-(K+1)) .* binomial n k = expo N p     * fact N     * φ N      n0     * Ψ N.  hence  fact K * φ K k0 * Ψ K * fact (N-(K+1)) * φ (N-(K+1)) (p-(k0-n0)) * Ψ (N-(K+1)) * binomial n k = p * ....  then in Z/Zp all the left factor are invertible except binomial n k which must thus be〚0〛 *)
Section binomial_without_p_not_zero.
Variable (n N n0 k K k0 : nat) (Hn : n = N*p+n0) (Hk : k = K*p+k0) (H1 : K <= N) (H2 : k0 <= n0).
Let Hkn : k <= n.
Let Hnk : n - k = (N-K)*p+(n0-k0).
Fact binomial_wo_p : φ K k0 * Ψ K * φ (N-K) (n0-k0) * Ψ (N-K) * binomial n k
= binomial N K * φ N n0 * Ψ N.
Hypothesis (Hn0 : n0 < p).
Hint Resolve Zp_mult_monoid.
Fact binomial_Zp_prod :〚binomial n k〛=〚binomial N K〛⊗〚binomial n0 k0〛.
End binomial_without_p_not_zero.
Section binomial_without_p_zero.
Variable (n N n0 k K k0 : nat) (Hn : n = N*p+n0) (Hk : k = K*p+k0)
(H1 : K < N) (H2 : n0 < k0) (Hk0 : k0 < p).
Let H3 : p - (k0-n0) < p.    Proof. omega. Qed.
Let H4 : S (N-1) = N.        Proof. omega. Qed.
Let H5 : N-1 = K+(N-(K+1)).  Proof. omega. Qed.
Let H6 : N = K+1+(N-(K+1)).  Proof. omega. Qed.
Let HNK : N-K = S (N-(K+1)). Proof. omega. Qed.
Let Hkn : k <= n.
Let Hnk : n - k = (N-(K+1))*p+(p-(k0-n0)).
Fact binomial_with_p : fact K * fact (N-(K+1)) * φ K k0 * Ψ K * φ (N-(K+1)) (p-(k0-n0)) * Ψ (N-(K+1)) * binomial n k
= p * fact N * φ N n0 * Ψ N.
Fact binomial_with_p' : φ K k0 * Ψ K * φ (N-(K+1)) (p-(k0-n0)) * Ψ (N-(K+1)) * binomial n k
= p * binomial N K * (N-K) * φ N n0 * Ψ N.
Fact binomial_Zp_zero :〚binomial n k〛= Zp.
End binomial_without_p_zero.
End fact.
Section lucas_lemma.
(* https://math.stackexchange.com/questions/1463758/proof-of-lucas-theorem-without-the-polynomial-hint *)
Variables (p : nat) (Hprime : prime p).
Let Hp : p <> 0.
Variables (n N n0 k K k0 : nat)
(G1 : n = N*p+n0)  (G2 : n0 < p)
(G3 : k = K*p+k0)  (G4 : k0 < p).
Let choice : (K <= N  /\ k0 <= n0)
\/ (n0 < k0 /\ K < N)
\/ ((n0 < k0 \/ N < K) /\ n < k).

(* Specifications: *)
Theorem lucas_lemma : rem (binomial n k) p = rem (binomial N K * binomial n0 k0) p.
End lucas_lemma.