1
(************************************************************************)
2
(* v * The Coq Proof Assistant / The Coq Development Team *)
3
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
4
(* \VV/ **************************************************************)
5
(* // * This file is distributed under the terms of the *)
6
(* * GNU Lesser General Public License Version 2.1 *)
7
(************************************************************************)
9
(*i $Id: Div2.v 11735 2009-01-02 17:22:31Z herbelin $ i*)
13
Require Import Compare_dec.
16
Open Local Scope nat_scope.
18
Implicit Type n : nat.
20
(** Here we define [n/2] and prove some of its properties *)
22
Fixpoint div2 n : nat :=
26
| S (S n') => S (div2 n')
29
(** Since [div2] is recursively defined on [0], [1] and [(S (S n))], it is
30
useful to prove the corresponding induction principle *)
34
P 0 -> P 1 -> (forall n, P n -> P (S (S n))) -> forall n, P n.
37
cut (forall n, P n /\ P (S n)).
38
intros H'n n. elim (H'n n). auto with arith.
40
induction n. auto with arith.
41
intros. elim IHn; auto with arith.
44
(** [0 <n => n/2 < n] *)
46
Lemma lt_div2 : forall n, 0 < n -> div2 n < n.
48
intro n. pattern n in |- *. apply ind_0_1_SS.
54
intro n'; case (zerop n').
55
intro n'_eq_0. rewrite n'_eq_0. auto with arith.
59
Hint Resolve lt_div2: arith.
61
(** Properties related to the parity *)
63
Lemma even_div2 : forall n, even n -> div2 n = div2 (S n)
64
with odd_div2 : forall n, odd n -> S (div2 n) = div2 (S n).
68
(* S n *) inversion_clear H. apply odd_div2 in H0 as <-. trivial.
71
(* S n *) inversion_clear H. apply even_div2 in H0 as <-. trivial.
74
Lemma div2_even : forall n, div2 n = div2 (S n) -> even n
75
with div2_odd : forall n, S (div2 n) = div2 (S n) -> odd n.
79
(* S n *) constructor. apply div2_odd. rewrite H. trivial.
82
(* S n *) constructor. apply div2_even. injection H as <-. trivial.
85
Hint Resolve even_div2 div2_even odd_div2 div2_odd: arith.
89
(even n <-> div2 n = div2 (S n)) /\ (odd n <-> S (div2 n) = div2 (S n)).
91
auto decomp using div2_odd, div2_even, odd_div2, even_div2.
96
(** Properties related to the double ([2n]) *)
98
Definition double n := n + n.
100
Hint Unfold double: arith.
102
Lemma double_S : forall n, double (S n) = S (S (double n)).
104
intro. unfold double in |- *. simpl in |- *. auto with arith.
107
Lemma double_plus : forall n (m:nat), double (n + m) = double n + double m.
109
intros m n. unfold double in |- *.
110
do 2 rewrite plus_assoc_reverse. rewrite (plus_permute n).
114
Hint Resolve double_S: arith.
116
Lemma even_odd_double :
118
(even n <-> n = double (div2 n)) /\ (odd n <-> n = S (double (div2 n))).
120
intro n. pattern n in |- *. apply ind_0_1_SS.
122
split; split; auto with arith.
123
intro H. inversion H.
125
split; split; auto with arith.
126
intro H. inversion H. inversion H1.
128
intros. destruct H as ((IH1,IH2),(IH3,IH4)).
130
intro H. inversion H. inversion H1.
131
simpl in |- *. rewrite (double_S (div2 n0)). auto with arith.
132
simpl in |- *. rewrite (double_S (div2 n0)). intro H. injection H. auto with arith.
133
intro H. inversion H. inversion H1.
134
simpl in |- *. rewrite (double_S (div2 n0)). auto with arith.
135
simpl in |- *. rewrite (double_S (div2 n0)). intro H. injection H. auto with arith.
137
(** Specializations *)
139
Lemma even_double : forall n, even n -> n = double (div2 n).
140
Proof fun n => proj1 (proj1 (even_odd_double n)).
142
Lemma double_even : forall n, n = double (div2 n) -> even n.
143
Proof fun n => proj2 (proj1 (even_odd_double n)).
145
Lemma odd_double : forall n, odd n -> n = S (double (div2 n)).
146
Proof fun n => proj1 (proj2 (even_odd_double n)).
148
Lemma double_odd : forall n, n = S (double (div2 n)) -> odd n.
149
Proof fun n => proj2 (proj2 (even_odd_double n)).
151
Hint Resolve even_double double_even odd_double double_odd: arith.
154
- if [n] is even then there is a [p] such that [n = 2p]
155
- if [n] is odd then there is a [p] such that [n = 2p+1]
157
(Immediate: it is [n/2]) *)
159
Lemma even_2n : forall n, even n -> {p : nat | n = double p}.
161
intros n H. exists (div2 n). auto with arith.
164
Lemma odd_S2n : forall n, odd n -> {p : nat | n = S (double p)}.
166
intros n H. exists (div2 n). auto with arith.
169
(** Doubling before dividing by two brings back to the initial number. *)
171
Lemma div2_double : forall n:nat, div2 (2*n) = n.
176
replace (n+S(n+0)) with (S (2*n)).
178
simpl; auto with arith.
181
Lemma div2_double_plus_one : forall n:nat, div2 (S (2*n)) = n.
186
replace (n+S(n+0)) with (S (2*n)).
188
simpl; auto with arith.