Section DivTerm.
Load "hCoefStructure".
Load "mCoefStructure".
Load "hOrderStructure".
Load "mOrderStructure".
Load "hTerm".
Set Implicit Arguments.
Unset Strict Implicit.
Definition divTerm :
Term A n ->
forall (b : Term A n) (nZb : ~ zeroP (A:=A) A0 eqA (n:=n) b), Term A n.
intros H; case H; intros b2 c2 H'; case H'; intros b3 c3; simpl in |- *.
intros nZb3; exact (divA b2 b3 nZb3, div_mon n c2 c3).
Defined.
Set Strict Implicit.
Unset Implicit Arguments.
intros a b c; case a; case b; case c; simpl in |- *; auto.
intros a0 m a1 m0 a2 m1 nZc H' H'0 H'1; split; auto.
case H'1; intros H'3 H'4; clear H'1.
case H'0; intros H'2 H'5; clear H'0.
apply
(eqA_trans _ _ _ _ _ _ _ _ _ cs)
with
(y := divA
(plusA (multA (divA a2 a0 nZc) a0) (multA (divA a1 a0 nZc) a0))
a0 nZc); auto.
apply
(eqA_trans _ _ _ _ _ _ _ _ _ cs)
with
(y := divA (multA (plusA (divA a2 a0 nZc) (divA a1 a0 nZc)) a0) a0 nZc);
auto.
apply divA_eqA_comp with (1 := cs); auto.
apply
(eqA_trans _ _ _ _ _ _ _ _ _ cs)
with (y := plusA (multA a0 (divA a2 a0 nZc)) (multA a0 (divA a1 a0 nZc)));
auto.
apply
(eqA_trans _ _ _ _ _ _ _ _ _ cs)
with (y := multA a0 (plusA (divA a2 a0 nZc) (divA a1 a0 nZc)));
auto.
apply
(eqA_trans _ _ _ _ _ _ _ _ _ cs)
with
(y := multA (plusA (divA a2 a0 nZc) (divA a1 a0 nZc)) (divA a0 a0 nZc));
auto.
apply
(eqA_trans _ _ _ _ _ _ _ _ _ cs)
with
(y := divA (multA a0 (plusA (divA a2 a0 nZc) (divA a1 a0 nZc))) a0 nZc);
auto.
apply
(eqA_trans _ _ _ _ _ _ _ _ _ cs)
with
(y := multA (divA a0 a0 nZc) (plusA (divA a2 a0 nZc) (divA a1 a0 nZc)));
auto.
apply divA_multA_comp_r with (1 := cs); auto.
apply
(eqA_trans _ _ _ _ _ _ _ _ _ cs)
with (y := multA (plusA (divA a2 a0 nZc) (divA a1 a0 nZc)) A1);
auto.
apply (eqA_sym _ _ _ _ _ _ _ _ _ cs); auto.
apply multA_eqA_comp with (1 := cs); auto.
apply (eqA_sym _ _ _ _ _ _ _ _ _ cs); auto.
apply divA_A1 with (1 := cs); auto.
apply multA_A1_r with (1 := cs); auto.
Qed.
intros a b; case a; case b; simpl in |- *; auto.
intros d c A0' c0 nZA2 H'0; split; auto.
case H'0; intros H'1 H'2; clear H'0.
apply
(eqA_trans _ _ _ _ _ _ _ _ _ cs)
with (y := divA (invA (multA (divA d A0' nZA2) A0')) A0' nZA2);
auto.
apply
(eqA_trans _ _ _ _ _ _ _ _ _ cs)
with (y := divA (multA (invA (divA d A0' nZA2)) A0') A0' nZA2);
auto.
apply divA_eqA_comp with (1 := cs); auto.
apply (eqA_sym _ _ _ _ _ _ _ _ _ cs); apply multA_invA_com_l with (1 := cs);
auto.
apply
(eqA_trans _ _ _ _ _ _ _ _ _ cs)
with (y := multA (invA (divA d A0' nZA2)) (divA A0' A0' nZA2));
auto.
apply divA_multA_comp_l with (1 := cs).
apply
(eqA_trans _ _ _ _ _ _ _ _ _ cs)
with (y := multA (invA (divA d A0' nZA2)) A1); auto.
apply multA_eqA_comp with (1 := cs); auto.
apply divA_A1 with (1 := cs).
apply multA_A1_r with (1 := cs).
Qed.
intros a b; case a; case b; simpl in |- *; auto.
split; auto.
apply divA_invA_r with (1 := cs); auto.
Qed.
intros a b c d; case a; case b; case c; case d; unfold eqT in |- *;
simpl in |- *; auto.
intros A0' c0 d2 c2 H' c3 H'0 c4 H'1 H'2 H'3 H'4; rewrite H'3; rewrite H'4;
auto.
Qed.
intros a b c d; case a; case b; case c; case d; simpl in |- *; auto.
intros A0' c0 d2 c2 d3 c3 d4 c4 nZd2 H'0 H'1 H'2.
case H'2; intros H'3 H'4; clear H'2.
case H'1; intros H'2 H'5; clear H'1.
split; auto.
rewrite H'5; rewrite H'4; auto.
Qed.
Hint Resolve eqTerm_divTerm_comp.
intros a b c; case a; case b; case c; simpl in |- *; auto.
intros d c0 A0' c2 d2 c3 nZd2 H'0; case H'0; intros H'1 H'2; auto.
split; auto.
apply divA_multA_comp_l with (1 := cs).
rewrite H'2.
repeat rewrite mult_div_com.
rewrite mult_mon_assoc.
repeat rewrite mult_div_com; auto.
Qed.
intros a b c; case a; case b; case c; simpl in |- *; auto.
intros a0 m a1 m0 a2 m1 nZa H'; split; auto.
apply divA_multA_comp_r with (1 := cs).
elim H'; intros H'0 H'1; rewrite H'1; clear H'.
rewrite mult_div_com; auto.
rewrite <- mult_mon_assoc.
rewrite (mult_mon_com n m1 m).
rewrite mult_mon_assoc.
rewrite mult_div_com; auto.
Qed.
Hint Resolve divTerm_multTerm_l divTerm_multTerm_r.
intros a; case a; simpl in |- *; auto.
intros a0 m nZa; split; auto.
apply divA_A1 with (1 := cs).
unfold M1 in |- *; apply mult_div_id; auto.
Qed.
Hint Resolve div_is_T1.
intros a b; case a; case b; simpl in |- *; auto.
intros a0 m a1 m0 H nZb; apply divA_nZ with (1 := cs); auto.
Qed.
intros a b c; case a; case b; case c; simpl in |- *; auto.
intros a1 m1 a2 m2 a3 m3 H1 H2 H3 H4 H5; case H5; intros H6 H7; split; auto.
apply divA_is_multA with (1 := cs); auto.
unfold eqT in H1; simpl in H1; rewrite <- H1; auto.
Qed.
Let gb : mon n * bool -> bool.
intros H'; case H'; auto.
Defined.
Let gm : mon n * bool -> mon n.
intros H'; case H'; auto.
Defined.
Definition mk_clean :
forall a b : mon n, {c : mon n * bool | c = div_mon_clean n a b}.
intros a b; exists (div_mon_clean n a b); auto.
Qed.
intros a b; case a; case b; simpl in |- *; auto.
intros b2 c2 b3 c3.
intros Zp1 Zp2.
case (mk_clean c3 c2).
intros x; case x.
intros c b4; case b4.
intros H0; left; simpl in |- *; auto.
generalize (div_clean_dec1 n c3 c2); rewrite <- H0; simpl in |- *; auto.
intros H1; case H1; auto; intros H2 H3; split; auto.
apply divA_is_multA with (1 := cs); auto.
intros H0; right; red in |- *; intros dviP_H; inversion dviP_H.
generalize (div_clean_dec2 n c3 c2); simpl in |- *; auto.
intros H'; lapply H'; [ intros H'0; apply H'0; clear H' | clear H' ].
rewrite <- H1; auto.
rewrite <- H0; simpl in |- *; auto.
Qed.
intros a b; case a; case b; simpl in |- *; auto.
intros d H' A0' H'0 H'1 nZd; auto.
apply (eqA_trans _ _ _ _ _ _ _ _ _ cs) with (y := divA A0 d nZd); auto.
apply divA_A0_l with (1 := cs).
Qed.
intros a b; case a; case b; unfold eqT in |- *; simpl in |- *; auto.
intros d c A0' c0 H' H'0 H'1; rewrite <- H'1.
split; auto.
apply divA_is_multA with (1 := cs); auto.
rewrite mult_div_id; auto.
rewrite mult_mon_zero_l; auto.
Qed.
intros a b; case a; case b; unfold eqT in |- *; simpl in |- *; auto.
intros b2 c b3 c0 H' H'0 H'1; rewrite H'1; auto.
rewrite mult_div_id; auto.
Qed.

Theorem divTerm_on_plusM_minusM :
forall a b : Term A n,
~ zeroP (A:=A) A0 eqA (n:=n) a ->
forall nZb : ~ zeroP (A:=A) A0 eqA (n:=n) b,
T2M a = mult_mon n (div_mon n (T2M a) (T2M b)) (T2M b) ->
eqTerm (A:=A) eqA (n:=n) a (multTerm (A:=A) multA (n:=n) (divTerm a nZb) b).