aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE.md21
-rw-r--r--.gitlab-ci.yml39
-rw-r--r--.travis.yml116
-rw-r--r--CHANGES.md33
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--INSTALL14
-rw-r--r--Makefile3
-rw-r--r--Makefile.build2
-rw-r--r--README.md4
-rw-r--r--default.nix6
-rwxr-xr-xdev/build/windows/makecoq_mingw.sh3
-rw-r--r--dev/ci/README-developers.md6
-rwxr-xr-xdev/ci/ci-wrapper.sh10
-rw-r--r--dev/ci/user-overlays/09263-maximedenes-parsing-state.sh12
-rw-r--r--dev/doc/MERGING.md2
-rw-r--r--dev/doc/profiling.txt6
-rw-r--r--dev/doc/release-process.md58
-rw-r--r--dev/doc/versions-history.tex2
-rwxr-xr-xdev/tools/merge-pr.sh2
-rwxr-xr-xdev/tools/update-compat.py245
-rw-r--r--doc/common/macros.tex10
-rw-r--r--doc/sphinx/addendum/parallel-proof-processing.rst54
-rw-r--r--doc/sphinx/language/cic.rst301
-rw-r--r--doc/sphinx/language/gallina-extensions.rst3
-rw-r--r--doc/sphinx/practical-tools/coq-commands.rst16
-rw-r--r--doc/sphinx/proof-engine/ssreflect-proof-language.rst77
-rw-r--r--doc/sphinx/proof-engine/tactics.rst2
-rw-r--r--doc/sphinx/refman-preamble.sty10
-rw-r--r--doc/sphinx/user-extensions/syntax-extensions.rst5
-rw-r--r--doc/stdlib/index-list.html.template1
-rw-r--r--dune2
-rw-r--r--ide/fake_ide.ml7
-rw-r--r--ide/idetop.ml32
-rw-r--r--interp/constrextern.ml9
-rw-r--r--lib/flags.ml6
-rw-r--r--lib/flags.mli2
-rw-r--r--lib/stateid.ml2
-rw-r--r--lib/stateid.mli1
-rw-r--r--man/coqtop.118
-rw-r--r--parsing/pcoq.ml1
-rw-r--r--parsing/pcoq.mli14
-rw-r--r--plugins/derive/g_derive.mlg2
-rw-r--r--plugins/funind/g_indfun.mlg2
-rw-r--r--plugins/ltac/g_ltac.mlg11
-rw-r--r--plugins/ltac/g_obligations.mlg2
-rw-r--r--plugins/ltac/g_rewrite.mlg4
-rw-r--r--plugins/nsatz/Nsatz.v3
-rw-r--r--plugins/setoid_ring/Ncring_initial.v1
-rw-r--r--plugins/setoid_ring/Ncring_tac.v18
-rw-r--r--plugins/setoid_ring/Rings_Q.v1
-rw-r--r--plugins/setoid_ring/Rings_R.v1
-rw-r--r--plugins/ssr/ssrast.mli14
-rw-r--r--plugins/ssr/ssrcommon.ml2
-rw-r--r--plugins/ssr/ssrcommon.mli2
-rw-r--r--plugins/ssr/ssrfwd.ml26
-rw-r--r--plugins/ssr/ssrfwd.mli6
-rw-r--r--plugins/ssr/ssripats.ml251
-rw-r--r--plugins/ssr/ssripats.mli38
-rw-r--r--plugins/ssr/ssrparser.mlg54
-rw-r--r--plugins/ssr/ssrprinters.ml10
-rw-r--r--plugins/ssr/ssrprinters.mli1
-rw-r--r--plugins/ssr/ssrview.ml9
-rw-r--r--plugins/syntax/numeral.ml100
-rw-r--r--printing/prettyp.ml2
-rw-r--r--proofs/proof_global.ml92
-rw-r--r--proofs/proof_global.mli45
-rw-r--r--stm/stm.ml485
-rw-r--r--stm/stm.mli13
-rw-r--r--stm/vernac_classifier.ml28
-rw-r--r--test-suite/Makefile37
-rw-r--r--test-suite/bugs/closed/HoTT_coq_056.v4
-rw-r--r--test-suite/bugs/closed/bug_3324.v4
-rw-r--r--test-suite/bugs/closed/bug_3454.v6
-rw-r--r--test-suite/bugs/closed/bug_3682.v2
-rw-r--r--test-suite/bugs/closed/bug_4782.v4
-rw-r--r--test-suite/bugs/closed/bug_4798.v2
-rw-r--r--test-suite/bugs/closed/bug_4836.v2
-rw-r--r--test-suite/bugs/closed/bug_5401.v2
-rw-r--r--test-suite/bugs/closed/bug_7811.v2
-rw-r--r--test-suite/bugs/closed/bug_9166.v2
-rw-r--r--test-suite/complexity/constructor.v1
-rw-r--r--test-suite/complexity/f_equal.v1
-rw-r--r--test-suite/complexity/injection.v1
-rw-r--r--test-suite/complexity/ring.v1
-rw-r--r--test-suite/complexity/ring2.v1
-rw-r--r--test-suite/complexity/setoid_rewrite.v1
-rw-r--r--test-suite/complexity/unification.v1
-rw-r--r--test-suite/ide/debug_ltac.fake2
-rwxr-xr-xtest-suite/misc/4722.sh6
-rwxr-xr-xtest-suite/misc/7704.sh2
-rw-r--r--test-suite/misc/aux7704.v1
-rwxr-xr-xtest-suite/misc/deps-checksum.sh2
-rwxr-xr-xtest-suite/misc/deps-order.sh6
-rwxr-xr-xtest-suite/misc/deps-utf8.sh2
-rw-r--r--test-suite/output/Arguments_renaming.out2
-rw-r--r--test-suite/output/Binder.out4
-rw-r--r--test-suite/output/Cases.out13
-rw-r--r--test-suite/output/FunExt.v1
-rw-r--r--test-suite/output/Implicit.out1
-rw-r--r--test-suite/output/Load.out4
-rw-r--r--test-suite/output/Notations3.out5
-rw-r--r--test-suite/output/Notations4.out6
-rw-r--r--test-suite/output/Notations4.v16
-rw-r--r--test-suite/output/PatternsInBinders.out12
-rw-r--r--test-suite/output/PrintInfos.out2
-rw-r--r--test-suite/output/RecognizePluginWarning.v2
-rw-r--r--test-suite/output/Show.v2
-rw-r--r--test-suite/output/StringSyntax.out3
-rw-r--r--test-suite/output/TranspModtype.out8
-rw-r--r--test-suite/output/UnclosedBlocks.v1
-rw-r--r--test-suite/output/UnivBinders.out34
-rw-r--r--test-suite/output/UsePluginWarning.v3
-rw-r--r--test-suite/output/goal_output.out4
-rw-r--r--test-suite/output/inference.out2
-rw-r--r--test-suite/output/simpl.v1
-rw-r--r--test-suite/output/unifconstraints.v1
-rwxr-xr-xtest-suite/report.sh16
-rw-r--r--test-suite/ssr/ipat_replace.v17
-rw-r--r--test-suite/success/CompatCurrentFlag.v4
-rw-r--r--test-suite/success/CompatOldFlag.v4
-rw-r--r--test-suite/success/CompatOldOldFlag.v6
-rw-r--r--test-suite/success/CompatPreviousFlag.v4
-rw-r--r--test-suite/success/Typeclasses.v12
-rw-r--r--test-suite/success/auto.v10
-rw-r--r--test-suite/success/bteauto.v8
-rw-r--r--test-suite/success/destruct.v2
-rw-r--r--test-suite/success/eauto.v12
-rw-r--r--test-suite/success/setoid_test2.v4
-rwxr-xr-xtest-suite/tools/update-compat/run.sh2
-rw-r--r--theories/Classes/CRelationClasses.v7
-rw-r--r--theories/Classes/RelationClasses.v4
-rw-r--r--theories/Classes/RelationPairs.v3
-rw-r--r--theories/Classes/SetoidTactics.v1
-rw-r--r--theories/Compat/Coq810.v11
-rw-r--r--theories/Compat/Coq89.v2
-rw-r--r--theories/Init/Decimal.v5
-rw-r--r--theories/Numbers/BinNums.v1
-rw-r--r--tools/coq_dune.ml2
-rw-r--r--tools/coqc.ml39
-rw-r--r--toplevel/coqargs.ml19
-rw-r--r--toplevel/coqloop.ml23
-rw-r--r--toplevel/g_toplevel.mlg18
-rw-r--r--toplevel/usage.ml45
-rw-r--r--toplevel/usage.mli3
-rw-r--r--toplevel/vernac.ml74
-rw-r--r--vernac/classes.ml4
-rw-r--r--vernac/g_vernac.mlg3
-rw-r--r--vernac/lemmas.ml2
-rw-r--r--vernac/pvernac.ml38
-rw-r--r--vernac/pvernac.mli28
-rw-r--r--vernac/vernacentries.ml43
-rw-r--r--vernac/vernacentries.mli5
-rw-r--r--vernac/vernacextend.ml6
-rw-r--r--vernac/vernacextend.mli6
-rw-r--r--vernac/vernacstate.ml32
-rw-r--r--vernac/vernacstate.mli17
156 files changed, 1763 insertions, 1383 deletions
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index c9cb516cd3..aec6cd0a21 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,18 +1,11 @@
-<!-- Thank you for your contribution.
- Please complete the following information when reporting a bug. -->
+<!-- Thank you for reporting a bug to Coq! -->
-#### Version
-
-<!-- You can get this information by running `coqtop -v`. -->
-
-
-#### Operating system
+#### Description of the problem
+<!-- If you can, it's helpful to provide self-contained example of some code
+that reproduces the bug. If not, a link to a larger example is also helpful. -->
-#### Description of the problem
+#### Coq Version
-<!-- It is helpful to provide enough information so that we can reproduce the bug.
- In particular, please include a code example which produces it.
- If the example is small, you can include it here between ``` ```.
- Otherwise, please provide a link to a repository, a gist (https://gist.github.com)
- or drag-and-drop a `.zip` archive. -->
+<!-- You can get this information by running `coqtop -v`. If relevant, please
+also include your operating system. -->
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e981c592a2..a6858c6802 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -288,16 +288,15 @@ pkg:opam:
variables:
OPAM_SWITCH: edge
-pkg:nix:
+.nix-template: &nix-template
image: nixorg/nix:latest # Minimal NixOS image which doesn't even contain git
stage: test
variables:
# By default we use coq.cachix.org as an extra substituter but this can be overridden
EXTRA_SUBSTITUTERS: https://coq.cachix.org
- EXTRA_PUBLIC_KEYS: coq.cachix.org-1:Jgt0DwGAUo+wpxCM52k2V+E0hLoOzFPzvg94F65agtI=
+ EXTRA_PUBLIC_KEYS: coq.cachix.org-1:5QW/wwEnD+l2jvN6QRbRRsa4hBHG3QiQQ26cxu1F5tI=
# The following variables should not be overridden
GIT_STRATEGY: none
- CACHIX_PUBLIC_KEY: cachix.cachix.org-1:eWNHQldwUO7G2VkjpnjDbWwy4KQ/HNxht7H4SSoMckM=
NIXOS_PUBLIC_KEY: cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
dependencies: [] # We don't need to download build artifacts
@@ -305,8 +304,6 @@ pkg:nix:
script:
# Use current worktree as tmpdir to allow exporting artifacts in case of failure
- export TMPDIR=$PWD
- # Install Cachix as documented at https://github.com/cachix/cachix
- - nix-env -if https://github.com/cachix/cachix/tarball/master --substituters https://cachix.cachix.org --trusted-public-keys "$CACHIX_PUBLIC_KEY"
# We build an expression rather than a direct URL to not be dependent on
# the URL location; we are forced to put the public key of cache.nixos.org
# because there is no --extra-trusted-public-key option.
@@ -317,6 +314,24 @@ pkg:nix:
paths:
- nix-build-coq.drv-0/*/test-suite/logs
+pkg:nix:deploy:
+ <<: *nix-template
+ environment:
+ name: cachix
+ url: https://coq.cachix.org
+ before_script:
+ # Install Cachix as documented at https://github.com/cachix/cachix
+ - nix-env -iA cachix -f https://cachix.org/api/v1/install
+ only:
+ - master
+ - /^v.*\..*$/
+
+pkg:nix:
+ <<: *nix-template
+ except:
+ - master
+ - /^v.*\..*$/
+
doc:refman:
<<: *doc-template
dependencies:
@@ -386,11 +401,11 @@ test-suite:edge+trunk+make:
stage: test
dependencies: []
script:
- - opam switch create 4.08.0 --empty
+ - opam switch create 4.09.0 --empty
- eval $(opam env)
- - opam repo add ocaml-pr https://github.com/ocaml/ocaml-pr-repository.git
+ - opam repo add ocaml-beta https://github.com/ocaml/ocaml-beta-repository.git
- opam update
- - opam install ocaml-variants=4.08.0 num
+ - opam install ocaml-variants=4.09.0+trunk num
- eval $(opam env)
# We avoid problems with warnings:
- ./configure -profile devel -warn-error no
@@ -410,18 +425,18 @@ test-suite:edge+trunk+dune:
stage: test
dependencies: []
script:
- - opam switch create 4.08.0 --empty
+ - opam switch create 4.09.0 --empty
- eval $(opam env)
- - opam repo add ocaml-pr https://github.com/ocaml/ocaml-pr-repository.git
+ - opam repo add ocaml-beta https://github.com/ocaml/ocaml-beta-repository.git
- opam update
- - opam install ocaml-variants=4.08.0 num
+ - opam install ocaml-variants=4.09.0+trunk num
- opam pin add dune --dev # ounit lablgtk conf-gtksourceview
- opam install dune
- eval $(opam env)
# We use the release profile to avoid problems with warnings
- make -f Makefile.dune trunk
- export COQ_UNIT_TEST=noop
- - dune runtest --profile=ocaml408
+ - dune runtest --profile=ocaml409
variables:
OPAM_SWITCH: edge
artifacts:
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 855d36048d..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,116 +0,0 @@
-dist: trusty
-
-# Travis builds are slower using sudo: false (the container-based
-# infrastructure) as of March 2017; see
-# https://github.com/coq/coq/pull/467 for some discussion.
-sudo: required
-
-# Until Ocaml becomes a language, we set a known one.
-language: c
-
-cache:
- directories:
- - $HOME/.opam
-
-before_cache:
- - rm -rf ~/.opam/log/
-
-env:
- global:
- - NJOBS=2
- - COMPILER="4.07.0"
- - DUNE_VER=".1.2.1"
- - FINDLIB_VER=".1.8.0"
- - LABLGTK="lablgtk.2.18.6 conf-gtksourceview.2"
- - NATIVE_COMP="yes"
- - COQ_DEST="-local"
- - MAIN_TARGET="world"
-
-matrix:
- include:
- - os: osx
- env:
- - TEST_TARGET="test-suite"
- - NATIVE_COMP="no"
- - COQ_DEST="-local"
- - EXTRA_OPAM="ounit"
- before_install:
- - brew update
- - brew unlink python
- - brew install gnu-time
- # only way to continue using OPAM 1.2
- - brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/d156edeeed7291f4bc1e08620b331bbd05d52b78/Formula/opam.rb
- - opam init -j "$NJOBS" --compiler="$COMPILER" -n -y
- - opam switch "$COMPILER" && opam update
- - eval $(opam config env)
- - opam config list
- - opam install -j "$NJOBS" -y num ocamlfind${FINDLIB_VER} dune${DUNE_VER} ${EXTRA_OPAM}
- - opam list
-
- - if: NOT (type = pull_request)
- os: osx
- osx_image: xcode7.3
- env:
- - TEST_TARGET=""
- - NATIVE_COMP="no"
- - COQ_DEST="-prefix $PWD/_install_ci"
- - EXTRA_CONF="-coqide opt -warn-error yes"
- - EXTRA_OPAM="$LABLGTK"
- before_install:
- - brew update
- - brew unlink python
- - brew install gnu-time gtk+ expat gtksourceview gdk-pixbuf
- # only way to continue using OPAM 1.2
- - brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/d156edeeed7291f4bc1e08620b331bbd05d52b78/Formula/opam.rb
- - brew unlink python@2
- - brew install python3
- - pip3 install macpack
- - opam init -j "$NJOBS" --compiler="$COMPILER" -n -y
- - opam switch "$COMPILER" && opam update
- - eval $(opam config env)
- - opam config list
- - opam install -j "$NJOBS" -y num ocamlfind${FINDLIB_VER} dune${DUNE_VER} ${EXTRA_OPAM}
- - opam list
- before_deploy:
- - dev/build/osx/make-macos-dmg.sh
- deploy:
- - provider: bintray
- user: maximedenes
- file: .bintray.json
- key:
- secure: "gUvXWwWR0gicDqsKOnBfe45taToSFied6gN8tCa5IOtl6E6gFoHoPZ83ZWXQsZP50oMDFS5eji0VQAFGEbOsGrTZaD9Y9Jnu34NND78SWL1tsJ6nHO3aCAoMpB0N3+oRuF6S+9HStU6KXWqgj+GeU4vZ4TOlG01RGctJa6U3vII="
- skip_cleanup: true
- on:
- all_branches: true
-
-before_install:
-- if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then echo "Tested commit (followed by parent commits):"; git log -1; for commit in `git log -1 --format="%P"`; do echo; git log -1 $commit; done; fi
-
-script:
-
-- set -e
-- echo 'Testing make clean...' && echo -en 'travis_fold:start:coq.clean\\r'
-- make clean # ensure that `make clean` works on a fresh clone
-- echo -en 'travis_fold:end:coq.clean\\r'
-
-- echo 'Configuring Coq...' && echo -en 'travis_fold:start:coq.config\\r'
-- ./configure $COQ_DEST -warn-error yes -native-compiler $NATIVE_COMP $EXTRA_CONF
-- echo -en 'travis_fold:end:coq.config\\r'
-
-- echo 'Building Coq...' && echo -en 'travis_fold:start:coq.build\\r'
-- make -j $NJOBS $MAIN_TARGET
-- echo -en 'travis_fold:end:coq.build\\r'
-
-- echo 'Running tests...' && echo -en 'travis_fold:start:coq.test\\r'
-- if [ -n "$TEST_TARGET" ]; then $TW make -j $NJOBS $TEST_TARGET; fi
-- echo -en 'travis_fold:end:coq.test\\r'
-- set +e
-
-# Testing Gitter webhook
-notifications:
- webhooks:
- urls:
- - https://webhooks.gitter.im/e/3cdabdec318214c7cd63
- on_success: change # options: [always|never|change] default: always
- on_failure: always # options: [always|never|change] default: always
- on_start: never # options: [always|never|change] default: always
diff --git a/CHANGES.md b/CHANGES.md
index 54acb610bb..9d912a63b1 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -22,6 +22,11 @@ Coqide
Coqtop
+- the use of `coqtop` as a compiler has been deprecated, in favor of
+ `coqc`. Consequently option `-compile` will stop to be accepted in
+ the next release. `coqtop` is now reserved to interactive
+ use. (@ejgallego #9095)
+
- new option -topfile filename, which will set the current module name
(à la -top) based on the filename passed, taking into account the
proper -R/-Q options. For example, given -R Foo foolib using
@@ -49,6 +54,9 @@ Notations
- New command `String Notation` to register string syntax for custom
inductive types.
+- Various bugs have been fixed (e.g. PR #9214 on removing spurious
+ parentheses on abbreviations shortening a strict prefix of an application).
+
Plugins
- The quote plugin (https://coq.inria.fr/distrib/V8.8.1/refman/proof-engine/detailed-tactic-examples.html#quote)
@@ -109,6 +117,11 @@ Vernacular commands
- Option `Refine Instance Mode` has been turned off by default, meaning that
`Instance` no longer opens a proof when a body is provided.
+- `Instance`, when no body is provided, now always opens a proof. This is a
+ breaking change, as instance of `Instance foo : C.` where `C` is a trivial
+ class will have to be changed into `Instance foo : C := {}.` or
+ `Instance foo : C. Proof. Qed.`.
+
Tools
- The `-native-compiler` flag of `coqc` and `coqtop` now takes an argument which can have three values:
@@ -169,12 +182,24 @@ Misc
SSReflect
- New intro patterns:
- - temporary introduction: => +
- - block introduction: => [^ prefix ] [^~ suffix ]
- - fast introduction: => >
- - tactics as views: => /ltac:mytac
+ - temporary introduction: `=> +`
+ - block introduction: `=> [^ prefix ] [^~ suffix ]`
+ - fast introduction: `=> >`
+ - tactics as views: `=> /ltac:mytac`
+ - replace hypothesis: `=> {}H`
See the reference manual for the actual documentation.
+- Clear discipline made consistent across the entire proof language.
+ Whenever a clear switch `{x..}` comes immediately before an existing proof
+ context entry (used as a view, as a rewrite rule or as name for a new
+ context entry) then such entry is cleared too.
+
+ E.g. The following sentences are elaborated as follows (when H is an existing
+ proof context entry):
+ - `=> {x..} H` -> `=> {x..H} H`
+ - `=> {x..} /H` -> `=> /v {x..H}`
+ - `rewrite {x..} H` -> `rewrite E {x..H}`
+
Changes from 8.8.2 to 8.9+beta1
===============================
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index de7fb9183c..bb0e388cdd 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -55,7 +55,7 @@ please add an entry to [`dev/doc/critical-bugs`](/dev/doc/critical-bugs).
Don't be alarmed if the pull request process takes some time. It can take a few days to get feedback, approval on the final changes, and then a merge. Coq doesn't release new versions very frequently so it can take a few months for your change to land in a released version. That said, you can start using the latest Coq `master` branch to take advantage of all the new features, improvements, and fixes.
-Whitespace discipline (do not indent using tabs, no trailing spaces, text files end with newlines) is checked by Travis (using `git diff --check`). We ship a [`dev/tools/pre-commit`](/dev/tools/pre-commit) git hook which fixes these errors at commit time. `configure` automatically sets you up to use it, unless you already have a hook at `.git/hooks/pre-commit`.
+Whitespace discipline (do not indent using tabs, no trailing spaces, text files end with newlines) is checked by the `lint` job on GitLab CI (using `git diff --check`). We ship a [`dev/tools/pre-commit`](/dev/tools/pre-commit) git hook which fixes these errors at commit time. `configure` automatically sets you up to use it, unless you already have a hook at `.git/hooks/pre-commit`.
Here are a few tags Coq developers may add to your PR and what they mean. In general feedback and requests for you as the pull request author will be in the comments and tags are only used to organize pull requests.
diff --git a/INSTALL b/INSTALL
index 8d8efd4d4d..44ea195f59 100644
--- a/INSTALL
+++ b/INSTALL
@@ -113,9 +113,8 @@ INSTALLATION PROCEDURE IN DETAILS (NORMAL USERS).
"./configure -help". The main options accepted are:
-prefix <dir>
- Binaries, library, man pages and Emacs mode will be respectively
- installed in <dir>/bin, <dir>/lib/coq, <dir>/man and
- <dir>/lib/emacs/site-lisp
+ Binaries, library, and man pages will be respectively
+ installed in <dir>/bin, <dir>/lib/coq, and <dir>/man
-bindir <dir> (default: /usr/local/bin)
Directory where the binaries will be installed
@@ -126,9 +125,6 @@ INSTALLATION PROCEDURE IN DETAILS (NORMAL USERS).
-mandir <dir> (default: /usr/local/share/man)
Directory where the Coq manual pages will be installed
--emacslib <dir> (default: /usr/local/lib/emacs/site-lisp)
- Directory where the Coq Emacs mode will be installed
-
-arch <value> (default is the result of the command "arch")
An arbitrary architecture name for your machine (useful when
compiling Coq on two different architectures for which the
@@ -175,9 +171,9 @@ INSTALLATION PROCEDURE IN DETAILS (NORMAL USERS).
it is recommended to compile in parallel, via make -jN where N is your number
of cores.
-5- You can now install the Coq system. Executables, libraries, manual pages
- and emacs mode are copied in some standard places of your system, defined at
- configuration time (step 3). Just do
+5- You can now install the Coq system. Executables, libraries, and
+ manual pages are copied in some standard places of your system,
+ defined at configuration time (step 3). Just do
umask 022
make install
diff --git a/Makefile b/Makefile
index 99d4611dce..03cb51e6a3 100644
--- a/Makefile
+++ b/Makefile
@@ -82,7 +82,8 @@ export MLPACKFILES := $(call find, '*.mlpack')
export MLGFILES := $(call find, '*.mlg')
export CFILES := $(call findindir, 'kernel/byterun', '*.c')
-MERLININFILES := $(call find, '.merlin.in')
+# NB our find wrapper ignores the test suite
+MERLININFILES := $(call find, '.merlin.in') test-suite/unit-tests/.merlin.in
export MERLINFILES := $(MERLININFILES:.in=)
# NB: The lists of currently existing .ml and .mli files will change
diff --git a/Makefile.build b/Makefile.build
index e683a6bda8..4f42768227 100644
--- a/Makefile.build
+++ b/Makefile.build
@@ -198,7 +198,7 @@ TIMER=$(if $(TIMED), $(STDTIME), $(TIMECMD))
# TIME="%C (%U user, %S sys, %e total, %M maxres)"
COQOPTS=$(NATIVECOMPUTE) $(COQWARNERROR) $(COQUSERFLAGS)
-BOOTCOQC=$(TIMER) $(COQTOPBEST) -boot $(COQOPTS) -compile
+BOOTCOQC=$(TIMER) $(COQTOPBEST) -boot $(COQOPTS) -w -deprecate-compile-arg -compile
LOCALINCLUDES=$(addprefix -I ,$(SRCDIRS))
MLINCLUDES=$(LOCALINCLUDES)
diff --git a/README.md b/README.md
index e8300ca552..65673ab1fe 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,6 @@
[![GitLab][gitlab-badge]][gitlab-link]
[![Azure Pipelines][azure-badge]][azure-link]
-[![Travis][travis-badge]][travis-link]
[![Appveyor][appveyor-badge]][appveyor-link]
[![Gitter][gitter-badge]][gitter-link]
[![DOI][doi-badge]][doi-link]
@@ -13,9 +12,6 @@
[azure-badge]: https://dev.azure.com/coq/coq/_apis/build/status/coq.coq?branchName=master
[azure-link]: https://dev.azure.com/coq/coq/_build/latest?definitionId=1?branchName=master
-[travis-badge]: https://travis-ci.org/coq/coq.svg?branch=master
-[travis-link]: https://travis-ci.org/coq/coq/builds
-
[appveyor-badge]: https://ci.appveyor.com/api/projects/status/eln43k05pa2vm908/branch/master?svg=true
[appveyor-link]: https://ci.appveyor.com/project/coq/coq/branch/master
diff --git a/default.nix b/default.nix
index 89d69cc40f..b65d736d79 100644
--- a/default.nix
+++ b/default.nix
@@ -23,10 +23,10 @@
{ pkgs ?
(import (fetchTarball {
- url = "https://github.com/NixOS/nixpkgs/archive/958a6c6dd39b0d6628e1408e798a8f1308f2f3e1.tar.gz";
- sha256 = "0vs6k4jn0rbdfzaxmh3xh64q213326680i9g3cjgr7l9y6h6m5sy";
+ url = "https://github.com/NixOS/nixpkgs/archive/11cf7d6e1ffd5fbc09a51b76d668ad0858a772ed.tar.gz";
+ sha256 = "0zcg4mgfdk3ryiqj1j5iv5bljjvsgi6q6j9z1vkq383c4g4clc72";
}) {})
-, ocamlPackages ? pkgs.ocaml-ng.ocamlPackages_4_06
+, ocamlPackages ? pkgs.ocamlPackages
, buildIde ? true
, buildDoc ? true
, doInstallCheck ? true
diff --git a/dev/build/windows/makecoq_mingw.sh b/dev/build/windows/makecoq_mingw.sh
index 07a13b8204..2e934ff0c0 100755
--- a/dev/build/windows/makecoq_mingw.sh
+++ b/dev/build/windows/makecoq_mingw.sh
@@ -444,9 +444,6 @@ function load_overlay_data {
else
export CI_BRANCH=""
export CI_PULL_REQUEST=""
- # Used when building 8.8.0 with the latest scripts
- export TRAVIS_BRANCH=""
- export TRAVIS_PULL_REQUEST=""
fi
for overlay in /build/user-overlays/*.sh; do
diff --git a/dev/ci/README-developers.md b/dev/ci/README-developers.md
index 6663fbecf8..10b4f9b044 100644
--- a/dev/ci/README-developers.md
+++ b/dev/ci/README-developers.md
@@ -16,14 +16,12 @@ We are currently running tests on the following platforms:
`./configure`. It should allow complying with this discipline
without pain.
-- Travis CI is used to test the compilation of Coq and run the test-suite on
- macOS.
-
- AppVeyor is used to test the compilation of Coq and run the test-suite on
Windows.
- Azure Pipelines is used to test the compilation of Coq and run the
- test-suite on Windows. It is expected to replace appveyor eventually.
+ test-suite on Windows and on macOS. It is expected to replace
+ appveyor eventually.
You can anticipate the results of most of these tests prior to submitting your
PR by running GitLab CI on your private branches. To do so follow these steps:
diff --git a/dev/ci/ci-wrapper.sh b/dev/ci/ci-wrapper.sh
index 12a70176c2..9ca8f76054 100755
--- a/dev/ci/ci-wrapper.sh
+++ b/dev/ci/ci-wrapper.sh
@@ -6,13 +6,6 @@
set -eo pipefail
-function travis_fold {
- if [ -n "${TRAVIS}" ];
- then
- echo "travis_fold:$1:$2"
- fi
-}
-
CI_NAME="$1"
CI_SCRIPT="ci-${CI_NAME}.sh"
@@ -22,6 +15,5 @@ cd "${DIR}/../.."
export TIMED=1
"${DIR}/${CI_SCRIPT}" 2>&1 | tee time-of-build.log
-travis_fold 'start' 'coq.test.timing' && echo 'Aggregating timing log...'
+echo 'Aggregating timing log...'
python ./tools/make-one-time-file.py time-of-build.log
-travis_fold 'end' 'coq.test.timing'
diff --git a/dev/ci/user-overlays/09263-maximedenes-parsing-state.sh b/dev/ci/user-overlays/09263-maximedenes-parsing-state.sh
new file mode 100644
index 0000000000..ebd1b524da
--- /dev/null
+++ b/dev/ci/user-overlays/09263-maximedenes-parsing-state.sh
@@ -0,0 +1,12 @@
+if [ "$CI_PULL_REQUEST" = "9263" ] || [ "$CI_BRANCH" = "parsing-state" ]; then
+
+ mtac2_CI_REF=proof-mode
+ mtac2_CI_GITURL=https://github.com/maximedenes/Mtac2
+
+ ltac2_CI_REF=proof-mode
+ ltac2_CI_GITURL=https://github.com/maximedenes/ltac2
+
+ equations_CI_REF=proof-mode
+ equations_CI_GITURL=https://github.com/maximedenes/Coq-Equations
+
+fi
diff --git a/dev/doc/MERGING.md b/dev/doc/MERGING.md
index 56fdab0c26..5705857d76 100644
--- a/dev/doc/MERGING.md
+++ b/dev/doc/MERGING.md
@@ -93,7 +93,7 @@ put the approriate label. Otherwise, they are expected to merge the PR using the
When CI has a few failures which look spurious, restarting the corresponding
jobs is a good way of ensuring this was indeed the case.
-To restart a job on Travis or on AppVeyor, you should connect using your GitHub
+To restart a job on AppVeyor, you should connect using your GitHub
account; being part of the Coq organization on GitHub should give you the
permission to do so.
To restart a job on GitLab CI, you should sign into GitLab (this can be done
diff --git a/dev/doc/profiling.txt b/dev/doc/profiling.txt
index 29e87df6b8..8455d13377 100644
--- a/dev/doc/profiling.txt
+++ b/dev/doc/profiling.txt
@@ -10,7 +10,7 @@ In Coq source folder:
opam switch 4.05.0+trunk+fp
./configure -local -debug
make
-perf record -g bin/coqtop -compile file.v
+perf record -g bin/coqc file.v
perf report -g fractal,callee --no-children
To profile only part of a file, first load it using
@@ -96,7 +96,7 @@ https://github.com/mshinwell/opam-repo-dev
### For memory dump:
-CAMLRUNPARAM=T,mj bin/coqtop -compile file.v
+CAMLRUNPARAM=T,mj bin/coqc file.v
In another terminal:
@@ -112,7 +112,7 @@ number of objects and third is the place where the objects where allocated.
### For complete memory graph:
-CAMLRUNPARAM=T,gr bin/coqtop -compile file.v
+CAMLRUNPARAM=T,gr bin/coqc file.v
In another terminal:
diff --git a/dev/doc/release-process.md b/dev/doc/release-process.md
index b1c111685b..d05b6c8eef 100644
--- a/dev/doc/release-process.md
+++ b/dev/doc/release-process.md
@@ -4,37 +4,20 @@
- [ ] Create a new issue to track the release process where you can copy-paste
the present checklist.
-- [ ] Change the version name to the next major version and the magic numbers
- (see [#7008](https://github.com/coq/coq/pull/7008/files)).
-- [ ] Update the compatibility infrastructure, which consists of doing
- the following steps. Note that all but the final step can be
- performed automatically by
- [`dev/tools/update-compat.py`](/dev/tools/update-compat.py) so
- long as you have already updated `coq_version` in
- [`configure.ml`](/configure.ml).
- + [ ] Add a file `theories/Compat/CoqXX.v` which contains just the header
- from [`dev/header.ml`](/dev/header.ml)
- + [ ] Add the line `Require Export Coq.Compat.CoqXX.` at the top of
- `theories/Compat/CoqYY.v`, where Y.Y is the version prior to X.X.
- + [ ] Delete the file `theories/Compat/CoqWW.v`, where W.W is three versions
- prior to X.X.
- + [ ] Update
- [`doc/stdlib/index-list.html.template`](/doc/stdlib/index-list.html.template)
- with the deleted/added files.
- + [ ] Remove any notations in the standard library which have `compat "W.W"`.
- + [ ] Update the type `compat_version` in [`lib/flags.ml`](/lib/flags.ml) by
- bumping all the version numbers by one, and update the interpretations
- of those flags in [`toplevel/coqargs.ml`](/toplevel/coqargs.ml) and
- [`vernac/g_vernac.mlg`](/vernac/g_vernac.mlg).
- + [ ] Update the files
- [`test-suite/success/CompatCurrentFlag.v`](/test-suite/success/CompatCurrentFlag.v),
- [`test-suite/success/CompatPreviousFlag.v`](/test-suite/success/CompatPreviousFlag.v),
- and
- [`test-suite/success/CompatOldFlag.v`](/test-suite/success/CompatOldFlag.v)
- by bumping all version numbers by 1.
- + [ ] Decide what to do about all test-suite files which mention `-compat
- W.W` or `Coq.Comapt.CoqWW` (which is no longer valid, since we only
- keep compatibility against the two previous versions)
+- [ ] Change the version name to the next major version and the magic
+ numbers (see [#7008](https://github.com/coq/coq/pull/7008/files)).
+
+ Additionally, in the same commit, update the compatibility
+ infrastructure, which consists of invoking
+ [`dev/tools/update-compat.py`](../tools/update-compat.py) with the
+ `--master` flag.
+
+ Note that the `update-compat.py` script must be run twice: once
+ *immediately after* branching with the `--master` flag (which sets
+ up Coq to support four `-compat` flag arguments), *in the same
+ commit* as the one that updates `coq_version` in
+ [`configure.ml`](../../configure.ml), and once again later on before
+ the next branch point with the `--release` flag (see next section).
- [ ] Put the corresponding alpha tag using `git tag -s`.
The `VX.X+alpha` tag marks the first commit to be in `master` and not in the
branch of the previous version.
@@ -43,6 +26,19 @@
release date) and put this information in the milestone (using the
description and due date fields).
+## Anytime after the previous version is branched off master ##
+
+- [ ] Update the compatibility infrastructure to the next release,
+ which consists of invoking
+ [`dev/tools/update-compat.py`](../tools/update-compat.py) with the
+ `--release` flag; this sets up Coq to support three `-compat` flag
+ arguments. To ensure that CI passes, you will have to decide what
+ to do about all test-suite files which mention `-compat U.U` or
+ `Coq.Comapt.CoqUU` (which is no longer valid, since we only keep
+ compatibility against the two previous versions on releases), and
+ you may have to prepare overlays for projects using the
+ compatibility flags.
+
## About one month before the beta ##
- [ ] Create the `X.X.0` milestone and set its due date.
diff --git a/dev/doc/versions-history.tex b/dev/doc/versions-history.tex
index 8f9c3171da..1c4913d201 100644
--- a/dev/doc/versions-history.tex
+++ b/dev/doc/versions-history.tex
@@ -271,7 +271,7 @@ Coq ``V7'' archive & August 1999 & new cvs archive based on J.-C. Filliâtre's \
& & \feature{kernel-centric} architecture \\
& & more care for outside readers\\
& & (indentation, ocaml warning protection)\\
-Coq V7.0beta& released 27 December 2000 & \feature{${\cal L}_{\mathit{tac}}$} \\
+Coq V7.0beta& released 27 December 2000 & \feature{${\mathcal{L}}_{\mathit{tac}}$} \\
Coq V7.0beta2& released 2 February 2001\\
Coq V7.0& released 25 April 2001 & \feature{extraction} (version 2) [6-2-2001] \\
diff --git a/dev/tools/merge-pr.sh b/dev/tools/merge-pr.sh
index a27dacc5a7..72e2930386 100755
--- a/dev/tools/merge-pr.sh
+++ b/dev/tools/merge-pr.sh
@@ -143,7 +143,7 @@ fi
# Sanity check: PR has an outdated version of CI
BASE_COMMIT=$(echo "$PRDATA" | jq -r '.base.sha')
-CI_FILES=(".travis.yml" ".gitlab-ci.yml" "appveyor.yml")
+CI_FILES=(".gitlab-ci.yml" "appveyor.yml")
if ! git diff --quiet "$BASE_COMMIT" "$LOCAL_BRANCH_COMMIT" -- "${CI_FILES[@]}"
then
diff --git a/dev/tools/update-compat.py b/dev/tools/update-compat.py
index 14094553a2..ff9b32fe78 100755
--- a/dev/tools/update-compat.py
+++ b/dev/tools/update-compat.py
@@ -1,6 +1,60 @@
#!/usr/bin/env python
from __future__ import with_statement
-import os, re, sys
+import os, re, sys, subprocess
+
+# When passed `--release`, this script sets up Coq to support three
+# `-compat` flag arguments. If executed manually, this would consist
+# of doing the following steps:
+#
+# - Delete the file `theories/Compat/CoqUU.v`, where U.U is four
+# versions prior to the new version X.X. After this, there
+# should be exactly three `theories/Compat/CoqNN.v` files.
+# - Update
+# [`doc/stdlib/index-list.html.template`](/doc/stdlib/index-list.html.template)
+# with the deleted file.
+# - Remove any notations in the standard library which have `compat "U.U"`.
+# - Update the type `compat_version` in [`lib/flags.ml`](/lib/flags.ml) by
+# bumping all the version numbers by one, and update the interpretations
+# of those flags in [`toplevel/coqargs.ml`](/toplevel/coqargs.ml) and
+# [`vernac/g_vernac.mlg`](/vernac/g_vernac.mlg).
+#
+# - Remove the file
+# [`test-suite/success/CompatOldOldFlag.v`](/test-suite/success/CompatOldOldFlag.v).
+# - Update
+# [`test-suite/tools/update-compat/run.sh`](/test-suite/tools/update-compat/run.sh)
+# to ensure that it passes `--release` to the `update-compat.py`
+# script.
+
+# When passed the `--master` flag, this script sets up Coq to support
+# four `-compat` flag arguments. If executed manually, this would
+# consist of doing the following steps:
+#
+# - Add a file `theories/Compat/CoqXX.v` which contains just the header
+# from [`dev/header.ml`](/dev/header.ml)
+# - Add the line `Require Export Coq.Compat.CoqXX.` at the top of
+# `theories/Compat/CoqYY.v`, where Y.Y is the version prior to X.X.
+# - Update
+# [`doc/stdlib/index-list.html.template`](/doc/stdlib/index-list.html.template)
+# with the added file.
+# - Update the type `compat_version` in [`lib/flags.ml`](/lib/flags.ml) by
+# bumping all the version numbers by one, and update the interpretations
+# of those flags in [`toplevel/coqargs.ml`](/toplevel/coqargs.ml) and
+# [`vernac/g_vernac.mlg`](/vernac/g_vernac.mlg).
+# - Update the files
+# [`test-suite/success/CompatCurrentFlag.v`](/test-suite/success/CompatCurrentFlag.v),
+# [`test-suite/success/CompatPreviousFlag.v`](/test-suite/success/CompatPreviousFlag.v),
+# and
+# [`test-suite/success/CompatOldFlag.v`](/test-suite/success/CompatOldFlag.v)
+# by bumping all version numbers by 1. Re-create the file
+# [`test-suite/success/CompatOldOldFlag.v`](/test-suite/success/CompatOldOldFlag.v)
+# with its version numbers also bumped by 1 (file should have
+# been removed before branching; see above).
+# - Update
+# [`test-suite/tools/update-compat/run.sh`](/test-suite/tools/update-compat/run.sh)
+# to ensure that it passes `--master` to the `update-compat.py`
+# script.
+
+
# Obtain the absolute path of the script being run. By assuming that
# the script lives in dev/tools/, and basing all calls on the path of
@@ -11,6 +65,8 @@ ROOT_PATH = os.path.realpath(os.path.join(SCRIPT_PATH, '..', '..'))
CONFIGURE_PATH = os.path.join(ROOT_PATH, 'configure.ml')
HEADER_PATH = os.path.join(ROOT_PATH, 'dev', 'header.ml')
DEFAULT_NUMBER_OF_OLD_VERSIONS = 2
+RELEASE_NUMBER_OF_OLD_VERSIONS = 2
+MASTER_NUMBER_OF_OLD_VERSIONS = 3
EXTRA_HEADER = '\n(** Compatibility file for making Coq act similar to Coq v%s *)\n'
FLAGS_MLI_PATH = os.path.join(ROOT_PATH, 'lib', 'flags.mli')
FLAGS_ML_PATH = os.path.join(ROOT_PATH, 'lib', 'flags.ml')
@@ -18,18 +74,46 @@ COQARGS_ML_PATH = os.path.join(ROOT_PATH, 'toplevel', 'coqargs.ml')
G_VERNAC_PATH = os.path.join(ROOT_PATH, 'vernac', 'g_vernac.mlg')
DOC_INDEX_PATH = os.path.join(ROOT_PATH, 'doc', 'stdlib', 'index-list.html.template')
BUG_4798_PATH = os.path.join(ROOT_PATH, 'test-suite', 'bugs', 'closed', 'bug_4798.v')
+BUG_9166_PATH = os.path.join(ROOT_PATH, 'test-suite', 'bugs', 'closed', 'bug_9166.v')
+TEST_SUITE_RUN_PATH = os.path.join(ROOT_PATH, 'test-suite', 'tools', 'update-compat', 'run.sh')
TEST_SUITE_PATHS = tuple(os.path.join(ROOT_PATH, 'test-suite', 'success', i)
for i in ('CompatOldOldFlag.v', 'CompatOldFlag.v', 'CompatPreviousFlag.v', 'CompatCurrentFlag.v'))
TEST_SUITE_DESCRIPTIONS = ('current-minus-three', 'current-minus-two', 'current-minus-one', 'current')
# sanity check that we are where we think we are
assert(os.path.normpath(os.path.realpath(SCRIPT_PATH)) == os.path.normpath(os.path.realpath(os.path.join(ROOT_PATH, 'dev', 'tools'))))
assert(os.path.exists(CONFIGURE_PATH))
+BUG_HEADER = r"""(* DO NOT MODIFY THIS FILE DIRECTLY *)
+(* It is autogenerated by %s. *)
+""" % os.path.relpath(os.path.realpath(__file__), ROOT_PATH)
def get_header():
with open(HEADER_PATH, 'r') as f: return f.read()
HEADER = get_header()
+def break_or_continue():
+ msg = 'Press ENTER to continue, or Ctrl+C to break...'
+ try:
+ raw_input(msg)
+ except NameError: # we must be running python3
+ input(msg)
+
+def maybe_git_add(local_path, suggest_add=True, **args):
+ if args['git_add']:
+ print("Running 'git add %s'..." % local_path)
+ retc = subprocess.call(['git', 'add', local_path], cwd=ROOT_PATH)
+ if retc is not None and retc != 0:
+ print('!!! Process returned code %d' % retc)
+ elif suggest_add:
+ print(r"!!! Don't forget to 'git add %s'!" % local_path)
+
+def maybe_git_rm(local_path, **args):
+ if args['git_add']:
+ print("Running 'git rm %s'..." % local_path)
+ retc = subprocess.call(['git', 'rm', local_path], cwd=ROOT_PATH)
+ if retc is not None and retc != 0:
+ print('!!! Process returned code %d' % retc)
+
def get_version(cur_version=None):
if cur_version is not None: return cur_version
with open(CONFIGURE_PATH, 'r') as f:
@@ -72,11 +156,56 @@ def get_known_versions():
def get_new_versions(known_versions, **args):
if args['cur_version'] in known_versions:
assert(known_versions[-1] == args['cur_version'])
- assert(len(known_versions) == args['number_of_compat_versions'])
- return known_versions
+ known_versions = known_versions[:-1]
assert(len(known_versions) >= args['number_of_old_versions'])
return tuple(list(known_versions[-args['number_of_old_versions']:]) + [args['cur_version']])
+def print_diff(olds, news, numch=30):
+ for ch in range(min(len(olds), len(news))):
+ if olds[ch] != news[ch]:
+ print('Character %d differs:\nOld: %s\nNew: %s' % (ch, repr(olds[ch:][:numch]), repr(news[ch:][numch])))
+ return
+ ch = min(len(olds), len(news))
+ assert(len(olds) != len(news))
+ print('Strings are different lengths:\nOld tail: %s\nNew tail: %s' % (repr(olds[ch:]), repr(news[ch:])))
+
+def update_shebang_to_match(contents, new_contents, path):
+ contents_lines = contents.split('\n')
+ new_contents_lines = new_contents.split('\n')
+ if not (contents_lines[0].startswith('#!/') and contents_lines[0].endswith('bash')):
+ raise Exception('Unrecognized #! line in existing %s: %s' % (os.path.relpath(path, ROOT_PATH), repr(contents_lines[0])))
+ if not (new_contents_lines[0].startswith('#!/') and new_contents_lines[0].endswith('bash')):
+ raise Exception('Unrecognized #! line in new %s: %s' % (os.path.relpath(path, ROOT_PATH), repr(new_contents_lines[0])))
+ new_contents_lines[0] = contents_lines[0]
+ return '\n'.join(new_contents_lines)
+
+def update_if_changed(contents, new_contents, path, exn_string='%s changed!', suggest_add=False, pass_through_shebang=False, assert_unchanged=False, **args):
+ if contents is not None and pass_through_shebang:
+ new_contents = update_shebang_to_match(contents, new_contents, path)
+ if contents is None or contents != new_contents:
+ if not assert_unchanged:
+ print('Updating %s...' % os.path.relpath(path, ROOT_PATH))
+ with open(path, 'w') as f:
+ f.write(new_contents)
+ maybe_git_add(os.path.relpath(path, ROOT_PATH), suggest_add=suggest_add, **args)
+ else:
+ if contents is not None:
+ print('Unexpected change:\nOld contents:\n%s\n\nNew contents:\n%s\n' % (contents, new_contents))
+ print_diff(contents, new_contents)
+ raise Exception(exn_string % os.path.relpath(path, ROOT_PATH))
+
+def remove_if_exists(path, exn_string='%s exists when it should not!', assert_unchanged=False, **args):
+ if os.path.exists(path):
+ if not assert_unchanged:
+ print('Removing %s...' % os.path.relpath(path, ROOT_PATH))
+ os.remove(path)
+ maybe_git_rm(os.path.relpath(path, ROOT_PATH), **args)
+ else:
+ raise Exception(exn_string % os.path.relpath(path, ROOT_PATH))
+
+def update_file(new_contents, path, **args):
+ update_if_changed(None, new_contents, path, **args)
+
def update_compat_files(old_versions, new_versions, assert_unchanged=False, **args):
for v in old_versions:
if v not in new_versions:
@@ -85,6 +214,7 @@ def update_compat_files(old_versions, new_versions, assert_unchanged=False, **ar
print('Removing %s...' % compat_file)
compat_path = os.path.join(ROOT_PATH, compat_file)
os.rename(compat_path, compat_path + '.bak')
+ maybe_git_rm(compat_file, **args)
else:
raise Exception('%s exists!' % compat_file)
for v, next_v in zip(new_versions, list(new_versions[1:]) + [None]):
@@ -95,12 +225,7 @@ def update_compat_files(old_versions, new_versions, assert_unchanged=False, **ar
contents = HEADER + (EXTRA_HEADER % v)
if next_v is not None:
contents += '\nRequire Export Coq.Compat.%s.\n' % version_name_to_compat_name(next_v, ext='')
- if not assert_unchanged:
- with open(compat_path, 'w') as f:
- f.write(contents)
- print(r"Don't forget to 'git add %s'!" % compat_file)
- else:
- raise Exception('%s does not exist!' % compat_file)
+ update_file(contents, compat_path, exn_string='%s does not exist!', assert_unchanged=assert_unchanged, **args)
else:
# print('Checking %s...' % compat_file)
with open(compat_path, 'r') as f:
@@ -116,12 +241,7 @@ def update_compat_files(old_versions, new_versions, assert_unchanged=False, **ar
if not contents.startswith(header + '\n'):
contents = contents.replace(header, header + '\n')
contents = contents.replace(header, '%s\n%s' % (header, line))
- if not assert_unchanged:
- print('Updating %s...' % compat_file)
- with open(compat_path, 'w') as f:
- f.write(contents)
- else:
- raise Exception('Compat file %s is missing line %s' % (compat_file, line))
+ update_file(contents, compat_path, exn_string=('Compat file %%s is missing line %s' % line), assert_unchanged=assert_unchanged, **args)
def update_compat_versions_type_line(new_versions, contents, relpath):
compat_version_string = ' | '.join(['V%s_%s' % tuple(v.split('.')) for v in new_versions[:-1]] + ['Current'])
@@ -173,11 +293,18 @@ def update_add_compat_require(new_versions, contents, relpath):
return new_contents
def update_parse_compat_version(new_versions, contents, relpath, **args):
- line_count = args['number_of_compat_versions']+2 # 1 for the first line, 1 for the invalid flags
+ line_count = 3 # 1 for the first line, 1 for the invalid flags, and 1 for Current
first_line = 'let parse_compat_version = let open Flags in function'
- old_function_lines = contents[contents.index(first_line):].split('\n')[:line_count]
- if re.match(r'^ \| \([0-9 "\.\|]*\) as s ->$', old_function_lines[-1]) is None:
- raise Exception('Could not recognize line %d of parse_compat_version in %s as a list of invalid versions' % (line_count, relpath))
+ split_contents = contents[contents.index(first_line):].split('\n')
+ while True:
+ cur_line = split_contents[:line_count][-1]
+ if re.match(r'^ \| \([0-9 "\.\|]*\) as s ->$', cur_line) is not None:
+ break
+ elif re.match(r'^ \| "[0-9\.]*" -> V[0-9_]*$', cur_line) is not None:
+ line_count += 1
+ else:
+ raise Exception('Could not recognize line %d of parse_compat_version in %s as a list of invalid versions (line was %s)' % (line_count, relpath, repr(cur_line)))
+ old_function_lines = split_contents[:line_count]
all_versions = re.findall(r'"([0-9\.]+)"', ''.join(old_function_lines))
invalid_versions = tuple(i for i in all_versions if i not in new_versions)
new_function_lines = [first_line]
@@ -197,15 +324,6 @@ def check_no_old_versions(old_versions, new_versions, contents, relpath):
if V in contents:
raise Exception('Unreplaced usage of %s remaining in %s' % (V, relpath))
-def update_if_changed(contents, new_contents, path, assert_unchanged=False, **args):
- if contents != new_contents:
- if not assert_unchanged:
- print('Updating %s...' % os.path.relpath(path, ROOT_PATH))
- with open(path, 'w') as f:
- f.write(new_contents)
- else:
- raise Exception('%s changed!' % os.path.relpath(path, ROOT_PATH))
-
def update_flags_mli(old_versions, new_versions, **args):
with open(FLAGS_MLI_PATH, 'r') as f: contents = f.read()
new_contents = update_compat_versions_type_line(new_versions, contents, os.path.relpath(FLAGS_MLI_PATH, ROOT_PATH))
@@ -238,21 +356,26 @@ def update_flags(old_versions, new_versions, **args):
update_coqargs_ml(old_versions, new_versions, **args)
update_g_vernac(old_versions, new_versions, **args)
-def update_test_suite(new_versions, assert_unchanged=False, test_suite_paths=TEST_SUITE_PATHS, test_suite_descriptions=TEST_SUITE_DESCRIPTIONS, **args):
+def update_test_suite(new_versions, assert_unchanged=False, test_suite_paths=TEST_SUITE_PATHS, test_suite_descriptions=TEST_SUITE_DESCRIPTIONS, test_suite_outdated_paths=tuple(), **args):
assert(len(new_versions) == len(test_suite_paths))
assert(len(new_versions) == len(test_suite_descriptions))
for i, (v, path, descr) in enumerate(zip(new_versions, test_suite_paths, test_suite_descriptions)):
- if not os.path.exists(path):
- raise Exception('Could not find existing file %s' % os.path.relpath(path, ROOT_PATH))
+ contents = None
+ suggest_add = False
+ if os.path.exists(path):
+ with open(path, 'r') as f: contents = f.read()
+ else:
+ suggest_add = True
if '%s' in descr: descr = descr % v
- with open(path, 'r') as f: contents = f.read()
lines = ['(* -*- coq-prog-args: ("-compat" "%s") -*- *)' % v,
'(** Check that the %s compatibility flag actually requires the relevant modules. *)' % descr]
for imp_v in reversed(new_versions[i:]):
lines.append('Import Coq.Compat.%s.' % version_name_to_compat_name(imp_v, ext=''))
lines.append('')
new_contents = '\n'.join(lines)
- update_if_changed(contents, new_contents, path, **args)
+ update_if_changed(contents, new_contents, path, suggest_add=suggest_add, **args)
+ for path in test_suite_outdated_paths:
+ remove_if_exists(path, assert_unchanged=assert_unchanged, **args)
def update_doc_index(new_versions, **args):
with open(DOC_INDEX_PATH, 'r') as f: contents = f.read()
@@ -264,17 +387,48 @@ def update_doc_index(new_versions, **args):
new_contents = new_contents.replace(firstline, '\n'.join([firstline] + extra_lines))
update_if_changed(contents, new_contents, DOC_INDEX_PATH, **args)
+def update_test_suite_run(**args):
+ with open(TEST_SUITE_RUN_PATH, 'r') as f: contents = f.read()
+ new_contents = r'''#!/usr/bin/env bash
+
+# allow running this script from any directory by basing things on where the script lives
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
+
+# we assume that the script lives in test-suite/tools/update-compat/,
+# and that update-compat.py lives in dev/tools/
+cd "${SCRIPT_DIR}/../../.."
+dev/tools/update-compat.py --assert-unchanged %s || exit $?
+''' % ' '.join([('--master' if args['master'] else ''), ('--release' if args['release'] else '')]).strip()
+ update_if_changed(contents, new_contents, TEST_SUITE_RUN_PATH, pass_through_shebang=True, **args)
+
def update_bug_4789(new_versions, **args):
# we always update this compat notation to oldest
# currently-supported compat version, which should never be the
# current version
with open(BUG_4798_PATH, 'r') as f: contents = f.read()
- new_contents = r"""Check match 2 with 0 => 0 | S n => n end.
+ new_contents = BUG_HEADER + r"""Check match 2 with 0 => 0 | S n => n end.
Notation "|" := 1 (compat "%s").
Check match 2 with 0 => 0 | S n => n end. (* fails *)
""" % new_versions[0]
update_if_changed(contents, new_contents, BUG_4798_PATH, **args)
+def update_bug_9166(new_versions, **args):
+ # we always update this compat notation to oldest
+ # currently-supported compat version, which should never be the
+ # current version
+ with open(BUG_9166_PATH, 'r') as f: contents = f.read()
+ new_contents = BUG_HEADER + r"""Set Warnings "+deprecated".
+
+Notation bar := option (compat "%s").
+
+Definition foo (x: nat) : nat :=
+ match x with
+ | 0 => 0
+ | S bar => bar
+ end.
+""" % new_versions[0]
+ update_if_changed(contents, new_contents, BUG_9166_PATH, **args)
+
def update_compat_notations_in(old_versions, new_versions, contents):
for v in old_versions:
if v not in new_versions:
@@ -305,11 +459,26 @@ def parse_args(argv):
args = {
'assert_unchanged': False,
'cur_version': None,
- 'number_of_old_versions': DEFAULT_NUMBER_OF_OLD_VERSIONS
+ 'number_of_old_versions': None,
+ 'master': False,
+ 'release': False,
+ 'git_add': False,
}
+ if '--master' not in argv and '--release' not in argv:
+ print(r'''WARNING: You should pass either --release (sometime before branching)
+ or --master (right after branching and updating the version number in version.ml)''')
+ if '--assert-unchanged' not in args: break_or_continue()
for arg in argv[1:]:
if arg == '--assert-unchanged':
args['assert_unchanged'] = True
+ elif arg == '--git-add':
+ args['git_add'] = True
+ elif arg == '--master':
+ args['master'] = True
+ if args['number_of_old_versions'] is None: args['number_of_old_versions'] = MASTER_NUMBER_OF_OLD_VERSIONS
+ elif arg == '--release':
+ args['release'] = True
+ if args['number_of_old_versions'] is None: args['number_of_old_versions'] = RELEASE_NUMBER_OF_OLD_VERSIONS
elif arg.startswith('--cur-version='):
args['cur_version'] = arg[len('--cur-version='):]
assert(len(args['cur_version'].split('.')) == 2)
@@ -317,10 +486,11 @@ def parse_args(argv):
elif arg.startswith('--number-of-old-versions='):
args['number_of_old_versions'] = int(arg[len('--number-of-old-versions='):])
else:
- print('USAGE: %s [--assert-unchanged] [--cur-version=NN.NN] [--number-of-old-versions=NN]' % argv[0])
+ print('USAGE: %s [--assert-unchanged] [--cur-version=NN.NN] [--number-of-old-versions=NN] [--git-add]' % argv[0])
print('')
print('ERROR: Unrecognized argument: %s' % arg)
sys.exit(1)
+ if args['number_of_old_versions'] is None: args['number_of_old_versions'] = DEFAULT_NUMBER_OF_OLD_VERSIONS
return args
if __name__ == '__main__':
@@ -331,11 +501,14 @@ if __name__ == '__main__':
new_versions = get_new_versions(known_versions, **args)
assert(len(TEST_SUITE_PATHS) >= args['number_of_compat_versions'])
args['test_suite_paths'] = tuple(TEST_SUITE_PATHS[-args['number_of_compat_versions']:])
+ args['test_suite_outdated_paths'] = tuple(TEST_SUITE_PATHS[:-args['number_of_compat_versions']])
args['test_suite_descriptions'] = tuple(TEST_SUITE_DESCRIPTIONS[-args['number_of_compat_versions']:])
update_compat_files(known_versions, new_versions, **args)
update_flags(known_versions, new_versions, **args)
update_test_suite(new_versions, **args)
+ update_test_suite_run(**args)
update_doc_index(new_versions, **args)
update_bug_4789(new_versions, **args)
+ update_bug_9166(new_versions, **args)
update_compat_notations(known_versions, new_versions, **args)
display_git_grep(known_versions, new_versions)
diff --git a/doc/common/macros.tex b/doc/common/macros.tex
index 6a28c5b3d1..927a912fbf 100644
--- a/doc/common/macros.tex
+++ b/doc/common/macros.tex
@@ -242,7 +242,7 @@
\newcommand{\vref}{\nterm{ref}}
\newcommand{\zarithformula}{\nterm{zarith\_formula}}
\newcommand{\zarith}{\nterm{zarith}}
-\newcommand{\ltac}{\mbox{${\cal L}_{tac}$}}
+\newcommand{\ltac}{\mbox{${\mathcal{L}}_{tac}$}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \mbox{\sf } series for roman text in maths formulas %
@@ -373,15 +373,15 @@
\newcommand{\sumbool}[2]{\{#1\}+\{#2\}}
\newcommand{\myifthenelse}[3]{\kw{if} ~ #1 ~\kw{then} ~ #2 ~ \kw{else} ~ #3}
\newcommand{\fun}[2]{\item[]{\tt {#1}}. \quad\\ #2}
-\newcommand{\WF}[2]{\ensuremath{{\cal W\!F}(#1)[#2]}}
-\newcommand{\WFTWOLINES}[2]{\ensuremath{{\cal W\!F}\begin{array}{l}(#1)\\\mbox{}[{#2}]\end{array}}}
+\newcommand{\WF}[2]{\ensuremath{{\mathcal{W\!F}}(#1)[#2]}}
+\newcommand{\WFTWOLINES}[2]{\ensuremath{{\mathcal{W\!F}}\begin{array}{l}(#1)\\\mbox{}[{#2}]\end{array}}}
\newcommand{\WFE}[1]{\WF{E}{#1}}
\newcommand{\WT}[4]{\ensuremath{#1[#2] \vdash #3 : #4}}
\newcommand{\WTE}[3]{\WT{E}{#1}{#2}{#3}}
\newcommand{\WTEG}[2]{\WTE{\Gamma}{#1}{#2}}
\newcommand{\WTM}[3]{\WT{#1}{}{#2}{#3}}
-\newcommand{\WFT}[2]{\ensuremath{#1[] \vdash {\cal W\!F}(#2)}}
+\newcommand{\WFT}[2]{\ensuremath{#1[] \vdash {\mathcal{W\!F}}(#2)}}
\newcommand{\WS}[3]{\ensuremath{#1[] \vdash #2 <: #3}}
\newcommand{\WSE}[2]{\WS{E}{#1}{#2}}
\newcommand{\WEV}[3]{\mbox{$#1[] \vdash #2 \lra #3$}}
@@ -427,7 +427,7 @@
\newcommand{\letin}[3]{\kw{let}~#1:=#2~\kw{in}~#3}
\newcommand{\subst}[3]{#1\{#2/#3\}}
\newcommand{\substs}[4]{#1\{(#2/#3)_{#4}\}}
-\newcommand{\Sort}{\mbox{$\cal S$}}
+\newcommand{\Sort}{\mbox{$\mathcal{S}$}}
\newcommand{\convert}{=_{\beta\delta\iota\zeta\eta}}
\newcommand{\leconvert}{\leq_{\beta\delta\iota\zeta\eta}}
\newcommand{\NN}{\mathbb{N}}
diff --git a/doc/sphinx/addendum/parallel-proof-processing.rst b/doc/sphinx/addendum/parallel-proof-processing.rst
index 8b7214e2ab..903ee115c9 100644
--- a/doc/sphinx/addendum/parallel-proof-processing.rst
+++ b/doc/sphinx/addendum/parallel-proof-processing.rst
@@ -52,7 +52,7 @@ in interactive mode.
It is not strictly mandatory in batch mode if it is not the first time
the file is compiled and if the file itself did not change. When the
proof does not begin with Proof using, the system records in an
-auxiliary file, produced along with the `.vo` file, the list of section
+auxiliary file, produced along with the ``.vo`` file, the list of section
variables used.
Automatic suggestion of proof annotations
@@ -154,22 +154,22 @@ to a worker process. The threshold can be configured with
Batch mode
---------------
-When |Coq| is used as a batch compiler by running `coqc` or `coqtop`
--compile, it produces a `.vo` file for each `.v` file. A `.vo` file contains,
-among other things, theorem statements and proofs. Hence to produce a
-.vo |Coq| need to process all the proofs of the `.v` file.
+When |Coq| is used as a batch compiler by running ``coqc``, it produces
+a ``.vo`` file for each ``.v`` file. A ``.vo`` file contains, among other
+things, theorem statements and proofs. Hence to produce a .vo |Coq|
+need to process all the proofs of the ``.v`` file.
The asynchronous processing of proofs can decouple the generation of a
-compiled file (like the `.vo` one) that can be loaded by ``Require`` from the
+compiled file (like the ``.vo`` one) that can be loaded by ``Require`` from the
generation and checking of the proof objects. The ``-quick`` flag can be
-passed to `coqc` or `coqtop` to produce, quickly, `.vio` files.
-Alternatively, when using a Makefile produced by `coq_makefile`,
+passed to ``coqc`` or ``coqtop`` to produce, quickly, ``.vio`` files.
+Alternatively, when using a Makefile produced by ``coq_makefile``,
the ``quick`` target can be used to compile all files using the ``-quick`` flag.
-A `.vio` file can be loaded using ``Require`` exactly as a `.vo` file but
+A ``.vio`` file can be loaded using ``Require`` exactly as a ``.vo`` file but
proofs will not be available (the Print command produces an error).
Moreover, some universe constraints might be missing, so universes
-inconsistencies might go unnoticed. A `.vio` file does not contain proof
+inconsistencies might go unnoticed. A ``.vio`` file does not contain proof
objects, but proof tasks, i.e. what a worker process can transform
into a proof object.
@@ -177,52 +177,52 @@ Compiling a set of files with the ``-quick`` flag allows one to work,
interactively, on any file without waiting for all the proofs to be
checked.
-When working interactively, one can fully check all the `.v` files by
-running `coqc` as usual.
+When working interactively, one can fully check all the ``.v`` files by
+running ``coqc`` as usual.
-Alternatively one can turn each `.vio` into the corresponding `.vo`. All
+Alternatively one can turn each ``.vio`` into the corresponding ``.vo``. All
.vio files can be processed in parallel, hence this alternative might
be faster. The command ``coqtop -schedule-vio2vo 2 a b c`` can be used to
-obtain a good scheduling for two workers to produce `a.vo`, `b.vo`, and
-`c.vo`. When using a Makefile produced by `coq_makefile`, the ``vio2vo`` target
-can be used for that purpose. Variable `J` should be set to the number
+obtain a good scheduling for two workers to produce ``a.vo``, ``b.vo``, and
+``c.vo``. When using a Makefile produced by ``coq_makefile``, the ``vio2vo`` target
+can be used for that purpose. Variable ``J`` should be set to the number
of workers, e.g. ``make vio2vo J=2``. The only caveat is that, while the
-.vo files obtained from `.vio` files are complete (they contain all proof
+.vo files obtained from ``.vio`` files are complete (they contain all proof
terms and universe constraints), the satisfiability of all universe
constraints has not been checked globally (they are checked to be
consistent for every single proof). Constraints will be checked when
-these `.vo` files are (recursively) loaded with ``Require``.
+these ``.vo`` files are (recursively) loaded with ``Require``.
There is an extra, possibly even faster, alternative: just check the
-proof tasks stored in `.vio` files without producing the `.vo` files. This
+proof tasks stored in ``.vio`` files without producing the ``.vo`` files. This
is possibly faster because all the proof tasks are independent, hence
one can further partition the job to be done between workers. The
``coqtop -schedule-vio-checking 6 a b c`` command can be used to obtain a
-good scheduling for 6 workers to check all the proof tasks of `a.vio`,
-`b.vio`, and `c.vio`. Auxiliary files are used to predict how long a proof
+good scheduling for 6 workers to check all the proof tasks of ``a.vio``,
+``b.vio``, and ``c.vio``. Auxiliary files are used to predict how long a proof
task will take, assuming it will take the same amount of time it took
last time. When using a Makefile produced by coq_makefile, the
-``checkproofs`` target can be used to check all `.vio` files. Variable `J`
+``checkproofs`` target can be used to check all ``.vio`` files. Variable ``J``
should be set to the number of workers, e.g. ``make checkproofs J=6``. As
-when converting `.vio` files to `.vo` files, universe constraints are not
+when converting ``.vio`` files to ``.vo`` files, universe constraints are not
checked to be globally consistent. Hence this compilation mode is only
useful for quick regression testing and on developments not making
-heavy use of the `Type` hierarchy.
+heavy use of the ``Type`` hierarchy.
Limiting the number of parallel workers
--------------------------------------------
Many |Coq| processes may run on the same computer, and each of them may
-start many additional worker processes. The `coqworkmgr` utility lets
+start many additional worker processes. The ``coqworkmgr`` utility lets
one limit the number of workers, globally.
The utility accepts the ``-j`` argument to specify the maximum number of
-workers (defaults to 2). `coqworkmgr` automatically starts in the
+workers (defaults to 2). ``coqworkmgr`` automatically starts in the
background and prints an environment variable assignment
like ``COQWORKMGR_SOCKET=localhost:45634``. The user must set this variable
in all the shells from which |Coq| processes will be started. If one
uses just one terminal running the bash shell, then
``export ‘coqworkmgr -j 4‘`` will do the job.
-After that, all |Coq| processes, e.g. `coqide` and `coqc`, will respect the
+After that, all |Coq| processes, e.g. ``coqide`` and ``coqc``, will respect the
limit, globally.
diff --git a/doc/sphinx/language/cic.rst b/doc/sphinx/language/cic.rst
index 91504089a8..67683902cd 100644
--- a/doc/sphinx/language/cic.rst
+++ b/doc/sphinx/language/cic.rst
@@ -84,7 +84,7 @@ implemented using *algebraic
universes*. An algebraic universe :math:`u` is either a variable (a qualified
identifier with a number) or a successor of an algebraic universe (an
expression :math:`u+1`), or an upper bound of algebraic universes (an
-expression :math:`\max(u 1 ,...,u n )`), or the base universe (the expression
+expression :math:`\max(u_1 ,...,u_n )`), or the base universe (the expression
:math:`0`) which corresponds, in the arity of template polymorphic inductive
types (see Section
:ref:`well-formed-inductive-definitions`),
@@ -117,18 +117,18 @@ the following rules.
#. variables, hereafter ranged over by letters :math:`x`, :math:`y`, etc., are terms
#. constants, hereafter ranged over by letters :math:`c`, :math:`d`, etc., are terms.
#. if :math:`x` is a variable and :math:`T`, :math:`U` are terms then
- :math:`∀ x:T,U` (:g:`forall x:T, U` in |Coq| concrete syntax) is a term.
- If :math:`x` occurs in :math:`U`, :math:`∀ x:T,U` reads as
+ :math:`∀ x:T,~U` (:g:`forall x:T, U` in |Coq| concrete syntax) is a term.
+ If :math:`x` occurs in :math:`U`, :math:`∀ x:T,~U` reads as
“for all :math:`x` of type :math:`T`, :math:`U`”.
- As :math:`U` depends on :math:`x`, one says that :math:`∀ x:T,U` is
+ As :math:`U` depends on :math:`x`, one says that :math:`∀ x:T,~U` is
a *dependent product*. If :math:`x` does not occur in :math:`U` then
- :math:`∀ x:T,U` reads as
+ :math:`∀ x:T,~U` reads as
“if :math:`T` then :math:`U`”. A *non dependent product* can be
written: :math:`T \rightarrow U`.
#. if :math:`x` is a variable and :math:`T`, :math:`u` are terms then
- :math:`λ x:T . u` (:g:`fun x:T => u`
+ :math:`λ x:T .~u` (:g:`fun x:T => u`
in |Coq| concrete syntax) is a term. This is a notation for the
- λ-abstraction of λ-calculus :cite:`Bar81`. The term :math:`λ x:T . u` is a function
+ λ-abstraction of λ-calculus :cite:`Bar81`. The term :math:`λ x:T .~u` is a function
which maps elements of :math:`T` to the expression :math:`u`.
#. if :math:`t` and :math:`u` are terms then :math:`(t~u)` is a term
(:g:`t u` in |Coq| concrete
@@ -172,11 +172,11 @@ implicative proposition, to denote :math:`\nat →\Prop` which is the type of
unary predicates over the natural numbers, etc.
Let us assume that ``mult`` is a function of type :math:`\nat→\nat→\nat` and ``eqnat`` a
-predicate of type \nat→\nat→ \Prop. The λ-abstraction can serve to build
-“ordinary” functions as in :math:`λ x:\nat.(\kw{mult}~x~x)` (i.e.
+predicate of type :math:`\nat→\nat→ \Prop`. The λ-abstraction can serve to build
+“ordinary” functions as in :math:`λ x:\nat.~(\kw{mult}~x~x)` (i.e.
:g:`fun x:nat => mult x x`
in |Coq| notation) but may build also predicates over the natural
-numbers. For instance :math:`λ x:\nat.(\kw{eqnat}~x~0)`
+numbers. For instance :math:`λ x:\nat.~(\kw{eqnat}~x~0)`
(i.e. :g:`fun x:nat => eqnat x 0`
in |Coq| notation) will represent the predicate of one variable :math:`x` which
asserts the equality of :math:`x` with :math:`0`. This predicate has type
@@ -186,7 +186,7 @@ object :math:`P~t` of type :math:`\Prop`, namely a proposition.
Furthermore :g:`forall x:nat, P x` will represent the type of functions
which associate to each natural number :math:`n` an object of type :math:`(P~n)` and
-consequently represent the type of proofs of the formula “:math:`∀ x. P(x`)”.
+consequently represent the type of proofs of the formula “:math:`∀ x.~P(x)`”.
.. _Typing-rules:
@@ -206,7 +206,7 @@ A *local context* is an ordered list of *local declarations* of names
which we call *variables*. The declaration of some variable :math:`x` is
either a *local assumption*, written :math:`x:T` (:math:`T` is a type) or a *local
definition*, written :math:`x:=t:T`. We use brackets to write local contexts.
-A typical example is :math:`[x:T;y:=u:U;z:V]`. Notice that the variables
+A typical example is :math:`[x:T;~y:=u:U;~z:V]`. Notice that the variables
declared in a local context must be distinct. If :math:`Γ` is a local context
that declares some :math:`x`, we
write :math:`x ∈ Γ`. By writing :math:`(x:T) ∈ Γ` we mean that either :math:`x:T` is an
@@ -232,9 +232,9 @@ A *global assumption* will be represented in the global environment as
:math:`(c:T)` which assumes the name :math:`c` to be of some type :math:`T`. A *global
definition* will be represented in the global environment as :math:`c:=t:T`
which defines the name :math:`c` to have value :math:`t` and type :math:`T`. We shall call
-such names *constants*. For the rest of the chapter, the :math:`E;c:T` denotes
+such names *constants*. For the rest of the chapter, the :math:`E;~c:T` denotes
the global environment :math:`E` enriched with the global assumption :math:`c:T`.
-Similarly, :math:`E;c:=t:T` denotes the global environment :math:`E` enriched with the
+Similarly, :math:`E;~c:=t:T` denotes the global environment :math:`E` enriched with the
global definition :math:`(c:=t:T)`.
The rules for inductive definitions (see Section
@@ -284,14 +284,14 @@ following rules.
s \in \Sort
c \notin E
------------
- \WF{E;c:T}{}
+ \WF{E;~c:T}{}
.. inference:: W-Global-Def
\WTE{}{t}{T}
c \notin E
---------------
- \WF{E;c:=t:T}{}
+ \WF{E;~c:=t:T}{}
.. inference:: Ax-Prop
@@ -328,10 +328,10 @@ following rules.
.. inference:: Prod-Prop
\WTEG{T}{s}
- s \in {\Sort}
+ s \in \Sort
\WTE{\Gamma::(x:T)}{U}{\Prop}
-----------------------------
- \WTEG{\forall~x:T,U}{\Prop}
+ \WTEG{∀ x:T,~U}{\Prop}
.. inference:: Prod-Set
@@ -339,25 +339,25 @@ following rules.
s \in \{\Prop, \Set\}
\WTE{\Gamma::(x:T)}{U}{\Set}
----------------------------
- \WTEG{\forall~x:T,U}{\Set}
+ \WTEG{∀ x:T,~U}{\Set}
.. inference:: Prod-Type
\WTEG{T}{\Type(i)}
\WTE{\Gamma::(x:T)}{U}{\Type(i)}
--------------------------------
- \WTEG{\forall~x:T,U}{\Type(i)}
+ \WTEG{∀ x:T,~U}{\Type(i)}
.. inference:: Lam
- \WTEG{\forall~x:T,U}{s}
+ \WTEG{∀ x:T,~U}{s}
\WTE{\Gamma::(x:T)}{t}{U}
------------------------------------
- \WTEG{\lb x:T\mto t}{\forall x:T, U}
+ \WTEG{λ x:T\mto t}{∀ x:T,~U}
.. inference:: App
- \WTEG{t}{\forall~x:U,T}
+ \WTEG{t}{∀ x:U,~T}
\WTEG{u}{U}
------------------------------
\WTEG{(t\ u)}{\subst{T}{x}{u}}
@@ -406,7 +406,7 @@ can decide if two programs are *intentionally* equal (one says
We want to be able to identify some terms as we can identify the
application of a function to a given argument with its result. For
-instance the identity function over a given type T can be written
+instance the identity function over a given type :math:`T` can be written
:math:`λx:T.~x`. In any global environment :math:`E` and local context
:math:`Γ`, we want to identify any object :math:`a` (of type
:math:`T`) with the application :math:`((λ x:T.~x)~a)`. We define for
@@ -490,10 +490,10 @@ destroyed, this reduction differs from δ-reduction. It is called
~~~~~~~~~~~
Another important concept is η-expansion. It is legal to identify any
-term :math:`t` of functional type :math:`∀ x:T, U` with its so-called η-expansion
+term :math:`t` of functional type :math:`∀ x:T,~U` with its so-called η-expansion
.. math::
- λx:T. (t~x)
+ λx:T.~(t~x)
for :math:`x` an arbitrary variable name fresh in :math:`t`.
@@ -503,26 +503,26 @@ for :math:`x` an arbitrary variable name fresh in :math:`t`.
We deliberately do not define η-reduction:
.. math::
- λ x:T. (t~x) \not\triangleright_η t
+ λ x:T.~(t~x)~\not\triangleright_η~t
This is because, in general, the type of :math:`t` need not to be convertible
- to the type of :math:`λ x:T. (t~x)`. E.g., if we take :math:`f` such that:
+ to the type of :math:`λ x:T.~(t~x)`. E.g., if we take :math:`f` such that:
.. math::
- f : ∀ x:\Type(2),\Type(1)
+ f ~:~ ∀ x:\Type(2),~\Type(1)
then
.. math::
- λ x:\Type(1),(f~x) : ∀ x:\Type(1),\Type(1)
+ λ x:\Type(1).~(f~x) ~:~ ∀ x:\Type(1),~\Type(1)
We could not allow
.. math::
- λ x:Type(1),(f~x) \triangleright_η f
+ λ x:\Type(1).~(f~x) ~\triangleright_η~ f
- because the type of the reduced term :math:`∀ x:\Type(2),\Type(1)` would not be
- convertible to the type of the original term :math:`∀ x:\Type(1),\Type(1).`
+ because the type of the reduced term :math:`∀ x:\Type(2),~\Type(1)` would not be
+ convertible to the type of the original term :math:`∀ x:\Type(1),~\Type(1)`.
.. _convertibility:
@@ -541,9 +541,9 @@ global environment :math:`E` and local context :math:`Γ` iff there
exist terms :math:`u_1` and :math:`u_2` such that :math:`E[Γ] ⊢ t_1 \triangleright
… \triangleright u_1` and :math:`E[Γ] ⊢ t_2 \triangleright … \triangleright u_2` and either :math:`u_1` and
:math:`u_2` are identical, or they are convertible up to η-expansion,
-i.e. :math:`u_1` is :math:`λ x:T. u_1'` and :math:`u_2 x` is
+i.e. :math:`u_1` is :math:`λ x:T.~u_1'` and :math:`u_2 x` is
recursively convertible to :math:`u_1'` , or, symmetrically,
-:math:`u_2` is :math:`λx:T. u_2'`
+:math:`u_2` is :math:`λx:T.~u_2'`
and :math:`u_1 x` is recursively convertible to :math:`u_2'`. We then write
:math:`E[Γ] ⊢ t_1 =_{βδιζη} t_2` .
@@ -601,8 +601,8 @@ Subtyping rules
-------------------
At the moment, we did not take into account one rule between universes
-which says that any term in a universe of index i is also a term in
-the universe of index i+1 (this is the *cumulativity* rule of |Cic|).
+which says that any term in a universe of index :math:`i` is also a term in
+the universe of index :math:`i+1` (this is the *cumulativity* rule of |Cic|).
This property extends the equivalence relation of convertibility into
a *subtyping* relation inductively defined by:
@@ -614,25 +614,25 @@ a *subtyping* relation inductively defined by:
:math:`E[Γ] ⊢ \Prop ≤_{βδιζη} \Type(i)`, for any :math:`i`
#. if :math:`E[Γ] ⊢ T =_{βδιζη} U` and
:math:`E[Γ::(x:T)] ⊢ T' ≤_{βδιζη} U'` then
- :math:`E[Γ] ⊢ ∀x:T, T′ ≤_{βδιζη} ∀ x:U, U′`.
+ :math:`E[Γ] ⊢ ∀x:T,~T′ ≤_{βδιζη} ∀ x:U,~U′`.
#. if :math:`\ind{p}{Γ_I}{Γ_C}` is a universe polymorphic and cumulative
(see Chapter :ref:`polymorphicuniverses`) inductive type (see below)
and
- :math:`(t : ∀Γ_P ,∀Γ_{\mathit{Arr}(t)}, \Sort)∈Γ_I`
+ :math:`(t : ∀Γ_P ,∀Γ_{\mathit{Arr}(t)}, S)∈Γ_I`
and
- :math:`(t' : ∀Γ_P' ,∀Γ_{\mathit{Arr}(t)}', \Sort')∈Γ_I`
+ :math:`(t' : ∀Γ_P' ,∀Γ_{\mathit{Arr}(t)}', S')∈Γ_I`
are two different instances of *the same* inductive type (differing only in
universe levels) with constructors
.. math::
- [c_1 : ∀Γ_P ,∀ T_{1,1} … T_{1,n_1} ,~t~v_{1,1} … v_{1,m} ;…;
- c_k : ∀Γ_P ,∀ T_{k,1} … T_{k,n_k} ,~t~v_{k,1} … v_{k,m} ]
+ [c_1 : ∀Γ_P ,∀ T_{1,1} … T_{1,n_1} ,~t~v_{1,1} … v_{1,m} ;~…;~
+ c_k : ∀Γ_P ,∀ T_{k,1} … T_{k,n_k} ,~t~v_{k,1} … v_{k,m} ]
and
.. math::
- [c_1 : ∀Γ_P' ,∀ T_{1,1}' … T_{1,n_1}' ,~t'~v_{1,1}' … v_{1,m}' ;…;
- c_k : ∀Γ_P' ,∀ T_{k,1}' … T_{k,n_k}' ,~t'~v_{k,1}' … v_{k,m}' ]
+ [c_1 : ∀Γ_P' ,∀ T_{1,1}' … T_{1,n_1}' ,~t'~v_{1,1}' … v_{1,m}' ;~…;~
+ c_k : ∀Γ_P' ,∀ T_{k,1}' … T_{k,n_k}' ,~t'~v_{k,1}' … v_{k,m}' ]
respectively then
@@ -656,8 +656,8 @@ a *subtyping* relation inductively defined by:
.. math::
E[Γ] ⊢ A_i ≤_{βδιζη} A_i'
- where :math:`Γ_{\mathit{Arr}(t)} = [a_1 : A_1 ; … ; a_l : A_l ]` and
- :math:`Γ_{\mathit{Arr}(t)}' = [a_1 : A_1'; … ; a_l : A_l']`.
+ where :math:`Γ_{\mathit{Arr}(t)} = [a_1 : A_1 ;~ … ;~a_l : A_l ]` and
+ :math:`Γ_{\mathit{Arr}(t)}' = [a_1 : A_1';~ … ;~a_l : A_l']`.
The conversion rule up to subtyping is now exactly:
@@ -677,19 +677,19 @@ The conversion rule up to subtyping is now exactly:
form*. There are several ways (or strategies) to apply the reduction
rules. Among them, we have to mention the *head reduction* which will
play an important role (see Chapter :ref:`tactics`). Any term :math:`t` can be written as
-:math:`λ x_1 :T_1 . … λ x_k :T_k . (t_0~t_1 … t_n )` where :math:`t_0` is not an
+:math:`λ x_1 :T_1 .~… λ x_k :T_k .~(t_0~t_1 … t_n )` where :math:`t_0` is not an
application. We say then that :math:`t_0` is the *head of* :math:`t`. If we assume
-that :math:`t_0` is :math:`λ x:T. u_0` then one step of β-head reduction of :math:`t` is:
+that :math:`t_0` is :math:`λ x:T.~u_0` then one step of β-head reduction of :math:`t` is:
.. math::
- λ x_1 :T_1 . … λ x_k :T_k . (λ x:T. u_0~t_1 … t_n ) \triangleright
- λ (x_1 :T_1 )…(x_k :T_k ). (\subst{u_0}{x}{t_1}~t_2 … t_n )
+ λ x_1 :T_1 .~… λ x_k :T_k .~(λ x:T.~u_0~t_1 … t_n ) ~\triangleright~
+ λ (x_1 :T_1 )…(x_k :T_k ).~(\subst{u_0}{x}{t_1}~t_2 … t_n )
Iterating the process of head reduction until the head of the reduced
term is no more an abstraction leads to the *β-head normal form* of :math:`t`:
.. math::
- t \triangleright … \triangleright λ x_1 :T_1 . …λ x_k :T_k . (v~u_1 … u_m )
+ t \triangleright … \triangleright λ x_1 :T_1 .~…λ x_k :T_k .~(v~u_1 … u_m )
where :math:`v` is not an abstraction (nor an application). Note that the head
normal form must not be confused with the normal form since some :math:`u_i`
@@ -713,12 +713,12 @@ Formally, we can represent any *inductive definition* as
These inductive definitions, together with global assumptions and
global definitions, then form the global environment. Additionally,
-for any :math:`p` there always exists :math:`Γ_P =[a_1 :A_1 ;…;a_p :A_p ]` such that
+for any :math:`p` there always exists :math:`Γ_P =[a_1 :A_1 ;~…;~a_p :A_p ]` such that
each :math:`T` in :math:`(t:T)∈Γ_I \cup Γ_C` can be written as: :math:`∀Γ_P , T'` where :math:`Γ_P` is
called the *context of parameters*. Furthermore, we must have that
each :math:`T` in :math:`(t:T)∈Γ_I` can be written as: :math:`∀Γ_P,∀Γ_{\mathit{Arr}(t)}, S` where
-:math:`Γ_{\mathit{Arr}(t)}` is called the *Arity* of the inductive type t and :math:`S` is called
-the sort of the inductive type t (not to be confused with :math:`\Sort` which is the set of sorts).
+:math:`Γ_{\mathit{Arr}(t)}` is called the *Arity* of the inductive type :math:`t` and :math:`S` is called
+the sort of the inductive type :math:`t` (not to be confused with :math:`\Sort` which is the set of sorts).
.. example::
@@ -726,8 +726,8 @@ the sort of the inductive type t (not to be confused with :math:`\Sort` which is
.. math::
\ind{1}{[\List:\Set→\Set]}{\left[\begin{array}{rcl}
- \Nil & : & \forall A:\Set,\List~A \\
- \cons & : & \forall A:\Set, A→ \List~A→ \List~A
+ \Nil & : & ∀ A:\Set,~\List~A \\
+ \cons & : & ∀ A:\Set,~A→ \List~A→ \List~A
\end{array}
\right]}
@@ -771,8 +771,8 @@ the sort of the inductive type t (not to be confused with :math:`\Sort` which is
\odd&:&\nat → \Prop \end{array}\right]}
{\left[\begin{array}{rcl}
\evenO &:& \even~0\\
- \evenS &:& \forall n, \odd~n → \even~(\nS~n)\\
- \oddS &:& \forall n, \even~n → \odd~(\nS~n)
+ \evenS &:& ∀ n,~\odd~n → \even~(\nS~n)\\
+ \oddS &:& ∀ n,~\even~n → \odd~(\nS~n)
\end{array}\right]}
which corresponds to the result of the |Coq| declaration:
@@ -792,7 +792,7 @@ the sort of the inductive type t (not to be confused with :math:`\Sort` which is
Types of inductive objects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We have to give the type of constants in a global environment E which
+We have to give the type of constants in a global environment :math:`E` which
contains an inductive declaration.
.. inference:: Ind
@@ -821,8 +821,8 @@ contains an inductive declaration.
E[Γ] ⊢ \even : \nat→\Prop\\
E[Γ] ⊢ \odd : \nat→\Prop\\
E[Γ] ⊢ \evenO : \even~\nO\\
- E[Γ] ⊢ \evenS : \forall~n:\nat,~\odd~n → \even~(\nS~n)\\
- E[Γ] ⊢ \oddS : \forall~n:\nat,~\even~n → \odd~(\nS~n)
+ E[Γ] ⊢ \evenS : ∀ n:\nat,~\odd~n → \even~(\nS~n)\\
+ E[Γ] ⊢ \oddS : ∀ n:\nat,~\even~n → \odd~(\nS~n)
\end{array}
@@ -842,11 +842,11 @@ Arity of a given sort
+++++++++++++++++++++
A type :math:`T` is an *arity of sort* :math:`s` if it converts to the sort :math:`s` or to a
-product :math:`∀ x:T,U` with :math:`U` an arity of sort :math:`s`.
+product :math:`∀ x:T,~U` with :math:`U` an arity of sort :math:`s`.
.. example::
- :math:`A→\Set` is an arity of sort :math:`\Set`. :math:`∀ A:\Prop,A→ \Prop` is an arity of sort
+ :math:`A→\Set` is an arity of sort :math:`\Set`. :math:`∀ A:\Prop,~A→ \Prop` is an arity of sort
:math:`\Prop`.
@@ -858,21 +858,21 @@ sort :math:`s`.
.. example::
- :math:`A→ Set` and :math:`∀ A:\Prop,A→ \Prop` are arities.
+ :math:`A→ \Set` and :math:`∀ A:\Prop,~A→ \Prop` are arities.
Type of constructor
+++++++++++++++++++
-We say that T is a *type of constructor of I* in one of the following
+We say that :math:`T` is a *type of constructor of* :math:`I` in one of the following
two cases:
+ :math:`T` is :math:`(I~t_1 … t_n )`
-+ :math:`T` is :math:`∀ x:U,T'` where :math:`T'` is also a type of constructor of :math:`I`
++ :math:`T` is :math:`∀ x:U,~T'` where :math:`T'` is also a type of constructor of :math:`I`
.. example::
:math:`\nat` and :math:`\nat→\nat` are types of constructor of :math:`\nat`.
- :math:`∀ A:Type,\List~A` and :math:`∀ A:Type,A→\List~A→\List~A` are types of constructor of :math:`\List`.
+ :math:`∀ A:\Type,~\List~A` and :math:`∀ A:\Type,~A→\List~A→\List~A` are types of constructor of :math:`\List`.
.. _positivity:
@@ -883,7 +883,7 @@ The type of constructor :math:`T` will be said to *satisfy the positivity
condition* for a constant :math:`X` in the following cases:
+ :math:`T=(X~t_1 … t_n )` and :math:`X` does not occur free in any :math:`t_i`
-+ :math:`T=∀ x:U,V` and :math:`X` occurs only strictly positively in :math:`U` and the type :math:`V`
++ :math:`T=∀ x:U,~V` and :math:`X` occurs only strictly positively in :math:`U` and the type :math:`V`
satisfies the positivity condition for :math:`X`.
Strict positivity
@@ -895,13 +895,13 @@ cases:
+ :math:`X` does not occur in :math:`T`
+ :math:`T` converts to :math:`(X~t_1 … t_n )` and :math:`X` does not occur in any of :math:`t_i`
-+ :math:`T` converts to :math:`∀ x:U,V` and :math:`X` does not occur in type :math:`U` but occurs
++ :math:`T` converts to :math:`∀ x:U,~V` and :math:`X` does not occur in type :math:`U` but occurs
strictly positively in type :math:`V`
+ :math:`T` converts to :math:`(I~a_1 … a_m~t_1 … t_p )` where :math:`I` is the name of an
inductive declaration of the form
.. math::
- \ind{m}{I:A}{c_1 :∀ p_1 :P_1 ,… ∀p_m :P_m ,C_1 ;…;c_n :∀ p_1 :P_1 ,… ∀p_m :P_m ,C_n}
+ \ind{m}{I:A}{c_1 :∀ p_1 :P_1 ,… ∀p_m :P_m ,~C_1 ;~…;~c_n :∀ p_1 :P_1 ,… ∀p_m :P_m ,~C_n}
(in particular, it is
not mutually defined and it has :math:`m` parameters) and :math:`X` does not occur in
@@ -916,7 +916,7 @@ condition* for a constant :math:`X` in the following cases:
+ :math:`T=(I~b_1 … b_m~u_1 … u_p)`, :math:`I` is an inductive definition with :math:`m`
parameters and :math:`X` does not occur in any :math:`u_i`
-+ :math:`T=∀ x:U,V` and :math:`X` occurs only strictly positively in :math:`U` and the type :math:`V`
++ :math:`T=∀ x:U,~V` and :math:`X` occurs only strictly positively in :math:`U` and the type :math:`V`
satisfies the nested positivity condition for :math:`X`
@@ -930,7 +930,6 @@ condition* for a constant :math:`X` in the following cases:
Inductive nattree (A:Type) : Type :=
| leaf : nattree A
| node : A -> (nat -> nattree A) -> nattree A.
- End TreeExample.
Then every instantiated constructor of ``nattree A`` satisfies the nested positivity
condition for ``nattree``:
@@ -958,8 +957,8 @@ We shall now describe the rules allowing the introduction of a new
inductive definition.
Let :math:`E` be a global environment and :math:`Γ_P`, :math:`Γ_I`, :math:`Γ_C` be contexts
-such that :math:`Γ_I` is :math:`[I_1 :∀ Γ_P ,A_1 ;…;I_k :∀ Γ_P ,A_k]`, and
-:math:`Γ_C` is :math:`[c_1:∀ Γ_P ,C_1 ;…;c_n :∀ Γ_P ,C_n ]`. Then
+such that :math:`Γ_I` is :math:`[I_1 :∀ Γ_P ,A_1 ;~…;~I_k :∀ Γ_P ,A_k]`, and
+:math:`Γ_C` is :math:`[c_1:∀ Γ_P ,C_1 ;~…;~c_n :∀ Γ_P ,C_n ]`. Then
.. inference:: W-Ind
@@ -967,7 +966,7 @@ such that :math:`Γ_I` is :math:`[I_1 :∀ Γ_P ,A_1 ;…;I_k :∀ Γ_P ,A_k]`,
(E[Γ_P ] ⊢ A_j : s_j )_{j=1… k}
(E[Γ_I ;Γ_P ] ⊢ C_i : s_{q_i} )_{i=1… n}
------------------------------------------
- \WF{E;\ind{p}{Γ_I}{Γ_C}}{Γ}
+ \WF{E;~\ind{p}{Γ_I}{Γ_C}}{Γ}
provided that the following side conditions hold:
@@ -990,8 +989,8 @@ the Type hierarchy.
.. example::
It is well known that the existential quantifier can be encoded as an
- inductive definition. The following declaration introduces the second-
- order existential quantifier :math:`∃ X.P(X)`.
+ inductive definition. The following declaration introduces the
+ second-order existential quantifier :math:`∃ X.P(X)`.
.. coqtop:: in
@@ -1028,7 +1027,7 @@ in :math:`\Type`.
.. flag:: Auto Template Polymorphism
This option, enabled by default, makes every inductive type declared
- at level :math:`Type` (without annotations or hiding it behind a
+ at level :math:`\Type` (without annotations or hiding it behind a
definition) template polymorphic.
This can be prevented using the ``notemplate`` attribute.
@@ -1055,9 +1054,9 @@ Calculus of Inductive Constructions. The following typing rule is
added to the theory.
Let :math:`\ind{p}{Γ_I}{Γ_C}` be an inductive definition. Let
-:math:`Γ_P = [p_1 :P_1 ;…;p_p :P_p ]` be its context of parameters,
-:math:`Γ_I = [I_1:∀ Γ_P ,A_1 ;…;I_k :∀ Γ_P ,A_k ]` its context of definitions and
-:math:`Γ_C = [c_1 :∀ Γ_P ,C_1 ;…;c_n :∀ Γ_P ,C_n]` its context of constructors,
+:math:`Γ_P = [p_1 :P_1 ;~…;~p_p :P_p ]` be its context of parameters,
+:math:`Γ_I = [I_1:∀ Γ_P ,A_1 ;~…;~I_k :∀ Γ_P ,A_k ]` its context of definitions and
+:math:`Γ_C = [c_1 :∀ Γ_P ,C_1 ;~…;~c_n :∀ Γ_P ,C_n]` its context of constructors,
with :math:`c_i` a constructor of :math:`I_{q_i}`. Let :math:`m ≤ p` be the length of the
longest prefix of parameters such that the :math:`m` first arguments of all
occurrences of all :math:`I_j` in all :math:`C_k` (even the occurrences in the
@@ -1077,15 +1076,15 @@ uniform parameters of :math:`Γ_P` . We have:
\end{array}
\right.
-----------------------------
- E[] ⊢ I_j~q_1 … q_r :∀ [p_{r+1} :P_{r+1} ;…;p_p :P_p], (A_j)_{/s_j}
+ E[] ⊢ I_j~q_1 … q_r :∀ [p_{r+1} :P_{r+1} ;~…;~p_p :P_p], (A_j)_{/s_j}
provided that the following side conditions hold:
+ :math:`Γ_{P′}` is the context obtained from :math:`Γ_P` by replacing each :math:`P_l` that is
an arity with :math:`P_l'` for :math:`1≤ l ≤ r` (notice that :math:`P_l` arity implies :math:`P_l'`
- arity since :math:`(E[] ⊢ P_l' ≤_{βδιζη} \subst{P_l}{p_u}{q_u}_{u=1\ldots l-1} )`;
+ arity since :math:`E[] ⊢ P_l' ≤_{βδιζη} \subst{P_l}{p_u}{q_u}_{u=1\ldots l-1}`);
+ there are sorts :math:`s_i` , for :math:`1 ≤ i ≤ k` such that, for
- :math:`Γ_{I'} = [I_1 :∀ Γ_{P'} ,(A_1)_{/s_1} ;…;I_k :∀ Γ_{P'} ,(A_k)_{/s_k}]`
+ :math:`Γ_{I'} = [I_1 :∀ Γ_{P'} ,(A_1)_{/s_1} ;~…;~I_k :∀ Γ_{P'} ,(A_k)_{/s_k}]`
we have :math:`(E[Γ_{I′} ;Γ_{P′}] ⊢ C_i : s_{q_i})_{i=1… n}` ;
+ the sorts :math:`s_i` are such that all eliminations, to
:math:`\Prop`, :math:`\Set` and :math:`\Type(j)`, are allowed
@@ -1103,7 +1102,7 @@ replacements of sorts, needed for this derivation, in the parameters
that are arities (this is possible because :math:`\ind{p}{Γ_I}{Γ_C}` well-formed
implies that :math:`\ind{p}{Γ_{I'}}{Γ_{C'}}` is well-formed and has the
same allowed eliminations, where :math:`Γ_{I′}` is defined as above and
-:math:`Γ_{C′} = [c_1 :∀ Γ_{P′} ,C_1 ;…;c_n :∀ Γ_{P′} ,C_n ]`). That is, the changes in the
+:math:`Γ_{C′} = [c_1 :∀ Γ_{P′} ,C_1 ;~…;~c_n :∀ Γ_{P′} ,C_n ]`). That is, the changes in the
types of each partial instance :math:`q_1 … q_r` can be characterized by the
ordered sets of arity sorts among the types of parameters, and to each
signature is associated a new inductive definition with fresh names.
@@ -1206,7 +1205,7 @@ recursion (even terminating). So the basic idea is to restrict
ourselves to primitive recursive functions and functionals.
For instance, assuming a parameter :math:`A:\Set` exists in the local context,
-we want to build a function length of type :math:`\List~A → \nat` which computes
+we want to build a function :math:`\length` of type :math:`\List~A → \nat` which computes
the length of the list, such that :math:`(\length~(\Nil~A)) = \nO` and
:math:`(\length~(\cons~A~a~l)) = (\nS~(\length~l))`.
We want these equalities to be
@@ -1232,7 +1231,7 @@ principles. For instance, in order to prove
:math:`(\kw{has}\_\kw{length}~A~(\cons~A~a~l)~(\length~(\cons~A~a~l)))`
-which given the conversion equalities satisfied by length is the same
+which given the conversion equalities satisfied by :math:`\length` is the same
as proving:
@@ -1268,7 +1267,7 @@ The |Coq| term for this proof
will be written:
.. math::
- \Match~m~\with~(c_1~x_{11} ... x_{1p_1} ) ⇒ f_1 | … | (c_n~x_{n1} ... x_{np_n} ) ⇒ f_n \kwend
+ \Match~m~\with~(c_1~x_{11} ... x_{1p_1} ) ⇒ f_1 | … | (c_n~x_{n1} ... x_{np_n} ) ⇒ f_n~\kwend
In this expression, if :math:`m` eventually happens to evaluate to
:math:`(c_i~u_1 … u_{p_i})` then the expression will behave as specified in its :math:`i`-th branch
@@ -1276,7 +1275,7 @@ and it will reduce to :math:`f_i` where the :math:`x_{i1} …x_{ip_i}` are repla
:math:`u_1 … u_{p_i}` according to the ι-reduction.
Actually, for type checking a :math:`\Match…\with…\kwend` expression we also need
-to know the predicate P to be proved by case analysis. In the general
+to know the predicate :math:`P` to be proved by case analysis. In the general
case where :math:`I` is an inductively defined :math:`n`-ary relation, :math:`P` is a predicate
over :math:`n+1` arguments: the :math:`n` first ones correspond to the arguments of :math:`I`
(parameters excluded), and the last one corresponds to object :math:`m`. |Coq|
@@ -1310,7 +1309,7 @@ inference rules, we use a more compact notation:
.. _Allowed-elimination-sorts:
-**Allowed elimination sorts.** An important question for building the typing rule for match is what
+**Allowed elimination sorts.** An important question for building the typing rule for :math:`\Match` is what
can be the type of :math:`λ a x . P` with respect to the type of :math:`m`. If :math:`m:I`
and :math:`I:A` and :math:`λ a x . P : B` then by :math:`[I:A|B]` we mean that one can use
:math:`λ a x . P` with :math:`m` in the above match-construct.
@@ -1328,7 +1327,7 @@ There is no restriction on the sort of the predicate to be eliminated.
[(I~x):A′|B′]
-----------------------
- [I:∀ x:A, A′|∀ x:A, B′]
+ [I:∀ x:A,~A′|∀ x:A,~B′]
.. inference:: Set & Type
@@ -1348,7 +1347,7 @@ sort :math:`\Prop`.
~
---------------
- [I:Prop|I→Prop]
+ [I:\Prop|I→\Prop]
:math:`\Prop` is the type of logical propositions, the proofs of properties :math:`P` in
@@ -1377,7 +1376,7 @@ the proof of :g:`or A B` is not accepted:
From the computational point of view, the structure of the proof of
:g:`(or A B)` in this term is needed for computing the boolean value.
-In general, if :math:`I` has type :math:`\Prop` then :math:`P` cannot have type :math:`I→Set,` because
+In general, if :math:`I` has type :math:`\Prop` then :math:`P` cannot have type :math:`I→\Set`, because
it will mean to build an informative proof of type :math:`(P~m)` doing a case
analysis over a non-computational object that will disappear in the
extracted program. But the other way is safe with respect to our
@@ -1385,11 +1384,11 @@ interpretation we can have :math:`I` a computational object and :math:`P` a
non-computational one, it just corresponds to proving a logical property
of a computational object.
-In the same spirit, elimination on :math:`P` of type :math:`I→Type` cannot be allowed
-because it trivially implies the elimination on :math:`P` of type :math:`I→ Set` by
+In the same spirit, elimination on :math:`P` of type :math:`I→\Type` cannot be allowed
+because it trivially implies the elimination on :math:`P` of type :math:`I→ \Set` by
cumulativity. It also implies that there are two proofs of the same
-property which are provably different, contradicting the proof-
-irrelevance property which is sometimes a useful axiom:
+property which are provably different, contradicting the
+proof-irrelevance property which is sometimes a useful axiom:
.. example::
@@ -1398,7 +1397,7 @@ irrelevance property which is sometimes a useful axiom:
Axiom proof_irrelevance : forall (P : Prop) (x y : P), x=y.
The elimination of an inductive definition of type :math:`\Prop` on a predicate
-:math:`P` of type :math:`I→ Type` leads to a paradox when applied to impredicative
+:math:`P` of type :math:`I→ \Type` leads to a paradox when applied to impredicative
inductive definition like the second-order existential quantifier
:g:`exProp` defined above, because it gives access to the two projections on
this type.
@@ -1414,7 +1413,7 @@ this type.
I~\kw{is an empty or singleton definition}
s ∈ \Sort
-------------------------------------
- [I:Prop|I→ s]
+ [I:\Prop|I→ s]
A *singleton definition* has only one constructor and all the
arguments of this constructor have type :math:`\Prop`. In that case, there is a
@@ -1451,7 +1450,7 @@ corresponding to the :math:`c:C` constructor.
.. math::
\begin{array}{ll}
\{c:(I~p_1\ldots p_r\ t_1 \ldots t_p)\}^P &\equiv (P~t_1\ldots ~t_p~c) \\
- \{c:\forall~x:T,C\}^P &\equiv \forall~x:T,\{(c~x):C\}^P
+ \{c:∀ x:T,~C\}^P &\equiv ∀ x:T,~\{(c~x):C\}^P
\end{array}
We write :math:`\{c\}^P` for :math:`\{c:C\}^P` with :math:`C` the type of :math:`c`.
@@ -1470,7 +1469,7 @@ We write :math:`\{c\}^P` for :math:`\{c:C\}^P` with :math:`C` the type of :math:
can be represented in abstract syntax as
.. math::
- \case(t,P,f 1 | f 2 )
+ \case(t,P,f_1 | f_2 )
where
@@ -1478,9 +1477,9 @@ We write :math:`\{c\}^P` for :math:`\{c:C\}^P` with :math:`C` the type of :math:
:nowrap:
\begin{eqnarray*}
- P & = & \lambda~l~.~P^\prime\\
+ P & = & λ l.~P^\prime\\
f_1 & = & t_1\\
- f_2 & = & \lambda~(hd:\nat)~.~\lambda~(tl:\List~\nat)~.~t_2
+ f_2 & = & λ (hd:\nat).~λ (tl:\List~\nat).~t_2
\end{eqnarray*}
According to the definition:
@@ -1492,9 +1491,9 @@ We write :math:`\{c\}^P` for :math:`\{c:C\}^P` with :math:`C` the type of :math:
\begin{array}{rl}
\{(\cons~\nat)\}^P & ≡\{(\cons~\nat) : (\nat→\List~\nat→\List~\nat)\}^P \\
- & ≡∀ n:\nat, \{(\cons~\nat~n) : \List~\nat→\List~\nat)\}^P \\
- & ≡∀ n:\nat, ∀ l:\List~\nat, \{(\cons~\nat~n~l) : \List~\nat)\}^P \\
- & ≡∀ n:\nat, ∀ l:\List~\nat,(P~(\cons~\nat~n~l)).
+ & ≡∀ n:\nat,~\{(\cons~\nat~n) : (\List~\nat→\List~\nat)\}^P \\
+ & ≡∀ n:\nat,~∀ l:\List~\nat,~\{(\cons~\nat~n~l) : (\List~\nat)\}^P \\
+ & ≡∀ n:\nat,~∀ l:\List~\nat,~(P~(\cons~\nat~n~l)).
\end{array}
Given some :math:`P` then :math:`\{(\Nil~\nat)\}^P` represents the expected type of :math:`f_1` ,
@@ -1519,7 +1518,7 @@ following typing rule
E[Γ] ⊢ \case(c,P,f_1 |… |f_l ) : (P~t_1 … t_s~c)
provided :math:`I` is an inductive type in a
-definition :math:`\ind{r}{Γ_I}{Γ_C}` with :math:`Γ_C = [c_1 :C_1 ;…;c_n :C_n ]` and
+definition :math:`\ind{r}{Γ_I}{Γ_C}` with :math:`Γ_C = [c_1 :C_1 ;~…;~c_n :C_n ]` and
:math:`c_{p_1} … c_{p_l}` are the only constructors of :math:`I`.
@@ -1558,7 +1557,7 @@ The ι-contraction of this term is :math:`(f_i~a_1 … a_m )` leading to the
general reduction rule:
.. math::
- \case((c_{p_i}~q_1 … q_r~a_1 … a_m ),P,f_1 |… |f_n ) \triangleright_ι (f_i~a_1 … a_m )
+ \case((c_{p_i}~q_1 … q_r~a_1 … a_m ),P,f_1 |… |f_l ) \triangleright_ι (f_i~a_1 … a_m )
.. _Fixpoint-definitions:
@@ -1599,7 +1598,7 @@ The typing rule is the expected one for a fixpoint.
.. inference:: Fix
(E[Γ] ⊢ A_i : s_i )_{i=1… n}
- (E[Γ,f_1 :A_1 ,…,f_n :A_n ] ⊢ t_i : A_i )_{i=1… n}
+ (E[Γ;~f_1 :A_1 ;~…;~f_n :A_n ] ⊢ t_i : A_i )_{i=1… n}
-------------------------------------------------------
E[Γ] ⊢ \Fix~f_i\{f_1 :A_1 :=t_1 … f_n :A_n :=t_n \} : A_i
@@ -1639,7 +1638,7 @@ fixpoints is extended and becomes
where :math:`k_i` are positive integers. Each :math:`k_i` represents the index of
parameter of :math:`f_i` , on which :math:`f_i` is decreasing. Each :math:`A_i` should be a
type (reducible to a term) starting with at least :math:`k_i` products
-:math:`∀ y_1 :B_1 ,… ∀ y_{k_i} :B_{k_i} , A_i'` and :math:`B_{k_i}` an inductive type.
+:math:`∀ y_1 :B_1 ,~… ∀ y_{k_i} :B_{k_i} ,~A_i'` and :math:`B_{k_i}` an inductive type.
Now in the definition :math:`t_i`, if :math:`f_j` occurs then it should be applied to
at least :math:`k_j` arguments and the :math:`k_j`-th argument should be
@@ -1649,23 +1648,23 @@ The definition of being structurally smaller is a bit technical. One
needs first to define the notion of *recursive arguments of a
constructor*. For an inductive definition :math:`\ind{r}{Γ_I}{Γ_C}`, if the
type of a constructor :math:`c` has the form
-:math:`∀ p_1 :P_1 ,… ∀ p_r :P_r, ∀ x_1:T_1, … ∀ x_r :T_r, (I_j~p_1 … p_r~t_1 … t_s )`,
+:math:`∀ p_1 :P_1 ,~… ∀ p_r :P_r,~∀ x_1:T_1,~… ∀ x_r :T_r,~(I_j~p_1 … p_r~t_1 … t_s )`,
then the recursive
arguments will correspond to :math:`T_i` in which one of the :math:`I_l` occurs.
The main rules for being structurally smaller are the following.
Given a variable :math:`y` of an inductively defined type in a declaration
-:math:`\ind{r}{Γ_I}{Γ_C}` where :math:`Γ_I` is :math:`[I_1 :A_1 ;…;I_k :A_k]`, and :math:`Γ_C` is
-:math:`[c_1 :C_1 ;…;c_n :C_n ]`, the terms structurally smaller than :math:`y` are:
+:math:`\ind{r}{Γ_I}{Γ_C}` where :math:`Γ_I` is :math:`[I_1 :A_1 ;~…;~I_k :A_k]`, and :math:`Γ_C` is
+:math:`[c_1 :C_1 ;~…;~c_n :C_n ]`, the terms structurally smaller than :math:`y` are:
-+ :math:`(t~u)` and :math:`λ x:u . t` when :math:`t` is structurally smaller than :math:`y`.
++ :math:`(t~u)` and :math:`λ x:U .~t` when :math:`t` is structurally smaller than :math:`y`.
+ :math:`\case(c,P,f_1 … f_n)` when each :math:`f_i` is structurally smaller than :math:`y`.
If :math:`c` is :math:`y` or is structurally smaller than :math:`y`, its type is an inductive
definition :math:`I_p` part of the inductive declaration corresponding to :math:`y`.
Each :math:`f_i` corresponds to a type of constructor
- :math:`C_q ≡ ∀ p_1 :P_1 ,…,∀ p_r :P_r , ∀ y_1 :B_1 , … ∀ y_k :B_k , (I~a_1 … a_k )`
- and can consequently be written :math:`λ y_1 :B_1' . … λ y_k :B_k'. g_i`. (:math:`B_i'` is
+ :math:`C_q ≡ ∀ p_1 :P_1 ,~…,∀ p_r :P_r ,~∀ y_1 :B_1 ,~… ∀ y_k :B_k ,~(I~a_1 … a_k )`
+ and can consequently be written :math:`λ y_1 :B_1' .~… λ y_k :B_k'.~g_i`. (:math:`B_i'` is
obtained from :math:`B_i` by substituting parameters for variables) the variables
:math:`y_j` occurring in :math:`g_i` corresponding to recursive arguments :math:`B_i` (the
ones in which one of the :math:`I_l` occurs) are structurally smaller than y.
@@ -1709,7 +1708,7 @@ Let :math:`F` be the set of declarations:
The reduction for fixpoints is:
.. math::
- (\Fix~f_i \{F\}~a_1 …a_{k_i}) \triangleright_ι \subst{t_i}{f_k}{\Fix~f_k \{F\}}_{k=1… n} ~a_1 … a_{k_i}
+ (\Fix~f_i \{F\}~a_1 …a_{k_i}) ~\triangleright_ι~ \subst{t_i}{f_k}{\Fix~f_k \{F\}}_{k=1… n} ~a_1 … a_{k_i}
when :math:`a_{k_i}` starts with a constructor. This last restriction is needed
in order to keep strong normalization and corresponds to the reduction
@@ -1719,13 +1718,11 @@ possible:
.. math::
:nowrap:
- {\def\plus{\mathsf{plus}}
- \def\tri{\triangleright_\iota}
- \begin{eqnarray*}
- \plus~(\nS~(\nS~\nO))~(\nS~\nO) & \tri & \nS~(\plus~(\nS~\nO)~(\nS~\nO))\\
- & \tri & \nS~(\nS~(\plus~\nO~(\nS~\nO)))\\
- & \tri & \nS~(\nS~(\nS~\nO))\\
- \end{eqnarray*}}
+ \begin{eqnarray*}
+ \plus~(\nS~(\nS~\nO))~(\nS~\nO)~& \trii & \nS~(\plus~(\nS~\nO)~(\nS~\nO))\\
+ & \trii & \nS~(\nS~(\plus~\nO~(\nS~\nO)))\\
+ & \trii & \nS~(\nS~(\nS~\nO))\\
+ \end{eqnarray*}
.. _Mutual-induction:
@@ -1755,9 +1752,9 @@ reference to the global declaration in the subsequent global
environment and local context by explicitly applying this constant to
the constant :math:`c'`.
-Below, if :math:`Γ` is a context of the form :math:`[y_1 :A_1 ;…;y_n :A_n]`, we write
-:math:`∀x:U,\subst{Γ}{c}{x}` to mean
-:math:`[y_1 :∀ x:U,\subst{A_1}{c}{x};…;y_n :∀ x:U,\subst{A_n}{c}{x}]`
+Below, if :math:`Γ` is a context of the form :math:`[y_1 :A_1 ;~…;~y_n :A_n]`, we write
+:math:`∀x:U,~\subst{Γ}{c}{x}` to mean
+:math:`[y_1 :∀ x:U,~\subst{A_1}{c}{x};~…;~y_n :∀ x:U,~\subst{A_n}{c}{x}]`
and :math:`\subst{E}{|Γ|}{|Γ|c}` to mean the parallel substitution
:math:`E\{y_1 /(y_1~c)\}…\{y_n/(y_n~c)\}`.
@@ -1767,25 +1764,25 @@ and :math:`\subst{E}{|Γ|}{|Γ|c}` to mean the parallel substitution
**First abstracting property:**
.. math::
- \frac{\WF{E;c:U;E′;c′:=t:T;E″}{Γ}}
- {\WF{E;c:U;E′;c′:=λ x:U.~\subst{t}{c}{x}:∀x:U,~\subst{T}{c}{x};\subst{E″}{c′}{(c′~c)}}
- {\subst{Γ}{c}{(c~c′)}}}
+ \frac{\WF{E;~c:U;~E′;~c′:=t:T;~E″}{Γ}}
+ {\WF{E;~c:U;~E′;~c′:=λ x:U.~\subst{t}{c}{x}:∀x:U,~\subst{T}{c}{x};~\subst{E″}{c′}{(c′~c)}}
+ {\subst{Γ}{c′}{(c′~c)}}}
.. math::
- \frac{\WF{E;c:U;E′;c′:T;E″}{Γ}}
- {\WF{E;c:U;E′;c′:∀ x:U,~\subst{T}{c}{x};\subst{E″}{c′}{(c′~c)}}{\subst{Γ}{c}{(c~c′)}}}
+ \frac{\WF{E;~c:U;~E′;~c′:T;~E″}{Γ}}
+ {\WF{E;~c:U;~E′;~c′:∀ x:U,~\subst{T}{c}{x};~\subst{E″}{c′}{(c′~c)}}{\subst{Γ}{c′}{(c′~c)}}}
.. math::
- \frac{\WF{E;c:U;E′;\ind{p}{Γ_I}{Γ_C};E″}{Γ}}
- {\WFTWOLINES{E;c:U;E′;\ind{p+1}{∀ x:U,~\subst{Γ_I}{c}{x}}{∀ x:U,~\subst{Γ_C}{c}{x}};
- \subst{E″}{|Γ_I ,Γ_C |}{|Γ_I ,Γ_C | c}}
- {\subst{Γ}{|Γ_I ,Γ_C|}{|Γ_I ,Γ_C | c}}}
+ \frac{\WF{E;~c:U;~E′;~\ind{p}{Γ_I}{Γ_C};~E″}{Γ}}
+ {\WFTWOLINES{E;~c:U;~E′;~\ind{p+1}{∀ x:U,~\subst{Γ_I}{c}{x}}{∀ x:U,~\subst{Γ_C}{c}{x}};~
+ \subst{E″}{|Γ_I ;Γ_C |}{|Γ_I ;Γ_C | c}}
+ {\subst{Γ}{|Γ_I ;Γ_C|}{|Γ_I ;Γ_C | c}}}
One can similarly modify a global declaration by generalizing it over
a previously defined constant :math:`c′`. Below, if :math:`Γ` is a context of the form
-:math:`[y_1 :A_1 ;…;y_n :A_n]`, we write :math:`\subst{Γ}{c}{u}` to mean
-:math:`[y_1 :\subst{A_1} {c}{u};…;y_n:\subst{A_n} {c}{u}]`.
+:math:`[y_1 :A_1 ;~…;~y_n :A_n]`, we write :math:`\subst{Γ}{c}{u}` to mean
+:math:`[y_1 :\subst{A_1} {c}{u};~…;~y_n:\subst{A_n} {c}{u}]`.
.. _Second-abstracting-property:
@@ -1793,16 +1790,16 @@ a previously defined constant :math:`c′`. Below, if :math:`Γ` is a context of
**Second abstracting property:**
.. math::
- \frac{\WF{E;c:=u:U;E′;c′:=t:T;E″}{Γ}}
- {\WF{E;c:=u:U;E′;c′:=(\letin{x}{u:U}{\subst{t}{c}{x}}):\subst{T}{c}{u};E″}{Γ}}
+ \frac{\WF{E;~c:=u:U;~E′;~c′:=t:T;~E″}{Γ}}
+ {\WF{E;~c:=u:U;~E′;~c′:=(\letin{x}{u:U}{\subst{t}{c}{x}}):\subst{T}{c}{u};~E″}{Γ}}
.. math::
- \frac{\WF{E;c:=u:U;E′;c′:T;E″}{Γ}}
- {\WF{E;c:=u:U;E′;c′:\subst{T}{c}{u};E″}{Γ}}
+ \frac{\WF{E;~c:=u:U;~E′;~c′:T;~E″}{Γ}}
+ {\WF{E;~c:=u:U;~E′;~c′:\subst{T}{c}{u};~E″}{Γ}}
.. math::
- \frac{\WF{E;c:=u:U;E′;\ind{p}{Γ_I}{Γ_C};E″}{Γ}}
- {\WF{E;c:=u:U;E′;\ind{p}{\subst{Γ_I}{c}{u}}{\subst{Γ_C}{c}{u}};E″}{Γ}}
+ \frac{\WF{E;~c:=u:U;~E′;~\ind{p}{Γ_I}{Γ_C};~E″}{Γ}}
+ {\WF{E;~c:=u:U;~E′;~\ind{p}{\subst{Γ_I}{c}{u}}{\subst{Γ_C}{c}{u}};~E″}{Γ}}
.. _Pruning-the-local-context:
@@ -1817,7 +1814,7 @@ One can consequently derive the following property.
.. inference:: First pruning property:
- \WF{E;c:U;E′}{Γ}
+ \WF{E;~c:U;~E′}{Γ}
c~\kw{does not occur in}~E′~\kw{and}~Γ
--------------------------------------
\WF{E;E′}{Γ}
@@ -1827,7 +1824,7 @@ One can consequently derive the following property.
.. inference:: Second pruning property:
- \WF{E;c:=u:U;E′}{Γ}
+ \WF{E;~c:=u:U;~E′}{Γ}
c~\kw{does not occur in}~E′~\kw{and}~Γ
--------------------------------------
\WF{E;E′}{Γ}
@@ -1868,10 +1865,10 @@ in the sort :math:`\Set`, which is extended to a domain in any sort:
.. inference:: ProdImp
E[Γ] ⊢ T : s
- s ∈ {\Sort}
- E[Γ::(x:T)] ⊢ U : Set
+ s ∈ \Sort
+ E[Γ::(x:T)] ⊢ U : \Set
---------------------
- E[Γ] ⊢ ∀ x:T,U : Set
+ E[Γ] ⊢ ∀ x:T,~U : \Set
This extension has consequences on the inductive definitions which are
allowed. In the impredicative system, one can build so-called *large
@@ -1886,15 +1883,15 @@ impredicative system for sort :math:`\Set` become:
.. inference:: Set1
- s ∈ \{Prop, Set\}
+ s ∈ \{\Prop, \Set\}
-----------------
- [I:Set|I→ s]
+ [I:\Set|I→ s]
.. inference:: Set2
I~\kw{is a small inductive definition}
s ∈ \{\Type(i)\}
----------------
- [I:Set|I→ s]
+ [I:\Set|I→ s]
diff --git a/doc/sphinx/language/gallina-extensions.rst b/doc/sphinx/language/gallina-extensions.rst
index d0e44cd212..50a56f1d51 100644
--- a/doc/sphinx/language/gallina-extensions.rst
+++ b/doc/sphinx/language/gallina-extensions.rst
@@ -234,7 +234,8 @@ Primitive Projections
extended the Calculus of Inductive Constructions with a new binary
term constructor `r.(p)` representing a primitive projection `p` applied
to a record object `r` (i.e., primitive projections are always applied).
- Even if the record type has parameters, these do not appear at
+ Even if the record type has parameters, these do not appear
+ in the internal representation of
applications of the projection, considerably reducing the sizes of
terms when manipulating parameterized records and type checking time.
On the user level, primitive projections can be used as a replacement
diff --git a/doc/sphinx/practical-tools/coq-commands.rst b/doc/sphinx/practical-tools/coq-commands.rst
index 9bc67147f7..1b4d2315aa 100644
--- a/doc/sphinx/practical-tools/coq-commands.rst
+++ b/doc/sphinx/practical-tools/coq-commands.rst
@@ -163,14 +163,14 @@ and ``coqtop``, unless stated otherwise:
is equivalent to runningRequire dirpath.
:-require dirpath: Load |Coq| compiled library dirpath and import it.
This is equivalent to running Require Import dirpath.
-:-batch: Exit just after argument parsing. Available for `coqtop` only.
-:-compile *file.v*: Compile file *file.v* into *file.vo*. This option
+:-batch: Exit just after argument parsing. Available for ``coqtop`` only.
+:-compile *file.v*: Deprecated; use ``coqc`` instead. Compile file *file.v* into *file.vo*. This option
implies -batch (exit just after argument parsing). It is available only
- for `coqtop`, as this behavior is the purpose of `coqc`.
-:-compile-verbose *file.v*: Same as -compile but also output the
+ for `coqtop`, as this behavior is the purpose of ``coqc``.
+:-compile-verbose *file.v*: Deprecated. Use ``coqc -verbose``. Same as -compile but also output the
content of *file.v* as it is compiled.
:-verbose: Output the content of the input file as it is compiled.
- This option is available for `coqc` only; it is the counterpart of
+ This option is available for ``coqc`` only; it is the counterpart of
-compile-verbose.
:-w (all|none|w₁,…,wₙ): Configure the display of warnings. This
option expects all, none or a comma-separated list of warning names or
@@ -211,11 +211,11 @@ and ``coqtop``, unless stated otherwise:
(to be used by coqdoc, see :ref:`coqdoc`). By default, if *file.v* is being
compiled, *file.glob* is used.
:-no-glob: Disable the dumping of references for global names.
-:-image *file*: Set the binary image to be used by `coqc` to be *file*
+:-image *file*: Set the binary image to be used by ``coqc`` to be *file*
instead of the standard one. Not of general use.
:-bindir *directory*: Set the directory containing |Coq| binaries to be
- used by `coqc`. It is equivalent to doing export COQBIN= *directory*
- before launching `coqc`.
+ used by ``coqc``. It is equivalent to doing export COQBIN= *directory*
+ before launching ``coqc``.
:-where: Print the location of |Coq|’s standard library and exit.
:-config: Print the locations of |Coq|’s binaries, dependencies, and
libraries, then exit.
diff --git a/doc/sphinx/proof-engine/ssreflect-proof-language.rst b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
index 92bd4dbd1d..483dbd311d 100644
--- a/doc/sphinx/proof-engine/ssreflect-proof-language.rst
+++ b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
@@ -1445,6 +1445,16 @@ section constant.
If tactic is ``move`` or ``case`` and an equation :token:`ident` is given, then clear
(step 3) for :token:`d_item` is suppressed (see section :ref:`generation_of_equations_ssr`).
+Intro patterns (see section :ref:`introduction_ssr`)
+and the ``rewrite`` tactic (see section :ref:`rewriting_ssr`)
+let one place a :token:`clear_switch` in the middle of other items
+(namely identifiers, views and rewrite rules). This can trigger the
+addition of proof context items to the ones being explicitly
+cleared, and in turn this can result in clear errors (e.g. if the
+context item automatically added occurs in the goal). The
+relevant sections describe ways to avoid the unintended clear of
+context items.
+
Matching for apply and exact
````````````````````````````
@@ -1572,6 +1582,9 @@ The :token:`i_pattern`\s can be seen as a variant of *intro patterns*
(see :tacn:`intros`:) each performs an introduction operation, i.e., pops some
variables or assumptions from the goal.
+Simplification items
+`````````````````````
+
An :token:`s_item` can simplify the set of subgoals or the subgoals themselves:
+ ``//`` removes all the “trivial” subgoals that can be resolved by the
@@ -1583,18 +1596,32 @@ An :token:`s_item` can simplify the set of subgoals or the subgoals themselves:
``/= //``, i.e., ``simpl; try done``.
-When an :token:`s_item` bears a :token:`clear_switch`, then the
+When an :token:`s_item` immediately precedes a :token:`clear_switch`, then the
:token:`clear_switch` is executed
*after* the :token:`s_item`, e.g., ``{IHn}//`` will solve some subgoals,
possibly using the fact ``IHn``, and will erase ``IHn`` from the context
of the remaining subgoals.
+Views
+`````
+
The first entry in the :token:`i_view` grammar rule, :n:`/@term`,
represents a view (see section :ref:`views_and_reflection_ssr`).
It interprets the top of the stack with the view :token:`term`.
-It is equivalent to ``move/term``. The optional flag ``{}`` can
-be used to signal that the :token:`term`, when it is a context entry,
-has to be cleared.
+It is equivalent to :n:`move/@term`.
+
+A :token:`clear_switch` that immediately precedes an :token:`i_view`
+is complemented with the name of the view if an only if the :token:`i_view`
+is a simple proof context entry [#10]_.
+E.g. ``{}/v`` is equivalent to ``/v{v}``.
+This behavior can be avoided by separating the :token:`clear_switch`
+from the :token:`i_view` with the ``-`` intro pattern or by putting
+parentheses around the view.
+
+A :token:`clear_switch` that immediately precedes an :token:`i_view`
+is executed after the view application.
+
+
If the next :token:`i_item` is a view, then the view is
applied to the assumption in top position once all the
previous :token:`i_item` have been performed.
@@ -1608,6 +1635,9 @@ Notations can be used to name tactics, for example::
lets one write just ``/myop`` in the intro pattern. Note the scope
annotation: views are interpreted opening the ``ssripat`` scope.
+Intro patterns
+``````````````
+
|SSR| supports the following :token:`i_pattern`\s:
:token:`ident`
@@ -1615,6 +1645,13 @@ annotation: views are interpreted opening the ``ssripat`` scope.
a new constant, fact, or defined constant :token:`ident`, respectively.
Note that defined constants cannot be introduced when δ-expansion is
required to expose the top variable or assumption.
+ A :token:`clear_switch` (even an empty one) immediately preceding an
+ :token:`ident` is complemented with that :token:`ident` if and only if
+ the identifier is a simple proof context entry [#10]_.
+ As a consequence by prefixing the
+ :token:`ident` with ``{}`` one can *replace* a context entry.
+ This behavior can be avoided by separating the :token:`clear_switch`
+ from the :token:`ident` with the ``-`` intro pattern.
``>``
pops every variable occurring in the rest of the stack.
Type class instances are popped even if they don't occur
@@ -1708,6 +1745,9 @@ annotation: views are interpreted opening the ``ssripat`` scope.
Note that |SSR| does not support the syntax ``(ipat, …, ipat)`` for
destructing intro-patterns.
+Clear switch
+````````````
+
Clears are deferred until the end of the intro pattern.
.. example::
@@ -1730,6 +1770,9 @@ is performed behind the scenes.
Facts mentioned in a clear switch must be valid names in the proof
context (excluding the section context).
+Branching and destructuring
+```````````````````````````
+
The rules for interpreting branching and destructing :token:`i_pattern` are
motivated by the fact that it would be pointless to have a branching
pattern if tactic is a ``move``, and in most of the remaining cases
@@ -1754,6 +1797,9 @@ interpretation, e.g.:
are all equivalent.
+Block introduction
+``````````````````
+
|SSR| supports the following :token:`i_block`\s:
:n:`[^ @ident ]`
@@ -3030,13 +3076,22 @@ operation should be performed:
pattern. In its simplest form, it is a regular term. If no explicit
redex switch is present the rewrite pattern to be matched is inferred
from the :token:`r_item`.
-+ This optional term, or the :token:`r_item`, may be preceded by an occurrence
- switch (see section :ref:`selectors_ssr`) or a clear item
- (see section :ref:`discharge_ssr`),
- these two possibilities being exclusive. An occurrence switch selects
++ This optional term, or the :token:`r_item`, may be preceded by an
+ :token:`occ_switch` (see section :ref:`selectors_ssr`) or a
+ :token:`clear_switch` (see section :ref:`discharge_ssr`),
+ these two possibilities being exclusive.
+
+ An occurrence switch selects
the occurrences of the rewrite pattern which should be affected by the
rewrite operation.
+ A clear switch, even an empty one, is performed *after* the
+ :token:`r_item` is actually processed and is complemented with the name of
+ the rewrite rule if an only if it is a simple proof context entry [#10]_.
+ As a consequence one can
+ write ``rewrite {}H`` to rewrite with ``H`` and dispose ``H`` immediately
+ afterwards.
+ This behavior can be avoided by putting parentheses around the rewrite rule.
An :token:`r_item` can be:
@@ -3291,10 +3346,6 @@ the rewrite tactic. The effect of the tactic on the initial goal is to
rewrite this lemma at the second occurrence of the first matching
``x + y + 0`` of the explicit rewrite redex ``_ + y + 0``.
-An empty occurrence switch ``{}`` is not interpreted as a valid occurrence
-switch. It has the effect of clearing the :token:`r_item` (when it is the name
-of a context entry).
-
Occurrence selection and repetition
```````````````````````````````````
@@ -5520,3 +5571,5 @@ Settings
in the metatheory
.. [#9] The current state of the proof shall be displayed by the Show
Proof command of |Coq| proof mode.
+.. [#10] A simple proof context entry is a naked identifier (i.e. not between
+ parentheses) designating a context entry that is not a section variable.
diff --git a/doc/sphinx/proof-engine/tactics.rst b/doc/sphinx/proof-engine/tactics.rst
index 250d9c3a8a..7eef504ea9 100644
--- a/doc/sphinx/proof-engine/tactics.rst
+++ b/doc/sphinx/proof-engine/tactics.rst
@@ -3388,7 +3388,7 @@ Automation
:name: auto
This tactic implements a Prolog-like resolution procedure to solve the
- current goal. It first tries to solve the goal using the assumption
+ current goal. It first tries to solve the goal using the :tacn:`assumption`
tactic, then it reduces the goal to an atomic one using intros and
introduces the newly generated hypotheses as hints. Then it looks at
the list of tactics associated to the head symbol of the goal and
diff --git a/doc/sphinx/refman-preamble.sty b/doc/sphinx/refman-preamble.sty
index b4fc608e47..8f7b1bb1e8 100644
--- a/doc/sphinx/refman-preamble.sty
+++ b/doc/sphinx/refman-preamble.sty
@@ -56,27 +56,29 @@
\newcommand{\oddS}{\textsf{odd}_\textsf{S}}
\newcommand{\ovl}[1]{\overline{#1}}
\newcommand{\Pair}{\textsf{pair}}
+\newcommand{\plus}{\mathsf{plus}}
\newcommand{\Prod}{\textsf{prod}}
\newcommand{\Prop}{\textsf{Prop}}
\newcommand{\return}{\kw{return}}
\newcommand{\Set}{\textsf{Set}}
\newcommand{\si}{\textsf{if}}
\newcommand{\sinon}{\textsf{else}}
-\newcommand{\Sort}{\cal S}
+\newcommand{\Sort}{\mathcal{S}}
\newcommand{\Str}{\textsf{Stream}}
\newcommand{\Struct}{\kw{Struct}}
\newcommand{\subst}[3]{#1\{#2/#3\}}
\newcommand{\tl}{\textsf{tl}}
\newcommand{\tree}{\textsf{tree}}
+\newcommand{\trii}{\triangleright_\iota}
\newcommand{\true}{\textsf{true}}
\newcommand{\Type}{\textsf{Type}}
\newcommand{\unfold}{\textsf{unfold}}
\newcommand{\WEV}[3]{\mbox{$#1[] \vdash #2 \lra #3$}}
\newcommand{\WEVT}[3]{\mbox{$#1[] \vdash #2 \lra$}\\ \mbox{$ #3$}}
-\newcommand{\WF}[2]{{\cal W\!F}(#1)[#2]}
+\newcommand{\WF}[2]{{\mathcal{W\!F}}(#1)[#2]}
\newcommand{\WFE}[1]{\WF{E}{#1}}
-\newcommand{\WFT}[2]{#1[] \vdash {\cal W\!F}(#2)}
-\newcommand{\WFTWOLINES}[2]{{\cal W\!F}\begin{array}{l}(#1)\\\mbox{}[{#2}]\end{array}}
+\newcommand{\WFT}[2]{#1[] \vdash {\mathcal{W\!F}}(#2)}
+\newcommand{\WFTWOLINES}[2]{{\mathcal{W\!F}}\begin{array}{l}(#1)\\\mbox{}[{#2}]\end{array}}
\newcommand{\with}{\kw{with}}
\newcommand{\WS}[3]{#1[] \vdash #2 <: #3}
\newcommand{\WSE}[2]{\WS{E}{#1}{#2}}
diff --git a/doc/sphinx/user-extensions/syntax-extensions.rst b/doc/sphinx/user-extensions/syntax-extensions.rst
index c707da1353..ae66791b0c 100644
--- a/doc/sphinx/user-extensions/syntax-extensions.rst
+++ b/doc/sphinx/user-extensions/syntax-extensions.rst
@@ -1496,12 +1496,13 @@ Numeral notations
function returns :g:`None`, or if the interpretation is registered
for only non-negative integers, and the given numeral is negative.
- .. exn:: @ident should go from Decimal.int to @type or (option @type). Instead of Decimal.int, the types Decimal.uint or Z could be used{? (require BinNums first)}.
+
+ .. exn:: @ident should go from Decimal.int to @type or (option @type). Instead of Decimal.int, the types Decimal.uint or Z could be used (you may need to require BinNums or Decimal first).
The parsing function given to the :cmd:`Numeral Notation`
vernacular is not of the right type.
- .. exn:: @ident should go from @type to Decimal.int or (option Decimal.int). Instead of Decimal.int, the types Decimal.uint or Z could be used{? (require BinNums first)}.
+ .. exn:: @ident should go from @type to Decimal.int or (option Decimal.int). Instead of Decimal.int, the types Decimal.uint or Z could be used (you may need to require BinNums or Decimal first).
The printing function given to the :cmd:`Numeral Notation`
vernacular is not of the right type.
diff --git a/doc/stdlib/index-list.html.template b/doc/stdlib/index-list.html.template
index 51f94d7e5a..c33df52038 100644
--- a/doc/stdlib/index-list.html.template
+++ b/doc/stdlib/index-list.html.template
@@ -618,5 +618,6 @@ through the <tt>Require Import</tt> command.</p>
theories/Compat/Coq87.v
theories/Compat/Coq88.v
theories/Compat/Coq89.v
+ theories/Compat/Coq810.v
</dd>
</dl>
diff --git a/dune b/dune
index a7264ba91e..1706cb44b1 100644
--- a/dune
+++ b/dune
@@ -5,7 +5,7 @@
(ocamlopt_flags -O3 -unbox-closures))
(ireport (flags :standard -rectypes -w -9-27-40+60)
(ocamlopt_flags :standard -O3 -unbox-closures -inlining-report))
- (ocaml408
+ (ocaml409
(flags :standard -strict-sequence -strict-formats -short-paths -keep-locs -rectypes -w -9-27+40+60 -warn-error -5 -alert --deprecated)))
; The _ profile could help factoring the above, however it doesn't
diff --git a/ide/fake_ide.ml b/ide/fake_ide.ml
index 8b0c736f50..4e26cb6095 100644
--- a/ide/fake_ide.ml
+++ b/ide/fake_ide.ml
@@ -241,6 +241,9 @@ let eval_print l coq =
| [ Tok(_,"ADD"); Top [Tok(_,name)]; Tok(_,phrase) ] ->
let eid, tip = add_sentence ~name phrase in
after_add (base_eval_call (add ((phrase,eid),(tip,true))) coq)
+ | [ Tok(_,"FAILADD"); Tok(_,phrase) ] ->
+ let eid, tip = add_sentence phrase in
+ after_fail coq (base_eval_call ~fail:false (add ((phrase,eid),(tip,true))) coq)
| [ Tok(_,"GOALS"); ] ->
eval_call (goals ()) coq
| [ Tok(_,"FAILGOALS"); ] ->
@@ -267,7 +270,8 @@ let eval_print l coq =
prerr_endline "Quitting fake_ide";
exit 0
| Tok("#[^\n]*",_) :: _ -> ()
- | _ -> error "syntax error"
+ | Tok(s,_) :: _ -> error ("syntax error at " ^ s)
+ | _ -> error ("syntax error")
let grammar =
let open Parser in
@@ -275,6 +279,7 @@ let grammar =
let eat_phrase = eat_balanced '{' in
Alt
[ Seq [Item (eat_rex "ADD"); Opt (Item eat_id); Item eat_phrase]
+ ; Seq [Item (eat_rex "FAILADD"); Item eat_phrase]
; Seq [Item (eat_rex "EDIT_AT"); Item eat_id]
; Seq [Item (eat_rex "QUERY"); Opt (Item eat_id); Item eat_phrase]
; Seq [Item (eat_rex "WAIT")]
diff --git a/ide/idetop.ml b/ide/idetop.ml
index 716a942d5c..205f4455a3 100644
--- a/ide/idetop.ml
+++ b/ide/idetop.ml
@@ -64,11 +64,19 @@ let is_known_option cmd = match Vernacprop.under_control cmd with
(** Check whether a command is forbidden in the IDE *)
-let ide_cmd_checks ~id {CAst.loc;v=ast} =
- let user_error s = CErrors.user_err ?loc ~hdr:"IDE" (str s) in
- let warn msg = Feedback.(feedback ~id (Message (Warning, loc, strbrk msg))) in
+let ide_cmd_checks ~last_valid {CAst.loc;v=ast} =
+ let user_error s =
+ try CErrors.user_err ?loc ~hdr:"IDE" (str s)
+ with e ->
+ let (e, info) = CErrors.push e in
+ let info = Stateid.add info ~valid:last_valid Stateid.dummy in
+ Exninfo.raise ~info e
+ in
if is_debug ast then
- user_error "Debug mode not available in the IDE";
+ user_error "Debug mode not available in the IDE"
+
+let ide_cmd_warns ~id {CAst.loc;v=ast} =
+ let warn msg = Feedback.(feedback ~id (Message (Warning, loc, strbrk msg))) in
if is_known_option ast then
warn "Set this option from the IDE menu instead";
if is_navigation_vernac ast || is_undo ast then
@@ -83,11 +91,15 @@ let set_doc doc = ide_doc := Some doc
let add ((s,eid),(sid,verbose)) =
let doc = get_doc () in
let pa = Pcoq.Parsable.make (Stream.of_string s) in
- let loc_ast = Stm.parse_sentence ~doc sid pa in
+ match Stm.parse_sentence ~doc sid ~entry:Pvernac.main_entry pa with
+ | None -> assert false (* s is not an empty string *)
+ | Some (loc, ast) ->
+ let loc_ast = CAst.make ~loc ast in
+ ide_cmd_checks ~last_valid:sid loc_ast;
let doc, newid, rc = Stm.add ~doc ~ontop:sid verbose loc_ast in
set_doc doc;
let rc = match rc with `NewTip -> CSig.Inl () | `Unfocus id -> CSig.Inr id in
- ide_cmd_checks ~id:newid loc_ast;
+ ide_cmd_warns ~id:newid loc_ast;
(* TODO: the "" parameter is a leftover of the times the protocol
* used to include stderr/stdout output.
*
@@ -121,10 +133,10 @@ let query (route, (s,id)) =
let annotate phrase =
let doc = get_doc () in
- let {CAst.loc;v=ast} =
- let pa = Pcoq.Parsable.make (Stream.of_string phrase) in
- Stm.parse_sentence ~doc (Stm.get_current_state ~doc) pa
- in
+ let pa = Pcoq.Parsable.make (Stream.of_string phrase) in
+ match Stm.parse_sentence ~doc (Stm.get_current_state ~doc) ~entry:Pvernac.main_entry pa with
+ | None -> Richpp.richpp_of_pp 78 (Pp.mt ())
+ | Some (_, ast) ->
(* XXX: Width should be a parameter of annotate... *)
Richpp.richpp_of_pp 78 (Ppvernac.pr_vernac ast)
diff --git a/interp/constrextern.ml b/interp/constrextern.ml
index 444ac5ab6d..13078840ef 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -625,8 +625,13 @@ let explicitize inctx impl (cf,f) args =
CApp ((ip,f),args1@args2)
| None ->
let args = exprec 1 (args,impl) in
- if List.is_empty args then f.CAst.v else CApp ((None, f), args)
- in
+ if List.is_empty args then f.CAst.v else
+ match f.CAst.v with
+ | CApp (g,args') ->
+ (* may happen with notations for a prefix of an n-ary
+ application *)
+ CApp (g,args'@args)
+ | _ -> CApp ((None, f), args) in
try expl ()
with Expl ->
let f',us = match f with { CAst.v = CRef (f,us) } -> f,us | _ -> assert false in
diff --git a/lib/flags.ml b/lib/flags.ml
index ae4d337ded..55bfa3cbde 100644
--- a/lib/flags.ml
+++ b/lib/flags.ml
@@ -66,7 +66,7 @@ let we_are_parsing = ref false
(* Current means no particular compatibility consideration.
For correct comparisons, this constructor should remain the last one. *)
-type compat_version = V8_7 | V8_8 | Current
+type compat_version = V8_7 | V8_8 | V8_9 | Current
let compat_version = ref Current
@@ -77,6 +77,9 @@ let version_compare v1 v2 = match v1, v2 with
| V8_8, V8_8 -> 0
| V8_8, _ -> -1
| _, V8_8 -> 1
+ | V8_9, V8_9 -> 0
+ | V8_9, _ -> -1
+ | _, V8_9 -> 1
| Current, Current -> 0
let version_strictly_greater v = version_compare !compat_version v > 0
@@ -85,6 +88,7 @@ let version_less_or_equal v = not (version_strictly_greater v)
let pr_version = function
| V8_7 -> "8.7"
| V8_8 -> "8.8"
+ | V8_9 -> "8.9"
| Current -> "current"
(* Translate *)
diff --git a/lib/flags.mli b/lib/flags.mli
index d883cf1e30..7336b9beaf 100644
--- a/lib/flags.mli
+++ b/lib/flags.mli
@@ -58,7 +58,7 @@ val we_are_parsing : bool ref
(* Set Printing All flag. For some reason it is a global flag *)
val raw_print : bool ref
-type compat_version = V8_7 | V8_8 | Current
+type compat_version = V8_7 | V8_8 | V8_9 | Current
val compat_version : compat_version ref
val version_compare : compat_version -> compat_version -> int
val version_strictly_greater : compat_version -> bool
diff --git a/lib/stateid.ml b/lib/stateid.ml
index 5485c4bf19..8f45f3605d 100644
--- a/lib/stateid.ml
+++ b/lib/stateid.ml
@@ -27,6 +27,8 @@ let get exn = Exninfo.get exn state_id_info
let equal = Int.equal
let compare = Int.compare
+let print id = Pp.int id
+
module Self = struct
type t = int
let compare = compare
diff --git a/lib/stateid.mli b/lib/stateid.mli
index 5d4b71a354..f6ce7ddc40 100644
--- a/lib/stateid.mli
+++ b/lib/stateid.mli
@@ -20,6 +20,7 @@ val initial : t
val dummy : t
val fresh : unit -> t
val to_string : t -> string
+val print : t -> Pp.t
val of_int : int -> t
val to_int : t -> int
diff --git a/man/coqtop.1 b/man/coqtop.1
index 084adfe453..addfb54672 100644
--- a/man/coqtop.1
+++ b/man/coqtop.1
@@ -85,22 +85,6 @@ load Coq library
and import it (Require Import path.)
.TP
-.BI \-compile \ filename.v
-compile Coq file
-.I filename.v
-(implies
-.B \-batch
-)
-
-.TP
-.BI \-compile\-verbose \ filename.v
-verbosely compile Coq file
-.I filename.v
-(implies
-.B \-batch
-)
-
-.TP
.B \-where
print Coq's standard library location and exit
@@ -125,8 +109,6 @@ batch mode (exits just after arguments parsing)
.B \-boot
boot mode (implies
.B \-q
-and
-.B \-batch
)
.TP
diff --git a/parsing/pcoq.ml b/parsing/pcoq.ml
index 19ae97da77..759e60fbca 100644
--- a/parsing/pcoq.ml
+++ b/parsing/pcoq.ml
@@ -439,7 +439,6 @@ module Module =
let module_expr = Entry.create "module_expr"
let module_type = Entry.create "module_type"
end
-
let epsilon_value f e =
let r = G.production (G.r_next G.r_stop (symbol_of_prod_entry_key e), (fun x _ -> f x)) in
let ext = [None, None, [r]] in
diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli
index 352857d4cd..3203a25b46 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -41,6 +41,16 @@ end
- static rules explicitly defined in files g_*.ml4
- static rules macro-generated by ARGUMENT EXTEND, TACTIC EXTEND and
VERNAC EXTEND (see e.g. file extratactics.ml4)
+
+ Note that parsing a Coq document is in essence stateful: the parser
+ needs to recognize commands that start proofs and use a different
+ parsing entry point for them.
+
+ We thus provide two different interfaces: the "raw" parsing
+ interface, in the style of camlp5, which provides more flexibility,
+ and a more specialize "parse_vernac" one, which will indeed adjust
+ the state as needed.
+
*)
(** Dynamic extension of rules
@@ -269,3 +279,7 @@ type any_entry = AnyEntry : 'a Entry.t -> any_entry
val register_grammars_by_name : string -> any_entry list -> unit
val find_grammars_by_name : string -> any_entry list
+
+(** Parsing state handling *)
+val freeze : marshallable:bool -> frozen_t
+val unfreeze : frozen_t -> unit
diff --git a/plugins/derive/g_derive.mlg b/plugins/derive/g_derive.mlg
index df4b647642..0cdf8fb5d8 100644
--- a/plugins/derive/g_derive.mlg
+++ b/plugins/derive/g_derive.mlg
@@ -18,7 +18,7 @@ DECLARE PLUGIN "derive_plugin"
{
-let classify_derive_command _ = Vernacextend.(VtStartProof ("Classic",Doesn'tGuaranteeOpacity,[]),VtLater)
+let classify_derive_command _ = Vernacextend.(VtStartProof (Doesn'tGuaranteeOpacity,[]),VtLater)
}
diff --git a/plugins/funind/g_indfun.mlg b/plugins/funind/g_indfun.mlg
index 8f0440a2a4..c4f8843e51 100644
--- a/plugins/funind/g_indfun.mlg
+++ b/plugins/funind/g_indfun.mlg
@@ -186,7 +186,7 @@ VERNAC COMMAND EXTEND Function
(Vernacexpr.(VernacExpr([], VernacFixpoint(Decl_kinds.NoDischarge, List.map snd recsl))))
with
| Vernacextend.VtSideff ids, _ when hard ->
- Vernacextend.(VtStartProof ("Classic", GuaranteesOpacity, ids), VtLater)
+ Vernacextend.(VtStartProof (GuaranteesOpacity, ids), VtLater)
| x -> x }
-> { do_generate_principle false (List.map snd recsl) }
END
diff --git a/plugins/ltac/g_ltac.mlg b/plugins/ltac/g_ltac.mlg
index d9b19c1ae6..4c24f51b1e 100644
--- a/plugins/ltac/g_ltac.mlg
+++ b/plugins/ltac/g_ltac.mlg
@@ -58,15 +58,8 @@ let new_entry name =
let toplevel_selector = new_entry "vernac:toplevel_selector"
let tacdef_body = new_entry "tactic:tacdef_body"
-(* Registers the Classic Proof Mode (which uses [tactic_mode] as a parser for
- proof editing and changes nothing else). Then sets it as the default proof mode. *)
-let _ =
- let mode = {
- Proof_global.name = "Classic";
- set = (fun () -> Pvernac.set_command_entry tactic_mode);
- reset = (fun () -> Pvernac.(set_command_entry noedit_mode));
- } in
- Proof_global.register_proof_mode mode
+(* Registers [tactic_mode] as a parser for proof editing *)
+let classic_proof_mode = Pvernac.register_proof_mode "Classic" tactic_mode
(* Hack to parse "[ id" without dropping [ *)
let test_bracket_ident =
diff --git a/plugins/ltac/g_obligations.mlg b/plugins/ltac/g_obligations.mlg
index 1ea6ff84d4..cdee012a82 100644
--- a/plugins/ltac/g_obligations.mlg
+++ b/plugins/ltac/g_obligations.mlg
@@ -83,7 +83,7 @@ open Obligations
let obligation obl tac = with_tac (fun t -> Obligations.obligation obl t) tac
let next_obligation obl tac = with_tac (fun t -> Obligations.next_obligation obl t) tac
-let classify_obbl _ = Vernacextend.(VtStartProof ("Classic",Doesn'tGuaranteeOpacity,[]), VtLater)
+let classify_obbl _ = Vernacextend.(VtStartProof (Doesn'tGuaranteeOpacity,[]), VtLater)
}
diff --git a/plugins/ltac/g_rewrite.mlg b/plugins/ltac/g_rewrite.mlg
index 31fb1c9abf..db8d1b20d8 100644
--- a/plugins/ltac/g_rewrite.mlg
+++ b/plugins/ltac/g_rewrite.mlg
@@ -285,13 +285,13 @@ VERNAC COMMAND EXTEND AddSetoid1 CLASSIFIED AS SIDEFF
add_morphism_infer atts m n;
}
| #[ atts = rewrite_attributes; ] [ "Add" "Morphism" constr(m) "with" "signature" lconstr(s) "as" ident(n) ]
- => { VtStartProof("Classic",GuaranteesOpacity,[n]), VtLater }
+ => { VtStartProof(GuaranteesOpacity,[n]), VtLater }
-> {
add_morphism atts [] m s n;
}
| #[ atts = rewrite_attributes; ] [ "Add" "Parametric" "Morphism" binders(binders) ":" constr(m)
"with" "signature" lconstr(s) "as" ident(n) ]
- => { VtStartProof("Classic",GuaranteesOpacity,[n]), VtLater }
+ => { VtStartProof(GuaranteesOpacity,[n]), VtLater }
-> {
add_morphism atts binders m s n;
}
diff --git a/plugins/nsatz/Nsatz.v b/plugins/nsatz/Nsatz.v
index c5a09d677e..a964febf9c 100644
--- a/plugins/nsatz/Nsatz.v
+++ b/plugins/nsatz/Nsatz.v
@@ -452,6 +452,7 @@ constructor;red;intros;subst;trivial.
Qed.
Instance Rops: (@Ring_ops R 0%R 1%R Rplus Rmult Rminus Ropp (@eq R)).
+Defined.
Instance Rri : (Ring (Ro:=Rops)).
constructor;
@@ -468,6 +469,7 @@ Class can_compute_Z (z : Z) := dummy_can_compute_Z : True.
Hint Extern 0 (can_compute_Z ?v) =>
match isZcst v with true => exact I end : typeclass_instances.
Instance reify_IZR z lvar {_ : can_compute_Z z} : reify (PEc z) lvar (IZR z).
+Defined.
Lemma R_one_zero: 1%R <> 0%R.
discrR.
@@ -484,6 +486,7 @@ exact Rmult_integral. exact R_one_zero. Defined.
Require Import QArith.
Instance Qops: (@Ring_ops Q 0%Q 1%Q Qplus Qmult Qminus Qopp Qeq).
+Defined.
Instance Qri : (Ring (Ro:=Qops)).
constructor.
diff --git a/plugins/setoid_ring/Ncring_initial.v b/plugins/setoid_ring/Ncring_initial.v
index 1ca6227f25..aa0370b2ac 100644
--- a/plugins/setoid_ring/Ncring_initial.v
+++ b/plugins/setoid_ring/Ncring_initial.v
@@ -32,6 +32,7 @@ Lemma Zsth : Equivalence (@eq Z).
Proof. exact Z.eq_equiv. Qed.
Instance Zops:@Ring_ops Z 0%Z 1%Z Z.add Z.mul Z.sub Z.opp (@eq Z).
+Defined.
Instance Zr: (@Ring _ _ _ _ _ _ _ _ Zops).
Proof.
diff --git a/plugins/setoid_ring/Ncring_tac.v b/plugins/setoid_ring/Ncring_tac.v
index 7958507819..c8d560cfe9 100644
--- a/plugins/setoid_ring/Ncring_tac.v
+++ b/plugins/setoid_ring/Ncring_tac.v
@@ -27,41 +27,50 @@ Class nth (R:Type) (t:R) (l:list R) (i:nat).
Instance Ifind0 (R:Type) (t:R) l
: nth t(t::l) 0.
+Defined.
Instance IfindS (R:Type) (t2 t1:R) l i
{_:nth t1 l i}
: nth t1 (t2::l) (S i) | 1.
+Defined.
Class closed (T:Type) (l:list T).
Instance Iclosed_nil T
: closed (T:=T) nil.
+Defined.
Instance Iclosed_cons T t (l:list T)
{_:closed l}
: closed (t::l).
+Defined.
Class reify (R:Type)`{Rr:Ring (T:=R)} (e:PExpr Z) (lvar:list R) (t:R).
Instance reify_zero (R:Type) lvar op
`{Ring (T:=R)(ring0:=op)}
: reify (ring0:=op)(PEc 0%Z) lvar op.
+Defined.
Instance reify_one (R:Type) lvar op
`{Ring (T:=R)(ring1:=op)}
: reify (ring1:=op) (PEc 1%Z) lvar op.
+Defined.
Instance reifyZ0 (R:Type) lvar
`{Ring (T:=R)}
: reify (PEc Z0) lvar Z0|11.
+Defined.
Instance reifyZpos (R:Type) lvar (p:positive)
`{Ring (T:=R)}
: reify (PEc (Zpos p)) lvar (Zpos p)|11.
+Defined.
Instance reifyZneg (R:Type) lvar (p:positive)
`{Ring (T:=R)}
: reify (PEc (Zneg p)) lvar (Zneg p)|11.
+Defined.
Instance reify_add (R:Type)
e1 lvar t1 e2 t2 op
@@ -69,6 +78,7 @@ Instance reify_add (R:Type)
{_:reify (add:=op) e1 lvar t1}
{_:reify (add:=op) e2 lvar t2}
: reify (add:=op) (PEadd e1 e2) lvar (op t1 t2).
+Defined.
Instance reify_mul (R:Type)
e1 lvar t1 e2 t2 op
@@ -76,6 +86,7 @@ Instance reify_mul (R:Type)
{_:reify (mul:=op) e1 lvar t1}
{_:reify (mul:=op) e2 lvar t2}
: reify (mul:=op) (PEmul e1 e2) lvar (op t1 t2)|10.
+Defined.
Instance reify_mul_ext (R:Type) `{Ring R}
lvar (z:Z) e2 t2
@@ -83,6 +94,7 @@ Instance reify_mul_ext (R:Type) `{Ring R}
{_:reify e2 lvar t2}
: reify (PEmul (PEc z) e2) lvar
(@multiplication Z _ _ z t2)|9.
+Defined.
Instance reify_sub (R:Type)
e1 lvar t1 e2 t2 op
@@ -90,24 +102,28 @@ Instance reify_sub (R:Type)
{_:reify (sub:=op) e1 lvar t1}
{_:reify (sub:=op) e2 lvar t2}
: reify (sub:=op) (PEsub e1 e2) lvar (op t1 t2).
+Defined.
Instance reify_opp (R:Type)
e1 lvar t1 op
`{Ring (T:=R)(opp:=op)}
{_:reify (opp:=op) e1 lvar t1}
: reify (opp:=op) (PEopp e1) lvar (op t1).
+Defined.
Instance reify_pow (R:Type) `{Ring R}
e1 lvar t1 n
`{Ring (T:=R)}
{_:reify e1 lvar t1}
: reify (PEpow e1 n) lvar (pow_N t1 n)|1.
+Defined.
Instance reify_var (R:Type) t lvar i
`{nth R t lvar i}
`{Rr: Ring (T:=R)}
: reify (Rr:= Rr) (PEX Z (Pos.of_succ_nat i))lvar t
| 100.
+Defined.
Class reifylist (R:Type)`{Rr:Ring (T:=R)} (lexpr:list (PExpr Z)) (lvar:list R)
(lterm:list R).
@@ -115,12 +131,14 @@ Class reifylist (R:Type)`{Rr:Ring (T:=R)} (lexpr:list (PExpr Z)) (lvar:list R)
Instance reify_nil (R:Type) lvar
`{Rr: Ring (T:=R)}
: reifylist (Rr:= Rr) nil lvar (@nil R).
+Defined.
Instance reify_cons (R:Type) e1 lvar t1 lexpr2 lterm2
`{Rr: Ring (T:=R)}
{_:reify (Rr:= Rr) e1 lvar t1}
{_:reifylist (Rr:= Rr) lexpr2 lvar lterm2}
: reifylist (Rr:= Rr) (e1::lexpr2) lvar (t1::lterm2).
+Defined.
Definition list_reifyl (R:Type) lexpr lvar lterm
`{Rr: Ring (T:=R)}
diff --git a/plugins/setoid_ring/Rings_Q.v b/plugins/setoid_ring/Rings_Q.v
index ae91ee1664..df3677e1c3 100644
--- a/plugins/setoid_ring/Rings_Q.v
+++ b/plugins/setoid_ring/Rings_Q.v
@@ -15,6 +15,7 @@ Require Export Integral_domain.
Require Import QArith.
Instance Qops: (@Ring_ops Q 0%Q 1%Q Qplus Qmult Qminus Qopp Qeq).
+Defined.
Instance Qri : (Ring (Ro:=Qops)).
constructor.
diff --git a/plugins/setoid_ring/Rings_R.v b/plugins/setoid_ring/Rings_R.v
index 901b36ed3b..fe7558845d 100644
--- a/plugins/setoid_ring/Rings_R.v
+++ b/plugins/setoid_ring/Rings_R.v
@@ -20,6 +20,7 @@ constructor;red;intros;subst;trivial.
Qed.
Instance Rops: (@Ring_ops R 0%R 1%R Rplus Rmult Rminus Ropp (@eq R)).
+Defined.
Instance Rri : (Ring (Ro:=Rops)).
constructor;
diff --git a/plugins/ssr/ssrast.mli b/plugins/ssr/ssrast.mli
index dd2c2d0ba4..9ce9250a43 100644
--- a/plugins/ssr/ssrast.mli
+++ b/plugins/ssr/ssrast.mli
@@ -67,7 +67,7 @@ type ssrview = ast_closure_term list
type id_block = Prefix of Id.t | SuffixId of Id.t | SuffixNum of int
(* Only [One] forces an introduction, possibly reducing the goal. *)
-type anon_iter =
+type anon_kind =
| One of string option (* name hint *)
| Drop
| All
@@ -76,25 +76,23 @@ type anon_iter =
type ssripat =
| IPatNoop
| IPatId of Id.t
- | IPatAnon of anon_iter (* inaccessible name *)
-(* TODO | IPatClearMark *)
- | IPatDispatch of bool (* ssr exception: accept a dispatch on the empty list even when there are subgoals *) * ssripatss_or_block (* (..|..) *)
- | IPatCase of (* ipats_mod option * *) ssripatss_or_block (* this is not equivalent to /case /[..|..] if there are already multiple goals *)
+ | IPatAnon of anon_kind (* inaccessible name *)
+ | IPatDispatch of ssripatss_or_block (* (..|..) *)
+ | IPatCase of ssripatss_or_block (* [..|..] *)
| IPatInj of ssripatss
| IPatRewrite of (*occurrence option * rewrite_pattern **) ssrocc * ssrdir
- | IPatView of bool * ssrview (* {}/view (true if the clear is present) *)
+ | IPatView of ssrview (* /view *)
| IPatClear of ssrclear (* {H1 H2} *)
| IPatSimpl of ssrsimpl
| IPatAbstractVars of Id.t list
| IPatFastNondep
- | IPatEqGen of unit Proofview.tactic (* internal use: generation of eqn *)
and ssripats = ssripat list
and ssripatss = ssripats list
and ssripatss_or_block =
| Block of id_block
| Regular of ssripats list
-type ssrhpats = ((ssrclear * ssripats) * ssripats) * ssripats
+type ssrhpats = ((ssrclear option * ssripats) * ssripats) * ssripats
type ssrhpats_wtransp = bool * ssrhpats
(* tac => inpats *)
diff --git a/plugins/ssr/ssrcommon.ml b/plugins/ssr/ssrcommon.ml
index 311d912efd..c3b9bde9b8 100644
--- a/plugins/ssr/ssrcommon.ml
+++ b/plugins/ssr/ssrcommon.ml
@@ -66,7 +66,7 @@ let check_hyp_exists hyps (SsrHyp(_, id)) =
try ignore(Context.Named.lookup id hyps)
with Not_found -> errorstrm Pp.(str"No assumption is named " ++ Id.print id)
-let test_hypname_exists hyps id =
+let test_hyp_exists hyps (SsrHyp(_, id)) =
try ignore(Context.Named.lookup id hyps); true
with Not_found -> false
diff --git a/plugins/ssr/ssrcommon.mli b/plugins/ssr/ssrcommon.mli
index 51116ccd75..e642b5e788 100644
--- a/plugins/ssr/ssrcommon.mli
+++ b/plugins/ssr/ssrcommon.mli
@@ -29,7 +29,7 @@ val allocc : ssrocc
val hyp_id : ssrhyp -> Id.t
val hyps_ids : ssrhyps -> Id.t list
val check_hyp_exists : ('a, 'b) Context.Named.pt -> ssrhyp -> unit
-val test_hypname_exists : ('a, 'b) Context.Named.pt -> Id.t -> bool
+val test_hyp_exists : ('a, 'b) Context.Named.pt -> ssrhyp -> bool
val check_hyps_uniq : Id.t list -> ssrhyps -> unit
val not_section_id : Id.t -> bool
val hyp_err : ?loc:Loc.t -> string -> Id.t -> 'a
diff --git a/plugins/ssr/ssrfwd.ml b/plugins/ssr/ssrfwd.ml
index 257ecd2a85..8c1363020a 100644
--- a/plugins/ssr/ssrfwd.ml
+++ b/plugins/ssr/ssrfwd.ml
@@ -94,17 +94,23 @@ let basecuttac name c gl =
let introstac ipats = Proofview.V82.of_tactic (tclIPAT ipats)
let havetac ist
- (transp,((((clr, pats), binders), simpl), (((fk, _), t), hint)))
+ (transp,((((clr, orig_pats), binders), simpl), (((fk, _), t), hint)))
suff namefst gl
=
let concl = pf_concl gl in
+ let pats = tclCompileIPats orig_pats in
+ let binders = tclCompileIPats binders in
+ let simpl = tclCompileIPats simpl in
let skols, pats =
- List.partition (function IPatAbstractVars _ -> true | _ -> false) pats in
+ List.partition (function IOpAbstractVars _ -> true | _ -> false) pats in
let itac_mkabs = introstac skols in
- let itac_c = introstac (IPatClear clr :: pats) in
+ let itac_c, clr =
+ match clr with
+ | None -> introstac pats, []
+ | Some clr -> introstac (tclCompileIPats (IPatClear clr :: orig_pats)), clr in
let itac, id, clr = introstac pats, Tacticals.tclIDTAC, old_cleartac clr in
let binderstac n =
- let rec aux = function 0 -> [] | n -> IPatAnon (One None) :: aux (n-1) in
+ let rec aux = function 0 -> [] | n -> IOpInaccessible None :: aux (n-1) in
Tacticals.tclTHEN (if binders <> [] then introstac (aux n) else Tacticals.tclIDTAC)
(introstac binders) in
let simpltac = introstac simpl in
@@ -160,7 +166,7 @@ let havetac ist
gl, ty, Tacticals.tclTHEN assert_is_conv (Proofview.V82.of_tactic (Tactics.apply t)), id, itac_c
| FwdHave, false, false ->
let skols = List.flatten (List.map (function
- | IPatAbstractVars ids -> ids
+ | IOpAbstractVars ids -> ids
| _ -> assert false) skols) in
let skols_args =
List.map (fun id -> Ssripats.Internal.examine_abstract (EConstr.mkVar id) gl) skols in
@@ -203,10 +209,12 @@ let destProd_or_LetIn sigma c =
| _ -> raise DestKO
let wlogtac ist (((clr0, pats),_),_) (gens, ((_, ct))) hint suff ghave gl =
+ let clr0 = Option.default [] clr0 in
+ let pats = tclCompileIPats pats in
let mkabs gen = abs_wgen false (fun x -> x) gen in
let mkclr gen clrs = clr_of_wgen gen clrs in
let mkpats = function
- | _, Some ((x, _), _) -> fun pats -> IPatId (hoi_id x) :: pats
+ | _, Some ((x, _), _) -> fun pats -> IOpId (hoi_id x) :: pats
| _ -> fun x -> x in
let ct = match Ssrcommon.ssrterm_of_ast_closure_term ct with
| (a, (b, Some ct)) ->
@@ -265,7 +273,7 @@ let wlogtac ist (((clr0, pats),_),_) (gens, ((_, ct))) hint suff ghave gl =
if gens = [] then errorstrm(str"gen have requires some generalizations");
let clear0 = old_cleartac clr0 in
let id, name_general_hyp, cleanup, pats = match id, pats with
- | None, (IPatId id as ip)::pats -> Some id, tacipat [ip], clear0, pats
+ | None, (IOpId id as ip)::pats -> Some id, tacipat [ip], clear0, pats
| None, _ -> None, Tacticals.tclIDTAC, clear0, pats
| Some (Some id),_ -> Some id, introid id, clear0, pats
| Some _,_ ->
@@ -289,6 +297,10 @@ let wlogtac ist (((clr0, pats),_),_) (gens, ((_, ct))) hint suff ghave gl =
(** The "suffice" tactic *)
let sufftac ist ((((clr, pats),binders),simpl), ((_, c), hint)) =
+ let clr = Option.default [] clr in
+ let pats = tclCompileIPats pats in
+ let binders = tclCompileIPats binders in
+ let simpl = tclCompileIPats simpl in
let htac = Tacticals.tclTHEN (introstac pats) (hinttac ist true hint) in
let c = match Ssrcommon.ssrterm_of_ast_closure_term c with
| (a, (b, Some ct)) ->
diff --git a/plugins/ssr/ssrfwd.mli b/plugins/ssr/ssrfwd.mli
index 8a05e25504..35e89dbcea 100644
--- a/plugins/ssr/ssrfwd.mli
+++ b/plugins/ssr/ssrfwd.mli
@@ -22,7 +22,7 @@ val ssrposetac : Id.t * (ssrfwdfmt * ast_closure_term) -> v82tac
val havetac : ist ->
bool *
- ((((Ssrast.ssrclear * Ssrast.ssripat list) * Ssrast.ssripats) *
+ ((((Ssrast.ssrclear option * Ssrast.ssripat list) * Ssrast.ssripats) *
Ssrast.ssripats) *
(((Ssrast.ssrfwdkind * 'a) * ast_closure_term) *
(bool * Tacinterp.Value.t option list))) ->
@@ -35,7 +35,7 @@ val basecuttac :
val wlogtac :
Ltac_plugin.Tacinterp.interp_sign ->
- ((Ssrast.ssrhyps * Ssrast.ssripats) * 'a) * 'b ->
+ ((Ssrast.ssrclear option * Ssrast.ssripats) * 'a) * 'b ->
(Ssrast.ssrhyps *
((Ssrast.ssrhyp_or_id * string) *
Ssrmatching_plugin.Ssrmatching.cpattern option)
@@ -50,7 +50,7 @@ val wlogtac :
val sufftac :
Ssrast.ist ->
- (((Ssrast.ssrhyps * Ssrast.ssripats) * Ssrast.ssripat list) *
+ (((Ssrast.ssrclear option * Ssrast.ssripats) * Ssrast.ssripat list) *
Ssrast.ssripat list) *
(('a *
ast_closure_term) *
diff --git a/plugins/ssr/ssripats.ml b/plugins/ssr/ssripats.ml
index ce81d83661..a8dfd69240 100644
--- a/plugins/ssr/ssripats.ml
+++ b/plugins/ssr/ssripats.ml
@@ -19,14 +19,78 @@ open Proofview.Notations
open Ssrast
+type ssriop =
+ | IOpId of Names.Id.t
+ | IOpDrop
+ | IOpTemporay
+ | IOpInaccessible of string option
+ | IOpInaccessibleAll
+ | IOpAbstractVars of Names.Id.t list
+ | IOpFastNondep
+
+ | IOpInj of ssriops list
+
+ | IOpDispatchBlock of id_block
+ | IOpDispatchBranches of ssriops list
+
+ | IOpCaseBlock of id_block
+ | IOpCaseBranches of ssriops list
+
+ | IOpRewrite of ssrocc * ssrdir
+ | IOpView of ssrclear option * ssrview (* extra clears to be performed *)
+
+ | IOpClear of ssrclear * ssrhyp option (* must clear, may clear *)
+ | IOpSimpl of ssrsimpl
+
+ | IOpEqGen of unit Proofview.tactic (* generation of eqn *)
+
+ | IOpNoop
+
+and ssriops = ssriop list
+
+let rec pr_ipatop = function
+ | IOpId id -> Names.Id.print id
+ | IOpDrop -> Pp.str "_"
+ | IOpTemporay -> Pp.str "+"
+ | IOpInaccessible None -> Pp.str "?"
+ | IOpInaccessible (Some s) -> Pp.str ("?«"^s^"»")
+ | IOpInaccessibleAll -> Pp.str "*"
+ | IOpAbstractVars l -> Pp.str ("[:"^String.concat " " (List.map Names.Id.to_string l)^"]")
+ | IOpFastNondep -> Pp.str ">"
+
+ | IOpInj l -> Pp.(str "[=" ++ ppl l ++ str "]")
+
+ | IOpDispatchBlock b -> Pp.(str"(" ++ Ssrprinters.pr_block b ++ str")")
+ | IOpDispatchBranches l -> Pp.(str "(" ++ ppl l ++ str ")")
+
+ | IOpCaseBlock b -> Pp.(str"[" ++ Ssrprinters.pr_block b ++ str"]")
+ | IOpCaseBranches l -> Pp.(str "[" ++ ppl l ++ str "]")
+
+ | IOpRewrite (occ,dir) -> Pp.(Ssrprinters.(pr_occ occ ++ pr_dir dir))
+ | IOpView (None,vs) -> Pp.(prlist_with_sep mt (fun c -> str "/" ++ Ssrprinters.pr_ast_closure_term c) vs)
+ | IOpView (Some cl,vs) -> Pp.(Ssrprinters.pr_clear Pp.spc cl ++ prlist_with_sep mt (fun c -> str "/" ++ Ssrprinters.pr_ast_closure_term c) vs)
+
+ | IOpClear (clmust,clmay) ->
+ Pp.(Ssrprinters.pr_clear spc clmust ++
+ match clmay with
+ | Some cl -> str "(try " ++ Ssrprinters.pr_clear spc [cl] ++ str")"
+ | None -> mt ())
+ | IOpSimpl s -> Ssrprinters.pr_simpl s
+
+ | IOpEqGen _ -> Pp.str "E:"
+ | IOpNoop -> Pp.str"-"
+and ppl x = Pp.(prlist_with_sep (fun () -> str"|") (prlist_with_sep spc pr_ipatop)) x
+
+
module IpatMachine : sig
(* the => tactical. ?eqtac is a tactic to be eventually run
* after the first [..] block. first_case_is_dispatch is the
* ssr exception to elim: and case: *)
val main : ?eqtac:unit tactic -> first_case_is_dispatch:bool ->
- ssripats -> unit tactic
+ ssriops -> unit tactic
+ val tclCompileIPats : ssripats -> ssriops
val tclSEED_SUBGOALS : Names.Name.t list array -> unit tactic -> unit tactic
@@ -53,7 +117,7 @@ module State : sig
val isNSEED_CONSUME : (Names.Name.t list option -> unit tactic) -> unit tactic
(* Some data may expire *)
- val isTICK : ssripat -> unit tactic
+ val isTICK : ssriop -> unit tactic
val isPRINT : Proofview.Goal.t -> Pp.t
@@ -149,7 +213,7 @@ let isNSEED_CONSUME k =
k x)
let isTICK = function
- | IPatSimpl _ | IPatClear _ -> tclUNIT ()
+ | IOpSimpl _ | IOpClear _ -> tclUNIT ()
| _ -> tclGET (fun s -> tclSET { s with name_seed = None })
end (* }}} *************************************************************** *)
@@ -238,6 +302,13 @@ let tacCHECK_HYPS_EXIST hyps = Goal.enter begin fun gl ->
tclUNIT ()
end
+let tacFILTER_HYP_EXIST hyps k = Goal.enter begin fun gl ->
+ let ctx = Goal.hyps gl in
+ k (Option.bind hyps (fun h ->
+ if Ssrcommon.test_hyp_exists ctx h &&
+ Ssrcommon.(not_section_id (hyp_id h)) then Some h else None))
+end
+
(** [=> []] *****************************************************************)
(* calls t1 then t2 on each subgoal passing to t2 the index of the current
@@ -286,13 +357,13 @@ let tac_intro_seed interp_ipats fix = Goal.enter begin fun gl ->
| Prefix id -> Id.to_string id ^ "?"
| SuffixNum n -> "?" ^ string_of_int n
| SuffixId id -> "?" ^ Id.to_string id in
- IPatAnon (One (Some s))
+ IOpInaccessible (Some s)
| Name id ->
let s = match fix with
| Prefix fix -> Id.to_string fix ^ Id.to_string id
| SuffixNum n -> Id.to_string id ^ string_of_int n
| SuffixId fix -> Id.to_string id ^ Id.to_string fix in
- IPatId (Id.of_string s)) seeds in
+ IOpId (Id.of_string s)) seeds in
interp_ipats ipats
end end
@@ -342,7 +413,7 @@ let tclMK_ABSTRACT_VARS ids =
(* Debugging *)
let tclLOG p t =
tclUNIT () >>= begin fun () ->
- Ssrprinters.ppdebug (lazy Pp.(str "exec: " ++ Ssrprinters.pr_ipat p));
+ Ssrprinters.ppdebug (lazy Pp.(str "exec: " ++ pr_ipatop p));
tclUNIT ()
end <*>
Goal.enter begin fun g ->
@@ -362,58 +433,74 @@ let tclLOG p t =
let notTAC = tclUNIT false
+let duplicate_clear =
+ CWarnings.create ~name:"duplicate-clear" ~category:"ssr"
+ (fun id -> Pp.(str "Duplicate clear of " ++ Id.print id))
+
(* returns true if it was a tactic (eg /ltac:tactic) *)
let rec ipat_tac1 ipat : bool tactic =
match ipat with
- | IPatView (clear_if_id,l) ->
+ | IOpView (glued_clear,l) ->
+ let clear_if_id, extra_clear =
+ match glued_clear with
+ | None -> false, []
+ | Some x -> true, List.map Ssrcommon.hyp_id x in
Ssrview.tclIPAT_VIEWS
~views:l ~clear_if_id
- ~conclusion:(fun ~to_clear:clr -> intro_clear clr)
+ ~conclusion:(fun ~to_clear:clr ->
+ let inter = CList.intersect Id.equal clr extra_clear in
+ List.iter duplicate_clear inter;
+ let cl = CList.union Id.equal clr extra_clear in
+ intro_clear cl)
- | IPatDispatch(true, Regular [[]]) ->
- notTAC
- | IPatDispatch(_, Regular ipatss) ->
+ | IOpDispatchBranches ipatss ->
tclDISPATCH (List.map ipat_tac ipatss) <*> notTAC
- | IPatDispatch(_,Block id_block) ->
+ | IOpDispatchBlock id_block ->
tac_intro_seed ipat_tac id_block <*> notTAC
-
- | IPatId id -> Ssrcommon.tclINTRO_ID id <*> notTAC
- | IPatFastNondep -> intro_anon_deps <*> notTAC
-
- | IPatCase (Block id_block) ->
+ | IOpCaseBlock id_block ->
Ssrcommon.tclWITHTOP tac_case <*> tac_intro_seed ipat_tac id_block <*> notTAC
- | IPatCase (Regular ipatss) ->
+ | IOpCaseBranches ipatss ->
tclIORPAT (Ssrcommon.tclWITHTOP tac_case) ipatss <*> notTAC
- | IPatInj ipatss ->
+
+ | IOpId id -> Ssrcommon.tclINTRO_ID id <*> notTAC
+ | IOpFastNondep -> intro_anon_deps <*> notTAC
+ | IOpDrop -> intro_drop <*> notTAC
+ | IOpInaccessible seed -> Ssrcommon.tclINTRO_ANON ?seed () <*> notTAC
+ | IOpInaccessibleAll -> intro_anon_all <*> notTAC
+ | IOpTemporay -> intro_anon_temp <*> notTAC
+
+ | IOpSimpl Nop -> assert false
+
+ | IOpInj ipatss ->
tclIORPAT (Ssrcommon.tclWITHTOP
(fun t -> V82.tactic ~nf_evars:false (Ssrelim.perform_injection t)))
ipatss
<*> notTAC
- | IPatAnon Drop -> intro_drop <*> notTAC
- | IPatAnon (One seed) -> Ssrcommon.tclINTRO_ANON ?seed () <*> notTAC
- | IPatAnon All -> intro_anon_all <*> notTAC
- | IPatAnon Temporary -> intro_anon_temp <*> notTAC
-
- | IPatNoop -> notTAC
- | IPatSimpl Nop -> notTAC
-
- | IPatClear ids ->
- tacCHECK_HYPS_EXIST ids <*>
- intro_clear (List.map Ssrcommon.hyp_id ids) <*>
+ | IOpClear (must,may) ->
+ tacCHECK_HYPS_EXIST must <*>
+ tacFILTER_HYP_EXIST may (fun may ->
+ let must = List.map Ssrcommon.hyp_id must in
+ let cl = Option.fold_left (fun cls (SsrHyp(_,id)) ->
+ if CList.mem_f Id.equal id cls then begin
+ duplicate_clear id;
+ cls
+ end else id :: cls) must may in
+ intro_clear cl) <*>
notTAC
- | IPatSimpl x ->
+ | IOpSimpl x ->
V82.tactic ~nf_evars:false (Ssrequality.simpltac x) <*> notTAC
- | IPatRewrite (occ,dir) ->
+ | IOpRewrite (occ,dir) ->
Ssrcommon.tclWITHTOP
(fun x -> V82.tactic ~nf_evars:false (Ssrequality.ipat_rewrite occ dir x)) <*> notTAC
- | IPatAbstractVars ids -> tclMK_ABSTRACT_VARS ids <*> notTAC
+ | IOpAbstractVars ids -> tclMK_ABSTRACT_VARS ids <*> notTAC
- | IPatEqGen t -> t <*> notTAC
+ | IOpEqGen t -> t <*> notTAC
+ | IOpNoop -> notTAC
and ipat_tac pl : unit tactic =
match pl with
@@ -433,51 +520,88 @@ and tclIORPAT tac = function
| p -> Tacticals.New.tclTHENS tac (List.map ipat_tac p)
and ssr_exception is_on = function
- | Some (IPatCase l) when is_on -> Some (IPatDispatch(true, l))
+ | Some (IOpCaseBranches [[]]) when is_on -> Some IOpNoop
+ | Some (IOpCaseBranches l) when is_on ->
+ Some (IOpDispatchBranches l)
+ | Some (IOpCaseBlock s) when is_on ->
+ Some (IOpDispatchBlock s)
| x -> x
and option_to_list = function None -> [] | Some x -> [x]
and split_at_first_case ipats =
let rec loop acc = function
- | (IPatSimpl _ | IPatClear _) as x :: rest -> loop (x :: acc) rest
- | (IPatCase _ | IPatDispatch _) as x :: xs -> CList.rev acc, Some x, xs
+ | (IOpSimpl _ | IOpClear _) as x :: rest -> loop (x :: acc) rest
+ | (IOpCaseBlock _ | IOpCaseBranches _
+ | IOpDispatchBlock _ | IOpDispatchBranches _) as x :: xs ->
+ CList.rev acc, Some x, xs
| pats -> CList.rev acc, None, pats
in
loop [] ipats
;;
(* Simple pass doing {x}/v -> /v{x} *)
-let elaborate_ipats l =
+let tclCompileIPats l =
let rec elab = function
+
+ | (IPatClear cl) :: (IPatView v) :: rest ->
+ (IOpView(Some cl,v)) :: elab rest
+ | (IPatClear cl) :: (IPatId id) :: rest ->
+ (IOpClear (cl,Some (SsrHyp(None,id)))) :: IOpId id :: elab rest
+
+ (* boring code *)
| [] -> []
- | (IPatClear _ as p1) :: (IPatView _ as p2) :: rest -> p2 :: p1 :: elab rest
- | IPatDispatch(s, Regular p) :: rest -> IPatDispatch (s, Regular (List.map elab p)) :: elab rest
- | IPatCase (Regular p) :: rest -> IPatCase (Regular (List.map elab p)) :: elab rest
- | IPatInj p :: rest -> IPatInj (List.map elab p) :: elab rest
- | (IPatEqGen _ | IPatId _ | IPatSimpl _ | IPatClear _ | IPatFastNondep |
- IPatAnon _ | IPatView _ | IPatNoop | IPatRewrite _ |
- IPatAbstractVars _ | IPatDispatch(_, Block _) | IPatCase(Block _)) as x :: rest -> x :: elab rest
- in
- elab l
-let main ?eqtac ~first_case_is_dispatch ipats =
- let ipats = elaborate_ipats ipats in
- let ip_before, case, ip_after = split_at_first_case ipats in
+ | IPatId id :: rest -> IOpId id :: elab rest
+ | IPatAnon (One hint) ::rest -> IOpInaccessible hint :: elab rest
+ | IPatAnon Drop :: rest -> IOpDrop :: elab rest
+ | IPatAnon All :: rest -> IOpInaccessibleAll :: elab rest
+ | IPatAnon Temporary :: rest -> IOpTemporay :: elab rest
+ | IPatAbstractVars vs :: rest -> IOpAbstractVars vs :: elab rest
+ | IPatFastNondep :: rest -> IOpFastNondep :: elab rest
+
+ | IPatInj pats :: rest -> IOpInj (List.map elab pats) :: elab rest
+ | IPatRewrite(occ,dir) :: rest -> IOpRewrite(occ,dir) :: elab rest
+ | IPatView vs :: rest -> IOpView (None,vs) :: elab rest
+ | IPatSimpl s :: rest -> IOpSimpl s :: elab rest
+ | IPatClear cl :: rest -> IOpClear (cl,None) :: elab rest
+
+ | IPatCase (Block seed) :: rest -> IOpCaseBlock seed :: elab rest
+ | IPatCase (Regular bs) :: rest -> IOpCaseBranches (List.map elab bs) :: elab rest
+ | IPatDispatch (Block seed) :: rest -> IOpDispatchBlock seed :: elab rest
+ | IPatDispatch (Regular bs) :: rest -> IOpDispatchBranches (List.map elab bs) :: elab rest
+ | IPatNoop :: rest -> IOpNoop :: elab rest
+
+ in
+ elab l
+;;
+let tclCompileIPats l =
+ Ssrprinters.ppdebug (lazy Pp.(str "tclCompileIPats input: " ++
+ prlist_with_sep spc Ssrprinters.pr_ipat l));
+ let ops = tclCompileIPats l in
+ Ssrprinters.ppdebug (lazy Pp.(str "tclCompileIPats output: " ++
+ prlist_with_sep spc pr_ipatop ops));
+ ops
+
+let main ?eqtac ~first_case_is_dispatch iops =
+ let ip_before, case, ip_after = split_at_first_case iops in
let case = ssr_exception first_case_is_dispatch case in
let case = option_to_list case in
- let eqtac = option_to_list (Option.map (fun x -> IPatEqGen x) eqtac) in
- Ssrcommon.tcl0G ~default:() (ipat_tac (ip_before @ case @ eqtac @ ip_after) <*> intro_end)
+ let eqtac = option_to_list (Option.map (fun x -> IOpEqGen x) eqtac) in
+ let ipats = ip_before @ case @ eqtac @ ip_after in
+ Ssrcommon.tcl0G ~default:() (ipat_tac ipats <*> intro_end)
end (* }}} *)
let tclIPAT_EQ eqtac ip =
Ssrprinters.ppdebug (lazy Pp.(str "ipat@run: " ++ Ssrprinters.pr_ipats ip));
- IpatMachine.main ~eqtac ~first_case_is_dispatch:true ip
+ IpatMachine.(main ~eqtac ~first_case_is_dispatch:true (tclCompileIPats ip))
let tclIPATssr ip =
Ssrprinters.ppdebug (lazy Pp.(str "ipat@run: " ++ Ssrprinters.pr_ipats ip));
- IpatMachine.main ~first_case_is_dispatch:true ip
+ IpatMachine.(main ~first_case_is_dispatch:true (tclCompileIPats ip))
+
+let tclCompileIPats = IpatMachine.tclCompileIPats
(* Common code to handle generalization lists along with the defective case *)
let with_defective maintac deps clr = Goal.enter begin fun g ->
@@ -721,12 +845,12 @@ let eqmovetac _ gen =
;;
let rec eqmoveipats eqpat = function
- | (IPatSimpl _ | IPatClear _ as ipat) :: ipats ->
+ | (IOpSimpl _ | IOpClear _ as ipat) :: ipats ->
ipat :: eqmoveipats eqpat ipats
- | (IPatAnon All :: _ | []) as ipats ->
- IPatAnon (One None) :: eqpat :: ipats
+ | (IOpInaccessibleAll :: _ | []) as ipats ->
+ IOpInaccessible None :: eqpat @ ipats
| ipat :: ipats ->
- ipat :: eqpat :: ipats
+ ipat :: eqpat @ ipats
let ssrsmovetac = Goal.enter begin fun g ->
let sigma, concl = Goal.(sigma g, concl g) in
@@ -736,7 +860,6 @@ let ssrsmovetac = Goal.enter begin fun g ->
end
let tclIPAT ip =
- Ssrprinters.ppdebug (lazy Pp.(str "ipat@run: " ++ Ssrprinters.pr_ipats ip));
IpatMachine.main ~first_case_is_dispatch:false ip
let ssrmovetac = function
@@ -748,17 +871,17 @@ let ssrmovetac = function
gentac <*>
tclLAST_GEN ~to_ind:false lastgen
(tacVIEW_THEN_GRAB view ~conclusion) <*>
- tclIPAT (IPatClear clr :: ipats)
+ tclIPAT (IOpClear (clr,None) :: IpatMachine.tclCompileIPats ipats)
| _::_ as view, (_, ({ gens = []; clr }, ipats)) ->
- tclIPAT (IPatView (false,view) :: IPatClear clr :: ipats)
+ tclIPAT (IOpView (None,view) :: IOpClear (clr,None) :: IpatMachine.tclCompileIPats ipats)
| _, (Some pat, (dgens, ipats)) ->
let dgentac = with_dgens dgens eqmovetac in
- dgentac <*> tclIPAT (eqmoveipats pat ipats)
+ dgentac <*> tclIPAT (eqmoveipats (IpatMachine.tclCompileIPats [pat]) (IpatMachine.tclCompileIPats ipats))
| _, (_, ({ gens = (_ :: _ as gens); dgens = []; clr}, ipats)) ->
let gentac = V82.tactic ~nf_evars:false (Ssrcommon.genstac (gens, clr)) in
- gentac <*> tclIPAT ipats
+ gentac <*> tclIPAT (IpatMachine.tclCompileIPats ipats)
| _, (_, ({ clr }, ipats)) ->
- Tacticals.New.tclTHENLIST [ssrsmovetac; Tactics.clear (List.map Ssrcommon.hyp_id clr); tclIPAT ipats]
+ Tacticals.New.tclTHENLIST [ssrsmovetac; Tactics.clear (List.map Ssrcommon.hyp_id clr); tclIPAT (IpatMachine.tclCompileIPats ipats)]
(** [abstract: absvar gens] **************************************************)
let rec is_Evar_or_CastedMeta sigma x =
diff --git a/plugins/ssr/ssripats.mli b/plugins/ssr/ssripats.mli
index 89cba4be71..893061b154 100644
--- a/plugins/ssr/ssripats.mli
+++ b/plugins/ssr/ssripats.mli
@@ -19,8 +19,44 @@
open Ssrast
+(* Atomic operations for the IPat machine. Use this if you are "patching" an
+ * ipat written by the user, since patching it at he AST level and then
+ * compiling it may have tricky effects, eg adding a clear in front of a view
+ * also has the effect of disposing the view (the compilation phase takes care
+ * of this, by using the compiled ipats you can be more precise *)
+type ssriop =
+ | IOpId of Names.Id.t
+ | IOpDrop
+ | IOpTemporay
+ | IOpInaccessible of string option
+ | IOpInaccessibleAll
+ | IOpAbstractVars of Names.Id.t list
+ | IOpFastNondep
+
+ | IOpInj of ssriops list
+
+ | IOpDispatchBlock of id_block
+ | IOpDispatchBranches of ssriops list
+
+ | IOpCaseBlock of id_block
+ | IOpCaseBranches of ssriops list
+
+ | IOpRewrite of ssrocc * ssrdir
+ | IOpView of ssrclear option * ssrview (* extra clears to be performed *)
+
+ | IOpClear of ssrclear * ssrhyp option
+ | IOpSimpl of ssrsimpl
+
+ | IOpEqGen of unit Proofview.tactic (* generation of eqn *)
+
+ | IOpNoop
+
+and ssriops = ssriop list
+
+val tclCompileIPats : ssripats -> ssriops
+
(* The => tactical *)
-val tclIPAT : ssripats -> unit Proofview.tactic
+val tclIPAT : ssriops -> unit Proofview.tactic
(* As above but with the SSR exception: first case is dispatch *)
val tclIPATssr : ssripats -> unit Proofview.tactic
diff --git a/plugins/ssr/ssrparser.mlg b/plugins/ssr/ssrparser.mlg
index 76726009ac..3fb21e5ef6 100644
--- a/plugins/ssr/ssrparser.mlg
+++ b/plugins/ssr/ssrparser.mlg
@@ -635,11 +635,10 @@ let rec map_ipat map_id map_ssrhyp map_ast_closure_term = function
| IPatClear clr -> IPatClear (List.map map_ssrhyp clr)
| IPatCase (Regular iorpat) -> IPatCase (Regular (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat))
| IPatCase (Block(hat)) -> IPatCase (Block(map_block map_id hat))
- | IPatDispatch (s, Regular iorpat) -> IPatDispatch (s, Regular (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat))
- | IPatDispatch (s, Block (hat)) -> IPatDispatch (s, Block(map_block map_id hat))
+ | IPatDispatch (Regular iorpat) -> IPatDispatch (Regular (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat))
+ | IPatDispatch (Block (hat)) -> IPatDispatch (Block(map_block map_id hat))
| IPatInj iorpat -> IPatInj (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat)
- | IPatView (clr,v) -> IPatView (clr,List.map map_ast_closure_term v)
- | IPatEqGen _ -> assert false (*internal usage only *)
+ | IPatView v -> IPatView (List.map map_ast_closure_term v)
and map_block map_id = function
| Prefix id -> Prefix (map_id id)
| SuffixId id -> SuffixId (map_id id)
@@ -715,22 +714,22 @@ let interp_ipat ist gl =
if not (ltacvar id) then hyp :: hyps else
add_intro_pattern_hyps CAst.(make ?loc (interp_introid ist gl id)) hyps in
let clr' = List.fold_right add_hyps clr [] in
- check_hyps_uniq [] clr'; IPatClear clr'
+ check_hyps_uniq [] clr';
+ IPatClear clr'
| IPatCase(Regular iorpat) ->
IPatCase(Regular(List.map (List.map interp) iorpat))
| IPatCase(Block(hat)) -> IPatCase(Block(interp_block hat))
- | IPatDispatch(s,Regular iorpat) ->
- IPatDispatch(s,Regular (List.map (List.map interp) iorpat))
- | IPatDispatch(s,Block(hat)) -> IPatDispatch(s,Block(interp_block hat))
+ | IPatDispatch(Regular iorpat) ->
+ IPatDispatch(Regular (List.map (List.map interp) iorpat))
+ | IPatDispatch(Block(hat)) -> IPatDispatch(Block(interp_block hat))
| IPatInj iorpat -> IPatInj (List.map (List.map interp) iorpat)
| IPatAbstractVars l ->
IPatAbstractVars (List.map get_intro_id (List.map (interp_introid ist gl) l))
- | IPatView (clr,l) -> IPatView (clr,List.map (fun x -> snd(interp_ast_closure_term ist
+ | IPatView l -> IPatView (List.map (fun x -> snd(interp_ast_closure_term ist
gl x)) l)
| (IPatSimpl _ | IPatAnon _ | IPatRewrite _ | IPatNoop | IPatFastNondep) as x -> x
- | IPatEqGen _ -> assert false (*internal usage only *)
in
interp
@@ -765,10 +764,6 @@ ARGUMENT EXTEND ssripat TYPED AS ssripatrep list PRINTED BY { pr_ssripats }
| Some [], _ -> CErrors.user_err ~loc (str"occ_switch expected")
| None, occ -> [IPatRewrite (occ, R2L)]
| Some clr, _ -> [IPatClear clr; IPatRewrite (allocc, R2L)] }
- | [ ssrdocc(occ) ssrfwdview(v) ] -> { match occ with
- | Some [], _ -> [IPatView (true,v)]
- | Some cl, _ -> check_hyps_uniq [] cl; [IPatClear cl;IPatView (false,v)]
- | _ -> CErrors.user_err ~loc (str"Only identifiers are allowed here") }
| [ ssrdocc(occ) ] -> { match occ with
| Some cl, _ -> check_hyps_uniq [] cl; [IPatClear cl]
| _ -> CErrors.user_err ~loc (str"Only identifiers are allowed here") }
@@ -786,7 +781,7 @@ ARGUMENT EXTEND ssripat TYPED AS ssripatrep list PRINTED BY { pr_ssripats }
| [ "-/" integer(n) "/=" ] -> { [IPatNoop;IPatSimpl(SimplCut (n,~-1))] }
| [ "-/" integer(n) "/" integer (m) "=" ] ->
{ [IPatNoop;IPatSimpl(SimplCut(n,m))] }
- | [ ssrfwdview(v) ] -> { [IPatView (false,v)] }
+ | [ ssrfwdview(v) ] -> { [IPatView v] }
| [ "[" ":" ident_list(idl) "]" ] -> { [IPatAbstractVars idl] }
| [ "[:" ident_list(idl) "]" ] -> { [IPatAbstractVars idl] }
END
@@ -875,11 +870,12 @@ ARGUMENT EXTEND ssripats_ne TYPED AS ssripat PRINTED BY { pr_ssripats }
let check_ssrhpats loc w_binders ipats =
let err_loc s = CErrors.user_err ~loc ~hdr:"ssreflect" s in
let clr, ipats =
+ let opt_app = function None -> fun l -> Some l
+ | Some l1 -> fun l2 -> Some (l1 @ l2) in
let rec aux clr = function
- | IPatClear cl :: tl -> aux (clr @ cl) tl
-(* | IPatSimpl (cl, sim) :: tl -> clr @ cl, IPatSimpl ([], sim) :: tl *)
+ | IPatClear cl :: tl -> aux (opt_app clr cl) tl
| tl -> clr, tl
- in aux [] ipats in
+ in aux None ipats in
let simpl, ipats =
match List.rev ipats with
| IPatSimpl _ as s :: tl -> [s], List.rev tl
@@ -903,27 +899,29 @@ let check_ssrhpats loc w_binders ipats =
in loop [] ipats in
((clr, ipat), binders), simpl
+let pr_clear_opt sep = function None -> mt () | Some x -> pr_clear sep x
+
let pr_hpats (((clr, ipat), binders), simpl) =
- pr_clear mt clr ++ pr_ipats ipat ++ pr_ipats binders ++ pr_ipats simpl
+ pr_clear_opt mt clr ++ pr_ipats ipat ++ pr_ipats binders ++ pr_ipats simpl
let pr_ssrhpats _ _ _ = pr_hpats
let pr_ssrhpats_wtransp _ _ _ (_, x) = pr_hpats x
}
-ARGUMENT EXTEND ssrhpats TYPED AS (((ssrclear * ssripat) * ssripat) * ssripat)
+ARGUMENT EXTEND ssrhpats TYPED AS (((ssrclear option * ssripat) * ssripat) * ssripat)
PRINTED BY { pr_ssrhpats }
| [ ssripats(i) ] -> { check_ssrhpats loc true i }
END
ARGUMENT EXTEND ssrhpats_wtransp
- TYPED AS (bool * (((ssrclear * ssripats) * ssripats) * ssripats))
+ TYPED AS (bool * (((ssrclear option * ssripats) * ssripats) * ssripats))
PRINTED BY { pr_ssrhpats_wtransp }
| [ ssripats(i) ] -> { false,check_ssrhpats loc true i }
| [ ssripats(i) "@" ssripats(j) ] -> { true,check_ssrhpats loc true (i @ j) }
END
ARGUMENT EXTEND ssrhpats_nobs
-TYPED AS (((ssrclear * ssripats) * ssripats) * ssripats) PRINTED BY { pr_ssrhpats }
+TYPED AS (((ssrclear option * ssripats) * ssripats) * ssripats) PRINTED BY { pr_ssrhpats }
| [ ssripats(i) ] -> { check_ssrhpats loc false i }
END
@@ -2051,7 +2049,7 @@ END
(* We just add a numeric version that clears the n top assumptions. *)
TACTIC EXTEND ssrclear
- | [ "clear" natural(n) ] -> { tclIPAT (List.init n (fun _ -> IPatAnon Drop)) }
+ | [ "clear" natural(n) ] -> { tclIPAT (List.init n (fun _ -> IOpDrop)) }
END
(** The "move" tactic *)
@@ -2090,10 +2088,10 @@ let movearg_of_parsed_movearg (v,(eq,(dg,ip))) =
TACTIC EXTEND ssrmove
| [ "move" ssrmovearg(arg) ssrrpat(pat) ] ->
- { ssrmovetac (movearg_of_parsed_movearg arg) <*> tclIPAT [pat] }
+ { ssrmovetac (movearg_of_parsed_movearg arg) <*> tclIPAT (tclCompileIPats [pat]) }
| [ "move" ssrmovearg(arg) ssrclauses(clauses) ] ->
{ tclCLAUSES (ssrmovetac (movearg_of_parsed_movearg arg)) clauses }
-| [ "move" ssrrpat(pat) ] -> { tclIPAT [pat] }
+| [ "move" ssrrpat(pat) ] -> { tclIPAT (tclCompileIPats [pat]) }
| [ "move" ] -> { ssrsmovetac }
END
@@ -2632,7 +2630,11 @@ END
{
-let augment_preclr clr1 (((clr0, x),y),z) = (((clr1 @ clr0, x),y),z)
+let augment_preclr clr1 (((clr0, x),y),z) =
+ let cl = match clr0 with
+ | None -> if clr1 = [] then None else Some clr1
+ | Some clr0 -> Some (clr1 @ clr0) in
+ (((cl, x),y),z)
}
diff --git a/plugins/ssr/ssrprinters.ml b/plugins/ssr/ssrprinters.ml
index 898e03b00e..38f5b7d107 100644
--- a/plugins/ssr/ssrprinters.ml
+++ b/plugins/ssr/ssrprinters.ml
@@ -74,7 +74,7 @@ let pr_occ = function
| None -> str "{}"
let pr_clear_ne clr = str "{" ++ pr_hyps clr ++ str "}"
-let pr_clear sep clr = if clr = [] then mt () else sep () ++ pr_clear_ne clr
+let pr_clear sep clr = sep () ++ pr_clear_ne clr
let pr_dir = function L2R -> str "->" | R2L -> str "<-"
@@ -102,20 +102,18 @@ let rec pr_ipat p =
| IPatClear clr -> pr_clear mt clr
| IPatCase (Regular iorpat) -> hov 1 (str "[" ++ pr_iorpat iorpat ++ str "]")
| IPatCase (Block m) -> hov 1 (str"[" ++ pr_block m ++ str"]")
- | IPatDispatch(_,Regular iorpat) -> hov 1 (str "(" ++ pr_iorpat iorpat ++ str ")")
- | IPatDispatch (_,Block m) -> hov 1 (str"(" ++ pr_block m ++ str")")
+ | IPatDispatch(Regular iorpat) -> hov 1 (str "(" ++ pr_iorpat iorpat ++ str ")")
+ | IPatDispatch (Block m) -> hov 1 (str"(" ++ pr_block m ++ str")")
| IPatInj iorpat -> hov 1 (str "[=" ++ pr_iorpat iorpat ++ str "]")
| IPatRewrite (occ, dir) -> pr_occ occ ++ pr_dir dir
| IPatAnon All -> str "*"
| IPatAnon Drop -> str "_"
| IPatAnon (One _) -> str "?"
- | IPatView (false,v) -> pr_view2 v
- | IPatView (true,v) -> str"{}" ++ pr_view2 v
+ | IPatView v -> pr_view2 v
| IPatAnon Temporary -> str "+"
| IPatNoop -> str "-"
| IPatAbstractVars l -> str "[:" ++ pr_list spc Id.print l ++ str "]"
| IPatFastNondep -> str">"
- | IPatEqGen _ -> str "<tac>"
and pr_ipats ipats = pr_list spc pr_ipat ipats
and pr_iorpat iorpat = pr_list pr_bar pr_ipats iorpat
and pr_block = function (Prefix id) -> str"^" ++ Id.print id
diff --git a/plugins/ssr/ssrprinters.mli b/plugins/ssr/ssrprinters.mli
index 31c360ad6d..5f20ac2705 100644
--- a/plugins/ssr/ssrprinters.mli
+++ b/plugins/ssr/ssrprinters.mli
@@ -43,6 +43,7 @@ val pr_view2 : ast_closure_term list -> Pp.t
val pr_ipat : ssripat -> Pp.t
val pr_ipats : ssripats -> Pp.t
val pr_iorpat : ssripatss -> Pp.t
+val pr_block : id_block -> Pp.t
val pr_hyp : ssrhyp -> Pp.t
val pr_hyps : ssrhyps -> Pp.t
diff --git a/plugins/ssr/ssrview.ml b/plugins/ssr/ssrview.ml
index 4816027296..2794696017 100644
--- a/plugins/ssr/ssrview.ml
+++ b/plugins/ssr/ssrview.ml
@@ -142,7 +142,7 @@ let intern_constr_expr { Genintern.genv; ltacvars = vars } sigma ce =
To allow for t being a notation, like "Notation foo x := ltac:(foo x)", we
need to internalize t.
*)
-let is_tac_in_term ?extra_scope { body; glob_env; interp_env } =
+let is_tac_in_term ?extra_scope { annotation; body; glob_env; interp_env } =
Goal.(enter_one ~__LOC__ begin fun goal ->
let genv = env goal in
let sigma = sigma goal in
@@ -161,7 +161,7 @@ let is_tac_in_term ?extra_scope { body; glob_env; interp_env } =
| Glob_term.GHole (_,_, Some x)
when Genarg.has_type x (Genarg.glbwit Tacarg.wit_tactic)
-> tclUNIT (`Tac (Genarg.out_gen (Genarg.glbwit Tacarg.wit_tactic) x))
- | _ -> tclUNIT (`Term (interp_env, g))
+ | _ -> tclUNIT (`Term (annotation, interp_env, g))
end)
(* To inject a constr into a glob_constr we use an Ltac variable *)
@@ -207,7 +207,7 @@ let tclKeepOpenConstr (_env, sigma, t) = Unsafe.tclEVARS sigma <*> tclUNIT t
let tclADD_CLEAR_IF_ID (env, ist, t) x =
Ssrprinters.ppdebug (lazy
Pp.(str"tclADD_CLEAR_IF_ID: " ++ Printer.pr_econstr_env env ist t));
- let hd, _ = EConstr.decompose_app ist t in
+ let hd, args = EConstr.decompose_app ist t in
match EConstr.kind ist hd with
| Constr.Var id when Ssrcommon.not_section_id id -> tclUNIT (x, [id])
| _ -> tclUNIT (x,[])
@@ -280,8 +280,9 @@ let interp_view ~clear_if_id ist v p =
else tclKeepOpenConstr ot >>= tclPAIR []
(* we store in the state (v top), then (v1 (v2 top))... *)
-let pile_up_view ~clear_if_id (ist, v) =
+let pile_up_view ~clear_if_id (annotation, ist, v) =
let ist = Ssrcommon.option_assert_get ist (Pp.str"not a term") in
+ let clear_if_id = clear_if_id && annotation <> `Parens in
State.vsPUSH (fun p -> interp_view ~clear_if_id ist v p)
let finalize_view s0 ?(simple_types=true) p =
diff --git a/plugins/syntax/numeral.ml b/plugins/syntax/numeral.ml
index 470deb4a60..ea564ae2ba 100644
--- a/plugins/syntax/numeral.ml
+++ b/plugins/syntax/numeral.ml
@@ -33,30 +33,41 @@ let get_constructors ind =
Array.to_list
(Array.mapi (fun j c -> ConstructRef (ind, j + 1)) mc)
-let q_z = qualid_of_string "Coq.Numbers.BinNums.Z"
-let q_positive = qualid_of_string "Coq.Numbers.BinNums.positive"
-let q_int = qualid_of_string "Coq.Init.Decimal.int"
-let q_uint = qualid_of_string "Coq.Init.Decimal.uint"
-let q_option = qualid_of_string "Coq.Init.Datatypes.option"
+let qualid_of_ref n =
+ n |> Coqlib.lib_ref |> Nametab.shortest_qualid_of_global Id.Set.empty
+
+let q_option () = qualid_of_ref "core.option.type"
let unsafe_locate_ind q =
match Nametab.locate q with
| IndRef i -> i
| _ -> raise Not_found
-let locate_ind q =
- try unsafe_locate_ind q
- with Not_found -> Nametab.error_global_not_found q
-
let locate_z () =
- try
- Some { z_ty = unsafe_locate_ind q_z;
- pos_ty = unsafe_locate_ind q_positive }
- with Not_found -> None
+ let zn = "num.Z.type" in
+ let pn = "num.pos.type" in
+ if Coqlib.has_ref zn && Coqlib.has_ref pn
+ then
+ let q_z = qualid_of_ref zn in
+ let q_pos = qualid_of_ref pn in
+ Some ({
+ z_ty = unsafe_locate_ind q_z;
+ pos_ty = unsafe_locate_ind q_pos;
+ }, mkRefC q_z)
+ else None
let locate_int () =
- { uint = locate_ind q_uint;
- int = locate_ind q_int }
+ let int = "num.int.type" in
+ let uint = "num.uint.type" in
+ if Coqlib.has_ref int && Coqlib.has_ref uint
+ then
+ let q_int = qualid_of_ref int in
+ let q_uint = qualid_of_ref uint in
+ Some ({
+ int = unsafe_locate_ind q_int;
+ uint = unsafe_locate_ind q_uint;
+ }, mkRefC q_int, mkRefC q_uint)
+ else None
let has_type f ty =
let (sigma, env) = Pfedit.get_current_context () in
@@ -64,19 +75,17 @@ let has_type f ty =
try let _ = Constrintern.interp_constr env sigma c in true
with Pretype_errors.PretypeError _ -> false
-let type_error_to f ty loadZ =
+let type_error_to f ty =
CErrors.user_err
(pr_qualid f ++ str " should go from Decimal.int to " ++
pr_qualid ty ++ str " or (option " ++ pr_qualid ty ++ str ")." ++
- fnl () ++ str "Instead of Decimal.int, the types Decimal.uint or Z could be used" ++
- (if loadZ then str " (require BinNums first)." else str "."))
+ fnl () ++ str "Instead of Decimal.int, the types Decimal.uint or Z could be used (you may need to require BinNums or Decimal first).")
-let type_error_of g ty loadZ =
+let type_error_of g ty =
CErrors.user_err
(pr_qualid g ++ str " should go from " ++ pr_qualid ty ++
str " to Decimal.int or (option Decimal.int)." ++ fnl () ++
- str "Instead of Decimal.int, the types Decimal.uint or Z could be used" ++
- (if loadZ then str " (require BinNums first)." else str "."))
+ str "Instead of Decimal.int, the types Decimal.uint or Z could be used (you may need to require BinNums or Decimal first).")
let vernac_numeral_notation local ty f g scope opts =
let int_ty = locate_int () in
@@ -86,43 +95,36 @@ let vernac_numeral_notation local ty f g scope opts =
let of_ty = Smartlocate.global_with_alias g in
let cty = mkRefC ty in
let app x y = mkAppC (x,[y]) in
- let cref q = mkRefC q in
let arrow x y =
mkProdC ([CAst.make Anonymous],Default Decl_kinds.Explicit, x, y)
in
- let cZ = cref q_z in
- let cint = cref q_int in
- let cuint = cref q_uint in
- let coption = cref q_option in
- let opt r = app coption r in
+ let opt r = app (mkRefC (q_option ())) r in
let constructors = get_constructors tyc in
(* Check the type of f *)
let to_kind =
- if has_type f (arrow cint cty) then Int int_ty, Direct
- else if has_type f (arrow cint (opt cty)) then Int int_ty, Option
- else if has_type f (arrow cuint cty) then UInt int_ty.uint, Direct
- else if has_type f (arrow cuint (opt cty)) then UInt int_ty.uint, Option
- else
- match z_pos_ty with
- | Some z_pos_ty ->
- if has_type f (arrow cZ cty) then Z z_pos_ty, Direct
- else if has_type f (arrow cZ (opt cty)) then Z z_pos_ty, Option
- else type_error_to f ty false
- | None -> type_error_to f ty true
+ match int_ty with
+ | Some (int_ty, cint, _) when has_type f (arrow cint cty) -> Int int_ty, Direct
+ | Some (int_ty, cint, _) when has_type f (arrow cint (opt cty)) -> Int int_ty, Option
+ | Some (int_ty, _, cuint) when has_type f (arrow cuint cty) -> UInt int_ty.uint, Direct
+ | Some (int_ty, _, cuint) when has_type f (arrow cuint (opt cty)) -> UInt int_ty.uint, Option
+ | _ ->
+ match z_pos_ty with
+ | Some (z_pos_ty, cZ) when has_type f (arrow cZ cty) -> Z z_pos_ty, Direct
+ | Some (z_pos_ty, cZ) when has_type f (arrow cZ (opt cty)) -> Z z_pos_ty, Option
+ | _ -> type_error_to f ty
in
(* Check the type of g *)
let of_kind =
- if has_type g (arrow cty cint) then Int int_ty, Direct
- else if has_type g (arrow cty (opt cint)) then Int int_ty, Option
- else if has_type g (arrow cty cuint) then UInt int_ty.uint, Direct
- else if has_type g (arrow cty (opt cuint)) then UInt int_ty.uint, Option
- else
- match z_pos_ty with
- | Some z_pos_ty ->
- if has_type g (arrow cty cZ) then Z z_pos_ty, Direct
- else if has_type g (arrow cty (opt cZ)) then Z z_pos_ty, Option
- else type_error_of g ty false
- | None -> type_error_of g ty true
+ match int_ty with
+ | Some (int_ty, cint, _) when has_type g (arrow cty cint) -> Int int_ty, Direct
+ | Some (int_ty, cint, _) when has_type g (arrow cty (opt cint)) -> Int int_ty, Option
+ | Some (int_ty, _, cuint) when has_type g (arrow cty cuint) -> UInt int_ty.uint, Direct
+ | Some (int_ty, _, cuint) when has_type g (arrow cty (opt cuint)) -> UInt int_ty.uint, Option
+ | _ ->
+ match z_pos_ty with
+ | Some (z_pos_ty, cZ) when has_type g (arrow cty cZ) -> Z z_pos_ty, Direct
+ | Some (z_pos_ty, cZ) when has_type g (arrow cty (opt cZ)) -> Z z_pos_ty, Option
+ | _ -> type_error_of g ty
in
let o = { to_kind; to_ty; of_kind; of_ty;
ty_name = ty;
diff --git a/printing/prettyp.ml b/printing/prettyp.ml
index c417ef8a66..408bd5f60b 100644
--- a/printing/prettyp.ml
+++ b/printing/prettyp.ml
@@ -267,7 +267,6 @@ let print_name_infos ref =
print_ref true ref None; blankline]
else
[] in
- print_polymorphism ref @
print_type_in_type ref @
print_primitive ref @
type_info_for_implicit @
@@ -838,6 +837,7 @@ let print_about_any ?loc env sigma k udecl =
Dumpglob.add_glob ?loc ref;
pr_infos_list
(print_ref false ref udecl :: blankline ::
+ print_polymorphism ref @
print_name_infos ref @
(if Pp.ismt rb then [] else [rb]) @
print_opacity ref @
diff --git a/proofs/proof_global.ml b/proofs/proof_global.ml
index 4cc73f419e..9ee9e7ae2c 100644
--- a/proofs/proof_global.ml
+++ b/proofs/proof_global.ml
@@ -22,51 +22,6 @@ open Names
module NamedDecl = Context.Named.Declaration
-(*** Proof Modes ***)
-
-(* Type of proof modes :
- - A function [set] to set it *from standard mode*
- - A function [reset] to reset the *standard mode* from it *)
-type proof_mode_name = string
-type proof_mode = {
- name : proof_mode_name ;
- set : unit -> unit ;
- reset : unit -> unit
-}
-
-let proof_modes = Hashtbl.create 6
-let find_proof_mode n =
- try Hashtbl.find proof_modes n
- with Not_found ->
- CErrors.user_err Pp.(str (Format.sprintf "No proof mode named \"%s\"." n))
-
-let register_proof_mode ({name = n} as m) =
- Hashtbl.add proof_modes n (CEphemeron.create m)
-
-(* initial mode: standard mode *)
-let standard = { name = "No" ; set = (fun ()->()) ; reset = (fun () -> ()) }
-let _ = register_proof_mode standard
-
-(* Default proof mode, to be set at the beginning of proofs. *)
-let default_proof_mode = ref (find_proof_mode "No")
-
-let get_default_proof_mode_name () =
- (CEphemeron.default !default_proof_mode standard).name
-
-let proof_mode_opt_name = ["Default";"Proof";"Mode"]
-let () =
- Goptions.(declare_string_option {
- optdepr = false;
- optname = "default proof mode" ;
- optkey = proof_mode_opt_name ;
- optread = begin fun () ->
- (CEphemeron.default !default_proof_mode standard).name
- end;
- optwrite = begin fun n ->
- default_proof_mode := find_proof_mode n
- end
- })
-
(*** Proof Global Environment ***)
(* Extra info on proofs. *)
@@ -95,7 +50,6 @@ type pstate = {
endline_tactic : Genarg.glob_generic_argument option;
section_vars : Constr.named_context option;
proof : Proof.t;
- mode : proof_mode CEphemeron.key;
universe_decl: UState.universe_decl;
strength : Decl_kinds.goal_kind;
}
@@ -109,23 +63,8 @@ let apply_terminator f = f
to be resumed when the current proof is closed or aborted. *)
let pstates = ref ([] : pstate list)
-(* Current proof_mode, for bookkeeping *)
-let current_proof_mode = ref !default_proof_mode
-
-(* combinators for proof modes *)
-let update_proof_mode () =
- match !pstates with
- | { mode = m } :: _ ->
- CEphemeron.iter_opt !current_proof_mode (fun x -> x.reset ());
- current_proof_mode := m;
- CEphemeron.iter_opt !current_proof_mode (fun x -> x.set ())
- | _ ->
- CEphemeron.iter_opt !current_proof_mode (fun x -> x.reset ());
- current_proof_mode := find_proof_mode "No"
-
(* combinators for the current_proof lists *)
-let push a l = l := a::!l;
- update_proof_mode ()
+let push a l = l := a::!l
exception NoSuchProof
let () = CErrors.register_handler begin function
@@ -221,25 +160,8 @@ let discard {CAst.loc;v=id} =
let discard_current () =
if List.is_empty !pstates then raise NoCurrentProof else pstates := List.tl !pstates
-
let discard_all () = pstates := []
-(* [set_proof_mode] sets the proof mode to be used after it's called. It is
- typically called by the Proof Mode command. *)
-let set_proof_mode m id =
- pstates := List.map
- (fun ps -> if pf_name_eq id ps then { ps with mode = m } else ps)
- !pstates;
- update_proof_mode ()
-
-let set_proof_mode mn =
- set_proof_mode (find_proof_mode mn) (get_current_proof_name ())
-
-let activate_proof_mode mode =
- CEphemeron.iter_opt (find_proof_mode mode) (fun x -> x.set ())
-let disactivate_current_proof_mode () =
- CEphemeron.iter_opt !current_proof_mode (fun x -> x.reset ())
-
(** [start_proof sigma id pl str goals terminator] starts a proof of name
[id] with goals [goals] (a list of pairs of environment and
conclusion); [str] describes what kind of theorem/definition this
@@ -254,9 +176,8 @@ let start_proof sigma name ?(pl=UState.default_univ_decl) kind goals terminator
proof = Proof.start ~name ~poly:(pi2 kind) sigma goals;
endline_tactic = None;
section_vars = None;
- mode = find_proof_mode "No";
- universe_decl = pl;
- strength = kind } in
+ strength = kind;
+ universe_decl = pl } in
push initial_state pstates
let start_dependent_proof name ?(pl=UState.default_univ_decl) kind goals terminator =
@@ -265,9 +186,8 @@ let start_dependent_proof name ?(pl=UState.default_univ_decl) kind goals termina
proof = Proof.dependent_start ~name ~poly:(pi2 kind) goals;
endline_tactic = None;
section_vars = None;
- mode = find_proof_mode "No";
- universe_decl = pl;
- strength = kind } in
+ strength = kind;
+ universe_decl = pl } in
push initial_state pstates
let get_used_variables () = (cur_pstate ()).section_vars
@@ -478,7 +398,7 @@ end
let freeze ~marshallable =
if marshallable then CErrors.anomaly (Pp.str"full marshalling of proof state not supported.")
else !pstates
-let unfreeze s = pstates := s; update_proof_mode ()
+let unfreeze s = pstates := s
let proof_of_state = function { proof }::_ -> proof | _ -> raise NoCurrentProof
let copy_terminators ~src ~tgt =
assert(List.length src = List.length tgt);
diff --git a/proofs/proof_global.mli b/proofs/proof_global.mli
index e762f3b7dc..40920f51a3 100644
--- a/proofs/proof_global.mli
+++ b/proofs/proof_global.mli
@@ -13,7 +13,6 @@
environment. *)
type t
-
val there_are_pending_proofs : unit -> bool
val check_no_pending_proof : unit -> unit
@@ -139,47 +138,3 @@ val freeze : marshallable:bool -> t
val unfreeze : t -> unit
val proof_of_state : t -> Proof.t
val copy_terminators : src:t -> tgt:t -> t
-
-
-(**********************************************************)
-(* Proof Mode API *)
-(* The current Proof Mode API is deprecated and a new one *)
-(* will be (hopefully) defined in 8.8 *)
-(**********************************************************)
-
-(** Type of proof modes :
- - A name
- - A function [set] to set it *from standard mode*
- - A function [reset] to reset the *standard mode* from it
-
-*)
-type proof_mode_name = string
-type proof_mode = {
- name : proof_mode_name ;
- set : unit -> unit ;
- reset : unit -> unit
-}
-
-(** Registers a new proof mode which can then be adressed by name
- in [set_default_proof_mode].
- One mode is already registered - the standard mode - named "No",
- It corresponds to Coq default setting are they are set when coqtop starts. *)
-val register_proof_mode : proof_mode -> unit
-(* Can't make this deprecated due to limitations of camlp5 *)
-(* [@@ocaml.deprecated "the current proof mode API is deprecated, use with care, see PR #459 and #566 "] *)
-
-val proof_mode_opt_name : string list
-
-val get_default_proof_mode_name : unit -> proof_mode_name
-[@@ocaml.deprecated "the current proof mode API is deprecated, use with care, see PR #459 and #566 "]
-
-(** [set_proof_mode] sets the proof mode to be used after it's called. It is
- typically called by the Proof Mode command. *)
-val set_proof_mode : proof_mode_name -> unit
-[@@ocaml.deprecated "the current proof mode API is deprecated, use with care, see PR #459 and #566 "]
-
-val activate_proof_mode : proof_mode_name -> unit
-[@@ocaml.deprecated "the current proof mode API is deprecated, use with care, see PR #459 and #566 "]
-
-val disactivate_current_proof_mode : unit -> unit
-[@@ocaml.deprecated "the current proof mode API is deprecated, use with care, see PR #459 and #566 "]
diff --git a/stm/stm.ml b/stm/stm.ml
index 8ed7f2c866..0165b3c029 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -126,8 +126,6 @@ type aast = {
}
let pr_ast { expr; indentation } = Pp.(int indentation ++ str " " ++ Ppvernac.pr_vernac expr)
-let default_proof_mode () = Proof_global.get_default_proof_mode_name () [@ocaml.warning "-3"]
-
(* Commands piercing opaque *)
let may_pierce_opaque = function
| VernacPrint _
@@ -146,13 +144,13 @@ let update_global_env () =
module Vcs_ = Vcs.Make(Stateid.Self)
type future_proof = Proof_global.closed_proof_output Future.computation
-type proof_mode = string
+
type depth = int
type branch_type =
[ `Master
- | `Proof of proof_mode * depth
+ | `Proof of depth
| `Edit of
- proof_mode * Stateid.t * Stateid.t * Vernacextend.vernac_qed_type * Vcs_.Branch.t ]
+ Stateid.t * Stateid.t * Vernacextend.vernac_qed_type * Vcs_.Branch.t ]
(* TODO 8.7 : split commands and tactics, since this type is too messy now *)
type cmd_t = {
ctac : bool; (* is a tactic *)
@@ -203,10 +201,10 @@ let summary_pstate = Evarutil.meta_counter_summary_tag,
Obligations.program_tcc_summary_tag
type cached_state =
- | Empty
- | Error of Exninfo.iexn
- | Valid of Vernacstate.t
-
+ | EmptyState
+ | ParsingState of Vernacstate.Parser.state
+ | FullState of Vernacstate.t
+ | ErrorState of Vernacstate.Parser.state option * Exninfo.iexn
type branch = Vcs_.Branch.t * branch_type Vcs_.branch_info
type backup = { mine : branch; others : branch list }
@@ -214,10 +212,16 @@ type 'vcs state_info = { (* TODO: Make this record private to VCS *)
mutable n_reached : int; (* debug cache: how many times was computed *)
mutable n_goals : int; (* open goals: indentation *)
mutable state : cached_state; (* state value *)
+ mutable proof_mode : Pvernac.proof_mode option;
mutable vcs_backup : 'vcs option * backup option;
}
-let default_info () =
- { n_reached = 0; n_goals = 0; state = Empty; vcs_backup = None,None }
+let default_info proof_mode =
+ {
+ n_reached = 0; n_goals = 0;
+ state = EmptyState;
+ proof_mode;
+ vcs_backup = (None,None);
+ }
module DynBlockData : Dyn.S = Dyn.Make ()
@@ -256,15 +260,15 @@ end = struct (* {{{ *)
List.fold_left max 0
(CList.map_filter
(function
- | { Vcs_.kind = `Proof (_,n) } -> Some n
+ | { Vcs_.kind = `Proof n } -> Some n
| { Vcs_.kind = `Edit _ } -> Some 1
| _ -> None)
(List.map (Vcs_.get_branch vcs) (Vcs_.branches vcs)))
let find_proof_at_depth vcs pl =
try List.find (function
- | _, { Vcs_.kind = `Proof(m, n) } -> Int.equal n pl
- | _, { Vcs_.kind = `Edit _ } -> anomaly(Pp.str "find_proof_at_depth.")
+ | _, { Vcs_.kind = `Proof n } -> Int.equal n pl
+ | _, { Vcs_.kind = `Edit _ } -> anomaly(Pp.str "find_proof_at_depth")
| _ -> false)
(List.map (fun h -> h, Vcs_.get_branch vcs h) (Vcs_.branches vcs))
with Not_found -> failwith "find_proof_at_depth"
@@ -326,7 +330,7 @@ module VCS : sig
type vcs = (branch_type, transaction, vcs state_info, box) Vcs_.t
- val init : stm_doc_type -> id -> doc
+ val init : stm_doc_type -> id -> Vernacstate.Parser.state -> doc
(* val get_type : unit -> stm_doc_type *)
val set_ldir : Names.DirPath.t -> unit
val get_ldir : unit -> Names.DirPath.t
@@ -339,7 +343,7 @@ module VCS : sig
val branches : unit -> Branch.t list
val get_branch : Branch.t -> branch_type branch_info
val get_branch_pos : Branch.t -> id
- val new_node : ?id:Stateid.t -> unit -> id
+ val new_node : ?id:Stateid.t -> Pvernac.proof_mode option -> unit -> id
val merge : id -> ours:transaction -> ?into:Branch.t -> Branch.t -> unit
val rewrite_merge : id -> ours:transaction -> at:id -> Branch.t -> unit
val delete_branch : Branch.t -> unit
@@ -356,6 +360,10 @@ module VCS : sig
val goals : id -> int -> unit
val set_state : id -> cached_state -> unit
val get_state : id -> cached_state
+ val set_parsing_state : id -> Vernacstate.Parser.state -> unit
+ val get_parsing_state : id -> Vernacstate.Parser.state option
+ val get_proof_mode : id -> Pvernac.proof_mode option
+ val set_proof_mode : id -> Pvernac.proof_mode option -> unit
(* cuts from start -> stop, raising Expired if some nodes are not there *)
val slice : block_start:id -> block_stop:id -> vcs
@@ -369,7 +377,8 @@ module VCS : sig
val proof_nesting : unit -> int
val checkout_shallowest_proof_branch : unit -> unit
- val propagate_sideff : action:seff_t -> unit
+ val propagate_sideff : action:seff_t -> Stateid.t list
+ val propagate_qed : unit -> unit
val gc : unit -> unit
@@ -411,11 +420,11 @@ end = struct (* {{{ *)
| Qed { qast } -> Pp.string_of_ppcmds (pr_ast qast) in
let is_green id =
match get_info vcs id with
- | Some { state = Valid _ } -> true
+ | Some { state = FullState _ } -> true
| _ -> false in
let is_red id =
match get_info vcs id with
- | Some { state = Error _ } -> true
+ | Some { state = ErrorState _ } -> true
| _ -> false in
let head = current_branch vcs in
let heads =
@@ -517,10 +526,11 @@ end = struct (* {{{ *)
let doc_type = ref (Interactive (TopLogical (Names.DirPath.make [])))
let ldir = ref Names.DirPath.empty
- let init dt id =
+ let init dt id ps =
doc_type := dt;
vcs := empty id;
- vcs := set_info !vcs id (default_info ());
+ let info = { (default_info None) with state = ParsingState ps } in
+ vcs := set_info !vcs id info;
dummy_doc
let set_ldir ld =
@@ -545,9 +555,9 @@ end = struct (* {{{ *)
let branches () = branches !vcs
let get_branch head = get_branch !vcs head
let get_branch_pos head = (get_branch head).pos
- let new_node ?(id=Stateid.fresh ()) () =
+ let new_node ?(id=Stateid.fresh ()) proof_mode () =
assert(Vcs_.get_info !vcs id = None);
- vcs := set_info !vcs id (default_info ());
+ vcs := set_info !vcs id (default_info proof_mode);
id
let merge id ~ours ?into branch =
vcs := merge !vcs id ~ours ~theirs:Noop ?into branch
@@ -569,9 +579,39 @@ end = struct (* {{{ *)
| Some x -> x
| None -> raise Vcs_aux.Expired
let set_state id s =
- (get_info id).state <- s;
- if async_proofs_is_master !cur_opt then Hooks.(call state_ready ~doc:dummy_doc (* XXX should be taken in input *) id)
+ let info = get_info id in
+ info.state <- s;
+ let is_full_state_valid = match s with
+ | FullState _ -> true
+ | EmptyState | ErrorState _ | ParsingState _ -> false
+ in
+ if async_proofs_is_master !cur_opt && is_full_state_valid then
+ Hooks.(call state_ready ~doc:dummy_doc (* XXX should be taken in input *) id)
+
let get_state id = (get_info id).state
+
+ let get_parsing_state id =
+ stm_pperr_endline (fun () -> str "retrieve parsing state state " ++ str (Stateid.to_string id) ++ str " }}}");
+ match (get_info id).state with
+ | FullState s -> Some s.Vernacstate.parsing
+ | ParsingState s -> Some s
+ | ErrorState (s,_) -> s
+ | EmptyState -> None
+
+ let set_parsing_state id ps =
+ let info = get_info id in
+ let new_state =
+ match info.state with
+ | FullState s -> assert false
+ | ParsingState s -> assert false
+ | ErrorState _ -> assert false
+ | EmptyState -> ParsingState ps
+ in
+ info.state <- new_state
+
+ let get_proof_mode id = (get_info id).proof_mode
+ let set_proof_mode id pm = (get_info id).proof_mode <- pm
+
let reached id =
let info = get_info id in
info.n_reached <- info.n_reached + 1
@@ -582,28 +622,33 @@ end = struct (* {{{ *)
let checkout_shallowest_proof_branch () =
if List.mem edit_branch (Vcs_.branches !vcs) then begin
- checkout edit_branch;
- match get_branch edit_branch with
- | { kind = `Edit (mode, _,_,_,_) } -> Proof_global.activate_proof_mode mode [@ocaml.warning "-3"]
- | _ -> assert false
+ checkout edit_branch
end else
let pl = proof_nesting () in
try
- let branch, mode = match Vcs_aux.find_proof_at_depth !vcs pl with
- | h, { Vcs_.kind = `Proof (m, _) } -> h, m | _ -> assert false in
- checkout branch;
- stm_prerr_endline (fun () -> "mode:" ^ mode);
- Proof_global.activate_proof_mode mode [@ocaml.warning "-3"]
+ let branch = fst @@ Vcs_aux.find_proof_at_depth !vcs pl in
+ checkout branch
with Failure _ ->
- checkout Branch.master;
- Proof_global.disactivate_current_proof_mode () [@ocaml.warning "-3"]
+ checkout Branch.master
(* copies the transaction on every open branch *)
let propagate_sideff ~action =
+ List.map (fun b ->
+ checkout b;
+ let proof_mode = get_proof_mode @@ get_branch_pos b in
+ let id = new_node proof_mode () in
+ merge id ~ours:(Sideff action) ~into:b Branch.master;
+ id)
+ (List.filter (fun b -> not (Branch.equal b Branch.master)) (branches ()))
+
+ let propagate_qed () =
List.iter (fun b ->
checkout b;
- let id = new_node () in
- merge id ~ours:(Sideff action) ~into:b Branch.master)
+ let proof_mode = get_proof_mode @@ get_branch_pos b in
+ let id = new_node proof_mode () in
+ let parsing = Option.get @@ get_parsing_state (get_branch_pos b) in
+ merge id ~ours:(Sideff CherryPickEnv) ~into:b Branch.master;
+ set_parsing_state id parsing)
(List.filter (fun b -> not (Branch.equal b Branch.master)) (branches ()))
let visit id = Vcs_aux.visit !vcs id
@@ -625,10 +670,12 @@ end = struct (* {{{ *)
let slice ~block_start ~block_stop =
let l = nodes_in_slice ~block_start ~block_stop in
let copy_info v id =
+ let info = get_info id in
Vcs_.set_info v id
- { (get_info id) with state = Empty; vcs_backup = None,None } in
+ { info with state = EmptyState;
+ vcs_backup = None,None } in
let make_shallow = function
- | Valid st -> Valid (Vernacstate.make_shallow st)
+ | FullState st -> FullState (Vernacstate.make_shallow st)
| x -> x
in
let copy_info_w_state v id =
@@ -651,12 +698,14 @@ end = struct (* {{{ *)
let v = copy_info v id in
v) l v in
(* Stm should have reached the beginning of proof *)
- assert (match (get_info block_start).state with Valid _ -> true | _ -> false);
+ assert (match get_state block_start
+ with FullState _ -> true | _ -> false);
(* We put in the new dag the most recent state known to master *)
let rec fill id =
- match (get_info id).state with
- | Empty | Error _ -> fill (Vcs_aux.visit v id).next
- | Valid _ -> copy_info_w_state v id in
+ match get_state id with
+ | EmptyState | ErrorState _ | ParsingState _ -> fill (Vcs_aux.visit v id).next
+ | FullState _ -> copy_info_w_state v id
+ in
let v = fill block_stop in
(* We put in the new dag the first state (since Qed shall run on it,
* see check_task_aux) *)
@@ -753,13 +802,12 @@ end = struct (* {{{ *)
end (* }}} *)
let state_of_id ~doc id =
- try match (VCS.get_info id).state with
- | Valid s -> `Valid (Some s)
- | Error (e,_) -> `Error e
- | Empty -> `Valid None
+ try match VCS.get_state id with
+ | FullState s -> `Valid (Some s)
+ | ErrorState (_,(e,_)) -> `Error e
+ | EmptyState | ParsingState _ -> `Valid None
with VCS.Expired -> `Expired
-
(****** A cache: fills in the nodes of the VCS document with their value ******)
module State : sig
@@ -782,6 +830,7 @@ module State : sig
val fix_exn_ref : (Exninfo.iexn -> Exninfo.iexn) ref
val install_cached : Stateid.t -> unit
+ (* val install_parsing_state : Stateid.t -> unit *)
val is_cached : ?cache:bool -> Stateid.t -> bool
val is_cached_and_valid : ?cache:bool -> Stateid.t -> bool
@@ -804,10 +853,6 @@ module State : sig
val register_root_state : unit -> unit
val restore_root_state : unit -> unit
- (* Only for internal use to catch problems in parse_sentence, should
- be removed in the state handling refactoring. *)
- val cur_id : Stateid.t ref
-
val purify : ('a -> 'b) -> 'a -> 'b
end = struct (* {{{ *)
@@ -824,6 +869,8 @@ end = struct (* {{{ *)
Vernacstate.unfreeze_interp_state st.vernac_state;
cur_id := st.id
+ let invalidate_cur_state () = cur_id := Stateid.dummy
+
type proof_part =
Proof_global.t *
int * (* Evarutil.meta_counter_summary_tag *)
@@ -842,49 +889,58 @@ end = struct (* {{{ *)
Summary.project_from_summary st Util.(pi3 summary_pstate)
let cache_state ~marshallable id =
- VCS.set_state id (Valid (Vernacstate.freeze_interp_state ~marshallable))
+ VCS.set_state id (FullState (Vernacstate.freeze_interp_state ~marshallable))
- let freeze_invalid id iexn = VCS.set_state id (Error iexn)
+ let freeze_invalid id iexn =
+ let ps = VCS.get_parsing_state id in
+ VCS.set_state id (ErrorState (ps,iexn))
let is_cached ?(cache=false) id only_valid =
if Stateid.equal id !cur_id then
try match VCS.get_info id with
- | { state = Empty } when cache -> cache_state ~marshallable:false id; true
+ | ({ state = EmptyState } | { state = ParsingState _ }) when cache -> cache_state ~marshallable:false id; true
| _ -> true
with VCS.Expired -> false
else
- try match VCS.get_info id with
- | { state = Empty } -> false
- | { state = Valid _ } -> true
- | { state = Error _ } -> not only_valid
+ try match VCS.get_state id with
+ | EmptyState | ParsingState _ -> false
+ | FullState _ -> true
+ | ErrorState _ -> not only_valid
with VCS.Expired -> false
let is_cached_and_valid ?cache id = is_cached ?cache id true
let is_cached ?cache id = is_cached ?cache id false
let install_cached id =
- match VCS.get_info id with
- | { state = Valid s } ->
+ match VCS.get_state id with
+ | FullState s ->
Vernacstate.unfreeze_interp_state s;
cur_id := id
- | { state = Error ie } ->
+ | ErrorState (_,ie) ->
Exninfo.iraise ie
- | _ ->
- (* coqc has a 1 slot cache and only for valid states *)
- if not (VCS.is_interactive ()) && Stateid.equal id !cur_id then ()
- else anomaly Pp.(str "installing a non cached state.")
+ | EmptyState | ParsingState _ ->
+ (* coqc has a 1 slot cache and only for valid states *)
+ if (VCS.is_interactive ()) || not (Stateid.equal id !cur_id) then
+ anomaly Pp.(str "installing a non cached state.")
+
+ (*
+ let install_parsing_state id =
+ if not (Stateid.equal id !cur_id) then begin
+ Vernacstate.Parser.install @@ VCS.get_parsing_state id
+ end
+ *)
let get_cached id =
- try match VCS.get_info id with
- | { state = Valid s } -> s
+ try match VCS.get_state id with
+ | FullState s -> s
| _ -> anomaly Pp.(str "not a cached state.")
with VCS.Expired -> anomaly Pp.(str "not a cached state (expired).")
let assign id what =
let open Vernacstate in
- if VCS.get_state id <> Empty then () else
+ if VCS.get_state id <> EmptyState then () else
try match what with
| `Full s ->
let s =
@@ -896,7 +952,7 @@ end = struct (* {{{ *)
~src:(get_cached prev).proof ~tgt:s.proof }
else s
with VCS.Expired -> s in
- VCS.set_state id (Valid s)
+ VCS.set_state id (FullState s)
| `ProofOnly(ontop,(pstate,c1,c2,c3)) ->
if is_cached_and_valid ontop then
let s = get_cached ontop in
@@ -912,7 +968,7 @@ end = struct (* {{{ *)
st
end
} in
- VCS.set_state id (Valid s)
+ VCS.set_state id (FullState s)
with VCS.Expired -> ()
let exn_on id ~valid (e, info) =
@@ -958,7 +1014,7 @@ end = struct (* {{{ *)
with e ->
let (e, info) = CErrors.push e in
let good_id = !cur_id in
- cur_id := Stateid.dummy;
+ invalidate_cur_state ();
VCS.reached id;
let ie =
match Stateid.get info, safe_id with
@@ -1130,7 +1186,7 @@ module Backtrack : sig
val branches_of : Stateid.t -> backup
(* Returns the state that the command should backtract to *)
- val undo_vernac_classifier : vernac_control -> doc:doc -> Stateid.t * vernac_when
+ val undo_vernac_classifier : vernac_control -> doc:doc -> Stateid.t
val get_prev_proof : doc:doc -> Stateid.t -> Proof.t option
end = struct (* {{{ *)
@@ -1205,30 +1261,30 @@ end = struct (* {{{ *)
try
match Vernacprop.under_control v with
| VernacResetInitial ->
- Stateid.initial, VtNow
+ Stateid.initial
| VernacResetName {CAst.v=name} ->
- let id = VCS.get_branch_pos (VCS.current_branch ()) in
+ let id = VCS.cur_tip () in
(try
let oid =
fold_until (fun b (id,_,label,_,_) ->
if b then `Stop id else `Cont (List.mem name label))
false id in
- oid, VtNow
+ oid
with Not_found ->
- id, VtNow)
+ id)
| VernacBack n ->
- let id = VCS.get_branch_pos (VCS.current_branch ()) in
+ let id = VCS.cur_tip () in
let oid = fold_until (fun n (id,_,_,_,_) ->
if Int.equal n 0 then `Stop id else `Cont (n-1)) n id in
- oid, VtNow
+ oid
| VernacUndo n ->
- let id = VCS.get_branch_pos (VCS.current_branch ()) in
+ let id = VCS.cur_tip () in
let oid = fold_until back_tactic n id in
- oid, VtLater
+ oid
| VernacUndoTo _
| VernacRestart as e ->
let m = match e with VernacUndoTo m -> m | _ -> 0 in
- let id = VCS.get_branch_pos (VCS.current_branch ()) in
+ let id = VCS.cur_tip () in
let vcs =
match (VCS.get_info id).vcs_backup with
| None, _ -> anomaly Pp.(str"Backtrack: tip with no vcs_backup.")
@@ -1241,15 +1297,15 @@ end = struct (* {{{ *)
0 id in
let oid = fold_until (fun n (id,_,_,_,_) ->
if Int.equal n 0 then `Stop id else `Cont (n-1)) (n-m-1) id in
- oid, VtLater
+ oid
| VernacAbortAll ->
- let id = VCS.get_branch_pos (VCS.current_branch ()) in
+ let id = VCS.cur_tip () in
let oid = fold_until (fun () (id,vcs,_,_,_) ->
match Vcs_.branches vcs with [_] -> `Stop id | _ -> `Cont ())
() id in
- oid, VtLater
+ oid
| VernacBackTo id ->
- Stateid.of_int id, VtNow
+ Stateid.of_int id
| _ -> anomaly Pp.(str "incorrect VtMeta classification")
with
| Not_found ->
@@ -1615,7 +1671,7 @@ end = struct (* {{{ *)
when is_tac expr && State.same_env o n -> (* A pure tactic *)
Some (id, `ProofOnly (prev, State.proof_part_of_frozen n))
| Some _, Some s ->
- msg_debug (Pp.str "STM: sending back a fat state");
+ if !Flags.debug then msg_debug (Pp.str "STM: sending back a fat state");
Some (id, `Full s)
| _, Some s -> Some (id, `Full s) in
let rec aux seen = function
@@ -2331,8 +2387,8 @@ let known_state ~doc ?(redefine_qed=false) ~cache id =
(Proofview.Goal.goal gl) goals_to_admit then
Proofview.give_up else Proofview.tclUNIT ()
end in
- match (VCS.get_info base_state).state with
- | Valid { Vernacstate.proof } ->
+ match VCS.get_state base_state with
+ | FullState { Vernacstate.proof } ->
Proof_global.unfreeze proof;
Proof_global.with_current_proof (fun _ p ->
feedback ~id:id Feedback.AddedAxiom;
@@ -2469,7 +2525,7 @@ let known_state ~doc ?(redefine_qed=false) ~cache id =
VCS.create_proof_task_box nodes ~qed:id ~block_start;
begin match brinfo, qed.fproof with
| { VCS.kind = `Edit _ }, None -> assert false
- | { VCS.kind = `Edit (_,_,_, okeep, _) }, Some (ofp, cancel) ->
+ | { VCS.kind = `Edit (_,_, okeep, _) }, Some (ofp, cancel) ->
assert(redefine_qed = true);
if okeep <> keep then
msg_warning(strbrk("The command closing the proof changed. "
@@ -2655,7 +2711,7 @@ let new_doc { doc_type ; iload_path; require_libs; stm_options } =
(* We must reset the whole state before creating a document! *)
State.restore_root_state ();
- let doc = VCS.init doc_type Stateid.initial in
+ let doc = VCS.init doc_type Stateid.initial (Vernacstate.Parser.init ()) in
(* Set load path; important, this has to happen before we declare
the library below as [Declaremods/Library] will infer the module
@@ -2723,16 +2779,8 @@ let observe ~doc id =
let finish ~doc =
let head = VCS.current_branch () in
- let doc =observe ~doc (VCS.get_branch_pos head) in
- VCS.print ();
- (* EJGA: Setting here the proof state looks really wrong, and it
- hides true bugs cf bug #5363. Also, what happens with observe? *)
- (* Some commands may by side effect change the proof mode *)
- (match VCS.get_branch head with
- | { VCS.kind = `Edit (mode,_,_,_,_) } -> Proof_global.activate_proof_mode mode [@ocaml.warning "-3"]
- | { VCS.kind = `Proof (mode, _) } -> Proof_global.activate_proof_mode mode [@ocaml.warning "-3"]
- | _ -> ()
- ); doc
+ let doc = observe ~doc (VCS.get_branch_pos head) in
+ VCS.print (); doc
let wait ~doc =
let doc = observe ~doc (VCS.get_branch_pos VCS.Branch.master) in
@@ -2809,12 +2857,14 @@ let merge_proof_branch ~valid ?id qast keep brname =
match brinfo with
| { VCS.kind = `Proof _ } ->
VCS.checkout VCS.Branch.master;
- let id = VCS.new_node ?id () in
+ let id = VCS.new_node ?id None () in
+ let parsing = Option.get @@ VCS.get_parsing_state (VCS.cur_tip ()) in
VCS.merge id ~ours:(Qed (qed None)) brname;
+ VCS.set_parsing_state id parsing;
VCS.delete_branch brname;
- VCS.propagate_sideff ~action:CherryPickEnv;
+ VCS.propagate_qed ();
`Ok
- | { VCS.kind = `Edit (mode, qed_id, master_id, _,_) } ->
+ | { VCS.kind = `Edit (qed_id, master_id, _,_) } ->
let ofp =
match VCS.visit qed_id with
| { step = `Qed ({ fproof }, _) } -> fproof
@@ -2846,25 +2896,32 @@ let snapshot_vio ~doc ldir long_f_dot_vo =
let reset_task_queue = Slaves.reset_task_queue
(* Document building *)
-let process_back_meta_command ~newtip ~head oid aast w =
- let id = VCS.new_node ~id:newtip () in
- let { mine; others } = Backtrack.branches_of oid in
+
+(* We process a meta command found in the document *)
+let process_back_meta_command ~newtip ~head oid aast =
let valid = VCS.get_branch_pos head in
+ let old_parsing = Option.get @@ VCS.get_parsing_state oid in
+
+ (* Merge in and discard all the branches currently open that were not open in `oid` *)
+ let { mine; others } = Backtrack.branches_of oid in
List.iter (fun branch ->
if not (List.mem_assoc branch (mine::others)) then
ignore(merge_proof_branch ~valid aast VtDrop branch))
(VCS.branches ());
+
+ (* We add a node on top of every branch, to represent state aliasing *)
VCS.checkout_shallowest_proof_branch ();
let head = VCS.current_branch () in
List.iter (fun b ->
- if not(VCS.Branch.equal b head) then begin
- VCS.checkout b;
- VCS.commit (VCS.new_node ()) (Alias (oid,aast));
- end)
+ VCS.checkout b;
+ let id = if (VCS.Branch.equal b head) then Some newtip else None in
+ let proof_mode = VCS.get_proof_mode @@ VCS.cur_tip () in
+ let id = VCS.new_node ?id proof_mode () in
+ VCS.commit id (Alias (oid,aast));
+ VCS.set_parsing_state id old_parsing)
(VCS.branches ());
VCS.checkout_shallowest_proof_branch ();
- VCS.commit id (Alias (oid,aast));
- Backtrack.record (); if w == VtNow then ignore(finish ~doc:dummy_doc); `Ok
+ Backtrack.record (); `Ok
let get_allow_nested_proofs =
Goptions.declare_bool_option_and_ref
@@ -2873,6 +2930,7 @@ let get_allow_nested_proofs =
~key:Vernac_classifier.stm_allow_nested_proofs_option_name
~value:false
+(** [process_transaction] adds a node in the document *)
let process_transaction ~doc ?(newtip=Stateid.fresh ())
({ verbose; loc; expr } as x) c =
stm_pperr_endline (fun () -> str "{{{ processing: " ++ pr_ast x);
@@ -2880,18 +2938,21 @@ let process_transaction ~doc ?(newtip=Stateid.fresh ())
try
let head = VCS.current_branch () in
VCS.checkout head;
+ let head_parsing =
+ Option.get @@ VCS.(get_parsing_state (get_branch_pos head)) in
+ let proof_mode = VCS.(get_proof_mode (get_branch_pos head)) in
let rc = begin
stm_prerr_endline (fun () ->
" classified as: " ^ Vernac_classifier.string_of_vernac_classification c);
match c with
(* Meta *)
| VtMeta, _ ->
- let id, w = Backtrack.undo_vernac_classifier expr ~doc in
- process_back_meta_command ~newtip ~head id x w
+ let id = Backtrack.undo_vernac_classifier expr ~doc in
+ process_back_meta_command ~newtip ~head id x
(* Query *)
| VtQuery, w ->
- let id = VCS.new_node ~id:newtip () in
+ let id = VCS.new_node ~id:newtip proof_mode () in
let queue =
if VCS.is_vio_doc () &&
VCS.((get_branch head).kind = `Master) &&
@@ -2899,10 +2960,11 @@ let process_transaction ~doc ?(newtip=Stateid.fresh ())
then `SkipQueue
else `MainQueue in
VCS.commit id (mkTransCmd x [] false queue);
- Backtrack.record (); if w == VtNow then ignore(finish ~doc:dummy_doc); `Ok
+ VCS.set_parsing_state id head_parsing;
+ Backtrack.record (); assert (w == VtLater); `Ok
(* Proof *)
- | VtStartProof (mode, guarantee, names), w ->
+ | VtStartProof (guarantee, names), w ->
if not (get_allow_nested_proofs ()) && VCS.proof_nesting () > 0 then
"Nested proofs are not allowed unless you turn option Nested Proofs Allowed on."
@@ -2912,39 +2974,22 @@ let process_transaction ~doc ?(newtip=Stateid.fresh ())
|> Exninfo.iraise
else
- let id = VCS.new_node ~id:newtip () in
+ let proof_mode = Some (Vernacentries.get_default_proof_mode ()) in
+ let id = VCS.new_node ~id:newtip proof_mode () in
let bname = VCS.mk_branch_name x in
VCS.checkout VCS.Branch.master;
if VCS.Branch.equal head VCS.Branch.master then begin
VCS.commit id (Fork (x, bname, guarantee, names));
- VCS.branch bname (`Proof (mode, VCS.proof_nesting () + 1))
+ VCS.branch bname (`Proof (VCS.proof_nesting () + 1))
end else begin
- VCS.branch bname (`Proof (mode, VCS.proof_nesting () + 1));
+ VCS.branch bname (`Proof (VCS.proof_nesting () + 1));
VCS.merge id ~ours:(Fork (x, bname, guarantee, names)) head
end;
- Proof_global.activate_proof_mode mode [@ocaml.warning "-3"];
- Backtrack.record (); if w == VtNow then ignore(finish ~doc:dummy_doc); `Ok
- | VtProofMode _, VtLater ->
- anomaly(str"VtProofMode must be executed VtNow.")
- | VtProofMode mode, VtNow ->
- let id = VCS.new_node ~id:newtip () in
- VCS.commit id (mkTransCmd x [] false `MainQueue);
- List.iter
- (fun bn -> match VCS.get_branch bn with
- | { VCS.root; kind = `Master; pos } -> ()
- | { VCS.root; kind = `Proof(_,d); pos } ->
- VCS.delete_branch bn;
- VCS.branch ~root ~pos bn (`Proof(mode,d))
- | { VCS.root; kind = `Edit(_,f,q,k,ob); pos } ->
- VCS.delete_branch bn;
- VCS.branch ~root ~pos bn (`Edit(mode,f,q,k,ob)))
- (VCS.branches ());
- VCS.checkout_shallowest_proof_branch ();
- Backtrack.record ();
- ignore(finish ~doc:dummy_doc);
- `Ok
+ VCS.set_parsing_state id head_parsing;
+ Backtrack.record (); assert (w == VtLater); `Ok
+
| VtProofStep { parallel; proof_block_detection = cblock }, w ->
- let id = VCS.new_node ~id:newtip () in
+ let id = VCS.new_node ~id:newtip proof_mode () in
let queue =
match parallel with
| `Yes(solve,abstract) -> `TacQueue (solve, abstract, ref false)
@@ -2954,21 +2999,25 @@ let process_transaction ~doc ?(newtip=Stateid.fresh ())
If/when and UI will make something useful with this piece of info,
detection should occur here.
detect_proof_block id cblock; *)
- Backtrack.record (); if w == VtNow then ignore(finish ~doc:dummy_doc); `Ok
+ VCS.set_parsing_state id head_parsing;
+ Backtrack.record (); assert (w == VtLater); `Ok
+
| VtQed keep, w ->
let valid = VCS.get_branch_pos head in
- let rc = merge_proof_branch ~valid ~id:newtip x keep head in
+ let rc =
+ merge_proof_branch ~valid ~id:newtip x keep head in
VCS.checkout_shallowest_proof_branch ();
- Backtrack.record (); if w == VtNow then ignore(finish ~doc:dummy_doc);
+ Backtrack.record (); assert (w == VtLater);
rc
(* Side effect in a (still open) proof is replayed on all branches*)
| VtSideff l, w ->
- let id = VCS.new_node ~id:newtip () in
- begin match (VCS.get_branch head).VCS.kind with
- | `Edit _ -> VCS.commit id (mkTransCmd x l true `MainQueue);
- | `Master -> VCS.commit id (mkTransCmd x l false `MainQueue);
- | `Proof _ ->
+ let id = VCS.new_node ~id:newtip proof_mode () in
+ let new_ids =
+ match (VCS.get_branch head).VCS.kind with
+ | `Edit _ -> VCS.commit id (mkTransCmd x l true `MainQueue); []
+ | `Master -> VCS.commit id (mkTransCmd x l false `MainQueue); []
+ | `Proof _ ->
VCS.checkout VCS.Branch.master;
VCS.commit id (mkTransCmd x l true `MainQueue);
(* We can't replay a Definition since universes may be differently
@@ -2976,10 +3025,27 @@ let process_transaction ~doc ?(newtip=Stateid.fresh ())
let action = match Vernacprop.under_control x.expr with
| VernacDefinition(_, _, DefineBody _) -> CherryPickEnv
| _ -> ReplayCommand x in
- VCS.propagate_sideff ~action;
- end;
+ VCS.propagate_sideff ~action
+ in
VCS.checkout_shallowest_proof_branch ();
- Backtrack.record (); if w == VtNow then ignore(finish ~doc:dummy_doc); `Ok
+ Backtrack.record ();
+ let parsing_state =
+ begin match w with
+ | VtNow ->
+ (* We need to execute to get the new parsing state *)
+ ignore(finish ~doc:dummy_doc);
+ let parsing = Vernacstate.Parser.cur_state () in
+ (* If execution has not been put in cache, we need to save the parsing state *)
+ if (VCS.get_info id).state == EmptyState then VCS.set_parsing_state id parsing;
+ parsing
+ | VtLater -> VCS.set_parsing_state id head_parsing; head_parsing
+ end
+ in
+ (* We save the parsing state on non-master branches *)
+ List.iter (fun id ->
+ if (VCS.get_info id).state == EmptyState then
+ VCS.set_parsing_state id parsing_state) new_ids;
+ `Ok
(* Unknown: we execute it, check for open goals and propagate sideeff *)
| VtUnknown, VtNow ->
@@ -2991,7 +3057,7 @@ let process_transaction ~doc ?(newtip=Stateid.fresh ())
|> State.exn_on ~valid:Stateid.dummy Stateid.dummy
|> Exninfo.iraise
else
- let id = VCS.new_node ~id:newtip () in
+ let id = VCS.new_node ~id:newtip proof_mode () in
let head_id = VCS.get_branch_pos head in
let _st : unit = Reach.known_state ~doc ~cache:true head_id in (* ensure it is ok *)
let step () =
@@ -3009,9 +3075,8 @@ let process_transaction ~doc ?(newtip=Stateid.fresh ())
| VernacInstance (_,_ , None, _) -> GuaranteesOpacity
| _ -> Doesn'tGuaranteeOpacity in
VCS.commit id (Fork (x,bname,opacity_of_produced_term (Vernacprop.under_control x.expr),[]));
- let proof_mode = default_proof_mode () in
- VCS.branch bname (`Proof (proof_mode, VCS.proof_nesting () + 1));
- Proof_global.activate_proof_mode proof_mode [@ocaml.warning "-3"];
+ VCS.set_proof_mode id (Some (Vernacentries.get_default_proof_mode ()));
+ VCS.branch bname (`Proof (VCS.proof_nesting () + 1));
end else begin
begin match (VCS.get_branch head).VCS.kind with
| `Edit _ -> VCS.commit id (mkTransCmd x [] in_proof `MainQueue);
@@ -3019,7 +3084,7 @@ let process_transaction ~doc ?(newtip=Stateid.fresh ())
| `Proof _ ->
VCS.commit id (mkTransCmd x [] in_proof `MainQueue);
(* We hope it can be replayed, but we can't really know *)
- VCS.propagate_sideff ~action:(ReplayCommand x);
+ ignore(VCS.propagate_sideff ~action:(ReplayCommand x));
end;
VCS.checkout_shallowest_proof_branch ();
end in
@@ -3028,6 +3093,17 @@ let process_transaction ~doc ?(newtip=Stateid.fresh ())
| VtUnknown, VtLater ->
anomaly(str"classifier: VtUnknown must imply VtNow.")
+
+ | VtProofMode pm, VtNow ->
+ let proof_mode = Pvernac.lookup_proof_mode pm in
+ let id = VCS.new_node ~id:newtip proof_mode () in
+ VCS.commit id (mkTransCmd x [] false `MainQueue);
+ VCS.set_parsing_state id head_parsing;
+ Backtrack.record (); `Ok
+
+ | VtProofMode _, VtLater ->
+ anomaly(str"classifier: VtProofMode must imply VtNow.")
+
end in
let pr_rc rc = match rc with
| `Ok -> Pp.(seq [str "newtip ("; str (Stateid.to_string (VCS.cur_tip ())); str ")"])
@@ -3051,45 +3127,10 @@ let get_ast ~doc id =
let stop_worker n = Slaves.cancel_worker n
-(* We must parse on top of a state id, it should be something like:
-
- - get parsing information for that state.
- - feed the parsable / parser with the right parsing information.
- - call the parser
-
- Now, the invariant in ensured by the callers, but this is a bit
- problematic.
-*)
-exception End_of_input
-
-let parse_sentence ~doc sid pa =
- (* XXX: Should this restore the previous state?
- Using reach here to try to really get to the
- proper state makes the error resilience code fail *)
- (* Reach.known_state ~cache:`Yes sid; *)
- let cur_tip = VCS.cur_tip () in
- let real_tip = !State.cur_id in
- if not (Stateid.equal sid cur_tip) then
- user_err ~hdr:"Stm.parse_sentence"
- (str "Currently, the parsing api only supports parsing at the tip of the document." ++ fnl () ++
- str "You wanted to parse at: " ++ str (Stateid.to_string sid) ++
- str " but the current tip is: " ++ str (Stateid.to_string cur_tip)) ;
- if not (Stateid.equal sid real_tip) && !Flags.debug && !stm_debug then
- Feedback.msg_debug
- (str "Warning, the real tip doesn't match the current tip." ++
- str "You wanted to parse at: " ++ str (Stateid.to_string sid) ++
- str " but the real tip is: " ++ str (Stateid.to_string real_tip) ++ fnl () ++
- str "This is usually due to use of Stm.observe to evaluate a state different than the tip. " ++
- str "All is good if not parsing changes occur between the two states, however if they do, a problem might occur.");
- Flags.with_option Flags.we_are_parsing (fun () ->
- try
- match Pcoq.Entry.parse Pvernac.main_entry pa with
- | None -> raise End_of_input
- | Some (loc, cmd) -> CAst.make ~loc cmd
- with e when CErrors.noncritical e ->
- let (e, info) = CErrors.push e in
- Exninfo.iraise (e, info))
- ()
+let parse_sentence ~doc sid ~entry pa =
+ let ps = Option.get @@ VCS.get_parsing_state sid in
+ let proof_mode = VCS.get_proof_mode sid in
+ Vernacstate.Parser.parse ps (entry proof_mode) pa
(* You may need to know the len + indentation of previous command to compute
* the indentation of the current one.
@@ -3153,20 +3194,20 @@ let query ~doc ~at ~route s =
State.purify (fun s ->
if Stateid.equal at Stateid.dummy then ignore(finish ~doc:dummy_doc)
else Reach.known_state ~doc ~cache:true at;
- try
- while true do
- let { CAst.loc; v=ast } = parse_sentence ~doc at s in
- let indentation, strlen = compute_indentation ?loc at in
- let st = State.get_cached at in
- let aast = { verbose = true; indentation; strlen; loc; expr = ast } in
- ignore(stm_vernac_interp ~route at st aast)
- done;
- with
- | End_of_input -> ()
- | exn ->
- let iexn = CErrors.push exn in
- Exninfo.iraise iexn
- )
+ let rec loop () =
+ match parse_sentence ~doc at ~entry:Pvernac.main_entry s with
+ | None -> ()
+ | Some (loc, ast) ->
+ let indentation, strlen = compute_indentation ~loc at in
+ let st = State.get_cached at in
+ let aast = {
+ verbose = true; indentation; strlen;
+ loc = Some loc; expr = ast } in
+ ignore(stm_vernac_interp ~route at st aast);
+ loop ()
+ in
+ loop ()
+ )
s
let edit_at ~doc id =
@@ -3204,21 +3245,21 @@ let edit_at ~doc id =
| { step = `Sideff (ReplayCommand _,id) } -> id
| { step = `Sideff _ } -> tip
| { next } -> master_for_br root next in
- let reopen_branch start at_id mode qed_id tip old_branch =
+ let reopen_branch start at_id qed_id tip old_branch =
let master_id, cancel_switch, keep =
(* Hum, this should be the real start_id in the cluster and not next *)
match VCS.visit qed_id with
| { step = `Qed ({ fproof = Some (_,cs); keep },_) } -> start, cs, keep
| _ -> anomaly (str "ProofTask not ending with Qed.") in
VCS.branch ~root:master_id ~pos:id
- VCS.edit_branch (`Edit (mode, qed_id, master_id, keep, old_branch));
+ VCS.edit_branch (`Edit (qed_id, master_id, keep, old_branch));
VCS.delete_boxes_of id;
cancel_switch := true;
Reach.known_state ~doc ~cache:(VCS.is_interactive ()) id;
VCS.checkout_shallowest_proof_branch ();
`Focus { stop = qed_id; start = master_id; tip } in
let no_edit = function
- | `Edit (pm, _,_,_,_) -> `Proof(pm,1)
+ | `Edit (_,_,_,_) -> `Proof 1
| x -> x in
let backto id bn =
List.iter VCS.delete_branch (VCS.branches ());
@@ -3244,17 +3285,17 @@ let edit_at ~doc id =
let focused = List.exists ((=) VCS.edit_branch) (VCS.branches ()) in
let branch_info =
match snd (VCS.get_info id).vcs_backup with
- | Some{ mine = bn, { VCS.kind = `Proof(m,_) }} -> Some(m,bn)
- | Some{ mine = _, { VCS.kind = `Edit(m,_,_,_,bn) }} -> Some (m,bn)
+ | Some{ mine = bn, { VCS.kind = `Proof _ }} -> Some bn
+ | Some{ mine = _, { VCS.kind = `Edit(_,_,_,bn) }} -> Some bn
| _ -> None in
match focused, VCS.proof_task_box_of id, branch_info with
| _, Some _, None -> assert false
- | false, Some { qed = qed_id ; lemma = start }, Some(mode,bn) ->
+ | false, Some { qed = qed_id ; lemma = start }, Some bn ->
let tip = VCS.cur_tip () in
if has_failed qed_id && is_pure qed_id && not !cur_opt.async_proofs_never_reopen_branch
- then reopen_branch start id mode qed_id tip bn
+ then reopen_branch start id qed_id tip bn
else backto id (Some bn)
- | true, Some { qed = qed_id }, Some(mode,bn) ->
+ | true, Some { qed = qed_id }, Some bn ->
if on_cur_branch id then begin
assert false
end else if is_ancestor_of_cur_branch id then begin
@@ -3273,7 +3314,7 @@ let edit_at ~doc id =
end else begin
anomaly(str"Cannot leave an `Edit branch open.")
end
- | false, None, Some(_,bn) -> backto id (Some bn)
+ | false, None, Some bn -> backto id (Some bn)
| false, None, None -> backto id None
in
VCS.print ();
diff --git a/stm/stm.mli b/stm/stm.mli
index b6071fa56b..821ab59a43 100644
--- a/stm/stm.mli
+++ b/stm/stm.mli
@@ -93,16 +93,17 @@ val init_core : unit -> unit
(** [new_doc opt] Creates a new document with options [opt] *)
val new_doc : stm_init_options -> doc * Stateid.t
-(** [parse_sentence sid pa] Reads a sentence from [pa] with parsing
- state [sid] Returns [End_of_input] if the stream ends *)
-val parse_sentence : doc:doc -> Stateid.t -> Pcoq.Parsable.t ->
- Vernacexpr.vernac_control CAst.t
+(** [parse_sentence sid entry pa] Reads a sentence from [pa] with parsing state
+ [sid] and non terminal [entry]. [entry] receives in input the current proof
+ mode. [sid] should be associated with a valid parsing state (which may not
+ be the case if an error was raised at parsing time). *)
+val parse_sentence :
+ doc:doc -> Stateid.t ->
+ entry:(Pvernac.proof_mode option -> 'a Pcoq.Entry.t) -> Pcoq.Parsable.t -> 'a
(* Reminder: A parsable [pa] is constructed using
[Pcoq.Parsable.t stream], where [stream : char Stream.t]. *)
-exception End_of_input
-
(* [add ~ontop ?newtip verbose cmd] adds a new command [cmd] ontop of
the state [ontop].
The [ontop] parameter just asserts that the GUI is on
diff --git a/stm/vernac_classifier.ml b/stm/vernac_classifier.ml
index 09f531ce13..292e3966a1 100644
--- a/stm/vernac_classifier.ml
+++ b/stm/vernac_classifier.ml
@@ -15,8 +15,6 @@ open CAst
open Vernacextend
open Vernacexpr
-let default_proof_mode () = Proof_global.get_default_proof_mode_name () [@ocaml.warning "-3"]
-
let string_of_parallel = function
| `Yes (solve,abs) ->
"par" ^ if solve then "solve" else "" ^ if abs then "abs" else ""
@@ -32,9 +30,9 @@ let string_of_vernac_type = function
| VtProofStep { parallel; proof_block_detection } ->
"ProofStep " ^ string_of_parallel parallel ^
Option.default "" proof_block_detection
- | VtProofMode s -> "ProofMode " ^ s
| VtQuery -> "Query"
| VtMeta -> "Meta "
+ | VtProofMode _ -> "Proof Mode"
let string_of_vernac_when = function
| VtLater -> "Later"
@@ -57,7 +55,7 @@ let stm_allow_nested_proofs_option_name = ["Nested";"Proofs";"Allowed"]
let options_affecting_stm_scheduling =
[ Attributes.universe_polymorphism_option_name;
stm_allow_nested_proofs_option_name;
- Proof_global.proof_mode_opt_name;
+ Vernacentries.proof_mode_opt_name;
]
let classify_vernac e =
@@ -97,15 +95,15 @@ let classify_vernac e =
| VernacSetOption (_, ["Default";"Proof";"Using"],_) -> VtSideff [], VtNow
(* StartProof *)
| VernacDefinition ((Decl_kinds.DoDischarge,_),({v=i},_),ProveBody _) ->
- VtStartProof(default_proof_mode (),Doesn'tGuaranteeOpacity, idents_of_name i), VtLater
+ VtStartProof(Doesn'tGuaranteeOpacity, idents_of_name i), VtLater
| VernacDefinition (_,({v=i},_),ProveBody _) ->
let guarantee = if poly then Doesn'tGuaranteeOpacity else GuaranteesOpacity in
- VtStartProof(default_proof_mode (),guarantee, idents_of_name i), VtLater
+ VtStartProof(guarantee, idents_of_name i), VtLater
| VernacStartTheoremProof (_,l) ->
let ids = List.map (fun (({v=i}, _), _) -> i) l in
let guarantee = if poly then Doesn'tGuaranteeOpacity else GuaranteesOpacity in
- VtStartProof (default_proof_mode (),guarantee,ids), VtLater
+ VtStartProof (guarantee,ids), VtLater
| VernacFixpoint (discharge,l) ->
let guarantee =
if discharge = Decl_kinds.DoDischarge || poly then Doesn'tGuaranteeOpacity
@@ -115,7 +113,7 @@ let classify_vernac e =
List.fold_left (fun (l,b) ((({v=id},_),_,_,_,p),_) ->
id::l, b || p = None) ([],false) l in
if open_proof
- then VtStartProof (default_proof_mode (),guarantee,ids), VtLater
+ then VtStartProof (guarantee,ids), VtLater
else VtSideff ids, VtLater
| VernacCoFixpoint (discharge,l) ->
let guarantee =
@@ -126,7 +124,7 @@ let classify_vernac e =
List.fold_left (fun (l,b) ((({v=id},_),_,_,p),_) ->
id::l, b || p = None) ([],false) l in
if open_proof
- then VtStartProof (default_proof_mode (),guarantee,ids), VtLater
+ then VtStartProof (guarantee,ids), VtLater
else VtSideff ids, VtLater
(* Sideff: apply to all open branches. usually run on master only *)
| VernacAssumption (_,_,l) ->
@@ -163,7 +161,6 @@ let classify_vernac e =
| VernacExistingClass _ | VernacExistingInstance _
| VernacRegister _
| VernacNameSectionHypSet _
- | VernacDeclareCustomEntry _
| VernacComments _
| VernacDeclareInstance _ -> VtSideff [], VtLater
(* Who knows *)
@@ -177,6 +174,7 @@ let classify_vernac e =
| VernacDeclareModuleType ({v=id},bl,_,_) ->
VtSideff [id], if bl = [] then VtLater else VtNow
(* These commands alter the parser *)
+ | VernacDeclareCustomEntry _
| VernacOpenCloseScope _ | VernacDeclareScope _
| VernacDelimiters _ | VernacBindScope _
| VernacInfix _ | VernacNotation _ | VernacNotationAddFormat _
@@ -184,8 +182,8 @@ let classify_vernac e =
| VernacSyntacticDefinition _
| VernacRequire _ | VernacImport _ | VernacInclude _
| VernacDeclareMLModule _
- | VernacContext _ (* TASSI: unsure *)
- | VernacProofMode _ -> VtSideff [], VtNow
+ | VernacContext _ (* TASSI: unsure *) -> VtSideff [], VtNow
+ | VernacProofMode pm -> VtProofMode pm, VtNow
(* These are ambiguous *)
| VernacInstance _ -> VtUnknown, VtNow
(* Stm will install a new classifier to handle these *)
@@ -211,10 +209,10 @@ let classify_vernac e =
| VernacFail e -> (* Fail Qed or Fail Lemma must not join/fork the DAG *)
(match static_control_classifier e with
| ( VtQuery | VtProofStep _ | VtSideff _
- | VtProofMode _ | VtMeta), _ as x -> x
+ | VtMeta), _ as x -> x
| VtQed _, _ ->
VtProofStep { parallel = `No; proof_block_detection = None },
- VtNow
- | (VtStartProof _ | VtUnknown), _ -> VtQuery, VtLater)
+ VtLater
+ | (VtStartProof _ | VtUnknown | VtProofMode _), _ -> VtQuery, VtLater)
in
static_control_classifier e
diff --git a/test-suite/Makefile b/test-suite/Makefile
index 37091a49e5..111bd52a33 100644
--- a/test-suite/Makefile
+++ b/test-suite/Makefile
@@ -38,14 +38,15 @@ LIB := ..
BIN := $(shell cd ..; pwd)/bin/
COQFLAGS?=
-coqtop := $(BIN)coqtop -coqlib $(LIB) -boot -q -batch -test-mode -R prerequisite TestSuite $(COQFLAGS)
+coqc_boot := $(BIN)coqc -coqlib $(LIB) -boot -q -test-mode -R prerequisite TestSuite $(COQFLAGS)
coqc := $(BIN)coqc -coqlib $(LIB) -R prerequisite TestSuite $(COQFLAGS)
coqchk := $(BIN)coqchk -coqlib $(LIB) -R prerequisite TestSuite
coqdoc := $(BIN)coqdoc
+coqtop := $(BIN)coqtop -batch -coqlib $(LIB) -boot -q -test-mode -R prerequisite TestSuite
coqtopbyte := $(BIN)coqtop.byte
-coqtopload := $(coqtop) -async-proofs-cache force -load-vernac-source
-coqtopcompile := $(coqtop) -async-proofs-cache force -compile
+coqc_interactive := $(coqc) -async-proofs-cache force
+coqc_boot_interactive := $(coqc_boot) -async-proofs-cache force
coqdep := $(BIN)coqdep -coqlib $(LIB)
VERBOSE?=
@@ -60,12 +61,8 @@ SINGLE_QUOTE="
#" # double up on the quotes, in a comment, to appease the emacs syntax highlighter
# wrap the arguments in parens, but only if they exist
get_coq_prog_args_in_parens = $(subst $(SINGLE_QUOTE),,$(if $(call get_coq_prog_args,$(1)), ($(call get_coq_prog_args,$(1)))))
-# get the command to use with this set of arguments; if there's -compile, use coqc, else use coqtop
-has_profile_ltac_or_compile_flag = $(filter "-profile-ltac-cutoff" "-profile-ltac" "-compile",$(call get_coq_prog_args,$(1)))
-get_command_based_on_flags = $(if $(call has_profile_ltac_or_compile_flag,$(1)),$(coqtopcompile),$(coqtopload))
get_set_impredicativity= $(filter "-impredicative-set",$(call get_coq_prog_args,$(1)))
-
bogomips:=
ifneq (,$(wildcard /proc/cpuinfo))
sedbogo := -e "s/bogomips.*: \([0-9]*\).*/\1/p" # i386, ppc
@@ -209,7 +206,7 @@ $(addsuffix .log,$(wildcard bugs/opened/*.v)): %.v.log: %.v
@echo "TEST $< $(call get_coq_prog_args_in_parens,"$<")"
$(HIDE){ \
echo $(call log_intro,$<); \
- $(coqtopcompile) "$<" $(call get_coq_prog_args,"$<") 2>&1; R=$$?; times; \
+ $(coqc) "$<" $(call get_coq_prog_args,"$<") 2>&1; R=$$?; times; \
if [ $$R = 0 ]; then \
echo $(log_success); \
echo " $<...still active"; \
@@ -231,7 +228,7 @@ $(addsuffix .log,$(wildcard bugs/closed/*.v)): %.v.log: %.v
@echo "TEST $< $(call get_coq_prog_args_in_parens,"$<")"
$(HIDE){ \
echo $(call log_intro,$<); \
- $(coqtopcompile) "$<" $(call get_coq_prog_args,"$<") 2>&1; R=$$?; times; \
+ $(coqc) "$<" $(call get_coq_prog_args,"$<") 2>&1; R=$$?; times; \
if [ $$R = 0 ]; then \
echo $(log_success); \
echo " $<...Ok"; \
@@ -297,7 +294,7 @@ $(addsuffix .log,$(wildcard prerequisite/*.v)): %.v.log: %.v
@echo "TEST $< $(call get_coq_prog_args_in_parens,"$<")"
$(HIDE){ \
echo $(call log_intro,$<); \
- $(coqtopcompile) "$<" $(call get_coq_prog_args,"$<") 2>&1; R=$$?; times; \
+ $(coqc) "$<" $(call get_coq_prog_args,"$<") 2>&1; R=$$?; times; \
if [ $$R != 0 ]; then \
echo $(log_failure); \
echo " $<...could not be prepared" ; \
@@ -316,7 +313,7 @@ $(addsuffix .log,$(wildcard ssr/*.v success/*.v micromega/*.v modules/*.v)): %.v
$(HIDE){ \
opts="$(if $(findstring modules/,$<),-R modules Mods)"; \
echo $(call log_intro,$<); \
- $(coqtopcompile) "$<" $(call get_coq_prog_args,"$<") $$opts 2>&1; R=$$?; times; \
+ $(coqc) "$<" $(call get_coq_prog_args,"$<") $$opts 2>&1; R=$$?; times; \
if [ $$R = 0 ]; then \
echo $(log_success); \
echo " $<...Ok"; \
@@ -342,7 +339,7 @@ $(addsuffix .log,$(wildcard stm/*.v)): %.v.log: %.v
@echo "TEST $< $(call get_coq_prog_args_in_parens,"$<")"
$(HIDE){ \
echo $(call log_intro,$<); \
- $(coqtopcompile) "$<" $(call get_coq_prog_args,"$<") -async-proofs on \
+ $(coqc) "$<" $(call get_coq_prog_args,"$<") -async-proofs on \
$$opts 2>&1; R=$$?; times; \
if [ $$R = 0 ]; then \
echo $(log_success); \
@@ -367,7 +364,7 @@ $(addsuffix .log,$(wildcard failure/*.v)): %.v.log: %.v $(PREREQUISITELOG)
@echo "TEST $< $(call get_coq_prog_args_in_parens,"$<")"
$(HIDE){ \
echo $(call log_intro,$<); \
- $(coqtopcompile) "$<" $(call get_coq_prog_args,"$<") 2>&1; R=$$?; times; \
+ $(coqc) "$<" $(call get_coq_prog_args,"$<") 2>&1; R=$$?; times; \
if [ $$R = 0 ]; then \
echo $(log_success); \
echo " $<...Ok"; \
@@ -392,7 +389,7 @@ $(addsuffix .log,$(wildcard output/*.v)): %.v.log: %.v %.out $(PREREQUISITELOG)
$(HIDE){ \
echo $(call log_intro,$<); \
output=$*.out.real; \
- $(call get_command_based_on_flags,"$<") "$<" $(call get_coq_prog_args,"$<") 2>&1 \
+ $(coqc_boot_interactive) "$<" $(call get_coq_prog_args,"$<") 2>&1 \
| grep -v "Welcome to Coq" \
| grep -v "\[Loading ML file" \
| grep -v "Skipping rcfile loading" \
@@ -431,7 +428,7 @@ $(addsuffix .log,$(wildcard output-modulo-time/*.v)): %.v.log: %.v %.out
echo $(call log_intro,$<); \
tmpoutput=`mktemp /tmp/coqcheck.XXXXXX`; \
tmpexpected=`mktemp /tmp/coqcheck.XXXXXX`; \
- $(call get_command_based_on_flags,"$<") "$<" $(call get_coq_prog_args,"$<") 2>&1 \
+ $(coqc_boot_interactive) "$<" $(call get_coq_prog_args,"$<") 2>&1 \
| grep -v "Welcome to Coq" \
| grep -v "\[Loading ML file" \
| grep -v "Skipping rcfile loading" \
@@ -486,7 +483,7 @@ $(addsuffix .log,$(wildcard complexity/*.v)): %.v.log: %.v $(PREREQUISITELOG)
$(HIDE){ \
echo $(call log_intro,$<); \
true "extract effective user time"; \
- res=`$(call get_command_based_on_flags,"$<") "$<" $(call get_coq_prog_args,"$<") 2>&1 | sed -n -e "s/Finished transaction in .*(\([0-9]*\.[0-9]*\)u.*)/\1/p" | head -1`; \
+ res=`$(coqc_boot_interactive) "$<" $(call get_coq_prog_args,"$<") 2>&1 | sed -n -e "s/Finished transaction in .*(\([0-9]*\.[0-9]*\)u.*)/\1/p" | head -1`; \
R=$$?; times; \
if [ $$R != 0 ]; then \
echo $(log_failure); \
@@ -517,7 +514,7 @@ $(addsuffix .log,$(wildcard ideal-features/*.v)): %.v.log: %.v $(PREREQUISITELOG
@echo "TEST $< $(call get_coq_prog_args_in_parens,"$<")"
$(HIDE){ \
echo $(call log_intro,$<); \
- $(coqtopcompile) "$<" $(call get_coq_prog_args,"$<") 2>&1; R=$$?; times; \
+ $(coqc) "$<" $(call get_coq_prog_args,"$<") 2>&1; R=$$?; times; \
if [ $$R != 0 ]; then \
echo $(log_success); \
echo " $<...still wished"; \
@@ -531,7 +528,7 @@ $(addsuffix .log,$(wildcard ideal-features/*.v)): %.v.log: %.v $(PREREQUISITELOG
# Additional dependencies for module tests
$(addsuffix .log,$(wildcard modules/*.v)): %.v.log: modules/Nat.vo modules/plik.vo
modules/%.vo: modules/%.v
- $(HIDE)$(coqtop) -R modules Mods -compile $<
+ $(HIDE)$(coqc) -R modules Mods $<
#######################################################################
# Miscellaneous tests
@@ -550,7 +547,7 @@ $(patsubst %.sh,%.log,$(wildcard misc/*.sh)): %.log: %.sh $(PREREQUISITELOG)
echo $(call log_intro,$<); \
export BIN="$(BIN)"; \
export coqc="$(coqc)"; \
- export coqtop="$(coqtop)"; \
+ export coqtop="$(coqc_boot)"; \
export coqdep="$(coqdep)"; \
export coqtopbyte="$(coqtopbyte)"; \
"$<" 2>&1; R=$$?; times; \
@@ -591,7 +588,7 @@ vio: $(patsubst %.v,%.vio.log,$(wildcard vio/*.v))
@echo "TEST $<"
$(HIDE){ \
$(coqc) -quick -R vio vio $* 2>&1 && \
- $(coqtop) -R vio vio -vio2vo $*.vio 2>&1 && \
+ $(coqc) -R vio vio -vio2vo $*.vio 2>&1 && \
$(coqchk) -R vio vio -norec $(subst /,.,$*) 2>&1; \
if [ $$? = 0 ]; then \
echo $(log_success); \
diff --git a/test-suite/bugs/closed/HoTT_coq_056.v b/test-suite/bugs/closed/HoTT_coq_056.v
index 3e3a987a7c..b80e0bb0e4 100644
--- a/test-suite/bugs/closed/HoTT_coq_056.v
+++ b/test-suite/bugs/closed/HoTT_coq_056.v
@@ -94,9 +94,9 @@ Definition FunctorApplicationOf {C D} F {argsT} args {T} {rtn}
Global Arguments FunctorApplicationOf / {C} {D} F {argsT} args {T} {rtn} {_}.
Global Instance FunctorApplicationDash C D (F : Functor C D)
-: FunctorApplicationInterpretable F (IdentityFunctor C) F | 0.
+: FunctorApplicationInterpretable F (IdentityFunctor C) F | 0 := {}.
Global Instance FunctorApplicationFunctorFunctor' A B C C' D (F : Functor (A * B) D) (G : Functor C A) (H : Functor C' B)
-: FunctorApplicationInterpretable F (G, H) (F ∘ (FunctorProduct' G H))%functor | 100.
+: FunctorApplicationInterpretable F (G, H) (F ∘ (FunctorProduct' G H))%functor | 100 := {}.
Notation "F ⟨ x ⟩" := (FunctorApplicationOf F%functor x%functor) : functor_scope.
diff --git a/test-suite/bugs/closed/bug_3324.v b/test-suite/bugs/closed/bug_3324.v
index 45dbb57aa2..dae0d4c024 100644
--- a/test-suite/bugs/closed/bug_3324.v
+++ b/test-suite/bugs/closed/bug_3324.v
@@ -6,7 +6,7 @@ Module ETassi.
Record hProp := hp { hproptype :> Type ; isp : IsHProp hproptype}.
Record hSet := BuildhSet {setT:> Type; iss :> IsHSet setT}.
Canonical Structure default_HSet:= fun T P => (@BuildhSet T P).
- Global Instance isset_hProp : IsHSet hProp | 0.
+ Global Instance isset_hProp : IsHSet hProp | 0 := {}.
Check (eq_refl _ : setT (default_HSet _ _) = hProp).
Check (eq_refl _ : setT _ = hProp).
@@ -22,7 +22,7 @@ Module JGross.
Definition Unit_hp:hProp:=(hp Unit admit).
Record hSet := BuildhSet {setT:> Type; iss :> IsHSet setT}.
Canonical Structure default_HSet:= fun T P => (@BuildhSet T P).
- Global Instance isset_hProp : IsHSet hProp | 0.
+ Global Instance isset_hProp : IsHSet hProp | 0 := {}.
Definition isepi {X Y} `(f:X->Y) := forall Z: hSet,
forall g h: Y -> Z, (fun x => g (f x)) = (fun x => h (f x)) -> g = h.
Lemma isepi_issurj {X Y} (f:X->Y): isepi f -> True.
diff --git a/test-suite/bugs/closed/bug_3454.v b/test-suite/bugs/closed/bug_3454.v
index e4cd60cb24..0a01adec33 100644
--- a/test-suite/bugs/closed/bug_3454.v
+++ b/test-suite/bugs/closed/bug_3454.v
@@ -32,14 +32,14 @@ Local Instance isequiv_tgt_compose A B
: @IsEquiv (A -> {xy : B * B & fst xy = snd xy})
(A -> B)
(@compose A {xy : B * B & fst xy = snd xy} B
- (@compose {xy : B * B & fst xy = snd xy} _ B (@snd B B) pr1)).
+ (@compose {xy : B * B & fst xy = snd xy} _ B (@snd B B) pr1)) := {}.
(* Toplevel input, characters 220-223: *)
(* Error: Cannot infer this placeholder. *)
Local Instance isequiv_tgt_compose' A B
: @IsEquiv (A -> {xy : B * B & fst xy = snd xy})
(A -> B)
- (@compose A {xy : B * B & fst xy = snd xy} B (@compose {xy : B * B & fst xy = snd xy} _ B (@snd _ _) pr1)).
+ (@compose A {xy : B * B & fst xy = snd xy} B (@compose {xy : B * B & fst xy = snd xy} _ B (@snd _ _) pr1)) := {}.
(* Toplevel input, characters 221-232: *)
(* Error: *)
(* In environment *)
@@ -52,7 +52,7 @@ Local Instance isequiv_tgt_compose'' A B
: @IsEquiv (A -> {xy : B * B & fst xy = snd xy})
(A -> B)
(@compose A {xy : B * B & fst xy = snd xy} B (@compose {xy : B * B & fst xy = snd xy} _ B (@snd _ _)
- (fun s => s.(projT1)))).
+ (fun s => s.(projT1)))) := {}.
(* Toplevel input, characters 15-241:
Error:
Cannot infer an internal placeholder of type "Type" in environment:
diff --git a/test-suite/bugs/closed/bug_3682.v b/test-suite/bugs/closed/bug_3682.v
index 9d37d1a2d0..07b759afb5 100644
--- a/test-suite/bugs/closed/bug_3682.v
+++ b/test-suite/bugs/closed/bug_3682.v
@@ -1,6 +1,6 @@
Require Import TestSuite.admit.
Class Foo.
Definition bar `{Foo} (x : Set) := Set.
-Instance: Foo.
+Instance: Foo := {}.
Definition bar1 := bar nat.
Definition bar2 := bar ltac:(admit).
diff --git a/test-suite/bugs/closed/bug_4782.v b/test-suite/bugs/closed/bug_4782.v
index be17a96f15..c08195d502 100644
--- a/test-suite/bugs/closed/bug_4782.v
+++ b/test-suite/bugs/closed/bug_4782.v
@@ -15,8 +15,8 @@ Record T := { dom : Type }.
Definition pairT A B := {| dom := (dom A * dom B)%type |}.
Class C (A:Type).
Parameter B:T.
-Instance c (A:T) : C (dom A).
-Instance cn : C (dom B).
+Instance c (A:T) : C (dom A) := {}.
+Instance cn : C (dom B) := {}.
Parameter F : forall A:T, C (dom A) -> forall x:dom A, x=x -> A = A.
Set Typeclasses Debug.
Goal forall (A:T) (x:dom A), pairT A A = pairT A A.
diff --git a/test-suite/bugs/closed/bug_4798.v b/test-suite/bugs/closed/bug_4798.v
index 41a1251ca5..696812dee1 100644
--- a/test-suite/bugs/closed/bug_4798.v
+++ b/test-suite/bugs/closed/bug_4798.v
@@ -1,3 +1,5 @@
+(* DO NOT MODIFY THIS FILE DIRECTLY *)
+(* It is autogenerated by dev/tools/update-compat.py. *)
Check match 2 with 0 => 0 | S n => n end.
Notation "|" := 1 (compat "8.7").
Check match 2 with 0 => 0 | S n => n end. (* fails *)
diff --git a/test-suite/bugs/closed/bug_4836.v b/test-suite/bugs/closed/bug_4836.v
index 5838dcd8a7..9aefb10172 100644
--- a/test-suite/bugs/closed/bug_4836.v
+++ b/test-suite/bugs/closed/bug_4836.v
@@ -1 +1 @@
-(* -*- coq-prog-args: ("-compile" "bugs/closed/PLACEHOLDER.v") -*- *)
+(* -*- coq-prog-args: ("bugs/closed/PLACEHOLDER.v") -*- *)
diff --git a/test-suite/bugs/closed/bug_5401.v b/test-suite/bugs/closed/bug_5401.v
index 95193b993b..466e669d00 100644
--- a/test-suite/bugs/closed/bug_5401.v
+++ b/test-suite/bugs/closed/bug_5401.v
@@ -5,7 +5,7 @@ Parameter P : nat -> Type.
Parameter v : forall m, P m.
Parameter f : forall (P : nat -> Type), (forall a, P a) -> P 0.
Class U (R : P 0) (m : forall x, P x) : Prop.
-Instance w : U (f _ (fun _ => v _)) v.
+Instance w : U (f _ (fun _ => v _)) v := {}.
Print HintDb typeclass_instances.
End A.
diff --git a/test-suite/bugs/closed/bug_7811.v b/test-suite/bugs/closed/bug_7811.v
index fee330f22d..155f3285b7 100644
--- a/test-suite/bugs/closed/bug_7811.v
+++ b/test-suite/bugs/closed/bug_7811.v
@@ -1,4 +1,4 @@
-(* -*- mode: coq; coq-prog-args: ("-emacs" "-top" "atomic" "-Q" "." "iris" "-R" "." "stdpp") -*- *)
+(* -*- mode: coq; coq-prog-args: ("-top" "atomic" "-Q" "." "iris" "-R" "." "stdpp") -*- *)
(* File reduced by coq-bug-finder from original input, then from 140 lines to 26 lines, then from 141 lines to 27 lines, then from 142 lines to 27 lines, then from 272 lines to 61 lines, then from 291 lines to 94 lines, then from 678 lines to 142 lines, then from 418 lines to 161 lines, then from 538 lines to 189 lines, then from 840 lines to 493 lines, then from 751 lines to 567 lines, then from 913 lines to 649 lines, then from 875 lines to 666 lines, then from 784 lines to 568 lines, then from 655 lines to 173 lines, then from 317 lines to 94 lines, then from 172 lines to 86 lines, then from 102 lines to 86 lines, then from 130 lines to 86 lines, then from 332 lines to 112 lines, then from 279 lines to 111 lines, then from 3996 lines to 5697 lines, then from 153 lines to 117 lines, then from 146 lines to 108 lines, then from 124 lines to 108 lines *)
(* coqc version 8.8.0 (May 2018) compiled on May 2 2018 16:49:46 with OCaml 4.02.3
coqtop version 8.8.0 (May 2018) *)
diff --git a/test-suite/bugs/closed/bug_9166.v b/test-suite/bugs/closed/bug_9166.v
index 8a7e9c37b0..a89837dd12 100644
--- a/test-suite/bugs/closed/bug_9166.v
+++ b/test-suite/bugs/closed/bug_9166.v
@@ -1,3 +1,5 @@
+(* DO NOT MODIFY THIS FILE DIRECTLY *)
+(* It is autogenerated by dev/tools/update-compat.py. *)
Set Warnings "+deprecated".
Notation bar := option (compat "8.7").
diff --git a/test-suite/complexity/constructor.v b/test-suite/complexity/constructor.v
index c5e1953829..31217ca75e 100644
--- a/test-suite/complexity/constructor.v
+++ b/test-suite/complexity/constructor.v
@@ -214,3 +214,4 @@ Fixpoint expand (n : nat) : Prop :=
Example Expand : expand 2500.
Time constructor. (* ~0.45 secs *)
+Qed.
diff --git a/test-suite/complexity/f_equal.v b/test-suite/complexity/f_equal.v
index 86698fa872..c2c566930b 100644
--- a/test-suite/complexity/f_equal.v
+++ b/test-suite/complexity/f_equal.v
@@ -12,3 +12,4 @@ end.
Goal stupid 23 = stupid 23.
Timeout 5 Time f_equal.
+Abort.
diff --git a/test-suite/complexity/injection.v b/test-suite/complexity/injection.v
index a76fa19d3c..298a07c1c4 100644
--- a/test-suite/complexity/injection.v
+++ b/test-suite/complexity/injection.v
@@ -111,3 +111,4 @@ Lemma test: forall n1 w1 n2 w2, mk_world n1 w1 = mk_world n2 w2 ->
Proof.
intros.
Timeout 10 Time injection H.
+Abort.
diff --git a/test-suite/complexity/ring.v b/test-suite/complexity/ring.v
index 51f7c4dabc..2d585ce5c5 100644
--- a/test-suite/complexity/ring.v
+++ b/test-suite/complexity/ring.v
@@ -5,3 +5,4 @@ Require Import ZArith.
Open Scope Z_scope.
Goal forall a, a+a+a+a+a+a+a+a+a+a+a+a+a = a*13.
Timeout 5 Time intro; ring.
+Abort.
diff --git a/test-suite/complexity/ring2.v b/test-suite/complexity/ring2.v
index 04fa59075b..1c119b8e42 100644
--- a/test-suite/complexity/ring2.v
+++ b/test-suite/complexity/ring2.v
@@ -50,3 +50,4 @@ Infix "+" := Zadd : Z_scope.
Goal forall a, a+a+a+a+a+a+a+a+a+a+a+a+a = a*13.
Timeout 5 Time intro; ring.
+Abort.
diff --git a/test-suite/complexity/setoid_rewrite.v b/test-suite/complexity/setoid_rewrite.v
index 2e3b006ef0..10b270ccad 100644
--- a/test-suite/complexity/setoid_rewrite.v
+++ b/test-suite/complexity/setoid_rewrite.v
@@ -8,3 +8,4 @@ Variable f : nat -> Prop.
Goal forall U:Prop, f 100 <-> U.
intros U.
Timeout 5 Time setoid_replace U with False.
+Abort.
diff --git a/test-suite/complexity/unification.v b/test-suite/complexity/unification.v
index d2ea527516..0c9915c84e 100644
--- a/test-suite/complexity/unification.v
+++ b/test-suite/complexity/unification.v
@@ -49,3 +49,4 @@ Goal
))))
.
Timeout 2 Time try refine (refl_equal _).
+Abort.
diff --git a/test-suite/ide/debug_ltac.fake b/test-suite/ide/debug_ltac.fake
new file mode 100644
index 0000000000..aa68fad39e
--- /dev/null
+++ b/test-suite/ide/debug_ltac.fake
@@ -0,0 +1,2 @@
+FAILADD { Debug On. }
+ADD { Set Debug On. }
diff --git a/test-suite/misc/4722.sh b/test-suite/misc/4722.sh
index 86bc50b5cd..70071b9d60 100755
--- a/test-suite/misc/4722.sh
+++ b/test-suite/misc/4722.sh
@@ -4,12 +4,12 @@ set -e
# create test files
mkdir -p misc/4722
ln -sf toto misc/4722/tata
-touch misc/4722.v
+touch misc/bug_4722.v
# run test
-$coqtop "-R" "misc/4722" "Foo" -top Top -load-vernac-source misc/4722.v
+$coqc "-R" "misc/4722" "Foo" -top Top misc/bug_4722.v
# clean up test files
rm misc/4722/tata
rmdir misc/4722
-rm misc/4722.v
+rm misc/bug_4722.v
diff --git a/test-suite/misc/7704.sh b/test-suite/misc/7704.sh
index 0ca2c97d24..5fc171649e 100755
--- a/test-suite/misc/7704.sh
+++ b/test-suite/misc/7704.sh
@@ -4,4 +4,4 @@ set -e
export PATH=$BIN:$PATH
-${coqtop#"$BIN"} -compile misc/aux7704.v
+${coqc#"$BIN"} misc/aux7704.v
diff --git a/test-suite/misc/aux7704.v b/test-suite/misc/aux7704.v
index 6fdcf67684..1c95211a71 100644
--- a/test-suite/misc/aux7704.v
+++ b/test-suite/misc/aux7704.v
@@ -1,4 +1,3 @@
-
Goal True /\ True.
Proof.
split.
diff --git a/test-suite/misc/deps-checksum.sh b/test-suite/misc/deps-checksum.sh
index a15a8fbee9..8523358303 100755
--- a/test-suite/misc/deps-checksum.sh
+++ b/test-suite/misc/deps-checksum.sh
@@ -3,4 +3,4 @@ rm -f misc/deps/A/*.vo misc/deps/B/*.vo
$coqc -R misc/deps/A A misc/deps/A/A.v
$coqc -R misc/deps/B A misc/deps/B/A.v
$coqc -R misc/deps/B A misc/deps/B/B.v
-$coqtop -R misc/deps/B A -R misc/deps/A A -load-vernac-source misc/deps/checksum.v
+$coqc -R misc/deps/B A -R misc/deps/A A misc/deps/checksum.v
diff --git a/test-suite/misc/deps-order.sh b/test-suite/misc/deps-order.sh
index 6bb2ba2da0..551515b0d6 100755
--- a/test-suite/misc/deps-order.sh
+++ b/test-suite/misc/deps-order.sh
@@ -10,12 +10,12 @@ R=$?
times
$coqc -R misc/deps/lib lib misc/deps/lib/foo.v 2>&1
$coqc -R misc/deps/lib lib -R misc/deps/client client misc/deps/client/foo.v 2>&1
-$coqtop -R misc/deps/lib lib -R misc/deps/client client -load-vernac-source misc/deps/client/bar.v 2>&1
+$coqc -R misc/deps/lib lib -R misc/deps/client client misc/deps/client/bar.v 2>&1
S=$?
if [ $R = 0 ] && [ $S = 0 ]; then
- printf "coqdep and coqtop agree\n"
+ printf "coqdep and coqc agree\n"
exit 0
else
- printf "coqdep and coqtop disagree\n"
+ printf "coqdep and coqc disagree\n"
exit 1
fi
diff --git a/test-suite/misc/deps-utf8.sh b/test-suite/misc/deps-utf8.sh
index acb45b2292..af69370ce4 100755
--- a/test-suite/misc/deps-utf8.sh
+++ b/test-suite/misc/deps-utf8.sh
@@ -8,7 +8,7 @@ rm -f misc/deps/théorèmes/*.v
tmpoutput=$(mktemp /tmp/coqcheck.XXXXXX)
$coqc -R misc/deps AlphaBêta misc/deps/αβ/γδ.v
R=$?
-$coqtop -R misc/deps AlphaBêta -load-vernac-source misc/deps/αβ/εζ.v
+$coqc -R misc/deps AlphaBêta misc/deps/αβ/εζ.v
S=$?
if [ $R = 0 ] && [ $S = 0 ]; then
exit 0
diff --git a/test-suite/output/Arguments_renaming.out b/test-suite/output/Arguments_renaming.out
index 583ea0cb43..ba4bc070c6 100644
--- a/test-suite/output/Arguments_renaming.out
+++ b/test-suite/output/Arguments_renaming.out
@@ -52,7 +52,6 @@ fix myplus (T : Type) (t : T) (n m : nat) {struct n} : nat :=
end
: forall T : Type, T -> nat -> nat -> nat
-myplus is not universe polymorphic
Arguments are renamed to Z, t, n, m
Argument Z is implicit and maximally inserted
Argument scopes are [type_scope _ nat_scope nat_scope]
@@ -92,7 +91,6 @@ fix myplus (T : Type) (t : T) (n m : nat) {struct n} : nat :=
end
: forall T : Type, T -> nat -> nat -> nat
-myplus is not universe polymorphic
Arguments are renamed to Z, t, n, m
Argument Z is implicit and maximally inserted
Argument scopes are [type_scope _ nat_scope nat_scope]
diff --git a/test-suite/output/Binder.out b/test-suite/output/Binder.out
index 6e27837b26..34558e9a6b 100644
--- a/test-suite/output/Binder.out
+++ b/test-suite/output/Binder.out
@@ -1,12 +1,8 @@
foo = fun '(x, y) => x + y
: nat * nat -> nat
-
-foo is not universe polymorphic
forall '(a, b), a /\ b
: Prop
foo = λ '(x, y), x + y
: nat * nat → nat
-
-foo is not universe polymorphic
∀ '(a, b), a ∧ b
: Prop
diff --git a/test-suite/output/Cases.out b/test-suite/output/Cases.out
index efcc299e82..cb835ab48d 100644
--- a/test-suite/output/Cases.out
+++ b/test-suite/output/Cases.out
@@ -7,7 +7,6 @@ fix F (t : t) : P t :=
: forall P : t -> Type,
(let x := t in forall x0 : x, P x0 -> P (k x0)) -> forall t : t, P t
-t_rect is not universe polymorphic
Argument scopes are [function_scope function_scope _]
= fun d : TT => match d with
| {| f3 := b |} => b
@@ -27,7 +26,6 @@ match Nat.eq_dec x y with
end
: forall (x y : nat) (P : nat -> Type), P x -> P y -> P y
-proj is not universe polymorphic
Argument scopes are [nat_scope nat_scope function_scope _ _]
foo =
fix foo (A : Type) (l : list A) {struct l} : option A :=
@@ -38,7 +36,6 @@ fix foo (A : Type) (l : list A) {struct l} : option A :=
end
: forall A : Type, list A -> option A
-foo is not universe polymorphic
Argument scopes are [type_scope list_scope]
uncast =
fun (A : Type) (x : I A) => match x with
@@ -46,12 +43,9 @@ fun (A : Type) (x : I A) => match x with
end
: forall A : Type, I A -> A
-uncast is not universe polymorphic
Argument scopes are [type_scope _]
foo' = if A 0 then true else false
: bool
-
-foo' is not universe polymorphic
f =
fun H : B =>
match H with
@@ -62,8 +56,6 @@ match H with
else fun _ : P false => Logic.I) x
end
: B -> True
-
-f is not universe polymorphic
The command has indeed failed with message:
Non exhaustive pattern-matching: no clause found for pattern
gadtTy _ _
@@ -86,19 +78,14 @@ The constructor D (in type J) expects 3 arguments.
lem1 =
fun dd : nat * nat => let (bb, cc) as aa return (aa = aa) := dd in eq_refl
: forall k : nat * nat, k = k
-
-lem1 is not universe polymorphic
lem2 =
fun dd : bool => if dd as aa return (aa = aa) then eq_refl else eq_refl
: forall k : bool, k = k
-lem2 is not universe polymorphic
Argument scope is [bool_scope]
lem3 =
fun dd : nat * nat => let (bb, cc) as aa return (aa = aa) := dd in eq_refl
: forall k : nat * nat, k = k
-
-lem3 is not universe polymorphic
1 subgoal
x : nat
diff --git a/test-suite/output/FunExt.v b/test-suite/output/FunExt.v
index 7658ce718e..440fe46003 100644
--- a/test-suite/output/FunExt.v
+++ b/test-suite/output/FunExt.v
@@ -1,3 +1,4 @@
+(* -*- coq-prog-args: ("-async-proofs" "no") -*- *)
Require Import FunctionalExtensionality.
(* Basic example *)
diff --git a/test-suite/output/Implicit.out b/test-suite/output/Implicit.out
index 0b0f501f9a..3b65003c29 100644
--- a/test-suite/output/Implicit.out
+++ b/test-suite/output/Implicit.out
@@ -5,7 +5,6 @@ ex_intro (P:=fun _ : nat => True) (x:=0) I
d2 = fun x : nat => d1 (y:=x)
: forall x x0 : nat, x0 = x -> x0 = x
-d2 is not universe polymorphic
Arguments x, x0 are implicit
Argument scopes are [nat_scope nat_scope _]
map id (1 :: nil)
diff --git a/test-suite/output/Load.out b/test-suite/output/Load.out
index ebbd5d422b..0904d5540b 100644
--- a/test-suite/output/Load.out
+++ b/test-suite/output/Load.out
@@ -1,10 +1,6 @@
f = 2
: nat
-
-f is not universe polymorphic
u = I
: True
-
-u is not universe polymorphic
The command has indeed failed with message:
Files processed by Load cannot leave open proofs.
diff --git a/test-suite/output/Notations3.out b/test-suite/output/Notations3.out
index 71d92482d0..015dac2512 100644
--- a/test-suite/output/Notations3.out
+++ b/test-suite/output/Notations3.out
@@ -232,7 +232,6 @@ fun l : list nat => match l with
end
: list nat -> list nat
-foo is not universe polymorphic
Argument scope is [list_scope]
Notation
"'exists' x .. y , p" := ex (fun x => .. (ex (fun y => p)) ..) : type_scope
@@ -263,9 +262,5 @@ myfoo01 tt
: list (list nat)
amatch = mmatch 0 (with 0 => 1| 1 => 2 end)
: unit
-
-amatch is not universe polymorphic
alist = [0; 1; 2]
: list nat
-
-alist is not universe polymorphic
diff --git a/test-suite/output/Notations4.out b/test-suite/output/Notations4.out
index 94016e170b..7a64b7eb45 100644
--- a/test-suite/output/Notations4.out
+++ b/test-suite/output/Notations4.out
@@ -45,5 +45,9 @@ fun x : nat => (x.-1)%pred
: Prop
##
: Prop
+myAnd1 True True
+ : Prop
+r 2 3
+ : Prop
Notation Cn := Foo.FooCn
-Expands to: Notation Top.J.Mfoo.Foo.Bar.Cn
+Expands to: Notation Notations4.J.Mfoo.Foo.Bar.Cn
diff --git a/test-suite/output/Notations4.v b/test-suite/output/Notations4.v
index 309115848f..90babf9c55 100644
--- a/test-suite/output/Notations4.v
+++ b/test-suite/output/Notations4.v
@@ -165,6 +165,22 @@ Check ##.
End H.
+(* Fixing bugs reported by G. Gonthier in #9207 *)
+
+Module I.
+
+Definition myAnd A B := A /\ B.
+Notation myAnd1 A := (myAnd A).
+Check myAnd1 True True.
+
+Set Warnings "-auto-template".
+
+Record Pnat := {inPnat :> nat -> Prop}.
+Axiom r : nat -> Pnat.
+Check r 2 3.
+
+End I.
+
(* Fixing a bug reported by G. Gonthier in #9207 *)
Module J.
diff --git a/test-suite/output/PatternsInBinders.out b/test-suite/output/PatternsInBinders.out
index bdbc5a5960..8a6d94c732 100644
--- a/test-suite/output/PatternsInBinders.out
+++ b/test-suite/output/PatternsInBinders.out
@@ -1,29 +1,20 @@
swap = fun '(x, y) => (y, x)
: A * B -> B * A
-
-swap is not universe polymorphic
fun '(x, y) => (y, x)
: A * B -> B * A
forall '(x, y), swap (x, y) = (y, x)
: Prop
proj_informative = fun '(exist _ x _) => x : A
: {x : A | P x} -> A
-
-proj_informative is not universe polymorphic
foo = fun '(Bar n b tt p) => if b then n + p else n - p
: Foo -> nat
-
-foo is not universe polymorphic
baz =
fun '(Bar n1 _ tt p1) '(Bar _ _ tt _) => n1 + p1
: Foo -> Foo -> nat
-
-baz is not universe polymorphic
swap =
fun (A B : Type) '(x, y) => (y, x)
: forall A B : Type, A * B -> B * A
-swap is not universe polymorphic
Arguments A, B are implicit and maximally inserted
Argument scopes are [type_scope type_scope _]
fun (A B : Type) '(x, y) => swap (x, y) = (y, x)
@@ -42,8 +33,6 @@ both_z =
fun pat : nat * nat =>
let '(n, p) as x := pat return (F x) in (Z n, Z p) : F (n, p)
: forall pat : nat * nat, F pat
-
-both_z is not universe polymorphic
fun '(x, y) '(z, t) => swap (x, y) = (z, t)
: A * B -> B * A -> Prop
forall '(x, y) '(z, t), swap (x, y) = (z, t)
@@ -53,7 +42,6 @@ fun (pat : nat) '(x, y) => x + y = pat
f = fun x : nat => x + x
: nat -> nat
-f is not universe polymorphic
Argument scope is [nat_scope]
fun x : nat => x + x
: nat -> nat
diff --git a/test-suite/output/PrintInfos.out b/test-suite/output/PrintInfos.out
index da1fca7134..ab4172711e 100644
--- a/test-suite/output/PrintInfos.out
+++ b/test-suite/output/PrintInfos.out
@@ -46,7 +46,6 @@ fix add (n m : nat) {struct n} : nat :=
end
: nat -> nat -> nat
-Nat.add is not universe polymorphic
Argument scopes are [nat_scope nat_scope]
Nat.add : nat -> nat -> nat
@@ -86,7 +85,6 @@ Argument x is implicit and maximally inserted
Expands to: Constant PrintInfos.bar
*** [ bar : foo ]
-bar is not universe polymorphic
Expanded type for implicit arguments
bar : forall x : nat, x = 0
diff --git a/test-suite/output/RecognizePluginWarning.v b/test-suite/output/RecognizePluginWarning.v
index cd667bbd00..a53b52396f 100644
--- a/test-suite/output/RecognizePluginWarning.v
+++ b/test-suite/output/RecognizePluginWarning.v
@@ -1,4 +1,4 @@
-(* -*- mode: coq; coq-prog-args: ("-emacs" "-w" "extraction-logical-axiom") -*- *)
+(* -*- mode: coq; coq-prog-args: ("-w" "extraction-logical-axiom") -*- *)
(* Test that mentioning a warning defined in plugins works. The failure
mode here is that these result in a warning about unknown warnings, since the
diff --git a/test-suite/output/Show.v b/test-suite/output/Show.v
index 60faac8dd9..c875051bdc 100644
--- a/test-suite/output/Show.v
+++ b/test-suite/output/Show.v
@@ -5,7 +5,7 @@
Theorem nums : forall (n m : nat), n = m -> (S n) = (S m).
Proof.
intros.
- induction n as [| n'].
+ induction n as [| n'].
induction m as [| m'].
Show.
Admitted.
diff --git a/test-suite/output/StringSyntax.out b/test-suite/output/StringSyntax.out
index c7e6ef950e..9366113c0c 100644
--- a/test-suite/output/StringSyntax.out
+++ b/test-suite/output/StringSyntax.out
@@ -433,7 +433,6 @@ end
P "167" ->
P "168" -> P "169" -> P "170" -> P "171" -> P "172" -> P "173" -> P "174" -> P "175" -> P "176" -> P "177" -> P "178" -> P "179" -> P "180" -> P "181" -> P "182" -> P "183" -> P "184" -> P "185" -> P "186" -> P "187" -> P "188" -> P "189" -> P "190" -> P "191" -> P "192" -> P "193" -> P "194" -> P "195" -> P "196" -> P "197" -> P "198" -> P "199" -> P "200" -> P "201" -> P "202" -> P "203" -> P "204" -> P "205" -> P "206" -> P "207" -> P "208" -> P "209" -> P "210" -> P "211" -> P "212" -> P "213" -> P "214" -> P "215" -> P "216" -> P "217" -> P "218" -> P "219" -> P "220" -> P "221" -> P "222" -> P "223" -> P "224" -> P "225" -> P "226" -> P "227" -> P "228" -> P "229" -> P "230" -> P "231" -> P "232" -> P "233" -> P "234" -> P "235" -> P "236" -> P "237" -> P "238" -> P "239" -> P "240" -> P "241" -> P "242" -> P "243" -> P "244" -> P "245" -> P "246" -> P "247" -> P "248" -> P "249" -> P "250" -> P "251" -> P "252" -> P "253" -> P "254" -> P "255" -> forall b : byte, P b
-byte_rect is not universe polymorphic
Argument scopes are [function_scope _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ byte_scope]
byte_rec =
fun P : byte -> Set => byte_rect P
@@ -608,7 +607,6 @@ fun P : byte -> Set => byte_rect P
P "167" ->
P "168" -> P "169" -> P "170" -> P "171" -> P "172" -> P "173" -> P "174" -> P "175" -> P "176" -> P "177" -> P "178" -> P "179" -> P "180" -> P "181" -> P "182" -> P "183" -> P "184" -> P "185" -> P "186" -> P "187" -> P "188" -> P "189" -> P "190" -> P "191" -> P "192" -> P "193" -> P "194" -> P "195" -> P "196" -> P "197" -> P "198" -> P "199" -> P "200" -> P "201" -> P "202" -> P "203" -> P "204" -> P "205" -> P "206" -> P "207" -> P "208" -> P "209" -> P "210" -> P "211" -> P "212" -> P "213" -> P "214" -> P "215" -> P "216" -> P "217" -> P "218" -> P "219" -> P "220" -> P "221" -> P "222" -> P "223" -> P "224" -> P "225" -> P "226" -> P "227" -> P "228" -> P "229" -> P "230" -> P "231" -> P "232" -> P "233" -> P "234" -> P "235" -> P "236" -> P "237" -> P "238" -> P "239" -> P "240" -> P "241" -> P "242" -> P "243" -> P "244" -> P "245" -> P "246" -> P "247" -> P "248" -> P "249" -> P "250" -> P "251" -> P "252" -> P "253" -> P "254" -> P "255" -> forall b : byte, P b
-byte_rec is not universe polymorphic
Argument scopes are [function_scope _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ byte_scope]
byte_ind =
fun (P : byte -> Prop) (f : P "000") (f0 : P "001") (f1 : P "002") (f2 : P "003") (f3 : P "004") (f4 : P "005") (f5 : P "006") (f6 : P "007") (f7 : P "008") (f8 : P "009") (f9 : P "010") (f10 : P "011") (f11 : P "012") (f12 : P "013") (f13 : P "014") (f14 : P "015") (f15 : P "016") (f16 : P "017") (f17 : P "018") (f18 : P "019") (f19 : P "020") (f20 : P "021") (f21 : P "022") (f22 : P "023") (f23 : P "024") (f24 : P "025") (f25 : P "026") (f26 : P "027") (f27 : P "028") (f28 : P "029") (f29 : P "030") (f30 : P "031") (f31 : P " ") (f32 : P "!") (f33 : P """") (f34 : P "#") (f35 : P "$") (f36 : P "%") (f37 : P "&") (f38 : P "'") (f39 : P "(") (f40 : P ")") (f41 : P "*") (f42 : P "+") (f43 : P ",") (f44 : P "-") (f45 : P ".") (f46 : P "/") (f47 : P "0") (f48 : P "1") (f49 : P "2") (f50 : P "3") (f51 : P "4") (f52 : P "5") (f53 : P "6") (f54 : P "7") (f55 : P "8") (f56 : P "9") (f57 : P ":") (f58 : P ";") (f59 : P "<") (f60 : P "=") (f61 : P ">") (f62 : P "?")
@@ -1045,7 +1043,6 @@ end
P "167" ->
P "168" -> P "169" -> P "170" -> P "171" -> P "172" -> P "173" -> P "174" -> P "175" -> P "176" -> P "177" -> P "178" -> P "179" -> P "180" -> P "181" -> P "182" -> P "183" -> P "184" -> P "185" -> P "186" -> P "187" -> P "188" -> P "189" -> P "190" -> P "191" -> P "192" -> P "193" -> P "194" -> P "195" -> P "196" -> P "197" -> P "198" -> P "199" -> P "200" -> P "201" -> P "202" -> P "203" -> P "204" -> P "205" -> P "206" -> P "207" -> P "208" -> P "209" -> P "210" -> P "211" -> P "212" -> P "213" -> P "214" -> P "215" -> P "216" -> P "217" -> P "218" -> P "219" -> P "220" -> P "221" -> P "222" -> P "223" -> P "224" -> P "225" -> P "226" -> P "227" -> P "228" -> P "229" -> P "230" -> P "231" -> P "232" -> P "233" -> P "234" -> P "235" -> P "236" -> P "237" -> P "238" -> P "239" -> P "240" -> P "241" -> P "242" -> P "243" -> P "244" -> P "245" -> P "246" -> P "247" -> P "248" -> P "249" -> P "250" -> P "251" -> P "252" -> P "253" -> P "254" -> P "255" -> forall b : byte, P b
-byte_ind is not universe polymorphic
Argument scopes are [function_scope _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ byte_scope]
"000"
: byte
diff --git a/test-suite/output/TranspModtype.out b/test-suite/output/TranspModtype.out
index 67b65d4b81..f94ed64234 100644
--- a/test-suite/output/TranspModtype.out
+++ b/test-suite/output/TranspModtype.out
@@ -1,15 +1,7 @@
TrM.A = M.A
: Set
-
-TrM.A is not universe polymorphic
OpM.A = M.A
: Set
-
-OpM.A is not universe polymorphic
TrM.B = M.B
: Set
-
-TrM.B is not universe polymorphic
*** [ OpM.B : Set ]
-
-OpM.B is not universe polymorphic
diff --git a/test-suite/output/UnclosedBlocks.v b/test-suite/output/UnclosedBlocks.v
index 854bd6a6d5..b9ba579246 100644
--- a/test-suite/output/UnclosedBlocks.v
+++ b/test-suite/output/UnclosedBlocks.v
@@ -1,4 +1,3 @@
-(* -*- mode: coq; coq-prog-args: ("-compile" "UnclosedBlocks.v") *)
Module Foo.
Module Closed.
End Closed.
diff --git a/test-suite/output/UnivBinders.out b/test-suite/output/UnivBinders.out
index 0bd6ade690..a960fe3441 100644
--- a/test-suite/output/UnivBinders.out
+++ b/test-suite/output/UnivBinders.out
@@ -9,7 +9,6 @@ fun (A : Type@{u}) (p : PWrap@{u} A) => punwrap _ p
: forall A : Type@{u}, PWrap@{u} A -> A
(* u |= *)
-punwrap is universe polymorphic
Argument scopes are [type_scope _]
Record RWrap (A : Type@{u}) : Type@{u} := rwrap { runwrap : A }
@@ -20,33 +19,26 @@ fun (A : Type@{u}) (r : RWrap@{u} A) => let (runwrap) := r in runwrap
: forall A : Type@{u}, RWrap@{u} A -> A
(* u |= *)
-runwrap is universe polymorphic
Argument scopes are [type_scope _]
Wrap@{u} = fun A : Type@{u} => A
: Type@{u} -> Type@{u}
(* u |= *)
-Wrap is universe polymorphic
Argument scope is [type_scope]
wrap@{u} =
fun (A : Type@{u}) (Wrap : Wrap@{u} A) => Wrap
: forall A : Type@{u}, Wrap@{u} A -> A
(* u |= *)
-wrap is universe polymorphic
Arguments A, Wrap are implicit and maximally inserted
Argument scopes are [type_scope _]
bar@{u} = nat
: Wrap@{u} Set
(* u |= Set < u *)
-
-bar is universe polymorphic
foo@{u UnivBinders.17 v} =
Type@{UnivBinders.17} -> Type@{v} -> Type@{u}
: Type@{max(u+1,UnivBinders.17+1,v+1)}
(* u UnivBinders.17 v |= *)
-
-foo is universe polymorphic
Type@{i} -> Type@{j}
: Type@{max(i+1,j+1)}
(* {j i} |= *)
@@ -56,8 +48,6 @@ Type@{i} -> Type@{j}
mono = Type@{mono.u}
: Type@{mono.u+1}
(* {mono.u} |= *)
-
-mono is not universe polymorphic
mono
: Type@{mono.u+1}
Type@{mono.u}
@@ -78,22 +68,16 @@ bobmorane =
let tt := Type@{UnivBinders.32} in
let ff := Type@{UnivBinders.34} in tt -> ff
: Type@{max(UnivBinders.31,UnivBinders.33)}
-
-bobmorane is not universe polymorphic
The command has indeed failed with message:
Universe u already bound.
foo@{E M N} =
Type@{M} -> Type@{N} -> Type@{E}
: Type@{max(E+1,M+1,N+1)}
(* E M N |= *)
-
-foo is universe polymorphic
foo@{u UnivBinders.17 v} =
Type@{UnivBinders.17} -> Type@{v} -> Type@{u}
: Type@{max(u+1,UnivBinders.17+1,v+1)}
(* u UnivBinders.17 v |= *)
-
-foo is universe polymorphic
Inductive Empty@{E} : Type@{E} :=
Record PWrap (A : Type@{E}) : Type@{E} := pwrap { punwrap : A }
@@ -119,26 +103,18 @@ bind_univs.mono =
Type@{bind_univs.mono.u}
: Type@{bind_univs.mono.u+1}
(* {bind_univs.mono.u} |= *)
-
-bind_univs.mono is not universe polymorphic
bind_univs.poly@{u} = Type@{u}
: Type@{u+1}
(* u |= *)
-
-bind_univs.poly is universe polymorphic
insec@{v} = Type@{u} -> Type@{v}
: Type@{max(u+1,v+1)}
(* v |= *)
-
-insec is universe polymorphic
Inductive insecind@{k} : Type@{k+1} := inseccstr : Type@{k} -> insecind@{k}
For inseccstr: Argument scope is [type_scope]
insec@{u v} = Type@{u} -> Type@{v}
: Type@{max(u+1,v+1)}
(* u v |= *)
-
-insec is universe polymorphic
Inductive insecind@{u k} : Type@{k+1} :=
inseccstr : Type@{k} -> insecind@{u k}
@@ -146,29 +122,19 @@ For inseccstr: Argument scope is [type_scope]
insec2@{u} = Prop
: Type@{Set+1}
(* u |= *)
-
-insec2 is universe polymorphic
inmod@{u} = Type@{u}
: Type@{u+1}
(* u |= *)
-
-inmod is universe polymorphic
SomeMod.inmod@{u} = Type@{u}
: Type@{u+1}
(* u |= *)
-
-SomeMod.inmod is universe polymorphic
inmod@{u} = Type@{u}
: Type@{u+1}
(* u |= *)
-
-inmod is universe polymorphic
Applied.infunct@{u v} =
inmod@{u} -> Type@{v}
: Type@{max(u+1,v+1)}
(* u v |= *)
-
-Applied.infunct is universe polymorphic
axfoo@{i UnivBinders.56 UnivBinders.57} :
Type@{UnivBinders.56} -> Type@{i}
(* i UnivBinders.56 UnivBinders.57 |= *)
diff --git a/test-suite/output/UsePluginWarning.v b/test-suite/output/UsePluginWarning.v
index c6e0054641..618b8fd42f 100644
--- a/test-suite/output/UsePluginWarning.v
+++ b/test-suite/output/UsePluginWarning.v
@@ -1,5 +1,4 @@
-(* -*- mode: coq; coq-prog-args: ("-emacs" "-w" "-extraction-logical-axiom") -*- *)
-
+(* -*- mode: coq; coq-prog-args: ("-w" "-extraction-logical-axiom") -*- *)
Require Extraction.
Axiom foo : Prop.
diff --git a/test-suite/output/goal_output.out b/test-suite/output/goal_output.out
index 20568f742a..773533a8d3 100644
--- a/test-suite/output/goal_output.out
+++ b/test-suite/output/goal_output.out
@@ -1,11 +1,7 @@
Nat.t = nat
: Set
-
-Nat.t is not universe polymorphic
Nat.t = nat
: Set
-
-Nat.t is not universe polymorphic
1 subgoal
============================
diff --git a/test-suite/output/inference.out b/test-suite/output/inference.out
index f545ca679c..f7ffd1959a 100644
--- a/test-suite/output/inference.out
+++ b/test-suite/output/inference.out
@@ -4,8 +4,6 @@ fun e : option L => match e with
| None => None
end
: option L -> option L
-
-P is not universe polymorphic
fun n : nat => let y : T n := A n in ?t ?x : T n
: forall n : nat, T n
where
diff --git a/test-suite/output/simpl.v b/test-suite/output/simpl.v
index 5f1926f142..5f7e3ab9dd 100644
--- a/test-suite/output/simpl.v
+++ b/test-suite/output/simpl.v
@@ -11,3 +11,4 @@ Undo.
simpl (0 + _).
Show.
Undo.
+Abort.
diff --git a/test-suite/output/unifconstraints.v b/test-suite/output/unifconstraints.v
index 179dec3fb0..c987d66c5f 100644
--- a/test-suite/output/unifconstraints.v
+++ b/test-suite/output/unifconstraints.v
@@ -1,3 +1,4 @@
+(* -*- coq-prog-args: ("-async-proofs" "no") -*- *)
(* Set Printing Existential Instances. *)
Unset Solve Unification Constraints.
Axiom veeryyyyyyyyyyyyloooooooooooooonggidentifier : nat.
diff --git a/test-suite/report.sh b/test-suite/report.sh
index cef615266b..71aac029ea 100755
--- a/test-suite/report.sh
+++ b/test-suite/report.sh
@@ -24,21 +24,11 @@ cp summary.log "$SAVEDIR"/
rm "$FAILED"
# print info
-if [ -n "$TRAVIS" ] || [ -n "$APPVEYOR" ] || [ -n "$PRINT_LOGS" ]; then
+if [ -n "$APPVEYOR" ] || [ -n "$PRINT_LOGS" ]; then
find logs/ -name '*.log' -not -name 'summary.log' -print0 | while IFS= read -r -d '' file; do
- if [ -n "$TRAVIS" ]; then
- # ${foo////.} replaces every / by . in $foo
- printf 'travis_fold:start:coq.logs.%s\n' "${file////.}";
- else printf '%s\n' "$file"
- fi
-
+ printf '%s\n' "$file"
cat "$file"
-
- if [ -n "$TRAVIS" ]; then
- # ${foo////.} replaces every / by . in $foo
- printf 'travis_fold:end:coq.logs.%s\n' "${file////.}";
- else printf '\n'
- fi
+ printf '\n'
done
printed_logs=1
fi
diff --git a/test-suite/ssr/ipat_replace.v b/test-suite/ssr/ipat_replace.v
new file mode 100644
index 0000000000..528f33f30d
--- /dev/null
+++ b/test-suite/ssr/ipat_replace.v
@@ -0,0 +1,17 @@
+Require Import ssreflect.
+
+Lemma test : True.
+Proof.
+have H : True.
+ by [].
+have {}H : True.
+ by apply: H.
+by apply: H.
+Qed.
+
+Lemma test2 (H : True) : False -> False -> False.
+Proof.
+move=> {}W.
+move=> {}H.
+by apply: H.
+Qed.
diff --git a/test-suite/success/CompatCurrentFlag.v b/test-suite/success/CompatCurrentFlag.v
index 5650dba236..81469d79c3 100644
--- a/test-suite/success/CompatCurrentFlag.v
+++ b/test-suite/success/CompatCurrentFlag.v
@@ -1,3 +1,3 @@
-(* -*- coq-prog-args: ("-compat" "8.9") -*- *)
+(* -*- coq-prog-args: ("-compat" "8.10") -*- *)
(** Check that the current compatibility flag actually requires the relevant modules. *)
-Import Coq.Compat.Coq89.
+Import Coq.Compat.Coq810.
diff --git a/test-suite/success/CompatOldFlag.v b/test-suite/success/CompatOldFlag.v
index 37d50ee67d..afeb57f9f2 100644
--- a/test-suite/success/CompatOldFlag.v
+++ b/test-suite/success/CompatOldFlag.v
@@ -1,5 +1,5 @@
-(* -*- coq-prog-args: ("-compat" "8.7") -*- *)
+(* -*- coq-prog-args: ("-compat" "8.8") -*- *)
(** Check that the current-minus-two compatibility flag actually requires the relevant modules. *)
+Import Coq.Compat.Coq810.
Import Coq.Compat.Coq89.
Import Coq.Compat.Coq88.
-Import Coq.Compat.Coq87.
diff --git a/test-suite/success/CompatOldOldFlag.v b/test-suite/success/CompatOldOldFlag.v
new file mode 100644
index 0000000000..1f62635f50
--- /dev/null
+++ b/test-suite/success/CompatOldOldFlag.v
@@ -0,0 +1,6 @@
+(* -*- coq-prog-args: ("-compat" "8.7") -*- *)
+(** Check that the current-minus-three compatibility flag actually requires the relevant modules. *)
+Import Coq.Compat.Coq810.
+Import Coq.Compat.Coq89.
+Import Coq.Compat.Coq88.
+Import Coq.Compat.Coq87.
diff --git a/test-suite/success/CompatPreviousFlag.v b/test-suite/success/CompatPreviousFlag.v
index 9981388381..c8f75915c8 100644
--- a/test-suite/success/CompatPreviousFlag.v
+++ b/test-suite/success/CompatPreviousFlag.v
@@ -1,4 +1,4 @@
-(* -*- coq-prog-args: ("-compat" "8.8") -*- *)
+(* -*- coq-prog-args: ("-compat" "8.9") -*- *)
(** Check that the current-minus-one compatibility flag actually requires the relevant modules. *)
+Import Coq.Compat.Coq810.
Import Coq.Compat.Coq89.
-Import Coq.Compat.Coq88.
diff --git a/test-suite/success/Typeclasses.v b/test-suite/success/Typeclasses.v
index 9086621344..3888cafed3 100644
--- a/test-suite/success/Typeclasses.v
+++ b/test-suite/success/Typeclasses.v
@@ -14,7 +14,7 @@ Module onlyclasses.
Module RJung.
Class Foo (x : nat).
- Instance foo x : x = 2 -> Foo x.
+ Instance foo x : x = 2 -> Foo x := {}.
Hint Extern 0 (_ = _) => reflexivity : typeclass_instances.
Typeclasses eauto := debug.
Check (_ : Foo 2).
@@ -63,7 +63,7 @@ End RefineVsNoTceauto.
Module Leivantex2PR339.
(** Was a bug preventing to find hints associated with no pattern *)
Class Bar := {}.
- Instance bar1 (t:Type) : Bar.
+ Instance bar1 (t:Type) : Bar := {}.
Hint Extern 0 => exact True : typeclass_instances.
Typeclasses eauto := debug.
Goal Bar.
@@ -222,10 +222,10 @@ Module IterativeDeepening.
Class B.
Class C.
- Instance: B -> A | 0.
- Instance: C -> A | 0.
- Instance: C -> B -> A | 0.
- Instance: A -> A | 0.
+ Instance: B -> A | 0 := {}.
+ Instance: C -> A | 0 := {}.
+ Instance: C -> B -> A | 0 := {}.
+ Instance: A -> A | 0 := {}.
Goal C -> A.
intros.
diff --git a/test-suite/success/auto.v b/test-suite/success/auto.v
index 5477c83316..62a66daf7d 100644
--- a/test-suite/success/auto.v
+++ b/test-suite/success/auto.v
@@ -51,7 +51,7 @@ Qed.
Class B (A : Type).
Class I.
-Instance i : I.
+Instance i : I := {}.
Definition flip {A B C : Type} (f : A -> B -> C) := fun y x => f x y.
Class D (f : nat -> nat -> nat).
@@ -59,7 +59,7 @@ Definition ftest (x y : nat) := x + y.
Definition flipD (f : nat -> nat -> nat) : D f -> D (flip f).
Admitted.
Module Instnopat.
- Local Instance: B nat.
+ Local Instance: B nat := {}.
(* pattern_of_constr -> B nat *)
(* exact hint *)
Check (_ : B nat).
@@ -72,7 +72,7 @@ Module Instnopat.
eauto with typeclass_instances.
Qed.
- Local Instance: D ftest.
+ Local Instance: D ftest := {}.
Local Hint Resolve flipD | 0 : typeclass_instances.
(* pattern: D (flip _) *)
Fail Timeout 1 Check (_ : D _). (* loops applying flipD *)
@@ -80,7 +80,7 @@ Module Instnopat.
End Instnopat.
Module InstnopatApply.
- Local Instance: I -> B nat.
+ Local Instance: I -> B nat := {}.
(* pattern_of_constr -> B nat *)
(* apply hint *)
Check (_ : B nat).
@@ -116,7 +116,7 @@ Module InstPat.
Hint Extern 0 (D (flip _)) => apply flipD : typeclass_instances.
Module withftest.
- Local Instance: D ftest.
+ Local Instance: D ftest := {}.
Check (_ : D _).
(* D_instance_0 : D ftest *)
diff --git a/test-suite/success/bteauto.v b/test-suite/success/bteauto.v
index 730b367d60..cea7d92c0b 100644
--- a/test-suite/success/bteauto.v
+++ b/test-suite/success/bteauto.v
@@ -149,10 +149,10 @@ Module IterativeDeepening.
Class B.
Class C.
- Instance: B -> A | 0.
- Instance: C -> A | 0.
- Instance: C -> B -> A | 0.
- Instance: A -> A | 0.
+ Instance: B -> A | 0 := {}.
+ Instance: C -> A | 0 := {}.
+ Instance: C -> B -> A | 0 := {}.
+ Instance: A -> A | 0 := {}.
Goal C -> A.
intros.
diff --git a/test-suite/success/destruct.v b/test-suite/success/destruct.v
index d1d384659b..573912c7cd 100644
--- a/test-suite/success/destruct.v
+++ b/test-suite/success/destruct.v
@@ -263,7 +263,7 @@ Abort.
(* This one was working in 8.4 (because of full conv on closed arguments) *)
Class E.
-Instance a:E.
+Instance a:E := {}.
Goal forall h : E -> nat -> nat, h (id a) 0 = h a 0.
intros.
destruct (h _).
diff --git a/test-suite/success/eauto.v b/test-suite/success/eauto.v
index c44747379f..5b616ccc33 100644
--- a/test-suite/success/eauto.v
+++ b/test-suite/success/eauto.v
@@ -9,11 +9,11 @@
(************************************************************************)
Class A (A : Type).
- Instance an: A nat.
+ Instance an: A nat := {}.
Class B (A : Type) (a : A).
-Instance bn0: B nat 0.
-Instance bn1: B nat 1.
+Instance bn0: B nat 0 := {}.
+Instance bn1: B nat 1 := {}.
Goal A nat.
Proof.
@@ -39,7 +39,7 @@ Proof.
eexists. eexists. typeclasses eauto.
Defined.
-Instance ab: A bool. (* Backtrack on A instance *)
+Instance ab: A bool := {}. (* Backtrack on A instance *)
Goal exists (T : Type) (t : T), A T /\ B T t.
Proof.
eexists. eexists. typeclasses eauto.
@@ -51,7 +51,7 @@ Hint Extern 0 { x : ?A & _ } =>
unshelve class_apply @existT : typeclass_instances.
Existing Class sigT.
Set Typeclasses Debug.
-Instance can: C an 0.
+Instance can: C an 0 := {}.
(* Backtrack on instance implementation *)
Goal exists (T : Type) (t : T), { x : A T & C x t }.
Proof.
@@ -59,7 +59,7 @@ Proof.
Defined.
Class D T `(a: A T).
- Instance: D _ an.
+ Instance: D _ an := {}.
Goal exists (T : Type), { x : A T & D T x }.
Proof.
eexists. typeclasses eauto.
diff --git a/test-suite/success/setoid_test2.v b/test-suite/success/setoid_test2.v
index 79467e549c..351481b0b6 100644
--- a/test-suite/success/setoid_test2.v
+++ b/test-suite/success/setoid_test2.v
@@ -120,7 +120,7 @@ Axiom eqS1: S1 -> S1 -> Prop.
Axiom SetoidS1 : Setoid_Theory S1 eqS1.
Add Setoid S1 eqS1 SetoidS1 as S1setoid.
-Instance eqS1_default : DefaultRelation eqS1.
+Instance eqS1_default : DefaultRelation eqS1 := {}.
Axiom eqS1': S1 -> S1 -> Prop.
Axiom SetoidS1' : Setoid_Theory S1 eqS1'.
@@ -220,7 +220,7 @@ Axiom eqS1_test8: S1_test8 -> S1_test8 -> Prop.
Axiom SetoidS1_test8 : Setoid_Theory S1_test8 eqS1_test8.
Add Setoid S1_test8 eqS1_test8 SetoidS1_test8 as S1_test8setoid.
-Instance eqS1_test8_default : DefaultRelation eqS1_test8.
+Instance eqS1_test8_default : DefaultRelation eqS1_test8 := {}.
Axiom f_test8 : S2 -> S1_test8.
Add Morphism f_test8 with signature (eqS2 ==> eqS1_test8) as f_compat_test8. Admitted.
diff --git a/test-suite/tools/update-compat/run.sh b/test-suite/tools/update-compat/run.sh
index 02a2348450..61273c4f37 100755
--- a/test-suite/tools/update-compat/run.sh
+++ b/test-suite/tools/update-compat/run.sh
@@ -6,4 +6,4 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# we assume that the script lives in test-suite/tools/update-compat/,
# and that update-compat.py lives in dev/tools/
cd "${SCRIPT_DIR}/../../.."
-dev/tools/update-compat.py --assert-unchanged --cur-version=8.9 || exit $?
+dev/tools/update-compat.py --assert-unchanged --master || exit $?
diff --git a/theories/Classes/CRelationClasses.v b/theories/Classes/CRelationClasses.v
index bc821532fe..bb873588b1 100644
--- a/theories/Classes/CRelationClasses.v
+++ b/theories/Classes/CRelationClasses.v
@@ -177,6 +177,7 @@ Section Defs.
a rewrite crelation. *)
Global Instance equivalence_rewrite_crelation `(Equivalence eqA) : RewriteRelation eqA.
+ Defined.
(** Leibniz equality. *)
Section Leibniz.
@@ -195,7 +196,10 @@ End Defs.
(** Default rewrite crelations handled by [setoid_rewrite]. *)
Instance: RewriteRelation impl.
+Defined.
+
Instance: RewriteRelation iff.
+Defined.
(** Hints to drive the typeclass resolution avoiding loops
due to the use of full unification. *)
@@ -299,7 +303,8 @@ Section Binary.
fun R R' => forall x y, iffT (R x y) (R' x y).
Global Instance: RewriteRelation relation_equivalence.
-
+ Defined.
+
Definition relation_conjunction (R : crelation A) (R' : crelation A) : crelation A :=
fun x y => prod (R x y) (R' x y).
diff --git a/theories/Classes/RelationClasses.v b/theories/Classes/RelationClasses.v
index 4b97d75cea..6e2ff49536 100644
--- a/theories/Classes/RelationClasses.v
+++ b/theories/Classes/RelationClasses.v
@@ -171,6 +171,7 @@ Section Defs.
a rewrite relation. *)
Global Instance equivalence_rewrite_relation `(Equivalence eqA) : RewriteRelation eqA.
+ Defined.
(** Leibniz equality. *)
Section Leibniz.
@@ -189,7 +190,9 @@ End Defs.
(** Default rewrite relations handled by [setoid_rewrite]. *)
Instance: RewriteRelation impl.
+Defined.
Instance: RewriteRelation iff.
+Defined.
(** Hints to drive the typeclass resolution avoiding loops
due to the use of full unification. *)
@@ -430,6 +433,7 @@ Section Binary.
@predicate_equivalence (_::_::Tnil).
Global Instance: RewriteRelation relation_equivalence.
+ Defined.
Definition relation_conjunction (R : relation A) (R' : relation A) : relation A :=
@predicate_intersection (A::A::Tnil) R R'.
diff --git a/theories/Classes/RelationPairs.v b/theories/Classes/RelationPairs.v
index 3e6358c8f3..341dacd4b2 100644
--- a/theories/Classes/RelationPairs.v
+++ b/theories/Classes/RelationPairs.v
@@ -62,7 +62,10 @@ Class Measure {A B} (f : A -> B).
(** Standard measures. *)
Instance fst_measure : @Measure (A * B) A Fst.
+Defined.
+
Instance snd_measure : @Measure (A * B) B Snd.
+Defined.
(** We define a product relation over [A*B]: each components should
satisfy the corresponding initial relation. *)
diff --git a/theories/Classes/SetoidTactics.v b/theories/Classes/SetoidTactics.v
index 3fab3c5a07..94920f74ec 100644
--- a/theories/Classes/SetoidTactics.v
+++ b/theories/Classes/SetoidTactics.v
@@ -41,6 +41,7 @@ Definition default_relation `{DefaultRelation A R} := R.
(lowest priority). *)
Instance equivalence_default `(Equivalence A R) : DefaultRelation R | 4.
+Defined.
(** The setoid_replace tactics in Ltac, defined in terms of default relations
and the setoid_rewrite tactic. *)
diff --git a/theories/Compat/Coq810.v b/theories/Compat/Coq810.v
new file mode 100644
index 0000000000..f10201661e
--- /dev/null
+++ b/theories/Compat/Coq810.v
@@ -0,0 +1,11 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Compatibility file for making Coq act similar to Coq v8.10 *)
diff --git a/theories/Compat/Coq89.v b/theories/Compat/Coq89.v
index decb5c7519..05d63d9a47 100644
--- a/theories/Compat/Coq89.v
+++ b/theories/Compat/Coq89.v
@@ -11,5 +11,7 @@
(** Compatibility file for making Coq act similar to Coq v8.9 *)
Local Set Warnings "-deprecated".
+Require Export Coq.Compat.Coq810.
+
Unset Private Polymorphic Universes.
Set Refine Instance Mode.
diff --git a/theories/Init/Decimal.v b/theories/Init/Decimal.v
index 537400fb05..3d4b3d0568 100644
--- a/theories/Init/Decimal.v
+++ b/theories/Init/Decimal.v
@@ -40,7 +40,7 @@ Notation zero := (D0 Nil).
(** For signed integers, we use two constructors [Pos] and [Neg]. *)
-Inductive int := Pos (d:uint) | Neg (d:uint).
+Variant int := Pos (d:uint) | Neg (d:uint).
Declare Scope dec_uint_scope.
Delimit Scope dec_uint_scope with uint.
@@ -50,6 +50,9 @@ Declare Scope dec_int_scope.
Delimit Scope dec_int_scope with int.
Bind Scope dec_int_scope with int.
+Register uint as num.uint.type.
+Register int as num.int.type.
+
(** This representation favors simplicity over canonicity.
For normalizing numbers, we need to remove head zero digits,
and choose our canonical representation of 0 (here [D0 Nil]
diff --git a/theories/Numbers/BinNums.v b/theories/Numbers/BinNums.v
index ef2c688759..247827597a 100644
--- a/theories/Numbers/BinNums.v
+++ b/theories/Numbers/BinNums.v
@@ -29,6 +29,7 @@ Bind Scope positive_scope with positive.
Arguments xO _%positive.
Arguments xI _%positive.
+Register positive as num.pos.type.
Register xI as num.pos.xI.
Register xO as num.pos.xO.
Register xH as num.pos.xH.
diff --git a/tools/coq_dune.ml b/tools/coq_dune.ml
index 9ecd8f19ce..8f6c4c0968 100644
--- a/tools/coq_dune.ml
+++ b/tools/coq_dune.ml
@@ -186,7 +186,7 @@ let pp_vo_dep dir fmt vo =
(* We explicitly include the location of coqlib to avoid tricky issues with coqlib location *)
let libflag = "-coqlib %{project_root}" in
(* The final build rule *)
- let action = sprintf "(chdir %%{project_root} (run coqtop -boot %s %s %s -compile %s))" libflag eflag cflag source in
+ let action = sprintf "(chdir %%{project_root} (run coqtop -boot %s %s %s -w -deprecate-compile-arg -compile %s))" libflag eflag cflag source in
let all_targets = gen_coqc_targets vo in
pp_rule fmt all_targets deps action
diff --git a/tools/coqc.ml b/tools/coqc.ml
index ae841212a7..0f65823740 100644
--- a/tools/coqc.ml
+++ b/tools/coqc.ml
@@ -32,8 +32,9 @@ let verbose = ref false
let rec make_compilation_args = function
| [] -> []
| file :: fl ->
- (if !verbose then "-compile-verbose" else "-compile")
- :: file :: (make_compilation_args fl)
+ "-w" :: "-deprecate-compile-arg"
+ :: (if !verbose then "-compile-verbose" else "-compile")
+ :: file :: (make_compilation_args fl)
(* compilation of files [files] with command [command] and args [args] *)
@@ -61,16 +62,28 @@ let usage () =
(* parsing of the command line *)
let extra_arg_needed = ref true
+let deprecated_coqc_warning = CWarnings.(create
+ ~name:"deprecate-compile-arg"
+ ~category:"toplevel"
+ ~default:Enabled
+ (fun opt_name -> Pp.(seq [str "The option "; str opt_name; str" is deprecated."])))
+
let parse_args () =
let rec parse (cfiles,args) = function
| [] ->
List.rev cfiles, List.rev args
| ("-verbose" | "--verbose") :: rem ->
verbose := true ; parse (cfiles,args) rem
- | "-image" :: f :: rem -> image := f; parse (cfiles,args) rem
+ | "-image" :: f :: rem ->
+ deprecated_coqc_warning "-image";
+ image := f; parse (cfiles,args) rem
| "-image" :: [] -> usage ()
- | "-byte" :: rem -> use_bytecode := true; parse (cfiles,args) rem
- | "-opt" :: rem -> use_bytecode := false; parse (cfiles,args) rem
+ | "-byte" :: rem ->
+ deprecated_coqc_warning "-byte";
+ use_bytecode := true; parse (cfiles,args) rem
+ | "-opt" :: rem ->
+ deprecated_coqc_warning "-opt";
+ use_bytecode := false; parse (cfiles,args) rem
(* Informative options *)
@@ -87,7 +100,7 @@ let parse_args () =
Envars.set_coqlib ~fail:(fun x -> x);
Envars.print_config stdout Coq_config.all_src_dirs;
exit 0
-
+
| ("-print-version" | "--print-version") :: _ ->
Usage.machine_readable_version 0
@@ -97,7 +110,7 @@ let parse_args () =
|"-batch"|"-noinit"|"-nois"|"-noglob"|"-no-glob"
|"-q"|"-profile"|"-echo" |"-quiet"
|"-silent"|"-m"|"-beautify"|"-strict-implicit"
- |"-impredicative-set"|"-vm"
+ |"-impredicative-set"|"-vm"|"-test-mode"|"-emacs"
|"-indices-matter"|"-quick"|"-type-in-type"
|"-async-proofs-always-delegate"|"-async-proofs-never-reopen-branch"
|"-stm-debug"
@@ -108,22 +121,28 @@ let parse_args () =
| ("-outputstate"|"-inputstate"|"-is"|"-exclude-dir"|"-color"
|"-load-vernac-source"|"-l"|"-load-vernac-object"
- |"-load-ml-source"|"-require"|"-load-ml-object"
+ |"-load-ml-source"|"-require"|"-load-ml-object"|"-async-proofs-cache"
|"-init-file"|"-dump-glob"|"-compat"|"-coqlib"|"-top"|"-topfile"
|"-async-proofs-j" |"-async-proofs-private-flags" |"-async-proofs" |"-w"
- |"-o"|"-profile-ltac-cutoff"|"-mangle-names"|"-bytecode-compiler"|"-native-compiler"
+ |"-profile-ltac-cutoff"|"-mangle-names"|"-bytecode-compiler"|"-native-compiler"
as o) :: rem ->
begin
match rem with
| s :: rem' -> parse (cfiles,s::o::args) rem'
| [] -> usage ()
end
+ | "-o" :: rem->
+ begin
+ match rem with
+ | s :: rem' -> parse (cfiles,s::"-o"::args) rem'
+ | [] -> usage ()
+ end
| ("-I"|"-include" as o) :: s :: rem -> parse (cfiles,s::o::args) rem
(* Options for coqtop : c) options with 1 argument and possibly more *)
| ("-R"|"-Q" as o) :: s :: t :: rem -> parse (cfiles,t::s::o::args) rem
- | ("-schedule-vio-checking"
+ | ("-schedule-vio-checking"|"-vio2vo"
|"-check-vio-tasks" | "-schedule-vio2vo" as o) :: s :: rem ->
let nodash, rem =
CList.split_when (fun x -> String.length x > 1 && x.[0] = '-') rem in
diff --git a/toplevel/coqargs.ml b/toplevel/coqargs.ml
index 0a32879764..f822c68843 100644
--- a/toplevel/coqargs.ml
+++ b/toplevel/coqargs.ml
@@ -165,7 +165,8 @@ let add_compat_require opts v =
match v with
| Flags.V8_7 -> add_vo_require opts "Coq.Compat.Coq87" None (Some false)
| Flags.V8_8 -> add_vo_require opts "Coq.Compat.Coq88" None (Some false)
- | Flags.Current -> add_vo_require opts "Coq.Compat.Coq89" None (Some false)
+ | Flags.V8_9 -> add_vo_require opts "Coq.Compat.Coq89" None (Some false)
+ | Flags.Current -> add_vo_require opts "Coq.Compat.Coq810" None (Some false)
let set_batch_mode opts =
(* XXX: This should be in the argument record *)
@@ -322,6 +323,12 @@ let usage batch =
then Usage.print_usage_coqc ()
else Usage.print_usage_coqtop ()
+let deprecated_coqc_warning = CWarnings.(create
+ ~name:"deprecate-compile-arg"
+ ~category:"toplevel"
+ ~default:Enabled
+ (fun opt_name -> Pp.(seq [str "The option "; str opt_name; str" is deprecated, please use coqc."])))
+
(* Main parsing routine *)
let parse_args init_opts arglist : coq_cmdopts * string list =
let args = ref arglist in
@@ -435,10 +442,12 @@ let parse_args init_opts arglist : coq_cmdopts * string list =
Flags.compat_version := v;
add_compat_require oval v
- |"-compile" ->
+ |"-compile" as opt ->
+ deprecated_coqc_warning opt;
add_compile oval false (next ())
- |"-compile-verbose" ->
+ |"-compile-verbose" as opt ->
+ deprecated_coqc_warning opt;
add_compile oval true (next ())
|"-dump-glob" ->
@@ -518,7 +527,9 @@ let parse_args init_opts arglist : coq_cmdopts * string list =
CWarnings.set_flags (CWarnings.normalize_flags_string w);
oval
- |"-o" -> { oval with compilation_output_name = Some (next()) }
+ |"-o" as opt ->
+ deprecated_coqc_warning opt;
+ { oval with compilation_output_name = Some (next()) }
|"-bytecode-compiler" ->
{ oval with enable_VM = get_bool opt (next ()) }
diff --git a/toplevel/coqloop.ml b/toplevel/coqloop.ml
index e58b9ccac7..cdbe444e5b 100644
--- a/toplevel/coqloop.ml
+++ b/toplevel/coqloop.ml
@@ -243,7 +243,7 @@ let set_prompt prompt =
let parse_to_dot =
let rec dot st = match Stream.next st with
| Tok.KEYWORD ("."|"...") -> ()
- | Tok.EOI -> raise Stm.End_of_input
+ | Tok.EOI -> ()
| _ -> dot st
in
Pcoq.Entry.of_parser "Coqtoplevel.dot" dot
@@ -257,12 +257,12 @@ let rec discard_to_dot () =
Pcoq.Entry.parse parse_to_dot top_buffer.tokens
with
| Gramlib.Plexing.Error _ | CLexer.Error.E _ -> discard_to_dot ()
- | Stm.End_of_input -> raise Stm.End_of_input
| e when CErrors.noncritical e -> ()
let read_sentence ~state input =
(* XXX: careful with ignoring the state Eugene!*)
- try G_toplevel.parse_toplevel input
+ let open Vernac.State in
+ try Stm.parse_sentence ~doc:state.doc state.sid ~entry:G_toplevel.vernac_toplevel input
with reraise ->
let reraise = CErrors.push reraise in
discard_to_dot ();
@@ -366,7 +366,6 @@ let top_goal_print ~doc c oldp newp =
let msg = CErrors.iprint (e, info) in
TopErr.print_error_for_buffer ?loc Feedback.Error msg top_buffer
-(* Careful to keep this loop tail-rec *)
let rec vernac_loop ~state =
let open CAst in
let open Vernac.State in
@@ -379,26 +378,30 @@ let rec vernac_loop ~state =
try
let input = top_buffer.tokens in
match read_sentence ~state input with
- | {v=VernacBacktrack(bid,_,_)} ->
+ | Some { v = VernacBacktrack(bid,_,_) } ->
let bid = Stateid.of_int bid in
let doc, res = Stm.edit_at ~doc:state.doc bid in
assert (res = `NewTip);
let state = { state with doc; sid = bid } in
vernac_loop ~state
- | {v=VernacQuit} ->
+ | Some { v = VernacQuit } ->
exit 0
- | {v=VernacDrop} ->
+
+ | Some { v = VernacDrop } ->
if Mltop.is_ocaml_top()
then (drop_last_doc := Some state; state)
else (Feedback.msg_warning (str "There is no ML toplevel."); vernac_loop ~state)
- | {v=VernacControl c; loc} ->
+
+ | Some { v = VernacControl c; loc } ->
let nstate = Vernac.process_expr ~state (make ?loc c) in
top_goal_print ~doc:state.doc c state.proof nstate.proof;
vernac_loop ~state:nstate
+
+ | None ->
+ top_stderr (fnl ()); exit 0
+
with
- | Stm.End_of_input ->
- top_stderr (fnl ()); exit 0
(* Exception printing should be done by the feedback listener,
however this is not yet ready so we rely on the exception for
now. *)
diff --git a/toplevel/g_toplevel.mlg b/toplevel/g_toplevel.mlg
index 5aba3d6b0b..7f1cca277e 100644
--- a/toplevel/g_toplevel.mlg
+++ b/toplevel/g_toplevel.mlg
@@ -21,7 +21,7 @@ type vernac_toplevel =
| VernacControl of vernac_control
module Toplevel_ : sig
- val vernac_toplevel : vernac_toplevel CAst.t Entry.t
+ val vernac_toplevel : vernac_toplevel CAst.t option Entry.t
end = struct
let gec_vernac s = Entry.create ("toplevel:" ^ s)
let vernac_toplevel = gec_vernac "vernac_toplevel"
@@ -34,14 +34,14 @@ open Toplevel_
GRAMMAR EXTEND Gram
GLOBAL: vernac_toplevel;
vernac_toplevel: FIRST
- [ [ IDENT "Drop"; "." -> { CAst.make VernacDrop }
- | IDENT "Quit"; "." -> { CAst.make VernacQuit }
+ [ [ IDENT "Drop"; "." -> { Some (CAst.make VernacDrop) }
+ | IDENT "Quit"; "." -> { Some (CAst.make VernacQuit) }
| IDENT "Backtrack"; n = natural ; m = natural ; p = natural; "." ->
- { CAst.make (VernacBacktrack (n,m,p)) }
- | cmd = Pvernac.main_entry ->
+ { Some (CAst.make (VernacBacktrack (n,m,p))) }
+ | cmd = Pvernac.Vernac_.main_entry ->
{ match cmd with
- | None -> raise Stm.End_of_input
- | Some (loc,c) -> CAst.make ~loc (VernacControl c) }
+ | None -> None
+ | Some (loc,c) -> Some (CAst.make ~loc (VernacControl c)) }
]
]
;
@@ -49,6 +49,8 @@ END
{
-let parse_toplevel pa = Pcoq.Entry.parse vernac_toplevel pa
+let vernac_toplevel pm =
+ Pvernac.Unsafe.set_tactic_entry pm;
+ vernac_toplevel
}
diff --git a/toplevel/usage.ml b/toplevel/usage.ml
index c43538017c..53bfeddf00 100644
--- a/toplevel/usage.ml
+++ b/toplevel/usage.ml
@@ -23,7 +23,7 @@ let machine_readable_version ret =
let extra_usage = ref []
let add_to_usage name text = extra_usage := (name,text) :: !extra_usage
-let print_usage_channel co command =
+let print_usage_common co command =
output_string co command;
output_string co "Coq options are:\n";
output_string co
@@ -48,9 +48,6 @@ let print_usage_channel co command =
\n -lv f (idem)\
\n -load-vernac-object f load Coq object file f.vo\
\n -require path load Coq library path and import it (Require Import path.)\
-\n -compile f.v compile Coq file f.v (implies -batch)\
-\n -compile-verbose f.v verbosely compile Coq file f.v (implies -batch)\
-\n -o f.vo use f.vo as the output file name\
\n -quick quickly compile .v files to .vio files (skip proofs)\
\n -schedule-vio2vo j f1..fn run up to j instances of Coq to turn each fi.vio\
\n into fi.vo\
@@ -66,16 +63,15 @@ let print_usage_channel co command =
\n -quiet unset display of extra information (implies -w \"-all\")\
\n -w (w1,..,wn) configure display of warnings\
\n -color (yes|no|auto) configure color output\
+\n -emacs tells Coq it is executed under Emacs\
\n\
\n -q skip loading of rcfile\
\n -init-file f set the rcfile to f\
-\n -batch batch mode (exits just after arguments parsing)\
\n -boot boot mode (implies -q and -batch)\
\n -bt print backtraces (requires configure debug flag)\
\n -debug debug mode (implies -bt)\
\n -diffs (on|off|removed) highlight differences between proof steps\
\n -stm-debug STM debug mode (will trace every transaction)\
-\n -emacs tells Coq it is executed under Emacs\
\n -noglob do not dump globalizations\
\n -dump-glob f dump globalizations in file f (to be used by coqdoc)\
\n -impredicative-set set sort Set impredicative\
@@ -101,21 +97,36 @@ let print_usage_channel co command =
(* print the usage on standard error *)
-let print_usage = print_usage_channel stderr
-
let print_usage_coqtop () =
- print_usage "Usage: coqtop <options>\n\n";
+ print_usage_common stderr "Usage: coqtop <options>\n\n";
+ output_string stderr "\n\
+coqtop specific options:\
+\n\
+\n -batch batch mode (exits just after arguments parsing)\
+\n\
+\nDeprecated options [use coqc instead]:\
+\n\
+\n -compile f.v compile Coq file f.v (implies -batch)\
+\n -compile-verbose f.v verbosely compile Coq file f.v (implies -batch)\
+\n -o f.vo use f.vo as the output file name\
+\n";
flush stderr ;
exit 1
let print_usage_coqc () =
- print_usage "Usage: coqc <options> <Coq options> file...\n\
-\noptions are:\
-\n -verbose compile verbosely\
-\n -image f specify an alternative executable for Coq\
-\n -opt run the native-code version of Coq\
-\n -byte run the bytecode version of Coq\
-\n -t keep temporary files\n\n";
+ print_usage_common stderr "Usage: coqc <options> <Coq options> file...";
+ output_string stderr "\n\
+coqc specific options:\
+\n\
+\n -o f.vo use f.vo as the output file name\
+\n -verbose compile and output the input file\
+\n\
+\nDeprecated options:\
+\n\
+\n -image f specify an alternative executable for Coq\
+\n -opt run the native-code version of Coq\
+\n -byte run the bytecode version of Coq\
+\n -t keep temporary files\
+\n";
flush stderr ;
exit 1
-
diff --git a/toplevel/usage.mli b/toplevel/usage.mli
index fbb0117d45..64170adaa4 100644
--- a/toplevel/usage.mli
+++ b/toplevel/usage.mli
@@ -13,9 +13,6 @@
val version : int -> 'a
val machine_readable_version : int -> 'a
-(** {6 Prints the usage on the error output, preceeded by a user-provided message. } *)
-val print_usage : string -> unit
-
(** {6 Enable toploop plugins to insert some text in the usage message. } *)
val add_to_usage : string -> string -> unit
diff --git a/toplevel/vernac.ml b/toplevel/vernac.ml
index d8465aac27..45ca658857 100644
--- a/toplevel/vernac.ml
+++ b/toplevel/vernac.ml
@@ -68,10 +68,8 @@ let interp_vernac ~check ~interactive ~state ({CAst.loc;_} as com) =
if ntip <> `NewTip then
anomaly (str "vernac.ml: We got an unfocus operation on the toplevel!");
- (* Due to bug #5363 we cannot use observe here as we should,
- it otherwise reveals bugs *)
- (* Stm.observe nsid; *)
- let ndoc = if check then Stm.finish ~doc else doc in
+ (* Force the command *)
+ let ndoc = if check then Stm.observe ~doc nsid else doc in
let new_proof = Proof_global.give_me_the_proof_opt () in
{ state with doc = ndoc; sid = nsid; proof = new_proof; }
with reraise ->
@@ -92,51 +90,37 @@ let load_vernac_core ~echo ~check ~interactive ~state file =
let in_echo = if echo then Some (open_utf8_file_in file) else None in
let input_cleanup () = close_in in_chan; Option.iter close_in in_echo in
- let in_pa = Pcoq.Parsable.make ~file:(Loc.InFile file) (Stream.of_channel in_chan) in
- let rstate = ref state in
- (* For beautify, list of parsed sids *)
- let rids = ref [] in
+ let in_pa =
+ Pcoq.Parsable.make ~file:(Loc.InFile file) (Stream.of_channel in_chan) in
let open State in
- try
- (* we go out of the following infinite loop when a End_of_input is
- * raised, which means that we raised the end of the file being loaded *)
- while true do
- let { CAst.loc; _ } as ast =
- Stm.parse_sentence ~doc:!rstate.doc !rstate.sid in_pa
- (* If an error in parsing occurs, we propagate the exception
- so the caller of load_vernac will take care of it. However,
- in the future it could be possible that we want to handle
- all the errors as feedback events, thus in this case we
- should relay the exception here for convenience. A
- possibility is shown below, however we may want to refactor
- this code:
-
- try Stm.parse_sentence !rsid in_pa
- with
- | any when not is_end_of_input any ->
- let (e, info) = CErrors.push any in
- let loc = Loc.get_loc info in
- let msg = CErrors.iprint (e, info) in
- Feedback.msg_error ?loc msg;
- iraise (e, info)
- *)
- in
- (* Printing of vernacs *)
- Option.iter (vernac_echo ?loc) in_echo;
-
- checknav_simple ast;
- let state = Flags.silently (interp_vernac ~check ~interactive ~state:!rstate) ast in
- rids := state.sid :: !rids;
- rstate := state;
- done;
- input_cleanup ();
- !rstate, !rids, Pcoq.Parsable.comment_state in_pa
+
+ (* ids = For beautify, list of parsed sids *)
+ let rec loop state ids =
+ match
+ Stm.parse_sentence
+ ~doc:state.doc ~entry:Pvernac.main_entry state.sid in_pa
+ with
+ | None ->
+ input_cleanup ();
+ state, ids, Pcoq.Parsable.comment_state in_pa
+ | Some (loc, ast) ->
+ let ast = CAst.make ~loc ast in
+
+ (* Printing of AST for -compile-verbose *)
+ Option.iter (vernac_echo ~loc) in_echo;
+
+ checknav_simple ast;
+
+ let state =
+ Flags.silently (interp_vernac ~check ~interactive ~state) ast in
+
+ loop state (state.sid :: ids)
+ in
+ try loop state []
with any -> (* whatever the exception *)
let (e, info) = CErrors.push any in
input_cleanup ();
- match e with
- | Stm.End_of_input -> !rstate, !rids, Pcoq.Parsable.comment_state in_pa
- | reraise -> iraise (e, info)
+ iraise (e, info)
let process_expr ~state loc_ast =
checknav_deep loc_ast;
diff --git a/vernac/classes.ml b/vernac/classes.ml
index 748a2628c5..5cac6af4b2 100644
--- a/vernac/classes.ml
+++ b/vernac/classes.ml
@@ -269,9 +269,9 @@ let do_instance env env' sigma ?hook ~refine ~tac ~global ~poly ~program_mode ct
Pretyping.check_evars env (Evd.from_env env) sigma termtype;
let termtype = to_constr sigma termtype in
let term = Option.map (to_constr ~abort_on_undefined_evars:false sigma) term in
- if not (Evd.has_undefined sigma) && not (Option.is_empty term) then
+ if not (Evd.has_undefined sigma) && not (Option.is_empty props) then
declare_instance_constant k pri global imps ?hook id decl poly sigma (Option.get term) termtype
- else if program_mode || refine || Option.is_empty term then
+ else if program_mode || refine || Option.is_empty props then
declare_instance_open env sigma ?hook ~tac ~program_mode ~global ~poly k id pri imps decl (List.map RelDecl.get_name ctx) term termtype
else CErrors.user_err Pp.(str "Unsolved obligations remaining.");
id
diff --git a/vernac/g_vernac.mlg b/vernac/g_vernac.mlg
index 3bc4aecdb1..79adefdcf7 100644
--- a/vernac/g_vernac.mlg
+++ b/vernac/g_vernac.mlg
@@ -61,7 +61,8 @@ let make_bullet s =
| _ -> assert false
let parse_compat_version = let open Flags in function
- | "8.9" -> Current
+ | "8.10" -> Current
+ | "8.9" -> V8_9
| "8.8" -> V8_8
| "8.7" -> V8_7
| ("8.6" | "8.5" | "8.4" | "8.3" | "8.2" | "8.1" | "8.0") as s ->
diff --git a/vernac/lemmas.ml b/vernac/lemmas.ml
index 8f155adb8a..0dfbba0e83 100644
--- a/vernac/lemmas.ml
+++ b/vernac/lemmas.ml
@@ -340,7 +340,7 @@ let start_proof id ?pl kind sigma ?terminator ?sign ?(compute_guard=[]) ?hook c
| None -> standard_proof_terminator ?hook compute_guard
| Some terminator -> terminator ?hook compute_guard
in
- let sign =
+ let sign =
match sign with
| Some sign -> sign
| None -> initialize_named_context_for_proof ()
diff --git a/vernac/pvernac.ml b/vernac/pvernac.ml
index a647b2ef73..0e46df2320 100644
--- a/vernac/pvernac.ml
+++ b/vernac/pvernac.ml
@@ -12,6 +12,27 @@ open Pcoq
let uvernac = create_universe "vernac"
+type proof_mode = string
+
+(* Tactic parsing modes *)
+let register_proof_mode, find_proof_mode, lookup_proof_mode =
+ let proof_mode : (string, Vernacexpr.vernac_expr Entry.t) Hashtbl.t =
+ Hashtbl.create 19 in
+ let register_proof_mode ename e = Hashtbl.add proof_mode ename e; ename in
+ let find_proof_mode ename =
+ try Hashtbl.find proof_mode ename
+ with Not_found ->
+ CErrors.anomaly Pp.(str "proof mode not found: " ++ str ename) in
+ let lookup_proof_mode name =
+ if Hashtbl.mem proof_mode name then Some name
+ else None
+ in
+ register_proof_mode, find_proof_mode, lookup_proof_mode
+
+let proof_mode_to_string name = name
+
+let command_entry_ref = ref None
+
module Vernac_ =
struct
let gec_vernac s = Entry.create ("vernac:" ^ s)
@@ -39,17 +60,24 @@ module Vernac_ =
] in
Pcoq.grammar_extend main_entry None (None, [None, None, rule])
- let command_entry_ref = ref noedit_mode
+ let select_tactic_entry spec =
+ match spec with
+ | None -> noedit_mode
+ | Some ename -> find_proof_mode ename
+
let command_entry =
Pcoq.Entry.of_parser "command_entry"
- (fun strm -> Pcoq.Entry.parse_token_stream !command_entry_ref strm)
+ (fun strm -> Pcoq.Entry.parse_token_stream (select_tactic_entry !command_entry_ref) strm)
end
-let main_entry = Vernac_.main_entry
+module Unsafe = struct
+ let set_tactic_entry oname = command_entry_ref := oname
+end
-let set_command_entry e = Vernac_.command_entry_ref := e
-let get_command_entry () = !Vernac_.command_entry_ref
+let main_entry proof_mode =
+ Unsafe.set_tactic_entry proof_mode;
+ Vernac_.main_entry
let () =
register_grammar Genredexpr.wit_red_expr (Vernac_.red_expr);
diff --git a/vernac/pvernac.mli b/vernac/pvernac.mli
index b2f8f71462..fa251281dc 100644
--- a/vernac/pvernac.mli
+++ b/vernac/pvernac.mli
@@ -14,6 +14,8 @@ open Vernacexpr
val uvernac : gram_universe
+type proof_mode
+
module Vernac_ :
sig
val gallina : vernac_expr Entry.t
@@ -24,13 +26,31 @@ module Vernac_ :
val rec_definition : (fixpoint_expr * decl_notation list) Entry.t
val noedit_mode : vernac_expr Entry.t
val command_entry : vernac_expr Entry.t
+ val main_entry : (Loc.t * vernac_control) option Entry.t
val red_expr : raw_red_expr Entry.t
val hint_info : Hints.hint_info_expr Entry.t
end
+(* To be removed when the parser is made functional wrt the tactic
+ * non terminal *)
+module Unsafe : sig
+ (* To let third party grammar entries reuse Vernac_ and
+ * do something with the proof mode *)
+ val set_tactic_entry : proof_mode option -> unit
+end
+
(** The main entry: reads an optional vernac command *)
-val main_entry : (Loc.t * vernac_control) option Entry.t
+val main_entry : proof_mode option -> (Loc.t * vernac_control) option Entry.t
+
+(** Grammar entry for tactics: proof mode(s).
+ By default Coq's grammar has an empty entry (non-terminal) for
+ tactics. A plugin can register its non-terminal by providing a name
+ and a grammar entry.
+
+ For example the Ltac plugin register the "Classic" grammar
+ entry for parsing its tactics.
+ *)
-(** Handling of the proof mode entry *)
-val get_command_entry : unit -> vernac_expr Entry.t
-val set_command_entry : vernac_expr Entry.t -> unit
+val register_proof_mode : string -> Vernacexpr.vernac_expr Entry.t -> proof_mode
+val lookup_proof_mode : string -> proof_mode option
+val proof_mode_to_string : proof_mode -> string
diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml
index 26859cd2cf..996fe320f9 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -489,6 +489,28 @@ let vernac_notation ~module_local =
let vernac_custom_entry ~module_local s =
Metasyntax.declare_custom_entry module_local s
+(* Default proof mode, to be set at the beginning of proofs for
+ programs that cannot be statically classified. *)
+let default_proof_mode = ref (Pvernac.register_proof_mode "Noedit" Pvernac.Vernac_.noedit_mode)
+let get_default_proof_mode () = !default_proof_mode
+
+let get_default_proof_mode_opt () = Pvernac.proof_mode_to_string !default_proof_mode
+let set_default_proof_mode_opt name =
+ default_proof_mode :=
+ match Pvernac.lookup_proof_mode name with
+ | Some pm -> pm
+ | None -> CErrors.user_err Pp.(str (Format.sprintf "No proof mode named \"%s\"." name))
+
+let proof_mode_opt_name = ["Default";"Proof";"Mode"]
+let () =
+ Goptions.declare_string_option Goptions.{
+ optdepr = false;
+ optname = "default proof mode" ;
+ optkey = proof_mode_opt_name;
+ optread = get_default_proof_mode_opt;
+ optwrite = set_default_proof_mode_opt;
+ }
+
(***********)
(* Gallina *)
@@ -2115,13 +2137,9 @@ exception End_of_input
let vernac_load interp fname =
if Proof_global.there_are_pending_proofs () then
CErrors.user_err Pp.(str "Load is not supported inside proofs.");
- let interp x =
- let proof_mode = Proof_global.get_default_proof_mode_name () [@ocaml.warning "-3"] in
- Proof_global.activate_proof_mode proof_mode [@ocaml.warning "-3"];
- interp x in
- let parse_sentence = Flags.with_option Flags.we_are_parsing
+ let parse_sentence proof_mode = Flags.with_option Flags.we_are_parsing
(fun po ->
- match Pcoq.Entry.parse Pvernac.main_entry po with
+ match Pcoq.Entry.parse (Pvernac.main_entry proof_mode) po with
| Some x -> x
| None -> raise End_of_input) in
let fname =
@@ -2132,7 +2150,15 @@ let vernac_load interp fname =
let in_chan = open_utf8_file_in longfname in
Pcoq.Parsable.make ~file:(Loc.InFile longfname) (Stream.of_channel in_chan) in
begin
- try while true do interp (snd (parse_sentence input)) done
+ try while true do
+ let proof_mode =
+ if Proof_global.there_are_pending_proofs () then
+ Some (get_default_proof_mode ())
+ else
+ None
+ in
+ interp (snd (parse_sentence proof_mode input));
+ done
with End_of_input -> ()
end;
(* If Load left a proof open, we fail too. *)
@@ -2312,8 +2338,7 @@ let interp ?proof ~atts ~st c =
Aux_file.record_in_aux_at "VernacProof" (tacs^" "^usings);
Option.iter vernac_set_end_tac tac;
Option.iter vernac_set_used_variables using
- | VernacProofMode mn -> unsupported_attributes atts;
- Proof_global.set_proof_mode mn [@ocaml.warning "-3"]
+ | VernacProofMode mn -> unsupported_attributes atts; ()
(* Extensions *)
| VernacExtend (opn,args) ->
diff --git a/vernac/vernacentries.mli b/vernac/vernacentries.mli
index 8d8d7cfcf0..4fbd3849b0 100644
--- a/vernac/vernacentries.mli
+++ b/vernac/vernacentries.mli
@@ -10,6 +10,11 @@
val dump_global : Libnames.qualid Constrexpr.or_by_notation -> unit
+(** Default proof mode set by `start_proof` *)
+val get_default_proof_mode : unit -> Pvernac.proof_mode
+
+val proof_mode_opt_name : string list
+
(** Vernacular entries *)
val vernac_require :
Libnames.qualid option -> bool option -> Libnames.qualid list -> unit
diff --git a/vernac/vernacextend.ml b/vernac/vernacextend.ml
index 05687afd8b..f5cf3401d0 100644
--- a/vernac/vernacextend.ml
+++ b/vernac/vernacextend.ml
@@ -29,15 +29,15 @@ type vernac_type =
parallel : [ `Yes of solving_tac * anon_abstracting_tac | `No ];
proof_block_detection : proof_block_name option
}
- (* To be removed *)
- | VtProofMode of string
(* Queries are commands assumed to be "pure", that is to say, they
don't modify the interpretation state. *)
| VtQuery
+ (* Commands that change the current proof mode *)
+ | VtProofMode of string
(* To be removed *)
| VtMeta
| VtUnknown
-and vernac_start = string * opacity_guarantee * Names.Id.t list
+and vernac_start = opacity_guarantee * Names.Id.t list
and vernac_sideff_type = Names.Id.t list
and opacity_guarantee =
| GuaranteesOpacity (** Only generates opaque terms at [Qed] *)
diff --git a/vernac/vernacextend.mli b/vernac/vernacextend.mli
index 0d43eb1ee8..118907c31b 100644
--- a/vernac/vernacextend.mli
+++ b/vernac/vernacextend.mli
@@ -45,15 +45,15 @@ type vernac_type =
parallel : [ `Yes of solving_tac * anon_abstracting_tac | `No ];
proof_block_detection : proof_block_name option
}
- (* To be removed *)
- | VtProofMode of string
(* Queries are commands assumed to be "pure", that is to say, they
don't modify the interpretation state. *)
| VtQuery
+ (* Commands that change the current proof mode *)
+ | VtProofMode of string
(* To be removed *)
| VtMeta
| VtUnknown
-and vernac_start = string * opacity_guarantee * Names.Id.t list
+and vernac_start = opacity_guarantee * Names.Id.t list
and vernac_sideff_type = Names.Id.t list
and opacity_guarantee =
| GuaranteesOpacity (** Only generates opaque terms at [Qed] *)
diff --git a/vernac/vernacstate.ml b/vernac/vernacstate.ml
index 61540024ef..c691dc8559 100644
--- a/vernac/vernacstate.ml
+++ b/vernac/vernacstate.ml
@@ -8,10 +8,30 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+module Parser = struct
+
+ type state = Pcoq.frozen_t
+
+ let init () = Pcoq.freeze ~marshallable:false
+
+ let cur_state () = Pcoq.freeze ~marshallable:false
+
+ let parse ps entry pa =
+ Pcoq.unfreeze ps;
+ Flags.with_option Flags.we_are_parsing (fun () ->
+ try Pcoq.Entry.parse entry pa
+ with e when CErrors.noncritical e ->
+ let (e, info) = CErrors.push e in
+ Exninfo.iraise (e, info))
+ ()
+
+end
+
type t = {
- system : States.state; (* summary + libstack *)
- proof : Proof_global.t; (* proof state *)
- shallow : bool (* is the state trimmed down (libstack) *)
+ parsing: Parser.state;
+ system : States.state; (* summary + libstack *)
+ proof : Proof_global.t; (* proof state *)
+ shallow : bool; (* is the state trimmed down (libstack) *)
}
let s_cache = ref None
@@ -37,11 +57,13 @@ let freeze_interp_state ~marshallable =
{ system = update_cache s_cache (States.freeze ~marshallable);
proof = update_cache s_proof (Proof_global.freeze ~marshallable);
shallow = false;
+ parsing = Parser.cur_state ();
}
-let unfreeze_interp_state { system; proof } =
+let unfreeze_interp_state { system; proof; parsing } =
do_if_not_cached s_cache States.unfreeze system;
- do_if_not_cached s_proof Proof_global.unfreeze proof
+ do_if_not_cached s_proof Proof_global.unfreeze proof;
+ Pcoq.unfreeze parsing
let make_shallow st =
let lib = States.lib_of_state st.system in
diff --git a/vernac/vernacstate.mli b/vernac/vernacstate.mli
index ed20cb935a..581c23386a 100644
--- a/vernac/vernacstate.mli
+++ b/vernac/vernacstate.mli
@@ -8,10 +8,21 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
+module Parser : sig
+ type state
+
+ val init : unit -> state
+ val cur_state : unit -> state
+
+ val parse : state -> 'a Pcoq.Entry.t -> Pcoq.Parsable.t -> 'a
+
+end
+
type t = {
- system : States.state; (* summary + libstack *)
- proof : Proof_global.t; (* proof state *)
- shallow : bool (* is the state trimmed down (libstack) *)
+ parsing: Parser.state;
+ system : States.state; (* summary + libstack *)
+ proof : Proof_global.t; (* proof state *)
+ shallow : bool; (* is the state trimmed down (libstack) *)
}
val freeze_interp_state : marshallable:bool -> t