apply f_equal2 with (f := Zplus). replace (2 ^ (p + w) / M / 2 ^ w) with 1. ring.
rewrite Zdivdivdiv. rewrite Zmult_comm. rewrite <- Zdivdivdiv. rewrite Zpower_exp; auto with a.
rewrite Z_div_mult. symmetry. exact div_M_1. apply Zlt_gt. auto with a. apply Zle_ge. auto with a.
apply Zle_ge. auto with a. auto with a. omega. omega. auto with a. trivial. apply Zdivmod_split.
auto with a. Qed.
(* <KEEP TOGETHER - multired_equations *)
Let r'_i := ltw d_Si M_in_Z_ r_Si (minusw r_Si M_in_Z_).
Let s_i := ursh x_i_in_Z_ p_in_Z_w.
Let s'_i := multp2 s_i p_in_Z_w.
Let s''_i := ltw r'_i c_in_Z_ s_i (minusw s_i M''_in_Z_).
Let h_i := multp2 r'_i t_in_Z_w.
Let h'_i := plusw h_i s''_i.
Let q_i := uhwm h'_i M'_in_Z_.
Let q'_i := plusw q_i h'_i.
Let y_i := multw q'_i M_in_Z_.
Definition d_i := minusw s'_i y_i.
Definition r_i := minusw x_i_in_Z_ y_i.
(* KEEP TOGETHER> *)
Let d0 := d_Si. (* notation *)
Let r0 := r_Si. (* notation *)
(* <KEEP TOGETHER - multired_final *)
Let r'0 := ltw d0 M_in_Z_ r0 (minusw r0 M_in_Z_). (* notation *)
Let r''0 := ltw r'0 c_in_Z_ r'0 (minusw r'0 M_in_Z_). (* only needed after the loop *)
Definition r'''0 := ltw r''0 M_in_Z_ r''0 (minusw r''0 M_in_Z_). (* only needed after the loop *)
(* KEEP TOGETHER> *)
Let h_i' := multp2 r''0 t_in_Z_w.
Let h'_i' := plusw h_i' s_i.
Definition g' := r'''0. (* only needed after the loop *)
Let x := h * 2 ^ w + l.
Let x' := r''0 * 2 ^ w + x_i.

(* Specifications: *)
Lemma x_i_eq : x_i = x' mod 2 ^ w.
unfold x'. rewrite Zmod_km_plus. symmetry. unfold x_i. apply modred. apply le_0__Z. apply lt_z__Z. exact lt02w. Qed.
Lemma lt_0_2ppw : 0 < 2 ^ (p + w).
apply lt_0_Zpow. fold (0 + 0). apply Zplus_le_compat; auto with a. Qed.
Lemma lt_0_2pp : 0 < 2 ^ p.
apply lt_0_Zpow. auto with a. Qed.