(*CompCert imports*)
(* A minimal preservation property we sometimes require.*)
Definition mem_forward (m1 m2:mem) :=
(forall b, Mem.valid_block m1 b ->
Mem.valid_block m2 b /\
forall ofs p, Mem.perm m2 b ofs Max p -> Mem.perm m1 b ofs Max p).
Definition val_inject_opt (j: meminj) (v1 v2: option val) :=
match v1, v2 with Some v1', Some v2' => val_inject j v1' v2'
| None, None => True
| _, _ => False
end.
(******** Compatibility of memory operation with mem_forward********)
(*This is an [F,V]-independent definition of meminj_preserves_globals*)
Definition meminj_preserves_globals_ind (globals: (block->Prop)*(block->Prop)) f :=
(forall b, fst globals b -> f b = Some (b, 0)) /\
(forall b, snd globals b -> f b = Some (b, 0)) /\
(forall b1 b2 delta, snd globals b2 -> f b1 = Some (b2, delta) -> b1=b2).
Definition genv2blocks {F V: Type} (ge: Genv.t F V) :=
(fun b => exists id, Genv.find_symbol ge id = Some b,
fun b => exists gv, Genv.find_var_info ge b = Some gv).
Definition genvs_domain_eq {F1 F2 V1 V2: Type} (ge1: Genv.t F1 V1) (ge2: Genv.t F2 V2) :=
(forall b, fst (genv2blocks ge1) b <-> fst (genv2blocks ge2) b) /\
(forall b, snd (genv2blocks ge1) b <-> snd (genv2blocks ge2) b).

Lemma meminj_preserves_globals_ind_compose:
forall {F1 V1 F2 V2} (ge1: Genv.t F1 V1) (ge2: Genv.t F2 V2)
j1 j2 (G: genvs_domain_eq ge1 ge2)
(PG1: meminj_preserves_globals_ind (genv2blocks ge1) j1)
(PG2: meminj_preserves_globals_ind (genv2blocks ge2) j2),
meminj_preserves_globals_ind (genv2blocks ge1) (compose_meminj j1 j2).