Section inv.
Let Zp_invert_full x : { i | (x = Zp -> i = Zp) /\ (x <> Zp -> i ⊗ x = Op) }.
Definition Zp_invert x := proj1_sig (Zp_invert_full x).
Fact Zp_invert_spec1 : Zp_invert Zp = Zp.
Fact Zp_invert_opp x : inv (∸x) = ∸(inv x).
Fact Zp_invert_one : inv Op = Op.
Fact Zp_invert_minus_one : inv (∸ Op) = ∸ Op.
Fact Zp_invert_involutive x : inv (inv x) = x.
Fact Zp_invert_not_fix n : (1 < n < p-1)%nat -> inv〚n〛<>〚n〛.
Fact Zp_invert_stable n : (1 < n < p-1)%nat -> exists m, (1 < m < p-1)%nat /\〚m〛= inv〚n〛.
Definition Zp_lprod := fold_right Zp_mult Zp_one.
Fact Zp_lprod_nil : Zp_lprod nil = Op.
Fact Zp_lprod_fact n : 〚fact (S n)〛= Zp_lprod (map nat2Zp (list_an 2 n)).
End prime.
Fact Zp_divides_and_invertible d k n i : (d * k = n)%nat ->〚i〛⊗〚d〛= Op ->〚k〛=〚i〛⊗〚n〛.
End Z2Zp.
End Zp.
Fact divides_not_0_interval p q : q <> 0 -> divides p q -> 1 <= p <= q.
Fact divides_fact_lt q n : 1 <= q <= n -> divides q (fact n).

Theorem Wilson_theorem p : 2 <= p -> prime p <-> divides p (fact (p-1)+1).