diff --git a/theories/examples/keyideas/simulations.v b/theories/examples/keyideas/simulations.v index 35f5f9e38d923e01386577c392a7a57127dc25c7..af35838dcaa6acf1c39115b2db2bce4401846a33 100644 --- a/theories/examples/keyideas/simulations.v +++ b/theories/examples/keyideas/simulations.v @@ -91,7 +91,7 @@ Section simulations. Qed. Lemma sim_execute_tgt t s t': - rtc tgt_step t t' → satisfiable (sim t s) + rtc tgt_step t t' → satisfiable (sim t s) → ∃ s', rtc src_step s s' ∧ satisfiable (sim t' s'). Proof. induction 1 in s. @@ -127,3 +127,126 @@ Section simulations. Qed. End simulations. + + +From Coq.Logic Require Import Classical_Prop. + +Section finite_stepindex_simulation. + Context {SI} {Σ: gFunctors SI} `{!FiniteIndex SI}. + + (* Some generic properties about reduction relations *) + + Lemma ex_loop_sn {X: Type} (R: relation X) (x: X): + ex_loop R x ↔ ¬ sn R x. + Proof. + split. + - intros Hloop Hsn. by eapply acc_not_ex_loop. + - intros Hsn. revert x Hsn. cofix IH. + intros x Hsn. enough (∃ x', R x x' ∧ ¬ sn R x') as [x' [Hstep Hsn']]. + { econstructor; eauto. } + destruct (classic (∃ x' : X, R x x' ∧ ¬ sn R x')); first done. + exfalso. eapply Hsn. constructor. intros x' Hstep. + destruct (classic (sn R x')); first done. + exfalso. eapply H. eauto. + Qed. + + Lemma sn_finite_nondet_bounded {X: Type} (R: relation X) (x: X): + (∀ x, ∃ X: list X, (∀ x', R x x' ↔ x' ∈ X)) → + sn R x → + ∃ n, ∀ x' m, nsteps R m x x' → m < n. + Proof. + intros Hbounded. induction 1. + destruct (Hbounded x) as [xs Hbounded']. + assert (∀ y, y ∈ xs → ∃ n : nat, ∀ (x' : X) (m : nat), nsteps R m y x' → m < n) as Hx. + { intros ??. eapply H0. simpl. eapply Hbounded'. eauto. } + assert (∃ n : nat, ∀ y, y ∈ xs → ∀ (x' : X) (m : nat), nsteps R m y x' → m < n) as Hx'. + - clear Hbounded'. induction xs as [|y xs IH]; first by exists 0; set_solver. + destruct (Hx y) as [n1 Hx'']; first set_solver. + destruct (IH) as [n2 Hxs]; first set_solver. exists (n1 `max` n2). + intros z. rewrite elem_of_cons. intros [->|?]. + + intros ?? Hsteps. eapply Hx'' in Hsteps. lia. + + intros x' m. intros ?. eapply Hxs in H1; last done. lia. + - destruct Hx' as [n Hx']. exists (1 + n). intros x' m Hsteps. + inversion Hsteps; subst; first lia. eapply Hbounded' in H1. + eapply Hx' in H1; last done. lia. + Qed. + + + Lemma finite_nondet_ex_loop_diverge {X: Type} (R: relation X) (x: X): + (∀ x, ∃ X: list X, ∀ x', R x x' ↔ x' ∈ X) → + (∀ n, ∃ m, n ≤ m ∧ ∃ x', nsteps R m x x') → + ex_loop R x. + Proof. + intros Hb Hsteps. eapply ex_loop_sn. destruct (classic (sn R x)) as [Hsn|]; last done. + eapply sn_finite_nondet_bounded in Hsn; last done. + destruct Hsn as [n Hsn]. destruct (Hsteps n) as [m [Hle [x' Hsteps']]]. + eapply Hsn in Hsteps'. lia. + Qed. + + Lemma ex_loop_extract_finite_execution {X: Type} (R: relation X) (x: X) n: + ex_loop R x → + ∃ x', nsteps R n x x'. + Proof. + intros Hloop. induction n as [|n IH] in x, Hloop |-*. + - exists x. constructor. + - destruct Hloop as [x x' Hstep Hloop]. eapply IH in Hloop. + destruct Hloop as [x'' Hsteps]. exists x''. econstructor; eauto. + Qed. + + + + (* We assume a source and a target language *) + Variable (S T: Type) (src_step: S → S → Prop) (tgt_step: T → T → Prop). + Variable (V: Type) (val_to_src: V → S) (val_to_tgt: V → T). + Variable (val_irred: ∀ v, ¬ ∃ t', tgt_step (val_to_tgt v) t') (val_inj: Inj eq eq val_to_tgt). + + Definition sim_finite_ref (t: T) (s: S) := + ∀ n t', nsteps tgt_step n t t' → + ∃ m s', nsteps src_step m s s' ∧ n ≤ m ∧ + (∀ v, val_to_tgt v = t' → val_to_src v = s'). + + Notation sim := (sim (Σ := Σ) S T src_step tgt_step V val_to_src val_to_tgt). + Notation tpr := (tpr S T src_step tgt_step V val_to_src val_to_tgt). + + Lemma satisfiable_laterN n (P: iProp Σ): satisfiable (▷^n P)%I → satisfiable P. + Proof. induction n; eauto using satisfiable_later. Qed. + + Lemma sim_to_sim_finite_ref t s: (⊢ sim t s) → sim_finite_ref t s. + Proof. + intros Hsim n t' Hsteps. + eapply sim_valid_satisfiable in Hsim. + eapply satisfiable_pure, (satisfiable_laterN n), satisfiable_mono; eauto. + iIntros "Hsim". clear Hsim. iInduction Hsteps as [] "IH" forall (s). + - rewrite sim_unfold. iDestruct "Hsim" as "[H|[H _]]". + + iDestruct "H" as (v') "[<- <-]". iPureIntro. + eexists _, _. split; first constructor. split; first lia. + intros v <-%val_inj. done. + + iDestruct "H" as (t') "%". iPureIntro. + eexists _, _. split; first constructor. split; first lia. + intros ??. exfalso. naive_solver. + - rewrite sim_unfold. iDestruct "Hsim" as "[H|[H X]]". + + iDestruct "H" as (v') "[<- <-]". exfalso. naive_solver. + + iDestruct "H" as (t') "_". iDestruct ("X" with "[//]") as "X". + iDestruct "X" as (s' Hstep) "Hsim". simpl. iNext. simpl. + iDestruct ("IH" with "Hsim") as "Hn". iNext. simpl. + iDestruct "Hn" as (m s'') "%". iPureIntro. destruct H0 as (?&?). + eexists _, s''. split; first eauto using nsteps_l. split; first lia. + naive_solver. + Qed. + + Lemma sim_finite_ref_tpr t s: + (∀ s, ∃ ss: list S, ∀ s', src_step s s' ↔ s' ∈ ss) → + sim_finite_ref t s → + tpr t s. + Proof. + intros Hb Href. split. + - intros v Hsteps. eapply rtc_nsteps in Hsteps as [n Hsteps]. + eapply Href in Hsteps as (m & s'&?&?& Hv); eauto. + specialize (Hv v eq_refl). subst. by eapply nsteps_rtc. + - intros Hloop. eapply finite_nondet_ex_loop_diverge; first done. + intros n. eapply (ex_loop_extract_finite_execution _ _ n) in Hloop as [x' Hsteps]. + eapply Href in Hsteps as (m & s'&?&?&?); eauto. + Qed. + +End finite_stepindex_simulation. +