1
<html xmlns="http://www.w3.org/1999/xhtml">
3
<meta http-equiv="Content-Type" content="text/html; charset="><link rel="stylesheet" href="style.css" type="text/css"><title>Coq.ZArith.Zpower</title>
8
<h1>Library Coq.ZArith.Zpower</h1>
11
<code class="keyword">Require</code> <code class="keyword">Import</code> ZArith_base.<br/>
12
<code class="keyword">Require</code> <code class="keyword">Import</code> Omega.<br/>
13
<code class="keyword">Require</code> <code class="keyword">Import</code> Zcomplements.<br/>
14
Open <code class="keyword">Local</code> Scope Z_scope.<br/>
17
<code class="keyword">Section</code> section1.<br/>
22
<table width="100%"><tr class="doc"><td>
23
<code>Zpower_nat z n</code> is the n-th power of <code>z</code> when <code>n</code> is an unary
24
integer (type <code>nat</code>) and <code>z</code> a signed integer (type <code>Z</code>)
29
<code class="keyword">Definition</code> <a name="Zpower_nat"></a>Zpower_nat (z:<a href="Coq.ZArith.BinInt.html#Z">Z</a>) (n:<a href="Coq.Init.Datatypes.html#nat">nat</a>) := <a href="Coq.ZArith.Zmisc.html#iter_nat">iter_nat</a> n <a href="Coq.ZArith.BinInt.html#Z">Z</a> (fun x:<a href="Coq.ZArith.BinInt.html#Z">Z</a> => z * x) 1.<br/>
34
<table width="100%"><tr class="doc"><td>
35
<code>Zpower_nat_is_exp</code> says <code>Zpower_nat</code> is a morphism for
36
<code>plus : nat->nat</code> and <code>Zmult : Z->Z</code>
41
<code class="keyword">Lemma</code> <a name="Zpower_nat_is_exp"></a>Zpower_nat_is_exp :<br/>
42
forall (n m:<a href="Coq.Init.Datatypes.html#nat">nat</a>) (z:<a href="Coq.ZArith.BinInt.html#Z">Z</a>),<br/>
43
<a href="Coq.ZArith.Zpower.html#Zpower_nat">Zpower_nat</a> z (n + m) = <a href="Coq.ZArith.Zpower.html#Zpower_nat">Zpower_nat</a> z n * <a href="Coq.ZArith.Zpower.html#Zpower_nat">Zpower_nat</a> z m.<br/>
47
[ simpl in |- *; elim (Zpower_nat z m); auto with zarith
48
| unfold Zpower_nat in |- *; intros; simpl in |- *; rewrite H;
49
apply Zmult_assoc ].<br/>
50
<code class="keyword">Qed</code>.<br/>
55
<table width="100%"><tr class="doc"><td>
56
<code>Zpower_pos z n</code> is the n-th power of <code>z</code> when <code>n</code> is an binary
57
integer (type <code>positive</code>) and <code>z</code> a signed integer (type <code>Z</code>)
62
<code class="keyword">Definition</code> <a name="Zpower_pos"></a>Zpower_pos (z:<a href="Coq.ZArith.BinInt.html#Z">Z</a>) (n:<a href="Coq.NArith.BinPos.html#positive">positive</a>) := <a href="Coq.ZArith.Zmisc.html#iter_pos">iter_pos</a> n <a href="Coq.ZArith.BinInt.html#Z">Z</a> (fun x:<a href="Coq.ZArith.BinInt.html#Z">Z</a> => z * x) 1.<br/>
67
<table width="100%"><tr class="doc"><td>
68
This theorem shows that powers of unary and binary integers
69
are the same thing, modulo the function convert : <code>positive -> nat</code>
74
<code class="keyword">Theorem</code> <a name="Zpower_pos_nat"></a>Zpower_pos_nat :<br/>
75
forall (z:<a href="Coq.ZArith.BinInt.html#Z">Z</a>) (p:<a href="Coq.NArith.BinPos.html#positive">positive</a>), <a href="Coq.ZArith.Zpower.html#Zpower_pos">Zpower_pos</a> z p = <a href="Coq.ZArith.Zpower.html#Zpower_nat">Zpower_nat</a> z (<a href="Coq.NArith.BinPos.html#nat_of_P">nat_of_P</a> p).<br/>
78
intros; unfold Zpower_pos in |- *; unfold Zpower_nat in |- *;<br/>
79
apply <a href="Coq.ZArith.Zmisc.html#iter_nat_of_P">iter_nat_of_P</a>.<br/>
80
<code class="keyword">Qed</code>.<br/>
85
<table width="100%"><tr class="doc"><td>
86
Using the theorem <code>Zpower_pos_nat</code> and the lemma <code>Zpower_nat_is_exp</code> we
87
deduce that the function <code>[n:positive](Zpower_pos z n)</code> is a morphism
88
for <code>add : positive->positive</code> and <code>Zmult : Z->Z</code>
93
<code class="keyword">Theorem</code> <a name="Zpower_pos_is_exp"></a>Zpower_pos_is_exp :<br/>
94
forall (n m:<a href="Coq.NArith.BinPos.html#positive">positive</a>) (z:<a href="Coq.ZArith.BinInt.html#Z">Z</a>),<br/>
95
<a href="Coq.ZArith.Zpower.html#Zpower_pos">Zpower_pos</a> z (n + m) = <a href="Coq.ZArith.Zpower.html#Zpower_pos">Zpower_pos</a> z n * <a href="Coq.ZArith.Zpower.html#Zpower_pos">Zpower_pos</a> z m.<br/>
99
rewrite (<a href="Coq.ZArith.Zpower.html#Zpower_pos_nat">Zpower_pos_nat</a> z n).<br/>
100
rewrite (<a href="Coq.ZArith.Zpower.html#Zpower_pos_nat">Zpower_pos_nat</a> z m).<br/>
101
rewrite (<a href="Coq.ZArith.Zpower.html#Zpower_pos_nat">Zpower_pos_nat</a> z (n + m)).<br/>
102
rewrite (<a href="Coq.NArith.Pnat.html#nat_of_P_plus_morphism">nat_of_P_plus_morphism</a> n m).<br/>
103
apply <a href="Coq.ZArith.Zpower.html#Zpower_nat_is_exp">Zpower_nat_is_exp</a>.<br/>
104
<code class="keyword">Qed</code>.<br/>
107
<code class="keyword">Definition</code> <a name="Zpower"></a>Zpower (x y:<a href="Coq.ZArith.BinInt.html#Z">Z</a>) :=<br/>
108
match y with<br/>
109
| <a href="Coq.ZArith.BinInt.html#Zpos">Zpos</a> p => <a href="Coq.ZArith.Zpower.html#Zpower_pos">Zpower_pos</a> x p<br/>
110
| <a href="Coq.ZArith.BinInt.html#Z0">Z0</a> => 1<br/>
111
| <a href="Coq.ZArith.BinInt.html#Zneg">Zneg</a> p => 0<br/>
112
end.<br/>
115
<code class="keyword">Infix</code> "^" := <a href="Coq.ZArith.Zpower.html#Zpower">Zpower</a> : Z_scope.<br/>
118
<code class="keyword">Hint</code> <code class="keyword">Immediate</code> <a href="Coq.ZArith.Zpower.html#Zpower_nat_is_exp">Zpower_nat_is_exp</a>: zarith.<br/>
119
<code class="keyword">Hint</code> <code class="keyword">Immediate</code> <a href="Coq.ZArith.Zpower.html#Zpower_pos_is_exp">Zpower_pos_is_exp</a>: zarith.<br/>
120
<code class="keyword">Hint</code> Unfold Zpower_pos: zarith.<br/>
121
<code class="keyword">Hint</code> Unfold Zpower_nat: zarith.<br/>
124
<code class="keyword">Lemma</code> <a name="Zpower_exp"></a>Zpower_exp :<br/>
125
forall x n m:<a href="Coq.ZArith.BinInt.html#Z">Z</a>, n >= 0 -> m >= 0 -> x ^ (n + m) = x ^ n * x ^ m.<br/>
126
destruct n; destruct m; auto with zarith.<br/>
127
simpl in |- *; intros; apply <a href="Coq.ZArith.auxiliary.html#Zred_factor0">Zred_factor0</a>.<br/>
128
simpl in |- *; auto with zarith.<br/>
129
intros; compute in H0; absurd (Datatypes.Lt = Datatypes.Lt); auto with zarith.<br/>
130
intros; compute in H0; absurd (Datatypes.Lt = Datatypes.Lt); auto with zarith.<br/>
131
<code class="keyword">Qed</code>.<br/>
134
<code class="keyword">End</code> section1.<br/>
137
<code class="keyword">Infix</code> "^" := <a href="Coq.ZArith.Zpower.html#Zpower">Zpower</a> : Z_scope.<br/>
140
<code class="keyword">Hint</code> <code class="keyword">Immediate</code> <a href="Coq.ZArith.Zpower.html#Zpower_nat_is_exp">Zpower_nat_is_exp</a>: zarith.<br/>
141
<code class="keyword">Hint</code> <code class="keyword">Immediate</code> <a href="Coq.ZArith.Zpower.html#Zpower_pos_is_exp">Zpower_pos_is_exp</a>: zarith.<br/>
142
<code class="keyword">Hint</code> Unfold Zpower_pos: zarith.<br/>
143
<code class="keyword">Hint</code> Unfold Zpower_nat: zarith.<br/>
146
<code class="keyword">Section</code> Powers_of_2.<br/>
151
<table width="100%"><tr class="doc"><td>
152
For the powers of two, that will be widely used, a more direct
153
calculus is possible. We will also prove some properties such
154
as <code>(x:positive) x < 2^x</code> that are true for all integers bigger
155
than 2 but more difficult to prove and useless.
162
<table width="100%"><tr class="doc"><td>
163
<code>shift n m</code> computes <code>2^n * m</code>, or <code>m</code> shifted by <code>n</code> positions
168
<code class="keyword">Definition</code> <a name="shift_nat"></a>shift_nat (n:<a href="Coq.Init.Datatypes.html#nat">nat</a>) (z:<a href="Coq.NArith.BinPos.html#positive">positive</a>) := <a href="Coq.ZArith.Zmisc.html#iter_nat">iter_nat</a> n <a href="Coq.NArith.BinPos.html#positive">positive</a> <a href="Coq.NArith.BinPos.html#xO">xO</a> z. <br/>
169
<code class="keyword">Definition</code> <a name="shift_pos"></a>shift_pos (n z:<a href="Coq.NArith.BinPos.html#positive">positive</a>) := <a href="Coq.ZArith.Zmisc.html#iter_pos">iter_pos</a> n <a href="Coq.NArith.BinPos.html#positive">positive</a> <a href="Coq.NArith.BinPos.html#xO">xO</a> z. <br/>
170
<code class="keyword">Definition</code> <a name="shift"></a>shift (n:<a href="Coq.ZArith.BinInt.html#Z">Z</a>) (z:<a href="Coq.NArith.BinPos.html#positive">positive</a>) :=<br/>
171
match n with<br/>
172
| <a href="Coq.ZArith.BinInt.html#Z0">Z0</a> => z<br/>
173
| <a href="Coq.ZArith.BinInt.html#Zpos">Zpos</a> p => <a href="Coq.ZArith.Zmisc.html#iter_pos">iter_pos</a> p <a href="Coq.NArith.BinPos.html#positive">positive</a> <a href="Coq.NArith.BinPos.html#xO">xO</a> z<br/>
174
| <a href="Coq.ZArith.BinInt.html#Zneg">Zneg</a> p => z<br/>
175
end.<br/>
178
<code class="keyword">Definition</code> <a name="two_power_nat"></a>two_power_nat (n:<a href="Coq.Init.Datatypes.html#nat">nat</a>) := <a href="Coq.ZArith.BinInt.html#Zpos">Zpos</a> (<a href="Coq.ZArith.Zpower.html#shift_nat">shift_nat</a> n 1).<br/>
179
<code class="keyword">Definition</code> <a name="two_power_pos"></a>two_power_pos (x:<a href="Coq.NArith.BinPos.html#positive">positive</a>) := <a href="Coq.ZArith.BinInt.html#Zpos">Zpos</a> (<a href="Coq.ZArith.Zpower.html#shift_pos">shift_pos</a> x 1).<br/>
182
<code class="keyword">Lemma</code> <a name="two_power_nat_S"></a>two_power_nat_S :<br/>
183
forall n:<a href="Coq.Init.Datatypes.html#nat">nat</a>, <a href="Coq.ZArith.Zpower.html#two_power_nat">two_power_nat</a> (<a href="Coq.Init.Datatypes.html#S">S</a> n) = 2 * <a href="Coq.ZArith.Zpower.html#two_power_nat">two_power_nat</a> n.<br/>
184
intro; simpl in |- *; apply <a href="Coq.Init.Logic.html#refl_equal">refl_equal</a>.<br/>
185
<code class="keyword">Qed</code>.<br/>
188
<code class="keyword">Lemma</code> <a name="shift_nat_plus"></a>shift_nat_plus :<br/>
189
forall (n m:<a href="Coq.Init.Datatypes.html#nat">nat</a>) (x:<a href="Coq.NArith.BinPos.html#positive">positive</a>),<br/>
190
<a href="Coq.ZArith.Zpower.html#shift_nat">shift_nat</a> (n + m) x = <a href="Coq.ZArith.Zpower.html#shift_nat">shift_nat</a> n (<a href="Coq.ZArith.Zpower.html#shift_nat">shift_nat</a> m x).<br/>
193
intros; unfold shift_nat in |- *; apply <a href="Coq.ZArith.Zmisc.html#iter_nat_plus">iter_nat_plus</a>.<br/>
194
<code class="keyword">Qed</code>.<br/>
197
<code class="keyword">Theorem</code> <a name="shift_nat_correct"></a>shift_nat_correct :<br/>
198
forall (n:<a href="Coq.Init.Datatypes.html#nat">nat</a>) (x:<a href="Coq.NArith.BinPos.html#positive">positive</a>), <a href="Coq.ZArith.BinInt.html#Zpos">Zpos</a> (<a href="Coq.ZArith.Zpower.html#shift_nat">shift_nat</a> n x) = <a href="Coq.ZArith.Zpower.html#Zpower_nat">Zpower_nat</a> 2 n * <a href="Coq.ZArith.BinInt.html#Zpos">Zpos</a> x.<br/>
201
unfold shift_nat in |- *; simple induction n;<br/>
202
[ simpl in |- *; trivial with zarith<br/>
203
| intros; replace (<a href="Coq.ZArith.Zpower.html#Zpower_nat">Zpower_nat</a> 2 (<a href="Coq.Init.Datatypes.html#S">S</a> n0)) with (2 * <a href="Coq.ZArith.Zpower.html#Zpower_nat">Zpower_nat</a> 2 n0);<br/>
204
[ rewrite <- Zmult_assoc; rewrite <- (H x); simpl in |- *; reflexivity
205
| auto with zarith ] ].<br/>
206
<code class="keyword">Qed</code>.<br/>
209
<code class="keyword">Theorem</code> <a name="two_power_nat_correct"></a>two_power_nat_correct :<br/>
210
forall n:<a href="Coq.Init.Datatypes.html#nat">nat</a>, <a href="Coq.ZArith.Zpower.html#two_power_nat">two_power_nat</a> n = <a href="Coq.ZArith.Zpower.html#Zpower_nat">Zpower_nat</a> 2 n.<br/>
214
unfold two_power_nat in |- *.<br/>
215
rewrite (<a href="Coq.ZArith.Zpower.html#shift_nat_correct">shift_nat_correct</a> n).<br/>
217
<code class="keyword">Qed</code>.<br/>
221
<table width="100%"><tr class="doc"><td>
222
Second we show that <code>two_power_pos</code> and <code>two_power_nat</code> are the same
225
<code class="keyword">Lemma</code> <a name="shift_pos_nat"></a>shift_pos_nat :<br/>
226
forall p x:<a href="Coq.NArith.BinPos.html#positive">positive</a>, <a href="Coq.ZArith.Zpower.html#shift_pos">shift_pos</a> p x = <a href="Coq.ZArith.Zpower.html#shift_nat">shift_nat</a> (<a href="Coq.NArith.BinPos.html#nat_of_P">nat_of_P</a> p) x.<br/>
229
unfold shift_pos in |- *.<br/>
230
unfold shift_nat in |- *.<br/>
231
intros; apply <a href="Coq.ZArith.Zmisc.html#iter_nat_of_P">iter_nat_of_P</a>.<br/>
232
<code class="keyword">Qed</code>.<br/>
235
<code class="keyword">Lemma</code> <a name="two_power_pos_nat"></a>two_power_pos_nat :<br/>
236
forall p:<a href="Coq.NArith.BinPos.html#positive">positive</a>, <a href="Coq.ZArith.Zpower.html#two_power_pos">two_power_pos</a> p = <a href="Coq.ZArith.Zpower.html#two_power_nat">two_power_nat</a> (<a href="Coq.NArith.BinPos.html#nat_of_P">nat_of_P</a> p).<br/>
239
intro; unfold two_power_pos in |- *; unfold two_power_nat in |- *.<br/>
240
apply <a href="Coq.Init.Logic.html#f_equal">f_equal</a> with (f:= <a href="Coq.ZArith.BinInt.html#Zpos">Zpos</a>).<br/>
241
apply <a href="Coq.ZArith.Zpower.html#shift_pos_nat">shift_pos_nat</a>.<br/>
242
<code class="keyword">Qed</code>.<br/>
247
<table width="100%"><tr class="doc"><td>
248
Then we deduce that <code>two_power_pos</code> is also correct
253
<code class="keyword">Theorem</code> <a name="shift_pos_correct"></a>shift_pos_correct :<br/>
254
forall p x:<a href="Coq.NArith.BinPos.html#positive">positive</a>, <a href="Coq.ZArith.BinInt.html#Zpos">Zpos</a> (<a href="Coq.ZArith.Zpower.html#shift_pos">shift_pos</a> p x) = <a href="Coq.ZArith.Zpower.html#Zpower_pos">Zpower_pos</a> 2 p * <a href="Coq.ZArith.BinInt.html#Zpos">Zpos</a> x.<br/>
258
rewrite (<a href="Coq.ZArith.Zpower.html#shift_pos_nat">shift_pos_nat</a> p x).<br/>
259
rewrite (<a href="Coq.ZArith.Zpower.html#Zpower_pos_nat">Zpower_pos_nat</a> 2 p).<br/>
260
apply <a href="Coq.ZArith.Zpower.html#shift_nat_correct">shift_nat_correct</a>.<br/>
261
<code class="keyword">Qed</code>.<br/>
264
<code class="keyword">Theorem</code> <a name="two_power_pos_correct"></a>two_power_pos_correct :<br/>
265
forall x:<a href="Coq.NArith.BinPos.html#positive">positive</a>, <a href="Coq.ZArith.Zpower.html#two_power_pos">two_power_pos</a> x = <a href="Coq.ZArith.Zpower.html#Zpower_pos">Zpower_pos</a> 2 x.<br/>
269
rewrite <a href="Coq.ZArith.Zpower.html#two_power_pos_nat">two_power_pos_nat</a>.<br/>
270
rewrite <a href="Coq.ZArith.Zpower.html#Zpower_pos_nat">Zpower_pos_nat</a>.<br/>
271
apply <a href="Coq.ZArith.Zpower.html#two_power_nat_correct">two_power_nat_correct</a>.<br/>
272
<code class="keyword">Qed</code>.<br/>
277
<table width="100%"><tr class="doc"><td>
283
<code class="keyword">Theorem</code> <a name="two_power_pos_is_exp"></a>two_power_pos_is_exp :<br/>
284
forall x y:<a href="Coq.NArith.BinPos.html#positive">positive</a>,<br/>
285
<a href="Coq.ZArith.Zpower.html#two_power_pos">two_power_pos</a> (x + y) = <a href="Coq.ZArith.Zpower.html#two_power_pos">two_power_pos</a> x * <a href="Coq.ZArith.Zpower.html#two_power_pos">two_power_pos</a> y.<br/>
287
rewrite (<a href="Coq.ZArith.Zpower.html#two_power_pos_correct">two_power_pos_correct</a> (x + y)).<br/>
288
rewrite (<a href="Coq.ZArith.Zpower.html#two_power_pos_correct">two_power_pos_correct</a> x).<br/>
289
rewrite (<a href="Coq.ZArith.Zpower.html#two_power_pos_correct">two_power_pos_correct</a> y).<br/>
290
apply <a href="Coq.ZArith.Zpower.html#Zpower_pos_is_exp">Zpower_pos_is_exp</a>.<br/>
291
<code class="keyword">Qed</code>.<br/>
296
<table width="100%"><tr class="doc"><td>
297
The exponentiation <code>z -> 2^z</code> for <code>z</code> a signed integer.
298
For convenience, we assume that <code>2^z = 0</code> for all <code>z < 0</code>
299
We could also define a inductive type <code>Log_result</code> with
300
3 contructors <code> Zero | Pos positive -> | minus_infty</code>
301
but it's more complexe and not so useful.
305
<code class="keyword">Definition</code> <a name="two_p"></a>two_p (x:<a href="Coq.ZArith.BinInt.html#Z">Z</a>) :=<br/>
306
match x with<br/>
307
| <a href="Coq.ZArith.BinInt.html#Z0">Z0</a> => 1<br/>
308
| <a href="Coq.ZArith.BinInt.html#Zpos">Zpos</a> y => <a href="Coq.ZArith.Zpower.html#two_power_pos">two_power_pos</a> y<br/>
309
| <a href="Coq.ZArith.BinInt.html#Zneg">Zneg</a> y => 0<br/>
310
end.<br/>
313
<code class="keyword">Theorem</code> <a name="two_p_is_exp"></a>two_p_is_exp :<br/>
314
forall x y:<a href="Coq.ZArith.BinInt.html#Z">Z</a>, 0 <= x -> 0 <= y -> <a href="Coq.ZArith.Zpower.html#two_p">two_p</a> (x + y) = <a href="Coq.ZArith.Zpower.html#two_p">two_p</a> x * <a href="Coq.ZArith.Zpower.html#two_p">two_p</a> y.<br/>
315
simple induction x;<br/>
316
[ simple induction y; simpl in |- *; auto with zarith<br/>
317
| simple induction y;<br/>
318
[ unfold two_p in |- *; rewrite (Zmult_comm (two_power_pos p) 1);
319
rewrite (Zmult_1_l (two_power_pos p)); auto with zarith
320
| unfold Zplus in |- *; unfold two_p in |- *; intros;
321
apply two_power_pos_is_exp
322
| intros; unfold Zle in H0; unfold Zcompare in H0;
323
absurd (Datatypes.Gt = Datatypes.Gt); trivial with zarith ]<br/>
324
| simple induction y;<br/>
325
[ simpl in |- *; auto with zarith
326
| intros; unfold Zle in H; unfold Zcompare in H;
327
absurd (Datatypes.Gt = Datatypes.Gt); trivial with zarith
328
| intros; unfold Zle in H; unfold Zcompare in H;
329
absurd (Datatypes.Gt = Datatypes.Gt); trivial with zarith ] ].<br/>
330
<code class="keyword">Qed</code>.<br/>
333
<code class="keyword">Lemma</code> <a name="two_p_gt_ZERO"></a>two_p_gt_ZERO : forall x:<a href="Coq.ZArith.BinInt.html#Z">Z</a>, 0 <= x -> <a href="Coq.ZArith.Zpower.html#two_p">two_p</a> x > 0.<br/>
334
simple induction x; intros;<br/>
335
[ simpl in |- *; omega<br/>
336
| simpl in |- *; unfold two_power_pos in |- *; apply Zorder.Zgt_pos_0<br/>
337
| absurd (0 <= <a href="Coq.ZArith.BinInt.html#Zneg">Zneg</a> p);<br/>
338
[ simpl in |- *; unfold Zle in |- *; unfold Zcompare in |- *;
339
do 2 unfold not in |- *; auto with zarith
340
| assumption ] ].<br/>
341
<code class="keyword">Qed</code>.<br/>
344
<code class="keyword">Lemma</code> <a name="two_p_S"></a>two_p_S : forall x:<a href="Coq.ZArith.BinInt.html#Z">Z</a>, 0 <= x -> <a href="Coq.ZArith.Zpower.html#two_p">two_p</a> (<a href="Coq.ZArith.BinInt.html#Zsucc">Zsucc</a> x) = 2 * <a href="Coq.ZArith.Zpower.html#two_p">two_p</a> x.<br/>
345
intros; unfold Zsucc in |- *. <br/>
346
rewrite (<a href="Coq.ZArith.Zpower.html#two_p_is_exp">two_p_is_exp</a> x 1 H (Zorder.Zle_0_pos 1)).<br/>
347
apply <a href="Coq.ZArith.BinInt.html#Zmult_comm">Zmult_comm</a>.<br/>
348
<code class="keyword">Qed</code>.<br/>
351
<code class="keyword">Lemma</code> <a name="two_p_pred"></a>two_p_pred : forall x:<a href="Coq.ZArith.BinInt.html#Z">Z</a>, 0 <= x -> <a href="Coq.ZArith.Zpower.html#two_p">two_p</a> (<a href="Coq.ZArith.BinInt.html#Zpred">Zpred</a> x) < <a href="Coq.ZArith.Zpower.html#two_p">two_p</a> x.<br/>
352
intros; apply <a href="Coq.ZArith.Wf_Z.html#natlike_ind">natlike_ind</a> with (P:= fun x:<a href="Coq.ZArith.BinInt.html#Z">Z</a> => <a href="Coq.ZArith.Zpower.html#two_p">two_p</a> (<a href="Coq.ZArith.BinInt.html#Zpred">Zpred</a> x) < <a href="Coq.ZArith.Zpower.html#two_p">two_p</a> x);<br/>
353
[ simpl in |- *; unfold Zlt in |- *; auto with zarith<br/>
354
| intros; elim (<a href="Coq.ZArith.Zorder.html#Zle_lt_or_eq">Zle_lt_or_eq</a> 0 x0 H0);<br/>
355
[ intros;<br/>
356
replace (<a href="Coq.ZArith.Zpower.html#two_p">two_p</a> (<a href="Coq.ZArith.BinInt.html#Zpred">Zpred</a> (<a href="Coq.ZArith.BinInt.html#Zsucc">Zsucc</a> x0))) with (<a href="Coq.ZArith.Zpower.html#two_p">two_p</a> (<a href="Coq.ZArith.BinInt.html#Zsucc">Zsucc</a> (<a href="Coq.ZArith.BinInt.html#Zpred">Zpred</a> x0)));<br/>
357
[ rewrite (<a href="Coq.ZArith.Zpower.html#two_p_S">two_p_S</a> (<a href="Coq.ZArith.BinInt.html#Zpred">Zpred</a> x0));<br/>
358
[ rewrite (<a href="Coq.ZArith.Zpower.html#two_p_S">two_p_S</a> x0); [ omega | assumption ]<br/>
359
| apply Zorder.Zlt_0_le_0_pred; assumption ]<br/>
360
| rewrite <- (<a href="Coq.ZArith.BinInt.html#Zsucc_pred">Zsucc_pred</a> x0); rewrite <- (<a href="Coq.ZArith.BinInt.html#Zpred_succ">Zpred_succ</a> x0);<br/>
361
trivial with zarith ]<br/>
362
| intro Hx0; rewrite <- Hx0; simpl in |- *; unfold Zlt in |- *;<br/>
363
auto with zarith ]<br/>
364
| assumption ].<br/>
365
<code class="keyword">Qed</code>. <br/>
368
<code class="keyword">Lemma</code> <a name="Zlt_lt_double"></a>Zlt_lt_double : forall x y:<a href="Coq.ZArith.BinInt.html#Z">Z</a>, 0 <= x < y -> x < 2 * y.<br/>
369
intros; omega. <code class="keyword">Qed</code>. <br/>
372
<code class="keyword">End</code> Powers_of_2.<br/>
375
<code class="keyword">Hint</code> Resolve <a href="Coq.ZArith.Zpower.html#two_p_gt_ZERO">two_p_gt_ZERO</a>: zarith.<br/>
376
<code class="keyword">Hint</code> <code class="keyword">Immediate</code> <a href="Coq.ZArith.Zpower.html#two_p_pred">two_p_pred</a> <a href="Coq.ZArith.Zpower.html#two_p_S">two_p_S</a>: zarith.<br/>
379
<code class="keyword">Section</code> power_div_with_rest.<br/>
384
<table width="100%"><tr class="doc"><td>
385
Division by a power of two.
386
To <code>n:Z</code> and <code>p:positive</code>, <code>q</code>,<code>r</code> are associated such that
387
<code>n = 2^p.q + r</code> and <code>0 <= r < 2^p</code>
394
<table width="100%"><tr class="doc"><td>
395
Invariant: <code>d*q + r = d'*q + r /\ d' = 2*d /\ 0<= r < d /\ 0 <= r' < d'</code>
398
<code class="keyword">Definition</code> <a name="Zdiv_rest_aux"></a>Zdiv_rest_aux (qrd:<a href="Coq.ZArith.BinInt.html#Z">Z</a> * <a href="Coq.ZArith.BinInt.html#Z">Z</a> * <a href="Coq.ZArith.BinInt.html#Z">Z</a>) :=<br/>
399
let (qr, d) := qrd in<br/>
400
let (q, r) := qr in<br/>
401
(match q with<br/>
402
| <a href="Coq.ZArith.BinInt.html#Z0">Z0</a> => (0, r)<br/>
403
| <a href="Coq.ZArith.BinInt.html#Zpos">Zpos</a> <a href="Coq.NArith.BinPos.html#xH">xH</a> => (0, d + r)<br/>
404
| <a href="Coq.ZArith.BinInt.html#Zpos">Zpos</a> (<a href="Coq.NArith.BinPos.html#xI">xI</a> n) => (<a href="Coq.ZArith.BinInt.html#Zpos">Zpos</a> n, d + r)<br/>
405
| <a href="Coq.ZArith.BinInt.html#Zpos">Zpos</a> (<a href="Coq.NArith.BinPos.html#xO">xO</a> n) => (<a href="Coq.ZArith.BinInt.html#Zpos">Zpos</a> n, r)<br/>
406
| <a href="Coq.ZArith.BinInt.html#Zneg">Zneg</a> <a href="Coq.NArith.BinPos.html#xH">xH</a> => (-1, d + r)<br/>
407
| <a href="Coq.ZArith.BinInt.html#Zneg">Zneg</a> (<a href="Coq.NArith.BinPos.html#xI">xI</a> n) => (<a href="Coq.ZArith.BinInt.html#Zneg">Zneg</a> n - 1, d + r)<br/>
408
| <a href="Coq.ZArith.BinInt.html#Zneg">Zneg</a> (<a href="Coq.NArith.BinPos.html#xO">xO</a> n) => (<a href="Coq.ZArith.BinInt.html#Zneg">Zneg</a> n, r)<br/>
409
end, 2 * d).<br/>
412
<code class="keyword">Definition</code> <a name="Zdiv_rest"></a>Zdiv_rest (x:<a href="Coq.ZArith.BinInt.html#Z">Z</a>) (p:<a href="Coq.NArith.BinPos.html#positive">positive</a>) :=<br/>
413
let (qr, d) := <a href="Coq.ZArith.Zmisc.html#iter_pos">iter_pos</a> p _ <a href="Coq.ZArith.Zpower.html#Zdiv_rest_aux">Zdiv_rest_aux</a> (x, 0, 1) in qr.<br/>
416
<code class="keyword">Lemma</code> <a name="Zdiv_rest_correct1"></a>Zdiv_rest_correct1 :<br/>
417
forall (x:<a href="Coq.ZArith.BinInt.html#Z">Z</a>) (p:<a href="Coq.NArith.BinPos.html#positive">positive</a>),<br/>
418
let (qr, d) := <a href="Coq.ZArith.Zmisc.html#iter_pos">iter_pos</a> p _ <a href="Coq.ZArith.Zpower.html#Zdiv_rest_aux">Zdiv_rest_aux</a> (x, 0, 1) in d = <a href="Coq.ZArith.Zpower.html#two_power_pos">two_power_pos</a> p.<br/>
421
intros x p; rewrite (<a href="Coq.ZArith.Zmisc.html#iter_nat_of_P">iter_nat_of_P</a> p _ <a href="Coq.ZArith.Zpower.html#Zdiv_rest_aux">Zdiv_rest_aux</a> (x, 0, 1));<br/>
422
rewrite (<a href="Coq.ZArith.Zpower.html#two_power_pos_nat">two_power_pos_nat</a> p); elim (<a href="Coq.NArith.BinPos.html#nat_of_P">nat_of_P</a> p); <br/>
423
simpl in |- *;<br/>
424
[ trivial with zarith<br/>
425
| intro n; rewrite (<a href="Coq.ZArith.Zpower.html#two_power_nat_S">two_power_nat_S</a> n); unfold Zdiv_rest_aux at 2 in |- *;<br/>
426
elim (<a href="Coq.ZArith.Zmisc.html#iter_nat">iter_nat</a> n (<a href="Coq.ZArith.BinInt.html#Z">Z</a> * <a href="Coq.ZArith.BinInt.html#Z">Z</a> * <a href="Coq.ZArith.BinInt.html#Z">Z</a>) <a href="Coq.ZArith.Zpower.html#Zdiv_rest_aux">Zdiv_rest_aux</a> (x, 0, 1)); <br/>
427
destruct a; intros; apply <a href="Coq.Init.Logic.html#f_equal">f_equal</a> with (f:= fun z:<a href="Coq.ZArith.BinInt.html#Z">Z</a> => 2 * z);<br/>
428
assumption ]. <br/>
429
<code class="keyword">Qed</code>.<br/>
432
<code class="keyword">Lemma</code> <a name="Zdiv_rest_correct2"></a>Zdiv_rest_correct2 :<br/>
433
forall (x:<a href="Coq.ZArith.BinInt.html#Z">Z</a>) (p:<a href="Coq.NArith.BinPos.html#positive">positive</a>),<br/>
434
let (qr, d) := <a href="Coq.ZArith.Zmisc.html#iter_pos">iter_pos</a> p _ <a href="Coq.ZArith.Zpower.html#Zdiv_rest_aux">Zdiv_rest_aux</a> (x, 0, 1) in<br/>
435
let (q, r) := qr in x = q * d + r /\ 0 <= r < d.<br/>
439
apply <a href="Coq.ZArith.Zmisc.html#iter_pos_invariant">iter_pos_invariant</a> with<br/>
440
(f:= <a href="Coq.ZArith.Zpower.html#Zdiv_rest_aux">Zdiv_rest_aux</a>)<br/>
441
(Inv:= fun qrd:<a href="Coq.ZArith.BinInt.html#Z">Z</a> * <a href="Coq.ZArith.BinInt.html#Z">Z</a> * <a href="Coq.ZArith.BinInt.html#Z">Z</a> =><br/>
442
let (qr, d) := qrd in<br/>
443
let (q, r) := qr in x = q * d + r /\ 0 <= r < d);<br/>
444
[ intro x0; elim x0; intro y0; elim y0; intros q r d;<br/>
445
unfold Zdiv_rest_aux in |- *; elim q;<br/>
446
[ omega<br/>
447
| destruct p0;<br/>
448
[ rewrite BinInt.Zpos_xI; intro; elim H; intros; split;<br/>
449
[ rewrite H0; rewrite Zplus_assoc; rewrite Zmult_plus_distr_l;
450
rewrite Zmult_1_l; rewrite Zmult_assoc;
451
rewrite (Zmult_comm (Zpos p0) 2); apply refl_equal
453
| rewrite BinInt.Zpos_xO; intro; elim H; intros; split;<br/>
454
[ rewrite H0; rewrite Zmult_assoc; rewrite (Zmult_comm (Zpos p0) 2);
457
| omega ]<br/>
458
| destruct p0;<br/>
459
[ rewrite BinInt.Zneg_xI; unfold Zminus in |- *; intro; elim H; intros;<br/>
460
split;<br/>
461
[ rewrite H0; rewrite <a href="Coq.ZArith.BinInt.html#Zplus_assoc">Zplus_assoc</a>;<br/>
462
apply <a href="Coq.Init.Logic.html#f_equal">f_equal</a> with (f:= fun z:<a href="Coq.ZArith.BinInt.html#Z">Z</a> => z + r);<br/>
463
do 2 rewrite <a href="Coq.ZArith.BinInt.html#Zmult_plus_distr_l">Zmult_plus_distr_l</a>; rewrite <a href="Coq.ZArith.BinInt.html#Zmult_assoc">Zmult_assoc</a>;<br/>
464
rewrite (<a href="Coq.ZArith.BinInt.html#Zmult_comm">Zmult_comm</a> (<a href="Coq.ZArith.BinInt.html#Zneg">Zneg</a> p0) 2); rewrite <- <a href="Coq.ZArith.BinInt.html#Zplus_assoc">Zplus_assoc</a>;<br/>
465
apply <a href="Coq.Init.Logic.html#f_equal">f_equal</a> with (f:= fun z:<a href="Coq.ZArith.BinInt.html#Z">Z</a> => 2 * <a href="Coq.ZArith.BinInt.html#Zneg">Zneg</a> p0 * d + z); <br/>
466
omega<br/>
467
| omega ]<br/>
468
| rewrite BinInt.Zneg_xO; unfold Zminus in |- *; intro; elim H; intros;<br/>
469
split;<br/>
470
[ rewrite H0; rewrite Zmult_assoc; rewrite (Zmult_comm (Zneg p0) 2);
473
| omega ] ]<br/>
474
| omega ].<br/>
475
<code class="keyword">Qed</code>.<br/>
478
<code class="keyword">Inductive</code> <a name="Zdiv_rest_proofs"></a>Zdiv_rest_proofs (x:<a href="Coq.ZArith.BinInt.html#Z">Z</a>) (p:<a href="Coq.NArith.BinPos.html#positive">positive</a>) : Set :=<br/>
479
<a name="Zdiv_rest_proof"></a>Zdiv_rest_proof :<br/>
480
forall q r:<a href="Coq.ZArith.BinInt.html#Z">Z</a>,<br/>
481
x = q * <a href="Coq.ZArith.Zpower.html#two_power_pos">two_power_pos</a> p + r -><br/>
482
0 <= r -> r < <a href="Coq.ZArith.Zpower.html#two_power_pos">two_power_pos</a> p -> Zdiv_rest_proofs x p.<br/>
485
<code class="keyword">Lemma</code> <a name="Zdiv_rest_correct"></a>Zdiv_rest_correct : forall (x:<a href="Coq.ZArith.BinInt.html#Z">Z</a>) (p:<a href="Coq.NArith.BinPos.html#positive">positive</a>), <a href="Coq.ZArith.Zpower.html#Zdiv_rest_proofs">Zdiv_rest_proofs</a> x p.<br/>
487
generalize (<a href="Coq.ZArith.Zpower.html#Zdiv_rest_correct1">Zdiv_rest_correct1</a> x p); generalize (<a href="Coq.ZArith.Zpower.html#Zdiv_rest_correct2">Zdiv_rest_correct2</a> x p).<br/>
488
elim (<a href="Coq.ZArith.Zmisc.html#iter_pos">iter_pos</a> p (<a href="Coq.ZArith.BinInt.html#Z">Z</a> * <a href="Coq.ZArith.BinInt.html#Z">Z</a> * <a href="Coq.ZArith.BinInt.html#Z">Z</a>) <a href="Coq.ZArith.Zpower.html#Zdiv_rest_aux">Zdiv_rest_aux</a> (x, 0, 1)).<br/>
489
simple induction a.<br/>
491
elim H; intros H1 H2; clear H.<br/>
492
rewrite H0 in H1; rewrite H0 in H2; elim H2; intros;<br/>
493
apply <a href="Coq.ZArith.Zpower.html#Zdiv_rest_proof">Zdiv_rest_proof</a> with (q:= a0) (r:= b); assumption.<br/>
494
<code class="keyword">Qed</code>.<br/>
497
<code class="keyword">End</code> power_div_with_rest.</code>
498
<hr/><a href="index.html">Index</a><hr/><font size="-1">This page has been generated by <a href="http://www.lri.fr/~filliatr/coqdoc/">coqdoc</a></font>
b'\\ No newline at end of file'