Ltac jmstep_inv :=
match goal with
| H : JuicyMachine.start_thread _ _ _ _  |- _ => inversion H
| H : JuicyMachine.resume_thread _ _ _   |- _ => inversion H
| H : JuicyMachine.threadStep _ _ _ _ _           |- _ => inversion H
| H : JuicyMachine.suspend_thread _ _ _ |- _ => inversion H
| H : JuicyMachine.syncStep _ _ _ _ _ _           |- _ => inversion H
(*  | H : JuicyMachine.threadHalted _                   |- _ => inversion H*)
| H : JuicyMachine.schedfail _         |- _ => inversion H
end; try subst.
Ltac getThread_inv :=
match goal with
| [ H : getThreadC ?i _ _ = _ ,
H2 : getThreadC ?i _ _ = _ |- _ ] =>
pose proof (getThreadC_fun _ _ _ _ _ _ _ H H2)
| [ H : getThreadR ?i _ _ = _ ,
H2 : getThreadR ?i _ _ = _ |- _ ] =>
pose proof (getThreadR_fun _ _ _ _ _ _ _ H H2)
end.
Ltac substwith x y := assert (x = y) by apply proof_irr; subst x.

Lemma resource_decay_join_all' ge {tp : jstate ge} {m Phi} c' {phi' i} {cnti : containsThread tp i}:
rmap_bound (Mem.nextblock m) Phi ->
resource_decay (Mem.nextblock m) (getThreadR i tp cnti) phi' /\
level (getThreadR i tp cnti) = level phi' /\
ghost_of phi' = ghost_fmap (approx (level phi')) (approx (level phi')) (ghost_of (getThreadR i tp cnti)) ->
join_all tp Phi ->
exists Phi',
join_all (updThread i (age_tp_to (level phi') tp) (cnt_age' cnti) c' phi') Phi' /\
resource_decay (Mem.nextblock m) Phi Phi' /\
ghost_of Phi' = own.ghost_approx Phi' (ghost_of Phi) /\
level Phi = level Phi'.