Section Pmults.
Load "hCoefStructure".
Load "hOrderStructure".
Load "hPlus".
Set Implicit Arguments.
Unset Strict Implicit.
Definition mults : Term A n -> list (Term A n) -> list (Term A n).
intros a p; elim p; clear p.
exact (pO A n).
intros b p1 p'1.
exact (pX (multTerm (A:=A) multA (n:=n) a b) p'1).
Defined.
Set Strict Implicit.
Unset Implicit Arguments.
Hint Resolve multTerm_eqT.
Hint Resolve invTerm_eqT.
Hint Resolve T1_is_min_ltT.
intros l; elim l; simpl in |- *; auto.
intros m1 m2 H' H'0.
apply canonicalp1; auto.
red in |- *; intros H'1; apply H'.
elim multTerm_zeroP_div with (1 := cs) (a := m1) (b := m2); auto; intros H'5.
absurd (zeroP (A:=A) A0 eqA (n:=n) m2); auto.
apply canonical_nzeroP with (ltM := ltM) (p := pO A n); auto.
intros a l0 H' m1 m2 H'0 H'1.
apply canonical_cons; auto.
apply multTerm_ltT_l; auto.
apply (canonical_pX_order A A0 eqA) with (l := l0); auto.
red in |- *; intros H'2; apply H'0.
elim multTerm_zeroP_div with (1 := cs) (a := m1) (b := m2); auto; intros H'5.
absurd (zeroP (A:=A) A0 eqA (n:=n) m2); auto.
apply canonical_nzeroP with (ltM := ltM) (p := pX a l0); auto.
apply H'; auto.
apply canonical_imp_canonical with (a := m2); auto.
Qed.
intros m l; elim l; simpl in |- *; auto.
intros a l0 H' H'0 H'1.
apply mults_order_l; auto.
Qed.
intros p; elim p; simpl in |- *; auto.
intros a l; case l; simpl in |- *; auto.
intros H' a0 H'0 H'1.
change (canonical A0 eqA ltM (pX a (pO A n))) in |- *; apply canonicalp1;
auto.
red in |- *; intros H'2;
absurd (zeroP (A:=A) A0 eqA (n:=n) (multTerm (A:=A) multA (n:=n) a0 a));
auto.
apply canonical_nzeroP with (ltM := ltM) (p := pO A n); auto.
intros a0 l0 H' a1 H'0 H'1.
change (canonical A0 eqA ltM (pX a (pX a0 l0))) in |- *.
apply canonical_cons; auto.
case (ltT_dec A n ltM ltM_dec a0 a);
[ intros temp; case temp; clear temp | idtac ]; intros H;
auto.
absurd
(ltT ltM (multTerm (A:=A) multA (n:=n) a1 a)
(multTerm (A:=A) multA (n:=n) a1 a0)); auto.
apply ltT_not_ltT; auto.
apply (canonical_pX_order A A0 eqA) with (l := mults a1 l0); auto.
apply multTerm_ltT_l with (1 := os); auto.
absurd
(ltT ltM (multTerm (A:=A) multA (n:=n) a1 a0)
(multTerm (A:=A) multA (n:=n) a1 a)); auto.
apply (canonical_pX_order A A0 eqA) with (l := mults a1 l0); auto.
red in |- *; intros H'2;
absurd (zeroP (A:=A) A0 eqA (n:=n) (multTerm (A:=A) multA (n:=n) a1 a));
auto.
apply canonical_nzeroP with (ltM := ltM) (p := mults a1 l0); auto.
apply canonical_skip_fst with (b := multTerm (A:=A) multA (n:=n) a1 a0); auto.
apply H' with (a := a1); auto.
apply canonical_imp_canonical with (a := multTerm (A:=A) multA (n:=n) a1 a);
auto.
Qed.
Set Implicit Arguments.
Unset Strict Implicit.
Definition tmults : Term A n -> list (Term A n) -> list (Term A n).
intros a; case (zeroP_dec A A0 eqA eqA_dec n a); intros Z0.
intros H'; exact (pO A n).
intros p; exact (mults a p).
Defined.
Set Strict Implicit.
Unset Implicit Arguments.
intros p a; unfold tmults in |- *; case (zeroP_dec A A0 eqA eqA_dec n a);
auto.
intros H' H'0; elim H'; auto.
Qed.
unfold pO in |- *; intros p a H'; inversion H'; auto.
Qed.
intros p; case p; simpl in |- *; auto.
intros a l H'; inversion H'.
Qed.
intros a H' p; elim p; simpl in |- *; auto.
intros a0 l H'0 H'1; inversion H'1; auto.
Qed.
intros p; elim p; simpl in |- *; auto.
intros; apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n);
apply p0_pluspf_l with (1 := cs); auto.
intros a l H' a0 b H'0 H'1 H'2 H'3 H'4.
cut (canonical A0 eqA ltM l); try apply canonical_imp_canonical with (a := a);
auto; intros C0.
apply
(eqp_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := pX
(plusTerm (A:=A) plusA (n:=n) (multTerm (A:=A) multA (n:=n) a0 a)
(multTerm (A:=A) multA (n:=n) b a))
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM)
ltM_dec (mults a0 l) (mults b l)));
auto.
apply
(eqp_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := pX
(plusTerm (A:=A) plusA (n:=n) (multTerm (A:=A) multA (n:=n) a0 a)
(multTerm (A:=A) multA (n:=n) b a))
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM)
ltM_dec (mults a0 l) (mults b l)));
auto.
apply (eqpP1 _ eqA n); auto.
apply (eqTerm_sym _ _ _ _ _ _ _ _ _ cs n);
apply multTerm_plusTerm_dist_l with (1 := cs); auto.
apply pluspf_inv3b with (1 := cs); auto.
red in |- *; intros H'5;
absurd
(zeroP (A:=A) A0 eqA (n:=n)
(multTerm (A:=A) multA (n:=n) (plusTerm (A:=A) plusA (n:=n) a0 b) a));
auto.
red in |- *; intros H'6.
elim
multTerm_zeroP_div
with (1 := cs) (a := plusTerm (A:=A) plusA (n:=n) a0 b) (b := a);
auto.
intros H'7; absurd (zeroP (A:=A) A0 eqA (n:=n) a); auto.
apply canonical_nzeroP with (ltM := ltM) (p := l); auto.
apply
zeroP_comp_eqTerm
with
(1 := cs)
(a := plusTerm (A:=A) plusA (n:=n) (multTerm (A:=A) multA (n:=n) a0 a)
(multTerm (A:=A) multA (n:=n) b a)); auto.
apply multTerm_plusTerm_dist_l with (1 := cs); auto.
Qed.

Theorem mults_dist2 :
forall (p : list (Term A n)) (a b : Term A n),
eqT a b ->
~ zeroP (A:=A) A0 eqA (n:=n) a ->
~ zeroP (A:=A) A0 eqA (n:=n) b ->
zeroP (A:=A) A0 eqA (n:=n) (plusTerm (A:=A) plusA (n:=n) a b) ->
canonical A0 eqA ltM p ->
eqP A eqA n (pO A n)
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(mults a p) (mults b p)).