Local Open Scope pred.
Definition cleave (sh: share) :=
(Share.lub (fst (Share.split (Share.glb Share.Lsh sh))) (fst (Share.split (Share.glb Share.Rsh sh))),
Share.lub (snd (Share.split (Share.glb Share.Lsh sh))) (snd (Share.split (Share.glb Share.Rsh sh)))).
Definition split_resource r :=
match r with YES sh rsh k pp =>
(YES (fst (cleave sh)) (cleave_readable1 _ rsh) k pp ,
YES (snd (cleave sh)) (cleave_readable2 _ rsh) k pp)
| PURE k pp => (PURE k pp, PURE k pp)
| NO sh nsh => (NO (fst (cleave sh)) (cleave_nonreadable1 _ nsh),
NO (snd (cleave sh)) (cleave_nonreadable2 _ nsh))
end.
(* 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))). *)

(*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).