(* Definition split_rmap (m: rmap) : rmap * rmap := (proj1_sig (make_rmap _ (split_rmap_valid1 m) (level m) (split_rmap_ok1 m)), proj1_sig (make_rmap _ (split_rmap_valid2 m) (level m) (split_rmap_ok2 m))). *)

(* Specifications: *)
Lemma split_resource_join:
forall r, join (fst (split_resource r)) (snd (split_resource r)) r.
(*Lemma split_rmap_join: forall m, join (fst (split_rmap m)) (snd (split_rmap m)) m.  Lemma split_rmap_at1: forall m l , fst (split_rmap m) @ l = fst (split_resource (m @ l)).  Lemma split_rmap_at2: forall m l , snd (split_rmap m) @ l = snd (split_resource (m @ l)).  Definition split_shareval (shv: Share.t * val) : ((Share.t * val) * (Share.t * val)) := ((fst (Share.split (fst shv)), snd shv), (snd (Share.split (fst shv)), snd shv)).  Definition slice_resource (sh: share) (r: resource) : resource := match r with | NO _ _ => NO (retainer_part sh) (retainer_part_nonreadable sh) | YES _ _ k pp => match readable_share_dec sh with | left r1 => YES sh r1 k pp | right n => NO sh n end | PURE k pp => PURE k pp end.   Lemma make_slice_rmap: forall w (P: address -> Prop) (P_DEC: forall l, {P l} + {~ P l}) sh, (forall l : AV.address, ~ P l -> identity (w @ l)) -> {w' | level w' = level w /\ resource_at w' = (fun l => if P_DEC l then slice_resource sh (w @ l) else w @ l) /\ ghost_of w' = ghost_of w}.  Lemma jam_noat_splittable_aux: forall S' S Q (PARAMETRIC: spec_parametric Q) (sh1 sh2 sh3: share) (rsh1: readable_share sh1) (rsh2: readable_share sh2) l (H: join sh1 sh2 sh3) w (H0: allp (@jam _ _ _ _ _ _ (S' l) (S l) (Q l sh3) noat) w) f (Hf: resource_at f = fun loc => slice_resource (if S l loc then sh1 else Share.bot) (w @ loc)) g (Hg: resource_at g = fun loc => slice_resource (if S l loc then sh2 else Share.bot) (w @ loc)) (H1: join f g w), allp (jam (S l) (Q l sh1) noat) f.  Lemma slice_resource_identity: forall r, identity r -> slice_resource Share.bot r = r.  Definition splittable {A} {JA: Join A}{PA: Perm_alg A}{agA: ageable A}{AgeA: Age_alg A} (Q: Share.t -> pred A) := forall (sh1 sh2 sh3: Share.t) (rsh1: readable_share sh1) (rsh2: readable_share sh2), join sh1 sh2 sh3 -> Q sh1 * Q sh2 = Q sh3.  (*Lemma jam_noat_splittable: forall (S': address -> address -> Prop) S (Q: address -> spec) (PARAMETRIC: spec_parametric Q), forall l, splittable (fun sh => allp (@jam _ _ _ _ _ _ (S' l) (S l) (Q l sh) noat)).  (*Lemma address_mapsto_splittable: forall ch v l, splittable (fun sh => address_mapsto ch v sh l).  Lemma VALspec_splittable: forall l, splittable (fun sh => VALspec sh l).  Lemma LKspec_splittable size: forall R l, splittable (fun sh => LKspec size R sh l).  Lemma VALspec_range_splittable: forall n l, splittable (fun sh => VALspec_range n sh l).  Definition share_oblivious (P: pred rmap) := forall w w', (forall l, match w' @ l , w @ l with | NO _ _, NO _ _ => True | YES _ sh1 k1 p1 , YES _ sh2 k2 p2 => k1=k2 /\ p1=p2 | PURE k1 p1, PURE k2 p2 => k1=k2 /\ p1=p2 | _ , _ => False end) -> P w' -> P w.  (*Lemma intersection_splittable: forall (S': address -> address -> Prop) S P Q, spec_parametric P -> (forall l, share_oblivious (Q l)) -> forall l, splittable (fun sh => allp (@jam _ _ _ _ _ _ (S' l) (S l) (P l sh) noat) && Q l).  Lemma not_readable_share_retainer_part_eq: forall sh, ~ readable_share sh -> retainer_part sh = sh. intros. apply not_not_share_identity in H. unfold retainer_part. rewrite (comp_parts comp_Lsh_Rsh sh) at 2. apply identity_share_bot in H; rewrite H. rewrite Share.lub_bot. auto. Qed.  Lemma slice_resource_resource_share: forall r sh sh', resource_share r = Some sh -> join_sub sh' sh -> resource_share (slice_resource sh' r) = Some sh'.  Lemma slice_resource_nonlock: forall r sh sh', resource_share r = Some sh -> join_sub sh' sh -> nonlock r -> nonlock (slice_resource sh' r).  Lemma NO_ext: forall sh1 sh2 rsh1 rsh2, sh1=sh2 -> NO sh1 rsh1 = NO sh2 rsh2.  Lemma slice_resource_share_join: forall sh1 sh2 sh r, join sh1 sh2 sh -> resource_share r = Some sh -> join (slice_resource sh1 r) (slice_resource sh2 r) r.  Definition resource_share_split (p q r: address -> pred rmap): Prop := exists p' q' r' p_sh q_sh r_sh, is_resource_pred p p' /\ is_resource_pred q q' /\ is_resource_pred r r' /\ join q_sh r_sh p_sh /\ (forall res l n, p' res l n -> resource_share res = Some p_sh /\ q' (slice_resource q_sh res) l n /\ r' (slice_resource r_sh res) l n) /\ (forall p_res q_res r_res l n, join q_res r_res p_res -> q' q_res l n -> r' r_res l n -> p' p_res l n).  (* We should use this lemma to prove all share_join lemmas, also all splittable lemmas. *)
Lemma allp_jam_share_split: forall (P: address -> Prop) (p q r: address -> pred rmap)
(P_DEC: forall l, {P l} + {~ P l}),
resource_share_split p q r ->
allp (jam P_DEC p noat) && noghost =
(allp (jam P_DEC q noat) && noghost) * (allp (jam P_DEC r noat) && noghost).
Lemma address_mapsto_share_join:
forall (sh1 sh2 sh : share) ch v a,
join sh1 sh2 sh ->
readable_share sh1 -> readable_share sh2 ->
address_mapsto ch v sh1 a * address_mapsto ch v sh2 a
= address_mapsto ch v sh a.
Lemma nonlock_permission_bytes_address_mapsto_join:
forall (sh1 sh2 sh : share) ch v a,
join sh1 sh2 sh ->
readable_share sh2 ->
nonlock_permission_bytes sh1 a (Memdata.size_chunk ch)
* address_mapsto ch v sh2 a
= address_mapsto ch v sh a.
Lemma VALspec_range_share_join:
forall sh1 sh2 sh n p,
readable_share sh1 ->
readable_share sh2 ->
join sh1 sh2 sh ->
VALspec_range n sh1 p *
VALspec_range n sh2 p =
VALspec_range n sh p.
Lemma nonlock_permission_bytes_share_join:
forall sh1 sh2 sh a n,
join sh1 sh2 sh ->
nonlock_permission_bytes sh1 a n *
nonlock_permission_bytes sh2 a n =
nonlock_permission_bytes sh a n.
Lemma nonlock_permission_bytes_VALspec_range_join:
forall sh1 sh2 (rsh2: readable_share sh2) sh p n,
join sh1 sh2 sh ->
nonlock_permission_bytes sh1 p n *
VALspec_range n sh2 p =
VALspec_range n sh p.
Lemma is_resource_pred_YES_LK lock_size (l: address) (R: pred rmap) sh:
is_resource_pred
(fun l' => yesat (SomeP rmaps.Mpred (fun _ => R)) (LK lock_size (snd l' - snd l)) sh l')
(fun r (l': address) n => exists p, r = YES sh p (LK lock_size (snd l' - snd l))
(SomeP rmaps.Mpred (fun _ => approx n R))).