(** *Monotonicity (inject_incr)*)
Class Inject_Monotonic {A:Type}(R: meminj -> relation A):=
monotonicity: forall j j' a1 a2,
R j a1 a2 ->
inject_incr j j' ->
R j' a1 a2.
Ltac emonotonicity:=
try (unfold Inject_Monotonic);
eapply monotonicity.
Instance list_map_rel_monotonicity:
forall {A} {R: meminj -> relation A},
Inject_Monotonic R ->
Inject_Monotonic (fun j => list_map_rel (R j)).
Instance memval_inject_monotonic:
Inject_Monotonic memval_inject:=
memval_inject_incr.
Instance list_memval_inject_monotonic:
Inject_Monotonic list_memval_inject.
Instance inject_hi_low_monotonic:
Inject_Monotonic inject_hi_low.
Instance list_inject_hi_low_monotonic:
Inject_Monotonic list_inject_hi_low.
Instance list_inject_mem_effect_monotonic :
Inject_Monotonic Events.list_inject_mem_effect.
(** *strict_injection_evolution *)
Inductive injection_evolution_effect:
meminj -> meminj ->
Events.mem_effect -> Events.mem_effect -> Prop:=
|EffEvolWrite: forall b1 b2 ofs1 ofs2 mvs1 mvs2 j,
Events.inject_mem_effect
j
(common.Events.Write b1 ofs1 mvs1)
(common.Events.Write b2 ofs2 mvs2) ->
injection_evolution_effect
j j
(common.Events.Write b1 ofs1 mvs1)
(common.Events.Write b2 ofs2 mvs2)
|EffEvolAlloc: forall j j' (b1 b2:block) ofs1 ofs1',
j b1 = None -> (* Do we need this? *)
j' = (fun b => if eq_block b b1 then
Some (b2, 0%Z) else j b) ->
injection_evolution_effect
j j'
(common.Events.Alloc b1 ofs1 ofs1')
(common.Events.Alloc b2 ofs1 ofs1')
|EffEvolFree: forall  j ls1 ls2,
Events.inject_mem_effect j
(common.Events.Free ls1)
(common.Events.Free ls2) ->
injection_evolution_effect
j j
(common.Events.Free ls1)
(common.Events.Free ls2).
Inductive strict_injection_evolution:
meminj -> meminj ->
list Events.mem_effect -> list Events.mem_effect -> Prop:=
| EvolutionNil: forall j,
strict_injection_evolution j j nil nil
| EvolutionCons: forall j j' j'' ev1 ev2 ls1 ls2,
injection_evolution_effect j j' ev1 ev2 ->
strict_injection_evolution j' j'' ls1 ls2 ->
strict_injection_evolution
j j''
(ev1::ls1) (ev2::ls2).

Lemma evolution_inject_incr:
forall j j' lev1 lev2,
strict_injection_evolution j j' lev1 lev2 ->
inject_incr j j'.