Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************)
(*         *   The Coq Proof Assistant / The Coq Development Team       *)
(*  v      *   INRIA, CNRS and contributors - Copyright 1999-2018       *)
(* <O___,, *       (see CREDITS file for the list of authors)           *)
(*   \VV/  **************************************************************)
(*    //   *    This file is distributed under the terms of the         *)
(*         *     GNU Lesser General Public License Version 2.1          *)
(*         *     (see LICENSE file for the text of the license)         *)
(************************************************************************)

Require Import ZArithRing.
Require Import ZArith_base.
Require Export Omega.
Require Import Wf_nat.
Local Open Scope Z_scope.


(**********************************************************************)
About parity
Notation two_or_two_plus_one := Z_modulo_2 (only parsing).

(**********************************************************************)
The biggest power of 2 that is stricly less than a
Easy to compute: replace all "1" of the binary representation by "0", except the first "1" (or the first one :-)
Fixpoint floor_pos (a:positive) : positive :=
  match a with
    | xH => 1%positive
    | xO a' => xO (floor_pos a')
    | xI b' => xO (floor_pos b')
  end.

Definition floor (a:positive) := Zpos (floor_pos a).


forall p : positive, floor p > 0

forall p : positive, floor p > 0
reflexivity. Qed.

forall p : positive, floor p <= Z.pos p < 2 * floor p

forall p : positive, floor p <= Z.pos p < 2 * floor p

forall p : positive, Z.pos (floor_pos p) <= Z.pos p < 2 * Z.pos (floor_pos p)
p:positive
IHp:Z.pos (floor_pos p) <= Z.pos p < 2 * Z.pos (floor_pos p)

Z.pos (floor_pos p)~0 <= Z.pos p~1 < Z.pos (floor_pos p)~0~0
p:positive
IHp:Z.pos (floor_pos p) <= Z.pos p < 2 * Z.pos (floor_pos p)
Z.pos (floor_pos p)~0 <= Z.pos p~0 < Z.pos (floor_pos p)~0~0

1 <= 1 < 2
p:positive
IHp:Z.pos (floor_pos p) <= Z.pos p < 2 * Z.pos (floor_pos p)

Z.pos (floor_pos p)~0 <= Z.pos p~1 < Z.pos (floor_pos p)~0~0
p:positive
IHp:Z.pos (floor_pos p) <= Z.pos p < 2 * Z.pos (floor_pos p)

2 * Z.pos (floor_pos p) <= 2 * Z.pos p + 1 < 2 * (2 * Z.pos (floor_pos p))
omega.
p:positive
IHp:Z.pos (floor_pos p) <= Z.pos p < 2 * Z.pos (floor_pos p)

Z.pos (floor_pos p)~0 <= Z.pos p~0 < Z.pos (floor_pos p)~0~0
p:positive
IHp:Z.pos (floor_pos p) <= Z.pos p < 2 * Z.pos (floor_pos p)

2 * Z.pos (floor_pos p) <= 2 * Z.pos p < 2 * (2 * Z.pos (floor_pos p))
omega.

1 <= 1 < 2
omega. Qed. (**********************************************************************)
Two more induction principles over Z.

forall P : Z -> Set, (forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n) -> forall n : Z, P n

forall P : Z -> Set, (forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n) -> forall n : Z, P n
P:Z -> Set
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p:Z

P p
P:Z -> Set
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p:Z
Q:=fun z : Z => 0 <= z -> P z * P (- z):Z -> Set

P p
P:Z -> Set
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p:Z
Q:=fun z : Z => 0 <= z -> P z * P (- z):Z -> Set

Q (Z.abs p)
P:Z -> Set
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p:Z
Q:=fun z : Z => 0 <= z -> P z * P (- z):Z -> Set

forall x : Z, (forall y : Z, 0 <= y < x -> Q y) -> Q x
P:Z -> Set
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) y

(fun z : Z => 0 <= z -> P z * P (- z)) x
P:Z -> Set
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) y
H0:0 <= x

forall m : Z, Z.abs m < Z.abs x -> P m
P:Z -> Set
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) y
H0:0 <= x
forall m : Z, Z.abs m < Z.abs (- x) -> P m
P:Z -> Set
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) y
H0:0 <= x

forall m : Z, Z.abs m < Z.abs x -> P m
P:Z -> Set
HP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) y
H0:0 <= x
m:Z
H1:Z.abs m < x

P m
P:Z -> Set
HP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) y
H0:0 <= x
m:Z
H1:Z.abs m < x
p0:P (Z.abs m)
p1:P (- Z.abs m)

P m
destruct (Zabs_dec m) as [-> | ->]; trivial.
P:Z -> Set
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) y
H0:0 <= x

forall m : Z, Z.abs m < Z.abs (- x) -> P m
P:Z -> Set
HP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) y
H0:0 <= x
m:Z
H1:Z.abs m < x

P m
P:Z -> Set
HP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) y
H0:0 <= x
m:Z
H1:Z.abs m < x
p0:P (Z.abs m)
p1:P (- Z.abs m)

P m
destruct (Zabs_dec m) as [-> | ->]; trivial. Qed.

forall P : Z -> Prop, (forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n) -> forall n : Z, P n

forall P : Z -> Prop, (forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n) -> forall n : Z, P n
P:Z -> Prop
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p:Z

P p
P:Z -> Prop
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p:Z
Q:=fun z : Z => 0 <= z -> P z /\ P (- z):Z -> Prop

P p
P:Z -> Prop
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p:Z
Q:=fun z : Z => 0 <= z -> P z /\ P (- z):Z -> Prop

Q (Z.abs p)
P:Z -> Prop
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p:Z
Q:=fun z : Z => 0 <= z -> P z /\ P (- z):Z -> Prop

forall x : Z, (forall y : Z, 0 <= y < x -> Q y) -> Q x
P:Z -> Prop
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) y

(fun z : Z => 0 <= z -> P z /\ P (- z)) x
P:Z -> Prop
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) y
H0:0 <= x

forall m : Z, Z.abs m < Z.abs x -> P m
P:Z -> Prop
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) y
H0:0 <= x
forall m : Z, Z.abs m < Z.abs (- x) -> P m
P:Z -> Prop
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) y
H0:0 <= x

forall m : Z, Z.abs m < Z.abs x -> P m
P:Z -> Prop
HP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) y
H0:0 <= x
m:Z
H1:Z.abs m < x

P m
P:Z -> Prop
HP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) y
H0:0 <= x
m:Z
H1:Z.abs m < x
H2:P (Z.abs m)
H3:P (- Z.abs m)

P m
elim (Zabs_dec m); intro eq; rewrite eq; trivial.
P:Z -> Prop
HP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) y
H0:0 <= x

forall m : Z, Z.abs m < Z.abs (- x) -> P m
P:Z -> Prop
HP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) y
H0:0 <= x
m:Z
H1:Z.abs m < x

P m
P:Z -> Prop
HP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P n
p, x:Z
H:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) y
H0:0 <= x
m:Z
H1:Z.abs m < x
H2:P (Z.abs m)
H3:P (- Z.abs m)

P m
destruct (Zabs_dec m) as [-> | ->]; trivial. Qed.
To do case analysis over the sign of z

forall (n : Z) (P : Prop), (n = 0 -> P) -> (n > 0 -> P) -> (n < 0 -> P) -> P

forall (n : Z) (P : Prop), (n = 0 -> P) -> (n > 0 -> P) -> (n < 0 -> P) -> P
x:Z
P:Prop
Hzero:x = 0 -> P
Hpos:x > 0 -> P
Hneg:x < 0 -> P

P
destruct x; [apply Hzero|apply Hpos|apply Hneg]; easy. Qed.
n:Z

n * n >= 0
n:Z

n * n >= 0
n:Z

0 <= n * n
apply Z.square_nonneg. Qed. (**********************************************************************)
A list length in Z, tail recursive.
Require Import List.

Fixpoint Zlength_aux (acc:Z) (A:Type) (l:list A) : Z :=
  match l with
    | nil => acc
    | _ :: l => Zlength_aux (Z.succ acc) A l
  end.

Definition Zlength := Zlength_aux 0.
Arguments Zlength [A] l.

Section Zlength_properties.

  Variable A : Type.

  Implicit Type l : list A.

  
A:Type
l:list A

Zlength l = Z.of_nat (length l)
A:Type
l:list A

Zlength l = Z.of_nat (length l)
A:Type
l:list A

forall (l0 : list A) (acc : Z), Zlength_aux acc A l0 = acc + Z.of_nat (length l0)
A:Type
l:list A
H:forall (l0 : list A) (acc : Z), Zlength_aux acc A l0 = acc + Z.of_nat (length l0)
Zlength l = Z.of_nat (length l)
A:Type

forall (l : list A) (acc : Z), Zlength_aux acc A l = acc + Z.of_nat (length l)
A:Type
l:list A
H:forall (l0 : list A) (acc : Z), Zlength_aux acc A l0 = acc + Z.of_nat (length l0)
Zlength l = Z.of_nat (length l)
A:Type

forall acc : Z, Zlength_aux acc A nil = acc + Z.of_nat (length nil)
A:Type
a:A
l:list A
IHl:forall acc : Z, Zlength_aux acc A l = acc + Z.of_nat (length l)
forall acc : Z, Zlength_aux acc A (a :: l) = acc + Z.of_nat (length (a :: l))
A:Type
l:list A
H:forall (l0 : list A) (acc : Z), Zlength_aux acc A l0 = acc + Z.of_nat (length l0)
Zlength l = Z.of_nat (length l)
A:Type
a:A
l:list A
IHl:forall acc : Z, Zlength_aux acc A l = acc + Z.of_nat (length l)

forall acc : Z, Zlength_aux acc A (a :: l) = acc + Z.of_nat (length (a :: l))
A:Type
l:list A
H:forall (l0 : list A) (acc : Z), Zlength_aux acc A l0 = acc + Z.of_nat (length l0)
Zlength l = Z.of_nat (length l)
A:Type
a:A
l:list A
IHl:forall acc0 : Z, Zlength_aux acc0 A l = acc0 + Z.of_nat (length l)
acc:Z

Zlength_aux acc A (a :: l) = acc + Z.of_nat (length (a :: l))
A:Type
l:list A
H:forall (l0 : list A) (acc : Z), Zlength_aux acc A l0 = acc + Z.of_nat (length l0)
Zlength l = Z.of_nat (length l)
A:Type
a:A
l:list A
IHl:forall acc0 : Z, Zlength_aux acc0 A l = acc0 + Z.of_nat (length l)
acc:Z

Zlength_aux (Z.succ acc) A l = acc + Z.of_nat (S (length l))
A:Type
l:list A
H:forall (l0 : list A) (acc : Z), Zlength_aux acc A l0 = acc + Z.of_nat (length l0)
Zlength l = Z.of_nat (length l)
A:Type
l:list A
H:forall (l0 : list A) (acc : Z), Zlength_aux acc A l0 = acc + Z.of_nat (length l0)

Zlength l = Z.of_nat (length l)
A:Type
l:list A
H:forall (l0 : list A) (acc : Z), Zlength_aux acc A l0 = acc + Z.of_nat (length l0)

Zlength_aux 0 A l = Z.of_nat (length l)
now rewrite H. Qed.
A:Type

Zlength nil = 0
A:Type

Zlength nil = 0
reflexivity. Qed.
A:Type
x:A
l:list A

Zlength (x :: l) = Z.succ (Zlength l)
A:Type
x:A
l:list A

Zlength (x :: l) = Z.succ (Zlength l)
A:Type
x:A
l:list A

Zlength (x :: l) = Z.succ (Zlength l)
now rewrite !Zlength_correct, <- Nat2Z.inj_succ. Qed.
A:Type
l:list A

Zlength l = 0 -> l = nil
A:Type
l:list A

Zlength l = 0 -> l = nil
A:Type
l:list A

Z.of_nat (length l) = 0 -> l = nil
A:Type
x:A
l:list A

Z.of_nat (length (x :: l)) = 0 -> x :: l = nil
now rewrite <- Nat2Z.inj_0, Nat2Z.inj_iff. Qed. End Zlength_properties. Arguments Zlength_correct [A] l. Arguments Zlength_cons [A] x l. Arguments Zlength_nil_inv [A] l _.