Section Pmult.
Load "hCoefStructure".
Load "hOrderStructure".
Load "hMults".
Fixpoint multpf (p : list (Term A n)) : list (Term A n) -> list (Term A n) :=
fun q : list (Term A n) =>
match p with
| nil => pO A n
| a :: p' =>
pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(mults (A:=A) multA (n:=n) a q) (multpf p' q)
end.
intros l1; elim l1; simpl in |- *; auto.
intros a l H' l2 H'0 H'1; try assumption.
apply canonical_pluspf; auto.
apply canonical_mults with (1 := cs); auto.
apply canonical_nzeroP with (ltM := ltM) (p := l); auto.
apply H'; auto.
apply canonical_imp_canonical with (a := a); auto.
Qed.
Hint Resolve canonical_multpf.
intros p; case p; clear p; auto.
intros a H;
change
(eqP A eqA n (pX a (pO A n))
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(pX a (pO A n)) (pO A n))) in |- *.
apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n); auto.
intros a1 p a0 H'.
cut (canonical A0 eqA ltM (pX a1 p));
[ intros Op0 | apply canonical_imp_canonical with (a := a0) ];
auto.
apply
(eqp_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := pX a0
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM)
ltM_dec (pO A n) (pX a1 p))); auto.
apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n); auto.
change
(eqP A eqA n
(pX a0
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(pO A n) (pX a1 p)))
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(pX a0 (pO A n)) (pX a1 p))) in |- *; auto.
apply pluspf_inv1 with (1 := cs); auto.
apply (canonical_pX_order _ A0 eqA) with (l := p); auto.
Qed.
intros p; elim p; clear p; simpl in |- *; auto.
intros; apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n); auto.
intros b p Rec q a Op0 Op1.
cut (canonical A0 eqA ltM q);
[ intros Op2 | apply canonical_imp_canonical with (a := a) ];
auto.
cut (canonical A0 eqA ltM p);
[ intros Op3 | apply canonical_imp_canonical with (a := b) ];
auto.
cut (~ zeroP (A:=A) A0 eqA (n:=n) a);
[ intros nZ0 | apply canonical_nzeroP with (ltM := ltM) (p := q) ];
auto.
cut (~ zeroP (A:=A) A0 eqA (n:=n) b);
[ intros nZ1 | apply canonical_nzeroP with (ltM := ltM) (p := p) ];
auto.
cut (~ zeroP (A:=A) A0 eqA (n:=n) (multTerm (A:=A) multA (n:=n) b a));
[ intros nZ2 | idtac ]; auto.
cut (~ zeroP (A:=A) A0 eqA (n:=n) (multTerm (A:=A) multA (n:=n) a b));
[ intros nZ3 | idtac ]; auto.
apply
(eqp_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(pX (multTerm (A:=A) multA (n:=n) b a)
(mults (A:=A) multA (n:=n) b q))
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM)
ltM_dec (mults (A:=A) multA (n:=n) a p)
(multpf p q))); auto.
apply eqp_pluspf_com with (1 := cs); auto.
change (canonical A0 eqA ltM (mults (A:=A) multA (n:=n) b (pX a q))) in |- *;
auto.
change (canonical A0 eqA ltM (mults (A:=A) multA (n:=n) b (pX a q))) in |- *;
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 (pX (multTerm (A:=A) multA (n:=n) b a) (pO A n))
(mults (A:=A) multA (n:=n) b q))
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM)
ltM_dec (mults (A:=A) multA (n:=n) a p)
(multpf p q))); auto.
cut
(canonical A0 eqA ltM
(pX (multTerm (A:=A) multA (n:=n) b a) (mults (A:=A) multA (n:=n) b q)));
[ intros Op4 | idtac ]; auto.
apply eqp_pluspf_com with (1 := cs); auto.
apply pluspf_pX; auto.
change (canonical A0 eqA ltM (mults (A:=A) multA (n:=n) b (pX a q))) in |- *;
auto.
apply
(eqp_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(pX (multTerm (A:=A) multA (n:=n) b a) (pO A n))
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM)
ltM_dec (mults (A:=A) multA (n:=n) b q)
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM)
ltM_dec (mults (A:=A) multA (n:=n) a p)
(multpf 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
(pX (multTerm (A:=A) multA (n:=n) b a) (pO A n))
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM)
ltM_dec (mults (A:=A) multA (n:=n) b q)
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM)
ltM_dec (multpf p q) (mults (A:=A) multA (n:=n) a p))));
auto.
apply
(eqp_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(pX (multTerm (A:=A) multA (n:=n) b a) (pO A n))
(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) b q)
(multpf p q)) (mults (A:=A) multA (n:=n) a p)));
auto.
apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n); auto.
apply
(eqp_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(pX (multTerm (A:=A) multA (n:=n) b a) (pO A n))
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM)
ltM_dec (mults (A:=A) multA (n:=n) a p)
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM)
ltM_dec (mults (A:=A) multA (n:=n) b q)
(multpf 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
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM)
ltM_dec (pX (multTerm (A:=A) multA (n:=n) b a) (pO A n))
(mults (A:=A) multA (n:=n) a p))
(pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM)
ltM_dec (mults (A:=A) multA (n:=n) b q)
(multpf p q))); auto.
apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n); auto.
apply eqp_pluspf_com with (1 := cs); auto.
change (canonical A0 eqA ltM (mults (A:=A) multA (n:=n) a (pX b p))) in |- *;
auto.
apply
(eqp_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := pluspf (A:=A) A0 (eqA:=eqA) plusA eqA_dec (n:=n) (ltM:=ltM) ltM_dec
(pX (multTerm (A:=A) multA (n:=n) a b) (pO A n))
(mults (A:=A) multA (n:=n) a p)); auto.
apply (eqp_sym _ _ _ _ _ _ _ _ _ cs n); auto.
apply pluspf_pX; auto.
change (canonical A0 eqA ltM (mults (A:=A) multA (n:=n) a (pX b p))) in |- *;
auto.
Qed.

Theorem multpf_head :
forall (p q : list (Term A n)) (a b : Term A n),
canonical A0 eqA ltM (pX a p) ->
canonical A0 eqA ltM (pX b q) ->
exists c : list (Term A n),
multpf (pX a p) (pX b q) = pX (multTerm (A:=A) multA (n:=n) a b) c.