From 5ac24c8d496b9340c49b063e57458b7729ca537f Mon Sep 17 00:00:00 2001 From: Robbert Krebbers <mail@robbertkrebbers.nl> Date: Tue, 31 May 2016 02:08:30 +0200 Subject: [PATCH] Formalization of Ralf's boxes. --- _CoqProject | 1 + program_logic/boxes.v | 190 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 program_logic/boxes.v diff --git a/_CoqProject b/_CoqProject index a5ec5612f..40bab7a3c 100644 --- a/_CoqProject +++ b/_CoqProject @@ -82,6 +82,7 @@ program_logic/saved_one_shot.v program_logic/auth.v program_logic/sts.v program_logic/namespaces.v +program_logic/boxes.v heap_lang/lang.v heap_lang/tactics.v heap_lang/wp_tactics.v diff --git a/program_logic/boxes.v b/program_logic/boxes.v new file mode 100644 index 000000000..85e95a5cb --- /dev/null +++ b/program_logic/boxes.v @@ -0,0 +1,190 @@ +From iris.algebra Require Import upred_big_op. +From iris.program_logic Require Import auth saved_prop. +From iris.proofmode Require Import tactics invariants ghost_ownership. +Import uPred. + +(** The CMRAs we need. *) +Class boxG Λ Σ := + boxG_inG :> inG Λ Σ (prodR + (authR (optionUR (exclR boolC))) + (optionR (agreeR (laterC (iPrePropG Λ Σ))))). + +Section box_defs. + Context `{boxG Λ Σ} (N : namespace). + Notation iProp := (iPropG Λ Σ). + + Definition box_own_auth (γ : gname) (a : auth (option (excl bool))) : iProp := + own γ (a, ∅). + + Definition box_own_prop (γ : gname) (P : iProp) : iProp := + own γ (∅:auth _, Some (to_agree (Next (iProp_unfold P)))). + + Definition box_inv (γ : gname) (P : iProp) : iProp := + (∃ b, box_own_auth γ (◠Excl' b) ★ box_own_prop γ P ★ if b then P else True)%I. + + Definition box_slice (γ : gname) (P : iProp) : iProp := + inv N (box_inv γ P). + + Definition box (f : gmap gname bool) (P : iProp) : iProp := + (∃ Φ : gname → iProp, + ▷ (P ≡ [★ map] γ ↦ b ∈ f, Φ γ) ★ + [★ map] γ ↦ b ∈ f, box_own_auth γ (◯ Excl' b) ★ box_own_prop γ (Φ γ) ★ + inv N (box_inv γ (Φ γ)))%I. +End box_defs. + +Section box. +Context `{boxG Λ Σ} (N : namespace). +Notation iProp := (iPropG Λ Σ). +Implicit Types P Q : iProp. + +Instance box_own_auth_timeless γ + (a : auth (option (excl bool))) : TimelessP (box_own_auth γ a). +Proof. apply own_timeless, pair_timeless; apply _. Qed. + +Lemma box_own_auth_agree γ b1 b2 : + (box_own_auth γ (◠Excl' b1) ★ box_own_auth γ (◯ Excl' b2)) ⊢ (b1 = b2). +Proof. + rewrite /box_own_prop -own_op own_valid prod_validI /= and_elim_l. + iIntros "Hb". + by iDestruct "Hb" as % [[[] [=]%leibniz_equiv] ?]%auth_valid_discrete. +Qed. + +Lemma box_own_auth_update E γ b1 b2 b3 : + (box_own_auth γ (◠Excl' b1) ★ box_own_auth γ (◯ Excl' b2)) + ⊢ |={E}=> (box_own_auth γ (◠Excl' b3) ★ box_own_auth γ (◯ Excl' b3)). +Proof. + rewrite /box_own_prop -!own_op. + apply own_update, prod_update; simpl; last reflexivity. + by apply (auth_local_update (λ _, Excl' b3)). +Qed. + +Lemma box_own_agree γ Q1 Q2 : + (box_own_prop γ Q1 ★ box_own_prop γ Q2) ⊢ ▷ (Q1 ≡ Q2). +Proof. + rewrite /box_own_prop -own_op own_valid prod_validI /= and_elim_r. + rewrite option_validI /= agree_validI agree_equivI later_equivI /=. + iIntros "#HQ >". rewrite -{2}(iProp_fold_unfold Q1). + iRewrite "HQ". by rewrite iProp_fold_unfold. +Qed. + +Lemma box_alloc : True ⊢ box N ∅ True. +Proof. + iIntros; iExists (λ _, True)%I; iSplit. + - iNext. by rewrite big_sepM_empty. + - by rewrite big_sepM_empty. +Qed. + +Lemma box_insert f P Q : + ▷ box N f P ⊢ |={N}=> ∃ γ, f !! γ = None ★ + box_slice N γ Q ★ ▷ box N (<[γ:=false]> f) (Q ★ P). +Proof. + iIntros "H"; iDestruct "H" as {Φ} "[#HeqP Hf]". + iPvs (own_alloc_strong (◠Excl' false ⋅ ◯ Excl' false, + Some (to_agree (Next (iProp_unfold Q)))) _ (dom _ f)) + as {γ} "[Hdom Hγ]"; first done. + rewrite pair_split. iDestruct "Hγ" as "[[Hγ Hγ'] #HγQ]". + iDestruct "Hdom" as % ?%not_elem_of_dom. + iPvs (inv_alloc N _ (box_inv γ Q) with "[Hγ]") as "#Hinv"; first done. + { iNext. iExists false. by repeat iSplit. } + iPvsIntro; iExists γ; repeat iSplit; auto. + iNext. iExists (<[γ:=Q]> Φ); iSplit. + - iNext. iRewrite "HeqP". by rewrite big_sepM_fn_insert'. + - rewrite (big_sepM_fn_insert (λ _ _ P', _ ★ _ _ P' ★ _ _ (_ _ P')))%I //. + iFrame "Hf Hγ'". by iSplit. +Qed. + +Lemma box_delete f P Q γ : + f !! γ = Some false → + (box_slice N γ Q ★ ▷ box N f P) ⊢ |={N}=> ∃ P', + ▷ ▷ (P ≡ (Q ★ P')) ★ ▷ box N (delete γ f) P'. +Proof. + iIntros {?} "[#Hinv H]"; iDestruct "H" as {Φ} "[#HeqP Hf]". + iExists ([★ map] γ'↦_ ∈ delete γ f, Φ γ')%I. + iInv N as {b} "(Hγ & #HγQ &_)"; iPvsIntro; iNext. + iDestruct (big_sepM_delete _ f _ false with "Hf") + as "[[Hγ' #[HγΦ ?]] ?]"; first done. + iDestruct (box_own_agree γ Q (Φ γ) with "[#]") as "HeqQ"; first by iSplit. + iDestruct (box_own_auth_agree γ b false with "[#]") + as "%"; subst; first by iFrame "Hγ". + iSplitL "Hγ"; last iSplit. + - iExists false; repeat iSplit; auto. + - iNext. iRewrite "HeqP". iRewrite "HeqQ". by rewrite -big_sepM_delete. + - iExists Φ; by iSplit; [iNext|]. +Qed. + +Lemma box_fill f γ b P Q : + f !! γ = Some b → + (box_slice N γ Q ★ ▷ Q ★ ▷ box N f P) ⊢ |={N}=> ▷ box N (<[γ:=true]> f) P. +Proof. + iIntros {?} "(#Hinv & HQ & H)"; iDestruct "H" as {Φ} "[#HeqP Hf]". + iInv N as {b'} "(Hγ & #HγQ & _)"; iTimeless "Hγ". + iDestruct (big_sepM_later _ f with "Hf") as "Hf". + iDestruct (big_sepM_delete _ f _ b with "Hf") + as "[[Hγ' #[HγΦ Hinv']] ?]"; first done; iTimeless "Hγ'". + iPvs (box_own_auth_update _ γ b' b true with "[Hγ Hγ']") + as "[Hγ Hγ']"; first by iFrame "Hγ". + iPvsIntro; iNext; iSplitL "Hγ HQ"; first (iExists true; by iFrame "Hγ HQ"). + iExists Φ; iSplit. + - by rewrite -insert_delete big_sepM_insert ?lookup_delete // big_sepM_delete. + - rewrite -insert_delete big_sepM_insert ?lookup_delete //. + iFrame "Hγ'". by repeat iSplit. +Qed. + +Lemma box_empty f P Q γ : + f !! γ = Some true → + (box_slice N γ Q ★ ▷ box N f P) ⊢ |={N}=> ▷ Q ★ ▷ box N (<[γ:=false]> f) P. +Proof. + iIntros {?} "[#Hinv H]"; iDestruct "H" as {Φ} "[#HeqP Hf]". + iInv N as {b} "(Hγ & #HγQ & HQ)"; iTimeless "Hγ". + iDestruct (big_sepM_later _ f with "Hf") as "Hf". + iDestruct (big_sepM_delete _ f _ true with "Hf") + as "[[Hγ' #[HγΦ Hinv']] ?]"; first done; iTimeless "Hγ'". + iDestruct (box_own_auth_agree γ b true with "[#]") + as "%"; subst; first by iFrame "Hγ". + iFrame "HQ". + iPvs (box_own_auth_update _ γ true true false with "[Hγ Hγ']") + as "[Hγ Hγ']"; first by iFrame "Hγ". + iPvsIntro; iNext; iSplitL "Hγ"; first (iExists false; by repeat iSplit). + iExists Φ; iSplit. + - by rewrite -insert_delete big_sepM_insert ?lookup_delete // big_sepM_delete. + - rewrite -insert_delete big_sepM_insert ?lookup_delete //. + iFrame "Hγ'". by repeat iSplit. +Qed. + +Lemma box_fill_all f P Q : + (box N f P ★ ▷ P) ⊢ |={N}=> box N (const true <$> f) P. +Proof. + iIntros "[H HP]"; iDestruct "H" as {Φ} "[#HeqP Hf]". + iExists Φ; iSplitR; first by rewrite big_sepM_fmap. + rewrite eq_iff later_iff big_sepM_later; iDestruct ("HeqP" with "HP") as "HP". + iCombine "Hf" "HP" as "Hf". + rewrite big_sepM_fmap; iApply (pvs_big_sepM _ _ f). + iApply (big_sepM_impl _ _ f); iFrame "Hf". + iAlways; iIntros {γ b' ?} "[(Hγ' & #$ & #$) HΦ]". + iInv N as {b} "[Hγ _]"; iTimeless "Hγ". + iPvs (box_own_auth_update _ γ b b' true with "[Hγ Hγ']") + as "[Hγ $]"; first by iFrame "Hγ". + iPvsIntro; iNext; iExists true. by iFrame "HΦ Hγ". +Qed. + +Lemma box_empty_all f P Q : + map_Forall (λ _, (true =)) f → + box N f P ⊢ |={N}=> ▷ P ★ box N (const false <$> f) P. +Proof. + iIntros {?} "H"; iDestruct "H" as {Φ} "[#HeqP Hf]". + iAssert ([★ map] γ↦b ∈ f, ▷ Φ γ ★ box_own_auth γ (◯ Excl' false) ★ + box_own_prop γ (Φ γ) ★ inv N (box_inv γ (Φ γ)))%I with "=>[Hf]" as "[HΦ ?]". + { iApply (pvs_big_sepM _ _ f); iApply (big_sepM_impl _ _ f); iFrame "Hf". + iAlways; iIntros {γ b ?} "(Hγ' & #$ & #$)". + assert (true = b) as <- by eauto. + iInv N as {b} "(Hγ & _ & HΦ)"; iTimeless "Hγ". + iDestruct (box_own_auth_agree γ b true with "[#]") + as "%"; subst; first by iFrame "Hγ". + iPvs (box_own_auth_update _ γ true true false with "[Hγ Hγ']") + as "[Hγ $]"; first by iFrame "Hγ". + iPvsIntro; iNext. iFrame "HΦ". iExists false. by iFrame "Hγ"; iSplit. } + iPvsIntro; iSplitL "HΦ". + - rewrite eq_iff later_iff big_sepM_later. by iApply "HeqP". + - iExists Φ; iSplit; by rewrite big_sepM_fmap. +Qed. +End box. -- GitLab