Skip to content

Commit d4e1a81

Browse files
Unobjectionable rewrite rules for saturated arithmetic
For mit-plv#1609 We don't yet include the ones that are higher-order-than 3, those need more debugging. Co-authored-by: Andres Erbsen <[email protected]>
1 parent d839f89 commit d4e1a81

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

src/Rewriter/Rules.v

+32
Original file line numberDiff line numberDiff line change
@@ -288,18 +288,35 @@ Definition arith_rewrite_rulesT (max_const_val : Z) : list (bool * Prop)
288288
; (forall s y x,
289289
Z.add_get_carry_full s (- y) x
290290
= dlet vb := Z.sub_get_borrow_full s x y in (fst vb, - snd vb))
291+
; (forall s y x k,
292+
Z.add_get_carry_full s x (-y * k)
293+
= dlet vb := Z.sub_get_borrow_full s x (y * k) in (fst vb, - snd vb))
294+
; (forall s y x k,
295+
Z.add_get_carry_full s (-y * k) x
296+
= dlet vb := Z.sub_get_borrow_full s x (y * k) in (fst vb, - snd vb))
291297
; (forall s y x,
292298
Z.add_with_get_carry_full s 0 x (- y)
293299
= dlet vb := Z.sub_get_borrow_full s x y in (fst vb, - snd vb))
294300
; (forall s y x,
295301
Z.add_with_get_carry_full s 0 (- y) x
296302
= dlet vb := Z.sub_get_borrow_full s x y in (fst vb, - snd vb))
303+
304+
; (forall s c x,
305+
Z.add_with_get_carry_full s (- c) x 0
306+
= dlet vb := Z.sub_with_get_borrow_full s c x 0 in (fst vb, - snd vb))
307+
297308
; (forall s c y x,
298309
Z.add_with_get_carry_full s (- c) (- y) x
299310
= dlet vb := Z.sub_with_get_borrow_full s c x y in (fst vb, - snd vb))
300311
; (forall s c y x,
301312
Z.add_with_get_carry_full s (- c) x (- y)
302313
= dlet vb := Z.sub_with_get_borrow_full s c x y in (fst vb, - snd vb))
314+
; (forall s c y x k,
315+
Z.add_with_get_carry_full s c x (-y * k)
316+
= dlet vb := Z.sub_with_get_borrow_full s (-c) x (y * k) in (fst vb, - snd vb))
317+
; (forall s c y x k,
318+
Z.add_with_get_carry_full s c (-y * k) x
319+
= dlet vb := Z.sub_with_get_borrow_full s (-c) x (y * k) in (fst vb, - snd vb))
303320
; (forall b x, (* inline negation when the rewriter wouldn't already inline it *)
304321
ident.gets_inlined b x = false
305322
-> -x = dlet v := x in -v)
@@ -395,6 +412,16 @@ Definition arith_with_casts_rewrite_rulesT (adc_no_carry_to_add : bool) : list (
395412
y ∈ ry -> y = Z.ones (Z.succ (Z.log2 y))
396413
-> cstZ rv (cstZ ry ('y) &' cstZ rx x) = cstZ rx x)
397414
]%Z%zrange
415+
; mymap
416+
do_again
417+
[ (forall x y, cstZ r[0~>1] x * y = Z.zselect (cstZ r[0~>1] x) (cstZ r[0~>0] (' 0)) y)
418+
; (forall x y, y * cstZ r[0~>1] x = Z.zselect (cstZ r[0~>1] x) (cstZ r[0~>0] (' 0)) y)
419+
; (forall c M rv r0 rM, 0 ∈ r0 -> M ∈ rM -> M ∈ rv -> 2^Z.log2 (M+1) = M + 1 -> 1 <= M ->
420+
cstZ rv (Z.zselect (cstZ r[0~>1] c) (cstZ r0 ('0)) (cstZ rM ('M)))
421+
= (dlet vc := cstZZ rv r[0~>1] (Z.sub_with_get_borrow_full ('(M+1)) (cstZ r[0~>1] c) 0 0) in
422+
cstZ rv (fst vc)))
423+
; (forall rv c x y, cstZ rv (Z.zselect c x y) = dlet v := cstZ rv (Z.zselect c x y) in cstZ rv v)
424+
]
398425
; mymap
399426
do_again
400427
[ (* [do_again], so that we can trigger add/sub rules on the output *)
@@ -415,6 +442,11 @@ Definition arith_with_casts_rewrite_rulesT (adc_no_carry_to_add : bool) : list (
415442
adc_no_carry_to_add = true -> s ∈ rs -> (n rx - n ry - n rc <= r[0~>s-1])%zrange
416443
-> cstZZ rv r[0~>0] (Z.sub_with_get_borrow_full (cstZ rs ('s)) (cstZ rc c) (cstZ rx x) (cstZ ry y))
417444
= (cstZ rv (cstZ rx x - cstZ ry y - cstZ rc c), (cstZ r[0~>0] ('0))))
445+
(* 0-0-c passes through the carry *)
446+
; (forall rv rs s c rx ry,
447+
s ∈ rs -> 0 ∈ rx -> 0 ∈ ry -> -1 / s = -1
448+
-> cstZZ rv r[0~>1] (Z.sub_with_get_borrow_full (cstZ rs ('s)) (cstZ r[0~>1] c) (cstZ rx ('0)) (cstZ ry ('0)))
449+
= (cstZ rv (-(cstZ r[0~>1]c) mod 's), (cstZ r[0~>1] c)))
418450
]%Z%zrange
419451
; mymap
420452
dont_do_again

src/Rewriter/RulesProofs.v

+14-3
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,13 @@ Local Ltac interp_good_t_step_arith :=
258258
=> cbv [Z.ltz];
259259
apply unfold_is_bounded_by_bool in Hx;
260260
apply unfold_is_bounded_by_bool in Hy
261+
| [ H : is_bounded_by_bool _ (ZRange.normalize r[0 ~> 1]) = true |- _ ]
262+
=> change (ZRange.normalize r[0 ~> 1]) with r[0 ~> 1]%zrange in *;
263+
cbv [is_bounded_by_bool] in H; cbn [upper lower] in H
264+
| [ H : ?x <> ?a, H' : ?a <= ?x |- _ ] => assert (a < x) by lia; clear H H'
265+
| [ H : 0 < ?x, H' : ?x <= 1 |- _ ] => assert (x = 1) by lia; clear H H'
266+
| [ H : ?x <= 1, H' : 0 <= ?x |- _ ] => assert (x = 0 \/ x = 1) by lia; clear H H'
267+
| [ H : ?x = Z.neg _ |- context[?x] ] => rewrite H
261268
| [ |- context[ident.cast r[0~>0] ?v] ]
262269
=> rewrite (ident.platform_specific_cast_0_is_mod 0 v) by reflexivity
263270
| [ H : ?x = Z.ones _ |- context [Z.land _ ?x] ] => rewrite H
@@ -283,6 +290,7 @@ Local Ltac interp_good_t_step_arith :=
283290
| progress destruct_head'_and
284291
| progress Z.ltb_to_lt
285292
| progress split_andb
293+
| progress change (0 - 1) with (-1) in *
286294
| match goal with
287295
| [ |- ?a mod ?b = ?a' mod ?b ] => apply f_equal2; lia
288296
| [ |- ?a / ?b = ?a' / ?b ] => apply f_equal2; lia
@@ -394,6 +402,9 @@ Local Ltac interp_good_t_step_arith :=
394402
=> tryif constr_eq x x' then fail else replace x with x' by lia
395403
| [ |- _ = _ :> BinInt.Z ] => progress autorewrite with zsimplify_fast
396404
end
405+
| match goal with
406+
| [ |- context[(- _) mod _] ] => rewrite Z.mod_opp_small by lia
407+
end
397408
| saturate_add_sub_bounds_step ].
398409

399410
Local Ltac remove_casts :=
@@ -598,17 +609,17 @@ Proof.
598609
-- rewrite <- Z.mod_divide_full. assumption.
599610
+ rewrite H2. apply Ones.Z.ones_nonneg. remember (Z.log2_nonneg (upper)). lia.
600611
+ lia.
601-
+ rewrite H2. apply Ones.Z.ones_nonneg. remember (Z.log2_nonneg (upper)). lia.
612+
+ rewrite H2. apply Ones.Z.ones_nonneg. remember (Z.log2_nonneg (upper)). lia.
602613
Qed.
603-
614+
604615
Lemma arith_with_relaxed_casts_rewrite_rules_proofs
605616
: PrimitiveHList.hlist (@snd bool Prop) arith_with_relaxed_casts_rewrite_rulesT.
606617
Proof using Type.
607618
start_proof; auto; intros; try lia.
608619
- apply relaxed_rules_work; assumption.
609620
- rewrite Z.land_comm. apply relaxed_rules_work; assumption.
610621
Qed.
611-
622+
612623
Lemma strip_literal_casts_rewrite_rules_proofs
613624
: PrimitiveHList.hlist (@snd bool Prop) strip_literal_casts_rewrite_rulesT.
614625
Proof using Type.

0 commit comments

Comments
 (0)