Library Shuffle.Shuffle




Require Import Bool.
Require Import Words.
Require Import Alternate.
Require Import Opposite.
Require Import Paired.


Inductive shuffle : wordwordwordProp :=
  | shuffle_empty : shuffle empty empty empty
  | shuffle_bit_left :
       u v w : word,
      shuffle u v w b : bool, shuffle (bit b u) v (bit b w)
  | shuffle_bit_right :
       u v w : word,
      shuffle u v w b : bool, shuffle u (bit b v) (bit b w).


Lemma Shuffling :
  u v w : word,
 shuffle u v w
  b : bool,
 alt b u
 odd u
 (odd v (alt (negb b) vpaired w) (alt b vpaired_bet b w)
  even v
  (alt b vpaired_odd_l b w)
  (alt (negb b) vpaired_odd_r (negb b) w))
 even u
 (odd v
  (alt (negb b) vpaired_odd_r b w) (alt b vpaired_odd_l b w)
  even v (alt b vpaired_rot b w) (alt (negb b) vpaired w)).
Proof.
simple induction 1; intros.
right.
split; auto.
right.
split; auto.
split; intro.
apply paired_rot_empty.
apply paired_empty.
elim (alt_eq b0 b u0); trivial.
elim (H1 (negb b0)); intros.
right.
elim H3; intros.
split; auto.
elim H5; intros.
elim H6; intros.
left.
elim H8; intros.
split; auto.
split; intro.
apply paired_odd_r_from_bet; auto.
apply paired_odd_l_intro; apply H9; rewrite (negb_elim b0); auto.
elim H6; intros.
elim H8; intros.
right.
split; auto.
split; intro.
apply paired_rot_bit; rewrite (negb_intro b0); apply H10;
 rewrite (negb_elim b0); auto.
apply paired_odd_l_elim; auto.
left.
elim H3; intros.
split; auto.
elim H5; intros.
left.
elim H6; intros.
elim H8; intros.
split; auto.
split; intro.
apply paired_odd_l_elim; auto.
apply paired_bet_bit; apply H9; rewrite (negb_elim b0); auto.
right.
elim H6; intros.
elim H8; intros.
split; auto.
split; intro.
apply paired_odd_l_intro; apply H10; rewrite (negb_elim b0); auto.
pattern b0 at 2 in |- *; rewrite (negb_intro b0).
apply paired_odd_r_from_rot; auto.
apply alt_neg_intro with b; trivial.
elim (H1 b0); intros.
left.
elim H3; intros.
split; auto.
elim H5; intros.
right.
elim H6; intros.
elim H8; intros.
split; auto.
split; intro.
elim (alt_eq b0 b v0); trivial.
apply paired_odd_l_intro; apply H9; apply alt_neg_intro with b; auto.
elim (alt_eq (negb b0) b v0); trivial.
apply paired_odd_r_from_bet; rewrite (negb_elim b0); apply H10;
 apply alt_neg_elim with b; auto.
left.
elim H6; intros.
elim H8; intros.
split; auto.
split; intro.
apply paired_odd_l_elim.
elim (alt_eq (negb b0) b v0); trivial.
rewrite (negb_elim b0).
apply H9.
rewrite (negb_intro b0).
apply alt_neg_intro with b; auto.
elim (alt_eq b0 b v0); trivial.
apply paired_bet_bit; apply H10; apply alt_neg_intro with b; auto.
right.
elim H3; intros.
split; auto.
elim H5; intros.
right.
elim H6; intros.
elim H8; intros.
split; auto.
split; intro.
elim (alt_eq b0 b v0); trivial.
apply paired_rot_bit; apply H9; apply alt_neg_intro with b; auto.
elim (alt_eq (negb b0) b v0); trivial.
apply paired_odd_l_elim.
rewrite (negb_elim b0); apply H10; rewrite (negb_intro b0);
 apply alt_neg_intro with b; auto.
left.
elim H6; intros.
elim H8; intros.
split; auto.
split; intro.
elim (alt_eq (negb b0) b v0); trivial.
apply paired_odd_r_from_rot; apply H9; rewrite (negb_intro b0);
 apply alt_neg_intro with b; auto.
elim (alt_eq b0 b v0); trivial.
apply paired_odd_l_intro; apply H10; apply alt_neg_intro with b; auto.
trivial.
Qed.