Definition reducep (L : list (poly A0 eqA ltM)) (p q : poly A0 eqA ltM) :
  Prop :=
  reduce A A0 A1 eqA invA minusA multA divA eqA_dec n ltM ltM_dec L
    (s2p A A0 eqA n ltM p) (s2p A A0 eqA n ltM q).

(* Specifications: *)
Theorem grobner_def : forall L : list (poly A0 eqA ltM), Grobner A A0 A1 eqA plusA invA minusA multA divA eqA_dec n ltM ltM_dec L -> forall p : poly A0 eqA ltM, Cb A A0 eqA plusA multA eqA_dec n ltM ltM_dec p L -> zerop A A0 eqA n ltM p \/ (exists q : poly A0 eqA ltM, reducep L p q).
Theorem def_grobner : forall L : list (poly A0 eqA ltM), (forall p : poly A0 eqA ltM, Cb A A0 eqA plusA multA eqA_dec n ltM ltM_dec p L -> zerop A A0 eqA n ltM p \/ (exists q : poly A0 eqA ltM, reducep L p q)) -> Grobner A A0 A1 eqA plusA invA minusA multA divA eqA_dec n ltM ltM_dec L.
Theorem reduce_divp : forall (p q : poly A0 eqA ltM) (Q : list (poly A0 eqA ltM)), reduce A A0 A1 eqA invA minusA multA divA eqA_dec n ltM ltM_dec Q (s2p A A0 eqA n ltM p) (s2p A A0 eqA n ltM q) -> exists r : poly A0 eqA ltM, In r (q :: Q) /\ divp A A0 eqA multA divA n ltM p r /\ ~ zerop A A0 eqA n ltM r.
Theorem reduceplus_divp_lem : forall (a b : list (Term A n)) (Q : list (poly A0 eqA ltM)), reduceplus A A0 A1 eqA invA minusA multA divA eqA_dec n ltM ltM_dec Q a b -> canonical A0 eqA ltM a -> forall x y : poly A0 eqA ltM, s2p A A0 eqA n ltM x = a -> s2p A A0 eqA n ltM y = b -> ~ zerop A A0 eqA n ltM x -> exists r : poly A0 eqA ltM, In r (y :: Q) /\ divp A A0 eqA multA divA n ltM x r /\ ~ zerop A A0 eqA n ltM r.
Theorem reduceplus_divp : forall (a b : poly A0 eqA ltM) (Q : list (poly A0 eqA ltM)), reduceplus A A0 A1 eqA invA minusA multA divA eqA_dec n ltM ltM_dec Q (s2p A A0 eqA n ltM a) (s2p A A0 eqA n ltM b) -> ~ zerop A A0 eqA n ltM a -> exists r : poly A0 eqA ltM, In r (b :: Q) /\ divp A A0 eqA multA divA n ltM a r /\ ~ zerop A A0 eqA n ltM r.
Theorem reducestar_divp : forall (a b : poly A0 eqA ltM) (Q : list (poly A0 eqA ltM)), reducestar A A0 A1 eqA invA minusA multA divA eqA_dec n ltM ltM_dec Q (s2p A A0 eqA n ltM a) (s2p A A0 eqA n ltM b) -> ~ zerop A A0 eqA n ltM a -> exists r : poly A0 eqA ltM, In r (b :: Q) /\ divp A A0 eqA multA divA n ltM a r /\ ~ zerop A A0 eqA n ltM r.
Theorem nf_divp : forall (p : poly A0 eqA ltM) (L : list (poly A0 eqA ltM)), ~ zerop A A0 eqA n ltM p -> ~ zerop A A0 eqA n ltM (nf A A0 A1 eqA plusA invA minusA multA divA cs eqA_dec n ltM ltM_dec os p L) -> exists q : poly A0 eqA ltM, In q (nf A A0 A1 eqA plusA invA minusA multA divA cs eqA_dec n ltM ltM_dec os p L :: L) /\ divp A A0 eqA multA divA n ltM p q /\ ~ zerop A A0 eqA n ltM q.
Theorem divp_reduce1 : forall (p : poly A0 eqA ltM) (L1 L2 : list (poly A0 eqA ltM)), (forall r1 : poly A0 eqA ltM, In r1 L1 -> ~ zerop A A0 eqA n ltM r1 -> exists r2 : poly A0 eqA ltM, In r2 L2 /\ divp A A0 eqA multA divA n ltM r1 r2) -> forall q : poly A0 eqA ltM, reducep L1 p q -> exists r : poly A0 eqA ltM, reducep L2 p r.
Theorem nf_divp_zero : forall (p : poly A0 eqA ltM) (L : list (poly A0 eqA ltM)), ~ zerop A A0 eqA n ltM p -> zerop A A0 eqA n ltM (nf A A0 A1 eqA plusA invA minusA multA divA cs eqA_dec n ltM ltM_dec os p L) -> exists q : poly A0 eqA ltM, In q L /\ divp A A0 eqA multA divA n ltM p q /\ ~ zerop A A0 eqA n ltM q.
Theorem zerop_elim_cb : forall (L : list (poly A0 eqA ltM)) (p q : poly A0 eqA ltM), zerop A A0 eqA n ltM p -> Cb A A0 eqA plusA multA eqA_dec n ltM ltM_dec q (p :: L) -> Cb A A0 eqA plusA multA eqA_dec n ltM ltM_dec q L.
Theorem zerop_nf_cb : forall (L : list (poly A0 eqA ltM)) (p : poly A0 eqA ltM), zerop A A0 eqA n ltM (nf A A0 A1 eqA plusA invA minusA multA divA cs eqA_dec n ltM ltM_dec os p L) -> Cb A A0 eqA plusA multA eqA_dec n ltM ltM_dec p L.