(** We can use this fact to prove a part of the gcd correctness *)

(* Specifications: *)
Lemma gcd_divide_l a b : (gcd a b | a).
Lemma gcd_divide_r a b : (gcd a b | b).
(** We now prove directly that gcd is the greatest amongst common divisors *)
Lemma gcd_greatest a b c : (c|a) -> (c|b) -> (c|gcd a b).
Lemma gcd_nonneg a b : 0 <= gcd a b.
Lemma testbit_odd_0 a : testbit (2*a+1) 0 = true.
Lemma testbit_succ_r_div2 a n : 0<=n ->
testbit a (succ n) = testbit (div2 a) n.
Lemma testbit_odd_succ a n : 0<=n ->
testbit (2*a+1) (succ n) = testbit a n.
Lemma testbit_even_succ a n : 0<=n ->
testbit (2*a) (succ n) = testbit a n.
Lemma testbit_neg_r a n : n<0 -> testbit a n = false.
(** Correctness proofs for shifts *)
Lemma shiftr_succ_r a n :
shiftr a (succ n) = div2 (shiftr a n).
Lemma shiftl_succ_r a n :
shiftl a (succ n) = double (shiftl a n).
Lemma shiftr_spec a n m : 0<=m ->
testbit (shiftr a n) m = testbit a (m+n).
Lemma shiftl_spec_high a n m : 0<=m -> n<=m ->
testbit (shiftl a n) m = testbit a (m-n).
Lemma shiftl_spec_low a n m : m<n ->
testbit (shiftl a n) m = false.
Lemma div2_spec a : div2 a = shiftr a 1.
(** Semantics of bitwise operations *)
Lemma pos_lxor_spec p p' n :
testbit (Pos.lxor p p') n = xorb (Pos.testbit p n) (Pos.testbit p' n).
Lemma lxor_spec a a' n :
testbit (lxor a a') n = xorb (testbit a n) (testbit a' n).
Lemma pos_lor_spec p p' n :
Pos.testbit (Pos.lor p p') n = (Pos.testbit p n) || (Pos.testbit p' n).
Lemma lor_spec a a' n :
testbit (lor a a') n = (testbit a n) || (testbit a' n).
Lemma pos_land_spec p p' n :
testbit (Pos.land p p') n = (Pos.testbit p n) && (Pos.testbit p' n).
Lemma land_spec a a' n :
testbit (land a a') n = (testbit a n) && (testbit a' n).
Lemma pos_ldiff_spec p p' n :
testbit (Pos.ldiff p p') n = (Pos.testbit p n) && negb (Pos.testbit p' n).
Lemma ldiff_spec a a' n :
testbit (ldiff a a') n = (testbit a n) && negb (testbit a' n).
Lemma div_0_r a : a / 0 = 0.
Lemma gt_lt n m : n > m -> m < n.
Lemma lt_gt n m : n < m -> m > n.
Lemma ge_le_iff n m : n >= m <-> m <= n.
Lemma ge_le n m : n >= m -> m <= n.
Lemma le_ge n m : n <= m -> m >= n.
(** Auxiliary results about right shift on positive numbers, used in BinInt *)
Lemma pos_pred_shiftl_low : forall p n m, m<n ->
testbit (Pos.pred_N (Pos.shiftl p n)) m = true.
Lemma pos_pred_shiftl_high : forall p n m, n<=m ->
testbit (Pos.pred_N (Pos.shiftl p n)) m =
testbit (shiftl (Pos.pred_N p) n) m.
Lemma pred_div2_up p : Pos.pred_N (Pos.div2_up p) = div2 (Pos.pred_N p).
(** ** Properties of [iter] *)
Lemma iter_swap_gen A B (f:A -> B) (g:A -> A) (h:B -> B) :
(forall a, f (g a) = h (f a)) -> forall n a,
f (iter n g a) = iter n h (f a).
Theorem iter_swap :
forall n (A:Type) (f:A -> A) (x:A),
iter n f (f x) = f (iter n f x).
Theorem iter_succ :
forall n (A:Type) (f:A -> A) (x:A),
iter (succ n) f x = f (iter n f x).
Theorem iter_succ_r :
forall n (A:Type) (f:A -> A) (x:A),
iter (succ n) f x = iter n f (f x).
Theorem iter_add :
forall p q (A:Type) (f:A -> A) (x:A),
iter (p+q) f x = iter p f (iter q f x).
Theorem iter_ind (A:Type) (f:A -> A) (a:A) (P:N -> A -> Prop) :
P 0 a ->
(forall n a', P n a' -> P (succ n) (f a')) ->
forall n, P n (iter n f a).
Theorem iter_invariant :
forall (n:N) (A:Type) (f:A -> A) (Inv:A -> Prop),
(forall x:A, Inv x -> Inv (f x)) ->
forall x:A, Inv x -> Inv (iter n f x).
Lemma gcd_divide_l : forall a b, (gcd a b | a).
Lemma gcd_divide_r : forall a b, (gcd a b | b).
(** We now prove directly that gcd is the greatest amongst common divisors *)
Lemma gcdn_greatest : forall n a b, (size_nat a + size_nat b <= n)%nat ->
forall p, (p|a) -> (p|b) -> (p|gcdn n a b).
Lemma gcd_greatest : forall a b p, (p|a) -> (p|b) -> (p|gcd a b).
(** As a consequence, the rests after division by gcd are relatively prime *)
Lemma ggcd_greatest : forall a b,
let (aa,bb) := snd (ggcd a b) in
forall p, (p|aa) -> (p|bb) -> p=1.