(** Preservation of [free] operations *)

(* Specifications: *)
Lemma free_left_inject:
forall f m1 m2 b lo hi m1',
inject f m1 m2 ->
free m1 b lo hi = Some m1' ->
inject f m1' m2.
Lemma free_list_left_inject:
forall f m2 l m1 m1',
inject f m1 m2 ->
free_list m1 l = Some m1' ->
inject f m1' m2.
Lemma free_right_inject:
forall f m1 m2 b lo hi m2',
inject f m1 m2 ->
free m2 b lo hi = Some m2' ->
(forall b1 delta ofs k p,
f b1 = Some(b, delta) -> perm m1 b1 ofs k p ->
lo <= ofs + delta < hi -> False) ->
inject f m1 m2'.
Lemma perm_free_list:
forall l m m' b ofs k p,
free_list m l = Some m' ->
perm m' b ofs k p ->
perm m b ofs k p /\
(forall lo hi, In (b, lo, hi) l -> lo <= ofs < hi -> False).
Theorem free_inject:
forall f m1 l m1' m2 b lo hi m2',
inject f m1 m2 ->
free_list m1 l = Some m1' ->
free m2 b lo hi = Some m2' ->
(forall b1 delta ofs k p,
f b1 = Some(b, delta) ->
perm m1 b1 ofs k p -> lo <= ofs + delta < hi ->
exists lo1, exists hi1, In (b1, lo1, hi1) l /\ lo1 <= ofs < hi1) ->
inject f m1' m2'.
Theorem free_parallel_inject:
forall f m1 m2 b lo hi m1' b' delta,
inject f m1 m2 ->
free m1 b lo hi = Some m1' ->
f b = Some(b', delta) ->
exists m2',
free m2 b' (lo + delta) (hi + delta) = Some m2'
/\ inject f m1' m2'.
Lemma drop_outside_inject: forall f m1 m2 b lo hi p m2',
inject f m1 m2 ->
drop_perm m2 b lo hi p = Some m2' ->
(forall b' delta ofs k p,
f b' = Some(b, delta) ->
perm m1 b' ofs k p -> lo <= ofs + delta < hi -> False) ->
inject f m1 m2'.
Lemma free_left_inject:
forall f m1 m2 b lo hi m1',
inject f m1 m2 ->
free m1 b lo hi = Some m1' ->
inject f m1' m2.
Lemma free_list_left_inject:
forall f m2 l m1 m1',
inject f m1 m2 ->
free_list m1 l = Some m1' ->
inject f m1' m2.
Lemma free_right_inject:
forall f m1 m2 b lo hi m2',
inject f m1 m2 ->
free m2 b lo hi = Some m2' ->
(forall b1 delta ofs k p,
f b1 = Some(b, delta) -> perm m1 b1 ofs k p ->
lo <= ofs + delta < hi -> False) ->
inject f m1 m2'.
Lemma perm_free_list:
forall l m m' b ofs k p,
free_list m l = Some m' ->
perm m' b ofs k p ->
perm m b ofs k p /\
(forall lo hi, In (b, lo, hi) l -> lo <= ofs < hi -> False).
Theorem free_inject:
forall f m1 l m1' m2 b lo hi m2',
inject f m1 m2 ->
free_list m1 l = Some m1' ->
free m2 b lo hi = Some m2' ->
(forall b1 delta ofs k p,
f b1 = Some(b, delta) ->
perm m1 b1 ofs k p -> lo <= ofs + delta < hi ->
exists lo1, exists hi1, In (b1, lo1, hi1) l /\ lo1 <= ofs < hi1) ->
inject f m1' m2'.
Theorem free_parallel_inject:
forall f m1 m2 b lo hi m1' b' delta,
inject f m1 m2 ->
free m1 b lo hi = Some m1' ->
f b = Some(b', delta) ->
exists m2',
free m2 b' (lo + delta) (hi + delta) = Some m2'
/\ inject f m1' m2'.
Lemma drop_outside_inject: forall f m1 m2 b lo hi p m2',
inject f m1 m2 ->
drop_perm m2 b lo hi p = Some m2' ->
(forall b' delta ofs k p,
f b' = Some(b, delta) ->
perm m1 b' ofs k p -> lo <= ofs + delta < hi -> False) ->
inject f m1 m2'.