Skip to content
Snippets Groups Projects
Commit 95561ad3 authored by Ralf Jung's avatar Ralf Jung
Browse files

vastly simplify the counterexample

parent c6668f89
No related branches found
No related tags found
No related merge requests found
...@@ -90,36 +90,22 @@ Module inv. Section inv. ...@@ -90,36 +90,22 @@ Module inv. Section inv.
Hypothesis inv_open : Hypothesis inv_open :
forall i P Q R, (P Q pvs0 (P R)) (inv i P Q pvs1 R). forall i P Q R, (P Q pvs0 (P R)) (inv i P Q pvs1 R).
(* We have tokens for a little "three-state STS": [fresh] -> [start n] -> (* We have tokens for a little "two-state STS": [start] -> [finish].
[finish n]. The [auth_*] tokens are in the invariant and assert an exact state. [start] also asserts the exact state; it is only ever owned by the
state. [fresh] also asserts the exact state; it is owned by threads (i.e., invariant. [finished] is duplicable. *)
there's a token needed to transition to [start].) [started] and [finished] Context (gname : Type).
are *lower bounds*. We don't need "auth_finish" because the state will Context (start finished : gname iProp).
never change again, so [finished] is just as good. *)
Context (auth_fresh fresh : iProp). Hypothesis sts_alloc : True pvs0 ( γ, start γ).
Context (auth_start started finished : name iProp). Hypotheses start_finish : forall γ, start γ pvs0 (finished γ).
Hypothesis fresh_start :
forall n, auth_fresh fresh pvs0 (auth_start n started n). Hypothesis finished_not_start : forall γ, start γ finished γ False.
Hypotheses start_finish :
forall n, auth_start n pvs0 (finished n). Hypothesis finished_dup : forall γ, finished γ finished γ finished γ.
Hypothesis fresh_not_start : forall n, auth_start n fresh False.
Hypothesis fresh_not_finished : forall n, finished n fresh False.
Hypothesis started_not_fresh : forall n, auth_fresh started n False.
Hypothesis finished_not_start : forall n m, auth_start n finished m False.
Hypothesis started_start_agree : forall n m, auth_start n started m n = m.
Hypothesis started_finished_agree :
forall n m, finished n started m n = m.
Hypothesis finished_agree :
forall n m, finished n finished m n = m.
Hypothesis started_dup : forall n, started n started n started n.
Hypothesis finished_dup : forall n, finished n finished n finished n.
(* We have that we cannot view shift from the initial state to false (* We have that we cannot view shift from the initial state to false
(because the initial state is actually achievable). *) (because the initial state is actually achievable). *)
Hypothesis soundness : ¬ (auth_fresh fresh pvs1 False). Hypothesis soundness : ¬ (True pvs1 False).
(** Some general lemmas and proof mode compatibility. *) (** Some general lemmas and proof mode compatibility. *)
Lemma inv_open' i P R: Lemma inv_open' i P R:
...@@ -191,144 +177,73 @@ Module inv. Section inv. ...@@ -191,144 +177,73 @@ Module inv. Section inv.
apply pvs1_mono. by rewrite -HP -(uPred.exist_intro a). apply pvs1_mono. by rewrite -HP -(uPred.exist_intro a).
Qed. Qed.
(* "Weak box" -- a weak form of □ for non-persistent assertions. *)
Definition wbox P : iProp :=
Q, Q (Q P) (Q Q Q).
Lemma wbox_dup P :
wbox P wbox P wbox P.
Proof.
iIntros "H". iDestruct "H" as (Q) "(HQ & #HP & #Hdup)".
iDestruct ("Hdup" with "HQ") as "[HQ HQ']".
iSplitL "HQ"; iExists Q; iSplit; eauto.
Qed.
Lemma wbox_out P :
wbox P P.
Proof.
iIntros "H". iDestruct "H" as (Q) "(HQ & #HP & _)".
iApply "HP". done.
Qed.
(** Now to the actual counterexample. We start with a weird for of saved propositions. *) (** Now to the actual counterexample. We start with a weird for of saved propositions. *)
Definition saved (i : name) (P : iProp) : iProp := Definition saved (γ : gname) (P : iProp) : iProp :=
F : name iProp, P = F i started i i, inv i (start γ (finished γ P)).
inv i (auth_fresh j, auth_start j (finished j wbox (F j))). Global Instance : forall γ P, PersistentP (saved γ P) := _.
Lemma saved_dup i P : Lemma saved_alloc (P : gname iProp) :
saved i P saved i P saved i P. True pvs1 ( γ, saved γ (P γ)).
Proof. Proof.
iIntros "H". iDestruct "H" as (F) "(#? & Hs & #?)". iIntros "". iVs (sts_alloc) as (γ) "Hs".
iDestruct (started_dup with "Hs") as "[Hs Hs']". iSplitL "Hs". iVs (inv_alloc (start γ (finished γ (P γ))) with "[Hs]") as (i) "#Hi".
- iExists F. eauto.
- iExists F. eauto.
Qed.
Lemma saved_alloc (P : name iProp) :
auth_fresh fresh pvs1 ( i, saved i (P i)).
Proof.
iIntros "[Haf Hf]". iVs (inv_alloc (auth_fresh j, auth_start j (finished j wbox (P j))) with "[Haf]") as (i) "#Hi".
{ iLeft. done. } { iLeft. done. }
iExists i. iApply inv_open'. iSplit; first done. iIntros "[Haf|Has]"; last first. iApply pvs1_intro. iExists γ, i. done.
{ iExFalso. iDestruct "Has" as (j) "[Has | [Haf _]]".
- iApply fresh_not_start. iSplitL "Has"; done.
- iApply fresh_not_finished. iSplitL "Haf"; done. }
iVs ((fresh_start i) with "[Hf Haf]") as "[Has Hs]"; first by iFrame.
iDestruct (started_dup with "Hs") as "[Hs Hs']".
iApply pvs0_intro. iSplitR "Hs'".
- iRight. iExists i. iLeft. done.
- iApply pvs1_intro. iExists P. iSplit; first done. by iFrame.
Qed. Qed.
Lemma saved_cast i P Q : Lemma saved_cast γ P Q :
saved i P saved i Q wbox P pvs1 (wbox Q). saved γ P saved γ Q P pvs1 ( Q).
Proof. Proof.
iIntros "(HsP & HsQ & HP)". iDestruct "HsP" as (FP) "(% & HsP & #HiP)". iIntros "(#HsP & #HsQ & #HP)". iDestruct "HsP" as (i) "HiP".
iApply (inv_open' i). iSplit; first done. iApply (inv_open' i). iSplit; first done.
iIntros "[HaP|HaP]".
{ iExFalso. iApply started_not_fresh. iSplitL "HaP"; done. }
(* Can I state a view-shift and immediately run it? *) (* Can I state a view-shift and immediately run it? *)
iAssert (pvs0 (finished i)) with "[HaP HsP]" as "Hf". iIntros "HaP". iAssert (pvs0 (finished γ)) with "[HaP]" as "Hf".
{ iDestruct "HaP" as (j) "[Hs | [Hf _]]". { iDestruct "HaP" as "[Hs | [Hf _]]".
- iApply start_finish. - by iApply start_finish.
iDestruct (started_start_agree with "[#]") as "%"; first by iSplitL "Hs". - by iApply pvs0_intro. }
subst j. done. iVs "Hf" as "Hf". iDestruct (finished_dup with "Hf") as "[Hf Hf']".
- iApply pvs0_intro. iApply pvs0_intro. iSplitL "Hf'"; first by eauto.
iDestruct (started_finished_agree with "[#]") as "%"; first by iSplitL "Hf". (* Step 2: Open the Q-invariant. *)
subst j. done. } iClear "HiP". clear i. iDestruct "HsQ" as (i) "HiQ".
iVs "Hf" as "Hf". iApply pvs0_intro. iApply (inv_open' i). iSplit; first done.
iDestruct (finished_dup with "Hf") as "[Hf Hf']". iSplitL "Hf' HP". iIntros "[HaQ | [_ #HQ]]".
{ iRight. iExists i. iRight. subst. iSplitL "Hf'"; done. } { iExFalso. iApply finished_not_start. iSplitL "HaQ"; done. }
iDestruct "HsQ" as (FQ) "(% & HsQ & HiQ)". iApply pvs0_intro. iSplitL "Hf".
iApply (inv_open' i). iSplit; first iExact "HiQ". { iRight. by iSplitL "Hf". }
iIntros "[HaQ | HaQ]". by iApply pvs1_intro.
{ iExFalso. iApply started_not_fresh. iSplitL "HaQ"; done. }
iDestruct "HaQ" as (j) "[HaS | [Hf' HQ]]".
{ iExFalso. iApply finished_not_start. iSplitL "HaS"; done. }
iApply pvs0_intro.
iDestruct (finished_dup with "Hf'") as "[Hf' Hf'']".
iDestruct (wbox_dup with "HQ") as "[HQ HQ']".
iSplitL "Hf'' HQ'".
{ iRight. iExists j. iRight. by iSplitR "HQ'". }
iPoseProof (finished_agree with "[#]") as "H".
{ iFrame "Hf Hf'". done. }
iDestruct "H" as %<-. iApply pvs1_intro. subst Q. done.
Qed. Qed.
(** And now we tie a bad knot. *) (** And now we tie a bad knot. *)
Notation "¬ P" := (wbox (P -★ pvs1 False))%I : uPred_scope. Notation "¬ P" := ( (P -★ pvs1 False))%I : uPred_scope.
Definition A i : iProp := P, ¬P saved i P. Definition A i : iProp := P, ¬P saved i P.
Lemma A_dup i : Global Instance : forall i, PersistentP (A i) := _.
A i A i A i.
Proof.
iIntros "HA". iDestruct "HA" as (P) "[HNP HsP]".
iDestruct (wbox_dup with "HNP") as "[HNP HNP']".
iDestruct (saved_dup with "HsP") as "[HsP HsP']".
iSplitL "HNP HsP"; iExists P.
- by iSplitL "HNP".
- by iSplitL "HNP'".
Qed.
Lemma A_wbox i :
A i wbox (A i).
Proof.
iIntros "H". iExists (A i). iSplitL "H"; first done.
iSplit; first by iIntros "!# ?". iIntros "!# HA".
by iApply A_dup.
Qed.
Lemma A_alloc : Lemma A_alloc :
auth_fresh fresh pvs1 ( i, saved i (A i)). True pvs1 ( i, saved i (A i)).
Proof. by apply saved_alloc. Qed. Proof. by apply saved_alloc. Qed.
Lemma alloc_NA i : Lemma alloc_NA i :
saved i (A i) (¬A i). saved i (A i) (¬A i).
Proof. Proof.
iIntros "Hi". iExists (saved i (A i)). iSplitL "Hi"; first done. iIntros "#Hi !# #HA". iPoseProof "HA" as "HA'".
iSplit; last by (iIntros "!# ?"; iApply saved_dup). iDestruct "HA'" as (P) "#[HNP Hi']".
iIntros "!# Hi HAi". iVs ((saved_cast i) with "[]") as "HP".
iDestruct (A_dup with "HAi") as "[HAi HAi']". { iSplit; first iExact "Hi". iSplit; first iExact "Hi'". done. }
iDestruct "HAi'" as (P) "[HNP Hi']". by iApply "HNP".
iVs ((saved_cast i) with "[Hi Hi' HAi]") as "HP".
{ iSplitL "Hi"; first done. iSplitL "Hi'"; first done. by iApply A_wbox. }
iPoseProof (wbox_out with "HNP") as "HNP".
iApply "HNP". iApply wbox_out. done.
Qed. Qed.
Lemma alloc_A i : Lemma alloc_A i :
saved i (A i) A i. saved i (A i) A i.
Proof. Proof.
iIntros "Hi". iDestruct (saved_dup with "Hi") as "[Hi Hi']". iIntros "#Hi". iPoseProof (alloc_NA with "Hi") as "HNA".
iPoseProof (alloc_NA with "Hi") as "HNA". iExists (A i). iSplit; done.
iExists (A i). iSplitL "HNA"; done.
Qed. Qed.
Lemma contradiction : False. Lemma contradiction : False.
Proof. Proof.
apply soundness. iIntros "H". apply soundness. iIntros "".
iVs (A_alloc with "H") as "H". iDestruct "H" as (i) "H". iVs A_alloc as (i) "#H".
iDestruct (saved_dup with "H") as "[H H']".
iPoseProof (alloc_NA with "H") as "HN". iPoseProof (alloc_NA with "H") as "HN".
iPoseProof (wbox_out with "HN") as "HN".
iApply "HN". iApply "HN".
iApply alloc_A. done. iApply alloc_A. done.
Qed. Qed.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment