Section RAB.
Context {A B : Type}.
Context (RAB : A -> B -> Prop).  (* relation on Imp / Asm values *)
Definition state_invariant (a : Imp.env * A) (b : Asm.memory * (Asm.registers * B))  :=
Renv (fst a) (fst b) /\ (RAB (snd a) (snd (snd b))).
Definition bisimilar {E} (t1 : itree (ImpState +' E) A) (t2 : itree (Reg +' Memory +' E) B)  :=
forall g_asm g_imp l,
Renv g_imp g_asm ->
eutt state_invariant
(interp_imp t1 g_imp)
(interp_asm t2 g_asm l).
End RAB.
(** [bisimilar] is compatible with [eutt]. *)
Global Instance eutt_bisimilar  {A B E}  (RAB : A -> B -> Prop):
Proper (eutt eq ==> eutt eq ==> iff) (@bisimilar A B RAB E).

(** [sim_rel] at [n] entails that [GetVar (gen_tmp n)] gets interpreted as returning the same value as the _Imp_ related one. *)
Lemma sim_rel_get_tmp0:
forall {E} n l l' g_asm g_imp v,
sim_rel l' n (g_imp,v) (g_asm, (l,tt)) ->
(interp_asm ((trigger (GetReg n)) : itree (Reg +' Memory +' E) value)
g_asm l)
≈     (Ret (g_asm, (l, v))).