~ubuntu-branches/ubuntu/wily/coq-doc/wily

« back to all changes in this revision

Viewing changes to theories/NArith/BinPos.v

  • Committer: Bazaar Package Importer
  • Author(s): Stéphane Glondu, Stéphane Glondu, Samuel Mimram
  • Date: 2010-01-07 22:50:39 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100107225039-n3cq82589u0qt0s2
Tags: 8.2pl1-1
[ Stéphane Glondu ]
* New upstream release (Closes: #563669)
  - remove patches
* Packaging overhaul:
  - use git, advertise it in Vcs-* fields of debian/control
  - use debhelper 7 and dh with override
  - use source format 3.0 (quilt)
* debian/control:
  - set Maintainer to d-o-m, set Uploaders to Sam and myself
  - add Homepage field
  - bump Standards-Version to 3.8.3
* Register PDF documentation into doc-base
* Add debian/watch
* Update debian/copyright

[ Samuel Mimram ]
* Change coq-doc's description to mention that it provides documentation in
  pdf format, not postscript, closes: #543545.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
(************************************************************************)
 
8
 
 
9
(*i $Id: BinPos.v 11033 2008-06-01 22:56:50Z letouzey $ i*)
 
10
 
 
11
Unset Boxed Definitions.
 
12
 
 
13
(**********************************************************************)
 
14
(** Binary positive numbers *)
 
15
 
 
16
(** Original development by Pierre Crégut, CNET, Lannion, France *)
 
17
 
 
18
Inductive positive : Set :=
 
19
| xI : positive -> positive
 
20
| xO : positive -> positive
 
21
| xH : positive.
 
22
 
 
23
(** Declare binding key for scope positive_scope *)
 
24
 
 
25
Delimit Scope positive_scope with positive.
 
26
 
 
27
(** Automatically open scope positive_scope for type positive, xO and xI *)
 
28
 
 
29
Bind Scope positive_scope with positive.
 
30
Arguments Scope xO [positive_scope].
 
31
Arguments Scope xI [positive_scope].
 
32
 
 
33
(** Postfix notation for positive numbers, allowing to mimic 
 
34
    the position of bits in a big-endian representation. 
 
35
    For instance, we can write 1~1~0 instead of (xO (xI xH)) 
 
36
    for the number 6 (which is 110 in binary notation).
 
37
*)
 
38
 
 
39
Notation "p ~ 1" := (xI p) 
 
40
 (at level 7, left associativity, format "p '~' '1'") : positive_scope.
 
41
Notation "p ~ 0" := (xO p) 
 
42
 (at level 7, left associativity, format "p '~' '0'") : positive_scope.
 
43
 
 
44
Open Local Scope positive_scope.
 
45
 
 
46
(* In the current file, [xH] cannot yet be written as [1], since the
 
47
   interpretation of positive numerical constants is not available
 
48
   yet. We fix this here with an ad-hoc temporary notation. *)
 
49
 
 
50
Notation Local "1" := xH (at level 7).
 
51
 
 
52
(** Successor *)
 
53
 
 
54
Fixpoint Psucc (x:positive) : positive :=
 
55
  match x with
 
56
    | p~1 => (Psucc p)~0
 
57
    | p~0 => p~1
 
58
    | 1 => 1~0
 
59
  end.
 
60
 
 
61
(** Addition *)
 
62
 
 
63
Set Boxed Definitions.
 
64
 
 
65
Fixpoint Pplus (x y:positive) : positive :=
 
66
  match x, y with
 
67
    | p~1, q~1 => (Pplus_carry p q)~0
 
68
    | p~1, q~0 => (Pplus p q)~1
 
69
    | p~1, 1 => (Psucc p)~0
 
70
    | p~0, q~1 => (Pplus p q)~1
 
71
    | p~0, q~0 => (Pplus p q)~0
 
72
    | p~0, 1 => p~1
 
73
    | 1, q~1 => (Psucc q)~0
 
74
    | 1, q~0 => q~1
 
75
    | 1, 1 => 1~0
 
76
  end
 
77
  
 
78
with Pplus_carry (x y:positive) : positive :=
 
79
  match x, y with
 
80
    | p~1, q~1 => (Pplus_carry p q)~1
 
81
    | p~1, q~0 => (Pplus_carry p q)~0
 
82
    | p~1, 1 => (Psucc p)~1
 
83
    | p~0, q~1 => (Pplus_carry p q)~0
 
84
    | p~0, q~0 => (Pplus p q)~1
 
85
    | p~0, 1 => (Psucc p)~0
 
86
    | 1, q~1 => (Psucc q)~1
 
87
    | 1, q~0 => (Psucc q)~0
 
88
    | 1, 1 => 1~1
 
89
  end.
 
90
 
 
91
Unset Boxed Definitions.
 
92
 
 
93
Infix "+" := Pplus : positive_scope.
 
94
 
 
95
(** From binary positive numbers to Peano natural numbers *)
 
96
 
 
97
Fixpoint Pmult_nat (x:positive) (pow2:nat) : nat :=
 
98
  match x with
 
99
    | p~1 => (pow2 + Pmult_nat p (pow2 + pow2))%nat
 
100
    | p~0 => Pmult_nat p (pow2 + pow2)%nat
 
101
    | 1 => pow2
 
102
  end.
 
103
 
 
104
Definition nat_of_P (x:positive) := Pmult_nat x (S O).
 
105
 
 
106
(** From Peano natural numbers to binary positive numbers *)
 
107
 
 
108
Fixpoint P_of_succ_nat (n:nat) : positive :=
 
109
  match n with
 
110
    | O => 1
 
111
    | S x => Psucc (P_of_succ_nat x)
 
112
  end.
 
113
 
 
114
(** Operation x -> 2*x-1 *)
 
115
 
 
116
Fixpoint Pdouble_minus_one (x:positive) : positive :=
 
117
  match x with
 
118
    | p~1 => p~0~1
 
119
    | p~0 => (Pdouble_minus_one p)~1
 
120
    | 1 => 1
 
121
  end.
 
122
 
 
123
(** Predecessor *)
 
124
 
 
125
Definition Ppred (x:positive) :=
 
126
  match x with
 
127
    | p~1 => p~0
 
128
    | p~0 => Pdouble_minus_one p
 
129
    | 1 => 1
 
130
  end.
 
131
 
 
132
(** An auxiliary type for subtraction *)
 
133
 
 
134
Inductive positive_mask : Set :=
 
135
| IsNul : positive_mask
 
136
| IsPos : positive -> positive_mask
 
137
| IsNeg : positive_mask.
 
138
 
 
139
(** Operation x -> 2*x+1 *)
 
140
 
 
141
Definition Pdouble_plus_one_mask (x:positive_mask) :=
 
142
  match x with
 
143
    | IsNul => IsPos 1
 
144
    | IsNeg => IsNeg
 
145
    | IsPos p => IsPos p~1
 
146
  end.
 
147
 
 
148
(** Operation x -> 2*x *)
 
149
 
 
150
Definition Pdouble_mask (x:positive_mask) :=
 
151
  match x with
 
152
    | IsNul => IsNul
 
153
    | IsNeg => IsNeg
 
154
    | IsPos p => IsPos p~0
 
155
  end.
 
156
 
 
157
(** Operation x -> 2*x-2 *)
 
158
 
 
159
Definition Pdouble_minus_two (x:positive) :=
 
160
  match x with
 
161
    | p~1 => IsPos p~0~0
 
162
    | p~0 => IsPos (Pdouble_minus_one p)~0
 
163
    | 1 => IsNul
 
164
  end.
 
165
 
 
166
(** Subtraction of binary positive numbers into a positive numbers mask *)
 
167
 
 
168
Fixpoint Pminus_mask (x y:positive) {struct y} : positive_mask :=
 
169
  match x, y with
 
170
    | p~1, q~1 => Pdouble_mask (Pminus_mask p q)
 
171
    | p~1, q~0 => Pdouble_plus_one_mask (Pminus_mask p q)
 
172
    | p~1, 1 => IsPos p~0
 
173
    | p~0, q~1 => Pdouble_plus_one_mask (Pminus_mask_carry p q)
 
174
    | p~0, q~0 => Pdouble_mask (Pminus_mask p q)
 
175
    | p~0, 1 => IsPos (Pdouble_minus_one p)
 
176
    | 1, 1 => IsNul
 
177
    | 1, _ => IsNeg
 
178
  end
 
179
  
 
180
with Pminus_mask_carry (x y:positive) {struct y} : positive_mask :=
 
181
  match x, y with
 
182
    | p~1, q~1 => Pdouble_plus_one_mask (Pminus_mask_carry p q)
 
183
    | p~1, q~0 => Pdouble_mask (Pminus_mask p q)
 
184
    | p~1, 1 => IsPos (Pdouble_minus_one p)
 
185
    | p~0, q~1 => Pdouble_mask (Pminus_mask_carry p q)
 
186
    | p~0, q~0 => Pdouble_plus_one_mask (Pminus_mask_carry p q)
 
187
    | p~0, 1 => Pdouble_minus_two p
 
188
    | 1, _ => IsNeg
 
189
  end.
 
190
 
 
191
(** Subtraction of binary positive numbers x and y, returns 1 if x<=y *)
 
192
 
 
193
Definition Pminus (x y:positive) :=
 
194
  match Pminus_mask x y with
 
195
    | IsPos z => z
 
196
    | _ => 1
 
197
  end.
 
198
 
 
199
Infix "-" := Pminus : positive_scope.
 
200
 
 
201
(** Multiplication on binary positive numbers *)
 
202
 
 
203
Fixpoint Pmult (x y:positive) : positive :=
 
204
  match x with
 
205
    | p~1 => y + (Pmult p y)~0
 
206
    | p~0 => (Pmult p y)~0
 
207
    | 1 => y
 
208
  end.
 
209
 
 
210
Infix "*" := Pmult : positive_scope.
 
211
 
 
212
(** Division by 2 rounded below but for 1 *)
 
213
 
 
214
Definition Pdiv2 (z:positive) :=
 
215
  match z with
 
216
    | 1 => 1
 
217
    | p~0 => p
 
218
    | p~1 => p
 
219
  end.
 
220
 
 
221
Infix "/" := Pdiv2 : positive_scope.
 
222
 
 
223
(** Comparison on binary positive numbers *)
 
224
 
 
225
Fixpoint Pcompare (x y:positive) (r:comparison) {struct y} : comparison :=
 
226
  match x, y with
 
227
    | p~1, q~1 => Pcompare p q r
 
228
    | p~1, q~0 => Pcompare p q Gt
 
229
    | p~1, 1 => Gt
 
230
    | p~0, q~1 => Pcompare p q Lt
 
231
    | p~0, q~0 => Pcompare p q r
 
232
    | p~0, 1 => Gt
 
233
    | 1, q~1 => Lt
 
234
    | 1, q~0 => Lt
 
235
    | 1, 1 => r
 
236
  end.
 
237
 
 
238
Infix "?=" := Pcompare (at level 70, no associativity) : positive_scope.
 
239
 
 
240
Definition Plt (x y:positive) := (Pcompare x y Eq) = Lt.
 
241
Definition Pgt (x y:positive) := (Pcompare x y Eq) = Gt.
 
242
Definition Ple (x y:positive) := (Pcompare x y Eq) <> Gt.
 
243
Definition Pge (x y:positive) := (Pcompare x y Eq) <> Lt.
 
244
 
 
245
Infix "<=" := Ple : positive_scope.
 
246
Infix "<" := Plt : positive_scope.
 
247
Infix ">=" := Pge : positive_scope.
 
248
Infix ">" := Pgt : positive_scope.
 
249
 
 
250
Notation "x <= y <= z" := (x <= y /\ y <= z) : positive_scope.
 
251
Notation "x <= y < z" := (x <= y /\ y < z) : positive_scope.
 
252
Notation "x < y < z" := (x < y /\ y < z) : positive_scope.
 
253
Notation "x < y <= z" := (x < y /\ y <= z) : positive_scope.
 
254
 
 
255
 
 
256
Definition Pmin (p p' : positive) := match Pcompare p p' Eq with 
 
257
 | Lt | Eq => p 
 
258
 | Gt => p'
 
259
 end.
 
260
 
 
261
Definition Pmax (p p' : positive) := match Pcompare p p' Eq with 
 
262
 | Lt | Eq => p' 
 
263
 | Gt => p
 
264
 end.
 
265
 
 
266
(**********************************************************************)
 
267
(** Miscellaneous properties of binary positive numbers *)
 
268
 
 
269
Lemma ZL11 : forall p:positive, p = 1 \/ p <> 1.
 
270
Proof.
 
271
  intros x; case x; intros; (left; reflexivity) || (right; discriminate).
 
272
Qed.
 
273
 
 
274
(**********************************************************************)
 
275
(** Properties of successor on binary positive numbers *)
 
276
 
 
277
(** Specification of [xI] in term of [Psucc] and [xO] *)
 
278
 
 
279
Lemma xI_succ_xO : forall p:positive, p~1 = Psucc p~0.
 
280
Proof.
 
281
  reflexivity.
 
282
Qed.
 
283
 
 
284
Lemma Psucc_discr : forall p:positive, p <> Psucc p.
 
285
Proof.
 
286
  destruct p; discriminate.
 
287
Qed.
 
288
 
 
289
(** Successor and double *)
 
290
 
 
291
Lemma Psucc_o_double_minus_one_eq_xO :
 
292
  forall p:positive, Psucc (Pdouble_minus_one p) = p~0.
 
293
Proof.
 
294
  induction p; simpl; f_equal; auto.
 
295
Qed.
 
296
 
 
297
Lemma Pdouble_minus_one_o_succ_eq_xI :
 
298
  forall p:positive, Pdouble_minus_one (Psucc p) = p~1.
 
299
Proof.
 
300
  induction p; simpl; f_equal; auto.
 
301
Qed.
 
302
 
 
303
Lemma xO_succ_permute :
 
304
  forall p:positive, (Psucc p)~0 = Psucc (Psucc p~0).
 
305
Proof.
 
306
  induction p; simpl; auto.
 
307
Qed.
 
308
 
 
309
Lemma double_moins_un_xO_discr :
 
310
  forall p:positive, Pdouble_minus_one p <> p~0.
 
311
Proof.
 
312
  destruct p; discriminate.
 
313
Qed.
 
314
 
 
315
(** Successor and predecessor *)
 
316
 
 
317
Lemma Psucc_not_one : forall p:positive, Psucc p <> 1.
 
318
Proof.
 
319
  destruct p; discriminate.
 
320
Qed.
 
321
 
 
322
Lemma Ppred_succ : forall p:positive, Ppred (Psucc p) = p.
 
323
Proof.
 
324
  intros [[p|p| ]|[p|p| ]| ]; simpl; auto.
 
325
  f_equal; apply Pdouble_minus_one_o_succ_eq_xI.
 
326
Qed.
 
327
 
 
328
Lemma Psucc_pred : forall p:positive, p = 1 \/ Psucc (Ppred p) = p.
 
329
Proof.
 
330
  induction p; simpl; auto.
 
331
  right; apply Psucc_o_double_minus_one_eq_xO.
 
332
Qed.
 
333
 
 
334
Ltac destr_eq H := discriminate H || (try (injection H; clear H; intro H)).
 
335
 
 
336
(** Injectivity of successor *)
 
337
 
 
338
Lemma Psucc_inj : forall p q:positive, Psucc p = Psucc q -> p = q.
 
339
Proof.
 
340
  induction p; intros [q|q| ] H; simpl in *; destr_eq H; f_equal; auto.
 
341
  elim (Psucc_not_one p); auto.
 
342
  elim (Psucc_not_one q); auto.
 
343
Qed.
 
344
 
 
345
(**********************************************************************)
 
346
(** Properties of addition on binary positive numbers *)
 
347
 
 
348
(** Specification of [Psucc] in term of [Pplus] *)
 
349
 
 
350
Lemma Pplus_one_succ_r : forall p:positive, Psucc p = p + 1.
 
351
Proof.
 
352
  destruct p; reflexivity.
 
353
Qed.
 
354
 
 
355
Lemma Pplus_one_succ_l : forall p:positive, Psucc p = 1 + p.
 
356
Proof.
 
357
  destruct p; reflexivity.
 
358
Qed.
 
359
 
 
360
(** Specification of [Pplus_carry] *)
 
361
 
 
362
Theorem Pplus_carry_spec :
 
363
  forall p q:positive, Pplus_carry p q = Psucc (p + q).
 
364
Proof.
 
365
  induction p; destruct q; simpl; f_equal; auto.
 
366
Qed.
 
367
 
 
368
(** Commutativity *)
 
369
 
 
370
Theorem Pplus_comm : forall p q:positive, p + q = q + p.
 
371
Proof.
 
372
  induction p; destruct q; simpl; f_equal; auto.
 
373
  rewrite 2 Pplus_carry_spec; f_equal; auto.
 
374
Qed. 
 
375
 
 
376
(** Permutation of [Pplus] and [Psucc] *)
 
377
 
 
378
Theorem Pplus_succ_permute_r :
 
379
  forall p q:positive, p + Psucc q = Psucc (p + q).
 
380
Proof.
 
381
  induction p; destruct q; simpl; f_equal; 
 
382
   auto using Pplus_one_succ_r; rewrite Pplus_carry_spec; auto.
 
383
Qed.
 
384
 
 
385
Theorem Pplus_succ_permute_l :
 
386
  forall p q:positive, Psucc p + q = Psucc (p + q).
 
387
Proof.
 
388
  intros p q; rewrite Pplus_comm, (Pplus_comm p);
 
389
    apply Pplus_succ_permute_r.
 
390
Qed.
 
391
 
 
392
Theorem Pplus_carry_pred_eq_plus :
 
393
  forall p q:positive, q <> 1 -> Pplus_carry p (Ppred q) = p + q.
 
394
Proof.
 
395
  intros p q H; rewrite Pplus_carry_spec, <- Pplus_succ_permute_r; f_equal.
 
396
  destruct (Psucc_pred q); [ elim H; assumption | assumption ].
 
397
Qed.
 
398
 
 
399
(** No neutral for addition on strictly positive numbers *)
 
400
 
 
401
Lemma Pplus_no_neutral : forall p q:positive, q + p <> p.
 
402
Proof.
 
403
  induction p as [p IHp|p IHp| ]; intros [q|q| ] H;
 
404
   destr_eq H; apply (IHp q H).
 
405
Qed.
 
406
 
 
407
Lemma Pplus_carry_no_neutral :
 
408
  forall p q:positive, Pplus_carry q p <> Psucc p.
 
409
Proof.
 
410
  intros p q H; elim (Pplus_no_neutral p q).
 
411
  apply Psucc_inj; rewrite <- Pplus_carry_spec; assumption.
 
412
Qed.
 
413
 
 
414
(** Simplification *)
 
415
 
 
416
Lemma Pplus_carry_plus :
 
417
  forall p q r s:positive, Pplus_carry p r = Pplus_carry q s -> p + r = q + s.
 
418
Proof.
 
419
  intros p q r s H; apply Psucc_inj; do 2 rewrite <- Pplus_carry_spec;
 
420
    assumption.
 
421
Qed.
 
422
 
 
423
Lemma Pplus_reg_r : forall p q r:positive, p + r = q + r -> p = q.
 
424
Proof.
 
425
  intros p q r; revert p q; induction r.
 
426
  intros [p|p| ] [q|q| ] H; simpl; destr_eq H; 
 
427
    f_equal; auto using Pplus_carry_plus; 
 
428
    contradict H; auto using Pplus_carry_no_neutral.
 
429
  intros [p|p| ] [q|q| ] H; simpl; destr_eq H; f_equal; auto; 
 
430
    contradict H; auto using Pplus_no_neutral.
 
431
  intros p q H; apply Psucc_inj; do 2 rewrite Pplus_one_succ_r; assumption.
 
432
Qed.
 
433
 
 
434
Lemma Pplus_reg_l : forall p q r:positive, p + q = p + r -> q = r.
 
435
Proof.
 
436
  intros p q r H; apply Pplus_reg_r with (r:=p).
 
437
  rewrite (Pplus_comm r), (Pplus_comm q); assumption.
 
438
Qed.
 
439
 
 
440
Lemma Pplus_carry_reg_r :
 
441
  forall p q r:positive, Pplus_carry p r = Pplus_carry q r -> p = q.
 
442
Proof.
 
443
  intros p q r H; apply Pplus_reg_r with (r:=r); apply Pplus_carry_plus;
 
444
    assumption.
 
445
Qed.
 
446
 
 
447
Lemma Pplus_carry_reg_l :
 
448
  forall p q r:positive, Pplus_carry p q = Pplus_carry p r -> q = r.
 
449
Proof.
 
450
  intros p q r H; apply Pplus_reg_r with (r:=p);
 
451
  rewrite (Pplus_comm r), (Pplus_comm q); apply Pplus_carry_plus; assumption.
 
452
Qed.
 
453
 
 
454
(** Addition on positive is associative *)
 
455
 
 
456
Theorem Pplus_assoc : forall p q r:positive, p + (q + r) = p + q + r.
 
457
Proof.
 
458
  induction p.
 
459
  intros [q|q| ] [r|r| ]; simpl; f_equal; auto; 
 
460
    rewrite ?Pplus_carry_spec, ?Pplus_succ_permute_r, 
 
461
     ?Pplus_succ_permute_l, ?Pplus_one_succ_r; f_equal; auto.
 
462
  intros [q|q| ] [r|r| ]; simpl; f_equal; auto;
 
463
    rewrite ?Pplus_carry_spec, ?Pplus_succ_permute_r, 
 
464
     ?Pplus_succ_permute_l, ?Pplus_one_succ_r; f_equal; auto.
 
465
  intros p r; rewrite <- 2 Pplus_one_succ_l, Pplus_succ_permute_l; auto.
 
466
Qed.
 
467
 
 
468
(** Commutation of addition with the double of a positive number *)
 
469
 
 
470
Lemma Pplus_xO : forall m n : positive, (m + n)~0 = m~0 + n~0.
 
471
Proof.
 
472
  destruct n; destruct m; simpl; auto.
 
473
Qed.
 
474
 
 
475
Lemma Pplus_xI_double_minus_one :
 
476
  forall p q:positive, (p + q)~0 = p~1 + Pdouble_minus_one q.
 
477
Proof.
 
478
  intros; change (p~1) with (p~0 + 1).
 
479
  rewrite <- Pplus_assoc, <- Pplus_one_succ_l, Psucc_o_double_minus_one_eq_xO.
 
480
  reflexivity.
 
481
Qed.
 
482
 
 
483
Lemma Pplus_xO_double_minus_one :
 
484
  forall p q:positive, Pdouble_minus_one (p + q) = p~0 + Pdouble_minus_one q.
 
485
Proof.
 
486
  induction p as [p IHp| p IHp| ]; destruct q; simpl;
 
487
  rewrite ?Pplus_carry_spec, ?Pdouble_minus_one_o_succ_eq_xI, 
 
488
    ?Pplus_xI_double_minus_one; try reflexivity.
 
489
  rewrite IHp; auto.
 
490
  rewrite <- Psucc_o_double_minus_one_eq_xO, Pplus_one_succ_l; reflexivity.
 
491
Qed.
 
492
 
 
493
(** Misc *)
 
494
 
 
495
Lemma Pplus_diag : forall p:positive, p + p = p~0.
 
496
Proof.
 
497
  induction p as [p IHp| p IHp| ]; simpl; 
 
498
   try rewrite ?Pplus_carry_spec, ?IHp; reflexivity.
 
499
Qed.
 
500
 
 
501
(**********************************************************************)
 
502
(** Peano induction and recursion on binary positive positive numbers *)
 
503
(** (a nice proof from Conor McBride, see "The view from the left")   *)
 
504
 
 
505
Inductive PeanoView : positive -> Type :=
 
506
| PeanoOne : PeanoView 1
 
507
| PeanoSucc : forall p, PeanoView p -> PeanoView (Psucc p).
 
508
 
 
509
Fixpoint peanoView_xO p (q:PeanoView p) : PeanoView (p~0) :=
 
510
  match q in PeanoView x return PeanoView (x~0) with
 
511
    | PeanoOne => PeanoSucc _ PeanoOne
 
512
    | PeanoSucc _ q => PeanoSucc _ (PeanoSucc _ (peanoView_xO _ q))
 
513
  end.
 
514
 
 
515
Fixpoint peanoView_xI p (q:PeanoView p) : PeanoView (p~1) :=
 
516
  match q in PeanoView x return PeanoView (x~1) with
 
517
    | PeanoOne => PeanoSucc _ (PeanoSucc _ PeanoOne)
 
518
    | PeanoSucc _ q => PeanoSucc _ (PeanoSucc _ (peanoView_xI _ q))
 
519
  end.
 
520
 
 
521
Fixpoint peanoView p : PeanoView p :=
 
522
  match p return PeanoView p with
 
523
    | 1 => PeanoOne
 
524
    | p~0 => peanoView_xO p (peanoView p)
 
525
    | p~1 => peanoView_xI p (peanoView p)
 
526
  end.
 
527
 
 
528
Definition PeanoView_iter (P:positive->Type) 
 
529
  (a:P 1) (f:forall p, P p -> P (Psucc p)) :=
 
530
  (fix iter p (q:PeanoView p) : P p :=
 
531
    match q in PeanoView p return P p with 
 
532
      | PeanoOne => a
 
533
      | PeanoSucc _ q => f _ (iter _ q)
 
534
    end).
 
535
 
 
536
Require Import Eqdep_dec EqdepFacts.
 
537
 
 
538
Theorem eq_dep_eq_positive :
 
539
  forall (P:positive->Type) (p:positive) (x y:P p), 
 
540
    eq_dep positive P p x p y -> x = y.
 
541
Proof.
 
542
  apply eq_dep_eq_dec.
 
543
  decide equality.
 
544
Qed.
 
545
 
 
546
Theorem PeanoViewUnique : forall p (q q':PeanoView p), q = q'.  
 
547
Proof.
 
548
  intros. 
 
549
  induction q as [ | p q IHq ].
 
550
  apply eq_dep_eq_positive.
 
551
  cut (1=1). pattern 1 at 1 2 5, q'. destruct q'. trivial.
 
552
  destruct p0; intros; discriminate.
 
553
  trivial.
 
554
  apply eq_dep_eq_positive.
 
555
  cut (Psucc p=Psucc p). pattern (Psucc p) at 1 2 5, q'. destruct q'. 
 
556
  intro. destruct p; discriminate.
 
557
  intro. unfold p0 in H. apply Psucc_inj in H.
 
558
  generalize q'. rewrite H. intro.
 
559
  rewrite (IHq q'0).
 
560
  trivial.
 
561
  trivial.
 
562
Qed.
 
563
 
 
564
Definition Prect (P:positive->Type) (a:P 1) (f:forall p, P p -> P (Psucc p)) 
 
565
  (p:positive) :=
 
566
  PeanoView_iter P a f p (peanoView p).
 
567
 
 
568
Theorem Prect_succ : forall (P:positive->Type) (a:P 1) 
 
569
  (f:forall p, P p -> P (Psucc p)) (p:positive), 
 
570
  Prect P a f (Psucc p) = f _ (Prect P a f p).
 
571
Proof.
 
572
  intros.
 
573
  unfold Prect.
 
574
  rewrite (PeanoViewUnique _ (peanoView (Psucc p)) (PeanoSucc _ (peanoView p))).
 
575
  trivial.
 
576
Qed.
 
577
 
 
578
Theorem Prect_base : forall (P:positive->Type) (a:P 1) 
 
579
  (f:forall p, P p -> P (Psucc p)), Prect P a f 1 = a.
 
580
Proof.
 
581
  trivial.
 
582
Qed.
 
583
 
 
584
Definition Prec (P:positive->Set) := Prect P.
 
585
 
 
586
(** Peano induction *)
 
587
 
 
588
Definition Pind (P:positive->Prop) := Prect P.
 
589
 
 
590
(** Peano case analysis *)
 
591
 
 
592
Theorem Pcase :
 
593
  forall P:positive -> Prop,
 
594
    P 1 -> (forall n:positive, P (Psucc n)) -> forall p:positive, P p.
 
595
Proof.
 
596
  intros; apply Pind; auto.
 
597
Qed.
 
598
 
 
599
(**********************************************************************)
 
600
(** Properties of multiplication on binary positive numbers *)
 
601
 
 
602
(** One is right neutral for multiplication *)
 
603
 
 
604
Lemma Pmult_1_r : forall p:positive, p * 1 = p.
 
605
Proof.
 
606
  induction p; simpl; f_equal; auto.
 
607
Qed.
 
608
 
 
609
(** Successor and multiplication *)
 
610
 
 
611
Lemma Pmult_Sn_m : forall n m : positive, (Psucc n) * m = m + n * m.
 
612
Proof.
 
613
  induction n as [n IHn | n IHn | ]; simpl; intro m.
 
614
  rewrite IHn, Pplus_assoc, Pplus_diag, <-Pplus_xO; reflexivity.
 
615
  reflexivity.
 
616
  symmetry; apply Pplus_diag.
 
617
Qed.
 
618
 
 
619
(** Right reduction properties for multiplication *)
 
620
 
 
621
Lemma Pmult_xO_permute_r : forall p q:positive, p * q~0 = (p * q)~0.
 
622
Proof.
 
623
  intros p q; induction p; simpl; do 2 (f_equal; auto).
 
624
Qed.
 
625
 
 
626
Lemma Pmult_xI_permute_r : forall p q:positive, p * q~1 = p + (p * q)~0.
 
627
Proof.
 
628
  intros p q; induction p as [p IHp|p IHp| ]; simpl; f_equal; auto.
 
629
  rewrite IHp, 2 Pplus_assoc, (Pplus_comm p); reflexivity.
 
630
Qed.
 
631
 
 
632
(** Commutativity of multiplication *)
 
633
 
 
634
Theorem Pmult_comm : forall p q:positive, p * q = q * p.
 
635
Proof.
 
636
  intros p q; induction q as [q IHq|q IHq| ]; simpl; try rewrite <- IHq;
 
637
   auto using Pmult_xI_permute_r, Pmult_xO_permute_r, Pmult_1_r.
 
638
Qed.
 
639
 
 
640
(** Distributivity of multiplication over addition *)
 
641
 
 
642
Theorem Pmult_plus_distr_l :
 
643
  forall p q r:positive, p * (q + r) = p * q + p * r.
 
644
Proof.
 
645
  intros p q r; induction p as [p IHp|p IHp| ]; simpl.
 
646
  rewrite IHp. set (m:=(p*q)~0). set (n:=(p*r)~0).
 
647
  change ((p*q+p*r)~0) with (m+n).
 
648
  rewrite 2 Pplus_assoc; f_equal.
 
649
  rewrite <- 2 Pplus_assoc; f_equal.
 
650
  apply Pplus_comm.
 
651
  f_equal; auto.
 
652
  reflexivity.
 
653
Qed.
 
654
 
 
655
Theorem Pmult_plus_distr_r :
 
656
  forall p q r:positive, (p + q) * r = p * r + q * r.
 
657
Proof.
 
658
  intros p q r; do 3 rewrite Pmult_comm with (q:=r); apply Pmult_plus_distr_l.
 
659
Qed.
 
660
 
 
661
(** Associativity of multiplication *)
 
662
 
 
663
Theorem Pmult_assoc : forall p q r:positive, p * (q * r) = p * q * r.
 
664
Proof.
 
665
  induction p as [p IHp| p IHp | ]; simpl; intros q r.
 
666
  rewrite IHp; rewrite Pmult_plus_distr_r; reflexivity.
 
667
  rewrite IHp; reflexivity.
 
668
  reflexivity.
 
669
Qed.
 
670
 
 
671
(** Parity properties of multiplication *)
 
672
 
 
673
Lemma Pmult_xI_mult_xO_discr : forall p q r:positive, p~1 * r <> q~0 * r.
 
674
Proof.
 
675
  intros p q r; induction r; try discriminate.
 
676
  rewrite 2 Pmult_xO_permute_r; intro H; destr_eq H; auto.
 
677
Qed.
 
678
 
 
679
Lemma Pmult_xO_discr : forall p q:positive, p~0 * q <> q.
 
680
Proof.
 
681
  intros p q; induction q; try discriminate.
 
682
  rewrite Pmult_xO_permute_r; injection; assumption.
 
683
Qed.
 
684
 
 
685
(** Simplification properties of multiplication *)
 
686
 
 
687
Theorem Pmult_reg_r : forall p q r:positive, p * r = q * r -> p = q.
 
688
Proof.
 
689
  induction p as [p IHp| p IHp| ]; intros [q|q| ] r H;
 
690
    reflexivity || apply (f_equal (A:=positive)) || apply False_ind.
 
691
  apply IHp with (r~0); simpl in *;
 
692
    rewrite 2 Pmult_xO_permute_r; apply Pplus_reg_l with (1:=H).
 
693
  apply Pmult_xI_mult_xO_discr with (1:=H).
 
694
  simpl in H; rewrite Pplus_comm in H; apply Pplus_no_neutral with (1:=H).
 
695
  symmetry in H; apply Pmult_xI_mult_xO_discr with (1:=H).
 
696
  apply IHp with (r~0); simpl; rewrite 2 Pmult_xO_permute_r; assumption.
 
697
  apply Pmult_xO_discr with (1:= H).
 
698
  simpl in H; symmetry in H; rewrite Pplus_comm in H;
 
699
    apply Pplus_no_neutral with (1:=H).
 
700
  symmetry in H; apply Pmult_xO_discr with (1:=H).
 
701
Qed.
 
702
 
 
703
Theorem Pmult_reg_l : forall p q r:positive, r * p = r * q -> p = q.
 
704
Proof.
 
705
  intros p q r H; apply Pmult_reg_r with (r:=r).
 
706
  rewrite (Pmult_comm p), (Pmult_comm q); assumption.
 
707
Qed.
 
708
 
 
709
(** Inversion of multiplication *)
 
710
 
 
711
Lemma Pmult_1_inversion_l : forall p q:positive, p * q = 1 -> p = 1.
 
712
Proof.
 
713
  intros [p|p| ] [q|q| ] H; destr_eq H; auto.
 
714
Qed.
 
715
 
 
716
(**********************************************************************)
 
717
(** Properties of comparison on binary positive numbers *)
 
718
 
 
719
Theorem Pcompare_refl : forall p:positive, (p ?= p) Eq = Eq.
 
720
  induction p; auto.
 
721
Qed.
 
722
 
 
723
(* A generalization of Pcompare_refl *)
 
724
 
 
725
Theorem Pcompare_refl_id : forall (p : positive) (r : comparison), (p ?= p) r = r.
 
726
  induction p; auto.
 
727
Qed.
 
728
 
 
729
Theorem Pcompare_not_Eq :
 
730
  forall p q:positive, (p ?= q) Gt <> Eq /\ (p ?= q) Lt <> Eq.
 
731
Proof.
 
732
  induction p as [p IHp| p IHp| ]; intros [q| q| ]; split; simpl; auto;
 
733
    discriminate || (elim (IHp q); auto).
 
734
Qed.
 
735
 
 
736
Theorem Pcompare_Eq_eq : forall p q:positive, (p ?= q) Eq = Eq -> p = q.
 
737
Proof.
 
738
  induction p; intros [q| q| ] H; simpl in *; auto; 
 
739
   try discriminate H; try (f_equal; auto; fail).
 
740
  destruct (Pcompare_not_Eq p q) as (H',_); elim H'; auto.
 
741
  destruct (Pcompare_not_Eq p q) as (_,H'); elim H'; auto.
 
742
Qed.
 
743
 
 
744
Lemma Pcompare_Gt_Lt :
 
745
  forall p q:positive, (p ?= q) Gt = Lt -> (p ?= q) Eq = Lt.
 
746
Proof.
 
747
  induction p; intros [q|q| ] H; simpl; auto; discriminate.
 
748
Qed.
 
749
 
 
750
Lemma Pcompare_eq_Lt :
 
751
  forall p q : positive, (p ?= q) Eq = Lt <-> (p ?= q) Gt = Lt.
 
752
Proof.
 
753
  intros p q; split; [| apply Pcompare_Gt_Lt].
 
754
  revert q; induction p; intros [q|q| ] H; simpl; auto; discriminate.
 
755
Qed.
 
756
 
 
757
Lemma Pcompare_Lt_Gt :
 
758
  forall p q:positive, (p ?= q) Lt = Gt -> (p ?= q) Eq = Gt.
 
759
Proof.
 
760
  induction p; intros [q|q| ] H; simpl; auto; discriminate.
 
761
Qed.
 
762
 
 
763
Lemma Pcompare_eq_Gt :
 
764
  forall p q : positive, (p ?= q) Eq = Gt <-> (p ?= q) Lt = Gt.
 
765
Proof.
 
766
  intros p q; split; [| apply Pcompare_Lt_Gt].
 
767
  revert q; induction p; intros [q|q| ] H; simpl; auto; discriminate.
 
768
Qed.
 
769
 
 
770
Lemma Pcompare_Lt_Lt :
 
771
  forall p q:positive, (p ?= q) Lt = Lt -> (p ?= q) Eq = Lt \/ p = q.
 
772
Proof.
 
773
  induction p as [p IHp| p IHp| ]; intros [q|q| ] H; simpl in *; auto;
 
774
   destruct (IHp q H); subst; auto.
 
775
Qed.
 
776
 
 
777
Lemma Pcompare_Lt_eq_Lt :
 
778
  forall p q:positive, (p ?= q) Lt = Lt <-> (p ?= q) Eq = Lt \/ p = q.
 
779
Proof.
 
780
  intros p q; split; [apply Pcompare_Lt_Lt |].
 
781
  intros [H|H]; [|subst; apply Pcompare_refl_id].
 
782
  revert q H; induction p; intros [q|q| ] H; simpl in *;
 
783
  auto; discriminate.
 
784
Qed.
 
785
 
 
786
Lemma Pcompare_Gt_Gt :
 
787
  forall p q:positive, (p ?= q) Gt = Gt -> (p ?= q) Eq = Gt \/ p = q.
 
788
Proof.
 
789
  induction p as [p IHp|p IHp| ]; intros [q|q| ] H; simpl in *; auto;
 
790
    destruct (IHp q H); subst; auto.
 
791
Qed.
 
792
 
 
793
Lemma Pcompare_Gt_eq_Gt :
 
794
  forall p q:positive, (p ?= q) Gt = Gt <-> (p ?= q) Eq = Gt \/ p = q.
 
795
Proof.
 
796
  intros p q; split; [apply Pcompare_Gt_Gt |].
 
797
  intros [H|H]; [|subst; apply Pcompare_refl_id].
 
798
  revert q H; induction p; intros [q|q| ] H; simpl in *;
 
799
  auto; discriminate.
 
800
Qed.
 
801
 
 
802
Lemma Dcompare : forall r:comparison, r = Eq \/ r = Lt \/ r = Gt.
 
803
Proof.
 
804
  destruct r; auto.
 
805
Qed.
 
806
 
 
807
Ltac ElimPcompare c1 c2 :=
 
808
  elim (Dcompare ((c1 ?= c2) Eq));
 
809
    [ idtac | let x := fresh "H" in (intro x; case x; clear x) ].
 
810
 
 
811
Lemma Pcompare_antisym :
 
812
  forall (p q:positive) (r:comparison),
 
813
    CompOpp ((p ?= q) r) = (q ?= p) (CompOpp r).
 
814
Proof.
 
815
  induction p as [p IHp|p IHp| ]; intros [q|q| ] r; simpl; auto; 
 
816
   rewrite IHp; auto.
 
817
Qed.
 
818
 
 
819
Lemma ZC1 : forall p q:positive, (p ?= q) Eq = Gt -> (q ?= p) Eq = Lt.
 
820
Proof.
 
821
  intros p q H; change Eq with (CompOpp Eq).
 
822
  rewrite <- Pcompare_antisym, H; reflexivity.
 
823
Qed.
 
824
 
 
825
Lemma ZC2 : forall p q:positive, (p ?= q) Eq = Lt -> (q ?= p) Eq = Gt.
 
826
Proof.
 
827
  intros p q H; change Eq with (CompOpp Eq).
 
828
  rewrite <- Pcompare_antisym, H; reflexivity.
 
829
Qed.
 
830
 
 
831
Lemma ZC3 : forall p q:positive, (p ?= q) Eq = Eq -> (q ?= p) Eq = Eq.
 
832
Proof.
 
833
  intros p q H; change Eq with (CompOpp Eq).
 
834
  rewrite <- Pcompare_antisym, H; reflexivity.
 
835
Qed.
 
836
 
 
837
Lemma ZC4 : forall p q:positive, (p ?= q) Eq = CompOpp ((q ?= p) Eq).
 
838
Proof.
 
839
  intros; change Eq at 1 with (CompOpp Eq).
 
840
  symmetry; apply Pcompare_antisym.
 
841
Qed.
 
842
 
 
843
(** Comparison and the successor *)
 
844
 
 
845
Lemma Pcompare_p_Sp : forall p : positive, (p ?= Psucc p) Eq = Lt.
 
846
Proof.
 
847
  induction p; simpl in *;
 
848
    [ elim (Pcompare_eq_Lt p (Psucc p)); auto |
 
849
      apply Pcompare_refl_id | reflexivity].
 
850
Qed.
 
851
 
 
852
Theorem Pcompare_p_Sq : forall p q : positive,
 
853
  (p ?= Psucc q) Eq = Lt <-> (p ?= q) Eq = Lt \/ p = q.
 
854
Proof.
 
855
  intros p q; split.
 
856
  (* -> *)
 
857
  revert p q; induction p as [p IHp|p IHp| ]; intros [q|q| ] H; simpl in *;
 
858
   try (left; reflexivity); try (right; reflexivity).
 
859
  destruct (IHp q (Pcompare_Gt_Lt _ _ H)); subst; auto.
 
860
  destruct (Pcompare_eq_Lt p q); auto.
 
861
  destruct p; discriminate.
 
862
  left; destruct (IHp q H);
 
863
   [ elim (Pcompare_Lt_eq_Lt p q); auto | subst; apply Pcompare_refl_id].
 
864
  destruct (Pcompare_Lt_Lt p q H); subst; auto.
 
865
  destruct p; discriminate.
 
866
  (* <- *)
 
867
  intros [H|H]; [|subst; apply Pcompare_p_Sp].
 
868
  revert q H; induction p; intros [q|q| ] H; simpl in *;
 
869
   auto; try discriminate.
 
870
  destruct (Pcompare_eq_Lt p (Psucc q)); auto.
 
871
  apply Pcompare_Gt_Lt; auto.
 
872
  destruct (Pcompare_Lt_Lt p q H); subst; auto using Pcompare_p_Sp.
 
873
  destruct (Pcompare_Lt_eq_Lt p q); auto.
 
874
Qed.
 
875
 
 
876
(** 1 is the least positive number *)
 
877
 
 
878
Lemma Pcompare_1 : forall p, ~ (p ?= 1) Eq = Lt.
 
879
Proof.
 
880
  destruct p; discriminate.
 
881
Qed.
 
882
 
 
883
(** Properties of the strict order on positive numbers *)
 
884
 
 
885
Lemma Plt_1 : forall p, ~ p < 1.
 
886
Proof.
 
887
 exact Pcompare_1.
 
888
Qed.
 
889
 
 
890
Lemma Plt_lt_succ : forall n m : positive, n < m -> n < Psucc m.
 
891
Proof.
 
892
  unfold Plt; intros n m H; apply <- Pcompare_p_Sq; auto.
 
893
Qed.
 
894
 
 
895
Lemma Plt_irrefl : forall p : positive, ~ p < p.
 
896
Proof.
 
897
  unfold Plt; intro p; rewrite Pcompare_refl; discriminate.
 
898
Qed.
 
899
 
 
900
Lemma Plt_trans : forall n m p : positive, n < m -> m < p -> n < p.
 
901
Proof.
 
902
  intros n m p; induction p using Pind; intros H H0.
 
903
  elim (Plt_1 _ H0).
 
904
  apply Plt_lt_succ.
 
905
  destruct (Pcompare_p_Sq m p) as (H',_); destruct (H' H0); subst; auto.
 
906
Qed.
 
907
 
 
908
Theorem Plt_ind : forall (A : positive -> Prop) (n : positive),
 
909
  A (Psucc n) ->
 
910
    (forall m : positive, n < m -> A m -> A (Psucc m)) ->
 
911
      forall m : positive, n < m -> A m.
 
912
Proof.
 
913
  intros A n AB AS m. induction m using Pind; intros H.
 
914
  elim (Plt_1 _ H).
 
915
  destruct (Pcompare_p_Sq n m) as (H',_); destruct (H' H); subst; auto.
 
916
Qed.
 
917
 
 
918
(**********************************************************************)
 
919
(** Properties of subtraction on binary positive numbers *)
 
920
 
 
921
Lemma Ppred_minus : forall p, Ppred p = Pminus p 1.
 
922
Proof.
 
923
  destruct p; auto.
 
924
Qed.
 
925
 
 
926
Definition Ppred_mask (p : positive_mask) :=
 
927
match p with
 
928
| IsPos 1 => IsNul
 
929
| IsPos q => IsPos (Ppred q)
 
930
| IsNul => IsNeg
 
931
| IsNeg => IsNeg
 
932
end.
 
933
 
 
934
Lemma Pminus_mask_succ_r :
 
935
  forall p q : positive, Pminus_mask p (Psucc q) = Pminus_mask_carry p q.
 
936
Proof.
 
937
  induction p ; destruct q; simpl; f_equal; auto; destruct p; auto.
 
938
Qed.
 
939
 
 
940
Theorem Pminus_mask_carry_spec :
 
941
  forall p q : positive, Pminus_mask_carry p q = Ppred_mask (Pminus_mask p q).
 
942
Proof.
 
943
  induction p as [p IHp|p IHp| ]; destruct q; simpl; 
 
944
   try reflexivity; try rewrite IHp;
 
945
   destruct (Pminus_mask p q) as [|[r|r| ]|] || destruct p; auto.
 
946
Qed.
 
947
 
 
948
Theorem Pminus_succ_r : forall p q : positive, p - (Psucc q) = Ppred (p - q).
 
949
Proof.
 
950
  intros p q; unfold Pminus; 
 
951
  rewrite Pminus_mask_succ_r, Pminus_mask_carry_spec.
 
952
  destruct (Pminus_mask p q) as [|[r|r| ]|]; auto.
 
953
Qed.
 
954
 
 
955
Lemma double_eq_zero_inversion :
 
956
  forall p:positive_mask, Pdouble_mask p = IsNul -> p = IsNul.
 
957
Proof.
 
958
  destruct p; simpl; intros; trivial; discriminate.
 
959
Qed.
 
960
 
 
961
Lemma double_plus_one_zero_discr :
 
962
  forall p:positive_mask, Pdouble_plus_one_mask p <> IsNul.
 
963
Proof.
 
964
  destruct p; discriminate.
 
965
Qed.
 
966
 
 
967
Lemma double_plus_one_eq_one_inversion :
 
968
  forall p:positive_mask, Pdouble_plus_one_mask p = IsPos 1 -> p = IsNul.
 
969
Proof.
 
970
  destruct p; simpl; intros; trivial; discriminate.
 
971
Qed.
 
972
 
 
973
Lemma double_eq_one_discr :
 
974
  forall p:positive_mask, Pdouble_mask p <> IsPos 1.
 
975
Proof.
 
976
  destruct p; discriminate.
 
977
Qed.
 
978
 
 
979
Theorem Pminus_mask_diag : forall p:positive, Pminus_mask p p = IsNul.
 
980
Proof.
 
981
  induction p as [p IHp| p IHp| ]; simpl; try rewrite IHp; auto.
 
982
Qed.
 
983
 
 
984
Lemma Pminus_mask_carry_diag : forall p, Pminus_mask_carry p p = IsNeg.
 
985
Proof.
 
986
  induction p as [p IHp| p IHp| ]; simpl; try rewrite IHp; auto.
 
987
Qed.
 
988
 
 
989
Lemma Pminus_mask_IsNeg : forall p q:positive, 
 
990
 Pminus_mask p q = IsNeg -> Pminus_mask_carry p q = IsNeg.
 
991
Proof.
 
992
  induction p as [p IHp|p IHp| ]; intros [q|q| ] H; simpl in *; auto; 
 
993
   try discriminate; unfold Pdouble_mask, Pdouble_plus_one_mask in H; 
 
994
   specialize IHp with q.
 
995
  destruct (Pminus_mask p q); try discriminate; rewrite IHp; auto.
 
996
  destruct (Pminus_mask p q); simpl; auto; try discriminate.
 
997
  destruct (Pminus_mask_carry p q); simpl; auto; try discriminate.
 
998
  destruct (Pminus_mask p q); try discriminate; rewrite IHp; auto.
 
999
Qed.
 
1000
 
 
1001
Lemma ZL10 :
 
1002
  forall p q:positive,
 
1003
    Pminus_mask p q = IsPos 1 -> Pminus_mask_carry p q = IsNul.
 
1004
Proof.
 
1005
  induction p; intros [q|q| ] H; simpl in *; try discriminate.
 
1006
  elim (double_eq_one_discr _ H).
 
1007
  rewrite (double_plus_one_eq_one_inversion _ H); auto.
 
1008
  rewrite (double_plus_one_eq_one_inversion _ H); auto.
 
1009
  elim (double_eq_one_discr _ H).
 
1010
  destruct p; simpl; auto; discriminate.
 
1011
Qed.
 
1012
 
 
1013
(** Properties of subtraction valid only for x>y *)
 
1014
 
 
1015
Lemma Pminus_mask_Gt :
 
1016
  forall p q:positive,
 
1017
    (p ?= q) Eq = Gt ->
 
1018
    exists h : positive,
 
1019
      Pminus_mask p q = IsPos h /\
 
1020
      q + h = p /\ (h = 1 \/ Pminus_mask_carry p q = IsPos (Ppred h)).
 
1021
Proof.
 
1022
  induction p as [p IHp| p IHp| ]; intros [q| q| ] H; simpl in *; 
 
1023
   try discriminate H.
 
1024
  (* p~1, q~1 *) 
 
1025
  destruct (IHp q H) as (r & U & V & W); exists (r~0); rewrite ?U, ?V; auto.
 
1026
  repeat split; auto; right.
 
1027
  destruct (ZL11 r) as [EQ|NE]; [|destruct W as [|W]; [elim NE; auto|]].
 
1028
  rewrite ZL10; subst; auto.
 
1029
  rewrite W; simpl; destruct r; auto; elim NE; auto.
 
1030
  (* p~1, q~0 *)
 
1031
  destruct (Pcompare_Gt_Gt _ _ H) as [H'|H']; clear H; rename H' into H.
 
1032
  destruct (IHp q H) as (r & U & V & W); exists (r~1); rewrite ?U, ?V; auto.
 
1033
  exists 1; subst; rewrite Pminus_mask_diag; auto.
 
1034
  (* p~1, 1 *)
 
1035
  exists (p~0); auto.
 
1036
  (* p~0, q~1 *)
 
1037
  destruct (IHp q (Pcompare_Lt_Gt _ _ H)) as (r & U & V & W).
 
1038
  destruct (ZL11 r) as [EQ|NE]; [|destruct W as [|W]; [elim NE; auto|]].
 
1039
  exists 1; subst; rewrite ZL10, Pplus_one_succ_r; auto.
 
1040
  exists ((Ppred r)~1); rewrite W, Pplus_carry_pred_eq_plus, V; auto.
 
1041
  (* p~0, q~0 *)
 
1042
  destruct (IHp q H) as (r & U & V & W); exists (r~0); rewrite ?U, ?V; auto.
 
1043
  repeat split; auto; right.
 
1044
  destruct (ZL11 r) as [EQ|NE]; [|destruct W as [|W]; [elim NE; auto|]].
 
1045
  rewrite ZL10; subst; auto.
 
1046
  rewrite W; simpl; destruct r; auto; elim NE; auto.
 
1047
  (* p~0, 1 *)
 
1048
  exists (Pdouble_minus_one p); repeat split; destruct p; simpl; auto.
 
1049
  rewrite Psucc_o_double_minus_one_eq_xO; auto.
 
1050
Qed.
 
1051
 
 
1052
Theorem Pplus_minus :
 
1053
  forall p q:positive, (p ?= q) Eq = Gt -> q + (p - q) = p.
 
1054
Proof.
 
1055
  intros p q H; destruct (Pminus_mask_Gt p q H) as (r & U & V & _).
 
1056
  unfold Pminus; rewrite U; simpl; auto.
 
1057
Qed.
 
1058
 
 
1059
(** When x<y, the substraction of x by y returns 1 *)
 
1060
 
 
1061
Lemma Pminus_mask_Lt : forall p q:positive, p<q -> Pminus_mask p q = IsNeg.
 
1062
Proof.
 
1063
  unfold Plt; induction p as [p IHp|p IHp| ]; destruct q; simpl; intros;
 
1064
   try discriminate; try rewrite IHp; auto.
 
1065
  apply Pcompare_Gt_Lt; auto.
 
1066
  destruct (Pcompare_Lt_Lt _ _ H).
 
1067
  rewrite Pminus_mask_IsNeg; simpl; auto.
 
1068
  subst; rewrite Pminus_mask_carry_diag; auto.
 
1069
Qed.
 
1070
 
 
1071
Lemma Pminus_Lt : forall p q:positive, p<q -> p-q = 1.
 
1072
Proof.
 
1073
  intros; unfold Plt, Pminus; rewrite Pminus_mask_Lt; auto.
 
1074
Qed.
 
1075
 
 
1076
(** The substraction of x by x returns 1 *)
 
1077
 
 
1078
Lemma Pminus_Eq : forall p:positive, p-p = 1.
 
1079
Proof.
 
1080
 intros; unfold Pminus; rewrite Pminus_mask_diag; auto.
 
1081
Qed.
 
1082
 
 
1083
(** Number of digits in a number *)
 
1084
 
 
1085
Fixpoint Psize (p:positive) : nat := 
 
1086
  match p with 
 
1087
    | 1 => S O
 
1088
    | p~1 => S (Psize p) 
 
1089
    | p~0 => S (Psize p)
 
1090
  end.
 
1091
 
 
1092
Lemma Psize_monotone : forall p q, (p?=q) Eq = Lt -> (Psize p <= Psize q)%nat.
 
1093
Proof.
 
1094
  assert (le0 : forall n, (0<=n)%nat) by (induction n; auto).
 
1095
  assert (leS : forall n m, (n<=m -> S n <= S m)%nat) by (induction 1; auto).
 
1096
  induction p; destruct q; simpl; auto; intros; try discriminate.
 
1097
  intros; generalize (Pcompare_Gt_Lt _ _ H); auto.
 
1098
  intros; destruct (Pcompare_Lt_Lt _ _ H); auto; subst; auto.
 
1099
Qed.
 
1100
 
 
1101
 
 
1102
 
 
1103
 
 
1104