intros p q; case p; case q; simpl in |- *.
intros x H' x0 c Q H'0; inversion H'0.
generalize c; rewrite <- H2; simpl in |- *; auto.
case inPolySet_inv1 with (1 := H); auto.
intros q1 E; case E; intros H'1 H'2; clear E.
intros c0; exists q1; split; [ right | split ]; auto.
generalize H'2; case q1; simpl in |- *; auto.
intros x1; case x1; auto.
intros H'4 H'5; discriminate H'5; auto.
intros a0 l H'4 H'5; injection H'5; intros.
rewrite <- H5; trivial.
generalize H'1 H'2 c0; case q1; simpl in |- *; auto.
intros x1; case x1; auto.
intros c1 H'3 H'4; discriminate H'4.
exists (exist (fun l : list (Term A n) => canonical A0 eqA ltM l) x H');
split; [ left | split ]; simpl in |- *; auto.
generalize c; rewrite <- H1; unfold pX in |- *; auto.
generalize H'; rewrite <- H2; unfold pX in |- *; auto.
intros H'1 H'2.
apply divP_eqTerm_comp with (a := b) (1 := cs); auto.
cut (~ zeroP (A:=A) A0 eqA (n:=n) b); [ intros Z | idtac ]; auto.
apply divTerm_def with (nZb := Z); auto.
apply canonical_nzeroP with (ltM := ltM) (p := q0); auto.
apply (eqTerm_sym _ _ _ _ _ _ _ _ _ cs n); auto.
generalize c H'; rewrite <- H2; auto.
Qed.

(* Specifications: *)
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.