@@ -254,3 +254,108 @@ Instance euttge_interp_mrec' {E D R} (ctx : D ~> itree (D +' E)) :
254254Proof .
255255 do 4 red. eapply euttge_interp_mrec. reflexivity.
256256Qed .
257+
258+ Module Interp_mrec_loop2.
259+
260+ Inductive invariant {D E} (ctx : D ~> itree (D +' E)) {R}
261+ : itree (D +' E) R -> itree (D +' E) R -> Prop :=
262+ | Equal {t} : invariant ctx t t
263+ | Interp {A} {t : itree (D +' E) A} {k k' : A -> _} : (forall a, invariant ctx (k a) (k' a)) -> invariant ctx (t >>= k) (interp (Handler.case_ ctx Handler.inr_) t >>= k')
264+ | Bind {A} {t : itree (D +' E) A} {k k' : A -> _}
265+ : (forall (a : A), invariant ctx (k a) (k' a)) ->
266+ invariant ctx (t >>= k) (t >>= fun x => k' x)
267+ .
268+
269+ Local Transparent interp_mrec.
270+
271+ Inductive itree_case {E R} (t : itree E R) : Prop :=
272+ | CaseRet r : Ret r ≅ t -> itree_case t
273+ | CaseTau u : Tau u ≅ t -> itree_case t
274+ | CaseVis A (e : E A) k : Vis e k ≅ t -> itree_case t.
275+
276+ Lemma case_itree {E R} (t : itree E R) : itree_case t.
277+ Proof .
278+ destruct (observe t) eqn:Eq.
279+ - econstructor 1. rewrite <- Eq, <- itree_eta; reflexivity.
280+ - econstructor 2. rewrite <- Eq, <- itree_eta; reflexivity.
281+ - econstructor 3. rewrite <- Eq, <- itree_eta; reflexivity.
282+ Qed .
283+
284+ Instance Proper_paco2_eqit {E A} (r : itree E A -> itree E A -> Prop ) :
285+ Proper (euttge eq ==> euttge eq ==> flip impl) (paco2 (eqit_ eq true true id) r).
286+ Proof .
287+ Admitted .
288+
289+ Lemma interp_mrec_loop2_ {D E} (ctx : D ~> itree (D +' E)) {R}
290+ : forall {t : itree (D +' E) R} {u : itree (D +' E) R},
291+ invariant ctx t u -> interp_mrec ctx t ≈ interp_mrec (Handler.cat ctx (Handler.case_ ctx Handler.inr_)) u.
292+ Proof .
293+ pcofix SELF. induction 1 as [t | A t k | A t k k'].
294+ - destruct (case_itree t) as [ ? H | u H | A [d|e] k H ]; rewrite <- H; rewrite 2 unfold_interp_mrec; simpl.
295+ + pfold. constructor. reflexivity.
296+ + pfold. constructor. right; apply SELF. constructor.
297+ + pfold. constructor. right; apply SELF. constructor. constructor.
298+ + pfold. constructor; intros x; red. left; pfold; constructor. right; apply SELF. constructor.
299+ - destruct (case_itree t) as [ ? W | u W | ? [d|e] h W ]; rewrite <- W.
300+ + rewrite interp_ret. rewrite 2 bind_ret_l.
301+ apply H0.
302+ + rewrite interp_tau, 2 bind_tau, 2 unfold_interp_mrec. simpl.
303+ pfold; constructor; right; apply SELF. constructor. auto.
304+ + rewrite interp_vis. simpl. rewrite bind_bind.
305+ rewrite unfold_interp_mrec; simpl.
306+ destruct (case_itree (ctx _ d)) as [ ? H1 | ? H1 | ? [d'|e] ? H1 ]; rewrite <- H1.
307+ * rewrite 2 bind_ret_l.
308+ rewrite bind_tau.
309+ rewrite unfold_interp_mrec with (t := Tau _); simpl.
310+ pfold; constructor. right; apply SELF. constructor. auto.
311+ * rewrite 2 bind_tau.
312+ rewrite 2 unfold_interp_mrec; simpl.
313+ rewrite tau_euttge.
314+ setoid_rewrite tau_euttge at 3.
315+ pfold; constructor. right; apply SELF. constructor. constructor. auto.
316+ * rewrite 2 bind_vis, 2 unfold_interp_mrec. simpl.
317+ rewrite tau_euttge.
318+ unfold Handler.cat at 2.
319+ setoid_rewrite tau_euttge at 3.
320+ pfold; constructor. right; apply SELF. constructor. constructor. constructor. auto.
321+ * rewrite 2 bind_vis, 2 unfold_interp_mrec; simpl.
322+ rewrite tau_euttge.
323+ setoid_rewrite tau_euttge at 3.
324+ pfold; constructor; left; pfold; constructor; right; apply SELF.
325+ repeat constructor; auto.
326+ + rewrite interp_vis; simpl. unfold Handler.inr_ at 2, Handler.htrigger.
327+ rewrite bind_trigger. rewrite 2 bind_vis.
328+ rewrite 2 unfold_interp_mrec; simpl.
329+ setoid_rewrite bind_tau.
330+ setoid_rewrite unfold_interp_mrec at 2; simpl.
331+ pfold; constructor; left; pfold; constructor 5; [ auto | ]; constructor. right; apply SELF.
332+ constructor. auto.
333+ - destruct (case_itree t) as [ ? W | ? W | ? [d|e] h W]; rewrite <- W.
334+ + rewrite 2 bind_ret_l. apply H0.
335+ + rewrite 2 bind_tau, 2 unfold_interp_mrec; simpl.
336+ pfold; constructor; right; apply SELF. constructor; auto.
337+ + rewrite 2 bind_vis, 2 unfold_interp_mrec; simpl.
338+ unfold Handler.cat at 2.
339+ pfold; constructor; right; apply SELF. constructor. constructor. auto.
340+ + rewrite 2 bind_vis, 2 unfold_interp_mrec; simpl.
341+ pfold; constructor; left; pfold; constructor; right; apply SELF.
342+ constructor; auto.
343+ Qed .
344+
345+ End Interp_mrec_loop2.
346+
347+ Lemma interp_mrec_loop2 {D E} (ctx : D ~> itree (D +' E)) {R} {t : itree (D +' E) R}
348+ : interp_mrec ctx t ≈ interp_mrec (Handler.cat ctx (Handler.case_ ctx inr_)) t.
349+ Proof .
350+ apply Interp_mrec_loop2.interp_mrec_loop2_.
351+ constructor.
352+ Qed .
353+
354+ Theorem mrec_loop2 {D E} (ctx : D ~> itree (D +' E)) {R} {d : D R}
355+ : mrec ctx d ≈ mrec (Handler.cat ctx (Handler.case_ ctx inr_)) d.
356+ Proof .
357+ unfold mrec.
358+ unfold Handler.cat at 2.
359+ rewrite <- unfold_interp_mrec_h.
360+ apply interp_mrec_loop2.
361+ Qed .
0 commit comments