Definition inj_offset_aligned (delta: Z) (size: Z) : Prop :=
forall chunk, size_chunk chunk <= size -> (align_chunk chunk | delta).

(* Specifications: *)
Lemma alloc_left_mapped_inj:
forall f m1 m2 lo hi m1' b1 b2 delta,
mem_inj f m1 m2 ->
alloc m1 lo hi = (m1', b1) ->
valid_block m2 b2 ->
inj_offset_aligned delta (hi-lo) ->
(forall ofs k p, lo <= ofs < hi -> perm m2 b2 (ofs + delta) k p) ->
f b1 = Some(b2, delta) ->
mem_inj f m1' m2.
Lemma free_left_inj:
forall f m1 m2 b lo hi m1',
mem_inj f m1 m2 ->
free m1 b lo hi = Some m1' ->
mem_inj f m1' m2.
Lemma free_right_inj:
forall f m1 m2 b lo hi m2',
mem_inj f m1 m2 ->
free m2 b lo hi = Some m2' ->
(forall b' delta ofs k p,
f b' = Some(b, delta) ->
perm m1 b' ofs k p -> lo <= ofs + delta < hi -> False) ->
mem_inj f m1 m2'.
Axiom alloc_left_mapped_inject:
forall f m1 m2 lo hi m1' b1 b2 delta,
inject f m1 m2 ->
alloc m1 lo hi = (m1', b1) ->
valid_block m2 b2 ->
0 <= delta <= Ptrofs.max_unsigned ->
(forall ofs k p, perm m2 b2 ofs k p -> delta = 0 \/ 0 <= ofs < Ptrofs.max_unsigned) ->
(forall ofs k p, lo <= ofs < hi -> perm m2 b2 (ofs + delta) k p) ->
inj_offset_aligned delta (hi-lo) ->
(forall b delta' ofs k p,
f b = Some (b2, delta') ->
perm m1 b ofs k p ->
lo + delta <= ofs + delta' < hi + delta -> False) ->
exists f',
inject f' m1' m2
/\ inject_incr f f'
/\ f' b1 = Some(b2, delta)
/\ (forall b, b <> b1 -> f' b = f b).
Axiom alloc_parallel_inject:
forall f m1 m2 lo1 hi1 m1' b1 lo2 hi2,
inject f m1 m2 ->
alloc m1 lo1 hi1 = (m1', b1) ->
lo2 <= lo1 -> hi1 <= hi2 ->
exists f', exists m2', exists b2,
alloc m2 lo2 hi2 = (m2', b2)
/\ inject f' m1' m2'
/\ inject_incr f f'
/\ f' b1 = Some(b2, 0)
/\ (forall b, b <> b1 -> f' b = f b).
Axiom 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'.
Axiom 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'.
Axiom 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 alloc_left_mapped_inj:
forall f m1 m2 lo hi m1' b1 b2 delta,
mem_inj f m1 m2 ->
alloc m1 lo hi = (m1', b1) ->
valid_block m2 b2 ->
inj_offset_aligned delta (hi-lo) ->
(forall ofs k p, lo <= ofs < hi -> perm m2 b2 (ofs + delta) k p) ->
f b1 = Some(b2, delta) ->
mem_inj f m1' m2.
Lemma free_left_inj:
forall f m1 m2 b lo hi m1',
mem_inj f m1 m2 ->
free m1 b lo hi = Some m1' ->
mem_inj f m1' m2.
Lemma free_right_inj:
forall f m1 m2 b lo hi m2',
mem_inj f m1 m2 ->
free m2 b lo hi = Some m2' ->
(forall b' delta ofs k p,
f b' = Some(b, delta) ->
perm m1 b' ofs k p -> lo <= ofs + delta < hi -> False) ->
mem_inj f m1 m2'.
Axiom alloc_left_mapped_inject:
forall f m1 m2 lo hi m1' b1 b2 delta,
inject f m1 m2 ->
alloc m1 lo hi = (m1', b1) ->
valid_block m2 b2 ->
0 <= delta <= Ptrofs.max_unsigned ->
(forall ofs k p, perm m2 b2 ofs k p -> delta = 0 \/ 0 <= ofs < Ptrofs.max_unsigned) ->
(forall ofs k p, lo <= ofs < hi -> perm m2 b2 (ofs + delta) k p) ->
inj_offset_aligned delta (hi-lo) ->
(forall b delta' ofs k p,
f b = Some (b2, delta') ->
perm m1 b ofs k p ->
lo + delta <= ofs + delta' < hi + delta -> False) ->
exists f',
inject f' m1' m2
/\ inject_incr f f'
/\ f' b1 = Some(b2, delta)
/\ (forall b, b <> b1 -> f' b = f b).
Axiom alloc_parallel_inject:
forall f m1 m2 lo1 hi1 m1' b1 lo2 hi2,
inject f m1 m2 ->
alloc m1 lo1 hi1 = (m1', b1) ->
lo2 <= lo1 -> hi1 <= hi2 ->
exists f', exists m2', exists b2,
alloc m2 lo2 hi2 = (m2', b2)
/\ inject f' m1' m2'
/\ inject_incr f f'
/\ f' b1 = Some(b2, 0)
/\ (forall b, b <> b1 -> f' b = f b).
Axiom 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'.
Axiom 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'.
Axiom 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'.