Commit 23c9e418 authored by Robbert Krebbers's avatar Robbert Krebbers

Merge branch 'master' into iris3.0

parents 1ded5657 fcc1c439
......@@ -7,13 +7,19 @@ Coq development, but not every API-breaking change is listed. Changes marked
This version accompanies the final ICFP paper.
* [# algebra] Make the core of an RA or CMRA a partial function.
* [algebra] Make the core of an RA or CMRA a partial function.
* [heap_lang] No longer use dependent types for expressions. Instead, values
carry a proof of closedness. Substitution, closedness and value-ness proofs
are performed by computation after reflecting into a term langauge that knows
about values and closed expressions.
* [program_logic/language] The language does not define its own "atomic"
predicate. Instead, atomicity is defined as reducing in one step to a value.
* [program_logic/lifting] Lifting lemmas no longer round-trip through a
user-chosen predicate to define the configurations we can reduce to; they
directly relate to the operational semantics. This is equivalent and
much simpler to read.
Due to a lack of maintenance and usefulness, lifting lemmas for Hoare triples
are removed.
## Iris 2.0-rc1
......
Tactic overview
===============
Many of the tactics below apply to more goals than described in this document
since the behavior of these tactics can be tuned via instances of the type
classes in the file `proofmode/classes`. Most notable, many of the tactics can
be applied when the to be introduced or to be eliminated connective appears
under a later, a primitive view shift, or in the conclusion of a weakest
precondition connective.
Applying hypotheses and lemmas
------------------------------
- `iExact "H"` : finish the goal if the conclusion matches the hypothesis `H`
- `iAssumption` : finish the goal if the conclusion matches any hypothesis
- `iApply trm` : match the conclusion of the current goal against the
conclusion of `tetrmrm` and generates goals for the premises of `trm`. See
- `iApply pm_trm` : match the conclusion of the current goal against the
conclusion of `pm_trm` and generates goals for the premises of `pm_trm`. See
proof mode terms below.
Context management
......@@ -23,9 +30,10 @@ Context management
`x1 ... xn` into universal quantifiers. The symbol `★` can be used to revert
the entire spatial context.
- `iRename "H1" into "H2"` : rename the hypothesis `H1` into `H2`.
- `iSpecialize trm` : instantiate universal quantifiers and eliminate
implications/wands of a hypothesis `trm`. See proof mode terms below.
- `iPoseProof trm as "H"` : put `trm` into the context as a new hypothesis `H`.
- `iSpecialize pm_trm` : instantiate universal quantifiers and eliminate
implications/wands of a hypothesis `pm_trm`. See proof mode terms below.
- `iPoseProof pm_trm as "H"` : put `pm_trm` into the context as a new hypothesis
`H`.
- `iAssert P with "spat" as "ipat"` : create a new goal with conclusion `P` and
put `P` in the context of the original goal. The specialization pattern
`spat` specifies which hypotheses will be consumed by proving `P` and the
......@@ -52,11 +60,11 @@ Elimination of logical connectives
----------------------------------
- `iExFalso` : Ex falso sequitur quod libet.
- `iDestruct trm as (x1 ... xn) "spat1 ... spatn"` : elimination of existential
quantifiers using Coq introduction patterns `x1 ... xn` and elimination of
object level connectives using the proof mode introduction patterns
`ipat1 ... ipatn`.
- `iDestruct trm as %cpat` : elimination of a pure hypothesis using the Coq
- `iDestruct pm_trm as (x1 ... xn) "spat1 ... spatn"` : elimination of
existential quantifiers using Coq introduction patterns `x1 ... xn` and
elimination of object level connectives using the proof mode introduction
patterns `ipat1 ... ipatn`.
- `iDestruct pm_trm as %cpat` : elimination of a pure hypothesis using the Coq
introduction pattern `cpat`.
Separating logic specific tactics
......@@ -75,15 +83,15 @@ The later modality
Rewriting
---------
- `iRewrite trm` : rewrite an equality in the conclusion.
- `iRewrite trm in "H"` : rewrite an equality in the hypothesis `H`.
- `iRewrite pm_trm` : rewrite an equality in the conclusion.
- `iRewrite pm_trm in "H"` : rewrite an equality in the hypothesis `H`.
Iris
----
- `iPvsIntro` : introduction of a primitive view shift. Generates a goal if
the masks are not syntactically equal.
- `iPvs trm as (x1 ... xn) "ipat"` : runs a primitive view shift `trm`.
- `iPvs pm_trm as (x1 ... xn) "ipat"` : runs a primitive view shift `pm_trm`.
- `iInv N as (x1 ... xn) "ipat"` : open the invariant `N`.
- `iInv> N as (x1 ... xn) "ipat"` : open the invariant `N` and establish that
it is timeless so no laters have to be added.
......@@ -186,7 +194,7 @@ Many of the proof mode tactics (such as `iDestruct`, `iApply`, `iRewrite`) can
take both hypotheses and lemmas, and allow one to instantiate universal
quantifiers and implications/wands of these hypotheses/lemmas on the fly.
The syntax for the arguments, called _proof mode terms_, of these tactics is:
The syntax for the arguments of these tactics, called _proof mode terms_, is:
(H $! t1 ... tn with "spat1 .. spatn")
......
......@@ -122,3 +122,4 @@ proofmode/weakestpre.v
proofmode/ghost_ownership.v
proofmode/sts.v
proofmode/classes.v
proofmode/class_instances.v
......@@ -191,11 +191,17 @@ Proof.
exists bf2. rewrite -assoc.
apply (Hab' _ (Some _)); auto. by rewrite /= assoc.
Qed.
Lemma auth_update_no_frame a b : a ~l~> b @ Some a a ~~> b b.
Proof.
intros. rewrite -{1}(right_id _ _ a) -{1}(right_id _ _ b).
by apply auth_update.
Qed.
Lemma auth_update_no_frag af b : ~l~> b @ Some af af ~~> (b af) b.
Proof.
intros. rewrite -{1}(left_id _ _ af) -{1}(right_id _ _ ( _)).
by apply auth_update.
Qed.
End cmra.
Arguments authR : clear implicits.
......
......@@ -57,24 +57,47 @@ Section gset.
Context `{Fresh K (gset K), !FreshSpec K (gset K)}.
Arguments op _ _ _ _ : simpl never.
Lemma gset_alloc_updateP_strong (Q : gset_disj K Prop) (I : gset K) X :
( i, i X i I Q (GSet ({[i]} X))) GSet X ~~>: Q.
Lemma gset_alloc_updateP_strong P (Q : gset_disj K Prop) X :
( Y, X Y j, j Y P j)
( i, i X P i Q (GSet ({[i]} X))) GSet X ~~>: Q.
Proof.
intros HQ; apply cmra_discrete_updateP=> ? /gset_disj_valid_inv_l [Y [->?]].
destruct (exist_fresh (X Y I)) as [i ?].
intros Hfresh HQ.
apply cmra_discrete_updateP=> ? /gset_disj_valid_inv_l [Y [->?]].
destruct (Hfresh (X Y)) as (i&?&?); first set_solver.
exists (GSet ({[ i ]} X)); split.
- apply HQ; set_solver by eauto.
- apply gset_disj_valid_op. set_solver by eauto.
Qed.
Lemma gset_alloc_updateP (Q : gset_disj K Prop) X :
( i, i X Q (GSet ({[i]} X))) GSet X ~~>: Q.
Proof. move=>??. eapply gset_alloc_updateP_strong with (I:=); by eauto. Qed.
Lemma gset_alloc_updateP_strong' (I : gset K) X :
GSet X ~~>: λ Y, i, Y = GSet ({[ i ]} X) i I i X.
Proof.
intro; eapply gset_alloc_updateP_strong with (λ _, True); eauto.
intros Y ?; exists (fresh Y); eauto using is_fresh.
Qed.
Lemma gset_alloc_updateP_strong' P X :
( Y, X Y j, j Y P j)
GSet X ~~>: λ Y, i, Y = GSet ({[ i ]} X) i X P i.
Proof. eauto using gset_alloc_updateP_strong. Qed.
Lemma gset_alloc_updateP' X : GSet X ~~>: λ Y, i, Y = GSet ({[ i ]} X) i X.
Proof. eauto using gset_alloc_updateP. Qed.
Lemma gset_alloc_empty_updateP_strong P (Q : gset_disj K Prop) :
( Y : gset K, j, j Y P j)
( i, P i Q (GSet {[i]})) GSet ~~>: Q.
Proof.
intros. apply (gset_alloc_updateP_strong P); eauto.
intros i; rewrite right_id_L; auto.
Qed.
Lemma gset_alloc_empty_updateP (Q : gset_disj K Prop) :
( i, Q (GSet {[i]})) GSet ~~>: Q.
Proof. intro. apply gset_alloc_updateP. intros i; rewrite right_id_L; auto. Qed.
Lemma gset_alloc_empty_updateP_strong' P :
( Y : gset K, j, j Y P j)
GSet ~~>: λ Y, i, Y = GSet {[ i ]} P i.
Proof. eauto using gset_alloc_empty_updateP_strong. Qed.
Lemma gset_alloc_empty_updateP' : GSet ~~>: λ Y, i, Y = GSet {[ i ]}.
Proof. eauto using gset_alloc_empty_updateP. Qed.
Lemma gset_alloc_local_update X i Xf :
i X i Xf GSet X ~l~> GSet ({[i]} X) @ Some (GSet Xf).
Proof.
......@@ -83,6 +106,12 @@ Section gset.
- intros mZ ?%gset_disj_valid_op HXf.
rewrite -gset_disj_union -?assoc ?HXf ?cmra_opM_assoc; set_solver.
Qed.
Lemma gset_alloc_empty_local_update i Xf :
i Xf GSet ~l~> GSet {[i]} @ Some (GSet Xf).
Proof.
intros. rewrite -(right_id_L _ _ {[i]}).
apply gset_alloc_local_update; set_solver.
Qed.
End gset.
Arguments gset_disjR _ {_ _}.
......
......@@ -211,7 +211,7 @@ Furthermore, discrete CMRAs can be turned into RAs by ignoring their COFE struct
\end{defn}
Note that every object/arrow in $\CMRAs$ is also an object/arrow of $\COFEs$.
The notion of a locally non-expansive (or contractive) bifunctor naturally generalizes to bifunctors between these categories.
\ralf{Discuss how we probably have a commuting square of functors between Set, RA, CMRA, COFE.}
%%% Local Variables:
%%% mode: latex
......
......@@ -3,7 +3,7 @@
\subsection{Next (type-level later)}
Given a COFE $\cofe$, we define $\latert\cofe$ as follows:
Given a COFE $\cofe$, we define $\latert\cofe$ as follows (using a datatype-like notation to define the type):
\begin{align*}
\latert\cofe \eqdef{}& \latertinj(x:\cofe) \\
\latertinj(x) \nequiv{n} \latertinj(y) \eqdef{}& n = 0 \lor x \nequiv{n-1} y
......@@ -62,7 +62,7 @@ Frame-preserving updates on the $M_i$ lift to the product:
\subsection{Sum}
\label{sec:summ}
The \emph{sum CMRA} $\monoid_1 \csumm \monoid_2$ for any CMRAs $\monoid_1$ and $\monoid_2$ is defined as:
The \emph{sum CMRA} $\monoid_1 \csumm \monoid_2$ for any CMRAs $\monoid_1$ and $\monoid_2$ is defined as (again, we use a datatype-like notation):
\begin{align*}
\monoid_1 \csumm \monoid_2 \eqdef{}& \cinl(\melt_1:\monoid_1) \mid \cinr(\melt_2:\monoid_2) \mid \bot \\
\mval_n \eqdef{}& \setComp{\cinl(\melt_1)\!}{\!\melt_1 \in \mval'_n}
......@@ -104,36 +104,35 @@ We obtain the following frame-preserving updates:
{\emptyset \mupd \setComp{[\gname \mapsto \melt]}{\gname \in K}}
\inferH{fpfn-update}
{\melt \mupd \meltsB}
{\melt \mupd_\monoid \meltsB}
{f[i \mapsto \melt] \mupd \setComp{ f[i \mapsto \meltB]}{\meltB \in \meltsB}}
\end{mathpar}
Remember that $\mval$ is the set of elements of a CMRA that are valid at \emph{all} step-indices.
Above, $\mval$ refers to the validity of $\monoid$.
$K \fpfn (-)$ is a locally non-expansive functor from $\CMRAs$ to $\CMRAs$.
\subsection{Agreement}
Given some COFE $\cofe$, we define $\agm(\cofe)$ as follows:
\newcommand{\aginjc}{\mathrm{c}} % the "c" field of an agreement element
\newcommand{\aginjV}{\mathrm{V}} % the "V" field of an agreement element
\begin{align*}
\agm(\cofe) \eqdef{}& \record{\aginjc : \mathbb{N} \to \cofe , \aginjV : \SProp} \\
& \text{quotiented by} \\
\melt \equiv \meltB \eqdef{}& \melt.\aginjV = \meltB.\aginjV \land \All n. n \in \melt.\aginjV \Ra \melt.\aginjc(n) \nequiv{n} \meltB.\aginjc(n) \\
\melt \nequiv{n} \meltB \eqdef{}& (\All m \leq n. m \in \melt.\aginjV \Lra m \in \meltB.\aginjV) \land (\All m \leq n. m \in \melt.\aginjV \Ra \melt.\aginjc(m) \nequiv{m} \meltB.\aginjc(m)) \\
\mval_n \eqdef{}& \setComp{\melt \in \agm(\cofe)}{ n \in \melt.\aginjV \land \All m \leq n. \melt.\aginjc(n) \nequiv{m} \melt.\aginjc(m) } \\
\agm(\cofe) \eqdef{}& \set{(c, V) \in (\mathbb{N} \to \cofe) \times \SProp}/\ {\sim} \\[-0.2em]
\textnormal{where }& \melt \sim \meltB \eqdef{} \melt.V = \meltB.V \land
\All n. n \in \melt.V \Ra \melt.c(n) \nequiv{n} \meltB.c(n) \\
% \All n \in {\melt.V}.\, \melt.x \nequiv{n} \meltB.x \\
\melt \nequiv{n} \meltB \eqdef{}& (\All m \leq n. m \in \melt.V \Lra m \in \meltB.V) \land (\All m \leq n. m \in \melt.V \Ra \melt.c(m) \nequiv{m} \meltB.c(m)) \\
\mval_n \eqdef{}& \setComp{\melt \in \agm(\cofe)}{ n \in \melt.V \land \All m \leq n. \melt.c(n) \nequiv{m} \melt.c(m) } \\
\mcore\melt \eqdef{}& \melt \\
\melt \mtimes \meltB \eqdef{}& (\melt.\aginjc, \setComp{n}{n \in \melt.\aginjV \land n \in \meltB.\aginjV \land \melt \nequiv{n} \meltB })
\melt \mtimes \meltB \eqdef{}& \left(\melt.c, \setComp{n}{n \in \melt.V \land n \in \meltB.V \land \melt \nequiv{n} \meltB }\right)
\end{align*}
Note that the carrier $\agm(\cofe)$ is a \emph{record} consisting of the two fields $\aginjc$ and $\aginjV$.
%Note that the carrier $\agm(\cofe)$ is a \emph{record} consisting of the two fields $c$ and $V$.
$\agm(-)$ is a locally non-expansive functor from $\COFEs$ to $\CMRAs$.
You can think of the $\aginjc$ as a \emph{chain} of elements of $\cofe$ that has to converge only for $n \in \aginjV$ steps.
You can think of the $c$ as a \emph{chain} of elements of $\cofe$ that has to converge only for $n \in V$ steps.
The reason we store a chain, rather than a single element, is that $\agm(\cofe)$ needs to be a COFE itself, so we need to be able to give a limit for every chain of $\agm(\cofe)$.
However, given such a chain, we cannot constructively define its limit: Clearly, the $\aginjV$ of the limit is the limit of the $\aginjV$ of the chain.
However, given such a chain, we cannot constructively define its limit: Clearly, the $V$ of the limit is the limit of the $V$ of the chain.
But what to pick for the actual data, for the element of $\cofe$?
Only if $\aginjV = \mathbb{N}$ we have a chain of $\cofe$ that we can take a limit of; if the $\aginjV$ is smaller, the chain ``cancels'', \ie stops converging as we reach indices $n \notin \aginjV$.
Only if $V = \mathbb{N}$ we have a chain of $\cofe$ that we can take a limit of; if the $V$ is smaller, the chain ``cancels'', \ie stops converging as we reach indices $n \notin V$.
To mitigate this, we apply the usual construction to close a set; we go from elements of $\cofe$ to chains of $\cofe$.
We define an injection $\aginj$ into $\agm(\cofe)$ as follows:
......@@ -160,12 +159,12 @@ All cases of composition go to $\bot$.
\mcore{\exinj(x)} \eqdef{}& \mnocore &
\mcore{\bot} \eqdef{}& \bot
\end{align*}
Remember that $\mnocore$ is the ``dummy'' element in $\maybe\monoid$ indicating (in this case) that $\exinj(x)$ has no core.
The step-indexed equivalence is inductively defined as follows:
\begin{mathpar}
\infer{x \nequiv{n} y}{\exinj(x) \nequiv{n} \exinj(y)}
\axiom{\munit \nequiv{n} \munit}
\axiom{\bot \nequiv{n} \bot}
\end{mathpar}
$\exm(-)$ is a locally non-expansive functor from $\COFEs$ to $\CMRAs$.
......
......@@ -221,9 +221,9 @@ We can derive some specialized forms of the lifting axioms for the operational s
\begin{mathparpagebreakable}
\infer[wp-lift-atomic-step]
{\atomic(\expr_1) \and
\red(\expr_1, \state_1) \and
\All \expr_2, \state_2, \expr_\f. \expr_1,\state_1 \step \expr_2,\state_2,\expr_\f \Ra \pred(\expr_2,\state_2,\expr_\f)}
{\later\ownPhys{\state_1} * \later\All \val_2, \state_2, \expr_\f. \pred(\ofval(\val), \state_2, \expr_\f) \land \ownPhys{\state_2} \wand \prop[\val_2/\var] * \wpre{\expr_\f}[\top]{\Ret\any.\TRUE} \proves \wpre{\expr_1}[\mask_1]{\Ret\var.\prop}}
\red(\expr_1, \state_1)}
{ {\begin{inbox}~~\later\ownPhys{\state_1} * \later\All \val_2, \state_2, \expr_\f. (\expr_1,\state_1 \step \ofval(\val),\state_2,\expr_\f) \land \ownPhys{\state_2} \wand \prop[\val_2/\var] * \wpre{\expr_\f}[\top]{\Ret\any.\TRUE} {}\\ \proves \wpre{\expr_1}[\mask_1]{\Ret\var.\prop}
\end{inbox}} }
\infer[wp-lift-atomic-det-step]
{\atomic(\expr_1) \and
......@@ -238,50 +238,12 @@ We can derive some specialized forms of the lifting axioms for the operational s
{\later ( \wpre{\expr_2}[\mask_1]{\Ret\var.\prop} * \wpre{\expr_\f}[\top]{\Ret\any.\TRUE}) \proves \wpre{\expr_1}[\mask_1]{\Ret\var.\prop}}
\end{mathparpagebreakable}
Furthermore, we derive some forms that directly involve view shifts and Hoare triples.
\begin{mathparpagebreakable}
\infer[ht-lift-step]
{\mask_2 \subseteq \mask_1 \and
\toval(\expr_1) = \bot \and
\red(\expr_1, \state_1) \and
\All \expr_2, \state_2, \expr_\f. \expr_1,\state_1 \step \expr_2,\state_2,\expr_\f \Ra \pred(\expr_2,\state_2,\expr_\f) \\\\
\prop \vs[\mask_1][\mask_2] \later\ownPhys{\state_1} * \later\prop' \and
\All \expr_2, \state_2, \expr_\f. \pred(\expr_2, \state_2, \expr_\f) * \ownPhys{\state_2} * \prop' \vs[\mask_2][\mask_1] \propB_1 * \propB_2 \\\\
\All \expr_2, \state_2, \expr_\f. \hoare{\propB_1}{\expr_2}{\Ret\val.\propC}[\mask_1] \and
\All \expr_2, \state_2, \expr_\f. \hoare{\propB_2}{\expr_\f}{\Ret\any. \TRUE}[\top]}
{ \hoare\prop{\expr_1}{\Ret\val.\propC}[\mask_1] }
\infer[ht-lift-atomic-step]
{\atomic(\expr_1) \and
\red(\expr_1, \state_1) \and
\All \expr_2, \state_2, \expr_\f. \expr_1,\state_1 \step \expr_2,\state_2,\expr_\f \Ra \pred(\expr_2,\state_2,\expr_\f) \\\\
\prop \vs[\mask_1][\mask_2] \later\ownPhys{\state_1} * \later\prop' \and
\All \expr_2, \state_2, \expr_\f. \hoare{\pred(\expr_2,\state_2,\expr_\f) * \prop}{\expr_\f}{\Ret\any. \TRUE}[\top]}
{ \hoare{\later\ownPhys{\state_1} * \later\prop}{\expr_1}{\Ret\val.\Exists \state_2, \expr_\f. \ownPhys{\state_2} * \pred(\ofval(\expr_2),\state_2,\expr_\f)}[\mask_1] }
\infer[ht-lift-pure-step]
{\toval(\expr_1) = \bot \and
\All\state_1. \red(\expr_1, \state_1) \and
\All \state_1, \expr_2, \state_2, \expr_\f. \expr_1,\state_1 \step \expr_2,\state_2,\expr_\f \Ra \state_1 = \state_2 \land \pred(\expr_2,\expr_\f) \\\\
\All \expr_2, \expr_\f. \hoare{\pred(\expr_2,\expr_\f) * \prop}{\expr_2}{\Ret\val.\propB}[\mask_1] \and
\All \expr_2, \expr_\f. \hoare{\pred(\expr_2,\expr_\f) * \prop'}{\expr_\f}{\Ret\any. \TRUE}[\top]}
{ \hoare{\later(\prop*\prop')}{\expr_1}{\Ret\val.\propB}[\mask_1] }
\infer[ht-lift-pure-det-step]
{\toval(\expr_1) = \bot \and
\All\state_1. \red(\expr_1, \state_1) \and
\All \state_1, \expr_2', \state_2, \expr_\f'. \expr_1,\state_1 \step \expr_2,\state_2,\expr_\f \Ra \state_1 = \state_2 \land \expr_2 = \expr_2' \land \expr_\f = \expr_\f' \\\\
\hoare{\prop}{\expr_2}{\Ret\val.\propB}[\mask_1] \and
\hoare{\prop'}{\expr_\f}{\Ret\any. \TRUE}[\top]}
{ \hoare{\later(\prop*\prop')}{\expr_1}{\Ret\val.\propB}[\mask_1] }
\end{mathparpagebreakable}
\subsection{Global functor and ghost ownership}
Hereinafter we assume the global CMRA functor (served up as a parameter to Iris) is obtained from a family of functors $(F_i)_{i \in I}$ for some finite $I$ by picking
\[ F(\cofe) \eqdef \prod_{i \in I} \textlog{GhName} \fpfn F_i(\cofe) \]
Hereinafter we assume the global CMRA functor (served up as a parameter to Iris) is obtained from a family of functors $(\iFunc_i)_{i \in I}$ for some finite $I$ by picking
\[ \iFunc(\cofe) \eqdef \prod_{i \in I} \textlog{GhName} \fpfn \iFunc_i(\cofe) \]
We don't care so much about what concretely $\textlog{GhName}$ is, as long as it is countable and infinite.
With $M_i \eqdef F_i(\iProp)$, we write $\ownGhost{\gname}{\melt : M_i}$ (or just $\ownGhost{\gname}{\melt}$ if $M_i$ is clear from the context) for $\ownGGhost{[i \mapsto [\gname \mapsto \melt]]}$.
With $M_i \eqdef \iFunc_i(\iProp)$, we write $\ownGhost{\gname}{\melt : M_i}$ (or just $\ownGhost{\gname}{\melt}$ if $M_i$ is clear from the context) for $\ownGGhost{[i \mapsto [\gname \mapsto \melt]]}$.
In other words, $\ownGhost{\gname}{\melt : M_i}$ asserts that in the current state of monoid $M_i$, the ``ghost location'' $\gname$ is allocated and we own piece $\melt$.
From~\ruleref{pvs-update}, \ruleref{vs-update} and the frame-preserving updates in~\Sref{sec:prodm} and~\Sref{sec:fpfnm}, we have the following derived rules.
......
......@@ -58,6 +58,7 @@ For any language $\Lang$, we define the corresponding thread-pool semantics.
\clearpage
\section{Logic}
\label{sec:logic}
To instantiate Iris, you need to define the following parameters:
\begin{itemize}
......@@ -134,7 +135,7 @@ Recursive predicates must be \emph{guarded}: in $\MU \var. \term$, the variable
Note that $\always$ and $\later$ bind more tightly than $*$, $\wand$, $\land$, $\lor$, and $\Ra$.
We will write $\pvs[\term] \prop$ for $\pvs[\term][\term] \prop$.
If we omit the mask, then it is $\top$ for weakest precondition $\wpre\expr{\Ret\var.\prop}$ and $\emptyset$ for primitive view shifts $\pvs \prop$.
%FIXME $\top$ is not a term in the logic. Neither is any of the operations on masks that we use in the rules for weakestpre.
\ralf{$\top$ is not a term in the logic. Neither is any of the operations on masks that we use in the rules for weakestpre.}
Some propositions are \emph{timeless}, which intuitively means that step-indexing does not affect them.
This is a \emph{meta-level} assertion about propositions, defined as follows:
......@@ -382,15 +383,17 @@ This is entirely standard.
{\vctx\mid\pfctx \proves \exists \var: \type.\; \prop \\
\vctx,\var : \type\mid\pfctx , \prop \proves \propB}
{\vctx\mid\pfctx \proves \propB}
\and
\infer[$\lambda$]
{}
{\pfctx \proves (\Lam\var: \type. \prop)(\term) =_{\type\to\type'} \prop[\term/\var]}
\and
\infer[$\mu$]
{}
{\pfctx \proves \mu\var: \type. \prop =_{\type} \prop[\mu\var: \type. \prop/\var]}
% \and
% \infer[$\lambda$]
% {}
% {\pfctx \proves (\Lam\var: \type. \prop)(\term) =_{\type\to\type'} \prop[\term/\var]}
% \and
% \infer[$\mu$]
% {}
% {\pfctx \proves \mu\var: \type. \prop =_{\type} \prop[\mu\var: \type. \prop/\var]}
\end{mathparpagebreakable}
Furthermore, we have the usual $\eta$ and $\beta$ laws for projections, $\lambda$ and $\mu$.
\paragraph{Laws of (affine) bunched implications.}
\begin{mathpar}
......@@ -449,6 +452,7 @@ This is entirely standard.
\later{(\prop * \propB)} &\provesIff& \later\prop * \later\propB
\end{array}
\end{mathpar}
A type $\type$ being \emph{inhabited} means that $ \proves \wtt{\term}{\type}$ is derivable for some $\term$.
\begin{mathpar}
\infer
......@@ -589,18 +593,16 @@ This is entirely standard.
\begin{mathpar}
\infer[wp-lift-step]
{\mask_2 \subseteq \mask_1 \and
\toval(\expr_1) = \bot \and
\red(\expr_1, \state_1) \and
\All \expr_2, \state_2, \expr_\f. \expr_1,\state_1 \step \expr_2,\state_2,\expr_\f \Ra \pred(\expr_2,\state_2,\expr_\f)}
\toval(\expr_1) = \bot}
{ {\begin{inbox} % for some crazy reason, LaTeX is actually sensitive to the space between the "{ {" here and the "} }" below...
~~\pvs[\mask_1][\mask_2] \later\ownPhys{\state_1} * \later\All \expr_2, \state_2, \expr_\f. \pred(\expr_2, \state_2, \expr_\f) \land {}\\\qquad\qquad\qquad\qquad\qquad \ownPhys{\state_2} \wand \pvs[\mask_2][\mask_1] \wpre{\expr_2}[\mask_1]{\Ret\var.\prop} * \wpre{\expr_\f}[\top]{\Ret\any.\TRUE} {}\\\proves \wpre{\expr_1}[\mask_1]{\Ret\var.\prop}
~~\pvs[\mask_1][\mask_2] \Exists \state_1. \red(\expr_1,\state_1) \land \later\ownPhys{\state_1} * \later\All \expr_2, \state_2, \expr_\f. (\expr_1, \state_1 \step \expr_2, \state_2, \expr_\f) \land {}\\\qquad\qquad\qquad\qquad\qquad \ownPhys{\state_2} \wand \pvs[\mask_2][\mask_1] \wpre{\expr_2}[\mask_1]{\Ret\var.\prop} * \wpre{\expr_\f}[\top]{\Ret\any.\TRUE} {}\\\proves \wpre{\expr_1}[\mask_1]{\Ret\var.\prop}
\end{inbox}} }
\infer[wp-lift-pure-step]
{\toval(\expr_1) = \bot \and
\All \state_1. \red(\expr_1, \state_1) \and
\All \state_1, \expr_2, \state_2, \expr_\f. \expr_1,\state_1 \step \expr_2,\state_2,\expr_\f \Ra \state_1 = \state_2 \land \pred(\expr_2,\expr_\f)}
{\later\All \expr_2, \expr_\f. \pred(\expr_2, \expr_\f) \Ra \wpre{\expr_2}[\mask_1]{\Ret\var.\prop} * \wpre{\expr_\f}[\top]{\Ret\any.\TRUE} \proves \wpre{\expr_1}[\mask_1]{\Ret\var.\prop}}
\All \state_1, \expr_2, \state_2, \expr_\f. \expr_1,\state_1 \step \expr_2,\state_2,\expr_\f \Ra \state_1 = \state_2 }
{\later\All \state, \expr_2, \expr_\f. (\expr_1,\state \step \expr_2, \state,\expr_\f) \Ra \wpre{\expr_2}[\mask_1]{\Ret\var.\prop} * \wpre{\expr_\f}[\top]{\Ret\any.\TRUE} \proves \wpre{\expr_1}[\mask_1]{\Ret\var.\prop}}
\end{mathpar}
Here we define $\wpre{\expr_\f}[\mask]{\Ret\var.\prop} \eqdef \TRUE$ if $\expr_\f = \bot$ (remember that our stepping relation can, but does not have to, define a forked-off expression).
......
......@@ -52,9 +52,11 @@ For every definition, we have to show all the side-conditions: The maps have to
The first complicated task in building a model of full Iris is defining the semantic model of $\Prop$.
We start by defining the functor that assembles the CMRAs we need to the global resource CMRA:
\begin{align*}
\textdom{ResF}(\cofe^\op, \cofe) \eqdef{}& \record{\wld: \mathbb{N} \fpfn \agm(\latert \cofe), \pres: \exm(\textdom{State}), \ghostRes: \iFunc(\cofe^\op, \cofe)}
\textdom{ResF}(\cofe^\op, \cofe) \eqdef{}& \record{\wld: \mathbb{N} \fpfn \agm(\latert \cofe), \pres: \maybe{\exm(\textdom{State})}, \ghostRes: \iFunc(\cofe^\op, \cofe)}
\end{align*}
Remember that $\iFunc$ is the user-chosen bifunctor from $\COFEs$ to $\CMRAs$.
Above, $\maybe\monoid$ is the monoid obtained by adding a unit to $\monoid$.
(It's not a coincidence that we used the same notation for the range of the core; it's the same type either way: $\monoid + 1$.)
Remember that $\iFunc$ is the user-chosen bifunctor from $\COFEs$ to $\CMRAs$ (see~\Sref{sec:logic}).
$\textdom{ResF}(\cofe^\op, \cofe)$ is a CMRA by lifting the individual CMRAs pointwise.
Furthermore, if $F$ is locally contractive, then so is $\textdom{ResF}$.
......
......@@ -179,6 +179,7 @@ Definition atomic (e : expr) :=
| Store e1 e2 => bool_decide (is_Some (to_val e1) is_Some (to_val e2))
| CAS e0 e1 e2 =>
bool_decide (is_Some (to_val e0) is_Some (to_val e1) is_Some (to_val e2))
| Fork _ => true
(* Make "skip" atomic *)
| App (Rec _ _ (Lit _)) (Lit _) => true
| _ => false
......
......@@ -315,9 +315,22 @@ Proof.
apply coPset_finite_spec; destruct X as [[t ?]]; apply of_Pset_raw_finite.
Qed.
(** * Conversion from gsets of positives *)
(** * Conversion to and from gsets of positives *)
Lemma to_gset_wf (m : Pmap ()) : gmap_wf (K:=positive) m.
Proof. done. Qed.
Definition to_gset (X : coPset) : gset positive :=
let 'Mapset m := to_Pset X in
Mapset (GMap m (bool_decide_pack _ (to_gset_wf m))).
Definition of_gset (X : gset positive) : coPset :=
let 'Mapset (GMap (PMap t Ht) _) := X in of_Pset_raw t of_Pset_wf _ Ht.
Lemma elem_of_to_gset X i : set_finite X i to_gset X i X.
Proof.
intros ?. rewrite <-elem_of_to_Pset by done.
unfold to_gset. by destruct (to_Pset X).
Qed.
Lemma elem_of_of_gset X i : i of_gset X i X.
Proof. destruct X as [[[t ?]]]; apply elem_of_of_Pset_raw. Qed.
Lemma of_gset_finite X : set_finite (of_gset X).
......
From iris.prelude Require Import tactics.
Local Set Universe Polymorphism.
(* Not using [list Type] in order to avoid universe inconsistencies *)
Inductive tlist := tnil : tlist | tcons : Type tlist tlist.
......
......@@ -28,7 +28,6 @@ Class inG (Λ : language) (Σ : gFunctors) (A : cmraT) := InG {
inG_prf : A = projT2 Σ inG_id (iPreProp Λ (globalF Σ))
}.
Arguments inG_id {_ _ _} _.
Hint Mode inG - - + : typeclass_instances.
Definition to_globalF `{i : inG Λ Σ A} (γ : gname) (a : A) : iGst Λ (globalF Σ) :=
iprod_singleton (inG_id i) {[ γ := cmra_transport inG_prf a ]}.
......
......@@ -43,7 +43,7 @@ Lemma inv_open E N P :
|={E,E'}=> P ( P ={E',E}= True).
Proof.
rewrite inv_eq /inv. iDestruct 1 as (i) "[% #Hi]".
iExists (E {[ i ]}). iSplit. { iPureIntro. set_solver. }
iExists (E {[ i ]}). iSplit; first (iPureIntro; set_solver).
iPvs (pvs_openI' with "Hi") as "HP"; [set_solver..|].
iPvsIntro. iSplitL "HP"; first done. iIntros "HP".
iPvs (pvs_closeI' _ _ P with "[HP]"); [set_solver|iSplit; done|set_solver|].
......
This diff is collapsed.
This diff is collapsed.
From iris.algebra Require Export upred.
From iris.algebra Require Import upred_big_op upred_tactics gmap.
From iris.algebra Require Import upred_big_op upred_tactics.
From iris.proofmode Require Export environments classes.
From iris.prelude Require Import stringmap hlist.
Import uPred.
......@@ -551,25 +551,13 @@ Proof.
by rewrite right_id {1}(persistentP P) always_and_sep_l wand_elim_r.
Qed.
(** Whenever posing [lem : True ⊢ Q] as [H] we want it to appear as [H : Q] and
not as [H : True -★ Q]. The class [IntoPosedProof] is used to strip off the
[True]. Note that [to_posed_proof_True] is declared using a [Hint Extern] to
make sure it is not used while posing [lem : ?P ⊢ Q] with [?P] an evar. *)
Class IntoPosedProof (P1 P2 R : uPred M) :=
into_pose_proof : (P1 P2) True R.
Arguments into_pose_proof : clear implicits.
Instance to_posed_proof_True P : IntoPosedProof True P P.
Proof. by rewrite /IntoPosedProof. Qed.
Global Instance to_posed_proof_wand P Q : IntoPosedProof P Q (P - Q).
Proof. rewrite /IntoPosedProof. apply entails_wand. Qed.
Lemma tac_pose_proof Δ Δ' j P1 P2 R Q :
(P1 P2) IntoPosedProof P1 P2 R
envs_app true (Esnoc Enil j R) Δ = Some Δ'
Lemma tac_pose_proof Δ Δ' j P Q :
(True P)
envs_app true (Esnoc Enil j P) Δ = Some Δ'
(Δ' Q) Δ Q.
Proof.
intros HP ?? <-. rewrite envs_app_sound //; simpl.
by rewrite right_id -(into_pose_proof P1 P2 R) // always_pure wand_True.
intros HP ? <-. rewrite envs_app_sound //; simpl.
by rewrite right_id -HP always_pure wand_True.
Qed.
Lemma tac_pose_proof_hyp Δ Δ' Δ'' i p j P Q :
......@@ -747,6 +735,3 @@ Proof.
rewrite envs_simple_replace_sound' //; simpl. by rewrite right_id wand_elim_r.
Qed.
End tactics.
Hint Extern 0 (IntoPosedProof True _ _) =>
class_apply @to_posed_proof_True : typeclass_instances.
......@@ -112,45 +112,45 @@ Tactic Notation "iPvsCore" constr(H) :=
|env_cbv; reflexivity|simpl]
end.
Tactic Notation "iPvs" open_constr(H) :=
iDestructHelp H as (fun H => iPvsCore H; last iDestruct H as "?").
Tactic Notation "iPvs" open_constr(H) "as" constr(pat) :=
iDestructHelp H as (fun H => iPvsCore H; last iDestruct H as pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1) ")"
Tactic Notation "iPvs" open_constr(lem) :=
iDestructCore lem as (fun H => iPvsCore H; last iDestruct H as "?").
Tactic Notation "iPvs" open_constr(lem) "as" constr(pat) :=
iDestructCore lem as (fun H => iPvsCore H; last iDestruct H as pat).
Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1) ")"
constr(pat) :=
iDestructHelp H as (fun H => iPvsCore H; last iDestruct H as ( x1 ) pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1)
iDestructCore lem as (fun H => iPvsCore H; last iDestruct H as ( x1 ) pat).
Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) ")" constr(pat) :=
iDestructHelp H as (fun H => iPvsCore H; last iDestruct H as ( x1 x2 ) pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1)
iDestructCore lem as (fun H => iPvsCore H; last iDestruct H as ( x1 x2 ) pat).
Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) ")" constr(pat) :=
iDestructHelp H as (fun H => iPvsCore H; last iDestruct H as ( x1 x2 x3 ) pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1)
iDestructCore lem as (fun H => iPvsCore H; last iDestruct H as ( x1 x2 x3 ) pat).
Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4) ")"
constr(pat) :=
iDestructHelp H as (fun H =>
iDestructCore lem as (fun H =>
iPvsCore H; last iDestruct H as ( x1 x2 x3 x4 ) pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1)
Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4)
simple_intropattern(x5) ")" constr(pat) :=
iDestructHelp H as (fun H =>
iDestructCore lem as (fun H =>
iPvsCore H; last iDestruct H as ( x1 x2 x3 x4 x5 ) pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1)
Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4)
simple_intropattern(x5) simple_intropattern(x6) ")" constr(pat) :=
iDestructHelp H as (fun H =>
iDestructCore lem as (fun H =>
iPvsCore H; last iDestruct H as ( x1 x2 x3 x4 x5 x6 ) pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1)
Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4)
simple_intropattern(x5) simple_intropattern(x6) simple_intropattern(x7) ")"
constr(pat) :=
iDestructHelp H as (fun H =>
iDestructCore lem as (fun H =>
iPvsCore H; last iDestruct H as ( x1 x2 x3 x4 x5 x6 x7 ) pat).
Tactic Notation "iPvs" open_constr(H) "as" "(" simple_intropattern(x1)
Tactic Notation "iPvs" open_constr(lem) "as" "(" simple_intropattern(x1)
simple_intropattern(x2) simple_intropattern(x3) simple_intropattern(x4)
simple_intropattern(x5) simple_intropattern(x6) simple_intropattern(x7)
simple_intropattern(x8) ")" constr(pat) :=
iDestructHelp H as (fun H =>
iDestructCore lem as (fun H =>
iPvsCore H; last iDestruct H as ( x1 x2 x3 x4 x5 x6 x7 x8 ) pat).
Hint Extern 2 (of_envs _ _) =>
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment