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) *)
(************************************************************************)
Author: Pierre Letouzey
The alternate Zgcd_alt given here used to be the main Z.gcd
function (see file Znumtheory), but this main Z.gcd is now
based on a modern binary-efficient algorithm. This earlier
version, based on Euclid's algorithm of iterated modulo, is kept
here due to both its intrinsic interest and its use as reference
point when proving gcd on Int31 numbers
Require Import ZArith_base. Require Import ZArithRing. Require Import Zdiv. Require Import Znumtheory. Require Import Omega. Open Scope Z_scope.
In Coq, we need to control the number of iteration of modulo.
For that, we use an explicit measure in nat, and we prove later
that using 2*d is enough, where d is the number of binary
digits of the first argument.
Fixpoint Zgcdn (n:nat) : Z -> Z -> Z := fun a b => match n with | O => 1 (* arbitrary, since n should be big enough *) | S n => match a with | Z0 => Z.abs b | Zpos _ => Zgcdn n (Z.modulo b a) a | Zneg a => Zgcdn n (Z.modulo b (Zpos a)) (Zpos a) end end. Definition Zgcd_bound (a:Z) := match a with | Z0 => S O | Zpos p => let n := Pos.size_nat p in (n+n)%nat | Zneg p => let n := Pos.size_nat p in (n+n)%nat end. Definition Zgcd_alt a b := Zgcdn (Zgcd_bound a) a b.
A first obvious fact : Z.gcd a b is positive.
forall (n : nat) (a b : Z), 0 <= Zgcdn n a bforall (n : nat) (a b : Z), 0 <= Zgcdn n a bforall a b : Z, 0 <= Zgcdn 0 a bn:natIHn:forall a b : Z, 0 <= Zgcdn n a bforall a b : Z, 0 <= Zgcdn (S n) a bdestruct a; simpl; intros; auto with zarith; auto. Qed.n:natIHn:forall a b : Z, 0 <= Zgcdn n a bforall a b : Z, 0 <= Zgcdn (S n) a bforall a b : Z, 0 <= Zgcd_alt a bintros; unfold Z.gcd; apply Zgcdn_pos; auto. Qed.forall a b : Z, 0 <= Zgcd_alt a b
We now prove that Z.gcd is indeed a gcd.
1) We prove a weaker & easier bound.
forall (n : nat) (a b : Z), Z.abs a < Z.of_nat n -> Zis_gcd a b (Zgcdn n a b)forall (n : nat) (a b : Z), Z.abs a < Z.of_nat n -> Zis_gcd a b (Zgcdn n a b)forall a b : Z, Z.abs a < Z.of_nat 0 -> Zis_gcd a b (Zgcdn 0 a b)n:natIHn:forall a b : Z, Z.abs a < Z.of_nat n -> Zis_gcd a b (Zgcdn n a b)forall a b : Z, Z.abs a < Z.of_nat (S n) -> Zis_gcd a b (Zgcdn (S n) a b)a, b:ZH:Z.abs a < 0Zis_gcd a b 1n:natIHn:forall a b : Z, Z.abs a < Z.of_nat n -> Zis_gcd a b (Zgcdn n a b)forall a b : Z, Z.abs a < Z.of_nat (S n) -> Zis_gcd a b (Zgcdn (S n) a b)n:natIHn:forall a b : Z, Z.abs a < Z.of_nat n -> Zis_gcd a b (Zgcdn n a b)forall a b : Z, Z.abs a < Z.of_nat (S n) -> Zis_gcd a b (Zgcdn (S n) a b)n:natp:positiveb:ZH:Z.pos p < Z.succ (Z.of_nat n)q, r:ZH0:b = Z.pos p * q + rH1:0 <= r < Z.pos pH2:Z.abs r < Z.of_nat nIH:Zis_gcd r (Z.pos p) (Zgcdn n r (Z.pos p))Zis_gcd (Z.pos p) (Z.pos p * q + r) (Zgcdn n r (Z.pos p))n:natp:positiveb:ZH:Z.pos p < Z.succ (Z.of_nat n)q, r:ZH0:b = Z.pos p * q + rH1:0 <= r < Z.pos pH2:Z.abs r < Z.of_nat nIH:Zis_gcd r (Z.pos p) (Zgcdn n r (Z.pos p))Zis_gcd (Z.neg p) (Z.pos p * q + r) (Zgcdn n r (Z.pos p))n:natp:positiveb:ZH:Z.pos p < Z.succ (Z.of_nat n)q, r:ZH0:b = Z.pos p * q + rH1:0 <= r < Z.pos pH2:Z.abs r < Z.of_nat nIH:Zis_gcd r (Z.pos p) (Zgcdn n r (Z.pos p))Zis_gcd (Z.neg p) (Z.pos p * q + r) (Zgcdn n r (Z.pos p))apply Zis_gcd_for_euclid2; auto. Qed.n:natp:positiveb:ZH:Z.pos p < Z.succ (Z.of_nat n)q, r:ZH0:b = Z.pos p * q + rH1:0 <= r < Z.pos pH2:Z.abs r < Z.of_nat nIH:Zis_gcd r (Z.pos p) (Zgcdn n r (Z.pos p))Zis_gcd (- Z.neg p) (Z.pos p * q + r) (Zgcdn n r (Z.pos p))
2) For Euclid's algorithm, the worst-case situation corresponds
to Fibonacci numbers. Let's define them:
Fixpoint fibonacci (n:nat) : Z := match n with | O => 1 | S O => 1 | S (S n as p) => fibonacci p + fibonacci n end.forall n : nat, 0 <= fibonacci nforall n : nat, 0 <= fibonacci nforall N n : nat, (n < N)%nat -> 0 <= fibonacci nforall n : nat, (n < 0)%nat -> 0 <= fibonacci nN:natIHN:forall n : nat, (n < N)%nat -> 0 <= fibonacci nforall n : nat, (n < S N)%nat -> 0 <= fibonacci nN:natIHN:forall n : nat, (n < N)%nat -> 0 <= fibonacci nforall n : nat, (n < S N)%nat -> 0 <= fibonacci nN:natIHN:forall n0 : nat, (n0 < N)%nat -> 0 <= fibonacci n0n:natH:(n < S N)%nat0 <= fibonacci nN:natIHN:forall n : nat, (n < N)%nat -> 0 <= fibonacci nH:(0 < S N)%nat0 <= fibonacci 0N:natIHN:forall n0 : nat, (n0 < N)%nat -> 0 <= fibonacci n0n:natH:(S n < S N)%nat0 <= fibonacci (S n)N:natIHN:forall n0 : nat, (n0 < N)%nat -> 0 <= fibonacci n0n:natH:(S n < S N)%nat0 <= fibonacci (S n)N:natIHN:forall n : nat, (n < N)%nat -> 0 <= fibonacci nH:(1 < S N)%nat0 <= fibonacci 1N:natIHN:forall n0 : nat, (n0 < N)%nat -> 0 <= fibonacci n0n:natH:(S (S n) < S N)%nat0 <= fibonacci (S (S n))N:natIHN:forall n0 : nat, (n0 < N)%nat -> 0 <= fibonacci n0n:natH:(S (S n) < S N)%nat0 <= fibonacci (S (S n))generalize (IHN n) (IHN (S n)); omega. Qed.N:natIHN:forall n0 : nat, (n0 < N)%nat -> 0 <= fibonacci n0n:natH:(S (S n) < S N)%nat0 <= fibonacci (S n) + fibonacci nforall n m : nat, (n <= m)%nat -> fibonacci n <= fibonacci mforall n m : nat, (n <= m)%nat -> fibonacci n <= fibonacci mn:natfibonacci n <= fibonacci nn, m:natH:(n <= m)%natIHle:fibonacci n <= fibonacci mfibonacci n <= fibonacci (S m)n, m:natH:(n <= m)%natIHle:fibonacci n <= fibonacci mfibonacci n <= fibonacci (S m)n, m:natH:(n <= m)%natIHle:fibonacci n <= fibonacci mfibonacci m <= fibonacci (S m)m:natfibonacci m <= fibonacci (S m)fibonacci 0 <= fibonacci 1m:natfibonacci (S m) <= fibonacci (S (S m))m:natfibonacci (S m) <= fibonacci (S (S m))generalize (fibonacci_pos m); omega. Qed.m:natfibonacci (S m) <= fibonacci (S m) + fibonacci m
3) We prove that fibonacci numbers are indeed worst-case:
for a given number n, if we reach a conclusion about gcd(a,b) in
exactly n+1 loops, then fibonacci (n+1)<=a ∧ fibonacci(n+2)<=b
forall (n : nat) (a b : Z), 0 < a < b -> Zis_gcd a b (Zgcdn (S n) a b) -> Zgcdn n a b <> Zgcdn (S n) a b -> fibonacci (S n) <= a /\ fibonacci (S (S n)) <= bforall (n : nat) (a b : Z), 0 < a < b -> Zis_gcd a b (Zgcdn (S n) a b) -> Zgcdn n a b <> Zgcdn (S n) a b -> fibonacci (S n) <= a /\ fibonacci (S (S n)) <= bforall a b : Z, 0 < a < b -> Zis_gcd a b (Zgcdn 1 a b) -> Zgcdn 0 a b <> Zgcdn 1 a b -> fibonacci 1 <= a /\ fibonacci 2 <= bn:natIHn:forall a b : Z, 0 < a < b -> Zis_gcd a b (Zgcdn (S n) a b) -> Zgcdn n a b <> Zgcdn (S n) a b -> fibonacci (S n) <= a /\ fibonacci (S (S n)) <= bforall a b : Z, 0 < a < b -> Zis_gcd a b (Zgcdn (S (S n)) a b) -> Zgcdn (S n) a b <> Zgcdn (S (S n)) a b -> fibonacci (S (S n)) <= a /\ fibonacci (S (S (S n))) <= bn:natIHn:forall a b : Z, 0 < a < b -> Zis_gcd a b (Zgcdn (S n) a b) -> Zgcdn n a b <> Zgcdn (S n) a b -> fibonacci (S n) <= a /\ fibonacci (S (S n)) <= bforall a b : Z, 0 < a < b -> Zis_gcd a b (Zgcdn (S (S n)) a b) -> Zgcdn (S n) a b <> Zgcdn (S (S n)) a b -> fibonacci (S (S n)) <= a /\ fibonacci (S (S (S n))) <= bn:natIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn (S n) a0 b0) -> Zgcdn n a0 b0 <> Zgcdn (S n) a0 b0 -> fibonacci (S n) <= a0 /\ fibonacci (S (S n)) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bZis_gcd (Z.pos a) b (Zgcdn (S (S n)) (Z.pos a) b) -> Zgcdn (S n) (Z.pos a) b <> Zgcdn (S (S n)) (Z.pos a) b -> fibonacci (S (S n)) <= Z.pos a /\ fibonacci (S (S (S n))) <= bn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bZis_gcd (Z.pos a) b (Zgcdn (S m) (Z.pos a) b) -> Zgcdn m (Z.pos a) b <> Zgcdn (S m) (Z.pos a) b -> fibonacci (S m) <= Z.pos a /\ fibonacci (S (S m)) <= bn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bZis_gcd (Z.pos a) b (Zgcdn (S m) (Z.pos a) b) -> Zgcdn (S n) (Z.pos a) b <> Zgcdn (S m) (Z.pos a) b -> fibonacci (S m) <= Z.pos a /\ fibonacci (S (S m)) <= bn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bZis_gcd (Z.pos a) b (Zgcdn m (b mod Z.pos a) (Z.pos a)) -> Zgcdn n (b mod Z.pos a) (Z.pos a) <> Zgcdn m (b mod Z.pos a) (Z.pos a) -> fibonacci (S m) <= Z.pos a /\ fibonacci (S (S m)) <= bn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < b(let (q, r) := Z.div_eucl b (Z.pos a) in b = Z.pos a * q + r /\ 0 <= r < Z.pos a) -> Zis_gcd (Z.pos a) b (Zgcdn m (let (_, r) := Z.div_eucl b (Z.pos a) in r) (Z.pos a)) -> Zgcdn n (let (_, r) := Z.div_eucl b (Z.pos a) in r) (Z.pos a) <> Zgcdn m (let (_, r) := Z.div_eucl b (Z.pos a) in r) (Z.pos a) -> fibonacci (S m) <= Z.pos a /\ fibonacci (S (S m)) <= bn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:Zb = Z.pos a * q + r /\ 0 <= r < Z.pos a -> Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a)) -> Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a) -> fibonacci (S m) <= Z.pos a /\ fibonacci (S (S m)) <= bn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 <= rHr':r < Z.pos aZis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a)) -> Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a) -> fibonacci (S m) <= Z.pos a /\ fibonacci (S (S m)) <= bn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aZis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a)) -> Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a) -> fibonacci (S m) <= Z.pos a /\ fibonacci (S (S m)) <= bn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 = rHr':r < Z.pos aZis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a)) -> Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a) -> fibonacci (S m) <= Z.pos a /\ fibonacci (S (S m)) <= bn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aZis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a)) -> Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a) -> fibonacci (S m) <= Z.pos a /\ fibonacci (S (S m)) <= bn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aZis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a)) -> Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a) -> fibonacci (S m) <= Z.pos a /\ fibonacci (S m) + fibonacci m <= bn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)fibonacci (S m) <= Z.pos a /\ fibonacci (S m) + fibonacci m <= bn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)Zis_gcd r (Z.pos a) (Zgcdn m r (Z.pos a))n, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)H1:fibonacci m <= rH2:fibonacci (S m) <= Z.pos afibonacci (S m) <= Z.pos a /\ fibonacci (S m) + fibonacci m <= bn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)Zis_gcd r (Z.pos a) (Zgcdn m r (Z.pos a))n, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)EQ':r = Z.pos a * - q + bZis_gcd r (Z.pos a) (Zgcdn m r (Z.pos a))n, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)EQ':r = Z.pos a * - q + bZis_gcd (Z.pos a * - q + b) (Z.pos a) (Zgcdn m r (Z.pos a))n, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)EQ':r = Z.pos a * - q + bZis_gcd (Z.pos a) (Z.pos a * - q + b) (Zgcdn m r (Z.pos a))apply Zis_gcd_sym; auto.n, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)EQ':r = Z.pos a * - q + bZis_gcd b (Z.pos a) (Zgcdn m r (Z.pos a))n, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)H1:fibonacci m <= rH2:fibonacci (S m) <= Z.pos afibonacci (S m) <= Z.pos a /\ fibonacci (S m) + fibonacci m <= bn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)H1:fibonacci m <= rH2:fibonacci (S m) <= Z.pos afibonacci (S m) + fibonacci m <= bn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)H1:fibonacci m <= rH2:fibonacci (S m) <= Z.pos afibonacci (S m) + fibonacci m <= Z.pos a * q + rn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)H1:fibonacci m <= rH2:fibonacci (S m) <= Z.pos afibonacci (S m) <= Z.pos a * qn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)H1:fibonacci m <= rH2:fibonacci (S m) <= Z.pos afibonacci (S m) <= Z.pos a * 1n, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)H1:fibonacci m <= rH2:fibonacci (S m) <= Z.pos aZ.pos a * 1 <= Z.pos a * qn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)H1:fibonacci m <= rH2:fibonacci (S m) <= Z.pos aZ.pos a * 1 <= Z.pos a * qn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)H1:fibonacci m <= rH2:fibonacci (S m) <= Z.pos a1 <= qn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)H1:fibonacci m <= rH2:fibonacci (S m) <= Z.pos aZ.succ 0 <= qn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)H1:fibonacci m <= rH2:fibonacci (S m) <= Z.pos a0 < qn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bp:positiver:ZEQ:b = Z.pos a * Z.neg p + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)H1:fibonacci m <= rH2:fibonacci (S m) <= Z.pos a0 < Z.neg pomega.n, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bp:positiver:ZEQ:b = Z.pos a * Z.neg p + rHr:0 < rHr':r < Z.pos aH:Zis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a))H0:Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a)H1:fibonacci m <= rH2:fibonacci (S m) <= Z.pos aH3:Z.pos a * Z.neg p < 00 < Z.neg pn, m:natHeqm:m = S nIHn:forall a0 b0 : Z, 0 < a0 < b0 -> Zis_gcd a0 b0 (Zgcdn m a0 b0) -> Zgcdn n a0 b0 <> Zgcdn m a0 b0 -> fibonacci m <= a0 /\ fibonacci (S m) <= b0a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZEQ:b = Z.pos a * q + rHr:0 = rHr':r < Z.pos aZis_gcd (Z.pos a) b (Zgcdn m r (Z.pos a)) -> Zgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a) -> fibonacci (S m) <= Z.pos a /\ fibonacci (S (S m)) <= bn, m:natHeqm:m = S na:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq, r:ZHr:0 = rZgcdn n r (Z.pos a) <> Zgcdn m r (Z.pos a) -> fibonacci (S m) <= Z.pos a /\ fibonacci (S (S m)) <= bn, m:natHeqm:m = S na:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq:ZZgcdn n 0 (Z.pos a) <> Zgcdn (S n) 0 (Z.pos a) -> fibonacci (S n) + fibonacci n <= Z.pos a /\ fibonacci (S n) + fibonacci n + fibonacci (S n) <= bm:natHeqm:m = 1%nata:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq:ZZgcdn 0 0 (Z.pos a) <> Zgcdn 1 0 (Z.pos a) -> fibonacci 1 + fibonacci 0 <= Z.pos a /\ fibonacci 1 + fibonacci 0 + fibonacci 1 <= bn, m:natHeqm:m = S (S n)a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq:ZZgcdn (S n) 0 (Z.pos a) <> Zgcdn (S (S n)) 0 (Z.pos a) -> fibonacci (S (S n)) + fibonacci (S n) <= Z.pos a /\ fibonacci (S (S n)) + fibonacci (S n) + fibonacci (S (S n)) <= bm:natHeqm:m = 1%nata:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq:ZZgcdn 0 0 (Z.pos a) <> Zgcdn 1 0 (Z.pos a) -> fibonacci 1 + fibonacci 0 <= Z.pos a /\ fibonacci 1 + fibonacci 0 + fibonacci 1 <= bomega.m:natHeqm:m = 1%nata:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq:Z1 <> Z.pos a -> 2 <= Z.pos a /\ 3 <= bnow destruct 1. Qed.n, m:natHeqm:m = S (S n)a:positiveb:ZHa:0 < Z.pos aHa':Z.pos a < bq:ZZgcdn (S n) 0 (Z.pos a) <> Zgcdn (S (S n)) 0 (Z.pos a) -> fibonacci (S (S n)) + fibonacci (S n) <= Z.pos a /\ fibonacci (S (S n)) + fibonacci (S n) + fibonacci (S (S n)) <= b
3b) We reformulate the previous result in a more positive way.
forall (n : nat) (a b : Z), 0 < a < b -> a < fibonacci (S n) -> Zis_gcd a b (Zgcdn n a b)forall (n : nat) (a b : Z), 0 < a < b -> a < fibonacci (S n) -> Zis_gcd a b (Zgcdn n a b)n:natp:positiveforall b : Z, 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)n:natp:positive(forall (k n0 : nat) (b : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b (Zgcdn n0 (Z.pos p) b)) -> forall b : Z, 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)n:natp:positiveforall (k n0 : nat) (b : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b (Zgcdn n0 (Z.pos p) b)n:natp:positiveforall (k n0 : nat) (b : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b (Zgcdn n0 (Z.pos p) b)p:positiveforall (n : nat) (b : Z), 0%nat = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positivek:natIHk:forall (n : nat) (b : Z), k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)forall (n : nat) (b : Z), S k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positiven:natb:ZH:0%nat = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positivek:natIHk:forall (n : nat) (b : Z), k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)forall (n : nat) (b : Z), S k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positiven:natb:ZH:0%nat = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:(Pos.to_nat p < n)%natZis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positivek:natIHk:forall (n : nat) (b : Z), k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)forall (n : nat) (b : Z), S k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positiven:natb:ZH:0%nat = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:(Pos.to_nat p < n)%natZ.abs (Z.pos p) < Z.of_nat np:positivek:natIHk:forall (n : nat) (b : Z), k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)forall (n : nat) (b : Z), S k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positiven:natb:ZH:0%nat = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:(Pos.to_nat p < n)%natZ.pos p < Z.of_nat np:positivek:natIHk:forall (n : nat) (b : Z), k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)forall (n : nat) (b : Z), S k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positiven:natb:ZH:0%nat = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:(Pos.to_nat p < n)%natZ.of_nat (S (Pos.to_nat p)) <= Z.of_nat n -> Z.pos p < Z.of_nat np:positivek:natIHk:forall (n : nat) (b : Z), k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)forall (n : nat) (b : Z), S k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positiven:natb:ZH:0%nat = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:(Pos.to_nat p < n)%natZ.succ (Z.of_nat (Pos.to_nat p)) <= Z.of_nat n -> Z.pos p < Z.of_nat np:positivek:natIHk:forall (n : nat) (b : Z), k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)forall (n : nat) (b : Z), S k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positiven:natb:ZH:0%nat = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:(Pos.to_nat p < n)%natZ.succ (Z.pos p) <= Z.of_nat n -> Z.pos p < Z.of_nat np:positivek:natIHk:forall (n : nat) (b : Z), k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)forall (n : nat) (b : Z), S k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positivek:natIHk:forall (n : nat) (b : Z), k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)forall (n : nat) (b : Z), S k = (S (Pos.to_nat p) - n)%nat -> 0 < Z.pos p < b -> Z.pos p < fibonacci (S n) -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positivek:natIHk:forall (n0 : nat) (b0 : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b0 -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b0 (Zgcdn n0 (Z.pos p) b0)n:natb:ZH:S k = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positivek:natIHk:forall (n0 : nat) (b0 : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b0 -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b0 (Zgcdn n0 (Z.pos p) b0)n:natb:ZH:S k = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b) -> Zgcdn n (Z.pos p) b <> Zgcdn (S n) (Z.pos p) b -> fibonacci (S n) <= Z.pos p /\ fibonacci (S (S n)) <= bZis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positivek:natIHk:forall (n0 : nat) (b0 : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b0 -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b0 (Zgcdn n0 (Z.pos p) b0)n:natb:ZH:S k = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b) -> Zgcdn n (Z.pos p) b <> Zgcdn (S n) (Z.pos p) b -> fibonacci (S n) <= Z.pos p /\ fibonacci (S (S n)) <= bZis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b)p:positivek:natIHk:forall (n0 : nat) (b0 : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b0 -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b0 (Zgcdn n0 (Z.pos p) b0)n:natb:ZH:S k = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b) -> Zgcdn n (Z.pos p) b <> Zgcdn (S n) (Z.pos p) b -> fibonacci (S n) <= Z.pos p /\ fibonacci (S (S n)) <= bH3:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b)Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positivek:natIHk:forall (n0 : nat) (b0 : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b0 -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b0 (Zgcdn n0 (Z.pos p) b0)n:natb:ZH:S k = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b) -> Zgcdn n (Z.pos p) b <> Zgcdn (S n) (Z.pos p) b -> fibonacci (S n) <= Z.pos p /\ fibonacci (S (S n)) <= bk = (S (Pos.to_nat p) - S n)%natp:positivek:natIHk:forall (n0 : nat) (b0 : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b0 -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b0 (Zgcdn n0 (Z.pos p) b0)n:natb:ZH:S k = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b) -> Zgcdn n (Z.pos p) b <> Zgcdn (S n) (Z.pos p) b -> fibonacci (S n) <= Z.pos p /\ fibonacci (S (S n)) <= bZ.pos p < fibonacci (S (S n))p:positivek:natIHk:forall (n0 : nat) (b0 : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b0 -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b0 (Zgcdn n0 (Z.pos p) b0)n:natb:ZH:S k = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b) -> Zgcdn n (Z.pos p) b <> Zgcdn (S n) (Z.pos p) b -> fibonacci (S n) <= Z.pos p /\ fibonacci (S (S n)) <= bH3:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b)Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positivek:natIHk:forall (n0 : nat) (b0 : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b0 -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b0 (Zgcdn n0 (Z.pos p) b0)n:natb:ZH:S k = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b) -> Zgcdn n (Z.pos p) b <> Zgcdn (S n) (Z.pos p) b -> fibonacci (S n) <= Z.pos p /\ fibonacci (S (S n)) <= bZ.pos p < fibonacci (S (S n))p:positivek:natIHk:forall (n0 : nat) (b0 : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b0 -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b0 (Zgcdn n0 (Z.pos p) b0)n:natb:ZH:S k = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b) -> Zgcdn n (Z.pos p) b <> Zgcdn (S n) (Z.pos p) b -> fibonacci (S n) <= Z.pos p /\ fibonacci (S (S n)) <= bH3:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b)Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positivek:natIHk:forall (n0 : nat) (b0 : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b0 -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b0 (Zgcdn n0 (Z.pos p) b0)n:natb:ZH:S k = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b) -> Zgcdn n (Z.pos p) b <> Zgcdn (S n) (Z.pos p) b -> fibonacci (S n) <= Z.pos p /\ fibonacci (S (S n)) <= bZ.pos p < fibonacci (S n) + fibonacci np:positivek:natIHk:forall (n0 : nat) (b0 : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b0 -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b0 (Zgcdn n0 (Z.pos p) b0)n:natb:ZH:S k = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b) -> Zgcdn n (Z.pos p) b <> Zgcdn (S n) (Z.pos p) b -> fibonacci (S n) <= Z.pos p /\ fibonacci (S (S n)) <= bH3:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b)Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)p:positivek:natIHk:forall (n0 : nat) (b0 : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b0 -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b0 (Zgcdn n0 (Z.pos p) b0)n:natb:ZH:S k = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b) -> Zgcdn n (Z.pos p) b <> Zgcdn (S n) (Z.pos p) b -> fibonacci (S n) <= Z.pos p /\ fibonacci (S (S n)) <= bH3:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b)Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)generalize (H2 H3); clear H2 H3; omega. Qed.p:positivek:natIHk:forall (n0 : nat) (b0 : Z), k = (S (Pos.to_nat p) - n0)%nat -> 0 < Z.pos p < b0 -> Z.pos p < fibonacci (S n0) -> Zis_gcd (Z.pos p) b0 (Zgcdn n0 (Z.pos p) b0)n:natb:ZH:S k = (S (Pos.to_nat p) - n)%natH0:0 < Z.pos p < bH1:Z.pos p < fibonacci (S n)H2:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b) -> Zgcdn n (Z.pos p) b <> Zgcdn (S n) (Z.pos p) b -> fibonacci (S n) <= Z.pos p /\ fibonacci (S (S n)) <= bH3:Zis_gcd (Z.pos p) b (Zgcdn (S n) (Z.pos p) b)Zgcdn (S n) (Z.pos p) b = Zgcdn n (Z.pos p) b
4) The proposed bound leads to a fibonacci number that is big enough.
forall a : Z, 0 < a -> a < fibonacci (Zgcd_bound a)forall a : Z, 0 < a -> a < fibonacci (Zgcd_bound a)p:positive0 < Z.pos p -> Z.pos p < fibonacci (Zgcd_bound (Z.pos p))p:positiveZ.pos p < fibonacci (Zgcd_bound (Z.pos p))p:positiven:=(Pos.size_nat p + Pos.size_nat p)%nat:natIHp:Z.pos p < fibonacci nH:n <> 0%natZ.pos p~1 < match n with | 0%nat => 1 | S n0 => fibonacci n + fibonacci n0 end + fibonacci np:positiven:=(Pos.size_nat p + Pos.size_nat p)%nat:natIHp:Z.pos p < fibonacci nH:n <> 0%natZ.pos p~0 < match n with | 0%nat => 1 | S n0 => fibonacci n + fibonacci n0 end + fibonacci np:positivem:natIHp:Z.pos p < fibonacci (S m)H:S m <> 0%natZ.pos p~1 < fibonacci (S m) + fibonacci m + fibonacci (S m)p:positiven:=(Pos.size_nat p + Pos.size_nat p)%nat:natIHp:Z.pos p < fibonacci nH:n <> 0%natZ.pos p~0 < match n with | 0%nat => 1 | S n0 => fibonacci n + fibonacci n0 end + fibonacci np:positiven:=(Pos.size_nat p + Pos.size_nat p)%nat:natIHp:Z.pos p < fibonacci nH:n <> 0%natZ.pos p~0 < match n with | 0%nat => 1 | S n0 => fibonacci n + fibonacci n0 end + fibonacci ngeneralize (fibonacci_pos m); rewrite Pos2Z.inj_xO; omega. Qed. (* 5) the end: we glue everything together and take care of situations not corresponding to [0<a<b]. *)p:positivem:natIHp:Z.pos p < fibonacci (S m)H:S m <> 0%natZ.pos p~0 < fibonacci (S m) + fibonacci m + fibonacci (S m)a:ZZgcd_bound (- a) = Zgcd_bound anow destruct a. Qed.a:ZZgcd_bound (- a) = Zgcd_bound an:nata, b:ZZgcdn n (- a) b = Zgcdn n a bn:nata, b:ZZgcdn n (- a) b = Zgcdn n a bdestruct a; simpl; auto. Qed.n:nata, b:ZIHn:Zgcdn n (- a) b = Zgcdn n a bmatch - a with | 0 => Z.abs b | Z.pos _ => Zgcdn n (b mod - a) (- a) | Z.neg a0 => Zgcdn n (b mod Z.pos a0) (Z.pos a0) end = match a with | 0 => Z.abs b | Z.pos _ => Zgcdn n (b mod a) a | Z.neg a0 => Zgcdn n (b mod Z.pos a0) (Z.pos a0) endn:nata:positiveb:Z(Zgcd_bound (Z.pos a) <= n)%nat -> Zis_gcd (Z.pos a) b (Zgcdn n (Z.pos a) b)n:nata:positiveb:Z(Zgcd_bound (Z.pos a) <= n)%nat -> Zis_gcd (Z.pos a) b (Zgcdn n (Z.pos a) b)n:nata:positiveb:ZH:(Zgcd_bound (Z.pos a) <= n)%natZis_gcd (Z.pos a) b (Zgcdn n (Z.pos a) b)n:nata:positiveb:ZH:(Zgcd_bound (Z.pos a) <= n)%nat(0 < Z.pos a -> Z.pos a < fibonacci (Zgcd_bound (Z.pos a))) -> Zis_gcd (Z.pos a) b (Zgcdn n (Z.pos a) b)n:nata:positiveb:ZH:(Pos.size_nat a + Pos.size_nat a <= n)%nat(0 < Z.pos a -> Z.pos a < fibonacci (Pos.size_nat a + Pos.size_nat a)) -> Zis_gcd (Z.pos a) b (Zgcdn n (Z.pos a) b)n:nata:positiveb:Zm:natHeqm:m = (Pos.size_nat a + Pos.size_nat a)%natH:(m <= n)%nat(0 < Z.pos a -> Z.pos a < fibonacci m) -> Zis_gcd (Z.pos a) b (Zgcdn n (Z.pos a) b)n:nata:positiveb:Zm:natHeqm:m = (Pos.size_nat a + Pos.size_nat a)%natH:(m <= n)%nat(1 < m)%natn:nata:positiveb:Zm:natHeqm:m = (Pos.size_nat a + Pos.size_nat a)%natH:(m <= n)%natH0:(1 < m)%nat(0 < Z.pos a -> Z.pos a < fibonacci m) -> Zis_gcd (Z.pos a) b (Zgcdn n (Z.pos a) b)rewrite Heqm; destruct a; simpl; rewrite 1?plus_comm; auto with arith.n:nata:positiveb:Zm:natHeqm:m = (Pos.size_nat a + Pos.size_nat a)%natH:(m <= n)%nat(1 < m)%natn:nata:positiveb:Zm:natHeqm:m = (Pos.size_nat a + Pos.size_nat a)%natH:(m <= n)%natH0:(1 < m)%nat(0 < Z.pos a -> Z.pos a < fibonacci m) -> Zis_gcd (Z.pos a) b (Zgcdn n (Z.pos a) b)n:nata:positiveb:Zm:natHeqm:S m = (Pos.size_nat a + Pos.size_nat a)%natH:(S m <= n)%natH0:(1 < S m)%nat(0 < Z.pos a -> Z.pos a < fibonacci (S m)) -> Zis_gcd (Z.pos a) b (Zgcdn n (Z.pos a) b)n:nata:positiveb:Zm:natHeqm:S m = (Pos.size_nat a + Pos.size_nat a)%natH:(S m <= S n)%natH0:(1 < S m)%nat(0 < Z.pos a -> Z.pos a < fibonacci (S m)) -> Zis_gcd (Z.pos a) b (Zgcdn (S n) (Z.pos a) b)n:nata:positiveb:Zm:natHeqm:S m = (Pos.size_nat a + Pos.size_nat a)%natH:(S m <= S n)%natH0:(1 < S m)%nat(0 < Z.pos a -> Z.pos a < fibonacci (S m)) -> Zis_gcd (Z.pos a) b (Zgcdn n (b mod Z.pos a) (Z.pos a))n:nata:positiveb:Zm:natHeqm:S m = (Pos.size_nat a + Pos.size_nat a)%natH:(S m <= S n)%natH0:(1 < S m)%nat(0 < Z.pos a -> Z.pos a < fibonacci (S m)) -> Zis_gcd (Z.pos a) b (Zgcdn n (let (_, r) := Z.div_eucl b (Z.pos a) in r) (Z.pos a))n:nata:positiveb:Zm:natHeqm:S m = (Pos.size_nat a + Pos.size_nat a)%natH:(S m <= S n)%natH0:(1 < S m)%nat(let (q, r) := Z.div_eucl b (Z.pos a) in b = Z.pos a * q + r /\ 0 <= r < Z.pos a) -> (0 < Z.pos a -> Z.pos a < fibonacci (S m)) -> Zis_gcd (Z.pos a) b (Zgcdn n (let (_, r) := Z.div_eucl b (Z.pos a) in r) (Z.pos a))n:nata:positiveb:Zm:natHeqm:S m = (Pos.size_nat a + Pos.size_nat a)%natH:(S m <= S n)%natH0:(1 < S m)%natq, r:Zb = Z.pos a * q + r /\ 0 <= r < Z.pos a -> (0 < Z.pos a -> Z.pos a < fibonacci (S m)) -> Zis_gcd (Z.pos a) b (Zgcdn n r (Z.pos a))n:nata:positivem:natHeqm:S m = (Pos.size_nat a + Pos.size_nat a)%natH:(S m <= S n)%natH0:(1 < S m)%natq, r:ZH1:0 <= rH2:r < Z.pos aH3:0 < Z.pos a -> Z.pos a < fibonacci (S m)Zis_gcd (Z.pos a) (Z.pos a * q + r) (Zgcdn n r (Z.pos a))n:nata:positivem:natHeqm:S m = (Pos.size_nat a + Pos.size_nat a)%natH:(S m <= S n)%natH0:(1 < S m)%natq, r:ZH1:0 <= rH2:r < Z.pos aH3:0 < Z.pos a -> Z.pos a < fibonacci (S m)Zis_gcd r (Z.pos a) (Zgcdn n r (Z.pos a))n:nata:positivem:natHeqm:S m = (Pos.size_nat a + Pos.size_nat a)%natH:(S m <= S n)%natH0:(1 < S m)%natq, r:ZH1:0 < rH2:r < Z.pos aH3:0 < Z.pos a -> Z.pos a < fibonacci (S m)Zis_gcd r (Z.pos a) (Zgcdn n r (Z.pos a))n:nata:positivem:natHeqm:S m = (Pos.size_nat a + Pos.size_nat a)%natH:(S m <= S n)%natH0:(1 < S m)%natq, r:ZH1:0 = rH2:r < Z.pos aH3:0 < Z.pos a -> Z.pos a < fibonacci (S m)Zis_gcd r (Z.pos a) (Zgcdn n r (Z.pos a))n:nata:positivem:natHeqm:S m = (Pos.size_nat a + Pos.size_nat a)%natH:(S m <= S n)%natH0:(1 < S m)%natq, r:ZH1:0 < rH2:r < Z.pos aH3:0 < Z.pos a -> Z.pos a < fibonacci (S m)Zis_gcd r (Z.pos a) (Zgcdn n r (Z.pos a))apply Z.lt_le_trans with (fibonacci (S m)); [ omega | apply fibonacci_incr; auto].n:nata:positivem:natHeqm:S m = (Pos.size_nat a + Pos.size_nat a)%natH:(S m <= S n)%natH0:(1 < S m)%natq, r:ZH1:0 < rH2:r < Z.pos aH3:0 < Z.pos a -> Z.pos a < fibonacci (S m)r < fibonacci (S n)n:nata:positivem:natHeqm:S m = (Pos.size_nat a + Pos.size_nat a)%natH:(S m <= S n)%natH0:(1 < S m)%natq, r:ZH1:0 = rH2:r < Z.pos aH3:0 < Z.pos a -> Z.pos a < fibonacci (S m)Zis_gcd r (Z.pos a) (Zgcdn n r (Z.pos a))n:nata:positivem:natHeqm:S m = (Pos.size_nat a + Pos.size_nat a)%natH:(S m <= S n)%natH0:(1 < S m)%natq:ZH2:0 < Z.pos aH3:0 < Z.pos a -> Z.pos a < fibonacci (S m)Zis_gcd 0 (Z.pos a) (Zgcdn n 0 (Z.pos a))n:nata:positivem:natHeqm:S (S m) = (Pos.size_nat a + Pos.size_nat a)%natH:(S (S m) <= S n)%natH0:(1 < S (S m))%natq:ZH2:0 < Z.pos aH3:0 < Z.pos a -> Z.pos a < fibonacci (S (S m))Zis_gcd 0 (Z.pos a) (Zgcdn n 0 (Z.pos a))simpl; apply Zis_gcd_sym; apply Zis_gcd_0. Qed.n:nata:positivem:natHeqm:S (S m) = (Pos.size_nat a + Pos.size_nat a)%natH:(S (S m) <= S (S n))%natH0:(1 < S (S m))%natq:ZH2:0 < Z.pos aH3:0 < Z.pos a -> Z.pos a < fibonacci (S (S m))Zis_gcd 0 (Z.pos a) (Zgcdn (S n) 0 (Z.pos a))n:nata, b:Z(Zgcd_bound a <= n)%nat -> Zis_gcd a b (Zgcdn n a b)n:nata, b:Z(Zgcd_bound a <= n)%nat -> Zis_gcd a b (Zgcdn n a b)n:natb:Z(Zgcd_bound 0 <= n)%nat -> Zis_gcd 0 b (Zgcdn n 0 b)n:natp:positiveb:Z(Zgcd_bound (Z.pos p) <= n)%nat -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)n:natp:positiveb:Z(Zgcd_bound (Z.neg p) <= n)%nat -> Zis_gcd (Z.neg p) b (Zgcdn n (Z.neg p) b)n:natb:Z(Zgcd_bound 0 <= n)%nat -> Zis_gcd 0 b (Zgcdn n 0 b)n:natb:ZH:(1 <= n)%natZis_gcd 0 b (Zgcdn n 0 b)simpl; generalize (Zis_gcd_0_abs b); intuition.n:natb:ZH:(1 <= S n)%natZis_gcd 0 b (Zgcdn (S n) 0 b)apply Zgcdn_is_gcd_pos.n:natp:positiveb:Z(Zgcd_bound (Z.pos p) <= n)%nat -> Zis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)n:natp:positiveb:Z(Zgcd_bound (Z.neg p) <= n)%nat -> Zis_gcd (Z.neg p) b (Zgcdn n (Z.neg p) b)n:natp:positiveb:Z(Zgcd_bound (- Z.neg p) <= n)%nat -> Zis_gcd (Z.neg p) b (Zgcdn n (- Z.neg p) b)n:natp:positiveb:ZH:(Zgcd_bound (- Z.neg p) <= n)%natZis_gcd (Z.neg p) b (Zgcdn n (- Z.neg p) b)n:natp:positiveb:ZH:(Zgcd_bound (- Z.neg p) <= n)%natZis_gcd (- Z.neg p) b (Zgcdn n (- Z.neg p) b)now apply Zgcdn_is_gcd_pos. Qed.n:natp:positiveb:ZH:(Zgcd_bound (- Z.neg p) <= n)%natZis_gcd (Z.pos p) b (Zgcdn n (Z.pos p) b)forall a b : Z, Zis_gcd a b (Zgcd_alt a b)unfold Zgcd_alt; intros; apply Zgcdn_is_gcd; auto. Qed.forall a b : Z, Zis_gcd a b (Zgcd_alt a b)