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.
intros a b; case a; case b; simpl in |- *; auto.
split; auto.
apply divA_is_multA with (1 := cs); auto.
Qed.
Set Implicit Arguments.
Unset Strict Implicit.
Definition ppc : Term A n -> Term A n -> Term A n.
intros H; case H; intros b2 c2 H'; case H'; intros b3 c3; simpl in |- *;
exact (A1, ppcm_mon n c2 c3).
Defined.
Set Strict Implicit.
Unset Implicit Arguments.
intros a b; case a; case b; simpl in |- *; auto.
intros a0 m a1 m0; split; auto.
apply ppcm_com; auto.
Qed.
intros a b c; case a; case b; case c; simpl in |- *; auto.
intros a0 m a1 m0 a2 m1 nZa nZb nZppab H H0; split; auto.
apply divA_is_multA with (1 := cs); auto.
apply ppcm_mom_is_ppcm; intuition.
Qed.
intros a b; case a; case b; simpl in |- *; auto.
intros a0 m a1 m0 nZa H; split; auto.
apply divA_is_multA with (1 := cs); auto.
apply ppcm_prop_l.
Qed.
intros a b; case a; case b; simpl in |- *; auto.
intros a0 m a1 m0 H nZb; split; auto.
apply divA_is_multA with (1 := cs); auto.
apply ppcm_prop_r.
Qed.
intros a b; case a; case b; simpl in |- *; auto.
Qed.
intros a b; case a; case b; simpl in |- *; auto.
intros a0 m a1 m0 nZ1 nZ2.
rewrite divA_rew with (1 := cs) (nZ2 := nZ2); auto.
Qed.
Inductive divP : Term A n -> Term A n -> Prop :=
divTerm_def :
forall a b : Term A n,
~ zeroP (A:=A) A0 eqA (n:=n) a ->
forall nZb : ~ zeroP (A:=A) A0 eqA (n:=n) b,
eqTerm (A:=A) eqA (n:=n) a
(multTerm (A:=A) multA (n:=n) (divTerm a nZb) b) ->
divP a b.
intros a b H; inversion H; auto.
Qed.
intros a b H; inversion H; auto.
Qed.
intros a b nZb H; inversion H; auto.
apply
(eqTerm_trans _ _ _ _ _ _ _ _ _ cs n)
with (y := multTerm (A:=A) multA (n:=n) (divTerm a nZb0) b);
auto.
Qed.
Hint Resolve divP_inv1 divP_inv2 divP_inv3.
intros a b c H' H'0; inversion H'0; inversion H'.
intros H'1 H'2; apply divTerm_def with (nZb := nZb0); auto.
apply
(eqTerm_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := plusTerm (A:=A) plusA (n:=n)
(multTerm (A:=A) multA (n:=n) (divTerm a nZb0) c)
(multTerm (A:=A) multA (n:=n) (divTerm b nZb0) c));
auto.
apply eqTerm_plusTerm_comp with (1 := cs); auto.
apply multTerm_eqT; auto.
apply eqT_divTerm; auto.
apply (eqT_refl A n).
apply (eqT_refl A n).
apply
(eqTerm_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := multTerm (A:=A) multA (n:=n)
(plusTerm (A:=A) plusA (n:=n) (divTerm a nZb0) (divTerm b nZb0))
c); auto.
apply multTerm_plusTerm_dist_l with (1 := cs); auto.
apply eqTerm_multTerm_comp with (1 := cs); auto.
apply (eqTerm_sym _ _ _ _ _ _ _ _ _ cs n); auto.
apply eqT_divTerm_plusTerm; auto.
Qed.
Hint Resolve divP_plusTerm.
intros a b H'; inversion H'; auto.
apply divTerm_def with (nZb := nZb); auto.
apply
(eqTerm_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := multTerm (A:=A) multA (n:=n)
(invTerm (A:=A) invA (n:=n) (divTerm a nZb)) b);
auto.
apply
(eqTerm_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := invTerm (A:=A) invA (n:=n)
(multTerm (A:=A) multA (n:=n) (divTerm a nZb) b));
auto.
apply (eqTerm_sym _ _ _ _ _ _ _ _ _ cs n);
apply mult_invTerm_com with (1 := cs); auto.
apply eqTerm_multTerm_comp with (1 := cs); auto.
apply (eqTerm_sym _ _ _ _ _ _ _ _ _ cs n); apply divTerm_invTerm_l; auto.
Qed.
Hint Resolve divP_invTerm_l.
intros a b H'; inversion H'.
cut (~ zeroP (A:=A) A0 eqA (n:=n) (invTerm (A:=A) invA (n:=n) b));
[ intros nZib | auto ].
apply divTerm_def with (nZb := nZib); auto.
apply
(eqTerm_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := multTerm (A:=A) multA (n:=n)
(invTerm (A:=A) invA (n:=n) (divTerm a nZb))
(invTerm (A:=A) invA (n:=n) b)); auto.
apply
(eqTerm_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := invTerm (A:=A) invA (n:=n)
(multTerm (A:=A) multA (n:=n) (divTerm a nZb)
(invTerm (A:=A) invA (n:=n) b))); auto.
apply
(eqTerm_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := invTerm (A:=A) invA (n:=n)
(invTerm (A:=A) invA (n:=n)
(multTerm (A:=A) multA (n:=n) (divTerm a nZb) b)));
auto.
apply
(eqTerm_trans _ _ _ _ _ _ _ _ _ cs n)
with (y := multTerm (A:=A) multA (n:=n) (divTerm a nZb) b);
auto.
apply eqTerm_invTerm_comp with (1 := cs); auto.
apply (eqTerm_sym _ _ _ _ _ _ _ _ _ cs n);
apply mult_invTerm_com_r with (1 := cs); auto.
apply (eqTerm_sym _ _ _ _ _ _ _ _ _ cs n);
apply mult_invTerm_com with (1 := cs); auto.
apply eqTerm_multTerm_comp with (1 := cs); auto.
apply (eqTerm_sym _ _ _ _ _ _ _ _ _ cs n); apply divTerm_invTerm_r; auto.
Qed.
Hint Resolve divTerm_nZ.
Hint Resolve divP_invTerm_r.
intros a b nZa nZb.
apply divTerm_def with (nZb := nZa); auto.
apply
(eqTerm_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := multTerm (A:=A) multA (n:=n)
(multTerm (A:=A) multA (n:=n) (divTerm a nZa) b) a);
auto.
apply
(eqTerm_trans _ _ _ _ _ _ _ _ _ cs n)
with
(y := multTerm (A:=A) multA (n:=n)
(multTerm (A:=A) multA (n:=n) (T1 A1 n) b) a);
auto.
apply
(eqTerm_trans _ _ _ _ _ _ _ _ _ cs n)
with (y := multTerm (A:=A) multA (n:=n) b a); auto.
apply eqTerm_multTerm_comp with (1 := cs); auto.
apply eqTerm_multTerm_comp with (1 := cs); auto.
apply (eqTerm_sym _ _ _ _ _ _ _ _ _ cs n); apply div_is_T1; auto.
apply eqTerm_multTerm_comp with (1 := cs); auto.
apply (eqTerm_sym _ _ _ _ _ _ _ _ _ cs n); apply divTerm_multTerm_r; auto.
Qed.

Theorem divTerm_multTermr :
forall a b : Term A n,
~ zeroP (A:=A) A0 eqA (n:=n) a ->
~ zeroP (A:=A) A0 eqA (n:=n) b -> divP (multTerm (A:=A) multA (n:=n) a b) b.