ITree.Interp.TranslateFacts
Section TranslateFacts.
Context {E F : Type → Type}.
Context {R : Type}.
Context (h : E ~> F).
Lemma unfold_translate_ : ∀ (t : itree E R),
observing eq
(translate h t)
(translateF h (fun t ⇒ translate h t) (observe t)).
Proof.
intros t. econstructor. reflexivity.
Qed.
Lemma unfold_translate : ∀ (t : itree E R),
eq_itree eq
(translate h t)
(translateF h (fun t ⇒ translate h t) (observe t)).
Proof.
intros. rewrite unfold_translate_. reflexivity.
Qed.
Lemma translate_ret : ∀ (r:R), translate h (Ret r) ≅ Ret r.
Proof.
intros r.
rewrite itree_eta, unfold_translate. cbn. reflexivity.
Qed.
Lemma translate_tau : ∀ (t : itree E R), translate h (Tau t) ≅ Tau (translate h t).
Proof.
intros t.
rewrite itree_eta, unfold_translate. cbn. reflexivity.
Qed.
Lemma translate_vis : ∀ X (e:E X) (k : X → itree E R),
translate h (Vis e k) ≅ Vis (h _ e) (fun x ⇒ translate h (k x)).
Proof.
intros X e k.
rewrite itree_eta, unfold_translate. cbn. reflexivity.
Qed.
#[global]
Instance eq_itree_translate' :
Proper (eq_itree eq ==> eq_itree eq) (@translate _ _ h R).
Proof.
ginit. pcofix CIH.
intros x y H.
rewrite itree_eta, (itree_eta (translate h y)), !unfold_translate, <-!itree_eta.
punfold H. gstep. red in H |- ×.
destruct (observe x); dependent destruction H; try discriminate;
pclearbot; simpobs; simpl; eauto 7 with paco itree.
Qed.
#[global]
Instance eq_itree_translateF :
Proper (going (eq_itree eq) ==> eq_itree eq)
(translateF h (@translate _ _ h R)).
Proof.
repeat red. intros.
rewrite (itree_eta' x), (itree_eta' y), <- !unfold_translate, H.
apply reflexivity.
Qed.
End TranslateFacts.
Lemma translate_bind : ∀ {E F R S} (h : E ~> F) (t : itree E S) (k : S → itree E R),
translate h (x <- t ;; k x) ≅ (x <- (translate h t) ;; translate h (k x)).
Proof.
intros E F R S h t k.
revert S t k.
ginit. pcofix CIH.
intros s t k.
match goal with
| [ |- _ ?t1 ?t2 ] ⇒ rewrite (itree_eta_ t1), (itree_eta_ t2)
end; cbn.
unfold observe; cbn.
destruct (observe t); cbn.
- apply reflexivity.
- gstep. constructor. eauto with paco.
- gstep. constructor. eauto with paco itree.
Qed.
Lemma translate_id : ∀ E R (t : itree E R), translate (id_ _) t ≅ t.
Proof.
intros E R t.
revert t.
ginit. pcofix CIH.
intros t.
rewrite itree_eta.
rewrite (itree_eta t).
rewrite unfold_translate.
unfold translateF.
destruct (observe t); cbn.
- apply reflexivity.
- gstep. econstructor. gbase. apply CIH.
- gstep. econstructor. intros. gbase. apply CIH.
Qed.
Import CatNotations.
Lemma translate_cmpE : ∀ E F G R (g : F ~> G) (f : E ~> F) (t : itree E R),
translate (f >>> g)%cat t ≅ translate g (translate f t).
Proof.
intros E F G R g f t.
revert t.
ginit. pcofix CIH.
intros t.
rewrite !unfold_translate.
genobs_clear t ot. destruct ot; cbn.
- apply reflexivity.
- gstep. econstructor. gbase. apply CIH.
- gstep. econstructor. intros. gbase. apply CIH.
Qed.
(**)
Definition respectful_eq_itree {E F : Type → Type}
: (itree E ~> itree F) → (itree E ~> itree F) → Prop
:= i_respectful (fun _ ⇒ eq_itree eq) (fun _ ⇒ eq_itree eq).
Definition respectful_eutt {E F : Type → Type}
: (itree E ~> itree F) → (itree E ~> itree F) → Prop
:= i_respectful (fun _ ⇒ eutt eq) (fun _ ⇒ eutt eq).
Require ITree.Core.KTreeFacts. (* TODO: only needed to avoid a universe inconsistency right around here (errors if you try to move this to the end of the file, or just under the next instance)... *)
#[global]
Instance eq_itree_apply_IFun {E F : Type → Type} {T : Type}
: Proper (respectful_eq_itree ==> eq_itree eq ==> eq_itree eq)
(@apply_IFun (itree E) (itree F) T).
Proof.
repeat red. intros. repeat red in H. eauto.
Qed.
#[global]
Instance eutt_apply_IFun {E F : Type → Type} {T : Type}
: Proper (respectful_eutt ==> eutt eq ==> eutt eq)
(@apply_IFun (itree E) (itree F) T).
Proof.
repeat red. intros. repeat red in H. eauto.
Qed.
#[global]
Instance eq_itree_translate {E F}
: @Proper (IFun E F → (itree E ~> itree F))
(eq2 ==> respectful_eq_itree)
translate.
Proof.
intros f g Hfg T.
ginit. pcofix CIH; rename r into rr; intros l r Hlr.
rewrite 2 unfold_translate.
punfold Hlr; red in Hlr.
destruct Hlr; cbn; try discriminate; pclearbot.
- gstep. constructor; auto.
- gstep. constructor; auto with paco.
- rewrite Hfg. gstep. constructor; red; auto with paco itree.
Qed.
#[global]
Instance eutt_translate {E F}
: @Proper (IFun E F → (itree E ~> itree F))
(eq2 ==> respectful_eutt)
translate.
Proof.
repeat red.
intros until T.
ginit. pcofix CIH. intros.
rewrite !unfold_translate. punfold H1. red in H1.
induction H1; intros; subst; simpl.
- gstep. econstructor. eauto.
- gstep. econstructor. pclearbot. eauto with paco.
- gstep. rewrite H. econstructor. pclearbot. red. eauto 7 with paco itree.
- rewrite tau_euttge, unfold_translate. eauto.
- rewrite tau_euttge, unfold_translate. eauto.
Qed.
#[global]
Instance eutt_translate' {E F : Type → Type} {R : Type} (f : E ~> F) :
Proper (eutt eq ==> eutt eq)
(@translate E F f R).
Proof.
repeat red.
apply eutt_translate.
reflexivity.
Qed.
Lemma eutt_translate_gen :
∀ {E F X Y} (f : E ~> F) (RR : X → Y → Prop) (t : itree E X) (s : itree E Y),
eutt RR t s →
eutt RR (translate f t) (translate f s).
Proof.
intros ×.
revert t s.
einit.
ecofix CIH.
intros × EUTT.
rewrite !unfold_translate. punfold EUTT. red in EUTT.
induction EUTT; intros; subst; simpl; pclearbot.
- estep.
- estep.
- estep; intros ?; ebase.
- rewrite tau_euttge, unfold_translate. eauto with itree.
- rewrite tau_euttge, unfold_translate. eauto with itree.
Qed.
Lemma translate_trigger {E F G} `{E -< F} :
∀ X (e: E X) (h: F ~> G),
translate h (trigger e) ≈ trigger (h _ (subevent X e)).
Proof.
intros; unfold trigger; rewrite translate_vis; setoid_rewrite translate_ret; reflexivity.
Qed.