(** ** Lemmas about erased values*)

  Definition isDefined v :=
    match v with
    | Vundef => false
    | _ => true
    end.

(* Specifications: *)
Lemma val_erasure_add_result: forall v1 v1' v2 v2' v, val_erasure v1 v1' -> val_erasure v2 v2' -> Val.add v1 v2 = v -> isDefined v -> Val.add v1' v2' = v.
Lemma isPointer_isDefined: forall v, isPointer v -> isDefined v.
Lemma val_erasure_add: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.add v1 v2) (Val.add v1' v2').
Lemma val_erasure_mul: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.mul v1 v2) (Val.mul v1' v2').
Lemma val_erasure_mul_result: forall v1 v2 v1' v2' v, val_erasure v1 v1'-> val_erasure v2 v2' -> Val.mul v1 v2 = v -> isDefined v -> Val.mul v1' v2' = v.
Lemma val_erasure_hiword: forall v v', val_erasure v v' -> val_erasure (Val.hiword v) (Val.hiword v').
Lemma val_erasure_loword: forall v v', val_erasure v v' -> val_erasure (Val.loword v) (Val.loword v').
Lemma val_erasure_cmp_bool: forall c v1 v1', v1 <> Vundef -> val_erasure v1 v1' -> Val.cmp_bool c v1 Vzero = Val.cmp_bool c v1' Vzero.
Lemma val_erasure_zero_ext: forall v v' n, val_erasure v v' -> val_erasure (Val.zero_ext n v) (Val.zero_ext n v').
Lemma val_erasure_sign_ext: forall v v' n, val_erasure v v' -> val_erasure (Val.sign_ext n v) (Val.sign_ext n v').
Lemma val_erasure_singleoffloat: forall v v', val_erasure v v' -> val_erasure (Val.singleoffloat v) (Val.singleoffloat v').
Lemma val_erasure_floatofsingle: forall v v', val_erasure v v' -> val_erasure (Val.floatofsingle v) (Val.floatofsingle v').
Lemma val_erasure_intoffloat: forall v v', val_erasure v v' -> val_erasure (Val.maketotal (Val.intoffloat v)) (Val.maketotal (Val.intoffloat v')).
Lemma val_erasure_floatofint: forall v v', val_erasure v v' -> val_erasure (Val.maketotal (Val.floatofint v)) (Val.maketotal (Val.floatofint v')).
Lemma val_erasure_intofsingle: forall v v', val_erasure v v' -> val_erasure (Val.maketotal (Val.intofsingle v)) (Val.maketotal (Val.intofsingle v')).
Lemma val_erasure_singleofint: forall v v', val_erasure v v' -> val_erasure (Val.maketotal (Val.singleofint v)) (Val.maketotal (Val.singleofint v')).
Lemma val_erasure_neg: forall v v', val_erasure v v' -> val_erasure (Val.neg v) (Val.neg v').
Lemma val_erasure_notint: forall v v', val_erasure v v' -> val_erasure (Val.notint v) (Val.notint v').
Lemma val_erasure_negative: forall v v', val_erasure v v' -> val_erasure (Val.negative v) (Val.negative v').
Lemma val_erasure_sub_overflow: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.sub_overflow v1 v2) (Val.sub_overflow v1' v2').
Lemma val_erasure_sub: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.sub v1 v2) (Val.sub v1' v2').
Lemma val_erasure_mulhu: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.mulhu v1 v2) (Val.mulhu v1' v2').
Lemma val_erasure_mulhs: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.mulhs v1 v2) (Val.mulhs v1' v2').
Lemma val_erasure_and: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.and v1 v2) (Val.and v1' v2').
Lemma val_erasure_or: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.or v1 v2) (Val.or v1' v2').
Lemma val_erasure_xor: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.xor v1 v2) (Val.xor v1' v2').
Lemma val_erasure_shl: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.shl v1 v2) (Val.shl v1' v2').
Lemma val_erasure_shr: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.shr v1 v2) (Val.shr v1' v2').
Lemma val_erasure_shru: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.shru v1 v2) (Val.shru v1' v2').
Lemma val_erasure_ror: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.ror v1 v2) (Val.ror v1' v2').
Lemma val_erasure_divu_result: forall v1 v2 v1' v2' v, val_erasure v1 v1' -> val_erasure v2 v2' -> Val.divu v1 v2 = Some v -> Val.divu v1' v2' = Some v.
Lemma val_erasure_modu_result: forall v1 v2 v1' v2' v, val_erasure v1 v1' -> val_erasure v2 v2' -> Val.modu v1 v2 = Some v -> Val.modu v1' v2' = Some v.
Lemma val_erasure_divs_result: forall v1 v2 v1' v2' v, val_erasure v1 v1' -> val_erasure v2 v2' -> Val.divs v1 v2 = Some v -> Val.divs v1' v2' = Some v.
Lemma val_erasure_mods_result: forall v1 v2 v1' v2' v, val_erasure v1 v1' -> val_erasure v2 v2' -> Val.mods v1 v2 = Some v -> Val.mods v1' v2' = Some v.
Lemma val_erasure_addf: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.addf v1 v2) (Val.addf v1' v2').
Lemma val_erasure_addfs: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.addfs v1 v2) (Val.addfs v1' v2').
Lemma val_erasure_subf: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.subf v1 v2) (Val.subf v1' v2').
Lemma val_erasure_subfs: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.subfs v1 v2) (Val.subfs v1' v2').
Lemma val_erasure_mulf: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.mulf v1 v2) (Val.mulf v1' v2').
Lemma val_erasure_mulfs: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.mulfs v1 v2) (Val.mulfs v1' v2').
Lemma val_erasure_divf: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.divf v1 v2) (Val.divf v1' v2').
Lemma val_erasure_divfs: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.divfs v1 v2) (Val.divfs v1' v2').
Lemma val_erasure_negf: forall v v', val_erasure v v' -> val_erasure (Val.negf v) (Val.negf v').
Lemma val_erasure_negfs: forall v v', val_erasure v v' -> val_erasure (Val.negfs v) (Val.negfs v').
Lemma val_erasure_absf: forall v v', val_erasure v v' -> val_erasure (Val.absf v) (Val.absf v').
Lemma val_erasure_absfs: forall v v', val_erasure v v' -> val_erasure (Val.absfs v) (Val.absfs v').
Lemma inj_bytes_erasure : forall (bl : seq.seq byte), memval_erasure_list (inj_bytes bl) (inj_bytes bl).
Lemma inj_value_erasure : forall (v1 v2 : val) (q : quantity), val_erasure v1 v2 -> memval_erasure_list (inj_value q v1) (inj_value q v2).
Lemma repeat_Undef_erasure_self : forall (n : nat), memval_erasure_list (list_repeat n Undef) (list_repeat n Undef).
Lemma repeat_Undef_inject_encode_val : forall (chunk : memory_chunk) (v : val), memval_erasure_list (list_repeat (size_chunk_nat chunk) Undef) (encode_val chunk v).
Lemma val_erasure_encode_val: forall chunk v v', val_erasure v v' -> memval_erasure_list (encode_val chunk v) (encode_val chunk v').
Lemma val_defined_add_1: forall v1 v2 v, Val.add v1 v2 = v -> isDefined v -> isDefined v1.
Lemma val_defined_add_2: forall v1 v2 v, Val.add v1 v2 = v -> isDefined v -> isDefined v2.
Lemma val_erasure_offset_ptr: forall v v' z (Hval_erasure: val_erasure v v'), val_erasure (Val.offset_ptr v z) (Val.offset_ptr v' z).
Lemma val_erasure_longofintu: forall v v' (Hval_erasure: val_erasure v v'), val_erasure (Val.longofintu v) (Val.longofintu v').
Lemma val_erasure_longofint: forall v v' (Hval_erasure: val_erasure v v'), val_erasure (Val.longofint v) (Val.longofint v').
Lemma val_erasure_longoffloat: forall v v' (Hval_erasure: val_erasure v v'), val_erasure (Val.maketotal (Val.longoffloat v)) (Val.maketotal (Val.longoffloat v')).
Lemma val_erasure_floatoflong: forall v v' (Hval_erasure: val_erasure v v'), val_erasure (Val.maketotal (Val.floatoflong v)) (Val.maketotal (Val.floatoflong v')).
Lemma val_erasure_longofsingle: forall v v' (Hval_erasure: val_erasure v v'), val_erasure (Val.maketotal (Val.longofsingle v)) (Val.maketotal (Val.longofsingle v')).
Lemma val_erasure_longofwords: forall v1 v1' v2 v2' (Hval_erasure: val_erasure v1 v1') (Hval_erasure: val_erasure v2 v2'), val_erasure (Val.longofwords v1 v2) (Val.longofwords v1' v2').
Lemma val_erasure_singleoflong: forall v v' (Hval_erasure: val_erasure v v'), val_erasure (Val.maketotal (Val.singleoflong v)) (Val.maketotal (Val.singleoflong v')).
Lemma val_erasure_negl: forall v v', val_erasure v v' -> val_erasure (Val.negl v) (Val.negl v').
Lemma val_erasure_addl: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.addl v1 v2) (Val.addl v1' v2').
Lemma val_erasure_subl: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.subl v1 v2) (Val.subl v1' v2').
Lemma val_erasure_subl_overflow: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.subl_overflow v1 v2) (Val.subl_overflow v1' v2').
Lemma val_erasure_mull: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.mull v1 v2) (Val.mull v1' v2').
Lemma val_erasure_mullhs: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.mullhs v1 v2) (Val.mullhs v1' v2').
Lemma val_erasure_mullhu: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.mullhu v1 v2) (Val.mullhu v1' v2').
Lemma val_erasure_shrl: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.shrl v1 v2) (Val.shrl v1' v2').
Lemma val_erasure_andl: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.andl v1 v2) (Val.andl v1' v2').
Lemma val_erasure_orl: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.orl v1 v2) (Val.orl v1' v2').
Lemma val_erasure_xorl: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.xorl v1 v2) (Val.xorl v1' v2').
Lemma val_erasure_notl: forall v v', val_erasure v v' -> val_erasure (Val.notl v) (Val.notl v').
Lemma val_erasure_shll: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.shll v1 v2) (Val.shll v1' v2').
Lemma val_erasure_shrlu: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.shrlu v1 v2) (Val.shrlu v1' v2').
Lemma val_erasure_rorl: forall v1 v2 v1' v2', val_erasure v1 v1' -> val_erasure v2 v2' -> val_erasure (Val.rorl v1 v2) (Val.rorl v1' v2').
Lemma val_erasure_negativel: forall v v', val_erasure v v' -> val_erasure (Val.negativel v) (Val.negativel v').