(* In fact we need locks to two resources: 1) the resource invariant, for passing the resources 2) the join resource invariant, for returning all resources, including itself for this we need to define them in a mutually recursive fashion: *)
Definition res_invariants Q sh1 p1 sh2 p2 : bool -> mpred := HORec (res_invariants_fun Q sh1 p1 sh2 p2).
Definition res_invariant Q sh1 p1 sh2 p2 : mpred := res_invariants Q sh1 p1 sh2 p2 true.
Definition join_res_invariant Q sh1 p1 sh2 p2 : mpred := res_invariants Q sh1 p1 sh2 p2 false.

(* Specifications: *)
Lemma res_invariants_eq Q sh1 p1 sh2 p2 : res_invariants Q sh1 p1 sh2 p2 =
res_invariants_fun Q sh1 p1 sh2 p2 (res_invariants Q sh1 p1 sh2 p2).
Lemma res_invariant_eq Q sh1 p1 sh2 p2 :
res_invariant Q sh1 p1 sh2 p2 =
(Q *
lock_inv sh2 p2 (|> join_res_invariant Q sh1 p1 sh2 p2))%logic.
Lemma join_res_invariant_eq Q sh1 p1 sh2 p2 :
join_res_invariant Q sh1 p1 sh2 p2 =
(Q *
lock_inv sh1 p1 (|> res_invariant Q sh1 p1 sh2 p2) *
lock_inv sh2 p2 (|> join_res_invariant Q sh1 p1 sh2 p2))%logic.
Lemma res_invariants_eq Q sh1 p1 sh2 p2 : res_invariants Q sh1 p1 sh2 p2 =
res_invariants_fun Q sh1 p1 sh2 p2 (res_invariants Q sh1 p1 sh2 p2).
Lemma res_invariant_eq Q sh1 p1 sh2 p2 :
res_invariant Q sh1 p1 sh2 p2 =
(Q *
lock_inv sh2 p2 (|> join_res_invariant Q sh1 p1 sh2 p2))%logic.
Lemma join_res_invariant_eq Q sh1 p1 sh2 p2 :
join_res_invariant Q sh1 p1 sh2 p2 =
(Q *
lock_inv sh1 p1 (|> res_invariant Q sh1 p1 sh2 p2) *
lock_inv sh2 p2 (|> join_res_invariant Q sh1 p1 sh2 p2))%logic.