Require Import
Coqlib Integers
Utf8 DLib
LatticeSignatures AbEnvironment
AbNumDomain
IntervalDomain.
Instance: (signed) interval domain.
Definition botlift_backop {
A}
op (
x y:
A+⊥) :=
match x,
y with
|
NotBot x',
NotBot y' =>
op x'
y'
|
_,
_ => (@
Bot A, @
Bot A)
end.
Definition bb {
A B C} (
f:
A →
B →
C) (
a:
A) (
b:
B) :
C+⊥ :=
NotBot (
f a b).
Instance itv_num :
num_dom Interval.itv :=
Build_num_dom
Interval.signed_itv_adom
Interval.meet
Interval.signed
Interval.booleans
(
fun i s =>
NotBot (
match s with Signed =>
i |
Unsigned =>
Interval.reduc2unsigned i end))
(@
NotBot _ ∘
Interval.neg) (@
NotBot _ ∘
Interval.not)
(@
NotBot _ ∘
Interval.notbool)
(@
NotBot _ ∘
Interval.boolval)
(
bb Interval.add) (
bb Interval.sub)
(
bb Interval.mult) (
bb Interval.div) (
bb Interval.shl)
(
bb Interval.and) (
bb Interval.or)
(
bb Interval.xor)
(
fun m M x =>
Interval.is_in_interval (
Int.signed m) (
Int.signed M)
x)
Interval.backward_boolval
Interval.backward_notbool
Interval.backward_neg
Interval.backward_not
Interval.backward_add
Interval.backward_sub
Interval.backward_cmp
Interval.backward_cmpu
Interval.backward_and
Interval.backward_or
.
Instance itv_num_correct :
num_dom_correct itv_num.
Proof.
Instance: (unsigned) interval domain.
Module UInterval.
Import Interval.
Definition const (
i:
int) :
itv :=
ITV (
Int.unsigned i) (
Int.unsigned i).
Definition neg (
x:
itv) :
itv :=
if zeq 0 (
max x)
then x
else if zle (
min x) 0
then utop
else ITV (
Int.modulus -
max x) (
Int.modulus -
min x).
Definition repr (
x:
itv) :
itv :=
if x ⊑
utop then x else utop.
Definition add (
x y:
itv) :
itv :=
let m :=
min x +
min y in
let M :=
max x +
max y in
if zle m Int.max_unsigned
then if zle M Int.max_unsigned
then ITV m M
else utop
else ITV (
m -
Int.modulus) (
M -
Int.modulus).
Definition not (
x:
itv) :
itv :=
add (
neg x) (
ITV Int.max_unsigned Int.max_unsigned).
Definition sub (
x y:
itv) :
itv :=
repr (
ITV (
min x -
max y) (
max x -
min y)).
Definition notbool (
i:
itv) :
itv :=
if zlt 0 (
min i) ||
zlt (
max i) 0
then ITV 0 0
else if zeq 0 (
min i) &&
zeq 0 (
max i)
then ITV 1 1
else ITV 0 1.
Definition todo (
x y:
itv) :
itv :=
utop.
Definition back_id1 (
x y:
itv) :
itv+⊥ :=
NotBot x.
Definition back_id2 (
x y z:
itv) :
itv+⊥ *
itv+⊥ := (
NotBot x,
NotBot y).
Definition back_id_list (
x y z:
itv) :
list (
itv+⊥ *
itv+⊥) := (
NotBot x,
NotBot y)::
nil.
Definition backward_ltu (
i1 i2:
itv) :
itv+⊥ *
itv+⊥ :=
(
i1 ⊓ (
reduce 0 ((
max i2)-1)),
i2 ⊓ (
reduce ((
min i1)+1)
Int.max_unsigned)).
Definition backward_ne (
x y:
itv) :
itv+⊥ *
itv+⊥ :=
let '(
x',
y') :=
backward_ltu x y in
let '(
y'',
x'') :=
backward_ltu y x in
(
x' ⊔
x'',
y' ⊔
y'').
Definition backward_leu (
i1 i2:
itv) :
itv+⊥ *
itv+⊥ :=
(
i1 ⊓ (
reduce 0 (
max i2)),
i2 ⊓ (
reduce (
min i1)
Int.max_unsigned)).
Definition backward_cmpu (
c:
comparison) (
ab1 ab2 res:
itv) :
itv+⊥ *
itv+⊥ :=
match is_singleton res with
|
None => (
NotBot ab1,
NotBot ab2)
|
Some i =>
if Int.eq i Int.one then
match c with
|
Ceq =>
let ab :=
ab1 ⊓ (
NotBot ab2)
in (
ab,
ab)
|
Cne =>
backward_ne ab1 ab2
|
Clt =>
backward_ltu ab1 ab2
|
Cle =>
backward_leu ab1 ab2
|
Cgt =>
swap (
backward_ltu ab2 ab1)
|
Cge =>
swap (
backward_leu ab2 ab1)
end
else if Int.eq i Int.zero then
match c with
|
Ceq =>
backward_ne ab1 ab2
|
Cne =>
let ab :=
ab1 ⊓ (
NotBot ab2)
in (
ab,
ab)
|
Cge =>
backward_ltu ab1 ab2
|
Cgt =>
backward_leu ab1 ab2
|
Cle =>
swap (
backward_ltu ab2 ab1)
|
Clt =>
swap (
backward_leu ab2 ab1)
end
else (
NotBot ab1,
NotBot ab2)
end.
Instance itvu_num :
num_dom itv :=
Build_num_dom
unsigned_itv_adom
meet
const
booleans
(
fun i s =>
NotBot (
match s with Signed =>
reduc2signed i |
Unsigned =>
i end))
(@
NotBot _ ∘
neg) (@
NotBot _ ∘
not)
(@
NotBot _ ∘
notbool)
(@
NotBot _ ∘
boolval)
(
bb add) (
bb sub)
(
bb todo) (
bb todo)
(
bb todo) (
bb todo)
(
bb todo) (
bb todo)
(
fun _ _ _ =>
false)
back_id1 back_id1
back_id1 back_id1
back_id2 back_id2
(
fun _ =>
back_id2)
(
backward_cmpu)
back_id_list back_id_list
.
Lemma neg_correct: ∀
x i,
ugamma x i →
ugamma (
neg x) (
Int.neg i).
Proof.
Lemma reduce_correct (
m M:
Z) (
i:
int) :
m <=
Int.unsigned i <=
M →
γ (
reduce m M)
i.
Proof.
unfold reduce.
destruct zle. 2:
intuition.
simpl.
auto.
Qed.
Lemma add_correct x y i j:
ugamma x i →
ugamma y j →
ugamma (
add x y) (
Int.add i j).
Proof.
Lemma backward_ltu_correct x y i j :
γ
x i →
γ
y j →
Int.unsigned i <
Int.unsigned j →
let '(
u,
v) :=
backward_ltu x y in
γ
u i ∧ γ
v j.
Proof.
Lemma backward_ne_correct x y i j :
γ
x i →
γ
y j →
Int.unsigned i ≠
Int.unsigned j →
let '(
u,
v) :=
backward_ne x y in
γ
u i ∧ γ
v j.
Proof.
Lemma backward_leu_correct x y i j :
γ
x i →
γ
y j →
Int.unsigned i <=
Int.unsigned j →
let '(
u,
v) :=
backward_leu x y in
γ
u i ∧ γ
v j.
Proof.
Instance itvu_num_correct :
num_dom_correct itvu_num.
Proof.
split.
apply meet_correctu.
intros i.
split;
simpl;
apply Zle_refl.
simpl.
split;
simpl;
intuition.
simpl.
split;
simpl;
intuition.
split;
simpl.
apply reduc2signed_correct;
auto.
auto.
simpl.
intros a j (
i &
H & ->).
now apply neg_correct.
simpl.
intros a j (
i &
H & ->).
rewrite Int.not_neg.
unfold not.
apply add_correct.
apply neg_correct.
auto.
vm_compute.
split;
discriminate.
intros x i.
simpl.
unfold notbool,
of_bool.
intros (
A &
B).
generalize (
Int.eq_spec i Int.zero).
bif.
intros ->.
change (
Int.unsigned Int.zero)
with 0
in *.
repeat (
destruct zlt);
try now intuition.
simpl orb.
red.
repeat destruct zeq;
try now intuition.
intros H.
repeat destruct zlt;
try (
now intuition);
simpl orb;
red;
try (
vm_compute;
split;
discriminate).
repeat destruct zeq;
try now intuition.
absurd (
Int.unsigned i = 0).
intros K.
pose proof (
Int.repr_unsigned i)
as Q.
rewrite K in Q.
subst.
intuition.
intuition.
intros (
a &
b)
i.
simpl.
unfold boolval,
is_singleton.
destruct zeq.
subst.
intros [
A B].
generalize (
Int.eq_spec i Int.zero).
destruct Int.eq.
intros ->.
change (
Int.unsigned Int.zero)
with 0
in *.
assert (
b = 0).
simpl in *;
intuition.
subst.
vm_compute;
split;
discriminate.
intros K.
rewrite zeq_false.
vm_compute;
split;
discriminate.
intros H.
assert (
b =
Int.unsigned i).
simpl in *;
intuition.
pose proof (
Int.unsigned_range i).
subst.
simpl in *.
destruct i as (
i &
I).
unfold Int.unsigned in H.
rewrite Zmod_small in H;
auto.
simpl in H.
subst.
elim K.
unfold Int.zero,
Int.repr.
f_equal.
apply Axioms.proof_irr.
intros [
A B].
generalize (
Int.eq_spec i Int.zero).
destruct Int.eq.
intros ->.
simpl.
repeat destruct zle;
try now intuition.
apply bool_correct_zero.
intros _.
simpl.
bif.
apply bool_correct_one.
vm_compute;
split;
discriminate.
intros x y i (
u &
v &
A);
simpl in *.
intuition.
subst.
now apply add_correct.
intros x y i (
u &
v &
A &
B & ->).
destruct A as [
A A'].
destruct B as [
B B'].
simpl;
unfold sub,
repr,
Int.sub.
simpl.
destruct zle.
destruct zle.
unfold ugamma;
simpl.
rewrite Zmod_small.
omega.
unfold Int.max_unsigned in *.
intuition.
apply ugamma_top.
apply ugamma_top.
intros x y i (
u &
v &
A);
simpl in *;
intuition.
unfold todo.
apply ugamma_top.
intros x y i (
u &
v &
A);
simpl in *;
intuition.
unfold todo.
apply ugamma_top.
intros x y i (
u &
v &
A);
simpl in *;
intuition.
unfold todo.
apply ugamma_top.
intros x y i (
u &
v &
A);
simpl in *;
intuition.
unfold todo.
apply ugamma_top.
intros x y i (
u &
v &
A);
simpl in *;
intuition.
unfold todo.
apply ugamma_top.
intros x y i (
u &
v &
A);
simpl in *;
intuition.
unfold todo.
apply ugamma_top.
simpl.
intuition.
intros ? ? ?
H _;
exact H.
intros ? ? ?
H _;
exact H.
intros ? ? ?
H _;
exact H.
intros ? ? ?
H _;
exact H.
intros ? ? ? ? ?
H K _;
exact (
conj H K).
intros ? ? ? ? ?
H K _;
exact (
conj H K).
intros ? ? ? ? ? ?
H K _;
exact (
conj H K).
Opaque meet.
simpl.
unfold backward_cmpu.
intros c x y (
rl,
rr)
i j I J R.
unfold is_singleton.
simpl in I,
J,
R.
destruct zeq. 2:
simpl;
intuition.
subst.
generalize (
Int.eq_spec (
of_bool (
Int.cmpu c i j))
Int.one).
destruct Int.eq;
intros C.
autorw'.
assert (
rr = 1)
by (
destruct rr as [|
p|
p];
vm_compute in R;
try destruct p;
intuition).
subst.
clear R.
repeat red.
destruct c;
simpl in C.
generalize (
Int.eq_spec i j).
destruct Int.eq.
intros ->.
split;
simpl;
apply meet_correctu;
intuition.
discriminate.
generalize (
Int.eq_spec i j).
destruct Int.eq.
intros ->.
discriminate.
intros.
apply backward_ne_correct;
auto.
apply unsigned_inj;
auto.
unfold Int.ltu in C.
destruct zlt. 2:
discriminate.
eapply backward_ltu_correct;
auto.
unfold Int.ltu in C.
destruct zlt.
discriminate.
eapply backward_leu_correct;
auto.
intuition.
unfold Int.ltu in C.
destruct zlt. 2:
discriminate.
repeat red;
apply and_comm.
eapply backward_ltu_correct;
auto.
unfold Int.ltu in C.
destruct zlt.
discriminate.
repeat red;
apply and_comm.
eapply backward_leu_correct;
auto.
intuition.
assert (
rr = 0).
unfold of_bool in R.
destruct Int.cmpu.
elim C;
reflexivity.
destruct rr;
vm_compute in R;
intuition.
subst.
clear R.
repeat red.
destruct c;
simpl in C.
generalize (
Int.eq_spec i j).
destruct Int.eq.
intros ->.
elim C;
reflexivity.
intros.
apply backward_ne_correct;
auto.
apply unsigned_inj;
auto.
generalize (
Int.eq_spec i j).
destruct Int.eq.
intros ->.
simpl;
split;
apply meet_correctu;
intuition.
elim C.
reflexivity.
unfold Int.ltu in C.
destruct zlt.
elim C;
reflexivity.
repeat red.
apply and_comm.
apply backward_leu_correct;
intuition.
unfold Int.ltu in C.
destruct zlt. 2:
elim C;
reflexivity.
repeat red.
apply and_comm.
apply backward_ltu_correct;
intuition.
unfold Int.ltu in C.
destruct zlt.
elim C;
reflexivity.
apply backward_leu_correct;
intuition.
unfold Int.ltu in C.
destruct zlt. 2:
elim C;
reflexivity.
apply backward_ltu_correct;
intuition.
intros ? ? ? ? ?
H K _.
eexists.
split.
left.
reflexivity.
exact (
conj H K).
intros ? ? ? ? ?
H K _.
eexists.
split.
left.
reflexivity.
exact (
conj H K).
Qed.
End UInterval.
Instance: reduction for signed/unsigned intervals.
Import Interval.
Instance itv_red :
reduction itv itv :=
{| ρ :=
botbind2 (
fun s u =>
let s' :=
reduc2signed u in
let u' :=
reduc2unsigned s in
match s ⊓
NotBot s',
u ⊓
NotBot u'
with
|
Bot,
_ |
_,
Bot =>
Bot
|
NotBot a,
NotBot b =>
NotBot (
a,
b)
end)
|}.
Instance itv_red_correct :
reduction_correct signed_itv_adom unsigned_itv_adom.
Proof.
Instance intervals :
num_dom _ := @
reduced_product_num_dom _ _ itv_num UInterval.itvu_num itv_red.
Instance intervals_correct :
num_dom_correct intervals :=
reduced_product_num_dom_correct _ _ itv_num_correct UInterval.itvu_num_correct _ _.