|
|
|
|
(** Some derived lemmas for ectx-based languages *)
|
|
|
|
|
From iris.proofmode Require Import proofmode.
|
|
|
|
|
From iris.program_logic Require Export ectx_language.
|
|
|
|
|
From semantics.pl.program_logic Require Export sequential_wp lifting.
|
|
|
|
|
From iris.prelude Require Import options.
|
|
|
|
|
|
|
|
|
|
Section wp.
|
|
|
|
|
Context {Λ : ectxLanguage} `{!irisGS Λ Σ} {Hinh : Inhabited (state Λ)}.
|
|
|
|
|
Implicit Types s : stuckness.
|
|
|
|
|
Implicit Types P : iProp Σ.
|
|
|
|
|
Implicit Types Φ : val Λ → iProp Σ.
|
|
|
|
|
Implicit Types v : val Λ.
|
|
|
|
|
Implicit Types e : expr Λ.
|
|
|
|
|
Local Hint Resolve head_prim_reducible head_reducible_prim_step : core.
|
|
|
|
|
Local Definition reducible_not_val_inhabitant e := reducible_not_val e inhabitant.
|
|
|
|
|
Local Hint Resolve reducible_not_val_inhabitant : core.
|
|
|
|
|
Local Hint Resolve head_stuck_stuck : core.
|
|
|
|
|
|
|
|
|
|
Lemma wp_lift_head_step_fupd {s E1 E2 Φ} e1 :
|
|
|
|
|
to_val e1 = None →
|
|
|
|
|
(|={E1, ∅}=> ∀ σ1, state_interp σ1 ={∅,∅}=∗
|
|
|
|
|
⌜head_reducible e1 σ1⌝ ∗
|
|
|
|
|
∀ e2 σ2 κ efs, ⌜head_step e1 σ1 κ e2 σ2 efs⌝ ={∅}=∗ ▷ |={∅}=>
|
|
|
|
|
state_interp σ2 ∗ ⌜efs = []⌝ ∗ ⌜κ = []⌝ ∗
|
|
|
|
|
WP e2 @ s; ∅; E2 {{ Φ }})
|
|
|
|
|
⊢ WP e1 @ s; E1; E2 {{ Φ }}.
|
|
|
|
|
Proof.
|
|
|
|
|
iIntros (?) "H". iApply wp_lift_step_fupd=>//. iMod "H". iIntros "!>" (σ1) "Hσ".
|
|
|
|
|
iMod ("H" with "Hσ") as "[% H]"; iModIntro.
|
|
|
|
|
iSplit; first by destruct s; eauto. iIntros (e2 σ2 κ efs ?).
|
|
|
|
|
iApply (step_fupd_wand with "(H []) []"); first eauto.
|
|
|
|
|
iIntros "($ & $ & $)".
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Lemma wp_lift_head_step {s E1 E2 Φ} e1 :
|
|
|
|
|
to_val e1 = None →
|
|
|
|
|
(|={E1, ∅}=> ∀ σ1, state_interp σ1 ={∅}=∗
|
|
|
|
|
⌜head_reducible e1 σ1⌝ ∗
|
|
|
|
|
▷ ∀ e2 σ2 κ efs, ⌜head_step e1 σ1 κ e2 σ2 efs⌝ ={∅}=∗
|
|
|
|
|
state_interp σ2 ∗ ⌜efs = []⌝ ∗ ⌜κ = []⌝ ∗ WP e2 @ s; ∅; E2 {{ Φ }})
|
|
|
|
|
⊢ WP e1 @ s; E1; E2 {{ Φ }}.
|
|
|
|
|
Proof.
|
|
|
|
|
iIntros (?) "H". iApply wp_lift_head_step_fupd; [done|]. iMod "H".
|
|
|
|
|
iIntros "!>" (?) "?".
|
|
|
|
|
iMod ("H" with "[$]") as "[$ H]". iIntros "!>" (e2 σ2 κ efs ?) "!> !>". by iApply "H".
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Lemma wp_lift_head_step_fupd_nomask {s E1 E2 E3 Φ} e1 :
|
|
|
|
|
to_val e1 = None →
|
|
|
|
|
(∀ σ1, state_interp σ1 ={E1}=∗
|
|
|
|
|
⌜head_reducible e1 σ1⌝ ∗
|
|
|
|
|
∀ e2 σ2 κ efs, ⌜head_step e1 σ1 κ e2 σ2 efs⌝ ={E1}[E3]▷=∗
|
|
|
|
|
state_interp σ2 ∗ ⌜efs = []⌝ ∗ ⌜κ = []⌝ ∗
|
|
|
|
|
WP e2 @ s; E1; E2 {{ Φ }})
|
|
|
|
|
⊢ WP e1 @ s; E1; E2 {{ Φ }}.
|
|
|
|
|
Proof.
|
|
|
|
|
iIntros (?) "H". iApply wp_lift_step_fupd_nomask; [done|].
|
|
|
|
|
iIntros (σ1) "Hσ1". iMod ("H" with "Hσ1") as "[% H]"; iModIntro.
|
|
|
|
|
iSplit; first by destruct s; auto. iIntros (e2 σ2 κ efs Hstep).
|
|
|
|
|
iApply (step_fupd_wand with "(H []) []"); first by eauto.
|
|
|
|
|
iIntros "($ & $)".
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Lemma wp_lift_pure_det_head_step {s E1 E2 E' Φ} e1 e2 :
|
|
|
|
|
to_val e1 = None →
|
|
|
|
|
(∀ σ1, head_reducible e1 σ1) →
|
|
|
|
|
(∀ σ1 κ e2' σ2 efs',
|
|
|
|
|
head_step e1 σ1 κ e2' σ2 efs' → κ = [] ∧ σ2 = σ1 ∧ e2' = e2 ∧ efs' = []) →
|
|
|
|
|
(|={E1}[E']▷=> WP e2 @ s; E1; E2 {{ Φ }}) ⊢ WP e1 @ s; E1; E2 {{ Φ }}.
|
|
|
|
|
Proof using Hinh.
|
|
|
|
|
intros. rewrite -(wp_lift_pure_det_step e1 e2); eauto.
|
|
|
|
|
destruct s; by auto.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Lemma wp_lift_pure_det_head_step' {s E1 E2 Φ} e1 e2 :
|
|
|
|
|
to_val e1 = None →
|
|
|
|
|
(∀ σ1, head_reducible e1 σ1) →
|
|
|
|
|
(∀ σ1 κ e2' σ2 efs',
|
|
|
|
|
head_step e1 σ1 κ e2' σ2 efs' → κ = [] ∧ σ2 = σ1 ∧ e2' = e2 ∧ efs' = []) →
|
|
|
|
|
▷ WP e2 @ s; E1; E2 {{ Φ }} ⊢ WP e1 @ s; E1; E2 {{ Φ }}.
|
|
|
|
|
Proof using Hinh.
|
|
|
|
|
intros. rewrite -[(WP e1 @ s; _ {{ _ }})%I]wp_lift_pure_det_head_step //.
|
|
|
|
|
rewrite -step_fupd_intro //.
|
|
|
|
|
Qed.
|
|
|
|
|
End wp.
|