diff options
author | xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e> | 2006-02-09 14:55:48 +0000 |
---|---|---|
committer | xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e> | 2006-02-09 14:55:48 +0000 |
commit | 2ae43be7b9d4118335c9d2cef6e098f9b9f807fe (patch) | |
tree | bbb5e49ccbf7e3614966571acc317f8d318fecad /backend/Values.v | |
download | compcert-kvx-2ae43be7b9d4118335c9d2cef6e098f9b9f807fe.tar.gz compcert-kvx-2ae43be7b9d4118335c9d2cef6e098f9b9f807fe.zip |
Initial import of compcert
git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'backend/Values.v')
-rw-r--r-- | backend/Values.v | 888 |
1 files changed, 888 insertions, 0 deletions
diff --git a/backend/Values.v b/backend/Values.v new file mode 100644 index 00000000..aa59e045 --- /dev/null +++ b/backend/Values.v @@ -0,0 +1,888 @@ +(** This module defines the type of values that is used in the dynamic + semantics of all our intermediate languages. *) + +Require Import Coqlib. +Require Import AST. +Require Import Integers. +Require Import Floats. + +Definition block : Set := Z. +Definition eq_block := zeq. + +(** A value is either: +- a machine integer; +- a floating-point number; +- a pointer: a pair of a memory address and an integer offset with respect + to this address; +- the [Vundef] value denoting an arbitrary bit pattern, such as the + value of an uninitialized variable. +*) + +Inductive val: Set := + | Vundef: val + | Vint: int -> val + | Vfloat: float -> val + | Vptr: block -> int -> val. + +Definition Vzero: val := Vint Int.zero. +Definition Vone: val := Vint Int.one. +Definition Vmone: val := Vint Int.mone. + +Definition Vtrue: val := Vint Int.one. +Definition Vfalse: val := Vint Int.zero. + +(** The module [Val] defines a number of arithmetic and logical operations + over type [val]. Most of these operations are straightforward extensions + of the corresponding integer or floating-point operations. *) + +Module Val. + +Definition of_bool (b: bool): val := if b then Vtrue else Vfalse. + +Definition has_type (v: val) (t: typ) : Prop := + match v, t with + | Vundef, _ => True + | Vint _, Tint => True + | Vfloat _, Tfloat => True + | Vptr _ _, Tint => True + | _, _ => False + end. + +Fixpoint has_type_list (vl: list val) (tl: list typ) {struct vl} : Prop := + match vl, tl with + | nil, nil => True + | v1 :: vs, t1 :: ts => has_type v1 t1 /\ has_type_list vs ts + | _, _ => False + end. + +(** Truth values. Pointers and non-zero integers are treated as [True]. + The integer 0 (also used to represent the null pointer) is [False]. + [Vundef] and floats are neither true nor false. *) + +Definition is_true (v: val) : Prop := + match v with + | Vint n => n <> Int.zero + | Vptr b ofs => True + | _ => False + end. + +Definition is_false (v: val) : Prop := + match v with + | Vint n => n = Int.zero + | _ => False + end. + +Inductive bool_of_val: val -> bool -> Prop := + | bool_of_val_int_true: + forall n, n <> Int.zero -> bool_of_val (Vint n) true + | bool_of_val_int_false: + bool_of_val (Vint Int.zero) false + | bool_of_val_ptr: + forall b ofs, bool_of_val (Vptr b ofs) true. + +Definition neg (v: val) : val := + match v with + | Vint n => Vint (Int.neg n) + | _ => Vundef + end. + +Definition negf (v: val) : val := + match v with + | Vfloat f => Vfloat (Float.neg f) + | _ => Vundef + end. + +Definition absf (v: val) : val := + match v with + | Vfloat f => Vfloat (Float.abs f) + | _ => Vundef + end. + +Definition intoffloat (v: val) : val := + match v with + | Vfloat f => Vint (Float.intoffloat f) + | _ => Vundef + end. + +Definition floatofint (v: val) : val := + match v with + | Vint n => Vfloat (Float.floatofint n) + | _ => Vundef + end. + +Definition floatofintu (v: val) : val := + match v with + | Vint n => Vfloat (Float.floatofintu n) + | _ => Vundef + end. + +Definition notint (v: val) : val := + match v with + | Vint n => Vint (Int.xor n Int.mone) + | _ => Vundef + end. + +Definition notbool (v: val) : val := + match v with + | Vint n => of_bool (Int.eq n Int.zero) + | Vptr b ofs => Vfalse + | _ => Vundef + end. + +Definition cast8signed (v: val) : val := + match v with + | Vint n => Vint(Int.cast8signed n) + | _ => Vundef + end. + +Definition cast8unsigned (v: val) : val := + match v with + | Vint n => Vint(Int.cast8unsigned n) + | _ => Vundef + end. + +Definition cast16signed (v: val) : val := + match v with + | Vint n => Vint(Int.cast16signed n) + | _ => Vundef + end. + +Definition cast16unsigned (v: val) : val := + match v with + | Vint n => Vint(Int.cast16unsigned n) + | _ => Vundef + end. + +Definition singleoffloat (v: val) : val := + match v with + | Vfloat f => Vfloat(Float.singleoffloat f) + | _ => Vundef + end. + +Definition add (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => Vint(Int.add n1 n2) + | Vptr b1 ofs1, Vint n2 => Vptr b1 (Int.add ofs1 n2) + | Vint n1, Vptr b2 ofs2 => Vptr b2 (Int.add ofs2 n1) + | _, _ => Vundef + end. + +Definition sub (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => Vint(Int.sub n1 n2) + | Vptr b1 ofs1, Vint n2 => Vptr b1 (Int.sub ofs1 n2) + | Vptr b1 ofs1, Vptr b2 ofs2 => + if zeq b1 b2 then Vint(Int.sub ofs1 ofs2) else Vundef + | _, _ => Vundef + end. + +Definition mul (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => Vint(Int.mul n1 n2) + | _, _ => Vundef + end. + +Definition divs (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => + if Int.eq n2 Int.zero then Vundef else Vint(Int.divs n1 n2) + | _, _ => Vundef + end. + +Definition mods (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => + if Int.eq n2 Int.zero then Vundef else Vint(Int.mods n1 n2) + | _, _ => Vundef + end. + +Definition divu (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => + if Int.eq n2 Int.zero then Vundef else Vint(Int.divu n1 n2) + | _, _ => Vundef + end. + +Definition modu (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => + if Int.eq n2 Int.zero then Vundef else Vint(Int.modu n1 n2) + | _, _ => Vundef + end. + +Definition and (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => Vint(Int.and n1 n2) + | _, _ => Vundef + end. + +Definition or (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => Vint(Int.or n1 n2) + | _, _ => Vundef + end. + +Definition xor (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => Vint(Int.xor n1 n2) + | _, _ => Vundef + end. + +Definition shl (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => + if Int.ltu n2 (Int.repr 32) + then Vint(Int.shl n1 n2) + else Vundef + | _, _ => Vundef + end. + +Definition shr (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => + if Int.ltu n2 (Int.repr 32) + then Vint(Int.shr n1 n2) + else Vundef + | _, _ => Vundef + end. + +Definition shr_carry (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => + if Int.ltu n2 (Int.repr 32) + then Vint(Int.shr_carry n1 n2) + else Vundef + | _, _ => Vundef + end. + +Definition shrx (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => + if Int.ltu n2 (Int.repr 32) + then Vint(Int.shrx n1 n2) + else Vundef + | _, _ => Vundef + end. + +Definition shru (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => + if Int.ltu n2 (Int.repr 32) + then Vint(Int.shru n1 n2) + else Vundef + | _, _ => Vundef + end. + +Definition rolm (v: val) (amount mask: int): val := + match v with + | Vint n => Vint(Int.rolm n amount mask) + | _ => Vundef + end. + +Definition addf (v1 v2: val): val := + match v1, v2 with + | Vfloat f1, Vfloat f2 => Vfloat(Float.add f1 f2) + | _, _ => Vundef + end. + +Definition subf (v1 v2: val): val := + match v1, v2 with + | Vfloat f1, Vfloat f2 => Vfloat(Float.sub f1 f2) + | _, _ => Vundef + end. + +Definition mulf (v1 v2: val): val := + match v1, v2 with + | Vfloat f1, Vfloat f2 => Vfloat(Float.mul f1 f2) + | _, _ => Vundef + end. + +Definition divf (v1 v2: val): val := + match v1, v2 with + | Vfloat f1, Vfloat f2 => Vfloat(Float.div f1 f2) + | _, _ => Vundef + end. + +Definition cmp_mismatch (c: comparison): val := + match c with + | Ceq => Vfalse + | Cne => Vtrue + | _ => Vundef + end. + +Definition cmp (c: comparison) (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => of_bool (Int.cmp c n1 n2) + | Vint n1, Vptr b2 ofs2 => + if Int.eq n1 Int.zero then cmp_mismatch c else Vundef + | Vptr b1 ofs1, Vptr b2 ofs2 => + if zeq b1 b2 + then of_bool (Int.cmp c ofs1 ofs2) + else cmp_mismatch c + | Vptr b1 ofs1, Vint n2 => + if Int.eq n2 Int.zero then cmp_mismatch c else Vundef + | _, _ => Vundef + end. + +Definition cmpu (c: comparison) (v1 v2: val): val := + match v1, v2 with + | Vint n1, Vint n2 => + of_bool (Int.cmpu c n1 n2) + | Vint n1, Vptr b2 ofs2 => + if Int.eq n1 Int.zero then cmp_mismatch c else Vundef + | Vptr b1 ofs1, Vptr b2 ofs2 => + if zeq b1 b2 + then of_bool (Int.cmpu c ofs1 ofs2) + else cmp_mismatch c + | Vptr b1 ofs1, Vint n2 => + if Int.eq n2 Int.zero then cmp_mismatch c else Vundef + | _, _ => Vundef + end. + +Definition cmpf (c: comparison) (v1 v2: val): val := + match v1, v2 with + | Vfloat f1, Vfloat f2 => of_bool (Float.cmp c f1 f2) + | _, _ => Vundef + end. + +(** [load_result] is used in the memory model (library [Mem]) + to post-process the results of a memory read. For instance, + consider storing the integer value [0xFFF] on 1 byte at a + given address, and reading it back. If it is read back with + chunk [Mint8unsigned], zero-extension must be performed, resulting + in [0xFF]. If it is read back as a [Mint8signed], sign-extension + is performed and [0xFFFFFFFF] is returned. Type mismatches + (e.g. reading back a float as a [Mint32]) read back as [Vundef]. *) + +Definition load_result (chunk: memory_chunk) (v: val) := + match chunk, v with + | Mint8signed, Vint n => Vint (Int.cast8signed n) + | Mint8unsigned, Vint n => Vint (Int.cast8unsigned n) + | Mint16signed, Vint n => Vint (Int.cast16signed n) + | Mint16unsigned, Vint n => Vint (Int.cast16unsigned n) + | Mint32, Vint n => Vint n + | Mint32, Vptr b ofs => Vptr b ofs + | Mfloat32, Vfloat f => Vfloat(Float.singleoffloat f) + | Mfloat64, Vfloat f => Vfloat f + | _, _ => Vundef + end. + +(** Theorems on arithmetic operations. *) + +Theorem cast8unsigned_and: + forall x, cast8unsigned x = and x (Vint(Int.repr 255)). +Proof. + destruct x; simpl; auto. decEq. apply Int.cast8unsigned_and. +Qed. + +Theorem cast16unsigned_and: + forall x, cast16unsigned x = and x (Vint(Int.repr 65535)). +Proof. + destruct x; simpl; auto. decEq. apply Int.cast16unsigned_and. +Qed. + +Theorem istrue_not_isfalse: + forall v, is_false v -> is_true (notbool v). +Proof. + destruct v; simpl; try contradiction. + intros. subst i. simpl. discriminate. +Qed. + +Theorem isfalse_not_istrue: + forall v, is_true v -> is_false (notbool v). +Proof. + destruct v; simpl; try contradiction. + intros. generalize (Int.eq_spec i Int.zero). + case (Int.eq i Int.zero); intro. + contradiction. simpl. auto. + auto. +Qed. + +Theorem bool_of_true_val: + forall v, is_true v -> bool_of_val v true. +Proof. + intro. destruct v; simpl; intros; try contradiction. + constructor; auto. constructor. +Qed. + +Theorem bool_of_true_val2: + forall v, bool_of_val v true -> is_true v. +Proof. + intros. inversion H; simpl; auto. +Qed. + +Theorem bool_of_true_val_inv: + forall v b, is_true v -> bool_of_val v b -> b = true. +Proof. + intros. inversion H0; subst v b; simpl in H; auto. +Qed. + +Theorem bool_of_false_val: + forall v, is_false v -> bool_of_val v false. +Proof. + intro. destruct v; simpl; intros; try contradiction. + subst i; constructor. +Qed. + +Theorem bool_of_false_val2: + forall v, bool_of_val v false -> is_false v. +Proof. + intros. inversion H; simpl; auto. +Qed. + +Theorem bool_of_false_val_inv: + forall v b, is_false v -> bool_of_val v b -> b = false. +Proof. + intros. inversion H0; subst v b; simpl in H. + congruence. auto. contradiction. +Qed. + +Theorem notbool_negb_1: + forall b, of_bool (negb b) = notbool (of_bool b). +Proof. + destruct b; reflexivity. +Qed. + +Theorem notbool_negb_2: + forall b, of_bool b = notbool (of_bool (negb b)). +Proof. + destruct b; reflexivity. +Qed. + +Theorem notbool_idem2: + forall b, notbool(notbool(of_bool b)) = of_bool b. +Proof. + destruct b; reflexivity. +Qed. + +Theorem notbool_idem3: + forall x, notbool(notbool(notbool x)) = notbool x. +Proof. + destruct x; simpl; auto. + case (Int.eq i Int.zero); reflexivity. +Qed. + +Theorem add_commut: forall x y, add x y = add y x. +Proof. + destruct x; destruct y; simpl; auto. + decEq. apply Int.add_commut. +Qed. + +Theorem add_assoc: forall x y z, add (add x y) z = add x (add y z). +Proof. + destruct x; destruct y; destruct z; simpl; auto. + rewrite Int.add_assoc; auto. + rewrite Int.add_assoc; auto. + decEq. decEq. apply Int.add_commut. + decEq. rewrite Int.add_commut. rewrite <- Int.add_assoc. + decEq. apply Int.add_commut. + decEq. rewrite Int.add_assoc. auto. +Qed. + +Theorem add_permut: forall x y z, add x (add y z) = add y (add x z). +Proof. + intros. rewrite (add_commut y z). rewrite <- add_assoc. apply add_commut. +Qed. + +Theorem add_permut_4: + forall x y z t, add (add x y) (add z t) = add (add x z) (add y t). +Proof. + intros. rewrite add_permut. rewrite add_assoc. + rewrite add_permut. symmetry. apply add_assoc. +Qed. + +Theorem neg_zero: neg Vzero = Vzero. +Proof. + reflexivity. +Qed. + +Theorem neg_add_distr: forall x y, neg(add x y) = add (neg x) (neg y). +Proof. + destruct x; destruct y; simpl; auto. decEq. apply Int.neg_add_distr. +Qed. + +Theorem sub_zero_r: forall x, sub Vzero x = neg x. +Proof. + destruct x; simpl; auto. +Qed. + +Theorem sub_add_opp: forall x y, sub x (Vint y) = add x (Vint (Int.neg y)). +Proof. + destruct x; intro y; simpl; auto; rewrite Int.sub_add_opp; auto. +Qed. + +Theorem sub_add_l: + forall v1 v2 i, sub (add v1 (Vint i)) v2 = add (sub v1 v2) (Vint i). +Proof. + destruct v1; destruct v2; intros; simpl; auto. + rewrite Int.sub_add_l. auto. + rewrite Int.sub_add_l. auto. + case (zeq b b0); intro. rewrite Int.sub_add_l. auto. reflexivity. +Qed. + +Theorem sub_add_r: + forall v1 v2 i, sub v1 (add v2 (Vint i)) = add (sub v1 v2) (Vint (Int.neg i)). +Proof. + destruct v1; destruct v2; intros; simpl; auto. + rewrite Int.sub_add_r. auto. + repeat rewrite Int.sub_add_opp. decEq. + repeat rewrite Int.add_assoc. decEq. apply Int.add_commut. + decEq. repeat rewrite Int.sub_add_opp. + rewrite Int.add_assoc. decEq. apply Int.neg_add_distr. + case (zeq b b0); intro. simpl. decEq. + repeat rewrite Int.sub_add_opp. rewrite Int.add_assoc. decEq. + apply Int.neg_add_distr. + reflexivity. +Qed. + +Theorem mul_commut: forall x y, mul x y = mul y x. +Proof. + destruct x; destruct y; simpl; auto. decEq. apply Int.mul_commut. +Qed. + +Theorem mul_assoc: forall x y z, mul (mul x y) z = mul x (mul y z). +Proof. + destruct x; destruct y; destruct z; simpl; auto. + decEq. apply Int.mul_assoc. +Qed. + +Theorem mul_add_distr_l: + forall x y z, mul (add x y) z = add (mul x z) (mul y z). +Proof. + destruct x; destruct y; destruct z; simpl; auto. + decEq. apply Int.mul_add_distr_l. +Qed. + + +Theorem mul_add_distr_r: + forall x y z, mul x (add y z) = add (mul x y) (mul x z). +Proof. + destruct x; destruct y; destruct z; simpl; auto. + decEq. apply Int.mul_add_distr_r. +Qed. + +Theorem mul_pow2: + forall x n logn, + Int.is_power2 n = Some logn -> + mul x (Vint n) = shl x (Vint logn). +Proof. + intros; destruct x; simpl; auto. + change 32 with (Z_of_nat wordsize). + rewrite (Int.is_power2_range _ _ H). decEq. apply Int.mul_pow2. auto. +Qed. + +Theorem mods_divs: + forall x y, mods x y = sub x (mul (divs x y) y). +Proof. + destruct x; destruct y; simpl; auto. + case (Int.eq i0 Int.zero); simpl. auto. decEq. apply Int.mods_divs. +Qed. + +Theorem modu_divu: + forall x y, modu x y = sub x (mul (divu x y) y). +Proof. + destruct x; destruct y; simpl; auto. + generalize (Int.eq_spec i0 Int.zero); + case (Int.eq i0 Int.zero); simpl. auto. + intro. decEq. apply Int.modu_divu. auto. +Qed. + +Theorem divs_pow2: + forall x n logn, + Int.is_power2 n = Some logn -> + divs x (Vint n) = shrx x (Vint logn). +Proof. + intros; destruct x; simpl; auto. + change 32 with (Z_of_nat wordsize). + rewrite (Int.is_power2_range _ _ H). + generalize (Int.eq_spec n Int.zero); + case (Int.eq n Int.zero); intro. + subst n. compute in H. discriminate. + decEq. apply Int.divs_pow2. auto. +Qed. + +Theorem divu_pow2: + forall x n logn, + Int.is_power2 n = Some logn -> + divu x (Vint n) = shru x (Vint logn). +Proof. + intros; destruct x; simpl; auto. + change 32 with (Z_of_nat wordsize). + rewrite (Int.is_power2_range _ _ H). + generalize (Int.eq_spec n Int.zero); + case (Int.eq n Int.zero); intro. + subst n. compute in H. discriminate. + decEq. apply Int.divu_pow2. auto. +Qed. + +Theorem modu_pow2: + forall x n logn, + Int.is_power2 n = Some logn -> + modu x (Vint n) = and x (Vint (Int.sub n Int.one)). +Proof. + intros; destruct x; simpl; auto. + generalize (Int.eq_spec n Int.zero); + case (Int.eq n Int.zero); intro. + subst n. compute in H. discriminate. + decEq. eapply Int.modu_and; eauto. +Qed. + +Theorem and_commut: forall x y, and x y = and y x. +Proof. + destruct x; destruct y; simpl; auto. decEq. apply Int.and_commut. +Qed. + +Theorem and_assoc: forall x y z, and (and x y) z = and x (and y z). +Proof. + destruct x; destruct y; destruct z; simpl; auto. + decEq. apply Int.and_assoc. +Qed. + +Theorem or_commut: forall x y, or x y = or y x. +Proof. + destruct x; destruct y; simpl; auto. decEq. apply Int.or_commut. +Qed. + +Theorem or_assoc: forall x y z, or (or x y) z = or x (or y z). +Proof. + destruct x; destruct y; destruct z; simpl; auto. + decEq. apply Int.or_assoc. +Qed. + +Theorem xor_commut: forall x y, xor x y = xor y x. +Proof. + destruct x; destruct y; simpl; auto. decEq. apply Int.xor_commut. +Qed. + +Theorem xor_assoc: forall x y z, xor (xor x y) z = xor x (xor y z). +Proof. + destruct x; destruct y; destruct z; simpl; auto. + decEq. apply Int.xor_assoc. +Qed. + +Theorem shl_mul: forall x y, Val.mul x (Val.shl Vone y) = Val.shl x y. +Proof. + destruct x; destruct y; simpl; auto. + case (Int.ltu i0 (Int.repr 32)); auto. + decEq. symmetry. apply Int.shl_mul. +Qed. + +Theorem shl_rolm: + forall x n, + Int.ltu n (Int.repr 32) = true -> + shl x (Vint n) = rolm x n (Int.shl Int.mone n). +Proof. + intros; destruct x; simpl; auto. + rewrite H. decEq. apply Int.shl_rolm. exact H. +Qed. + +Theorem shru_rolm: + forall x n, + Int.ltu n (Int.repr 32) = true -> + shru x (Vint n) = rolm x (Int.sub (Int.repr 32) n) (Int.shru Int.mone n). +Proof. + intros; destruct x; simpl; auto. + rewrite H. decEq. apply Int.shru_rolm. exact H. +Qed. + +Theorem shrx_carry: + forall x y, + add (shr x y) (shr_carry x y) = shrx x y. +Proof. + destruct x; destruct y; simpl; auto. + case (Int.ltu i0 (Int.repr 32)); auto. + simpl. decEq. apply Int.shrx_carry. +Qed. + +Theorem or_rolm: + forall x n m1 m2, + or (rolm x n m1) (rolm x n m2) = rolm x n (Int.or m1 m2). +Proof. + intros; destruct x; simpl; auto. + decEq. apply Int.or_rolm. +Qed. + +Theorem rolm_rolm: + forall x n1 m1 n2 m2, + rolm (rolm x n1 m1) n2 m2 = + rolm x (Int.and (Int.add n1 n2) (Int.repr 31)) + (Int.and (Int.rol m1 n2) m2). +Proof. + intros; destruct x; simpl; auto. + decEq. + replace (Int.and (Int.add n1 n2) (Int.repr 31)) + with (Int.modu (Int.add n1 n2) (Int.repr 32)). + apply Int.rolm_rolm. + change (Int.repr 31) with (Int.sub (Int.repr 32) Int.one). + apply Int.modu_and with (Int.repr 5). reflexivity. +Qed. + +Theorem rolm_zero: + forall x m, + rolm x Int.zero m = and x (Vint m). +Proof. + intros; destruct x; simpl; auto. decEq. apply Int.rolm_zero. +Qed. + +Theorem addf_commut: forall x y, addf x y = addf y x. +Proof. + destruct x; destruct y; simpl; auto. decEq. apply Float.addf_commut. +Qed. + +Lemma negate_cmp_mismatch: + forall c, + cmp_mismatch (negate_comparison c) = notbool(cmp_mismatch c). +Proof. + destruct c; reflexivity. +Qed. + +Theorem negate_cmp: + forall c x y, + cmp (negate_comparison c) x y = notbool (cmp c x y). +Proof. + destruct x; destruct y; simpl; auto. + rewrite Int.negate_cmp. apply notbool_negb_1. + case (Int.eq i Int.zero). apply negate_cmp_mismatch. reflexivity. + case (Int.eq i0 Int.zero). apply negate_cmp_mismatch. reflexivity. + case (zeq b b0); intro. + rewrite Int.negate_cmp. apply notbool_negb_1. + apply negate_cmp_mismatch. +Qed. + +Theorem negate_cmpu: + forall c x y, + cmpu (negate_comparison c) x y = notbool (cmpu c x y). +Proof. + destruct x; destruct y; simpl; auto. + rewrite Int.negate_cmpu. apply notbool_negb_1. + case (Int.eq i Int.zero). apply negate_cmp_mismatch. reflexivity. + case (Int.eq i0 Int.zero). apply negate_cmp_mismatch. reflexivity. + case (zeq b b0); intro. + rewrite Int.negate_cmpu. apply notbool_negb_1. + apply negate_cmp_mismatch. +Qed. + +Lemma swap_cmp_mismatch: + forall c, cmp_mismatch (swap_comparison c) = cmp_mismatch c. +Proof. + destruct c; reflexivity. +Qed. + +Theorem swap_cmp: + forall c x y, + cmp (swap_comparison c) x y = cmp c y x. +Proof. + destruct x; destruct y; simpl; auto. + rewrite Int.swap_cmp. auto. + case (Int.eq i Int.zero). apply swap_cmp_mismatch. auto. + case (Int.eq i0 Int.zero). apply swap_cmp_mismatch. auto. + case (zeq b b0); intro. + subst b0. rewrite zeq_true. rewrite Int.swap_cmp. auto. + rewrite zeq_false. apply swap_cmp_mismatch. auto. +Qed. + +Theorem swap_cmpu: + forall c x y, + cmpu (swap_comparison c) x y = cmpu c y x. +Proof. + destruct x; destruct y; simpl; auto. + rewrite Int.swap_cmpu. auto. + case (Int.eq i Int.zero). apply swap_cmp_mismatch. auto. + case (Int.eq i0 Int.zero). apply swap_cmp_mismatch. auto. + case (zeq b b0); intro. + subst b0. rewrite zeq_true. rewrite Int.swap_cmpu. auto. + rewrite zeq_false. apply swap_cmp_mismatch. auto. +Qed. + +Theorem negate_cmpf_eq: + forall v1 v2, notbool (cmpf Cne v1 v2) = cmpf Ceq v1 v2. +Proof. + destruct v1; destruct v2; simpl; auto. + rewrite Float.cmp_ne_eq. rewrite notbool_negb_1. + apply notbool_idem2. +Qed. + +Lemma or_of_bool: + forall b1 b2, or (of_bool b1) (of_bool b2) = of_bool (b1 || b2). +Proof. + destruct b1; destruct b2; reflexivity. +Qed. + +Theorem cmpf_le: + forall v1 v2, cmpf Cle v1 v2 = or (cmpf Clt v1 v2) (cmpf Ceq v1 v2). +Proof. + destruct v1; destruct v2; simpl; auto. + rewrite or_of_bool. decEq. apply Float.cmp_le_lt_eq. +Qed. + +Theorem cmpf_ge: + forall v1 v2, cmpf Cge v1 v2 = or (cmpf Cgt v1 v2) (cmpf Ceq v1 v2). +Proof. + destruct v1; destruct v2; simpl; auto. + rewrite or_of_bool. decEq. apply Float.cmp_ge_gt_eq. +Qed. + +Definition is_bool (v: val) := + v = Vundef \/ v = Vtrue \/ v = Vfalse. + +Lemma of_bool_is_bool: + forall b, is_bool (of_bool b). +Proof. + destruct b; unfold is_bool; simpl; tauto. +Qed. + +Lemma undef_is_bool: is_bool Vundef. +Proof. + unfold is_bool; tauto. +Qed. + +Lemma cmp_mismatch_is_bool: + forall c, is_bool (cmp_mismatch c). +Proof. + destruct c; simpl; unfold is_bool; tauto. +Qed. + +Lemma cmp_is_bool: + forall c v1 v2, is_bool (cmp c v1 v2). +Proof. + destruct v1; destruct v2; simpl; try apply undef_is_bool. + apply of_bool_is_bool. + case (Int.eq i Int.zero). apply cmp_mismatch_is_bool. apply undef_is_bool. + case (Int.eq i0 Int.zero). apply cmp_mismatch_is_bool. apply undef_is_bool. + case (zeq b b0); intro. apply of_bool_is_bool. apply cmp_mismatch_is_bool. +Qed. + +Lemma cmpu_is_bool: + forall c v1 v2, is_bool (cmpu c v1 v2). +Proof. + destruct v1; destruct v2; simpl; try apply undef_is_bool. + apply of_bool_is_bool. + case (Int.eq i Int.zero). apply cmp_mismatch_is_bool. apply undef_is_bool. + case (Int.eq i0 Int.zero). apply cmp_mismatch_is_bool. apply undef_is_bool. + case (zeq b b0); intro. apply of_bool_is_bool. apply cmp_mismatch_is_bool. +Qed. + +Lemma cmpf_is_bool: + forall c v1 v2, is_bool (cmpf c v1 v2). +Proof. + destruct v1; destruct v2; simpl; + apply undef_is_bool || apply of_bool_is_bool. +Qed. + +Lemma notbool_is_bool: + forall v, is_bool (notbool v). +Proof. + destruct v; simpl. + apply undef_is_bool. apply of_bool_is_bool. + apply undef_is_bool. unfold is_bool; tauto. +Qed. + +Lemma notbool_xor: + forall v, is_bool v -> v = xor (notbool v) Vone. +Proof. + intros. elim H; intro. + subst v. reflexivity. + elim H0; intro; subst v; reflexivity. +Qed. + +End Val. |