Library Coq.NArith.BinNatDef
Require Export BinNums.
Require Import BinPos.
Local Open Scope N_scope.
Binary natural numbers, definitions of operations
Module N.
Definition t :=
N.
Nicer name N.pos for contructor Npos
Definition zero := 0.
Definition one := 1.
Definition two := 2.
Definition double n :=
match n with
| 0 => 0
|
pos p =>
pos p~0
end.
The successor of a N can be seen as a positive
Definition add n m :=
match n,
m with
| 0,
_ =>
m
|
_, 0 =>
n
|
pos p,
pos q =>
pos (
p + q)
end.
Infix "+" :=
add :
N_scope.
Subtraction
Definition sub n m :=
match n,
m with
| 0,
_ => 0
|
n, 0 =>
n
|
pos n´,
pos m´ =>
match Pos.sub_mask n´ m´ with
|
IsPos p =>
pos p
|
_ => 0
end
end.
Infix "-" :=
sub :
N_scope.
Multiplication
Definition mul n m :=
match n,
m with
| 0,
_ => 0
|
_, 0 => 0
|
pos p,
pos q =>
pos (
p * q)
end.
Infix "*" :=
mul :
N_scope.
Order
Definition compare n m :=
match n,
m with
| 0, 0 =>
Eq
| 0,
pos m´ =>
Lt
|
pos n´, 0 =>
Gt
|
pos n´,
pos m´ => (
n´ ?= m´)%
positive
end.
Infix "?=" :=
compare (
at level 70,
no associativity) :
N_scope.
Boolean equality and comparison
Fixpoint eqb n m :=
match n,
m with
| 0, 0 =>
true
|
pos p,
pos q =>
Pos.eqb p q
|
_,
_ =>
false
end.
Definition leb x y :=
match x ?= y with Gt =>
false |
_ =>
true end.
Definition ltb x y :=
match x ?= y with Lt =>
true |
_ =>
false end.
Infix "=?" :=
eqb (
at level 70,
no associativity) :
N_scope.
Infix "<=?" :=
leb (
at level 70,
no associativity) :
N_scope.
Infix "<?" :=
ltb (
at level 70,
no associativity) :
N_scope.
Min and max
Dividing by 2
Definition div2 n :=
match n with
| 0 => 0
| 1 => 0
|
pos (
p~0) =>
pos p
|
pos (
p~1) =>
pos p
end.
Parity
Power
Definition pow n p :=
match p,
n with
| 0,
_ => 1
|
_, 0 => 0
|
pos p,
pos q =>
pos (
q^p)
end.
Infix "^" :=
pow :
N_scope.
Square
Base-2 logarithm
How many digits in a number ?
Number 0 is said to have no digits at all.
Euclidean division
Fixpoint pos_div_eucl (
a:
positive)(
b:
N) :
N * N :=
match a with
|
xH =>
match b with 1 =>
(1
,0
) |
_ =>
(0
,1
) end
|
xO a´ =>
let (
q,
r) :=
pos_div_eucl a´ b in
let r´ :=
double r in
if b <=? r´ then (succ_double q, r´ - b)
else (double q, r´)
|
xI a´ =>
let (
q,
r) :=
pos_div_eucl a´ b in
let r´ :=
succ_double r in
if b <=? r´ then (succ_double q, r´ - b)
else (double q, r´)
end.
Definition div_eucl (
a b:
N) :
N * N :=
match a,
b with
| 0,
_ =>
(0
, 0
)
|
_, 0 =>
(0
, a)
|
pos na,
_ =>
pos_div_eucl na b
end.
Definition div a b :=
fst (
div_eucl a b).
Definition modulo a b :=
snd (
div_eucl a b).
Infix "/" :=
div :
N_scope.
Infix "mod" :=
modulo (
at level 40,
no associativity) :
N_scope.
Greatest common divisor
Definition gcd a b :=
match a,
b with
| 0,
_ =>
b
|
_, 0 =>
a
|
pos p,
pos q =>
pos (
Pos.gcd p q)
end.
Generalized Gcd, also computing rests of a and b after
division by gcd.
Definition ggcd a b :=
match a,
b with
| 0,
_ =>
(b,(0
,1
))
|
_, 0 =>
(a,(1
,0
))
|
pos p,
pos q =>
let ´
(g,(aa,bb)) :=
Pos.ggcd p q in
(pos g, (pos aa, pos bb))
end.
Square root
Operation over bits of a
N number.
Logical
or
Definition lor n m :=
match n,
m with
| 0,
_ =>
m
|
_, 0 =>
n
|
pos p,
pos q =>
pos (
Pos.lor p q)
end.
Logical and
Definition land n m :=
match n,
m with
| 0,
_ => 0
|
_, 0 => 0
|
pos p,
pos q =>
Pos.land p q
end.
Logical diff
Fixpoint ldiff n m :=
match n,
m with
| 0,
_ => 0
|
_, 0 =>
n
|
pos p,
pos q =>
Pos.ldiff p q
end.
xor
Definition lxor n m :=
match n,
m with
| 0,
_ =>
m
|
_, 0 =>
n
|
pos p,
pos q =>
Pos.lxor p q
end.
Shifts
Checking whether a particular bit is set or not
Same, but with index in N
Translation from N to nat and back.
Iteration of a function