(** * Properties of compile-time approximations of values *)

Definition val_match_approx (a: approx) (v: val) : Prop :=
  match a with
  | Int1 => v = Val.zero_ext 1 v
  | Int7 => v = Val.zero_ext 8 v /\ v = Val.sign_ext 8 v
  | Int8u => v = Val.zero_ext 8 v
  | Int8s => v = Val.sign_ext 8 v
  | Int15 => v = Val.zero_ext 16 v /\ v = Val.sign_ext 16 v
  | Int16u => v = Val.zero_ext 16 v
  | Int16s => v = Val.sign_ext 16 v
  | Float32 => v = Val.singleoffloat v
  | Any => True
  end.Remark undef_match_approx: forall a, val_match_approx a Vundef.

Lemma approx_bitwise_or_sound: forall (sem_op: val -> val -> val) a1 v1 a2 v2, (forall a b c, sem_op (Val.and a (Vint c)) (Val.and b (Vint c)) = Val.and (sem_op a b) (Vint c)) -> val_match_approx a1 v1 -> val_match_approx a2 v2 -> val_match_approx (Approx.bitwise_or a1 a2) (sem_op v1 v2).