unfold r'0. elim d_Si_eq; intro H. left. rewrite ltw_true. unfold r0. rewrite r_Si_eq_lit. rewrite H. trivial. unfold d0.
rewrite H. fold M. apply Zmod_lt_z_m. omega. elim H; intro H0. left. rewrite ltw_false. simpl. unfold r0. rewrite r_Si_eq_lit.
rewrite <- Zmod_minus_distr_l. fold M. rewrite H0. apply f_equal2 with (f := Zmod). ring. trivial. auto with a. fold M.
unfold d0. rewrite H0. cut (0 <= ((h mod M * 2 ^ w + l) / 2 ^ p * 2 ^ p) mod M). omega. apply Zmod_le_0_z. omega. elim H0;
intro H1. right. rewrite ltw_true. unfold r0. rewrite r_Si_eq_lit. rewrite H1. trivial. unfold d0. rewrite H1. fold M.
apply Zmod_lt_z_m. omega. right. rewrite ltw_false. simpl. unfold r0. rewrite r_Si_eq_lit. rewrite <- Zmod_minus_distr_l. fold M.
rewrite H1. apply f_equal2 with (f := Zmod). ring. trivial. auto with a. fold M. unfold d0. rewrite H1.
cut (0 <= (((h mod M + M) * 2 ^ w + l) / 2 ^ p * 2 ^ p) mod M). omega. apply Zmod_le_0_z. omega. Qed.

(* Specifications: *)
Lemma r'0_eq_2 :
_Z r'0 = (h mod M * 2 ^ w + l) / 2 ^ p * 2 ^ p mod M + l mod 2 ^ p mod M \/
_Z r'0 = ((h mod M + M) * 2 ^ w + l) / 2 ^ p * 2 ^ p mod M + l mod 2 ^ p mod M.