Module Rmaps_Lemmas (R0: RMAPS).
Module R := R0.
Hint Resolve (@subp_sepcon _ Join_rmap Perm_rmap Sep_rmap): contractive.

(* Specifications: *)
Lemma approx_p  : forall (p:pred rmap) n w, approx n p w -> p w.
Lemma NO_identity: forall nsh, identity (NO Share.bot nsh).
Lemma PURE_identity: forall k pds, identity (PURE k pds).
Lemma identity_NO:
forall r, identity  r -> r = NO Share.bot bot_unreadable \/ exists k, exists pds, r = PURE k pds.
Lemma age1_resource_at_identity:
forall phi phi' loc, age1 phi = Some phi' ->
(identity (phi@loc) <-> identity (phi'@loc)).
Lemma necR_resource_at_identity:
forall phi phi' loc, necR phi phi' ->
identity (phi@loc) ->
identity (phi'@loc).
Lemma make_rmap': forall f g,
exists phi: rmap', phi = (f, g).
Lemma make_rmap (f: AV.address -> resource) g
(n: nat) (H: resource_fmap (approx n) (approx n) oo f = f)
(HG: ghost_fmap (approx n) (approx n) g = g) :
{phi: rmap | level phi = n /\ resource_at phi = f /\ ghost_of phi = g}.
Lemma make_rmap'':
forall n (f: AV.address -> resource) g,
exists phi:rmap, level phi = n /\ resource_at phi = resource_fmap (approx n) (approx n) oo f /\
ghost_of phi = ghost_fmap (approx n) (approx n) g.
Lemma approx_oo_approx':
forall n n', (n' >= n)%nat -> approx n oo approx n' = approx n.
Lemma approx'_oo_approx:
forall n n', (n' >= n)%nat -> approx n' oo approx n = approx n.
Lemma approx_oo_approx: forall n, approx n oo approx n = approx n.
Lemma preds_fmap_fmap:
forall f1 f2 g1 g2 pp, preds_fmap f1 f2 (preds_fmap g1 g2 pp) = preds_fmap (f1 oo g1) (g2 oo f2) pp.
Lemma resources_same_level:
forall f phi,
(forall l : AV.address, join_sub (f l) (phi @ l)) ->
resource_fmap (approx (level phi)) (approx (level phi)) oo f = f.
Lemma ghost_fmap_fmap:  forall f1 f2 g1 g2 r,
ghost_fmap f1 f2 (ghost_fmap g1 g2 r) = ghost_fmap (f1 oo g1) (g2 oo f2) r.
Lemma ghost_same_level:
forall g phi, join_sub g (ghost_of phi) ->
ghost_fmap (approx (level phi)) (approx (level phi)) g = g.
Lemma deallocate:
forall (phi: rmap) (f g : AV.address -> resource) a b,
(forall l, join  (f l) (g l) (phi@l)) -> join a b (ghost_of phi) ->
exists phi1, exists phi2,
join phi1 phi2 phi /\ resource_at phi1 = f /\ ghost_of phi1 = a.
Lemma unsquash_inj : forall x y,
unsquash x = unsquash y -> x = y.
Lemma resource_fmap_fmap:  forall f1 f2 g1 g2 r, resource_fmap f1 f2 (resource_fmap g1 g2 r) =
resource_fmap (f1 oo g1) (g2 oo f2) r.
Lemma ghost_of_approx:
forall phi,
ghost_fmap (approx (level phi)) (approx (level phi)) (ghost_of phi) = ghost_of phi.
Lemma ghost_same_level_gen:
forall n a b c, join (ghost_fmap (approx n) (approx n) a) (ghost_fmap (approx n) (approx n) b) c ->
ghost_fmap (approx n) (approx n) c = c.
Lemma allocate:
forall (phi : rmap) (f : AV.address -> resource) a,
resource_fmap (approx (level phi)) (approx (level phi)) oo f = f ->
(forall l, {r' | join (phi@l) (f l) r'}) ->
ghost_fmap (approx (level phi)) (approx (level phi)) a = a ->
{a' | join (ghost_of phi) a a'} ->
exists phi1 : rmap,
exists phi2 : rmap,
join phi phi1 phi2 /\ resource_at phi1 = f /\ ghost_of phi1 = a.
Lemma rmap_ext: forall phi1 phi2,
level phi1 = level phi2 ->
(forall l, phi1@l = phi2@l) ->
ghost_of phi1 = ghost_of phi2 ->
phi1=phi2.
Lemma resource_at_join:
forall phi1 phi2 phi3 loc,
join phi1 phi2 phi3 ->
join (phi1@loc) (phi2@loc) (phi3@loc).
Lemma ghost_of_join:
forall phi1 phi2 phi3,
join phi1 phi2 phi3 ->
join (ghost_of phi1) (ghost_of phi2) (ghost_of phi3).
Lemma resource_at_join2:
forall phi1 phi2 phi3,
level phi1 = level phi3 -> level phi2 = level phi3 ->
(forall loc, join (phi1@loc) (phi2@loc) (phi3@loc)) ->
join (ghost_of phi1) (ghost_of phi2) (ghost_of phi3) ->
join phi1 phi2 phi3.
Lemma all_resource_at_identity:
forall w, (forall l, identity (w@l)) -> identity (ghost_of w) ->
identity w.
Lemma ageN_squash : forall d n rm, le d n ->
ageN d (squash (n, rm)) = Some (squash ((n - d)%nat, rm)).
Lemma unageN: forall n (phi': rmap),   exists phi, ageN n phi = Some phi'.
Lemma ex_level0: exists phi, age1 phi = None.
Lemma ex_level: forall n, exists phi, level phi = n.
Lemma YES_join_full:
forall sh rsh n P r2 r3,
join (R.YES sh rsh n P) r2 r3 ->
writable0_share sh ->
exists sh2 rsh2, r2 = NO sh2 rsh2.
Lemma YES_not_identity:
forall sh rsh k Q, ~ identity (YES sh rsh k Q).
Lemma YES_overlap:
forall sh0 rsh0 sh1 rsh1 (phi0 phi1: rmap) loc k k' p p',
joins phi0 phi1 ->
phi1@loc = R.YES sh1 rsh1 k p ->
writable0_share sh1 ->
phi0@loc = R.YES sh0 rsh0 k' p' ->
False.
Lemma necR_NOx:
forall phi phi' l sh nsh,
necR phi phi' ->
phi@l = NO sh nsh ->
phi'@l = NO sh nsh.