Opaque trace E0 Eapp Eappinf.
(** The following [traceEq] tactic proves equalities between traces or infinite traces. *)
Ltac substTraceHyp :=
match goal with
| [ H: (@eq trace ?x ?y) |- _ ] =>
subst x || clear H
end.
Ltac decomposeTraceEq :=
match goal with
| [ |- (_ ** _) = (_ ** _) ] =>
apply (f_equal2 Eapp); auto; decomposeTraceEq
| _ =>
auto
end.
Ltac traceEq :=
repeat substTraceHyp; autorewrite with trace_rewrite; decomposeTraceEq.
(** Bisimilarity between infinite traces. *)
CoInductive traceinf_sim: traceinf -> traceinf -> Prop :=
| traceinf_sim_cons: forall e T1 T2,
traceinf_sim T1 T2 ->
traceinf_sim (Econsinf e T1) (Econsinf e T2).

(* Specifications: *)
Lemma traceinf_sim_refl:
forall T, traceinf_sim T T.
Lemma traceinf_sim_sym:
forall T1 T2, traceinf_sim T1 T2 -> traceinf_sim T2 T1.
Lemma traceinf_sim_trans:
forall T1 T2 T3,
traceinf_sim T1 T2 -> traceinf_sim T2 T3 -> traceinf_sim T1 T3.