diff options
author | jadep <jadep@mit.edu> | 2018-12-10 15:54:02 -0500 |
---|---|---|
committer | jadep <jade.philipoom@gmail.com> | 2019-01-03 04:45:31 -0500 |
commit | fa0fd7e036d4be7e40f5605cb61ca06730ad1f5f (patch) | |
tree | d0144824d0b87c94a9f799dec63e73bf8e03dcd3 /src | |
parent | 240c19a1dafd054eb1ad5444f4d05f7013dd966a (diff) |
remove dead code
Diffstat (limited to 'src')
-rw-r--r-- | src/Experiments/NewPipeline/Toplevel2.v | 1283 |
1 files changed, 0 insertions, 1283 deletions
diff --git a/src/Experiments/NewPipeline/Toplevel2.v b/src/Experiments/NewPipeline/Toplevel2.v index 754db6d5a..0475f0451 100644 --- a/src/Experiments/NewPipeline/Toplevel2.v +++ b/src/Experiments/NewPipeline/Toplevel2.v @@ -371,1210 +371,6 @@ mulmod = fun var : type -> Type => λ x x0 : var (type.base (base.type.list (bas End P192_64. -(* -(* TODO : delete *) -Module PreFancy. - Section with_wordmax. - Context (log2wordmax : Z) (log2wordmax_pos : 1 < log2wordmax) (log2wordmax_even : log2wordmax mod 2 = 0). - Let wordmax := 2 ^ log2wordmax. - Lemma wordmax_gt_2 : 2 < wordmax. - Proof. - apply Z.le_lt_trans with (m:=2 ^ 1); [ reflexivity | ]. - apply Z.pow_lt_mono_r; omega. - Qed. - - Lemma wordmax_even : wordmax mod 2 = 0. - Proof. - replace 2 with (2 ^ 1) by reflexivity. - subst wordmax. apply Z.mod_same_pow; omega. - Qed. - - Let half_bits := log2wordmax / 2. - - Lemma half_bits_nonneg : 0 <= half_bits. - Proof. subst half_bits; Z.zero_bounds. Qed. - - Let wordmax_half_bits := 2 ^ half_bits. - - Lemma wordmax_half_bits_pos : 0 < wordmax_half_bits. - Proof. subst wordmax_half_bits half_bits. Z.zero_bounds. Qed. - - Lemma half_bits_squared : (wordmax_half_bits - 1) * (wordmax_half_bits - 1) <= wordmax - 1. - Proof. - pose proof wordmax_half_bits_pos. - subst wordmax_half_bits. - transitivity (2 ^ (half_bits + half_bits) - 2 * 2 ^ half_bits + 1). - { rewrite Z.pow_add_r by (subst half_bits; Z.zero_bounds). - autorewrite with push_Zmul; omega. } - { transitivity (wordmax - 2 * 2 ^ half_bits + 1); [ | lia]. - subst wordmax. - apply Z.add_le_mono_r. - apply Z.sub_le_mono_r. - apply Z.pow_le_mono_r; [ omega | ]. - rewrite Z.add_diag; subst half_bits. - apply BinInt.Z.mul_div_le; omega. } - Qed. - - Lemma wordmax_half_bits_le_wordmax : wordmax_half_bits <= wordmax. - Proof. - subst wordmax half_bits wordmax_half_bits. - apply Z.pow_le_mono_r; [lia|]. - apply Z.div_le_upper_bound; lia. - Qed. - - Lemma ones_half_bits : wordmax_half_bits - 1 = Z.ones half_bits. - Proof. - subst wordmax_half_bits. cbv [Z.ones]. - rewrite Z.shiftl_mul_pow2, <-Z.sub_1_r by auto using half_bits_nonneg. - lia. - Qed. - - Lemma wordmax_half_bits_squared : wordmax_half_bits * wordmax_half_bits = wordmax. - Proof. - subst wordmax half_bits wordmax_half_bits. - rewrite <-Z.pow_add_r by Z.zero_bounds. - rewrite Z.add_diag, Z.mul_div_eq by omega. - f_equal; lia. - Qed. - -(* - Section interp. - Context {interp_cast : zrange -> Z -> Z}. - Local Notation interp_scalar := (interp_scalar (interp_cast:=interp_cast)). - Local Notation interp_cast2 := (interp_cast2 (interp_cast:=interp_cast)). - Local Notation low x := (Z.land x (wordmax_half_bits - 1)). - Local Notation high x := (x >> half_bits). - Local Notation shift x imm := ((x << imm) mod wordmax). - - Definition interp_ident {s d} (idc : ident s d) : type.interp s -> type.interp d := - match idc with - | add imm => fun x => Z.add_get_carry_full wordmax (fst x) (shift (snd x) imm) - | addc imm => fun x => Z.add_with_get_carry_full wordmax (fst (fst x)) (snd (fst x)) (shift (snd x) imm) - | sub imm => fun x => Z.sub_get_borrow_full wordmax (fst x) (shift (snd x) imm) - | subb imm => fun x => Z.sub_with_get_borrow_full wordmax (fst (fst x)) (snd (fst x)) (shift (snd x) imm) - | mulll => fun x => low (fst x) * low (snd x) - | mullh => fun x => low (fst x) * high (snd x) - | mulhl => fun x => high (fst x) * low (snd x) - | mulhh => fun x => high (fst x) * high (snd x) - | rshi n => fun x => Z.rshi wordmax (fst x) (snd x) n - | selc => fun x => Z.zselect (fst (fst x)) (snd (fst x)) (snd x) - | selm => fun x => Z.zselect (Z.cc_m wordmax (fst (fst x))) (snd (fst x)) (snd x) - | sell => fun x => Z.zselect (Z.land (fst (fst x)) 1) (snd (fst x)) (snd x) - | addm => fun x => Z.add_modulo (fst (fst x)) (snd (fst x)) (snd x) - end. - - Fixpoint interp {t} (e : @expr type.interp ident t) : type.interp t := - match e with - | Scalar t s => interp_scalar s - | LetInAppIdentZ s d r idc x f => - interp (f (interp_cast r (interp_ident idc (interp_scalar x)))) - | LetInAppIdentZZ s d r idc x f => - interp (f (interp_cast2 r (interp_ident idc (interp_scalar x)))) - end. - End interp. - - Section proofs. - Context (dummy_arrow : forall s d, type.interp (s -> d)%ctype) (consts : list Z) - (consts_ok : forall x, In x consts -> 0 <= x <= wordmax - 1). - Context {interp_cast : zrange -> Z -> Z} {interp_cast_correct : forall r x, lower r <= x <= upper r -> interp_cast r x = x}. - Local Notation interp_scalar := (interp_scalar (interp_cast:=interp_cast)). - Local Notation interp_cast2 := (interp_cast2 (interp_cast:=interp_cast)). - - Local Notation word_range := (r[0~>wordmax-1])%zrange. - Local Notation half_word_range := (r[0~>wordmax_half_bits-1])%zrange. - Local Notation flag_range := (r[0~>1])%zrange. - - Definition in_word_range (r : zrange) := is_tighter_than_bool r word_range = true. - Definition in_flag_range (r : zrange) := is_tighter_than_bool r flag_range = true. - - Fixpoint get_range_var (t : type) : type.interp t -> range_type t := - match t with - | type.type_primitive type.Z => - fun x => {| lower := x; upper := x |} - | type.prod a b => - fun x => (get_range_var a (fst x), get_range_var b (snd x)) - | _ => fun _ => tt - end. - - Fixpoint get_range {t} (x : @scalar type.interp t) : range_type t := - match x with - | Var t v => get_range_var t v - | TT => tt - | Nil _ => tt - | Pair _ _ x y => (get_range x, get_range y) - | Cast r _ => r - | Cast2 r _ => r - | Fst _ _ p => fst (get_range p) - | Snd _ _ p => snd (get_range p) - | Shiftr n x => ZRange.map (fun y => Z.shiftr y n) (get_range x) - | Shiftl n x => ZRange.map (fun y => Z.shiftl y n) (get_range x) - | Land n x => r[0~>n]%zrange - | CC_m n x => ZRange.map (Z.cc_m n) (get_range x) - | Primitive type.Z x => {| lower := x; upper := x |} - | Primitive p x => tt - end. - - Fixpoint has_range {t} : range_type t -> type.interp t -> Prop := - match t with - | type.type_primitive type.Z => - fun r x => - lower r <= x <= upper r - | type.prod a b => - fun r x => - has_range (fst r) (fst x) /\ has_range (snd r) (snd x) - | _ => fun _ _ => True - end. - - Inductive ok_scalar : forall {t}, @scalar type.interp t -> Prop := - | sc_ok_var : forall t v, ok_scalar (Var t v) - | sc_ok_unit : ok_scalar TT - | sc_ok_nil : forall t, ok_scalar (Nil t) - | sc_ok_pair : forall A B x y, - @ok_scalar A x -> - @ok_scalar B y -> - ok_scalar (Pair x y) - | sc_ok_cast : forall r (x : scalar type.Z), - ok_scalar x -> - is_tighter_than_bool (get_range x) r = true -> - ok_scalar (Cast r x) - | sc_ok_cast2 : forall r (x : scalar (type.prod type.Z type.Z)), - ok_scalar x -> - is_tighter_than_bool (fst (get_range x)) (fst r) = true -> - is_tighter_than_bool (snd (get_range x)) (snd r) = true -> - ok_scalar (Cast2 r x) - | sc_ok_fst : - forall A B p, @ok_scalar (A * B) p -> ok_scalar (Fst p) - | sc_ok_snd : - forall A B p, @ok_scalar (A * B) p -> ok_scalar (Snd p) - | sc_ok_shiftr : - forall n x, 0 <= n -> ok_scalar x -> ok_scalar (Shiftr n x) - | sc_ok_shiftl : - forall n x, 0 <= n -> 0 <= lower (@get_range type.Z x) -> ok_scalar x -> ok_scalar (Shiftl n x) - | sc_ok_land : - forall n x, 0 <= n -> 0 <= lower (@get_range type.Z x) -> ok_scalar x -> ok_scalar (Land n x) - | sc_ok_cc_m : - forall x, ok_scalar x -> ok_scalar (CC_m wordmax x) - | sc_ok_prim : forall p x, ok_scalar (@Primitive _ p x) - . - - Inductive is_halved : scalar type.Z -> Prop := - | is_halved_lower : - forall x : scalar type.Z, - in_word_range (get_range x) -> - is_halved (Cast half_word_range (Land (wordmax_half_bits - 1) x)) - | is_halved_upper : - forall x : scalar type.Z, - in_word_range (get_range x) -> - is_halved (Cast half_word_range (Shiftr half_bits x)) - | is_halved_constant : - forall y z, - constant_to_scalar consts z = Some y -> - is_halved y -> - is_halved (Primitive (t:=type.Z) z) - . - - Inductive ok_ident : forall s d, scalar s -> range_type d -> ident.ident s d -> Prop := - | ok_add : - forall x y : scalar type.Z, - in_word_range (get_range x) -> - in_word_range (get_range y) -> - ok_ident _ - (type.prod type.Z type.Z) - (Pair x y) - (word_range, flag_range) - (ident.Z.add_get_carry_concrete wordmax) - | ok_addc : - forall (c x y : scalar type.Z) outr, - in_flag_range (get_range c) -> - in_word_range (get_range x) -> - in_word_range (get_range y) -> - lower outr = 0 -> - (0 <= upper (get_range c) + upper (get_range x) + upper (get_range y) <= upper outr \/ outr = word_range) -> - ok_ident _ - (type.prod type.Z type.Z) - (Pair (Pair c x) y) - (outr, flag_range) - (ident.Z.add_with_get_carry_concrete wordmax) - | ok_sub : - forall x y : scalar type.Z, - in_word_range (get_range x) -> - in_word_range (get_range y) -> - ok_ident _ - (type.prod type.Z type.Z) - (Pair x y) - (word_range, flag_range) - (ident.Z.sub_get_borrow_concrete wordmax) - | ok_subb : - forall b x y : scalar type.Z, - in_flag_range (get_range b) -> - in_word_range (get_range x) -> - in_word_range (get_range y) -> - ok_ident _ - (type.prod type.Z type.Z) - (Pair (Pair b x) y) - (word_range, flag_range) - (ident.Z.sub_with_get_borrow_concrete wordmax) - | ok_rshi : - forall (x : scalar (type.prod type.Z type.Z)) n outr, - in_word_range (fst (get_range x)) -> - in_word_range (snd (get_range x)) -> - (* note : using [outr] rather than [word_range] allows for cases where the result has been put in a smaller word size. *) - lower outr = 0 -> - 0 <= n -> - ((0 <= (upper (snd (get_range x)) + upper (fst (get_range x)) * wordmax) / 2^n <= upper outr) - \/ outr = word_range) -> - ok_ident (type.prod type.Z type.Z) type.Z x outr (ident.Z.rshi_concrete wordmax n) - | ok_selc : - forall (x : scalar (type.prod type.Z type.Z)) (y z : scalar type.Z), - in_flag_range (snd (get_range x)) -> - in_word_range (get_range y) -> - in_word_range (get_range z) -> - ok_ident _ - type.Z - (Pair (Pair (Cast flag_range (Snd x)) y) z) - word_range - ident.Z.zselect - | ok_selm : - forall x y z : scalar type.Z, - in_word_range (get_range x) -> - in_word_range (get_range y) -> - in_word_range (get_range z) -> - ok_ident _ - type.Z - (Pair (Pair (Cast flag_range (CC_m wordmax x)) y) z) - word_range - ident.Z.zselect - | ok_sell : - forall x y z : scalar type.Z, - in_word_range (get_range x) -> - in_word_range (get_range y) -> - in_word_range (get_range z) -> - ok_ident _ - type.Z - (Pair (Pair (Cast flag_range (Land 1 x)) y) z) - word_range - ident.Z.zselect - | ok_addm : - forall (x : scalar (type.prod (type.prod type.Z type.Z) type.Z)), - in_word_range (fst (fst (get_range x))) -> - in_word_range (snd (fst (get_range x))) -> - in_word_range (snd (get_range x)) -> - upper (fst (fst (get_range x))) + upper (snd (fst (get_range x))) - lower (snd (get_range x)) < wordmax -> - ok_ident _ - type.Z - x - word_range - ident.Z.add_modulo - | ok_mul : - forall x y : scalar type.Z, - is_halved x -> - is_halved y -> - ok_ident (type.prod type.Z type.Z) - type.Z - (Pair x y) - word_range - ident.Z.mul - . - - Inductive ok_expr : forall {t}, @expr type.interp ident.ident t -> Prop := - | ok_of_scalar : forall t s, ok_scalar s -> @ok_expr t (Scalar s) - | ok_letin_z : forall s d r idc x f, - ok_ident _ type.Z x r idc -> - (r <=? word_range)%zrange = true -> - ok_scalar x -> - (forall y, has_range (t:=type.Z) r y -> ok_expr (f y)) -> - ok_expr (@LetInAppIdentZ _ _ s d r idc x f) - | ok_letin_zz : forall s d r idc x f, - ok_ident _ (type.prod type.Z type.Z) x (r, flag_range) idc -> - (r <=? word_range)%zrange = true -> - ok_scalar x -> - (forall y, has_range (t:=type.Z * type.Z) (r, flag_range) y -> ok_expr (f y)) -> - ok_expr (@LetInAppIdentZZ _ _ s d (r, flag_range) idc x f) - . - - Ltac invert H := - inversion H; subst; - repeat match goal with - | H : existT _ _ _ = existT _ _ _ |- _ => apply (Eqdep_dec.inj_pair2_eq_dec _ type.type_eq_dec) in H; subst - end. - - Lemma has_range_get_range_var {t} (v : type.interp t) : - has_range (get_range_var _ v) v. - Proof. - induction t; cbn [get_range_var has_range fst snd]; auto. - destruct p; auto; cbn [upper lower]; omega. - Qed. - - Lemma has_range_loosen r1 r2 (x : Z) : - @has_range type.Z r1 x -> - is_tighter_than_bool r1 r2 = true -> - @has_range type.Z r2 x. - Proof. - cbv [is_tighter_than_bool has_range]; intros; - match goal with H : _ && _ = true |- _ => rewrite andb_true_iff in H; destruct H end; - Z.ltb_to_lt; omega. - Qed. - - Lemma interp_cast_noop x r : - @has_range type.Z r x -> - interp_cast r x = x. - Proof. cbv [has_range]; intros; auto. Qed. - - Lemma interp_cast2_noop x r : - @has_range (type.prod type.Z type.Z) r x -> - interp_cast2 r x = x. - Proof. - cbv [has_range interp_cast2]; intros. - rewrite !interp_cast_correct by tauto. - destruct x; reflexivity. - Qed. - - Lemma has_range_shiftr n (x : scalar type.Z) : - 0 <= n -> - has_range (get_range x) (interp_scalar x) -> - @has_range type.Z (ZRange.map (fun y : Z => y >> n) (get_range x)) (interp_scalar x >> n). - Proof. cbv [has_range]; intros; cbn. auto using Z.shiftr_le with omega. Qed. - Hint Resolve has_range_shiftr : has_range. - - Lemma has_range_shiftl n r x : - 0 <= n -> 0 <= lower r -> - @has_range type.Z r x -> - @has_range type.Z (ZRange.map (fun y : Z => y << n) r) (x << n). - Proof. cbv [has_range]; intros; cbn. auto using Z.shiftl_le_mono with omega. Qed. - Hint Resolve has_range_shiftl : has_range. - - Lemma has_range_land n (x : scalar type.Z) : - 0 <= n -> 0 <= lower (get_range x) -> - has_range (get_range x) (interp_scalar x) -> - @has_range type.Z (r[0~>n])%zrange (Z.land (interp_scalar x) n). - Proof. - cbv [has_range]; intros; cbn. - split; [ apply Z.land_nonneg | apply Z.land_upper_bound_r ]; omega. - Qed. - Hint Resolve has_range_land : has_range. - - Lemma has_range_interp_scalar {t} (x : scalar t) : - ok_scalar x -> - has_range (get_range x) (interp_scalar x). - Proof. - induction 1; cbn [interp_scalar get_range]; - auto with has_range; - try solve [try inversion IHok_scalar; cbn [has_range]; - auto using has_range_get_range_var]; [ | | | ]. - { rewrite interp_cast_noop by eauto using has_range_loosen. - eapply has_range_loosen; eauto. } - { inversion IHok_scalar. - rewrite interp_cast2_noop; - cbn [has_range]; split; eapply has_range_loosen; eauto. } - { cbn. cbv [has_range] in *. - pose proof wordmax_gt_2. - rewrite !Z.cc_m_eq by omega. - split; apply Z.div_le_mono; Z.zero_bounds; omega. } - { destruct p; cbn [has_range upper lower]; auto; omega. } - Qed. - Hint Resolve has_range_interp_scalar : has_range. - - Lemma has_word_range_interp_scalar (x : scalar type.Z) : - ok_scalar x -> - in_word_range (get_range x) -> - @has_range type.Z word_range (interp_scalar x). - Proof. eauto using has_range_loosen, has_range_interp_scalar. Qed. - - Lemma in_word_range_nonneg r : in_word_range r -> 0 <= lower r. - Proof. - cbv [in_word_range is_tighter_than_bool]. - rewrite andb_true_iff; intuition. - Qed. - - Lemma in_word_range_upper_nonneg r x : @has_range type.Z r x -> in_word_range r -> 0 <= upper r. - Proof. - cbv [in_word_range is_tighter_than_bool]; cbn. - rewrite andb_true_iff; intuition. - Z.ltb_to_lt. omega. - Qed. - - Lemma has_word_range_shiftl n r x : - 0 <= n -> upper r * 2 ^ n <= wordmax - 1 -> - @has_range type.Z r x -> - in_word_range r -> - @has_range type.Z word_range (x << n). - Proof. - intros. - eapply has_range_loosen; - [ apply has_range_shiftl; eauto using in_word_range_nonneg with has_range; omega | ]. - cbv [is_tighter_than_bool]. cbn. - apply andb_true_iff; split; apply Z.leb_le; - [ apply Z.shiftl_nonneg; solve [auto using in_word_range_nonneg] | ]. - rewrite Z.shiftl_mul_pow2 by omega. - auto. - Qed. - - Lemma has_range_rshi r n x y : - 0 <= n -> - 0 <= x -> - 0 <= y -> - lower r = 0 -> - (0 <= (y + x * wordmax) / 2^n <= upper r \/ r = word_range) -> - @has_range type.Z r (Z.rshi wordmax x y n). - Proof. - pose proof wordmax_gt_2. - intros. cbv [has_range]. - rewrite Z.rshi_correct by omega. - match goal with |- context [?x mod ?m] => - pose proof (Z.mod_pos_bound x m ltac:(omega)) end. - split; [lia|]. - intuition. - { destruct (Z_lt_dec (upper r) wordmax); [ | lia]. - rewrite Z.mod_small by (split; Z.zero_bounds; omega). - omega. } - { subst r. cbn [upper]. omega. } - Qed. - - Lemma in_word_range_spec r : - (0 <= lower r /\ upper r <= wordmax - 1) - <-> in_word_range r. - Proof. - intros; cbv [in_word_range is_tighter_than_bool]. - rewrite andb_true_iff. - intuition; apply Z.leb_le; cbn [upper lower]; try omega. - Qed. - - Ltac destruct_scalar := - match goal with - | x : scalar (type.prod (type.prod _ _) _) |- _ => - match goal with |- context [interp_scalar x] => - destruct (interp_scalar x) as [ [? ?] ?]; - destruct (get_range x) as [ [? ?] ?] - end - | x : scalar (type.prod _ _) |- _ => - match goal with |- context [interp_scalar x] => - destruct (interp_scalar x) as [? ?]; destruct (get_range x) as [? ?] - end - end. - - Ltac extract_ok_scalar' level x := - match goal with - | H : ok_scalar (Pair (Pair (?f (?g x)) _) _) |- _ => - match (eval compute in (4 <=? level)) with - | true => invert H; extract_ok_scalar' 3 x - | _ => fail - end - | H : ok_scalar (Pair (?f (?g x)) _) |- _ => - match (eval compute in (3 <=? level)) with - | true => invert H; extract_ok_scalar' 2 x - | _ => fail - end - | H : ok_scalar (Pair _ (?f (?g x))) |- _ => - match (eval compute in (3 <=? level)) with - | true => invert H; extract_ok_scalar' 2 x - | _ => fail - end - | H : ok_scalar (?f (?g x)) |- _ => - match (eval compute in (2 <=? level)) with - | true => invert H; extract_ok_scalar' 1 x - | _ => fail - end - | H : ok_scalar (Pair (Pair x _) _) |- _ => - match (eval compute in (2 <=? level)) with - | true => invert H; extract_ok_scalar' 1 x - | _ => fail - end - | H : ok_scalar (Pair (Pair _ x) _) |- _ => - match (eval compute in (2 <=? level)) with - | true => invert H; extract_ok_scalar' 1 x - | _ => fail - end - | H : ok_scalar (?g x) |- _ => invert H - | H : ok_scalar (Pair x _) |- _ => invert H - | H : ok_scalar (Pair _ x) |- _ => invert H - end. - - Ltac extract_ok_scalar := - match goal with |- ok_scalar ?x => extract_ok_scalar' 4 x; assumption end. - - Lemma has_half_word_range_shiftr r x : - in_word_range r -> - @has_range type.Z r x -> - @has_range type.Z half_word_range (x >> half_bits). - Proof. - cbv [in_word_range is_tighter_than_bool]. - rewrite andb_true_iff. - cbn [has_range upper lower]; intros; intuition; Z.ltb_to_lt. - { apply Z.shiftr_nonneg. omega. } - { pose proof half_bits_nonneg. - pose proof half_bits_squared. - assert (x >> half_bits < wordmax_half_bits); [|omega]. - rewrite Z.shiftr_div_pow2 by auto. - apply Z.div_lt_upper_bound; Z.zero_bounds. - subst wordmax_half_bits half_bits. - rewrite <-Z.pow_add_r by omega. - rewrite Z.add_diag, Z.mul_div_eq, log2wordmax_even by omega. - autorewrite with zsimplify_fast. subst wordmax. omega. } - Qed. - - Lemma has_half_word_range_land r x : - in_word_range r -> - @has_range type.Z r x -> - @has_range type.Z half_word_range (x &' (wordmax_half_bits - 1)). - Proof. - pose proof wordmax_half_bits_pos. - cbv [in_word_range is_tighter_than_bool]. - rewrite andb_true_iff. - cbn [has_range upper lower]; intros; intuition; Z.ltb_to_lt. - { apply Z.land_nonneg; omega. } - { apply Z.land_upper_bound_r; omega. } - Qed. - - Section constant_to_scalar. - Lemma constant_to_scalar_single_correct s x z : - 0 <= x <= wordmax - 1 -> - constant_to_scalar_single x z = Some s -> interp_scalar s = z. - Proof. - cbv [constant_to_scalar_single]. - break_match; try discriminate; intros; Z.ltb_to_lt; subst; - try match goal with H : Some _ = Some _ |- _ => inversion H; subst end; - cbn [interp_scalar]; apply interp_cast_noop. - { apply has_half_word_range_shiftr with (r:=r[x~>x]%zrange); - cbv [in_word_range is_tighter_than_bool upper lower has_range]; try omega. - apply andb_true_iff; split; apply Z.leb_le; omega. } - { apply has_half_word_range_land with (r:=r[x~>x]%zrange); - cbv [in_word_range is_tighter_than_bool upper lower has_range]; try omega. - apply andb_true_iff; split; apply Z.leb_le; omega. } - Qed. - - Lemma constant_to_scalar_correct s z : - constant_to_scalar consts z = Some s -> interp_scalar s = z. - Proof. - cbv [constant_to_scalar]. - apply fold_right_invariant; try discriminate. - intros until 2; break_match; eauto using constant_to_scalar_single_correct. - Qed. - - Lemma constant_to_scalar_single_cases x y z : - @constant_to_scalar_single type.interp x z = Some y -> - (y = Cast half_word_range (Land (wordmax_half_bits - 1) (Primitive (t:=type.Z) x))) - \/ (y = Cast half_word_range (Shiftr half_bits (Primitive (t:=type.Z) x))). - Proof. - cbv [constant_to_scalar_single]. - break_match; try discriminate; intros; Z.ltb_to_lt; subst; - try match goal with H : Some _ = Some _ |- _ => inversion H; subst end; - tauto. - Qed. - - Lemma constant_to_scalar_cases y z : - @constant_to_scalar type.interp consts z = Some y -> - (exists x, - @has_range type.Z word_range x - /\ y = Cast half_word_range (Land (wordmax_half_bits - 1) (Primitive x))) - \/ (exists x, - @has_range type.Z word_range x - /\ y = Cast half_word_range (Shiftr half_bits (Primitive x))). - Proof. - cbv [constant_to_scalar]. - apply fold_right_invariant; try discriminate. - intros until 2; break_match; eauto; intros. - match goal with H : constant_to_scalar_single _ _ = _ |- _ => - destruct (constant_to_scalar_single_cases _ _ _ H); subst end. - { left; eexists; split; eauto. - apply consts_ok; auto. } - { right; eexists; split; eauto. - apply consts_ok; auto. } - Qed. - - Lemma ok_scalar_constant_to_scalar y z : constant_to_scalar consts z = Some y -> ok_scalar y. - Proof. - pose proof wordmax_half_bits_pos. pose proof half_bits_nonneg. - let H := fresh in - intro H; apply constant_to_scalar_cases in H; destruct H as [ [? ?] | [? ?] ]; intuition; subst; - cbn [has_range lower upper] in *; repeat constructor; cbn [lower get_range]; try apply Z.leb_refl; try omega. - assert (in_word_range r[x~>x]) by (apply in_word_range_spec; cbn [lower upper]; omega). - pose proof (has_half_word_range_shiftr r[x~>x] x ltac:(assumption) ltac:(cbv [has_range lower upper]; omega)). - cbn [has_range ZRange.map is_tighter_than_bool lower upper] in *. - apply andb_true_iff; cbn [lower upper]; split; apply Z.leb_le; omega. - Qed. - End constant_to_scalar. - Hint Resolve ok_scalar_constant_to_scalar. - - Lemma is_halved_has_range x : - ok_scalar x -> - is_halved x -> - @has_range type.Z half_word_range (interp_scalar x). - Proof. - intro; pose proof (has_range_interp_scalar x ltac:(assumption)). - induction 1; cbn [interp_scalar] in *; intros; try assumption; [ ]. - rewrite <-(constant_to_scalar_correct y z) by assumption. - eauto using has_range_interp_scalar. - Qed. - - Lemma ident_interp_has_range s d x r idc: - ok_scalar x -> - ok_ident s d x r idc -> - has_range r (ident.interp idc (interp_scalar x)). - Proof. - intro. - pose proof (has_range_interp_scalar x ltac:(assumption)). - pose proof wordmax_gt_2. - induction 1; cbn [ident.interp ident.gen_interp]; intros; try destruct_scalar; - repeat match goal with - | H : _ && _ = true |- _ => rewrite andb_true_iff in H; destruct H; Z.ltb_to_lt - | H : _ /\ _ |- _ => destruct H - | H : is_halved _ |- _ => apply is_halved_has_range in H; [ | extract_ok_scalar ] - | _ => progress subst - | _ => progress (cbv [in_word_range in_flag_range is_tighter_than_bool] in * ) - | _ => progress (cbn [interp_scalar get_range has_range upper lower fst snd] in * ) - end. - { - autorewrite with to_div_mod. - match goal with |- context[?x mod ?m] => pose proof (Z.mod_pos_bound x m ltac:(omega)) end. - rewrite Z.div_between_0_if by omega. - split; break_match; lia. } - { - autorewrite with to_div_mod. - match goal with |- context[?x mod ?m] => pose proof (Z.mod_pos_bound x m ltac:(omega)) end. - rewrite Z.div_between_0_if by omega. - match goal with H : _ \/ _ |- _ => destruct H; subst end. - { split; break_match; try lia. - destruct (Z_lt_dec (upper outr) wordmax). - { match goal with |- _ <= ?y mod _ <= ?u => - assert (y <= u) by nia end. - rewrite Z.mod_small by omega. omega. } - { match goal with|- context [?x mod ?m] => pose proof (Z.mod_pos_bound x m ltac:(omega)) end. - omega. } } - { split; break_match; cbn; lia. } } - { - autorewrite with to_div_mod. - match goal with |- context[?x mod ?m] => pose proof (Z.mod_pos_bound x m ltac:(omega)) end. - rewrite Z.div_sub_small by omega. - split; break_match; lia. } - { - autorewrite with to_div_mod. - match goal with |- context [?a - ?b - ?c] => replace (a - b - c) with (a - (b + c)) by ring end. - match goal with |- context[?x mod ?m] => pose proof (Z.mod_pos_bound x m ltac:(omega)) end. - rewrite Z.div_sub_small by omega. - split; break_match; lia. } - { apply has_range_rshi; try nia; [ ]. - match goal with H : context [upper ?ra + upper ?rb * wordmax] |- context [?a + ?b * wordmax] => - assert ((a + b * wordmax) / 2^n <= (upper ra + upper rb * wordmax) / 2^n) by (apply Z.div_le_mono; Z.zero_bounds; nia) - end. - match goal with H : _ \/ ?P |- _ \/ ?P => destruct H; [left|tauto] end. - split; Z.zero_bounds; nia. } - { rewrite Z.zselect_correct. break_match; omega. } - { cbn [interp_scalar fst snd get_range] in *. - rewrite Z.zselect_correct. break_match; omega. } - { cbn [interp_scalar fst snd get_range] in *. - rewrite Z.zselect_correct. break_match; omega. } - { rewrite Z.add_modulo_correct. - break_match; Z.ltb_to_lt; omega. } - { cbn [interp_scalar has_range fst snd get_range upper lower] in *. - pose proof half_bits_squared. nia. } - Qed. - - Lemma has_flag_range_cc_m r x : - @has_range type.Z r x -> - in_word_range r -> - @has_range type.Z flag_range (Z.cc_m wordmax x). - Proof. - cbv [has_range in_word_range is_tighter_than_bool]. - cbn [upper lower]; rewrite andb_true_iff; intros. - match goal with H : _ /\ _ |- _ => destruct H; Z.ltb_to_lt end. - pose proof wordmax_gt_2. pose proof wordmax_even. - pose proof (Z.cc_m_small wordmax x). omega. - Qed. - - Lemma has_flag_range_cc_m' (x : scalar type.Z) : - ok_scalar x -> - in_word_range (get_range x) -> - @has_range type.Z flag_range (Z.cc_m wordmax (interp_scalar x)). - Proof. eauto using has_flag_range_cc_m with has_range. Qed. - - Lemma has_flag_range_land r x : - @has_range type.Z r x -> - in_word_range r -> - @has_range type.Z flag_range (Z.land x 1). - Proof. - cbv [has_range in_word_range is_tighter_than_bool]. - cbn [upper lower]; rewrite andb_true_iff; intuition; Z.ltb_to_lt. - { apply Z.land_nonneg. left; omega. } - { apply Z.land_upper_bound_r; omega. } - Qed. - - Lemma has_flag_range_land' (x : scalar type.Z) : - ok_scalar x -> - in_word_range (get_range x) -> - @has_range type.Z flag_range (Z.land (interp_scalar x) 1). - Proof. eauto using has_flag_range_land with has_range. Qed. - - Ltac rewrite_cast_noop_in_mul := - repeat match goal with - | _ => rewrite interp_cast_noop with (r:=half_word_range) in * - by (eapply has_range_loosen; auto using has_range_land, has_range_interp_scalar) - | _ => rewrite interp_cast_noop with (r:=half_word_range) in * - by (eapply has_range_loosen; try apply has_range_shiftr; auto using has_range_interp_scalar; - cbn [ZRange.map get_range] in *; auto) - | _ => rewrite interp_cast_noop by assumption - end. - - Lemma is_halved_cases x : - is_halved x -> - ok_scalar x -> - (exists y, - invert_lower consts x = Some y - /\ invert_upper consts x = None - /\ interp_scalar y &' (wordmax_half_bits - 1) = interp_scalar x) - \/ (exists y, - invert_lower consts x = None - /\ invert_upper consts x = Some y - /\ interp_scalar y >> half_bits = interp_scalar x). - Proof. - induction 1; intros; cbn; rewrite ?Z.eqb_refl; cbn. - { left. eexists; repeat split; auto. - rewrite interp_cast_noop; [ reflexivity | ]. - apply has_half_word_range_land with (r:=get_range x); auto. - apply has_range_interp_scalar; extract_ok_scalar. } - { right. eexists; repeat split; auto. - rewrite interp_cast_noop; [ reflexivity | ]. - apply has_half_word_range_shiftr with (r:=get_range x); auto. - apply has_range_interp_scalar; extract_ok_scalar. } - { match goal with H : constant_to_scalar _ _ = Some _ |- _ => - rewrite H; - let P := fresh in - destruct (constant_to_scalar_cases _ _ H) as [ [? [? ?] ] | [? [? ?] ] ]; - subst; cbn; rewrite ?Z.eqb_refl; cbn - end. - { left; eexists; repeat split; auto. - erewrite <-constant_to_scalar_correct by eassumption. - subst. cbn. - rewrite interp_cast_noop; [ reflexivity | ]. - eapply has_half_word_range_land with (r:=word_range); auto. - cbv [in_word_range is_tighter_than_bool]. - rewrite !Z.leb_refl; reflexivity. } - { right; eexists; repeat split; auto. - erewrite <-constant_to_scalar_correct by eassumption. - subst. cbn. - rewrite interp_cast_noop; [ reflexivity | ]. - eapply has_half_word_range_shiftr with (r:=word_range); auto. - cbv [in_word_range is_tighter_than_bool]. - rewrite !Z.leb_refl; reflexivity. } } - Qed. - - Lemma halved_mul_range x y : - ok_scalar (Pair x y) -> - is_halved x -> - is_halved y -> - 0 <= interp_scalar x * interp_scalar y < wordmax. - Proof. - intro Hok; invert Hok. intros. - repeat match goal with H : _ |- _ => apply is_halved_has_range in H; [|assumption] end. - cbv [has_range lower upper] in *. - pose proof half_bits_squared. nia. - Qed. - - Lemma of_straightline_ident_mul_correct r t x y g : - is_halved x -> - is_halved y -> - ok_scalar (Pair x y) -> - (word_range <=? r)%zrange = true -> - @has_range type.Z word_range (ident.interp ident.Z.mul (interp_scalar (Pair x y))) -> - @interp interp_cast _ (of_straightline_ident dummy_arrow consts ident.Z.mul t r (Pair x y) g) = - @interp interp_cast _ (g (ident.interp ident.Z.mul (interp_scalar (Pair x y)))). - Proof. - intros Hx Hy Hok ? ?; invert Hok; cbn [interp_scalar of_straightline_ident]; - destruct (is_halved_cases x Hx ltac:(assumption)) as [ [? [Pxlow [Pxhigh Pxi] ] ] | [? [Pxlow [Pxhigh Pxi] ] ] ]; - rewrite ?Pxlow, ?Pxhigh; - destruct (is_halved_cases y Hy ltac:(assumption)) as [ [? [Pylow [Pyhigh Pyi] ] ] | [? [Pylow [Pyhigh Pyi] ] ] ]; - rewrite ?Pylow, ?Pyhigh; - cbn; rewrite Pxi, Pyi; assert (0 <= interp_scalar x * interp_scalar y < wordmax) by (auto using halved_mul_range); - rewrite interp_cast_noop by (cbv [is_tighter_than_bool] in *; cbn [has_range upper lower] in *; rewrite andb_true_iff in *; intuition; Z.ltb_to_lt; lia); reflexivity. - Qed. - - Lemma has_word_range_mod_small x: - @has_range type.Z word_range x -> - x mod wordmax = x. - Proof. - cbv [has_range upper lower]. - intros. apply Z.mod_small; omega. - Qed. - - Lemma half_word_range_le_word_range r : - upper r = wordmax_half_bits - 1 -> - lower r = 0 -> - (r <=? word_range)%zrange = true. - Proof. - pose proof wordmax_half_bits_le_wordmax. - destruct r; cbv [is_tighter_than_bool ZRange.lower ZRange.upper]. - intros; subst. - apply andb_true_iff; split; Z.ltb_to_lt; lia. - Qed. - - Lemma and_shiftl_half_bits_eq x : - (x &' (wordmax_half_bits - 1)) << half_bits = x << half_bits mod wordmax. - Proof. - rewrite ones_half_bits. - rewrite Z.land_ones, !Z.shiftl_mul_pow2 by auto using half_bits_nonneg. - rewrite <-wordmax_half_bits_squared. - subst wordmax_half_bits. - rewrite Z.mul_mod_distr_r_full. - reflexivity. - Qed. - - Lemma in_word_range_word_range : in_word_range word_range. - Proof. - cbv [in_word_range is_tighter_than_bool]. - rewrite !Z.leb_refl; reflexivity. - Qed. - - Lemma invert_shift_correct (s : scalar type.Z) x imm : - ok_scalar s -> - invert_shift consts s = Some (x, imm) -> - interp_scalar s = (interp_scalar x << imm) mod wordmax. - Proof. - intros Hok ?; invert Hok; - try match goal with H : ok_scalar ?x, H' : context[Cast _ ?x] |- _ => - invert H end; - try match goal with H : ok_scalar ?x, H' : context[Shiftl _ ?x] |- _ => - invert H end; - try match goal with H : ok_scalar ?x, H' : context[Shiftl _ (Cast _ ?x)] |- _ => - invert H end; - try (cbn [invert_shift invert_upper invert_upper'] in *; discriminate); - repeat match goal with - | _ => progress (cbn [invert_shift invert_lower invert_lower' invert_upper invert_upper' interp_scalar fst snd] in * ) - | _ => rewrite interp_cast_noop by eauto using has_half_word_range_land, has_half_word_range_shiftr, in_word_range_word_range, has_range_loosen - | H : ok_scalar (Shiftr _ _) |- _ => apply has_range_interp_scalar in H - | H : ok_scalar (Shiftl _ _) |- _ => apply has_range_interp_scalar in H - | H : ok_scalar (Land _ _) |- _ => apply has_range_interp_scalar in H - | H : context [if ?x then _ else _] |- _ => - let Heq := fresh in case_eq x; intro Heq; rewrite Heq in H - | H : context [match @constant_to_scalar ?v ?consts ?x with _ => _ end] |- _ => - let Heq := fresh in - case_eq (@constant_to_scalar v consts x); intros until 0; intro Heq; rewrite Heq in *; [|discriminate]; - destruct (constant_to_scalar_cases _ _ Heq) as [ [? [? ?] ] | [? [? ?] ] ]; subst; - pose proof (ok_scalar_constant_to_scalar _ _ Heq) - | H : constant_to_scalar _ _ = Some _ |- _ => erewrite <-(constant_to_scalar_correct _ _ H) - | H : _ |- _ => rewrite andb_true_iff in H; destruct H; Z.ltb_to_lt - | H : Some _ = Some _ |- _ => progress (invert H) - | _ => rewrite has_word_range_mod_small by eauto using has_range_loosen, half_word_range_le_word_range - | _ => rewrite has_word_range_mod_small by - (eapply has_range_loosen with (r1:=half_word_range); - [ eapply has_half_word_range_shiftr with (r:=word_range) | ]; - eauto using in_word_range_word_range, half_word_range_le_word_range) - | _ => rewrite and_shiftl_half_bits_eq - | _ => progress subst - | _ => reflexivity - | _ => discriminate - end. - Qed. - - Local Ltac solve_commutative_replace := - match goal with - | |- @eq (_ * _) ?x ?y => - replace x with (fst x, snd x) by (destruct x; reflexivity); - replace y with (fst y, snd y) by (destruct y; reflexivity) - end; autorewrite with to_div_mod; solve [repeat (f_equal; try ring)]. - - Fixpoint is_tighter_than_bool_range_type t : range_type t -> range_type t -> bool := - match t with - | type.type_primitive type.Z => (fun r1 r2 => (r1 <=? r2)%zrange) - | type.prod a b => fun r1 r2 => - (is_tighter_than_bool_range_type a (fst r1) (fst r2)) - && (is_tighter_than_bool_range_type b (snd r1) (snd r2)) - | _ => fun _ _ => true - end. - - Definition range_ok {t} : range_type t -> Prop := - match t with - | type.type_primitive type.Z => fun r => in_word_range r - | type.prod type.Z type.Z => fun r => in_word_range (fst r) /\ snd r = flag_range - | _ => fun _ => False - end. - - Lemma of_straightline_ident_correct s d t x r r' (idc : ident.ident s d) g : - ok_ident s d x r idc -> - range_ok r' -> - is_tighter_than_bool_range_type d r r' = true -> - ok_scalar x -> - @interp interp_cast _ (of_straightline_ident dummy_arrow consts idc t r' x g) = - @interp interp_cast _ (g (ident.interp idc (interp_scalar x))). - Proof. - intros. - pose proof wordmax_half_bits_pos. - pose proof (ident_interp_has_range _ _ x r idc ltac:(assumption) ltac:(assumption)). - match goal with H : ok_ident _ _ _ _ _ |- _ => induction H end; - try solve [auto using of_straightline_ident_mul_correct]; - cbv [is_tighter_than_bool_range_type is_tighter_than_bool range_ok] in *; - cbn [of_straightline_ident ident.interp ident.gen_interp - invert_selm invert_sell] in *; - intros; rewrite ?Z.eqb_refl; cbn [andb]; - try match goal with |- context [invert_shift] => break_match end; - cbn [interp interp_ident]; try destruct_scalar; - repeat match goal with - | _ => progress (cbn [fst snd interp_scalar] in * ) - | _ => progress break_match; [ ] - | _ => progress autorewrite with zsimplify_fast - | _ => progress Z.ltb_to_lt - | H : _ /\ _ |- _ => destruct H - | _ => rewrite andb_true_iff in * - | _ => rewrite interp_cast_noop with (r:=flag_range) in * - by (apply has_flag_range_cc_m'; auto; extract_ok_scalar) - | _ => rewrite interp_cast_noop with (r:=flag_range) in * - by (apply has_flag_range_land'; auto; extract_ok_scalar) - | H : _ = (_,_) |- _ => progress (inversion H; subst) - | H : invert_shift _ _ = Some _ |- _ => - apply invert_shift_correct in H; [|extract_ok_scalar]; - rewrite <-H - | H : has_range ?r (?f ?x ?y) |- context [?f ?y ?x] => - replace (f y x) with (f x y) by solve_commutative_replace - | _ => rewrite has_word_range_mod_small - by (eapply has_range_loosen; - [apply has_range_interp_scalar; extract_ok_scalar|]; - assumption) - | _ => rewrite interp_cast_noop by (cbn [has_range fst snd] in *; split; lia) - | _ => rewrite interp_cast2_noop by (cbn [has_range fst snd] in *; split; lia) - | _ => reflexivity - end. - Qed. - - Lemma of_straightline_correct {t} (e : expr t) : - ok_expr e -> - @interp interp_cast _ (of_straightline dummy_arrow consts e) - = Straightline.expr.interp (interp_ident:=@ident.interp) (interp_cast:=interp_cast) e. - Proof. - induction 1; cbn [of_straightline]; intros; - repeat match goal with - | _ => progress cbn [Straightline.expr.interp] - | _ => erewrite of_straightline_ident_correct - by (cbv [range_ok is_tighter_than_bool_range_type]; - eauto using in_word_range_word_range; - try apply andb_true_iff; auto) - | _ => rewrite interp_cast_noop by eauto using has_range_loosen, ident_interp_has_range - | _ => rewrite interp_cast2_noop by eauto using has_range_loosen, ident_interp_has_range - | H : forall y, has_range _ y -> interp _ = _ |- _ => rewrite H by eauto using has_range_loosen, ident_interp_has_range - | _ => reflexivity - end. - Qed. - End proofs. - - Section no_interp_cast. - Context (dummy_arrow : forall s d, type.interp (s -> d)%ctype) (consts : list Z) - (consts_ok : forall x, In x consts -> 0 <= x <= wordmax - 1). - - Local Arguments interp _ {_} _. - Local Arguments interp_scalar _ {_} _. - - Local Ltac tighter_than_to_le := - repeat match goal with - | _ => progress (cbv [is_tighter_than_bool] in * ) - | _ => rewrite andb_true_iff in * - | H : _ /\ _ |- _ => destruct H - end; Z.ltb_to_lt. - - Lemma replace_interp_cast_scalar {t} (x : scalar t) interp_cast interp_cast' - (interp_cast_correct : forall r x, lower r <= x <= upper r -> interp_cast r x = x) - (interp_cast'_correct : forall r x, lower r <= x <= upper r -> interp_cast' r x = x) : - ok_scalar x -> - interp_scalar interp_cast x = interp_scalar interp_cast' x. - Proof. - induction 1; cbn [interp_scalar Straightline.expr.interp_scalar]; - repeat match goal with - | _ => progress (cbv [has_range interp_cast2] in * ) - | _ => progress tighter_than_to_le - | H : ok_scalar _ |- _ => apply (has_range_interp_scalar (interp_cast_correct:=interp_cast_correct)) in H - | _ => rewrite <-IHok_scalar - | _ => rewrite interp_cast_correct by omega - | _ => rewrite interp_cast'_correct by omega - | _ => congruence - end. - Qed. - - Lemma replace_interp_cast {t} (e : expr t) interp_cast interp_cast' - (interp_cast_correct : forall r x, lower r <= x <= upper r -> interp_cast r x = x) - (interp_cast'_correct : forall r x, lower r <= x <= upper r -> interp_cast' r x = x) : - ok_expr consts e -> - interp interp_cast (of_straightline dummy_arrow consts e) = - interp interp_cast' (of_straightline dummy_arrow consts e). - Proof. - induction 1; intros; cbn [of_straightline interp]. - { apply replace_interp_cast_scalar; auto. } - { erewrite !of_straightline_ident_correct by (eauto; cbv [range_ok]; apply in_word_range_word_range). - rewrite replace_interp_cast_scalar with (interp_cast'0:=interp_cast') by auto. - eauto using ident_interp_has_range. } - { erewrite !of_straightline_ident_correct by - (eauto; try solve [cbv [range_ok]; split; auto using in_word_range_word_range]; - cbv [is_tighter_than_bool_range_type]; apply andb_true_iff; split; auto). - rewrite replace_interp_cast_scalar with (interp_cast'0:=interp_cast') by auto. - eauto using ident_interp_has_range. } - Qed. - End no_interp_cast. -*) - End with_wordmax. -(* - Definition of_Expr {s d} (log2wordmax : Z) (consts : list Z) (e : Expr (s -> d)) - (var : type -> Type) (x : var s) dummy_arrow : @Straightline.expr.expr var ident d := - @of_straightline log2wordmax var dummy_arrow consts _ (Straightline.of_Expr e var x dummy_arrow). -*) - Definition interp_cast_mod w r x := if (lower r =? 0) - then if (upper r =? 2^w - 1) - then x mod (2^w) - else if (upper r =? 1) - then x mod 2 - else x - else x. - - Lemma interp_cast_mod_correct w r x : - lower r <= x <= upper r -> - interp_cast_mod w r x = x. - Proof. - cbv [interp_cast_mod]. - intros; break_match; rewrite ?andb_true_iff in *; intuition; Z.ltb_to_lt; - apply Z.mod_small; omega. - Qed. -(* - Lemma of_Expr_correct {s d} (log2wordmax : Z) (consts : list Z) (e : Expr (s -> d)) - (e' : (type.interp s -> Uncurried.expr.expr d)) - (x : type.interp s) dummy_arrow : - e type.interp = Abs e' -> - 1 < log2wordmax -> - log2wordmax mod 2 = 0 -> - Straightline.expr.ok_expr (e' x) -> - (forall x0 : Z, In x0 consts -> 0 <= x0 <= 2 ^ log2wordmax - 1) -> - ok_expr log2wordmax consts - (of_uncurried (dummy_arrow:=dummy_arrow) (depth (fun _ : type => unit) (fun _ : type => tt) (e _)) (e' x)) -> - (depth type.interp (@DefaultValue.type.default) (e' x) <= depth (fun _ : type => unit) (fun _ : type => tt) (e _))%nat -> - @interp log2wordmax (interp_cast_mod log2wordmax) _ (of_Expr log2wordmax consts e type.interp x dummy_arrow) = @Uncurried.expr.interp _ (@ident.interp) _ (e type.interp) x. - Proof. - intro He'; intros; cbv [of_Expr Straightline.of_Expr]. - rewrite He'; cbn [invert_Abs expr.interp]. - assert (forall r z, lower r <= z <= upper r -> ident.cast ident.cast_outside_of_range r z = z) as interp_cast_correct. - { cbv [ident.cast]; intros; break_match; rewrite ?andb_true_iff, ?andb_false_iff in *; intuition; Z.ltb_to_lt; omega. } - erewrite replace_interp_cast with (interp_cast':=ident.cast ident.cast_outside_of_range) by auto using interp_cast_mod_correct. - rewrite of_straightline_correct by auto. - erewrite Straightline.expr.of_uncurried_correct by eassumption. - reflexivity. - Qed. -*) - Notation LetInAppIdentZ S D r eidc x f - := (expr.LetIn - (A:=type.base (base.type.type_base base.type.Z)) - (B:=type.base D) - (expr.App - (s:=type.base (base.type.type_base base.type.Z)) - (d:=type.base (base.type.type_base base.type.Z)) - (expr.Ident (ident.Z_cast r)) - (expr.App - (s:=type.base S) - (d:=type.base (base.type.type_base base.type.Z)) - eidc - x)) - f). - Notation LetInAppIdentZZ S D r eidc x f - := (expr.LetIn - (A:=type.base (base.type.prod (base.type.type_base base.type.Z) (base.type.type_base base.type.Z))) - (B:=type.base D) - (expr.App - (s:=type.base (base.type.prod (base.type.type_base base.type.Z) (base.type.type_base base.type.Z))) - (d:=type.base (base.type.prod (base.type.type_base base.type.Z) (base.type.type_base base.type.Z))) - (expr.Ident (ident.Z_cast2 r)) - (expr.App - (s:=type.base S) - (d:=type.base (base.type.prod (base.type.type_base base.type.Z) (base.type.type_base base.type.Z))) - eidc - x)) - f). - Module Notations. - Import PrintingNotations. - (*Import Straightline.expr.*) - - Local Open Scope expr_scope. - Local Notation "'tZ'" := (base.type.type_base base.type.Z). - Notation "'RegZero'" := (expr.Ident (ident.Literal 0)). - Notation "$ x" := (#(ident.Z_cast uint256) @ (#ident.fst @ (#(ident.Z_cast2 (uint256,bool)%core) @ (expr.Var x)))) (at level 10, format "$ x"). - Notation "$ x" := (#(ident.Z_cast uint128) @ (#ident.fst @ (#(ident.Z_cast2 (uint128,bool)%core) @ (expr.Var x)))) (at level 10, format "$ x"). - Notation "$ x ₁" := (#(ident.Z_cast uint256) @ (#ident.fst @ (expr.Var x))) (at level 10, format "$ x ₁"). - Notation "$ x ₂" := (#(ident.Z_cast uint256) @ (#ident.snd @ (expr.Var x))) (at level 10, format "$ x ₂"). - Notation "$ x" := (#(ident.Z_cast uint256) @ (expr.Var x)) (at level 10, format "$ x"). - Notation "$ x" := (#(ident.Z_cast uint128) @ (expr.Var x)) (at level 10, format "$ x"). - Notation "$ x" := (#(ident.Z_cast bool) @ (expr.Var x)) (at level 10, format "$ x"). - Notation "carry{ $ x }" := (#(ident.Z_cast bool) @ (#ident.snd @ (#(ident.Z_cast2 (uint256, bool)%core) @ (expr.Var x)))) - (at level 10, format "carry{ $ x }"). - Notation "Lower{ x }" := (#(ident.Z_cast uint128) @ (#(ident.Z_land 340282366920938463463374607431768211455) @ x)) - (at level 10, format "Lower{ x }"). - Notation "f @( y , x1 , x2 ); g " - := (LetInAppIdentZZ _ _ (uint256, bool)%core f (x1, x2) (fun y => g)) - (at level 10, g at level 200, format "f @( y , x1 , x2 ); '//' g "). - Notation "f @( y , x1 , x2 , x3 ); g " - := (LetInAppIdentZZ _ _ (uint256, bool)%core f (#ident.pair @ (#ident.pair @ x1 @ x2) @ x3) (fun y => g)) - (at level 10, g at level 200, format "f @( y , x1 , x2 , x3 ); '//' g "). - Notation "f @( y , x1 , x2 , x3 ); '#128' g " - := (LetInAppIdentZZ _ _ (uint128, bool)%core f (#ident.pair @ (#ident.pair @ x1 @ x2) @ x3) (fun y => g)) - (at level 10, g at level 200, format "f @( y , x1 , x2 , x3 ); '#128' '//' g "). - Notation "f @( y , x1 , x2 ); g " - := (LetInAppIdentZ _ _ uint256 f (#ident.pair @ x1 @ x2) (fun y => g)) - (at level 10, g at level 200, format "f @( y , x1 , x2 ); '//' g "). - Notation "f @( y , x1 , x2 , x3 ); g " - := (LetInAppIdentZ _ _ uint256 f (#ident.pair @ (#ident.pair @ x1 x2) x3) (fun y => g)) - (at level 10, g at level 200, format "f @( y , x1 , x2 , x3 ); '//' g "). - (* special cases for when the ident constructor takes a constant argument *) - Notation "add@( y , x1 , x2 , n ); g" - := (LetInAppIdentZZ _ _ (uint256, bool) (#(ident.fancy_add 256 n)) (#ident.pair @ x1 x2) (fun y => g)) - (at level 10, g at level 200, format "add@( y , x1 , x2 , n ); '//' g"). - Notation "addc@( y , x1 , x2 , x3 , n ); g" - := (LetInAppIdentZZ _ _ (uint256, bool) (#(ident.fancy_addc 256 n)) (#ident.pair @ (#ident.pair @ x1 x2) x3) (fun y => g)) - (at level 10, g at level 200, format "addc@( y , x1 , x2 , x3 , n ); '//' g"). - Notation "addc@( y , x1 , x2 , x3 , n ); '#128' g" - := (LetInAppIdentZZ _ _ (uint128, bool) (#(ident.fancy_addc 256 n)) (#ident.pair @ (#ident.pair @ x1 x2) x3) (fun y => g)) - (at level 10, g at level 200, format "addc@( y , x1 , x2 , x3 , n ); '#128' '//' g"). - Notation "sub@( y , x1 , x2 , n ); g" - := (LetInAppIdentZZ _ _ (uint256, bool) (#(ident.fancy_sub 256 n)) (#ident.pair @ x1 x2) (fun y => g)) - (at level 10, g at level 200, format "sub@( y , x1 , x2 , n ); '//' g"). - Notation "subb@( y , x1 , x2 , x3 , n ); g" - := (LetInAppIdentZZ _ _ (uint256, bool) (#(ident.fancy_subb 256 n)) (#ident.pair @ (#ident.pair @ x1 x2) x3) (fun y => g)) - (at level 10, g at level 200, format "subb@( y , x1 , x2 , x3 , n ); '//' g"). - Notation "rshi@( y , x1 , x2 , n ); g" - := (LetInAppIdentZ _ _ _ (#(ident.fancy_rshi 256 n)) (#ident.pair @ x1 x2) (fun y => g)) - (at level 10, g at level 200, format "rshi@( y , x1 , x2 , n ); '//' g "). - (*Notation "'ret' $ x" := (Scalar (expr.Var x)) (at level 10, format "'ret' $ x").*) - Notation "( x , y )" := (#ident.pair @ x @ y) (at level 10, left associativity). - End Notations. -(* - Module Tactics. - Ltac ok_expr_step' := - match goal with - | _ => assumption - | |- _ <= _ <= _ \/ @eq zrange _ _ => - right; lazy; try split; congruence - | |- _ <= _ <= _ \/ @eq zrange _ _ => - left; lazy; try split; congruence - | |- context [PreFancy.ok_ident] => constructor - | |- context [PreFancy.ok_scalar] => constructor; try omega - | |- context [PreFancy.is_halved] => eapply PreFancy.is_halved_constant; [lazy; reflexivity | ] - | |- context [PreFancy.is_halved] => constructor - | |- context [PreFancy.in_word_range] => lazy; reflexivity - | |- context [PreFancy.in_flag_range] => lazy; reflexivity - | |- context [PreFancy.get_range] => - cbn [PreFancy.get_range lower upper fst snd ZRange.map] - | x : type.interp (type.prod _ _) |- _ => destruct x - | |- (_ <=? _)%zrange = true => - match goal with - | |- context [PreFancy.get_range_var] => - cbv [is_tighter_than_bool PreFancy.has_range fst snd upper lower] in *; cbn; - apply andb_true_iff; split; apply Z.leb_le - | _ => lazy - end; omega || reflexivity - | |- @eq zrange _ _ => lazy; reflexivity - | |- _ <= _ => omega - | |- _ <= _ <= _ => omega - end; intros. - - Ltac ok_expr_step := - match goal with - | |- context [PreFancy.ok_expr] => constructor; cbn [fst snd]; repeat ok_expr_step' - end; intros; cbn [Nat.max]. - End Tactics. - *) - Notation interp w := (@expr.interp base.type ident.ident base.interp (@ident.gen_interp (PreFancy.interp_cast_mod w))). - Notation Interp w := (@expr.Interp base.type ident.ident base.interp (@ident.gen_interp (PreFancy.interp_cast_mod w))). -End PreFancy. - *) - Module Fancy. Module CC. @@ -3299,85 +2095,6 @@ Module ProdEquiv. end. End ProdEquiv. -(* TODO : delete -(* Lemmas to help prove that a fancy and prefancy expression have the -same meaning -- should be replaced eventually with a proof of fancy -passes in general. *) - -Module Fancy_PreFancy_Equiv. - Import LanguageWf.Compilers. - Import ZRange.Operations. - Import Fancy.Registers. - - Lemma interp_cast_mod_eq w u x: 1 <= 2^w -> u = 2^w - 1 -> ident.cast (PreFancy.interp_cast_mod w) r[0 ~> u] x = x mod 2^w. - Proof. - cbv [PreFancy.interp_cast_mod]; intros. - rewrite ident.cast_out_of_bounds_simple_0; cbn [lower upper]; subst; - rewrite ?Z.eqb_refl; intros. - all: Z.rewrite_mod_small; Z.div_mod_to_quot_rem; auto with zarith. - Qed. - Lemma interp_cast_mod_flag w x: ident.cast (PreFancy.interp_cast_mod w) r[0 ~> 1] x = x mod 2. - Proof. - cbv [PreFancy.interp_cast_mod]. - rewrite ident.cast_out_of_bounds_simple_0_mod; cbn [lower upper]; subst; - rewrite ?Z.eqb_refl; intros. - all: break_match; Bool.split_andb; Z.ltb_to_lt; Z.rewrite_mod_small; subst; try omega. - replace (2^w) with 2 by omega. - Z.rewrite_mod_small; reflexivity. - Qed. - - Lemma interp_equivZ {s} w u (Hw : 1 <= 2^w) (Hu : u = 2^w-1) i rd regs e cc ctx idc args f : - (Fancy.spec i (Tuple.map ctx regs) cc - = ident.gen_interp (PreFancy.interp_cast_mod w) (t:=type.arrow _ base.type.Z) idc (PreFancy.interp w args)) -> - ( let r := Fancy.spec i (Tuple.map ctx regs) cc in - Fancy.interp reg_eqb (2 ^ w) Fancy.cc_spec e - (Fancy.CC.update (Fancy.writes_conditions i) r Fancy.cc_spec cc) - (fun n : register => if reg_eqb n rd then r mod 2 ^ w else ctx n) = - @PreFancy.interp w base.type.Z (f (r mod 2 ^ w))) -> - Fancy.interp reg_eqb (2^w) Fancy.cc_spec (Fancy.Instr i rd regs e) cc ctx - = @PreFancy.interp w base.type.Z - (@PreFancy.LetInAppIdentZ s _ (r[0~>2^w-1])%zrange (#idc) args f). - Proof. - cbv zeta; intros spec_eq next_eq. - cbn [Fancy.interp PreFancy.interp]. - cbv [Let_In]. - rewrite next_eq. - cbn in *. - rewrite <-spec_eq. - rewrite interp_cast_mod_eq by omega. - reflexivity. - Qed. - - Lemma interp_equivZZ {s} w (Hw : 2 < 2 ^ w) u (Hu : u = 2^w - 1) i rd regs e cc ctx idc args f : - ((Fancy.spec i (Tuple.map ctx regs) cc) mod 2 ^ w - = fst (ident.gen_interp (PreFancy.interp_cast_mod w) (t:=type.arrow _ (base.type.Z*base.type.Z)) idc (PreFancy.interp w args))) -> - ((if Fancy.cc_spec Fancy.CC.C(Fancy.spec i (Tuple.map ctx regs) cc) then 1 else 0) - = snd (ident.gen_interp (PreFancy.interp_cast_mod w) (t:=type.arrow _ (base.type.Z*base.type.Z)) idc (PreFancy.interp w args)) mod 2) -> - ( let r := Fancy.spec i (Tuple.map ctx regs) cc in - Fancy.interp reg_eqb (2 ^ w) Fancy.cc_spec e - (Fancy.CC.update (Fancy.writes_conditions i) r Fancy.cc_spec cc) - (fun n : register => if reg_eqb n rd then r mod 2 ^ w else ctx n) = - @PreFancy.interp w base.type.Z - (f (r mod 2 ^ w, if (Fancy.cc_spec Fancy.CC.C r) then 1 else 0))) -> - Fancy.interp reg_eqb (2^w) Fancy.cc_spec (Fancy.Instr i rd regs e) cc ctx - = @PreFancy.interp w base.type.Z - (@PreFancy.LetInAppIdentZZ s _ (r[0~>u], r[0~>1])%zrange (#idc) args f). - Proof. - cbv zeta; intros spec_eq1 spec_eq2 next_eq. - cbn [Fancy.interp PreFancy.interp]. - cbv [Let_In]. - cbn [ident.gen_interp]; Prod.eta_expand. - rewrite next_eq. - rewrite interp_cast_mod_eq by omega. - rewrite interp_cast_mod_flag by omega. - cbn -[Fancy.cc_spec] in *. - rewrite <-spec_eq1, <-spec_eq2. - rewrite Z.mod_mod by omega. - reflexivity. - Qed. -End Fancy_PreFancy_Equiv. -*) - Module Barrett256. Import LanguageWf.Compilers. |