Section Pcomb.
Load "hCoefStructure".
Load "hOrderStructure".
Load "hSpoly".
Inductive CombLinear (Q : list (poly A0 eqA ltM)) :
list (Term A n) -> Prop :=
| CombLinear_0 : CombLinear Q (pO A n)
| CombLinear_1 :
forall (a : Term A n) (p q s : list (Term A n)),
~ zeroP (A:=A) A0 eqA (n:=n) a ->
inPolySet A A0 eqA n ltM q Q ->
CombLinear Q p ->
eqP A eqA n s
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(mults (A:=A) multA (n:=n) a q) p) -> CombLinear Q s.
Hint Resolve CombLinear_0 CombLinear_1.
intros Q p H'; elim H'; auto.
intros a p0 q s H'0 H'1 H'2 H'3 H'4.
apply
eqp_imp_canonical
with
(p := pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(mults (A:=A) multA (n:=n) a q) p0)
(1 := cs); auto.
apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n); auto.
apply canonical_pluspf; auto.
apply canonical_mults with (1 := cs); auto.
apply inPolySet_imp_canonical with (L := Q); auto.
Qed.
intros Q p H'; elim H'; auto.
intros q H'0 H'1; inversion H'1; auto.
intros a p0 q s H'0 H'1 H'2 H'3 H'4 q0 H'5 H'6.
cut (canonical A0 eqA ltM q); [ intros C0 | idtac ].
cut (canonical A0 eqA ltM s); [ intros C1 | idtac ].
apply CombLinear_1 with (a := a) (p := p0) (q := q); auto.
apply (eqp_trans _ _ _ _ _ _ _ _ _ cs n) with (y := s); auto;
apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n); auto.
apply eqp_imp_canonical with (p := q0) (1 := cs); auto.
apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n); auto.
apply inPolySet_imp_canonical with (L := Q); auto.
Qed.
Hint Resolve CombLinear_canonical.
intros Q p H'; elim H'; auto.
intros q H'0.
cut (canonical A0 eqA ltM q);
[ intros Op1 | apply CombLinear_canonical with (Q := Q); auto ].
apply CombLinear_comp with (p := q); auto.
apply
(eqp_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(pO A n) q); auto; apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n);
auto.
intros a p0 q s H'0 H'1 H'2 H'3 H'4 q0 H'5.
cut (canonical A0 eqA ltM q);
[ intros C0 | apply inPolySet_imp_canonical with (L := Q); auto ].
cut (canonical A0 eqA ltM q0);
[ intros Op1 | apply CombLinear_canonical with (Q := Q); auto ].
cut (canonical A0 eqA ltM p0);
[ intros Op2 | apply CombLinear_canonical with (Q := Q); auto ].
apply
CombLinear_1
with
(a := a)
(p := pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
p0 q0)
(q := q); auto.
apply
(eqp_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM)
ltM_dec (mults (A:=A) multA (n:=n) a q) p0) q0);
auto.
apply eqp_pluspf_com with (1 := cs); auto.
apply
eqp_imp_canonical
with
(p := pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(mults (A:=A) multA (n:=n) a q) p0)
(1 := cs); auto.
apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n); auto.
Qed.
Hint Resolve CombLinear_pluspf.
intros Q a p H' H'0; elim H'0; auto.
intros a0 p0 q s H'1 H'2 H'3 H'4 H'5.
cut (canonical A0 eqA ltM q);
[ intros C0 | apply inPolySet_imp_canonical with (L := Q); auto ].
cut (canonical A0 eqA ltM p0);
[ intros Op1 | apply CombLinear_canonical with (Q := Q); auto ].
apply
CombLinear_1
with
(a := multTerm (A:=A) multA (n:=n) a a0)
(p := mults (A:=A) multA (n:=n) a p0)
(q := q); auto.
apply
(eqp_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := mults (A:=A) multA (n:=n) a
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM)
ltM_dec (mults (A:=A) multA (n:=n) a0 q) p0));
auto.
apply
(eqp_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(mults (A:=A) multA (n:=n) a (mults (A:=A) multA (n:=n) a0 q))
(mults (A:=A) multA (n:=n) a p0)); auto.
apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n); auto.
Qed.
Hint Resolve CombLinear_mults1.
intros Q p H' q H'0; try assumption.
cut (canonical A0 eqA ltM p);
[ intros Op1 | apply CombLinear_canonical with (Q := Q); auto ].
cut (canonical A0 eqA ltM q);
[ intros Op2 | apply CombLinear_canonical with (Q := Q); auto ].
apply
CombLinear_comp
with
(p := pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
p
(mults (A:=A) multA (n:=n) (invTerm (A:=A) invA (n:=n) (T1 A1 n))
q)); auto.
apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n); auto.
Qed.
Hint Resolve CombLinear_minuspf.
intros Q p H'.
cut (canonical A0 eqA ltM p);
[ intros C0 | apply inPolySet_imp_canonical with (L := Q); auto ].
apply
CombLinear_comp
with
(p := pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(mults (A:=A) multA (n:=n) (T1 A1 n) p)
(pO A n)); auto.
apply CombLinear_1 with (a := T1 A1 n) (p := pO A n) (q := p); auto.
apply
(eqp_trans _ _ _ _ _ _ _ _ _ cs n)
with (y := mults (A:=A) multA (n:=n) (T1 A1 n) p);
auto.
Qed.
Hint Resolve CombLinear_id.
intros Q p; case p.
simpl in |- *; auto.
intros a l q; case q.
simpl in |- *; auto.
intros a0 l0 Cp Cq H' H'0.
cut (canonical A0 eqA ltM l0);
[ intros Op1 | apply canonical_imp_canonical with (a := a0) ];
auto.
cut (canonical A0 eqA ltM l);
[ intros Op2 | apply canonical_imp_canonical with (a := a) ];
auto.
cut (~ zeroP (A:=A) A0 eqA (n:=n) a);
[ intros nZa | apply (canonical_nzeroP A A0 eqA n ltM) with (p := l); auto ].
cut (~ zeroP (A:=A) A0 eqA (n:=n) a0);
[ intros nZa0
| apply (canonical_nzeroP A A0 eqA n ltM) with (p := l0); auto ].
apply
CombLinear_comp
with
(p := minuspf A A0 A1 eqA invA minusA multA eqA_dec n ltM ltM_dec
(mults (A:=A) multA (n:=n)
(divTerm (A:=A) (A0:=A0) (eqA:=eqA) divA (n:=n)
(ppc (A:=A) A1 (n:=n) a a0) (b:=a) nZa)
(pX a l))
(mults (A:=A) multA (n:=n)
(divTerm (A:=A) (A0:=A0) (eqA:=eqA) divA (n:=n)
(ppc (A:=A) A1 (n:=n) a a0) (b:=a0) nZa0)
(pX a0 l0))); auto.
apply spolyf_canonical with (1 := cs); auto.
apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n); auto.
change
(eqP A eqA n
(spolyf A A0 A1 eqA invA minusA multA divA eqA_dec n ltM ltM_dec
(pX a l) (pX a0 l0) Cp Cq)
(minuspf A A0 A1 eqA invA minusA multA eqA_dec n ltM ltM_dec
(mults (A:=A) multA (n:=n)
(divTerm (A:=A) (A0:=A0) (eqA:=eqA) divA (n:=n)
(ppc (A:=A) A1 (n:=n) a a0) (b:=a) nZa)
(pX a l))
(mults (A:=A) multA (n:=n)
(divTerm (A:=A) (A0:=A0) (eqA:=eqA) divA (n:=n)
(ppc (A:=A) A1 (n:=n) a a0) (b:=a0) nZa0)
(pX a0 l0)))) in |- *.
apply spoly_is_minus with (1 := cs); auto.
Qed.
intros Q p q H'0 H'1 H'2.
case reduce_inv2 with (1 := cs) (3 := H'0); auto.
intros x H; elim H; intros a H0; elim H0; intros H1 H2; elim H2; intros H3 H4;
elim H4; intros H5 H6; clear H4 H2 H0 H.
apply CombLinear_1 with (a := a) (p := q) (q := x); auto.
apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n).
cut (canonical A0 eqA ltM q);
[ intros Op1 | apply canonical_reduce with (1 := cs) (3 := H'0) ];
auto.
apply
(eqp_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(mults (A:=A) multA (n:=n) a x)
(minuspf A A0 A1 eqA invA minusA multA eqA_dec n ltM ltM_dec p
(mults (A:=A) multA (n:=n) a x))); auto.
apply
(eqp_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(minuspf A A0 A1 eqA invA minusA multA eqA_dec n ltM ltM_dec p
(mults (A:=A) multA (n:=n) a x))
(mults (A:=A) multA (n:=n) a x)); auto.
apply pluspf_minuspf_id with (1 := cs); auto.
Qed.

Theorem CombLinear_reduceplus :
forall (Q : list (poly A0 eqA ltM)) (p q : list (Term A n)),
reduceplus A A0 A1 eqA invA minusA multA divA eqA_dec n ltM ltM_dec Q p q ->
canonical A0 eqA ltM p -> CombLinear Q q -> CombLinear Q p.