(* Copyright 2001, 2009 Luc Rutten  This file is part of ModRed.  ModRed 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.  ModRed 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 GNU Lesser General Public License for more details.  You should have received a copy of the GNU Lesser General Public License along with ModRed.  If not, see <http://www.gnu.org/licenses/>. *)
(* Fast reduction of integers in Z_(2 ^ (log_sup M + w))) by moduli M such that 1 <= M <= 2 ^ (w - 1) where w denotes a processor's word size. *)
(* Coq 8.2 *)
Open Scope Z_scope.
Section parm_sec.
Variable M_in_Z_ : Z_ (2 ^ w).
Variable ptM' : Z_ w * Z_ w * Z_ (2 ^ w).
Variables v_in_Z_ u_in_Z_ : Z_ (2 ^ w).
Let p_in_Z_w := fst (fst ptM').
Let t_in_Z_w := snd (fst ptM').
Let M'_in_Z_ := snd ptM'.
Let M := _Z M_in_Z_.
Let p := _Z p_in_Z_w.
Let t := _Z t_in_Z_w.
Let M' := _Z M'_in_Z_.
Let v := _Z v_in_Z_.
Let u := _Z u_in_Z_.
Hypothesis le_1_M : 1 <= M.
Hypothesis le_M_max : M <= 2 ^ (w - 1).
Hypothesis p_M : p = Zlog_sup M.
Hypothesis t_M : t = w - p \/ M = 1.
Hypothesis M'_M : M' = 2 ^ (p + w) / M mod 2 ^ w.
Hypothesis v_M : v < 2 ^ p.
Let x := v * 2 ^ w + u.

(* Specifications: *)
Lemma le_0_p : 0 <= p.
unfold p. apply le_0__Z. Qed.
Lemma le_0_l : 0 <= u.
unfold u. apply le_0__Z. Qed.
Lemma lt_l_2w : u < 2 ^ w.
unfold u. apply lt_z__Z. Qed.
Lemma le_0_v : 0 <= v.
unfold v. apply le_0__Z. Qed.
Lemma lt_v_2w : v < 2 ^ w.
unfold v. apply lt_z__Z. Qed.
Lemma le02w : 0 <= 2 ^ w.
apply Zlt_le_weak. exact lt02w. Qed.