Inductive res_join' : resource -> resource -> resource -> Type :=
res_join'_NO1 : forall (sh1 sh2 sh3 : Share.t) nsh1 nsh2 nsh3,
sepalg.join sh1 sh2 sh3 ->
res_join' (NO sh1 nsh1) (NO sh2 nsh2) (NO sh3 nsh3)
| res_join'_NO2 : forall (sh1 sh2 sh3 : Share.t) rsh1 nsh2 rsh3
(k : AV.kind) (p : preds),
sepalg.join sh1 sh2 sh3 ->
res_join' (YES sh1 rsh1 k p) (NO sh2 nsh2) (YES sh3 rsh3 k p)
| res_join'_NO3 : forall (sh1 sh2 sh3 : Share.t) nsh1 rsh2 rsh3
(k : AV.kind) (p : preds),
sepalg.join sh1 sh2 sh3 ->
res_join' (NO sh1 nsh1) (YES sh2 rsh2 k p) (YES sh3 rsh3 k p)
| res_join'_YES : forall (sh1 sh2 sh3 : Share.t) rsh1 rsh2 rsh3
(k : AV.kind) (p : preds),
sepalg.join sh1 sh2 sh3 ->
res_join' (YES sh1 rsh1 k p) (YES sh2 rsh2 k p) (YES sh3 rsh3 k p)
| res_join'_PURE : forall (k : AV.kind) (p : preds),
res_join' (PURE k p) (PURE k p) (PURE k p).

(* Specifications: *)
Lemma res_join'_spec r1 r2 r3 : res_join r1 r2 r3 -> res_join' r1 r2 r3.
Lemma res_join'_spec_inv r1 r2 r3 : res_join' r1 r2 r3 -> res_join r1 r2 r3.
Lemma res_option_age_to n phi loc : res_option ((age_to n phi) @ loc) = res_option (phi @ loc).
Lemma resource_decay_at_LK {nextb n r1 r2 b sh n' i} :
resource_decay_at nextb n r1 r2 b ->
res_option r1 = Some (sh, LK n' i) <->
res_option r2 = Some (sh, LK n' i).
Lemma resource_decay_join b phi1 phi1' phi2 phi3 :
rmap_bound b phi2 ->
resource_decay b phi1 phi1' ->
ghost_of phi1' = own.ghost_approx phi1' (ghost_of phi1) ->
sepalg.join phi1 phi2 phi3 ->
exists phi3',
sepalg.join phi1' (age_to (level phi1') phi2) phi3' /\
resource_decay b phi3 phi3' /\ ghost_of phi3' = own.ghost_approx phi3' (ghost_of phi3).