Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • iris/iris
  • jeehoon.kang/iris-coq
  • amintimany/iris-coq
  • dfrumin/iris-coq
  • Villetaneuse/iris
  • gares/iris
  • shiatsumat/iris
  • Blaisorblade/iris
  • jihgfee/iris-coq
  • mrhaandi/iris
  • tlsomers/iris
  • Quarkbeast/iris-coq
  • janno/iris
  • amaurremi/iris-coq
  • proux/iris
  • tchajed/iris
  • herbelin/iris-coq
  • msammler/iris-coq
  • maximedenes/iris-coq
  • bpeters/iris
  • haidang/iris
  • lepigre/iris
  • lczch/iris
  • simonspies/iris
  • gpirlea/iris
  • dkhalanskiyjb/iris
  • gmalecha/iris
  • germanD/iris
  • aa755/iris
  • jules/iris
  • abeln/iris
  • simonfv/iris
  • atrieu/iris
  • arthuraa/iris
  • simonh/iris
  • jung/iris
  • mattam82/iris
  • Armael/iris
  • adamAndMath/iris
  • gmevel/iris
  • snyke7/iris
  • johannes/iris
  • NiklasM/iris
  • simonspies/iris-parametric-index
  • svancollem/iris
  • proux1/iris
  • wmansky/iris
  • LukeXuan/iris
  • ivanbakel/iris
  • SkySkimmer/iris
  • tjhance/iris
  • yiyunliu/iris
  • Lee-Janggun/iris
  • thomas-lamiaux/iris
  • dongjae/iris
  • dnezam/iris
  • Tragicus/iris
  • clef-men/iris
  • ffengyu/iris
59 results
Show changes
Commits on Source (5684)
*.v gitlab-language=coq
# Convert to native line endings on checkout.
*.ref text
# Shell scripts need Linux line endings.
*.sh eol=lf
*.vo *.vo
*.vos
*.vok
*.vio *.vio
*.v.d *.v.d
.coqdeps.d
*.glob *.glob
*.cache *.cache
*.aux *.aux
...@@ -8,6 +11,17 @@ ...@@ -8,6 +11,17 @@
.\#* .\#*
*~ *~
*.bak *.bak
.coqdeps.d
.coq-native/ .coq-native/
Makefile.coq
*.crashcoqide *.crashcoqide
.env
builddep/
_CoqProject.*
Makefile.coq
Makefile.coq.conf
.Makefile.coq.d
Makefile.package.*
.Makefile.package.*
_opam
_build
*.install
image: coq:8.5 image: ralfjung/opam-ci:opam2
buildjob: stages:
- build
variables:
CPU_CORES: "10"
OCAML: "ocaml-variants.4.14.0+options ocaml-option-flambda"
# Avoid needlessly increasing our TCB with native_compute
COQEXTRAFLAGS: "-native-compiler no"
.only_branches: &only_branches
only:
- /^master/@iris/iris
- /^ci/@iris/iris
.only_mr: &only_mr
only:
- merge_requests
.branches_and_mr: &branches_and_mr
only:
- /^master/@iris/iris
- /^ci/@iris/iris
- merge_requests
.template: &template
<<: *only_branches
stage: build
interruptible: true
tags: tags:
- coq - fp
script: script:
- coqc -v - git clone https://gitlab.mpi-sws.org/iris/ci.git ci -b opam2
- 'time make -j8 TIMED=y 2>&1 | tee build-log.txt' - ci/buildjob
- 'fgrep Axiom build-log.txt && exit 1' cache:
- 'cat build-log.txt | egrep "[a-zA-Z0-9_/-]+ \(user: [0-9]" | tee build-time.txt' key: "$CI_JOB_NAME"
- make validate
only:
- master
- timing
artifacts:
paths: paths:
- build-time.txt - _opam/
except:
- triggers
- schedules
- api
## Build jobs
# The newest version runs with timing.
build-coq.8.20.1:
<<: *template
variables:
OPAM_PINS: "coq version 8.20.1"
DENY_WARNINGS: "1"
MANGLE_NAMES: "1"
OPAM_PKG: "1"
DOC_DIR: "coqdoc@center.mpi-sws.org:iris"
DOC_OPTS: "--external https://plv.mpi-sws.org/coqdoc/stdpp/ stdpp"
tags:
- fp-timing
interruptible: false
# The newest version also runs in MRs, without timing.
build-coq.8.20.1-mr:
<<: *template
<<: *only_mr
variables:
OPAM_PINS: "coq version 8.20.1"
DENY_WARNINGS: "1"
MANGLE_NAMES: "1"
# Also ensure Dune works.
build-coq.8.20.1-dune:
<<: *template
<<: *branches_and_mr
variables:
OPAM_PINS: "coq version 8.20.1 dune version 3.15.2"
MAKE_TARGET: "dune"
# The oldest version runs in MRs, without name mangling.
build-coq.8.19.2:
<<: *template
<<: *branches_and_mr
variables:
OPAM_PINS: "coq version 8.19.2"
trigger-stdpp.dev:
<<: *template
variables:
STDPP_REPO: "iris/stdpp"
OPAM_PINS: "coq version $NIGHTLY_COQ git+https://gitlab.mpi-sws.org/$STDPP_REPO#$STDPP_REV"
CI_COQCHK: "1"
except:
only:
- triggers
- schedules
- api
<!--
When reporting a bug, please always include the version of Iris you are using.
If you are using opam, you can determine your Iris version by running
opam show coq-iris -f version
-->
This diff is collapsed.
# Contributing to the Iris Coq Development
Here you can find some how-tos for various thing sthat might come up when doing
Iris development. This is for contributing to Iris itself; see
[the README](README.md#further-resources) for resources helpful for all Iris
users.
To work on Iris itself, you need to install its build-dependencies. Again we
recommend you do that with opam (2.0.0 or newer). This requires the following
two repositories:
opam repo add coq-released https://coq.inria.fr/opam/released
opam repo add iris-dev https://gitlab.mpi-sws.org/iris/opam.git
Once you got opam set up, run `make builddep` 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.
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 builddep`.
## How to submit a merge request
To contribute code, you need an MPI-SWS GitLab account as described on the
[chat page](https://iris-project.org/chat.html). Then you can fork the
[Iris git repository][iris], make your changes in your fork, and create a merge
request. If forking fails with an error, please send your MPI-SWS GitLab
username to [Ralf Jung][jung] to unlock forks for your account.
Please do *not* use the master branch of your fork, that might confuse CI. Use
a feature branch instead.
[jung]: https://gitlab.mpi-sws.org/jung
[iris]: https://gitlab.mpi-sws.org/iris/iris
We prefer small and self-contained merge requests that add a single feature
over merge requests that add arbitrary collections of lemmas. Small merge
requests are easier to review, and will typically be merged more quickly
(because it avoids blocking the whole merge request on a single
discussion).
Please follow the coding style laid out in our [style
guide](docs/style_guide.md).
## 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, then run
`opam update iris-dev`.
* In Iris, change the `opam` file to depend on the new version.
(In case you do not use opam yourself, you can see recently published versions
[in this repository](https://gitlab.mpi-sws.org/iris/opam/commits/master).)
* Run `make builddep` (in Iris) to install the new version of std++.
You may have to do `make clean` as Coq will likely complain about .vo file
mismatches.
## How to write/update test cases
The files in `tests/` are test cases. Each of the `.v` files comes with a
matching `.ref` file containing the expected output of `coqc`. Adding `Show.`
in selected places in the proofs makes `coqc` print the current goal state.
This is used to make sure the proof mode prints goals and reduces terms the way
we expect it to. You can run `make MAKE_REF=1` to re-generate all the `.ref` files;
this is useful after adding or removing `Show.` from a test. If you do this,
make sure to check the diff for any unexpected changes in the output!
Some test cases have per-Coq-version `.ref` files (e.g., `atomic.8.8.ref` is a
Coq-8.8-specific `.ref` file). If you change one of these, remember to update
*all* the `.ref` files.
If you want to compile without tests run `make NO_TEST=1`.
## How to build/install only one package
Iris is split into multiple packages that can be installed separately via opam.
You can invoke the Makefile of a particular package by doing `./make-package
$PACKAGE $MAKE_ARGS`, where `$MAKE_ARGS` are passed to `make` (so you can use
the usual `-jN`, `install`, ...). This should only rarely be necessary. For
example, if you are not using opam and you want to install only the `iris`
package (without HeapLang, to avoid waiting on that part of the build), you can
do `./make-package iris install`. (If you are using opam, you can achieve the
same by pinning `coq-iris` to your Iris checkout.)
Note that `./make-package` will never run the test suite, so please always do a
regular `make -jN` before submitting an MR.
## How to test effects on reverse dependencies
The `iris-bot` script makes it easy to test the effect of a branch on reverse
dependencies. It can start tests ensuring they all still build, and it can do
comparative timing runs.
If you have suitable permissions, you can trigger these builds yourself.
But first, you need to do some setup: you need to create a GitLab access token
and set the `GITLAB_TOKEN` environment variable to it. Go to
<https://gitlab.mpi-sws.org/-/profile/personal_access_tokens>, pick a suitable
name (such as "iris-bot"), select the "api" scope, and then click "Create
personal access token". Copy the value it shows and store it in some suitable
place; you will not be able to retrieve this value from GitLab in the future!
For example, you could create a `.env` file in your Iris clone containing:
```
export GITLAB_TOKEN=<your token here>
```
Then you can easily get the token back into the environment via `. .env`.
Once that setup is done, you can now use `iris-bot`. Set at least one of
`IRIS_REV` or `STDPP_REV` to control which branches of these projects to build
against (they default to the default git branch). `IRIS_REPO` and `STDPP_REPO`
can be used to control the repository in which the branch is situated. Setting
`IRIS` to "user:branch" will use the given branch on that user's fork of Iris,
and similar for `STDPP`.
Supported commands:
- `./iris-bot build [$filter]`: Builds all reverse dependencies against the
given branches. The optional `filter` argument only builds projects whose
names contains that string.
- `./iris-bot time $project`: Measure the impact of this branch on the build
time of the given reverse dependency. Only Iris branches are supported for
now.
Examples:
- `IRIS_REV=myname/mybranch ./iris-bot build` builds *all* reverse dependencies
against `myname/mybranch` from the main Iris repository.
- `IRIS=user:branch ./iris-bot build examples` builds the [examples] against
the `branch` in `user`'s fork of Iris.
- `IRIS_REV=myname/mybranch ./iris-bot time examples` measures the timing impact
of `myname/mybranch` from the main Iris repository on the [examples].
[examples]: https://gitlab.mpi-sws.org/iris/examples
The source code (i.e., everything except for files in the docs/ folder) in this The source code (i.e., everything except for files in the docs/ and tex/
development is licensed under the terms of the BSD license, while the folders) in this development is licensed under the terms of the BSD license,
documentation (i.e., everything inside the docs/ folder) is licensed under the while the documentation (i.e., everything inside the docs/ and tex/ folders) is
terms of the CC-BY 4.0 license. Fur further details, see LICENSE-CODE and licensed under the terms of the CC-BY 4.0 license. Fur further details, see
LICENSE-DOCS, respectively. LICENSE-CODE and LICENSE-DOCS, respectively.
All files in this development, excluding those in docs/, are distributed All files in this development, excluding those in docs/ and tex/, are
under the terms of the BSD license, included below. distributed under the terms of the 3-clause BSD license
(https://opensource.org/licenses/BSD-3-Clause), included below.
------------------------------------------------------------------------------ Copyright: Iris developers and contributors
BSD LICENCE ------------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
...@@ -12,17 +13,17 @@ modification, are permitted provided that the following conditions are met: ...@@ -12,17 +13,17 @@ modification, are permitted provided that the following conditions are met:
* Redistributions in binary form must reproduce the above copyright * Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the * Neither the name of the copyright holder nor the names of its contributors
names of its contributors may be used to endorse or promote products may be used to endorse or promote products derived from this software
derived from this software without specific prior written permission. without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
All files in the docs/ folder of this development are distributed All files in the docs/ and tex/ folders of this development are distributed
under the terms of the CC-BY 4.0 license <https://creativecommons.org/licenses/by/4.0/>. under the terms of the CC-BY 4.0 license <https://creativecommons.org/licenses/by/4.0/>.
For your convenience, a plain-text version of the license is included below. For your convenience, a plain-text version of the license is included below.
......
# Determine Coq version # Default target
COQ_VERSION=$(shell coqc --version | egrep -o 'version 8.[0-9]' | egrep -o '8.[0-9]') all: Makefile.coq
COQ_MAKEFILE_FLAGS ?= +@$(MAKE) -f Makefile.coq all
.PHONY: all
ifeq ($(COQ_VERSION), 8.6) # Build with dune.
COQ_MAKEFILE_FLAGS += -arg -w -arg -notation-overridden,-redundant-canonical-projection # This exists only for CI; you should just call `dune build` directly instead.
endif dune:
@dune build --display=short
.PHONY: dune
%: Makefile.coq phony # Permit local customization
+@make -f Makefile.coq $@ -include Makefile.local
all: Makefile.coq # Forward most targets to Coq makefile (with some trick to make this phony)
+@make -f Makefile.coq all %: Makefile.coq phony
@#echo "Forwarding $@"
+@$(MAKE) -f Makefile.coq $@
phony: ;
.PHONY: phony
clean: Makefile.coq clean: Makefile.coq
+@make -f Makefile.coq clean +@$(MAKE) -f Makefile.coq clean
find \( -name "*.v.d" -o -name "*.vo" -o -name "*.aux" -o -name "*.cache" -o -name "*.glob" -o -name "*.vio" \) -print -delete @# Make sure not to enter the `_opam` folder.
rm -f Makefile.coq find [a-z]*/ \( -name "*.d" -o -name "*.vo" -o -name "*.vo[sk]" -o -name "*.aux" -o -name "*.cache" -o -name "*.glob" -o -name "*.vio" \) -print -delete || true
rm -f Makefile.coq .lia.cache builddep/*
.PHONY: clean
# Create Coq Makefile.
Makefile.coq: _CoqProject Makefile Makefile.coq: _CoqProject Makefile
coq_makefile $(COQ_MAKEFILE_FLAGS) -f _CoqProject -o Makefile.coq.tmp "$(COQBIN)coq_makefile" -f _CoqProject -o Makefile.coq $(EXTRA_COQFILES)
sed 's/$$(COQCHK) $$(COQCHKFLAGS) $$(COQLIBS)/$$(COQCHK) $$(COQCHKFLAGS) $$(subst -Q,-R,$$(COQLIBS))/' < Makefile.coq.tmp \
| awk '/^install:$$/{print;print "\tif [ -d \"$$(DSTROOT)\"$$(COQLIBINSTALL)/iris/ ]; then find \"$$(DSTROOT)\"$$(COQLIBINSTALL)/iris/ -name \"*.vo\" -print -delete; fi";next}1' > Makefile.coq # Install build-dependencies
rm Makefile.coq.tmp OPAMFILES=$(wildcard *.opam)
BUILDDEPFILES=$(addsuffix -builddep.opam, $(addprefix builddep/,$(basename $(OPAMFILES))))
_CoqProject: ;
builddep/%-builddep.opam: %.opam Makefile
Makefile: ; @echo "# Creating builddep package for $<."
@mkdir -p builddep
phony: ; @sed <$< -E 's/^(build|install|remove):.*/\1: []/; s/"(.*)"(.*= *version.*)$$/"\1-builddep"\2/;' >$@
.PHONY: all clean phony builddep-opamfiles: $(BUILDDEPFILES)
.PHONY: builddep-opamfiles
builddep: builddep-opamfiles
@# We want opam to not just install the build-deps now, but to also keep satisfying these
@# constraints. Otherwise, `opam upgrade` may well update some packages to versions
@# that are incompatible with our build requirements.
@# To achieve this, we create a fake opam package that has our build-dependencies as
@# dependencies, but does not actually install anything itself.
@echo "# Installing builddep packages."
@opam install $(OPAMFLAGS) $(BUILDDEPFILES)
.PHONY: builddep
# Backwards compatibility target
build-dep: builddep
.PHONY: build-dep
# Some files that do *not* need to be forwarded to Makefile.coq.
# ("::" lets Makefile.local overwrite this.)
Makefile Makefile.local _CoqProject $(OPAMFILES):: ;
# use NO_TEST=1 to skip the tests
NO_TEST:=
# use MAKE_REF=1 to generate new reference files
MAKE_REF:=
# Only test reference output on known versions of Coq, to avoid blocking
# Coq CI when they change the printing a little.
# Need to make this a lazy variable (`=` instead of `:=`) since COQ_VERSION is only set later.
COQ_REF=$(shell echo "$(COQ_VERSION)" | grep -E "^8\.(20)\." -q && echo 1)
# Run tests interleaved with main build. They have to be in the same target for this.
real-all: style $(if $(NO_TEST),,test)
style: $(VFILES) coq-lint.sh
# Make sure everything imports the options, and some general linting.
$(SHOW)"COQLINT"
$(HIDE)for FILE in $(VFILES); do \
if ! grep -F -q 'From iris.prelude Require Import options.' "$$FILE"; then echo "ERROR: $$FILE does not import 'options'."; echo; exit 1; fi ; \
./coq-lint.sh "$$FILE" || exit 1; \
done
# Make sure main Iris does not import other Iris packages.
$(HIDE)if grep -E 'iris\.(heap_lang|deprecated|unstable)' --include "*.v" -R iris; then echo "ERROR: Iris may not import modules from other Iris packages (see above for violations)."; echo; exit 1; fi
.PHONY: style
# the test suite
TESTFILES:=$(shell find tests -name "*.v")
NORMALIZER:=test-normalizer.sed
test: $(TESTFILES:.v=.vo)
.PHONY: test
COQ_TEST=$(COQTOP) $(COQDEBUG) -batch -test-mode
tests/.coqdeps.d: $(TESTFILES)
$(SHOW)'COQDEP TESTFILES'
$(HIDE)$(COQDEP) -dyndep var $(COQMF_COQLIBS_NOML) $^ $(redir_if_ok)
-include tests/.coqdeps.d
# Main test script (comments out-of-line because macOS otherwise barfs?!?)
# - Determine reference file (`REF`).
# - Print user-visible status line.
# - unset env vars that change Coq's output
# - Dump Coq output into a temporary file.
# - Run `sed -i` on that file in a way that works on macOS.
# - Either compare the result with the reference file, or move it over the reference file.
# - Cleanup, and mark as done for make.
$(TESTFILES:.v=.vo): %.vo: %.v $(if $(MAKE_REF),,%.ref) $(NORMALIZER)
$(HIDE)REF=$*".ref" && \
echo "COQTEST$(if $(COQ_REF),$(if $(MAKE_REF), [make ref],), [ref ignored]) $< (ref: $$REF)" && \
TMPFILE="$$(mktemp)" && \
unset OCAMLRUNPARAM && \
$(TIMER) $(COQ_TEST) $(COQFLAGS) $(COQLIBS) -load-vernac-source $< > "$$TMPFILE" && \
sed -E -f $(NORMALIZER) "$$TMPFILE" > "$$TMPFILE".new && \
mv "$$TMPFILE".new "$$TMPFILE" && \
$(if $(COQ_REF),\
$(if $(MAKE_REF),mv "$$TMPFILE" "$$REF",diff --strip-trailing-cr -u "$$REF" "$$TMPFILE"), \
true \
) && \
rm -f "$$TMPFILE" && \
touch $@
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](proofmode/classes.v). Most notable, many
of the tactics can be applied when the to be introduced or to be eliminated
connective appears under a later, an update modality, or in the conclusion of a
weakest precondition.
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 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
------------------
- `iIntros (x1 ... xn) "ipat1 ... ipatn"` : introduce universal quantifiers
using Coq introduction patterns `x1 ... xn` and implications/wands using proof
mode introduction patterns `ipat1 ... ipatn`.
- `iClear (x1 ... xn) "selpat"` : clear the hypotheses given by the selection
pattern `selpat` and the Coq level hypotheses/variables `x1 ... xn`.
- `iRevert (x1 ... xn) "selpat"` : revert the hypotheses given by the selection
pattern `selpat` into wands, and the Coq level hypotheses/variables
`x1 ... xn` into universal quantifiers. Persistent hypotheses are wrapped into
the always modality.
- `iRename "H1" into "H2"` : rename the hypothesis `H1` into `H2`.
- `iSpecialize pm_trm` : instantiate universal quantifiers and eliminate
implications/wands of a hypothesis `pm_trm`. See proof mode terms below.
- `iSpecialize pm_trm as #` : instantiate universal quantifiers and eliminate
implications/wands of a hypothesis whose conclusion is persistent. In this
case, all hypotheses can be used for proving the premises, as well as for
the resulting goal.
- `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`. The
introduction pattern `ipat` specifies how to eliminate `P`.
- `iAssert P with "spat" as %cpat` : assert `P` and eliminate it using the Coq
introduction pattern `cpat`.
Introduction of logical connectives
-----------------------------------
- `iPureIntro` : turn a pure goal into a Coq goal. This tactic works for goals
of the shape `■ φ`, `a ≡ b` on discrete COFEs, and `✓ a` on discrete CMRAs.
- `iLeft` : left introduction of disjunction.
- `iRight` : right introduction of disjunction.
- `iSplit` : introduction of a conjunction, or separating conjunction provided
one of the operands is persistent.
- `iSplitL "H1 ... Hn"` : introduction of a separating conjunction. The
hypotheses `H1 ... Hn` are used for the left conjunct, and the remaining ones
for the right conjunct. Persistent hypotheses are ignored, since these do not
need to be split.
- `iSplitR "H0 ... Hn"` : symmetric version of the above.
- `iExist t1, .., tn` : introduction of an existential quantifier.
Elimination of logical connectives
----------------------------------
- `iExFalso` : Ex falso sequitur quod libet.
- `iDestruct pm_trm as (x1 ... xn) "ipat"` : elimination of existential
quantifiers using Coq introduction patterns `x1 ... xn` and elimination of
object level connectives using the proof mode introduction pattern `ipat`.
In case all branches of `ipat` start with an `#` (moving the hypothesis to the
persistent context) or `%` (moving the hypothesis to the pure Coq context),
one can use all hypotheses for proving the premises of `pm_trm`, as well as
for proving the resulting goal.
- `iDestruct pm_trm as %cpat` : elimination of a pure hypothesis using the Coq
introduction pattern `cpat`. When using this tactic, all hypotheses can be
used for proving the premises of `pm_trm`, as well as for proving the
resulting goal.
Separating logic specific tactics
---------------------------------
- `iFrame (t1 .. tn) "selpat"` : cancel the Coq terms (or Coq hypotheses)
`t1 ... tn` and Iris hypotheses given by `selpat` in the goal. The constructs
of the selection pattern have the following meaning:
+ `%` : repeatedly frame hypotheses from the Coq context.
+ `#` : repeatedly frame hypotheses from the persistent context.
+ `★` : frame as much of the spatial context as possible.
Notice that framing spatial hypotheses makes them disappear, but framing Coq
or persistent hypotheses does not make them disappear.
This tactic finishes the goal in case everything in the conclusion has been
framed.
- `iCombine "H1" "H2" as "H"` : turns `H1 : P1` and `H2 : P2` into
`H : P1 ★ P2`.
Modalities
----------
- `iModIntro` : introduction of a modality that is an instance of the
`IntoModal` type class. Instances include: later, except 0, basic update and
fancy update.
- `iMod pm_trm as (x1 ... xn) "ipat"` : eliminate a modality `pm_trm` that is
an instance of the `ElimModal` type class. Instances include: later, except 0,
basic update and fancy update.
The later modality
------------------
- `iNext n` : introduce `n` laters by stripping that number of laters from all
hypotheses. If the argument `n` is not given, it strips one later if the
leftmost conjuct is of the shape `▷ P`, or `n` laters if the leftmost conjuct
is of the shape `▷^n P`.
- `iLöb as "IH" forall (x1 ... xn)` : perform Löb induction by generating a
hypothesis `IH : ▷ goal`. The tactic generalizes over the Coq level variables
`x1 ... xn`, the hypotheses given by the selection pattern `selpat`, and the
spatial context.
Induction
---------
- `iInduction x as cpat "IH" forall (x1 ... xn) "selpat"` : perform induction on
the Coq term `x`. The Coq introduction pattern is used to name the introduced
variables. The induction hypotheses are inserted into the persistent context
and given fresh names prefixed `IH`. The tactic generalizes over the Coq level
variables `x1 ... xn`, the hypotheses given by the selection pattern `selpat`,
and the spatial context.
Rewriting
---------
- `iRewrite pm_trm` : rewrite an equality in the conclusion.
- `iRewrite pm_trm in "H"` : rewrite an equality in the hypothesis `H`.
Iris
----
- `iInv N as (x1 ... xn) "ipat" "Hclose"` : open the invariant `N`, the update
for closing the invariant is put in a hypothesis named `Hclose`.
Miscellaneous
-------------
- The tactic `done` is extended so that it also performs `iAssumption` and
introduces pure connectives.
- The proof mode adds hints to the core `eauto` database so that `eauto`
automatically introduces: conjunctions and disjunctions, universal and
existential quantifiers, implications and wand, always, later and update
modalities, and pure connectives.
Selection patterns
==================
Selection patterns are used to select hypotheses in the tactics `iRevert`,
`iClear`, `iFrame`, `iLöb` and `iInduction`. The proof mode supports the
following _selection patterns_:
- `H` : select the hypothesis named `H`.
- `%` : select the entire pure/Coq context.
- `#` : select the entire persistent context.
- `★` : select the entire spatial context.
Introduction patterns
=====================
Introduction patterns are used to perform introductions and eliminations of
multiple connectives on the fly. The proof mode supports the following
_introduction patterns_:
- `H` : create a hypothesis named `H`.
- `?` : create an anonymous hypothesis.
- `_` : remove the hypothesis.
- `$` : frame the hypothesis in the goal.
- `[ipat ipat]` : (separating) conjunction elimination.
- `[ipat|ipat]` : disjunction elimination.
- `[]` : false elimination.
- `%` : move the hypothesis to the pure Coq context (anonymously).
- `# ipat` : move the hypothesis to the persistent context.
- `> ipat` : eliminate a modality (if the goal permits).
Apart from this, there are the following introduction patterns that can only
appear at the top level:
- `{H1 ... Hn}` : clear `H1 ... Hn`.
- `{$H1 ... $Hn}` : frame `H1 ... Hn` (this pattern can be mixed with the
previous pattern, e.g., `{$H1 H2 $H3}`).
- `!%` : introduce a pure goal (and leave the proof mode).
- `!#` : introduce an always modality (given that the spatial context is empty).
- `!>` : introduce a modality.
- `/=` : perform `simpl`.
- `*` : introduce all universal quantifiers.
- `**` : introduce all universal quantifiers, as well as all arrows and wands.
For example, given:
∀ x, x = 0 ⊢ □ (P → False ∨ □ (Q ∧ ▷ R) -★ P ★ ▷ (R ★ Q ∧ x = pred 2)).
You can write
iIntros (x) "% !# $ [[] | #[HQ HR]] /= !>".
which results in:
x : nat
H : x = 0
______________________________________(1/1)
"HQ" : Q
"HR" : R
--------------------------------------□
R ★ Q ∧ x = 1
Specialization patterns
=======================
Since we are reasoning in a spatial logic, when eliminating a lemma or
hypothesis of type ``P_0 -★ ... -★ P_n -★ R``, one has to specify how the
hypotheses are split between the premises. The proof mode supports the following
_specification patterns_ to express splitting of hypotheses:
- `H` : use the hypothesis `H` (it should match the premise exactly). If `H` is
spatial, it will be consumed.
- `[H1 ... Hn]` : generate a goal with the (spatial) hypotheses `H1 ... Hn` and
all persistent hypotheses. The spatial hypotheses among `H1 ... Hn` will be
consumed. Hypotheses may be prefixed with a `$`, which results in them being
framed in the generated goal.
- `[-H1 ... Hn]` : negated form of the above pattern.
- `>[H1 ... Hn]` : same as the above pattern, but can only be used if the goal
is a modality, in which case the modality will be kept in the generated goal
for the premise will be wrapped into the modality.
- `[#]` : This pattern can be used when eliminating `P -★ Q` with `P`
persistent. Using this pattern, all hypotheses are available in the goal for
`P`, as well the remaining goal.
- `[%]` : This pattern can be used when eliminating `P -★ Q` when `P` is pure.
It will generate a Coq goal for `P` and does not consume any hypotheses.
- `*` : instantiate all top-level universal quantifiers with meta variables.
For example, given:
H : □ P -★ P 2 -★ x = 0 -★ Q1 ∗ Q2
You can write:
iDestruct ("H" with "[#] [H1 H2] [%]") as "[H4 H5]".
Proof mode terms
================
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 of these tactics, called _proof mode terms_, is:
(H $! t1 ... tn with "spat1 .. spatn")
Here, `H` can be both a hypothesis, as well as a Coq lemma whose conclusion is
of the shape `P ⊢ Q`. In the above, `t1 ... tn` are arbitrary Coq terms used
for instantiation of universal quantifiers, and `spat1 .. spatn` are
specialization patterns to eliminate implications and wands.
Proof mode terms can be written down using the following short hands too:
(H with "spat1 .. spatn")
(H $! t1 ... tn)
H
# IRIS COQ DEVELOPMENT # Iris Coq Development [[coqdoc]](https://plv.mpi-sws.org/coqdoc/iris/)
This is the Coq development of the [Iris Project](http://iris-project.org). This is the Coq development of the [Iris Project](http://iris-project.org),
which includes [MoSeL](http://iris-project.org/mosel/), a general proof mode
for carrying out separation logic proofs in Coq.
## Prerequisites For using the Coq library, check out the
[API documentation](https://plv.mpi-sws.org/coqdoc/iris/).
For understanding the theory of Iris, a LaTeX version of the core logic
definitions and some derived forms is available in
[tex/iris.tex](tex/iris.tex). A compiled PDF version of this document is
[available online](http://plv.mpi-sws.org/iris/appendix-3.4.pdf).
## Side-effects
Importing Iris has some side effects as the library sets some global options.
* First of all, Iris imports std++, so the
[std++ side-effects](https://gitlab.mpi-sws.org/iris/stdpp/#side-effects)
apply.
* On top of that, Iris imports ssreflect, which replaces the default `rewrite`
tactic with the ssreflect version. However, `done` is overwritten to keep
using the std++ version of the tactic. We also set `SsrOldRewriteGoalsOrder`
and re-open `general_if_scope` to un-do some effects of ssreflect.
## Building Iris
### Prerequisites
This version is known to compile with: This version is known to compile with:
- Coq 8.5pl2 - Coq 8.19.2 / 8.20.1
- [Ssreflect 1.6](https://github.com/math-comp/math-comp/releases/tag/mathcomp-1.6) - A development version of [std++](https://gitlab.mpi-sws.org/iris/stdpp)
For development, better make sure you have a version of Ssreflect that includes Generally we always aim to support the last two stable Coq releases. Support for
commit ad273277 (no such version has been released so far, you will have to older versions will be dropped when it is convenient.
fetch the development branch yourself). Iris compiles fine even without this
patch, but proof bullets will only be in 'strict' (enforcing) mode with the If you need to work with older versions of Coq, you can check out the
fixed version of Ssreflect. If you are using opam, you can easily get a fixed [tags](https://gitlab.mpi-sws.org/iris/iris/-/tags) for old Iris releases that
version by running still support them.
opam pin add coq-mathcomp-ssreflect https://github.com/math-comp/math-comp.git#ad273277ab38bfe458e9332dea5f3a79e3885567 ### Working *with* Iris
## Building Instructions To use Iris in your own proofs, we recommend you install Iris via opam (2.0.0 or
newer). To obtain the latest stable release, you have to add the Coq opam
Run the following command to build the full development: repository:
make opam repo add coq-released https://coq.inria.fr/opam/released
The development can then be installed as the Coq user contribution `iris` by To obtain a development version, also add the Iris opam repository:
running:
opam repo add iris-dev https://gitlab.mpi-sws.org/iris/opam.git
make install
Either way, you can now install Iris:
## Structure - `opam install coq-iris` will install the libraries making up the Iris logic,
but leave it up to you to instantiate the `program_logic.language` interface
* The folder [prelude](prelude) contains an extended "Standard Library" by to define a programming language for Iris to reason about.
[Robbert Krebbers](http://robbertkrebbers.nl/thesis.html). - `opam install coq-iris-heap-lang` will additionally install HeapLang, the
* The folder [algebra](algebra) contains the COFE and CMRA constructions as well default language used by various Iris projects.
as the solver for recursive domain equations.
* The folder [base_logic](base_logic) defines the Iris base logic and the To fetch updates later, run `opam update && opam upgrade`.
primitive connectives. It also contains derived constructions that are
entirely independent of the choice of resources. #### Be notified of breaking changes
* The subfolder [lib](base_logic/lib) contains some generally useful
derived constructions. Most importantly, it defines composeable We do not guarantee backwards-compatibility, so upgrading Iris may break your
dynamic resources and ownership of them; the other constructions depend Iris-using developments. If you want to be notified of breaking changes, please
on this setup. let us know your account name on the
* The folder [program_logic](program_logic) specializes the base logic to build [MPI-SWS GitLab](https://gitlab.mpi-sws.org/) so we can add you to the
Iris, the program logic. This includes weakest preconditions that are notification group. Note that this excludes the "unstable" and "deprecated"
defined for any language satisfying some generic axioms, and some derived packages (see below).
constructions that work for any such language.
* The folder [proofmode](proofmode) contains the Iris proof mode, which extends #### Use of Iris in submitted artifacts
Coq with contexts for persistent and spatial Iris assertions. It also contains
tactics for interactive proofs in Iris. Documentation can be found in If you are using Iris as part of an artifact submitted for publication with a
[ProofMode.md](ProofMode.md). paper, we recommend you make the artifact self-contained so that it can be built
* The folder [heap_lang](heap_lang) defines the ML-like concurrent heap language in the future without relying in any other server to still exist. However, if
* The subfolder [lib](heap_lang/lib) contains a few derived constructions that is for some reason not possible, and if you are using opam to obtain the
within this language, e.g., parallel composition. right version of Iris and you used a `dev.*` version, please let us know which
Most notable here is [lib/barrier](heap_lang/lib/barrier), the implementation exact Iris version you artifact relies on so that we can
and proof of a barrier as described in <http://doi.acm.org/10.1145/2818638>. [add it to this wiki page](https://gitlab.mpi-sws.org/iris/iris/-/wikis/Pinned-Iris-package-versions)
* The folder [tests](tests) contains modules we use to test our infrastructure. and avoid removing it from our opam repository in the future.
Users of the Iris Coq library should *not* depend on these modules; they may
change or disappear without any notice. ### Working *on* Iris
## Documentation See the [contribution guide](CONTRIBUTING.md) for information on how to work on
the Iris development itself.
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 ## Directory Structure
document is [available online](http://plv.mpi-sws.org/iris/appendix-3.0.pdf).
Iris is structured into multiple *packages*, some of which contain multiple
modules in separate folders.
* The [iris](iris) package contains the language-independent parts of Iris.
+ The folder [prelude](iris/prelude) contains modules imported everywhere in
Iris.
+ The folder [algebra](iris/algebra) contains the COFE and CMRA
constructions as well as the solver for recursive domain equations.
- The subfolder [lib](iris/algebra/lib) contains some general derived RA
constructions.
+ The folder [bi](iris/bi) contains the BI++ laws, as well as derived
connectives, laws and constructions that are applicable for general BIs.
- The subfolder [lib](iris/bi/lib) contains some general derived logical
constructions.
+ The folder [proofmode](iris/proofmode) contains
[MoSeL](http://iris-project.org/mosel/), which extends Coq with contexts for
intuitionistic and spatial BI++ assertions. It also contains tactics for
interactive proofs. Documentation can be found in
[proof_mode.md](docs/proof_mode.md).
+ The folder [base_logic](iris/base_logic) defines the Iris base logic and
the primitive connectives. It also contains derived constructions that are
entirely independent of the choice of resources.
- The subfolder [lib](iris/base_logic/lib) contains some generally useful
derived constructions. Most importantly, it defines composable
dynamic resources and ownership of them; the other constructions depend
on this setup.
+ The folder [program_logic](iris/program_logic) specializes the base logic
to build Iris, the program logic. This includes weakest preconditions that
are defined for any language satisfying some generic axioms, and some derived
constructions that work for any such language.
+ The folder [si_logic](iris/si_logic) defines a "plain" step-indexed logic
and shows that it is an instance of the BI interface.
* The [iris_heap_lang](iris_heap_lang) package defines the ML-like concurrent
language HeapLang and provides tactic support and proof mode integration.
+ The subfolder [lib](iris_heap_lang/lib) contains a few derived
constructions within this language, e.g., parallel composition.
For more examples of using Iris and heap_lang, have a look at the
[Iris Examples](https://gitlab.mpi-sws.org/iris/examples).
* The [iris_unstable](iris_unstable) package contains libraries that are not yet
ready for inclusion in Iris proper. For each library, there is a corresponding
"tracking issue" in the Iris issue tracker (also linked from the library
itself) which tracks the work that still needs to be done before moving the
library to Iris. No stability guarantees whatsoever are made for this package.
* The [iris_deprecated](iris_deprecated) package contains libraries that have been
removed from Iris proper, but are kept around to give users some more time to
switch to their intended replacements. The individual libraries come with comments
explaining the deprecation and making recommendations for what to use
instead. No stability guarantees whatsoever are made for this package.
* The folder [tests](tests) contains modules we use to test our
infrastructure. These modules are not installed by `make install`, and should
not be imported.
Note that the unstable and deprecated packages are not released, so they only
exist in the development version of Iris.
## 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/iris/examples) is where we
collect miscellaneous case studies that do not have their own repository.
* [LambdaRust](https://gitlab.mpi-sws.org/iris/lambda-rust) is a Coq
formalization of the core Rust type system.
* [GPFSL](https://gitlab.mpi-sws.org/iris/gpfsl) is a logic for release-acquire
and relaxed memory.
* [Iron](https://gitlab.mpi-sws.org/iris/iron) is a linear separation logic
built on top of Iris for precise reasoning about resources (such as making
sure there are no memory leaks).
* [Actris](https://gitlab.mpi-sws.org/iris/actris) is a separation logic
built on top of Iris for session-type based reasoning of message-passing
programs.
## Further Resources
Getting along with Iris in Coq:
* The coding style is documented in the [style guide](docs/style_guide.md).
* Iris proof patterns and conventions are documented in the
[proof guide](docs/proof_guide.md).
* Various notions of equality and logical entailment in Iris and their Coq
interface are described in the
[equality docs](docs/equalities_and_entailments.md).
* The Iris tactics are described in the
[the Iris Proof Mode (IPM) / MoSeL documentation](docs/proof_mode.md) as well as the
[HeapLang documentation](docs/heap_lang.md).
* The generated coqdoc is [available online](https://plv.mpi-sws.org/coqdoc/iris/).
Contacting the developers:
* Discussion about the Iris Coq development happens in the [Iris
Chat](https://iris-project.org/chat.html). 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/iris/iris/issues), which requires
an MPI-SWS GitLab account. The [chat page](https://iris-project.org/chat.html)
describes how to create such an account.
* To contribute to Iris itself, see the [contribution guide](CONTRIBUTING.md).
Miscellaneous:
* Information on how to set up your editor for unicode input and output is
collected in [editor.md](docs/editor.md).
* If you are writing a paper that uses Iris in one way or another, you could use
the [Iris LaTeX macros](tex/iris.sty) for typesetting the various Iris
connectives.
-Q . iris # Search paths for all packages. They must all match the regex
prelude/option.v # `-Q $PACKAGE[/ ]` so that we can filter out the right ones for each package.
prelude/fin_map_dom.v -Q iris/prelude iris.prelude
prelude/bset.v -Q iris/algebra iris.algebra
prelude/fin_maps.v -Q iris/si_logic iris.si_logic
prelude/vector.v -Q iris/bi iris.bi
prelude/pmap.v -Q iris/proofmode iris.proofmode
prelude/stringmap.v -Q iris/base_logic iris.base_logic
prelude/fin_collections.v -Q iris/program_logic iris.program_logic
prelude/mapset.v -Q iris_heap_lang iris.heap_lang
prelude/proof_irrel.v -Q iris_unstable iris.unstable
prelude/hashset.v -Q iris_deprecated iris.deprecated
prelude/pretty.v
prelude/countable.v # Custom flags (to be kept in sync with the dune file at the root of the repo).
prelude/orders.v # We sometimes want to locally override notation, and there is no good way to do that with scopes.
prelude/natmap.v -arg -w -arg -notation-overridden
prelude/strings.v # Cannot use non-canonical projections as it causes massive unification failures
prelude/relations.v # (https://github.com/coq/coq/issues/6294).
prelude/collections.v -arg -w -arg -redundant-canonical-projection
prelude/listset.v # Warning seems incorrect, see https://gitlab.mpi-sws.org/iris/stdpp/-/issues/216
prelude/streams.v -arg -w -arg -notation-incompatible-prefix
prelude/gmap.v # We can't do this migration yet until we require Coq 9.0
prelude/gmultiset.v -arg -w -arg -deprecated-from-Coq
prelude/base.v -arg -w -arg -deprecated-dirpath-Coq
prelude/tactics.v
prelude/prelude.v iris/prelude/options.v
prelude/listset_nodup.v iris/prelude/prelude.v
prelude/finite.v iris/algebra/monoid.v
prelude/numbers.v iris/algebra/cmra.v
prelude/nmap.v iris/algebra/big_op.v
prelude/zmap.v iris/algebra/cmra_big_op.v
prelude/coPset.v iris/algebra/sts.v
prelude/lexico.v iris/algebra/numbers.v
prelude/set.v iris/algebra/view.v
prelude/decidable.v iris/algebra/auth.v
prelude/list.v iris/algebra/gmap.v
prelude/functions.v iris/algebra/ofe.v
prelude/hlist.v iris/algebra/cofe_solver.v
prelude/sorting.v iris/algebra/agree.v
algebra/cmra.v iris/algebra/excl.v
algebra/cmra_big_op.v iris/algebra/functions.v
algebra/cmra_tactics.v iris/algebra/frac.v
algebra/sts.v iris/algebra/dfrac.v
algebra/auth.v iris/algebra/csum.v
algebra/gmap.v iris/algebra/list.v
algebra/ofe.v iris/algebra/vector.v
algebra/base.v iris/algebra/updates.v
algebra/dra.v iris/algebra/local_updates.v
algebra/cofe_solver.v iris/algebra/gset.v
algebra/agree.v iris/algebra/gmultiset.v
algebra/dec_agree.v iris/algebra/coPset.v
algebra/excl.v iris/algebra/proofmode_classes.v
algebra/iprod.v iris/algebra/ufrac.v
algebra/frac.v iris/algebra/reservation_map.v
algebra/csum.v iris/algebra/dyn_reservation_map.v
algebra/list.v iris/algebra/max_prefix_list.v
algebra/updates.v iris/algebra/mra.v
algebra/local_updates.v iris/algebra/lib/excl_auth.v
algebra/gset.v iris/algebra/lib/frac_auth.v
algebra/coPset.v iris/algebra/lib/ufrac_auth.v
algebra/deprecated.v iris/algebra/lib/dfrac_agree.v
base_logic/upred.v iris/algebra/lib/gmap_view.v
base_logic/primitive.v iris/algebra/lib/mono_nat.v
base_logic/derived.v iris/algebra/lib/mono_Z.v
base_logic/base_logic.v iris/algebra/lib/mono_list.v
base_logic/tactics.v iris/algebra/lib/gset_bij.v
base_logic/big_op.v iris/si_logic/siprop.v
base_logic/hlist.v iris/si_logic/bi.v
base_logic/soundness.v iris/bi/notation.v
base_logic/double_negation.v iris/bi/interface.v
base_logic/deprecated.v iris/bi/derived_connectives.v
base_logic/lib/iprop.v iris/bi/extensions.v
base_logic/lib/own.v iris/bi/derived_laws.v
base_logic/lib/saved_prop.v iris/bi/derived_laws_later.v
base_logic/lib/namespaces.v iris/bi/plainly.v
base_logic/lib/wsat.v iris/bi/internal_eq.v
base_logic/lib/invariants.v iris/bi/big_op.v
base_logic/lib/fancy_updates.v iris/bi/updates.v
base_logic/lib/viewshifts.v iris/bi/ascii.v
base_logic/lib/auth.v iris/bi/bi.v
base_logic/lib/sts.v iris/bi/monpred.v
base_logic/lib/boxes.v iris/bi/embedding.v
base_logic/lib/thread_local.v iris/bi/weakestpre.v
base_logic/lib/cancelable_invariants.v iris/bi/telescopes.v
base_logic/lib/counter_examples.v iris/bi/lib/cmra.v
base_logic/lib/fractional.v iris/bi/lib/counterexamples.v
program_logic/adequacy.v iris/bi/lib/fixpoint_mono.v
program_logic/lifting.v iris/bi/lib/fixpoint_banach.v
program_logic/weakestpre.v iris/bi/lib/fractional.v
program_logic/hoare.v iris/bi/lib/laterable.v
program_logic/language.v iris/bi/lib/atomic.v
program_logic/ectx_language.v iris/bi/lib/core.v
program_logic/ectxi_language.v iris/bi/lib/relations.v
program_logic/ectx_lifting.v iris/base_logic/upred.v
heap_lang/lang.v iris/base_logic/bi.v
heap_lang/tactics.v iris/base_logic/derived.v
heap_lang/wp_tactics.v iris/base_logic/proofmode.v
heap_lang/lifting.v iris/base_logic/base_logic.v
heap_lang/derived.v iris/base_logic/algebra.v
heap_lang/notation.v iris/base_logic/bupd_alt.v
heap_lang/heap.v iris/base_logic/lib/iprop.v
heap_lang/lib/spawn.v iris/base_logic/lib/own.v
heap_lang/lib/par.v iris/base_logic/lib/saved_prop.v
heap_lang/lib/assert.v iris/base_logic/lib/wsat.v
heap_lang/lib/lock.v iris/base_logic/lib/invariants.v
heap_lang/lib/spin_lock.v iris/base_logic/lib/fancy_updates.v
heap_lang/lib/ticket_lock.v iris/base_logic/lib/boxes.v
heap_lang/lib/counter.v iris/base_logic/lib/na_invariants.v
heap_lang/lib/barrier/barrier.v iris/base_logic/lib/cancelable_invariants.v
heap_lang/lib/barrier/specification.v iris/base_logic/lib/gen_heap.v
heap_lang/lib/barrier/protocol.v iris/base_logic/lib/gen_inv_heap.v
heap_lang/lib/barrier/proof.v iris/base_logic/lib/fancy_updates_from_vs.v
heap_lang/proofmode.v iris/base_logic/lib/proph_map.v
heap_lang/adequacy.v iris/base_logic/lib/ghost_var.v
tests/heap_lang.v iris/base_logic/lib/mono_nat.v
tests/one_shot.v iris/base_logic/lib/gset_bij.v
tests/joining_existentials.v iris/base_logic/lib/ghost_map.v
tests/proofmode.v iris/base_logic/lib/later_credits.v
tests/barrier_client.v iris/base_logic/lib/token.v
tests/list_reverse.v iris/program_logic/adequacy.v
tests/tree_sum.v iris/program_logic/lifting.v
tests/counter.v iris/program_logic/weakestpre.v
proofmode/strings.v iris/program_logic/total_weakestpre.v
proofmode/coq_tactics.v iris/program_logic/total_adequacy.v
proofmode/environments.v iris/program_logic/language.v
proofmode/intro_patterns.v iris/program_logic/ectx_language.v
proofmode/spec_patterns.v iris/program_logic/ectxi_language.v
proofmode/sel_patterns.v iris/program_logic/ectx_lifting.v
proofmode/tactics.v iris/program_logic/ownp.v
proofmode/notation.v iris/program_logic/total_lifting.v
proofmode/classes.v iris/program_logic/total_ectx_lifting.v
proofmode/class_instances.v iris/program_logic/atomic.v
iris/proofmode/base.v
iris/proofmode/ident_name.v
iris/proofmode/string_ident.v
iris/proofmode/tokens.v
iris/proofmode/coq_tactics.v
iris/proofmode/ltac_tactics.v
iris/proofmode/environments.v
iris/proofmode/reduction.v
iris/proofmode/intro_patterns.v
iris/proofmode/spec_patterns.v
iris/proofmode/sel_patterns.v
iris/proofmode/tactics.v
iris/proofmode/notation.v
iris/proofmode/classes.v
iris/proofmode/classes_make.v
iris/proofmode/class_instances.v
iris/proofmode/class_instances_later.v
iris/proofmode/class_instances_updates.v
iris/proofmode/class_instances_embedding.v
iris/proofmode/class_instances_plainly.v
iris/proofmode/class_instances_internal_eq.v
iris/proofmode/class_instances_frame.v
iris/proofmode/class_instances_make.v
iris/proofmode/monpred.v
iris/proofmode/modalities.v
iris/proofmode/modality_instances.v
iris/proofmode/proofmode.v
iris_heap_lang/locations.v
iris_heap_lang/lang.v
iris_heap_lang/class_instances.v
iris_heap_lang/pretty.v
iris_heap_lang/metatheory.v
iris_heap_lang/tactics.v
iris_heap_lang/primitive_laws.v
iris_heap_lang/derived_laws.v
iris_heap_lang/notation.v
iris_heap_lang/proofmode.v
iris_heap_lang/adequacy.v
iris_heap_lang/total_adequacy.v
iris_heap_lang/proph_erasure.v
iris_heap_lang/lib/spawn.v
iris_heap_lang/lib/par.v
iris_heap_lang/lib/assert.v
iris_heap_lang/lib/lock.v
iris_heap_lang/lib/rw_lock.v
iris_heap_lang/lib/spin_lock.v
iris_heap_lang/lib/ticket_lock.v
iris_heap_lang/lib/rw_spin_lock.v
iris_heap_lang/lib/nondet_bool.v
iris_heap_lang/lib/lazy_coin.v
iris_heap_lang/lib/clairvoyant_coin.v
iris_heap_lang/lib/counter.v
iris_heap_lang/lib/atomic_heap.v
iris_heap_lang/lib/increment.v
iris_heap_lang/lib/diverge.v
iris_heap_lang/lib/arith.v
iris_heap_lang/lib/array.v
iris_heap_lang/lib/logatom_lock.v
iris_unstable/algebra/list.v
iris_unstable/base_logic/algebra.v
iris_unstable/base_logic/mono_list.v
iris_unstable/heap_lang/interpreter.v
iris_deprecated/base_logic/auth.v
iris_deprecated/base_logic/sts.v
iris_deprecated/base_logic/viewshifts.v
iris_deprecated/program_logic/hoare.v
From iris.algebra Require Export cmra.
From iris.algebra Require Import list.
From iris.base_logic Require Import base_logic.
Local Arguments validN _ _ _ !_ /.
Local Arguments valid _ _ !_ /.
Local Arguments op _ _ _ !_ /.
Local Arguments pcore _ _ !_ /.
Record agree (A : Type) : Type := Agree {
agree_car : A;
agree_with : list A;
}.
Arguments Agree {_} _ _.
Arguments agree_car {_} _.
Arguments agree_with {_} _.
(* Some theory about set-inclusion on lists and lists of which all elements are equal.
TODO: Move this elsewhere. *)
Definition list_setincl `(R : relation A) (al bl : list A) :=
a, a al b, b bl R a b.
Definition list_setequiv `(R : relation A) (al bl : list A) :=
list_setincl R al bl list_setincl R bl al.
(* list_agrees is carefully written such that, when applied to a singleton, it is convertible to True. This makes working with agreement much more pleasant. *)
Definition list_agrees `(R : relation A) (al : list A) :=
match al with
| [] => True
| [a] => True
| a :: al => b, b al R a b
end.
Lemma list_agrees_alt `(R : relation A) `{Equivalence _ R} al :
list_agrees R al ( a b, a al b al R a b).
Proof.
destruct al as [|a [|b al]].
- split; last done. intros _ ? ? []%elem_of_nil.
- split; last done. intros _ ? ? ->%elem_of_list_singleton ->%elem_of_list_singleton. done.
- simpl. split.
+ intros Hl a' b' [->|Ha']%elem_of_cons.
* intros [->|Hb']%elem_of_cons; first done. auto.
* intros [->|Hb']%elem_of_cons; first by (symmetry; auto).
trans a; last by auto. symmetry. auto.
+ intros Hl b' Hb'. apply Hl; set_solver.
Qed.
Section list_theory.
Context `(R: relation A) `{Equivalence A R}.
Global Instance: PreOrder (list_setincl R).
Proof.
split.
- intros al a Ha. set_solver.
- intros al bl cl Hab Hbc a Ha. destruct (Hab _ Ha) as (b & Hb & Rab).
destruct (Hbc _ Hb) as (c & Hc & Rbc). exists c. split; first done.
by trans b.
Qed.
Global Instance: Equivalence (list_setequiv R).
Proof.
split.
- by split.
- intros ?? [??]. split; auto.
- intros ??? [??] [??]. split; etrans; done.
Qed.
Global Instance list_setincl_subrel `(R' : relation A) :
subrelation R R' subrelation (list_setincl R) (list_setincl R').
Proof.
intros HRR' al bl Hab. intros a Ha. destruct (Hab _ Ha) as (b & Hb & HR).
exists b. split; first done. exact: HRR'.
Qed.
Global Instance list_setequiv_subrel `(R' : relation A) :
subrelation R R' subrelation (list_setequiv R) (list_setequiv R').
Proof. intros HRR' ?? [??]. split; exact: list_setincl_subrel. Qed.
Global Instance list_setincl_perm : subrelation () (list_setincl R).
Proof.
intros al bl Hab a Ha. exists a. split; last done.
by rewrite -Hab.
Qed.
Global Instance list_setincl_app l :
Proper (list_setincl R ==> list_setincl R) (app l).
Proof.
intros al bl Hab a [Ha|Ha]%elem_of_app.
- exists a. split; last done. apply elem_of_app. by left.
- destruct (Hab _ Ha) as (b & Hb & HR). exists b. split; last done.
apply elem_of_app. by right.
Qed.
Global Instance list_setequiv_app l :
Proper (list_setequiv R ==> list_setequiv R) (app l).
Proof. intros al bl [??]. split; apply list_setincl_app; done. Qed.
Global Instance: subrelation () (flip (list_setincl R)).
Proof. intros ???. apply list_setincl_perm. done. Qed.
Global Instance list_agrees_setincl :
Proper (flip (list_setincl R) ==> impl) (list_agrees R).
Proof.
move=> al bl /= Hab /list_agrees_alt Hal. apply (list_agrees_alt _) => a b Ha Hb.
destruct (Hab _ Ha) as (a' & Ha' & HRa).
destruct (Hab _ Hb) as (b' & Hb' & HRb).
trans a'; first done. etrans; last done.
eapply Hal; done.
Qed.
Global Instance list_agrees_setequiv :
Proper (list_setequiv R ==> iff) (list_agrees R).
Proof.
intros ?? [??]. split; by apply: list_agrees_setincl.
Qed.
Lemma list_setincl_contains al bl :
( x, x al x bl) list_setincl R al bl.
Proof. intros Hin a Ha. exists a. split; last done. naive_solver. Qed.
Lemma list_setequiv_equiv al bl :
( x, x al x bl) list_setequiv R al bl.
Proof.
intros Hin. split; apply list_setincl_contains; naive_solver.
Qed.
Lemma list_agrees_contains al bl :
( x, x bl x al)
list_agrees R al list_agrees R bl.
Proof. intros ?. by eapply (list_agrees_setincl _),list_setincl_contains. Qed.
Lemma list_agrees_equiv al bl :
( x, x bl x al)
list_agrees R al list_agrees R bl.
Proof. intros ?. by eapply (list_agrees_setequiv _), list_setequiv_equiv. Qed.
Lemma list_setincl_singleton a b :
R a b list_setincl R [a] [b].
Proof.
intros HR c ->%elem_of_list_singleton. exists b. split; last done.
apply elem_of_list_singleton. done.
Qed.
Lemma list_setincl_singleton_rev a b :
list_setincl R [a] [b] R a b.
Proof.
intros Hl. destruct (Hl a) as (? & ->%elem_of_list_singleton & HR); last done.
by apply elem_of_list_singleton.
Qed.
Lemma list_setequiv_singleton a b :
R a b list_setequiv R [a] [b].
Proof. intros ?. split; by apply list_setincl_singleton. Qed.
Lemma list_agrees_iff_setincl al a :
a al list_agrees R al list_setincl R al [a].
Proof.
intros Hin. split.
- move=>/list_agrees_alt Hl b Hb. exists a. split; first set_solver+. exact: Hl.
- intros Hl. apply (list_agrees_alt _)=> b c Hb Hc.
destruct (Hl _ Hb) as (? & ->%elem_of_list_singleton & ?).
destruct (Hl _ Hc) as (? & ->%elem_of_list_singleton & ?).
by trans a.
Qed.
Lemma list_setincl_singleton_in al a :
a al list_setincl R [a] al.
Proof.
intros Hin b ->%elem_of_list_singleton. exists a. split; done.
Qed.
Global Instance list_setincl_ext : subrelation (Forall2 R) (list_setincl R).
Proof.
move=>al bl. induction 1.
- intros ? []%elem_of_nil.
- intros a [->|Ha]%elem_of_cons.
+ eexists. split; first constructor. done.
+ destruct (IHForall2 _ Ha) as (b & ? & ?).
exists b. split; first by constructor. done.
Qed.
Global Instance list_setequiv_ext : subrelation (Forall2 R) (list_setequiv R).
Proof.
move=>al bl ?. split; apply list_setincl_ext; done.
Qed.
Lemma list_agrees_subrel `(R' : relation A) `{Equivalence _ R'} :
subrelation R R' l, list_agrees R l list_agrees R' l.
Proof. move=> HR l /list_agrees_alt Hl. apply (list_agrees_alt _)=> a b Ha Hb. by apply HR, Hl. Qed.
Section fmap.
Context `(R' : relation B) (f : A B) {Hf: Proper (R ==> R') f}.
Global Instance list_setincl_fmap :
Proper (list_setincl R ==> list_setincl R') (fmap f).
Proof.
intros al bl Hab a' (a & -> & Ha)%elem_of_list_fmap.
destruct (Hab _ Ha) as (b & Hb & HR). exists (f b).
split; first eapply elem_of_list_fmap; eauto.
Qed.
Global Instance list_setequiv_fmap :
Proper (list_setequiv R ==> list_setequiv R') (fmap f).
Proof. intros ?? [??]. split; apply list_setincl_fmap; done. Qed.
Lemma list_agrees_fmap `{Equivalence _ R'} al :
list_agrees R al list_agrees R' (f <$> al).
Proof.
move=> /list_agrees_alt Hl. apply <-(list_agrees_alt R')=> a' b'.
intros (a & -> & Ha)%elem_of_list_fmap (b & -> & Hb)%elem_of_list_fmap.
apply Hf. exact: Hl.
Qed.
End fmap.
End list_theory.
Section agree.
Context {A : ofeT}.
Definition agree_list (x : agree A) := agree_car x :: agree_with x.
Instance agree_validN : ValidN (agree A) := λ n x,
list_agrees (dist n) (agree_list x).
Instance agree_valid : Valid (agree A) := λ x,
list_agrees (equiv) (agree_list x).
Instance agree_dist : Dist (agree A) := λ n x y,
list_setequiv (dist n) (agree_list x) (agree_list y).
Instance agree_equiv : Equiv (agree A) := λ x y,
n, list_setequiv (dist n) (agree_list x) (agree_list y).
Definition agree_dist_incl n (x y : agree A) :=
list_setincl (dist n) (agree_list x) (agree_list y).
Definition agree_ofe_mixin : OfeMixin (agree A).
Proof.
split.
- intros x y; split; intros Hxy; done.
- split; rewrite /dist /agree_dist; intros ? *.
+ reflexivity.
+ by symmetry.
+ intros. etrans; eassumption.
- intros ???. apply list_setequiv_subrel=>??. apply dist_S.
Qed.
Canonical Structure agreeC := OfeT (agree A) agree_ofe_mixin.
Program Instance agree_op : Op (agree A) := λ x y,
{| agree_car := agree_car x;
agree_with := agree_with x ++ agree_car y :: agree_with y |}.
Instance agree_pcore : PCore (agree A) := Some.
Instance: Comm () (@op (agree A) _).
Proof. intros x y n. apply: list_setequiv_equiv. set_solver. Qed.
Lemma agree_idemp (x : agree A) : x x x.
Proof. intros n. apply: list_setequiv_equiv. set_solver. Qed.
Instance: n : nat, Proper (dist n ==> impl) (@validN (agree A) _ n).
Proof.
intros n x y. rewrite /dist /validN /agree_dist /agree_validN.
by intros ->.
Qed.
Instance: n : nat, Proper (equiv ==> iff) (@validN (agree A) _ n).
Proof.
intros n ???. assert (x {n} y) as Hxy by by apply equiv_dist.
split; rewrite Hxy; done.
Qed.
Instance: x : agree A, Proper (dist n ==> dist n) (op x).
Proof.
intros n x y1 y2. rewrite /dist /agree_dist /agree_list /=.
rewrite !app_comm_cons. apply: list_setequiv_app.
Qed.
Instance: Proper (dist n ==> dist n ==> dist n) (@op (agree A) _).
Proof. by intros n x1 x2 Hx y1 y2 Hy; rewrite Hy !(comm _ _ y2) Hx. Qed.
Instance: Proper (() ==> () ==> ()) op := ne_proper_2 _.
Instance: Assoc () (@op (agree A) _).
Proof. intros x y z n. apply: list_setequiv_equiv. set_solver. Qed.
Lemma agree_included (x y : agree A) : x y y x y.
Proof.
split; [|by intros ?; exists y].
by intros [z Hz]; rewrite Hz assoc agree_idemp.
Qed.
Lemma agree_op_inv_inclN n x1 x2 : {n} (x1 x2) agree_dist_incl n x1 x2.
Proof.
rewrite /validN /= => /list_agrees_alt Hv a /elem_of_cons Ha. exists (agree_car x2).
split; first by constructor. eapply Hv.
- simpl. destruct Ha as [->|Ha]; set_solver.
- simpl. set_solver+.
Qed.
Lemma agree_op_invN n (x1 x2 : agree A) : {n} (x1 x2) x1 {n} x2.
Proof.
intros Hxy. split; apply agree_op_inv_inclN; first done. by rewrite comm.
Qed.
Lemma agree_valid_includedN n (x y : agree A) : {n} y x {n} y x {n} y.
Proof.
move=> Hval [z Hy]; move: Hval; rewrite Hy.
by move=> /agree_op_invN->; rewrite agree_idemp.
Qed.
Definition agree_cmra_mixin : CMRAMixin (agree A).
Proof.
apply cmra_total_mixin; try apply _ || by eauto.
- move=>x. split.
+ move=>/list_agrees_alt Hx n. apply (list_agrees_alt _)=> a b Ha Hb.
apply equiv_dist, Hx; done.
+ intros Hx. apply (list_agrees_alt _)=> a b Ha Hb.
apply equiv_dist=>n. eapply (list_agrees_alt _); first (by apply Hx); done.
- intros n x. apply (list_agrees_subrel _ _)=>??. apply dist_S.
- intros x. apply agree_idemp.
- intros ??? Hl. apply: list_agrees_contains Hl. set_solver.
- intros n x y1 y2 Hval Hx; exists x, x; simpl; split.
+ by rewrite agree_idemp.
+ by move: Hval; rewrite Hx; move=> /agree_op_invN->; rewrite agree_idemp.
Qed.
Canonical Structure agreeR : cmraT :=
CMRAT (agree A) agree_ofe_mixin agree_cmra_mixin.
Global Instance agree_total : CMRATotal agreeR.
Proof. rewrite /CMRATotal; eauto. Qed.
Global Instance agree_persistent (x : agree A) : Persistent x.
Proof. by constructor. Qed.
Lemma agree_op_inv (x1 x2 : agree A) : (x1 x2) x1 x2.
Proof.
intros ?. apply equiv_dist=>n. by apply agree_op_invN, cmra_valid_validN.
Qed.
Global Instance agree_discrete :
Discrete A CMRADiscrete agreeR.
Proof.
intros HD. split.
- intros x y Hxy n. eapply list_setequiv_subrel; last exact Hxy. clear -HD.
intros x y ?. apply equiv_dist, HD. done.
- rewrite /valid /cmra_valid /agree_valid /validN /cmra_validN /agree_validN /=.
move=> x. apply (list_agrees_subrel _ _). clear -HD.
intros x y. apply HD.
Qed.
Definition to_agree (x : A) : agree A :=
{| agree_car := x; agree_with := [] |}.
Global Instance to_agree_ne n : Proper (dist n ==> dist n) to_agree.
Proof.
intros x1 x2 Hx; rewrite /= /dist /agree_dist /=.
exact: list_setequiv_singleton.
Qed.
Global Instance to_agree_proper : Proper (() ==> ()) to_agree := ne_proper _.
Global Instance to_agree_injN n : Inj (dist n) (dist n) (to_agree).
Proof. intros a b [Hxy%list_setincl_singleton_rev _]. done. Qed.
Global Instance to_agree_inj : Inj () () (to_agree).
Proof.
intros a b ?. apply equiv_dist=>n. apply to_agree_injN. by apply equiv_dist.
Qed.
Lemma to_agree_uninj n (x : agree A) : {n} x y : A, to_agree y {n} x.
Proof.
intros Hl. exists (agree_car x). rewrite /dist /agree_dist /=.
split.
- apply: list_setincl_singleton_in. set_solver+.
- apply (list_agrees_iff_setincl _); first set_solver+. done.
Qed.
Lemma to_agree_included (a b : A) : to_agree a to_agree b a b.
Proof.
split.
- intros (x & Heq). apply equiv_dist=>n. destruct (Heq n) as [_ Hincl].
(* TODO: This could become a generic lemma about list_setincl. *)
destruct (Hincl a) as (? & ->%elem_of_list_singleton & ?); first set_solver+.
done.
- intros Hab. rewrite Hab. eexists. symmetry. eapply agree_idemp.
Qed.
Lemma to_agree_comp_valid (a b : A) : (to_agree a to_agree b) a b.
Proof.
split.
- (* TODO: can this be derived from other stuff? Otherwise, should probably become sth. generic about list_agrees. *)
intros Hv. apply Hv; simpl; set_solver.
- intros ->. rewrite agree_idemp. done.
Qed.
(** Internalized properties *)
Lemma agree_equivI {M} a b : to_agree a to_agree b ⊣⊢ (a b : uPred M).
Proof.
uPred.unseal. do 2 split.
- intros Hx. exact: to_agree_injN.
- intros Hx. exact: to_agree_ne.
Qed.
Lemma agree_validI {M} x y : (x y) (x y : uPred M).
Proof. uPred.unseal; split=> r n _ ?; by apply: agree_op_invN. Qed.
End agree.
Arguments agreeC : clear implicits.
Arguments agreeR : clear implicits.
Program Definition agree_map {A B} (f : A B) (x : agree A) : agree B :=
{| agree_car := f (agree_car x); agree_with := f <$> (agree_with x) |}.
Lemma agree_map_id {A} (x : agree A) : agree_map id x = x.
Proof. rewrite /agree_map /= list_fmap_id. by destruct x. Qed.
Lemma agree_map_compose {A B C} (f : A B) (g : B C) (x : agree A) :
agree_map (g f) x = agree_map g (agree_map f x).
Proof. rewrite /agree_map /= list_fmap_compose. done. Qed.
Section agree_map.
Context {A B : ofeT} (f : A B) `{Hf: n, Proper (dist n ==> dist n) f}.
Instance agree_map_ne n : Proper (dist n ==> dist n) (agree_map f).
Proof.
intros x y Hxy.
change (list_setequiv (dist n)(f <$> (agree_list x))(f <$> (agree_list y))).
eapply list_setequiv_fmap; last exact Hxy. apply _.
Qed.
Instance agree_map_proper : Proper (() ==> ()) (agree_map f) := ne_proper _.
Lemma agree_map_ext (g : A B) x :
( x, f x g x) agree_map f x agree_map g x.
Proof.
intros Hfg n. apply: list_setequiv_ext.
change (f <$> (agree_list x) {n} g <$> (agree_list x)).
apply list_fmap_ext_ne=>y. by apply equiv_dist.
Qed.
Global Instance agree_map_monotone : CMRAMonotone (agree_map f).
Proof.
split; first apply _.
- intros n x. rewrite /cmra_validN /validN /= /agree_validN /= => ?.
change (list_agrees (dist n) (f <$> agree_list x)).
eapply (list_agrees_fmap _ _ _); done.
- intros x y; rewrite !agree_included=> ->.
rewrite /equiv /agree_equiv /agree_map /agree_op /agree_list /=.
rewrite !fmap_app=>n. apply: list_setequiv_equiv. set_solver+.
Qed.
End agree_map.
Definition agreeC_map {A B} (f : A -n> B) : agreeC A -n> agreeC B :=
CofeMor (agree_map f : agreeC A agreeC B).
Instance agreeC_map_ne A B n : Proper (dist n ==> dist n) (@agreeC_map A B).
Proof.
intros f g Hfg x. apply: list_setequiv_ext.
change (f <$> (agree_list x) {n} g <$> (agree_list x)).
apply list_fmap_ext_ne. done.
Qed.
Program Definition agreeRF (F : cFunctor) : rFunctor := {|
rFunctor_car A B := agreeR (cFunctor_car F A B);
rFunctor_map A1 A2 B1 B2 fg := agreeC_map (cFunctor_map F fg)
|}.
Next Obligation.
intros ? A1 A2 B1 B2 n ???; simpl. by apply agreeC_map_ne, cFunctor_ne.
Qed.
Next Obligation.
intros F A B x; simpl. rewrite -{2}(agree_map_id x).
apply agree_map_ext=>y. by rewrite cFunctor_id.
Qed.
Next Obligation.
intros F A1 A2 A3 B1 B2 B3 f g f' g' x; simpl. rewrite -agree_map_compose.
apply agree_map_ext=>y; apply cFunctor_compose.
Qed.
Instance agreeRF_contractive F :
cFunctorContractive F rFunctorContractive (agreeRF F).
Proof.
intros ? A1 A2 B1 B2 n ???; simpl.
by apply agreeC_map_ne, cFunctor_contractive.
Qed.
From iris.algebra Require Export excl local_updates.
From iris.base_logic Require Import base_logic.
From iris.proofmode Require Import class_instances.
Record auth (A : Type) := Auth { authoritative : excl' A; auth_own : A }.
Add Printing Constructor auth.
Arguments Auth {_} _ _.
Arguments authoritative {_} _.
Arguments auth_own {_} _.
Notation "◯ a" := (Auth None a) (at level 20).
Notation "● a" := (Auth (Excl' a) ) (at level 20).
(* COFE *)
Section cofe.
Context {A : ofeT}.
Implicit Types a : excl' A.
Implicit Types b : A.
Implicit Types x y : auth A.
Instance auth_equiv : Equiv (auth A) := λ x y,
authoritative x authoritative y auth_own x auth_own y.
Instance auth_dist : Dist (auth A) := λ n x y,
authoritative x {n} authoritative y auth_own x {n} auth_own y.
Global Instance Auth_ne : Proper (dist n ==> dist n ==> dist n) (@Auth A).
Proof. by split. Qed.
Global Instance Auth_proper : Proper (() ==> () ==> ()) (@Auth A).
Proof. by split. Qed.
Global Instance authoritative_ne: Proper (dist n ==> dist n) (@authoritative A).
Proof. by destruct 1. Qed.
Global Instance authoritative_proper : Proper (() ==> ()) (@authoritative A).
Proof. by destruct 1. Qed.
Global Instance own_ne : Proper (dist n ==> dist n) (@auth_own A).
Proof. by destruct 1. Qed.
Global Instance own_proper : Proper (() ==> ()) (@auth_own A).
Proof. by destruct 1. Qed.
Definition auth_ofe_mixin : OfeMixin (auth A).
Proof.
split.
- intros x y; unfold dist, auth_dist, equiv, auth_equiv.
rewrite !equiv_dist; naive_solver.
- intros n; split.
+ by intros ?; split.
+ by intros ?? [??]; split; symmetry.
+ intros ??? [??] [??]; split; etrans; eauto.
- by intros ? [??] [??] [??]; split; apply dist_S.
Qed.
Canonical Structure authC := OfeT (auth A) auth_ofe_mixin.
Definition auth_compl `{Cofe A} : Compl authC := λ c,
Auth (compl (chain_map authoritative c)) (compl (chain_map auth_own c)).
Global Program Instance auth_cofe `{Cofe A} : Cofe authC :=
{| compl := auth_compl |}.
Next Obligation.
intros ? n c; split. apply (conv_compl n (chain_map authoritative c)).
apply (conv_compl n (chain_map auth_own c)).
Qed.
Global Instance Auth_timeless a b :
Timeless a Timeless b Timeless (Auth a b).
Proof. by intros ?? [??] [??]; split; apply: timeless. Qed.
Global Instance auth_discrete : Discrete A Discrete authC.
Proof. intros ? [??]; apply _. Qed.
Global Instance auth_leibniz : LeibnizEquiv A LeibnizEquiv (auth A).
Proof. by intros ? [??] [??] [??]; f_equal/=; apply leibniz_equiv. Qed.
End cofe.
Arguments authC : clear implicits.
(* CMRA *)
Section cmra.
Context {A : ucmraT}.
Implicit Types a b : A.
Implicit Types x y : auth A.
Instance auth_valid : Valid (auth A) := λ x,
match authoritative x with
| Excl' a => ( n, auth_own x {n} a) a
| None => auth_own x
| ExclBot' => False
end.
Global Arguments auth_valid !_ /.
Instance auth_validN : ValidN (auth A) := λ n x,
match authoritative x with
| Excl' a => auth_own x {n} a {n} a
| None => {n} auth_own x
| ExclBot' => False
end.
Global Arguments auth_validN _ !_ /.
Instance auth_pcore : PCore (auth A) := λ x,
Some (Auth (core (authoritative x)) (core (auth_own x))).
Instance auth_op : Op (auth A) := λ x y,
Auth (authoritative x authoritative y) (auth_own x auth_own y).
Definition auth_valid_eq :
valid = λ x, match authoritative x with
| Excl' a => ( n, auth_own x {n} a) a
| None => auth_own x
| ExclBot' => False
end := eq_refl _.
Definition auth_validN_eq :
validN = λ n x, match authoritative x with
| Excl' a => auth_own x {n} a {n} a
| None => {n} auth_own x
| ExclBot' => False
end := eq_refl _.
Lemma auth_included (x y : auth A) :
x y authoritative x authoritative y auth_own x auth_own y.
Proof.
split; [intros [[z1 z2] Hz]; split; [exists z1|exists z2]; apply Hz|].
intros [[z1 Hz1] [z2 Hz2]]; exists (Auth z1 z2); split; auto.
Qed.
Lemma authoritative_validN n x : {n} x {n} authoritative x.
Proof. by destruct x as [[[]|]]. Qed.
Lemma auth_own_validN n x : {n} x {n} auth_own x.
Proof.
rewrite auth_validN_eq.
destruct x as [[[]|]]; naive_solver eauto using cmra_validN_includedN.
Qed.
Lemma auth_valid_discrete `{CMRADiscrete A} x :
x match authoritative x with
| Excl' a => auth_own x a a
| None => auth_own x
| ExclBot' => False
end.
Proof.
rewrite auth_valid_eq. destruct x as [[[?|]|] ?]; simpl; try done.
setoid_rewrite <-cmra_discrete_included_iff; naive_solver eauto using 0.
Qed.
Lemma auth_validN_2 n a b : {n} ( a b) b {n} a {n} a.
Proof. by rewrite auth_validN_eq /= left_id. Qed.
Lemma auth_valid_discrete_2 `{CMRADiscrete A} a b : ( a b) b a a.
Proof. by rewrite auth_valid_discrete /= left_id. Qed.
Lemma authoritative_valid x : x authoritative x.
Proof. by destruct x as [[[]|]]. Qed.
Lemma auth_own_valid `{CMRADiscrete A} x : x auth_own x.
Proof.
rewrite auth_valid_discrete.
destruct x as [[[]|]]; naive_solver eauto using cmra_valid_included.
Qed.
Lemma auth_cmra_mixin : CMRAMixin (auth A).
Proof.
apply cmra_total_mixin.
- eauto.
- by intros n x y1 y2 [Hy Hy']; split; simpl; rewrite ?Hy ?Hy'.
- by intros n y1 y2 [Hy Hy']; split; simpl; rewrite ?Hy ?Hy'.
- intros n [x a] [y b] [Hx Ha]; simpl in *. rewrite !auth_validN_eq.
destruct Hx as [?? Hx|]; first destruct Hx; intros ?; cofe_subst; auto.
- intros [[[?|]|] ?]; rewrite /= ?auth_valid_eq
?auth_validN_eq /= ?cmra_included_includedN ?cmra_valid_validN;
naive_solver eauto using O.
- intros n [[[]|] ?]; rewrite !auth_validN_eq /=;
naive_solver eauto using cmra_includedN_S, cmra_validN_S.
- by split; simpl; rewrite assoc.
- by split; simpl; rewrite comm.
- by split; simpl; rewrite ?cmra_core_l.
- by split; simpl; rewrite ?cmra_core_idemp.
- intros ??; rewrite! auth_included; intros [??].
by split; simpl; apply cmra_core_mono.
- assert ( n (a b1 b2 : A), b1 b2 {n} a b1 {n} a).
{ intros n a b1 b2 <-; apply cmra_includedN_l. }
intros n [[[a1|]|] b1] [[[a2|]|] b2]; rewrite auth_validN_eq;
naive_solver eauto using cmra_validN_op_l, cmra_validN_includedN.
- intros n x y1 y2 ? [??]; simpl in *.
destruct (cmra_extend n (authoritative x) (authoritative y1)
(authoritative y2)) as (ea1&ea2&?&?&?); auto using authoritative_validN.
destruct (cmra_extend n (auth_own x) (auth_own y1) (auth_own y2))
as (b1&b2&?&?&?); auto using auth_own_validN.
by exists (Auth ea1 b1), (Auth ea2 b2).
Qed.
Canonical Structure authR := CMRAT (auth A) auth_ofe_mixin auth_cmra_mixin.
Global Instance auth_cmra_discrete : CMRADiscrete A CMRADiscrete authR.
Proof.
split; first apply _.
intros [[[?|]|] ?]; rewrite auth_valid_eq auth_validN_eq /=; auto.
- setoid_rewrite <-cmra_discrete_included_iff.
rewrite -cmra_discrete_valid_iff. tauto.
- by rewrite -cmra_discrete_valid_iff.
Qed.
Instance auth_empty : Empty (auth A) := Auth ∅.
Lemma auth_ucmra_mixin : UCMRAMixin (auth A).
Proof.
split; simpl.
- rewrite auth_valid_eq /=. apply ucmra_unit_valid.
- by intros x; constructor; rewrite /= left_id.
- do 2 constructor; simpl; apply (persistent_core _).
Qed.
Canonical Structure authUR :=
UCMRAT (auth A) auth_ofe_mixin auth_cmra_mixin auth_ucmra_mixin.
Global Instance auth_frag_persistent a : Persistent a Persistent ( a).
Proof. do 2 constructor; simpl; auto. by apply persistent_core. Qed.
(** Internalized properties *)
Lemma auth_equivI {M} (x y : auth A) :
x y ⊣⊢ (authoritative x authoritative y auth_own x auth_own y : uPred M).
Proof. by uPred.unseal. Qed.
Lemma auth_validI {M} (x : auth A) :
x ⊣⊢ (match authoritative x with
| Excl' a => ( b, a auth_own x b) a
| None => auth_own x
| ExclBot' => False
end : uPred M).
Proof. uPred.unseal. by destruct x as [[[]|]]. Qed.
Lemma auth_frag_op a b : (a b) = a b.
Proof. done. Qed.
Lemma auth_frag_mono a b : a b a b.
Proof. intros [c ->]. rewrite auth_frag_op. apply cmra_included_l. Qed.
Global Instance auth_frag_cmra_homomorphism : UCMRAHomomorphism (Auth None).
Proof. done. Qed.
Lemma auth_both_op a b : Auth (Excl' a) b a b.
Proof. by rewrite /op /auth_op /= left_id. Qed.
Lemma auth_auth_valid a : a ( a).
Proof. intros; split; simpl; auto using ucmra_unit_leastN. Qed.
Lemma auth_update a b a' b' :
(a,b) ~l~> (a',b') a b ~~> a' b'.
Proof.
intros Hup; apply cmra_total_update.
move=> n [[[?|]|] bf1] // [[bf2 Ha] ?]; do 2 red; simpl in *.
move: Ha; rewrite !left_id -assoc=> Ha.
destruct (Hup n (Some (bf1 bf2))); auto.
split; last done. exists bf2. by rewrite -assoc.
Qed.
Lemma auth_update_alloc a a' b' : (a,) ~l~> (a',b') a ~~> a' b'.
Proof. intros. rewrite -(right_id _ _ ( a)). by apply auth_update. Qed.
Lemma auth_update_dealloc a b a' : (a,b) ~l~> (a',) a b ~~> a'.
Proof. intros. rewrite -(right_id _ _ ( a')). by apply auth_update. Qed.
Lemma auth_local_update (a b0 b1 a' b0' b1': A) :
(b0, b1) ~l~> (b0', b1') b0' a' a'
( a b0, a b1) ~l~> ( a' b0', a' b1').
Proof.
rewrite !local_update_unital=> Hup ? ? n /=.
move=> [[[ac|]|] bc] /auth_validN_2 [Le Val] [] /=;
inversion_clear 1 as [?? Ha|]; inversion_clear Ha. (* need setoid_discriminate! *)
rewrite !left_id=> ?.
destruct (Hup n bc) as [Hval' Heq]; eauto using cmra_validN_includedN.
rewrite -!auth_both_op auth_validN_eq /=.
split_and!; [by apply cmra_included_includedN|by apply cmra_valid_validN|done].
Qed.
End cmra.
Arguments authR : clear implicits.
Arguments authUR : clear implicits.
(* Proof mode class instances *)
Instance from_op_auth_frag {A : ucmraT} (a b1 b2 : A) :
FromOp a b1 b2 FromOp ( a) ( b1) ( b2).
Proof. done. Qed.
Instance into_op_auth_frag {A : ucmraT} (a b1 b2 : A) :
IntoOp a b1 b2 IntoOp ( a) ( b1) ( b2).
Proof. done. Qed.
(* Functor *)
Definition auth_map {A B} (f : A B) (x : auth A) : auth B :=
Auth (excl_map f <$> authoritative x) (f (auth_own x)).
Lemma auth_map_id {A} (x : auth A) : auth_map id x = x.
Proof. by destruct x as [[[]|]]. Qed.
Lemma auth_map_compose {A B C} (f : A B) (g : B C) (x : auth A) :
auth_map (g f) x = auth_map g (auth_map f x).
Proof. by destruct x as [[[]|]]. Qed.
Lemma auth_map_ext {A B : ofeT} (f g : A B) x :
( x, f x g x) auth_map f x auth_map g x.
Proof.
constructor; simpl; auto.
apply option_fmap_setoid_ext=> a; by apply excl_map_ext.
Qed.
Instance auth_map_ne {A B : ofeT} n :
Proper ((dist n ==> dist n) ==> dist n ==> dist n) (@auth_map A B).
Proof.
intros f g Hf [??] [??] [??]; split; simpl in *; [|by apply Hf].
apply option_fmap_ne; [|done]=> x y ?; by apply excl_map_ne.
Qed.
Instance auth_map_cmra_monotone {A B : ucmraT} (f : A B) :
CMRAMonotone f CMRAMonotone (auth_map f).
Proof.
split; try apply _.
- intros n [[[a|]|] b]; rewrite !auth_validN_eq; try
naive_solver eauto using cmra_monotoneN, cmra_monotone_validN.
- by intros [x a] [y b]; rewrite !auth_included /=;
intros [??]; split; simpl; apply: cmra_monotone.
Qed.
Definition authC_map {A B} (f : A -n> B) : authC A -n> authC B :=
CofeMor (auth_map f).
Lemma authC_map_ne A B n : Proper (dist n ==> dist n) (@authC_map A B).
Proof. intros f f' Hf [[[a|]|] b]; repeat constructor; apply Hf. Qed.
Program Definition authRF (F : urFunctor) : rFunctor := {|
rFunctor_car A B := authR (urFunctor_car F A B);
rFunctor_map A1 A2 B1 B2 fg := authC_map (urFunctor_map F fg)
|}.
Next Obligation.
by intros F A1 A2 B1 B2 n f g Hfg; apply authC_map_ne, urFunctor_ne.
Qed.
Next Obligation.
intros F A B x. rewrite /= -{2}(auth_map_id x).
apply auth_map_ext=>y; apply urFunctor_id.
Qed.
Next Obligation.
intros F A1 A2 A3 B1 B2 B3 f g f' g' x. rewrite /= -auth_map_compose.
apply auth_map_ext=>y; apply urFunctor_compose.
Qed.
Instance authRF_contractive F :
urFunctorContractive F rFunctorContractive (authRF F).
Proof.
by intros ? A1 A2 B1 B2 n f g Hfg; apply authC_map_ne, urFunctor_contractive.
Qed.
Program Definition authURF (F : urFunctor) : urFunctor := {|
urFunctor_car A B := authUR (urFunctor_car F A B);
urFunctor_map A1 A2 B1 B2 fg := authC_map (urFunctor_map F fg)
|}.
Next Obligation.
by intros F A1 A2 B1 B2 n f g Hfg; apply authC_map_ne, urFunctor_ne.
Qed.
Next Obligation.
intros F A B x. rewrite /= -{2}(auth_map_id x).
apply auth_map_ext=>y; apply urFunctor_id.
Qed.
Next Obligation.
intros F A1 A2 A3 B1 B2 B3 f g f' g' x. rewrite /= -auth_map_compose.
apply auth_map_ext=>y; apply urFunctor_compose.
Qed.
Instance authURF_contractive F :
urFunctorContractive F urFunctorContractive (authURF F).
Proof.
by intros ? A1 A2 B1 B2 n f g Hfg; apply authC_map_ne, urFunctor_contractive.
Qed.
From mathcomp Require Export ssreflect.
From iris.prelude Require Export prelude.
Global Set Bullet Behavior "Strict Subproofs".
Global Open Scope general_if_scope.
Ltac done := prelude.tactics.done.
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.