Section Facts.
Context {D E : Type -> Type} (ctx : D ~> itree (D +' E)).
(** Unfolding of [interp_mrec]. *)
Definition _interp_mrec {R : Type} (ot : itreeF (D +' E) R _) : itree E R :=
match ot with
| RetF r => Ret r
| TauF t => Tau (interp_mrec ctx t)
| VisF e k =>
match e with
| inl1 d => Tau (interp_mrec ctx (ctx _ d >>= k))
| inr1 e => Vis e (fun x => Tau (interp_mrec ctx (k x)))
end
end.
(** [mrec ctx] is equivalent to [interp (mrecursive ctx)], where [mrecursive] is defined as follows. *)
Definition mrecursive (f : D ~> itree (D +' E))
: (D +' E) ~> itree E :=
case_ (mrec f) ITree.trigger.
Global Instance eq_itree_mrec {R} :
Proper (eq_itree eq ==> eq_itree eq) (@interp_mrec _ _ ctx R).
End Facts.
Local Opaque interp_mrec.
Global Instance Proper_interp_mrec {D E} :
@Proper ((D ~> itree (D +' E)) -> (itree (D +' E) ~> itree E))
(Relation.i_pointwise (fun _ => eutt eq) ==>
Relation.i_respectful (fun _ => eutt eq) (fun _ => eutt eq))
interp_mrec.
(** [rec body] is equivalent to [interp (recursive body)], where [recursive] is defined as follows. *)
Definition recursive {E A B} (f : A -> itree (callE A B +' E) B) : (callE A B +' E) ~> itree E :=
case_ (calling' (rec f)) ITree.trigger.

Lemma interp_recursive_call {E A B} (f : A -> itree (callE A B +' E) B) (x:A) :
interp (recursive f) (call x) ≈ rec f x.