(** * Facts about [aloop] and [loop] *)
(* begin hide *)
Program
Classes.Morphisms
Setoids.Setoid
Relations.Relations.
Basics.Basics
Basics.CategoryOps
Basics.CategoryTheory
Basics.CategoryKleisli
Basics.CategoryKleisliFacts
Basics.Function
Core.ITreeDefinition
Core.ITreeMonad
Core.KTree
Eq.Eq
Eq.UpToTaus.
Local Open Scope itree.
(* end hide *)
(** ** [ITree.aloop] *)
(** ** [iter] *)
Instance eq_itree_iter {E A B} :
@Proper ((A -> itree E (A + B)) -> A -> itree E B)
((eq ==> eq_itree eq) ==> pointwise_relation _ (eq_itree eq))
iter.
Instance eutt_iter {E A B} :
@Proper ((A -> itree E (A + B)) -> A -> itree E B)
(pointwise_relation _ (eutt eq) ==> pointwise_relation _ (eutt eq))
iter.
Definition eutt_iter_gen {F A B R S} :
@Proper ((A -> itree F (A + B)) -> A -> itree F B)
((R ==> eutt (sum_rel R S)) ==> R ==> (eutt S))
KTree.iter.
Instance eq2_ktree_iter {E A B} :
@Proper (ktree E A (A + B) -> ktree E A B)
(eq2 ==> eq2)
iter.
Instance IterUnfold_ktree {E} : IterUnfold (ktree E) sum.
Instance IterNatural_ktree {E} : IterNatural (ktree E) sum.

Lemma iter_dinatural_ktree {E A B C}
(f : ktree E A (C + B)) (g : ktree E C (A + B)) (a0 : A)
: iter (fun a =>
cb <- f a ;;
match cb with
| inl c => Tau (g c)
| inr b => Ret (inr b)
end) a0
≅ cb <- f a0 ;;
match cb with
| inl c0 => Tau (iter (fun c =>
ab <- g c ;;
match ab with
| inl a => Tau (f a)
| inr b => Ret (inr b)
end) c0)
| inr b => Ret b
end.