(** * Theorems about [interp] *)
(** Main facts: - [unfold_interp]: Unfold lemma. - [interp_bind]: [interp] is a monad morphism. - [interp_trigger]: Events are interpreted using a handler. *)
(* begin hide *)
Program
Setoid
Morphisms
RelationClasses.
Basics.Category
Basics.CategoryKleisli
Basics.CategoryKleisliFacts
Basics.Basics
Core.ITreeDefinition
Core.KTree
Core.KTreeFacts
Eq.Eq
Eq.UpToTaus
Indexed.Sum
Indexed.Function
Indexed.Relation
Interp.Interp
Interp.Handler
Interp.TranslateFacts.
(* end hide *)
Instance Equivalence_eq_Handler {E F : Type -> Type}
: Equivalence (@eq_Handler E F).
Instance Equivalence_eutt_Handler {E F : Type -> Type}
: Equivalence (@eutt_Handler E F).
Definition Equivalence_eq2_Handler {E F : Type -> Type}
: @Equivalence (Handler E F) eq2.
(** Unfolding of [interp]. *)
Definition _interp {E F R} (f : E ~> itree F) (ot : itreeF E R _)
: itree F R :=
match ot with
| RetF r => Ret r
| TauF t => Tau (interp f t)
| VisF e k => f _ e >>= (fun x => Tau (interp f (k x)))
end.
(** ** [interp] and constructors *)
(** These are specializations of [unfold_interp], which can be added as rewrite hints. *)
Hint Rewrite @interp_ret : itree.
Hint Rewrite @interp_vis : itree.
Hint Rewrite @interp_trigger : itree.
(** ** [interp] properness *)
Instance eq_itree_interp {E F}
: @Proper (Handler E F -> (itree E ~> itree F))
(eq_Handler ==> respectful_eq_itree)
interp.
Instance eq_itree_interp' {E F R f}
: Proper (eq_itree eq ==> eq_itree eq) (@interp E (itree F) _ _ _ f R).
Instance eutt_interp (E F : Type -> Type)
: @Proper (Handler E F -> (itree E ~> itree F))
(eq2 ==> respectful_eutt)
interp.
Instance euttge_interp (E F : Type -> Type)
: @Proper (Handler E F -> (itree E ~> itree F))
(i_pointwise (fun _ => euttge eq) ==>
i_respectful (fun _ => euttge eq) (fun _ => euttge eq))
interp.
Instance eutt_interp' {E F : Type -> Type} {R : Type} (RR: R -> R -> Prop) (f : E ~> itree F) :
Proper (eutt RR ==> eutt RR)
(@interp E (itree F) _ _ _ f R).
Instance euttge_interp' {E F : Type -> Type} {R : Type} (f : E ~> itree F) :
Proper (euttge eq ==> euttge eq)
(@interp E (itree F) _ _ _ f R).
(* Proof of [interp f (t >>= k) ~ (interp f t >>= fun r => interp f (k r))]  "By coinduction", case analysis on t:  - [t = Ret r] or [t = Vis e k] (...)  - [t = Tau t]: interp f (Tau t >>= k) = interp f (Tau (t >>= k)) = Tau (interp f (t >>= k)) { by "coinductive hypothesis" } ~ Tau (interp f t >>= fun ...) = Tau (interp f t) >>= fun ... = interp f (Tau t) >>= fun ... (QED)  *)

Lemma interp_bind {E F R S}
(f : E ~> itree F) (t : itree E R) (k : R -> itree E S) :
interp f (ITree.bind t k)
≅ ITree.bind (interp f t) (fun r => interp f (k r)).