aboutsummaryrefslogtreecommitdiff
path: root/src/Assembly/WordizeUtil.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/Assembly/WordizeUtil.v')
-rw-r--r--src/Assembly/WordizeUtil.v996
1 files changed, 0 insertions, 996 deletions
diff --git a/src/Assembly/WordizeUtil.v b/src/Assembly/WordizeUtil.v
deleted file mode 100644
index b5f246fb1..000000000
--- a/src/Assembly/WordizeUtil.v
+++ /dev/null
@@ -1,996 +0,0 @@
-Require Import Bedrock.Word Bedrock.Nomega.
-Require Import NArith PArith Ndigits Nnat NPow NPeano Ndec.
-Require Import List Omega NArith Nnat BoolEq Compare_dec.
-Require Import SetoidTactics.
-Require Import ProofIrrelevance FunctionalExtensionality.
-Require Import QhasmUtil QhasmEvalCommon.
-
-(* Custom replace-at wrapper for 8.4pl3 compatibility *)
-Definition ltac_nat_from_int (x:BinInt.Z) : nat :=
- match x with
- | BinInt.Z0 => 0%nat
- | BinInt.Zpos p => BinPos.nat_of_P p
- | BinInt.Zneg p => 0%nat
- end.
-
-Ltac nat_from_number N :=
- match type of N with
- | nat => constr:(N)
- | BinInt.Z => let N' := constr:(ltac_nat_from_int N) in eval compute in N'
- end.
-
-Tactic Notation "replace'" constr(x) "with" constr(y) "at" constr(n) "by" tactic(tac) :=
- let tmp := fresh in (
- match nat_from_number n with
- | 1 => set (tmp := x) at 1
- | 2 => set (tmp := x) at 2
- | 3 => set (tmp := x) at 3
- | 4 => set (tmp := x) at 4
- | 5 => set (tmp := x) at 5
- end;
- replace tmp with y by (unfold tmp; tac);
- clear tmp).
-
-(* Word-shattering tactic *)
-Ltac shatter a :=
- let H := fresh in
- pose proof (shatter_word a) as H; simpl in H;
- try rewrite H in *; clear H.
-
-Section Misc.
- Local Open Scope nword_scope.
-
- Lemma word_replace: forall n m, n = m -> word n = word m.
- Proof. intros; subst; intuition. Qed.
-
- Lemma of_nat_lt: forall x b, (x < b)%nat <-> (N.of_nat x < N.of_nat b)%N.
- Proof.
- intros x b; split; intro H.
-
- - unfold N.lt; rewrite N2Nat.inj_compare.
- repeat rewrite Nat2N.id.
- apply nat_compare_lt in H.
- intuition.
-
- - unfold N.lt in H; rewrite N2Nat.inj_compare in H.
- repeat rewrite Nat2N.id in H.
- apply nat_compare_lt in H.
- intuition.
- Qed.
-
- Lemma to_nat_lt: forall x b, (x < b)%N <-> (N.to_nat x < N.to_nat b)%nat.
- Proof.
- intros x b; split; intro H.
-
- - unfold N.lt in H; rewrite N2Nat.inj_compare in H.
- apply nat_compare_lt in H.
- intuition.
-
- - unfold N.lt; rewrite N2Nat.inj_compare.
- apply nat_compare_lt.
- intuition.
- Qed.
-
- Lemma to_nat_le: forall x b, (x <= b)%N <-> (N.to_nat x <= N.to_nat b)%nat.
- Proof.
- intros x b; split; intro H.
-
- - unfold N.le in H; rewrite N2Nat.inj_compare in H.
- apply nat_compare_le in H.
- intuition.
-
- - unfold N.le; rewrite N2Nat.inj_compare.
- apply nat_compare_le.
- intuition.
- Qed.
-
- Lemma word_size_bound : forall {n} (w: word n), (&w < Npow2 n)%N.
- Proof.
- intros; pose proof (wordToNat_bound w) as B;
- rewrite of_nat_lt in B;
- rewrite <- Npow2_nat in B;
- rewrite N2Nat.id in B;
- rewrite <- wordToN_nat in B;
- assumption.
- Qed.
-
- Lemma ge_to_le: forall (x y: N), (x >= y)%N <-> (y <= x)%N.
- Proof.
- intros x y; split; intro H;
- unfold N.ge, N.le in *;
- intro H0; contradict H;
- rewrite N.compare_antisym;
- rewrite H0; simpl; intuition.
- Qed.
-
- Lemma N_ge_0: forall x: N, (0 <= x)%N.
- Proof.
- intro x0; unfold N.le.
- pose proof (N.compare_0_r x0) as H.
- rewrite N.compare_antisym in H.
- induction x0; simpl in *;
- intro V; inversion V.
- Qed.
-
- Lemma Pos_ge_1: forall p, (1 <= N.pos p)%N.
- Proof.
- intro.
- replace (N.pos p) with (N.succ (N.pos p - 1)%N) by (
- induction p; simpl;
- try rewrite Pos.succ_pred_double;
- try reflexivity).
- unfold N.succ.
- apply N.le_pred_le_succ.
- replace (N.pred 1%N) with 0%N by (simpl; intuition).
- apply N_ge_0.
- Qed.
-
- Lemma testbit_wones_false: forall n k,
- (k >= N.of_nat n)%N
- -> false = N.testbit (& wones n) k.
- Proof.
- induction n; try abstract (simpl; intuition).
- induction k; try abstract (
- intro H; destruct H; simpl; intuition).
-
- intro H.
- assert (N.pos p - 1 >= N.of_nat n)%N as Z.
- apply ge_to_le;
- apply ge_to_le in H;
- apply (N.add_le_mono_r _ _ 1%N);
- replace (N.of_nat n + 1)%N with (N.of_nat (S n));
- replace (N.pos p - 1 + 1)%N with (N.pos p);
- try rewrite N.sub_add;
- try assumption;
- try nomega;
- apply Pos_ge_1.
-
- rewrite (IHn (N.pos p - 1)%N Z) at 1.
-
- assert (N.pos p = N.succ (N.pos p - 1)) as Hp by (
- rewrite <- N.pred_sub;
- rewrite N.succ_pred;
- try abstract intuition;
- intro H0; inversion H0).
-
- symmetry.
- rewrite Hp at 1.
- rewrite Hp in H.
-
- revert H; clear IHn Hp Z;
- generalize (N.pos p - 1)%N as x;
- intros x H.
-
- replace (& wones (S n)) with (2 * & (wones n) + N.b2n true)%N
- by (simpl; rewrite ?N.succ_double_spec; simpl; nomega).
-
- rewrite N.testbit_succ_r; reflexivity.
- Qed.
-
- Lemma testbit_wones_true: forall n k,
- (k < N.of_nat n)%N
- -> true = N.testbit (& wones n) k.
- Proof.
- induction n; intros k H; try nomega.
- destruct (N.eq_dec k (N.of_nat n)).
-
- - clear IHn H; subst.
- induction n.
-
- + simpl; intuition.
-
- + replace (& (wones (S (S n))))
- with (2 * (& (wones (S n))) + N.b2n true)%N
- by (simpl; rewrite ?N.succ_double_spec; simpl; nomega).
- rewrite Nat2N.inj_succ.
- rewrite N.testbit_succ_r.
- assumption.
-
- - induction k.
-
- + replace (& (wones (S n))) with (2 * (& (wones n)) + N.b2n true)%N
- by (simpl; rewrite ?N.succ_double_spec; simpl; nomega).
- rewrite N.testbit_0_r.
- reflexivity.
-
- + assert (N.pos p < N.of_nat n)%N as IH by (
- rewrite Nat2N.inj_succ in H;
- nomega).
- apply N.lt_lt_pred in IH.
- apply IHn in IH.
- replace (N.pos p) with (N.succ (N.pred (N.pos p))) by (
- induction p; simpl;
- try rewrite Pos.succ_pred_double;
- intuition).
- replace (& (wones (S n))) with (2 * (& (wones n)) + N.b2n true)%N
- by (simpl; rewrite ?N.succ_double_spec; simpl; nomega).
- rewrite N.testbit_succ_r.
- assumption.
- Qed.
-
-
- Lemma plus_le: forall {n} (x y: word n),
- (& (x ^+ y) <= &x + &y)%N.
- Proof.
- intros.
- unfold wplus, wordBin.
- rewrite wordToN_nat.
- rewrite NToWord_nat.
- pose proof (wordToNat_natToWord n (N.to_nat (& x + & y))) as H.
- destruct H as [k H].
- destruct H as [Heq Hk].
- rewrite Heq.
- rewrite Nat2N.inj_sub.
- rewrite N2Nat.id.
- generalize (&x + &y)%N; intro a.
- generalize (N.of_nat (k * pow2 n))%N; intro b.
- clear Heq Hk; clear x y k; clear n.
- replace a with (a - 0)%N by nomega.
- replace' (a - 0)%N with a at 1 by nomega.
- apply N.sub_le_mono_l.
- apply N_ge_0.
- Qed.
-
- Lemma mult_le: forall {n} (x y: word n),
- (& (x ^* y) <= &x * &y)%N.
- Proof.
- intros.
- unfold wmult, wordBin.
- rewrite wordToN_nat.
- rewrite NToWord_nat.
- pose proof (wordToNat_natToWord n (N.to_nat (& x * & y))) as H.
- destruct H as [k H].
- destruct H as [Heq Hk].
- rewrite Heq.
- rewrite Nat2N.inj_sub.
- rewrite N2Nat.id.
- generalize (&x * &y)%N; intro a.
- generalize (N.of_nat (k * pow2 n))%N; intro b.
- clear Heq Hk; clear x y k; clear n.
- replace a with (a - 0)%N by nomega.
- replace' (a - 0)%N with a at 1 by nomega.
- apply N.sub_le_mono_l.
- apply N_ge_0.
- Qed.
-
- Lemma log2_conv: forall z, Z.log2 z = Z.of_N (N.log2 (Z.to_N z)).
- Proof.
- intro z; induction z as [| |p]; auto.
- induction p; auto.
- Qed.
-End Misc.
-
-Section Exp.
- Local Open Scope nword_scope.
-
- Lemma pow2_inv : forall n m, pow2 n = pow2 m -> n = m.
- Proof.
- induction n; intros; simpl in *;
- induction m; simpl in *; try omega.
- f_equal; apply IHn.
- omega.
- Qed.
-
- Lemma pow2_gt0 : forall n, (pow2 n > O)%nat.
- Proof. induction n; simpl; omega. Qed.
-
- Lemma pow2_N_bound: forall n j,
- (j < pow2 n)%nat -> (N.of_nat j < Npow2 n)%N.
- Proof.
- intros.
- rewrite <- Npow2_nat in H.
- unfold N.lt.
- rewrite N2Nat.inj_compare.
- rewrite Nat2N.id.
- apply nat_compare_lt in H.
- assumption.
- Qed.
-
- Lemma Npow2_gt0 : forall x, (0 < Npow2 x)%N.
- Proof.
- intros; induction x.
-
- - simpl; apply N.lt_1_r; intuition.
-
- - replace (Npow2 (S x)) with (2 * (Npow2 x))%N by intuition.
- apply (N.lt_0_mul 2 (Npow2 x)); left; split; apply N.neq_0_lt_0.
-
- + intuition; inversion H.
-
- + apply N.neq_0_lt_0 in IHx; intuition.
- Qed.
-
- Lemma Npow2_ge1 : forall x, (1 <= Npow2 x)%N.
- Proof.
- intro x.
- pose proof (Npow2_gt0 x) as Z.
- apply N.lt_pred_le; simpl.
- assumption.
- Qed.
-
- Lemma Npow2_split: forall a b,
- (Npow2 (a + b) = (Npow2 a) * (Npow2 b))%N.
- Proof.
- intros; revert a.
- induction b.
-
- - intros; simpl; replace (a + 0) with a; try nomega.
- rewrite N.mul_1_r; intuition.
-
- - intros.
- replace (a + S b) with (S a + b) by omega.
- rewrite (IHb (S a)); simpl; clear IHb.
- induction (Npow2 a), (Npow2 b); simpl; intuition.
- rewrite Pos.mul_xO_r; intuition.
- Qed.
-
- Lemma Npow2_N: forall n, Npow2 n = (2 ^ N.of_nat n)%N.
- Proof.
- induction n.
-
- - simpl; intuition.
-
- - rewrite Nat2N.inj_succ.
- rewrite N.pow_succ_r; try apply N_ge_0.
- rewrite <- IHn.
- simpl; intuition.
- Qed.
-
- Lemma Npow2_succ: forall n, (Npow2 (S n) = 2 * (Npow2 n))%N.
- Proof. intros; simpl; induction (Npow2 n); intuition. Qed.
-
- Lemma Npow2_ordered: forall n m, (n <= m)%nat -> (Npow2 n <= Npow2 m)%N.
- Proof.
- induction n; intros m H; try rewrite Npow2_succ.
-
- - simpl; apply Npow2_ge1.
-
- - induction m; try rewrite Npow2_succ.
-
- + inversion H.
-
- + assert (n <= m)%nat as H0 by omega.
- apply IHn in H0.
- apply N.mul_le_mono_l.
- assumption.
- Qed.
-End Exp.
-
-Section Conversions.
- Local Open Scope nword_scope.
-
- Lemma NToWord_wordToN: forall sz x, NToWord sz (wordToN x) = x.
- Proof.
- intros.
- rewrite NToWord_nat.
- rewrite wordToN_nat.
- rewrite Nat2N.id.
- rewrite natToWord_wordToNat.
- intuition.
- Qed.
-
- Lemma NToWord_equal: forall n (x y: word n),
- wordToN x = wordToN y -> x = y.
- Proof.
- intros.
- rewrite <- (NToWord_wordToN _ x).
- rewrite <- (NToWord_wordToN _ y).
- rewrite H; reflexivity.
- Qed.
-
- Lemma wordToN_NToWord: forall sz x, (x < Npow2 sz)%N -> wordToN (NToWord sz x) = x.
- Proof.
- intros.
- rewrite NToWord_nat.
- rewrite wordToN_nat.
- rewrite <- (N2Nat.id x).
- apply Nat2N.inj_iff.
- rewrite Nat2N.id.
- apply natToWord_inj with (sz:=sz);
- try rewrite natToWord_wordToNat;
- intuition.
-
- - apply wordToNat_bound.
- - rewrite <- Npow2_nat; apply to_nat_lt; assumption.
- Qed.
-
- Lemma Npow2_ignore: forall {n} (x: word n),
- x = NToWord _ (& x + Npow2 n).
- Proof.
- intros.
- rewrite <- (NToWord_wordToN n x) at 1.
- repeat rewrite NToWord_nat.
- rewrite N2Nat.inj_add.
- rewrite Npow2_nat.
- replace' (N.to_nat (&x))
- with ((N.to_nat (&x) + pow2 n) - 1 * pow2 n)
- at 1 by omega.
- rewrite drop_sub; [intuition|omega].
- Qed.
-End Conversions.
-
-Section SpecialFunctions.
- Local Open Scope nword_scope.
-
- Lemma convS_id: forall n x p, (@convS n n x p) = x.
- Proof.
- intros; unfold convS; vm_compute.
- replace (convS_subproof n n x p)
- with (eq_refl (word n)) by (apply proof_irrelevance).
- reflexivity.
- Qed.
-
- Lemma wordToN_convS: forall {n m} x p,
- wordToN (@convS n m x p) = wordToN x.
- Proof.
- intros.
- revert x.
- rewrite p.
- intro x.
- rewrite convS_id.
- reflexivity.
- Qed.
-
- Lemma wordToN_zext: forall {n m} (x: word n),
- wordToN (@zext n x m) = wordToN x.
- Proof.
- intros; induction x; simpl; intuition.
-
- - unfold zext, Word.combine.
- rewrite wordToN_nat.
- unfold wzero.
- rewrite (@wordToNat_natToWord_idempotent m 0); simpl; intuition.
- apply Npow2_gt0.
-
- - unfold zext in IHx; rewrite IHx; clear IHx;
- destruct b; intuition.
- Qed.
-
- Lemma wordToN_div2: forall {n} (x: word (S n)),
- N.div2 (&x) = & (wtl x).
- Proof.
- intros.
- pose proof (shatter_word x) as Hx; simpl in Hx; rewrite Hx; simpl.
- destruct (whd x).
- replace (match & wtl x with
- | 0%N => 0%N
- | N.pos q => N.pos (xO q)
- end)
- with (N.double (& (wtl x)))
- by (induction (& (wtl x)); simpl; intuition).
-
- - rewrite N.div2_succ_double.
- reflexivity.
-
- - induction (& (wtl x)); simpl; intuition.
- Qed.
-
- Fixpoint wbit {n} (x: word n) (k: nat): bool :=
- match n as n' return word n' -> bool with
- | O => fun _ => false
- | S m => fun x' =>
- match k with
- | O => (whd x')
- | S k' => wbit (wtl x') k'
- end
- end x.
-
- Lemma wbit_wtl: forall {n} (x: word (S n)) k,
- wbit x (S k) = wbit (wtl x) k.
- Proof.
- intros.
- pose proof (shatter_word x) as Hx;
- simpl in Hx; rewrite Hx; simpl.
- reflexivity.
- Qed.
-
- Lemma wordToN_testbit: forall {n} (x: word n) k,
- N.testbit (& x) k = wbit x (N.to_nat k).
- Proof.
- assert (forall x: N, match x with
- | 0%N => 0%N
- | N.pos q => N.pos (q~0)%positive
- end = N.double x) as kill_match by (
- induction x; simpl; intuition).
-
- induction n; intros.
-
- - shatter x; simpl; intuition.
-
- - revert IHn; rewrite <- (N2Nat.id k).
- generalize (N.to_nat k) as k'; intros; clear k.
- rewrite Nat2N.id in *.
-
- induction k'.
-
- + clear IHn; induction x; simpl; intuition.
- destruct (& x), b; simpl; intuition.
-
- + clear IHk'.
- shatter x; simpl.
-
- rewrite N.succ_double_spec; simpl.
-
- rewrite kill_match.
- replace (N.pos (Pos.of_succ_nat k'))
- with (N.succ (N.of_nat k'))
- by (rewrite <- Nat2N.inj_succ;
- simpl; intuition).
-
- rewrite N.double_spec.
- replace (N.succ (2 * & wtl x))
- with (2 * & wtl x + 1)%N
- by nomega.
-
- destruct (whd x);
- try rewrite N.testbit_odd_succ;
- try rewrite N.testbit_even_succ;
- try abstract (
- unfold N.le; simpl;
- induction (N.of_nat k'); intuition;
- try inversion H);
- rewrite IHn;
- rewrite Nat2N.id;
- reflexivity.
- Qed.
-
- Lemma wordToN_split1: forall {n m} x,
- & (@split1 n m x) = N.land (& x) (& (wones n)).
- Proof.
- intros.
-
- pose proof (Word.combine_split _ _ x) as C; revert C.
- generalize (split1 n m x) as a, (split2 n m x) as b.
- intros a b C; rewrite <- C; clear C x.
-
- apply N.bits_inj_iff; unfold N.eqf; intro x.
- rewrite N.land_spec.
- repeat rewrite wordToN_testbit.
- revert x a b.
-
- induction n, m; intros;
- shatter a; shatter b;
- induction (N.to_nat x) as [|n0];
- try rewrite <- (Nat2N.id n0);
- try rewrite andb_false_r;
- try rewrite andb_true_r;
- simpl; intuition.
- Qed.
-
- Lemma wordToN_split2: forall {n m} x,
- & (@split2 n m x) = N.shiftr (& x) (N.of_nat n).
- Proof.
- intros.
-
- pose proof (Word.combine_split _ _ x) as C; revert C.
- generalize (split1 n m x) as a, (split2 n m x) as b.
- intros a b C.
- rewrite <- C; clear C x.
-
- apply N.bits_inj_iff; unfold N.eqf; intro x;
- rewrite N.shiftr_spec;
- repeat rewrite wordToN_testbit;
- try apply N_ge_0.
-
- revert x a b.
- induction n, m; intros;
- shatter a;
- try apply N_ge_0.
-
- - simpl; intuition.
-
- - replace (x + N.of_nat 0)%N with x by nomega.
- simpl; intuition.
-
- - rewrite (IHn x (wtl a) b).
- rewrite <- (N2Nat.id x).
- repeat rewrite <- Nat2N.inj_add.
- repeat rewrite Nat2N.id; simpl.
- replace (N.to_nat x + S n) with (S (N.to_nat x + n)) by omega.
- reflexivity.
-
- - rewrite (IHn x (wtl a) b).
- rewrite <- (N2Nat.id x).
- repeat rewrite <- Nat2N.inj_add.
- repeat rewrite Nat2N.id; simpl.
- replace (N.to_nat x + S n) with (S (N.to_nat x + n)) by omega.
- reflexivity.
- Qed.
-
- Lemma wordToN_combine: forall {n m} a b,
- & (@Word.combine n a m b) = N.lxor (N.shiftl (& b) (N.of_nat n)) (& a).
- Proof.
- intros; symmetry.
-
- replace' a with (Word.split1 _ _ (Word.combine a b)) at 1
- by (apply Word.split1_combine).
-
- replace' b with (Word.split2 _ _ (Word.combine a b)) at 1
- by (apply Word.split2_combine).
-
- generalize (Word.combine a b); intro x; clear a b.
-
- rewrite wordToN_split1, wordToN_split2.
- generalize (&x); clear x; intro x.
- apply N.bits_inj_iff; unfold N.eqf; intro k.
-
- rewrite N.lxor_spec.
- destruct (Nge_dec k (N.of_nat n)).
-
- - rewrite N.shiftl_spec_high; try apply N_ge_0;
- try (apply ge_to_le; assumption).
- rewrite N.shiftr_spec; try apply N_ge_0.
- replace (k - N.of_nat n + N.of_nat n)%N with k by nomega.
- rewrite N.land_spec.
- induction (N.testbit x k);
- replace (N.testbit (& wones n) k) with false;
- simpl; intuition;
- try apply testbit_wones_false;
- try assumption.
-
- - rewrite N.shiftl_spec_low; try assumption; try apply N_ge_0.
- rewrite N.land_spec.
- induction (N.testbit x k);
- replace (N.testbit (& wones n) k) with true;
- simpl; intuition;
- try apply testbit_wones_true;
- try assumption.
- Qed.
-
- Lemma wordToN_wones: forall x, & (wones x) = N.ones (N.of_nat x).
- Proof.
- induction x.
-
- - simpl; intuition.
-
- - rewrite Nat2N.inj_succ.
- replace (& wones (S x)) with (2 * & (wones x) + N.b2n true)%N
- by (simpl; rewrite ?N.succ_double_spec; simpl; nomega).
- replace (N.ones (N.succ _))
- with (2 * N.ones (N.of_nat x) + N.b2n true)%N.
-
- + rewrite IHx; nomega.
-
- + replace (N.succ (N.of_nat x)) with (1 + (N.of_nat x))%N by (
- rewrite N.add_comm; nomega).
- rewrite N.ones_add.
- replace (N.ones 1) with 1%N by (
- unfold N.ones; simpl; intuition).
- simpl.
- reflexivity.
- Qed.
-
- Lemma wordToN_zero: forall w, wordToN (wzero w) = 0%N.
- Proof.
- intros.
- unfold wzero; rewrite wordToN_nat.
- rewrite wordToNat_natToWord_idempotent; simpl; intuition.
- apply Npow2_gt0.
- Qed.
-
- Lemma NToWord_zero: forall w, NToWord w 0%N = wzero w.
- Proof.
- intros.
- unfold wzero; rewrite NToWord_nat.
- f_equal.
- Qed.
-
- Ltac propagate_wordToN :=
- unfold extend, low, high, break;
- repeat match goal with
- | [|- context[@wordToN _ (@convS _ _ _ _)] ] =>
- rewrite wordToN_convS
- | [|- context[@wordToN _ (@split1 _ _ _)] ] =>
- rewrite wordToN_split1
- | [|- context[@wordToN _ (@split2 _ _ _)] ] =>
- rewrite wordToN_split2
- | [|- context[@wordToN _ (@combine _ _ _ _)] ] =>
- rewrite wordToN_combine
- | [|- context[@wordToN _ (@zext _ _ _)] ] =>
- rewrite wordToN_zext
- | [|- context[@wordToN _ (@wones _)] ] =>
- rewrite wordToN_wones
- end.
-
- Lemma break_spec: forall (m n: nat) (x: word n) low high,
- (low, high) = break m x
- -> &x = (&high * Npow2 m + &low)%N.
- Proof.
- intros m n x low high H.
- unfold break in H.
- destruct (le_dec m n).
-
- - inversion H; subst; clear H.
- propagate_wordToN.
- rewrite N.land_ones.
- rewrite N.shiftr_div_pow2.
- replace (n - (n - m)) with m by omega.
- rewrite N.mul_comm.
- rewrite Npow2_N.
- rewrite <- (N.div_mod' (& x) (2 ^ (N.of_nat m))%N).
- reflexivity.
-
- - inversion H; subst; clear H.
- propagate_wordToN; simpl; nomega.
- Qed.
-
- Lemma extend_bound: forall k n (p: (k <= n)%nat) (w: word k),
- (& (extend p w) < Npow2 k)%N.
- Proof.
- intros.
- propagate_wordToN.
- apply word_size_bound.
- Qed.
-
- Lemma mask_spec : forall (n: nat) (x: word n) m,
- & (mask (N.to_nat m) x) = (N.land (& x) (N.ones m)).
- Proof.
- intros; unfold mask.
- destruct (le_dec (N.to_nat m) n).
-
- - propagate_wordToN.
- rewrite N2Nat.id.
- reflexivity.
-
- - rewrite N.land_ones.
- rewrite N.mod_small; try reflexivity.
- rewrite <- (N2Nat.id m).
- rewrite <- Npow2_N.
- apply (N.lt_le_trans _ (Npow2 n) _); try apply word_size_bound.
- apply Npow2_ordered.
- omega.
- Qed.
-
- Lemma mask_bound : forall (n: nat) (x: word n) m,
- (& (mask m x) < Npow2 m)%N.
- Proof.
- intros; unfold mask.
- destruct (le_dec m n).
-
- - apply extend_bound.
-
- - apply (N.lt_le_trans _ (Npow2 n) _); try apply word_size_bound.
- apply Npow2_ordered.
- omega.
- Qed.
-
-End SpecialFunctions.
-
-Section TopLevel.
- Local Open Scope nword_scope.
-
- Coercion ind : bool >-> N.
-
- Lemma wordize_plus: forall {n} (x y: word n),
- (&x + &y < Npow2 n)%N
- -> (&x + &y)%N = & (x ^+ y).
- Proof.
- intros n x y H.
- pose proof (word_size_bound x) as Hbx.
- pose proof (word_size_bound y) as Hby.
-
- unfold wplus, wordBin.
- rewrite wordToN_NToWord; intuition.
- Qed.
-
- Lemma wordize_awc: forall {n} (x y: word n) (c: bool),
- (&x + &y + c < Npow2 n)%N
- -> (&x + &y + c)%N = &(addWithCarry x y c).
- Proof.
- intros n x y c H.
- unfold wplus, wordBin, addWithCarry.
- destruct c; simpl in *.
-
- - replace 1%N with (wordToN (natToWord n 1)) in * by (
- rewrite wordToN_nat;
- rewrite wordToNat_natToWord_idempotent;
- nomega).
-
- rewrite <- N.add_assoc.
- rewrite wordize_plus; try nomega.
- rewrite wordize_plus; try nomega.
-
- + rewrite wplus_assoc.
- reflexivity.
-
- + apply (N.le_lt_trans _ (& x + & y + & natToWord n 1)%N _);
- try assumption.
- rewrite <- N.add_assoc.
- apply N.add_le_mono.
-
- * apply N.eq_le_incl; reflexivity.
-
- * apply plus_le.
-
- - rewrite wplus_comm.
- rewrite wplus_unit.
- rewrite N.add_0_r in *.
- apply wordize_plus; assumption.
- Qed.
-
- Lemma wordize_minus: forall {n} (x y: word n),
- (&x >= &y)%N -> (&x - &y)%N = &(x ^- y).
- Proof.
- intros n x y H.
-
- destruct (Nge_dec 0%N (&y)). {
- unfold wminus, wneg.
- replace (& y) with 0%N in * by nomega.
- replace (Npow2 n - 0)%N with (& (wzero n) + Npow2 n)%N
- by (rewrite wordToN_zero; nomega).
- rewrite <- Npow2_ignore.
- rewrite wplus_comm.
- rewrite wplus_unit.
- nomega.
- }
-
- assert (& x - & y < Npow2 n)%N. {
- transitivity (wordToN x);
- try apply word_size_bound;
- apply N.sub_lt;
- [apply N.ge_le|]; assumption.
- }
-
- assert (& x - & y + & y < Npow2 n)%N. {
- replace (& x - & y + & y)%N
- with (wordToN x) by nomega;
- apply word_size_bound.
- }
-
- assert (x = NToWord n (wordToN x - wordToN y) ^+ y) as Hv. {
- apply NToWord_equal.
- rewrite <- wordize_plus; rewrite wordToN_NToWord; try assumption.
- nomega.
- }
-
- symmetry.
- rewrite Hv at 1.
- unfold wminus.
- repeat rewrite <- wplus_assoc.
- rewrite wminus_inv.
- rewrite wplus_comm.
- rewrite wplus_unit.
- rewrite wordToN_NToWord; try assumption.
- reflexivity.
- Qed.
-
- Lemma wordize_mult: forall {n} (x y: word n),
- (&x * &y < Npow2 n)%N
- -> (&x * &y)%N = &(x ^* y).
- Proof.
- intros n x y H.
- pose proof (word_size_bound x) as Hbx.
- pose proof (word_size_bound y) as Hby.
-
- unfold wmult, wordBin.
- rewrite wordToN_NToWord; intuition.
- Qed.
-
- Lemma wordize_shiftr: forall {n} (x: word n) (k: nat),
- (N.shiftr_nat (&x) k) = & (shiftr x k).
- Proof.
- intros n x k.
- unfold shiftr, extend, high.
- destruct (le_dec k n).
-
- - repeat first [
- rewrite wordToN_convS
- | rewrite wordToN_zext
- | rewrite wordToN_split2 ].
- rewrite <- Nshiftr_equiv_nat.
- reflexivity.
-
- - rewrite (wordToN_nat (wzero n)); unfold wzero.
- destruct (Nat.eq_dec n O); subst.
-
- + rewrite (shatter_word_0 x); simpl; intuition.
- rewrite <- Nshiftr_equiv_nat.
- rewrite N.shiftr_0_l.
- reflexivity.
-
- + rewrite wordToNat_natToWord_idempotent;
- try nomega.
-
- * pose proof (word_size_bound x).
- rewrite <- Nshiftr_equiv_nat.
- rewrite N.shiftr_eq_0_iff.
- destruct (N.eq_dec (&x) 0%N) as [E|E];
- try rewrite E in *;
- try abstract (left; reflexivity).
-
- right; split; try nomega.
- apply (N.le_lt_trans _ (N.log2 (Npow2 n)) _). {
- apply N.log2_le_mono.
- apply N.lt_le_incl.
- assumption.
- }
-
- rewrite Npow2_N.
- rewrite N.log2_pow2; try nomega.
- apply N_ge_0.
-
- * simpl; apply Npow2_gt0.
- Qed.
-
- Lemma wordize_and: forall {n} (x y: word n),
- & (wand x y) = N.land (&x) (&y).
- Proof.
- intros.
- apply N.bits_inj_iff; unfold N.eqf; intro k.
- rewrite N.land_spec.
- repeat rewrite wordToN_testbit.
- revert x y.
- generalize (N.to_nat k) as k'; clear k.
- induction n; intros; shatter x; shatter y; simpl; [reflexivity|].
- induction k'; [reflexivity|].
- fold wand.
- rewrite IHn.
- reflexivity.
- Qed.
-
- Lemma wordize_or: forall {n} (x y: word n),
- & (wor x y) = N.lor (&x) (&y).
- Proof.
- intros.
- apply N.bits_inj_iff; unfold N.eqf; intro k.
- rewrite N.lor_spec.
- repeat rewrite wordToN_testbit.
- revert x y.
- generalize (N.to_nat k) as k'; clear k.
- induction n; intros; shatter x; shatter y; simpl; [reflexivity|].
- induction k'; [reflexivity|].
- rewrite IHn.
- reflexivity.
- Qed.
-
- Lemma conv_mask: forall {n} (x: word n) (k: nat),
- (k <= n)%nat ->
- mask k x = x ^& (NToWord _ (N.ones (N.of_nat k))).
- Proof.
- intros n x k H.
- apply NToWord_equal.
-
- rewrite <- (Nat2N.id k).
- rewrite mask_spec.
- apply N.bits_inj_iff; unfold N.eqf; intro m.
- rewrite N.land_spec.
- repeat rewrite wordToN_testbit.
- rewrite <- (N2Nat.id m).
- rewrite <- wordToN_wones.
- repeat rewrite wordToN_testbit.
- repeat rewrite N2Nat.id.
- rewrite <- wordToN_wones.
-
- assert (forall n (a b: word n) k,
- wbit (a ^& b) k = andb (wbit a k) (wbit b k)) as Hwand. {
- intros n0 a b.
- induction n0 as [|n1];
- shatter a; shatter b;
- simpl; try reflexivity.
-
- intro k0; induction k0 as [|k0];
- simpl; try reflexivity.
-
- fold wand.
- rewrite IHn1.
- reflexivity.
- }
-
- rewrite Hwand; clear Hwand.
- induction (wbit x (N.to_nat m));
- repeat rewrite andb_false_l;
- repeat rewrite andb_true_l;
- try reflexivity.
-
- repeat rewrite <- wordToN_testbit.
- rewrite wordToN_NToWord; try reflexivity.
- apply (N.lt_le_trans _ (Npow2 k) _).
-
- + apply word_size_bound.
-
- + apply Npow2_ordered.
- omega.
- Qed.
-
- Close Scope nword_scope.
-End TopLevel.