(** Bitwise operations: and, or, xor, not *)

Definition bitwise (x: nval) := x.Remark bitwise_idem: forall nv, bitwise (bitwise nv) = bitwise nv.

(* Specifications: *)
Lemma vagree_bitwise_binop: forall f, (forall p1 p2 q1 q2 m, iagree p1 q1 m -> iagree p2 q2 m -> iagree (f p1 p2) (f q1 q2) m) -> forall v1 w1 v2 w2 x, vagree v1 w1 (bitwise x) -> vagree v2 w2 (bitwise x) -> vagree (match v1, v2 with Vint i1, Vint i2 => Vint(f i1 i2) | _, _ => Vundef end) (match w1, w2 with Vint i1, Vint i2 => Vint(f i1 i2) | _, _ => Vundef end) x.
Lemma and_sound: forall v1 w1 v2 w2 x, vagree v1 w1 (bitwise x) -> vagree v2 w2 (bitwise x) -> vagree (Val.and v1 v2) (Val.and w1 w2) x.
Lemma or_sound: forall v1 w1 v2 w2 x, vagree v1 w1 (bitwise x) -> vagree v2 w2 (bitwise x) -> vagree (Val.or v1 v2) (Val.or w1 w2) x.
Lemma xor_sound: forall v1 w1 v2 w2 x, vagree v1 w1 (bitwise x) -> vagree v2 w2 (bitwise x) -> vagree (Val.xor v1 v2) (Val.xor w1 w2) x.
Lemma notint_sound: forall v w x, vagree v w (bitwise x) -> vagree (Val.notint v) (Val.notint w) x.