intro.
rewrite (shatter_word a).
replace (wtl a) with WO by auto.
destruct (whd a).
right; apply eq_refl.
left; apply eq_refl.
Defined.

(* Specifications: *)
Lemma neq0_wneq0: forall sz (n : word sz),
wordToNat n <> 0  <-> n <> $0.
Lemma gt0_wneq0: forall sz (n : word sz),
(wordToNat n > 0)%nat <-> n <> $0.
Lemma weq_minus1_wlt: forall sz (a b : word sz),
(a <> $0 -> a ^- $1 = b -> a > b)%word.
Lemma wordnat_minus1_eq : forall sz n (w : word sz),
(n > 0)%nat
-> n = wordToNat w
-> n - 1 = wordToNat (w ^- $1).
Theorem wlshift_0 : forall sz (w : word sz), @wlshift sz w 0 = w.
Theorem wrshift_0 : forall sz (w : word sz), @wrshift sz w 0 = w.
Theorem wlshift_gt : forall sz n (w : word sz), (n > sz)%nat ->
wlshift w n = wzero sz.
Theorem wrshift_gt : forall sz n (w : word sz), (n > sz)%nat ->
wrshift w n = wzero sz.
Theorem wlshift_bitwp : forall sz (w1 w2 : word sz) f n,
wlshift (bitwp f w1 w2) n = split1 sz n (
eq_rec _ word (combine (wzero n) (bitwp f w1 w2)) _ (eq_sym (Nat.add_comm sz n))).
Theorem wrshift_bitwp : forall sz (w1 w2 : word sz) f n,
wrshift (bitwp f w1 w2) n = split2 n sz (
eq_rect _ word (combine (bitwp f w1 w2) (wzero n)) _ (eq_sym (Nat.add_comm n sz))).
Theorem wnot_wlshift : forall sz (w : word sz) n,
wnot (wlshift w n) = split1 sz n (eq_rect _ word (combine (wones n) (wnot w)) _ (eq_sym (Nat.add_comm sz n))).
Theorem wnot_wrshift : forall sz (w : word sz) n,
wnot (wrshift w n) = split2 n sz (eq_rect _ word (combine (wnot w) (wones n)) _ (eq_sym (Nat.add_comm n sz))).
Lemma wlshift_alt: forall sz n (a: word sz),
wlshift' a n = wlshift a n.
Theorem div2_pow2_twice: forall n,
Nat.div2 (pow2 n + (pow2 n + 0)) = pow2 n.
Theorem zero_or_wordToNat_S: forall sz (n : word sz),
n = $0 \/
exists nn, wordToNat n = S nn /\ wordToNat (n ^- $1) = nn.
Theorem wbit_or_same : forall sz sz' (n : word sz'), (wordToNat n < sz)%nat
-> (wbit sz n) ^| (wbit sz n) <> wzero sz.
Theorem wbit_or_other : forall sz sz' (n1 n2 : word sz'), (wordToNat n1 < sz)%nat
-> (wordToNat n2 < sz)%nat
-> (n1 <> n2)
-> (wbit sz n1) ^& (wbit sz n2) = wzero sz.
Theorem wbit_and_not: forall sz sz' (n : word sz'), (wordToNat n < sz)%nat
-> (wbit sz n) ^& wnot (wbit sz n) = wzero sz.
Theorem wbit_and_not_other: forall sz sz' (n1 n2 : word sz'), (wordToNat n1 < sz)%nat
-> (wordToNat n2 < sz)%nat
-> n1 <> n2
-> (wbit sz n1) ^& wnot (wbit sz n2) = wbit sz n1.
Lemma wordToNat_wzero:
forall sz, wordToNat (wzero sz) = 0.
Lemma wordToN_wzero:
forall sz, wordToN (wzero sz) = 0%N.
Lemma combine_zero:
forall n m, combine (natToWord n 0) (natToWord m 0) = natToWord _ 0.
Lemma combine_one:
forall n m, combine (natToWord (S n) 1) (natToWord m 0) = natToWord _ 1.
Lemma wmsb_wzero':
forall sz, wmsb (wzero' sz) false = false.
Lemma wmsb_wones:
forall sz, wmsb (wones (S sz)) false = true.
Lemma wmsb_0: forall sz (m: word (S sz)) default,
(# m < pow2 sz)%nat ->
@wmsb (S sz) m default = false.
Lemma wmsb_1: forall sz (m: word (S sz)) default,
pow2 sz <= # m < 2 * pow2 sz ->
@wmsb (S sz) m default = true.
Lemma wmsb_0_natToWord: forall sz n default,
(2 * n < pow2 (S sz))%nat ->
@wmsb (S sz) (natToWord (S sz) n) default = false.
Lemma wmsb_1_natToWord: forall sz n default,
pow2 sz <= n < 2 * pow2 sz ->
@wmsb (S sz) (natToWord (S sz) n) default = true.
Lemma wordToN_wzero':
forall sz, wordToN (wzero' sz) = 0%N.
Lemma wordToZ_wzero':
forall sz, wordToZ (wzero' sz) = 0%Z.
Lemma wordToZ_wzero:
forall sz, wordToZ (wzero sz) = 0%Z.
Lemma wmsb_existT: (* Note: not axiom free *)
forall sz1 (w1: word sz1) sz2 (w2: word sz2),
existT word _ w1 = existT word _ w2 ->
forall b, wmsb w1 b = wmsb w2 b.
Lemma destruct_word_S: forall sz (w: word (S sz)),
exists v b, w = WS b v.
Lemma induct_word_S: forall (P : forall n : nat, word (S n) -> Prop),
(forall b, P 0 (WS b WO)) ->
(forall b b0 n (w : word n), P n (WS b0 w) -> P (S n) (WS b (WS b0 w))) ->
forall (n : nat) (w : word (S n)), P n w.
Lemma wmsb_ws:
forall sz (w: word (S sz)) b a, wmsb (WS b w) a = wmsb w a.
Lemma wmsb_extz:
forall sz (w: word sz) n,
wmsb (extz w n) false = wmsb w false.
Lemma wmsb_default:
forall sz (w: word sz) b1 b2,
sz <> 0 -> wmsb w b1 = wmsb w b2.
Lemma wmsb_nat_cast:
forall sz1 (w: word sz1) sz2 (Hsz: sz1 = sz2) b,
wmsb w b = wmsb (nat_cast word Hsz w) b.
Lemma wmsb_eq_rect:
forall sz1 (w: word sz1) sz2 (Hsz: sz1 = sz2) b,
wmsb w b = wmsb (eq_rect _ word w _ Hsz) b.