Remark in_remove:
  forall (A: Type) (eq: forall (x y: A), {x=y}+{x<>y}) x y l,
  In y (List.remove eq x l) <-> x <> y /\ In y l.

(* Specifications: *)
Lemma forget_reg_charact: forall n rd r v, wf_numbering n -> In r (PMap.get v (forget_reg n rd)) -> r <> rd /\ In r (PMap.get v n.(num_val)).
Lemma update_reg_charact: forall n rd vd r v, wf_numbering n -> In r (PMap.get v (update_reg n rd vd)) -> PTree.get r (PTree.set rd vd n.(num_reg)) = Some v.
Lemma rhs_eval_to_inj: forall valu ge sp m rh v1 v2, rhs_eval_to valu ge sp m rh v1 -> rhs_eval_to valu ge sp m rh v2 -> v1 = v2.
Lemma set_res_unknown_holds: forall valu ge sp rs m n r v, numbering_holds valu ge sp rs m n -> numbering_holds valu ge sp (regmap_setres r v rs) m (set_res_unknown n r).
Lemma kill_eqs_charact: forall pred l strict r eqs, In (Eq l strict r) (kill_eqs pred eqs) -> pred r = false /\ In (Eq l strict r) eqs.
Lemma kill_equations_hold: forall valu ge sp rs m n pred m', numbering_holds valu ge sp rs m n -> (forall r v, pred r = false -> rhs_eval_to valu ge sp m r v -> rhs_eval_to valu ge sp m' r v) -> numbering_holds valu ge sp rs m' (kill_equations pred n).
Lemma kill_all_loads_hold: forall valu ge sp rs m n m', numbering_holds valu ge sp rs m n -> numbering_holds valu ge sp rs m' (kill_all_loads n).
Lemma store_normalized_range_sound: forall bc chunk v, vmatch bc v (store_normalized_range chunk) -> Val.lessdef (Val.load_result chunk v) v.
Lemma kill_loads_after_storebytes_holds: forall valu ge sp rs m n dst b ofs bytes m' bc approx ae am sz, numbering_holds valu ge (Vptr sp Ptrofs.zero) rs m n -> pmatch bc b ofs dst -> Mem.storebytes m b (Ptrofs.unsigned ofs) bytes = Some m' -> genv_match bc ge -> bc sp = BCstack -> ematch bc rs ae -> approx = VA.State ae am -> length bytes = nat_of_Z sz -> sz >= 0 -> numbering_holds valu ge (Vptr sp Ptrofs.zero) rs m' (kill_loads_after_storebytes approx n dst sz).
Lemma shift_memcpy_eq_wf: forall src sz delta e e' next, shift_memcpy_eq src sz delta e = Some e' -> wf_equation next e -> wf_equation next e'.
Lemma shift_memcpy_eq_holds: forall src dst sz e e' m sp bytes m' valu ge, shift_memcpy_eq src sz (dst - src) e = Some e' -> Mem.loadbytes m sp src sz = Some bytes -> Mem.storebytes m sp dst bytes = Some m' -> equation_holds valu ge (Vptr sp Ptrofs.zero) m e -> equation_holds valu ge (Vptr sp Ptrofs.zero) m' e'.
Lemma add_memcpy_eqs_charact: forall e' src sz delta eqs2 eqs1, In e' (add_memcpy_eqs src sz delta eqs1 eqs2) -> In e' eqs2 \/ exists e, In e eqs1 /\ shift_memcpy_eq src sz delta e = Some e'.
Lemma add_memcpy_holds: forall m bsrc osrc sz bytes bdst odst m' valu ge sp rs n1 n2 bc asrc adst, Mem.loadbytes m bsrc (Ptrofs.unsigned osrc) sz = Some bytes -> Mem.storebytes m bdst (Ptrofs.unsigned odst) bytes = Some m' -> numbering_holds valu ge (Vptr sp Ptrofs.zero) rs m n1 -> numbering_holds valu ge (Vptr sp Ptrofs.zero) rs m' n2 -> pmatch bc bsrc osrc asrc -> pmatch bc bdst odst adst -> bc sp = BCstack -> Ple (num_next n1) (num_next n2) -> numbering_holds valu ge (Vptr sp Ptrofs.zero) rs m' (add_memcpy n1 n2 asrc adst sz).
Lemma symbols_preserved: forall (s: ident), Genv.find_symbol tge s = Genv.find_symbol ge s.
Lemma senv_preserved: Senv.equiv ge tge.
Lemma functions_translated: forall (v: val) (f: RTL.fundef), Genv.find_funct ge v = Some f -> exists cu tf, Genv.find_funct tge v = Some tf /\ transf_fundef (romem_for cu) f = OK tf /\ linkorder cu prog.
Lemma funct_ptr_translated: forall (b: block) (f: RTL.fundef), Genv.find_funct_ptr ge b = Some f -> exists cu tf, Genv.find_funct_ptr tge b = Some tf /\ transf_fundef (romem_for cu) f = OK tf /\ linkorder cu prog.
Lemma sig_preserved: forall rm f tf, transf_fundef rm f = OK tf -> funsig tf = funsig f.