aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--azure-pipelines.yml2
-rw-r--r--clib/cString.ml8
-rw-r--r--clib/cString.mli8
-rw-r--r--configure.ml5
-rw-r--r--default.nix2
-rw-r--r--dev/ci/nix/bignums.nix2
-rw-r--r--dev/ci/nix/unicoq/unicoq-num.patch31
-rw-r--r--dev/ci/user-overlays/08893-herbelin-master+moving-evars-of-term-on-econstr.sh7
-rw-r--r--dev/ci/user-overlays/10076-vbgl-canonical-disable-hint.sh6
-rw-r--r--dev/ci/user-overlays/10125-SkySkimmer-run_tactic_gen.sh6
-rw-r--r--dev/ci/user-overlays/10135-maximedenes-detype-anonymous.sh6
-rw-r--r--dev/doc/changes.md7
-rw-r--r--dev/doc/release-process.md22
-rw-r--r--dev/include_printers1
-rw-r--r--dev/nixpkgs.nix4
-rw-r--r--dev/top_printers.dbg1
-rw-r--r--dev/top_printers.ml10
-rw-r--r--dev/top_printers.mli1
-rw-r--r--doc/changelog/02-specification-language/10076-not-canonical-projection.rst4
-rw-r--r--doc/changelog/04-tactics/09996-hint-mode.rst5
-rw-r--r--doc/changelog/04-tactics/10059-change-no-check.rst7
-rw-r--r--doc/changelog/06-ssreflect/09995-notations.rst8
-rw-r--r--doc/changelog/07-commands-and-options/09530-rm-unknown.rst6
-rw-r--r--doc/changelog/10-standard-library/09984-pairusualdecidabletypefull.rst3
-rw-r--r--doc/changelog/12-misc/09964-changes.rst13
-rw-r--r--doc/sphinx/README.rst9
-rw-r--r--doc/sphinx/README.template.rst7
-rw-r--r--doc/sphinx/_static/coqnotations.sty29
-rw-r--r--doc/sphinx/_static/notations.css37
-rw-r--r--doc/sphinx/addendum/canonical-structures.rst13
-rw-r--r--doc/sphinx/addendum/extraction.rst2
-rw-r--r--doc/sphinx/addendum/generalized-rewriting.rst25
-rw-r--r--doc/sphinx/addendum/program.rst2
-rw-r--r--doc/sphinx/addendum/type-classes.rst39
-rw-r--r--doc/sphinx/changes.rst74
-rwxr-xr-xdoc/sphinx/conf.py2
-rw-r--r--doc/sphinx/language/gallina-extensions.rst43
-rw-r--r--doc/sphinx/language/gallina-specification-language.rst26
-rw-r--r--doc/sphinx/practical-tools/coqide.rst9
-rw-r--r--doc/sphinx/proof-engine/detailed-tactic-examples.rst378
-rw-r--r--doc/sphinx/proof-engine/ltac.rst446
-rw-r--r--doc/sphinx/proof-engine/ltac2.rst10
-rw-r--r--doc/sphinx/proof-engine/proof-handling.rst12
-rw-r--r--doc/sphinx/proof-engine/ssreflect-proof-language.rst22
-rw-r--r--doc/sphinx/proof-engine/tactics.rst84
-rw-r--r--doc/sphinx/proof-engine/vernacular-commands.rst32
-rw-r--r--doc/sphinx/user-extensions/proof-schemes.rst27
-rw-r--r--doc/sphinx/user-extensions/syntax-extensions.rst38
-rw-r--r--doc/tools/coqrst/coqdomain.py43
-rw-r--r--doc/tools/coqrst/notations/TacticNotations.g29
-rw-r--r--doc/tools/coqrst/notations/TacticNotations.tokens24
-rw-r--r--doc/tools/coqrst/notations/TacticNotationsLexer.py82
-rw-r--r--doc/tools/coqrst/notations/TacticNotationsLexer.tokens24
-rw-r--r--doc/tools/coqrst/notations/TacticNotationsParser.py624
-rw-r--r--doc/tools/coqrst/notations/TacticNotationsVisitor.py36
-rw-r--r--doc/tools/coqrst/notations/html.py25
-rw-r--r--doc/tools/coqrst/notations/parsing.py18
-rw-r--r--doc/tools/coqrst/notations/plain.py17
-rw-r--r--doc/tools/coqrst/notations/sphinx.py46
-rw-r--r--engine/evarutil.ml33
-rw-r--r--engine/evarutil.mli9
-rw-r--r--engine/evd.ml56
-rw-r--r--engine/evd.mli14
-rw-r--r--engine/ftactic.ml7
-rw-r--r--engine/ftactic.mli3
-rw-r--r--engine/proofview.ml13
-rw-r--r--engine/proofview.mli6
-rw-r--r--engine/termops.ml20
-rw-r--r--engine/termops.mli24
-rw-r--r--engine/uState.ml2
-rw-r--r--engine/uState.mli3
-rw-r--r--engine/univGen.ml42
-rw-r--r--engine/univGen.mli27
-rw-r--r--ide/coqide.ml8
-rw-r--r--ide/ide.mllib2
-rw-r--r--ide/microPG.ml (renamed from ide/nanoPG.ml)42
-rw-r--r--ide/microPG.mli (renamed from ide/nanoPG.mli)0
-rw-r--r--ide/preferences.ml5
-rw-r--r--ide/preferences.mli2
-rw-r--r--interp/constrextern.ml4
-rw-r--r--interp/constrintern.ml2
-rw-r--r--interp/impargs.ml62
-rw-r--r--interp/impargs.mli4
-rw-r--r--interp/implicit_quantifiers.ml2
-rw-r--r--kernel/byterun/coq_interp.c21
-rw-r--r--kernel/entries.ml14
-rw-r--r--kernel/indtypes.ml17
-rw-r--r--kernel/indtypes.mli19
-rw-r--r--kernel/modops.ml6
-rw-r--r--kernel/names.ml3
-rw-r--r--kernel/names.mli3
-rw-r--r--kernel/opaqueproof.ml29
-rw-r--r--kernel/opaqueproof.mli4
-rw-r--r--kernel/safe_typing.ml119
-rw-r--r--kernel/safe_typing.mli12
-rw-r--r--lib/acyclicGraph.ml5
-rw-r--r--lib/rtree.ml5
-rw-r--r--lib/rtree.mli6
-rw-r--r--library/global.ml5
-rw-r--r--library/global.mli8
-rw-r--r--library/globnames.ml12
-rw-r--r--library/globnames.mli18
-rw-r--r--library/lib.ml4
-rw-r--r--library/nametab.ml17
-rw-r--r--library/nametab.mli16
-rw-r--r--plugins/derive/derive.ml5
-rw-r--r--plugins/funind/recdef.ml30
-rw-r--r--plugins/ltac/g_rewrite.mlg2
-rw-r--r--plugins/ltac/rewrite.ml2
-rw-r--r--plugins/micromega/coq_micromega.ml2
-rw-r--r--plugins/ssr/ssrequality.ml4
-rw-r--r--plugins/ssr/ssrview.ml4
-rw-r--r--plugins/ssrmatching/ssrmatching.ml8
-rw-r--r--pretyping/detyping.ml13
-rw-r--r--pretyping/detyping.mli3
-rw-r--r--pretyping/evarconv.ml25
-rw-r--r--pretyping/evarconv.mli13
-rw-r--r--pretyping/recordops.ml54
-rw-r--r--pretyping/recordops.mli10
-rw-r--r--printing/printmod.ml2
-rw-r--r--proofs/pfedit.ml4
-rw-r--r--proofs/proof.ml72
-rw-r--r--proofs/proof.mli49
-rw-r--r--proofs/proof_global.ml2
-rw-r--r--proofs/refine.ml14
-rw-r--r--proofs/tacmach.ml4
-rw-r--r--proofs/tacmach.mli2
-rw-r--r--stm/proofBlockDelimiter.ml4
-rw-r--r--stm/stm.ml58
-rw-r--r--stm/vernac_classifier.ml36
-rw-r--r--tactics/abstract.ml2
-rw-r--r--tactics/equality.ml2
-rw-r--r--tactics/ind_tables.ml20
-rw-r--r--tactics/leminv.ml5
-rw-r--r--tactics/ppred.mli5
-rw-r--r--tactics/tactics.ml152
-rw-r--r--tactics/tactics.mli1
-rw-r--r--test-suite/bugs/closed/bug_10026.v3
-rw-r--r--test-suite/bugs/closed/bug_10189.v9
-rw-r--r--test-suite/bugs/closed/bug_3754.v (renamed from test-suite/bugs/opened/bug_3754.v)4
-rw-r--r--test-suite/bugs/closed/bug_3890.v12
-rw-r--r--test-suite/bugs/closed/bug_4429.v31
-rw-r--r--test-suite/bugs/closed/bug_4580.v1
-rw-r--r--test-suite/bugs/closed/bug_4638.v12
-rw-r--r--test-suite/bugs/opened/bug_3890.v22
-rw-r--r--test-suite/dune2
-rwxr-xr-xtest-suite/misc/changelog.sh18
-rw-r--r--test-suite/output/Notations4.out10
-rw-r--r--test-suite/output/Notations4.v1
-rw-r--r--test-suite/success/Notations2.v4
-rw-r--r--test-suite/success/Typeclasses.v4
-rw-r--r--test-suite/success/attribute_syntax.v4
-rw-r--r--theories/Compat/Coq89.v1
-rw-r--r--toplevel/coqargs.ml7
-rw-r--r--toplevel/coqtop.ml26
-rw-r--r--toplevel/usage.ml14
-rw-r--r--user-contrib/Ltac2/Constr.v1
-rw-r--r--user-contrib/Ltac2/Init.v1
-rw-r--r--user-contrib/Ltac2/tac2core.ml7
-rw-r--r--user-contrib/Ltac2/tac2entries.ml7
-rw-r--r--user-contrib/Ltac2/tac2ffi.ml23
-rw-r--r--user-contrib/Ltac2/tac2ffi.mli6
-rw-r--r--vernac/attributes.ml33
-rw-r--r--vernac/attributes.mli1
-rw-r--r--vernac/classes.ml25
-rw-r--r--vernac/classes.mli1
-rw-r--r--vernac/comDefinition.ml7
-rw-r--r--vernac/comProgramFixpoint.ml19
-rw-r--r--vernac/g_vernac.mlg12
-rw-r--r--vernac/himsg.ml3
-rw-r--r--vernac/himsg.mli5
-rw-r--r--vernac/lemmas.ml14
-rw-r--r--vernac/metasyntax.ml8
-rw-r--r--vernac/metasyntax.mli1
-rw-r--r--vernac/obligations.ml36
-rw-r--r--vernac/obligations.mli4
-rw-r--r--vernac/ppvernac.ml2
-rw-r--r--vernac/record.ml26
-rw-r--r--vernac/record.mli9
-rw-r--r--vernac/topfmt.ml2
-rw-r--r--vernac/vernacentries.ml3
-rw-r--r--vernac/vernacexpr.ml2
-rw-r--r--vernac/vernacextend.ml1
-rw-r--r--vernac/vernacextend.mli1
184 files changed, 2230 insertions, 2068 deletions
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index f2cec1eb19..c93920a884 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -43,7 +43,7 @@ jobs:
vmImage: 'macOS-10.13'
variables:
- MACOSX_DEPLOYMENT_TARGET: '10.12'
+ MACOSX_DEPLOYMENT_TARGET: '10.11'
steps:
- checkout: self
diff --git a/clib/cString.ml b/clib/cString.ml
index 111be3da82..423c08da13 100644
--- a/clib/cString.ml
+++ b/clib/cString.ml
@@ -17,16 +17,12 @@ sig
val is_empty : string -> bool
val explode : string -> string list
val implode : string list -> string
- val strip : string -> string
- [@@ocaml.deprecated "Use [trim]"]
val drop_simple_quotes : string -> string
val string_index_from : string -> int -> string -> int
val string_contains : where:string -> what:string -> bool
val plural : int -> string -> string
val conjugate_verb_to_be : int -> string
val ordinal : int -> string
- val split : char -> string -> string list
- [@@ocaml.deprecated "Use [split_on_char]"]
val is_sub : string -> string -> int -> bool
module Set : Set.S with type elt = t
module Map : CMap.ExtS with type key = t and module Set := Set
@@ -59,8 +55,6 @@ let implode sl = String.concat "" sl
let is_empty s = String.length s = 0
-let strip = String.trim
-
let drop_simple_quotes s =
let n = String.length s in
if n > 2 && s.[0] = '\'' && s.[n-1] = '\'' then String.sub s 1 (n-2) else s
@@ -124,8 +118,6 @@ let ordinal n =
(* string parsing *)
-let split = String.split_on_char
-
module Self =
struct
type t = string
diff --git a/clib/cString.mli b/clib/cString.mli
index 364b6a34b1..f68bd3bb65 100644
--- a/clib/cString.mli
+++ b/clib/cString.mli
@@ -30,10 +30,6 @@ sig
val implode : string list -> string
(** [implode [s1; ...; sn]] returns [s1 ^ ... ^ sn] *)
- val strip : string -> string
- [@@ocaml.deprecated "Use [trim]"]
- (** Alias for [String.trim] *)
-
val drop_simple_quotes : string -> string
(** Remove the eventual first surrounding simple quotes of a string. *)
@@ -52,10 +48,6 @@ sig
val ordinal : int -> string
(** Generate the ordinal number in English. *)
- val split : char -> string -> string list
- [@@ocaml.deprecated "Use [split_on_char]"]
- (** [split c s] alias of [String.split_on_char] *)
-
val is_sub : string -> string -> int -> bool
(** [is_sub p s off] tests whether [s] contains [p] at offset [off]. *)
diff --git a/configure.ml b/configure.ml
index 5b99851f83..57f31fec4c 100644
--- a/configure.ml
+++ b/configure.ml
@@ -17,6 +17,7 @@ let coq_macos_version = "8.9.90" (** "[...] should be a string comprised of
three non-negative, period-separated integers [...]" *)
let vo_magic = 8991
let state_magic = 58991
+let is_a_released_version = false
let distributed_exec =
["coqtop.opt"; "coqidetop.opt"; "coqqueryworker.opt"; "coqproofworker.opt"; "coqtacticworker.opt";
"coqc.opt";"coqchk";"coqdoc";"coqworkmgr";"coq_makefile";"coq-tex";"coqwc";"csdpcert";"coqdep"]
@@ -1205,8 +1206,8 @@ let write_configpy f =
safe_remove f;
let o = open_out f in
let pr s = fprintf o s in
- let pr_s = pr "%s = '%s'\n" in
pr "# DO NOT EDIT THIS FILE: automatically generated by ../configure\n";
- pr_s "version" coq_version
+ pr "version = '%s'\n" coq_version;
+ pr "is_a_released_version = %s\n" (if is_a_released_version then "True" else "False")
let _ = write_configpy "config/coq_config.py"
diff --git a/default.nix b/default.nix
index 1e2cb3625d..d5c6cdb8ad 100644
--- a/default.nix
+++ b/default.nix
@@ -74,7 +74,7 @@ stdenv.mkDerivation rec {
else
with builtins; filterSource
(path: _:
- !elem (baseNameOf path) [".git" "result" "bin" "_build" "_build_ci"]) ./.;
+ !elem (baseNameOf path) [".git" "result" "bin" "_build" "_build_ci" "nix"]) ./.;
preConfigure = ''
patchShebangs dev/tools/
diff --git a/dev/ci/nix/bignums.nix b/dev/ci/nix/bignums.nix
index 1d931c858e..d813ddd8d7 100644
--- a/dev/ci/nix/bignums.nix
+++ b/dev/ci/nix/bignums.nix
@@ -1,5 +1,5 @@
{ ocamlPackages }:
{
- buildInputs = with ocamlPackages; [ ocaml findlib camlp5 ];
+ buildInputs = [ ocamlPackages.ocaml ];
}
diff --git a/dev/ci/nix/unicoq/unicoq-num.patch b/dev/ci/nix/unicoq/unicoq-num.patch
index 6d96d94dfc..6d2f6470b1 100644
--- a/dev/ci/nix/unicoq/unicoq-num.patch
+++ b/dev/ci/nix/unicoq/unicoq-num.patch
@@ -4,19 +4,6 @@ Date: Thu Nov 29 08:59:22 2018 +0000
Make explicit dependency to num
-diff --git a/Make b/Make
-index 550dc6a..8aa1309 100644
---- a/Make
-+++ b/Make
-@@ -9,7 +9,7 @@ src/logger.ml
- src/munify.mli
- src/munify.ml
- src/unitactics.mlg
--src/unicoq.mllib
-+src/unicoq.mlpack
- theories/Unicoq.v
- test-suite/munifytest.v
- test-suite/microtests.v
diff --git a/Makefile.local b/Makefile.local
new file mode 100644
index 0000000..88be365
@@ -24,21 +11,3 @@ index 0000000..88be365
+++ b/Makefile.local
@@ -0,0 +1 @@
+CAMLPKGS += -package num
-diff --git a/src/unicoq.mllib b/src/unicoq.mllib
-deleted file mode 100644
-index 2b84e2d..0000000
---- a/src/unicoq.mllib
-+++ /dev/null
-@@ -1,3 +0,0 @@
--Logger
--Munify
--Unitactics
-diff --git a/src/unicoq.mlpack b/src/unicoq.mlpack
-new file mode 100644
-index 0000000..2b84e2d
---- /dev/null
-+++ b/src/unicoq.mlpack
-@@ -0,0 +1,3 @@
-+Logger
-+Munify
-+Unitactics
diff --git a/dev/ci/user-overlays/08893-herbelin-master+moving-evars-of-term-on-econstr.sh b/dev/ci/user-overlays/08893-herbelin-master+moving-evars-of-term-on-econstr.sh
new file mode 100644
index 0000000000..dc39ea5ef0
--- /dev/null
+++ b/dev/ci/user-overlays/08893-herbelin-master+moving-evars-of-term-on-econstr.sh
@@ -0,0 +1,7 @@
+if [ "$CI_PULL_REQUEST" = "8893" ] || [ "$CI_BRANCH" = "master+moving-evars-of-term-on-econstr" ]; then
+
+ equations_CI_BRANCH=master+fix-evars_of_term-pr8893
+ equations_CI_REF=master+fix-evars_of_term-pr8893
+ equations_CI_GITURL=https://github.com/herbelin/Coq-Equations
+
+fi
diff --git a/dev/ci/user-overlays/10076-vbgl-canonical-disable-hint.sh b/dev/ci/user-overlays/10076-vbgl-canonical-disable-hint.sh
new file mode 100644
index 0000000000..2015935dd9
--- /dev/null
+++ b/dev/ci/user-overlays/10076-vbgl-canonical-disable-hint.sh
@@ -0,0 +1,6 @@
+if [ "$CI_PULL_REQUEST" = "10076" ] || [ "$CI_BRANCH" = "canonical-disable-hint" ]; then
+
+ elpi_CI_REF=canonical-disable-hint
+ elpi_CI_GITURL=https://github.com/vbgl/coq-elpi
+
+fi
diff --git a/dev/ci/user-overlays/10125-SkySkimmer-run_tactic_gen.sh b/dev/ci/user-overlays/10125-SkySkimmer-run_tactic_gen.sh
new file mode 100644
index 0000000000..4032b1c6b5
--- /dev/null
+++ b/dev/ci/user-overlays/10125-SkySkimmer-run_tactic_gen.sh
@@ -0,0 +1,6 @@
+if [ "$CI_PULL_REQUEST" = "10125" ] || [ "$CI_BRANCH" = "run_tactic_gen" ]; then
+
+ paramcoq_CI_REF=run_tactic_gen
+ paramcoq_CI_GITURL=https://github.com/SkySkimmer/paramcoq
+
+fi
diff --git a/dev/ci/user-overlays/10135-maximedenes-detype-anonymous.sh b/dev/ci/user-overlays/10135-maximedenes-detype-anonymous.sh
new file mode 100644
index 0000000000..bc8aa33565
--- /dev/null
+++ b/dev/ci/user-overlays/10135-maximedenes-detype-anonymous.sh
@@ -0,0 +1,6 @@
+if [ "$CI_PULL_REQUEST" = "10135" ] || [ "$CI_BRANCH" = "detype-anonymous" ]; then
+
+ unicoq_CI_REF=detype-anonymous
+ unicoq_CI_GITURL=https://github.com/maximedenes/unicoq
+
+fi
diff --git a/dev/doc/changes.md b/dev/doc/changes.md
index 9e0d47651e..7221c3de56 100644
--- a/dev/doc/changes.md
+++ b/dev/doc/changes.md
@@ -1,3 +1,10 @@
+## Changes between Coq 8.10 and Coq 8.11
+
+### ML API
+
+- Functions and types deprecated in 8.10 have been removed in Coq
+ 8.11.
+
## Changes between Coq 8.9 and Coq 8.10
### ML4 Pre Processing
diff --git a/dev/doc/release-process.md b/dev/doc/release-process.md
index 60c0886896..189d6f9fa5 100644
--- a/dev/doc/release-process.md
+++ b/dev/doc/release-process.md
@@ -84,10 +84,18 @@
Coq has been tagged.
- [ ] Have some people test the recently auto-generated Windows and MacOS
packages.
-- [ ] Change the version name from alpha to beta1 (see
+- [ ] In a PR:
+ - Change the version name from alpha to beta1 (see
[#7009](https://github.com/coq/coq/pull/7009/files)).
- We generally do not update the magic numbers at this point.
+ - We generally do not update the magic numbers at this point.
+ - Set `is_a_released_version` to `true` in `configure.ml`.
- [ ] Put the `VX.X+beta1` tag using `git tag -s`.
+- [ ] Check using `git push --tags --dry-run` that you are not
+ pushing anything else than the new tag. If needed, remove spurious
+ tags with `git tag -d`. When this is OK, proceed with `git push --tags`.
+- [ ] Set `is_a_released_version` to `false` in `configure.ml`
+ (if you forget about it, you'll be reminded whenever you try to
+ backport a PR with a changelog entry).
### These steps are the same for all releases (beta, final, patch-level) ###
@@ -112,9 +120,17 @@
## At the final release time ##
-- [ ] Change the version name to X.X.0 and the magic numbers (see
+- [ ] In a PR:
+ - Change the version name from X.X.0 and the magic numbers (see
[#7271](https://github.com/coq/coq/pull/7271/files)).
+ - Set `is_a_released_version` to `true` in `configure.ml`.
- [ ] Put the `VX.X.0` tag.
+- [ ] Check using `git push --tags --dry-run` that you are not
+ pushing anything else than the new tag. If needed, remove spurious
+ tags with `git tag -d`. When this is OK, proceed with `git push --tags`.
+- [ ] Set `is_a_released_version` to `false` in `configure.ml`
+ (if you forget about it, you'll be reminded whenever you try to
+ backport a PR with a changelog entry).
Repeat the generic process documented above for all releases.
diff --git a/dev/include_printers b/dev/include_printers
index 90088e40bf..d077075eeb 100644
--- a/dev/include_printers
+++ b/dev/include_printers
@@ -11,6 +11,7 @@
#install_printer (* universes *) ppuniverses;;
#install_printer (* univ level *) ppuni_level;;
#install_printer (* univ context *) ppuniverse_context;;
+#install_printer (* univ context *) ppaucontext;;
#install_printer (* univ context future *) ppuniverse_context_future;;
#install_printer (* univ context set *) ppuniverse_context_set;;
#install_printer (* univ set *) ppuniverse_set;;
diff --git a/dev/nixpkgs.nix b/dev/nixpkgs.nix
index f4786d9431..8dfe1e7833 100644
--- a/dev/nixpkgs.nix
+++ b/dev/nixpkgs.nix
@@ -1,4 +1,4 @@
import (fetchTarball {
- url = "https://github.com/NixOS/nixpkgs/archive/8471ab76242987b11afd4486b82888e1588f8307.tar.gz";
- sha256 = "06pp6b6x78jlinxifnphkbp79dx58jr990fkm4qziq0ay5klpxd7";
+ url = "https://github.com/NixOS/nixpkgs/archive/bc9df0f66110039e495b6debe3a6cda4a1bb0fed.tar.gz";
+ sha256 = "0y2w259j0vqiwjhjvlbsaqnp1nl2zwz6sbwwhkrqn7k7fmhmxnq1";
})
diff --git a/dev/top_printers.dbg b/dev/top_printers.dbg
index a6ecec7e33..82f2e79549 100644
--- a/dev/top_printers.dbg
+++ b/dev/top_printers.dbg
@@ -62,6 +62,7 @@ install_printer Top_printers.ppuni_level
install_printer Top_printers.ppuniverse_set
install_printer Top_printers.ppuniverse_instance
install_printer Top_printers.ppuniverse_context
+install_printer Top_printers.ppaucontext
install_printer Top_printers.ppuniverse_context_set
install_printer Top_printers.ppuniverse_subst
install_printer Top_printers.ppuniverse_opt_subst
diff --git a/dev/top_printers.ml b/dev/top_printers.ml
index 816316487c..2859b56cbe 100644
--- a/dev/top_printers.ml
+++ b/dev/top_printers.ml
@@ -27,7 +27,6 @@ open Clenv
let _ = Detyping.print_evar_arguments := true
let _ = Detyping.print_universes := true
let _ = Goptions.set_bool_option_value ["Printing";"Matching"] false
-let _ = Detyping.set_detype_anonymous (fun ?loc _ -> raise Not_found)
(* std_ppcmds *)
let pp x = Pp.pp_with !Topfmt.std_ft x
@@ -236,6 +235,15 @@ let ppnamedcontextval e =
let sigma = Evd.from_env env in
pp (pr_named_context env sigma (named_context_of_val e))
+let ppaucontext auctx =
+ let nas = AUContext.names auctx in
+ let prlev l = match Level.var_index l with
+ | Some n -> Name.print nas.(n)
+ | None -> prlev l
+ in
+ pp (pr_universe_context prlev (AUContext.repr auctx))
+
+
let ppenv e = pp
(str "[" ++ pr_named_context_of e Evd.empty ++ str "]" ++ spc() ++
str "[" ++ pr_rel_context e Evd.empty (rel_context e) ++ str "]")
diff --git a/dev/top_printers.mli b/dev/top_printers.mli
index cb32d2294c..2aa1808322 100644
--- a/dev/top_printers.mli
+++ b/dev/top_printers.mli
@@ -137,6 +137,7 @@ val prlev : Univ.Level.t -> Pp.t (* with global names (does this work?) *)
val ppuniverse_set : Univ.LSet.t -> unit
val ppuniverse_instance : Univ.Instance.t -> unit
val ppuniverse_context : Univ.UContext.t -> unit
+val ppaucontext : Univ.AUContext.t -> unit
val ppuniverse_context_set : Univ.ContextSet.t -> unit
val ppuniverse_subst : Univ.universe_subst -> unit
val ppuniverse_opt_subst : UnivSubst.universe_opt_subst -> unit
diff --git a/doc/changelog/02-specification-language/10076-not-canonical-projection.rst b/doc/changelog/02-specification-language/10076-not-canonical-projection.rst
new file mode 100644
index 0000000000..0a902079b9
--- /dev/null
+++ b/doc/changelog/02-specification-language/10076-not-canonical-projection.rst
@@ -0,0 +1,4 @@
+- Record fields can be annotated to prevent them from being used as canonical projections;
+ see :ref:`canonicalstructures` for details
+ (`#10076 <https://github.com/coq/coq/pull/10076>`_,
+ by Vincent Laporte).
diff --git a/doc/changelog/04-tactics/09996-hint-mode.rst b/doc/changelog/04-tactics/09996-hint-mode.rst
deleted file mode 100644
index 06e9059b45..0000000000
--- a/doc/changelog/04-tactics/09996-hint-mode.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-- Modes are now taken into account by :tacn:`typeclasses eauto` for
- local hypotheses
- (`#9996 <https://github.com/coq/coq/pull/9996>`_,
- fixes `#5752 <https://github.com/coq/coq/issues/5752>`_,
- by Maxime Dénès, review by Pierre-Marie Pédrot).
diff --git a/doc/changelog/04-tactics/10059-change-no-check.rst b/doc/changelog/04-tactics/10059-change-no-check.rst
deleted file mode 100644
index 987b2a8ccd..0000000000
--- a/doc/changelog/04-tactics/10059-change-no-check.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-- New variant :tacn:`change_no_check` of :tacn:`change`, usable as a
- documented replacement of :tacn:`convert_concl_no_check`
- (`#10012 <https://github.com/coq/coq/pull/10012>`_,
- `#10017 <https://github.com/coq/coq/pull/10017>`_,
- `#10053 <https://github.com/coq/coq/pull/10053>`_, and
- `#10059 <https://github.com/coq/coq/pull/10059>`_,
- by Hugo Herbelin and Paolo G. Giarrusso).
diff --git a/doc/changelog/06-ssreflect/09995-notations.rst b/doc/changelog/06-ssreflect/09995-notations.rst
deleted file mode 100644
index 3dfc45242d..0000000000
--- a/doc/changelog/06-ssreflect/09995-notations.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-- `inE` now expands `y \in r x` when `r` is a `simpl_rel`.
- New `{pred T}` notation for a `pred T` alias in the `pred_sort` coercion
- class, simplified `predType` interface: `pred_class` and `mkPredType`
- deprecated, `{pred T}` and `PredType` should be used instead.
- `if c return t then ...` now expects `c` to be a variable bound in `t`.
- New `nonPropType` interface matching types that do _not_ have sort `Prop`.
- New `relpre R f` definition for the preimage of a relation R under f
- (`#9995 <https://github.com/coq/coq/pull/9995>`_, by Georges Gonthier).
diff --git a/doc/changelog/07-commands-and-options/09530-rm-unknown.rst b/doc/changelog/07-commands-and-options/09530-rm-unknown.rst
new file mode 100644
index 0000000000..78874cadb1
--- /dev/null
+++ b/doc/changelog/07-commands-and-options/09530-rm-unknown.rst
@@ -0,0 +1,6 @@
+- Deprecated flag `Refine Instance Mode` has been removed.
+ (`#09530 <https://github.com/coq/coq/pull/09530>`_, fixes
+ `#3632 <https://github.com/coq/coq/issues/3632>`_, `#3890
+ <https://github.com/coq/coq/issues/3890>`_ and `#4638
+ <https://github.com/coq/coq/issues/4638>`_
+ by Maxime Dénès, review by Gaëtan Gilbert).
diff --git a/doc/changelog/10-standard-library/09984-pairusualdecidabletypefull.rst b/doc/changelog/10-standard-library/09984-pairusualdecidabletypefull.rst
deleted file mode 100644
index 732c088f45..0000000000
--- a/doc/changelog/10-standard-library/09984-pairusualdecidabletypefull.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-- Added :g:`Coq.Structures.EqualitiesFacts.PairUsualDecidableTypeFull`
- (`#9984 <https://github.com/coq/coq/pull/9984>`_,
- by Jean-Christophe Léchenet and Oliver Nash).
diff --git a/doc/changelog/12-misc/09964-changes.rst b/doc/changelog/12-misc/09964-changes.rst
deleted file mode 100644
index 1113782180..0000000000
--- a/doc/changelog/12-misc/09964-changes.rst
+++ /dev/null
@@ -1,13 +0,0 @@
-- Changelog has been moved from a specific file `CHANGES.md` to the
- reference manual; former Credits chapter of the reference manual has
- been split in two parts: a History chapter which was enriched with
- additional historical information about Coq versions 1 to 5, and a
- Changes chapter which was enriched with the content formerly in
- `CHANGES.md` and `COMPATIBILITY`
- (`#9133 <https://github.com/coq/coq/pull/9133>`_,
- `#9668 <https://github.com/coq/coq/pull/9668>`_,
- `#9939 <https://github.com/coq/coq/pull/9939>`_,
- `#9964 <https://github.com/coq/coq/pull/9964>`_,
- by Théo Zimmermann,
- with help and ideas from Emilio Jesús Gallego Arias,
- Clément Pit-Claudel, Matthieu Sozeau, and Enrico Tassi).
diff --git a/doc/sphinx/README.rst b/doc/sphinx/README.rst
index 881f7a310d..b20669c7f1 100644
--- a/doc/sphinx/README.rst
+++ b/doc/sphinx/README.rst
@@ -60,8 +60,11 @@ The signatures of most objects can be written using a succinct DSL for Coq notat
``{*, …}``, ``{+, …}``
an optional or mandatory repeatable block, with repetitions separated by commas
-``%|``, ``%{``, …
- an escaped character (rendered without the leading ``%``)
+``{| … | … | … }``
+ an alternative, indicating than one of multiple constructs can be used
+
+``%{``, ``%}``, ``%|``
+ an escaped character (rendered without the leading ``%``). In most cases, escaping is not necessary. In particular, the following expressions are all parsed as plain text, and do not need escaping: ``{ xyz }``, ``x |- y``. But the following escapes *are* needed: ``{| a b %| c | d }``, ``all: %{``. (We use ``%`` instead of the usual ``\`` because you'd have to type ``\`` twice in your reStructuredText file.)
..
FIXME document the new subscript support
@@ -148,7 +151,7 @@ Here is the list of all objects of the Coq domain (The symbol :black_nib: indica
Example::
.. prodn:: term += let: @pattern := @term in @term
- .. prodn:: occ_switch ::= { {? + %| - } {* @num } }
+ .. prodn:: occ_switch ::= { {? {| + | - } } {* @num } }
``.. table::`` :black_nib: A Coq table, i.e. a setting that is a set of values.
Example::
diff --git a/doc/sphinx/README.template.rst b/doc/sphinx/README.template.rst
index 78803a927f..2093765608 100644
--- a/doc/sphinx/README.template.rst
+++ b/doc/sphinx/README.template.rst
@@ -60,8 +60,11 @@ The signatures of most objects can be written using a succinct DSL for Coq notat
``{*, …}``, ``{+, …}``
an optional or mandatory repeatable block, with repetitions separated by commas
-``%|``, ``%{``, …
- an escaped character (rendered without the leading ``%``)
+``{| … | … | … }``
+ an alternative, indicating than one of multiple constructs can be used
+
+``%{``, ``%}``, ``%|``
+ an escaped character (rendered without the leading ``%``). In most cases, escaping is not necessary. In particular, the following expressions are all parsed as plain text, and do not need escaping: ``{ xyz }``, ``x |- y``. But the following escapes *are* needed: ``{| a b %| c | d }``, ``all: %{``. (We use ``%`` instead of the usual ``\`` because you'd have to type ``\`` twice in your reStructuredText file.)
..
FIXME document the new subscript support
diff --git a/doc/sphinx/_static/coqnotations.sty b/doc/sphinx/_static/coqnotations.sty
index 75eac1f724..3548b8754c 100644
--- a/doc/sphinx/_static/coqnotations.sty
+++ b/doc/sphinx/_static/coqnotations.sty
@@ -18,6 +18,9 @@
\newlength{\nscriptsize}
\setlength{\nscriptsize}{0.8em}
+\newlength{\nboxsep}
+\setlength{\nboxsep}{2pt}
+
\newcommand*{\scriptsmallsquarebox}[1]{%
% Force width
\makebox[\nscriptsize]{%
@@ -31,7 +34,8 @@
\newcommand*{\nsup}[1]{^{\nscript{0.15}{#1}}}
\newcommand*{\nsub}[1]{_{\nscript{0.35}{#1}}}
\newcommand*{\nnotation}[1]{#1}
-\newcommand*{\nrepeat}[1]{\text{\adjustbox{cfbox=nbordercolor 0.5pt 2pt,bgcolor=nbgcolor}{#1\hspace{.5\nscriptsize}}}}
+\newcommand*{\nbox}[1]{\adjustbox{cfbox=nbordercolor 0.5pt \nboxsep,bgcolor=nbgcolor}{#1}}
+\newcommand*{\nrepeat}[1]{\text{\nbox{#1\hspace{.5\nscriptsize}}}}
\newcommand*{\nwrapper}[1]{\ensuremath{\displaystyle#1}} % https://tex.stackexchange.com/questions/310877/
\newcommand*{\nhole}[1]{\textit{\color{nholecolor}#1}}
@@ -42,9 +46,32 @@
}
% </magic>
+% https://tex.stackexchange.com/questions/490262/
+\def\naltsep{}
+\newsavebox{\nsavedalt}
+\newlength{\naltvruleht}
+\newlength{\naltvruledp}
+\def\naltvrule{\smash{\vrule height\naltvruleht depth\naltvruledp}}
+\newcommand{\nalternative}[2]{%
+ % First measure the contents of the box without the bar
+ \bgroup%
+ \def\naltsep{}%
+ \savebox{\nsavedalt}{#1}%
+ \setlength{\naltvruleht}{\ht\nsavedalt}%
+ \setlength{\naltvruledp}{\dp\nsavedalt}%
+ \addtolength{\naltvruleht}{#2}%
+ \addtolength{\naltvruledp}{#2}%
+ % Then redraw it with the bar
+ \def\naltsep{\naltvrule}%
+ #1\egroup}
+
\newcssclass{notation-sup}{\nsup{#1}}
\newcssclass{notation-sub}{\nsub{#1}}
\newcssclass{notation}{\nnotation{#1}}
\newcssclass{repeat}{\nrepeat{#1}}
\newcssclass{repeat-wrapper}{\nwrapper{#1}}
\newcssclass{hole}{\nhole{#1}}
+\newcssclass{alternative}{\nalternative{\nbox{#1}}{0pt}}
+\newcssclass{alternative-block}{#1}
+\newcssclass{repeated-alternative}{\nalternative{#1}{\nboxsep}}
+\newcssclass{alternative-separator}{\quad\naltsep{}\quad}
diff --git a/doc/sphinx/_static/notations.css b/doc/sphinx/_static/notations.css
index dcb47d1786..8322ab0137 100644
--- a/doc/sphinx/_static/notations.css
+++ b/doc/sphinx/_static/notations.css
@@ -45,15 +45,46 @@
width: 2.2em;
}
-.notation .repeat {
+.notation .repeat, .notation .alternative {
background: #EAEAEA;
border: 1px solid #AAA;
display: inline-block;
- padding-right: 0.6em; /* Space for the left half of the sub- and sup-scripts */
- padding-left: 0.2em;
+ padding: 0 0.2em 0 0.3em;
margin: 0.25em 0;
}
+.notation .repeated-alternative {
+ display: inline-table;
+}
+
+.notation .alternative {
+ display: inline-table;
+ padding: 0 0.2em;
+}
+
+.notation .alternative-block {
+ display: table-cell;
+ padding: 0 0.5em;
+}
+
+.notation .alternative-separator {
+ border-left: 1px solid black; /* Display a thin bar */
+ display: table-cell;
+ width: 0;
+}
+
+.alternative-block:first-child {
+ padding-left: 0;
+}
+
+.alternative-block:last-child {
+ padding-right: 0;
+}
+
+.notation .repeat {
+ padding-right: 0.6em; /* Space for the left half of the sub- and sup-scripts */
+}
+
.notation .repeat-wrapper {
display: inline-block;
position: relative;
diff --git a/doc/sphinx/addendum/canonical-structures.rst b/doc/sphinx/addendum/canonical-structures.rst
index dd21ea09bd..b593b0cef1 100644
--- a/doc/sphinx/addendum/canonical-structures.rst
+++ b/doc/sphinx/addendum/canonical-structures.rst
@@ -209,7 +209,7 @@ We need to define a new class that inherits from both ``EQ`` and ``LE``.
LE_class : LE.class T;
extra : mixin (EQ.Pack T EQ_class) (LE.cmp T LE_class) }.
- Structure type := _Pack { obj : Type; class_of : class obj }.
+ Structure type := _Pack { obj : Type; #[canonical(false)] class_of : class obj }.
Arguments Mixin {e le} _.
@@ -219,6 +219,9 @@ The mixin component of the ``LEQ`` class contains all the extra content we
are adding to ``EQ`` and ``LE``. In particular it contains the requirement
that the two relations we are combining are compatible.
+The `class_of` projection of the `type` structure is annotated as *not canonical*;
+it plays no role in the search for instances.
+
Unfortunately there is still an obstacle to developing the algebraic
theory of this new class.
@@ -313,9 +316,7 @@ constructor ``*``. It also tests that they work as expected.
Unfortunately, these declarations are very verbose. In the following
subsection we show how to make them more compact.
-.. FIXME shouldn't warn
-
-.. coqtop:: all warn
+.. coqtop:: all
Module Add_instance_attempt.
@@ -420,9 +421,7 @@ the reader can refer to :cite:`CSwcu`.
The declaration of canonical instances can now be way more compact:
-.. FIXME should not warn
-
-.. coqtop:: all warn
+.. coqtop:: all
Canonical Structure nat_LEQty := Eval hnf in Pack nat nat_LEQmx.
diff --git a/doc/sphinx/addendum/extraction.rst b/doc/sphinx/addendum/extraction.rst
index e93b01f14d..8a895eb515 100644
--- a/doc/sphinx/addendum/extraction.rst
+++ b/doc/sphinx/addendum/extraction.rst
@@ -99,7 +99,7 @@ Extraction Options
Setting the target language
~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. cmd:: Extraction Language ( OCaml | Haskell | Scheme )
+.. cmd:: Extraction Language {| OCaml | Haskell | Scheme }
:name: Extraction Language
The ability to fix target language is the first and more important
diff --git a/doc/sphinx/addendum/generalized-rewriting.rst b/doc/sphinx/addendum/generalized-rewriting.rst
index b474c51f17..847abb33fc 100644
--- a/doc/sphinx/addendum/generalized-rewriting.rst
+++ b/doc/sphinx/addendum/generalized-rewriting.rst
@@ -170,12 +170,12 @@ compatibility constraints.
Adding new relations and morphisms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. cmd:: Add Parametric Relation (x1 : T1) ... (xn : Tk) : (A t1 ... tn) (Aeq t′1 ... t′m) {? reflexivity proved by refl} {? symmetry proved by sym} {? transitivity proved by trans} as @ident
+.. cmd:: Add Parametric Relation @binders : (A t1 ... tn) (Aeq t′1 ... t′m) {? reflexivity proved by @term} {? symmetry proved by @term} {? transitivity proved by @term} as @ident
This command declares a parametric relation :g:`Aeq: forall (y1 : β1 ... ym : βm)`,
:g:`relation (A t1 ... tn)` over :g:`(A : αi -> ... αn -> Type)`.
- The :token:`ident` gives a unique name to the morphism and it is used
+ The final :token:`ident` gives a unique name to the morphism and it is used
by the command to generate fresh names for automatically provided
lemmas used internally.
@@ -219,15 +219,16 @@ replace terms with related ones only in contexts that are syntactic
compositions of parametric morphism instances declared with the
following command.
-.. cmd:: Add Parametric Morphism (x1 : T1) ... (xk : Tk) : (f t1 ... tn) with signature sig as @ident
+.. cmd:: Add Parametric Morphism @binders : (@ident {+ @term__1}) with signature @term__2 as @ident
- This command declares ``f`` as a parametric morphism of signature ``sig``. The
- identifier :token:`ident` gives a unique name to the morphism and it is used as
- the base name of the typeclass instance definition and as the name of
- the lemma that proves the well-definedness of the morphism. The
- parameters of the morphism as well as the signature may refer to the
- context of variables. The command asks the user to prove interactively
- that ``f`` respects the relations identified from the signature.
+ This command declares a parametric morphism :n:`@ident {+ @term__1}` of
+ signature :n:`@term__2`. The final identifier :token:`ident` gives a unique
+ name to the morphism and it is used as the base name of the typeclass
+ instance definition and as the name of the lemma that proves the
+ well-definedness of the morphism. The parameters of the morphism as well as
+ the signature may refer to the context of variables. The command asks the
+ user to prove interactively that the function denoted by the first
+ :token:`ident` respects the relations identified from the signature.
.. example::
@@ -577,7 +578,7 @@ Deprecated syntax and backward incompatibilities
Notice that the syntax is not completely backward compatible since the
identifier was not required.
-.. cmd:: Add Morphism f : @ident
+.. cmd:: Add Morphism @ident : @ident
:name: Add Morphism
This command is restricted to the declaration of morphisms
@@ -809,7 +810,7 @@ Usage
~~~~~
-.. tacn:: rewrite_strat @s [in @ident]
+.. tacn:: rewrite_strat @s {? in @ident }
:name: rewrite_strat
Rewrite using the strategy s in hypothesis ident or the conclusion.
diff --git a/doc/sphinx/addendum/program.rst b/doc/sphinx/addendum/program.rst
index b410833d25..22ddcae584 100644
--- a/doc/sphinx/addendum/program.rst
+++ b/doc/sphinx/addendum/program.rst
@@ -283,7 +283,7 @@ optional identifier is used when multiple functions have unsolved
obligations (e.g. when defining mutually recursive blocks). The
optional tactic is replaced by the default one if not specified.
-.. cmd:: {? Local|Global} Obligation Tactic := @tactic
+.. cmd:: {? {| Local | Global } } Obligation Tactic := @tactic
:name: Obligation Tactic
Sets the default obligation solving tactic applied to all obligations
diff --git a/doc/sphinx/addendum/type-classes.rst b/doc/sphinx/addendum/type-classes.rst
index 77a6ee79cc..65934efaa6 100644
--- a/doc/sphinx/addendum/type-classes.rst
+++ b/doc/sphinx/addendum/type-classes.rst
@@ -311,24 +311,24 @@ Summary of the commands
This command has no effect when used on a typeclass.
-.. cmd:: Instance @ident {? @binders} : @class t1 … tn [| priority] := { field1 := b1 ; …; fieldi := bi }
+.. cmd:: Instance @ident {? @binders} : @term__0 {+ @term} {? | @num} := { {*; @field_def} }
This command is used to declare a typeclass instance named
- :token:`ident` of the class :token:`class` with parameters ``t1`` to ``tn`` and
- fields ``b1`` to ``bi``, where each field must be a declared field of
- the class. Missing fields must be filled in interactive proof mode.
+ :token:`ident` of the class :n:`@term__0` with parameters :token:`term` and
+ fields defined by :token:`field_def`, where each field must be a declared field of
+ the class.
An arbitrary context of :token:`binders` can be put after the name of the
instance and before the colon to declare a parameterized instance. An
optional priority can be declared, 0 being the highest priority as for
- :tacn:`auto` hints. If the priority is not specified, it defaults to the number
+ :tacn:`auto` hints. If the priority :token:`num` is not specified, it defaults to the number
of non-dependent binders of the instance.
- .. cmdv:: Instance @ident {? @binders} : forall {? @binders}, @class @term__1 … @term__n [| priority] := @term
+ .. cmdv:: Instance @ident {? @binders} : forall {? @binders}, @term__0 {+ @term} {? | @num } := @term
This syntax is used for declaration of singleton class instances or
- for directly giving an explicit term of type :n:`forall @binders, @class
- @term__1 … @term__n`. One need not even mention the unique field name for
+ for directly giving an explicit term of type :n:`forall @binders, @term__0
+ {+ @term}`. One need not even mention the unique field name for
singleton classes.
.. cmdv:: Global Instance
@@ -356,11 +356,11 @@ Summary of the commands
Besides the :cmd:`Class` and :cmd:`Instance` vernacular commands, there are a
few other commands related to typeclasses.
-.. cmd:: Existing Instance {+ @ident} [| priority]
+.. cmd:: Existing Instance {+ @ident} {? | @num}
This command adds an arbitrary list of constants whose type ends with
an applied typeclass to the instance database with an optional
- priority. It can be used for redeclaring instances at the end of
+ priority :token:`num`. It can be used for redeclaring instances at the end of
sections, or declaring structure projections as instances. This is
equivalent to ``Hint Resolve ident : typeclass_instances``, except it
registers instances for :cmd:`Print Instances`.
@@ -408,7 +408,7 @@ few other commands related to typeclasses.
+ When considering local hypotheses, we use the union of all the modes
declared in the given databases.
- .. cmdv:: typeclasses eauto @num
+ .. tacv:: typeclasses eauto @num
.. warning::
The semantics for the limit :n:`@num`
@@ -417,7 +417,7 @@ few other commands related to typeclasses.
counted, which might result in larger limits being necessary when
searching with ``typeclasses eauto`` than with :tacn:`auto`.
- .. cmdv:: typeclasses eauto with {+ @ident}
+ .. tacv:: typeclasses eauto with {+ @ident}
This variant runs resolution with the given hint databases. It treats
typeclass subgoals the same as other subgoals (no shelving of
@@ -563,23 +563,10 @@ Settings
of goals. Setting this option to 1 or 2 turns on :flag:`Typeclasses Debug`; setting this
option to 0 turns that option off.
-.. flag:: Refine Instance Mode
-
- .. deprecated:: 8.10
-
- This flag allows to switch the behavior of instance declarations made through
- the Instance command.
-
- + When it is off (the default), they fail with an error instead.
-
- + When it is on, instances that have unsolved holes in
- their proof-term silently open the proof mode with the remaining
- obligations to prove.
-
Typeclasses eauto `:=`
~~~~~~~~~~~~~~~~~~~~~~
-.. cmd:: Typeclasses eauto := {? debug} {? (dfs) | (bfs) } @num
+.. cmd:: Typeclasses eauto := {? debug} {? {| (dfs) | (bfs) } } @num
:name: Typeclasses eauto
This command allows more global customization of the typeclass
diff --git a/doc/sphinx/changes.rst b/doc/sphinx/changes.rst
index 5704587ae0..cc2c43e7dd 100644
--- a/doc/sphinx/changes.rst
+++ b/doc/sphinx/changes.rst
@@ -2,7 +2,9 @@
Recent changes
--------------
-.. include:: ../unreleased.rst
+.. ifconfig:: not coq_config.is_a_released_version
+
+ .. include:: ../unreleased.rst
Version 8.10
------------
@@ -353,6 +355,11 @@ Other changes in 8.10+beta1
that will do it automatically, using the output of ``coqc``
(`#8638 <https://github.com/coq/coq/pull/8638>`_, by Jason Gross).
+ - Allow inspecting custom grammar entries by :cmd:`Print Custom Grammar`
+ (`#10061 <https://github.com/coq/coq/pull/10061>`_,
+ fixes `#9681 <http://github.com/coq/coq/pull/9681>`_,
+ by Jasper Hugunin, review by Pierre-Marie Pédrot and Hugo Herbelin).
+
- The `quote plugin
<https://coq.inria.fr/distrib/V8.9.0/refman/proof-engine/detailed-tactic-examples.html#quote>`_
was removed. If some users are interested in maintaining this plugin
@@ -398,7 +405,32 @@ Other changes in 8.10+beta1
closes `#7632 <https://github.com/coq/coq/issues/7632>`_,
by Théo Zimmermann).
- - SSReflect clear discipline made consistent across the entire proof language.
+ - Modes are now taken into account by :tacn:`typeclasses eauto` for
+ local hypotheses
+ (`#9996 <https://github.com/coq/coq/pull/9996>`_,
+ fixes `#5752 <https://github.com/coq/coq/issues/5752>`_,
+ by Maxime Dénès, review by Pierre-Marie Pédrot).
+
+ - New variant :tacn:`change_no_check` of :tacn:`change`, usable as a
+ documented replacement of :tacn:`convert_concl_no_check`
+ (`#10012 <https://github.com/coq/coq/pull/10012>`_,
+ `#10017 <https://github.com/coq/coq/pull/10017>`_,
+ `#10053 <https://github.com/coq/coq/pull/10053>`_, and
+ `#10059 <https://github.com/coq/coq/pull/10059>`_,
+ by Hugo Herbelin and Paolo G. Giarrusso).
+
+ - The simplified value returned by :tacn:`field_simplify` is not
+ always a fraction anymore. When the denominator is :g:`1`, it
+ returns :g:`x` while previously it was returning :g:`x/1`. This
+ change could break codes that were post-processing application of
+ :tacn:`field_simplify` to get rid of these :g:`x/1`
+ (`#9854 <https://github.com/coq/coq/pull/9854>`_,
+ by Laurent Théry,
+ with help from Michael Soegtrop, Maxime Dénès, and Vincent Laporte).
+
+- SSReflect:
+
+ - 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.
@@ -412,6 +444,15 @@ Other changes in 8.10+beta1
(`#9341 <https://github.com/coq/coq/pull/9341>`_, by Enrico Tassi).
+ - `inE` now expands `y \in r x` when `r` is a `simpl_rel`.
+ New `{pred T}` notation for a `pred T` alias in the `pred_sort` coercion
+ class, simplified `predType` interface: `pred_class` and `mkPredType`
+ deprecated, `{pred T}` and `PredType` should be used instead.
+ `if c return t then ...` now expects `c` to be a variable bound in `t`.
+ New `nonPropType` interface matching types that do _not_ have sort `Prop`.
+ New `relpre R f` definition for the preimage of a relation R under f
+ (`#9995 <https://github.com/coq/coq/pull/9995>`_, by Georges Gonthier).
+
- Vernacular commands:
- Binders for an :cmd:`Instance` now act more like binders for a :cmd:`Theorem`.
@@ -445,10 +486,9 @@ Other changes in 8.10+beta1
- :cmd:`Declare Instance` now requires an instance name.
- The flag :flag:`Refine Instance Mode` has been turned off by default,
- meaning that :cmd:`Instance` no longer opens a proof when a body is
- provided. The flag has been deprecated and will be removed in the next
- version.
+ The flag `Refine Instance Mode` has been turned off by default, meaning that
+ :cmd:`Instance` no longer opens a proof when a body is provided. The flag
+ has been deprecated and will be removed in the next version.
(`#9270 <https://github.com/coq/coq/pull/9270>`_,
and `#9825 <https://github.com/coq/coq/pull/9825>`_,
@@ -457,7 +497,7 @@ Other changes in 8.10+beta1
- Command :cmd:`Instance`, when no body is provided, now always opens
a proof. This is a breaking change, as instance of :n:`Instance
@ident__1 : @ident__2.` where :n:`@ident__2` is a trivial class will
- have to be changed into :n:`Instance @ident__1 : @ident__2 := {}.`
+ have to be changed into :n:`Instance @ident__1 : @ident__2 := %{%}.`
or :n:`Instance @ident__1 : @ident__2. Proof. Qed.`
(`#9274 <https://github.com/coq/coq/pull/9274>`_, by Maxime Dénès).
@@ -533,10 +573,28 @@ Other changes in 8.10+beta1
`fset` database
(`#9725 <https://github.com/coq/coq/pull/9725>`_, by Frédéric Besson).
+ - Added :g:`Coq.Structures.EqualitiesFacts.PairUsualDecidableTypeFull`
+ (`#9984 <https://github.com/coq/coq/pull/9984>`_,
+ by Jean-Christophe Léchenet and Oliver Nash).
+
- Some error messages that show problems with a pair of non-matching
values will now highlight the differences
(`#8669 <https://github.com/coq/coq/pull/8669>`_, by Jim Fehrle).
+- Changelog has been moved from a specific file `CHANGES.md` to the
+ reference manual; former Credits chapter of the reference manual has
+ been split in two parts: a History chapter which was enriched with
+ additional historical information about Coq versions 1 to 5, and a
+ Changes chapter which was enriched with the content formerly in
+ `CHANGES.md` and `COMPATIBILITY`
+ (`#9133 <https://github.com/coq/coq/pull/9133>`_,
+ `#9668 <https://github.com/coq/coq/pull/9668>`_,
+ `#9939 <https://github.com/coq/coq/pull/9939>`_,
+ `#9964 <https://github.com/coq/coq/pull/9964>`_,
+ and `#10085 <https://github.com/coq/coq/pull/10085>`_,
+ by Théo Zimmermann,
+ with help and ideas from Emilio Jesús Gallego Arias, Gaëtan
+ Gilbert, Clément Pit-Claudel, Matthieu Sozeau, and Enrico Tassi).
Version 8.9
-----------
@@ -3881,7 +3939,7 @@ Vernacular commands
Equality Schemes", this replaces deprecated option "Equality Scheme").
- Made support for automatic generation of case analysis schemes available
to user (governed by option "Set Case Analysis Schemes").
-- New command :n:`{? Global } Generalizable [All|No] [Variable|Variables] {* @ident}` to
+- New command :n:`{? Global } Generalizable {| All | No } {| Variable | Variables } {* @ident}` to
declare which identifiers are generalizable in `` `{} `` and `` `() `` binders.
- New command "Print Opaque Dependencies" to display opaque constants in
addition to all variables, parameters or axioms a theorem or
diff --git a/doc/sphinx/conf.py b/doc/sphinx/conf.py
index 972a53ae36..ec3343dac6 100755
--- a/doc/sphinx/conf.py
+++ b/doc/sphinx/conf.py
@@ -53,6 +53,7 @@ needs_sphinx = '1.7.8'
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
+ 'sphinx.ext.ifconfig',
'sphinx.ext.mathjax',
'sphinx.ext.todo',
'sphinxcontrib.bibtex',
@@ -100,6 +101,7 @@ def copy_formatspecific_files(app):
def setup(app):
app.connect('builder-inited', copy_formatspecific_files)
+ app.add_config_value('coq_config', coq_config, 'env')
# The master toctree document.
# We create this file in `copy_master_doc` above.
diff --git a/doc/sphinx/language/gallina-extensions.rst b/doc/sphinx/language/gallina-extensions.rst
index 5308330820..5e214f6f7f 100644
--- a/doc/sphinx/language/gallina-extensions.rst
+++ b/doc/sphinx/language/gallina-extensions.rst
@@ -85,7 +85,7 @@ To build an object of type :token:`ident`, one should provide the constructor
.. productionlist::
record_term : {| [`field_def` ; … ; `field_def`] |}
- field_def : name [binders] := `record_term`
+ field_def : `ident` [`binders`] := `term`
Alternatively, the following syntax allows creating objects by using named fields, as
shown in this grammar. The fields do not have to be in any particular order, nor do they have
@@ -831,16 +831,16 @@ Sections create local contexts which can be shared across multiple definitions.
Links :token:`type` to each :token:`ident`.
- .. cmdv:: Variable {+ ( {+ @ident } : @type ) }
+ .. cmdv:: Variable {+ ( {+ @ident } : @type ) }
Declare one or more variables with various types.
- .. cmdv:: Variables {+ ( {+ @ident } : @type) }
- Hypothesis {+ ( {+ @ident } : @type) }
- Hypotheses {+ ( {+ @ident } : @type) }
+ .. cmdv:: Variables {+ ( {+ @ident } : @type) }
+ Hypothesis {+ ( {+ @ident } : @type) }
+ Hypotheses {+ ( {+ @ident } : @type) }
:name: Variables; Hypothesis; Hypotheses
- These variants are synonyms of :n:`Variable {+ ( {+ @ident } : @type) }`.
+ These variants are synonyms of :n:`Variable {+ ( {+ @ident } : @type) }`.
.. cmd:: Let @ident := @term
@@ -931,7 +931,7 @@ In the syntax of module application, the ! prefix indicates that any
:token:`module_binding`. The output module type
is verified against each :token:`module_type`.
-.. cmdv:: Module [ Import | Export ]
+.. cmdv:: Module {| Import | Export }
Behaves like :cmd:`Module`, but automatically imports or exports the module.
@@ -1648,7 +1648,7 @@ Declaring Implicit Arguments
-.. cmd:: Arguments @qualid {* [ @ident ] | { @ident } | @ident }
+.. cmd:: Arguments @qualid {* {| [ @ident ] | { @ident } | @ident } }
:name: Arguments (implicits)
This command is used to set implicit arguments *a posteriori*,
@@ -1665,20 +1665,20 @@ Declaring Implicit Arguments
This command clears implicit arguments.
-.. cmdv:: Global Arguments @qualid {* [ @ident ] | { @ident } | @ident }
+.. cmdv:: Global Arguments @qualid {* {| [ @ident ] | { @ident } | @ident } }
This command is used to recompute the implicit arguments of
:token:`qualid` after ending of the current section if any, enforcing the
implicit arguments known from inside the section to be the ones
declared by the command.
-.. cmdv:: Local Arguments @qualid {* [ @ident ] | { @ident } | @ident }
+.. cmdv:: Local Arguments @qualid {* {| [ @ident ] | { @ident } | @ident } }
When in a module, tell not to activate the
implicit arguments of :token:`qualid` declared by this command to contexts that
require the module.
-.. cmdv:: {? Global | Local } Arguments @qualid {*, {+ [ @ident ] | { @ident } | @ident } }
+.. cmdv:: {? {| Global | Local } } Arguments @qualid {*, {+ {| [ @ident ] | { @ident } | @ident } } }
For names of constants, inductive types,
constructors, lemmas which can only be applied to a fixed number of
@@ -2048,6 +2048,21 @@ in :ref:`canonicalstructures`; here only a simple example is given.
If a same field occurs in several canonical structures, then
only the structure declared first as canonical is considered.
+ .. note::
+ To prevent a field from being involved in the inference of canonical instances,
+ its declaration can be annotated with the :g:`#[canonical(false)]` attribute.
+
+ .. example::
+
+ For instance, when declaring the :g:`Setoid` structure above, the
+ :g:`Prf_equiv` field declaration could be written as follows.
+
+ .. coqdoc::
+
+ #[canonical(false)] Prf_equiv : equivalence Carrier Equal
+
+ See :ref:`canonicalstructures` for a more realistic example.
+
.. cmdv:: Canonical {? Structure } @ident {? : @type } := @term
This is equivalent to a regular definition of :token:`ident` followed by the
@@ -2067,6 +2082,10 @@ in :ref:`canonicalstructures`; here only a simple example is given.
Print Canonical Projections.
+ .. note::
+
+ The last line would not show up if the corresponding projection (namely
+ :g:`Prf_equiv`) were annotated as not canonical, as described above.
Implicit types of variables
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2148,7 +2167,7 @@ that specify which variables should be generalizable.
Disable implicit generalization entirely. This is the default behavior.
-.. cmd:: Generalizable (Variable | Variables) {+ @ident }
+.. cmd:: Generalizable {| Variable | Variables } {+ @ident }
Allow generalization of the given identifiers only. Calling this command multiple times
adds to the allowed identifiers.
diff --git a/doc/sphinx/language/gallina-specification-language.rst b/doc/sphinx/language/gallina-specification-language.rst
index 5a1af9f9fa..8acbcbec8f 100644
--- a/doc/sphinx/language/gallina-specification-language.rst
+++ b/doc/sphinx/language/gallina-specification-language.rst
@@ -616,34 +616,34 @@ has type :token:`type`.
Adds several parameters with specification :token:`type`.
- .. cmdv:: Parameter {+ ( {+ @ident } : @type ) }
+ .. cmdv:: Parameter {+ ( {+ @ident } : @type ) }
Adds blocks of parameters with different specifications.
- .. cmdv:: Local Parameter {+ ( {+ @ident } : @type ) }
+ .. cmdv:: Local Parameter {+ ( {+ @ident } : @type ) }
:name: Local Parameter
Such parameters are never made accessible through their unqualified name by
:cmd:`Import` and its variants. You have to explicitly give their fully
qualified name to refer to them.
- .. cmdv:: {? Local } Parameters {+ ( {+ @ident } : @type ) }
- {? Local } Axiom {+ ( {+ @ident } : @type ) }
- {? Local } Axioms {+ ( {+ @ident } : @type ) }
- {? Local } Conjecture {+ ( {+ @ident } : @type ) }
- {? Local } Conjectures {+ ( {+ @ident } : @type ) }
+ .. cmdv:: {? Local } Parameters {+ ( {+ @ident } : @type ) }
+ {? Local } Axiom {+ ( {+ @ident } : @type ) }
+ {? Local } Axioms {+ ( {+ @ident } : @type ) }
+ {? Local } Conjecture {+ ( {+ @ident } : @type ) }
+ {? Local } Conjectures {+ ( {+ @ident } : @type ) }
:name: Parameters; Axiom; Axioms; Conjecture; Conjectures
- These variants are synonyms of :n:`{? Local } Parameter {+ ( {+ @ident } : @type ) }`.
+ These variants are synonyms of :n:`{? Local } Parameter {+ ( {+ @ident } : @type ) }`.
- .. cmdv:: Variable {+ ( {+ @ident } : @type ) }
- Variables {+ ( {+ @ident } : @type ) }
- Hypothesis {+ ( {+ @ident } : @type ) }
- Hypotheses {+ ( {+ @ident } : @type ) }
+ .. cmdv:: Variable {+ ( {+ @ident } : @type ) }
+ Variables {+ ( {+ @ident } : @type ) }
+ Hypothesis {+ ( {+ @ident } : @type ) }
+ Hypotheses {+ ( {+ @ident } : @type ) }
:name: Variable (outside a section); Variables (outside a section); Hypothesis (outside a section); Hypotheses (outside a section)
Outside of any section, these variants are synonyms of
- :n:`Local Parameter {+ ( {+ @ident } : @type ) }`.
+ :n:`Local Parameter {+ ( {+ @ident } : @type ) }`.
For their meaning inside a section, see :cmd:`Variable` in
:ref:`section-mechanism`.
diff --git a/doc/sphinx/practical-tools/coqide.rst b/doc/sphinx/practical-tools/coqide.rst
index 6cbd00f45d..efb5df720a 100644
--- a/doc/sphinx/practical-tools/coqide.rst
+++ b/doc/sphinx/practical-tools/coqide.rst
@@ -181,7 +181,14 @@ presented as a notebook.
The first section is for selecting the text font used for scripts,
goal and message windows.
-The second section is devoted to file management: you may configure
+The second and third sections are for controlling colors and style.
+
+The fourth section is for customizing the editor. It includes in
+particular the ability to activate an Emacs mode named
+micro-Proof-General (use the Help menu to know more about the
+available bindings).
+
+The next section is devoted to file management: you may configure
automatic saving of files, by periodically saving the contents into
files named `#f#` for each opened file `f`. You may also activate the
*revert* feature: in case a opened file is modified on the disk by a
diff --git a/doc/sphinx/proof-engine/detailed-tactic-examples.rst b/doc/sphinx/proof-engine/detailed-tactic-examples.rst
index b629d15b11..0ace9ef5b9 100644
--- a/doc/sphinx/proof-engine/detailed-tactic-examples.rst
+++ b/doc/sphinx/proof-engine/detailed-tactic-examples.rst
@@ -396,381 +396,3 @@ the optional tactic of the ``Hint Rewrite`` command.
.. coqtop:: none
Qed.
-
-Using the tactic language
--------------------------
-
-
-About the cardinality of the set of natural numbers
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The first example which shows how to use pattern matching over the
-proof context is a proof of the fact that natural numbers have more
-than two elements. This can be done as follows:
-
-.. coqtop:: in reset
-
- Lemma card_nat :
- ~ exists x : nat, exists y : nat, forall z:nat, x = z \/ y = z.
- Proof.
-
-.. coqtop:: in
-
- red; intros (x, (y, Hy)).
-
-.. coqtop:: in
-
- elim (Hy 0); elim (Hy 1); elim (Hy 2); intros;
-
- match goal with
- | _ : ?a = ?b, _ : ?a = ?c |- _ =>
- cut (b = c); [ discriminate | transitivity a; auto ]
- end.
-
-.. coqtop:: in
-
- Qed.
-
-We can notice that all the (very similar) cases coming from the three
-eliminations (with three distinct natural numbers) are successfully
-solved by a match goal structure and, in particular, with only one
-pattern (use of non-linear matching).
-
-
-Permutations of lists
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A more complex example is the problem of permutations of
-lists. The aim is to show that a list is a permutation of
-another list.
-
-.. coqtop:: in reset
-
- Section Sort.
-
-.. coqtop:: in
-
- Variable A : Set.
-
-.. coqtop:: in
-
- Inductive perm : list A -> list A -> Prop :=
- | perm_refl : forall l, perm l l
- | perm_cons : forall a l0 l1, perm l0 l1 -> perm (a :: l0) (a :: l1)
- | perm_append : forall a l, perm (a :: l) (l ++ a :: nil)
- | perm_trans : forall l0 l1 l2, perm l0 l1 -> perm l1 l2 -> perm l0 l2.
-
-.. coqtop:: in
-
- End Sort.
-
-First, we define the permutation predicate as shown above.
-
-.. coqtop:: none
-
- Require Import List.
-
-
-.. coqtop:: in
-
- Ltac perm_aux n :=
- match goal with
- | |- (perm _ ?l ?l) => apply perm_refl
- | |- (perm _ (?a :: ?l1) (?a :: ?l2)) =>
- let newn := eval compute in (length l1) in
- (apply perm_cons; perm_aux newn)
- | |- (perm ?A (?a :: ?l1) ?l2) =>
- match eval compute in n with
- | 1 => fail
- | _ =>
- let l1' := constr:(l1 ++ a :: nil) in
- (apply (perm_trans A (a :: l1) l1' l2);
- [ apply perm_append | compute; perm_aux (pred n) ])
- end
- end.
-
-Next we define an auxiliary tactic ``perm_aux`` which takes an argument
-used to control the recursion depth. This tactic behaves as follows. If
-the lists are identical (i.e. convertible), it concludes. Otherwise, if
-the lists have identical heads, it proceeds to look at their tails.
-Finally, if the lists have different heads, it rotates the first list by
-putting its head at the end if the new head hasn't been the head previously. To check this, we keep track of the
-number of performed rotations using the argument ``n``. We do this by
-decrementing ``n`` each time we perform a rotation. It works because
-for a list of length ``n`` we can make exactly ``n - 1`` rotations
-to generate at most ``n`` distinct lists. Notice that we use the natural
-numbers of Coq for the rotation counter. From :ref:`ltac-syntax` we know
-that it is possible to use the usual natural numbers, but they are only
-used as arguments for primitive tactics and they cannot be handled, so,
-in particular, we cannot make computations with them. Thus the natural
-choice is to use Coq data structures so that Coq makes the computations
-(reductions) by ``eval compute in`` and we can get the terms back by match.
-
-.. coqtop:: in
-
- Ltac solve_perm :=
- match goal with
- | |- (perm _ ?l1 ?l2) =>
- match eval compute in (length l1 = length l2) with
- | (?n = ?n) => perm_aux n
- end
- end.
-
-The main tactic is ``solve_perm``. It computes the lengths of the two lists
-and uses them as arguments to call ``perm_aux`` if the lengths are equal (if they
-aren't, the lists cannot be permutations of each other). Using this tactic we
-can now prove lemmas as follows:
-
-.. coqtop:: in
-
- Lemma solve_perm_ex1 :
- perm nat (1 :: 2 :: 3 :: nil) (3 :: 2 :: 1 :: nil).
- Proof. solve_perm. Qed.
-
-.. coqtop:: in
-
- Lemma solve_perm_ex2 :
- perm nat
- (0 :: 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: 9 :: nil)
- (0 :: 2 :: 4 :: 6 :: 8 :: 9 :: 7 :: 5 :: 3 :: 1 :: nil).
- Proof. solve_perm. Qed.
-
-Deciding intuitionistic propositional logic
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Pattern matching on goals allows a powerful backtracking when returning tactic
-values. An interesting application is the problem of deciding intuitionistic
-propositional logic. Considering the contraction-free sequent calculi LJT* of
-Roy Dyckhoff :cite:`Dyc92`, it is quite natural to code such a tactic using the
-tactic language as shown below.
-
-.. coqtop:: in reset
-
- Ltac basic :=
- match goal with
- | |- True => trivial
- | _ : False |- _ => contradiction
- | _ : ?A |- ?A => assumption
- end.
-
-.. coqtop:: in
-
- Ltac simplify :=
- repeat (intros;
- match goal with
- | H : ~ _ |- _ => red in H
- | H : _ /\ _ |- _ =>
- elim H; do 2 intro; clear H
- | H : _ \/ _ |- _ =>
- elim H; intro; clear H
- | H : ?A /\ ?B -> ?C |- _ =>
- cut (A -> B -> C);
- [ intro | intros; apply H; split; assumption ]
- | H: ?A \/ ?B -> ?C |- _ =>
- cut (B -> C);
- [ cut (A -> C);
- [ intros; clear H
- | intro; apply H; left; assumption ]
- | intro; apply H; right; assumption ]
- | H0 : ?A -> ?B, H1 : ?A |- _ =>
- cut B; [ intro; clear H0 | apply H0; assumption ]
- | |- _ /\ _ => split
- | |- ~ _ => red
- end).
-
-.. coqtop:: in
-
- Ltac my_tauto :=
- simplify; basic ||
- match goal with
- | H : (?A -> ?B) -> ?C |- _ =>
- cut (B -> C);
- [ intro; cut (A -> B);
- [ intro; cut C;
- [ intro; clear H | apply H; assumption ]
- | clear H ]
- | intro; apply H; intro; assumption ]; my_tauto
- | H : ~ ?A -> ?B |- _ =>
- cut (False -> B);
- [ intro; cut (A -> False);
- [ intro; cut B;
- [ intro; clear H | apply H; assumption ]
- | clear H ]
- | intro; apply H; red; intro; assumption ]; my_tauto
- | |- _ \/ _ => (left; my_tauto) || (right; my_tauto)
- end.
-
-The tactic ``basic`` tries to reason using simple rules involving truth, falsity
-and available assumptions. The tactic ``simplify`` applies all the reversible
-rules of Dyckhoff’s system. Finally, the tactic ``my_tauto`` (the main
-tactic to be called) simplifies with ``simplify``, tries to conclude with
-``basic`` and tries several paths using the backtracking rules (one of the
-four Dyckhoff’s rules for the left implication to get rid of the contraction
-and the right ``or``).
-
-Having defined ``my_tauto``, we can prove tautologies like these:
-
-.. coqtop:: in
-
- Lemma my_tauto_ex1 :
- forall A B : Prop, A /\ B -> A \/ B.
- Proof. my_tauto. Qed.
-
-.. coqtop:: in
-
- Lemma my_tauto_ex2 :
- forall A B : Prop, (~ ~ B -> B) -> (A -> B) -> ~ ~ A -> B.
- Proof. my_tauto. Qed.
-
-
-Deciding type isomorphisms
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A more tricky problem is to decide equalities between types modulo
-isomorphisms. Here, we choose to use the isomorphisms of the simply
-typed λ-calculus with Cartesian product and unit type (see, for
-example, :cite:`RC95`). The axioms of this λ-calculus are given below.
-
-.. coqtop:: in reset
-
- Open Scope type_scope.
-
-.. coqtop:: in
-
- Section Iso_axioms.
-
-.. coqtop:: in
-
- Variables A B C : Set.
-
-.. coqtop:: in
-
- Axiom Com : A * B = B * A.
-
- Axiom Ass : A * (B * C) = A * B * C.
-
- Axiom Cur : (A * B -> C) = (A -> B -> C).
-
- Axiom Dis : (A -> B * C) = (A -> B) * (A -> C).
-
- Axiom P_unit : A * unit = A.
-
- Axiom AR_unit : (A -> unit) = unit.
-
- Axiom AL_unit : (unit -> A) = A.
-
-.. coqtop:: in
-
- Lemma Cons : B = C -> A * B = A * C.
-
- Proof.
-
- intro Heq; rewrite Heq; reflexivity.
-
- Qed.
-
-.. coqtop:: in
-
- End Iso_axioms.
-
-.. coqtop:: in
-
- Ltac simplify_type ty :=
- match ty with
- | ?A * ?B * ?C =>
- rewrite <- (Ass A B C); try simplify_type_eq
- | ?A * ?B -> ?C =>
- rewrite (Cur A B C); try simplify_type_eq
- | ?A -> ?B * ?C =>
- rewrite (Dis A B C); try simplify_type_eq
- | ?A * unit =>
- rewrite (P_unit A); try simplify_type_eq
- | unit * ?B =>
- rewrite (Com unit B); try simplify_type_eq
- | ?A -> unit =>
- rewrite (AR_unit A); try simplify_type_eq
- | unit -> ?B =>
- rewrite (AL_unit B); try simplify_type_eq
- | ?A * ?B =>
- (simplify_type A; try simplify_type_eq) ||
- (simplify_type B; try simplify_type_eq)
- | ?A -> ?B =>
- (simplify_type A; try simplify_type_eq) ||
- (simplify_type B; try simplify_type_eq)
- end
- with simplify_type_eq :=
- match goal with
- | |- ?A = ?B => try simplify_type A; try simplify_type B
- end.
-
-.. coqtop:: in
-
- Ltac len trm :=
- match trm with
- | _ * ?B => let succ := len B in constr:(S succ)
- | _ => constr:(1)
- end.
-
-.. coqtop:: in
-
- Ltac assoc := repeat rewrite <- Ass.
-
-.. coqtop:: in
-
- Ltac solve_type_eq n :=
- match goal with
- | |- ?A = ?A => reflexivity
- | |- ?A * ?B = ?A * ?C =>
- apply Cons; let newn := len B in solve_type_eq newn
- | |- ?A * ?B = ?C =>
- match eval compute in n with
- | 1 => fail
- | _ =>
- pattern (A * B) at 1; rewrite Com; assoc; solve_type_eq (pred n)
- end
- end.
-
-.. coqtop:: in
-
- Ltac compare_structure :=
- match goal with
- | |- ?A = ?B =>
- let l1 := len A
- with l2 := len B in
- match eval compute in (l1 = l2) with
- | ?n = ?n => solve_type_eq n
- end
- end.
-
-.. coqtop:: in
-
- Ltac solve_iso := simplify_type_eq; compare_structure.
-
-The tactic to judge equalities modulo this axiomatization is shown above.
-The algorithm is quite simple. First types are simplified using axioms that
-can be oriented (this is done by ``simplify_type`` and ``simplify_type_eq``).
-The normal forms are sequences of Cartesian products without Cartesian product
-in the left component. These normal forms are then compared modulo permutation
-of the components by the tactic ``compare_structure``. If they have the same
-lengths, the tactic ``solve_type_eq`` attempts to prove that the types are equal.
-The main tactic that puts all these components together is called ``solve_iso``.
-
-Here are examples of what can be solved by ``solve_iso``.
-
-.. coqtop:: in
-
- Lemma solve_iso_ex1 :
- forall A B : Set, A * unit * B = B * (unit * A).
- Proof.
- intros; solve_iso.
- Qed.
-
-.. coqtop:: in
-
- Lemma solve_iso_ex2 :
- forall A B C : Set,
- (A * unit -> B * (C * unit)) =
- (A * unit -> (C -> unit) * C) * (unit -> A -> B).
- Proof.
- intros; solve_iso.
- Qed.
diff --git a/doc/sphinx/proof-engine/ltac.rst b/doc/sphinx/proof-engine/ltac.rst
index d3562b52c5..bbd7e0ba3d 100644
--- a/doc/sphinx/proof-engine/ltac.rst
+++ b/doc/sphinx/proof-engine/ltac.rst
@@ -3,12 +3,25 @@
Ltac
====
-This chapter gives a compact documentation of |Ltac|, the tactic language
-available in |Coq|. We start by giving the syntax, and next, we present the
-informal semantics. If you want to know more regarding this language and
-especially about its foundations, you can refer to :cite:`Del00`. Chapter
-:ref:`detailedexamplesoftactics` is devoted to giving small but nontrivial
-use examples of this language.
+This chapter documents the tactic language |Ltac|.
+
+We start by giving the syntax, and next, we present the informal
+semantics. To learn more about the language and
+especially about its foundations, please refer to :cite:`Del00`.
+
+.. example:: Basic tactic macros
+
+ Here are some examples of simple tactic macros that the
+ language lets you write.
+
+ .. coqdoc::
+
+ Ltac reduce_and_try_to_solve := simpl; intros; auto.
+
+ Ltac destruct_bool_and_rewrite b H1 H2 :=
+ destruct b; [ rewrite H1; eauto | rewrite H2; eauto ].
+
+ See Section :ref:`ltac-examples` for more advanced examples.
.. _ltac-syntax:
@@ -347,7 +360,7 @@ Detecting progress
We can check if a tactic made progress with:
-.. tacn:: progress expr
+.. tacn:: progress @expr
:name: progress
:n:`@expr` is evaluated to v which must be a tactic value. The tactic value ``v``
@@ -542,7 +555,7 @@ Identity
The constant :n:`idtac` is the identity tactic: it leaves any goal unchanged but
it appears in the proof script.
-.. tacn:: idtac {* message_token}
+.. tacn:: idtac {* @message_token}
:name: idtac
This prints the given tokens. Strings and integers are printed
@@ -671,7 +684,7 @@ Timing a tactic that evaluates to a term
Tactic expressions that produce terms can be timed with the experimental
tactic
-.. tacn:: time_constr expr
+.. tacn:: time_constr @expr
:name: time_constr
which evaluates :n:`@expr ()` and displays the time the tactic expression
@@ -867,7 +880,7 @@ We can perform pattern matching on goals using the following expression:
.. we should provide the full grammar here
-.. tacn:: match goal with {+| {+ hyp} |- @cpattern => @expr } | _ => @expr end
+.. tacn:: match goal with {+| {+, @context_hyp} |- @cpattern => @expr } | _ => @expr end
:name: match goal
If each hypothesis pattern :n:`hyp`\ :sub:`1,i`, with i = 1, ..., m\ :sub:`1` is
@@ -905,7 +918,7 @@ We can perform pattern matching on goals using the following expression:
first), but it possible to reverse this order (oldest first)
with the :n:`match reverse goal with` variant.
- .. tacv:: multimatch goal with {+| {+ hyp} |- @cpattern => @expr } | _ => @expr end
+ .. tacv:: multimatch goal with {+| {+, @context_hyp} |- @cpattern => @expr } | _ => @expr end
Using :n:`multimatch` instead of :n:`match` will allow subsequent tactics
to backtrack into a right-hand side tactic which has backtracking points
@@ -916,7 +929,7 @@ We can perform pattern matching on goals using the following expression:
The syntax :n:`match [reverse] goal …` is, in fact, a shorthand for
:n:`once multimatch [reverse] goal …`.
- .. tacv:: lazymatch goal with {+| {+ hyp} |- @cpattern => @expr } | _ => @expr end
+ .. tacv:: lazymatch goal with {+| {+, @context_hyp} |- @cpattern => @expr } | _ => @expr end
Using lazymatch instead of match will perform the same pattern matching
procedure but will commit to the first matching branch with the first
@@ -1122,33 +1135,33 @@ Defining |Ltac| functions
Basically, |Ltac| toplevel definitions are made as follows:
-.. cmd:: Ltac @ident {* @ident} := @expr
+.. cmd:: {? Local} Ltac @ident {* @ident} := @expr
+ :name: Ltac
This defines a new |Ltac| function that can be used in any tactic
script or new |Ltac| toplevel definition.
+ If preceded by the keyword ``Local``, the tactic definition will not be
+ exported outside the current module.
+
.. note::
The preceding definition can equivalently be written:
:n:`Ltac @ident := fun {+ @ident} => @expr`
- Recursive and mutual recursive function definitions are also possible
- with the syntax:
-
.. cmdv:: Ltac @ident {* @ident} {* with @ident {* @ident}} := @expr
- It is also possible to *redefine* an existing user-defined tactic using the syntax:
+ This syntax allows recursive and mutual recursive function definitions.
.. cmdv:: Ltac @qualid {* @ident} ::= @expr
+ This syntax *redefines* an existing user-defined tactic.
+
A previous definition of qualid must exist in the environment. The new
definition will always be used instead of the old one and it goes across
module boundaries.
- If preceded by the keyword Local the tactic definition will not be
- exported outside the current module.
-
Printing |Ltac| tactics
~~~~~~~~~~~~~~~~~~~~~~~
@@ -1160,6 +1173,399 @@ Printing |Ltac| tactics
This command displays a list of all user-defined tactics, with their arguments.
+
+.. _ltac-examples:
+
+Examples of using |Ltac|
+-------------------------
+
+Proof that the natural numbers have at least two elements
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. example:: Proof that the natural numbers have at least two elements
+
+ The first example shows how to use pattern matching over the proof
+ context to prove that natural numbers have at least two
+ elements. This can be done as follows:
+
+ .. coqtop:: reset all
+
+ Lemma card_nat :
+ ~ exists x y : nat, forall z:nat, x = z \/ y = z.
+ Proof.
+ intros (x & y & Hz).
+ destruct (Hz 0), (Hz 1), (Hz 2).
+
+ At this point, the :tacn:`congruence` tactic would finish the job:
+
+ .. coqtop:: all abort
+
+ all: congruence.
+
+ But for the purpose of the example, let's craft our own custom
+ tactic to solve this:
+
+ .. coqtop:: none
+
+ Lemma card_nat :
+ ~ exists x y : nat, forall z:nat, x = z \/ y = z.
+ Proof.
+ intros (x & y & Hz).
+ destruct (Hz 0), (Hz 1), (Hz 2).
+
+ .. coqtop:: all abort
+
+ all: match goal with
+ | _ : ?a = ?b, _ : ?a = ?c |- _ => assert (b = c) by now transitivity a
+ end.
+ all: discriminate.
+
+ Notice that all the (very similar) cases coming from the three
+ eliminations (with three distinct natural numbers) are successfully
+ solved by a ``match goal`` structure and, in particular, with only one
+ pattern (use of non-linear matching).
+
+
+Proving that a list is a permutation of a second list
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. example:: Proving that a list is a permutation of a second list
+
+ Let's first define the permutation predicate:
+
+ .. coqtop:: in reset
+
+ Section Sort.
+
+ Variable A : Set.
+
+ Inductive perm : list A -> list A -> Prop :=
+ | perm_refl : forall l, perm l l
+ | perm_cons : forall a l0 l1, perm l0 l1 -> perm (a :: l0) (a :: l1)
+ | perm_append : forall a l, perm (a :: l) (l ++ a :: nil)
+ | perm_trans : forall l0 l1 l2, perm l0 l1 -> perm l1 l2 -> perm l0 l2.
+
+ End Sort.
+
+ .. coqtop:: none
+
+ Require Import List.
+
+
+ Next we define an auxiliary tactic :g:`perm_aux` which takes an
+ argument used to control the recursion depth. This tactic works as
+ follows: If the lists are identical (i.e. convertible), it
+ completes the proof. Otherwise, if the lists have identical heads,
+ it looks at their tails. Finally, if the lists have different
+ heads, it rotates the first list by putting its head at the end.
+
+ Every time we perform a rotation, we decrement :g:`n`. When :g:`n`
+ drops down to :g:`1`, we stop performing rotations and we fail.
+ The idea is to give the length of the list as the initial value of
+ :g:`n`. This way of counting the number of rotations will avoid
+ going back to a head that had been considered before.
+
+ From Section :ref:`ltac-syntax` we know that Ltac has a primitive
+ notion of integers, but they are only used as arguments for
+ primitive tactics and we cannot make computations with them. Thus,
+ instead, we use Coq's natural number type :g:`nat`.
+
+ .. coqtop:: in
+
+ Ltac perm_aux n :=
+ match goal with
+ | |- (perm _ ?l ?l) => apply perm_refl
+ | |- (perm _ (?a :: ?l1) (?a :: ?l2)) =>
+ let newn := eval compute in (length l1) in
+ (apply perm_cons; perm_aux newn)
+ | |- (perm ?A (?a :: ?l1) ?l2) =>
+ match eval compute in n with
+ | 1 => fail
+ | _ =>
+ let l1' := constr:(l1 ++ a :: nil) in
+ (apply (perm_trans A (a :: l1) l1' l2);
+ [ apply perm_append | compute; perm_aux (pred n) ])
+ end
+ end.
+
+
+ The main tactic is :g:`solve_perm`. It computes the lengths of the
+ two lists and uses them as arguments to call :g:`perm_aux` if the
+ lengths are equal. (If they aren't, the lists cannot be
+ permutations of each other.)
+
+ .. coqtop:: in
+
+ Ltac solve_perm :=
+ match goal with
+ | |- (perm _ ?l1 ?l2) =>
+ match eval compute in (length l1 = length l2) with
+ | (?n = ?n) => perm_aux n
+ end
+ end.
+
+ And now, here is how we can use the tactic :g:`solve_perm`:
+
+ .. coqtop:: out
+
+ Goal perm nat (1 :: 2 :: 3 :: nil) (3 :: 2 :: 1 :: nil).
+
+ .. coqtop:: all abort
+
+ solve_perm.
+
+ .. coqtop:: out
+
+ Goal perm nat
+ (0 :: 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: 9 :: nil)
+ (0 :: 2 :: 4 :: 6 :: 8 :: 9 :: 7 :: 5 :: 3 :: 1 :: nil).
+
+ .. coqtop:: all abort
+
+ solve_perm.
+
+
+Deciding intuitionistic propositional logic
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Pattern matching on goals allows powerful backtracking when returning tactic
+values. An interesting application is the problem of deciding intuitionistic
+propositional logic. Considering the contraction-free sequent calculi LJT* of
+Roy Dyckhoff :cite:`Dyc92`, it is quite natural to code such a tactic using the
+tactic language as shown below.
+
+.. coqtop:: in reset
+
+ Ltac basic :=
+ match goal with
+ | |- True => trivial
+ | _ : False |- _ => contradiction
+ | _ : ?A |- ?A => assumption
+ end.
+
+.. coqtop:: in
+
+ Ltac simplify :=
+ repeat (intros;
+ match goal with
+ | H : ~ _ |- _ => red in H
+ | H : _ /\ _ |- _ =>
+ elim H; do 2 intro; clear H
+ | H : _ \/ _ |- _ =>
+ elim H; intro; clear H
+ | H : ?A /\ ?B -> ?C |- _ =>
+ cut (A -> B -> C);
+ [ intro | intros; apply H; split; assumption ]
+ | H: ?A \/ ?B -> ?C |- _ =>
+ cut (B -> C);
+ [ cut (A -> C);
+ [ intros; clear H
+ | intro; apply H; left; assumption ]
+ | intro; apply H; right; assumption ]
+ | H0 : ?A -> ?B, H1 : ?A |- _ =>
+ cut B; [ intro; clear H0 | apply H0; assumption ]
+ | |- _ /\ _ => split
+ | |- ~ _ => red
+ end).
+
+.. coqtop:: in
+
+ Ltac my_tauto :=
+ simplify; basic ||
+ match goal with
+ | H : (?A -> ?B) -> ?C |- _ =>
+ cut (B -> C);
+ [ intro; cut (A -> B);
+ [ intro; cut C;
+ [ intro; clear H | apply H; assumption ]
+ | clear H ]
+ | intro; apply H; intro; assumption ]; my_tauto
+ | H : ~ ?A -> ?B |- _ =>
+ cut (False -> B);
+ [ intro; cut (A -> False);
+ [ intro; cut B;
+ [ intro; clear H | apply H; assumption ]
+ | clear H ]
+ | intro; apply H; red; intro; assumption ]; my_tauto
+ | |- _ \/ _ => (left; my_tauto) || (right; my_tauto)
+ end.
+
+The tactic ``basic`` tries to reason using simple rules involving truth, falsity
+and available assumptions. The tactic ``simplify`` applies all the reversible
+rules of Dyckhoff’s system. Finally, the tactic ``my_tauto`` (the main
+tactic to be called) simplifies with ``simplify``, tries to conclude with
+``basic`` and tries several paths using the backtracking rules (one of the
+four Dyckhoff’s rules for the left implication to get rid of the contraction
+and the right ``or``).
+
+Having defined ``my_tauto``, we can prove tautologies like these:
+
+.. coqtop:: in
+
+ Lemma my_tauto_ex1 :
+ forall A B : Prop, A /\ B -> A \/ B.
+ Proof. my_tauto. Qed.
+
+.. coqtop:: in
+
+ Lemma my_tauto_ex2 :
+ forall A B : Prop, (~ ~ B -> B) -> (A -> B) -> ~ ~ A -> B.
+ Proof. my_tauto. Qed.
+
+
+Deciding type isomorphisms
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A trickier problem is to decide equalities between types modulo
+isomorphisms. Here, we choose to use the isomorphisms of the simply
+typed λ-calculus with Cartesian product and unit type (see, for
+example, :cite:`RC95`). The axioms of this λ-calculus are given below.
+
+.. coqtop:: in reset
+
+ Open Scope type_scope.
+
+.. coqtop:: in
+
+ Section Iso_axioms.
+
+.. coqtop:: in
+
+ Variables A B C : Set.
+
+.. coqtop:: in
+
+ Axiom Com : A * B = B * A.
+
+ Axiom Ass : A * (B * C) = A * B * C.
+
+ Axiom Cur : (A * B -> C) = (A -> B -> C).
+
+ Axiom Dis : (A -> B * C) = (A -> B) * (A -> C).
+
+ Axiom P_unit : A * unit = A.
+
+ Axiom AR_unit : (A -> unit) = unit.
+
+ Axiom AL_unit : (unit -> A) = A.
+
+.. coqtop:: in
+
+ Lemma Cons : B = C -> A * B = A * C.
+
+ Proof.
+
+ intro Heq; rewrite Heq; reflexivity.
+
+ Qed.
+
+.. coqtop:: in
+
+ End Iso_axioms.
+
+.. coqtop:: in
+
+ Ltac simplify_type ty :=
+ match ty with
+ | ?A * ?B * ?C =>
+ rewrite <- (Ass A B C); try simplify_type_eq
+ | ?A * ?B -> ?C =>
+ rewrite (Cur A B C); try simplify_type_eq
+ | ?A -> ?B * ?C =>
+ rewrite (Dis A B C); try simplify_type_eq
+ | ?A * unit =>
+ rewrite (P_unit A); try simplify_type_eq
+ | unit * ?B =>
+ rewrite (Com unit B); try simplify_type_eq
+ | ?A -> unit =>
+ rewrite (AR_unit A); try simplify_type_eq
+ | unit -> ?B =>
+ rewrite (AL_unit B); try simplify_type_eq
+ | ?A * ?B =>
+ (simplify_type A; try simplify_type_eq) ||
+ (simplify_type B; try simplify_type_eq)
+ | ?A -> ?B =>
+ (simplify_type A; try simplify_type_eq) ||
+ (simplify_type B; try simplify_type_eq)
+ end
+ with simplify_type_eq :=
+ match goal with
+ | |- ?A = ?B => try simplify_type A; try simplify_type B
+ end.
+
+.. coqtop:: in
+
+ Ltac len trm :=
+ match trm with
+ | _ * ?B => let succ := len B in constr:(S succ)
+ | _ => constr:(1)
+ end.
+
+.. coqtop:: in
+
+ Ltac assoc := repeat rewrite <- Ass.
+
+.. coqtop:: in
+
+ Ltac solve_type_eq n :=
+ match goal with
+ | |- ?A = ?A => reflexivity
+ | |- ?A * ?B = ?A * ?C =>
+ apply Cons; let newn := len B in solve_type_eq newn
+ | |- ?A * ?B = ?C =>
+ match eval compute in n with
+ | 1 => fail
+ | _ =>
+ pattern (A * B) at 1; rewrite Com; assoc; solve_type_eq (pred n)
+ end
+ end.
+
+.. coqtop:: in
+
+ Ltac compare_structure :=
+ match goal with
+ | |- ?A = ?B =>
+ let l1 := len A
+ with l2 := len B in
+ match eval compute in (l1 = l2) with
+ | ?n = ?n => solve_type_eq n
+ end
+ end.
+
+.. coqtop:: in
+
+ Ltac solve_iso := simplify_type_eq; compare_structure.
+
+The tactic to judge equalities modulo this axiomatization is shown above.
+The algorithm is quite simple. First types are simplified using axioms that
+can be oriented (this is done by ``simplify_type`` and ``simplify_type_eq``).
+The normal forms are sequences of Cartesian products without a Cartesian product
+in the left component. These normal forms are then compared modulo permutation
+of the components by the tactic ``compare_structure``. If they have the same
+length, the tactic ``solve_type_eq`` attempts to prove that the types are equal.
+The main tactic that puts all these components together is ``solve_iso``.
+
+Here are examples of what can be solved by ``solve_iso``.
+
+.. coqtop:: in
+
+ Lemma solve_iso_ex1 :
+ forall A B : Set, A * unit * B = B * (unit * A).
+ Proof.
+ intros; solve_iso.
+ Qed.
+
+.. coqtop:: in
+
+ Lemma solve_iso_ex2 :
+ forall A B C : Set,
+ (A * unit -> B * (C * unit)) =
+ (A * unit -> (C -> unit) * C) * (unit -> A -> B).
+ Proof.
+ intros; solve_iso.
+ Qed.
+
+
Debugging |Ltac| tactics
------------------------
diff --git a/doc/sphinx/proof-engine/ltac2.rst b/doc/sphinx/proof-engine/ltac2.rst
index 6e33862b39..aa603fc966 100644
--- a/doc/sphinx/proof-engine/ltac2.rst
+++ b/doc/sphinx/proof-engine/ltac2.rst
@@ -668,7 +668,7 @@ A scope is a name given to a grammar entry used to produce some Ltac2 expression
at parsing time. Scopes are described using a form of S-expression.
.. prodn::
- ltac2_scope ::= @string %| @integer %| @lident ({+, @ltac2_scope})
+ ltac2_scope ::= {| @string | @integer | @lident ({+, @ltac2_scope}) }
A few scopes contain antiquotation features. For sake of uniformity, all
antiquotations are introduced by the syntax :n:`$@lident`.
@@ -751,7 +751,7 @@ Notations
The Ltac2 parser can be extended by syntactic notations.
-.. cmd:: Ltac2 Notation {+ @lident (@ltac2_scope) %| @string } {? : @integer} := @ltac2_term
+.. cmd:: Ltac2 Notation {+ {| @lident (@ltac2_scope) | @string } } {? : @integer} := @ltac2_term
:name: Ltac2 Notation
A Ltac2 notation adds a parsing rule to the Ltac2 grammar, which is expanded
@@ -823,9 +823,9 @@ Ltac2 features a toplevel loop that can be used to evaluate expressions.
Debug
-----
-.. opt:: Ltac2 Backtrace
+.. flag:: Ltac2 Backtrace
- When this option is set, toplevel failures will be printed with a backtrace.
+ When this flag is set, toplevel failures will be printed with a backtrace.
Compatibility layer with Ltac1
------------------------------
@@ -966,7 +966,7 @@ errors produced by the typechecker.
In Ltac expressions
+++++++++++++++++++
-.. exn:: Unbound ( value | constructor ) X
+.. exn:: Unbound {| value | constructor } X
* if `X` is meant to be a term from the current stactic environment, replace
the problematic use by `'X`.
diff --git a/doc/sphinx/proof-engine/proof-handling.rst b/doc/sphinx/proof-engine/proof-handling.rst
index 16b158c397..4a2f9c0db3 100644
--- a/doc/sphinx/proof-engine/proof-handling.rst
+++ b/doc/sphinx/proof-engine/proof-handling.rst
@@ -322,7 +322,7 @@ Navigation in the proof tree
.. index:: {
}
-.. cmd:: %{ %| %}
+.. cmd:: {| %{ | %} }
The command ``{`` (without a terminating period) focuses on the first
goal, much like :cmd:`Focus` does, however, the subproof can only be
@@ -430,7 +430,7 @@ not go beyond enclosing ``{`` and ``}``, so bullets can be reused as further
nesting levels provided they are delimited by these. Bullets are made of
repeated ``-``, ``+`` or ``*`` symbols:
-.. prodn:: bullet ::= {+ - } %| {+ + } %| {+ * }
+.. prodn:: bullet ::= {| {+ - } | {+ + } | {+ * } }
Note again that when a focused goal is proved a message is displayed
together with a suggestion about the right bullet or ``}`` to unfocus it
@@ -492,7 +492,7 @@ The following example script illustrates all these features:
Set Bullet Behavior
```````````````````
-.. opt:: Bullet Behavior %( "None" %| "Strict Subproofs" %)
+.. opt:: Bullet Behavior {| "None" | "Strict Subproofs" }
:name: Bullet Behavior
This option controls the bullet behavior and can take two possible values:
@@ -544,9 +544,9 @@ Requesting information
``<Your Tactic Text here>``.
- .. deprecated:: 8.10
+ .. deprecated:: 8.10
- Please use a text editor.
+ Please use a text editor.
.. cmdv:: Show Proof
:name: Show Proof
@@ -680,7 +680,7 @@ This image shows an error message with diff highlighting in CoqIDE:
How to enable diffs
```````````````````
-.. opt:: Diffs %( "on" %| "off" %| "removed" %)
+.. opt:: Diffs {| "on" | "off" | "removed" }
:name: Diffs
The “on” setting highlights added tokens in green, while the “removed” setting
diff --git a/doc/sphinx/proof-engine/ssreflect-proof-language.rst b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
index 4e40df6f94..75e019592f 100644
--- a/doc/sphinx/proof-engine/ssreflect-proof-language.rst
+++ b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
@@ -617,7 +617,7 @@ Abbreviations
selected occurrences of a term.
.. prodn::
- occ_switch ::= { {? + %| - } {* @num } }
+ occ_switch ::= { {? {| + | - } } {* @num } }
where:
@@ -2273,7 +2273,7 @@ to the others.
Iteration
~~~~~~~~~
-.. tacn:: do {? @num } ( @tactic | [ {+| @tactic } ] )
+.. tacn:: do {? @num } {| @tactic | [ {+| @tactic } ] }
:name: do (ssreflect)
This tactical offers an accurate control on the repetition of tactics.
@@ -2300,7 +2300,7 @@ tactic should be repeated on the current subgoal.
There are four kinds of multipliers:
.. prodn::
- mult ::= @num ! %| ! %| @num ? %| ?
+ mult ::= {| @num ! | ! | @num ? | ? }
Their meaning is:
@@ -2571,7 +2571,7 @@ destruction of existential assumptions like in the tactic:
An alternative use of the ``have`` tactic is to provide the explicit proof
term for the intermediate lemma, using tactics of the form:
-.. tacv:: have {? @ident } := term
+.. tacv:: have {? @ident } := @term
This tactic creates a new assumption of type the type of :token:`term`.
If the
@@ -5444,7 +5444,7 @@ equivalences are indeed taken into account, otherwise only single
|SSR| searching tool
--------------------
-.. cmd:: Search {? @pattern } {* {? - } %( @string %| @pattern %) {? % @ident} } {? in {+ {? - } @qualid } }
+.. cmd:: Search {? @pattern } {* {? - } {| @string | @pattern } {? % @ident} } {? in {+ {? - } @qualid } }
:name: Search (ssreflect)
This is the |SSR| extension of the Search command. :token:`qualid` is the
@@ -5686,7 +5686,7 @@ respectively.
local cofix definition
-.. tacn:: set @ident {? : @term } := {? @occ_switch } %( @term %| ( @c_pattern) %)
+.. tacn:: set @ident {? : @term } := {? @occ_switch } {| @term | ( @c_pattern) }
abbreviation (see :ref:`abbreviations_ssr`)
@@ -5714,26 +5714,26 @@ introduction see :ref:`introduction_ssr`
localization see :ref:`localization_ssr`
-.. prodn:: tactic += do {? @mult } %( @tactic %| [ {+| @tactic } ] %)
+.. prodn:: tactic += do {? @mult } {| @tactic | [ {+| @tactic } ] }
iteration see :ref:`iteration_ssr`
-.. prodn:: tactic += @tactic ; %( first %| last %) {? @num } %( @tactic %| [ {+| @tactic } ] %)
+.. prodn:: tactic += @tactic ; {| first | last } {? @num } {| @tactic | [ {+| @tactic } ] }
selector see :ref:`selectors_ssr`
-.. prodn:: tactic += @tactic ; %( first %| last %) {? @num }
+.. prodn:: tactic += @tactic ; {| first | last } {? @num }
rotation see :ref:`selectors_ssr`
-.. prodn:: tactic += by %( @tactic %| [ {*| @tactic } ] %)
+.. prodn:: tactic += by {| @tactic | [ {*| @tactic } ] }
closing see :ref:`terminators_ssr`
Commands
~~~~~~~~
-.. cmd:: Hint View for %( move %| apply %) / @ident {? | @num }
+.. cmd:: Hint View for {| move | apply } / @ident {? | @num }
view hint declaration (see :ref:`declaring_new_hints_ssr`)
diff --git a/doc/sphinx/proof-engine/tactics.rst b/doc/sphinx/proof-engine/tactics.rst
index 0f78a9b84a..4e47621938 100644
--- a/doc/sphinx/proof-engine/tactics.rst
+++ b/doc/sphinx/proof-engine/tactics.rst
@@ -1749,7 +1749,7 @@ analysis on inductive or co-inductive objects (see :ref:`inductive-definitions`)
They combine the effects of the ``with``, ``as``, ``eqn:``, ``using``,
and ``in`` clauses.
-.. tacn:: case term
+.. tacn:: case @term
:name: case
The tactic :n:`case` is a more basic tactic to perform case analysis without
@@ -1982,7 +1982,7 @@ analysis on inductive or co-inductive objects (see :ref:`inductive-definitions`)
:n:`induction @ident; induction @ident` (or
:n:`induction @ident ; destruct @ident` depending on the exact needs).
-.. tacv:: double induction num1 num2
+.. tacv:: double induction @num__1 @num__2
This tactic is deprecated and should be replaced by
:n:`induction num1; induction num3` where :n:`num3` is the result
@@ -2271,11 +2271,11 @@ and an explanation of the underlying technique.
:undocumented:
.. tacv:: injection @term {? with @bindings_list} as {+ @simple_intropattern}
- injection @num as {+ simple_intropattern}
- injection as {+ simple_intropattern}
- einjection @term {? with @bindings_list} as {+ simple_intropattern}
- einjection @num as {+ simple_intropattern}
- einjection as {+ simple_intropattern}
+ injection @num as {+ @simple_intropattern}
+ injection as {+ @simple_intropattern}
+ einjection @term {? with @bindings_list} as {+ @simple_intropattern}
+ einjection @num as {+ @simple_intropattern}
+ einjection as {+ @simple_intropattern}
These variants apply :n:`intros {+ @simple_intropattern}` after the call to
:tacn:`injection` or :tacn:`einjection` so that all equalities generated are moved in
@@ -2637,7 +2637,7 @@ and an explanation of the underlying technique.
is correct at some time of the interactive development of a proof, use
the command ``Guarded`` (see Section :ref:`requestinginformation`).
-.. tacv:: fix @ident @num with {+ (ident {+ @binder} [{struct @ident}] : @type)}
+.. tacv:: fix @ident @num with {+ (@ident {+ @binder} [{struct @ident}] : @type)}
This starts a proof by mutual induction. The statements to be simultaneously
proved are respectively :g:`forall binder ... binder, type`.
@@ -3561,7 +3561,7 @@ Automation
.. tacn:: autorewrite with {+ @ident}
:name: autorewrite
- This tactic [4]_ carries out rewritings according to the rewriting rule
+ This tactic carries out rewritings according to the rewriting rule
bases :n:`{+ @ident}`.
Each rewriting rule from the base :n:`@ident` is applied to the main subgoal until
@@ -3777,8 +3777,8 @@ The general command to add a hint to some databases :n:`{+ @ident}` is
discrimination network to relax or constrain it in the case of discriminated
databases.
- .. cmdv:: Hint Variables %( Transparent %| Opaque %) : @ident
- Hint Constants %( Transparent %| Opaque %) : @ident
+ .. cmdv:: Hint Variables {| Transparent | Opaque } : @ident
+ Hint Constants {| Transparent | Opaque } : @ident
:name: Hint Variables; Hint Constants
This sets the transparency flag used during unification of
@@ -3850,7 +3850,7 @@ The general command to add a hint to some databases :n:`{+ @ident}` is
semantics of :n:`Hint Cut @regexp` is to set the cut expression
to :n:`c | regexp`, the initial cut expression being `emp`.
- .. cmdv:: Hint Mode @qualid {* (+ | ! | -)} : @ident
+ .. cmdv:: Hint Mode @qualid {* {| + | ! | - } } : @ident
:name: Hint Mode
This sets an optional mode of use of the identifier :n:`@qualid`. When
@@ -4016,7 +4016,7 @@ We propose a smooth transitional path by providing the :opt:`Loose Hint Behavior
option which accepts three flags allowing for a fine-grained handling of
non-imported hints.
-.. opt:: Loose Hint Behavior %( "Lax" %| "Warn" %| "Strict" %)
+.. opt:: Loose Hint Behavior {| "Lax" | "Warn" | "Strict" }
:name: Loose Hint Behavior
This option accepts three values, which control the behavior of hints w.r.t.
@@ -4048,7 +4048,7 @@ Setting implicit automation tactics
.. seealso:: :cmd:`Proof` in :ref:`proof-editing-mode`.
- .. cmdv:: Proof with tactic using {+ @ident}
+ .. cmdv:: Proof with @tactic using {+ @ident}
Combines in a single line ``Proof with`` and ``Proof using``, see :ref:`proof-editing-mode`
@@ -4400,6 +4400,11 @@ Equality
This tactic applies to a goal that has the form :g:`t=u` and transforms it
into the two subgoals :n:`t=@term` and :n:`@term=u`.
+ .. tacv:: etransitivity
+
+ This tactic behaves like :tacn:`transitivity`, using a fresh evar instead of
+ a concrete :token:`term`.
+
Equality and inductive sets
---------------------------
@@ -4661,9 +4666,12 @@ Non-logical tactics
.. example::
- .. coqtop:: all reset
+ .. coqtop:: none reset
Parameter P : nat -> Prop.
+
+ .. coqtop:: all abort
+
Goal P 1 /\ P 2 /\ P 3 /\ P 4 /\ P 5.
repeat split.
all: cycle 2.
@@ -4679,9 +4687,8 @@ Non-logical tactics
.. example::
- .. coqtop:: reset all
+ .. coqtop:: all abort
- Parameter P : nat -> Prop.
Goal P 1 /\ P 2 /\ P 3 /\ P 4 /\ P 5.
repeat split.
all: swap 1 3.
@@ -4694,9 +4701,8 @@ Non-logical tactics
.. example::
- .. coqtop:: all reset
+ .. coqtop:: all abort
- Parameter P : nat -> Prop.
Goal P 1 /\ P 2 /\ P 3 /\ P 4 /\ P 5.
repeat split.
all: revgoals.
@@ -4717,7 +4723,7 @@ Non-logical tactics
.. example::
- .. coqtop:: all reset
+ .. coqtop:: all abort
Goal exists n, n=0.
refine (ex_intro _ _ _).
@@ -4746,39 +4752,6 @@ Non-logical tactics
The ``give_up`` tactic can be used while editing a proof, to choose to
write the proof script in a non-sequential order.
-Simple tactic macros
--------------------------
-
-A simple example has more value than a long explanation:
-
-.. example::
-
- .. coqtop:: reset all
-
- Ltac Solve := simpl; intros; auto.
-
- Ltac ElimBoolRewrite b H1 H2 :=
- elim b; [ intros; rewrite H1; eauto | intros; rewrite H2; eauto ].
-
-The tactics macros are synchronous with the Coq section mechanism: a
-tactic definition is deleted from the current environment when you
-close the section (see also :ref:`section-mechanism`) where it was
-defined. If you want that a tactic macro defined in a module is usable in the
-modules that require it, you should put it outside of any section.
-
-:ref:`ltac` gives examples of more complex
-user-defined tactics.
-
-.. [1] Actually, only the second subgoal will be generated since the
- other one can be automatically checked.
-.. [2] This corresponds to the cut rule of sequent calculus.
-.. [3] Reminder: opaque constants will not be expanded by δ reductions.
-.. [4] The behavior of this tactic has changed a lot compared to the
- versions available in the previous distributions (V6). This may cause
- significant changes in your theories to obtain the same result. As a
- drawback of the re-engineering of the code, this tactic has also been
- completely revised to get a very compact and readable version.
-
Delaying solving unification constraints
----------------------------------------
@@ -4917,3 +4890,8 @@ Performance-oriented tactic variants
Goal False.
native_cast_no_check I.
Fail Qed.
+
+.. [1] Actually, only the second subgoal will be generated since the
+ other one can be automatically checked.
+.. [2] This corresponds to the cut rule of sequent calculus.
+.. [3] Reminder: opaque constants will not be expanded by δ reductions.
diff --git a/doc/sphinx/proof-engine/vernacular-commands.rst b/doc/sphinx/proof-engine/vernacular-commands.rst
index e207a072cc..26dc4e02cf 100644
--- a/doc/sphinx/proof-engine/vernacular-commands.rst
+++ b/doc/sphinx/proof-engine/vernacular-commands.rst
@@ -91,13 +91,13 @@ and tables:
Flags, options and tables are identified by a series of identifiers, each with an initial
capital letter.
-.. cmd:: {? Local | Global | Export } Set @flag
+.. cmd:: {? {| Local | Global | Export } } Set @flag
:name: Set
Sets :token:`flag` on. Scoping qualifiers are
described :ref:`here <set_unset_scope_qualifiers>`.
-.. cmd:: {? Local | Global | Export } Unset @flag
+.. cmd:: {? {| Local | Global | Export } } Unset @flag
:name: Unset
Sets :token:`flag` off. Scoping qualifiers are
@@ -108,13 +108,13 @@ capital letter.
Prints the current value of :token:`flag`.
-.. cmd:: {? Local | Global | Export } Set @option ( @num | @string )
+.. cmd:: {? {| Local | Global | Export } } Set @option {| @num | @string }
:name: Set @option
Sets :token:`option` to the specified value. Scoping qualifiers are
described :ref:`here <set_unset_scope_qualifiers>`.
-.. cmd:: {? Local | Global | Export } Unset @option
+.. cmd:: {? {| Local | Global | Export } } Unset @option
:name: Unset @option
Sets :token:`option` to its default value. Scoping qualifiers are
@@ -129,17 +129,17 @@ capital letter.
Prints the current value of all flags and options, and the names of all tables.
-.. cmd:: Add @table ( @string | @qualid )
+.. cmd:: Add @table {| @string | @qualid }
:name: Add @table
Adds the specified value to :token:`table`.
-.. cmd:: Remove @table ( @string | @qualid )
+.. cmd:: Remove @table {| @string | @qualid }
:name: Remove @table
Removes the specified value from :token:`table`.
-.. cmd:: Test @table for ( @string | @qualid )
+.. cmd:: Test @table for {| @string | @qualid }
:name: Test @table for
Reports whether :token:`table` contains the specified value.
@@ -162,7 +162,7 @@ capital letter.
Scope qualifiers for :cmd:`Set` and :cmd:`Unset`
`````````````````````````````````````````````````
-:n:`{? Local | Global | Export }`
+:n:`{? {| Local | Global | Export } }`
Flag and option settings can be global in scope or local to nested scopes created by
:cmd:`Module` and :cmd:`Section` commands. There are four alternatives:
@@ -277,7 +277,7 @@ Requests to the environment
:token:`term_pattern` (holes of the pattern are either denoted by `_` or by
:n:`?@ident` when non linear patterns are expected).
- .. cmdv:: Search { + [-]@term_pattern_string }
+ .. cmdv:: Search {+ {? -}@term_pattern_string}
where
:n:`@term_pattern_string` is a term_pattern, a string, or a string followed
@@ -289,17 +289,17 @@ Requests to the environment
prefixed by `-`, the search excludes the objects that mention that
term_pattern or that string.
- .. cmdv:: Search @term_pattern_string … @term_pattern_string inside {+ @qualid }
+ .. cmdv:: Search {+ {? -}@term_pattern_string} inside {+ @qualid }
This restricts the search to constructions defined in the modules
named by the given :n:`qualid` sequence.
- .. cmdv:: Search @term_pattern_string … @term_pattern_string outside {+ @qualid }
+ .. cmdv:: Search {+ {? -}@term_pattern_string} outside {+ @qualid }
This restricts the search to constructions not defined in the modules
named by the given :n:`qualid` sequence.
- .. cmdv:: @selector: Search [-]@term_pattern_string … [-]@term_pattern_string
+ .. cmdv:: @selector: Search {+ {? -}@term_pattern_string}
This specifies the goal on which to search hypothesis (see
Section :ref:`invocation-of-tactics`).
@@ -353,7 +353,7 @@ Requests to the environment
This restricts the search to constructions defined in the modules named
by the given :n:`qualid` sequence.
- .. cmdv:: SearchHead term outside {+ @qualid }
+ .. cmdv:: SearchHead @term outside {+ @qualid }
This restricts the search to constructions not defined in the modules
named by the given :n:`qualid` sequence.
@@ -443,7 +443,7 @@ Requests to the environment
SearchRewrite (_ + _ + _).
- .. cmdv:: SearchRewrite term inside {+ @qualid }
+ .. cmdv:: SearchRewrite @term inside {+ @qualid }
This restricts the search to constructions defined in the modules
named by the given :n:`qualid` sequence.
@@ -622,7 +622,7 @@ file is a particular case of module called *library file*.
but if a further module, say `A`, contains a command :cmd:`Require Export` `B`,
then the command :cmd:`Require Import` `A` also imports the module `B.`
- .. cmdv:: Require [Import | Export] {+ @qualid }
+ .. cmdv:: Require {| Import | Export } {+ @qualid }
This loads the
modules named by the :token:`qualid` sequence and their recursive
@@ -988,7 +988,7 @@ Controlling display
This option controls the normal displaying.
-.. opt:: Warnings "{+, {? %( - %| + %) } @ident }"
+.. opt:: Warnings "{+, {? {| - | + } } @ident }"
:name: Warnings
This option configures the display of warnings. It is experimental, and
diff --git a/doc/sphinx/user-extensions/proof-schemes.rst b/doc/sphinx/user-extensions/proof-schemes.rst
index 418922e9b3..3a12ee288a 100644
--- a/doc/sphinx/user-extensions/proof-schemes.rst
+++ b/doc/sphinx/user-extensions/proof-schemes.rst
@@ -336,29 +336,32 @@ Generation of induction principles with ``Functional`` ``Scheme``
Generation of inversion principles with ``Derive`` ``Inversion``
-----------------------------------------------------------------
-.. cmd:: Derive Inversion @ident with forall (x : T), I t Sort sort
+.. cmd:: Derive Inversion @ident with @ident Sort @sort
+ Derive Inversion @ident with (forall @binders, @ident @term) Sort @sort
This command generates an inversion principle for the
- :tacn:`inversion ... using ...` tactic. Let :g:`I` be an inductive
- predicate and :g:`x` the variables occurring in t. This command
- generates and stocks the inversion lemma for the sort :g:`sort`
- corresponding to the instance :g:`∀ (x:T), I t` with the name
- :n:`@ident` in the global environment. When applied, it is
- equivalent to having inverted the instance with the tactic
- :g:`inversion`.
-
+ :tacn:`inversion ... using ...` tactic. The first :token:`ident` is the name
+ of the generated principle. The second :token:`ident` should be an inductive
+ predicate, and :token:`binders` the variables occurring in the term
+ :token:`term`. This command generates the inversion lemma for the sort
+ :token:`sort` corresponding to the instance :n:`forall @binders, @ident @term`.
+ When applied, it is equivalent to having inverted the instance with the
+ tactic :g:`inversion`.
-.. cmdv:: Derive Inversion_clear @ident with forall (x:T), I t Sort @sort
+.. cmdv:: Derive Inversion_clear @ident with @ident Sort @sort
+ Derive Inversion_clear @ident with (forall @binders, @ident @term) Sort @sort
When applied, it is equivalent to having inverted the instance with the
tactic inversion replaced by the tactic `inversion_clear`.
-.. cmdv:: Derive Dependent Inversion @ident with forall (x:T), I t Sort @sort
+.. cmdv:: Derive Dependent Inversion @ident with @ident Sort @sort
+ Derive Dependent Inversion @ident with (forall @binders, @ident @term) Sort @sort
When applied, it is equivalent to having inverted the instance with
the tactic `dependent inversion`.
-.. cmdv:: Derive Dependent Inversion_clear @ident with forall(x:T), I t Sort @sort
+.. cmdv:: Derive Dependent Inversion_clear @ident with @ident Sort @sort
+ Derive Dependent Inversion_clear @ident with (forall @binders, @ident @term) Sort @sort
When applied, it is equivalent to having inverted the instance
with the tactic `dependent inversion_clear`.
diff --git a/doc/sphinx/user-extensions/syntax-extensions.rst b/doc/sphinx/user-extensions/syntax-extensions.rst
index ac079ea7d5..cda228a7da 100644
--- a/doc/sphinx/user-extensions/syntax-extensions.rst
+++ b/doc/sphinx/user-extensions/syntax-extensions.rst
@@ -327,22 +327,29 @@ symbols.
Reserving notations
~~~~~~~~~~~~~~~~~~~
-A given notation may be used in different contexts. Coq expects all
-uses of the notation to be defined at the same precedence and with the
-same associativity. To avoid giving the precedence and associativity
-every time, it is possible to declare a parsing rule in advance
-without giving its interpretation. Here is an example from the initial
-state of Coq.
+.. cmd:: Reserved Notation @string {? (@modifiers) }
-.. coqtop:: in
+ A given notation may be used in different contexts. Coq expects all
+ uses of the notation to be defined at the same precedence and with the
+ same associativity. To avoid giving the precedence and associativity
+ every time, this command declares a parsing rule (:token:`string`) in advance
+ without giving its interpretation. Here is an example from the initial
+ state of Coq.
+
+ .. coqtop:: in
+
+ Reserved Notation "x = y" (at level 70, no associativity).
+
+ Reserving a notation is also useful for simultaneously defining an
+ inductive type or a recursive constant and a notation for it.
- Reserved Notation "x = y" (at level 70, no associativity).
+ .. note:: The notations mentioned in the module :ref:`init-notations` are reserved. Hence
+ their precedence and associativity cannot be changed.
-Reserving a notation is also useful for simultaneously defining an
-inductive type or a recursive constant and a notation for it.
+ .. cmdv:: Reserved Infix "@symbol" {* @modifiers}
-.. note:: The notations mentioned in the module :ref:`init-notations` are reserved. Hence
- their precedence and associativity cannot be changed.
+ This command declares an infix parsing rule without giving its
+ interpretation.
Simultaneous definition of terms and notations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -840,10 +847,11 @@ gives a way to let any arbitrary expression which is not handled by the
custom entry ``expr`` be parsed or printed by the main grammar of term
up to the insertion of a pair of curly brackets.
-.. cmd:: Print Grammar @ident.
+.. cmd:: Print Custom Grammar @ident.
+ :name: Print Custom Grammar
- This displays the state of the grammar for terms and grammar for
- patterns associated to the custom entry :token:`ident`.
+ This displays the state of the grammar for terms associated to
+ the custom entry :token:`ident`.
Summary
~~~~~~~
diff --git a/doc/tools/coqrst/coqdomain.py b/doc/tools/coqrst/coqdomain.py
index 0ade9fdbf5..4bdfac7c42 100644
--- a/doc/tools/coqrst/coqdomain.py
+++ b/doc/tools/coqrst/coqdomain.py
@@ -39,14 +39,29 @@ from sphinx.ext import mathbase
from . import coqdoc
from .repl import ansicolors
from .repl.coqtop import CoqTop, CoqTopError
+from .notations.parsing import ParseError
from .notations.sphinx import sphinxify
from .notations.plain import stringify_with_ellipses
-def parse_notation(notation, source, line, rawtext=None):
+PARSE_ERROR = """Parse error in notation!
+Offending notation: {}
+Error message: {}"""
+
+def notation_to_sphinx(notation, source, line, rawtext=None):
"""Parse notation and wrap it in an inline node"""
- node = nodes.inline(rawtext or notation, '', *sphinxify(notation), classes=['notation'])
- node.source, node.line = source, line
- return node
+ try:
+ node = nodes.inline(rawtext or notation, '', *sphinxify(notation), classes=['notation'])
+ node.source, node.line = source, line
+ return node
+ except ParseError as e:
+ raise ExtensionError(PARSE_ERROR.format(notation, e.msg)) from e
+
+def notation_to_string(notation):
+ """Parse notation and format it as a string with ellipses."""
+ try:
+ return stringify_with_ellipses(notation)
+ except ParseError as e:
+ raise ExtensionError(PARSE_ERROR.format(notation, e.msg)) from e
def highlight_using_coqdoc(sentence):
"""Lex sentence using coqdoc, and yield inline nodes for each token"""
@@ -136,7 +151,7 @@ class CoqObject(ObjectDescription):
self._render_signature(signature, signode)
name = self._names.get(signature)
if name is None:
- name = self._name_from_signature(signature)
+ name = self._name_from_signature(signature) # pylint: disable=assignment-from-none
# remove trailing ‘.’ found in commands, but not ‘...’ (ellipsis)
if name is not None and name.endswith(".") and not name.endswith("..."):
name = name[:-1]
@@ -241,7 +256,7 @@ class NotationObject(DocumentableObject):
"""
def _render_signature(self, signature, signode):
position = self.state_machine.get_source_and_line(self.lineno)
- tacn_node = parse_notation(signature, *position)
+ tacn_node = notation_to_sphinx(signature, *position)
signode += addnodes.desc_name(signature, '', tacn_node)
class GallinaObject(PlainObject):
@@ -346,7 +361,7 @@ class OptionObject(NotationObject):
annotation = "Option"
def _name_from_signature(self, signature):
- return stringify_with_ellipses(signature)
+ return notation_to_string(signature)
class FlagObject(NotationObject):
@@ -365,7 +380,7 @@ class FlagObject(NotationObject):
annotation = "Flag"
def _name_from_signature(self, signature):
- return stringify_with_ellipses(signature)
+ return notation_to_string(signature)
class TableObject(NotationObject):
@@ -383,7 +398,7 @@ class TableObject(NotationObject):
annotation = "Table"
def _name_from_signature(self, signature):
- return stringify_with_ellipses(signature)
+ return notation_to_string(signature)
class ProductionObject(CoqObject):
r"""A grammar production.
@@ -403,7 +418,7 @@ class ProductionObject(CoqObject):
Example::
.. prodn:: term += let: @pattern := @term in @term
- .. prodn:: occ_switch ::= { {? + %| - } {* @num } }
+ .. prodn:: occ_switch ::= { {? {| + | - } } {* @num } }
"""
subdomain = "prodn"
@@ -432,7 +447,7 @@ class ProductionObject(CoqObject):
lhs_node = nodes.literal(lhs_op, lhs_op)
position = self.state_machine.get_source_and_line(self.lineno)
- rhs_node = parse_notation(rhs, *position)
+ rhs_node = notation_to_sphinx(rhs, *position)
signode += addnodes.desc_name(signature, '', lhs_node, rhs_node)
return ('token', lhs) if op == '::=' else None
@@ -475,7 +490,7 @@ class ExceptionObject(NotationObject):
# Generate names automatically
def _name_from_signature(self, signature):
- return stringify_with_ellipses(signature)
+ return notation_to_string(signature)
class WarningObject(NotationObject):
"""An warning raised by a Coq command or tactic..
@@ -497,7 +512,7 @@ class WarningObject(NotationObject):
# Generate names automatically
def _name_from_signature(self, signature):
- return stringify_with_ellipses(signature)
+ return notation_to_string(signature)
def NotationRole(role, rawtext, text, lineno, inliner, options={}, content=[]):
#pylint: disable=unused-argument, dangerous-default-value
@@ -516,7 +531,7 @@ def NotationRole(role, rawtext, text, lineno, inliner, options={}, content=[]):
"""
notation = utils.unescape(text, 1)
position = inliner.reporter.get_source_and_line(lineno)
- return [nodes.literal(rawtext, '', parse_notation(notation, *position, rawtext=rawtext))], []
+ return [nodes.literal(rawtext, '', notation_to_sphinx(notation, *position, rawtext=rawtext))], []
def coq_code_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
#pylint: disable=dangerous-default-value
diff --git a/doc/tools/coqrst/notations/TacticNotations.g b/doc/tools/coqrst/notations/TacticNotations.g
index a889ebda7b..01c656eb23 100644
--- a/doc/tools/coqrst/notations/TacticNotations.g
+++ b/doc/tools/coqrst/notations/TacticNotations.g
@@ -13,21 +13,38 @@ grammar TacticNotations;
// needs rendering (in particular whitespace (kept in output) vs. WHITESPACE
// (discarded)).
+// The distinction between nopipeblock and block is needed because we only want
+// to require escaping within alternative blocks, so that e.g. `first [ x | y ]`
+// can be written without escaping the `|`.
+
top: blocks EOF;
blocks: block ((whitespace)? block)*;
-block: atomic | meta | hole | repeat | curlies;
-repeat: LGROUP (ATOM)? WHITESPACE blocks (WHITESPACE)? RBRACE;
+
+block: pipe | nopipeblock;
+nopipeblock: atomic | escaped | hole | alternative | repeat | curlies;
+
+alternative: LALT (WHITESPACE)? altblocks (WHITESPACE)? RBRACE;
+altblocks: altblock ((WHITESPACE)? altsep (WHITESPACE)? altblock)+;
+altblock: nopipeblock ((whitespace)? nopipeblock)*;
+
+repeat: LGROUP (ATOM | PIPE)? WHITESPACE blocks (WHITESPACE)? RBRACE;
curlies: LBRACE (whitespace)? blocks (whitespace)? RBRACE;
+
+pipe: PIPE;
+altsep: PIPE;
whitespace: WHITESPACE;
-meta: METACHAR;
+escaped: ESCAPED;
atomic: ATOM (SUB)?;
hole: ID (SUB)?;
-LGROUP: '{' [+*?];
+
+LALT: '{|';
+LGROUP: '{+' | '{*' | '{?';
LBRACE: '{';
RBRACE: '}';
-METACHAR: '%' [|(){}];
-ATOM: '@' | '_' | ~[@_{} ]+;
+ESCAPED: '%{' | '%}' | '%|';
+PIPE: '|';
+ATOM: '@' | '_' | ~[@_{}| ]+;
ID: '@' ('_'? [a-zA-Z0-9])+;
SUB: '_' '_' [a-zA-Z0-9]+;
WHITESPACE: ' '+;
diff --git a/doc/tools/coqrst/notations/TacticNotations.tokens b/doc/tools/coqrst/notations/TacticNotations.tokens
index 88b38f97a6..2670e20aa6 100644
--- a/doc/tools/coqrst/notations/TacticNotations.tokens
+++ b/doc/tools/coqrst/notations/TacticNotations.tokens
@@ -1,10 +1,14 @@
-LGROUP=1
-LBRACE=2
-RBRACE=3
-METACHAR=4
-ATOM=5
-ID=6
-SUB=7
-WHITESPACE=8
-'{'=2
-'}'=3
+LALT=1
+LGROUP=2
+LBRACE=3
+RBRACE=4
+ESCAPED=5
+PIPE=6
+ATOM=7
+ID=8
+SUB=9
+WHITESPACE=10
+'{|'=1
+'{'=3
+'}'=4
+'|'=6
diff --git a/doc/tools/coqrst/notations/TacticNotationsLexer.py b/doc/tools/coqrst/notations/TacticNotationsLexer.py
index 27293e7e09..e3a115e32a 100644
--- a/doc/tools/coqrst/notations/TacticNotationsLexer.py
+++ b/doc/tools/coqrst/notations/TacticNotationsLexer.py
@@ -1,4 +1,4 @@
-# Generated from TacticNotations.g by ANTLR 4.7
+# Generated from TacticNotations.g by ANTLR 4.7.2
from antlr4 import *
from io import StringIO
from typing.io import TextIO
@@ -7,28 +7,34 @@ import sys
def serializedATN():
with StringIO() as buf:
- buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\n")
- buf.write(":\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
- buf.write("\4\b\t\b\4\t\t\t\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3")
- buf.write("\5\3\6\3\6\6\6 \n\6\r\6\16\6!\5\6$\n\6\3\7\3\7\5\7(\n")
- buf.write("\7\3\7\6\7+\n\7\r\7\16\7,\3\b\3\b\3\b\6\b\62\n\b\r\b\16")
- buf.write("\b\63\3\t\6\t\67\n\t\r\t\16\t8\2\2\n\3\3\5\4\7\5\t\6\13")
- buf.write("\7\r\b\17\t\21\n\3\2\7\4\2,-AA\4\2*+}\177\4\2BBaa\7\2")
- buf.write("\"\"BBaa}}\177\177\5\2\62;C\\c|\2?\2\3\3\2\2\2\2\5\3\2")
- buf.write("\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2")
- buf.write("\2\17\3\2\2\2\2\21\3\2\2\2\3\23\3\2\2\2\5\26\3\2\2\2\7")
- buf.write("\30\3\2\2\2\t\32\3\2\2\2\13#\3\2\2\2\r%\3\2\2\2\17.\3")
- buf.write("\2\2\2\21\66\3\2\2\2\23\24\7}\2\2\24\25\t\2\2\2\25\4\3")
- buf.write("\2\2\2\26\27\7}\2\2\27\6\3\2\2\2\30\31\7\177\2\2\31\b")
- buf.write("\3\2\2\2\32\33\7\'\2\2\33\34\t\3\2\2\34\n\3\2\2\2\35$")
- buf.write("\t\4\2\2\36 \n\5\2\2\37\36\3\2\2\2 !\3\2\2\2!\37\3\2\2")
- buf.write("\2!\"\3\2\2\2\"$\3\2\2\2#\35\3\2\2\2#\37\3\2\2\2$\f\3")
- buf.write("\2\2\2%*\7B\2\2&(\7a\2\2\'&\3\2\2\2\'(\3\2\2\2()\3\2\2")
- buf.write("\2)+\t\6\2\2*\'\3\2\2\2+,\3\2\2\2,*\3\2\2\2,-\3\2\2\2")
- buf.write("-\16\3\2\2\2./\7a\2\2/\61\7a\2\2\60\62\t\6\2\2\61\60\3")
- buf.write("\2\2\2\62\63\3\2\2\2\63\61\3\2\2\2\63\64\3\2\2\2\64\20")
- buf.write("\3\2\2\2\65\67\7\"\2\2\66\65\3\2\2\2\678\3\2\2\28\66\3")
- buf.write("\2\2\289\3\2\2\29\22\3\2\2\2\t\2!#\',\638\2")
+ buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\f")
+ buf.write("M\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
+ buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\3\2\3\2\3\2\3\3\3\3")
+ buf.write("\3\3\3\3\3\3\3\3\5\3!\n\3\3\4\3\4\3\5\3\5\3\6\3\6\3\6")
+ buf.write("\3\6\3\6\3\6\5\6-\n\6\3\7\3\7\3\b\3\b\6\b\63\n\b\r\b\16")
+ buf.write("\b\64\5\b\67\n\b\3\t\3\t\5\t;\n\t\3\t\6\t>\n\t\r\t\16")
+ buf.write("\t?\3\n\3\n\3\n\6\nE\n\n\r\n\16\nF\3\13\6\13J\n\13\r\13")
+ buf.write("\16\13K\2\2\f\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13")
+ buf.write("\25\f\3\2\5\4\2BBaa\6\2\"\"BBaa}\177\5\2\62;C\\c|\2V\2")
+ buf.write("\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3")
+ buf.write("\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2")
+ buf.write("\2\2\2\25\3\2\2\2\3\27\3\2\2\2\5 \3\2\2\2\7\"\3\2\2\2")
+ buf.write("\t$\3\2\2\2\13,\3\2\2\2\r.\3\2\2\2\17\66\3\2\2\2\218\3")
+ buf.write("\2\2\2\23A\3\2\2\2\25I\3\2\2\2\27\30\7}\2\2\30\31\7~\2")
+ buf.write("\2\31\4\3\2\2\2\32\33\7}\2\2\33!\7-\2\2\34\35\7}\2\2\35")
+ buf.write("!\7,\2\2\36\37\7}\2\2\37!\7A\2\2 \32\3\2\2\2 \34\3\2\2")
+ buf.write("\2 \36\3\2\2\2!\6\3\2\2\2\"#\7}\2\2#\b\3\2\2\2$%\7\177")
+ buf.write("\2\2%\n\3\2\2\2&\'\7\'\2\2\'-\7}\2\2()\7\'\2\2)-\7\177")
+ buf.write("\2\2*+\7\'\2\2+-\7~\2\2,&\3\2\2\2,(\3\2\2\2,*\3\2\2\2")
+ buf.write("-\f\3\2\2\2./\7~\2\2/\16\3\2\2\2\60\67\t\2\2\2\61\63\n")
+ buf.write("\3\2\2\62\61\3\2\2\2\63\64\3\2\2\2\64\62\3\2\2\2\64\65")
+ buf.write("\3\2\2\2\65\67\3\2\2\2\66\60\3\2\2\2\66\62\3\2\2\2\67")
+ buf.write("\20\3\2\2\28=\7B\2\29;\7a\2\2:9\3\2\2\2:;\3\2\2\2;<\3")
+ buf.write("\2\2\2<>\t\4\2\2=:\3\2\2\2>?\3\2\2\2?=\3\2\2\2?@\3\2\2")
+ buf.write("\2@\22\3\2\2\2AB\7a\2\2BD\7a\2\2CE\t\4\2\2DC\3\2\2\2E")
+ buf.write("F\3\2\2\2FD\3\2\2\2FG\3\2\2\2G\24\3\2\2\2HJ\7\"\2\2IH")
+ buf.write("\3\2\2\2JK\3\2\2\2KI\3\2\2\2KL\3\2\2\2L\26\3\2\2\2\13")
+ buf.write("\2 ,\64\66:?FK\2")
return buf.getvalue()
@@ -38,34 +44,36 @@ class TacticNotationsLexer(Lexer):
decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
- LGROUP = 1
- LBRACE = 2
- RBRACE = 3
- METACHAR = 4
- ATOM = 5
- ID = 6
- SUB = 7
- WHITESPACE = 8
+ LALT = 1
+ LGROUP = 2
+ LBRACE = 3
+ RBRACE = 4
+ ESCAPED = 5
+ PIPE = 6
+ ATOM = 7
+ ID = 8
+ SUB = 9
+ WHITESPACE = 10
channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ]
modeNames = [ "DEFAULT_MODE" ]
literalNames = [ "<INVALID>",
- "'{'", "'}'" ]
+ "'{|'", "'{'", "'}'", "'|'" ]
symbolicNames = [ "<INVALID>",
- "LGROUP", "LBRACE", "RBRACE", "METACHAR", "ATOM", "ID", "SUB",
- "WHITESPACE" ]
+ "LALT", "LGROUP", "LBRACE", "RBRACE", "ESCAPED", "PIPE", "ATOM",
+ "ID", "SUB", "WHITESPACE" ]
- ruleNames = [ "LGROUP", "LBRACE", "RBRACE", "METACHAR", "ATOM", "ID",
- "SUB", "WHITESPACE" ]
+ ruleNames = [ "LALT", "LGROUP", "LBRACE", "RBRACE", "ESCAPED", "PIPE",
+ "ATOM", "ID", "SUB", "WHITESPACE" ]
grammarFileName = "TacticNotations.g"
def __init__(self, input=None, output:TextIO = sys.stdout):
super().__init__(input, output)
- self.checkVersion("4.7")
+ self.checkVersion("4.7.2")
self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache())
self._actions = None
self._predicates = None
diff --git a/doc/tools/coqrst/notations/TacticNotationsLexer.tokens b/doc/tools/coqrst/notations/TacticNotationsLexer.tokens
index 88b38f97a6..2670e20aa6 100644
--- a/doc/tools/coqrst/notations/TacticNotationsLexer.tokens
+++ b/doc/tools/coqrst/notations/TacticNotationsLexer.tokens
@@ -1,10 +1,14 @@
-LGROUP=1
-LBRACE=2
-RBRACE=3
-METACHAR=4
-ATOM=5
-ID=6
-SUB=7
-WHITESPACE=8
-'{'=2
-'}'=3
+LALT=1
+LGROUP=2
+LBRACE=3
+RBRACE=4
+ESCAPED=5
+PIPE=6
+ATOM=7
+ID=8
+SUB=9
+WHITESPACE=10
+'{|'=1
+'{'=3
+'}'=4
+'|'=6
diff --git a/doc/tools/coqrst/notations/TacticNotationsParser.py b/doc/tools/coqrst/notations/TacticNotationsParser.py
index 645f078979..4a2a73672a 100644
--- a/doc/tools/coqrst/notations/TacticNotationsParser.py
+++ b/doc/tools/coqrst/notations/TacticNotationsParser.py
@@ -1,4 +1,4 @@
-# Generated from TacticNotations.g by ANTLR 4.7
+# Generated from TacticNotations.g by ANTLR 4.7.2
# encoding: utf-8
from antlr4 import *
from io import StringIO
@@ -7,31 +7,47 @@ import sys
def serializedATN():
with StringIO() as buf:
- buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\n")
- buf.write("J\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b")
- buf.write("\t\b\4\t\t\t\4\n\t\n\3\2\3\2\3\2\3\3\3\3\5\3\32\n\3\3")
- buf.write("\3\7\3\35\n\3\f\3\16\3 \13\3\3\4\3\4\3\4\3\4\3\4\5\4\'")
- buf.write("\n\4\3\5\3\5\5\5+\n\5\3\5\3\5\3\5\5\5\60\n\5\3\5\3\5\3")
- buf.write("\6\3\6\5\6\66\n\6\3\6\3\6\5\6:\n\6\3\6\3\6\3\7\3\7\3\b")
- buf.write("\3\b\3\t\3\t\5\tD\n\t\3\n\3\n\5\nH\n\n\3\n\2\2\13\2\4")
- buf.write("\6\b\n\f\16\20\22\2\2\2L\2\24\3\2\2\2\4\27\3\2\2\2\6&")
- buf.write("\3\2\2\2\b(\3\2\2\2\n\63\3\2\2\2\f=\3\2\2\2\16?\3\2\2")
- buf.write("\2\20A\3\2\2\2\22E\3\2\2\2\24\25\5\4\3\2\25\26\7\2\2\3")
- buf.write("\26\3\3\2\2\2\27\36\5\6\4\2\30\32\5\f\7\2\31\30\3\2\2")
- buf.write("\2\31\32\3\2\2\2\32\33\3\2\2\2\33\35\5\6\4\2\34\31\3\2")
- buf.write("\2\2\35 \3\2\2\2\36\34\3\2\2\2\36\37\3\2\2\2\37\5\3\2")
- buf.write("\2\2 \36\3\2\2\2!\'\5\20\t\2\"\'\5\16\b\2#\'\5\22\n\2")
- buf.write("$\'\5\b\5\2%\'\5\n\6\2&!\3\2\2\2&\"\3\2\2\2&#\3\2\2\2")
- buf.write("&$\3\2\2\2&%\3\2\2\2\'\7\3\2\2\2(*\7\3\2\2)+\7\7\2\2*")
- buf.write(")\3\2\2\2*+\3\2\2\2+,\3\2\2\2,-\7\n\2\2-/\5\4\3\2.\60")
- buf.write("\7\n\2\2/.\3\2\2\2/\60\3\2\2\2\60\61\3\2\2\2\61\62\7\5")
- buf.write("\2\2\62\t\3\2\2\2\63\65\7\4\2\2\64\66\5\f\7\2\65\64\3")
- buf.write("\2\2\2\65\66\3\2\2\2\66\67\3\2\2\2\679\5\4\3\28:\5\f\7")
- buf.write("\298\3\2\2\29:\3\2\2\2:;\3\2\2\2;<\7\5\2\2<\13\3\2\2\2")
- buf.write("=>\7\n\2\2>\r\3\2\2\2?@\7\6\2\2@\17\3\2\2\2AC\7\7\2\2")
- buf.write("BD\7\t\2\2CB\3\2\2\2CD\3\2\2\2D\21\3\2\2\2EG\7\b\2\2F")
- buf.write("H\7\t\2\2GF\3\2\2\2GH\3\2\2\2H\23\3\2\2\2\13\31\36&*/")
- buf.write("\659CG")
+ buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\f")
+ buf.write("\u0081\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
+ buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16")
+ buf.write("\t\16\4\17\t\17\4\20\t\20\3\2\3\2\3\2\3\3\3\3\5\3&\n\3")
+ buf.write("\3\3\7\3)\n\3\f\3\16\3,\13\3\3\4\3\4\5\4\60\n\4\3\5\3")
+ buf.write("\5\3\5\3\5\3\5\3\5\5\58\n\5\3\6\3\6\5\6<\n\6\3\6\3\6\5")
+ buf.write("\6@\n\6\3\6\3\6\3\7\3\7\5\7F\n\7\3\7\3\7\5\7J\n\7\3\7")
+ buf.write("\3\7\6\7N\n\7\r\7\16\7O\3\b\3\b\5\bT\n\b\3\b\7\bW\n\b")
+ buf.write("\f\b\16\bZ\13\b\3\t\3\t\5\t^\n\t\3\t\3\t\3\t\5\tc\n\t")
+ buf.write("\3\t\3\t\3\n\3\n\5\ni\n\n\3\n\3\n\5\nm\n\n\3\n\3\n\3\13")
+ buf.write("\3\13\3\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\5\17{\n\17\3")
+ buf.write("\20\3\20\5\20\177\n\20\3\20\2\2\21\2\4\6\b\n\f\16\20\22")
+ buf.write("\24\26\30\32\34\36\2\3\3\2\b\t\2\u0086\2 \3\2\2\2\4#\3")
+ buf.write("\2\2\2\6/\3\2\2\2\b\67\3\2\2\2\n9\3\2\2\2\fC\3\2\2\2\16")
+ buf.write("Q\3\2\2\2\20[\3\2\2\2\22f\3\2\2\2\24p\3\2\2\2\26r\3\2")
+ buf.write("\2\2\30t\3\2\2\2\32v\3\2\2\2\34x\3\2\2\2\36|\3\2\2\2 ")
+ buf.write("!\5\4\3\2!\"\7\2\2\3\"\3\3\2\2\2#*\5\6\4\2$&\5\30\r\2")
+ buf.write("%$\3\2\2\2%&\3\2\2\2&\'\3\2\2\2\')\5\6\4\2(%\3\2\2\2)")
+ buf.write(",\3\2\2\2*(\3\2\2\2*+\3\2\2\2+\5\3\2\2\2,*\3\2\2\2-\60")
+ buf.write("\5\24\13\2.\60\5\b\5\2/-\3\2\2\2/.\3\2\2\2\60\7\3\2\2")
+ buf.write("\2\618\5\34\17\2\628\5\32\16\2\638\5\36\20\2\648\5\n\6")
+ buf.write("\2\658\5\20\t\2\668\5\22\n\2\67\61\3\2\2\2\67\62\3\2\2")
+ buf.write("\2\67\63\3\2\2\2\67\64\3\2\2\2\67\65\3\2\2\2\67\66\3\2")
+ buf.write("\2\28\t\3\2\2\29;\7\3\2\2:<\7\f\2\2;:\3\2\2\2;<\3\2\2")
+ buf.write("\2<=\3\2\2\2=?\5\f\7\2>@\7\f\2\2?>\3\2\2\2?@\3\2\2\2@")
+ buf.write("A\3\2\2\2AB\7\6\2\2B\13\3\2\2\2CM\5\16\b\2DF\7\f\2\2E")
+ buf.write("D\3\2\2\2EF\3\2\2\2FG\3\2\2\2GI\5\26\f\2HJ\7\f\2\2IH\3")
+ buf.write("\2\2\2IJ\3\2\2\2JK\3\2\2\2KL\5\16\b\2LN\3\2\2\2ME\3\2")
+ buf.write("\2\2NO\3\2\2\2OM\3\2\2\2OP\3\2\2\2P\r\3\2\2\2QX\5\b\5")
+ buf.write("\2RT\5\30\r\2SR\3\2\2\2ST\3\2\2\2TU\3\2\2\2UW\5\b\5\2")
+ buf.write("VS\3\2\2\2WZ\3\2\2\2XV\3\2\2\2XY\3\2\2\2Y\17\3\2\2\2Z")
+ buf.write("X\3\2\2\2[]\7\4\2\2\\^\t\2\2\2]\\\3\2\2\2]^\3\2\2\2^_")
+ buf.write("\3\2\2\2_`\7\f\2\2`b\5\4\3\2ac\7\f\2\2ba\3\2\2\2bc\3\2")
+ buf.write("\2\2cd\3\2\2\2de\7\6\2\2e\21\3\2\2\2fh\7\5\2\2gi\5\30")
+ buf.write("\r\2hg\3\2\2\2hi\3\2\2\2ij\3\2\2\2jl\5\4\3\2km\5\30\r")
+ buf.write("\2lk\3\2\2\2lm\3\2\2\2mn\3\2\2\2no\7\6\2\2o\23\3\2\2\2")
+ buf.write("pq\7\b\2\2q\25\3\2\2\2rs\7\b\2\2s\27\3\2\2\2tu\7\f\2\2")
+ buf.write("u\31\3\2\2\2vw\7\7\2\2w\33\3\2\2\2xz\7\t\2\2y{\7\13\2")
+ buf.write("\2zy\3\2\2\2z{\3\2\2\2{\35\3\2\2\2|~\7\n\2\2}\177\7\13")
+ buf.write("\2\2~}\3\2\2\2~\177\3\2\2\2\177\37\3\2\2\2\23%*/\67;?")
+ buf.write("EIOSX]bhlz~")
return buf.getvalue()
@@ -45,37 +61,47 @@ class TacticNotationsParser ( Parser ):
sharedContextCache = PredictionContextCache()
- literalNames = [ "<INVALID>", "<INVALID>", "'{'", "'}'" ]
+ literalNames = [ "<INVALID>", "'{|'", "<INVALID>", "'{'", "'}'", "<INVALID>",
+ "'|'" ]
- symbolicNames = [ "<INVALID>", "LGROUP", "LBRACE", "RBRACE", "METACHAR",
- "ATOM", "ID", "SUB", "WHITESPACE" ]
+ symbolicNames = [ "<INVALID>", "LALT", "LGROUP", "LBRACE", "RBRACE",
+ "ESCAPED", "PIPE", "ATOM", "ID", "SUB", "WHITESPACE" ]
RULE_top = 0
RULE_blocks = 1
RULE_block = 2
- RULE_repeat = 3
- RULE_curlies = 4
- RULE_whitespace = 5
- RULE_meta = 6
- RULE_atomic = 7
- RULE_hole = 8
-
- ruleNames = [ "top", "blocks", "block", "repeat", "curlies", "whitespace",
- "meta", "atomic", "hole" ]
+ RULE_nopipeblock = 3
+ RULE_alternative = 4
+ RULE_altblocks = 5
+ RULE_altblock = 6
+ RULE_repeat = 7
+ RULE_curlies = 8
+ RULE_pipe = 9
+ RULE_altsep = 10
+ RULE_whitespace = 11
+ RULE_escaped = 12
+ RULE_atomic = 13
+ RULE_hole = 14
+
+ ruleNames = [ "top", "blocks", "block", "nopipeblock", "alternative",
+ "altblocks", "altblock", "repeat", "curlies", "pipe",
+ "altsep", "whitespace", "escaped", "atomic", "hole" ]
EOF = Token.EOF
- LGROUP=1
- LBRACE=2
- RBRACE=3
- METACHAR=4
- ATOM=5
- ID=6
- SUB=7
- WHITESPACE=8
+ LALT=1
+ LGROUP=2
+ LBRACE=3
+ RBRACE=4
+ ESCAPED=5
+ PIPE=6
+ ATOM=7
+ ID=8
+ SUB=9
+ WHITESPACE=10
def __init__(self, input:TokenStream, output:TextIO = sys.stdout):
super().__init__(input, output)
- self.checkVersion("4.7")
+ self.checkVersion("4.7.2")
self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache)
self._predicates = None
@@ -112,9 +138,9 @@ class TacticNotationsParser ( Parser ):
self.enterRule(localctx, 0, self.RULE_top)
try:
self.enterOuterAlt(localctx, 1)
- self.state = 18
+ self.state = 30
self.blocks()
- self.state = 19
+ self.state = 31
self.match(TacticNotationsParser.EOF)
except RecognitionException as re:
localctx.exception = re
@@ -163,24 +189,24 @@ class TacticNotationsParser ( Parser ):
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 21
+ self.state = 33
self.block()
- self.state = 28
+ self.state = 40
self._errHandler.sync(self)
_alt = self._interp.adaptivePredict(self._input,1,self._ctx)
while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
if _alt==1:
- self.state = 23
+ self.state = 35
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TacticNotationsParser.WHITESPACE:
- self.state = 22
+ self.state = 34
self.whitespace()
- self.state = 25
+ self.state = 37
self.block()
- self.state = 30
+ self.state = 42
self._errHandler.sync(self)
_alt = self._interp.adaptivePredict(self._input,1,self._ctx)
@@ -198,18 +224,77 @@ class TacticNotationsParser ( Parser ):
super().__init__(parent, invokingState)
self.parser = parser
+ def pipe(self):
+ return self.getTypedRuleContext(TacticNotationsParser.PipeContext,0)
+
+
+ def nopipeblock(self):
+ return self.getTypedRuleContext(TacticNotationsParser.NopipeblockContext,0)
+
+
+ def getRuleIndex(self):
+ return TacticNotationsParser.RULE_block
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitBlock" ):
+ return visitor.visitBlock(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def block(self):
+
+ localctx = TacticNotationsParser.BlockContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 4, self.RULE_block)
+ try:
+ self.state = 45
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [TacticNotationsParser.PIPE]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 43
+ self.pipe()
+ pass
+ elif token in [TacticNotationsParser.LALT, TacticNotationsParser.LGROUP, TacticNotationsParser.LBRACE, TacticNotationsParser.ESCAPED, TacticNotationsParser.ATOM, TacticNotationsParser.ID]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 44
+ self.nopipeblock()
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class NopipeblockContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
def atomic(self):
return self.getTypedRuleContext(TacticNotationsParser.AtomicContext,0)
- def meta(self):
- return self.getTypedRuleContext(TacticNotationsParser.MetaContext,0)
+ def escaped(self):
+ return self.getTypedRuleContext(TacticNotationsParser.EscapedContext,0)
def hole(self):
return self.getTypedRuleContext(TacticNotationsParser.HoleContext,0)
+ def alternative(self):
+ return self.getTypedRuleContext(TacticNotationsParser.AlternativeContext,0)
+
+
def repeat(self):
return self.getTypedRuleContext(TacticNotationsParser.RepeatContext,0)
@@ -219,48 +304,53 @@ class TacticNotationsParser ( Parser ):
def getRuleIndex(self):
- return TacticNotationsParser.RULE_block
+ return TacticNotationsParser.RULE_nopipeblock
def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitBlock" ):
- return visitor.visitBlock(self)
+ if hasattr( visitor, "visitNopipeblock" ):
+ return visitor.visitNopipeblock(self)
else:
return visitor.visitChildren(self)
- def block(self):
+ def nopipeblock(self):
- localctx = TacticNotationsParser.BlockContext(self, self._ctx, self.state)
- self.enterRule(localctx, 4, self.RULE_block)
+ localctx = TacticNotationsParser.NopipeblockContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 6, self.RULE_nopipeblock)
try:
- self.state = 36
+ self.state = 53
self._errHandler.sync(self)
token = self._input.LA(1)
if token in [TacticNotationsParser.ATOM]:
self.enterOuterAlt(localctx, 1)
- self.state = 31
+ self.state = 47
self.atomic()
pass
- elif token in [TacticNotationsParser.METACHAR]:
+ elif token in [TacticNotationsParser.ESCAPED]:
self.enterOuterAlt(localctx, 2)
- self.state = 32
- self.meta()
+ self.state = 48
+ self.escaped()
pass
elif token in [TacticNotationsParser.ID]:
self.enterOuterAlt(localctx, 3)
- self.state = 33
+ self.state = 49
self.hole()
pass
- elif token in [TacticNotationsParser.LGROUP]:
+ elif token in [TacticNotationsParser.LALT]:
self.enterOuterAlt(localctx, 4)
- self.state = 34
+ self.state = 50
+ self.alternative()
+ pass
+ elif token in [TacticNotationsParser.LGROUP]:
+ self.enterOuterAlt(localctx, 5)
+ self.state = 51
self.repeat()
pass
elif token in [TacticNotationsParser.LBRACE]:
- self.enterOuterAlt(localctx, 5)
- self.state = 35
+ self.enterOuterAlt(localctx, 6)
+ self.state = 52
self.curlies()
pass
else:
@@ -274,6 +364,232 @@ class TacticNotationsParser ( Parser ):
self.exitRule()
return localctx
+ class AlternativeContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def LALT(self):
+ return self.getToken(TacticNotationsParser.LALT, 0)
+
+ def altblocks(self):
+ return self.getTypedRuleContext(TacticNotationsParser.AltblocksContext,0)
+
+
+ def RBRACE(self):
+ return self.getToken(TacticNotationsParser.RBRACE, 0)
+
+ def WHITESPACE(self, i:int=None):
+ if i is None:
+ return self.getTokens(TacticNotationsParser.WHITESPACE)
+ else:
+ return self.getToken(TacticNotationsParser.WHITESPACE, i)
+
+ def getRuleIndex(self):
+ return TacticNotationsParser.RULE_alternative
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitAlternative" ):
+ return visitor.visitAlternative(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def alternative(self):
+
+ localctx = TacticNotationsParser.AlternativeContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 8, self.RULE_alternative)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 55
+ self.match(TacticNotationsParser.LALT)
+ self.state = 57
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la==TacticNotationsParser.WHITESPACE:
+ self.state = 56
+ self.match(TacticNotationsParser.WHITESPACE)
+
+
+ self.state = 59
+ self.altblocks()
+ self.state = 61
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la==TacticNotationsParser.WHITESPACE:
+ self.state = 60
+ self.match(TacticNotationsParser.WHITESPACE)
+
+
+ self.state = 63
+ self.match(TacticNotationsParser.RBRACE)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class AltblocksContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def altblock(self, i:int=None):
+ if i is None:
+ return self.getTypedRuleContexts(TacticNotationsParser.AltblockContext)
+ else:
+ return self.getTypedRuleContext(TacticNotationsParser.AltblockContext,i)
+
+
+ def altsep(self, i:int=None):
+ if i is None:
+ return self.getTypedRuleContexts(TacticNotationsParser.AltsepContext)
+ else:
+ return self.getTypedRuleContext(TacticNotationsParser.AltsepContext,i)
+
+
+ def WHITESPACE(self, i:int=None):
+ if i is None:
+ return self.getTokens(TacticNotationsParser.WHITESPACE)
+ else:
+ return self.getToken(TacticNotationsParser.WHITESPACE, i)
+
+ def getRuleIndex(self):
+ return TacticNotationsParser.RULE_altblocks
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitAltblocks" ):
+ return visitor.visitAltblocks(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def altblocks(self):
+
+ localctx = TacticNotationsParser.AltblocksContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 10, self.RULE_altblocks)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 65
+ self.altblock()
+ self.state = 75
+ self._errHandler.sync(self)
+ _alt = 1
+ while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
+ if _alt == 1:
+ self.state = 67
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la==TacticNotationsParser.WHITESPACE:
+ self.state = 66
+ self.match(TacticNotationsParser.WHITESPACE)
+
+
+ self.state = 69
+ self.altsep()
+ self.state = 71
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la==TacticNotationsParser.WHITESPACE:
+ self.state = 70
+ self.match(TacticNotationsParser.WHITESPACE)
+
+
+ self.state = 73
+ self.altblock()
+
+ else:
+ raise NoViableAltException(self)
+ self.state = 77
+ self._errHandler.sync(self)
+ _alt = self._interp.adaptivePredict(self._input,8,self._ctx)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class AltblockContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def nopipeblock(self, i:int=None):
+ if i is None:
+ return self.getTypedRuleContexts(TacticNotationsParser.NopipeblockContext)
+ else:
+ return self.getTypedRuleContext(TacticNotationsParser.NopipeblockContext,i)
+
+
+ def whitespace(self, i:int=None):
+ if i is None:
+ return self.getTypedRuleContexts(TacticNotationsParser.WhitespaceContext)
+ else:
+ return self.getTypedRuleContext(TacticNotationsParser.WhitespaceContext,i)
+
+
+ def getRuleIndex(self):
+ return TacticNotationsParser.RULE_altblock
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitAltblock" ):
+ return visitor.visitAltblock(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def altblock(self):
+
+ localctx = TacticNotationsParser.AltblockContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 12, self.RULE_altblock)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 79
+ self.nopipeblock()
+ self.state = 86
+ self._errHandler.sync(self)
+ _alt = self._interp.adaptivePredict(self._input,10,self._ctx)
+ while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
+ if _alt==1:
+ self.state = 81
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la==TacticNotationsParser.WHITESPACE:
+ self.state = 80
+ self.whitespace()
+
+
+ self.state = 83
+ self.nopipeblock()
+ self.state = 88
+ self._errHandler.sync(self)
+ _alt = self._interp.adaptivePredict(self._input,10,self._ctx)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
class RepeatContext(ParserRuleContext):
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
@@ -299,6 +615,9 @@ class TacticNotationsParser ( Parser ):
def ATOM(self):
return self.getToken(TacticNotationsParser.ATOM, 0)
+ def PIPE(self):
+ return self.getToken(TacticNotationsParser.PIPE, 0)
+
def getRuleIndex(self):
return TacticNotationsParser.RULE_repeat
@@ -314,33 +633,38 @@ class TacticNotationsParser ( Parser ):
def repeat(self):
localctx = TacticNotationsParser.RepeatContext(self, self._ctx, self.state)
- self.enterRule(localctx, 6, self.RULE_repeat)
+ self.enterRule(localctx, 14, self.RULE_repeat)
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 38
+ self.state = 89
self.match(TacticNotationsParser.LGROUP)
- self.state = 40
+ self.state = 91
self._errHandler.sync(self)
_la = self._input.LA(1)
- if _la==TacticNotationsParser.ATOM:
- self.state = 39
- self.match(TacticNotationsParser.ATOM)
+ if _la==TacticNotationsParser.PIPE or _la==TacticNotationsParser.ATOM:
+ self.state = 90
+ _la = self._input.LA(1)
+ if not(_la==TacticNotationsParser.PIPE or _la==TacticNotationsParser.ATOM):
+ self._errHandler.recoverInline(self)
+ else:
+ self._errHandler.reportMatch(self)
+ self.consume()
- self.state = 42
+ self.state = 93
self.match(TacticNotationsParser.WHITESPACE)
- self.state = 43
+ self.state = 94
self.blocks()
- self.state = 45
+ self.state = 96
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TacticNotationsParser.WHITESPACE:
- self.state = 44
+ self.state = 95
self.match(TacticNotationsParser.WHITESPACE)
- self.state = 47
+ self.state = 98
self.match(TacticNotationsParser.RBRACE)
except RecognitionException as re:
localctx.exception = re
@@ -388,31 +712,31 @@ class TacticNotationsParser ( Parser ):
def curlies(self):
localctx = TacticNotationsParser.CurliesContext(self, self._ctx, self.state)
- self.enterRule(localctx, 8, self.RULE_curlies)
+ self.enterRule(localctx, 16, self.RULE_curlies)
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 49
+ self.state = 100
self.match(TacticNotationsParser.LBRACE)
- self.state = 51
+ self.state = 102
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TacticNotationsParser.WHITESPACE:
- self.state = 50
+ self.state = 101
self.whitespace()
- self.state = 53
+ self.state = 104
self.blocks()
- self.state = 55
+ self.state = 106
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TacticNotationsParser.WHITESPACE:
- self.state = 54
+ self.state = 105
self.whitespace()
- self.state = 57
+ self.state = 108
self.match(TacticNotationsParser.RBRACE)
except RecognitionException as re:
localctx.exception = re
@@ -422,6 +746,80 @@ class TacticNotationsParser ( Parser ):
self.exitRule()
return localctx
+ class PipeContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def PIPE(self):
+ return self.getToken(TacticNotationsParser.PIPE, 0)
+
+ def getRuleIndex(self):
+ return TacticNotationsParser.RULE_pipe
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitPipe" ):
+ return visitor.visitPipe(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def pipe(self):
+
+ localctx = TacticNotationsParser.PipeContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 18, self.RULE_pipe)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 110
+ self.match(TacticNotationsParser.PIPE)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class AltsepContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def PIPE(self):
+ return self.getToken(TacticNotationsParser.PIPE, 0)
+
+ def getRuleIndex(self):
+ return TacticNotationsParser.RULE_altsep
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitAltsep" ):
+ return visitor.visitAltsep(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def altsep(self):
+
+ localctx = TacticNotationsParser.AltsepContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 20, self.RULE_altsep)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 112
+ self.match(TacticNotationsParser.PIPE)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
class WhitespaceContext(ParserRuleContext):
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
@@ -446,10 +844,10 @@ class TacticNotationsParser ( Parser ):
def whitespace(self):
localctx = TacticNotationsParser.WhitespaceContext(self, self._ctx, self.state)
- self.enterRule(localctx, 10, self.RULE_whitespace)
+ self.enterRule(localctx, 22, self.RULE_whitespace)
try:
self.enterOuterAlt(localctx, 1)
- self.state = 59
+ self.state = 114
self.match(TacticNotationsParser.WHITESPACE)
except RecognitionException as re:
localctx.exception = re
@@ -459,35 +857,35 @@ class TacticNotationsParser ( Parser ):
self.exitRule()
return localctx
- class MetaContext(ParserRuleContext):
+ class EscapedContext(ParserRuleContext):
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
super().__init__(parent, invokingState)
self.parser = parser
- def METACHAR(self):
- return self.getToken(TacticNotationsParser.METACHAR, 0)
+ def ESCAPED(self):
+ return self.getToken(TacticNotationsParser.ESCAPED, 0)
def getRuleIndex(self):
- return TacticNotationsParser.RULE_meta
+ return TacticNotationsParser.RULE_escaped
def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitMeta" ):
- return visitor.visitMeta(self)
+ if hasattr( visitor, "visitEscaped" ):
+ return visitor.visitEscaped(self)
else:
return visitor.visitChildren(self)
- def meta(self):
+ def escaped(self):
- localctx = TacticNotationsParser.MetaContext(self, self._ctx, self.state)
- self.enterRule(localctx, 12, self.RULE_meta)
+ localctx = TacticNotationsParser.EscapedContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 24, self.RULE_escaped)
try:
self.enterOuterAlt(localctx, 1)
- self.state = 61
- self.match(TacticNotationsParser.METACHAR)
+ self.state = 116
+ self.match(TacticNotationsParser.ESCAPED)
except RecognitionException as re:
localctx.exception = re
self._errHandler.reportError(self, re)
@@ -523,17 +921,17 @@ class TacticNotationsParser ( Parser ):
def atomic(self):
localctx = TacticNotationsParser.AtomicContext(self, self._ctx, self.state)
- self.enterRule(localctx, 14, self.RULE_atomic)
+ self.enterRule(localctx, 26, self.RULE_atomic)
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 63
+ self.state = 118
self.match(TacticNotationsParser.ATOM)
- self.state = 65
+ self.state = 120
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TacticNotationsParser.SUB:
- self.state = 64
+ self.state = 119
self.match(TacticNotationsParser.SUB)
@@ -572,17 +970,17 @@ class TacticNotationsParser ( Parser ):
def hole(self):
localctx = TacticNotationsParser.HoleContext(self, self._ctx, self.state)
- self.enterRule(localctx, 16, self.RULE_hole)
+ self.enterRule(localctx, 28, self.RULE_hole)
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 67
+ self.state = 122
self.match(TacticNotationsParser.ID)
- self.state = 69
+ self.state = 124
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TacticNotationsParser.SUB:
- self.state = 68
+ self.state = 123
self.match(TacticNotationsParser.SUB)
diff --git a/doc/tools/coqrst/notations/TacticNotationsVisitor.py b/doc/tools/coqrst/notations/TacticNotationsVisitor.py
index c0bcc4af37..aba696c89f 100644
--- a/doc/tools/coqrst/notations/TacticNotationsVisitor.py
+++ b/doc/tools/coqrst/notations/TacticNotationsVisitor.py
@@ -1,4 +1,4 @@
-# Generated from TacticNotations.g by ANTLR 4.7
+# Generated from TacticNotations.g by ANTLR 4.7.2
from antlr4 import *
if __name__ is not None and "." in __name__:
from .TacticNotationsParser import TacticNotationsParser
@@ -24,6 +24,26 @@ class TacticNotationsVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
+ # Visit a parse tree produced by TacticNotationsParser#nopipeblock.
+ def visitNopipeblock(self, ctx:TacticNotationsParser.NopipeblockContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TacticNotationsParser#alternative.
+ def visitAlternative(self, ctx:TacticNotationsParser.AlternativeContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TacticNotationsParser#altblocks.
+ def visitAltblocks(self, ctx:TacticNotationsParser.AltblocksContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TacticNotationsParser#altblock.
+ def visitAltblock(self, ctx:TacticNotationsParser.AltblockContext):
+ return self.visitChildren(ctx)
+
+
# Visit a parse tree produced by TacticNotationsParser#repeat.
def visitRepeat(self, ctx:TacticNotationsParser.RepeatContext):
return self.visitChildren(ctx)
@@ -34,13 +54,23 @@ class TacticNotationsVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
+ # Visit a parse tree produced by TacticNotationsParser#pipe.
+ def visitPipe(self, ctx:TacticNotationsParser.PipeContext):
+ return self.visitChildren(ctx)
+
+
+ # Visit a parse tree produced by TacticNotationsParser#altsep.
+ def visitAltsep(self, ctx:TacticNotationsParser.AltsepContext):
+ return self.visitChildren(ctx)
+
+
# Visit a parse tree produced by TacticNotationsParser#whitespace.
def visitWhitespace(self, ctx:TacticNotationsParser.WhitespaceContext):
return self.visitChildren(ctx)
- # Visit a parse tree produced by TacticNotationsParser#meta.
- def visitMeta(self, ctx:TacticNotationsParser.MetaContext):
+ # Visit a parse tree produced by TacticNotationsParser#escaped.
+ def visitEscaped(self, ctx:TacticNotationsParser.EscapedContext):
return self.visitChildren(ctx)
diff --git a/doc/tools/coqrst/notations/html.py b/doc/tools/coqrst/notations/html.py
index 87a41cf9f3..d2b5d86b37 100644
--- a/doc/tools/coqrst/notations/html.py
+++ b/doc/tools/coqrst/notations/html.py
@@ -13,12 +13,24 @@ Uses the dominate package.
"""
from dominate import tags
+from dominate.utils import text
from .parsing import parse
from .TacticNotationsParser import TacticNotationsParser
from .TacticNotationsVisitor import TacticNotationsVisitor
class TacticNotationsToHTMLVisitor(TacticNotationsVisitor):
+ def visitAlternative(self, ctx:TacticNotationsParser.AlternativeContext):
+ with tags.span(_class='alternative'):
+ self.visitChildren(ctx)
+
+ def visitAltblock(self, ctx:TacticNotationsParser.AltblockContext):
+ with tags.span(_class='alternative-block'):
+ self.visitChildren(ctx)
+
+ def visitAltsep(self, ctx:TacticNotationsParser.AltsepContext):
+ tags.span('\u200b', _class="alternative-separator")
+
def visitRepeat(self, ctx:TacticNotationsParser.RepeatContext):
with tags.span(_class="repeat-wrapper"):
with tags.span(_class="repeat"):
@@ -39,21 +51,20 @@ class TacticNotationsToHTMLVisitor(TacticNotationsVisitor):
def visitAtomic(self, ctx:TacticNotationsParser.AtomicContext):
tags.span(ctx.ATOM().getText())
+ def visitPipe(self, ctx:TacticNotationsParser.PipeContext):
+ text("|")
+
def visitHole(self, ctx:TacticNotationsParser.HoleContext):
tags.span(ctx.ID().getText()[1:], _class="hole")
sub = ctx.SUB()
if sub:
tags.sub(sub.getText()[1:])
- def visitMeta(self, ctx:TacticNotationsParser.MetaContext):
- txt = ctx.METACHAR().getText()[1:]
- if (txt == "{") or (txt == "}"):
- tags.span(txt)
- else:
- tags.span(txt, _class="meta")
+ def visitEscaped(self, ctx:TacticNotationsParser.EscapedContext):
+ tags.span(ctx.ESCAPED().getText()[1:])
def visitWhitespace(self, ctx:TacticNotationsParser.WhitespaceContext):
- tags.span(" ") # TODO: no need for a <span> here
+ text(" ")
def htmlize(notation):
"""Translate notation to a dominate HTML tree"""
diff --git a/doc/tools/coqrst/notations/parsing.py b/doc/tools/coqrst/notations/parsing.py
index 506240d907..2312e09090 100644
--- a/doc/tools/coqrst/notations/parsing.py
+++ b/doc/tools/coqrst/notations/parsing.py
@@ -11,10 +11,22 @@ from .TacticNotationsLexer import TacticNotationsLexer
from .TacticNotationsParser import TacticNotationsParser
from antlr4 import CommonTokenStream, InputStream
+from antlr4.error.ErrorListener import ErrorListener
SUBSTITUTIONS = [#("@bindings_list", "{+ (@id := @val) }"),
("@qualid_or_string", "@id|@string")]
+class ParseError(Exception):
+ def __init__(self, msg):
+ super().__init__()
+ self.msg = msg
+
+class ExceptionRaisingErrorListener(ErrorListener):
+ def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e):
+ raise ParseError("{}:{}: {}".format(line, column, msg))
+
+ERROR_LISTENER = ExceptionRaisingErrorListener()
+
def substitute(notation):
"""Perform common substitutions in the notation string.
@@ -27,11 +39,13 @@ def substitute(notation):
return notation
def parse(notation):
- """Parse a notation string.
+ """Parse a notation string, optionally reporting errors to `error_listener`.
:return: An ANTLR AST. Use one of the supplied visitors (or write your own)
to turn it into useful output.
"""
substituted = substitute(notation)
lexer = TacticNotationsLexer(InputStream(substituted))
- return TacticNotationsParser(CommonTokenStream(lexer)).top()
+ parser = TacticNotationsParser(CommonTokenStream(lexer))
+ parser.addErrorListener(ERROR_LISTENER)
+ return parser.top()
diff --git a/doc/tools/coqrst/notations/plain.py b/doc/tools/coqrst/notations/plain.py
index f6e82fc68e..2180c8e6a5 100644
--- a/doc/tools/coqrst/notations/plain.py
+++ b/doc/tools/coqrst/notations/plain.py
@@ -22,8 +22,16 @@ class TacticNotationsToDotsVisitor(TacticNotationsVisitor):
def __init__(self):
self.buffer = StringIO()
+ def visitAlternative(self, ctx:TacticNotationsParser.AlternativeContext):
+ self.buffer.write("[")
+ self.visitChildren(ctx)
+ self.buffer.write("]")
+
+ def visitAltsep(self, ctx:TacticNotationsParser.AltsepContext):
+ self.buffer.write("|")
+
def visitRepeat(self, ctx:TacticNotationsParser.RepeatContext):
- separator = ctx.ATOM()
+ separator = ctx.ATOM() or ctx.PIPE()
self.visitChildren(ctx)
if ctx.LGROUP().getText()[1] == "+":
spacer = (separator.getText() + " " if separator else "")
@@ -38,11 +46,14 @@ class TacticNotationsToDotsVisitor(TacticNotationsVisitor):
def visitAtomic(self, ctx:TacticNotationsParser.AtomicContext):
self.buffer.write(ctx.ATOM().getText())
+ def visitPipe(self, ctx:TacticNotationsParser.PipeContext):
+ self.buffer.write("|")
+
def visitHole(self, ctx:TacticNotationsParser.HoleContext):
self.buffer.write("‘{}’".format(ctx.ID().getText()[1:]))
- def visitMeta(self, ctx:TacticNotationsParser.MetaContext):
- self.buffer.write(ctx.METACHAR().getText()[1:])
+ def visitEscaped(self, ctx:TacticNotationsParser.EscapedContext):
+ self.buffer.write(ctx.ESCAPED().getText()[1:])
def visitWhitespace(self, ctx:TacticNotationsParser.WhitespaceContext):
self.buffer.write(" ")
diff --git a/doc/tools/coqrst/notations/sphinx.py b/doc/tools/coqrst/notations/sphinx.py
index e05b834184..4ed09e04a9 100644
--- a/doc/tools/coqrst/notations/sphinx.py
+++ b/doc/tools/coqrst/notations/sphinx.py
@@ -20,8 +20,6 @@ from .TacticNotationsVisitor import TacticNotationsVisitor
from docutils import nodes
from sphinx import addnodes
-import sys
-
class TacticNotationsToSphinxVisitor(TacticNotationsVisitor):
def defaultResult(self):
return []
@@ -31,16 +29,36 @@ class TacticNotationsToSphinxVisitor(TacticNotationsVisitor):
aggregate.extend(nextResult)
return aggregate
+ def visitAlternative(self, ctx:TacticNotationsParser.AlternativeContext):
+ return [nodes.inline('', '', *self.visitChildren(ctx), classes=['alternative'])]
+
+ def visitAltblock(self, ctx:TacticNotationsParser.AltblockContext):
+ return [nodes.inline('', '', *self.visitChildren(ctx), classes=['alternative-block'])]
+
+ def visitAltsep(self, ctx:TacticNotationsParser.AltsepContext):
+ return [nodes.inline('|', '\u200b', classes=['alternative-separator'])]
+
+ @staticmethod
+ def is_alternative(node):
+ return isinstance(node, nodes.inline) and node['classes'] == ['alternative']
+
def visitRepeat(self, ctx:TacticNotationsParser.RepeatContext):
# Uses inline nodes instead of subscript and superscript to ensure that
# we get the right customization hooks at the LaTeX level
wrapper = nodes.inline('', '', classes=['repeat-wrapper'])
- wrapper += nodes.inline('', '', *self.visitChildren(ctx), classes=["repeat"])
+
+ children = self.visitChildren(ctx)
+ if len(children) == 1 and self.is_alternative(children[0]):
+ # Use a custom style if an alternative is nested in a repeat.
+ # (We could detect this in CSS, but it's much harder in LaTeX.)
+
+ children[0]['classes'] = ['repeated-alternative']
+ wrapper += nodes.inline('', '', *children, classes=["repeat"])
repeat_marker = ctx.LGROUP().getText()[1]
wrapper += nodes.inline(repeat_marker, repeat_marker, classes=['notation-sup'])
- separator = ctx.ATOM()
+ separator = ctx.ATOM() or ctx.PIPE()
if separator:
sep = separator.getText()
wrapper += nodes.inline(sep, sep, classes=['notation-sub'])
@@ -65,6 +83,9 @@ class TacticNotationsToSphinxVisitor(TacticNotationsVisitor):
return [node]
+ def visitPipe(self, ctx:TacticNotationsParser.PipeContext):
+ return [nodes.Text("|")]
+
def visitHole(self, ctx:TacticNotationsParser.HoleContext):
hole = ctx.ID().getText()
token_name = hole[1:]
@@ -75,23 +96,18 @@ class TacticNotationsToSphinxVisitor(TacticNotationsVisitor):
sub_index = sub.getText()[2:]
node += nodes.subscript(sub_index, sub_index)
- return [addnodes.pending_xref(token_name, node, reftype='token', refdomain='std', reftarget=token_name)]
+ return [addnodes.pending_xref(token_name, node, reftype='token',
+ refdomain='std', reftarget=token_name)]
- def visitMeta(self, ctx:TacticNotationsParser.MetaContext):
- meta = ctx.METACHAR().getText()
- metachar = meta[1:] # remove escape char
- token_name = metachar
- if (metachar == "{") or (metachar == "}"):
- classes=[]
- else:
- classes=["meta"]
- return [nodes.inline(metachar, token_name, classes=classes)]
+ def visitEscaped(self, ctx:TacticNotationsParser.EscapedContext):
+ escaped = ctx.ESCAPED().getText()
+ return [nodes.inline(escaped, escaped[1:])]
def visitWhitespace(self, ctx:TacticNotationsParser.WhitespaceContext):
return [nodes.Text(" ")]
def sphinxify(notation):
- """Translate notation into a Sphinx document tree"""
+ """Translate a notation into a Sphinx document tree."""
vs = TacticNotationsToSphinxVisitor()
return vs.visit(parse(notation))
diff --git a/engine/evarutil.ml b/engine/evarutil.ml
index 96beb72a56..0a5bba39b9 100644
--- a/engine/evarutil.ml
+++ b/engine/evarutil.ml
@@ -26,24 +26,7 @@ let safe_evar_value sigma ev =
try Some (EConstr.Unsafe.to_constr @@ Evd.existential_value sigma ev)
with NotInstantiatedEvar | Not_found -> None
-(** Combinators *)
-
-let evd_comb0 f evdref =
- let (evd',x) = f !evdref in
- evdref := evd';
- x
-
-let evd_comb1 f evdref x =
- let (evd',y) = f !evdref x in
- evdref := evd';
- y
-
-let evd_comb2 f evdref x y =
- let (evd',z) = f !evdref x y in
- evdref := evd';
- z
-
-let new_global evd x =
+let new_global evd x =
let (evd, c) = Evd.fresh_global (Global.env()) evd x in
(evd, c)
@@ -673,26 +656,26 @@ let clear_hyps2_in_evi env sigma hyps t concl ids =
(* spiwack: a few functions to gather evars on which goals depend. *)
let queue_set q is_dependent set =
Evar.Set.iter (fun a -> Queue.push (is_dependent,a) q) set
-let queue_term q is_dependent c =
- queue_set q is_dependent (evars_of_term (EConstr.Unsafe.to_constr c))
+let queue_term evm q is_dependent c =
+ queue_set q is_dependent (evars_of_term evm c)
let process_dependent_evar q acc evm is_dependent e =
let evi = Evd.find evm e in
(* Queues evars appearing in the types of the goal (conclusion, then
hypotheses), they are all dependent. *)
- queue_term q true evi.evar_concl;
+ queue_term evm q true evi.evar_concl;
List.iter begin fun decl ->
let open NamedDecl in
- queue_term q true (NamedDecl.get_type decl);
+ queue_term evm q true (NamedDecl.get_type decl);
match decl with
| LocalAssum _ -> ()
- | LocalDef (_,b,_) -> queue_term q true b
+ | LocalDef (_,b,_) -> queue_term evm q true b
end (EConstr.named_context_of_val evi.evar_hyps);
match evi.evar_body with
| Evar_empty ->
if is_dependent then Evar.Map.add e None acc else acc
| Evar_defined b ->
- let subevars = evars_of_term (EConstr.Unsafe.to_constr b) in
+ let subevars = evars_of_term evm b in
(* evars appearing in the definition of an evar [e] are marked
as dependent when [e] is dependent itself: if [e] is a
non-dependent goal, then, unless they are reach from another
@@ -812,7 +795,7 @@ let filtered_undefined_evars_of_evar_info ?cache sigma evi =
in
let accu = match evi.evar_body with
| Evar_empty -> Evar.Set.empty
- | Evar_defined b -> evars_of_term (EConstr.Unsafe.to_constr b)
+ | Evar_defined b -> evars_of_term sigma b
in
let accu = Evar.Set.union (undefined_evars_of_term sigma evi.evar_concl) accu in
let ctxt = EConstr.Unsafe.to_named_context (evar_filtered_context evi) in
diff --git a/engine/evarutil.mli b/engine/evarutil.mli
index bb0da44103..8eaff8bd13 100644
--- a/engine/evarutil.mli
+++ b/engine/evarutil.mli
@@ -274,15 +274,6 @@ val push_rel_context_to_named_context : ?hypnaming:naming_mode ->
val generalize_evar_over_rels : evar_map -> existential -> types * constr list
-(** Evar combinators *)
-
-val evd_comb0 : (evar_map -> evar_map * 'a) -> evar_map ref -> 'a
-[@@ocaml.deprecated "References to [evar_map] are deprecated, please update your API calls"]
-val evd_comb1 : (evar_map -> 'b -> evar_map * 'a) -> evar_map ref -> 'b -> 'a
-[@@ocaml.deprecated "References to [evar_map] are deprecated, please update your API calls"]
-val evd_comb2 : (evar_map -> 'b -> 'c -> evar_map * 'a) -> evar_map ref -> 'b -> 'c -> 'a
-[@@ocaml.deprecated "References to [evar_map] are deprecated, please update your API calls"]
-
val subterm_source : Evar.t -> ?where:Evar_kinds.subevar_kind -> Evar_kinds.t Loc.located ->
Evar_kinds.t Loc.located
diff --git a/engine/evd.ml b/engine/evd.ml
index 96c2719f8f..15b4c31851 100644
--- a/engine/evd.ml
+++ b/engine/evd.ml
@@ -823,33 +823,6 @@ let loc_of_conv_pb evd (pbty,env,t1,t2) =
| Evar (evk2,_) -> fst (evar_source evk2 evd)
| _ -> None
-(** The following functions return the set of evars immediately
- contained in the object *)
-
-(* excluding defined evars *)
-
-let evars_of_term c =
- let rec evrec acc c =
- match kind c with
- | Evar (n, l) -> Evar.Set.add n (Array.fold_left evrec acc l)
- | _ -> Constr.fold evrec acc c
- in
- evrec Evar.Set.empty c
-
-let evars_of_named_context nc =
- Context.Named.fold_outside
- (NamedDecl.fold_constr (fun constr s -> Evar.Set.union s (evars_of_term constr)))
- nc
- ~init:Evar.Set.empty
-
-let evars_of_filtered_evar_info evi =
- Evar.Set.union (evars_of_term evi.evar_concl)
- (Evar.Set.union
- (match evi.evar_body with
- | Evar_empty -> Evar.Set.empty
- | Evar_defined b -> evars_of_term b)
- (evars_of_named_context (evar_filtered_context evi)))
-
(**********************************************************)
(* Sort variables *)
@@ -869,8 +842,6 @@ let to_universe_context evd = UState.context evd.universes
let univ_entry ~poly evd = UState.univ_entry ~poly evd.universes
-let const_univ_entry = univ_entry
-
let check_univ_decl ~poly evd decl = UState.check_univ_decl ~poly evd.universes decl
let restrict_universe_context evd vars =
@@ -1406,3 +1377,30 @@ module MiniEConstr = struct
let to_rel_decl sigma d = Context.Rel.Declaration.map_constr (to_constr sigma) d
end
+
+(** The following functions return the set of evars immediately
+ contained in the object *)
+
+(* excluding defined evars *)
+
+let evars_of_term evd c =
+ let rec evrec acc c =
+ match MiniEConstr.kind evd c with
+ | Evar (n, l) -> Evar.Set.add n (Array.fold_left evrec acc l)
+ | _ -> Constr.fold evrec acc c
+ in
+ evrec Evar.Set.empty c
+
+let evars_of_named_context evd nc =
+ Context.Named.fold_outside
+ (NamedDecl.fold_constr (fun constr s -> Evar.Set.union s (evars_of_term evd constr)))
+ nc
+ ~init:Evar.Set.empty
+
+let evars_of_filtered_evar_info evd evi =
+ Evar.Set.union (evars_of_term evd evi.evar_concl)
+ (Evar.Set.union
+ (match evi.evar_body with
+ | Evar_empty -> Evar.Set.empty
+ | Evar_defined b -> evars_of_term evd b)
+ (evars_of_named_context evd (evar_filtered_context evi)))
diff --git a/engine/evd.mli b/engine/evd.mli
index b0fcddb068..587a1de044 100644
--- a/engine/evd.mli
+++ b/engine/evd.mli
@@ -491,16 +491,15 @@ val extract_changed_conv_pbs : evar_map ->
val extract_all_conv_pbs : evar_map -> evar_map * evar_constraint list
val loc_of_conv_pb : evar_map -> evar_constraint -> Loc.t option
-(** The following functions return the set of evars immediately
- contained in the object; need the term to be evar-normal otherwise
- defined evars are returned too. *)
+(** The following functions return the set of undefined evars
+ contained in the object. *)
-val evars_of_term : constr -> Evar.Set.t
+val evars_of_term : evar_map -> econstr -> Evar.Set.t
(** including evars in instances of evars *)
-val evars_of_named_context : (econstr, etypes) Context.Named.pt -> Evar.Set.t
+val evars_of_named_context : evar_map -> (econstr, etypes) Context.Named.pt -> Evar.Set.t
-val evars_of_filtered_evar_info : evar_info -> Evar.Set.t
+val evars_of_filtered_evar_info : evar_map -> evar_info -> Evar.Set.t
(** Metas *)
val meta_list : evar_map -> (metavariable * clbinding) list
@@ -615,9 +614,6 @@ val to_universe_context : evar_map -> Univ.UContext.t
val univ_entry : poly:bool -> evar_map -> Entries.universes_entry
-val const_univ_entry : poly:bool -> evar_map -> Entries.universes_entry
-[@@ocaml.deprecated "Use [univ_entry]."]
-
val check_univ_decl : poly:bool -> evar_map -> UState.universe_decl -> Entries.universes_entry
val merge_universe_context : evar_map -> UState.t -> evar_map
diff --git a/engine/ftactic.ml b/engine/ftactic.ml
index ac0344148a..dab2e7d5ef 100644
--- a/engine/ftactic.ml
+++ b/engine/ftactic.ml
@@ -56,13 +56,6 @@ let bind (type a) (type b) (m : a t) (f : a -> b t) : b t = m >>= function
let goals = Proofview.Goal.goals >>= fun l -> Proofview.tclUNIT (Depends l)
-let nf_enter f =
- bind goals
- (fun gl ->
- gl >>= fun gl ->
- Proofview.Goal.normalize gl >>= fun nfgl ->
- Proofview.V82.wrap_exceptions (fun () -> f nfgl)) [@warning "-3"]
-
let enter f =
bind goals
(fun gl -> gl >>= fun gl -> Proofview.V82.wrap_exceptions (fun () -> f gl))
diff --git a/engine/ftactic.mli b/engine/ftactic.mli
index 3c4fa6f4e8..ed95d62bc6 100644
--- a/engine/ftactic.mli
+++ b/engine/ftactic.mli
@@ -41,9 +41,6 @@ val run : 'a t -> ('a -> unit Proofview.tactic) -> unit Proofview.tactic
(** {5 Focussing} *)
-val nf_enter : (Proofview.Goal.t -> 'a t) -> 'a t
-[@@ocaml.deprecated "Normalization is enforced by EConstr, please use [enter]"]
-
(** Enter a goal. The resulting tactic is focussed. *)
val enter : (Proofview.Goal.t -> 'a t) -> 'a t
diff --git a/engine/proofview.ml b/engine/proofview.ml
index 6992d15fcb..5c5a02d3fa 100644
--- a/engine/proofview.ml
+++ b/engine/proofview.ml
@@ -641,7 +641,7 @@ let shelve_goals l =
[sigma]. *)
let depends_on sigma src tgt =
let evi = Evd.find sigma tgt in
- Evar.Set.mem src (Evd.evars_of_filtered_evar_info (Evarutil.nf_evar_info sigma evi))
+ Evar.Set.mem src (Evd.evars_of_filtered_evar_info sigma (Evarutil.nf_evar_info sigma evi))
let unifiable_delayed g l =
CList.exists (fun (tgt, lazy evs) -> not (Evar.equal g tgt) && Evar.Set.mem g evs) l
@@ -1104,13 +1104,6 @@ module Goal = struct
tclZERO ~info e
end
end
-
- let normalize { self; state } =
- Env.get >>= fun env ->
- tclEVARMAP >>= fun sigma ->
- let (gl,sigma) = nf_gmake env sigma (goal_with_state self state) in
- tclTHEN (Unsafe.tclEVARS sigma) (tclUNIT gl)
-
let gmake env sigma goal =
let state = get_state goal in
let goal = drop_state goal in
@@ -1258,9 +1251,9 @@ module V82 = struct
let goals = CList.map (fun (t,_) -> fst (Constr.destEvar (EConstr.Unsafe.to_constr t))) initial in
{ Evd.it = goals ; sigma=solution; }
- let top_evars initial =
+ let top_evars initial { solution=sigma; } =
let evars_of_initial (c,_) =
- Evar.Set.elements (Evd.evars_of_term (EConstr.Unsafe.to_constr c))
+ Evar.Set.elements (Evd.evars_of_term sigma c)
in
CList.flatten (CList.map evars_of_initial initial)
diff --git a/engine/proofview.mli b/engine/proofview.mli
index 9455dae643..b7ff3ac432 100644
--- a/engine/proofview.mli
+++ b/engine/proofview.mli
@@ -505,10 +505,6 @@ module Goal : sig
(** Type of goals. *)
type t
- (** Normalises the argument goal. *)
- val normalize : t -> t tactic
- [@@ocaml.deprecated "Normalization is enforced by EConstr, [normalize] is not needed anymore"]
-
(** [concl], [hyps], [env] and [sigma] given a goal [gl] return
respectively the conclusion of [gl], the hypotheses of [gl], the
environment of [gl] (i.e. the global environment and the
@@ -599,7 +595,7 @@ module V82 : sig
val top_goals : entry -> proofview -> Evar.t list Evd.sigma
(* returns the existential variable used to start the proof *)
- val top_evars : entry -> Evar.t list
+ val top_evars : entry -> proofview -> Evar.t list
(* Caution: this function loses quite a bit of information. It
should be avoided as much as possible. It should work as
diff --git a/engine/termops.ml b/engine/termops.ml
index 8e12c9be88..fcacb53ac4 100644
--- a/engine/termops.ml
+++ b/engine/termops.ml
@@ -25,11 +25,6 @@ module CompactedDecl = Context.Compacted.Declaration
module Internal = struct
-let pr_sort_family = Sorts.pr_sort_family
-[@@ocaml.deprecated "Use [Sorts.pr_sort_family]"]
-let pr_fix = Constr.debug_print_fix
-[@@ocaml.deprecated "Use [Constr.debug_print_fix]"]
-
let debug_print_constr c = Constr.debug_print EConstr.Unsafe.(to_constr c)
let debug_print_constr_env env sigma c = Constr.debug_print EConstr.(to_constr sigma c)
let term_printer = ref debug_print_constr_env
@@ -192,7 +187,7 @@ let compute_evar_dependency_graph sigma =
in
match evar_body evi with
| Evar_empty -> acc
- | Evar_defined c -> Evar.Set.fold fold_ev (evars_of_term (EConstr.Unsafe.to_constr c)) acc
+ | Evar_defined c -> Evar.Set.fold fold_ev (evars_of_term sigma c) acc
in
Evd.fold fold sigma EvMap.empty
@@ -761,13 +756,6 @@ let fold_constr_with_binders sigma g f n acc c =
let c = Unsafe.to_constr (whd_evar sigma c) in
Constr.fold_constr_with_binders g f n acc c
-(* [iter_constr_with_full_binders g f acc c] iters [f acc] on the immediate
- subterms of [c]; it carries an extra data [acc] which is processed by [g] at
- each binder traversal; it is not recursive and the order with which
- subterms are processed is not specified *)
-
-let iter_constr_with_full_binders = EConstr.iter_with_full_binders
-
(***************************)
(* occurs check functions *)
(***************************)
@@ -862,8 +850,6 @@ let collect_vars sigma c =
| _ -> EConstr.fold sigma aux vars c in
aux Id.Set.empty c
-let vars_of_global_reference = vars_of_global
-
(* Tests whether [m] is a subterm of [t]:
[m] is appropriately lifted through abstractions of [t] *)
@@ -1417,10 +1403,6 @@ let prod_applist_assum sigma n c l =
| _ -> anomaly (Pp.str "Not enough prod/let's.") in
app n [] c l
-let on_judgment = Environ.on_judgment
-let on_judgment_value = Environ.on_judgment_value
-let on_judgment_type = Environ.on_judgment_type
-
(* Cut a context ctx in 2 parts (ctx1,ctx2) with ctx1 containing k non let-in
variables skips let-in's; let-in's in the middle are put in ctx2 *)
let context_chop k ctx =
diff --git a/engine/termops.mli b/engine/termops.mli
index 1dd9941c5e..a9217b3586 100644
--- a/engine/termops.mli
+++ b/engine/termops.mli
@@ -16,12 +16,6 @@ open Constr
open Environ
open EConstr
-(** printers *)
-val pr_sort_family : Sorts.family -> Pp.t
-[@@ocaml.deprecated "Use [Sorts.pr_sort_family]"]
-val pr_fix : ('a -> Pp.t) -> ('a, 'a) pfixpoint -> Pp.t
-[@@ocaml.deprecated "Use [Constr.debug_print_fix]"]
-
(** about contexts *)
val push_rel_assum : Name.t Context.binder_annot * types -> env -> env
val push_rels_assum : (Name.t Context.binder_annot * Constr.types) list -> env -> env
@@ -84,12 +78,6 @@ val fold_constr_with_full_binders : Evd.evar_map ->
('a -> 'b -> constr -> 'b) ->
'a -> 'b -> constr -> 'b
-val iter_constr_with_full_binders : Evd.evar_map ->
- (rel_declaration -> 'a -> 'a) ->
- ('a -> constr -> unit) -> 'a ->
- constr -> unit
-[@@ocaml.deprecated "Use [EConstr.iter_with_full_binders]."]
-
(**********************************************************************)
val strip_head_cast : Evd.evar_map -> constr -> constr
@@ -121,9 +109,6 @@ val count_occurrences : Evd.evar_map -> constr -> constr -> int
val collect_metas : Evd.evar_map -> constr -> int list
val collect_vars : Evd.evar_map -> constr -> Id.Set.t (** for visible vars only *)
-val vars_of_global_reference : env -> GlobRef.t -> Id.Set.t
-[@@ocaml.deprecated "Use [Environ.vars_of_global]"]
-
(* Substitution of metavariables *)
type meta_value_map = (metavariable * Constr.constr) list
val subst_meta : meta_value_map -> Constr.constr -> Constr.constr
@@ -292,15 +277,6 @@ val is_Type : Evd.evar_map -> constr -> bool
val reference_of_level : Evd.evar_map -> Univ.Level.t -> Libnames.qualid option
-(** Combinators on judgments *)
-
-val on_judgment : ('a -> 'b) -> ('a, 'a) punsafe_judgment -> ('b, 'b) punsafe_judgment
-[@@ocaml.deprecated "Use [Environ.on_judgment]."]
-val on_judgment_value : ('c -> 'c) -> ('c, 't) punsafe_judgment -> ('c, 't) punsafe_judgment
-[@@ocaml.deprecated "Use [Environ.on_judgment_value]."]
-val on_judgment_type : ('t -> 't) -> ('c, 't) punsafe_judgment -> ('c, 't) punsafe_judgment
-[@@ocaml.deprecated "Use [Environ.on_judgment_type]."]
-
(** {5 Debug pretty-printers} *)
open Evd
diff --git a/engine/uState.ml b/engine/uState.ml
index aa14f66df6..adea78d4c9 100644
--- a/engine/uState.ml
+++ b/engine/uState.ml
@@ -116,8 +116,6 @@ let univ_entry ~poly uctx =
Polymorphic_entry (nas, uctx)
else Monomorphic_entry (context_set uctx)
-let const_univ_entry = univ_entry
-
let of_context_set ctx = { empty with uctx_local = ctx }
let subst ctx = ctx.uctx_univ_variables
diff --git a/engine/uState.mli b/engine/uState.mli
index a358813825..3df7f9e8e9 100644
--- a/engine/uState.mli
+++ b/engine/uState.mli
@@ -67,9 +67,6 @@ val context : t -> Univ.UContext.t
val univ_entry : poly:bool -> t -> Entries.universes_entry
(** Pick from {!context} or {!context_set} based on [poly]. *)
-val const_univ_entry : poly:bool -> t -> Entries.universes_entry
-[@@ocaml.deprecated "Use [univ_entry]."]
-
(** {5 Constraints handling} *)
val drop_weak_constraints : bool ref
diff --git a/engine/univGen.ml b/engine/univGen.ml
index c310331b15..f1deb1bfaf 100644
--- a/engine/univGen.ml
+++ b/engine/univGen.ml
@@ -25,11 +25,6 @@ let new_univ_global () =
let fresh_level () =
Univ.Level.make (new_univ_global ())
-(* TODO: remove *)
-let new_univ () = Univ.Universe.make (fresh_level ())
-let new_Type () = mkType (new_univ ())
-let new_Type_sort () = sort_of_univ (new_univ ())
-
let fresh_instance auctx =
let inst = Array.init (AUContext.size auctx) (fun _ -> fresh_level()) in
let ctx = Array.fold_right LSet.add inst LSet.empty in
@@ -83,10 +78,6 @@ let constr_of_monomorphic_global gr =
Pp.(str "globalization of polymorphic reference " ++ Nametab.pr_global_env Id.Set.empty gr ++
str " would forget universes.")
-let constr_of_global gr = constr_of_monomorphic_global gr
-
-let constr_of_global_univ = mkRef
-
let fresh_global_or_constr_instance env = function
| IsConstr c -> c, ContextSet.empty
| IsGlobal gr -> fresh_global_instance env gr
@@ -99,34 +90,6 @@ let global_of_constr c =
| Var id -> VarRef id, Instance.empty
| _ -> raise Not_found
-open Declarations
-
-let type_of_reference env r =
- match r with
- | VarRef id -> Environ.named_type id env, ContextSet.empty
-
- | ConstRef c ->
- let cb = Environ.lookup_constant c env in
- let ty = cb.const_type in
- let auctx = Declareops.constant_polymorphic_context cb in
- let inst, ctx = fresh_instance auctx in
- Vars.subst_instance_constr inst ty, ctx
-
- | IndRef ind ->
- let (mib, _ as specif) = Inductive.lookup_mind_specif env ind in
- let auctx = Declareops.inductive_polymorphic_context mib in
- let inst, ctx = fresh_instance auctx in
- let ty = Inductive.type_of_inductive env (specif, inst) in
- ty, ctx
-
- | ConstructRef (ind,_ as cstr) ->
- let (mib,_ as specif) = Inductive.lookup_mind_specif env ind in
- let auctx = Declareops.inductive_polymorphic_context mib in
- let inst, ctx = fresh_instance auctx in
- Inductive.type_of_constructor (cstr,inst) specif, ctx
-
-let type_of_global t = type_of_reference (Global.env ()) t
-
let fresh_sort_in_family = function
| InSProp -> Sorts.sprop, ContextSet.empty
| InProp -> Sorts.prop, ContextSet.empty
@@ -135,11 +98,6 @@ let fresh_sort_in_family = function
let u = fresh_level () in
sort_of_univ (Univ.Universe.make u), ContextSet.singleton u
-let new_sort_in_family sf =
- fst (fresh_sort_in_family sf)
-
-let extend_context = Univ.extend_in_context_set
-
let new_global_univ () =
let u = fresh_level () in
(Univ.Universe.make u, ContextSet.singleton u)
diff --git a/engine/univGen.mli b/engine/univGen.mli
index b4598e10d0..34920e5620 100644
--- a/engine/univGen.mli
+++ b/engine/univGen.mli
@@ -24,16 +24,7 @@ val new_univ_id : unit -> univ_unique_id (** for the stm *)
val new_univ_global : unit -> Level.UGlobal.t
val fresh_level : unit -> Level.t
-val new_univ : unit -> Universe.t
-[@@ocaml.deprecated "Use [new_univ_level]"]
-val new_Type : unit -> types
-[@@ocaml.deprecated "Use [new_univ_level]"]
-val new_Type_sort : unit -> Sorts.t
-[@@ocaml.deprecated "Use [new_univ_level]"]
-
val new_global_univ : unit -> Universe.t in_universe_context_set
-val new_sort_in_family : Sorts.family -> Sorts.t
-[@@ocaml.deprecated "Use [fresh_sort_in_family]"]
(** Build a fresh instance for a given context, its associated substitution and
the instantiated constraints. *)
@@ -66,27 +57,9 @@ val fresh_universe_context_set_instance : ContextSet.t ->
(** Raises [Not_found] if not a global reference. *)
val global_of_constr : constr -> GlobRef.t puniverses
-val constr_of_global_univ : GlobRef.t puniverses -> constr
-[@@ocaml.deprecated "Use [Constr.mkRef]"]
-
-val extend_context : 'a in_universe_context_set -> ContextSet.t ->
- 'a in_universe_context_set
-[@@ocaml.deprecated "Use [Univ.extend_in_context_set]"]
-
(** Create a fresh global in the global environment, without side effects.
BEWARE: this raises an error on polymorphic constants/inductives:
the constraints should be properly added to an evd.
See Evd.fresh_global, Evarutil.new_global, and pf_constr_of_global for
the proper way to get a fresh copy of a polymorphic global reference. *)
val constr_of_monomorphic_global : GlobRef.t -> constr
-
-val constr_of_global : GlobRef.t -> constr
-[@@ocaml.deprecated "constr_of_global will crash on polymorphic constants,\
- use [constr_of_monomorphic_global] if the reference is guaranteed to\
- be monomorphic, [Evarutil.new_global] or [Tacmach.New.pf_constr_of_global] otherwise"]
-
-(** Returns the type of the global reference, by creating a fresh instance of polymorphic
- references and computing their instantiated universe context. (side-effect on the
- universe counter, use with care). *)
-val type_of_global : GlobRef.t -> types in_universe_context_set
-[@@ocaml.deprecated "use [Typeops.type_of_global]"]
diff --git a/ide/coqide.ml b/ide/coqide.ml
index aa9e150fd5..4f00be27a1 100644
--- a/ide/coqide.ml
+++ b/ide/coqide.ml
@@ -561,7 +561,7 @@ let update_status sn =
| None -> ""
| Some n -> ", proving " ^ n
in
- display ("Ready"^ (if nanoPG#get then ", [μPG]" else "") ^ path ^ name);
+ display ("Ready"^ (if microPG#get then ", [μPG]" else "") ^ path ^ name);
Coq.return ()
in
Coq.bind (Coq.status false) next
@@ -1200,7 +1200,7 @@ let build_ui () =
item "Help for μPG mode" ~label:"Help for μPG mode"
~callback:(fun _ -> on_current_term (fun sn ->
sn.messages#default_route#clear;
- sn.messages#default_route#add_string (NanoPG.get_documentation ())));
+ sn.messages#default_route#add_string (MicroPG.get_documentation ())));
item "About Coq" ~label:"_About" ~stock:`ABOUT
~callback:MiscMenu.about
];
@@ -1234,7 +1234,7 @@ let build_ui () =
let () = vbox#pack toolbar#coerce in
(* Emacs/PG mode *)
- NanoPG.init w notebook all_menus;
+ MicroPG.init w notebook all_menus;
(* On tab switch, reset, update location *)
let _ = notebook#connect#switch_page ~callback:(fun n ->
@@ -1251,7 +1251,7 @@ let build_ui () =
let () = refresh_notebook_pos () in
let lower_hbox = GPack.hbox ~homogeneous:false ~packing:vbox#pack () in
let () = lower_hbox#pack ~expand:true status#coerce in
- let () = push_info ("Ready"^ if nanoPG#get then ", [μPG]" else "") in
+ let () = push_info ("Ready"^ if microPG#get then ", [μPG]" else "") in
(* Location display *)
let l = GMisc.label
diff --git a/ide/ide.mllib b/ide/ide.mllib
index ed6520f29f..f8e8ff48d6 100644
--- a/ide/ide.mllib
+++ b/ide/ide.mllib
@@ -30,5 +30,5 @@ CoqOps
Wg_Command
Session
Coqide_ui
-NanoPG
+MicroPG
Coqide
diff --git a/ide/nanoPG.ml b/ide/microPG.ml
index d85d87142c..25cab4638c 100644
--- a/ide/nanoPG.ml
+++ b/ide/microPG.ml
@@ -65,14 +65,27 @@ type 'c entry = {
}
let mC = [`CONTROL]
-let mM = [`MOD1]
+let mM =
+ if Coq_config.arch = "Darwin" then
+ (* We add both MOD2 and META because both are
+ returned when pressing Command on MacOS X *)
+ [`CONTROL;`MOD2;`META]
+ else
+ [`MOD1]
-let mod_of t x = List.for_all (fun m -> List.mem m (GdkEvent.Key.state t)) x
+let mod_of t x =
+ let y = GdkEvent.Key.state t in
+ List.for_all (fun m -> List.mem m y) x &&
+ List.for_all (fun m -> List.mem m x) y
let pr_keymod l =
- if l = mC then "C-"
- else if l = mM then "M-"
- else ""
+ if l = mC then
+ "Ctrl-"
+ else
+ if l = mM then
+ if Coq_config.arch = "Darwin" then "Ctrl-Cmd-" else "Meta-"
+ else
+ ""
let mkE ?(mods=mC) key keyname doc ?(alias=[]) contents =
List.map (fun (mods, key, keyname) -> { mods; key; keyname; doc; contents })
@@ -147,6 +160,13 @@ let emacs = insert emacs "Emacs" [] [
mkE _e "e" "Move to end of line" (Motion(fun s i ->
(if not i#ends_line then i#forward_to_line_end else i),
{ s with move = None }));
+ mkE ~mods:mM _Right "->" "Move to end of buffer" (Motion(fun s i ->
+ i#forward_to_end,
+ { s with move = None }));
+ mkE ~mods:mM _Left "<-" "Move to start of buffer" (Motion(fun s i ->
+ let buffer = new GText.buffer i#buffer in
+ buffer#start_iter,
+ { s with move = None }));
mkE _a "a" "Move to beginning of line" (Motion(fun s i ->
(i#set_line_offset 0), { s with move = None }));
mkE ~mods:mM _e "e" "Move to end of sentence" (Motion(fun s i ->
@@ -286,9 +306,9 @@ let find gui (Step(here,konts)) t =
else
if k = _c && mod_of t mC && sel_nonempty () then
ignore(run t gui (Action("Edit","Copy")) empty);
- let cmp { key; mods } = key = k && mod_of t mods in
- try `Do (List.find cmp here) with Not_found ->
- try `Cont (List.find cmp konts).contents with Not_found -> `NotFound
+ let cmp { key; mods } = key = k && mod_of t mods in
+ try `Do (List.find cmp here) with Not_found ->
+ try `Cont (List.find cmp konts).contents with Not_found -> `NotFound
let init w nb ags =
let gui = { notebook = nb; action_groups = ags } in
@@ -305,7 +325,7 @@ let init w nb ags =
then false
else begin
eprintf "got key %s\n%!" (pr_key t);
- if nanoPG#get then begin
+ if microPG#get then begin
match find gui !cur t with
| `Do e ->
eprintf "run (%s) %s on %s\n%!" e.keyname e.doc (pr_status !status);
@@ -320,4 +340,6 @@ let init w nb ags =
-let get_documentation () = print_keypaths pg
+let get_documentation () =
+ "Chars, words, lines and sentences below pertain to standard unicode segmentation rules\n" ^
+ print_keypaths pg
diff --git a/ide/nanoPG.mli b/ide/microPG.mli
index bc9b39d823..bc9b39d823 100644
--- a/ide/nanoPG.mli
+++ b/ide/microPG.mli
diff --git a/ide/preferences.ml b/ide/preferences.ml
index 3893d023bd..4e2e3f31e6 100644
--- a/ide/preferences.ml
+++ b/ide/preferences.ml
@@ -561,7 +561,8 @@ let tab_length =
let highlight_current_line =
new preference ~name:["highlight_current_line"] ~init:false ~repr:Repr.(bool)
-let nanoPG =
+let microPG =
+ (* Legacy name in preference is "nanoPG" *)
new preference ~name:["nanoPG"] ~init:false ~repr:Repr.(bool)
let user_queries =
@@ -799,7 +800,7 @@ let configure ?(apply=(fun () -> ())) parent =
let () = button "Show progress bar" show_progress_bar in
let () = button "Insert spaces instead of tabs" spaces_instead_of_tabs in
let () = button "Highlight current line" highlight_current_line in
- let () = button "Emacs/PG keybindings (μPG mode)" nanoPG in
+ let () = button "Emacs/PG keybindings (μPG mode)" microPG in
let callback () = () in
custom ~label box callback true
in
diff --git a/ide/preferences.mli b/ide/preferences.mli
index 785c191b46..b01c4598d8 100644
--- a/ide/preferences.mli
+++ b/ide/preferences.mli
@@ -102,7 +102,7 @@ val show_progress_bar : bool preference
val spaces_instead_of_tabs : bool preference
val tab_length : int preference
val highlight_current_line : bool preference
-val nanoPG : bool preference
+val microPG : bool preference
val user_queries : (string * string) list preference
val diffs : string preference
diff --git a/interp/constrextern.ml b/interp/constrextern.ml
index e5bf52571c..bb66658a37 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -850,10 +850,10 @@ let rec extern inctx scopes vars r =
| Some c :: q ->
match locs with
| [] -> anomaly (Pp.str "projections corruption [Constrextern.extern].")
- | (_, false) :: locs' ->
+ | { Recordops.pk_true_proj = false } :: locs' ->
(* we don't want to print locals *)
ip q locs' args acc
- | (_, true) :: locs' ->
+ | { Recordops.pk_true_proj = true } :: locs' ->
match args with
| [] -> raise No_match
(* we give up since the constructor is not complete *)
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index c0801067ce..f06493b374 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -1368,7 +1368,7 @@ let sort_fields ~complete loc fields completer =
let first_field = GlobRef.equal field_glob_ref first_field_glob_ref in
begin match proj_kinds with
| [] -> anomaly (Pp.str "Number of projections mismatch.")
- | (_, regular) :: proj_kinds ->
+ | { Recordops.pk_true_proj = regular } :: proj_kinds ->
(* "regular" is false when the field is defined
by a let-in in the record declaration
(its value is fixed from other fields). *)
diff --git a/interp/impargs.ml b/interp/impargs.ml
index d83a0ce918..806fe93297 100644
--- a/interp/impargs.ml
+++ b/interp/impargs.ml
@@ -120,8 +120,6 @@ let argument_position_eq p1 p2 = match p1, p2 with
| Hyp h1, Hyp h2 -> Int.equal h1 h2
| _ -> false
-let explicitation_eq = Constrexpr_ops.explicitation_eq
-
type implicit_explanation =
| DepRigid of argument_position
| DepFlex of argument_position
@@ -499,9 +497,9 @@ type implicit_interactive_request =
type implicit_discharge_request =
| ImplLocal
- | ImplConstant of Constant.t * implicits_flags
+ | ImplConstant of implicits_flags
| ImplMutualInductive of MutInd.t * implicits_flags
- | ImplInteractive of GlobRef.t * implicits_flags *
+ | ImplInteractive of implicits_flags *
implicit_interactive_request
let implicits_table = Summary.ref GlobRef.Map.empty ~name:"implicits"
@@ -554,39 +552,24 @@ let add_section_impls vars extra_impls (cond,impls) =
let discharge_implicits (_,(req,l)) =
match req with
| ImplLocal -> None
- | ImplInteractive (ref,flags,exp) ->
- (try
- let vars = variable_section_segment_of_reference ref in
- let extra_impls = impls_of_context vars in
- let l' = [ref, List.map (add_section_impls vars extra_impls) (snd (List.hd l))] in
- Some (ImplInteractive (ref,flags,exp),l')
- with Not_found -> (* ref not defined in this section *) Some (req,l))
- | ImplConstant (con,flags) ->
- (try
- let vars = variable_section_segment_of_reference (ConstRef con) in
- let extra_impls = impls_of_context vars in
- let newimpls = List.map (add_section_impls vars extra_impls) (snd (List.hd l)) in
- let l' = [ConstRef con,newimpls] in
- Some (ImplConstant (con,flags),l')
- with Not_found -> (* con not defined in this section *) Some (req,l))
- | ImplMutualInductive (kn,flags) ->
- (try
- let l' = List.map (fun (gr, l) ->
- let vars = variable_section_segment_of_reference gr in
- let extra_impls = impls_of_context vars in
- (gr,
- List.map (add_section_impls vars extra_impls) l)) l
- in
- Some (ImplMutualInductive (kn,flags),l')
- with Not_found -> (* ref not defined in this section *) Some (req,l))
+ | ImplMutualInductive _ | ImplInteractive _ | ImplConstant _ ->
+ let l' =
+ try
+ List.map (fun (gr, l) ->
+ let vars = variable_section_segment_of_reference gr in
+ let extra_impls = impls_of_context vars in
+ let newimpls = List.map (add_section_impls vars extra_impls) l in
+ (gr, newimpls)) l
+ with Not_found -> l in
+ Some (req,l')
let rebuild_implicits (req,l) =
match req with
| ImplLocal -> assert false
- | ImplConstant (con,flags) ->
- let oldimpls = snd (List.hd l) in
- let newimpls = compute_constant_implicits flags con in
- req, [ConstRef con, List.map2 merge_impls oldimpls newimpls]
+ | ImplConstant flags ->
+ let ref,oldimpls = List.hd l in
+ let newimpls = compute_global_implicits flags ref in
+ req, [ref, List.map2 merge_impls oldimpls newimpls]
| ImplMutualInductive (kn,flags) ->
let newimpls = compute_all_mib_implicits flags kn in
let rec aux olds news =
@@ -597,15 +580,14 @@ let rebuild_implicits (req,l) =
| _, _ -> assert false
in req, aux l newimpls
- | ImplInteractive (ref,flags,o) ->
+ | ImplInteractive (flags,o) ->
+ let ref,oldimpls = List.hd l in
(if isVarRef ref && is_in_section ref then ImplLocal else req),
match o with
| ImplAuto ->
- let oldimpls = snd (List.hd l) in
let newimpls = compute_global_implicits flags ref in
[ref,List.map2 merge_impls oldimpls newimpls]
| ImplManual userimplsize ->
- let oldimpls = snd (List.hd l) in
if flags.auto then
let newimpls = List.hd (compute_global_implicits flags ref) in
let p = List.length (snd newimpls) - userimplsize in
@@ -640,7 +622,7 @@ let declare_implicits_gen req flags ref =
let declare_implicits local ref =
let flags = { !implicit_args with auto = true } in
let req =
- if is_local local ref then ImplLocal else ImplInteractive(ref,flags,ImplAuto) in
+ if is_local local ref then ImplLocal else ImplInteractive(flags,ImplAuto) in
declare_implicits_gen req flags ref
let declare_var_implicits id =
@@ -649,7 +631,7 @@ let declare_var_implicits id =
let declare_constant_implicits con =
let flags = !implicit_args in
- declare_implicits_gen (ImplConstant (con,flags)) flags (ConstRef con)
+ declare_implicits_gen (ImplConstant flags) flags (ConstRef con)
let declare_mib_implicits kn =
let flags = !implicit_args in
@@ -699,7 +681,7 @@ let declare_manual_implicits local ref ?enriching l =
let l = [DefaultImpArgs, set_manual_implicits flags enriching autoimpls l] in
let req =
if is_local local ref then ImplLocal
- else ImplInteractive(ref,flags,ImplManual (List.length autoimpls))
+ else ImplInteractive(flags,ImplManual (List.length autoimpls))
in add_anonymous_leaf (inImplicits (req,[ref,l]))
let maybe_declare_manual_implicits local ref ?enriching l =
@@ -758,7 +740,7 @@ let set_implicits local ref l =
compute_implicit_statuses autoimpls imps)) l in
let req =
if is_local local ref then ImplLocal
- else ImplInteractive(ref,flags,ImplManual (List.length autoimpls))
+ else ImplInteractive(flags,ImplManual (List.length autoimpls))
in add_anonymous_leaf (inImplicits (req,[ref,l']))
let extract_impargs_data impls =
diff --git a/interp/impargs.mli b/interp/impargs.mli
index 0070423530..ccdd448460 100644
--- a/interp/impargs.mli
+++ b/interp/impargs.mli
@@ -143,7 +143,3 @@ val projection_implicits : env -> Projection.t -> implicit_status list ->
val select_impargs_size : int -> implicits_list list -> implicit_status list
val select_stronger_impargs : implicits_list list -> implicit_status list
-
-val explicitation_eq : Constrexpr.explicitation -> Constrexpr.explicitation -> bool
- [@@ocaml.deprecated "Use Constrexpr_ops.explicitation_eq instead (since 8.10)"]
-(** Equality on [explicitation]. *)
diff --git a/interp/implicit_quantifiers.ml b/interp/implicit_quantifiers.ml
index dffccf02fc..6277d874dd 100644
--- a/interp/implicit_quantifiers.ml
+++ b/interp/implicit_quantifiers.ml
@@ -281,7 +281,7 @@ let implicits_of_glob_constr ?(with_products=true) l =
| _ -> ()
in []
| GLambda (na, bk, t, b) -> abs na bk b
- | GLetIn (na, b, t, c) -> aux i b
+ | GLetIn (na, b, t, c) -> aux i c
| GRec (fix_kind, nas, args, tys, bds) ->
let nb = match fix_kind with |GFix (_, n) -> n | GCoFix n -> n in
List.fold_left_i (fun i l (na,bk,_,_) -> add_impl i na bk l) i (aux (List.length args.(nb) + i) bds.(nb)) args.(nb)
diff --git a/kernel/byterun/coq_interp.c b/kernel/byterun/coq_interp.c
index 1b348ae777..4b45608ae5 100644
--- a/kernel/byterun/coq_interp.c
+++ b/kernel/byterun/coq_interp.c
@@ -97,7 +97,8 @@ if (sp - num_args < coq_stack_threshold) { \
several architectures.
*/
-#if defined(__GNUC__) && !defined(DEBUG)
+#if defined(__GNUC__) && !defined(DEBUG) && !defined(__INTEL_COMPILER) \
+ && !defined(__llvm__)
#ifdef __mips__
#define PC_REG asm("$16")
#define SP_REG asm("$17")
@@ -126,7 +127,7 @@ if (sp - num_args < coq_stack_threshold) { \
#define SP_REG asm("%edi")
#define ACCU_REG
#endif
-#if defined(PPC) || defined(_POWER) || defined(_IBMR2)
+#if defined(__ppc__) || defined(__ppc64__)
#define PC_REG asm("26")
#define SP_REG asm("27")
#define ACCU_REG asm("28")
@@ -141,8 +142,9 @@ if (sp - num_args < coq_stack_threshold) { \
#define SP_REG asm("a4")
#define ACCU_REG asm("d7")
#endif
-#if defined(__arm__) && !defined(__thumb2__)
-#define PC_REG asm("r9")
+/* OCaml PR#4953: these specific registers not available in Thumb mode */
+#if defined(__arm__) && !defined(__thumb__)
+#define PC_REG asm("r6")
#define SP_REG asm("r8")
#define ACCU_REG asm("r7")
#endif
@@ -152,6 +154,17 @@ if (sp - num_args < coq_stack_threshold) { \
#define ACCU_REG asm("38")
#define JUMPTBL_BASE_REG asm("39")
#endif
+#ifdef __x86_64__
+#define PC_REG asm("%r15")
+#define SP_REG asm("%r14")
+#define ACCU_REG asm("%r13")
+#endif
+#ifdef __aarch64__
+#define PC_REG asm("%x19")
+#define SP_REG asm("%x20")
+#define ACCU_REG asm("%x21")
+#define JUMPTBL_BASE_REG asm("%x22")
+#endif
#endif
#define CheckInt1() do{ \
diff --git a/kernel/entries.ml b/kernel/entries.ml
index a3d32267a7..adb3f6bd29 100644
--- a/kernel/entries.ml
+++ b/kernel/entries.ml
@@ -108,21 +108,7 @@ type module_entry =
| MExpr of
module_params_entry * module_struct_entry * module_struct_entry option
-
-type seff_env =
- [ `Nothing
- (* The proof term and its universes.
- Same as the constant_body's but not in an ephemeron *)
- | `Opaque of Constr.t * Univ.ContextSet.t ]
-
(** Not used by the kernel. *)
type side_effect_role =
| Subproof
| Schema of inductive * string
-
-type side_eff = {
- seff_constant : Constant.t;
- seff_body : Declarations.constant_body;
- seff_env : seff_env;
- seff_role : side_effect_role;
-}
diff --git a/kernel/indtypes.ml b/kernel/indtypes.ml
index 009eb3da38..bb3b0a538e 100644
--- a/kernel/indtypes.ml
+++ b/kernel/indtypes.ml
@@ -49,20 +49,6 @@ let weaker_noccur_between env x nvars t =
(************************************************************************)
(* Various well-formedness check for inductive declarations *)
-(* Errors related to inductive constructions *)
-type inductive_error = Type_errors.inductive_error =
- | NonPos of env * constr * constr
- | NotEnoughArgs of env * constr * constr
- | NotConstructor of env * Id.t * constr * constr * int * int
- | NonPar of env * constr * int * constr * constr
- | SameNamesTypes of Id.t
- | SameNamesConstructors of Id.t
- | SameNamesOverlap of Id.t list
- | NotAnArity of env * constr
- | BadEntry
- | LargeNonPropInductiveNotInType
- | BadUnivs
-
exception InductiveError = Type_errors.InductiveError
(************************************************************************)
@@ -84,6 +70,7 @@ exception IllFormedInd of ill_formed_ind
let mind_extract_params = decompose_prod_n_assum
let explain_ind_err id ntyp env nparamsctxt c err =
+ let open Type_errors in
let (_lparams,c') = mind_extract_params nparamsctxt c in
match err with
| LocalNonPos kt ->
@@ -329,7 +316,7 @@ let check_positivity_one ~chkpos recursive (env,_,ntypes,_ as ienv) paramsctxt (
| Prod (na,b,d) ->
let () = assert (List.is_empty largs) in
if not recursive && not (noccur_between n ntypes b) then
- raise (InductiveError BadEntry);
+ raise (InductiveError Type_errors.BadEntry);
let nmr',recarg = check_pos ienv nmr b in
let ienv' = ienv_push_var ienv (na,b,mk_norec) in
check_constr_rec ienv' nmr' (recarg::lrec) d
diff --git a/kernel/indtypes.mli b/kernel/indtypes.mli
index 7810c1723e..1b8e4208ff 100644
--- a/kernel/indtypes.mli
+++ b/kernel/indtypes.mli
@@ -9,28 +9,9 @@
(************************************************************************)
open Names
-open Constr
open Declarations
open Environ
open Entries
(** Check an inductive. *)
val check_inductive : env -> MutInd.t -> mutual_inductive_entry -> mutual_inductive_body
-
-(** Deprecated *)
-type inductive_error =
- | NonPos of env * constr * constr
- | NotEnoughArgs of env * constr * constr
- | NotConstructor of env * Id.t * constr * constr * int * int
- | NonPar of env * constr * int * constr * constr
- | SameNamesTypes of Id.t
- | SameNamesConstructors of Id.t
- | SameNamesOverlap of Id.t list
- | NotAnArity of env * constr
- | BadEntry
- | LargeNonPropInductiveNotInType
- | BadUnivs
-[@@ocaml.deprecated "Use [Type_errors.inductive_error]"]
-
-exception InductiveError of Type_errors.inductive_error
-[@@ocaml.deprecated "Use [Type_errors.InductiveError]"]
diff --git a/kernel/modops.ml b/kernel/modops.ml
index 4f992d3972..4fdd7ab334 100644
--- a/kernel/modops.ml
+++ b/kernel/modops.ml
@@ -608,11 +608,7 @@ let clean_bounded_mod_expr sign =
(** {6 Stm machinery } *)
let join_constant_body except otab cb =
match cb.const_body with
- | OpaqueDef o ->
- (match Opaqueproof.uuid_opaque otab o with
- | Some uuid when not(Future.UUIDSet.mem uuid except) ->
- Opaqueproof.join_opaque otab o
- | _ -> ())
+ | OpaqueDef o -> Opaqueproof.join_opaque ~except otab o
| _ -> ()
let join_structure except otab s =
diff --git a/kernel/names.ml b/kernel/names.ml
index 9f27212967..047a1d6525 100644
--- a/kernel/names.ml
+++ b/kernel/names.ml
@@ -376,9 +376,6 @@ module KerName = struct
{ modpath; knlabel; refhash = -1; }
let repr kn = (kn.modpath, kn.knlabel)
- let make2 = make
- [@@ocaml.deprecated "Please use [KerName.make]"]
-
let modpath kn = kn.modpath
let label kn = kn.knlabel
diff --git a/kernel/names.mli b/kernel/names.mli
index 61df3bad0e..2238e932b0 100644
--- a/kernel/names.mli
+++ b/kernel/names.mli
@@ -278,9 +278,6 @@ sig
val make : ModPath.t -> Label.t -> t
val repr : t -> ModPath.t * Label.t
- val make2 : ModPath.t -> Label.t -> t
- [@@ocaml.deprecated "Please use [KerName.make]"]
-
(** Projections *)
val modpath : t -> ModPath.t
val label : t -> Label.t
diff --git a/kernel/opaqueproof.ml b/kernel/opaqueproof.ml
index 303cb06c55..57059300b8 100644
--- a/kernel/opaqueproof.ml
+++ b/kernel/opaqueproof.ml
@@ -87,19 +87,18 @@ let discharge_direct_opaque ~cook_constr ci = function
| Direct (d,cu) ->
Direct (ci::d,Future.chain cu (fun (c, u) -> cook_constr c, u))
-let join_opaque { opaque_val = prfs; opaque_dir = odp; _ } = function
- | Direct (_,cu) -> ignore(Future.join cu)
+let join except cu = match except with
+| None -> ignore (Future.join cu)
+| Some except ->
+ if Future.UUIDSet.mem (Future.uuid cu) except then ()
+ else ignore (Future.join cu)
+
+let join_opaque ?except { opaque_val = prfs; opaque_dir = odp; _ } = function
+ | Direct (_,cu) -> join except cu
| Indirect (_,dp,i) ->
if DirPath.equal dp odp then
let fp = snd (Int.Map.find i prfs) in
- ignore(Future.join fp)
-
-let uuid_opaque { opaque_val = prfs; opaque_dir = odp; _ } = function
- | Direct (_,cu) -> Some (Future.uuid cu)
- | Indirect (_,dp,i) ->
- if DirPath.equal dp odp
- then Some (Future.uuid (snd (Int.Map.find i prfs)))
- else None
+ join except fp
let force_proof { opaque_val = prfs; opaque_dir = odp; _ } = function
| Direct (_,cu) ->
@@ -128,16 +127,6 @@ let get_constraints { opaque_val = prfs; opaque_dir = odp; _ } = function
then Some(Future.chain (snd (Int.Map.find i prfs)) snd)
else !get_univ dp i
-let get_proof { opaque_val = prfs; opaque_dir = odp; _ } = function
- | Direct (_,cu) -> Future.chain cu fst
- | Indirect (l,dp,i) ->
- let pt =
- if DirPath.equal dp odp
- then Future.chain (snd (Int.Map.find i prfs)) fst
- else !get_opaque dp i in
- Future.chain pt (fun c ->
- force_constr (List.fold_right subst_substituted l (from_val c)))
-
module FMap = Future.UUIDMap
let a_constr = Future.from_val (mkRel 1)
diff --git a/kernel/opaqueproof.mli b/kernel/opaqueproof.mli
index 5ea6da649b..d47c0bbb3c 100644
--- a/kernel/opaqueproof.mli
+++ b/kernel/opaqueproof.mli
@@ -39,7 +39,6 @@ val turn_indirect : DirPath.t -> opaque -> opaquetab -> opaque * opaquetab
indirect opaque accessor configured below. *)
val force_proof : opaquetab -> opaque -> constr
val force_constraints : opaquetab -> opaque -> Univ.ContextSet.t
-val get_proof : opaquetab -> opaque -> constr Future.computation
val get_constraints :
opaquetab -> opaque -> Univ.ContextSet.t Future.computation option
@@ -60,8 +59,7 @@ type cooking_info = {
val discharge_direct_opaque :
cook_constr:(constr -> constr) -> cooking_info -> opaque -> opaque
-val uuid_opaque : opaquetab -> opaque -> Future.UUID.t option
-val join_opaque : opaquetab -> opaque -> unit
+val join_opaque : ?except:Future.UUIDSet.t -> opaquetab -> opaque -> unit
val dump : opaquetab ->
Constr.t Future.computation array *
diff --git a/kernel/safe_typing.ml b/kernel/safe_typing.ml
index 673f025c75..75375812c0 100644
--- a/kernel/safe_typing.ml
+++ b/kernel/safe_typing.ml
@@ -228,6 +228,12 @@ let check_engagement env expected_impredicative_set =
(** {6 Stm machinery } *)
+type seff_env =
+ [ `Nothing
+ (* The proof term and its universes.
+ Same as the constant_body's but not in an ephemeron *)
+ | `Opaque of Constr.t * Univ.ContextSet.t ]
+
let get_opaque_body env cbo =
match cbo.const_body with
| Undef _ -> assert false
@@ -240,7 +246,10 @@ let get_opaque_body env cbo =
type side_effect = {
from_env : Declarations.structure_body CEphemeron.key;
- eff : Entries.side_eff list;
+ seff_constant : Constant.t;
+ seff_body : Declarations.constant_body;
+ seff_env : seff_env;
+ seff_role : Entries.side_effect_role;
}
module SideEffects :
@@ -254,11 +263,9 @@ end =
struct
module SeffOrd = struct
-open Entries
type t = side_effect
let compare e1 e2 =
- let cmp e1 e2 = Constant.CanOrd.compare e1.seff_constant e2.seff_constant in
- List.compare cmp e1.eff e2.eff
+ Constant.CanOrd.compare e1.seff_constant e2.seff_constant
end
module SeffSet = Set.Make(SeffOrd)
@@ -279,37 +286,37 @@ end
type private_constants = SideEffects.t
let side_effects_of_private_constants l =
- let ans = List.rev (SideEffects.repr l) in
- List.map_append (fun { eff; _ } -> eff) ans
+ List.rev (SideEffects.repr l)
+
+let push_private_constants env eff =
+ let eff = side_effects_of_private_constants eff in
+ let add_if_undefined env eff =
+ try ignore(Environ.lookup_constant eff.seff_constant env); env
+ with Not_found -> Environ.add_constant eff.seff_constant eff.seff_body env
+ in
+ List.fold_left add_if_undefined env eff
let empty_private_constants = SideEffects.empty
-let add_private mb eff effs =
- let from_env = CEphemeron.create mb in
- SideEffects.add { eff; from_env } effs
let concat_private = SideEffects.concat
-let make_eff env cst r =
- let open Entries in
+let private_constant env role cst =
+ (** The constant must be the last entry of the safe environment *)
+ let () = match env.revstruct with
+ | (lbl, SFBconst _) :: _ -> assert (Label.equal lbl (Constant.label cst))
+ | _ -> assert false
+ in
+ let from_env = CEphemeron.create env.revstruct in
let cbo = Environ.lookup_constant cst env.env in
- {
+ let eff = {
+ from_env = from_env;
seff_constant = cst;
seff_body = cbo;
seff_env = get_opaque_body env.env cbo;
- seff_role = r;
- }
-
-let private_con_of_con env c =
- let open Entries in
- let eff = [make_eff env c Subproof] in
- add_private env.revstruct eff empty_private_constants
-
-let private_con_of_scheme ~kind env cl =
- let open Entries in
- let eff = List.map (fun (i, c) -> make_eff env c (Schema (i, kind))) cl in
- add_private env.revstruct eff empty_private_constants
+ seff_role = role;
+ } in
+ SideEffects.add eff empty_private_constants
let universes_of_private eff =
- let open Entries in
let fold acc eff =
let acc = match eff.seff_env with
| `Nothing -> acc
@@ -588,22 +595,17 @@ let add_constant_aux ~in_section senv (kn, cb) =
let mk_pure_proof c = (c, Univ.ContextSet.empty), SideEffects.empty
let inline_side_effects env body side_eff =
- let open Entries in
let open Constr in
(** First step: remove the constants that are still in the environment *)
- let filter { eff = se; from_env = mb } =
- let map e = (e.seff_constant, e.seff_body, e.seff_env) in
- let cbl = List.map map se in
- let not_exists (c,_,_) =
- try ignore(Environ.lookup_constant c env); false
- with Not_found -> true in
- let cbl = List.filter not_exists cbl in
- (cbl, mb)
+ let filter e =
+ let cb = (e.seff_constant, e.seff_body, e.seff_env) in
+ try ignore (Environ.lookup_constant e.seff_constant env); None
+ with Not_found -> Some (cb, e.from_env)
in
(* CAVEAT: we assure that most recent effects come first *)
- let side_eff = List.map filter (SideEffects.repr side_eff) in
- let sigs = List.rev_map (fun (cbl, mb) -> mb, List.length cbl) side_eff in
- let side_eff = List.fold_left (fun accu (cbl, _) -> cbl @ accu) [] side_eff in
+ let side_eff = List.map_filter filter (SideEffects.repr side_eff) in
+ let sigs = List.rev_map (fun (_, mb) -> mb) side_eff in
+ let side_eff = List.fold_left (fun accu (cb, _) -> cb :: accu) [] side_eff in
let side_eff = List.rev side_eff in
(** Most recent side-effects first in side_eff *)
if List.is_empty side_eff then (body, Univ.ContextSet.empty, sigs)
@@ -675,24 +677,22 @@ let inline_private_constants_in_definition_entry env ce =
let inline_private_constants_in_constr env body side_eff =
pi1 (inline_side_effects env body side_eff)
-let rec is_nth_suffix n l suf =
- if Int.equal n 0 then l == suf
- else match l with
- | [] -> false
- | _ :: l -> is_nth_suffix (pred n) l suf
+let is_suffix l suf = match l with
+| [] -> false
+| _ :: l -> l == suf
(* Given the list of signatures of side effects, checks if they match.
* I.e. if they are ordered descendants of the current revstruct.
Returns the number of effects that can be trusted. *)
let check_signatures curmb sl =
- let is_direct_ancestor accu (mb, how_many) =
+ let is_direct_ancestor accu mb =
match accu with
| None -> None
| Some (n, curmb) ->
try
let mb = CEphemeron.get mb in
- if is_nth_suffix how_many mb curmb
- then Some (n + how_many, mb)
+ if is_suffix mb curmb
+ then Some (n + 1, mb)
else None
with CEphemeron.InvalidKey -> None in
let sl = List.fold_left is_direct_ancestor (Some (0, curmb)) sl in
@@ -725,7 +725,6 @@ let constant_entry_of_side_effect cb u =
const_entry_inline_code = cb.const_inline_code }
let turn_direct orig =
- let open Entries in
let cb = orig.seff_body in
if Declareops.is_opaque cb then
let p = match orig.seff_env with
@@ -738,7 +737,6 @@ let turn_direct orig =
else orig
let export_eff eff =
- let open Entries in
(eff.seff_constant, eff.seff_body, eff.seff_role)
let export_side_effects mb env c =
@@ -751,10 +749,9 @@ let export_side_effects mb env c =
let not_exists e =
try ignore(Environ.lookup_constant e.seff_constant env); false
with Not_found -> true in
- let aux (acc,sl) { eff = se; from_env = mb } =
- let cbl = List.filter not_exists se in
- if List.is_empty cbl then acc, sl
- else cbl :: acc, (mb,List.length cbl) :: sl in
+ let aux (acc,sl) e =
+ if not (not_exists e) then acc, sl
+ else e :: acc, e.from_env :: sl in
let seff, signatures = List.fold_left aux ([],[]) (SideEffects.repr eff) in
let trusted = check_signatures mb signatures in
let push_seff env eff =
@@ -772,10 +769,9 @@ let export_side_effects mb env c =
let rec translate_seff sl seff acc env =
match seff with
| [] -> List.rev acc, ce
- | cbs :: rest ->
+ | eff :: rest ->
if Int.equal sl 0 then
- let env, cbs =
- List.fold_left (fun (env,cbs) eff ->
+ let env, cb =
let { seff_constant = kn; seff_body = ocb; seff_env = u ; _ } = eff in
let ce = constant_entry_of_side_effect ocb u in
let cb = Term_typing.translate_constant Term_typing.Pure env kn ce in
@@ -783,15 +779,14 @@ let export_side_effects mb env c =
seff_body = cb;
seff_env = `Nothing;
} in
- (push_seff env eff, export_eff eff :: cbs))
- (env,[]) cbs in
- translate_seff 0 rest (cbs @ acc) env
+ (push_seff env eff, export_eff eff)
+ in
+ translate_seff 0 rest (cb :: acc) env
else
- let cbs_len = List.length cbs in
- let cbs = List.map turn_direct cbs in
- let env = List.fold_left push_seff env cbs in
- let ecbs = List.map export_eff cbs in
- translate_seff (sl - cbs_len) rest (ecbs @ acc) env
+ let cb = turn_direct eff in
+ let env = push_seff env cb in
+ let ecb = export_eff cb in
+ translate_seff (sl - 1) rest (ecb :: acc) env
in
translate_seff trusted seff [] env
diff --git a/kernel/safe_typing.mli b/kernel/safe_typing.mli
index 46c97c1fb8..d6c7022cf5 100644
--- a/kernel/safe_typing.mli
+++ b/kernel/safe_typing.mli
@@ -43,18 +43,13 @@ type 'a safe_transformer = safe_environment -> 'a * safe_environment
type private_constants
-val side_effects_of_private_constants :
- private_constants -> Entries.side_eff list
-(** Return the list of individual side-effects in the order of their
- creation. *)
-
val empty_private_constants : private_constants
val concat_private : private_constants -> private_constants -> private_constants
(** [concat_private e1 e2] adds the constants of [e1] to [e2], i.e. constants in
[e1] must be more recent than those of [e2]. *)
-val private_con_of_con : safe_environment -> Constant.t -> private_constants
-val private_con_of_scheme : kind:string -> safe_environment -> (inductive * Constant.t) list -> private_constants
+val private_constant : safe_environment -> Entries.side_effect_role -> Constant.t -> private_constants
+(** Constant must be the last definition of the safe_environment. *)
val mk_pure_proof : Constr.constr -> private_constants Entries.proof_output
val inline_private_constants_in_constr :
@@ -62,6 +57,9 @@ val inline_private_constants_in_constr :
val inline_private_constants_in_definition_entry :
Environ.env -> private_constants Entries.definition_entry -> unit Entries.definition_entry
+val push_private_constants : Environ.env -> private_constants -> Environ.env
+(** Push the constants in the environment if not already there. *)
+
val universes_of_private : private_constants -> Univ.ContextSet.t list
val is_curmod_library : safe_environment -> bool
diff --git a/lib/acyclicGraph.ml b/lib/acyclicGraph.ml
index 7d04c8f5a1..e1dcfcc6ce 100644
--- a/lib/acyclicGraph.ml
+++ b/lib/acyclicGraph.ml
@@ -721,7 +721,10 @@ module Make (Point:Point) = struct
let rmap, csts = PSet.fold (fun u (rmap,csts) ->
let arcu = repr g u in
if PSet.mem arcu.canon kept then
- PMap.add arcu.canon arcu.canon rmap, Constraint.add (u,Eq,arcu.canon) csts
+ let csts = if Point.equal u arcu.canon then csts
+ else Constraint.add (u,Eq,arcu.canon) csts
+ in
+ PMap.add arcu.canon arcu.canon rmap, csts
else
match PMap.find arcu.canon rmap with
| v -> rmap, Constraint.add (u,Eq,v) csts
diff --git a/lib/rtree.ml b/lib/rtree.ml
index e1c6a4c4d6..66d9eba3f7 100644
--- a/lib/rtree.ml
+++ b/lib/rtree.ml
@@ -115,8 +115,6 @@ struct
end
-let smartmap = Smart.map
-
(** Structural equality test, parametrized by an equality on elements *)
let rec raw_eq cmp t t' = match t, t' with
@@ -149,9 +147,6 @@ let equiv cmp cmp' =
let equal cmp t t' =
t == t' || raw_eq cmp t t' || equiv cmp cmp t t'
-(** Deprecated alias *)
-let eq_rtree = equal
-
(** Intersection of rtrees of same arity *)
let rec inter cmp interlbl def n histo t t' =
try
diff --git a/lib/rtree.mli b/lib/rtree.mli
index 5ab14f6039..67519aa387 100644
--- a/lib/rtree.mli
+++ b/lib/rtree.mli
@@ -77,15 +77,9 @@ val incl : ('a -> 'a -> bool) -> ('a -> 'a -> 'a option) -> 'a -> 'a t -> 'a t -
(** See also [Smart.map] *)
val map : ('a -> 'b) -> 'a t -> 'b t
-val smartmap : ('a -> 'a) -> 'a t -> 'a t
-(** @deprecated Same as [Smart.map] *)
-
(** A rather simple minded pretty-printer *)
val pp_tree : ('a -> Pp.t) -> 'a t -> Pp.t
-val eq_rtree : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
-(** @deprecated Same as [Rtree.equal] *)
-
module Smart :
sig
diff --git a/library/global.ml b/library/global.ml
index 55aed1c56e..06e06a8cf2 100644
--- a/library/global.ml
+++ b/library/global.ml
@@ -157,11 +157,6 @@ let import c u d = globalize (Safe_typing.import c u d)
let env_of_context hyps =
reset_with_named_context hyps (env())
-let type_of_global_in_context = Typeops.type_of_global_in_context
-
-let universes_of_global gr =
- universes_of_global (env ()) gr
-
let is_polymorphic r = Environ.is_polymorphic (env()) r
let is_template_polymorphic r = is_template_polymorphic (env ()) r
diff --git a/library/global.mli b/library/global.mli
index 76ac3f6279..a60de48897 100644
--- a/library/global.mli
+++ b/library/global.mli
@@ -131,14 +131,6 @@ val is_polymorphic : GlobRef.t -> bool
val is_template_polymorphic : GlobRef.t -> bool
val is_type_in_type : GlobRef.t -> bool
-val type_of_global_in_context : Environ.env ->
- GlobRef.t -> Constr.types * Univ.AUContext.t
- [@@ocaml.deprecated "alias of [Typeops.type_of_global_in_context]"]
-
-(** Returns the universe context of the global reference (whatever its polymorphic status is). *)
-val universes_of_global : GlobRef.t -> Univ.AUContext.t
-[@@ocaml.deprecated "Use [Environ.universes_of_global]"]
-
(** {6 Retroknowledge } *)
val register_inline : Constant.t -> unit
diff --git a/library/globnames.ml b/library/globnames.ml
index db2e8bfaed..99dcc43ad1 100644
--- a/library/globnames.ml
+++ b/library/globnames.ml
@@ -85,15 +85,6 @@ let printable_constr_of_global = function
| ConstructRef sp -> mkConstruct sp
| IndRef sp -> mkInd sp
-module RefOrdered = Names.GlobRef.Ordered
-module RefOrdered_env = Names.GlobRef.Ordered_env
-
-module Refmap = Names.GlobRef.Map
-module Refset = Names.GlobRef.Set
-
-module Refmap_env = Names.GlobRef.Map_env
-module Refset_env = Names.GlobRef.Set_env
-
(* Extended global references *)
type syndef_name = KerName.t
@@ -134,6 +125,3 @@ end
type global_reference_or_constr =
| IsGlobal of global_reference
| IsConstr of constr
-
-(* Deprecated *)
-let eq_gr = GlobRef.equal
diff --git a/library/globnames.mli b/library/globnames.mli
index d49ed453f5..14e422b743 100644
--- a/library/globnames.mli
+++ b/library/globnames.mli
@@ -25,8 +25,6 @@ val isConstRef : GlobRef.t -> bool
val isIndRef : GlobRef.t -> bool
val isConstructRef : GlobRef.t -> bool
-val eq_gr : GlobRef.t -> GlobRef.t -> bool
-[@@ocaml.deprecated "Use Names.GlobRef.equal"]
val canonical_gr : GlobRef.t -> GlobRef.t
val destVarRef : GlobRef.t -> variable
@@ -48,22 +46,6 @@ val printable_constr_of_global : GlobRef.t -> constr
raise [Not_found] if not a global reference *)
val global_of_constr : constr -> GlobRef.t
-module RefOrdered = Names.GlobRef.Ordered
-[@@ocaml.deprecated "Use Names.GlobRef.Ordered"]
-
-module RefOrdered_env = Names.GlobRef.Ordered_env
-[@@ocaml.deprecated "Use Names.GlobRef.Ordered_env"]
-
-module Refset = Names.GlobRef.Set
-[@@ocaml.deprecated "Use Names.GlobRef.Set"]
-module Refmap = Names.GlobRef.Map
-[@@ocaml.deprecated "Use Names.GlobRef.Map"]
-
-module Refset_env = GlobRef.Set_env
-[@@ocaml.deprecated "Use Names.GlobRef.Set_env"]
-module Refmap_env = GlobRef.Map_env
-[@@ocaml.deprecated "Use Names.GlobRef.Map_env"]
-
(** {6 Extended global references } *)
type syndef_name = KerName.t
diff --git a/library/lib.ml b/library/lib.ml
index d4381a6923..a046360822 100644
--- a/library/lib.ml
+++ b/library/lib.ml
@@ -278,7 +278,7 @@ let start_mod is_type export id mp fs =
let prefix = Nametab.{ obj_dir = dir; obj_mp = mp; obj_sec = Names.DirPath.empty } in
let exists =
if is_type then Nametab.exists_cci (make_path id)
- else Nametab.exists_module dir
+ else Nametab.exists_dir dir
in
if exists then
user_err ~hdr:"open_module" (Id.print id ++ str " already exists");
@@ -569,7 +569,7 @@ let open_section id =
let opp = !lib_state.path_prefix in
let obj_dir = add_dirpath_suffix opp.Nametab.obj_dir id in
let prefix = Nametab.{ obj_dir; obj_mp = opp.obj_mp; obj_sec = add_dirpath_suffix opp.obj_sec id } in
- if Nametab.exists_section obj_dir then
+ if Nametab.exists_dir obj_dir then
user_err ~hdr:"open_section" (Id.print id ++ str " already exists.");
let fs = Summary.freeze_summaries ~marshallable:false in
add_entry (make_foname id) (OpenedSection (prefix, fs));
diff --git a/library/nametab.ml b/library/nametab.ml
index 95890b2edf..bd0ea5f04f 100644
--- a/library/nametab.ml
+++ b/library/nametab.ml
@@ -43,12 +43,6 @@ module GlobDirRef = struct
end
-type global_dir_reference = GlobDirRef.t
-[@@ocaml.deprecated "Use [GlobDirRef.t]"]
-
-let eq_global_dir_reference = GlobDirRef.equal
-[@@ocaml.deprecated "Use [GlobDirRef.equal]"]
-
exception GlobalizationError of qualid
let error_global_not_found qid =
@@ -516,10 +510,6 @@ let exists_cci sp = ExtRefTab.exists sp !the_ccitab
let exists_dir dir = DirTab.exists dir !the_dirtab
-let exists_section = exists_dir
-
-let exists_module = exists_dir
-
let exists_modtype sp = MPTab.exists sp !the_modtypetab
let exists_universe kn = UnivTab.exists kn !the_univtab
@@ -585,10 +575,3 @@ let global_inductive qid =
| ref ->
user_err ?loc:qid.CAst.loc ~hdr:"global_inductive"
(pr_qualid qid ++ spc () ++ str "is not an inductive type")
-
-(********************************************************************)
-
-(* Deprecated synonyms *)
-
-let extended_locate = locate_extended
-let absolute_reference = global_of_path
diff --git a/library/nametab.mli b/library/nametab.mli
index fccb8fd918..a4f177aad0 100644
--- a/library/nametab.mli
+++ b/library/nametab.mli
@@ -89,13 +89,6 @@ module GlobDirRef : sig
val equal : t -> t -> bool
end
-type global_dir_reference = GlobDirRef.t
-[@@ocaml.deprecated "Use [GlobDirRef.t]"]
-
-val eq_global_dir_reference :
- GlobDirRef.t -> GlobDirRef.t -> bool
-[@@ocaml.deprecated "Use [GlobDirRef.equal]"]
-
exception GlobalizationError of qualid
(** Raises a globalization error *)
@@ -170,10 +163,6 @@ val extended_global_of_path : full_path -> extended_global_reference
val exists_cci : full_path -> bool
val exists_modtype : full_path -> bool
val exists_dir : DirPath.t -> bool
-val exists_section : DirPath.t -> bool (** deprecated synonym of [exists_dir] *)
-
-val exists_module : DirPath.t -> bool (** deprecated synonym of [exists_dir] *)
-
val exists_universe : full_path -> bool
(** {6 These functions locate qualids into full user names } *)
@@ -220,11 +209,6 @@ val shortest_qualid_of_modtype : ?loc:Loc.t -> ModPath.t -> qualid
val shortest_qualid_of_module : ?loc:Loc.t -> ModPath.t -> qualid
val shortest_qualid_of_universe : ?loc:Loc.t -> Univ.Level.UGlobal.t -> qualid
-(** Deprecated synonyms *)
-
-val extended_locate : qualid -> extended_global_reference (*= locate_extended *)
-val absolute_reference : full_path -> GlobRef.t (** = global_of_path *)
-
(** {5 Generic name handling} *)
(** NOT FOR PUBLIC USE YET. Plugin writers, please do not rely on this API. *)
diff --git a/plugins/derive/derive.ml b/plugins/derive/derive.ml
index 4425e41652..4769c2dc53 100644
--- a/plugins/derive/derive.ml
+++ b/plugins/derive/derive.ml
@@ -102,6 +102,7 @@ let start_deriving f suchthat lemma =
let terminator = Proof_global.make_terminator terminator in
let pstate = Proof_global.start_dependent_proof ~ontop:None lemma kind goals terminator in
- fst @@ Proof_global.with_current_proof begin fun _ p ->
- Proof.run_tactic env Proofview.(tclFOCUS 1 2 shelve) p
+ Proof_global.simple_with_current_proof begin fun _ p ->
+ let p,_,() = Proof.run_tactic env Proofview.(tclFOCUS 1 2 shelve) p in
+ p
end pstate
diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml
index 3dd3a430e8..1fca132655 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -132,7 +132,7 @@ let nat = function () -> (coq_init_constant "nat")
let iter_ref () =
try find_reference ["Recdef"] "iter"
with Not_found -> user_err Pp.(str "module Recdef not loaded")
-let iter_rd = function () -> (constr_of_global (delayed_force iter_ref))
+let iter_rd = function () -> (constr_of_monomorphic_global (delayed_force iter_ref))
let eq = function () -> (coq_init_constant "eq")
let le_lt_SS = function () -> (constant ["Recdef"] "le_lt_SS")
let le_lt_n_Sm = function () -> (coq_constant arith_Lt "le_lt_n_Sm")
@@ -145,7 +145,7 @@ let coq_O = function () -> (coq_init_constant "O")
let coq_S = function () -> (coq_init_constant "S")
let lt_n_O = function () -> (coq_constant arith_Nat "nlt_0_r")
let max_ref = function () -> (find_reference ["Recdef"] "max")
-let max_constr = function () -> EConstr.of_constr (constr_of_global (delayed_force max_ref))
+let max_constr = function () -> EConstr.of_constr (constr_of_monomorphic_global (delayed_force max_ref))
let f_S t = mkApp(delayed_force coq_S, [|t|]);;
@@ -1041,13 +1041,13 @@ let compute_terminate_type nb_args func =
let open Term in
let open Constr in
let open CVars in
- let _,a_arrow_b,_ = destLambda(def_of_const (constr_of_global func)) in
+ let _,a_arrow_b,_ = destLambda(def_of_const (constr_of_monomorphic_global func)) in
let rev_args,b = decompose_prod_n nb_args a_arrow_b in
let left =
mkApp(delayed_force iter_rd,
Array.of_list
(lift 5 a_arrow_b:: mkRel 3::
- constr_of_global func::mkRel 1::
+ constr_of_monomorphic_global func::mkRel 1::
List.rev (List.map_i (fun i _ -> mkRel (6+i)) 0 rev_args)
)
)
@@ -1065,7 +1065,7 @@ let compute_terminate_type nb_args func =
delayed_force nat,
(mkProd (make_annot (Name k_id) Sorts.Relevant, delayed_force nat,
mkArrow cond Sorts.Relevant result))))|])in
- let value = mkApp(constr_of_global (Util.delayed_force coq_sig_ref),
+ let value = mkApp(constr_of_monomorphic_global (Util.delayed_force coq_sig_ref),
[|b;
(mkLambda (make_annot (Name v_id) Sorts.Relevant, b, nb_iter))|]) in
compose_prod rev_args value
@@ -1161,7 +1161,7 @@ let whole_start (concl_tac:tactic) nb_args is_mes func input_type relation rec_a
fun g ->
let sigma = project g in
let ids = Termops.ids_of_named_context (pf_hyps g) in
- let func_body = (def_of_const (constr_of_global func)) in
+ let func_body = (def_of_const (constr_of_monomorphic_global func)) in
let func_body = EConstr.of_constr func_body in
let (f_name, _, body1) = destLambda sigma func_body in
let f_id =
@@ -1222,7 +1222,7 @@ let whole_start (concl_tac:tactic) nb_args is_mes func input_type relation rec_a
let get_current_subgoals_types pstate =
let p = Proof_global.give_me_the_proof pstate in
- let sgs,_,_,_,sigma = Proof.proof p in
+ let Proof.{ goals=sgs; sigma; _ } = Proof.data p in
sigma, List.map (Goal.V82.abstract_type sigma) sgs
exception EmptySubgoals
@@ -1253,7 +1253,7 @@ let build_and_l sigma l =
let c,tac,nb = f pl in
mk_and p1 c,
tclTHENS
- (Proofview.V82.of_tactic (apply (EConstr.of_constr (constr_of_global conj_constr))))
+ (Proofview.V82.of_tactic (apply (EConstr.of_constr (constr_of_monomorphic_global conj_constr))))
[tclIDTAC;
tac
],nb+1
@@ -1437,7 +1437,7 @@ let start_equation (f:GlobRef.t) (term_f:GlobRef.t)
(cont_tactic:Id.t list -> tactic) g =
let sigma = project g in
let ids = pf_ids_of_hyps g in
- let terminate_constr = constr_of_global term_f in
+ let terminate_constr = constr_of_monomorphic_global term_f in
let terminate_constr = EConstr.of_constr terminate_constr in
let nargs = nb_prod (project g) (EConstr.of_constr (type_of_const sigma terminate_constr)) in
let x = n_x_id ids nargs in
@@ -1457,7 +1457,7 @@ let com_eqn sign uctx nb_arg eq_name functional_ref f_ref terminate_ref equation
| _ -> anomaly ~label:"terminate_lemma" (Pp.str "not a constant.")
in
let evd = Evd.from_ctx uctx in
- let f_constr = constr_of_global f_ref in
+ let f_constr = constr_of_monomorphic_global f_ref in
let equation_lemma_type = subst1 f_constr equation_lemma_type in
let pstate = Lemmas.start_proof ~ontop:None eq_name (Global, false, Proof Lemma) ~sign evd
(EConstr.of_constr equation_lemma_type) in
@@ -1466,12 +1466,12 @@ let com_eqn sign uctx nb_arg eq_name functional_ref f_ref terminate_ref equation
(fun x ->
prove_eq (fun _ -> tclIDTAC)
{nb_arg=nb_arg;
- f_terminate = EConstr.of_constr (constr_of_global terminate_ref);
+ f_terminate = EConstr.of_constr (constr_of_monomorphic_global terminate_ref);
f_constr = EConstr.of_constr f_constr;
concl_tac = tclIDTAC;
func=functional_ref;
info=(instantiate_lambda Evd.empty
- (EConstr.of_constr (def_of_const (constr_of_global functional_ref)))
+ (EConstr.of_constr (def_of_const (constr_of_monomorphic_global functional_ref)))
(EConstr.of_constr f_constr::List.map mkVar x)
);
is_main_branch = true;
@@ -1570,9 +1570,9 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
if not stop
then
let eq_ref = Nametab.locate (qualid_of_ident equation_id ) in
- let f_ref = destConst (constr_of_global f_ref)
- and functional_ref = destConst (constr_of_global functional_ref)
- and eq_ref = destConst (constr_of_global eq_ref) in
+ let f_ref = destConst (constr_of_monomorphic_global f_ref)
+ and functional_ref = destConst (constr_of_monomorphic_global functional_ref)
+ and eq_ref = destConst (constr_of_monomorphic_global eq_ref) in
generate_induction_principle f_ref tcc_lemma_constr
functional_ref eq_ref rec_arg_num
(EConstr.of_constr rec_arg_type)
diff --git a/plugins/ltac/g_rewrite.mlg b/plugins/ltac/g_rewrite.mlg
index 469551809c..12b12bc7b0 100644
--- a/plugins/ltac/g_rewrite.mlg
+++ b/plugins/ltac/g_rewrite.mlg
@@ -278,7 +278,7 @@ VERNAC COMMAND EXTEND AddSetoid1 CLASSIFIED AS SIDEFF
}
| #[ atts = rewrite_attributes; ] ![ proof ] [ "Add" "Morphism" constr(m) ":" ident(n) ]
(* This command may or may not open a goal *)
- => { VtUnknown, VtNow }
+ => { (if Lib.is_modtype() then VtSideff([n]) else VtStartProof(GuaranteesOpacity, [n])), VtLater }
-> {
add_morphism_infer atts m n
}
diff --git a/plugins/ltac/rewrite.ml b/plugins/ltac/rewrite.ml
index a68efa4713..963b7189f9 100644
--- a/plugins/ltac/rewrite.ml
+++ b/plugins/ltac/rewrite.ml
@@ -1800,7 +1800,7 @@ let anew_instance ~pstate atts binders instance fields =
let program_mode = atts.program in
new_instance ~pstate ~program_mode atts.polymorphic
binders instance (Some (true, CAst.make @@ CRecord (fields)))
- ~global:atts.global ~generalize:false ~refine:false Hints.empty_hint_info
+ ~global:atts.global ~generalize:false Hints.empty_hint_info
let declare_instance_refl ~pstate atts binders a aeq n lemma =
let instance = declare_instance a aeq (add_suffix n "_Reflexive") "Coq.Classes.RelationClasses.Reflexive"
diff --git a/plugins/micromega/coq_micromega.ml b/plugins/micromega/coq_micromega.ml
index ef6af16036..de9dec0f74 100644
--- a/plugins/micromega/coq_micromega.ml
+++ b/plugins/micromega/coq_micromega.ml
@@ -207,7 +207,7 @@ struct
* ZMicromega.v
*)
- let gen_constant_in_modules s m n = EConstr.of_constr (UnivGen.constr_of_global @@ Coqlib.gen_reference_in_modules s m n)
+ let gen_constant_in_modules s m n = EConstr.of_constr (UnivGen.constr_of_monomorphic_global @@ Coqlib.gen_reference_in_modules s m n)
let init_constant = gen_constant_in_modules "ZMicromega" Coqlib.init_modules
[@@@ocaml.warning "+3"]
diff --git a/plugins/ssr/ssrequality.ml b/plugins/ssr/ssrequality.ml
index e349031952..93c0d5c236 100644
--- a/plugins/ssr/ssrequality.ml
+++ b/plugins/ssr/ssrequality.ml
@@ -446,7 +446,7 @@ let lz_setoid_relation =
| Some (env', srel) when env' == env -> srel
| _ ->
let srel =
- try Some (UnivGen.constr_of_global @@
+ try Some (UnivGen.constr_of_monomorphic_global @@
Coqlib.find_reference "Class_setoid" ("Coq"::sdir) "RewriteRelation" [@ocaml.warning "-3"])
with _ -> None in
last_srel := Some (env, srel); srel
@@ -491,7 +491,7 @@ let rwprocess_rule dir rule gl =
| _ ->
let sigma, pi2 = Evd.fresh_global env sigma coq_prod.Coqlib.proj2 in
EConstr.mkApp (pi2, ra), sigma in
- if EConstr.eq_constr sigma a.(0) (EConstr.of_constr (UnivGen.constr_of_global @@ Coqlib.(lib_ref "core.True.type"))) then
+ if EConstr.eq_constr sigma a.(0) (EConstr.of_constr (UnivGen.constr_of_monomorphic_global @@ Coqlib.(lib_ref "core.True.type"))) then
let s, sigma = sr sigma 2 in
loop (converse_dir d) sigma s a.(1) rs 0
else
diff --git a/plugins/ssr/ssrview.ml b/plugins/ssr/ssrview.ml
index 075ebf006a..0a5c85f4ab 100644
--- a/plugins/ssr/ssrview.ml
+++ b/plugins/ssr/ssrview.ml
@@ -290,7 +290,7 @@ let finalize_view s0 ?(simple_types=true) p =
Goal.enter_one ~__LOC__ begin fun g ->
let env = Goal.env g in
let sigma = Goal.sigma g in
- let evars_of_p = Evd.evars_of_term (EConstr.to_constr ~abort_on_undefined_evars:false sigma p) in
+ let evars_of_p = Evd.evars_of_term sigma p in
let filter x _ = Evar.Set.mem x evars_of_p in
let sigma = Typeclasses.resolve_typeclasses ~fail:false ~filter env sigma in
let p = Reductionops.nf_evar sigma p in
@@ -307,7 +307,7 @@ Goal.enter_one ~__LOC__ begin fun g ->
let und0 = (* Unassigned evars in the initial goal *)
let sigma0 = Tacmach.project s0 in
let g0info = Evd.find sigma0 (Tacmach.sig_it s0) in
- let g0 = Evd.evars_of_filtered_evar_info g0info in
+ let g0 = Evd.evars_of_filtered_evar_info sigma0 g0info in
List.filter (fun k -> Evar.Set.mem k g0)
(List.map fst (Evar.Map.bindings (Evd.undefined_map sigma0))) in
let rigid = rigid_of und0 in
diff --git a/plugins/ssrmatching/ssrmatching.ml b/plugins/ssrmatching/ssrmatching.ml
index 4e0866a0c5..adbcfb8f3b 100644
--- a/plugins/ssrmatching/ssrmatching.ml
+++ b/plugins/ssrmatching/ssrmatching.ml
@@ -529,8 +529,8 @@ exception FoundUnif of (evar_map * UState.t * tpattern)
(* Note: we don't update env as we descend into the term, as the primitive *)
(* unification procedure always rejects subterms with bound variables. *)
-let dont_impact_evars_in cl =
- let evs_in_cl = Evd.evars_of_term cl in
+let dont_impact_evars_in sigma0 cl =
+ let evs_in_cl = Evd.evars_of_term sigma0 cl in
fun sigma -> Evar.Set.for_all (fun k ->
try let _ = Evd.find_undefined sigma k in true
with Not_found -> false) evs_in_cl
@@ -544,7 +544,7 @@ let dont_impact_evars_in cl =
(* - w_unify expands let-in (zeta conversion) eagerly, whereas we want to *)
(* match a head let rigidly. *)
let match_upats_FO upats env sigma0 ise orig_c =
- let dont_impact_evars = dont_impact_evars_in orig_c in
+ let dont_impact_evars = dont_impact_evars_in sigma0 (EConstr.of_constr orig_c) in
let rec loop c =
let f, a = splay_app ise c in let i0 = ref (-1) in
let fpats =
@@ -586,7 +586,7 @@ let match_upats_FO upats env sigma0 ise orig_c =
let match_upats_HO ~on_instance upats env sigma0 ise c =
- let dont_impact_evars = dont_impact_evars_in c in
+ let dont_impact_evars = dont_impact_evars_in sigma0 (EConstr.of_constr c) in
let it_did_match = ref false in
let failed_because_of_TC = ref false in
let rec aux upats env sigma0 ise c =
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index 062e3ca8b2..82726eccf0 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -708,9 +708,6 @@ type binder_kind = BProd | BLambda | BLetIn
(**********************************************************************)
(* Main detyping function *)
-let detype_anonymous = ref (fun ?loc n -> anomaly ~label:"detype" (Pp.str "index to an anonymous variable."))
-let set_detype_anonymous f = detype_anonymous := f
-
let detype_level sigma l =
let l = hack_qualid_of_univ_level sigma l in
GType (UNamed l)
@@ -732,11 +729,13 @@ and detype_r d flags avoid env sigma t =
match EConstr.kind sigma (collapse_appl sigma t) with
| Rel n ->
(try match lookup_name_of_rel n (fst env) with
- | Name id -> GVar id
- | Anonymous -> GVar (!detype_anonymous n)
+ | Name id -> GVar id
+ | Anonymous ->
+ let s = "_ANONYMOUS_REL_"^(string_of_int n) in
+ GVar (Id.of_string s)
with Not_found ->
- let s = "_UNBOUND_REL_"^(string_of_int n)
- in GVar (Id.of_string s))
+ let s = "_UNBOUND_REL_"^(string_of_int n)
+ in GVar (Id.of_string s))
| Meta n ->
(* Meta in constr are not user-parsable and are mapped to Evar *)
if n = Constr_matching.special_meta then
diff --git a/pretyping/detyping.mli b/pretyping/detyping.mli
index 1a8e97efb8..00b0578a52 100644
--- a/pretyping/detyping.mli
+++ b/pretyping/detyping.mli
@@ -68,9 +68,6 @@ val detype_closed_glob : ?lax:bool -> bool -> Id.Set.t -> env -> evar_map -> clo
val lookup_name_as_displayed : env -> evar_map -> constr -> Id.t -> int option
val lookup_index_as_renamed : env -> evar_map -> constr -> int -> int option
-(* XXX: This is a hack and should go away *)
-val set_detype_anonymous : (?loc:Loc.t -> int -> Id.t) -> unit
-
val force_wildcard : unit -> bool
val synthetize_type : unit -> bool
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index 99013a19c9..6b149a8b41 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -1769,28 +1769,3 @@ let unify ?flags ?(with_ho=true) env evd cv_pb ty1 ty2 =
solve_unif_constraints_with_heuristics ~flags ~with_ho env evd
| UnifFailure (evd, reason) ->
raise (PretypeError (env, evd, CannotUnify (ty1, ty2, Some reason)))
-
-(* deprecated *)
-let the_conv_x env ?(ts=default_transparent_state env) t1 t2 evd =
- let flags = default_flags_of ts in
- match evar_conv_x flags env evd CONV t1 t2 with
- | Success evd' -> evd'
- | UnifFailure (evd',e) -> raise (UnableToUnify (evd',e))
-
-let the_conv_x_leq env ?(ts=default_transparent_state env) t1 t2 evd =
- let flags = default_flags_of ts in
- match evar_conv_x flags env evd CUMUL t1 t2 with
- | Success evd' -> evd'
- | UnifFailure (evd',e) -> raise (UnableToUnify (evd',e))
-
-let make_opt = function
- | Success evd -> Some evd
- | UnifFailure _ -> None
-
-let conv env ?(ts=default_transparent_state env) evd t1 t2 =
- let flags = default_flags_of ts in
- make_opt(evar_conv_x flags env evd CONV t1 t2)
-
-let cumul env ?(ts=default_transparent_state env) evd t1 t2 =
- let flags = default_flags_of ts in
- make_opt(evar_conv_x flags env evd CUMUL t1 t2)
diff --git a/pretyping/evarconv.mli b/pretyping/evarconv.mli
index bf83f5e88f..eae961714d 100644
--- a/pretyping/evarconv.mli
+++ b/pretyping/evarconv.mli
@@ -46,19 +46,6 @@ exception UnableToUnify of evar_map * Pretype_errors.unification_error
val unify_delay : ?flags:unify_flags -> env -> evar_map -> constr -> constr -> evar_map
val unify_leq_delay : ?flags:unify_flags -> env -> evar_map -> constr -> constr -> evar_map
-(** returns exception UnableToUnify with best known evar_map if not unifiable *)
-val the_conv_x : env -> ?ts:TransparentState.t -> constr -> constr -> evar_map -> evar_map
-[@@ocaml.deprecated "Use Evarconv.unify_delay instead"]
-val the_conv_x_leq : env -> ?ts:TransparentState.t -> constr -> constr -> evar_map -> evar_map
-[@@ocaml.deprecated "Use Evarconv.unify_leq_delay instead"]
-(** The same function resolving evars by side-effect and
- catching the exception *)
-
-val conv : env -> ?ts:TransparentState.t -> evar_map -> constr -> constr -> evar_map option
-[@@ocaml.deprecated "Use Evarconv.unify_delay instead"]
-val cumul : env -> ?ts:TransparentState.t -> evar_map -> constr -> constr -> evar_map option
-[@@ocaml.deprecated "Use Evarconv.unify_leq_delay instead"]
-
(** This function also calls [solve_unif_constraints_with_heuristics] to resolve any remaining
constraints. In case of success the two terms are unified without condition.
diff --git a/pretyping/recordops.ml b/pretyping/recordops.ml
index d69824a256..a23c58c062 100644
--- a/pretyping/recordops.ml
+++ b/pretyping/recordops.ml
@@ -27,16 +27,27 @@ open Reductionops
(*s A structure S is a non recursive inductive type with a single
constructor (the name of which defaults to Build_S) *)
-(* Table des structures: le nom de la structure (un [inductive]) donne
- le nom du constructeur, le nombre de paramètres et pour chaque
- argument réel du constructeur, le nom de la projection
- correspondante, si valide, et un booléen disant si c'est une vraie
- projection ou bien une fonction constante (associée à un LetIn) *)
+(* Table of structures.
+ It maps to each structure name (of type [inductive]):
+ - the name of its constructor;
+ - the number of parameters;
+ - for each true argument, some data about the corresponding projection:
+ * its name (may be anonymous);
+ * whether it is a true projection (as opposed to a constant function, LetIn);
+ * whether it should be used as a canonical hint;
+ * the constant realizing this projection (if any).
+*)
+
+type proj_kind = {
+ pk_name: Name.t;
+ pk_true_proj: bool;
+ pk_canonical: bool;
+}
type struc_typ = {
s_CONST : constructor;
s_EXPECTEDPARAM : int;
- s_PROJKIND : (Name.t * bool) list;
+ s_PROJKIND : proj_kind list;
s_PROJ : Constant.t option list }
let structure_table =
@@ -47,7 +58,7 @@ let projection_table =
(* TODO: could be unify struc_typ and struc_tuple ? *)
type struc_tuple =
- constructor * (Name.t * bool) list * Constant.t option list
+ constructor * proj_kind list * Constant.t option list
let register_structure env (id,kl,projs) =
let open Declarations in
@@ -161,7 +172,7 @@ let canonical_projections () =
!object_table []
let keep_true_projections projs kinds =
- let filter (p, (_, b)) = if b then Some p else None in
+ let filter (p, { pk_true_proj ; pk_canonical }) = if pk_true_proj then Some (p, pk_canonical) else None in
List.map_filter filter (List.combine projs kinds)
let rec cs_pattern_of_constr env t =
@@ -206,17 +217,20 @@ let compute_canonical_projections env ~warn (con,ind) =
let o_NPARAMS = List.length o_TPARAMS in
let lpj = keep_true_projections lpj kl in
let nenv = Termops.push_rels_assum sign env in
- List.fold_left2 (fun acc spopt t ->
- Option.cata (fun proji_sp ->
- match cs_pattern_of_constr nenv t with
- | patt, o_INJ, o_TCOMPS ->
- ((ConstRef proji_sp, (patt, t)),
- { o_DEF ; o_CTX ; o_INJ ; o_TABS ; o_TPARAMS ; o_NPARAMS ; o_TCOMPS })
- :: acc
- | exception Not_found ->
- if warn then warn_projection_no_head_constant (sign, env, t, con, proji_sp);
- acc
- ) acc spopt
+ List.fold_left2 (fun acc (spopt, canonical) t ->
+ if canonical
+ then
+ Option.cata (fun proji_sp ->
+ match cs_pattern_of_constr nenv t with
+ | patt, o_INJ, o_TCOMPS ->
+ ((ConstRef proji_sp, (patt, t)),
+ { o_DEF ; o_CTX ; o_INJ ; o_TABS ; o_TPARAMS ; o_NPARAMS ; o_TCOMPS })
+ :: acc
+ | exception Not_found ->
+ if warn then warn_projection_no_head_constant (sign, env, t, con, proji_sp);
+ acc
+ ) acc spopt
+ else acc
) [] lpj projs
let pr_cs_pattern = function
@@ -288,7 +302,7 @@ let check_and_decompose_canonical_structure env sigma ref =
with Not_found ->
error_not_structure ref
(str "Could not find the record or structure " ++ Termops.Internal.print_constr_env env sigma (EConstr.mkInd indsp)) in
- let ntrue_projs = List.count snd s.s_PROJKIND in
+ let ntrue_projs = List.count (fun { pk_true_proj } -> pk_true_proj) s.s_PROJKIND in
if s.s_EXPECTEDPARAM + ntrue_projs > Array.length args then
error_not_structure ref (str "Got too few arguments to the record or structure constructor.");
(sp,indsp)
diff --git a/pretyping/recordops.mli b/pretyping/recordops.mli
index f0594d513a..25b6cd0751 100644
--- a/pretyping/recordops.mli
+++ b/pretyping/recordops.mli
@@ -17,14 +17,20 @@ open Constr
(** A structure S is a non recursive inductive type with a single
constructor (the name of which defaults to Build_S) *)
+type proj_kind = {
+ pk_name: Name.t;
+ pk_true_proj: bool;
+ pk_canonical: bool;
+}
+
type struc_typ = {
s_CONST : constructor;
s_EXPECTEDPARAM : int;
- s_PROJKIND : (Name.t * bool) list;
+ s_PROJKIND : proj_kind list;
s_PROJ : Constant.t option list }
type struc_tuple =
- constructor * (Name.t * bool) list * Constant.t option list
+ constructor * proj_kind list * Constant.t option list
val register_structure : Environ.env -> struc_tuple -> unit
val subst_structure : Mod_subst.substitution -> struc_tuple -> struc_tuple
diff --git a/printing/printmod.ml b/printing/printmod.ml
index f4986652b3..bd97104f60 100644
--- a/printing/printmod.ml
+++ b/printing/printmod.ml
@@ -63,7 +63,7 @@ let keyword s = tag_keyword (str s)
let get_new_id locals id =
let rec get_id l id =
let dir = DirPath.make [id] in
- if not (Nametab.exists_module dir) then
+ if not (Nametab.exists_dir dir) then
id
else
get_id (Id.Set.add id l) (Namegen.next_ident_away id l)
diff --git a/proofs/pfedit.ml b/proofs/pfedit.ml
index 4f36354f79..52e15f466f 100644
--- a/proofs/pfedit.ml
+++ b/proofs/pfedit.ml
@@ -98,7 +98,7 @@ let solve ?with_end_tac gi info_lvl tac pr =
else tac
in
let env = Global.env () in
- let (p,(status,info)) = Proof.run_tactic env tac pr in
+ let (p,(status,info),()) = Proof.run_tactic env tac pr in
let env = Global.env () in
let sigma = Evd.from_env env in
let () =
@@ -161,7 +161,7 @@ let refine_by_tactic ~name ~poly env sigma ty tac =
let prev_future_goals = save_future_goals sigma in
(* Start a proof *)
let prf = Proof.start ~name ~poly sigma [env, ty] in
- let (prf, _) =
+ let (prf, _, ()) =
try Proof.run_tactic env tac prf
with Logic_monad.TacticFailure e as src ->
(* Catch the inner error of the monad tactic *)
diff --git a/proofs/proof.ml b/proofs/proof.ml
index 978b1f6f78..09e4e898fe 100644
--- a/proofs/proof.ml
+++ b/proofs/proof.ml
@@ -126,9 +126,6 @@ type t =
(** Locality, polymorphism, and "kind" [Coercion, Definition, etc...] *)
}
-let initial_goals pf = Proofview.initial_goals pf.entry
-let initial_euctx pf = pf.initial_euctx
-
(*** General proof functions ***)
let proof p =
@@ -147,33 +144,6 @@ let proof p =
let given_up = p.given_up in
(goals,stack,shelf,given_up,sigma)
-type 'a pre_goals = {
- fg_goals : 'a list;
- (** List of the focussed goals *)
- bg_goals : ('a list * 'a list) list;
- (** Zipper representing the unfocussed background goals *)
- shelved_goals : 'a list;
- (** List of the goals on the shelf. *)
- given_up_goals : 'a list;
- (** List of the goals that have been given up *)
-}
-
-let map_structured_proof pfts process_goal: 'a pre_goals =
- let (goals, zipper, shelf, given_up, sigma) = proof pfts in
- let fg = List.map (process_goal sigma) goals in
- let map_zip (lg, rg) =
- let lg = List.map (process_goal sigma) lg in
- let rg = List.map (process_goal sigma) rg in
- (lg, rg)
- in
- let bg = List.map map_zip zipper in
- let shelf = List.map (process_goal sigma) shelf in
- let given_up = List.map (process_goal sigma) given_up in
- { fg_goals = fg;
- bg_goals = bg;
- shelved_goals = shelf;
- given_up_goals = given_up; }
-
let rec unroll_focus pv = function
| (_,_,ctx)::stk -> unroll_focus (Proofview.unfocus ctx pv) stk
| [] -> pv
@@ -402,7 +372,7 @@ let run_tactic env tac pr =
let sp = pr.proofview in
let undef sigma l = List.filter (fun g -> Evd.is_undefined sigma g) l in
let tac =
- tac >>= fun () ->
+ tac >>= fun result ->
Proofview.tclEVARMAP >>= fun sigma ->
(* Already solved goals are not to be counted as shelved. Nor are
they to be marked as unresolvable. *)
@@ -413,10 +383,10 @@ let run_tactic env tac pr =
CErrors.anomaly Pp.(str "Evars generated outside of proof engine (e.g. V82, clear, ...) are not supposed to be explicitly given up.");
let sigma = Proofview.Unsafe.mark_as_goals sigma retrieved in
Proofview.Unsafe.tclEVARS sigma >>= fun () ->
- Proofview.tclUNIT retrieved
+ Proofview.tclUNIT (result,retrieved)
in
let { name; poly } = pr in
- let (retrieved,proofview,(status,to_shelve,give_up),info_trace) =
+ let ((result,retrieved),proofview,(status,to_shelve,give_up),info_trace) =
Proofview.apply ~name ~poly env tac sp
in
let sigma = Proofview.return proofview in
@@ -430,7 +400,7 @@ let run_tactic env tac pr =
in
let given_up = pr.given_up@give_up in
let proofview = Proofview.Unsafe.reset_future_goals proofview in
- { pr with proofview ; shelf ; given_up },(status,info_trace)
+ { pr with proofview ; shelf ; given_up },(status,info_trace),result
(*** Commands ***)
@@ -441,22 +411,6 @@ let in_proof p k = k (Proofview.return p.proofview)
let unshelve p =
{ p with proofview = Proofview.unshelve (p.shelf) (p.proofview) ; shelf = [] }
-let pr_proof p =
- let p = map_structured_proof p (fun _sigma g -> g) in
- Pp.(
- let pr_goal_list = prlist_with_sep spc Goal.pr_goal in
- let rec aux acc = function
- | [] -> acc
- | (before,after)::stack ->
- aux (pr_goal_list before ++ spc () ++ str "{" ++ acc ++ str "}" ++ spc () ++
- pr_goal_list after) stack in
- str "[" ++ str "focus structure: " ++
- aux (pr_goal_list p.fg_goals) p.bg_goals ++ str ";" ++ spc () ++
- str "shelved: " ++ pr_goal_list p.shelved_goals ++ str ";" ++ spc () ++
- str "given up: " ++ pr_goal_list p.given_up_goals ++
- str "]"
- )
-
(*** Compatibility layer with <=v8.2 ***)
module V82 = struct
@@ -471,7 +425,7 @@ module V82 = struct
{ Evd.it=List.hd gls ; sigma=sigma; }
let top_evars p =
- Proofview.V82.top_evars p.entry
+ Proofview.V82.top_evars p.entry p.proofview
let grab_evars p =
if not (is_done p) then
@@ -554,3 +508,19 @@ let data { proofview; focus_stack; entry; shelf; given_up; initial_euctx; name;
let stack =
map_minus_one (fun (_,_,c) -> Proofview.focus_context c) focus_stack in
{ sigma; goals; entry; stack; shelf; given_up; initial_euctx; name; poly }
+
+let pr_proof p =
+ let { goals=fg_goals; stack=bg_goals; shelf; given_up; _ } = data p in
+ Pp.(
+ let pr_goal_list = prlist_with_sep spc Goal.pr_goal in
+ let rec aux acc = function
+ | [] -> acc
+ | (before,after)::stack ->
+ aux (pr_goal_list before ++ spc () ++ str "{" ++ acc ++ str "}" ++ spc () ++
+ pr_goal_list after) stack in
+ str "[" ++ str "focus structure: " ++
+ aux (pr_goal_list fg_goals) bg_goals ++ str ";" ++ spc () ++
+ str "shelved: " ++ pr_goal_list shelf ++ str ";" ++ spc () ++
+ str "given up: " ++ pr_goal_list given_up ++
+ str "]"
+ )
diff --git a/proofs/proof.mli b/proofs/proof.mli
index defef57a8d..248b9d921e 100644
--- a/proofs/proof.mli
+++ b/proofs/proof.mli
@@ -34,30 +34,6 @@
(* Type of a proof. *)
type t
-(* Returns a stylised view of a proof for use by, for instance,
- ide-s. *)
-(* spiwack: the type of [proof] will change as we push more refined
- functions to ide-s. This would be better than spawning a new nearly
- identical function everytime. Hence the generic name. *)
-(* In this version: returns the focused goals, a representation of the
- focus stack (the goals at each level), a representation of the
- shelf (the list of goals on the shelf), a representation of the
- given up goals (the list of the given up goals) and the underlying
- evar_map *)
-val proof : t ->
- Goal.goal list
- * (Goal.goal list * Goal.goal list) list
- * Goal.goal list
- * Goal.goal list
- * Evd.evar_map
-[@@ocaml.deprecated "use [Proof.data]"]
-
-val initial_goals : t -> (EConstr.constr * EConstr.types) list
-[@@ocaml.deprecated "use [Proof.data]"]
-
-val initial_euctx : t -> UState.t
-[@@ocaml.deprecated "use [Proof.data]"]
-
type data =
{ sigma : Evd.evar_map
(** A representation of the evar_map [EJGA wouldn't it better to just return the proofview?] *)
@@ -81,29 +57,6 @@ type data =
val data : t -> data
-(* Generic records structured like the return type of proof *)
-type 'a pre_goals = {
- fg_goals : 'a list;
- [@ocaml.deprecated "use [Proof.data]"]
- (** List of the focussed goals *)
- bg_goals : ('a list * 'a list) list;
- [@ocaml.deprecated "use [Proof.data]"]
- (** Zipper representing the unfocussed background goals *)
- shelved_goals : 'a list;
- [@ocaml.deprecated "use [Proof.data]"]
- (** List of the goals on the shelf. *)
- given_up_goals : 'a list;
- [@ocaml.deprecated "use [Proof.data]"]
- (** List of the goals that have been given up *)
-}
-[@@ocaml.deprecated "use [Proof.data]"]
-
-(* needed in OCaml 4.05.0, not needed in newer ones *)
-[@@@ocaml.warning "-3"]
-val map_structured_proof : t -> (Evd.evar_map -> Goal.goal -> 'a) -> ('a pre_goals) [@ocaml.warning "-3"]
-[@@ocaml.deprecated "use [Proof.data]"]
-[@@@ocaml.warning "+3"]
-
(*** General proof functions ***)
val start
: name:Names.Id.t
@@ -219,7 +172,7 @@ val no_focused_goal : t -> bool
used. In which case it is [false]. *)
val run_tactic
: Environ.env
- -> unit Proofview.tactic -> t -> t * (bool*Proofview_monad.Info.tree)
+ -> 'a Proofview.tactic -> t -> t * (bool*Proofview_monad.Info.tree) * 'a
val maximal_unfocus : 'a focus_kind -> t -> t
diff --git a/proofs/proof_global.ml b/proofs/proof_global.ml
index 08b98d702a..40ae4acc88 100644
--- a/proofs/proof_global.ml
+++ b/proofs/proof_global.ml
@@ -345,6 +345,6 @@ let update_global_env (pf : t) =
with_current_proof (fun _ p ->
Proof.in_proof p (fun sigma ->
let tac = Proofview.Unsafe.tclEVARS (Evd.update_sigma_env sigma (Global.env ())) in
- let (p,(status,info)) = Proof.run_tactic (Global.env ()) tac p in
+ let (p,(status,info),()) = Proof.run_tactic (Global.env ()) tac p in
(p, ()))) pf
in res
diff --git a/proofs/refine.ml b/proofs/refine.ml
index 06e6b89df1..4a9404aa96 100644
--- a/proofs/refine.ml
+++ b/proofs/refine.ml
@@ -44,17 +44,6 @@ let typecheck_evar ev env sigma =
let sigma, _ = Typing.sort_of env sigma (Evd.evar_concl info) in
sigma
-(* Get the side-effect's constant declarations to update the monad's
- * environmnent *)
-let add_if_undefined env eff =
- let open Entries in
- try ignore(Environ.lookup_constant eff.seff_constant env); env
- with Not_found -> Environ.add_constant eff.seff_constant eff.seff_body env
-
-(* Add the side effects to the monad's environment, if not already done. *)
-let add_side_effects env eff =
- List.fold_left add_if_undefined env eff
-
let generic_refine ~typecheck f gl =
let sigma = Proofview.Goal.sigma gl in
let env = Proofview.Goal.env gl in
@@ -71,8 +60,7 @@ let generic_refine ~typecheck f gl =
let evs = Evd.save_future_goals sigma in
(* Redo the effects in sigma in the monad's env *)
let privates_csts = Evd.eval_side_effects sigma in
- let sideff = Safe_typing.side_effects_of_private_constants privates_csts in
- let env = add_side_effects env sideff in
+ let env = Safe_typing.push_private_constants env privates_csts in
(* Check that the introduced evars are well-typed *)
let fold accu ev = typecheck_evar ev env accu in
let sigma = if typecheck then Evd.fold_future_goals fold sigma evs else sigma in
diff --git a/proofs/tacmach.ml b/proofs/tacmach.ml
index 7b3d9e534b..93031c2202 100644
--- a/proofs/tacmach.ml
+++ b/proofs/tacmach.ml
@@ -104,10 +104,6 @@ let db_pr_goal sigma g =
let pr_gls gls =
hov 0 (pr_evar_map (Some 2) (pf_env gls) (sig_sig gls) ++ fnl () ++ db_pr_goal (project gls) (sig_it gls))
-let pr_glls glls =
- hov 0 (pr_evar_map (Some 2) (Global.env()) (sig_sig glls) ++ fnl () ++
- prlist_with_sep fnl (db_pr_goal (project glls)) (sig_it glls))
-
(* Variants of [Tacmach] functions built with the new proof engine *)
module New = struct
diff --git a/proofs/tacmach.mli b/proofs/tacmach.mli
index 218011c316..23e1e6f566 100644
--- a/proofs/tacmach.mli
+++ b/proofs/tacmach.mli
@@ -68,8 +68,6 @@ val pf_conv_x_leq : Goal.goal sigma -> constr -> constr -> bool
(** {6 Pretty-printing functions (debug only). } *)
val pr_gls : Goal.goal sigma -> Pp.t
-val pr_glls : Goal.goal list sigma -> Pp.t
-[@@ocaml.deprecated "Please move to \"new\" proof engine"]
(** Variants of [Tacmach] functions built with the new proof engine *)
module New : sig
diff --git a/stm/proofBlockDelimiter.ml b/stm/proofBlockDelimiter.ml
index 2b32838964..04f10e7399 100644
--- a/stm/proofBlockDelimiter.ml
+++ b/stm/proofBlockDelimiter.ml
@@ -41,8 +41,8 @@ let simple_goal sigma g gs =
let open Evd in
let open Evarutil in
let evi = Evd.find sigma g in
- Set.is_empty (evars_of_term (EConstr.Unsafe.to_constr evi.evar_concl)) &&
- Set.is_empty (evars_of_filtered_evar_info (nf_evar_info sigma evi)) &&
+ Set.is_empty (evars_of_term sigma evi.evar_concl) &&
+ Set.is_empty (evars_of_filtered_evar_info sigma (nf_evar_info sigma evi)) &&
not (List.exists (Proofview.depends_on sigma g) gs)
let is_focused_goal_simple ~doc id =
diff --git a/stm/stm.ml b/stm/stm.ml
index 3eb6d03529..6f7cefb582 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -364,7 +364,6 @@ module VCS : sig
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
@@ -572,6 +571,7 @@ end = struct (* {{{ *)
(match Vernacprop.under_control x with
| VernacDefinition (_,({CAst.v=Name i},_),_) -> Id.to_string i
| VernacStartTheoremProof (_,[({CAst.v=i},_),_]) -> Id.to_string i
+ | VernacInstance (_,(({CAst.v=Name i},_),_,_),_,_) -> Id.to_string i
| _ -> "branch")
let edit_branch = Branch.make "edit"
let branch ?root ?pos name kind = vcs := branch !vcs ?root ?pos name kind
@@ -611,7 +611,6 @@ end = struct (* {{{ *)
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
@@ -2085,8 +2084,8 @@ end = struct (* {{{ *)
let st = Vernacstate.freeze_interp_state ~marshallable:false in
stm_fail ~st fail (fun () ->
(if time then System.with_time ~batch ~header:(Pp.mt ()) else (fun x -> x)) (fun () ->
- ignore(TaskQueue.with_n_workers nworkers (fun queue ->
- PG_compat.with_current_proof (fun _ p ->
+ TaskQueue.with_n_workers nworkers (fun queue ->
+ PG_compat.simple_with_current_proof (fun _ p ->
let Proof.{goals} = Proof.data p in
let open TacTask in
let res = CList.map_i (fun i g ->
@@ -2131,7 +2130,8 @@ end = struct (* {{{ *)
if solve then Tacticals.New.tclSOLVE [] else tclUNIT ()
end)
in
- Proof.run_tactic (Global.env()) assign_tac p)))) ())
+ let p,_,() = Proof.run_tactic (Global.env()) assign_tac p in
+ p))) ())
end (* }}} *)
@@ -3049,53 +3049,6 @@ let process_transaction ~doc ?(newtip=Stateid.fresh ())
VCS.set_parsing_state id parsing_state) new_ids;
`Ok
- (* Unknown: we execute it, check for open goals and propagate sideeff *)
- | VtUnknown, VtNow ->
- let in_proof = not (VCS.Branch.equal head VCS.Branch.master) in
- if not (get_allow_nested_proofs ()) && in_proof then
- "Commands which may open proofs are not allowed in a proof unless you turn option Nested Proofs Allowed on."
- |> Pp.str
- |> (fun s -> (UserError (None, s), Exninfo.null))
- |> State.exn_on ~valid:Stateid.dummy newtip
- |> Exninfo.iraise
- else
- 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 () =
- VCS.checkout VCS.Branch.master;
- let mid = VCS.get_branch_pos VCS.Branch.master in
- let _st' : unit = Reach.known_state ~doc ~cache:(VCS.is_interactive ()) mid in
- let st = Vernacstate.freeze_interp_state ~marshallable:false in
- ignore(stm_vernac_interp id st x);
- (* Vernac x may or may not start a proof *)
- if not in_proof && PG_compat.there_are_pending_proofs () then
- begin
- let bname = VCS.mk_branch_name x in
- let opacity_of_produced_term = function
- (* This AST is ambiguous, hence we check it dynamically *)
- | VernacInstance (_,_ , None, _) -> GuaranteesOpacity
- | _ -> Doesn'tGuaranteeOpacity in
- VCS.commit id (Fork (x,bname,opacity_of_produced_term (Vernacprop.under_control x.expr),[]));
- 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);
- | `Master -> VCS.commit id (mkTransCmd x [] in_proof `MainQueue);
- | `Proof _ ->
- VCS.commit id (mkTransCmd x [] in_proof `MainQueue);
- (* We hope it can be replayed, but we can't really know *)
- ignore(VCS.propagate_sideff ~action:(ReplayCommand x));
- end;
- VCS.checkout_shallowest_proof_branch ();
- end in
- State.define ~doc ~safe_id:head_id ~cache:true step id;
- Backtrack.record (); `Ok
-
- | 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
@@ -3105,7 +3058,6 @@ let process_transaction ~doc ?(newtip=Stateid.fresh ())
| 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 ")"])
diff --git a/stm/vernac_classifier.ml b/stm/vernac_classifier.ml
index 4a4c5c94e9..7cecd801e4 100644
--- a/stm/vernac_classifier.ml
+++ b/stm/vernac_classifier.ml
@@ -21,7 +21,6 @@ let string_of_parallel = function
| `No -> ""
let string_of_vernac_type = function
- | VtUnknown -> "Unknown"
| VtStartProof _ -> "StartProof"
| VtSideff _ -> "Sideff"
| VtQed (VtKeep VtKeepAxiom) -> "Qed(admitted)"
@@ -61,7 +60,7 @@ let options_affecting_stm_scheduling =
]
let classify_vernac e =
- let static_classifier ~poly e = match e with
+ let static_classifier ~atts e = match e with
(* Univ poly compatibility: we run it now, so that we can just
* look at Flags in stm.ml. Would be nicer to have the stm
* look at the entire dag to detect this option. *)
@@ -97,15 +96,18 @@ let classify_vernac e =
VtStartProof(Doesn'tGuaranteeOpacity, idents_of_name i), VtLater
| VernacDefinition (_,({v=i},_),ProveBody _) ->
- let guarantee = if poly then Doesn'tGuaranteeOpacity else GuaranteesOpacity in
- VtStartProof(guarantee, idents_of_name i), VtLater
+ let polymorphic = Attributes.(parse_drop_extra polymorphic atts) in
+ let guarantee = if polymorphic then Doesn'tGuaranteeOpacity else GuaranteesOpacity in
+ 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 (guarantee,ids), VtLater
+ let polymorphic = Attributes.(parse_drop_extra polymorphic atts) in
+ let ids = List.map (fun (({v=i}, _), _) -> i) l in
+ let guarantee = if polymorphic then Doesn'tGuaranteeOpacity else GuaranteesOpacity in
+ VtStartProof (guarantee,ids), VtLater
| VernacFixpoint (discharge,l) ->
+ let polymorphic = Attributes.(parse_drop_extra polymorphic atts) in
let guarantee =
- if discharge = Decl_kinds.DoDischarge || poly then Doesn'tGuaranteeOpacity
+ if discharge = Decl_kinds.DoDischarge || polymorphic then Doesn'tGuaranteeOpacity
else GuaranteesOpacity
in
let ids, open_proof =
@@ -115,8 +117,9 @@ let classify_vernac e =
then VtStartProof (guarantee,ids), VtLater
else VtSideff ids, VtLater
| VernacCoFixpoint (discharge,l) ->
+ let polymorphic = Attributes.(parse_drop_extra polymorphic atts) in
let guarantee =
- if discharge = Decl_kinds.DoDischarge || poly then Doesn'tGuaranteeOpacity
+ if discharge = Decl_kinds.DoDischarge || polymorphic then Doesn'tGuaranteeOpacity
else GuaranteesOpacity
in
let ids, open_proof =
@@ -185,8 +188,12 @@ let classify_vernac e =
| VernacDeclareMLModule _
| VernacContext _ (* TASSI: unsure *) -> VtSideff [], VtNow
| VernacProofMode pm -> VtProofMode pm, VtNow
- (* These are ambiguous *)
- | VernacInstance _ -> VtUnknown, VtNow
+ | VernacInstance (_,((name,_),_,_),None,_) when not (Attributes.parse_drop_extra Attributes.program atts) ->
+ let polymorphic = Attributes.(parse_drop_extra polymorphic atts) in
+ let guarantee = if polymorphic then Doesn'tGuaranteeOpacity else GuaranteesOpacity in
+ VtStartProof (guarantee, idents_of_name name.CAst.v), VtLater
+ | VernacInstance (_,((name,_),_,_),_,_) ->
+ VtSideff (idents_of_name name.CAst.v), VtLater
(* Stm will install a new classifier to handle these *)
| VernacBack _ | VernacAbortAll
| VernacUndoTo _ | VernacUndo _
@@ -201,9 +208,8 @@ let classify_vernac e =
with Not_found -> anomaly(str"No classifier for"++spc()++str (fst s)++str".")
in
let rec static_control_classifier v = v |> CAst.with_val (function
- | VernacExpr (f, e) ->
- let poly = Attributes.(parse_drop_extra polymorphic_nowarn f) in
- static_classifier ~poly e
+ | VernacExpr (atts, e) ->
+ static_classifier ~atts e
| VernacTimeout (_,e) -> static_control_classifier e
| VernacTime (_,e) | VernacRedirect (_, e) ->
static_control_classifier e
@@ -214,6 +220,6 @@ let classify_vernac e =
| VtQed _, _ ->
VtProofStep { parallel = `No; proof_block_detection = None },
VtLater
- | (VtStartProof _ | VtUnknown | VtProofMode _), _ -> VtQuery, VtLater))
+ | (VtStartProof _ | VtProofMode _), _ -> VtQuery, VtLater))
in
static_control_classifier e
diff --git a/tactics/abstract.ml b/tactics/abstract.ml
index 7a61deba0c..499152f39a 100644
--- a/tactics/abstract.ml
+++ b/tactics/abstract.ml
@@ -174,7 +174,7 @@ let cache_term_by_tactic_then ~opaque ~name_op ?(goal_type=None) tac tacK =
let lem = mkConstU (cst, inst) in
let evd = Evd.set_universe_context evd ectx in
let open Safe_typing in
- let eff = private_con_of_con (Global.safe_env ()) cst in
+ let eff = private_constant (Global.safe_env ()) Entries.Subproof cst in
let effs = concat_private eff
Entries.(snd (Future.force const.const_entry_body)) in
let solve =
diff --git a/tactics/equality.ml b/tactics/equality.ml
index f049f8c568..45a4799ea1 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -417,7 +417,7 @@ let leibniz_rewrite_ebindings_clause cls lft2rgt tac c t l with_evars frzevars d
find_elim hdcncl lft2rgt dep cls (Some t) >>= fun elim ->
general_elim_clause with_evars frzevars tac cls c t l
(match lft2rgt with None -> false | Some b -> b)
- {elimindex = None; elimbody = (elim,NoBindings); elimrename = None}
+ {elimindex = None; elimbody = (elim,NoBindings) }
end
let adjust_rewriting_direction args lft2rgt =
diff --git a/tactics/ind_tables.ml b/tactics/ind_tables.ml
index 16829482e5..e95778a90d 100644
--- a/tactics/ind_tables.ml
+++ b/tactics/ind_tables.ml
@@ -147,9 +147,10 @@ let define_individual_scheme_base kind suff f mode idopt (mind,i as ind) =
| Some id -> id
| None -> add_suffix mib.mind_packets.(i).mind_typename suff in
let const = define mode id c (Declareops.inductive_is_polymorphic mib) ctx in
+ let role = Entries.Schema (ind, kind) in
+ let neff = Safe_typing.private_constant (Global.safe_env ()) role const in
declare_scheme kind [|ind,const|];
- const, Safe_typing.concat_private
- (Safe_typing.private_con_of_scheme ~kind (Global.safe_env()) [ind,const]) eff
+ const, Safe_typing.concat_private neff eff
let define_individual_scheme kind mode names (mind,i as ind) =
match Hashtbl.find scheme_object_table kind with
@@ -163,15 +164,16 @@ let define_mutual_scheme_base kind suff f mode names mind =
let ids = Array.init (Array.length mib.mind_packets) (fun i ->
try Int.List.assoc i names
with Not_found -> add_suffix mib.mind_packets.(i).mind_typename suff) in
- let consts = Array.map2 (fun id cl ->
- define mode id cl (Declareops.inductive_is_polymorphic mib) ctx) ids cl in
+ let fold i effs id cl =
+ let cst = define mode id cl (Declareops.inductive_is_polymorphic mib) ctx in
+ let role = Entries.Schema ((mind, i), kind)in
+ let neff = Safe_typing.private_constant (Global.safe_env ()) role cst in
+ (Safe_typing.concat_private neff effs, cst)
+ in
+ let (eff, consts) = Array.fold_left2_map_i fold eff ids cl in
let schemes = Array.mapi (fun i cst -> ((mind,i),cst)) consts in
declare_scheme kind schemes;
- consts,
- Safe_typing.concat_private
- (Safe_typing.private_con_of_scheme
- ~kind (Global.safe_env()) (Array.to_list schemes))
- eff
+ consts, eff
let define_mutual_scheme kind mode names mind =
match Hashtbl.find scheme_object_table kind with
diff --git a/tactics/leminv.ml b/tactics/leminv.ml
index 4aa4d13e1e..6efa1ece9c 100644
--- a/tactics/leminv.ml
+++ b/tactics/leminv.ml
@@ -204,10 +204,7 @@ let inversion_scheme ~name ~poly env sigma t sort dep_option inv_op =
(str"Computed inversion goal was not closed in initial signature.");
*)
let pf = Proof.start ~name ~poly (Evd.from_ctx (evar_universe_context sigma)) [invEnv,invGoal] in
- let pf =
- fst (Proof.run_tactic env (
- tclTHEN intro (onLastHypId inv_op)) pf)
- in
+ let pf, _, () = Proof.run_tactic env (tclTHEN intro (onLastHypId inv_op)) pf in
let pfterm = List.hd (Proof.partial_proof pf) in
let global_named_context = Global.named_context_val () in
let ownSign = ref begin
diff --git a/tactics/ppred.mli b/tactics/ppred.mli
index be21236f4e..c68fab5296 100644
--- a/tactics/ppred.mli
+++ b/tactics/ppred.mli
@@ -6,11 +6,6 @@ val pr_with_occurrences :
val pr_short_red_flag : ('a -> Pp.t) -> 'a glob_red_flag -> Pp.t
val pr_red_flag : ('a -> Pp.t) -> 'a glob_red_flag -> Pp.t
-val pr_red_expr :
- ('a -> Pp.t) * ('a -> Pp.t) * ('b -> Pp.t) * ('c -> Pp.t) ->
- (string -> Pp.t) -> ('a,'b,'c) red_expr_gen -> Pp.t
- [@@ocaml.deprecated "Use pr_red_expr_env instead"]
-
val pr_red_expr_env : Environ.env -> Evd.evar_map ->
(Environ.env -> Evd.evar_map -> 'a -> Pp.t) *
(Environ.env -> Evd.evar_map -> 'a -> Pp.t) *
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index 03b628dca3..9dafa8bad9 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -1363,14 +1363,11 @@ let do_replace id = function
[Ti] and the first one (resp last one) being [G] whose hypothesis
[id] is replaced by P using the proof given by [tac] *)
-let clenv_refine_in ?(sidecond_first=false) with_evars ?(with_classes=true)
- targetid id sigma0 clenv tac =
+let clenv_refine_in with_evars targetid id sigma0 clenv tac =
let clenv = Clenvtac.clenv_pose_dependent_evars ~with_evars clenv in
let clenv =
- if with_classes then
{ clenv with evd = Typeclasses.resolve_typeclasses
~fail:(not with_evars) clenv.env clenv.evd }
- else clenv
in
let new_hyp_typ = clenv_type clenv in
if not with_evars then check_unresolved_evars_of_metas sigma0 clenv;
@@ -1382,11 +1379,7 @@ let clenv_refine_in ?(sidecond_first=false) with_evars ?(with_classes=true)
let with_clear = do_replace (Some id) naming in
Tacticals.New.tclTHEN
(Proofview.Unsafe.tclEVARS (clear_metas clenv.evd))
- (if sidecond_first then
- Tacticals.New.tclTHENFIRST
- (assert_before_then_gen with_clear naming new_hyp_typ tac) exact_tac
- else
- Tacticals.New.tclTHENLAST
+ (Tacticals.New.tclTHENLAST
(assert_after_then_gen with_clear naming new_hyp_typ tac) exact_tac)
(********************************************)
@@ -1421,22 +1414,25 @@ let rec contract_letin_in_lam_header sigma c =
| LetIn (x,b,t,c) -> contract_letin_in_lam_header sigma (subst1 b c)
| _ -> c
-let elimination_clause_scheme with_evars ?(with_classes=true) ?(flags=elim_flags ())
- rename i (elim, elimty, bindings) indclause =
- Proofview.Goal.enter begin fun gl ->
- let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
- let elim = contract_letin_in_lam_header sigma elim in
- let elimclause = make_clenv_binding env sigma (elim, elimty) bindings in
- let indmv =
- (match EConstr.kind sigma (nth_arg sigma i elimclause.templval.rebus) with
- | Meta mv -> mv
- | _ -> user_err ~hdr:"elimination_clause"
- (str "The type of elimination clause is not well-formed."))
+let elimination_in_clause_scheme env sigma with_evars ~flags
+ id hypmv elimclause =
+ let hyp = mkVar id in
+ let hyp_typ = Retyping.get_type_of env sigma hyp in
+ let hypclause = mk_clenv_from_env env sigma (Some 0) (hyp, hyp_typ) in
+ let elimclause'' =
+ (* The evarmap of elimclause is assumed to be an extension of hypclause, so
+ we do not need to merge the universes coming from hypclause. *)
+ try clenv_fchain ~with_univs:false ~flags hypmv elimclause hypclause
+ with PretypeError (env,evd,NoOccurrenceFound (op,_)) ->
+ (* Set the hypothesis name in the message *)
+ raise (PretypeError (env,evd,NoOccurrenceFound (op,Some id)))
in
- let elimclause' = clenv_fchain ~flags indmv elimclause indclause in
- Clenvtac.res_pf elimclause' ~with_evars ~with_classes ~flags
- end
+ let new_hyp_typ = clenv_type elimclause'' in
+ if EConstr.eq_constr sigma hyp_typ new_hyp_typ then
+ user_err ~hdr:"general_rewrite_in"
+ (str "Nothing to rewrite in " ++ Id.print id ++ str".");
+ clenv_refine_in with_evars id id sigma elimclause''
+ (fun id -> Proofview.tclUNIT ())
(*
* Elimination tactic with bindings and using an arbitrary
@@ -1448,11 +1444,10 @@ let elimination_clause_scheme with_evars ?(with_classes=true) ?(flags=elim_flags
type eliminator = {
elimindex : int option; (* None = find it automatically *)
- elimrename : (bool * int array) option; (** None = don't rename Prop hyps with H-names *)
elimbody : EConstr.constr with_bindings
}
-let general_elim_clause_gen elimtac indclause elim =
+let general_elim_clause with_evars flags where indclause elim =
Proofview.Goal.enter begin fun gl ->
let env = Proofview.Goal.env gl in
let sigma = Tacmach.New.project gl in
@@ -1460,7 +1455,27 @@ let general_elim_clause_gen elimtac indclause elim =
let elimt = Retyping.get_type_of env sigma elimc in
let i =
match elim.elimindex with None -> index_of_ind_arg sigma elimt | Some i -> i in
- elimtac elim.elimrename i (elimc, elimt, lbindelimc) indclause
+ let elimc = contract_letin_in_lam_header sigma elimc in
+ let elimclause = make_clenv_binding env sigma (elimc, elimt) lbindelimc in
+ let indmv =
+ (match EConstr.kind sigma (nth_arg sigma i elimclause.templval.rebus) with
+ | Meta mv -> mv
+ | _ -> user_err ~hdr:"elimination_clause"
+ (str "The type of elimination clause is not well-formed."))
+ in
+ match where with
+ | None ->
+ let elimclause = clenv_fchain ~flags indmv elimclause indclause in
+ Clenvtac.res_pf elimclause ~with_evars ~with_classes:true ~flags
+ | Some id ->
+ let hypmv =
+ match List.remove Int.equal indmv (clenv_independent elimclause) with
+ | [a] -> a
+ | _ -> user_err ~hdr:"elimination_clause"
+ (str "The type of elimination clause is not well-formed.")
+ in
+ let elimclause = clenv_fchain ~flags indmv elimclause indclause in
+ elimination_in_clause_scheme env sigma with_evars ~flags id hypmv elimclause
end
let general_elim with_evars clear_flag (c, lbindc) elim =
@@ -1469,12 +1484,12 @@ let general_elim with_evars clear_flag (c, lbindc) elim =
let sigma = Tacmach.New.project gl in
let ct = Retyping.get_type_of env sigma c in
let t = try snd (reduce_to_quantified_ind env sigma ct) with UserError _ -> ct in
- let elimtac = elimination_clause_scheme with_evars in
let indclause = make_clenv_binding env sigma (c, t) lbindc in
let sigma = meta_merge sigma (clear_metas indclause.evd) in
+ let flags = elim_flags () in
Proofview.Unsafe.tclEVARS sigma <*>
Tacticals.New.tclTHEN
- (general_elim_clause_gen elimtac indclause elim)
+ (general_elim_clause with_evars flags None indclause elim)
(apply_clear_request clear_flag (use_clear_hyp_by_default ()) c)
end
@@ -1497,8 +1512,7 @@ let general_case_analysis_in_context with_evars clear_flag (c,lbindc) =
let elim = EConstr.of_constr elim in
Proofview.tclTHEN (Proofview.Unsafe.tclEVARS sigma)
(general_elim with_evars clear_flag (c,lbindc)
- {elimindex = None; elimbody = (elim,NoBindings);
- elimrename = Some (false, constructors_nrealdecls env (fst mind))})
+ {elimindex = None; elimbody = (elim,NoBindings); })
end
let general_case_analysis with_evars clear_flag (c,lbindc as cx) =
@@ -1529,8 +1543,7 @@ let find_eliminator c gl =
let ((ind,u),t) = Tacmach.New.pf_reduce_to_quantified_ind gl (Tacmach.New.pf_unsafe_type_of gl c) in
if is_nonrec ind then raise IsNonrec;
let evd, c = find_ind_eliminator ind (Tacticals.New.elimination_sort_of_goal gl) gl in
- evd, {elimindex = None; elimbody = (c,NoBindings);
- elimrename = Some (true, constructors_nrealdecls (Global.env()) ind)}
+ evd, { elimindex = None; elimbody = (c,NoBindings) }
let default_elim with_evars clear_flag (c,_ as cx) =
Proofview.tclORELSE
@@ -1550,7 +1563,7 @@ let default_elim with_evars clear_flag (c,_ as cx) =
let elim_in_context with_evars clear_flag c = function
| Some elim ->
general_elim with_evars clear_flag c
- {elimindex = Some (-1); elimbody = elim; elimrename = None}
+ { elimindex = Some (-1); elimbody = elim }
| None -> default_elim with_evars clear_flag c
let elim with_evars clear_flag (c,lbindc as cx) elim =
@@ -1576,48 +1589,6 @@ let simplest_elim c = default_elim false None (c,NoBindings)
(e.g. it could replace id:A->B->C by id:C, knowing A/\B)
*)
-let clenv_fchain_in id ?(flags=elim_flags ()) mv elimclause hypclause =
- (* The evarmap of elimclause is assumed to be an extension of hypclause, so
- we do not need to merge the universes coming from hypclause. *)
- try clenv_fchain ~with_univs:false ~flags mv elimclause hypclause
- with PretypeError (env,evd,NoOccurrenceFound (op,_)) ->
- (* Set the hypothesis name in the message *)
- raise (PretypeError (env,evd,NoOccurrenceFound (op,Some id)))
-
-let elimination_in_clause_scheme with_evars ?(flags=elim_flags ())
- id rename i (elim, elimty, bindings) indclause =
- Proofview.Goal.enter begin fun gl ->
- let env = Proofview.Goal.env gl in
- let sigma = Tacmach.New.project gl in
- let elim = contract_letin_in_lam_header sigma elim in
- let elimclause = make_clenv_binding env sigma (elim, elimty) bindings in
- let indmv = destMeta sigma (nth_arg sigma i elimclause.templval.rebus) in
- let hypmv =
- match List.remove Int.equal indmv (clenv_independent elimclause) with
- | [a] -> a
- | _ -> user_err ~hdr:"elimination_clause"
- (str "The type of elimination clause is not well-formed.")
- in
- let elimclause' = clenv_fchain ~flags indmv elimclause indclause in
- let hyp = mkVar id in
- let hyp_typ = Retyping.get_type_of env sigma hyp in
- let hypclause = mk_clenv_from_env env sigma (Some 0) (hyp, hyp_typ) in
- let elimclause'' = clenv_fchain_in id ~flags hypmv elimclause' hypclause in
- let new_hyp_typ = clenv_type elimclause'' in
- if EConstr.eq_constr sigma hyp_typ new_hyp_typ then
- user_err ~hdr:"general_rewrite_in"
- (str "Nothing to rewrite in " ++ Id.print id ++ str".");
- clenv_refine_in with_evars id id sigma elimclause''
- (fun id -> Proofview.tclUNIT ())
- end
-
-let general_elim_clause with_evars flags id c e =
- let elim = match id with
- | None -> elimination_clause_scheme with_evars ~with_classes:true ~flags
- | Some id -> elimination_in_clause_scheme with_evars ~flags id
- in
- general_elim_clause_gen elim c e
-
(* Apply a tactic below the products of the conclusion of a lemma *)
type conjunction_status =
@@ -1889,7 +1860,7 @@ let apply_in_once_main flags innerclause env sigma (loc,d,lbind) =
in
aux (make_clenv_binding env sigma (d,thm) lbind)
-let apply_in_once ?(respect_opaque = false) sidecond_first with_delta
+let apply_in_once ?(respect_opaque = false) with_delta
with_destruct with_evars naming id (clear_flag,{ CAst.loc; v= d,lbind}) tac =
let open Context.Rel.Declaration in
Proofview.Goal.enter begin fun gl ->
@@ -1910,7 +1881,7 @@ let apply_in_once ?(respect_opaque = false) sidecond_first with_delta
if with_delta then default_unify_flags () else default_no_delta_unify_flags ts in
try
let clause = apply_in_once_main flags innerclause env sigma (loc,c,lbind) in
- clenv_refine_in ~sidecond_first with_evars targetid id sigma clause
+ clenv_refine_in with_evars targetid id sigma clause
(fun id ->
Tacticals.New.tclTHENLIST [
apply_clear_request clear_flag false c;
@@ -1927,14 +1898,14 @@ let apply_in_once ?(respect_opaque = false) sidecond_first with_delta
aux [] with_destruct d
end
-let apply_in_delayed_once ?(respect_opaque = false) sidecond_first with_delta
+let apply_in_delayed_once ?(respect_opaque = false) with_delta
with_destruct with_evars naming id (clear_flag,{CAst.loc;v=f}) tac =
Proofview.Goal.enter begin fun gl ->
let env = Proofview.Goal.env gl in
let sigma = Tacmach.New.project gl in
let (sigma, c) = f env sigma in
Tacticals.New.tclWITHHOLES with_evars
- (apply_in_once ~respect_opaque sidecond_first with_delta with_destruct with_evars
+ (apply_in_once ~respect_opaque with_delta with_destruct with_evars
naming id (clear_flag,CAst.(make ?loc c)) tac)
sigma
end
@@ -2554,7 +2525,7 @@ and intro_pattern_action ?loc with_evars b style pat thin destopt tac id =
clear [id] in
let f env sigma = let (sigma, c) = f env sigma in (sigma,(c, NoBindings))
in
- apply_in_delayed_once false true true with_evars naming id (None,CAst.make ?loc:loc' f)
+ apply_in_delayed_once true true with_evars naming id (None,CAst.make ?loc:loc' f)
(fun id -> Tacticals.New.tclTHENLIST [doclear; tac_ipat id; tac thin None []])
and prepare_intros ?loc with_evars dft destopt = function
@@ -2622,10 +2593,10 @@ let assert_as first hd ipat t =
(* apply in as *)
-let general_apply_in ?(respect_opaque=false) sidecond_first with_delta
+let general_apply_in ?(respect_opaque=false) with_delta
with_destruct with_evars id lemmas ipat =
let tac (naming,lemma) tac id =
- apply_in_delayed_once ~respect_opaque sidecond_first with_delta
+ apply_in_delayed_once ~respect_opaque with_delta
with_destruct with_evars naming id lemma tac in
Proofview.Goal.enter begin fun gl ->
let destopt =
@@ -2654,10 +2625,10 @@ let general_apply_in ?(respect_opaque=false) sidecond_first with_delta
let apply_in simple with_evars id lemmas ipat =
let lemmas = List.map (fun (k,{CAst.loc;v=l}) -> k, CAst.make ?loc (fun _ sigma -> (sigma,l))) lemmas in
- general_apply_in false simple simple with_evars id lemmas ipat
+ general_apply_in simple simple with_evars id lemmas ipat
let apply_delayed_in simple with_evars id lemmas ipat =
- general_apply_in ~respect_opaque:true false simple simple with_evars id lemmas ipat
+ general_apply_in ~respect_opaque:true simple simple with_evars id lemmas ipat
(*****************************)
(* Tactics abstracting terms *)
@@ -4244,7 +4215,7 @@ let find_induction_type isrec elim hyp0 gl =
let scheme = compute_elim_sig sigma ~elimc elimt in
if Option.is_empty scheme.indarg then error "Cannot find induction type";
let indsign = compute_scheme_signature evd scheme hyp0 ind_guess in
- let elim = ({elimindex = Some(-1); elimbody = elimc; elimrename = None},elimt) in
+ let elim = ({ elimindex = Some(-1); elimbody = elimc },elimt) in
scheme, ElimUsing (elim,indsign)
in
match scheme.indref with
@@ -4271,10 +4242,7 @@ let get_eliminator elim dep s gl =
| ElimOver (isrec,id) ->
let evd, (elimc,elimt),_ as elims = guess_elim isrec dep s id gl in
let _, (l, s) = compute_elim_signature elims id in
- let branchlengthes = List.map (fun d -> assert (RelDecl.is_local_assum d); pi1 (decompose_prod_letin (Tacmach.New.project gl) (RelDecl.get_type d)))
- (List.rev s.branches)
- in
- evd, isrec, ({elimindex = None; elimbody = elimc; elimrename = Some (isrec,Array.of_list branchlengthes)}, elimt), l
+ evd, isrec, ({ elimindex = None; elimbody = elimc }, elimt), l
(* Instantiate all meta variables of elimclause using lid, some elts
of lid are parameters (first ones), the other are
@@ -4318,7 +4286,7 @@ let recolle_clenv i params args elimclause gl =
let induction_tac with_evars params indvars elim =
Proofview.Goal.enter begin fun gl ->
let sigma = Tacmach.New.project gl in
- let ({elimindex=i;elimbody=(elimc,lbindelimc);elimrename=rename},elimt) = elim in
+ let ({ elimindex=i;elimbody=(elimc,lbindelimc) },elimt) = elim in
let i = match i with None -> index_of_ind_arg sigma elimt | Some i -> i in
(* elimclause contains this: (elimc ?i ?j ?k...?l) *)
let elimc = contract_letin_in_lam_header sigma elimc in
@@ -4423,7 +4391,7 @@ let induction_without_atomization isrec with_evars elim names lid =
(* FIXME: Tester ca avec un principe dependant et non-dependant *)
induction_tac with_evars params realindvars elim;
] in
- let elim = ElimUsing (({elimindex = Some (-1); elimbody = Option.get scheme.elimc; elimrename = None}, scheme.elimt), indsign) in
+ let elim = ElimUsing (({ elimindex = Some (-1); elimbody = Option.get scheme.elimc }, scheme.elimt), indsign) in
apply_induction_in_context with_evars None [] elim indvars names induct_tac
end
diff --git a/tactics/tactics.mli b/tactics/tactics.mli
index 9eb8196280..32c64bacf6 100644
--- a/tactics/tactics.mli
+++ b/tactics/tactics.mli
@@ -282,7 +282,6 @@ val compute_elim_sig : evar_map -> ?elimc:constr with_bindings -> types -> elim_
(** elim principle with the index of its inductive arg *)
type eliminator = {
elimindex : int option; (** None = find it automatically *)
- elimrename : (bool * int array) option; (** None = don't rename Prop hyps with H-names *)
elimbody : constr with_bindings
}
diff --git a/test-suite/bugs/closed/bug_10026.v b/test-suite/bugs/closed/bug_10026.v
new file mode 100644
index 0000000000..0d3142d0f2
--- /dev/null
+++ b/test-suite/bugs/closed/bug_10026.v
@@ -0,0 +1,3 @@
+Require Import Coq.Lists.List.
+Set Debug RAKAM.
+Check fun _ => fold_right (fun A B => prod A B) unit _.
diff --git a/test-suite/bugs/closed/bug_10189.v b/test-suite/bugs/closed/bug_10189.v
new file mode 100644
index 0000000000..d603bff386
--- /dev/null
+++ b/test-suite/bugs/closed/bug_10189.v
@@ -0,0 +1,9 @@
+Definition foo : forall (x := unit) {y : nat}, nat := fun y => y.
+Check foo (y := 3). (*We fail to get implicits in the type past a let-in*)
+Definition foo' : forall (x : Set) {y : nat}, nat := fun _ y => y.
+Check foo' unit (y := 3). (* It works with a function binder *)
+
+Definition bar := let f {x} : nat -> nat := fun y => x in f (x := 3).
+(* Adding bar : nat -> nat gives implicits-in-term warning *)
+Fail Check bar (x := 3).
+(* The implicits from the type of the local definition leak to the outer term *)
diff --git a/test-suite/bugs/opened/bug_3754.v b/test-suite/bugs/closed/bug_3754.v
index 18820b1a4c..7031cbf132 100644
--- a/test-suite/bugs/opened/bug_3754.v
+++ b/test-suite/bugs/closed/bug_3754.v
@@ -281,5 +281,7 @@ Defined.
(factor2 fact)).
rewrite <- ap_p_pp; rewrite_moveL_Mp_p.
Set Debug Tactic Unification.
- Fail rewrite (concat_Ap ff2).
+ rewrite (concat_Ap ff2).
Abort.
+
+End Factorization.
diff --git a/test-suite/bugs/closed/bug_3890.v b/test-suite/bugs/closed/bug_3890.v
new file mode 100644
index 0000000000..e1823ac54c
--- /dev/null
+++ b/test-suite/bugs/closed/bug_3890.v
@@ -0,0 +1,12 @@
+Set Nested Proofs Allowed.
+
+Class Foo.
+Class Bar := b : Type.
+
+Instance foo : Foo.
+
+Instance bar : Bar.
+exact Type.
+Defined.
+
+Defined.
diff --git a/test-suite/bugs/closed/bug_4429.v b/test-suite/bugs/closed/bug_4429.v
deleted file mode 100644
index bf0e570ab8..0000000000
--- a/test-suite/bugs/closed/bug_4429.v
+++ /dev/null
@@ -1,31 +0,0 @@
-Require Import Arith.Compare_dec.
-Require Import Unicode.Utf8.
-
-Fixpoint my_nat_iter (n : nat) {A} (f : A → A) (x : A) : A :=
- match n with
- | O => x
- | S n' => f (my_nat_iter n' f x)
- end.
-
-Definition gcd_IT_F (f : nat * nat → nat) (mn : nat * nat) : nat :=
- match mn with
- | (0, 0) => 0
- | (0, S n') => S n'
- | (S m', 0) => S m'
- | (S m', S n') =>
- match le_gt_dec (S m') (S n') with
- | left _ => f (S m', S n' - S m')
- | right _ => f (S m' - S n', S n')
- end
- end.
-
-Axiom max_correct_l : ∀ m n : nat, m <= max m n.
-Axiom max_correct_r : ∀ m n : nat, n <= max m n.
-
-Hint Resolve max_correct_l max_correct_r : arith.
-
-Theorem foo : ∀ p p' p'' : nat, p'' < S (max p (max p' p'')).
-Proof.
- intros.
- Timeout 3 eauto with arith.
-Qed.
diff --git a/test-suite/bugs/closed/bug_4580.v b/test-suite/bugs/closed/bug_4580.v
index a8a446cc9b..3f40569d61 100644
--- a/test-suite/bugs/closed/bug_4580.v
+++ b/test-suite/bugs/closed/bug_4580.v
@@ -2,6 +2,5 @@ Require Import Program.
Class Foo (A : Type) := foo : A.
-Unset Refine Instance Mode.
Program Instance f1 : Foo nat := S _.
Next Obligation. exact 0. Defined.
diff --git a/test-suite/bugs/closed/bug_4638.v b/test-suite/bugs/closed/bug_4638.v
new file mode 100644
index 0000000000..951fe5302b
--- /dev/null
+++ b/test-suite/bugs/closed/bug_4638.v
@@ -0,0 +1,12 @@
+Set Nested Proofs Allowed.
+
+Class Foo.
+
+Goal True.
+
+Instance foo: Foo.
+Qed.
+
+trivial.
+
+Qed.
diff --git a/test-suite/bugs/opened/bug_3890.v b/test-suite/bugs/opened/bug_3890.v
deleted file mode 100644
index 9d83743b2a..0000000000
--- a/test-suite/bugs/opened/bug_3890.v
+++ /dev/null
@@ -1,22 +0,0 @@
-Set Nested Proofs Allowed.
-
-Class Foo.
-Class Bar := b : Type.
-
-Set Refine Instance Mode.
-Instance foo : Foo := _.
-Unset Refine Instance Mode.
-(* 1 subgoals, subgoal 1 (ID 4)
-
- ============================
- Foo *)
-
-Instance bar : Bar.
-exact Type.
-Defined.
-(* bar is defined *)
-
-About foo.
-(* foo not a defined object. *)
-
-Fail Defined.
diff --git a/test-suite/dune b/test-suite/dune
index c430400ba5..cd33319fa4 100644
--- a/test-suite/dune
+++ b/test-suite/dune
@@ -20,6 +20,8 @@
../dev/header.ml
../dev/tools/update-compat.py
../doc/stdlib/index-list.html.template
+ ; For the changelog test
+ ../config/coq_config.py
(package coq)
; For fake_ide
(package coqide-server)
diff --git a/test-suite/misc/changelog.sh b/test-suite/misc/changelog.sh
new file mode 100755
index 0000000000..8b4a49e577
--- /dev/null
+++ b/test-suite/misc/changelog.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+while read line; do
+ if [ "$line" = "is_a_released_version = False" ]; then
+ echo "This is not a released version: nothing to test."
+ exit 0
+ fi
+done < ../config/coq_config.py
+
+for d in ../doc/changelog/*; do
+ if [ -d "$d" ]; then
+ if [ "$(ls $d/*.rst | wc -l)" != "1" ]; then
+ echo "Fatal: unreleased changelog entries remain in ${d#../}/"
+ echo "Include them in doc/sphinx/changes.rst and remove them from doc/changelog/"
+ exit 1
+ fi
+ fi
+done
diff --git a/test-suite/output/Notations4.out b/test-suite/output/Notations4.out
index 9d972a68f7..c1b9a2b1c6 100644
--- a/test-suite/output/Notations4.out
+++ b/test-suite/output/Notations4.out
@@ -1,5 +1,15 @@
[< 0 > + < 1 > * < 2 >]
: nat
+Entry constr:myconstr is
+[ "6" RIGHTA
+ [ ]
+| "5" RIGHTA
+ [ SELF; "+"; NEXT ]
+| "4" RIGHTA
+ [ SELF; "*"; NEXT ]
+| "3" RIGHTA
+ [ "<"; constr:operconstr LEVEL "10"; ">" ] ]
+
[< b > + < b > * < 2 >]
: nat
[<< # 0 >>]
diff --git a/test-suite/output/Notations4.v b/test-suite/output/Notations4.v
index 81c64418cb..d1063bfd04 100644
--- a/test-suite/output/Notations4.v
+++ b/test-suite/output/Notations4.v
@@ -9,6 +9,7 @@ Notation "x + y" := (Nat.add x y) (in custom myconstr at level 5).
Notation "x * y" := (Nat.mul x y) (in custom myconstr at level 4).
Notation "< x >" := x (in custom myconstr at level 3, x constr at level 10).
Check [ < 0 > + < 1 > * < 2 >].
+Print Custom Grammar myconstr.
Axiom a : nat.
Notation b := a.
diff --git a/test-suite/success/Notations2.v b/test-suite/success/Notations2.v
index 2533a39cc4..d047f7560e 100644
--- a/test-suite/success/Notations2.v
+++ b/test-suite/success/Notations2.v
@@ -151,8 +151,8 @@ Module M16.
Local Notation "##" := 0 (in custom foo2).
(* Test Print Grammar *)
- Print Grammar foo.
- Print Grammar foo2.
+ Print Custom Grammar foo.
+ Print Custom Grammar foo2.
End M16.
(* Example showing the need for strong evaluation of
diff --git a/test-suite/success/Typeclasses.v b/test-suite/success/Typeclasses.v
index 3888cafed3..736d05fefc 100644
--- a/test-suite/success/Typeclasses.v
+++ b/test-suite/success/Typeclasses.v
@@ -198,9 +198,7 @@ Module UniqueInstances.
for it. *)
Set Typeclasses Unique Instances.
Class Eq (A : Type) : Set.
- Set Refine Instance Mode.
- Instance eqa : Eq nat := _. constructor. Qed.
- Unset Refine Instance Mode.
+ Instance eqa : Eq nat. Qed.
Instance eqb : Eq nat := {}.
Class Foo (A : Type) (e : Eq A) : Set.
Instance fooa : Foo _ eqa := {}.
diff --git a/test-suite/success/attribute_syntax.v b/test-suite/success/attribute_syntax.v
index f4f59a3c16..4717759dec 100644
--- a/test-suite/success/attribute_syntax.v
+++ b/test-suite/success/attribute_syntax.v
@@ -20,6 +20,10 @@ Check ι _ ι.
Fixpoint f (n: nat) {wf lt n} : nat := _.
Reset f.
+#[program(true)]
+Fixpoint f (n: nat) {wf lt n} : nat := _.
+Reset f.
+
#[deprecated(since="8.9.0")]
Ltac foo := foo.
diff --git a/theories/Compat/Coq89.v b/theories/Compat/Coq89.v
index 05d63d9a47..49e0af9b2c 100644
--- a/theories/Compat/Coq89.v
+++ b/theories/Compat/Coq89.v
@@ -14,4 +14,3 @@ Local Set Warnings "-deprecated".
Require Export Coq.Compat.Coq810.
Unset Private Polymorphic Universes.
-Set Refine Instance Mode.
diff --git a/toplevel/coqargs.ml b/toplevel/coqargs.ml
index 9a18baa0bc..ec43dbb1d7 100644
--- a/toplevel/coqargs.ml
+++ b/toplevel/coqargs.ml
@@ -184,10 +184,6 @@ let warn_deprecated_inputstate =
CWarnings.create ~name:"deprecated-inputstate" ~category:"deprecated"
(fun () -> Pp.strbrk "The inputstate option is deprecated and discouraged.")
-let warn_deprecated_boot =
- CWarnings.create ~name:"deprecated-boot" ~category:"noop"
- (fun () -> Pp.strbrk "The -boot option is deprecated, please use -q and/or -coqlib options instead.")
-
let set_inputstate opts s =
warn_deprecated_inputstate ();
{ opts with inputstate = Some s }
@@ -488,9 +484,6 @@ let parse_args ~help ~init arglist : t * string list =
{ oval with batch = true }
|"-test-mode" -> Vernacentries.test_mode := true; oval
|"-beautify" -> Flags.beautify := true; oval
- |"-boot" ->
- warn_deprecated_boot ();
- { oval with load_rcfile = false; }
|"-bt" -> Backtrace.record_backtrace true; oval
|"-color" -> set_color oval (next ())
|"-config"|"--config" -> { oval with print_config = true }
diff --git a/toplevel/coqtop.ml b/toplevel/coqtop.ml
index 9323a57417..b769405cf6 100644
--- a/toplevel/coqtop.ml
+++ b/toplevel/coqtop.ml
@@ -271,31 +271,6 @@ let init_toploop opts =
let state = { doc; sid; proof = None; time = opts.time } in
Ccompile.load_init_vernaculars opts ~state, opts
-(* To remove in 8.11 *)
-let call_coqc args =
- let remove str arr = Array.(of_list List.(filter (fun l -> not String.(equal l str)) (to_list arr))) in
- let coqc_name = Filename.remove_extension (System.get_toplevel_path "coqc") in
- let args = remove "-compile" args in
- Unix.execv coqc_name args
-
-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."])))
-
-let rec coqc_deprecated_check args acc extras =
- match extras with
- | [] -> acc
- | "-o" :: _ :: rem ->
- deprecated_coqc_warning "-o";
- coqc_deprecated_check args acc rem
- | ("-compile"|"-compile-verbose") :: file :: rem ->
- deprecated_coqc_warning "-compile";
- call_coqc args
- | x :: rem ->
- coqc_deprecated_check args (x::acc) rem
-
let coqtop_init ~opts extra =
init_color opts;
CoqworkmgrApi.(init !async_proofs_worker_priority);
@@ -317,7 +292,6 @@ let start_coq custom =
init_toplevel
~help:Usage.print_usage_coqtop ~init:default custom.init
(List.tl (Array.to_list Sys.argv)) in
- let extras = coqc_deprecated_check Sys.argv [] extras in
if not (CList.is_empty extras) then begin
prerr_endline ("Don't know what to do with "^String.concat " " extras);
prerr_endline "See -help for the list of supported options";
diff --git a/toplevel/usage.ml b/toplevel/usage.ml
index 7074215afe..da2094653b 100644
--- a/toplevel/usage.ml
+++ b/toplevel/usage.ml
@@ -102,12 +102,6 @@ let print_usage_coqtop () =
coqtop specific options:\
\n\
\n -batch batch mode (exits just after argument 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
@@ -128,14 +122,6 @@ coqc specific options:\
\nUndocumented:\
\n -vio2vo [see manual]\
\n -check-vio-tasks [see manual]\
-\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 -outputstate file save summary state in file \
\n";
flush stderr ;
exit 1
diff --git a/user-contrib/Ltac2/Constr.v b/user-contrib/Ltac2/Constr.v
index d8d222730e..1701bf4365 100644
--- a/user-contrib/Ltac2/Constr.v
+++ b/user-contrib/Ltac2/Constr.v
@@ -38,6 +38,7 @@ Ltac2 Type kind := [
| Fix (int array, int, ident option array, constr array, constr array)
| CoFix (int, ident option array, constr array, constr array)
| Proj (projection, constr)
+| Uint63 (uint63)
].
Ltac2 @ external kind : constr -> kind := "ltac2" "constr_kind".
diff --git a/user-contrib/Ltac2/Init.v b/user-contrib/Ltac2/Init.v
index 16e7d7a6f9..dc1690bdfb 100644
--- a/user-contrib/Ltac2/Init.v
+++ b/user-contrib/Ltac2/Init.v
@@ -14,6 +14,7 @@ Ltac2 Type int.
Ltac2 Type string.
Ltac2 Type char.
Ltac2 Type ident.
+Ltac2 Type uint63.
(** Constr-specific built-in types *)
Ltac2 Type meta.
diff --git a/user-contrib/Ltac2/tac2core.ml b/user-contrib/Ltac2/tac2core.ml
index d7e7b91ee6..da8600109e 100644
--- a/user-contrib/Ltac2/tac2core.ml
+++ b/user-contrib/Ltac2/tac2core.ml
@@ -424,8 +424,8 @@ let () = define1 "constr_kind" constr begin fun c ->
Value.of_ext Value.val_projection p;
Value.of_constr c;
|]
- | Int _ ->
- assert false
+ | Int n ->
+ v_blk 17 [|Value.of_uint63 n|]
end
end
@@ -503,6 +503,9 @@ let () = define1 "constr_make" valexpr begin fun knd ->
let p = Value.to_ext Value.val_projection p in
let c = Value.to_constr c in
EConstr.mkProj (p, c)
+ | (17, [|n|]) ->
+ let n = Value.to_uint63 n in
+ EConstr.mkInt n
| _ -> assert false
in
return (Value.of_constr c)
diff --git a/user-contrib/Ltac2/tac2entries.ml b/user-contrib/Ltac2/tac2entries.ml
index 9fd01426de..254c2e5086 100644
--- a/user-contrib/Ltac2/tac2entries.ml
+++ b/user-contrib/Ltac2/tac2entries.ml
@@ -740,7 +740,6 @@ let register_redefinition ?(local = false) qid e =
Lib.add_anonymous_leaf (inTac2Redefinition def)
let perform_eval ~pstate e =
- let open Proofview.Notations in
let env = Global.env () in
let (e, ty) = Tac2intern.intern ~strict:false e in
let v = Tac2interp.interp Tac2interp.empty_environment e in
@@ -761,12 +760,8 @@ let perform_eval ~pstate e =
| Goal_select.SelectAll -> v
| Goal_select.SelectAlreadyFocused -> assert false (* TODO **)
in
- (* HACK: the API doesn't allow to return a value *)
- let ans = ref None in
- let tac = (v >>= fun r -> ans := Some r; Proofview.tclUNIT ()) in
- let (proof, _) = Proof.run_tactic (Global.env ()) tac proof in
+ let (proof, _, ans) = Proof.run_tactic (Global.env ()) v proof in
let sigma = Proof.in_proof proof (fun sigma -> sigma) in
- let ans = match !ans with None -> assert false | Some r -> r in
let name = int_name () in
Feedback.msg_notice (str "- : " ++ pr_glbtype name (snd ty)
++ spc () ++ str "=" ++ spc () ++
diff --git a/user-contrib/Ltac2/tac2ffi.ml b/user-contrib/Ltac2/tac2ffi.ml
index e3127ab9df..1043d25a75 100644
--- a/user-contrib/Ltac2/tac2ffi.ml
+++ b/user-contrib/Ltac2/tac2ffi.ml
@@ -30,6 +30,8 @@ type valexpr =
(** Open constructors *)
| ValExt : 'a Tac2dyn.Val.tag * 'a -> valexpr
(** Arbitrary data *)
+| ValUint63 of Uint63.t
+ (** Primitive integers *)
and closure = MLTactic : (valexpr, 'v) arity0 * 'v -> closure
@@ -47,21 +49,21 @@ type t = valexpr
let is_int = function
| ValInt _ -> true
-| ValBlk _ | ValStr _ | ValCls _ | ValOpn _ | ValExt _ -> false
+| ValBlk _ | ValStr _ | ValCls _ | ValOpn _ | ValExt _ | ValUint63 _ -> false
let tag v = match v with
| ValBlk (n, _) -> n
-| ValInt _ | ValStr _ | ValCls _ | ValOpn _ | ValExt _ ->
+| ValInt _ | ValStr _ | ValCls _ | ValOpn _ | ValExt _ | ValUint63 _ ->
CErrors.anomaly (Pp.str "Unexpected value shape")
let field v n = match v with
| ValBlk (_, v) -> v.(n)
-| ValInt _ | ValStr _ | ValCls _ | ValOpn _ | ValExt _ ->
+| ValInt _ | ValStr _ | ValCls _ | ValOpn _ | ValExt _ | ValUint63 _ ->
CErrors.anomaly (Pp.str "Unexpected value shape")
let set_field v n w = match v with
| ValBlk (_, v) -> v.(n) <- w
-| ValInt _ | ValStr _ | ValCls _ | ValOpn _ | ValExt _ ->
+| ValInt _ | ValStr _ | ValCls _ | ValOpn _ | ValExt _ | ValUint63 _ ->
CErrors.anomaly (Pp.str "Unexpected value shape")
let make_block tag v = ValBlk (tag, v)
@@ -192,7 +194,7 @@ let of_closure cls = ValCls cls
let to_closure = function
| ValCls cls -> cls
-| ValExt _ | ValInt _ | ValBlk _ | ValStr _ | ValOpn _ -> assert false
+| ValExt _ | ValInt _ | ValBlk _ | ValStr _ | ValOpn _ | ValUint63 _ -> assert false
let closure = {
r_of = of_closure;
@@ -318,6 +320,17 @@ let open_ = {
r_id = false;
}
+let of_uint63 n = ValUint63 n
+let to_uint63 = function
+| ValUint63 n -> n
+| _ -> assert false
+
+let uint63 = {
+ r_of = of_uint63;
+ r_to = to_uint63;
+ r_id = false;
+}
+
let of_constant c = of_ext val_constant c
let to_constant c = to_ext val_constant c
let constant = repr_ext val_constant
diff --git a/user-contrib/Ltac2/tac2ffi.mli b/user-contrib/Ltac2/tac2ffi.mli
index bfc93d99e6..f8581061a0 100644
--- a/user-contrib/Ltac2/tac2ffi.mli
+++ b/user-contrib/Ltac2/tac2ffi.mli
@@ -28,6 +28,8 @@ type valexpr =
(** Open constructors *)
| ValExt : 'a Tac2dyn.Val.tag * 'a -> valexpr
(** Arbitrary data *)
+| ValUint63 of Uint63.t
+ (** Primitive integers *)
type 'a arity
@@ -143,6 +145,10 @@ val of_open : KerName.t * valexpr array -> valexpr
val to_open : valexpr -> KerName.t * valexpr array
val open_ : (KerName.t * valexpr array) repr
+val of_uint63 : Uint63.t -> valexpr
+val to_uint63 : valexpr -> Uint63.t
+val uint63 : Uint63.t repr
+
type ('a, 'b) fun1
val app_fun1 : ('a, 'b) fun1 -> 'a repr -> 'b repr -> 'a -> 'b Proofview.tactic
diff --git a/vernac/attributes.ml b/vernac/attributes.ml
index 9b8c4efb37..1ad5862d5d 100644
--- a/vernac/attributes.ml
+++ b/vernac/attributes.ml
@@ -82,9 +82,12 @@ let assert_empty k v =
if v <> VernacFlagEmpty
then user_err Pp.(str "Attribute " ++ str k ++ str " does not accept arguments")
+let error_twice ~name : 'a =
+ user_err Pp.(str "Attribute for " ++ str name ++ str " specified twice.")
+
let assert_once ~name prev =
if Option.has_some prev then
- user_err Pp.(str "Attribute for " ++ str name ++ str " specified twice.")
+ error_twice ~name
let attribute_of_list (l:(string * 'a key_parser) list) : 'a option attribute =
let rec p extra v = function
@@ -107,6 +110,24 @@ let bool_attribute ~name ~on ~off : bool option attribute =
attribute_of_list [(on, single_key_parser ~name ~key:on true);
(off, single_key_parser ~name ~key:off false)]
+(* Variant of the [bool] attribute with only two values (bool has three). *)
+let get_bool_value ~key ~default =
+ function
+ | VernacFlagEmpty -> default
+ | VernacFlagList [ "true", VernacFlagEmpty ] -> true
+ | VernacFlagList [ "false", VernacFlagEmpty ] -> false
+ | _ -> user_err Pp.(str "Attribute " ++ str key ++ str " only accepts boolean values.")
+
+let enable_attribute ~key ~default : bool attribute =
+ fun atts ->
+ let default = default () in
+ let this, extra = List.partition (fun (k, _) -> String.equal key k) atts in
+ extra,
+ match this with
+ | [] -> default
+ | [ _, value ] -> get_bool_value ~key ~default:true value
+ | _ -> error_twice ~name:key
+
let qualify_attribute qual (parser:'a attribute) : 'a attribute =
fun atts ->
let rec extract extra qualified = function
@@ -139,11 +160,8 @@ let () = let open Goptions in
optread = (fun () -> !program_mode);
optwrite = (fun b -> program_mode:=b) }
-let program_opt = bool_attribute ~name:"Program mode" ~on:"program" ~off:"noprogram"
-
-let program = program_opt >>= function
- | Some b -> return b
- | None -> return (!program_mode)
+let program =
+ enable_attribute ~key:"program" ~default:(fun () -> !program_mode)
let locality = bool_attribute ~name:"Locality" ~on:"local" ~off:"global"
@@ -219,3 +237,6 @@ let only_polymorphism atts = parse polymorphic atts
let vernac_polymorphic_flag = ukey, VernacFlagList ["polymorphic", VernacFlagEmpty]
let vernac_monomorphic_flag = ukey, VernacFlagList ["monomorphic", VernacFlagEmpty]
+
+let canonical =
+ enable_attribute ~key:"canonical" ~default:(fun () -> true)
diff --git a/vernac/attributes.mli b/vernac/attributes.mli
index 3cb4d69ca0..44688ddafc 100644
--- a/vernac/attributes.mli
+++ b/vernac/attributes.mli
@@ -52,6 +52,7 @@ val program : bool attribute
val template : bool option attribute
val locality : bool option attribute
val deprecation : deprecation option attribute
+val canonical : bool attribute
val program_mode_option_name : string list
(** For internal use when messing with the global option. *)
diff --git a/vernac/classes.ml b/vernac/classes.ml
index 9f233a2551..05a75ab435 100644
--- a/vernac/classes.ml
+++ b/vernac/classes.ml
@@ -31,16 +31,6 @@ module NamedDecl = Context.Named.Declaration
open Decl_kinds
open Entries
-let refine_instance = ref false
-
-let () = Goptions.(declare_bool_option {
- optdepr = true;
- optname = "definition of instances by refining";
- optkey = ["Refine";"Instance";"Mode"];
- optread = (fun () -> !refine_instance);
- optwrite = (fun b -> refine_instance := b)
-})
-
let set_typeclass_transparency c local b =
Hints.add_hints ~local [typeclasses_db]
(Hints.HintsTransparencyEntry (Hints.HintsReferences [c], b))
@@ -374,6 +364,7 @@ let declare_instance_open ~pstate env sigma ?hook ~tac ~program_mode ~global ~po
let obls, constr, typ =
match term with
| Some t ->
+ let termtype = EConstr.of_constr termtype in
let obls, _, constr, typ =
Obligations.eterm_obligations env id sigma 0 t termtype
in obls, Some constr, typ
@@ -400,7 +391,7 @@ let declare_instance_open ~pstate env sigma ?hook ~tac ~program_mode ~global ~po
if not (Option.is_empty term) then
let init_refine =
Tacticals.New.tclTHENLIST [
- Refine.refine ~typecheck:false (fun sigma -> (sigma,EConstr.of_constr (Option.get term)));
+ Refine.refine ~typecheck:false (fun sigma -> (sigma, Option.get term));
Proofview.Unsafe.tclNEWGOALS (CList.map Proofview.with_empty_state gls);
Tactics.New.reduce_after_refine;
]
@@ -418,7 +409,7 @@ let declare_instance_open ~pstate env sigma ?hook ~tac ~program_mode ~global ~po
| None ->
pstate) ())
-let do_instance ~pstate env env' sigma ?hook ~refine ~tac ~global ~poly ~program_mode cty k u ctx ctx' pri decl imps subst id props =
+let do_instance ~pstate env env' sigma ?hook ~tac ~global ~poly ~program_mode cty k u ctx ctx' pri decl imps subst id props =
let props =
match props with
| Some (true, { CAst.v = CRecord fs }) ->
@@ -497,12 +488,12 @@ let do_instance ~pstate env env' sigma ?hook ~refine ~tac ~global ~poly ~program
(* Check that the type is free of evars now. *)
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
let pstate =
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;
+ let term = to_constr sigma (Option.get term) in
+ (declare_instance_constant k pri global imps ?hook id decl poly sigma term termtype;
None)
- else if program_mode || refine || Option.is_empty props then
+ else if program_mode || Option.is_empty props then
declare_instance_open ~pstate 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.") in
id, pstate
@@ -549,7 +540,7 @@ let interp_instance_context ~program_mode env ctx ?(generalize=false) pl bk cl =
sigma, cl, u, c', ctx', ctx, imps, args, decl
-let new_instance ~pstate ?(global=false) ?(refine= !refine_instance) ~program_mode
+let new_instance ~pstate ?(global=false) ~program_mode
poly ctx (instid, bk, cl) props
?(generalize=true) ?(tac:unit Proofview.tactic option) ?hook pri =
let env = Global.env() in
@@ -565,7 +556,7 @@ let new_instance ~pstate ?(global=false) ?(refine= !refine_instance) ~program_mo
Namegen.next_global_ident_away i (Termops.vars_of_env env)
in
let env' = push_rel_context ctx env in
- do_instance ~pstate env env' sigma ?hook ~refine ~tac ~global ~poly ~program_mode
+ do_instance ~pstate env env' sigma ?hook ~tac ~global ~poly ~program_mode
cty k u ctx ctx' pri decl imps subst id props
let declare_new_instance ?(global=false) ~program_mode poly ctx (instid, bk, cl) pri =
diff --git a/vernac/classes.mli b/vernac/classes.mli
index e7f90ff306..57bb9ce312 100644
--- a/vernac/classes.mli
+++ b/vernac/classes.mli
@@ -48,7 +48,6 @@ val declare_instance_constant :
val new_instance :
pstate:Proof_global.t option ->
?global:bool (** Not global by default. *) ->
- ?refine:bool (** Allow refinement *) ->
program_mode:bool ->
Decl_kinds.polymorphic ->
local_binder_expr list ->
diff --git a/vernac/comDefinition.ml b/vernac/comDefinition.ml
index 12df3215ad..d2c986fe5c 100644
--- a/vernac/comDefinition.ml
+++ b/vernac/comDefinition.ml
@@ -88,11 +88,12 @@ let do_definition ~ontop ~program_mode ?hook ident k univdecl bl red_option c ct
let (c,ctx), sideff = Future.force ce.const_entry_body in
assert(Safe_typing.empty_private_constants = sideff);
assert(Univ.ContextSet.is_empty ctx);
+ Obligations.check_evars env evd;
+ let c = EConstr.of_constr c in
let typ = match ce.const_entry_type with
- | Some t -> t
- | None -> EConstr.to_constr ~abort_on_undefined_evars:false evd (Retyping.get_type_of env evd (EConstr.of_constr c))
+ | Some t -> EConstr.of_constr t
+ | None -> Retyping.get_type_of env evd c
in
- Obligations.check_evars env evd;
let obls, _, c, cty =
Obligations.eterm_obligations env ident evd 0 c typ
in
diff --git a/vernac/comProgramFixpoint.ml b/vernac/comProgramFixpoint.ml
index 20a2db7ca2..69e2a209eb 100644
--- a/vernac/comProgramFixpoint.ml
+++ b/vernac/comProgramFixpoint.ml
@@ -230,12 +230,9 @@ let build_wellfounded (recname,pl,bl,arityc,body) poly r measure notation =
in
(* XXX: Capturing sigma here... bad bad *)
let hook = Lemmas.mk_hook (hook sigma) in
- (* XXX: Grounding non-ground terms here... bad bad *)
- let fullcoqc = EConstr.to_constr ~abort_on_undefined_evars:false sigma def in
- let fullctyp = EConstr.to_constr ~abort_on_undefined_evars:false sigma typ in
Obligations.check_evars env sigma;
let evars, _, evars_def, evars_typ =
- Obligations.eterm_obligations env recname sigma 0 fullcoqc fullctyp
+ Obligations.eterm_obligations env recname sigma 0 def typ
in
let ctx = Evd.evar_universe_context sigma in
ignore(Obligations.add_definition recname ~term:evars_def ~univdecl:decl
@@ -246,7 +243,7 @@ let out_def = function
| None -> user_err Pp.(str "Program Fixpoint needs defined bodies.")
let collect_evars_of_term evd c ty =
- let evars = Evar.Set.union (Evd.evars_of_term c) (Evd.evars_of_term ty) in
+ let evars = Evar.Set.union (Evd.evars_of_term evd c) (Evd.evars_of_term evd ty) in
Evar.Set.fold (fun ev acc -> Evd.add acc ev (Evd.find_undefined evd ev))
evars (Evd.from_ctx (Evd.evar_universe_context evd))
@@ -262,17 +259,13 @@ let do_program_recursive local poly fixkind fixl ntns =
let evd = nf_evar_map_undefined evd in
let collect_evars id def typ imps =
(* Generalize by the recursive prototypes *)
- let def =
- EConstr.to_constr ~abort_on_undefined_evars:false evd (Termops.it_mkNamedLambda_or_LetIn def rec_sign)
- and typ =
- (* Worrying... *)
- EConstr.to_constr ~abort_on_undefined_evars:false evd (Termops.it_mkNamedProd_or_LetIn typ rec_sign)
- in
+ let def = nf_evar evd (Termops.it_mkNamedLambda_or_LetIn def rec_sign) in
+ let typ = nf_evar evd (Termops.it_mkNamedProd_or_LetIn typ rec_sign) in
let evm = collect_evars_of_term evd def typ in
let evars, _, def, typ =
Obligations.eterm_obligations env id evm
- (List.length rec_sign) def typ
- in (id, def, typ, imps, evars)
+ (List.length rec_sign) def typ in
+ (id, def, typ, imps, evars)
in
let (fixnames,fixrs,fixdefs,fixtypes) = fix in
let fiximps = List.map pi2 info in
diff --git a/vernac/g_vernac.mlg b/vernac/g_vernac.mlg
index 59d2a66259..6438b48e32 100644
--- a/vernac/g_vernac.mlg
+++ b/vernac/g_vernac.mlg
@@ -43,6 +43,7 @@ let query_command = Entry.create "vernac:query_command"
let subprf = Entry.create "vernac:subprf"
+let quoted_attributes = Entry.create "vernac:quoted_attributes"
let class_rawexpr = Entry.create "vernac:class_rawexpr"
let thm_token = Entry.create "vernac:thm_token"
let def_body = Entry.create "vernac:def_body"
@@ -75,7 +76,7 @@ let parse_compat_version = let open Flags in function
}
GRAMMAR EXTEND Gram
- GLOBAL: vernac_control gallina_ext noedit_mode subprf;
+ GLOBAL: vernac_control quoted_attributes gallina_ext noedit_mode subprf;
vernac_control: FIRST
[ [ IDENT "Time"; c = vernac_control -> { CAst.make ~loc @@ VernacTime (false,c) }
| IDENT "Redirect"; s = ne_string; c = vernac_control -> { CAst.make ~loc @@ VernacRedirect (s, c) }
@@ -447,10 +448,12 @@ GRAMMAR EXTEND Gram
*)
(* ... with coercions *)
record_field:
- [ [ bd = record_binder; rf_priority = OPT [ "|"; n = natural -> { n } ];
+ [ [ attr = LIST0 quoted_attributes ;
+ bd = record_binder; rf_priority = OPT [ "|"; n = natural -> { n } ];
rf_notation = decl_notation -> {
+ let rf_canonical = attr |> List.flatten |> parse canonical in
let rf_subclass, rf_decl = bd in
- rf_decl, { rf_subclass ; rf_priority ; rf_notation } } ] ]
+ rf_decl, { rf_subclass ; rf_priority ; rf_notation ; rf_canonical } } ] ]
;
record_fields:
[ [ f = record_field; ";"; fs = record_fields -> { f :: fs }
@@ -1003,6 +1006,9 @@ GRAMMAR EXTEND Gram
| IDENT "Grammar"; ent = IDENT ->
(* This should be in "syntax" section but is here for factorization*)
{ PrintGrammar ent }
+ | IDENT "Custom"; IDENT "Grammar"; ent = IDENT ->
+ (* Should also be in "syntax" section *)
+ { PrintCustomGrammar ent }
| IDENT "LoadPath"; dir = OPT dirpath -> { PrintLoadPath dir }
| IDENT "Modules" ->
{ user_err Pp.(str "Print Modules is obsolete; use Print Libraries instead") }
diff --git a/vernac/himsg.ml b/vernac/himsg.ml
index f58eeae6dc..b2382ce6fc 100644
--- a/vernac/himsg.ml
+++ b/vernac/himsg.ml
@@ -1348,9 +1348,6 @@ let explain_pattern_matching_error env sigma = function
| CannotInferPredicate typs ->
explain_cannot_infer_predicate env sigma typs
-let map_pguard_error = map_pguard_error
-let map_ptype_error = map_ptype_error
-
let explain_reduction_tactic_error = function
| Tacred.InvalidAbstraction (env,sigma,c,(env',e)) ->
let e = map_ptype_error EConstr.of_constr e in
diff --git a/vernac/himsg.mli b/vernac/himsg.mli
index d0f42ea16b..d1c1c092e3 100644
--- a/vernac/himsg.mli
+++ b/vernac/himsg.mli
@@ -43,9 +43,4 @@ val explain_module_error : Modops.module_typing_error -> Pp.t
val explain_module_internalization_error :
Modintern.module_internalization_error -> Pp.t
-val map_pguard_error : ('c -> 'd) -> 'c pguard_error -> 'd pguard_error
-[@@ocaml.deprecated "Use [Type_errors.map_pguard_error]."]
-val map_ptype_error : ('c -> 'd) -> ('c, 'c) ptype_error -> ('d, 'd) ptype_error
-[@@ocaml.deprecated "Use [Type_errors.map_ptype_error]."]
-
val explain_prim_token_notation_error : string -> env -> Evd.evar_map -> Notation.prim_token_notation_error -> Pp.t
diff --git a/vernac/lemmas.ml b/vernac/lemmas.ml
index 1c7cc5e636..317cf487cc 100644
--- a/vernac/lemmas.ml
+++ b/vernac/lemmas.ml
@@ -75,13 +75,7 @@ let adjust_guardness_conditions const = function
List.interval 0 (List.length ((lam_assum c))))
lemma_guard (Array.to_list fixdefs) in
*)
- let fold env eff =
- try
- let _ = Environ.lookup_constant eff.seff_constant env in
- env
- with Not_found -> Environ.add_constant eff.seff_constant eff.seff_body env
- in
- let env = List.fold_left fold env (Safe_typing.side_effects_of_private_constants eff) in
+ let env = Safe_typing.push_private_constants env eff in
let indexes =
search_guard env
possible_indexes fixdecls in
@@ -395,10 +389,10 @@ let start_proof_with_initialization ~ontop ?hook kind sigma decl recguard thms s
maybe_declare_manual_implicits false ref imps;
call_hook ?hook ctx [] strength ref) thms_data in
let pstate = start_proof ~ontop id ~pl:decl kind sigma t ~hook ~compute_guard:guard in
- let pstate, _ = Proof_global.with_current_proof (fun _ p ->
+ let pstate = Proof_global.simple_with_current_proof (fun _ p ->
match init_tac with
- | None -> p,(true,[])
- | Some tac -> Proof.run_tactic Global.(env ()) tac p) pstate in
+ | None -> p
+ | Some tac -> pi1 @@ Proof.run_tactic Global.(env ()) tac p) pstate in
pstate
let start_proof_com ~program_mode ~ontop ?inference_hook ?hook kind thms =
diff --git a/vernac/metasyntax.ml b/vernac/metasyntax.ml
index 843296d24e..50914959dc 100644
--- a/vernac/metasyntax.ml
+++ b/vernac/metasyntax.ml
@@ -50,10 +50,10 @@ let pr_entry e =
str (Buffer.contents entry_buf)
let pr_registered_grammar name =
- let gram = try Some (Pcoq.find_grammars_by_name name) with Not_found -> None in
+ let gram = Pcoq.find_grammars_by_name name in
match gram with
- | None -> user_err Pp.(str "Unknown or unprintable grammar entry.")
- | Some entries ->
+ | [] -> user_err Pp.(str "Unknown or unprintable grammar entry.")
+ | entries ->
let pr_one (Pcoq.AnyEntry e) =
str "Entry " ++ str (Pcoq.Entry.name e) ++ str " is" ++ fnl () ++
pr_entry e
@@ -85,6 +85,8 @@ let pr_grammar = function
pr_entry Pvernac.Vernac_.gallina_ext
| name -> pr_registered_grammar name
+let pr_custom_grammar name = pr_registered_grammar ("constr:"^name)
+
(**********************************************************************)
(* Parse a format (every terminal starting with a letter or a single
quote (except a single quote alone) must be quoted) *)
diff --git a/vernac/metasyntax.mli b/vernac/metasyntax.mli
index 38dbdf7e41..6435df23c7 100644
--- a/vernac/metasyntax.mli
+++ b/vernac/metasyntax.mli
@@ -57,6 +57,7 @@ val add_syntactic_definition : env -> Id.t -> Id.t list * constr_expr ->
(** Print the Camlp5 state of a grammar *)
val pr_grammar : string -> Pp.t
+val pr_custom_grammar : string -> Pp.t
val check_infix_modifiers : syntax_modifier list -> unit
diff --git a/vernac/obligations.ml b/vernac/obligations.ml
index 1b1c618dc7..f768278dd7 100644
--- a/vernac/obligations.ml
+++ b/vernac/obligations.ml
@@ -39,7 +39,7 @@ let check_evars env evm =
type oblinfo =
{ ev_name: int * Id.t;
- ev_hyps: Constr.named_context;
+ ev_hyps: EConstr.named_context;
ev_status: bool * Evar_kinds.obligation_definition_status;
ev_chop: int option;
ev_src: Evar_kinds.t Loc.located;
@@ -50,11 +50,11 @@ type oblinfo =
(** Substitute evar references in t using de Bruijn indices,
where n binders were passed through. *)
-let subst_evar_constr evs n idf t =
+let subst_evar_constr evm evs n idf t =
let seen = ref Int.Set.empty in
let transparent = ref Id.Set.empty in
let evar_info id = List.assoc_f Evar.equal id evs in
- let rec substrec (depth, fixrels) c = match Constr.kind c with
+ let rec substrec (depth, fixrels) c = match EConstr.kind evm c with
| Evar (k, args) ->
let { ev_name = (id, idstr) ;
ev_hyps = hyps ; ev_chop = chop } =
@@ -84,18 +84,18 @@ let subst_evar_constr evs n idf t =
in aux hyps args []
in
if List.exists
- (fun x -> match Constr.kind x with
+ (fun x -> match EConstr.kind evm x with
| Rel n -> Int.List.mem n fixrels
| _ -> false) args
then
transparent := Id.Set.add idstr !transparent;
- mkApp (idf idstr, Array.of_list args)
+ EConstr.mkApp (idf idstr, Array.of_list args)
| Fix _ ->
- Constr.map_with_binders succfix substrec (depth, 1 :: fixrels) c
- | _ -> Constr.map_with_binders succfix substrec (depth, fixrels) c
+ EConstr.map_with_binders evm succfix substrec (depth, 1 :: fixrels) c
+ | _ -> EConstr.map_with_binders evm succfix substrec (depth, fixrels) c
in
let t' = substrec (0, []) t in
- t', !seen, !transparent
+ EConstr.to_constr evm t', !seen, !transparent
(** Substitute variable references in t using de Bruijn indices,
@@ -112,18 +112,18 @@ let subst_vars acc n t =
to a product : forall H1 : t1, ..., forall Hn : tn, concl.
Changes evars and hypothesis references to variable references.
*)
-let etype_of_evar evs hyps concl =
+let etype_of_evar evm evs hyps concl =
let open Context.Named.Declaration in
let rec aux acc n = function
decl :: tl ->
- let t', s, trans = subst_evar_constr evs n mkVar (NamedDecl.get_type decl) in
+ let t', s, trans = subst_evar_constr evm evs n EConstr.mkVar (NamedDecl.get_type decl) in
let t'' = subst_vars acc 0 t' in
let rest, s', trans' = aux (NamedDecl.get_id decl :: acc) (succ n) tl in
let s' = Int.Set.union s s' in
let trans' = Id.Set.union trans trans' in
(match decl with
| LocalDef (id,c,_) ->
- let c', s'', trans'' = subst_evar_constr evs n mkVar c in
+ let c', s'', trans'' = subst_evar_constr evm evs n EConstr.mkVar c in
let c' = subst_vars acc 0 c' in
mkNamedProd_or_LetIn (LocalDef (id, c', t'')) rest,
Int.Set.union s'' s',
@@ -131,7 +131,7 @@ let etype_of_evar evs hyps concl =
| LocalAssum (id,_) ->
mkNamedProd_or_LetIn (LocalAssum (id, t'')) rest, s', trans')
| [] ->
- let t', s, trans = subst_evar_constr evs n mkVar concl in
+ let t', s, trans = subst_evar_constr evm evs n EConstr.mkVar concl in
subst_vars acc 0 t', s, trans
in aux [] 0 (List.rev hyps)
@@ -151,7 +151,7 @@ let evar_dependencies evm oev =
let one_step deps =
Evar.Set.fold (fun ev s ->
let evi = Evd.find evm ev in
- let deps' = evars_of_filtered_evar_info evi in
+ let deps' = evars_of_filtered_evar_info evm evi in
if Evar.Set.mem oev deps' then
invalid_arg ("Ill-formed evar map: cycle detected for evar " ^ Pp.string_of_ppcmds @@ Evar.print oev)
else Evar.Set.union deps' s)
@@ -209,9 +209,7 @@ let eterm_obligations env name evm fs ?status t ty =
(fun (id, (n, nstr), ev) l ->
let hyps = Evd.evar_filtered_context ev in
let hyps = trunc_named_context nc_len hyps in
- let hyps = EConstr.Unsafe.to_named_context hyps in
- let concl = EConstr.Unsafe.to_constr ev.evar_concl in
- let evtyp, deps, transp = etype_of_evar l hyps concl in
+ let evtyp, deps, transp = etype_of_evar evm l hyps ev.evar_concl in
let evtyp, hyps, chop =
match chop_product fs evtyp with
| Some t -> t, trunc_named_context fs hyps, fs
@@ -237,9 +235,9 @@ let eterm_obligations env name evm fs ?status t ty =
evn []
in
let t', _, transparent = (* Substitute evar refs in the term by variables *)
- subst_evar_constr evts 0 mkVar t
+ subst_evar_constr evm evts 0 EConstr.mkVar t
in
- let ty, _, _ = subst_evar_constr evts 0 mkVar ty in
+ let ty, _, _ = subst_evar_constr evm evts 0 EConstr.mkVar ty in
let evars =
List.map (fun (ev, info) ->
let { ev_name = (_, name); ev_status = force_status, status;
@@ -252,7 +250,7 @@ let eterm_obligations env name evm fs ?status t ty =
in name, typ, src, (force_status, status), deps, tac) evts
in
let evnames = List.map (fun (ev, info) -> ev, snd info.ev_name) evts in
- let evmap f c = pi1 (subst_evar_constr evts 0 f c) in
+ let evmap f c = pi1 (subst_evar_constr evm evts 0 f c) in
Array.of_list (List.rev evars), (evnames, evmap), t', ty
let hide_obligation () =
diff --git a/vernac/obligations.mli b/vernac/obligations.mli
index d25daeed9c..9214ddd4b9 100644
--- a/vernac/obligations.mli
+++ b/vernac/obligations.mli
@@ -26,14 +26,14 @@ val sort_dependencies : (Evar.t * evar_info * Evar.Set.t) list -> (Evar.t * evar
(* env, id, evars, number of function prototypes to try to clear from
evars contexts, object and type *)
val eterm_obligations : env -> Id.t -> evar_map -> int ->
- ?status:Evar_kinds.obligation_definition_status -> constr -> types ->
+ ?status:Evar_kinds.obligation_definition_status -> EConstr.constr -> EConstr.types ->
(Id.t * types * Evar_kinds.t Loc.located *
(bool * Evar_kinds.obligation_definition_status) * Int.Set.t *
unit Proofview.tactic option) array
(* Existential key, obl. name, type as product,
location of the original evar, associated tactic,
status and dependencies as indexes into the array *)
- * ((Evar.t * Id.t) list * ((Id.t -> constr) -> constr -> constr)) *
+ * ((Evar.t * Id.t) list * ((Id.t -> EConstr.constr) -> EConstr.constr -> constr)) *
constr * types
(* Translations from existential identifiers to obligation identifiers
and for terms with existentials to closed terms, given a
diff --git a/vernac/ppvernac.ml b/vernac/ppvernac.ml
index 889dbafabd..f2332bab8b 100644
--- a/vernac/ppvernac.ml
+++ b/vernac/ppvernac.ml
@@ -476,6 +476,8 @@ open Pputils
keyword "Print Section" ++ spc() ++ Libnames.pr_qualid s
| PrintGrammar ent ->
keyword "Print Grammar" ++ spc() ++ str ent
+ | PrintCustomGrammar ent ->
+ keyword "Print Custom Grammar" ++ spc() ++ str ent
| PrintLoadPath dir ->
keyword "Print LoadPath" ++ pr_opt DirPath.print dir
| PrintModules ->
diff --git a/vernac/record.ml b/vernac/record.ml
index f489707eb3..f737a8c524 100644
--- a/vernac/record.ml
+++ b/vernac/record.ml
@@ -276,8 +276,13 @@ let instantiate_possibly_recursive_type ind u ntypes paramdecls fields =
let subst' = List.init ntypes (fun i -> mkIndU ((ind, ntypes - i - 1), u)) in
Termops.substl_rel_context (subst @ subst') fields
+type projection_flags = {
+ pf_subclass: bool;
+ pf_canonical: bool;
+}
+
(* We build projections *)
-let declare_projections indsp ctx ?(kind=StructureComponent) binder_name coers fieldimpls fields =
+let declare_projections indsp ctx ?(kind=StructureComponent) binder_name flags fieldimpls fields =
let env = Global.env() in
let (mib,mip) = Global.lookup_inductive indsp in
let poly = Declareops.inductive_is_polymorphic mib in
@@ -299,7 +304,7 @@ let declare_projections indsp ctx ?(kind=StructureComponent) binder_name coers f
in
let (_,_,kinds,sp_projs,_) =
List.fold_left3
- (fun (nfi,i,kinds,sp_projs,subst) coe decl impls ->
+ (fun (nfi,i,kinds,sp_projs,subst) flags decl impls ->
let fi = RelDecl.get_name decl in
let ti = RelDecl.get_type decl in
let (sp_projs,i,subst) =
@@ -359,17 +364,17 @@ let declare_projections indsp ctx ?(kind=StructureComponent) binder_name coers f
in
let refi = ConstRef kn in
Impargs.maybe_declare_manual_implicits false refi impls;
- if coe then begin
+ if flags.pf_subclass then begin
let cl = Class.class_of_global (IndRef indsp) in
Class.try_add_new_coercion_with_source refi ~local:false poly ~source:cl
end;
let i = if is_local_assum decl then i+1 else i in
(Some kn::sp_projs, i, Projection term::subst)
with NotDefinable why ->
- warning_or_error coe indsp why;
+ warning_or_error flags.pf_subclass indsp why;
(None::sp_projs,i,NoProjection fi::subst) in
- (nfi-1,i,(fi, is_local_assum decl)::kinds,sp_projs,subst))
- (List.length fields,0,[],[],[]) coers (List.rev fields) (List.rev fieldimpls)
+ (nfi - 1, i, { Recordops.pk_name = fi ; pk_true_proj = is_local_assum decl ; pk_canonical = flags.pf_canonical } :: kinds, sp_projs, subst))
+ (List.length fields,0,[],[],[]) flags (List.rev fields) (List.rev fieldimpls)
in (kinds,sp_projs)
open Typeclasses
@@ -525,7 +530,8 @@ let declare_class def cum ubinders univs id idbuild paramimpls params arity
in
[cref, [Name proj_name, sub, Some proj_cst]]
| _ ->
- let record_data = [id, idbuild, arity, fieldimpls, fields, false, List.map (fun _ -> false) fields] in
+ let record_data = [id, idbuild, arity, fieldimpls, fields, false,
+ List.map (fun _ -> { pf_subclass = false ; pf_canonical = true }) fields] in
let inds = declare_structure ~cum Declarations.BiFinite ubinders univs paramimpls
params template ~kind:Method ~name:[|binder_name|] record_data
in
@@ -699,7 +705,11 @@ let definition_structure udecl kind ~template cum poly finite records =
let map impls = implpars @ Impargs.lift_implicits (succ (List.length params)) impls in
let data = List.map (fun (arity, implfs, fields) -> (arity, List.map map implfs, fields)) data in
let map (arity, implfs, fields) (is_coe, id, _, cfs, idbuild, _) =
- let coe = List.map (fun (_, { rf_subclass }) -> not (Option.is_empty rf_subclass)) cfs in
+ let coe = List.map (fun (_, { rf_subclass ; rf_canonical }) ->
+ { pf_subclass = not (Option.is_empty rf_subclass);
+ pf_canonical = rf_canonical })
+ cfs
+ in
id.CAst.v, idbuild, arity, implfs, fields, is_coe, coe
in
let data = List.map2 map data records in
diff --git a/vernac/record.mli b/vernac/record.mli
index d6e63901cd..24bb27e107 100644
--- a/vernac/record.mli
+++ b/vernac/record.mli
@@ -14,15 +14,20 @@ open Constrexpr
val primitive_flag : bool ref
+type projection_flags = {
+ pf_subclass: bool;
+ pf_canonical: bool;
+}
+
val declare_projections :
inductive ->
Entries.universes_entry ->
?kind:Decl_kinds.definition_object_kind ->
Id.t ->
- bool list ->
+ projection_flags list ->
Impargs.manual_implicits list ->
Constr.rel_context ->
- (Name.t * bool) list * Constant.t option list
+ Recordops.proj_kind list * Constant.t option list
val declare_structure_entry : Recordops.struc_tuple -> unit
diff --git a/vernac/topfmt.ml b/vernac/topfmt.ml
index 118c126970..bf2efb2542 100644
--- a/vernac/topfmt.ml
+++ b/vernac/topfmt.ml
@@ -201,7 +201,7 @@ let set_emacs_print_strings () =
let diff = "diff." in
List.iter (fun b ->
let (name, attrs) = b in
- if diff = (String.sub name 0 (String.length diff)) then
+ if CString.is_sub diff name 0 then
tag_map := CString.Map.add name
{ attrs with prefix = Some (Printf.sprintf "<%s>" name);
suffix = Some (Printf.sprintf "</%s>" name) }
diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml
index 279d4f0935..e1d134f3a9 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -744,7 +744,7 @@ let vernac_inductive ~atts cum lo finite indl =
let (coe, (lid, ce)) = l in
let coe' = if coe then Some true else None in
let f = AssumExpr ((make ?loc:lid.loc @@ Name lid.v), ce),
- { rf_subclass = coe' ; rf_priority = None ; rf_notation = [] } in
+ { rf_subclass = coe' ; rf_priority = None ; rf_notation = [] ; rf_canonical = true } in
vernac_record ~template udecl cum (Class true) poly finite [id, bl, c, None, [f]]
else if List.for_all is_record indl then
(* Mutual record case *)
@@ -1885,6 +1885,7 @@ let vernac_print ~(pstate : Proof_global.t option) ~atts =
| PrintSectionContext qid -> print_sec_context_typ env sigma qid
| PrintInspect n -> inspect env sigma n
| PrintGrammar ent -> Metasyntax.pr_grammar ent
+ | PrintCustomGrammar ent -> Metasyntax.pr_custom_grammar ent
| PrintLoadPath dir -> (* For compatibility ? *) print_loadpath dir
| PrintModules -> print_modules ()
| PrintModule qid -> print_module qid
diff --git a/vernac/vernacexpr.ml b/vernac/vernacexpr.ml
index 34a9b9394a..23633e39ab 100644
--- a/vernac/vernacexpr.ml
+++ b/vernac/vernacexpr.ml
@@ -29,6 +29,7 @@ type printable =
| PrintSectionContext of qualid
| PrintInspect of int
| PrintGrammar of string
+ | PrintCustomGrammar of string
| PrintLoadPath of DirPath.t option
| PrintModules
| PrintModule of qualid
@@ -148,6 +149,7 @@ type record_field_attr = {
rf_subclass: instance_flag; (* the projection is an implicit coercion or an instance *)
rf_priority: int option; (* priority of the instance, if relevant *)
rf_notation: decl_notation list;
+ rf_canonical: bool; (* use this projection in the search for canonical instances *)
}
type constructor_expr = (lident * constr_expr) with_coercion
type constructor_list_or_record_decl_expr =
diff --git a/vernac/vernacextend.ml b/vernac/vernacextend.ml
index ef06e59316..730f5fd6da 100644
--- a/vernac/vernacextend.ml
+++ b/vernac/vernacextend.ml
@@ -36,7 +36,6 @@ type vernac_type =
| VtProofMode of string
(* To be removed *)
| VtMeta
- | VtUnknown
and vernac_start = opacity_guarantee * Names.Id.t list
and vernac_sideff_type = Names.Id.t list
and opacity_guarantee =
diff --git a/vernac/vernacextend.mli b/vernac/vernacextend.mli
index 4d89eaffd9..54e08d0e95 100644
--- a/vernac/vernacextend.mli
+++ b/vernac/vernacextend.mli
@@ -52,7 +52,6 @@ type vernac_type =
| VtProofMode of string
(* To be removed *)
| VtMeta
- | VtUnknown
and vernac_start = opacity_guarantee * Names.Id.t list
and vernac_sideff_type = Names.Id.t list
and opacity_guarantee =