weakestpre.v 12.1 KB
Newer Older
1
From iris.program_logic Require Export fancy_updates.
2
From iris.program_logic Require Import wsat.
3
From iris.base_logic Require Import big_op.
4
From iris.prelude Require Export coPset.
5
From iris.proofmode Require Import tactics classes.
6 7 8 9 10 11 12 13 14 15
Import uPred.

Definition wp_pre `{irisG Λ Σ}
    (wp : coPset -c> expr Λ -c> (val Λ -c> iProp Σ) -c> iProp Σ) :
    coPset -c> expr Λ -c> (val Λ -c> iProp Σ) -c> iProp Σ := λ E e1 Φ, (
  (* value case *)
  ( v, to_val e1 = Some v  |={E}=> Φ v) 
  (* step case *)
  (to_val e1 = None   σ1,
     ownP_auth σ1 ={E,}=  reducible e1 σ1 
16
       e2 σ2 efs,  prim_step e1 σ1 e2 σ2 efs ={,E}=
17
       ownP_auth σ2  wp E e2 Φ 
18
       [ list] ef  efs, wp  ef (λ _, True)))%I.
Robbert Krebbers's avatar
Robbert Krebbers committed
19

20 21 22 23
Local Instance wp_pre_contractive `{irisG Λ Σ} : Contractive wp_pre.
Proof.
  rewrite /wp_pre=> n wp wp' Hwp E e1 Φ.
  apply or_ne, and_ne, forall_ne; auto=> σ1; apply wand_ne; auto.
24
  apply fupd_ne, sep_ne, later_contractive; auto=> i ?.
25
  apply forall_ne=> e2; apply forall_ne=> σ2; apply forall_ne=> efs.
26
  apply wand_ne, fupd_ne, sep_ne, sep_ne; auto; first by apply Hwp.
27
  apply big_opL_ne=> ? ef. by apply Hwp.
Robbert Krebbers's avatar
Robbert Krebbers committed
28
Qed.
29

30 31
Definition wp_def `{irisG Λ Σ} :
  coPset  expr Λ  (val Λ  iProp Σ)  iProp Σ := fixpoint wp_pre.
Ralf Jung's avatar
Ralf Jung committed
32 33 34 35
Definition wp_aux : { x | x = @wp_def }. by eexists. Qed.
Definition wp := proj1_sig wp_aux.
Definition wp_eq : @wp = @wp_def := proj2_sig wp_aux.

Janno's avatar
Janno committed
36
Arguments wp {_ _ _} _ _%E _.
37
Instance: Params (@wp) 5.
Robbert Krebbers's avatar
Robbert Krebbers committed
38

Janno's avatar
Janno committed
39
Notation "'WP' e @ E {{ Φ } }" := (wp E e%E Φ)
40
  (at level 20, e, Φ at level 200,
41
   format "'WP'  e  @  E  {{  Φ  } }") : uPred_scope.
Janno's avatar
Janno committed
42
Notation "'WP' e {{ Φ } }" := (wp  e%E Φ)
43
  (at level 20, e, Φ at level 200,
44
   format "'WP'  e  {{  Φ  } }") : uPred_scope.
45

Janno's avatar
Janno committed
46
Notation "'WP' e @ E {{ v , Q } }" := (wp E e%E (λ v, Q))
47 48
  (at level 20, e, Q at level 200,
   format "'WP'  e  @  E  {{  v ,  Q  } }") : uPred_scope.
Janno's avatar
Janno committed
49
Notation "'WP' e {{ v , Q } }" := (wp  e%E (λ v, Q))
50 51 52
  (at level 20, e, Q at level 200,
   format "'WP'  e  {{  v ,  Q  } }") : uPred_scope.

Ralf Jung's avatar
Ralf Jung committed
53
(* Texan triples *)
Ralf Jung's avatar
Ralf Jung committed
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
Notation "'{{{' P } } } e {{{ x .. y ; pat , Q } } }" :=
  (  Φ,
      P   ( x, .. ( y, Q - Φ pat%V) .. ) - WP e {{ Φ }})%I
    (at level 20, x closed binder, y closed binder,
     format "{{{  P  } } }  e  {{{ x .. y ;  pat ,  Q } } }") : uPred_scope.
Notation "'{{{' P } } } e @ E {{{ x .. y ; pat , Q } } }" :=
  (  Φ,
      P   ( x, .. ( y, Q - Φ pat%V) .. ) - WP e @ E {{ Φ }})%I
    (at level 20, x closed binder, y closed binder,
     format "{{{  P  } } }  e  @  E  {{{ x .. y ;  pat ,  Q } } }") : uPred_scope.
Notation "'{{{' P } } } e {{{ ; pat , Q } } }" :=
  (  Φ, P   (Q - Φ pat%V) - WP e {{ Φ }})%I
    (at level 20,
     format "{{{  P  } } }  e  {{{ ; pat ,  Q } } }") : uPred_scope.
Notation "'{{{' P } } } e @ E {{{ ; pat , Q } } }" :=
  (  Φ, P   (Q - Φ pat%V) - WP e @ E {{ Φ }})%I
    (at level 20,
     format "{{{  P  } } }  e  @  E  {{{ ; pat ,  Q } } }") : uPred_scope.

73 74 75
Notation "'{{{' P } } } e {{{ x .. y ; pat , Q } } }" :=
  ( Φ : _  uPred _,
      P   ( x, .. ( y, Q - Φ pat%V) .. )  WP e {{ Φ }})
76
    (at level 20, x closed binder, y closed binder,
77 78 79 80
     format "{{{  P  } } }  e  {{{ x .. y ;  pat ,  Q } } }") : C_scope.
Notation "'{{{' P } } } e @ E {{{ x .. y ; pat , Q } } }" :=
  ( Φ : _  uPred _,
      P   ( x, .. ( y, Q - Φ pat%V) .. )  WP e @ E {{ Φ }})
Ralf Jung's avatar
Ralf Jung committed
81
    (at level 20, x closed binder, y closed binder,
82 83 84
     format "{{{  P  } } }  e  @  E  {{{ x .. y ;  pat ,  Q } } }") : C_scope.
Notation "'{{{' P } } } e {{{ ; pat , Q } } }" :=
  ( Φ : _  uPred _, P   (Q - Φ pat%V)  WP e {{ Φ }})
85
    (at level 20,
86 87 88
     format "{{{  P  } } }  e  {{{ ; pat ,  Q } } }") : C_scope.
Notation "'{{{' P } } } e @ E {{{ ; pat , Q } } }" :=
  ( Φ : _  uPred _, P   (Q - Φ pat%V)  WP e @ E {{ Φ }})
Ralf Jung's avatar
Ralf Jung committed
89
    (at level 20,
90
     format "{{{  P  } } }  e  @  E  {{{ ; pat ,  Q } } }") : C_scope.
91

Robbert Krebbers's avatar
Robbert Krebbers committed
92
Section wp.
93 94 95
Context `{irisG Λ Σ}.
Implicit Types P : iProp Σ.
Implicit Types Φ : val Λ  iProp Σ.
96 97
Implicit Types v : val Λ.
Implicit Types e : expr Λ.
Robbert Krebbers's avatar
Robbert Krebbers committed
98

99 100 101
Lemma wp_unfold E e Φ : WP e @ E {{ Φ }}  wp_pre wp E e Φ.
Proof. rewrite wp_eq. apply (fixpoint_unfold wp_pre). Qed.

102
Global Instance wp_ne E e n :
103
  Proper (pointwise_relation _ (dist n) ==> dist n) (@wp Λ Σ _ E e).
Robbert Krebbers's avatar
Robbert Krebbers committed
104
Proof.
105 106 107
  revert e. induction (lt_wf n) as [n _ IH]=> e Φ Ψ HΦ.
  rewrite !wp_unfold /wp_pre. apply or_ne, and_ne; auto; first solve_proper.
  apply forall_ne=> σ1.
108
  apply wand_ne, fupd_ne, sep_ne, later_contractive; auto=> i ?.
109
  apply forall_ne=> e2; apply forall_ne=> σ2; apply forall_ne=> ef.
110
  apply wand_ne, fupd_ne, sep_ne, sep_ne; auto.
111
  apply IH; [done|]=> v. eapply dist_le; eauto with omega.
Robbert Krebbers's avatar
Robbert Krebbers committed
112 113
Qed.
Global Instance wp_proper E e :
114
  Proper (pointwise_relation _ () ==> ()) (@wp Λ Σ _ E e).
Robbert Krebbers's avatar
Robbert Krebbers committed
115
Proof.
116
  by intros Φ Φ' ?; apply equiv_dist=>n; apply wp_ne=>v; apply equiv_dist.
Robbert Krebbers's avatar
Robbert Krebbers committed
117
Qed.
118

119
Lemma wp_value' E Φ v : Φ v  WP of_val v @ E {{ Φ }}.
Robbert Krebbers's avatar
Robbert Krebbers committed
120
Proof.
121 122
  iIntros "HΦ". rewrite wp_unfold /wp_pre.
  iLeft; iExists v; rewrite to_of_val; auto.
Robbert Krebbers's avatar
Robbert Krebbers committed
123
Qed.
124
Lemma wp_value_inv E Φ v : WP of_val v @ E {{ Φ }} ={E}= Φ v.
Ralf Jung's avatar
Ralf Jung committed
125
Proof.
126 127
  rewrite wp_unfold /wp_pre to_of_val. iIntros "[H|[% _]]"; [|done].
  by iDestruct "H" as (v') "[% ?]"; simplify_eq.
Ralf Jung's avatar
Ralf Jung committed
128
Qed.
Robbert Krebbers's avatar
Robbert Krebbers committed
129

130 131 132
Lemma wp_strong_mono E1 E2 e Φ Ψ :
  E1  E2  ( v, Φ v ={E2}= Ψ v)  WP e @ E1 {{ Φ }}  WP e @ E2 {{ Ψ }}.
Proof.
133
  iIntros (?) "[HΦ H]". iLöb as "IH" forall (e). rewrite !wp_unfold /wp_pre.
134 135
  iDestruct "H" as "[Hv|[% H]]"; [iLeft|iRight].
  { iDestruct "Hv" as (v) "[% Hv]". iExists v; iSplit; first done.
136
    iApply ("HΦ" with ">[-]"). by iApply (fupd_mask_mono E1 _). }
137
  iSplit; [done|]; iIntros (σ1) "Hσ".
138 139 140 141 142
  iMod (fupd_intro_mask' E2 E1) as "Hclose"; first done.
  iMod ("H" $! σ1 with "Hσ") as "[$ H]".
  iModIntro. iNext. iIntros (e2 σ2 efs Hstep).
  iMod ("H" $! _ σ2 efs with "[#]") as "($ & H & $)"; auto.
  iMod "Hclose" as "_". by iApply ("IH" with "HΦ").
143 144
Qed.

145
Lemma fupd_wp E e Φ : (|={E}=> WP e @ E {{ Φ }})  WP e @ E {{ Φ }}.
Robbert Krebbers's avatar
Robbert Krebbers committed
146
Proof.
147 148
  rewrite wp_unfold /wp_pre. iIntros "H". destruct (to_val e) as [v|] eqn:?.
  { iLeft. iExists v; iSplit; first done.
149
    by iMod "H" as "[H|[% ?]]"; [iDestruct "H" as (v') "[% ?]"|]; simplify_eq. }
150
  iRight; iSplit; [done|]; iIntros (σ1) "Hσ1".
151
  iMod "H" as "[H|[% H]]"; last by iApply "H".
152
  iDestruct "H" as (v') "[% ?]"; simplify_eq.
153
Qed.
154
Lemma wp_fupd E e Φ : WP e @ E {{ v, |={E}=> Φ v }}  WP e @ E {{ Φ }}.
155
Proof. iIntros "H". iApply (wp_strong_mono E); try iFrame; auto. Qed.
156

157
Lemma wp_atomic E1 E2 e Φ :
158
  atomic e 
159
  (|={E1,E2}=> WP e @ E2 {{ v, |={E2,E1}=> Φ v }})  WP e @ E1 {{ Φ }}.
Robbert Krebbers's avatar
Robbert Krebbers committed
160
Proof.
161
  iIntros (Hatomic) "H". destruct (to_val e) as [v|] eqn:He.
162
  { apply of_to_val in He as <-. iApply wp_fupd. iApply wp_value'.
163
    iMod "H". by iMod (wp_value_inv with "H"). }
164
  setoid_rewrite wp_unfold; rewrite /wp_pre. iRight; iSplit; auto.
165
  iIntros (σ1) "Hσ". iMod "H" as "[H|[_ H]]".
166
  { iDestruct "H" as (v') "[% ?]"; simplify_eq. }
167 168
  iMod ("H" $! σ1 with "Hσ") as "[$ H]".
  iModIntro. iNext. iIntros (e2 σ2 efs Hstep).
169
  destruct (Hatomic _ _ _ _ Hstep) as [v <-%of_to_val].
170 171
  iMod ("H" $! _ σ2 efs with "[#]") as "($ & H & $)"; auto.
  iMod (wp_value_inv with "H") as ">H". by iApply wp_value'.
Robbert Krebbers's avatar
Robbert Krebbers committed
172
Qed.
173 174 175

Lemma wp_frame_step_l E1 E2 e Φ R :
  to_val e = None  E2  E1 
176
  (|={E1,E2}=> R)  WP e @ E2 {{ Φ }}  WP e @ E1 {{ v, R  Φ v }}.
177 178 179 180
Proof.
  rewrite !wp_unfold /wp_pre. iIntros (??) "[HR [Hv|[_ H]]]".
  { iDestruct "Hv" as (v) "[% Hv]"; simplify_eq. }
  iRight; iSplit; [done|]. iIntros (σ1) "Hσ".
181 182 183 184
  iMod "HR". iMod ("H" $! _ with "Hσ") as "[$ H]".
  iModIntro; iNext; iIntros (e2 σ2 efs Hstep).
  iMod ("H" $! e2 σ2 efs with "[%]") as "($ & H & $)"; auto.
  iMod "HR". iModIntro. iApply (wp_strong_mono E2 _ _ Φ); try iFrame; eauto.
Robbert Krebbers's avatar
Robbert Krebbers committed
185
Qed.
186

187
Lemma wp_bind K `{!LanguageCtx Λ K} E e Φ :
188
  WP e @ E {{ v, WP K (of_val v) @ E {{ Φ }} }}  WP K e @ E {{ Φ }}.
Robbert Krebbers's avatar
Robbert Krebbers committed
189
Proof.
190
  iIntros "H". iLöb as "IH" forall (E e Φ). rewrite wp_unfold /wp_pre.
191 192
  iDestruct "H" as "[Hv|[% H]]".
  { iDestruct "Hv" as (v) "[Hev Hv]"; iDestruct "Hev" as % <-%of_to_val.
193
    by iApply fupd_wp. }
194
  rewrite wp_unfold /wp_pre. iRight; iSplit; eauto using fill_not_val.
195 196
  iIntros (σ1) "Hσ". iMod ("H" $! _ with "Hσ") as "[% H]".
  iModIntro; iSplit.
197
  { iPureIntro. unfold reducible in *. naive_solver eauto using fill_step. }
198 199
  iNext; iIntros (e2 σ2 efs Hstep).
  destruct (fill_step_inv e σ1 e2 σ2 efs) as (e2'&->&?); auto.
200
  iMod ("H" $! e2' σ2 efs with "[%]") as "($ & H & $)"; auto.
201
  by iApply "IH".
Robbert Krebbers's avatar
Robbert Krebbers committed
202 203
Qed.

204
(** * Derived rules *)
205
Lemma wp_mono E e Φ Ψ : ( v, Φ v  Ψ v)  WP e @ E {{ Φ }}  WP e @ E {{ Ψ }}.
206 207
Proof.
  iIntros (HΦ) "H"; iApply (wp_strong_mono E E); auto.
208
  iFrame. iIntros (v) "?". by iApply HΦ.
209 210 211
Qed.
Lemma wp_mask_mono E1 E2 e Φ : E1  E2  WP e @ E1 {{ Φ }}  WP e @ E2 {{ Φ }}.
Proof. iIntros (?) "H"; iApply (wp_strong_mono E1 E2); auto. iFrame; eauto. Qed.
Robbert Krebbers's avatar
Robbert Krebbers committed
212
Global Instance wp_mono' E e :
213
  Proper (pointwise_relation _ () ==> ()) (@wp Λ Σ _ E e).
214
Proof. by intros Φ Φ' ?; apply wp_mono. Qed.
215

216
Lemma wp_value E Φ e v : to_val e = Some v  Φ v  WP e @ E {{ Φ }}.
217
Proof. intros; rewrite -(of_to_val e v) //; by apply wp_value'. Qed.
218 219 220
Lemma wp_value_fupd' E Φ v : (|={E}=> Φ v)  WP of_val v @ E {{ Φ }}.
Proof. intros. by rewrite -wp_fupd -wp_value'. Qed.
Lemma wp_value_fupd E Φ e v :
221
  to_val e = Some v  (|={E}=> Φ v)  WP e @ E {{ Φ }}.
222
Proof. intros. rewrite -wp_fupd -wp_value //. Qed.
223

224
Lemma wp_frame_l E e Φ R : R  WP e @ E {{ Φ }}  WP e @ E {{ v, R  Φ v }}.
225 226 227 228 229 230
Proof. iIntros "[??]". iApply (wp_strong_mono E E _ Φ); try iFrame; eauto. Qed.
Lemma wp_frame_r E e Φ R : WP e @ E {{ Φ }}  R  WP e @ E {{ v, Φ v  R }}.
Proof. iIntros "[??]". iApply (wp_strong_mono E E _ Φ); try iFrame; eauto. Qed.

Lemma wp_frame_step_r E1 E2 e Φ R :
  to_val e = None  E2  E1 
231
  WP e @ E2 {{ Φ }}  (|={E1,E2}=> R)  WP e @ E1 {{ v, Φ v  R }}.
Ralf Jung's avatar
Ralf Jung committed
232
Proof.
233 234
  rewrite [(WP _ @ _ {{ _ }}  _)%I]comm; setoid_rewrite (comm _ _ R).
  apply wp_frame_step_l.
Ralf Jung's avatar
Ralf Jung committed
235 236
Qed.
Lemma wp_frame_step_l' E e Φ R :
237
  to_val e = None   R  WP e @ E {{ Φ }}  WP e @ E {{ v, R  Φ v }}.
238 239 240 241 242
Proof. iIntros (?) "[??]". iApply (wp_frame_step_l E E); try iFrame; eauto. Qed.
Lemma wp_frame_step_r' E e Φ R :
  to_val e = None  WP e @ E {{ Φ }}   R  WP e @ E {{ v, Φ v  R }}.
Proof. iIntros (?) "[??]". iApply (wp_frame_step_r E E); try iFrame; eauto. Qed.

243
Lemma wp_wand_l E e Φ Ψ :
244
  ( v, Φ v - Ψ v)  WP e @ E {{ Φ }}  WP e @ E {{ Ψ }}.
245 246 247 248
Proof.
  iIntros "[H Hwp]". iApply (wp_strong_mono E); auto.
  iFrame "Hwp". iIntros (?) "?". by iApply "H".
Qed.
249
Lemma wp_wand_r E e Φ Ψ :
250
  WP e @ E {{ Φ }}  ( v, Φ v - Ψ v)  WP e @ E {{ Ψ }}.
251
Proof. by rewrite comm wp_wand_l. Qed.
Robbert Krebbers's avatar
Robbert Krebbers committed
252
End wp.
253 254 255 256 257 258 259 260 261 262 263

(** Proofmode class instances *)
Section proofmode_classes.
  Context `{irisG Λ Σ}.
  Implicit Types P Q : iProp Σ.
  Implicit Types Φ : val Λ  iProp Σ.

  Global Instance frame_wp E e R Φ Ψ :
    ( v, Frame R (Φ v) (Ψ v))  Frame R (WP e @ E {{ Φ }}) (WP e @ E {{ Ψ }}).
  Proof. rewrite /Frame=> HR. rewrite wp_frame_l. apply wp_mono, HR. Qed.

264 265
  Global Instance is_except_0_wp E e Φ : IsExcept0 (WP e @ E {{ Φ }}).
  Proof. by rewrite /IsExcept0 -{2}fupd_wp -except_0_fupd -fupd_intro. Qed.
266

267 268 269
  Global Instance elim_modal_bupd_wp E e P Φ :
    ElimModal (|==> P) P (WP e @ E {{ Φ }}) (WP e @ E {{ Φ }}).
  Proof. by rewrite /ElimModal (bupd_fupd E) fupd_frame_r wand_elim_r fupd_wp. Qed.
270

271 272 273
  Global Instance elim_modal_fupd_wp E e P Φ :
    ElimModal (|={E}=> P) P (WP e @ E {{ Φ }}) (WP e @ E {{ Φ }}).
  Proof. by rewrite /ElimModal fupd_frame_r wand_elim_r fupd_wp. Qed.
274

275
  (* lower precedence, if possible, it should always pick elim_upd_fupd_wp *)
276
  Global Instance elim_modal_fupd_wp_atomic E1 E2 e P Φ :
277
    atomic e 
278
    ElimModal (|={E1,E2}=> P) P
279
            (WP e @ E1 {{ Φ }}) (WP e @ E2 {{ v, |={E2,E1}=> Φ v }})%I | 100.
280
  Proof. intros. by rewrite /ElimModal fupd_frame_r wand_elim_r wp_atomic. Qed.
281
End proofmode_classes.