(**
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 using . intros x y Hxy. apply Zplus_le_reg_r with (-x - y)%Z. ring_simplify. easy. Qed.
Proof. intros. red. intros. subst x. omega. Qed.
Proof using . 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 using . 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 using . intros e1 e2 He. apply Znot_gt_le. intros H. apply Zlt_not_le with (1 := He). apply Zpower_le. clear -H. omega. Qed.
Proof. Admitted.
Proof using . intros [|n|n]. try easy. try easy. simpl. rewrite Zpower_pos_nat. rewrite Zpos_eq_Z_of_nat_o_nat_of_P. induction (nat_of_P n). easy. rewrite inj_S. change (Zpower_nat r (S n0)) with (r * Zpower_nat r n0)%Z. unfold Z.succ. apply Z.lt_le_trans with (r * (Z_of_nat n0 + 1))%Z. clear. apply Zlt_0_minus_lt. replace (r * (Z_of_nat n0 + 1) - (Z_of_nat n0 + 1))%Z with ((r - 1) * (Z_of_nat n0 + 1))%Z by ring. apply Zmult_lt_0_compat. cut (2 <= r)%Z. omega. apply Zle_bool_imp_le. apply r. apply (Zle_lt_succ 0). apply Zle_0_nat. apply Zmult_le_compat_l. apply Zlt_le_succ. easy. apply Z.le_trans with 2%Z. easy. apply Zle_bool_imp_le. apply r. try easy. Qed.
End Zpower. Section Div_Mod.
Proof. Admitted.
Proof using . 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 using . intros a b. rewrite (Z.quot_rem' a b) at 2. ring. Qed.
Proof. Admitted.
Proof using . 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. Admitted.
Proof using . intros n a b Ha Hb. destruct (Zle_lt_or_eq _ _ Ha) as [Ha'|Ha']. destruct (Zle_lt_or_eq _ _ Hb) as [Hb'|Hb']. rewrite (Zmod_eq n (a * b)). rewrite (Zmult_comm a b) at 2. rewrite Zmult_assoc. unfold Zminus. rewrite Zopp_mult_distr_l. rewrite Z_div_plus. idtac. rewrite <- Zdiv_Zdiv. idtac. apply sym_eq. apply Zmod_eq. apply Z.lt_gt. easy. easy . easy . apply Z.lt_gt. easy . apply Zmult_gt_0_compat. apply Z.lt_gt. easy. apply Z.lt_gt. easy. rewrite <- Hb'. rewrite Zmult_0_r. rewrite 2!Zmod_0_r. apply Zdiv_0_l. rewrite <- Ha'. now(rewrite 2!Zdiv_0_r ). Qed.
Proof. Admitted.
Proof using . 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 using . 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 using . 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 using . 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. destruct u. try easy. simpl. destruct v. try discriminate. easy. intuition. simpl. destruct v. try discriminate. zify. omega. easy. Qed.
Proof using . intros [|u|u] v Hp Hn. easy. apply Zmult_le_0_compat. easy. apply Hp. easy. replace (Zneg u * v)%Z with (Zpos u * (-v))%Z. apply Zmult_le_0_compat. easy. apply Hn. easy. rewrite <- Zopp_mult_distr_r. apply Zopp_mult_distr_l. Qed.
Proof. Admitted.
Proof using . 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 using . 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. intros. rewrite H. case Zeq_bool_spec. intros. eauto. intros. eauto. Qed.
Proof using . intros x y. apply -> Zeq_is_eq_bool. Qed.
Proof. intros. case Zeq_bool_spec. intros. elim H. easy. intros. eauto. Qed.
Proof using . 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 using . 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. intros. case Zle_bool_spec. intros. eauto. omega. Qed.
Proof using . intros x y. apply (proj1 (Zle_is_le_bool x y)). Qed.
Proof. intros. case Zle_bool_spec. intros. omega. intros. eauto. Qed.
Proof using . 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 using . 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. case Zlt_bool_spec. intros. eauto. intros. omega. Qed.
Proof using . intros x y. apply (proj1 (Zlt_is_lt_bool x y)). Qed.
Proof. intros. case Zlt_bool_spec. omega. intros. eauto. Qed.
Proof using . 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. intros. unfold negb. case Zlt_bool_spec. intros. case Zle_bool_spec. omega. easy. intros. case Zle_bool_spec. easy. omega. Qed.
Proof using . 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. intros. unfold negb. case Zlt_bool_spec. intros. case Zle_bool_spec. omega. easy. intros. case Zle_bool_spec. easy. omega. Qed.
Proof using . 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 using . 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 using . intros [|] y. apply sym_eq, Z.opp_involutive. easy. Qed.
Proof. induction b. intros. destruct m. reflexivity. simpl. eauto. simpl. eauto. intros. simpl. congruence. Qed.
Proof using . intros [|] m. apply Zabs_Zopp. apply refl_equal. Qed.
Proof. destruct m. reflexivity. simpl. eauto. simpl. eauto. Qed.
Proof using . intros m. apply sym_eq. case Zlt_bool_spec. intros Hm. apply Zabs_non_eq. apply Zlt_le_weak. easy. intros Hm. apply Z.abs_eq. easy. Qed.
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 using . 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 using . 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 using . 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 using . 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.
Proof. induction p. simpl. intros. eauto. intros. apply IHp. Qed.
Proof using . induction p. easy. simpl. intros x. apply IHp. Qed.
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.