Notation the_ge := (@the_ge the_program).

(* Specifications: *)
Lemma get_extcall_arg_erase: forall rs rs' m m' l v (Hrs: regs_erasure rs rs') (Hmem: mem_erasure m m') (Harg: get_extcall_arg rs m l = Some v), exists v', get_extcall_arg rs' m' l = Some v' /\ val_erasure v v'.
Lemma get_extcall_arguments_erase: forall rs rs' m m' ls vs (Hrs: regs_erasure rs rs') (Hmem: mem_erasure m m') (Hargs: get_extcall_arguments rs m ls = Some vs), exists vs', get_extcall_arguments rs' m' ls = Some vs' /\ val_erasure_list vs vs'.
Lemma at_external_erase: forall rs rs' m m' ef vs (Herase: core_erasure (State rs m) (State rs' m')) (Hmem_erase: mem_erasure m m') (Hat_external: at_external the_ge (State rs m) = Some (ef, vs)), exists vs', at_external the_ge (State rs' m') = Some (ef, vs') /\ val_erasure_list vs vs'.
Lemma after_external_erase : forall v v' c c' m m' c2 (HeraseCores: core_erasure c c') (HeraseVal: optionval_erasure v v') (HeraseMem: mem_erasure m m') (Hafter_external: after_external the_ge v c m = Some c2), exists (c2' : state), after_external the_ge v' c' m' = Some c2' /\ core_erasure c2 c2'.
Lemma make_arg_erasure: forall rs rs' m m' r arg arg' rs2 m2 (Hregs: regs_erasure rs rs') (Hmem: mem_erasure' m m') (Hargs: val_erasure arg arg') (Hmake: make_arg rs m r arg = Some (rs2, m2)), exists rs2' m2', make_arg rs' m' r arg' = Some (rs2', m2') /\ regs_erasure rs2 rs2' /\ mem_erasure' m2 m2'.
Lemma halted_erase: forall c c' h (HeraseCores: core_erasure c c') (Hhalted: halted semSem c h), halted semSem c' h.
Lemma eval_testcond_erasure: forall (c : testcond) rs rs' (Hrs: regs_erasure rs rs'), eval_testcond c rs <> None -> eval_testcond c rs = eval_testcond c rs'.
Lemma eval_addrmode32_erase: forall g a rs rs', regs_erasure rs rs' -> val_erasure (eval_addrmode32 g a rs) (eval_addrmode32 g a rs').
Lemma eval_addrmode_erase: forall g a rs rs', regs_erasure rs rs' -> isPointer (eval_addrmode g a rs) -> eval_addrmode g a rs = eval_addrmode g a rs'.
Lemma regs_erasure_undef: forall regs rs rs', regs_erasure rs rs' -> regs_erasure (undef_regs regs rs) (undef_regs regs rs').
Lemma regs_erasure_set_res: forall res v v' rs rs' (Hregs: regs_erasure rs rs') (Hval: val_erasure v v'), regs_erasure (set_res res v rs) (set_res res v' rs').
Lemma val_erasure_addrmode: forall g (a : addrmode) rs rs' (Hrs: regs_erasure rs rs'), val_erasure (eval_addrmode g a rs) (eval_addrmode g a rs').
Lemma compare_ints_erasure: forall v1 v2 v1' v2' rs rs' m m' (Hval_erasure: val_erasure v1 v1') (Hval_erasure': val_erasure v2 v2') (Hrs: regs_erasure rs rs') (Hmem: mem_erasure m m'), regs_erasure (compare_ints v1 v2 rs m) (compare_ints v1' v2' rs' m').
Lemma compare_floats_erasure: forall v1 v2 v1' v2' rs rs' (Hval_erasure: val_erasure v1 v1') (Hval_erasure2: val_erasure v2 v2') (Hrs: regs_erasure rs rs'), regs_erasure (compare_floats v1 v2 rs) (compare_floats v1' v2' rs').
Lemma compare_floats32_erasure: forall v1 v2 v1' v2' rs rs' (Hval_erasure: val_erasure v1 v1') (Hval_erasure2: val_erasure v2 v2') (Hrs: regs_erasure rs rs'), regs_erasure (compare_floats32 v1 v2 rs) (compare_floats32 v1' v2' rs').
Lemma get_reg_erasure: forall rs rs' r (Hregs_erasure: regs_erasure rs rs') (Hundef: rs r <> Vundef), rs r = rs' r.
Lemma erasure_eval_testcond: forall c rs rs' b, regs_erasure rs rs' -> eval_testcond c rs = Some b -> eval_testcond c rs' = Some b.
Lemma eval_addrmode64_erase: forall g a rs rs', regs_erasure rs rs' -> val_erasure (eval_addrmode64 g a rs) (eval_addrmode64 g a rs').
Lemma compare_longs_erasure: forall v1 v1' v2 v2' rs rs' m m' (Hval1: val_erasure v1 v1') (Hval2: val_erasure v2 v2') (Hregs: regs_erasure rs rs') (Hmem: mem_erasure m m'), regs_erasure (compare_longs v1 v2 rs m) (compare_longs v1' v2' rs' m').
Lemma exec_instr_erased: forall (fn : function) (i : instruction) (rs rs' rs2: regset) (m m' m2 : mem) ev (HeraseCores: regs_erasure rs rs') (HerasedMem: mem_erasure m m') (Hexec_ev: Asm_event.drf_instr the_ge (fn_code fn) i rs m = Some ev) (Hexec: exec_instr the_ge fn i rs m = Next rs2 m2), exists rs2' m2' ev', exec_instr the_ge fn i rs' m' = Next rs2' m2' /\ Asm_event.drf_instr the_ge (fn_code fn) i rs' m' = Some ev' /\ regs_erasure rs2 rs2' /\ mem_erasure m2 (erasePerm m2') /\ mem_event_list_erasure ev ev'.
Lemma eval_builtin_arg_ev_erasure: forall rs rs' sp sp' m m' ba v T (Hrs: regs_erasure rs rs') (Hsp: val_erasure sp sp') (Hmem: mem_erasure m m') (Hbuiltin: Asm_event.eval_builtin_arg_ev _ the_ge rs sp m ba v T), exists v' T', Asm_event.eval_builtin_arg_ev _ the_ge rs' sp' m' ba v' T' /\ val_erasure v v' /\ mem_event_list_erasure T T'.
Lemma eval_builtin_args_ev_erasure: forall rs rs' sp sp' m m' ba vs T (Hrs: regs_erasure rs rs') (Hsp: val_erasure sp sp') (Hmem: mem_erasure m m') (Hbuiltin_ev: Asm_event.eval_builtin_args_ev _ the_ge rs sp m ba vs T), exists vs' T', Asm_event.eval_builtin_args_ev _ the_ge rs' sp' m' ba vs' T' /\ val_erasure_list vs vs' /\ mem_event_list_erasure T T'.
Lemma builtin_event_erasure: forall ef m1 m1' vs1 vs1' T1 (Hmem: mem_erasure m1 m1') (Hval_erasure: val_erasure_list vs1 vs1') (Hbuiltin: Asm_event.builtin_event ef m1 vs1 T1), exists T1', Asm_event.builtin_event ef m1' vs1' T1' /\ mem_event_list_erasure T1 T1'.
Lemma external_call_erasure: forall ef m1 m1' vs1 vs1' t m2 vres (Hef: match ef with | EF_memcpy _ _ | EF_malloc | EF_free => True | _ => False end) (Hmem: mem_erasure m1 m1') (Hval_erasure: val_erasure_list vs1 vs1') (Hextcall: external_call ef the_ge vs1 m1 t vres m2), exists vres' m2', external_call ef the_ge vs1' m1' t vres' m2' /\ val_erasure vres vres' /\ mem_erasure m2 (erasePerm m2').
Lemma evstep_erase: forall c1 c1' c2 ev m1 m1' m2 (HeraseCores: core_erasure c1 c1') (HerasedMem: mem_erasure m1 m1') (Hstep: ev_step semSem c1 m1 ev c2 m2), exists c2' m2' ev', ev_step semSem c1' m1' ev' c2' m2' /\ core_erasure c2 c2' /\ mem_erasure m2 (erasePerm m2') /\ mem_event_list_erasure ev ev'.