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/stdpp
  • johannes/stdpp
  • proux1/stdpp
  • dosualdo/stdpp
  • benoit/coq-stdpp
  • dfrumin/coq-stdpp
  • haidang/stdpp
  • amintimany/coq-stdpp
  • swasey/coq-stdpp
  • simongregersen/stdpp
  • proux/stdpp
  • janno/coq-stdpp
  • amaurremi/coq-stdpp
  • msammler/stdpp
  • tchajed/stdpp
  • YaZko/stdpp
  • maximedenes/stdpp
  • jakobbotsch/stdpp
  • Blaisorblade/stdpp
  • simonspies/stdpp
  • lepigre/stdpp
  • devilhena/stdpp
  • simonfv/stdpp
  • jihgfee/stdpp
  • snyke7/stdpp
  • Armael/stdpp
  • gmalecha/stdpp
  • olaure01/stdpp
  • sarahzrf/stdpp
  • atrieu/stdpp
  • herbelin/stdpp
  • arthuraa/stdpp
  • lgaeher/stdpp
  • mrhaandi/stdpp
  • mattam82/stdpp
  • Quarkbeast/stdpp
  • aa755/stdpp
  • gmevel/stdpp
  • lstefane/stdpp
  • jung/stdpp
  • vsiles/stdpp
  • dlesbre/stdpp
  • bergwerf/stdpp
  • marijnvanwezel/stdpp
  • ivanbakel/stdpp
  • tperami/stdpp
  • adamAndMath/stdpp
  • Villetaneuse/stdpp
  • sanjit/stdpp
  • yiyunliu/stdpp
  • thomas-lamiaux/stdpp
  • Tragicus/stdpp
  • kbedarka/stdpp
53 results
Show changes
Commits on Source (625)
...@@ -22,3 +22,5 @@ Makefile.package.* ...@@ -22,3 +22,5 @@ Makefile.package.*
html/ html/
builddep/ builddep/
_opam _opam
_build/
*.install
...@@ -6,6 +6,8 @@ stages: ...@@ -6,6 +6,8 @@ stages:
variables: variables:
CPU_CORES: "10" CPU_CORES: "10"
OCAML: "ocaml-variants.4.14.0+options ocaml-option-flambda" 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_branches: &only_branches
only: only:
...@@ -42,17 +44,13 @@ variables: ...@@ -42,17 +44,13 @@ variables:
## Build jobs ## Build jobs
build-coq.8.16.dev: # The newest version runs with timing.
build-coq.9.0.0:
<<: *template <<: *template
variables: variables:
OPAM_PINS: "coq version 8.16.dev" OPAM_PINS: "coq version 9.0.0"
DENY_WARNINGS: "1"
build-coq.8.15.0:
<<: *template
variables:
OPAM_PINS: "coq version 8.15.0"
DENY_WARNINGS: "1" DENY_WARNINGS: "1"
MANGLE_NAMES: "1"
CI_COQCHK: "1" CI_COQCHK: "1"
OPAM_PKG: "1" OPAM_PKG: "1"
DOC_DIR: "coqdoc@center.mpi-sws.org:stdpp" DOC_DIR: "coqdoc@center.mpi-sws.org:stdpp"
...@@ -60,27 +58,38 @@ build-coq.8.15.0: ...@@ -60,27 +58,38 @@ build-coq.8.15.0:
- fp-timing - fp-timing
interruptible: false interruptible: false
build-coq.8.14.1: # The newest version also runs in MRs, without timing.
build-coq.9.0.0-mr:
<<: *template <<: *template
<<: *branches_and_mr <<: *only_mr
variables: variables:
OPAM_PINS: "coq version 8.14.1" OPAM_PINS: "coq version 9.0.0"
DENY_WARNINGS: "1"
MANGLE_NAMES: "1" MANGLE_NAMES: "1"
# Also ensure Dune works (currently broken on 9.0.0).
build-coq.8.20.1-dune:
<<: *template
variables:
OPAM_PINS: "coq version 8.20.1 dune version 3.18.1"
MAKE_TARGET: "dune"
build-coq.8.20.1:
<<: *template
variables:
OPAM_PINS: "coq version 8.20.1"
DENY_WARNINGS: "1" DENY_WARNINGS: "1"
OCAML: "ocaml-base-compiler.4.07.1"
build-coq.8.13.2: build-coq.8.19.1:
<<: *template <<: *template
variables: variables:
OPAM_PINS: "coq version 8.13.2" OPAM_PINS: "coq version 8.19.1"
MANGLE_NAMES: "1"
DENY_WARNINGS: "1" DENY_WARNINGS: "1"
OCAML: "ocaml-base-compiler.4.07.1"
build-coq.8.12.2: # The oldest version runs in MRs, without name mangling.
build-coq.8.18.0:
<<: *template <<: *template
<<: *branches_and_mr <<: *branches_and_mr
variables: variables:
OPAM_PINS: "coq version 8.12.2" OPAM_PINS: "coq version 8.18.0"
DENY_WARNINGS: "1" DENY_WARNINGS: "1"
OCAML: "ocaml-base-compiler.4.07.1"
This diff is collapsed.
...@@ -3,6 +3,12 @@ all: Makefile.coq ...@@ -3,6 +3,12 @@ all: Makefile.coq
+@$(MAKE) -f Makefile.coq all +@$(MAKE) -f Makefile.coq all
.PHONY: all .PHONY: all
# Build with dune.
# This exists only for CI; you should just call `dune build` directly instead.
dune:
@dune build --display=short
.PHONY: dune
# Permit local customization # Permit local customization
-include Makefile.local -include Makefile.local
......
...@@ -4,6 +4,11 @@ NO_TEST:= ...@@ -4,6 +4,11 @@ NO_TEST:=
# use MAKE_REF=1 to generate new reference files # use MAKE_REF=1 to generate new reference files
MAKE_REF:= 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. # Run tests interleaved with main build. They have to be in the same target for this.
real-all: style $(if $(NO_TEST),,test) real-all: style $(if $(NO_TEST),,test)
...@@ -24,8 +29,6 @@ test: $(TESTFILES:.v=.vo) ...@@ -24,8 +29,6 @@ test: $(TESTFILES:.v=.vo)
.PHONY: test .PHONY: test
COQ_TEST=$(COQTOP) $(COQDEBUG) -batch -test-mode COQ_TEST=$(COQTOP) $(COQDEBUG) -batch -test-mode
# Need to make this a lazy variable (`=` instead of `:=`) since COQ_VERSION is only set later.
COQ_MINOR_VERSION=$(shell echo "$(COQ_VERSION)" | grep -E '^[0-9]+\.[0-9]+\b' -o)
tests/.coqdeps.d: $(TESTFILES) tests/.coqdeps.d: $(TESTFILES)
$(SHOW)'COQDEP TESTFILES' $(SHOW)'COQDEP TESTFILES'
...@@ -41,17 +44,16 @@ tests/.coqdeps.d: $(TESTFILES) ...@@ -41,17 +44,16 @@ tests/.coqdeps.d: $(TESTFILES)
# - Either compare the result with the reference file, or move it over the reference file. # - Either compare the result with the reference file, or move it over the reference file.
# - Cleanup, and mark as done for make. # - Cleanup, and mark as done for make.
$(TESTFILES:.v=.vo): %.vo: %.v $(if $(MAKE_REF),,%.ref) $(NORMALIZER) $(TESTFILES:.v=.vo): %.vo: %.v $(if $(MAKE_REF),,%.ref) $(NORMALIZER)
$(HIDE)if test -f $*".$(COQ_MINOR_VERSION).ref"; then \ $(HIDE)REF=$*".ref" && \
REF=$*".$(COQ_MINOR_VERSION).ref"; \ echo "COQTEST$(if $(COQ_REF),$(if $(MAKE_REF), [make ref],), [ref ignored]) $< (ref: $$REF)" && \
else \
REF=$*".ref"; \
fi && \
echo "COQTEST$(if $(MAKE_REF), [make ref],) $< (ref: $$REF)" && \
TMPFILE="$$(mktemp)" && \ TMPFILE="$$(mktemp)" && \
unset OCAMLRUNPARAM && \ unset OCAMLRUNPARAM && \
$(TIMER) $(COQ_TEST) $(COQFLAGS) $(COQLIBS) -load-vernac-source $< > "$$TMPFILE" && \ $(TIMER) $(COQ_TEST) $(COQFLAGS) $(COQLIBS) -load-vernac-source $< > "$$TMPFILE" && \
sed -f $(NORMALIZER) "$$TMPFILE" > "$$TMPFILE".new && \ sed -E -f $(NORMALIZER) "$$TMPFILE" > "$$TMPFILE".new && \
mv "$$TMPFILE".new "$$TMPFILE" && \ mv "$$TMPFILE".new "$$TMPFILE" && \
$(if $(MAKE_REF),mv "$$TMPFILE" "$$REF",diff --strip-trailing-cr -u "$$REF" "$$TMPFILE") && \ $(if $(COQ_REF),\
$(if $(MAKE_REF),mv "$$TMPFILE" "$$REF",diff --strip-trailing-cr -u "$$REF" "$$TMPFILE"), \
true \
) && \
rm -f "$$TMPFILE" && \ rm -f "$$TMPFILE" && \
touch $@ touch $@
...@@ -26,26 +26,27 @@ Importing std++ has some side effects as the library sets some global options. ...@@ -26,26 +26,27 @@ Importing std++ has some side effects as the library sets some global options.
Notably: Notably:
* `Generalizable All Variables`: This option enables implicit generalization in * `Generalizable All Variables`: This option enables implicit generalization in
arguments of the form `` `{...}`` (i.e., anonymous arguments). Unfortunately, it arguments of the form `` `{...}`` (i.e., anonymous arguments) and in terms of
also enables implicit generalization in `Instance`. We think that the fact shape `` `{}``/`` `[]``/`` `()``. See [Coq's
that both behaviors are coupled together is a manual](https://coq.inria.fr/distrib/current/refman/language/extensions/implicit-arguments.html#implicit-generalization)
[bug in Coq](https://github.com/coq/coq/issues/6030). for further details.
* The behavior of `Program` is tweaked: `Unset Transparent Obligations`, * The behavior of `Program` is tweaked: `Unset Transparent Obligations`,
`Obligation Tactic := idtac`, `Add Search Blacklist "_obligation_"`. See `Obligation Tactic := idtac`, `Add Search Blacklist "_obligation_"`. See
[`base.v`](theories/base.v) for further details. [`base.v`](theories/base.v) for further details.
* It blocks `simpl` on all operations involving integers `Z` (by setting * It blocks `simpl` on all operations involving `Z`, `N`, and `positive` (by
`Arguments op : simpl never`). We do this because `simpl` tends to expose setting `Arguments op : simpl never`). We do this because `simpl` tends to
the internals of said operations (e.g. try `simpl` on `Z.of_nat (S n) + y`). expose the internals of said operations (e.g. try `simpl` on `Z.of_nat (S n) + y`).
As a consequence of blocking `simpl`, due to * It sets `intuition_solver` to `auto`. The default is `auto with *`, which is
[Coq bug #5039](https://github.com/coq/coq/issues/5039) the `omega` tactic very expensive.
becomes unreliable. We do not consider this an issue since we use `lia` (for
which the aforementioned Coq bug was fixed) instead of `omega` everywhere.
## Prerequisites ## Prerequisites
This version is known to compile with: This version is known to compile with:
- Coq version 8.12.2 / 8.13.2 / 8.14.1 / 8.15.0 - Coq version 8.18.0 / 8.19.1 / 8.20.1 / 9.0.0
Generally we always aim to support the last two stable Coq releases. Support for
older versions will be dropped when it is convenient.
## Installing via opam ## Installing via opam
...@@ -75,6 +76,9 @@ issue tracker (also linked from the library itself) which tracks the ...@@ -75,6 +76,9 @@ issue tracker (also linked from the library itself) which tracks the
work that still needs to be done before moving the library to std++. work that still needs to be done before moving the library to std++.
No stability guarantees whatsoever are made for this package. No stability guarantees whatsoever are made for this package.
Note that the unstable package is not released, so it only exists in the
development version of std++.
## Contributing to std++ ## Contributing to std++
If you want to report a bug, please use the If you want to report a bug, please use the
...@@ -89,9 +93,12 @@ your account. Then you can fork the ...@@ -89,9 +93,12 @@ your account. Then you can fork the
[Coq-std++ git repository](https://gitlab.mpi-sws.org/iris/stdpp), make your [Coq-std++ git repository](https://gitlab.mpi-sws.org/iris/stdpp), make your
changes in your fork, and create a merge request. changes in your fork, and create a merge request.
Please refer to [our style guide](https://gitlab.mpi-sws.org/iris/iris/-/blob/master/docs/style_guide.md)
for code formatting and naming policies.
## Common problems ## Common problems
On Windows, differences in line endings may cause tests to fail. This can be On Windows, differences in line endings may cause tests to fail. This can be
fixed by setting Git's autocrlf option to true: fixed by setting Git's autocrlf option to true:
git config --global core.autocrlf true git config --global core.autocrlf true
# Search paths for all packages. They must all match the regex # Search paths for all packages. They must all match the regex
# `-Q $PACKAGE[/ ]` so that we can filter out the right ones for each package. # `-Q $PACKAGE[/ ]` so that we can filter out the right ones for each package.
-Q stdpp stdpp -Q stdpp stdpp
-Q stdpp_bitvector stdpp.bitvector
-Q stdpp_unstable stdpp.unstable -Q stdpp_unstable stdpp.unstable
# 'Global Hint Rewrite' not supported before Coq 8.14.
-arg -w -arg -deprecated-hint-rewrite-without-locality # Custom flags (to be kept in sync with the dune file at the root of the repo).
# Fixing this one requires Coq 8.15. # Fixing this one requires Coq 8.19
-arg -w -arg -deprecated-typeclasses-transparency-without-locality -arg -w -arg -argument-scope-delimiter
# Fixing this one requires Coq 8.13. # Warning seems incorrect, see https://gitlab.mpi-sws.org/iris/stdpp/-/issues/216
-arg -w -arg -deprecated-syntactic-definition -arg -w -arg -notation-incompatible-prefix
# We can't do this migration yet until we require Coq 9.0
-arg -w -arg -deprecated-from-Coq
-arg -w -arg -deprecated-dirpath-Coq
stdpp/options.v stdpp/options.v
stdpp/base.v stdpp/base.v
...@@ -48,6 +52,11 @@ stdpp/lexico.v ...@@ -48,6 +52,11 @@ stdpp/lexico.v
stdpp/propset.v stdpp/propset.v
stdpp/decidable.v stdpp/decidable.v
stdpp/list.v stdpp/list.v
stdpp/list_basics.v
stdpp/list_relations.v
stdpp/list_monad.v
stdpp/list_misc.v
stdpp/list_tactics.v
stdpp/list_numbers.v stdpp/list_numbers.v
stdpp/functions.v stdpp/functions.v
stdpp/hlist.v stdpp/hlist.v
...@@ -57,7 +66,10 @@ stdpp/nat_cancel.v ...@@ -57,7 +66,10 @@ stdpp/nat_cancel.v
stdpp/namespaces.v stdpp/namespaces.v
stdpp/telescopes.v stdpp/telescopes.v
stdpp/binders.v stdpp/binders.v
stdpp/ssreflect.v
stdpp_bitvector/definitions.v
stdpp_bitvector/tactics.v
stdpp_bitvector/bitvector.v
stdpp_unstable/bitblast.v stdpp_unstable/bitblast.v
stdpp_unstable/bitvector.v
stdpp_unstable/bitvector_tactics.v
#!/bin/bash #!/bin/sh
set -e set -e
## A simple shell script checking for some common Coq issues. ## A simple shell script checking for some common Coq issues.
FILE="$1" FILE="$1"
if grep -E -n '^\s*((Existing\s+|Program\s+|Declare\s+)?Instance|Arguments|Remove|Hint\s+(Extern|Constructors|Resolve|Immediate|Mode|Opaque|Transparent|Unfold)|(Open|Close)\s+Scope|Opaque|Transparent)\b' "$FILE"; then if grep -E -n '^\s*((Existing\s+|Program\s+|Declare\s+)?Instance|Arguments|Remove|Hint\s+(Extern|Constructors|Resolve|Immediate|Mode|Opaque|Transparent|Unfold|Rewrite)|(Open|Close)\s+Scope|Opaque|Transparent|Typeclasses (Opaque|Transparent))\b' "$FILE"; then
echo "ERROR: $FILE contains 'Instance'/'Arguments'/'Hint' or another side-effect without locality (see above)." echo "ERROR: $FILE contains 'Instance'/'Arguments'/'Hint' or another side-effect without locality (see above)."
echo "Please add 'Global' or 'Local' as appropriate." echo "Please add 'Global' or 'Local' as appropriate."
echo echo
......
opam-version: "2.0"
maintainer: "Ralf Jung <jung@mpi-sws.org>"
authors: "The std++ team"
license: "BSD-3-Clause"
homepage: "https://gitlab.mpi-sws.org/iris/stdpp"
bug-reports: "https://gitlab.mpi-sws.org/iris/stdpp/issues"
dev-repo: "git+https://gitlab.mpi-sws.org/iris/stdpp.git"
version: "dev"
synopsis: "A library for bitvectors based on std++"
description: """
This library provides the `bv n` type for representing n-bit bitvectors (i.e.,
fixed-size integers with n bits). It comes with definitions for the standard operations
(e.g., the operations exposed by SMT-LIB) and some basic automation for solving bitvector
goals based on the lia tactic.
"""
tags: [
"logpath:stdpp.bitvector"
]
depends: [
"coq-stdpp" {= version}
]
build: ["./make-package" "stdpp_bitvector" "-j%{jobs}%"]
install: ["./make-package" "stdpp_bitvector" "install"]
...@@ -18,6 +18,7 @@ tags: [ ...@@ -18,6 +18,7 @@ tags: [
depends: [ depends: [
"coq-stdpp" {= version} "coq-stdpp" {= version}
"coq-stdpp-bitvector" {= version}
] ]
build: ["./make-package" "stdpp_unstable" "-j%{jobs}%"] build: ["./make-package" "stdpp_unstable" "-j%{jobs}%"]
......
...@@ -33,7 +33,7 @@ tags: [ ...@@ -33,7 +33,7 @@ tags: [
] ]
depends: [ depends: [
"coq" { (>= "8.12" & < "8.17~") | (= "dev") } "coq" { (>= "8.18" & < "9.1~") | (= "dev") }
] ]
build: ["./make-package" "stdpp" "-j%{jobs}%"] build: ["./make-package" "stdpp" "-j%{jobs}%"]
......
Support for the dune build system
=================================
**NOTE:** in case of problem with the dune build, you can ask @lepigre or
@Blaisorblade for help.
The library can be built using dune by running `dune build`. Note that `dune`
needs to be installed separately with `opam install dune`, as it is currently
not part of the dependencies of the project.
Useful links:
- [dune documentation](https://dune.readthedocs.io)
- [coq zulip channel](https://coq.zulipchat.com/#narrow/stream/240550-Dune-devs-.26-users)
Editor support
--------------
Good dune support in editors is lacking at the moment, but there are tricks you
can play to make it work.
One option is to configure your editor to invoke the `dune coq top` command
instead of `coqtop`, but that is not easy to configure.
Another option is to change the `_CoqProject` file to something like:
```
-Q stdpp stdpp
-Q _build/default/stdpp stdpp
-Q stdpp_bitvector stdpp.bitvector
-Q _build/default/stdpp_bitvector stdpp.bitvector
-Q stdpp_unstable stdpp.unstable
-Q _build/default/stdpp_unstable stdpp.unstable
```
Note that this includes two bindings for each logical path: a binding to a
folder in the source tree (where editors will find the `.v` files), and a
binding to the same folder under `_build/default` (where editors will find
the corresponding `.vo` files). The binding for a source folder must come
before the binding for the corresponding build folder, so that editors know
to jump to source files in the source tree (and not their read-only copy in
the build folder).
If you do this, you still need to invoke `dune` manually to make sure that the
dependencies of the file you are stepping through are up-to-date. To build a
single file, you can do, e.g., `dune build stdpp/options.vo`. To build only
the `stdpp` folder, you can do `dune build stdpp`.
(env
(_ ; Applies to all profiles (dev, release, ...).
(coq
(flags ; Configure the coqc flags.
(:standard ; Keeping the default flags.
; Add custom flags (to be kept in sync with _CoqProject).
-w -argument-scope-delimiter
-w -notation-incompatible-prefix)))))
(lang dune 3.8)
(using coq 0.8)
#!/bin/bash #!/bin/sh
set -e set -e
# Helper script to build and/or install just one package out of this repository. # Helper script to build and/or install just one package out of this repository.
# Assumes that all the other packages it depends on have been installed already! # Assumes that all the other packages it depends on have been installed already!
# Make sure we get a GNU version of make.
# This is exactly how opam determines which make executable to use.
OS=$(uname)
MAKE="make"
if [ $OS == "FreeBSD" ] || [ $OS == "OpenBSD" ] ||\
[ $OS == "NetBSD" ] || [ $OS == "DragonFly" ]; then
MAKE="gmake"
fi
PROJECT="$1" PROJECT="$1"
shift shift
...@@ -26,7 +35,7 @@ grep -E "^$PROJECT/" _CoqProject >> "$COQFILE" ...@@ -26,7 +35,7 @@ grep -E "^$PROJECT/" _CoqProject >> "$COQFILE"
"${COQBIN}coq_makefile" -f "$COQFILE" -o "$MAKEFILE" "${COQBIN}coq_makefile" -f "$COQFILE" -o "$MAKEFILE"
# Run build # Run build
make -f "$MAKEFILE" "$@" $MAKE -f "$MAKEFILE" "$@"
# Cleanup # Cleanup
rm -f ".$MAKEFILE.d" "$MAKEFILE"* rm -f ".$MAKEFILE.d" "$MAKEFILE"*
This diff is collapsed.
...@@ -17,6 +17,10 @@ Global Instance boolset_intersection {A} : Intersection (boolset A) := λ X1 X2, ...@@ -17,6 +17,10 @@ Global Instance boolset_intersection {A} : Intersection (boolset A) := λ X1 X2,
BoolSet (λ x, boolset_car X1 x && boolset_car X2 x). BoolSet (λ x, boolset_car X1 x && boolset_car X2 x).
Global Instance boolset_difference {A} : Difference (boolset A) := λ X1 X2, Global Instance boolset_difference {A} : Difference (boolset A) := λ X1 X2,
BoolSet (λ x, boolset_car X1 x && negb (boolset_car X2 x)). BoolSet (λ x, boolset_car X1 x && negb (boolset_car X2 x)).
Global Instance boolset_cprod {A B} :
CProd (boolset A) (boolset B) (boolset (A * B)) := λ X1 X2,
BoolSet (λ x, boolset_car X1 x.1 && boolset_car X2 x.2).
Global Instance boolset_top_set `{EqDecision A} : TopSet A (boolset A). Global Instance boolset_top_set `{EqDecision A} : TopSet A (boolset A).
Proof. Proof.
split; [split; [split| |]|]. split; [split; [split| |]|].
...@@ -31,6 +35,19 @@ Qed. ...@@ -31,6 +35,19 @@ Qed.
Global Instance boolset_elem_of_dec {A} : RelDecision (∈@{boolset A}). Global Instance boolset_elem_of_dec {A} : RelDecision (∈@{boolset A}).
Proof. refine (λ x X, cast_if (decide (boolset_car X x))); done. Defined. Proof. refine (λ x X, cast_if (decide (boolset_car X x))); done. Defined.
Typeclasses Opaque boolset_elem_of. Lemma elem_of_boolset_cprod {A B} (X1 : boolset A) (X2 : boolset B) (x : A * B) :
x cprod X1 X2 x.1 X1 x.2 X2.
Proof. apply andb_True. Qed.
Global Instance set_unfold_boolset_cprod {A B} (X1 : boolset A) (X2 : boolset B) x P Q :
SetUnfoldElemOf x.1 X1 P SetUnfoldElemOf x.2 X2 Q
SetUnfoldElemOf x (cprod X1 X2) (P Q).
Proof.
intros ??; constructor.
by rewrite elem_of_boolset_cprod, (set_unfold_elem_of x.1 X1 P),
(set_unfold_elem_of x.2 X2 Q).
Qed.
Global Typeclasses Opaque boolset_elem_of.
Global Opaque boolset_empty boolset_singleton boolset_union Global Opaque boolset_empty boolset_singleton boolset_union
boolset_intersection boolset_difference. boolset_intersection boolset_difference boolset_cprod.
...@@ -192,5 +192,5 @@ Lemma elem_of_coGset_to_top_set `{Countable A, TopSet A C} X x : ...@@ -192,5 +192,5 @@ Lemma elem_of_coGset_to_top_set `{Countable A, TopSet A C} X x :
x ∈@{C} coGset_to_top_set X x X. x ∈@{C} coGset_to_top_set X x X.
Proof. destruct X; set_solver. Qed. Proof. destruct X; set_solver. Qed.
Typeclasses Opaque coGset_elem_of coGset_empty coGset_top coGset_singleton. Global Typeclasses Opaque coGset_elem_of coGset_empty coGset_top coGset_singleton.
Typeclasses Opaque coGset_union coGset_intersection coGset_difference. Global Typeclasses Opaque coGset_union coGset_intersection coGset_difference.
...@@ -30,6 +30,13 @@ Fixpoint coPset_wf (t : coPset_raw) : bool := ...@@ -30,6 +30,13 @@ Fixpoint coPset_wf (t : coPset_raw) : bool :=
end. end.
Global Arguments coPset_wf !_ / : simpl nomatch, assert. Global Arguments coPset_wf !_ / : simpl nomatch, assert.
Lemma coPNode_wf b l r :
coPset_wf l coPset_wf r
(l = coPLeaf true r = coPLeaf true b = true False)
(l = coPLeaf false r = coPLeaf false b = false False)
coPset_wf (coPNode b l r).
Proof. destruct b, l as [[]|], r as [[]|]; naive_solver. Qed.
Lemma coPNode_wf_l b l r : coPset_wf (coPNode b l r) coPset_wf l. Lemma coPNode_wf_l b l r : coPset_wf (coPNode b l r) coPset_wf l.
Proof. destruct b, l as [[]|],r as [[]|]; simpl; rewrite ?andb_True; tauto. Qed. Proof. destruct b, l as [[]|],r as [[]|]; simpl; rewrite ?andb_True; tauto. Qed.
Lemma coPNode_wf_r b l r : coPset_wf (coPNode b l r) coPset_wf r. Lemma coPNode_wf_r b l r : coPset_wf (coPNode b l r) coPset_wf r.
...@@ -43,9 +50,9 @@ Definition coPNode' (b : bool) (l r : coPset_raw) : coPset_raw := ...@@ -43,9 +50,9 @@ Definition coPNode' (b : bool) (l r : coPset_raw) : coPset_raw :=
| _, _, _ => coPNode b l r | _, _, _ => coPNode b l r
end. end.
Global Arguments coPNode' : simpl never. Global Arguments coPNode' : simpl never.
Lemma coPNode_wf b l r : coPset_wf l coPset_wf r coPset_wf (coPNode' b l r). Lemma coPNode'_wf b l r : coPset_wf l coPset_wf r coPset_wf (coPNode' b l r).
Proof. destruct b, l as [[]|], r as [[]|]; simpl; auto. Qed. Proof. destruct b, l as [[]|], r as [[]|]; simpl; auto. Qed.
Global Hint Resolve coPNode_wf : core. Global Hint Resolve coPNode'_wf : core.
Fixpoint coPset_elem_of_raw (p : positive) (t : coPset_raw) {struct t} : bool := Fixpoint coPset_elem_of_raw (p : positive) (t : coPset_raw) {struct t} : bool :=
match t, p with match t, p with
...@@ -221,7 +228,7 @@ Proof. ...@@ -221,7 +228,7 @@ Proof.
unfold set_finite, elem_of at 1, coPset_elem_of; simpl; clear Ht; split. unfold set_finite, elem_of at 1, coPset_elem_of; simpl; clear Ht; split.
- induction t as [b|b l IHl r IHr]; simpl. - induction t as [b|b l IHl r IHr]; simpl.
{ destruct b; simpl; [intros [l Hl]|done]. { destruct b; simpl; [intros [l Hl]|done].
by apply (is_fresh (list_to_set l : Pset)), elem_of_list_to_set, Hl. } by apply (infinite_is_fresh l), Hl. }
intros [ll Hll]; rewrite andb_True; split. intros [ll Hll]; rewrite andb_True; split.
+ apply IHl; exists (omap (maybe (~0)) ll); intros i. + apply IHl; exists (omap (maybe (~0)) ll); intros i.
rewrite elem_of_list_omap; intros; exists (i~0); auto. rewrite elem_of_list_omap; intros; exists (i~0); auto.
...@@ -272,73 +279,91 @@ Proof. ...@@ -272,73 +279,91 @@ Proof.
Qed. Qed.
(** * Conversion to psets *) (** * Conversion to psets *)
Fixpoint coPset_to_Pset_raw (t : coPset_raw) : Pmap_raw () := Fixpoint coPset_to_Pset_raw (t : coPset_raw) : Pmap () :=
match t with match t with
| coPLeaf _ => PLeaf | coPLeaf _ => PEmpty
| coPNode false l r => PNode' None (coPset_to_Pset_raw l) (coPset_to_Pset_raw r) | coPNode false l r => pmap.PNode (coPset_to_Pset_raw l) None (coPset_to_Pset_raw r)
| coPNode true l r => PNode (Some ()) (coPset_to_Pset_raw l) (coPset_to_Pset_raw r) | coPNode true l r => pmap.PNode (coPset_to_Pset_raw l) (Some ()) (coPset_to_Pset_raw r)
end. end.
Lemma coPset_to_Pset_wf t : coPset_wf t Pmap_wf (coPset_to_Pset_raw t).
Proof. induction t as [|[]]; simpl; eauto using PNode_wf. Qed.
Definition coPset_to_Pset (X : coPset) : Pset := Definition coPset_to_Pset (X : coPset) : Pset :=
let (t,Ht) := X in Mapset (PMap (coPset_to_Pset_raw t) (coPset_to_Pset_wf _ Ht)). let (t,Ht) := X in Mapset (coPset_to_Pset_raw t).
Lemma elem_of_coPset_to_Pset X i : set_finite X i coPset_to_Pset X i X. Lemma elem_of_coPset_to_Pset X i : set_finite X i coPset_to_Pset X i X.
Proof. Proof.
rewrite coPset_finite_spec; destruct X as [t Ht]. rewrite coPset_finite_spec; destruct X as [t Ht].
change (coPset_finite t coPset_to_Pset_raw t !! i = Some () e_of i t). change (coPset_finite t coPset_to_Pset_raw t !! i = Some () e_of i t).
clear Ht; revert i; induction t as [[]|[] l IHl r IHr]; intros [i|i|]; clear Ht; revert i; induction t as [[]|[] l IHl r IHr]; intros [i|i|];
simpl; rewrite ?andb_True, ?PNode_lookup; naive_solver. simpl; rewrite ?andb_True, ?pmap.Pmap_lookup_PNode; naive_solver.
Qed. Qed.
(** * Conversion from psets *) (** * Conversion from psets *)
Fixpoint Pset_to_coPset_raw (t : Pmap_raw ()) : coPset_raw := Definition Pset_to_coPset_raw_aux (go : Pmap_ne () coPset_raw)
match t with (mt : Pmap ()) : coPset_raw :=
| PLeaf => coPLeaf false match mt with PNodes t => go t | PEmpty => coPLeaf false end.
| PNode None l r => coPNode false (Pset_to_coPset_raw l) (Pset_to_coPset_raw r) Fixpoint Pset_ne_to_coPset_raw (t : Pmap_ne ()) : coPset_raw :=
| PNode (Some _) l r => coPNode true (Pset_to_coPset_raw l) (Pset_to_coPset_raw r) pmap.Pmap_ne_case t $ λ ml mx mr,
end. coPNode match mx with Some _ => true | None => false end
Lemma Pset_to_coPset_wf t : Pmap_wf t coPset_wf (Pset_to_coPset_raw t). (Pset_to_coPset_raw_aux Pset_ne_to_coPset_raw ml)
(Pset_to_coPset_raw_aux Pset_ne_to_coPset_raw mr).
Definition Pset_to_coPset_raw : Pmap () coPset_raw :=
Pset_to_coPset_raw_aux Pset_ne_to_coPset_raw.
Lemma Pset_to_coPset_raw_PNode ml mx mr :
pmap.PNode_valid ml mx mr
Pset_to_coPset_raw (pmap.PNode ml mx mr) =
coPNode match mx with Some _ => true | None => false end
(Pset_to_coPset_raw ml) (Pset_to_coPset_raw mr).
Proof. by destruct ml, mx, mr. Qed.
Lemma Pset_to_coPset_raw_wf t : coPset_wf (Pset_to_coPset_raw t).
Proof. Proof.
induction t as [|[] l IHl r IHr]; simpl; rewrite ?andb_True; auto. induction t as [|ml mx mr] using pmap.Pmap_ind; [done|].
- intros [??]; destruct l as [|[]], r as [|[]]; simpl in *; auto. rewrite Pset_to_coPset_raw_PNode by done.
- destruct l as [|[]], r as [|[]]; simpl in *; rewrite ?andb_true_r; apply coPNode_wf; [done|done|..];
rewrite ?andb_True; rewrite ?andb_True in IHl, IHr; intuition. destruct mx; destruct ml using pmap.Pmap_ind; destruct mr using pmap.Pmap_ind;
rewrite ?Pset_to_coPset_raw_PNode by done; naive_solver.
Qed. Qed.
Lemma elem_of_Pset_to_coPset_raw i t : e_of i (Pset_to_coPset_raw t) t !! i = Some (). Lemma elem_of_Pset_to_coPset_raw i t : e_of i (Pset_to_coPset_raw t) t !! i = Some ().
Proof. by revert i; induction t as [|[[]|]]; intros []; simpl; auto; split. Qed. Proof.
revert i. induction t as [|ml mx mr] using pmap.Pmap_ind; [done|].
intros []; rewrite Pset_to_coPset_raw_PNode,
pmap.Pmap_lookup_PNode by done; destruct mx as [[]|]; naive_solver.
Qed.
Lemma Pset_to_coPset_raw_finite t : coPset_finite (Pset_to_coPset_raw t). Lemma Pset_to_coPset_raw_finite t : coPset_finite (Pset_to_coPset_raw t).
Proof. induction t as [|[[]|]]; simpl; rewrite ?andb_True; auto. Qed. Proof.
induction t as [|ml mx mr] using pmap.Pmap_ind; [done|].
rewrite Pset_to_coPset_raw_PNode by done. destruct mx; naive_solver.
Qed.
Definition Pset_to_coPset (X : Pset) : coPset := Definition Pset_to_coPset (X : Pset) : coPset :=
let 'Mapset (PMap t Ht) := X in Pset_to_coPset_raw t Pset_to_coPset_wf _ Ht. let 'Mapset t := X in Pset_to_coPset_raw t Pset_to_coPset_raw_wf _.
Lemma elem_of_Pset_to_coPset X i : i Pset_to_coPset X i X. Lemma elem_of_Pset_to_coPset X i : i Pset_to_coPset X i X.
Proof. destruct X as [[t ?]]; apply elem_of_Pset_to_coPset_raw. Qed. Proof. destruct X; apply elem_of_Pset_to_coPset_raw. Qed.
Lemma Pset_to_coPset_finite X : set_finite (Pset_to_coPset X). Lemma Pset_to_coPset_finite X : set_finite (Pset_to_coPset X).
Proof. Proof. apply coPset_finite_spec; destruct X; apply Pset_to_coPset_raw_finite. Qed.
apply coPset_finite_spec; destruct X as [[t ?]]; apply Pset_to_coPset_raw_finite.
Qed.
(** * Conversion to and from gsets of positives *) (** * Conversion to and from gsets of positives *)
Lemma coPset_to_gset_wf (m : Pmap ()) : gmap_wf positive m.
Proof. unfold gmap_wf. by rewrite bool_decide_spec. Qed.
Definition coPset_to_gset (X : coPset) : gset positive := Definition coPset_to_gset (X : coPset) : gset positive :=
let 'Mapset m := coPset_to_Pset X in let 'Mapset m := coPset_to_Pset X in
Mapset (GMap m (coPset_to_gset_wf m)). Mapset (pmap_to_gmap m).
Definition gset_to_coPset (X : gset positive) : coPset := Definition gset_to_coPset (X : gset positive) : coPset :=
let 'Mapset (GMap (PMap t Ht) _) := X in Pset_to_coPset_raw t Pset_to_coPset_wf _ Ht. let 'Mapset m := X in
Pset_to_coPset_raw (gmap_to_pmap m) Pset_to_coPset_raw_wf _.
Lemma elem_of_coPset_to_gset X i : set_finite X i coPset_to_gset X i X. Lemma elem_of_coPset_to_gset X i : set_finite X i coPset_to_gset X i X.
Proof. Proof.
intros ?. rewrite <-elem_of_coPset_to_Pset by done. intros ?. rewrite <-elem_of_coPset_to_Pset by done. destruct X as [X ?].
unfold coPset_to_gset. by destruct (coPset_to_Pset X). unfold elem_of, gset_elem_of, mapset_elem_of, coPset_to_gset; simpl.
by rewrite lookup_pmap_to_gmap.
Qed. Qed.
Lemma elem_of_gset_to_coPset X i : i gset_to_coPset X i X. Lemma elem_of_gset_to_coPset X i : i gset_to_coPset X i X.
Proof. destruct X as [[[t ?]]]; apply elem_of_Pset_to_coPset_raw. Qed. Proof.
destruct X as [m]. unfold elem_of, coPset_elem_of; simpl.
by rewrite elem_of_Pset_to_coPset_raw, lookup_gmap_to_pmap.
Qed.
Lemma gset_to_coPset_finite X : set_finite (gset_to_coPset X). Lemma gset_to_coPset_finite X : set_finite (gset_to_coPset X).
Proof. Proof.
apply coPset_finite_spec; destruct X as [[[t ?]]]; apply Pset_to_coPset_raw_finite. apply coPset_finite_spec; destruct X as [[?]]; apply Pset_to_coPset_raw_finite.
Qed. Qed.
(** * Infinite sets *) (** * Infinite sets *)
......
...@@ -61,10 +61,9 @@ Section choice. ...@@ -61,10 +61,9 @@ Section choice.
{ intros help. by apply (help (encode x)). } { intros help. by apply (help (encode x)). }
intros i. induction i as [|i IH] using Pos.peano_ind; intros p ??. intros i. induction i as [|i IH] using Pos.peano_ind; intros p ??.
{ constructor. intros j. assert (p = encode x) by lia; subst. { constructor. intros j. assert (p = encode x) by lia; subst.
inversion 1 as [? Hd|?? Hd]; subst; inv 1 as [? Hd|?? Hd]; rewrite decode_encode in Hd; congruence. }
rewrite decode_encode in Hd; congruence. }
constructor. intros j. constructor. intros j.
inversion 1 as [? Hd|? y Hd]; subst; auto with lia. inv 1 as [? Hd|? y Hd]; auto with lia.
Qed. Qed.
Context `{ x, Decision (P x)}. Context `{ x, Decision (P x)}.
...@@ -295,16 +294,16 @@ Qed. ...@@ -295,16 +294,16 @@ Qed.
Global Program Instance Qp_countable : Countable Qp := Global Program Instance Qp_countable : Countable Qp :=
inj_countable inj_countable
Qp_to_Qc Qp_to_Qc
(λ p : Qc, guard (0 < p)%Qc as Hp; Some (mk_Qp p Hp)) _. (λ p : Qc, Hp guard (0 < p)%Qc; Some (mk_Qp p Hp)) _.
Next Obligation. Next Obligation.
intros [p Hp]. unfold mguard, option_guard; simpl. intros [p Hp]. case_guard; simplify_eq/=; [|done].
case_match; [|done]. f_equal. by apply Qp.to_Qc_inj_iff. f_equal. by apply Qp.to_Qc_inj_iff.
Qed. Qed.
Global Program Instance fin_countable n : Countable (fin n) := Global Program Instance fin_countable n : Countable (fin n) :=
inj_countable inj_countable
fin_to_nat fin_to_nat
(λ m : nat, guard (m < n)%nat as Hm; Some (nat_to_fin Hm)) _. (λ m : nat, Hm guard (m < n)%nat; Some (nat_to_fin Hm)) _.
Next Obligation. Next Obligation.
intros n i; simplify_option_eq. intros n i; simplify_option_eq.
- by rewrite nat_to_fin_to_nat. - by rewrite nat_to_fin_to_nat.
...@@ -314,6 +313,18 @@ Qed. ...@@ -314,6 +313,18 @@ Qed.
(** ** Generic trees *) (** ** Generic trees *)
Local Close Scope positive. Local Close Scope positive.
(** This type can help you construct a [Countable] instance for an arbitrary
(even recursive) inductive datatype. The idea is tht you make [T] something like
[T1 + T2 + ...], covering all the data types that can be contained inside your
type.
- Each non-recursive constructor to a [GenLeaf]. Different constructors must use
different variants of [T] to ensure they remain distinguishable!
- Each recursive constructor to a [GenNode] where the [nat] is a (typically
small) constant representing the constructor itself, and then all the data in
the constructor (recursive or otherwise) is put into child nodes.
This data type is the same as [GenTree.tree] in mathcomp, see
https://github.com/math-comp/math-comp/blob/master/ssreflect/choice.v *)
Inductive gen_tree (T : Type) : Type := Inductive gen_tree (T : Type) : Type :=
| GenLeaf : T gen_tree T | GenLeaf : T gen_tree T
| GenNode : nat list (gen_tree T) gen_tree T. | GenNode : nat list (gen_tree T) gen_tree T.
...@@ -355,8 +366,8 @@ Proof. ...@@ -355,8 +366,8 @@ Proof.
- rewrite <-(assoc_L _). revert k. generalize ([inl (length ts, n)] ++ l). - rewrite <-(assoc_L _). revert k. generalize ([inl (length ts, n)] ++ l).
induction ts as [|t ts'' IH]; intros k ts'''; csimpl; auto. induction ts as [|t ts'' IH]; intros k ts'''; csimpl; auto.
rewrite reverse_cons, <-!(assoc_L _), FIX; simpl; auto. rewrite reverse_cons, <-!(assoc_L _), FIX; simpl; auto.
- simpl. by rewrite take_app_alt, drop_app_alt, reverse_involutive - simpl. by rewrite take_app_length', drop_app_length', reverse_involutive
by (by rewrite reverse_length). by (by rewrite length_reverse).
Qed. Qed.
Global Program Instance gen_tree_countable `{Countable T} : Countable (gen_tree T) := Global Program Instance gen_tree_countable `{Countable T} : Countable (gen_tree T) :=
...@@ -370,7 +381,7 @@ Qed. ...@@ -370,7 +381,7 @@ Qed.
Global Program Instance countable_sig `{Countable A} (P : A Prop) Global Program Instance countable_sig `{Countable A} (P : A Prop)
`{!∀ x, Decision (P x), !∀ x, ProofIrrel (P x)} : `{!∀ x, Decision (P x), !∀ x, ProofIrrel (P x)} :
Countable { x : A | P x } := Countable { x : A | P x } :=
inj_countable proj1_sig (λ x, guard (P x) as Hx; Some (x Hx)) _. inj_countable proj1_sig (λ x, Hx guard (P x); Some (x Hx)) _.
Next Obligation. Next Obligation.
intros A ?? P ?? [x Hx]. by erewrite (option_guard_True_pi (P x)). intros A ?? P ?? [x Hx]. by erewrite (option_guard_True_pi (P x)).
Qed. Qed.