@@ -254,3 +254,108 @@ Instance euttge_interp_mrec' {E D R} (ctx : D ~> itree (D +' E)) :
254
254
Proof .
255
255
do 4 red. eapply euttge_interp_mrec. reflexivity.
256
256
Qed .
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