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

(* Specifications: *)
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))).
Lemma LKspec_share_join lock_size: forall sh1 sh2 (rsh1: readable_share sh1) (rsh2: readable_share sh2) sh R p, join sh1 sh2 sh -> LKspec lock_size R sh1 p * LKspec lock_size R sh2 p = LKspec lock_size R sh p.