(**
This file is part of the Flocq formalization of floating-point
arithmetic in Coq: http://flocq.gforge.inria.fr/
Copyright (C) 2011-2018 Sylvie Boldo
#<br />#
Copyright (C) 2011-2018 Guillaume Melquiond
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
COPYING file for more details.
*)
Require Import ZArith Omega. Require Import Zquot. Section Zmissing.
Proof. intros. omega. Qed.
Proof. intros x y Hxy. apply Zplus_le_reg_r with (-x - y)%Z. ring_simplify. easy. Qed.
Proof. intros x y H Hn. apply Z.lt_irrefl with x. rewrite Hn at 1. easy. Qed.
End Zmissing. Section Proof_Irrelevance. Scheme eq_dep_elim := Induction for eq Sort Type. Definition eqbool_dep P (h1 : P true) b :=
match b return P b -> Prop with
| true => fun (h2 : P true) => h1 = h2
| false => fun (h2 : P false) => False
end.
Proof. Admitted.
Proof. assert (forall (h : true = true), refl_equal true = h). { apply (eq_dep_elim bool true (eqbool_dep _ _) (refl_equal _)). } { intros b. case b. { intros h1 h2. rewrite <- (H h1). easy. } { intros h. discriminate h. } } Qed.
Proof. intros n a [|b|b] Ha Hb. { rewrite 2!Zmod_0_r. easy. } { rewrite (Zmod_eq n (a * Zpos b)). { rewrite Zmult_assoc. unfold Zminus. rewrite Zopp_mult_distr_l. apply Z_mod_plus. easy. } { apply Zmult_gt_0_compat. { apply Z.lt_gt. easy. } { easy. } } } { elim Hb. easy. } Qed.
Proof. Admitted.
Proof. intros a b. rewrite (Z.quot_rem' a b) at 2. ring. Qed.
Proof. Admitted.
Proof. intros n a b. assert (Z.rem n (a * b) = n + - (Z.quot n (a * b) * a) * b)%Z. { rewrite <- Zopp_mult_distr_l. rewrite <- Zmult_assoc. apply ZOmod_eq. } { rewrite H. apply Z_rem_plus. rewrite <- H. apply Zrem_sgn2. } Qed.
Proof. intros n a b. destruct (Z.eq_dec a 0) as [Za|Za]. { rewrite Za. now(rewrite 2!Zquot_0_r ). } { assert (Z.rem n (a * b) = n + - (Z.quot (Z.quot n a) b * b) * a)%Z. { rewrite (ZOmod_eq n (a * b)) at 1. rewrite Zquot_Zquot. ring. } { rewrite H. rewrite Z_quot_plus with (2 := Za). { apply sym_eq. apply ZOmod_eq. } { rewrite <- H. apply Zrem_sgn2. } } } Qed.
Proof. Admitted.
Proof. intros a b Ha. destruct (Zle_or_lt 0 a) as [H|H]. { apply Z.quot_small. split. { exact H. } { rewrite Z.abs_eq in Ha. { easy. } { easy. } } } { apply Z.opp_inj. rewrite <- Zquot_opp_l. rewrite Z.opp_0. apply Z.quot_small. generalize (Zabs_non_eq a). omega. } Qed.
Proof. Admitted.
Proof. intros a b Ha. destruct (Zle_or_lt 0 a) as [H|H]. { apply Z.rem_small. split. { exact H. } { rewrite Z.abs_eq in Ha. { easy. } { easy. } } } { apply Z.opp_inj. rewrite <- Zrem_opp_l. apply Z.rem_small. generalize (Zabs_non_eq a). omega. } Qed.
Proof. Admitted.
Proof. intros a b c Hab. destruct (Z.eq_dec c 0) as [Zc|Zc]. now rewrite Zc, 4!Zquot_0_r. apply Zmult_reg_r with (1 := Zc). rewrite 2!Zmult_plus_distr_l. assert (forall d, Z.quot d c * c = d - Z.rem d c)%Z. intros d. rewrite ZOmod_eq. ring. rewrite 4!H. rewrite <- Zplus_rem with (1 := Hab). ring. Qed.
Proof. intros u v Hv. apply Zsame_sign_imp. { intros Hu. apply Z_quot_pos with (2 := Hv). apply Zlt_le_weak. easy. } { intros Hu. rewrite <- Zquot_opp_l. apply Z_quot_pos with (2 := Hv). apply Zlt_le_weak. easy. } Qed.
End Same_sign. (** Boolean comparisons *)
Section Zeq_bool. Inductive Zeq_bool_prop (x y : Z) : bool -> Prop :=
| Zeq_bool_true_ : x = y -> Zeq_bool_prop x y true
| Zeq_bool_false_ : x <> y -> Zeq_bool_prop x y false.
Proof. Admitted.
Proof. intros x y. generalize (Zeq_is_eq_bool x y). case (Zeq_bool x y). { intros (H1, H2). constructor. apply H2. easy. } { intros (H1, H2). constructor. intros H. specialize (H1 H). discriminate H1. } Qed.
Proof. Admitted.
Proof. intros x y. apply -> Zeq_is_eq_bool. Qed.
Proof. Admitted.
Proof. intros x y. generalize (proj2 (Zeq_is_eq_bool x y)). case Zeq_bool. { intros He Hn. elim Hn. apply He. easy. } { intros _ _. easy. } Qed.
End Zeq_bool. Section Zle_bool. Inductive Zle_bool_prop (x y : Z) : bool -> Prop :=
| Zle_bool_true_ : (x <= y)%Z -> Zle_bool_prop x y true
| Zle_bool_false_ : (y < x)%Z -> Zle_bool_prop x y false.
Proof. Admitted.
Proof. intros x y. generalize (Zle_is_le_bool x y). case Zle_bool. { intros (H1, H2). constructor. apply H2. easy. } { intros (H1, H2). constructor. destruct (Zle_or_lt x y) as [H|H]. { specialize (H1 H). easy. } { exact H. } } Qed.
Proof. Admitted.
Proof. intros x y. apply (proj1 (Zle_is_le_bool x y)). Qed.
Proof. Admitted.
Proof. intros x y Hxy. generalize (Zle_cases x y). case Zle_bool. { intros H. elim (Z.lt_irrefl x). apply Z.le_lt_trans with y. { easy. } { easy. } } { intros H. apply refl_equal. } Qed.
End Zle_bool. Section Zlt_bool. Inductive Zlt_bool_prop (x y : Z) : bool -> Prop :=
| Zlt_bool_true_ : (x < y)%Z -> Zlt_bool_prop x y true
| Zlt_bool_false_ : (y <= x)%Z -> Zlt_bool_prop x y false.
Proof. Admitted.
Proof. intros x y. generalize (Zlt_is_lt_bool x y). case Zlt_bool. { intros (H1, H2). constructor. apply H2. easy. } { intros (H1, H2). constructor. destruct (Zle_or_lt y x) as [H|H]. { exact H. } { specialize (H1 H). easy. } } Qed.
Proof. intros. unfold Z.ltb. rewrite H. eauto. Qed.
Proof. intros x y. apply (proj1 (Zlt_is_lt_bool x y)). Qed.
Proof. Admitted.
Proof. intros x y Hxy. generalize (Zlt_cases x y). case Zlt_bool. { intros H. elim (Z.lt_irrefl x). apply Z.lt_le_trans with y. { easy. } { easy. } } { intros H. apply refl_equal. } Qed.
Proof. Admitted.
Proof. intros x y. case Zle_bool_spec. { intros H. rewrite Zlt_bool_false. { easy. } { easy. } } { intros H. rewrite Zlt_bool_true. { easy. } { easy. } } Qed.
Proof. Admitted.
Proof. intros x y. case Zlt_bool_spec. { intros H. rewrite Zle_bool_false. { easy. } { easy. } } { intros H. rewrite Zle_bool_true. { easy. } { easy. } } Qed.
End Zlt_bool. Section Zcompare. Inductive Zcompare_prop (x y : Z) : comparison -> Prop :=
| Zcompare_Lt_ : (x < y)%Z -> Zcompare_prop x y Lt
| Zcompare_Eq_ : x = y -> Zcompare_prop x y Eq
| Zcompare_Gt_ : (y < x)%Z -> Zcompare_prop x y Gt.
Proof. Admitted.
Proof. intros x y. destruct (Z_dec x y) as [[H|H]|H]. { generalize (Zlt_compare _ _ H). case (Z.compare x y). { try easy. } { try easy. constructor. easy. } { try easy. } } { generalize (Zgt_compare _ _ H). case (Z.compare x y). { try easy. } { try easy. } { try easy. constructor. apply Z.gt_lt. easy. } } { generalize (proj2 (Zcompare_Eq_iff_eq _ _) H). case (Z.compare x y). { try easy. constructor. easy. } { try easy. } { try easy. } } Qed.
Proof. intros. easy. Qed.
Proof. easy. Qed.
Proof. Admitted.
Proof. intros x y. apply <- Zcompare_Eq_iff_eq. Qed.
Proof. Admitted.
Proof. intros x y. apply Z.lt_gt. Qed.
End Zcompare. Section cond_Zopp. Definition cond_Zopp (b : bool) m := if b then Z.opp m else m.
End cond_Zopp. Section fast_pow_pos. Fixpoint Zfast_pow_pos (v : Z) (e : positive) : Z :=
match e with
| xH => v
| xO e' => Z.square (Zfast_pow_pos v e')
| xI e' => Zmult v (Z.square (Zfast_pow_pos v e'))
end.
Proof. Admitted.
Proof. intros v e. rewrite <- (Zmult_1_r (Zfast_pow_pos v e)). unfold Z.pow_pos. generalize 1%Z. revert v. induction e. { intros v f. simpl. rewrite <- 2!IHe. rewrite Z.square_spec. ring. } { intros v f. simpl. rewrite <- 2!IHe. rewrite Z.square_spec. apply eq_sym, Zmult_assoc. } { intros v f. simpl. apply eq_refl. } Qed.
End fast_pow_pos. Section faster_div.
Proof. Admitted.
Proof. intros a b. unfold Z.div. unfold Zmod. case Z.div_eucl. easy. Qed.
Fixpoint Zpos_div_eucl_aux1 (a b : positive) {struct b} :=
match b with
| xO b' =>
match a with
| xO a' => let (q, r) := Zpos_div_eucl_aux1 a' b' in (q, 2 * r)%Z
| xI a' => let (q, r) := Zpos_div_eucl_aux1 a' b' in (q, 2 * r + 1)%Z
| xH => (Z0, Zpos a)
end
| xH => (Zpos a, Z0)
| xI _ => Z.pos_div_eucl a (Zpos b)
end.
Proof. Admitted.
Proof. intros a b. revert a. induction b ; intros a. - easy. - change (Z.pos_div_eucl a (Zpos b~0)) with (Z.div_eucl (Zpos a) (Zpos b~0)). rewrite Zdiv_eucl_unique. change (Zpos b~0) with (2 * Zpos b)%Z. rewrite Z.rem_mul_r by easy. rewrite <- Zdiv_Zdiv by easy. destruct a as [a|a|]. + change (Zpos_div_eucl_aux1 a~1 b~0) with (let (q, r) := Zpos_div_eucl_aux1 a b in (q, 2 * r + 1)%Z). rewrite IHb. clear IHb. change (Z.pos_div_eucl a (Zpos b)) with (Z.div_eucl (Zpos a) (Zpos b)). rewrite Zdiv_eucl_unique. change (Zpos a~1) with (1 + 2 * Zpos a)%Z. rewrite (Zmult_comm 2 (Zpos a)). rewrite Z_div_plus_full by easy. apply f_equal. rewrite Z_mod_plus_full. apply Zplus_comm. + change (Zpos_div_eucl_aux1 a~0 b~0) with (let (q, r) := Zpos_div_eucl_aux1 a b in (q, 2 * r)%Z). rewrite IHb. clear IHb. change (Z.pos_div_eucl a (Zpos b)) with (Z.div_eucl (Zpos a) (Zpos b)). rewrite Zdiv_eucl_unique. change (Zpos a~0) with (2 * Zpos a)%Z. rewrite (Zmult_comm 2 (Zpos a)). rewrite Z_div_mult_full by easy. apply f_equal. now rewrite Z_mod_mult. + easy. - change (Z.pos_div_eucl a 1) with (Z.div_eucl (Zpos a) 1). rewrite Zdiv_eucl_unique. now rewrite Zdiv_1_r, Zmod_1_r. Qed.
Definition Zpos_div_eucl_aux (a b : positive) :=
match Pos.compare a b with
| Lt => (Z0, Zpos a)
| Eq => (1%Z, Z0)
| Gt => Zpos_div_eucl_aux1 a b
end.
Proof. Admitted.
Proof. intros a b. unfold Zpos_div_eucl_aux. change (Z.pos_div_eucl a (Zpos b)) with (Z.div_eucl (Zpos a) (Zpos b)). rewrite Zdiv_eucl_unique. case Pos.compare_spec ; intros H. now rewrite H, Z_div_same, Z_mod_same. now rewrite Zdiv_small, Zmod_small by (split ; easy). rewrite Zpos_div_eucl_aux1_correct. change (Z.pos_div_eucl a (Zpos b)) with (Z.div_eucl (Zpos a) (Zpos b)). apply Zdiv_eucl_unique. Qed.
Definition Zfast_div_eucl (a b : Z) :=
match a with
| Z0 => (0, 0)%Z
| Zpos a' =>
match b with
| Z0 => (0, 0)%Z
| Zpos b' => Zpos_div_eucl_aux a' b'
| Zneg b' =>
let (q, r) := Zpos_div_eucl_aux a' b' in
match r with
| Z0 => (-q, 0)%Z
| Zpos _ => (-(q + 1), (b + r))%Z
| Zneg _ => (-(q + 1), (b + r))%Z
end
end
| Zneg a' =>
match b with
| Z0 => (0, 0)%Z
| Zpos b' =>
let (q, r) := Zpos_div_eucl_aux a' b' in
match r with
| Z0 => (-q, 0)%Z
| Zpos _ => (-(q + 1), (b - r))%Z
| Zneg _ => (-(q + 1), (b - r))%Z
end
| Zneg b' => let (q, r) := Zpos_div_eucl_aux a' b' in (q, (-r)%Z)
end
end.
End faster_div. Section Iter. Context {A : Type}. Variable (f : A -> A). Fixpoint iter_nat (n : nat) (x : A) {struct n} : A :=
match n with
| S n' => iter_nat n' (f x)
| O => x
end.
Fixpoint iter_pos (n : positive) (x : A) {struct n} : A :=
match n with
| xI n' => iter_pos n' (iter_pos n' (f x))
| xO n' => iter_pos n' (iter_pos n' x)
| xH => f x
end.