Ltac possibleTraceInv :=
match goal with
| [H: possible_trace _ E0 _ |- _] =>
inversion H; clear H; subst; possibleTraceInv
| [H: possible_trace _ (_ ** _) _ |- _] =>
let P1 := fresh "P" in
let w := fresh "w" in
let P2 := fresh "P" in
elim (possible_trace_app_inv _ _ _ _ H); clear H;
intros w [P1 P2];
possibleTraceInv
| [H: possible_traceinf _ (_ *** _) |- _] =>
let P1 := fresh "P" in
let w := fresh "w" in
let P2 := fresh "P" in
elim (possible_traceinf_app_inv _ _ _ H); clear H;
intros w [P1 P2];
possibleTraceInv
| [H: exists w, possible_trace _ _ w |- _] =>
let P := fresh "P" in let w := fresh "w" in
destruct H as [w P]; possibleTraceInv
| _ => idtac
end.
Definition possible_behavior (w: world) (b: program_behavior) : Prop :=
match b with
| Terminates t r => exists w', possible_trace w t w'
| Diverges t => exists w', possible_trace w t w'
| Reacts T => possible_traceinf w T
| Goes_wrong t => exists w', possible_trace w t w'
end.
CoInductive possible_traceinf': world -> traceinf -> Prop :=
| possible_traceinf'_app: forall w1 t w2 T,
possible_trace w1 t w2 -> t <> E0 ->
possible_traceinf' w2 T ->
possible_traceinf' w1 (t *** T).

(* Specifications: *)
Lemma possible_traceinf'_traceinf:
forall w T, possible_traceinf' w T -> possible_traceinf w T.
Lemma possible_traceinf'_traceinf:
forall w T, possible_traceinf' w T -> possible_traceinf w T.