exercises.timeless
From iris.base_logic.lib Require Export invariants.
From iris.heap_lang Require Import lang proofmode notation.
(* ################################ *)
From iris.heap_lang Require Import lang proofmode notation.
(* ################################ *)
(* ================================================================= *)
A large class of propositions do not depend on time; they are either
always true or always false. An example is equalities; 2 + 2 = 4 is
always true. We call such propositions timeless. All pure
propositions are timeless, and ownership of a resource is timeless if
the resource comes from a resource algebra (this includes points-to
predicates). Further, timelessness is preserved by most connectives.
As a rule of thumb, a predicate is timeless if
Naively, one might assume that if P is timeless, then ▷ P ⊢ P.
However, together with Löb induction, this would actually imply that
P is True. Instead, the power of timeless propositions is
reflected in the rule: ▷ P ⊢ |={⊤}=> P, whenever P is timeless.
This rule allows us to strip laters from timeless propositions
whenever the goal contains a fancy update modality.
To identify timeless propositions, Iris uses the typeclass Timeless.
- it does not contain a ▷
- it does not mention an invariant
- it is first-order
Lemma later_timeless_fup (P Q : iProp Σ) `{!Timeless P} :
(P -∗ Q) ∗ ▷ P ⊢ |={⊤}=> Q.
Proof.
iIntros "[HPQ HP]".
As ▷ is a modality, we can use the iMod tactic to strip it from
our hypothesis. In this case, this is allowed as the goal contains a
fancy update modality and P is timeless.
iMod "HP".
by iApply "HPQ".
Qed.
by iApply "HPQ".
Qed.
As usual, we can use the notation ">" to invoke iMod. This is how we
will usually invoke iMod to strip laters. The above proof can hence
be shortened as follows.
Lemma later_timeless_fup' (P Q : iProp Σ) `{!Timeless P} :
(P -∗ Q) ∗ ▷ P ⊢ |={⊤}=> Q.
Proof.
iIntros "[HPQ >HP]".
by iApply "HPQ".
Qed.
We may always add a fancy update modality in front of a WP
(concretely with the fupd_wp lemma), so we can also remove laters
from timeless propositions in our context if the goal is a weakest
precondition.
Lemma later_store (l : loc) (v : val) :
{{{ ▷ (l ↦ v) }}} #l <- #4 {{{ w, RET w; l ↦ #4 }}}.
Proof.
iIntros (Φ) ">Hl HΦ".
wp_store.
by iApply "HΦ".
Qed.
Since the points-to predicate is well supported, we do not actually
have to remove the later manually; the tactics work even when the
predicate has a later.
Lemma later_store' (l : loc) (v : val) :
{{{ ▷ (l ↦ v) }}} #l <- #4 {{{ w, RET w; l ↦ #4 }}}.
Proof.
iIntros (Φ) "Hl HΦ".
wp_store.
by iApply "HΦ".
Qed.
The last scenario we mention is when the goal contains a later. In
this case, we may remove laters from timeless hypotheses without
removing the later from the goal.
Lemma later_timeless_strip (P Q : iProp Σ) `{!Timeless P} :
(P -∗ ▷Q) ∗ ▷ P ⊢ ▷ Q.
Proof.
iIntros "[HPQ >HP]".
by iApply "HPQ".
Qed.
(* ================================================================= *)
Timeless Propositions and Invariants
Lemma inv_timeless (l : loc) (w : val) (P : iProp Σ) (N : namespace) :
{{{ inv N (⌜w = #5⌝ ∗ P) ∗ (l ↦ w) }}}
CAS #l #5 #6
{{{ v, RET v; l ↦ #6 }}}.
Proof.
iIntros (Φ) "[#Hinv Hl] HΦ".
To prove that the CAS succeeds, we need to know that w equals 5.
Thus, we must open the invariant.
wp_bind (CmpXchg #l #5 #6)%E.
iInv "Hinv" as "[Heq HP]".
iInv "Hinv" as "[Heq HP]".
Opening the invariant only gives us that w equals 5 later.
However, as pure propositions are timeless, we can strip the later.
iMod "Heq" as "%Heq".
rewrite Heq.
rewrite Heq.
Now we can prove that the CAS succeeds.
wp_cmpxchg_suc.
iSplitL "HP"; first by iFrame.
iModIntro.
wp_pures.
by iApply "HΦ".
Qed.
iSplitL "HP"; first by iFrame.
iModIntro.
wp_pures.
by iApply "HΦ".
Qed.
When opening invariants, we usually strip laters from timeless parts
of the invariant immediately.
Lemma inv_timeless' (l : loc) (w : val) (P : iProp Σ) (N : namespace) :
{{{ inv N (⌜w = #5⌝ ∗ P) ∗ (l ↦ w) }}}
CAS #l #5 #6
{{{ v, RET v; l ↦ #6 }}}.
Proof.
iIntros (Φ) "[#Hinv Hl] HΦ".
wp_bind (CmpXchg #l #5 #6)%E.
Open the invariant, strip the later from the equality (achieved by
">"), and rewrite with the equality (achieved by "->").
iInv "Hinv" as "[>-> HP]".
wp_cmpxchg_suc.
iSplitL "HP"; first by iFrame.
iModIntro.
wp_pures.
by iApply "HΦ".
Qed.
End timeless.
wp_cmpxchg_suc.
iSplitL "HP"; first by iFrame.
iModIntro.
wp_pures.
by iApply "HΦ".
Qed.
End timeless.