(** Special case of [external_call_mem_inject_gen] (for backward compatibility) *)

Definition meminj_preserves_globals (F V: Type) (ge: Genv.t F V) (f: block -> option (block * Z)) : Prop :=
     (forall id b, Genv.find_symbol ge id = Some b -> f b = Some(b, 0))
  /\ (forall b gv, Genv.find_var_info ge b = Some gv -> f b = Some(b, 0))
  /\ (forall b1 b2 delta gv, Genv.find_var_info ge b2 = Some gv -> f b1 = Some(b2, delta) -> b2 = b1).

(* Specifications: *)
Lemma external_call_mem_inject: forall ef F V (ge: Genv.t F V) vargs m1 t vres m2 f m1' vargs', meminj_preserves_globals ge f -> external_call ef ge vargs m1 t vres m2 -> Mem.inject f m1 m1' -> Val.inject_list f vargs vargs' -> exists f', exists vres', exists m2', external_call ef ge vargs' m1' t vres' m2' /\ Val.inject f' vres vres' /\ Mem.inject f' m2 m2' /\ Mem.unchanged_on (loc_unmapped f) m1 m2 /\ Mem.unchanged_on (loc_out_of_reach f m1) m1' m2' /\ inject_incr f f' /\ inject_separated f f' m1 m1'.
Lemma external_call_match_traces: forall ef ge vargs m t1 vres1 m1 t2 vres2 m2, external_call ef ge vargs m t1 vres1 m1 -> external_call ef ge vargs m t2 vres2 m2 -> match_traces ge t1 t2.
Lemma external_call_deterministic: forall ef ge vargs m t vres1 m1 vres2 m2, external_call ef ge vargs m t vres1 m1 -> external_call ef ge vargs m t vres2 m2 -> vres1 = vres2 /\ m1 = m2.
Lemma external_call_mem_inject: forall ef F V (ge: Genv.t F V) vargs m1 t vres m2 f m1' vargs', meminj_preserves_globals ge f -> external_call ef ge vargs m1 t vres m2 -> Mem.inject f m1 m1' -> injection_full f m1 -> Val.inject_list f vargs vargs' -> exists f', exists vres', exists m2', exists t', external_call ef ge vargs' m1' t' vres' m2' /\ Val.inject f' vres vres' /\ Mem.inject f' m2 m2' /\ Mem.unchanged_on (loc_unmapped f) m1 m2 /\ Mem.unchanged_on (loc_out_of_reach f m1) m1' m2' /\ inject_incr f f' /\ inject_separated f f' m1 m1' /\ inject_trace f' t t' /\ injection_full f' m2.
Lemma external_call_mem_inject': forall ef F V (ge: Genv.t F V) vargs m1 t vres m2 f m1' vargs', meminj_preserves_globals ge f -> external_call ef ge vargs m1 t vres m2 -> Mem.inject f m1 m1' -> Val.inject_list f vargs vargs' -> exists f', exists vres', exists m2', exists t', external_call ef ge vargs' m1' t' vres' m2' /\ Val.inject f' vres vres' /\ Mem.inject f' m2 m2' /\ Mem.unchanged_on (loc_unmapped f) m1 m2 /\ Mem.unchanged_on (loc_out_of_reach f m1) m1' m2' /\ inject_incr f f' /\ inject_separated f f' m1 m1' /\ inject_trace f' t t'.
Lemma external_call_match_traces: forall ef ge vargs m t1 vres1 m1 t2 vres2 m2, external_call ef ge vargs m t1 vres1 m1 -> external_call ef ge vargs m t2 vres2 m2 -> match_traces ge t1 t2.
Lemma external_call_deterministic: forall ef ge vargs m t vres1 m1 vres2 m2, external_call ef ge vargs m t vres1 m1 -> external_call ef ge vargs m t vres2 m2 -> vres1 = vres2 /\ m1 = m2.