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 > 0reflexivity. Qed.forall p : positive, floor p > 0forall p : positive, floor p <= Z.pos p < 2 * floor pforall p : positive, floor p <= Z.pos p < 2 * floor pforall p : positive, Z.pos (floor_pos p) <= Z.pos p < 2 * Z.pos (floor_pos p)p:positiveIHp: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~0p:positiveIHp: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~01 <= 1 < 2p:positiveIHp: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~0omega.p:positiveIHp: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))p:positiveIHp: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~0omega.p:positiveIHp: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. Qed. (**********************************************************************)1 <= 1 < 2
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 nforall P : Z -> Set, (forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n) -> forall n : Z, P nP:Z -> SetHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np:ZP pP:Z -> SetHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np:ZQ:=fun z : Z => 0 <= z -> P z * P (- z):Z -> SetP pP:Z -> SetHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np:ZQ:=fun z : Z => 0 <= z -> P z * P (- z):Z -> SetQ (Z.abs p)P:Z -> SetHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np:ZQ:=fun z : Z => 0 <= z -> P z * P (- z):Z -> Setforall x : Z, (forall y : Z, 0 <= y < x -> Q y) -> Q xP:Z -> SetHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np, x:ZH: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)) xP:Z -> SetHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) yH0:0 <= xforall m : Z, Z.abs m < Z.abs x -> P mP:Z -> SetHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) yH0:0 <= xforall m : Z, Z.abs m < Z.abs (- x) -> P mP:Z -> SetHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) yH0:0 <= xforall m : Z, Z.abs m < Z.abs x -> P mP:Z -> SetHP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) yH0:0 <= xm:ZH1:Z.abs m < xP mdestruct (Zabs_dec m) as [-> | ->]; trivial.P:Z -> SetHP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) yH0:0 <= xm:ZH1:Z.abs m < xp0:P (Z.abs m)p1:P (- Z.abs m)P mP:Z -> SetHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) yH0:0 <= xforall m : Z, Z.abs m < Z.abs (- x) -> P mP:Z -> SetHP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) yH0:0 <= xm:ZH1:Z.abs m < xP mdestruct (Zabs_dec m) as [-> | ->]; trivial. Qed.P:Z -> SetHP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z * P (- z)) yH0:0 <= xm:ZH1:Z.abs m < xp0:P (Z.abs m)p1:P (- Z.abs m)P mforall P : Z -> Prop, (forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n) -> forall n : Z, P nforall P : Z -> Prop, (forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P n) -> forall n : Z, P nP:Z -> PropHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np:ZP pP:Z -> PropHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np:ZQ:=fun z : Z => 0 <= z -> P z /\ P (- z):Z -> PropP pP:Z -> PropHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np:ZQ:=fun z : Z => 0 <= z -> P z /\ P (- z):Z -> PropQ (Z.abs p)P:Z -> PropHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np:ZQ:=fun z : Z => 0 <= z -> P z /\ P (- z):Z -> Propforall x : Z, (forall y : Z, 0 <= y < x -> Q y) -> Q xP:Z -> PropHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np, x:ZH: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)) xP:Z -> PropHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) yH0:0 <= xforall m : Z, Z.abs m < Z.abs x -> P mP:Z -> PropHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) yH0:0 <= xforall m : Z, Z.abs m < Z.abs (- x) -> P mP:Z -> PropHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) yH0:0 <= xforall m : Z, Z.abs m < Z.abs x -> P mP:Z -> PropHP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) yH0:0 <= xm:ZH1:Z.abs m < xP melim (Zabs_dec m); intro eq; rewrite eq; trivial.P:Z -> PropHP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) yH0:0 <= xm:ZH1:Z.abs m < xH2:P (Z.abs m)H3:P (- Z.abs m)P mP:Z -> PropHP:forall n : Z, (forall m : Z, Z.abs m < Z.abs n -> P m) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) yH0:0 <= xforall m : Z, Z.abs m < Z.abs (- x) -> P mP:Z -> PropHP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) yH0:0 <= xm:ZH1:Z.abs m < xP mdestruct (Zabs_dec m) as [-> | ->]; trivial. Qed.P:Z -> PropHP:forall n : Z, (forall m0 : Z, Z.abs m0 < Z.abs n -> P m0) -> P np, x:ZH:forall y : Z, 0 <= y < x -> (fun z : Z => 0 <= z -> P z /\ P (- z)) yH0:0 <= xm:ZH1:Z.abs m < xH2:P (Z.abs m)H3:P (- Z.abs m)P m
To do case analysis over the sign of z
forall (n : Z) (P : Prop), (n = 0 -> P) -> (n > 0 -> P) -> (n < 0 -> P) -> Pforall (n : Z) (P : Prop), (n = 0 -> P) -> (n > 0 -> P) -> (n < 0 -> P) -> Pdestruct x; [apply Hzero|apply Hpos|apply Hneg]; easy. Qed.x:ZP:PropHzero:x = 0 -> PHpos:x > 0 -> PHneg:x < 0 -> PPn:Zn * n >= 0n:Zn * n >= 0apply Z.square_nonneg. Qed. (**********************************************************************)n:Z0 <= n * n
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:Typel:list AZlength l = Z.of_nat (length l)A:Typel:list AZlength l = Z.of_nat (length l)A:Typel:list Aforall (l0 : list A) (acc : Z), Zlength_aux acc A l0 = acc + Z.of_nat (length l0)A:Typel:list AH: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:Typeforall (l : list A) (acc : Z), Zlength_aux acc A l = acc + Z.of_nat (length l)A:Typel:list AH: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:Typeforall acc : Z, Zlength_aux acc A nil = acc + Z.of_nat (length nil)A:Typea:Al:list AIHl: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:Typel:list AH: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:Typea:Al:list AIHl: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:Typel:list AH: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:Typea:Al:list AIHl:forall acc0 : Z, Zlength_aux acc0 A l = acc0 + Z.of_nat (length l)acc:ZZlength_aux acc A (a :: l) = acc + Z.of_nat (length (a :: l))A:Typel:list AH: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:Typea:Al:list AIHl:forall acc0 : Z, Zlength_aux acc0 A l = acc0 + Z.of_nat (length l)acc:ZZlength_aux (Z.succ acc) A l = acc + Z.of_nat (S (length l))A:Typel:list AH: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:Typel:list AH:forall (l0 : list A) (acc : Z), Zlength_aux acc A l0 = acc + Z.of_nat (length l0)Zlength l = Z.of_nat (length l)now rewrite H. Qed.A:Typel:list AH: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)A:TypeZlength nil = 0reflexivity. Qed.A:TypeZlength nil = 0A:Typex:Al:list AZlength (x :: l) = Z.succ (Zlength l)A:Typex:Al:list AZlength (x :: l) = Z.succ (Zlength l)now rewrite !Zlength_correct, <- Nat2Z.inj_succ. Qed.A:Typex:Al:list AZlength (x :: l) = Z.succ (Zlength l)A:Typel:list AZlength l = 0 -> l = nilA:Typel:list AZlength l = 0 -> l = nilA:Typel:list AZ.of_nat (length l) = 0 -> l = nilnow 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 _.A:Typex:Al:list AZ.of_nat (length (x :: l)) = 0 -> x :: l = nil