NDiv.v
(****************************************************************************
IEEE754 : NDiv
Laurent Thery
*****************************************************************************
Definition of the quotient and divisibility for natural and relative numbers*)
Require Import Omega.
Require Import Arith.
Require Import Compare.
Require Import Faux.
Require Import Euclid_proof.
Require Import Zpower.
Require Import Zcomplements.
Require Import Reals.
Require Import sTactic.
Require Import Digit.
(* We use the quotient function in Euclid proof to build our Nquotient *)
Definition
Nquotient :=
[m, n:nat]
Cases n of
O => O
| (S n') =>
Cases (quotient (S n') (lt_le_S O (S n') (lt_O_Sn n')) m) of
(exist x _) => x
end
end.
(* It has the required property *)
Theorem
NquotientProp:
(m, n:nat) (lt O n) ->
(ex nat [r:nat]m=(plus (mult (Nquotient m n) n) r) /\ (lt r n)).
Intros m n; Unfold Nquotient; Case n; Auto with arith.
Intros H'; Inversion H'.
Intros n0 H'; Case (quotient (S n0) (lt_le_S O (S n0) (lt_O_Sn n0)) m).
Intros x H'0; Elim H'0; Intros r E; Exists r; Intuition.
Qed.
(* We lift this quotient to relative numbers *)
Definition
ZNquotient :=
[m:Z] [n:nat]
Cases m of
ZERO => ZERO
| (POS x) => (INZ (Nquotient (absolu m) n))
| (NEG x) => (Zopp (INZ (Nquotient (absolu m) n)))
end.
Theorem
ZNquotientProp:
(m:Z) (n:nat) (lt O n) -> (absolu m)=(mult (Nquotient (absolu m) n) n) ->
m=(Zmult (ZNquotient m n) (INZ n)).
Intros m n; Case m; Simpl; Auto.
Intros p H' H'0.
Unfold INZ; Rewrite <- inj_mult; Auto.
Rewrite <- H'0; Auto with zarith.
Apply sym_equal.
Apply inject_nat_convert; Auto.
Intros p H' H'0.
Rewrite Zopp_Zmult.
Unfold INZ; Rewrite <- inj_mult; Auto.
Rewrite <- H'0; Auto with zarith.
Replace (NEG p) with (Zopp (POS p)).
Cut (POS p)=(INZ (convert p)).
Intros H'1; Rewrite H'1; Auto.
Apply sym_equal.
Apply inject_nat_convert; Auto.
Simpl; Auto.
Qed.
(* The property of a number to divide another one
(Ndivides n m) shoud be read as m divides n *)
Definition
Ndivides := [n, m:nat](Ex [q:nat] n=(mult m q)).
Theorem
NdividesNquotient:
(n, m:nat) (lt O m) -> (Ndivides n m) ->n=(mult (Nquotient n m) m).
Intros n m H' H'0.
Red in H'0.
Elim H'0; Intros q E; Clear H'0.
Elim (NquotientProp n m);
[Intros r E0; Elim E0; Intros H'3 H'4; Clear E0 | Idtac]; Auto.
Pattern 1 n; Rewrite E.
Case (le_or_lt q (Nquotient n m)); Intros H'5; Auto with arith.
Case (le_lt_or_eq ? ? H'5); Intros H'6; Auto with arith.
2:Elim H'6; Auto with arith.
Absurd (lt (mult m q) (mult m (Nquotient n m))); Auto with arith.
Rewrite <- E.
Pattern 1 n; Rewrite H'3; Rewrite (mult_sym m); Auto with arith.
Absurd (le (mult (S (Nquotient n m)) m) (mult m q)).
Simpl; Auto with zarith.
Rewrite (mult_sym m).
Apply lte_comp_mult; Auto with arith.
Qed.
Theorem
NdividesNquotientInv:
(n, m:nat) n=(mult (Nquotient n m) m) ->(Ndivides n m).
Intros n m H'; Red.
Exists (Nquotient n m); Auto.
Pattern 1 n; Rewrite H'; Auto with arith.
Qed.
Theorem
NdividesMult:
(n, m, p:nat) (Ndivides n m) ->(Ndivides (mult p n) (mult p m)).
Intros n m p H'; Red in H'.
Elim H'; Intros q E.
Red.
Exists q.
Rewrite E.
Auto with arith.
Qed.
Theorem
NdividesDiv:
(n, m, p:nat) (lt O p) -> (Ndivides (mult p n) (mult p m)) ->(Ndivides n m).
Intros n m p H' H'0; Red in H'0.
Elim H'0; Intros q E; Clear H'0.
Red.
Exists q.
Apply mult_eq_inv with n := p; Auto with arith; Rewrite mult_assoc_l; Auto.
Qed.
Definition
dividesP: (n, m:nat){(Ndivides n m)}+{~ (Ndivides n m)}.
Intros n m; Case m.
Case n.
Left; Red; Exists O; Auto with arith.
Intros n0; Right; Red; Intros H'; Red in H'.
Elim H'; Intros q; Simpl; Intros; Discriminate.
Intros n0.
Case (natEq n (mult (Nquotient n (S n0)) (S n0))).
Intros H'; Left.
Apply NdividesNquotientInv; Auto.
Intros H'; Right; Red; Intros H'0; Case H'.
Apply NdividesNquotient; Auto with arith.
Defined.
Theorem
Nquotient1: (m:nat)(Nquotient m (1))=m.
Intros m.
Elim (NquotientProp m (1)); Auto.
Intros x H'; Elim H'; Intros H'0 H'1.
Pattern 2 m; Rewrite H'0.
Auto with zarith.
Qed.
Theorem
ZNquotient1: (m:Z)(ZNquotient m (1))=m.
Intros m; Case m; Auto.
Intros p; Generalize (Nquotient1 (convert p)); Simpl.
Case (quotient (1) (lt_le_S O (1) (lt_O_Sn O)) (convert p)).
Intros x H' H'0; Rewrite H'0; Simpl; Auto with arith zarith.
Rewrite (inject_nat_convert (POS p)); Auto.
Intros p; Generalize (Nquotient1 (convert p)); Simpl.
Case (quotient (1) (lt_le_S O (1) (lt_O_Sn O)) (convert p)).
Intros x H' H'0; Rewrite H'0; Simpl; Auto with arith zarith.
Rewrite (inject_nat_convert (POS p)); Auto.
Qed.
Theorem
Ndivides1: (m:nat)(Ndivides m (1)).
Intros m; Exists m; Auto with arith.
Qed.
Theorem
NquotientUnique:
(m, n, q, r:nat) (lt O n) -> m=(plus (mult q n) r) -> (lt r n) ->
q=(Nquotient m n).
Intros m n q r H' H'0 H'1.
Elim (NquotientProp m n);
[Intros r1 E; Elim E; Intros H'7 H'8; Clear E | Idtac]; Auto.
Case (le_or_lt q (Nquotient m n)); Intros H'2; Auto with arith.
Case (le_lt_or_eq ? ? H'2); Clear H'2; Intros H'3; Auto with arith.
Contradict H'1.
Apply le_not_lt.
Apply le_trans with m := (plus n r1); Auto with arith.
Apply simpl_le_plus_l with p := m.
Pattern 1 m; Rewrite H'0.
Rewrite H'7.
Cut (le (plus (mult q n) n) (mult (Nquotient m n) n)); Auto with zarith.
Replace (plus (mult q n) n) with (mult (S q) n); Auto with arith; Simpl;
Auto with arith.
Contradict H'8.
Apply le_not_lt.
Apply le_trans with m := (plus n r); Auto with arith.
Apply simpl_le_plus_l with p := m.
Pattern 2 m; Rewrite H'0.
Rewrite H'7.
Cut (le (plus (mult (Nquotient m n) n) n) (mult q n)); Auto with zarith.
Replace (plus (mult (Nquotient m n) n) n) with (mult (S (Nquotient m n)) n);
Auto with arith; Simpl; Auto with arith.
Qed.
Theorem
NquotientMonotone:
(n, m, q:nat) ~ q=O -> (lt n m) ->(le (Nquotient n q) (Nquotient m q)).
Intros n m q H' H'0.
Case (le_or_lt (Nquotient n q) (Nquotient m q)); Auto.
Intros H'1.
Elim (NquotientProp m q);
[Intros r1 E; Elim E; Intros H'5 H'6; Clear E | Idtac]; Auto with zarith.
Elim (NquotientProp n q);
[Intros r2 E; Elim E; Intros H'7 H'8; Try Exact H'7; Clear E | Idtac];
Auto with zarith.
Contradict H'0.
Apply le_not_lt.
Apply le_trans with m := (plus (plus m (minus q r1)) r2); Auto with zarith.
Apply simpl_le_plus_l with p := r1; Auto with zarith.
Replace (plus r1 (plus (plus m (minus q r1)) r2)) with (plus (plus m q) r2);
Auto with zarith.
Rewrite H'5.
Rewrite H'7.
Replace (plus (plus (plus (mult (Nquotient m q) q) r1) q) r2)
with (plus r1 (plus (mult (S (Nquotient m q)) q) r2));
Auto with zarith arith.
Simpl; Auto with zarith arith.
Qed.
Theorem
ZNquotientMonotone:
(n, m:Z) (q:nat) ~ q=O -> (Zlt n m) ->(Zle (ZNquotient n q) (ZNquotient m q)).
Intros n m; Case n; Case m; Simpl; Auto with zarith arith.
Intros p q H' H'0; Replace ZERO with (INZ O); Auto with zarith arith.
Intros p q H' H'0; Inversion H'0.
Intros p q H' H'0; Inversion H'0.
Intros p p0 q H' H'0; Apply inj_le; Auto.
Apply NquotientMonotone; Auto.
Apply lt_Zlt_inv; Auto.
Simpl; Auto.
Unfold INZ; Rewrite (inject_nat_convert (POS p0) p0); Auto.
Unfold INZ; Rewrite (inject_nat_convert (POS p) p); Auto.
Intros p p0 q H' H'0; Inversion H'0.
Intros p q H' H'0; Replace ZERO with (Zopp (INZ O)); Auto with zarith arith.
Intros p p0 q H' H'0.
Apply Zle_trans with m := ZERO; Auto with zarith arith.
Replace ZERO with (Zopp (INZ O)); Auto with zarith arith.
Replace ZERO with (INZ O); Auto with zarith arith.
Intros p p0 q H' H'0.
Apply Zle_Zopp; Apply inj_le.
Apply NquotientMonotone; Auto.
Apply lt_Zlt_inv; Auto with zarith arith.
Unfold INZ; Rewrite (inject_nat_convert (Zopp (NEG p0)) p0); Auto.
Unfold INZ; Rewrite (inject_nat_convert (Zopp (NEG p)) p); Auto.
Auto with zarith arith.
Qed.
Theorem
NotDividesDigit:
(r:nat) (v:nat) (lt (1) r) -> ~ v=O ->~ (Ndivides v (exp r (digit r v))).
Intros r v H H'; Red; Intros H'0; Red in H'0.
Elim H'0; Intros q E; Clear H'0.
Absurd (lt v (exp r (digit r v))); Auto with arith.
Generalize H'; Pattern 1 2 v; Rewrite E; Auto.
Case q; Simpl; Auto with arith.
Intros n H'0; Rewrite mult_sym; Simpl; Auto with arith.
Qed.
Theorem
NDividesLt: (n, m:nat) ~ n=O -> (Ndivides n m) ->(le m n).
Intros n m H' H'0; Red in H'0.
Elim H'0; Intros q E; Generalize H'; Rewrite E; Clear H'0.
Repeat Rewrite (mult_sym m); Case q; Simpl; Auto with zarith arith.
Qed.
Theorem
Nquotient_mult_comp:
(m, n, p:nat) ~ n=O -> ~ p=O ->
(Nquotient (mult m p) (mult n p))=(Nquotient m n).
Intros m n p H' H'0.
Elim (NquotientProp m n); [Intros r E; Elim E; Intros H'4 H'5; Clear E | Idtac];
Auto with arith zarith.
Apply sym_equal.
Apply NquotientUnique with r := (mult r p); Auto with arith zarith.
Generalize H' H'0; Case n; Case p; Simpl; Auto with arith zarith.
Pattern 1 m; Rewrite H'4; Auto with arith zarith.
Rewrite mult_plus_distr; Auto with arith zarith.
Qed.
Theorem
ZNquotient_INZ:
(m, n:nat) ~ n=O ->(ZNquotient (INZ m) n)=(inject_nat (Nquotient m n)).
Intros m; Case m; Simpl; Auto with arith zarith.
Intros n H'.
Rewrite <- (NquotientUnique O n O O); Auto with arith zarith.
Intros n n0 H'.
Rewrite bij1; Auto.
Qed.
Theorem
ZNquotient_Zopp:
(m:Z) (n:nat)(ZNquotient (Zopp m) n)=(Zopp (ZNquotient m n)).
Intros m; Case m; Simpl; Auto with arith zarith.
Qed.
Theorem
ZNquotient_mult_comp:
(m:Z) (n, p:nat) ~ n=O -> ~ p=O ->
(ZNquotient (Zmult m (inject_nat p)) (mult n p))=(ZNquotient m n).
Intros m n p H' H'0; Case m; Auto.
Intros p0.
Replace (ZNquotient (POS p0) n) with (INZ (Nquotient (absolu (POS p0)) n)); Auto.
Replace (Zmult (POS p0) (inject_nat p)) with (INZ (mult (absolu (POS p0)) p));
Auto.
Simpl; Auto.
Rewrite ZNquotient_INZ; Auto with arith zarith.
Rewrite Nquotient_mult_comp; Auto.
Generalize H' H'0; Case n; Case p; Simpl; Auto with arith zarith.
Rewrite inj_mult; Auto with arith zarith.
Replace (absolu (POS p0)) with (convert p0); Auto.
Rewrite (inject_nat_convert (POS p0)); Auto.
Intros p0.
Replace (ZNquotient (NEG p0) n)
with (Zopp (INZ (Nquotient (absolu (NEG p0)) n))); Auto.
Replace (Zmult (NEG p0) (inject_nat p))
with (Zopp (INZ (mult (absolu (NEG p0)) p))); Auto.
Rewrite ZNquotient_Zopp.
Simpl.
Rewrite ZNquotient_INZ; Auto with arith zarith.
Rewrite Nquotient_mult_comp; Auto.
Generalize H' H'0; Case n; Case p; Simpl; Auto with arith zarith.
Replace (absolu (NEG p0)) with (convert p0); Auto.
Replace (NEG p0) with (Zopp (POS p0)); Auto.
Rewrite <- (inject_nat_convert (POS p0) p0); Auto with arith zarith.
Rewrite Zmult_Zopp_left; Auto.
Rewrite <- Zopp_Zmult_r; Auto with arith zarith.
Rewrite inj_mult; Auto with arith zarith.
Qed.
Theorem
NDivides_add:
(n, m, p:nat) (Ndivides n p) -> (Ndivides m p) ->(Ndivides (plus n m) p).
Intros n m p H' H'0.
Inversion H'0; Inversion H'.
Exists (plus x0 x).
Rewrite H0; Rewrite H.
Repeat Rewrite (mult_sym p); Auto with arith.
Qed.
Theorem
NDivides_minus:
(n, m, p:nat) (Ndivides n p) -> (Ndivides m p) ->(Ndivides (minus n m) p).
Intros n m p H' H'0.
Inversion H'0; Inversion H'.
Exists (minus x0 x).
Rewrite H0; Rewrite H.
Repeat Rewrite (mult_sym p); Auto with arith.
Qed.
Theorem
NDivides_mult:
(n, m, p, q:nat) (Ndivides n p) -> (Ndivides m q) ->
(Ndivides (mult n m) (mult p q)).
Intros n m p q H' H'0.
Inversion H'0; Inversion H'.
Exists (mult x0 x).
Rewrite H0; Rewrite H.
Ring.
Qed.
22/10/100, 19:44