(**
   For all numbers q in natlist qlist: 1 is a linear combination
   of a^(m*qlist/qi) and n modulo n.
*)

Definition allLinCombMod (a : Z) (n m : nat) (qlist : natlist) :=
  alllist nat
    (fun q : nat =>
     LinCombMod 1 (Exp a (m * multDrop q qlist) - 1) (Z_of_nat n) n) qlist.

(* Specifications: *)
Lemma allLinCombMod_ok : forall (a : Z) (n m : nat) (qlist : natlist), allLinCombMod a n m qlist <-> (forall qi : nat, inlist nat qi qlist -> LinCombMod 1 (Exp a (m * multDrop qi qlist) - 1) (Z_of_nat n) n).
Theorem pocklington : forall (n q m : nat) (a : Z) (qlist : natlist), n > 1 -> n = S (q * m) -> q = product qlist -> allPrime qlist -> Mod (Exp a (pred n)) 1 n -> allLinCombMod a n m qlist -> n <= q * q -> Prime n.