Ltac shatterer := simpl; intuition;
  match goal with
    | [ w : _ |- _ ] => rewrite (shatter_word w); simpl
  end; f_equal; auto.

(* Specifications: *)
Theorem combine_split : forall sz1 sz2 (w : word (sz1 + sz2)), combine (split1 sz1 sz2 w) (split2 sz1 sz2 w) = w.
Theorem split1_combine : forall sz1 sz2 (w : word sz1) (z : word sz2), split1 sz1 sz2 (combine w z) = w.
Theorem split2_combine : forall sz1 sz2 (w : word sz1) (z : word sz2), split2 sz1 sz2 (combine w z) = z.
Theorem combine_assoc : forall n1 (w1 : word n1) n2 n3 (w2 : word n2) (w3 : word n3) Heq, combine (combine w1 w2) w3 = match Heq in _ = N return word N with | refl_equal => combine w1 (combine w2 w3) end.
Theorem split1_iter : forall n1 n2 n3 Heq w, split1 n1 n2 (split1 (n1 + n2) n3 w) = split1 n1 (n2 + n3) (match Heq in _ = N return word N with | refl_equal => w end).
Theorem split2_iter : forall n1 n2 n3 Heq w, split2 n2 n3 (split2 n1 (n2 + n3) w) = split2 (n1 + n2) n3 (match Heq in _ = N return word N with | refl_equal => w end).
Theorem split1_split2 : forall n1 n2 n3 Heq w, split1 n2 n3 (split2 n1 (n2 + n3) w) = split2 n1 n2 (split1 (n1 + n2) n3 (match Heq in _ = N return word N with | refl_equal => w end)).
Theorem split2_split1 : forall n1 n2 n3 Heq w, split2 n1 n2 (split1 (n1+n2) n3 w) = split1 n2 n3 (split2 n1 (n2+n3) (match Heq in _ = N return word N with | refl_equal => w end)).
Theorem combine_0_n : forall sz2 (w: word 0) (v: word sz2), combine w v = v.
Lemma WS_eq_rect : forall b n (w: word n) n' H H', eq_rect _ word (@WS b n w) _ H = @WS b n' (eq_rect _ word w _ H').
Theorem combine_eq_rect2 : forall sz n n' (H: n = n') H' (a: word sz) (b: word n), combine a b = eq_rect _ word (combine a (eq_rect _ word b _ H)) _ H'.
Theorem combine_n_0 : forall sz1 (w : word sz1) (v : word 0), combine w v = eq_rect _ word w _ (plus_n_O sz1).
Lemma whd_eq_rect : forall n w Heq, whd (eq_rect (S n) word w (S (n + 0)) Heq) = whd w.
Lemma wtl_eq_rect : forall n w Heq Heq', wtl (eq_rect (S n) word w (S (n + 0)) Heq) = eq_rect n word (wtl w) (n + 0) Heq'.
Lemma whd_eq_rect_mul : forall n w Heq, whd (eq_rect (S n) word w (S (n * 1)) Heq) = whd w.
Lemma wtl_eq_rect_mul : forall n w b Heq Heq', wtl (eq_rect (S n) word (WS b w) (S (n * 1)) Heq) = eq_rect _ word w _ Heq'.
Theorem split1_0 : forall n w Heq, split1 n 0 (eq_rect _ word w _ Heq) = w.
Theorem split2_0 : forall n w Heq, split2 0 n (eq_rect _ word w _ Heq) = w.
Theorem combine_end : forall n1 n2 n3 Heq w, combine (split1 n2 n3 (split2 n1 (n2 + n3) w)) (split2 (n1 + n2) n3 (match Heq in _ = N return word N with | refl_equal => w end)) = split2 n1 (n2 + n3) w.
Theorem eq_rect_combine : forall n1 n2 n2' (w1 : word n1) (w2 : word n2') Heq, eq_rect (n1 + n2') (fun n => word n) (combine w1 w2) (n1 + n2) Heq = combine w1 (eq_rect n2' (fun n => word n) w2 n2 (plus_reg_l _ _ _ Heq)).
Lemma eq_rect_combine_assoc' : forall a b c H wa wb wc, eq_rect (a + (b + c)) word (combine wa (combine wb wc)) _ H = combine (combine wa wb) wc.
Lemma eq_rect_split2_helper : forall a b c, a = b -> c + a = c + b.
Theorem eq_rect_split2 : forall n1 n2 n2' (w : word (n1 + n2')) Heq, eq_rect n2' (fun n => word n) (split2 n1 n2' w) n2 Heq = split2 n1 n2 (eq_rect (n1+n2') (fun n => word n) w (n1+n2) (eq_rect_split2_helper _ Heq)).
Theorem eq_rect_split2_eq2 : forall n1 n2 n2' (w : word (n1 + n2)) Heq Heq2, eq_rect n2 (fun n => word n) (split2 n1 n2 w) n2' Heq = split2 n1 n2' (eq_rect (n1+n2) (fun n => word n) w (n1+n2') Heq2).
Theorem eq_rect_split2_eq1 : forall n1 n1' n2 (w: word (n1 + n2)) Heq, split2 n1 n2 w = split2 n1' n2 (eq_rect (n1 + n2) (fun y : nat => word y) w (n1' + n2) Heq).
Theorem combine_split_eq_rect2 : forall n1 n2 n2' (w : word (n1 + n2)) Heq, combine (split1 n1 n2 w) (eq_rect n2 (fun n => word n) (split2 n1 n2 w) n2' Heq) = eq_rect (n1 + n2) (fun n => word n) w (n1 + n2') (eq_rect_split2_helper _ Heq).
Lemma eq_rect_split1_helper : forall a b c, a = b -> a + c = b + c.
Lemma eq_rect_split1_eq2_helper : forall a b c, a = b -> c + a = c + b.
Theorem eq_rect_split1 : forall n1 n1' n2 (w : word (n1' + n2)) Heq, eq_rect n1' (fun n => word n) (split1 n1' n2 w) n1 Heq = split1 n1 n2 (eq_rect (n1'+n2) (fun n => word n) w (n1+n2) (eq_rect_split1_helper _ Heq)).
Theorem eq_rect_split1_eq1 : forall n1 n1' n2 (w : word (n1 + n2)) Heq Heq1, eq_rect n1 (fun n => word n) (split1 n1 n2 w) n1' Heq = split1 n1' n2 (eq_rect (n1+n2) (fun n => word n) w (n1'+n2) Heq1).
Lemma split1_eq_rect_eq1_helper : forall a b c, b = a -> a + c = b + c.
Theorem split1_eq_rect_eq1 : forall a a' b H w, split1 a b w = eq_rect _ word (split1 a' b (eq_rect _ word w _ (split1_eq_rect_eq1_helper b H))) _ H.
Theorem eq_rect_split1_eq2 : forall n1 n2 n2' (w: word (n1 + n2)) Heq, split1 n1 n2 w = split1 n1 n2' (eq_rect (n1 + n2) (fun y : nat => word y) w (n1 + n2') Heq).