Local Lemma wmultZ_helper: forall a b k1 k2 p,
((a - k1 * p) * (b - k2 * p) = a * b - (k1 * b + k2 * a - k1 * k2 * p) * p)%Z.

(* Specifications: *)
Lemma ZToWord_mult: forall sz a b, ZToWord sz (a * b) = ZToWord sz a ^* ZToWord sz b.
Lemma wmult_Z:  forall sz (a b : word sz),
a ^* b = ZToWord sz (wordToZ a * wordToZ b).
Lemma wordToZ_wplus_bound:
forall sz (w1 w2: word (S sz)),
(- Z.of_nat (pow2 sz) <= wordToZ w1 + wordToZ w2 < Z.of_nat (pow2 sz))%Z ->
(wordToZ w1 + wordToZ w2 = wordToZ (w1 ^+ w2))%Z.
Lemma wordToZ_wplus_bound':
forall sz (w1 w2: word sz),
sz <> 0 ->
(- Z.of_nat (pow2 (pred sz)) <= wordToZ w1 + wordToZ w2 < Z.of_nat (pow2 (pred sz)))%Z ->
(wordToZ w1 + wordToZ w2 = wordToZ (w1 ^+ w2))%Z.
Lemma wordToZ_size':
forall sz (w: word (S sz)),
(- Z.of_nat (pow2 sz) <= wordToZ w < Z.of_nat (pow2 sz))%Z.
Lemma wordToZ_size:
forall sz (w: word (S sz)),
(Z.abs (wordToZ w) <= Z.of_nat (pow2 sz))%Z.
Lemma wordToZ_size'': forall (sz : nat),
(0 < sz)%nat ->
forall  w : word sz,
(- 2 ^ (Z.of_nat sz - 1) <= wordToZ w < 2 ^ (Z.of_nat sz - 1))%Z.
Lemma wneg_wzero:
forall sz (w: word sz), wneg w = wzero sz -> w = wzero sz.
Lemma wmsb_false_pos:
forall sz (w: word sz),
wmsb w false = false <-> (wordToZ w >= 0)%Z.
Lemma wmsb_true_neg:
forall sz (w: word sz),
wmsb w false = true <-> (wordToZ w < 0)%Z.
Lemma wordToZ_distr_diff_wmsb:
forall sz (w1 w2: word sz),
wmsb w1 false = negb (wmsb w2 false) ->
wordToZ (w1 ^+ w2) = (wordToZ w1 + wordToZ w2)%Z.
Lemma sext_wplus_wordToZ_distr:
forall sz (w1 w2: word sz) n,
n <> 0 -> wordToZ (sext w1 n ^+ sext w2 n) =
(wordToZ (sext w1 n) + wordToZ (sext w2 n))%Z.
Lemma sext_wplus_wordToZ_distr_existT: (* Note: not axiom free *)
forall sz (w1 w2: word sz) ssz (sw1 sw2: word ssz) n,
existT word _ w1 = existT word _ (sext sw1 n) ->
existT word _ w2 = existT word _ (sext sw2 n) ->
n <> 0 -> wordToZ (w1 ^+ w2) = (wordToZ w1 + wordToZ w2)%Z.
Lemma split1_existT: (* Note: not axiom free *)
forall n sz1 (w1: word (n + sz1)) sz2 (w2: word (n + sz2)),
existT word _ w1 = existT word _ w2 ->
split1 n _ w1 = split1 n _ w2.
Lemma word_combinable:
forall sz1 sz2 (w: word (sz1 + sz2)),
exists w1 w2, w = combine w1 w2.
Lemma split1_combine_existT: (* Note: not axiom free *)
forall sz n (w: word (n + sz)) sl (wl: word (n + sl)) su (wu: word su),
existT word _ w = existT word _ (combine wl wu) ->
split1 n _ w = split1 n _ wl.
Lemma extz_pow2_wordToZ:
forall sz (w: word sz) n,
wordToZ (extz w n) = (wordToZ w * Z.of_nat (pow2 n))%Z.
Lemma extz_wneg:
forall sz (w: word sz) n,
extz (wneg w) n = wneg (extz w n).
Lemma wneg_wordToZ:
forall sz (w: word (S sz)),
w <> wpow2 sz ->
wordToZ (wneg w) = (- wordToZ w)%Z.
Lemma wneg_wordToZ':
forall sz (w: word (S sz)) z,
w <> wpow2 sz ->
(z + wordToZ (wneg w))%Z = (z - wordToZ w)%Z.
Lemma wneg_wplus_distr:
forall sz (w1 w2: word sz),
wneg (w1 ^+ w2) = wneg w1 ^+ wneg w2.
Lemma wminus_wneg:
forall sz (w1 w2: word sz),
wneg (w1 ^- w2) = w2 ^- w1.
Lemma wminus_wordToZ:
forall sz (w1 w2: word (S sz)),
w2 ^- w1 <> wpow2 sz ->
wordToZ (w1 ^- w2) = (- wordToZ (w2 ^- w1))%Z.
Lemma wminus_wordToZ':
forall sz (w1 w2: word (sz + 1)),
existT word _ (w2 ^- w1) <> existT word _ (wpow2 sz) ->
wordToZ (w1 ^- w2) = (- wordToZ (w2 ^- w1))%Z.
Lemma wminus_wminusZ: forall (sz : nat) (w1 w2 : word sz), w1 ^- w2 = wminusZ w1 w2.
Local Lemma wminusZ_helper: forall a b k1 k2 p,
((a - k1 * p) - (b - k2 * p) = a - b - (k1 - k2) * p)%Z.
Lemma wminus_Z: forall sz (a b : word sz),
a ^- b = ZToWord sz (wordToZ a - wordToZ b).
Lemma ZToWord_opp_wneg{sz: nat}: forall (x: Z),
ZToWord sz (- x) = ^~ (ZToWord sz x).
Lemma Zeqb_true_ZToWord: forall {sz: nat} (x y: Z),
(x =? y)%Z = true ->
ZToWord sz x = ZToWord sz y.
Lemma word_ring_theory_Z: forall (sz: nat),
ring_theory (ZToWord sz 0) (ZToWord sz 1)
(@wplus sz) (@wmult sz) (@wminus sz) (@wneg sz) eq.
Lemma word_ring_morph_Z: forall (sz: nat),
ring_morph (ZToWord sz 0) (ZToWord sz 1) (@wplus sz) (@wmult sz) (@wminus sz) (@wneg sz)
eq 0%Z 1%Z Z.add Z.mul Z.sub Z.opp Z.eqb
(ZToWord sz).
Lemma extz_zero:
forall sz n, extz (natToWord sz 0) n = wzero _.
Lemma sext_eq_rect:
forall sz (w: word sz) n nsz Hsz1,
exists Hsz2,
eq_rect (sz + n) word (sext w n) (nsz + n) Hsz1 =
sext (eq_rect sz word w nsz Hsz2) n.
Lemma wmsb_sext:
forall sz (w: word sz) n,
wmsb (sext w n) false = wmsb w false.
Lemma wmsb_wlshift_sext: (* Note: not axiom free *)
forall sz (w: word sz) n,
wmsb (sext w n) false = wmsb (wlshift (sext w n) n) false.
Lemma wordToZ_wordToNat_pos:
forall sz (w: word sz),
wmsb w false = false ->
Z.of_nat (wordToNat w) = wordToZ w.
Corollary wmsb_Zabs_pos:
forall sz (w: word sz),
wmsb w false = false -> Z.abs (wordToZ w) = wordToZ w.
Corollary wmsb_Zabs_neg:
forall sz (w: word sz),
wmsb w false = true -> (Z.abs (wordToZ w) = - wordToZ w)%Z.
Lemma wordToN_combine:
forall sz1 (w1: word sz1) sz2 (w2: word sz2),
wordToN (combine w1 w2) = (wordToN w1 + Npow2 sz1 * wordToN w2)%N.
Lemma word_exists_bound:
forall sz z,
(- Z.of_nat (pow2 sz) <= z < Z.of_nat (pow2 sz))%Z ->
exists w: word (S sz), wordToZ w = z.
Lemma sext_size:
forall sz n (w: word (sz + n)),
sz <> 0 ->
(- Z.of_nat (pow2 (sz - 1)) <= wordToZ w < Z.of_nat (pow2 (sz - 1)))%Z ->
exists sw, w = sext sw n.
Lemma wordToZ_combine_WO:
forall sz (w: word sz),
wordToZ (combine w WO) = wordToZ w.
Lemma combine_WO:
forall sz (w: word sz),
combine w WO = eq_rect _ word w _ (Nat.add_comm 0 sz).
Lemma zext_zero:
forall sz (w: word sz),
zext w 0 = eq_rect _ word w _ (Nat.add_comm 0 sz).
Lemma wmsb_false_wordToNat_eq:
forall sz (w: word (S sz)),
wmsb w false = false ->
wordToNat w = wordToNat (split1 sz _ (eq_rect _ word w _ (Nat.add_comm 1 sz))).
Lemma wordToZ_bound_weakened:
forall z n, (Z.abs z < n)%Z -> (- n <= z < n)%Z.
Lemma zext_size:
forall sz n (w: word (sz + n)),
(- Z.of_nat (pow2 sz) <= wordToZ w < Z.of_nat (pow2 sz))%Z ->
wmsb w false = false ->
exists sw, w = zext sw n.
Lemma zext_size_1: (* Note: not axiom free *)
forall sz (w: word (sz + 1)),
wmsb w false = false ->
exists sw, w = zext sw 1.
Lemma sext_wplus_exist:
forall sz (w1 w2: word sz) n,
exists w: word (S sz),
existT word _ (sext w1 (S n) ^+ sext w2 (S n)) =
existT word _ (sext w n).