(*Join juice from all threads *)
Fixpoint join_list (ls: seq.seq res) r:=
if ls is phi::ls' then exists r', join phi r' r /\ join_list ls' r' else
app_pred emp r.  (*Or is is just [amp r]?*)
Definition join_threads (tp : thread_pool) r:= join_list (getThreadsR tp) r.

(* Specifications: *)
Lemma list_nth_error_eq : forall {A} (l1 l2 : list A)
(Heq : forall j, nth_error l1 j = nth_error l2 j), l1 = l2.
Lemma nth_error_enum : forall n m (H : (n <= m)%coq_nat) i, i < n ->
exists Hlt, nth_error (enum_from H) i = Some (@Ordinal m (n - 1 - i)%coq_nat Hlt).
Lemma minus_comm : forall a b c, ((a - b)%coq_nat - c = (a - c)%coq_nat - b)%coq_nat.
Lemma getThreadsR_addThread tp v1 v2 phi :
getThreadsR (addThread tp v1 v2 phi) = getThreadsR tp ++ phi :: nil.
Lemma list_nth_error_eq : forall {A} (l1 l2 : list A)
(Heq : forall j, nth_error l1 j = nth_error l2 j), l1 = l2.
Lemma nth_error_enum : forall n m (H : (n <= m)%coq_nat) i, i < n ->
exists Hlt, nth_error (enum_from H) i = Some (@Ordinal m (n - 1 - i)%coq_nat Hlt).
Lemma minus_comm : forall a b c, ((a - b)%coq_nat - c = (a - c)%coq_nat - b)%coq_nat.
Lemma getThreadsR_addThread tp v1 v2 phi :
getThreadsR (addThread tp v1 v2 phi) = getThreadsR tp ++ phi :: nil.