Commit 02a11183 authored by Jacques-Henri Jourdan's avatar Jacques-Henri Jourdan

Merge branch 'master' into gen_proofmode

parents 1a1aa388 09741a03
......@@ -3,19 +3,43 @@ way the logic is used on paper. We also mention some significant changes in the
Coq development, but not every API-breaking change is listed. Changes marked
`[#]` still need to be ported to the Iris Documentation LaTeX file(s).
## Iris 3.1.0 (unfinished)
## Iris 3.1.0 (released 2017-12-19)
Changes in and extensions of the theory:
* Add new modality: ■ ("plainly").
* Define `uPred` as a quotient on monotone predicates `M -> SProp`.
* Get rid of some primitive laws; they can be derived:
`True ⊢ □ True` and `□ (P ∧ Q) ⊢ □ (P ∗ Q)`
* Camera morphisms have to be homomorphisms, not just monotone functions.
* Add a proof that `f` has a fixed point if `f^k` is contractive.
* Constructions for least and greatest fixed points over monotone predicates
(defined in the logic of Iris using impredicative quantification).
* Add a proof of the inverse of `wp_bind`.
* [Experimental feature] Add new modality: ■ ("plainly").
* [Experimental feature] Support verifying code that might get stuck by
distinguishing "non-stuck" vs. "(potentially) stuck" weakest
preconditions. (See [Swasey et al., OOPSLA '17] for examples.) The non-stuck
`WP e @ E {{ Φ }}` ensures that, as `e` runs, it does not get stuck. The stuck
`WP e @ E ?{{ Φ }}` ensures that, as usual, all invariants are preserved while
`e` runs, but it permits execution to get stuck. The former implies the
latter. The full judgment is `WP e @ s; E {{ Φ }}`, where non-stuck WP uses
*stuckness bit* `s = NotStuck` while stuck WP uses `s = MaybeStuck`.
Changes in Coq:
* Move the `prelude` folder to its own project:
[coq-std++](https://gitlab.mpi-sws.org/robbertkrebbers/coq-stdpp)
* Some extensions/improvements of heap_lang:
- Improve handling of pure (non-state-dependent) reductions.
- Add fetch-and-add (`FAA`) operation.
- Add syntax for all Coq's binary operations on `Z`.
* Generalize `saved_prop` to let the user choose the location of the type-level
later. Rename the general form to `saved_anything`. Provide `saved_prop` and
`saved_pred` as special cases.
* Improved big operators:
+ They are no longer tied to cameras, but work on any monoid
+ The version of big operations over lists was redefined so that it enjoys
more definitional equalities.
* Rename some things and change notation:
- The unit of a camera: `empty` -> `unit`, `∅` -> `ε`
- Disjointness: `⊥` -> `##`
......@@ -26,6 +50,7 @@ Changes in Coq:
- Camera elements such that `core x = x`: `Persistent` -> `CoreId`
- Persistent propositions: `PersistentP` -> `Persistent`
- The persistent modality: `always` -> `persistently`
- Adequacy for non-stuck weakestpre: `adequate_safe` -> `adequate_not_stuck`
- Consistently SnakeCase identifiers:
+ `CMRAMixin` -> `CmraMixin`
+ `CMRAT` -> `CmraT`
......@@ -53,6 +78,8 @@ Changes in Coq:
```
sed 's/\bPersistentP\b/Persistent/g; s/\bTimelessP\b/Timeless/g; s/\bCMRADiscrete\b/CmraDiscrete/g; s/\bCMRAT\b/CmraT/g; s/\bCMRAMixin\b/CmraMixin/g; s/\bUCMRAT\b/UcmraT/g; s/\bUCMRAMixin\b/UcmraMixin/g; s/\bSTS\b/Sts/g' -i $(find -name "*.v")
```
* `PersistentL` and `TimelessL` (persistence and timelessness of lists of
propositions) are replaces by `TCForall` from std++.
* Fix a bunch of consistency issues in the proof mode, and make it overall more
usable. In particular:
- All proof mode tactics start the proof mode if necessary; `iStartProof` is
......@@ -74,9 +101,6 @@ sed 's/\bPersistentP\b/Persistent/g; s/\bTimelessP\b/Timeless/g; s/\bCMRADiscret
behind a type class opaque definition. Furthermore, this can change the
name of anonymous identifiers introduced with the "%" pattern.
* Make `ofe_fun` dependently typed, subsuming `iprod`. The latter got removed.
* Generalize `saved_prop` to let the user choose the location of the type-level
later. Rename the general form to `saved_anything`. Provide `saved_prop` and
`saved_pred` as special cases.
* Define the generic `fill` operation of the `ectxi_language` construct in terms
of a left fold instead of a right fold. This gives rise to more definitional
equalities.
......@@ -85,18 +109,16 @@ sed 's/\bPersistentP\b/Persistent/g; s/\bTimelessP\b/Timeless/g; s/\bCMRADiscret
type classes and canonical structures. Also, it now uses explicit mixins. The
file `program_logic/ectxi_language` contains some documentation on how to
setup Iris for your language.
* Improved big operators:
+ They are no longer tied to cameras, but work on any monoid
+ The version of big operations over lists was redefined so that it enjoys
more definitional equalities.
* Restore the original, stronger notion of atomicity alongside the weaker
notion. These are `Atomic a e` where the stuckness bit `s` indicates whether
expression `e` is weakly (`a = WeaklyAtomic`) or strongly
(`a = StronglyAtomic`) atomic.
* Various improvements to `solve_ndisj`.
* Improve handling of pure (non-state-dependent) reductions in heap_lang.
* Use `Hint Mode` to prevent Coq from making arbitrary guesses in the presence
of evars, which often led to divergence. There are a few places where type
annotations are now needed.
* Move the `prelude` folder to its own project: std++
* The rules `internal_eq_rewrite` and `internal_eq_rewrite_contractive` are now
stated in the logic, i.e. they are `iApply` friendly.
stated in the logic, i.e., they are `iApply`-friendly.
## Iris 3.0.0 (released 2017-01-11)
......
# CONTRIBUTING TO THE IRIS COQ DEVELOPMENT
# Contributing to the Iris Coq Development
Discussion about the Iris Coq development happens on the mailing list
[iris-club@lists.mpi-sws.org](https://lists.mpi-sws.org/listinfo/iris-club).
This is also the right place to ask questions.
If you want to report a bug, please use the
[issue tracker](https://gitlab.mpi-sws.org/FP/iris-coq/issues). You will have
to create an account at the
[iris-club@lists.mpi-sws.org](https://lists.mpi-sws.org/listinfo/iris-club) and
in the [Iris Chat](https://mattermost.mpi-sws.org/iris). This is also the right
place to ask questions. The chat requires an account at the
[MPI-SWS GitLab](https://gitlab.mpi-sws.org/users/sign_in) (use the "Register"
tab).
To contribute code, please send your MPI-SWS GitLab username to
[Ralf Jung](https://gitlab.mpi-sws.org/jung) to enable personal projects for
your account. Then you can fork the
If you want to report a bug, please use the
[issue tracker](https://gitlab.mpi-sws.org/FP/iris-coq/issues), which also
requires an MPI-SWS GitLab account. To contribute code, please send your
MPI-SWS GitLab username to [Ralf Jung](https://gitlab.mpi-sws.org/jung) to
enable personal projects for your account. Then you can fork the
[Iris git repository](https://gitlab.mpi-sws.org/FP/iris-coq/), make your
changes in your fork, and create a merge request.
......@@ -6,34 +6,45 @@ This is the Coq development of the [Iris Project](http://iris-project.org).
This version is known to compile with:
- Coq 8.6.1 / 8.7.0
- Coq 8.6.1 / 8.7.0 / 8.7.1
- Ssreflect 1.6.4
- A development version of [std++](https://gitlab.mpi-sws.org/robbertkrebbers/coq-stdpp)
- [std++](https://gitlab.mpi-sws.org/robbertkrebbers/coq-stdpp) 1.1.0
If you need to work with Coq 8.5, please check out the
[iris-3.0 branch](https://gitlab.mpi-sws.org/FP/iris-coq/tree/iris-3.0).
The easiest way to install the correct versions of the dependencies is through
opam. You will need the Coq and Iris opam repositories:
## Installing via opam
To obtain the latest stable release via opam (1.2.2 or newer), you have to add
the Coq opam repository:
opam repo add coq-released https://coq.inria.fr/opam/released
Then you can do `opam install coq-iris`.
To obtain a development version, add the Iris opam repository:
opam repo add iris-dev https://gitlab.mpi-sws.org/FP/opam-dev.git
Once you got opam set up, run `make build-dep` to install the right versions
of the dependencies.
## Building from source
## Updating
When building Iris from source, we recommend to use opam (1.2.2 or newer) for
installing Iris's dependencies. This requires the following two repositories:
After doing `git pull`, the development may fail to compile because of outdated
dependencies. To fix that, please run `opam update` followed by
`make build-dep`.
opam repo add coq-released https://coq.inria.fr/opam/released
opam repo add iris-dev https://gitlab.mpi-sws.org/FP/opam-dev.git
## Building Instructions
Once you got opam set up, run `make build-dep` to install the right versions
of the dependencies.
Run `make -jN` to build the full development, where `N` is the number of your
CPU cores.
## Structure
To update Iris, do `git pull`. After an update, the development may fail to
compile because of outdated dependencies. To fix that, please run `opam update`
followed by `make build-dep`.
## Directory Structure
* The folder [algebra](theories/algebra) contains the COFE and CMRA
constructions as well as the solver for recursive domain equations.
......@@ -66,13 +77,26 @@ CPU cores.
A LaTeX version of the core logic definitions and some derived forms is
available in [docs/iris.tex](docs/iris.tex). A compiled PDF version of this
document is [available online](http://plv.mpi-sws.org/iris/appendix-3.0.pdf).
document is [available online](http://plv.mpi-sws.org/iris/appendix-3.1.pdf).
## Case Studies
The following is a (probably incomplete) list of case studies that use Iris, and
that should be compatible with this version:
* [Iris Examples](https://gitlab.mpi-sws.org/FP/iris-examples) is where we
collect miscellaneous case studies that do not have their own repository.
* [LambdaRust](https://gitlab.mpi-sws.org/FP/LambdaRust-coq/) is a Coq
formalization of the core Rust type system.
* [Iris Atomic](https://gitlab.mpi-sws.org/FP/iris-atomic/) is an experimental
formalization of logically atomic triples in Iris.
## For Developers: How to update the std++ dependency
* Do the change in std++, push it.
* Wait for CI to publish a new std++ version on the opam archive.
* In Iris, change opam to depend on the new version.
* Wait for CI to publish a new std++ version on the opam archive, then run
`opam update iris-dev`.
* In Iris, change the `opam` file to depend on the new version.
* Run `make build-dep` (in Iris) to install the new version of std++.
* You may have to do `make clean` as Coq will likely complain about .vo file
You may have to do `make clean` as Coq will likely complain about .vo file
mismatches.
This diff is collapsed.
\section{Base Logic}
\label{sec:base-logic}
The base logic is parameterized by an arbitrary CMRA $\monoid$ having a unit $\munit$.
By \lemref{lem:cmra-unit-total-core}, this means that the core of $\monoid$ is a total function, so we will treat it as such in the following.
The base logic is parameterized by an arbitrary camera $\monoid$ having a unit $\munit$.
By \lemref{lem:camera-unit-total-core}, this means that the core of $\monoid$ is a total function, so we will treat it as such in the following.
This defines the structure of resources that can be owned.
As usual for higher-order logics, you can furthermore pick a \emph{signature} $\Sig = (\SigType, \SigFn, \SigAx)$ to add more types, symbols and axioms to the language.
......@@ -193,7 +193,7 @@ In writing $\vctx, x:\type$, we presuppose that $x$ is not already declared in $
\infer{\vctx \proves \wtt{\melt}{\textlog{M}}}
{\vctx \proves \wtt{\ownM{\melt}}{\Prop}}
\and
\infer{\vctx \proves \wtt{\melt}{\type} \and \text{$\type$ is a CMRA}}
\infer{\vctx \proves \wtt{\melt}{\type} \and \text{$\type$ is a camera}}
{\vctx \proves \wtt{\mval(\melt)}{\Prop}}
\and
\infer{\vctx \proves \wtt{\prop}{\Prop}}
......@@ -212,13 +212,13 @@ In writing $\vctx, x:\type$, we presuppose that $x$ is not already declared in $
}
\end{mathparpagebreakable}
\subsection{Proof rules}
\subsection{Proof Rules}
\label{sec:proof-rules}
The judgment $\vctx \mid \prop \proves \propB$ says that with free variables $\vctx$, proposition $\propB$ holds whenever assumption $\prop$ holds.
Most of the rules will entirely omit the variable contexts $\vctx$.
In this case, we assume the same arbitrary context is used for every constituent of the rules.
%Furthermore, an arbitrary \emph{boxed} assertion context $\always\pfctx$ may be added to every constituent.
%Furthermore, an arbitrary \emph{boxed} proposition context $\always\pfctx$ may be added to every constituent.
Axioms $\vctx \mid \prop \provesIff \propB$ indicate that both $\vctx \mid \prop \proves \propB$ and $\vctx \mid \propB \proves \prop$ are proof rules of the logic.
\judgment{\vctx \mid \prop \proves \propB}
......@@ -448,7 +448,7 @@ Furthermore, we have the usual $\eta$ and $\beta$ laws for projections, $\textlo
{\upd\plainly\prop \proves \prop}
\end{mathpar}
The premise in \ruleref{upd-update} is a \emph{meta-level} side-condition that has to be proven about $a$ and $B$.
%\ralf{Trouble is, we don't actually have $\in$ inside the logic...}
%\ralf{Trouble is, we do not actually have $\in$ inside the logic...}
\subsection{Consistency}
......
......@@ -3829,3 +3829,10 @@ year = {2013}
pages = {256--269},
year = {2016},
}
@Article{iris-ground-up,
author={Ralf Jung and Robbert Krebbers and Jacques-Henri Jourdan and Ale\v{s} Bizjak and Lars Birkedal and Derek Dreyer},
title={Iris from the Ground Up},
journal={Submitted to JFP},
year = {2017},
}
This diff is collapsed.
\section{Derived constructions}
\section{Derived Constructions}
\subsection{Non-atomic (``thread-local'') invariants}
\subsection{Cancellable Invariants}
Iris invariants as described in \Sref{sec:invariants} are persistent---once established, they hold forever.
However, based on them, it is possible to \emph{encode} a form of invariants that can be ``cancelled'' again.
First, we need some ghost state:
\begin{align*}
\textmon{CInvTok} \eqdef{}& \fracm
\end{align*}
Now we define:
\begin{align*}
\CInvTok{\gname}{q} \eqdef{}& \ownGhost\gname{q} \\
\CInv{\gname}{\namesp}{\prop} \eqdef{}& \knowInv\namesp{\prop \lor \ownGhost\gname{1}}
\end{align*}
It is then straightforward to prove:
\begin{mathpar}
\inferH{CInv-new}{}
{\later\prop \vs[\bot] \Exists \gname. \CInvTok\gname{1} * \always\CInv\gname\namesp\prop}
\inferH{CInv-acc}{}
{\CInv\gname\namesp\prop \proves \Acc[\namesp][\emptyset]{\CInvTok\gname{q}}{\later\prop}}
\inferH{CInv-cancel}{}
{\CInv\gname\namesp\prop \proves \CInvTok\gname{1} \vs[\namesp] \later\prop}
\end{mathpar}
Cancellable invariants are useful, for example, when reasoning about data structures that will be deallocated: Every reference to the data structure comes with a fraction of the token, and when all fractions have been gathered, \ruleref{CInv-cancel} is used to cancel the invariant, after which the data structure can be deallocated.
\subsection{Non-atomic (``Thread-Local'') Invariants}
Sometimes it is necessary to maintain invariants that we need to open non-atomically.
Clearly, for this mechanism to be sound we need something that prevents us from opening the same invariant twice, something like the masks that avoid reentrancy on the ``normal'', atomic invariants.
......@@ -40,16 +70,16 @@ To simplify this construction,we piggy-back into ``normal'' invariants.
We easily obtain:
\begin{mathpar}
\axiom
\axiomH{NAInv-new-pool}
{\TRUE \vs[\bot] \Exists\pid. \NaTok\pid}
\axiom
\axiomH{NAInv-tok-split}
{\NaTokE\pid{\mask_1 \uplus \mask_2} \Lra \NaTokE\pid{\mask_1} * \NaTokE\pid{\mask_2}}
\axiom
\axiomH{NAInv-new-inv}
{\later\prop \vs[\namesp] \always\NaInv\pid\namesp\prop}
\axiom
\axiomH{NAInv-acc}
{\NaInv\pid\namesp\prop \proves \Acc[\namesp]{\NaTokE\pid\namesp}{\later\prop}}
\end{mathpar}
from which we can derive
......@@ -61,18 +91,18 @@ from which we can derive
\subsection{Boxes}
The idea behind the \emph{boxes} is to have an assertion $\prop$ that is actually split into a number of pieces, each of which can be taken out and back in separately.
In some sense, this is a replacement for having an ``authoritative PCM of Iris assertions itself''.
The idea behind the \emph{boxes} is to have an proposition $\prop$ that is actually split into a number of pieces, each of which can be taken out and back in separately.
In some sense, this is a replacement for having an ``authoritative PCM of Iris propositions itself''.
It is similar to the pattern involving saved propositions that was used for the barrier~\cite{iris2}, but more complicated because there are some operations that we want to perform without a later.
Roughly, the idea is that a \emph{box} is a container for an assertion $\prop$.
A box consists of a bunch of \emph{slices} which decompose $\prop$ into a separating conjunction of the assertions $\propB_\sname$ governed by the individual slices.
Roughly, the idea is that a \emph{box} is a container for an proposition $\prop$.
A box consists of a bunch of \emph{slices} which decompose $\prop$ into a separating conjunction of the propositions $\propB_\sname$ governed by the individual slices.
Each slice is either \emph{full} (it right now contains $\propB_\sname$), or \emph{empty} (it does not contain anything currently).
The assertion governing the box keeps track of the state of all the slices that make up the box.
The proposition governing the box keeps track of the state of all the slices that make up the box.
The crux is that opening and closing of a slice can be done even if we only have ownership of the boxes ``later'' ($\later$).
The interface for boxes is as follows:
The two core assertions are: $\BoxSlice\namesp\prop\sname$, saying that there is a slice in namespace $\namesp$ with name $\sname$ and content $\prop$; and $\ABox\namesp\prop{f}$, saying that $f$ describes the slices of a box in namespace $\namesp$, such that all the slices together contain $\prop$. Here, $f$ is of type $\nat \fpfn \BoxState$ mapping names to states, where $\BoxState \eqdef \set{\BoxFull, \BoxEmp}$.
The two core propositions are: $\BoxSlice\namesp\prop\sname$, saying that there is a slice in namespace $\namesp$ with name $\sname$ and content $\prop$; and $\ABox\namesp\prop{f}$, saying that $f$ describes the slices of a box in namespace $\namesp$, such that all the slices together contain $\prop$. Here, $f$ is of type $\nat \fpfn \BoxState$ mapping names to states, where $\BoxState \eqdef \set{\BoxFull, \BoxEmp}$.
\begin{mathpar}
\inferH{Box-create}{}
{\TRUE \vs[\namesp] \ABox\namesp\TRUE\emptyset}
......@@ -109,13 +139,13 @@ This is essentially an \emph{optional later}, indicating that the lemmas can be
\newcommand\SliceInv{\textlog{SliceInv}}
The above rules are validated by the following model.
We need a CMRA as follows:
We need a camera as follows:
\begin{align*}
\BoxState \eqdef{}& \BoxFull + \BoxEmp \\
\BoxM \eqdef{}& \authm(\maybe{\exm(\BoxState)}) \times \maybe{\agm(\latert \iProp)}
\end{align*}
Now we can define the assertions:
Now we can define the propositions:
\begin{align*}
\SliceInv(\sname, \prop) \eqdef{}& \Exists b. \ownGhost\sname{(\authfull b, \munit)} * ((b = \BoxFull) \Ra \prop) \\
\BoxSlice\namesp\prop\sname \eqdef{}& \ownGhost\sname{(\munit, \prop)} * \knowInv\namesp{\SliceInv(\sname,\prop)} \\
......
......@@ -3,7 +3,7 @@
In this section we discuss some additional constructions that we define within and on top of the base logic.
These are not ``extensions'' in the sense that they change the proof power of the logic, they just form useful derived principles.
\subsection{Derived rules about base connectives}
\subsection{Derived Rules about Base Connectives}
We collect here some important and frequently used derived proof rules.
\begin{mathparpagebreakable}
\infer{}
......@@ -42,9 +42,9 @@ We collect here some important and frequently used derived proof rules.
Noteworthy here is the fact that $\prop \proves \later\prop$ can be derived from Löb induction, and $\TRUE \proves \plainly\TRUE$ can be derived via $\plainly$ commuting with universal quantification ranging over the empty type $0$.
\subsection{Persistent assertions}
We call an assertion $\prop$ \emph{persistent} if $\prop \proves \always\prop$.
These are assertions that ``don't own anything'', so we can (and will) treat them like ``normal'' intuitionistic assertions.
\subsection{Persistent Propositions}
We call a proposition $\prop$ \emph{persistent} if $\prop \proves \always\prop$.
These are propositions that ``do not own anything'', so we can (and will) treat them like ``normal'' intuitionistic propositions.
Of course, $\always\prop$ is persistent for any $\prop$.
Furthermore, by the proof rules given in \Sref{sec:proof-rules}, $\TRUE$, $\FALSE$, $t = t'$ as well as $\ownGhost\gname{\mcore\melt}$ and $\mval(\melt)$ are persistent.
......@@ -52,15 +52,15 @@ Persistence is preserved by conjunction, disjunction, separating conjunction as
\subsection{Timeless assertions and except-0}
\subsection{Timeless Propositions and Except-0}
One of the troubles of working in a step-indexed logic is the ``later'' modality $\later$.
It turns out that we can somewhat mitigate this trouble by working below the following \emph{except-0} modality:
\[ \diamond \prop \eqdef \later\FALSE \lor \prop \]
This modality is useful because there is a class of assertions which we call \emph{timeless} assertions, for which we have
This modality is useful because there is a class of propositions which we call \emph{timeless} propositions, for which we have
\[ \timeless{\prop} \eqdef \later\prop \proves \diamond\prop \]
In other words, when working below the except-0 modality, we can \emph{strip away} the later from timeless assertions.
In other words, when working below the except-0 modality, we can \emph{strip away} the later from timeless propositions.
The following rules can be derived about except-0:
\begin{mathpar}
......@@ -88,7 +88,7 @@ The following rules can be derived about except-0:
\end{array}
\end{mathpar}
The following rules identify the class of timeless assertions:
The following rules identify the class of timeless propositions:
\begin{mathparpagebreakable}
\infer
{\vctx \proves \timeless{\prop} \and \vctx \proves \timeless{\propB}}
......@@ -135,11 +135,109 @@ The following rules identify the class of timeless assertions:
{\timeless{\ownM\melt}}
\infer
{\text{$\melt$ is an element of a discrete CMRA}}
{\text{$\melt$ is an element of a discrete camera}}
{\timeless{\mval(\melt)}}
\end{mathparpagebreakable}
\subsection{Dynamic Composeable Higher-Order Resources}
\label{sec:composeable-resources}
The base logic described in \Sref{sec:base-logic} works over an arbitrary camera $\monoid$ defining the structure of the resources.
It turns out that we can generalize this further and permit picking cameras ``$\iFunc(\Prop)$'' that depend on the structure of propositions themselves.
Of course, $\Prop$ is just the syntactic type of propositions; for this to make sense we have to look at the semantics.
Furthermore, there is a composability problem with the given logic: if we have one proof performed with camera $\monoid_1$, and another proof carried out with a \emph{different} camera $\monoid_2$, then the two proofs are actually carried out in two \emph{entirely separate logics} and hence cannot be combined.
Finally, in many cases just having a single ``instance'' of a camera available for reasoning is not enough.
For example, when reasoning about a dynamically allocated data structure, every time a new instance of that data structure is created, we will want a fresh resource governing the state of this particular instance.
While it would be possible to handle this problem whenever it comes up, it turns out to be useful to provide a general solution.
The purpose of this section is to describe how we solve these issues.
\paragraph{Picking the resources.}
The key ingredient that we will employ on top of the base logic is to give some more fixed structure to the resources.
To instantiate the logic with dynamic higher-order ghost state, the user picks a family of locally contractive bifunctors $(\iFunc_i : \OFEs^\op \times \OFEs \to \CMRAs)_{i \in \mathcal{I}}$.
(This is in contrast to the base logic, where the user picks a single, fixed camera that has a unit.)
From this, we construct the bifunctor defining the overall resources as follows:
\begin{align*}
\GName \eqdef{}& \nat \\
\textdom{ResF}(\ofe^\op, \ofe) \eqdef{}& \prod_{i \in \mathcal I} \GName \fpfn \iFunc_i(\ofe^\op, \ofe)
\end{align*}
We will motivate both the use of a product and the finite partial function below.
$\textdom{ResF}(\ofe^\op, \ofe)$ is a camera by lifting the individual cameras pointwise, and it has a unit (using the empty finite partial function).
Furthermore, since the $\iFunc_i$ are locally contractive, so is $\textdom{ResF}$.
Now we can write down the recursive domain equation:
\[ \iPreProp \cong \UPred(\textdom{ResF}(\iPreProp, \iPreProp)) \]
Here, $\iPreProp$ is a COFE defined as the fixed-point of a locally contractive bifunctor, which exists and is unique up to isomorphism by \thmref{thm:america_rutten}, so we obtain some object $\iPreProp$ such that:
\begin{align*}
\Res &\eqdef \textdom{ResF}(\iPreProp, \iPreProp) \\
\iProp &\eqdef \UPred(\Res) \\
\wIso &: \iProp \nfn \iPreProp \\
\wIso^{-1} &: \iPreProp \nfn \iProp \\
\wIso(\wIso^{-1}(x)) &\eqdef x \\
\wIso^{-1}(\wIso(x)) &\eqdef x
\end{align*}
Now we can instantiate the base logic described in \Sref{sec:base-logic} with $\Res$ as the chosen camera:
\[ \Sem{\Prop} \eqdef \UPred(\Res) \]
We obtain that $\Sem{\Prop} = \iProp$.
Effectively, we just defined a way to instantiate the base logic with $\Res$ as the camera of resources, while providing a way for $\Res$ to depend on $\iPreProp$, which is isomorphic to $\Sem\Prop$.
We thus obtain all the rules of \Sref{sec:base-logic}, and furthermore, we can use the maps $\wIso$ and $\wIso^{-1}$ \emph{in the logic} to convert between logical propositions $\Sem\Prop$ and the domain $\iPreProp$ which is used in the construction of $\Res$ -- so from elements of $\iPreProp$, we can construct elements of $\Sem{\textlog M}$, which are the elements that can be owned in our logic.
\paragraph{Proof composability.}
To make our proofs composeable, we \emph{generalize} our proofs over the family of functors.
This is possible because we made $\Res$ a \emph{product} of all the cameras picked by the user, and because we can actually work with that product ``pointwise''.
So instead of picking a \emph{concrete} family, proofs will assume to be given an \emph{arbitrary} family of functors, plus a proof that this family \emph{contains the functors they need}.
Composing two proofs is then merely a matter of conjoining the assumptions they make about the functors.
Since the logic is entirely parametric in the choice of functors, there is no trouble reasoning without full knowledge of the family of functors.
Only when the top-level proof is completed we will ``close'' the proof by picking a concrete family that contains exactly those functors the proof needs.
\paragraph{Dynamic resources.}
Finally, the use of finite partial functions lets us have as many instances of any camera as we could wish for:
Because there can only ever be finitely many instances already allocated, it is always possible to create a fresh instance with any desired (valid) starting state.
This is best demonstrated by giving some proof rules.
So let us first define the notion of ghost ownership that we use in this logic.
Assuming that the family of functors contains the functor $\Sigma_i$ at index $i$, and furthermore assuming that $\monoid_i = \Sigma_i(\iPreProp, \iPreProp)$, given some $\melt \in \monoid_i$ we define:
\[ \ownGhost\gname{\melt:\monoid_i} \eqdef \ownM{(\ldots, \emptyset, i:\mapsingleton \gname \melt, \emptyset, \ldots)} \]
This is ownership of the pair (element of the product over all the functors) that has the empty finite partial function in all components \emph{except for} the component corresponding to index $i$, where we own the element $\melt$ at index $\gname$ in the finite partial function.
We can show the following properties for this form of ownership:
\begin{mathparpagebreakable}
\inferH{res-alloc}{\text{$G$ infinite} \and \melt \in \mval_{M_i}}
{ \TRUE \proves \upd \Exists\gname\in G. \ownGhost\gname{\melt : M_i}
}
\and
\inferH{res-update}
{\melt \mupd_{M_i} B}
{\ownGhost\gname{\melt : M_i} \proves \upd \Exists \meltB\in B. \ownGhost\gname{\meltB : M_i}}
\inferH{res-empty}
{\text{$\munit$ is a unit of $M_i$}}
{\TRUE \proves \upd \ownGhost\gname\munit}
\axiomH{res-op}
{\ownGhost\gname{\melt : M_i} * \ownGhost\gname{\meltB : M_i} \provesIff \ownGhost\gname{\melt\mtimes\meltB : M_i}}
\axiomH{res-valid}
{\ownGhost\gname{\melt : M_i} \Ra \mval_{M_i}(\melt)}
\inferH{res-timeless}
{\text{$\melt$ is a discrete OFE element}}
{\timeless{\ownGhost\gname{\melt : M_i}}}
\end{mathparpagebreakable}
Below, we will always work within (an instance of) the logic as described here.
Whenever a camera is used in a proof, we implicitly assume it to be available in the global family of functors.
We will typically leave the $M_i$ implicit when asserting ghost ownership, as the type of $\melt$ will be clear from the context.
%%% Local Variables:
%%% mode: latex
......
......@@ -36,7 +36,7 @@
\newcommand{\upclose}{\mathord{\uparrow}}
\newcommand{\ALT}{\ |\ }
\newcommand{\spac}{\,} % a space
\newcommand{\spac}{\hskip 0.2em plus 0.1em} % a space
\def\All #1.{\forall #1.\spac}%
\def\Exists #1.{\exists #1.\spac}%
......@@ -95,6 +95,9 @@
\newcommand{\nil}{\epsilon}
% displaced dot
\newcommand{\dispdot}[2][.2ex]{\dot{\raisebox{0pt}[\dimexpr\height+#1][\depth]{$#2$}}}% \dispdot[<displace>]{<stuff>}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% MODEL-SPECIFIC SYMBOLS & NOTATION & IDENTIFIERS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
......@@ -117,6 +120,7 @@
\newcommand{\wtt}[2]{#1 : #2} % well-typed term
\newcommand{\nequiv}[1]{\ensuremath{\mathrel{\stackrel{#1}{=}}}}
\newcommand{\nincl}[1]{\ensuremath{\mathrel{\stackrel{#1}{\subseteq}}}}
\newcommand{\notnequiv}[1]{\ensuremath{\mathrel{\stackrel{#1}{\neq}}}}
\newcommand{\nequivset}[2]{\ensuremath{\mathrel{\stackrel{#1}{=}_{#2}}}}
\newcommand{\nequivB}[1]{\ensuremath{\mathrel{\stackrel{#1}{\equiv}}}}
......@@ -151,8 +155,8 @@
\newcommand{\ofeB}{U}
\newcommand{\cofe}{\ofe}
\newcommand{\cofeB}{\ofeB}
\newcommand{\OFEs}{\mathcal{OFE}} % category of OFEs
\newcommand{\COFEs}{\mathcal{COFE}} % category of COFEs
\newcommand{\OFEs}{\mathbf{OFE}} % category of OFEs
\newcommand{\COFEs}{\mathbf{COFE}} % category of COFEs
\newcommand{\iFunc}{\Sigma}
\newcommand{\fix}{\textdom{fix}}
......@@ -191,7 +195,7 @@
$\preccurlyeq$\cr
}}}}}
\newcommand{\CMRAs}{\mathcal{CMRA}} % category of CMRAs
\newcommand{\CMRAs}{\mathbf{Camera}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% LOGIC SYMBOLS & NOTATION & IDENTIFIERS
......@@ -216,6 +220,7 @@
\newcommand{\term}{t}
\newcommand{\termB}{u}
\newcommand{\venv}{\rho}
\newcommand{\vctx}{\Gamma}
\newcommand{\pfctx}{\Theta}
......@@ -241,8 +246,8 @@
\newcommand{\fixp}{\mathit{fix}}
%% various pieces of Syntax
\def\MU #1.{\mu\spac #1.\spac}%
\def\Lam #1.{\lambda #1.\spac}%
\def\MU #1.{\mu\,#1.\spac}%
\def\Lam #1.{\lambda\,#1.\spac}%
\newcommand{\proves}{\vdash}
\newcommand{\provesIff}{\mathrel{\dashv\vdash}}
......@@ -254,8 +259,14 @@
\newcommand{\gmapsto}{\hookrightarrow}%
\newcommand{\fgmapsto}[1][\mathrm{-}]{\xhookrightarrow{#1}}%
\NewDocumentCommand\wpre{m O{} m}%
{\textlog{wp}_{#2}\spac#1\spac{\left\{#3\right\}}}
\NewDocumentCommand\wpre{O{} m O{} m}%
{\textlog{wp}^{#1}_{#3}\spac#2\spac{\left\{#4\right\}}}
\newcommand{\stateinterp}{S}
\newcommand\stuckness{s}
\newcommand\NotStuck{\textlog{NotStuck}}
\newcommand\MaybeStuck{\textlog{Stuck}}
\newcommand{\later}{\mathop{{\triangleright}}}
\newcommand*{\lateropt}[1]{\mathop{{\later}^{#1}}}
......@@ -290,7 +301,7 @@
}%
}}%
\NewDocumentCommand \vs {O{} O{}} {\vsGen[#1]{\Rrightarrow}[#2]}
\NewDocumentCommand \bvs {O{} O{}} {\vsGen[#1]{\Rrightarrow_{\mathcal{B}}}[#2]}
\NewDocumentCommand \bvs {O{} O{}} {\vsGen[#1]{\dispdot[0.02ex]{\Rrightarrow}}[#2]}
\NewDocumentCommand \vsL {O{} O{}} {\vsGen[#1]{\Lleftarrow}[#2]}
\NewDocumentCommand \vsE {O{} O{}} %
{\vsGen[#1]{\Lleftarrow\!\!\!\Rrightarrow}[#2]}
......@@ -300,7 +311,7 @@
\NewDocumentCommand \vsW {O{} O{}} {\vsGen[#1]{\vsWand}[#2]}
% for now, the update modality looks like a pvs without masks.
\NewDocumentCommand \upd {} {\mathop{\mid\kern-0.4ex\Rrightarrow\kern-0.25ex}}
\NewDocumentCommand \upd {} {\mathop{\dispdot[-0.2ex]{\mid\kern-0.4ex\Rrightarrow\kern-0.25ex}}}
\NewDocumentCommand\Acc{O{} O{} m m}{\langle #3 \vsE #4 \rangle_{#1}^{#2}}
......@@ -352,7 +363,6 @@
\newcommand{\inhabited}[1]{\textlog{inhabited}(#1)}
\newcommand{\timeless}[1]{\textlog{timeless}(#1)}
\newcommand{\persistent}[1]{\textlog{persistent}(#1)}
\newcommand{\physatomic}[1]{\textlog{atomic}($#1$)}
\newcommand{\infinite}{\textlog{infinite}}
\newcommand\InvName{\textdom{InvName}}
......@@ -380,6 +390,7 @@
\newcommand{\toval}{\mathrm{expr\any to\any val}}
\newcommand{\ofval}{\mathrm{val\any to\any expr}}
\newcommand{\atomic}{\mathrm{atomic}}
\newcommand{\stronglyAtomic}{\mathrm{strongly\any atomic}}
\newcommand{\red}{\mathrm{red}}
\newcommand{\Lang}{\Lambda}
......@@ -402,6 +413,7 @@
% Fraction
\newcommand{\fracm}{\ensuremath{\textmon{Frac}}}
\newcommand{\fracinj}{\textlog{frac}}
% Exclusive
\newcommand{\exm}{\ensuremath{\textmon{Ex}}}
......@@ -445,6 +457,10 @@
%% Stored Propositions
\newcommand{\mapstoprop}{\mathrel{\kern-0.5ex\tikz[baseline=(m)]{\node at (0,0) (m){}; \draw[line cap=round] (0,0.16) -- (0,-0.004);}\kern-1.5ex\Ra}}
%% Cancellable invariants
\newcommand\CInv[3]{\textlog{CInv}^{#1,#2}(#3)}
\newcommand*\CInvTok[2]{{[}\textrm{CInv}:#1{]}_{#2}}
%% Non-atomic invariants
\newcommand*\pid{p}
\newcommand\NaInv[3]{\textlog{NaInv}^{#1.#2}(#3)}
......
......@@ -32,28 +32,49 @@ The latest versions of this document and the Coq formalization can be found in t
For further information, visit the Iris project website at \url{http://plv.mpi-sws.org/iris/}.
\end{abstract}
\clearpage
\clearpage\begingroup
\tableofcontents
\endgroup
\clearpage\begingroup
\section{Iris from the Ground Up}
In \citetitle{iris-ground-up}~\cite{iris-ground-up}, we describe Iris~3.1 in a bottom-up way.
That paper is hence much more suited as an introduction to the model of Iris than this reference, which mostly contains definitions, not explanations or examples.
The following differences between Iris as described in \citetitle{iris-ground-up} and the latest version documented here are worth mentioning:
\begin{itemize}
\item As an experimental feature, we added the \emph{plainly modality} $\plainly$.
\item As an experimental feature, weakest preconditions take a \emph{stuckness} $\stuckness$ as parameter, indicating whether the program may get stuck or not.
\end{itemize}
\endgroup
\clearpage\begingroup
\input{algebra}
\endgroup\clearpage\begingroup
\endgroup
\clearpage\begingroup
\input{constructions}
\endgroup\clearpage\begingroup
\endgroup
\clearpage\begingroup
\input{base-logic}
\endgroup\clearpage\begingroup
\endgroup
\clearpage\begingroup
\input{model}
\endgroup\clearpage\begingroup
\endgroup
\clearpage\begingroup
\input{ghost-state}
\endgroup\clearpage\begingroup
\endgroup
\clearpage\begingroup
\input{language}
\endgroup\clearpage\begingroup
\endgroup
\clearpage\begingroup
\input{program-logic}
\endgroup\clearpage\begingroup
\endgroup
\clearpage\begingroup
\input{derived}
\endgroup\clearpage\begingroup
\endgroup
\clearpage\begingroup
\input{paradoxes}
\endgroup\clearpage\begingroup
\endgroup
\clearpage\begingroup
\printbibliography
\endgroup
......
......@@ -21,9 +21,14 @@ A \emph{language} $\Lang$ consists of a set \Expr{} of \emph{expressions} (metav
\end{defn}