Definition Red (L : list (poly A0 eqA ltM)) : list (poly A0 eqA ltM) :=
  redacc L nil.

(* Specifications: *)
Theorem Red_cb : forall (L : list (poly A0 eqA ltM)) (p : poly A0 eqA ltM), In p (Red L) -> Cb A A0 eqA plusA multA eqA_dec n ltM ltM_dec p L.
Theorem cb_redacc : forall (L1 L2 : list (poly A0 eqA ltM)) (p : poly A0 eqA ltM), In p L1 -> Cb A A0 eqA plusA multA eqA_dec n ltM ltM_dec p (redacc L1 L2 ++ L2).
Theorem Cb_Red : forall (L : list (poly A0 eqA ltM)) (p : poly A0 eqA ltM), In p L -> Cb A A0 eqA plusA multA eqA_dec n ltM ltM_dec p (Red L).
Theorem cb_Red_cb1 : forall (p : poly A0 eqA ltM) (L : list (poly A0 eqA ltM)), Cb A A0 eqA plusA multA eqA_dec n ltM ltM_dec p L -> Cb A A0 eqA plusA multA eqA_dec n ltM ltM_dec p (Red L).
Theorem cb_Red_cb2 : forall (p : poly A0 eqA ltM) (L : list (poly A0 eqA ltM)), Cb A A0 eqA plusA multA eqA_dec n ltM ltM_dec p (Red L) -> Cb A A0 eqA plusA multA eqA_dec n ltM ltM_dec p L.
Theorem divp_id : forall p : poly A0 eqA ltM, ~ zerop A A0 eqA n ltM p -> divp A A0 eqA multA divA n ltM p p.
Theorem redacc_divp : forall (L1 L2 : list (poly A0 eqA ltM)) (p : poly A0 eqA ltM), ~ zerop A A0 eqA n ltM p -> In p (L1 ++ L2) -> exists q : poly A0 eqA ltM, In q (redacc L1 L2 ++ L2) /\ divp A A0 eqA multA divA n ltM p q /\ ~ zerop A A0 eqA n ltM q.
Theorem Red_divp : forall (L : list (poly A0 eqA ltM)) (p : poly A0 eqA ltM), In p L -> ~ zerop A A0 eqA n ltM p -> exists q : poly A0 eqA ltM, In q (Red L) /\ divp A A0 eqA multA divA n ltM p q /\ ~ zerop A A0 eqA n ltM q.
Theorem Red_grobner : forall L : list (poly A0 eqA ltM), Grobner A A0 A1 eqA plusA invA minusA multA divA eqA_dec n ltM ltM_dec L -> Grobner A A0 A1 eqA plusA invA minusA multA divA eqA_dec n ltM ltM_dec (Red L).