aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Reflection/Z/InterpretationsGen.v8
-rw-r--r--src/Util/FixedWordSizesEquality.v55
-rw-r--r--src/Util/WordUtil.v44
-rw-r--r--src/Util/ZUtil.v50
4 files changed, 111 insertions, 46 deletions
diff --git a/src/Reflection/Z/InterpretationsGen.v b/src/Reflection/Z/InterpretationsGen.v
index 6ccb23960..f11837e60 100644
--- a/src/Reflection/Z/InterpretationsGen.v
+++ b/src/Reflection/Z/InterpretationsGen.v
@@ -233,9 +233,9 @@ Module InterpretationsGen (Bit : BitSize).
Lemma wordWToZ_shl : bounds_2statement shl Z.shiftl.
Proof.
wWToZ_t; wWToZ_extra_t; unfold wordWToZ, wordBin.
- rewrite wordToN_NToWord_idempotent; [rewrite <- Z_inj_shiftl; reflexivity|].
+ rewrite wordToN_NToWord_idempotent; [rewrite <- N2Z.inj_shiftl; reflexivity|].
apply N2Z.inj_lt.
- rewrite Z_inj_shiftl.
+ rewrite N2Z.inj_shiftl.
destruct (Z.lt_ge_cases 0 ((wordWToZ x) << (wordWToZ y)))%Z;
[|eapply Z.le_lt_trans; [|apply N2Z.inj_lt, Npow2_gt0]; assumption].
rewrite Npow2_N, N2Z.inj_pow, ?nat_N_Z.
@@ -245,9 +245,9 @@ Module InterpretationsGen (Bit : BitSize).
Lemma wordWToZ_shr : bounds_2statement shr Z.shiftr.
Proof.
wWToZ_t; wWToZ_extra_t; unfold wordWToZ, wordBin.
- rewrite wordToN_NToWord_idempotent; [rewrite <- Z_inj_shiftr; reflexivity|].
+ rewrite wordToN_NToWord_idempotent; [rewrite <- N2Z.inj_shiftr; reflexivity|].
apply N2Z.inj_lt.
- rewrite Z_inj_shiftr.
+ rewrite N2Z.inj_shiftr.
destruct (Z.lt_ge_cases 0 ((wordWToZ x) >> (wordWToZ y)))%Z;
[|eapply Z.le_lt_trans; [|apply N2Z.inj_lt, Npow2_gt0]; assumption].
rewrite Npow2_N, N2Z.inj_pow, nat_N_Z.
diff --git a/src/Util/FixedWordSizesEquality.v b/src/Util/FixedWordSizesEquality.v
index 749750625..271668032 100644
--- a/src/Util/FixedWordSizesEquality.v
+++ b/src/Util/FixedWordSizesEquality.v
@@ -4,6 +4,7 @@ Require Import Coq.Arith.Arith.
Require Import Bedrock.Word.
Require Import Crypto.Util.FixedWordSizes.
Require Import Crypto.Util.WordUtil.
+Require Import Crypto.Util.ZUtil.
Require Import Crypto.Util.Tactics.BreakMatch.
Definition wordT_beq_hetero {logsz1 logsz2} : wordT logsz1 -> wordT logsz2 -> bool
@@ -225,7 +226,7 @@ Ltac syntactic_fixed_size_op_to_word :=
let P := lazymatch (eval pattern logsz in P) with ?P _ => P end in
revert logsz x;
refine (@wordToZ_word_case_dep_unop wop P _);
- intros logsz x; unfold wordToZ_gen; intros
+ intros logsz x; intros
| [ |- context[wordToZ (word_case_dep (T:=?T) ?logsz (?wop 32) (?wop 64) (?wop 128) ?f ?x ?y)] ]
=> lazymatch type of x with
| context[logsz]
@@ -236,7 +237,7 @@ Ltac syntactic_fixed_size_op_to_word :=
let P := lazymatch (eval pattern logsz in P) with ?P _ => P end in
revert logsz x y;
refine (@wordToZ_word_case_dep_binop wop P _);
- intros logsz x y; unfold wordToZ_gen; intros
+ intros logsz x y; intros
| _
=> move y at top;
revert dependent logsz; intros logsz y;
@@ -245,7 +246,7 @@ Ltac syntactic_fixed_size_op_to_word :=
let P := lazymatch (eval pattern logsz in P) with ?P _ => P end in
revert logsz y;
refine (@wordToZ_word_case_dep_11op _ wop P x _);
- intros logsz y; unfold wordToZ_gen; intros
+ intros logsz y; intros
end
| [ |- context[wordToZ (word_case_dep (T:=?T) ?logsz (?wop 32) (?wop 64) (?wop 128) ?f ?x ?y ?z ?w)] ]
=> move w at top; move z at top; move y at top; move x at top;
@@ -299,7 +300,7 @@ Section Updates.
g.
Proof.
intros H n; specialize (H (2^n)%nat).
- unfold valid_update; intros; fixed_size_op_to_word; auto.
+ unfold valid_update; intros; fixed_size_op_to_word; unfold wordToZ_gen; auto.
Qed.
Lemma wadd_valid_update: forall n,
@@ -351,3 +352,49 @@ Section Updates.
(fun l0 u0 l1 u1 => Z.shiftl u0 u1)%Z.
Proof. apply word_case_dep_valid_update, shl_valid_update. Qed.
End Updates.
+
+Section pull_ZToWord.
+ Local Ltac t0 :=
+ intros;
+ etransitivity; [ symmetry; apply ZToWord_wordToZ | ]; fixed_size_op_to_word; unfold wordToZ_gen, wordBin;
+ apply f_equal.
+ Local Ltac t1 lem :=
+ let solver := solve [ apply Npow2_Zlog2; autorewrite with push_Zof_N; assumption
+ | apply N2Z.inj_ge; unfold wordToZ_gen in *; omega ] in
+ first [ rewrite <- lem by solver | rewrite -> lem by solver ].
+ Local Ltac t2 :=
+ autorewrite with push_Zof_N; unfold wordToZ_gen in *;
+ try first [ reflexivity
+ | apply Z.max_case_strong; omega ].
+
+ Local Ltac t lem :=
+ t0; t1 lem; solve [ t2 ].
+
+ Local Notation pull_ZToWordT_2op wop zop
+ := (forall {logsz} (x y : wordT logsz),
+ (Z.log2 (zop (wordToZ x) (wordToZ y)) < Z.of_nat (2^logsz))%Z
+ -> wop logsz x y = ZToWord (zop (wordToZ x) (wordToZ y)))
+ (only parsing).
+ Local Notation pull_ZToWordT_2op' wop zop
+ := (forall {logsz} (x y : wordT logsz),
+ (0 <= zop (wordToZ x) (wordToZ y))%Z
+ -> wop logsz x y = ZToWord (zop (wordToZ x) (wordToZ y)))
+ (only parsing).
+
+ Lemma wadd_def_ZToWord : pull_ZToWordT_2op (@wadd) (@Z.add).
+ Proof. t (@wordize_plus). Qed.
+ Lemma wsub_def_ZToWord : pull_ZToWordT_2op' (@wsub) (@Z.sub).
+ Proof. t (@wordize_minus). Qed.
+ Lemma wmul_def_ZToWord : pull_ZToWordT_2op (@wmul) (@Z.mul).
+ Proof. t (@wordize_mult). Qed.
+ Lemma wland_def_ZToWord : pull_ZToWordT_2op (@wland) (@Z.land).
+ Proof. t (@wordize_and). Qed.
+ Lemma wlor_def_ZToWord : pull_ZToWordT_2op (@wlor) (@Z.lor).
+ Proof. t (@wordize_or). Qed.
+ Lemma wshl_def_ZToWord : pull_ZToWordT_2op (@wshl) (@Z.shiftl).
+ Proof. t (@wordToN_NToWord_idempotent). Qed.
+ Lemma wshr_def_ZToWord : pull_ZToWordT_2op (@wshr) (@Z.shiftr).
+ Proof. t (@wordToN_NToWord_idempotent). Qed.
+End pull_ZToWord.
+Hint Rewrite wadd_def_ZToWord wsub_def_ZToWord wmul_def_ZToWord wland_def_ZToWord wlor_def_ZToWord wshl_def_ZToWord wshr_def_ZToWord : pull_ZToWord.
+Hint Rewrite <- wadd_def_ZToWord wsub_def_ZToWord wmul_def_ZToWord wland_def_ZToWord wlor_def_ZToWord wshl_def_ZToWord wshr_def_ZToWord : push_ZToWord.
diff --git a/src/Util/WordUtil.v b/src/Util/WordUtil.v
index fd4863ce1..1a38c873f 100644
--- a/src/Util/WordUtil.v
+++ b/src/Util/WordUtil.v
@@ -22,9 +22,13 @@ Local Open Scope nat_scope.
Create HintDb pull_wordToN discriminated.
Create HintDb push_wordToN discriminated.
+Create HintDb pull_ZToWord discriminated.
+Create HintDb push_ZToWord discriminated.
Hint Extern 1 => autorewrite with pull_wordToN in * : pull_wordToN.
Hint Extern 1 => autorewrite with push_wordToN in * : push_wordToN.
+Hint Extern 1 => autorewrite with pull_ZToWord in * : pull_ZToWord.
+Hint Extern 1 => autorewrite with push_ZToWord in * : push_ZToWord.
Module Word.
Fixpoint weqb_hetero sz1 sz2 (x : word sz1) (y : word sz2) : bool :=
@@ -256,42 +260,6 @@ Section Pow2.
Qed.
End Pow2.
-Section Z2N.
- Lemma Z_inj_shiftl: forall x y, Z.of_N (N.shiftl x y) = Z.shiftl (Z.of_N x) (Z.of_N y).
- Proof.
- intros.
- apply Z.bits_inj_iff'; intros k Hpos.
- rewrite Z2N.inj_testbit; [|assumption].
- rewrite Z.shiftl_spec; [|assumption].
-
- assert ((Z.to_N k) >= y \/ (Z.to_N k) < y)%N as g by (
- unfold N.ge, N.lt; induction (N.compare (Z.to_N k) y); [left|auto|left];
- intro H; inversion H).
-
- destruct g as [g|g];
- [ rewrite N.shiftl_spec_high; [|apply N2Z.inj_le; rewrite Z2N.id|apply N.ge_le]
- | rewrite N.shiftl_spec_low]; try assumption.
-
- - rewrite <- N2Z.inj_testbit; f_equal.
- rewrite N2Z.inj_sub, Z2N.id; [reflexivity|assumption|apply N.ge_le; assumption].
-
- - apply N2Z.inj_lt in g.
- rewrite Z2N.id in g; [symmetry|assumption].
- apply Z.testbit_neg_r; omega.
- Qed.
-
- Lemma Z_inj_shiftr: forall x y, Z.of_N (N.shiftr x y) = Z.shiftr (Z.of_N x) (Z.of_N y).
- Proof.
- intros.
- apply Z.bits_inj_iff'; intros k Hpos.
- rewrite Z2N.inj_testbit; [|assumption].
- rewrite Z.shiftr_spec, N.shiftr_spec; [|apply N2Z.inj_le; rewrite Z2N.id|]; try assumption.
- rewrite <- N2Z.inj_testbit; f_equal.
- rewrite N2Z.inj_add; f_equal.
- apply Z2N.id; assumption.
- Qed.
-End Z2N.
-
Section WordToN.
Lemma wordToN_NToWord_idempotent : forall sz n, (n < Npow2 sz)%N ->
wordToN (NToWord sz n) = n.
@@ -1231,7 +1199,7 @@ Section Updates.
do 2 destruct B0 as [? B0], B1 as [? B1]; destruct B0, B1; intros.
repeat split; [assumption| | |assumption];
- (rewrite wordToN_NToWord_idempotent; [|apply Npow2_Zlog2]; rewrite Z_inj_shiftr);
+ (rewrite wordToN_NToWord_idempotent; [|apply Npow2_Zlog2]; rewrite N2Z.inj_shiftr);
[ | eapply Z.le_lt_trans; [apply Z.log2_le_mono|eassumption]
| | eapply Z.le_lt_trans; [apply Z.log2_le_mono|eassumption]];
apply Z.shiftr_le_mono; shift_mono.
@@ -1247,7 +1215,7 @@ Section Updates.
do 2 destruct B0 as [? B0], B1 as [? B1]; destruct B0, B1; intros.
repeat split; [assumption| | |assumption];
- (rewrite wordToN_NToWord_idempotent; [|apply Npow2_Zlog2]; rewrite Z_inj_shiftl);
+ (rewrite wordToN_NToWord_idempotent; [|apply Npow2_Zlog2]; rewrite N2Z.inj_shiftl);
[ | eapply Z.le_lt_trans; [apply Z.log2_le_mono|eassumption]
| | eapply Z.le_lt_trans; [apply Z.log2_le_mono|eassumption]];
apply Z.shiftl_le_mono; shift_mono.
diff --git a/src/Util/ZUtil.v b/src/Util/ZUtil.v
index 277b38121..bc9278960 100644
--- a/src/Util/ZUtil.v
+++ b/src/Util/ZUtil.v
@@ -3097,6 +3097,56 @@ for name in names:
End RemoveEquivModuloInstances.
End Z.
+Module N2Z.
+ Lemma inj_land n m : Z.of_N (N.land n m) = Z.land (Z.of_N n) (Z.of_N m).
+ Proof. destruct n, m; reflexivity. Qed.
+ Hint Rewrite inj_land : push_Zof_N.
+ Hint Rewrite <- inj_land : pull_Zof_N.
+
+ Lemma inj_lor n m : Z.of_N (N.lor n m) = Z.lor (Z.of_N n) (Z.of_N m).
+ Proof. destruct n, m; reflexivity. Qed.
+ Hint Rewrite inj_lor : push_Zof_N.
+ Hint Rewrite <- inj_lor : pull_Zof_N.
+
+ Lemma inj_shiftl: forall x y, Z.of_N (N.shiftl x y) = Z.shiftl (Z.of_N x) (Z.of_N y).
+ Proof.
+ intros.
+ apply Z.bits_inj_iff'; intros k Hpos.
+ rewrite Z2N.inj_testbit; [|assumption].
+ rewrite Z.shiftl_spec; [|assumption].
+
+ assert ((Z.to_N k) >= y \/ (Z.to_N k) < y)%N as g by (
+ unfold N.ge, N.lt; induction (N.compare (Z.to_N k) y); [left|auto|left];
+ intro H; inversion H).
+
+ destruct g as [g|g];
+ [ rewrite N.shiftl_spec_high; [|apply N2Z.inj_le; rewrite Z2N.id|apply N.ge_le]
+ | rewrite N.shiftl_spec_low]; try assumption.
+
+ - rewrite <- N2Z.inj_testbit; f_equal.
+ rewrite N2Z.inj_sub, Z2N.id; [reflexivity|assumption|apply N.ge_le; assumption].
+
+ - apply N2Z.inj_lt in g.
+ rewrite Z2N.id in g; [symmetry|assumption].
+ apply Z.testbit_neg_r; omega.
+ Qed.
+ Hint Rewrite inj_shiftl : push_Zof_N.
+ Hint Rewrite <- inj_shiftl : pull_Zof_N.
+
+ Lemma inj_shiftr: forall x y, Z.of_N (N.shiftr x y) = Z.shiftr (Z.of_N x) (Z.of_N y).
+ Proof.
+ intros.
+ apply Z.bits_inj_iff'; intros k Hpos.
+ rewrite Z2N.inj_testbit; [|assumption].
+ rewrite Z.shiftr_spec, N.shiftr_spec; [|apply N2Z.inj_le; rewrite Z2N.id|]; try assumption.
+ rewrite <- N2Z.inj_testbit; f_equal.
+ rewrite N2Z.inj_add; f_equal.
+ apply Z2N.id; assumption.
+ Qed.
+ Hint Rewrite inj_shiftr : push_Zof_N.
+ Hint Rewrite <- inj_shiftr : pull_Zof_N.
+End N2Z.
+
Module Export BoundsTactics.
Ltac prime_bound := Z.prime_bound.
Ltac zero_bounds := Z.zero_bounds.