aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/changelog/01-kernel/12738-fix-sr-cumul-inds.rst5
-rw-r--r--doc/changelog/01-kernel/13356-primarray-cumul.rst5
-rw-r--r--doc/changelog/02-specification-language/12653-cumul-syntax.rst5
-rw-r--r--doc/changelog/02-specification-language/12768-master+warn-non-underscore-catch-all-pattern-matching.rst7
-rw-r--r--doc/changelog/02-specification-language/13183-using-att.rst6
-rw-r--r--doc/changelog/02-specification-language/13188-instance-gen.rst6
-rw-r--r--doc/changelog/02-specification-language/13217-master+fix13216-typeclass-for-match-return-clause.rst5
-rw-r--r--doc/changelog/02-specification-language/13290-master+grant13278-small-inversion-in-prop.rst6
-rw-r--r--doc/changelog/02-specification-language/13376-master+minifix-NotFoundInstance.rst5
-rw-r--r--doc/changelog/02-specification-language/13383-master+fix11816-wf-not-allowed-in-local-fixpoint.rst5
-rw-r--r--doc/changelog/02-specification-language/13387-master+fix12348-debruijn-bug-imitation.rst6
-rw-r--r--doc/changelog/03-notations/12099-master+constraining-terms-occurring-also-as-pattern-in-notations.rst4
-rw-r--r--doc/changelog/03-notations/12218-numeral-notations-non-inductive.rst19
-rw-r--r--doc/changelog/03-notations/12685-master+propagate-scope-in-indirect-applied-ref.rst6
-rw-r--r--doc/changelog/03-notations/12946-master+fix12908-part1-collision-lonely-notation-printing.rst6
-rw-r--r--doc/changelog/03-notations/13026-master+fix-printing-custom-no-level-8.2.rst7
-rw-r--r--doc/changelog/03-notations/13067-master+fix-display-parentheses-default-coqide.rst5
-rw-r--r--doc/changelog/03-notations/13092-master+fix-13078-no-binder-in-pattern-notation.rst5
-rw-r--r--doc/changelog/04-tactics/12816-master+fix12787-K-redex-injection-anomaly.rst6
-rw-r--r--doc/changelog/04-tactics/12847-master+inversion-works-with-eq-in-type.rst6
-rw-r--r--doc/changelog/04-tactics/13337-master+improve-error-dependent-intro-wildcard.rst6
-rw-r--r--doc/changelog/04-tactics/13373-master+fix13363-metas-posed-to-evars-in-wrong-env.rst6
-rw-r--r--doc/changelog/04-tactics/13381-bfs_eauto.rst6
-rw-r--r--doc/changelog/05-tactic-language/13232-ltac2-if-then-else.rst5
-rw-r--r--doc/changelog/06-ssreflect/12857-changelog-for-12857.rst8
-rw-r--r--doc/changelog/06-ssreflect/13317-ssr_dup_swap_apply_ipat.rst4
-rw-r--r--doc/changelog/07-commands-and-options/12516-deprecate-grab-existentials.rst4
-rw-r--r--doc/changelog/07-commands-and-options/13040-gc+best_fit.rst9
-rw-r--r--doc/changelog/07-commands-and-options/13139-clean-hint-constr.rst6
-rw-r--r--doc/changelog/07-commands-and-options/13255-master+fix13244-use-coercions-in-search.rst7
-rw-r--r--doc/changelog/07-commands-and-options/13339-proof-using-noinit.rst5
-rw-r--r--doc/changelog/07-commands-and-options/13345-master+doc-add-ml-path-not-exported.rst5
-rw-r--r--doc/changelog/07-commands-and-options/13384-warn-unqualified-hint.rst8
-rw-r--r--doc/changelog/07-commands-and-options/13388-export-locality-for-all-hint-commands.rst6
-rw-r--r--doc/changelog/08-tools/12754-master+fix-coqdoc-index-escaping.rst6
-rw-r--r--doc/changelog/08-tools/12772-fix-details.rst5
-rw-r--r--doc/changelog/08-tools/13063-fix-no-output-sync-make-file.rst6
-rw-r--r--doc/changelog/09-coqide/13145-master+coqide-printing-goal-names-support.rst4
-rw-r--r--doc/changelog/10-standard-library/12420-decidable.rst4
-rw-r--r--doc/changelog/10-standard-library/13365-axiom-free-wf.rst4
-rw-r--r--doc/changelog/11-infrastructure-and-dependencies/12864-fix-approve-output.rst5
-rw-r--r--doc/changelog/11-infrastructure-and-dependencies/12972-ocaml+4_11.rst4
-rw-r--r--doc/changelog/11-infrastructure-and-dependencies/13011-sphinx-3.rst5
-rw-r--r--doc/sphinx/README.rst2
-rw-r--r--doc/sphinx/README.template.rst2
-rw-r--r--doc/sphinx/_static/coqdoc.css4
-rw-r--r--doc/sphinx/addendum/extraction.rst190
-rw-r--r--doc/sphinx/addendum/generalized-rewriting.rst70
-rw-r--r--doc/sphinx/addendum/implicit-coercions.rst66
-rw-r--r--doc/sphinx/addendum/micromega.rst82
-rw-r--r--doc/sphinx/addendum/miscellaneous-extensions.rst8
-rw-r--r--doc/sphinx/addendum/nsatz.rst78
-rw-r--r--doc/sphinx/addendum/omega.rst2
-rw-r--r--doc/sphinx/addendum/parallel-proof-processing.rst46
-rw-r--r--doc/sphinx/addendum/program.rst152
-rw-r--r--doc/sphinx/addendum/ring.rst164
-rw-r--r--doc/sphinx/addendum/sprop.rst4
-rw-r--r--doc/sphinx/addendum/type-classes.rst222
-rw-r--r--doc/sphinx/addendum/universe-polymorphism.rst58
-rw-r--r--doc/sphinx/changes.rst366
-rwxr-xr-xdoc/sphinx/conf.py2
-rw-r--r--doc/sphinx/history.rst58
-rw-r--r--doc/sphinx/introduction.rst2
-rw-r--r--doc/sphinx/language/cic.rst14
-rw-r--r--doc/sphinx/language/coq-library.rst18
-rw-r--r--doc/sphinx/language/core/assumptions.rst8
-rw-r--r--doc/sphinx/language/core/basic.rst52
-rw-r--r--doc/sphinx/language/core/coinductive.rst4
-rw-r--r--doc/sphinx/language/core/conversion.rst2
-rw-r--r--doc/sphinx/language/core/definitions.rst27
-rw-r--r--doc/sphinx/language/core/inductive.rst39
-rw-r--r--doc/sphinx/language/core/modules.rst34
-rw-r--r--doc/sphinx/language/core/primitive.rst2
-rw-r--r--doc/sphinx/language/core/records.rst21
-rw-r--r--doc/sphinx/language/core/variants.rst1
-rw-r--r--doc/sphinx/language/extensions/arguments-command.rst3
-rw-r--r--doc/sphinx/language/extensions/canonical.rst20
-rw-r--r--doc/sphinx/language/extensions/evars.rst2
-rw-r--r--doc/sphinx/language/extensions/implicit-arguments.rst10
-rw-r--r--doc/sphinx/language/extensions/match.rst58
-rw-r--r--doc/sphinx/practical-tools/coq-commands.rst76
-rw-r--r--doc/sphinx/practical-tools/coqide.rst44
-rw-r--r--doc/sphinx/practical-tools/utilities.rst54
-rw-r--r--doc/sphinx/proof-engine/ltac.rst41
-rw-r--r--doc/sphinx/proof-engine/ltac2.rst42
-rw-r--r--doc/sphinx/proof-engine/proof-handling.rst915
-rw-r--r--doc/sphinx/proof-engine/ssreflect-proof-language.rst91
-rw-r--r--doc/sphinx/proof-engine/tactics.rst2097
-rw-r--r--doc/sphinx/proof-engine/vernacular-commands.rst115
-rw-r--r--doc/sphinx/proofs/automatic-tactics/auto.rst689
-rw-r--r--doc/sphinx/proofs/automatic-tactics/index.rst10
-rw-r--r--doc/sphinx/proofs/automatic-tactics/logic.rst228
-rw-r--r--doc/sphinx/proofs/writing-proofs/index.rst9
-rw-r--r--doc/sphinx/proofs/writing-proofs/proof-mode.rst1043
-rw-r--r--doc/sphinx/proofs/writing-proofs/rewriting.rst857
-rw-r--r--doc/sphinx/refman-preamble.rst6
-rw-r--r--doc/sphinx/user-extensions/proof-schemes.rst81
-rw-r--r--doc/sphinx/user-extensions/syntax-extensions.rst416
-rw-r--r--doc/sphinx/using/libraries/funind.rst94
-rw-r--r--doc/sphinx/using/libraries/writing.rst2
-rw-r--r--doc/sphinx/using/tools/coqdoc.rst50
-rw-r--r--doc/stdlib/hidden-files1
-rw-r--r--doc/stdlib/index-list.html.template5
-rw-r--r--doc/tools/coqrst/notations/TacticNotations.g3
-rw-r--r--doc/tools/coqrst/notations/TacticNotationsLexer.py59
-rw-r--r--doc/tools/docgram/README.md4
-rw-r--r--doc/tools/docgram/common.edit_mlg1460
-rw-r--r--doc/tools/docgram/doc_grammar.ml133
-rw-r--r--doc/tools/docgram/dune6
-rw-r--r--doc/tools/docgram/fullGrammar1310
-rw-r--r--doc/tools/docgram/orderedGrammar604
111 files changed, 7222 insertions, 5469 deletions
diff --git a/doc/changelog/01-kernel/12738-fix-sr-cumul-inds.rst b/doc/changelog/01-kernel/12738-fix-sr-cumul-inds.rst
deleted file mode 100644
index 1bf62de3fd..0000000000
--- a/doc/changelog/01-kernel/12738-fix-sr-cumul-inds.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-- **Fixed:** Incompleteness of conversion checking on problems
- involving :ref:`eta-expansion` and :ref:`cumulative universe
- polymorphic inductive types <cumulative>` (`#12738
- <https://github.com/coq/coq/pull/12738>`_, fixes `#7015
- <https://github.com/coq/coq/issues/7015>`_, by Gaëtan Gilbert).
diff --git a/doc/changelog/01-kernel/13356-primarray-cumul.rst b/doc/changelog/01-kernel/13356-primarray-cumul.rst
new file mode 100644
index 0000000000..978ca325bf
--- /dev/null
+++ b/doc/changelog/01-kernel/13356-primarray-cumul.rst
@@ -0,0 +1,5 @@
+- **Changed:** Primitive arrays are now irrelevant in their single
+ polymorphic universe (same as a polymorphic cumulative list
+ inductive would be) (`#13356
+ <https://github.com/coq/coq/pull/13356>`_, fixes `#13354
+ <https://github.com/coq/coq/issues/13354>`_, by Gaëtan Gilbert).
diff --git a/doc/changelog/02-specification-language/12653-cumul-syntax.rst b/doc/changelog/02-specification-language/12653-cumul-syntax.rst
new file mode 100644
index 0000000000..ba97f7c796
--- /dev/null
+++ b/doc/changelog/02-specification-language/12653-cumul-syntax.rst
@@ -0,0 +1,5 @@
+- **Added:** Commands :cmd:`Inductive`, :cmd:`Record` and synonyms now
+ support syntax `Inductive foo@{=i +j *k l}` to specify variance
+ information for their universes (in :ref:`Cumulative <cumulative>`
+ mode) (`#12653 <https://github.com/coq/coq/pull/12653>`_, by Gaëtan
+ Gilbert).
diff --git a/doc/changelog/02-specification-language/12768-master+warn-non-underscore-catch-all-pattern-matching.rst b/doc/changelog/02-specification-language/12768-master+warn-non-underscore-catch-all-pattern-matching.rst
new file mode 100644
index 0000000000..c9e941743c
--- /dev/null
+++ b/doc/changelog/02-specification-language/12768-master+warn-non-underscore-catch-all-pattern-matching.rst
@@ -0,0 +1,7 @@
+- **Added:**
+ Warning on unused variables in pattern-matching branches of
+ :n:`match` serving as catch-all branches for at least two distinct
+ patterns.
+ (`#12768 <https://github.com/coq/coq/pull/12768>`_,
+ fixes `#12762 <https://github.com/coq/coq/issues/12762>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/02-specification-language/13183-using-att.rst b/doc/changelog/02-specification-language/13183-using-att.rst
new file mode 100644
index 0000000000..c380d932ed
--- /dev/null
+++ b/doc/changelog/02-specification-language/13183-using-att.rst
@@ -0,0 +1,6 @@
+- **Added:**
+ Definition and (Co)Fixpoint now support the :attr:`using` attribute.
+ It has the same effect as :cmd:`Proof using`, which is only available in
+ interactive mode.
+ (`#13183 <https://github.com/coq/coq/pull/13183>`_,
+ by Enrico Tassi).
diff --git a/doc/changelog/02-specification-language/13188-instance-gen.rst b/doc/changelog/02-specification-language/13188-instance-gen.rst
new file mode 100644
index 0000000000..6a431f85ed
--- /dev/null
+++ b/doc/changelog/02-specification-language/13188-instance-gen.rst
@@ -0,0 +1,6 @@
+- **Removed:** The type given to :cmd:`Instance` is no longer automatically
+ generalized over unbound and :ref:`generalizable <implicit-generalization>` variables.
+ Use :n:`Instance : \`{@type}` instead of :n:`Instance : @type` to get the old behaviour, or
+ enable the compatibility flag :flag:`Instance Generalized Output`.
+ (`#13188 <https://github.com/coq/coq/pull/13188>`_, fixes `#6042
+ <https://github.com/coq/coq/issues/6042>`_, by Gaëtan Gilbert).
diff --git a/doc/changelog/02-specification-language/13217-master+fix13216-typeclass-for-match-return-clause.rst b/doc/changelog/02-specification-language/13217-master+fix13216-typeclass-for-match-return-clause.rst
new file mode 100644
index 0000000000..2d8230b965
--- /dev/null
+++ b/doc/changelog/02-specification-language/13217-master+fix13216-typeclass-for-match-return-clause.rst
@@ -0,0 +1,5 @@
+- **Fixed:**
+ Allow use of type classes inference for the return predicate of a :n:`match`
+ (was deactivated in versions 8.10 to 8.12, `#13217 <https://github.com/coq/coq/pull/13217>`_,
+ fixes `#13216 <https://github.com/coq/coq/issues/13216>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/02-specification-language/13290-master+grant13278-small-inversion-in-prop.rst b/doc/changelog/02-specification-language/13290-master+grant13278-small-inversion-in-prop.rst
new file mode 100644
index 0000000000..bf792fda6d
--- /dev/null
+++ b/doc/changelog/02-specification-language/13290-master+grant13278-small-inversion-in-prop.rst
@@ -0,0 +1,6 @@
+- **Added:**
+ Inference of return predicate of a :g:`match` by inversion takes
+ sort elimination constraints into account
+ (`#13290 <https://github.com/coq/coq/pull/13290>`_,
+ grants `#13278 <https://github.com/coq/coq/issues/13278>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/02-specification-language/13376-master+minifix-NotFoundInstance.rst b/doc/changelog/02-specification-language/13376-master+minifix-NotFoundInstance.rst
new file mode 100644
index 0000000000..5758f35c3d
--- /dev/null
+++ b/doc/changelog/02-specification-language/13376-master+minifix-NotFoundInstance.rst
@@ -0,0 +1,5 @@
+- **Fixed:**
+ A case of unification raising an anomaly IllTypedInstance
+ (`#13376 <https://github.com/coq/coq/pull/13376>`_,
+ fixes `#13266 <https://github.com/coq/coq/issues/13266>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/02-specification-language/13383-master+fix11816-wf-not-allowed-in-local-fixpoint.rst b/doc/changelog/02-specification-language/13383-master+fix11816-wf-not-allowed-in-local-fixpoint.rst
new file mode 100644
index 0000000000..c0e5a81641
--- /dev/null
+++ b/doc/changelog/02-specification-language/13383-master+fix11816-wf-not-allowed-in-local-fixpoint.rst
@@ -0,0 +1,5 @@
+- **Fixed:**
+ Using :n:`{wf ...}` in local fixpoints is an error, not an anomaly
+ (`#13383 <https://github.com/coq/coq/pull/13383>`_,
+ fixes `#11816 <https://github.com/coq/coq/issues/11816>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/02-specification-language/13387-master+fix12348-debruijn-bug-imitation.rst b/doc/changelog/02-specification-language/13387-master+fix12348-debruijn-bug-imitation.rst
new file mode 100644
index 0000000000..eaf049dc97
--- /dev/null
+++ b/doc/changelog/02-specification-language/13387-master+fix12348-debruijn-bug-imitation.rst
@@ -0,0 +1,6 @@
+- **Fixed:**
+ A bug producing ill-typed instances of existential variables when let-ins
+ interleaved with assumptions
+ (`#13387 <https://github.com/coq/coq/pull/13387>`_,
+ fixes `#12348 <https://github.com/coq/coq/issues/13387>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/03-notations/12099-master+constraining-terms-occurring-also-as-pattern-in-notations.rst b/doc/changelog/03-notations/12099-master+constraining-terms-occurring-also-as-pattern-in-notations.rst
new file mode 100644
index 0000000000..e9b02aed6d
--- /dev/null
+++ b/doc/changelog/03-notations/12099-master+constraining-terms-occurring-also-as-pattern-in-notations.rst
@@ -0,0 +1,4 @@
+- **Changed:**
+ Improved support for notations/abbreviations with mixed terms and patterns (such as the forcing modality)
+ (`#12099 <https://github.com/coq/coq/pull/12099>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/03-notations/12218-numeral-notations-non-inductive.rst b/doc/changelog/03-notations/12218-numeral-notations-non-inductive.rst
new file mode 100644
index 0000000000..5ea37e7494
--- /dev/null
+++ b/doc/changelog/03-notations/12218-numeral-notations-non-inductive.rst
@@ -0,0 +1,19 @@
+- **Deprecated**
+ ``Numeral.v`` is deprecated, please use ``Number.v`` instead.
+- **Changed**
+ Rational and real constants are parsed differently.
+ The exponent is now encoded separately from the fractional part
+ using ``Z.pow_pos``. This way, parsing large exponents can no longer
+ blow up and constants are printed in a form closer to the one they
+ were parsed (i.e., ``102e-2`` is reprinted as such and not ``1.02``).
+- **Removed**
+ OCaml parser and printer for real constants have been removed.
+ Real constants are now handled with proven Coq code.
+- **Added:**
+ :ref:`Number Notation <number-notations>` and :ref:`String Notation
+ <string-notations>` commands now
+ support parameterized inductive and non inductive types
+ (`#12218 <https://github.com/coq/coq/pull/12218>`_,
+ fixes `#12035 <https://github.com/coq/coq/issues/12035>`_,
+ by Pierre Roux, review by Jason Gross and Jim Fehrle for the
+ reference manual).
diff --git a/doc/changelog/03-notations/12685-master+propagate-scope-in-indirect-applied-ref.rst b/doc/changelog/03-notations/12685-master+propagate-scope-in-indirect-applied-ref.rst
new file mode 100644
index 0000000000..048835a0e9
--- /dev/null
+++ b/doc/changelog/03-notations/12685-master+propagate-scope-in-indirect-applied-ref.rst
@@ -0,0 +1,6 @@
+- **Changed:**
+ Scope information is propagated in indirect applications to a
+ reference prefixed with :g:`@@`; this covers for instance the case
+ :g:`r.(@@p) t` where scope information from :g:`p` is now taken into
+ account for interpreting :g:`t` (`#12685
+ <https://github.com/coq/coq/pull/12685>`_, by Hugo Herbelin).
diff --git a/doc/changelog/03-notations/12946-master+fix12908-part1-collision-lonely-notation-printing.rst b/doc/changelog/03-notations/12946-master+fix12908-part1-collision-lonely-notation-printing.rst
deleted file mode 100644
index 95a9093272..0000000000
--- a/doc/changelog/03-notations/12946-master+fix12908-part1-collision-lonely-notation-printing.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-- **Fixed:**
- Undetected collision between a lonely notation and a notation in
- scope at printing time
- (`#12946 <https://github.com/coq/coq/pull/12946>`_,
- fixes the first part of `#12908 <https://github.com/coq/coq/issues/12908>`_,
- by Hugo Herbelin).
diff --git a/doc/changelog/03-notations/13026-master+fix-printing-custom-no-level-8.2.rst b/doc/changelog/03-notations/13026-master+fix-printing-custom-no-level-8.2.rst
deleted file mode 100644
index 42b62eed75..0000000000
--- a/doc/changelog/03-notations/13026-master+fix-printing-custom-no-level-8.2.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-- **Fixed:**
- Fixing printing of notations in custom entries with
- variables not mentioning an explicit level
- (`#13026 <https://github.com/coq/coq/pull/13026>`_,
- fixes `#12775 <https://github.com/coq/coq/issues/12775>`_
- and `#13018 <https://github.com/coq/coq/issues/13018>`_,
- by Hugo Herbelin).
diff --git a/doc/changelog/03-notations/13067-master+fix-display-parentheses-default-coqide.rst b/doc/changelog/03-notations/13067-master+fix-display-parentheses-default-coqide.rst
deleted file mode 100644
index 50aa4a9052..0000000000
--- a/doc/changelog/03-notations/13067-master+fix-display-parentheses-default-coqide.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-- **Fixed:**
- Repairing option :g:`Display parentheses` in CoqIDE
- (`#12794 <https://github.com/coq/coq/pull/12794>`_ and `#13067 <https://github.com/coq/coq/pull/13067>`_,
- fixes `#12793 <https://github.com/coq/coq/issues/12793>`_,
- by Jean-Christophe Léchenet and Hugo Herbelin).
diff --git a/doc/changelog/03-notations/13092-master+fix-13078-no-binder-in-pattern-notation.rst b/doc/changelog/03-notations/13092-master+fix-13078-no-binder-in-pattern-notation.rst
new file mode 100644
index 0000000000..fb12c91729
--- /dev/null
+++ b/doc/changelog/03-notations/13092-master+fix-13078-no-binder-in-pattern-notation.rst
@@ -0,0 +1,5 @@
+- **Fixed:**
+ Preventing notations for constructors to involve binders
+ (`#13092 <https://github.com/coq/coq/pull/13092>`_,
+ fixes `#13078 <https://github.com/coq/coq/issues/13078>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/04-tactics/12816-master+fix12787-K-redex-injection-anomaly.rst b/doc/changelog/04-tactics/12816-master+fix12787-K-redex-injection-anomaly.rst
deleted file mode 100644
index 289d17167d..0000000000
--- a/doc/changelog/04-tactics/12816-master+fix12787-K-redex-injection-anomaly.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-- **Fixed:**
- Anomaly with :tacn:`injection` involving artificial
- dependencies disappearing by reduction
- (`#12816 <https://github.com/coq/coq/pull/12816>`_,
- fixes `#12787 <https://github.com/coq/coq/issues/12787>`_,
- by Hugo Herbelin).
diff --git a/doc/changelog/04-tactics/12847-master+inversion-works-with-eq-in-type.rst b/doc/changelog/04-tactics/12847-master+inversion-works-with-eq-in-type.rst
deleted file mode 100644
index b444a2f436..0000000000
--- a/doc/changelog/04-tactics/12847-master+inversion-works-with-eq-in-type.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-- **Added:**
- :tacn:`replace` and :tacn:`inversion` support registration of a
- :g:`core.identity`-like equality in :g:`Type`, such as HoTT's :g:`path`
- (`#12847 <https://github.com/coq/coq/pull/12847>`_,
- partially fixes `#12846 <https://github.com/coq/coq/issues/12846>`_,
- by Hugo Herbelin).
diff --git a/doc/changelog/04-tactics/13337-master+improve-error-dependent-intro-wildcard.rst b/doc/changelog/04-tactics/13337-master+improve-error-dependent-intro-wildcard.rst
new file mode 100644
index 0000000000..089647a4b2
--- /dev/null
+++ b/doc/changelog/04-tactics/13337-master+improve-error-dependent-intro-wildcard.rst
@@ -0,0 +1,6 @@
+- **Fixed:**
+ Avoiding exposing an internal name of the form :n:`_tmp` when applying the
+ :n:`_` introduction pattern would break a dependency
+ (`#13337 <https://github.com/coq/coq/pull/13337>`_,
+ fixes `#13336 <https://github.com/coq/coq/issues/13336>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/04-tactics/13373-master+fix13363-metas-posed-to-evars-in-wrong-env.rst b/doc/changelog/04-tactics/13373-master+fix13363-metas-posed-to-evars-in-wrong-env.rst
new file mode 100644
index 0000000000..c02129a33f
--- /dev/null
+++ b/doc/changelog/04-tactics/13373-master+fix13363-metas-posed-to-evars-in-wrong-env.rst
@@ -0,0 +1,6 @@
+- **Fixed:**
+ The case of tactics, such as :tacn:`eapply`, producing existential variables
+ under binders with an ill-formed instance
+ (`#13373 <https://github.com/coq/coq/pull/13373>`_,
+ fixes `#13363 <https://github.com/coq/coq/issues/13363>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/04-tactics/13381-bfs_eauto.rst b/doc/changelog/04-tactics/13381-bfs_eauto.rst
new file mode 100644
index 0000000000..a51f96d0a2
--- /dev/null
+++ b/doc/changelog/04-tactics/13381-bfs_eauto.rst
@@ -0,0 +1,6 @@
+- **Deprecated:**
+ Undocumented :n:`eauto @int_or_var @int_or_var` syntax in favor of new ``bfs eauto``.
+ Also deprecated 2-integer syntax for ``debug eauto`` and ``info_eauto``;
+ replacement TBD.
+ (`#13381 <https://github.com/coq/coq/pull/13381>`_,
+ by Jim Fehrle).
diff --git a/doc/changelog/05-tactic-language/13232-ltac2-if-then-else.rst b/doc/changelog/05-tactic-language/13232-ltac2-if-then-else.rst
new file mode 100644
index 0000000000..d105561a23
--- /dev/null
+++ b/doc/changelog/05-tactic-language/13232-ltac2-if-then-else.rst
@@ -0,0 +1,5 @@
+- **Added:**
+ An if-then-else syntax to Ltac2
+ (`#13232 <https://github.com/coq/coq/pull/13232>`_,
+ fixes `#10110 <https://github.com/coq/coq/issues/10110>`_,
+ by Pierre-Marie Pédrot).
diff --git a/doc/changelog/06-ssreflect/12857-changelog-for-12857.rst b/doc/changelog/06-ssreflect/12857-changelog-for-12857.rst
deleted file mode 100644
index 4350fd0238..0000000000
--- a/doc/changelog/06-ssreflect/12857-changelog-for-12857.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-- **Fixed:**
- Regression in error reporting after :tacn:`case <case (ssreflect)>`.
- A generic error message "Could not fill dependent hole in apply" was
- reported for any error following :tacn:`case <case (ssreflect)>` or
- :tacn:`elim <elim (ssreflect)>`
- (`#12857 <https://github.com/coq/coq/pull/12857>`_,
- fixes `#12837 <https://github.com/coq/coq/issues/12837>`_,
- by Enrico Tassi).
diff --git a/doc/changelog/06-ssreflect/13317-ssr_dup_swap_apply_ipat.rst b/doc/changelog/06-ssreflect/13317-ssr_dup_swap_apply_ipat.rst
new file mode 100644
index 0000000000..8d1564533d
--- /dev/null
+++ b/doc/changelog/06-ssreflect/13317-ssr_dup_swap_apply_ipat.rst
@@ -0,0 +1,4 @@
+- **Added:**
+ SSReflect intro pattern ltac views ``/[dup]``, ``/[swap]`` and ``/[apply]``
+ (`#13317 <https://github.com/coq/coq/pull/13317>`_,
+ by Cyril Cohen).
diff --git a/doc/changelog/07-commands-and-options/12516-deprecate-grab-existentials.rst b/doc/changelog/07-commands-and-options/12516-deprecate-grab-existentials.rst
new file mode 100644
index 0000000000..1c7c3102a3
--- /dev/null
+++ b/doc/changelog/07-commands-and-options/12516-deprecate-grab-existentials.rst
@@ -0,0 +1,4 @@
+- **Deprecated:**
+ :cmd:`Grab Existential Variables` and :cmd:`Existential` commands
+ (`#12516 <https://github.com/coq/coq/pull/12516>`_,
+ by Maxime Dénès).
diff --git a/doc/changelog/07-commands-and-options/13040-gc+best_fit.rst b/doc/changelog/07-commands-and-options/13040-gc+best_fit.rst
new file mode 100644
index 0000000000..74818f8464
--- /dev/null
+++ b/doc/changelog/07-commands-and-options/13040-gc+best_fit.rst
@@ -0,0 +1,9 @@
+- **Changed:**
+ When compiled with OCaml >= 4.10.0, Coq will use the new best-fit GC
+ policy, which should provide some performance benefits. Coq's policy
+ is optimized for speed, but could increase memory consumption in
+ some cases. You are welcome to tune it using the ``OCAMLRUNPARAM``
+ variable and report back setting so we could optimize more.
+ (`#13040 <https://github.com/coq/coq/pull/13040>`_,
+ fixes `#11277 <https://github.com/coq/coq/issues/11277>`_,
+ by Emilio Jesus Gallego Arias).
diff --git a/doc/changelog/07-commands-and-options/13139-clean-hint-constr.rst b/doc/changelog/07-commands-and-options/13139-clean-hint-constr.rst
new file mode 100644
index 0000000000..1a6bc88c6c
--- /dev/null
+++ b/doc/changelog/07-commands-and-options/13139-clean-hint-constr.rst
@@ -0,0 +1,6 @@
+- **Changed:**
+ When declaring arbitrary terms as hints, unsolved
+ evars are not abstracted implicitly anymore and instead
+ raise an error
+ (`#13139 <https://github.com/coq/coq/pull/13139>`_,
+ by Pierre-Marie Pédrot).
diff --git a/doc/changelog/07-commands-and-options/13255-master+fix13244-use-coercions-in-search.rst b/doc/changelog/07-commands-and-options/13255-master+fix13244-use-coercions-in-search.rst
new file mode 100644
index 0000000000..03be92f897
--- /dev/null
+++ b/doc/changelog/07-commands-and-options/13255-master+fix13244-use-coercions-in-search.rst
@@ -0,0 +1,7 @@
+- **Added:**
+ Added support for automatic insertion of coercions in :cmd:`Search`
+ patterns. Additionally, head patterns are now automatically
+ interpreted as types
+ (`#13255 <https://github.com/coq/coq/pull/13255>`_,
+ fixes `#13244 <https://github.com/coq/coq/issues/13244>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/07-commands-and-options/13339-proof-using-noinit.rst b/doc/changelog/07-commands-and-options/13339-proof-using-noinit.rst
new file mode 100644
index 0000000000..9ae759be56
--- /dev/null
+++ b/doc/changelog/07-commands-and-options/13339-proof-using-noinit.rst
@@ -0,0 +1,5 @@
+- **Added:**
+ The :cmd:`Proof using` command can now be used without loading the
+ Ltac plugin (`-noinit` mode)
+ (`#13339 <https://github.com/coq/coq/pull/13339>`_,
+ by Théo Zimmermann).
diff --git a/doc/changelog/07-commands-and-options/13345-master+doc-add-ml-path-not-exported.rst b/doc/changelog/07-commands-and-options/13345-master+doc-add-ml-path-not-exported.rst
new file mode 100644
index 0000000000..dc8010b456
--- /dev/null
+++ b/doc/changelog/07-commands-and-options/13345-master+doc-add-ml-path-not-exported.rst
@@ -0,0 +1,5 @@
+- **Added:**
+ Clarify in the documentation that :cmd:`Add ML Path` is not exported to compiled files
+ (`#13345 <https://github.com/coq/coq/pull/13345>`_,
+ fixes `#13344 <https://github.com/coq/coq/issues/13344>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/07-commands-and-options/13384-warn-unqualified-hint.rst b/doc/changelog/07-commands-and-options/13384-warn-unqualified-hint.rst
new file mode 100644
index 0000000000..8ec7198b72
--- /dev/null
+++ b/doc/changelog/07-commands-and-options/13384-warn-unqualified-hint.rst
@@ -0,0 +1,8 @@
+- **Deprecated:**
+ The default value for hint locality is currently :attr:`local` in a section and
+ :attr:`global` otherwise, but is scheduled to change in a future release. For the
+ time being, adding hints outside of sections without specifying an explicit
+ locality is therefore triggering a deprecation warning. It is recommended to
+ use :attr:`export` whenever possible
+ (`#13384 <https://github.com/coq/coq/pull/13384>`_,
+ by Pierre-Marie Pédrot).
diff --git a/doc/changelog/07-commands-and-options/13388-export-locality-for-all-hint-commands.rst b/doc/changelog/07-commands-and-options/13388-export-locality-for-all-hint-commands.rst
new file mode 100644
index 0000000000..df2bdfeabb
--- /dev/null
+++ b/doc/changelog/07-commands-and-options/13388-export-locality-for-all-hint-commands.rst
@@ -0,0 +1,6 @@
+- **Changed:**
+ The :attr:`export` locality can now be used for all Hint commands,
+ including Hint Cut, Hint Mode, Hint Transparent / Opaque and
+ Remove Hints
+ (`#13388 <https://github.com/coq/coq/pull/13388>`_,
+ by Pierre-Marie Pédrot).
diff --git a/doc/changelog/08-tools/12754-master+fix-coqdoc-index-escaping.rst b/doc/changelog/08-tools/12754-master+fix-coqdoc-index-escaping.rst
deleted file mode 100644
index a05829b720..0000000000
--- a/doc/changelog/08-tools/12754-master+fix-coqdoc-index-escaping.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-- **Fixed:**
- Special symbols now escaped in the index produced by coqdoc,
- avoiding collision with the syntax of the output format
- (`#12754 <https://github.com/coq/coq/pull/12754>`_,
- fixes `#12752 <https://github.com/coq/coq/issues/12752>`_,
- by Hugo Herbelin).
diff --git a/doc/changelog/08-tools/12772-fix-details.rst b/doc/changelog/08-tools/12772-fix-details.rst
deleted file mode 100644
index 67ee061285..0000000000
--- a/doc/changelog/08-tools/12772-fix-details.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-- **Fixed:**
- The `details` environment added in the 8.12 release can now be used
- as advertised in the reference manual
- (`#12772 <https://github.com/coq/coq/pull/12772>`_,
- by Thomas Letan).
diff --git a/doc/changelog/08-tools/13063-fix-no-output-sync-make-file.rst b/doc/changelog/08-tools/13063-fix-no-output-sync-make-file.rst
deleted file mode 100644
index 75b1e26248..0000000000
--- a/doc/changelog/08-tools/13063-fix-no-output-sync-make-file.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-- **Fixed:**
- Targets such as ``print-pretty-timed`` in ``coq_makefile``-made
- ``Makefile``\s no longer error in rare cases where ``--output-sync`` is not
- passed to make and the timing output gets interleaved in just the wrong way
- (`#13063 <https://github.com/coq/coq/pull/13063>`_, fixes `#13062
- <https://github.com/coq/coq/issues/13062>`_, by Jason Gross).
diff --git a/doc/changelog/09-coqide/13145-master+coqide-printing-goal-names-support.rst b/doc/changelog/09-coqide/13145-master+coqide-printing-goal-names-support.rst
new file mode 100644
index 0000000000..f7446cc5aa
--- /dev/null
+++ b/doc/changelog/09-coqide/13145-master+coqide-printing-goal-names-support.rst
@@ -0,0 +1,4 @@
+- **Added:**
+ Support for flag :flag:`Printing Goal Names` in View menu
+ (`#13145 <https://github.com/coq/coq/pull/13145>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/10-standard-library/12420-decidable.rst b/doc/changelog/10-standard-library/12420-decidable.rst
new file mode 100644
index 0000000000..6a4da91fa3
--- /dev/null
+++ b/doc/changelog/10-standard-library/12420-decidable.rst
@@ -0,0 +1,4 @@
+- **Added:**
+ ``Decidable`` instance for negation
+ (`#12420 <https://github.com/coq/coq/pull/12420>`_,
+ by Yishuai Li).
diff --git a/doc/changelog/10-standard-library/13365-axiom-free-wf.rst b/doc/changelog/10-standard-library/13365-axiom-free-wf.rst
new file mode 100644
index 0000000000..1fc40894eb
--- /dev/null
+++ b/doc/changelog/10-standard-library/13365-axiom-free-wf.rst
@@ -0,0 +1,4 @@
+- **Fixed:**
+ `Coq.Program.Wf.Fix_F_inv` and `Coq.Program.Wf.Fix_eq` are now axiom-free. They no longer assume proof irrelevance.
+ (`#13365 <https://github.com/coq/coq/pull/13365>`_,
+ by Li-yao Xia).
diff --git a/doc/changelog/11-infrastructure-and-dependencies/12864-fix-approve-output.rst b/doc/changelog/11-infrastructure-and-dependencies/12864-fix-approve-output.rst
deleted file mode 100644
index c754826e62..0000000000
--- a/doc/changelog/11-infrastructure-and-dependencies/12864-fix-approve-output.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-- **Fixed:**
- ``make approve-output`` in the test-suite now correctly handles
- ``output-coqtop`` and ``output-coqchk`` tests (`#12864
- <https://github.com/coq/coq/pull/12864>`_, fixes `#12863
- <https://github.com/coq/coq/issues/12863>`_, by Jason Gross).
diff --git a/doc/changelog/11-infrastructure-and-dependencies/12972-ocaml+4_11.rst b/doc/changelog/11-infrastructure-and-dependencies/12972-ocaml+4_11.rst
deleted file mode 100644
index 855aa360f1..0000000000
--- a/doc/changelog/11-infrastructure-and-dependencies/12972-ocaml+4_11.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-- **Added:**
- Coq is now tested against OCaml 4.11.1
- (`#12972 <https://github.com/coq/coq/pull/12972>`_,
- by Emilio Jesus Gallego Arias).
diff --git a/doc/changelog/11-infrastructure-and-dependencies/13011-sphinx-3.rst b/doc/changelog/11-infrastructure-and-dependencies/13011-sphinx-3.rst
deleted file mode 100644
index d17a2dff6b..0000000000
--- a/doc/changelog/11-infrastructure-and-dependencies/13011-sphinx-3.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-- **Fixed:**
- The reference manual can now build with Sphinx 3
- (`#13011 <https://github.com/coq/coq/pull/13011>`_,
- fixes `#12332 <https://github.com/coq/coq/issues/12332>`_,
- by Théo Zimmermann and Jim Fehrle).
diff --git a/doc/sphinx/README.rst b/doc/sphinx/README.rst
index 4461ff9240..bfdbc4c4db 100644
--- a/doc/sphinx/README.rst
+++ b/doc/sphinx/README.rst
@@ -551,7 +551,7 @@ Add either ``abort`` to the first block or ``reset`` to the second block to avoi
Abbreviations and macros
------------------------
-Substitutions for specially-formatted names (like ``|Cic|``, ``|Coq|``, ``|CoqIDE|``, ``|Ltac|``, and ``|Gallina|``), along with some useful LaTeX macros, are defined in a `separate file </doc/sphinx/refman-preamble.rst>`_. This file is automatically included in all manual pages.
+Substitutions for specially-formatted names (like ``|Cic|``, ``|Ltac|`` and ``|Latex|``), along with some useful LaTeX macros, are defined in a `separate file </doc/sphinx/refman-preamble.rst>`_. This file is automatically included in all manual pages.
Emacs
-----
diff --git a/doc/sphinx/README.template.rst b/doc/sphinx/README.template.rst
index b4e21aa14a..d4e297299e 100644
--- a/doc/sphinx/README.template.rst
+++ b/doc/sphinx/README.template.rst
@@ -290,7 +290,7 @@ Add either ``abort`` to the first block or ``reset`` to the second block to avoi
Abbreviations and macros
------------------------
-Substitutions for specially-formatted names (like ``|Cic|``, ``|Coq|``, ``|CoqIDE|``, ``|Ltac|``, and ``|Gallina|``), along with some useful LaTeX macros, are defined in a `separate file </doc/sphinx/refman-preamble.rst>`_. This file is automatically included in all manual pages.
+Substitutions for specially-formatted names (like ``|Cic|``, ``|Ltac|`` and ``|Latex|``), along with some useful LaTeX macros, are defined in a `separate file </doc/sphinx/refman-preamble.rst>`_. This file is automatically included in all manual pages.
Emacs
-----
diff --git a/doc/sphinx/_static/coqdoc.css b/doc/sphinx/_static/coqdoc.css
index 32cb0a7a15..c0b4ee4a9f 100644
--- a/doc/sphinx/_static/coqdoc.css
+++ b/doc/sphinx/_static/coqdoc.css
@@ -66,3 +66,7 @@
.coqdoc-tactic {
font-weight: bold;
}
+
+.smallcaps {
+ font-variant: small-caps;
+}
diff --git a/doc/sphinx/addendum/extraction.rst b/doc/sphinx/addendum/extraction.rst
index c2249b8e57..3662822a5e 100644
--- a/doc/sphinx/addendum/extraction.rst
+++ b/doc/sphinx/addendum/extraction.rst
@@ -5,10 +5,10 @@ Program extraction
:Authors: Jean-Christophe Filliâtre and Pierre Letouzey
-We present here the |Coq| extraction commands, used to build certified
+We present here the Coq extraction commands, used to build certified
and relatively efficient functional programs, extracting them from
-either |Coq| functions or |Coq| proofs of specifications. The
-functional languages available as output are currently |OCaml|, Haskell
+either Coq functions or Coq proofs of specifications. The
+functional languages available as output are currently OCaml, Haskell
and Scheme. In the following, "ML" will be used (abusively) to refer
to any of the three.
@@ -29,23 +29,23 @@ Generating ML Code
.. note::
In the following, a qualified identifier :token:`qualid`
- can be used to refer to any kind of |Coq| global "object" : constant,
+ can be used to refer to any kind of Coq global "object" : constant,
inductive type, inductive constructor or module name.
The next two commands are meant to be used for rapid preview of
-extraction. They both display extracted term(s) inside |Coq|.
+extraction. They both display extracted term(s) inside Coq.
.. cmd:: Extraction @qualid
- Extraction of the mentioned object in the |Coq| toplevel.
+ Extraction of the mentioned object in the Coq toplevel.
.. cmd:: Recursive Extraction {+ @qualid }
Recursive extraction of all the mentioned objects and
- all their dependencies in the |Coq| toplevel.
+ all their dependencies in the Coq toplevel.
All the following commands produce real ML files. User can choose to
-produce one monolithic file or one file per |Coq| library.
+produce one monolithic file or one file per Coq library.
.. cmd:: Extraction @string {+ @qualid }
@@ -57,14 +57,14 @@ produce one monolithic file or one file per |Coq| library.
.. cmd:: Extraction Library @ident
- Extraction of the whole |Coq| library :n:`@ident.v` to an ML module
+ Extraction of the whole Coq library :n:`@ident.v` to an ML module
:n:`@ident.ml`. In case of name clash, identifiers are here renamed
using prefixes ``coq_`` or ``Coq_`` to ensure a session-independent
renaming.
.. cmd:: Recursive Extraction Library @ident
- Extraction of the |Coq| library :n:`@ident.v` and all other modules
+ Extraction of the Coq library :n:`@ident.v` and all other modules
:n:`@ident.v` depends on.
.. cmd:: Separate Extraction {+ @qualid }
@@ -82,16 +82,16 @@ produce one monolithic file or one file per |Coq| library.
The following command is meant to help automatic testing of
the extraction, see for instance the ``test-suite`` directory
-in the |Coq| sources.
+in the Coq sources.
.. cmd:: Extraction TestCompile {+ @qualid }
All the mentioned objects and all their dependencies are extracted
- to a temporary |OCaml| file, just as in ``Extraction "file"``. Then
+ to a temporary OCaml file, just as in ``Extraction "file"``. Then
this temporary file and its signature are compiled with the same
- |OCaml| compiler used to built |Coq|. This command succeeds only
- if the extraction and the |OCaml| compilation succeed. It fails
- if the current target language of the extraction is not |OCaml|.
+ OCaml compiler used to built Coq. This command succeeds only
+ if the extraction and the OCaml compilation succeed. It fails
+ if the current target language of the extraction is not OCaml.
Extraction Options
-------------------
@@ -99,10 +99,18 @@ Extraction Options
Setting the target language
~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. cmd:: Extraction Language {| OCaml | Haskell | Scheme | JSON }
+.. cmd:: Extraction Language @language
:name: Extraction Language
- The ability to fix target language is the first and more important
+ .. insertprodn language language
+
+ .. prodn::
+ language ::= OCaml
+ | Haskell
+ | Scheme
+ | JSON
+
+ The ability to fix target language is the first and most important
of the extraction options. Default is ``OCaml``.
The JSON output is mostly for development or debugging:
@@ -112,17 +120,17 @@ Setting the target language
Inlining and optimizations
~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Since |OCaml| is a strict language, the extracted code has to
+Since OCaml is a strict language, the extracted code has to
be optimized in order to be efficient (for instance, when using
induction principles we do not want to compute all the recursive calls
but only the needed ones). So the extraction mechanism provides an
automatic optimization routine that will be called each time the user
-wants to generate an |OCaml| program. The optimizations can be split in two
+wants to generate an OCaml program. The optimizations can be split in two
groups: the type-preserving ones (essentially constant inlining and
reductions) and the non type-preserving ones (some function
abstractions of dummy types are removed when it is deemed safe in order
to have more elegant types). Therefore some constants may not appear in the
-resulting monolithic |OCaml| program. In the case of modular extraction,
+resulting monolithic OCaml program. In the case of modular extraction,
even if some inlining is done, the inlined constants are nevertheless
printed, to ensure session-independent programs.
@@ -130,7 +138,7 @@ Concerning Haskell, type-preserving optimizations are less useful
because of laziness. We still make some optimizations, for example in
order to produce more readable code.
-The type-preserving optimizations are controlled by the following |Coq| flags
+The type-preserving optimizations are controlled by the following Coq flags
and commands:
.. flag:: Extraction Optimize
@@ -191,7 +199,7 @@ The user can explicitly ask for a constant to be extracted by two means:
* by mentioning it on the extraction command line
- * by extracting the whole |Coq| module of this constant.
+ * by extracting the whole Coq module of this constant.
In both cases, the declaration of this constant will be present in the
produced file. But this same constant may or may not be inlined in
@@ -215,14 +223,15 @@ code elimination performed during extraction, in a way which
is independent but complementary to the main elimination
principles of extraction (logical parts and types).
-.. cmd:: Extraction Implicit @qualid [ {+ @ident } ]
+.. cmd:: Extraction Implicit @qualid [ {* {| @ident | @integer } } ]
- This experimental command allows declaring some arguments of
- :token:`qualid` as implicit, i.e. useless in extracted code and hence to
- be removed by extraction. Here :token:`qualid` can be any function or
- inductive constructor, and the given :token:`ident` are the names of
- the concerned arguments. In fact, an argument can also be referred
- by a number indicating its position, starting from 1.
+ Declares some arguments of
+ :token:`qualid` as implicit, meaning that they are useless in extracted code.
+ The extracted code will omit these arguments.
+ Here :token:`qualid` can be
+ any function or inductive constructor, and the :token:`ident`\s are
+ the names of the useless arguments. Arguments can can also be
+ identified positionally by :token:`integer`\s starting from 1.
When an actual extraction takes place, an error is normally raised if the
:cmd:`Extraction Implicit` declarations cannot be honored, that is
@@ -254,12 +263,24 @@ a closed term, and of course the system cannot guess the program which
realizes an axiom. Therefore, it is possible to tell the system
what ML term corresponds to a given axiom.
-.. cmd:: Extract Constant @qualid => @string
+.. cmd:: Extract Constant @qualid {* @string__tv } => {| @ident | @string }
Give an ML extraction for the given constant.
- The :token:`string` may be an identifier or a quoted string.
-.. cmd:: Extract Inlined Constant @qualid => @string
+ :n:`@string__tv`
+ If the type scheme axiom is an arity (a sequence of products followed
+ by a sort), then some type
+ variables have to be given (as quoted strings).
+
+ The number of type variables is checked by the system. For example:
+
+ .. coqtop:: in
+
+ Axiom Y : Set -> Set -> Set.
+ Extract Constant Y "'a" "'b" => " 'a * 'b ".
+
+
+.. cmd:: Extract Inlined Constant @qualid => {| @ident | @string }
Same as the previous one, except that the given ML terms will
be inlined everywhere instead of being declared via a ``let``.
@@ -282,20 +303,6 @@ what ML term corresponds to a given axiom.
Extract Constant X => "int".
Extract Constant x => "0".
-Notice that in the case of type scheme axiom (i.e. whose type is an
-arity, that is a sequence of product finished by a sort), then some type
-variables have to be given (as quoted strings). The syntax is then:
-
-.. cmdv:: Extract Constant @qualid {+ @string } => @string
- :undocumented:
-
-The number of type variables is checked by the system. For example:
-
-.. coqtop:: in
-
- Axiom Y : Set -> Set -> Set.
- Extract Constant Y "'a" "'b" => " 'a * 'b ".
-
Realizing an axiom via :cmd:`Extract Constant` is only useful in the
case of an informative axiom (of sort ``Type`` or ``Set``). A logical axiom
has no computational content and hence will not appear in extracted
@@ -314,38 +321,37 @@ Realizing inductive types
The system also provides a mechanism to specify ML terms for inductive
types and constructors. For instance, the user may want to use the ML
-native boolean type instead of the |Coq| one. The syntax is the following:
+native boolean type instead of the Coq one. The syntax is the following:
-.. cmd:: Extract Inductive @qualid => @string__1 [ {+ @string } ]
+.. cmd:: Extract Inductive @qualid => {| @ident | @string } [ {* {| @ident | @string } } ] {? @string__match }
Give an ML extraction for the given inductive type. You must specify
- extractions for the type itself (:n:`@string__1`) and all its
- constructors (all the :n:`@string` between square brackets). In this form,
+ extractions for the type itself (the initial :n:`{| @ident | @string }`) and all its
+ constructors (the :n:`[ {* {| @ident | @string } } ]`). In this form,
the ML extraction must be an ML inductive datatype, and the native
pattern matching of the language will be used.
- When :n:`@string__1` matches the name of the type of characters or strings
+ When the initial :n:`{| @ident | @string }` matches the name of the type of characters or strings
(``char`` and ``string`` for OCaml, ``Prelude.Char`` and ``Prelude.String``
for Haskell), extraction of literals is handled in a specialized way, so as
to generate literals in the target language. This feature requires the type
designated by :n:`@qualid` to be registered as the standard char or string type,
using the :cmd:`Register` command.
-.. cmdv:: Extract Inductive @qualid => @string [ {+ @string } ] @string
-
- Same as before, with a final extra :token:`string` that indicates how to
- perform pattern matching over this inductive type. In this form,
- the ML extraction could be an arbitrary type.
- For an inductive type with :math:`k` constructors, the function used to
- emulate the pattern matching should expect :math:`k+1` arguments, first the :math:`k`
- branches in functional form, and then the inductive element to
- destruct. For instance, the match branch ``| S n => foo`` gives the
- functional form ``(fun n -> foo)``. Note that a constructor with no
- arguments is considered to have one unit argument, in order to block
- early evaluation of the branch: ``| O => bar`` leads to the functional
- form ``(fun () -> bar)``. For instance, when extracting :g:`nat`
- into |OCaml| ``int``, the code to be provided has type:
- ``(unit->'a)->(int->'a)->int->'a``.
+ :n:`@string__match`
+ Indicates how to
+ perform pattern matching over this inductive type. In this form,
+ the ML extraction could be an arbitrary type.
+ For an inductive type with :math:`k` constructors, the function used to
+ emulate the pattern matching should expect :math:`k+1` arguments, first the :math:`k`
+ branches in functional form, and then the inductive element to
+ destruct. For instance, the match branch ``| S n => foo`` gives the
+ functional form ``(fun n -> foo)``. Note that a constructor with no
+ arguments is considered to have one unit argument, in order to block
+ early evaluation of the branch: ``| O => bar`` leads to the functional
+ form ``(fun () -> bar)``. For instance, when extracting :g:`nat`
+ into OCaml ``int``, the code to be provided has type:
+ ``(unit->'a)->(int->'a)->int->'a``.
.. caution:: As for :cmd:`Extract Constant`, this command should be used with care:
@@ -355,15 +361,15 @@ native boolean type instead of the |Coq| one. The syntax is the following:
* Extracting an inductive type to a pre-existing ML inductive type
is quite sound. But extracting to a general type (by providing an
ad-hoc pattern matching) will often **not** be fully rigorously
- correct. For instance, when extracting ``nat`` to |OCaml| ``int``,
+ correct. For instance, when extracting ``nat`` to OCaml ``int``,
it is theoretically possible to build ``nat`` values that are
- larger than |OCaml| ``max_int``. It is the user's responsibility to
+ larger than OCaml ``max_int``. It is the user's responsibility to
be sure that no overflow or other bad events occur in practice.
* Translating an inductive type to an arbitrary ML type does **not**
magically improve the asymptotic complexity of functions, even if the
ML type is an efficient representation. For instance, when extracting
- ``nat`` to |OCaml| ``int``, the function ``Nat.mul`` stays quadratic.
+ ``nat`` to OCaml ``int``, the function ``Nat.mul`` stays quadratic.
It might be interesting to associate this translation with
some specific :cmd:`Extract Constant` when primitive counterparts exist.
@@ -377,9 +383,9 @@ Typical examples are the following:
.. note::
- When extracting to |OCaml|, if an inductive constructor or type has arity 2 and
+ When extracting to OCaml, if an inductive constructor or type has arity 2 and
the corresponding string is enclosed by parentheses, and the string meets
- |OCaml|'s lexical criteria for an infix symbol, then the rest of the string is
+ OCaml's lexical criteria for an infix symbol, then the rest of the string is
used as an infix constructor or type.
.. coqtop:: in
@@ -388,7 +394,7 @@ Typical examples are the following:
Extract Inductive prod => "(*)" [ "(,)" ].
As an example of translation to a non-inductive datatype, let's turn
-``nat`` into |OCaml| ``int`` (see caveat above):
+``nat`` into OCaml ``int`` (see caveat above):
.. coqtop:: in
@@ -398,11 +404,11 @@ Avoiding conflicts with existing filenames
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When using :cmd:`Extraction Library`, the names of the extracted files
-directly depend on the names of the |Coq| files. It may happen that
+directly depend on the names of the Coq files. It may happen that
these filenames are in conflict with already existing files,
either in the standard library of the target language or in other
code that is meant to be linked with the extracted code.
-For instance the module ``List`` exists both in |Coq| and in |OCaml|.
+For instance the module ``List`` exists both in Coq and in OCaml.
It is possible to instruct the extraction not to use particular filenames.
.. cmd:: Extraction Blacklist {+ @ident }
@@ -418,7 +424,7 @@ It is possible to instruct the extraction not to use particular filenames.
Allow the extraction to use any filename.
-For |OCaml|, a typical use of these commands is
+For OCaml, a typical use of these commands is
``Extraction Blacklist String List``.
Additional settings
@@ -467,12 +473,12 @@ Additional settings
If set, fully expand Coq types in ML. See the Coq source code to learn more.
-Differences between |Coq| and ML type systems
+Differences between Coq and ML type systems
----------------------------------------------
-Due to differences between |Coq| and ML type systems,
+Due to differences between Coq and ML type systems,
some extracted programs are not directly typable in ML.
-We now solve this problem (at least in |OCaml|) by adding
+We now solve this problem (at least in OCaml) by adding
when needed some unsafe casting ``Obj.magic``, which give
a generic type ``'a`` to any term.
@@ -486,7 +492,7 @@ function:
Definition dp {A B:Type}(x:A)(y:B)(f:forall C:Type, C->C) := (f A x, f B y).
-In |OCaml|, for instance, the direct extracted term would be::
+In OCaml, for instance, the direct extracted term would be::
let dp x y f = Pair((f () x),(f () y))
@@ -500,7 +506,7 @@ We now produce the following correct version::
let dp x y f = Pair ((Obj.magic f () x), (Obj.magic f () y))
-Secondly, some |Coq| definitions may have no counterpart in ML. This
+Secondly, some Coq definitions may have no counterpart in ML. This
happens when there is a quantification over types inside the type
of a constructor; for example:
@@ -509,29 +515,29 @@ of a constructor; for example:
Inductive anything : Type := dummy : forall A:Set, A -> anything.
which corresponds to the definition of an ML dynamic type.
-In |OCaml|, we must cast any argument of the constructor dummy
+In OCaml, we must cast any argument of the constructor dummy
(no GADT are produced yet by the extraction).
Even with those unsafe castings, you should never get error like
``segmentation fault``. In fact even if your program may seem
-ill-typed to the |OCaml| type checker, it can't go wrong : it comes
-from a Coq well-typed terms, so for example inductive types will always
+ill-typed to the OCaml type checker, it can't go wrong : it comes
+from a Coq well-typed terms, so for example inductive types will always
have the correct number of arguments, etc. Of course, when launching
manually some extracted function, you should apply it to arguments
-of the right shape (from the |Coq| point-of-view).
+of the right shape (from the Coq point-of-view).
More details about the correctness of the extracted programs can be
found in :cite:`Let02`.
We have to say, though, that in most "realistic" programs, these problems do not
-occur. For example all the programs of Coq library are accepted by the |OCaml|
+occur. For example all the programs of Coq library are accepted by the OCaml
type checker without any ``Obj.magic`` (see examples below).
Some examples
-------------
We present here two examples of extraction, taken from the
-|Coq| Standard Library. We choose |OCaml| as the target language,
+Coq Standard Library. We choose OCaml as the target language,
but everything, with slight modifications, can also be done in the
other languages supported by extraction.
We then indicate where to find other examples and tests of extraction.
@@ -548,7 +554,7 @@ This module contains a theorem ``eucl_dev``, whose type is::
where ``diveucl`` is a type for the pair of the quotient and the
modulo, plus some logical assertions that disappear during extraction.
-We can now extract this program to |OCaml|:
+We can now extract this program to OCaml:
.. coqtop:: none
@@ -564,11 +570,11 @@ We can now extract this program to |OCaml|:
The inlining of ``gt_wf_rec`` and others is not
mandatory. It only enhances readability of extracted code.
You can then copy-paste the output to a file ``euclid.ml`` or let
-|Coq| do it for you with the following command::
+Coq do it for you with the following command::
Extraction "euclid" eucl_dev.
-Let us play the resulting program (in an |OCaml| toplevel)::
+Let us play the resulting program (in an OCaml toplevel)::
#use "euclid.ml";;
type nat = O | S of nat
@@ -582,7 +588,7 @@ Let us play the resulting program (in an |OCaml| toplevel)::
# eucl_dev (S (S O)) (S (S (S (S (S O)))));;
- : diveucl = Divex (S (S O), S O)
-It is easier to test on |OCaml| integers::
+It is easier to test on OCaml integers::
# let rec nat_of_int = function 0 -> O | n -> S (nat_of_int (n-1));;
val nat_of_int : int -> nat = <fun>
@@ -608,12 +614,12 @@ Extraction's horror museum
~~~~~~~~~~~~~~~~~~~~~~~~~~
Some pathological examples of extraction are grouped in the file
-``test-suite/success/extraction.v`` of the sources of |Coq|.
+``test-suite/success/extraction.v`` of the sources of Coq.
Users' Contributions
~~~~~~~~~~~~~~~~~~~~
-Several of the |Coq| Users' Contributions use extraction to produce
+Several of the Coq Users' Contributions use extraction to produce
certified programs. In particular the following ones have an automatic
extraction test:
diff --git a/doc/sphinx/addendum/generalized-rewriting.rst b/doc/sphinx/addendum/generalized-rewriting.rst
index 759f630b85..27ae7cea3a 100644
--- a/doc/sphinx/addendum/generalized-rewriting.rst
+++ b/doc/sphinx/addendum/generalized-rewriting.rst
@@ -170,10 +170,17 @@ compatibility constraints.
Adding new relations and morphisms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. cmd:: Add Parametric Relation {* @binder } : (A t1 ... tn) (Aeq t′1 ... t′m) {? reflexivity proved by @term} {? symmetry proved by @term} {? transitivity proved by @term} as @ident
+.. cmd:: Add Parametric Relation {* @binder } : @one_term__A @one_term__Aeq {? reflexivity proved by @one_term } {? symmetry proved by @one_term } {? transitivity proved by @one_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)`.
+ Declares a parametric relation of :n:`@one_term__A`, which is a `Type`, say `T`, with
+ :n:`@one_term__Aeq`, which is a relation on `T`, i.e. of type `(T -> T -> Prop)`.
+ Thus, if :n:`@one_term__A` is
+ :n:`A: forall α__1 … α__n, Type` then :n:`@one_term__Aeq` is
+ :n:`Aeq: forall α__1 … α__n, (A α__1 … α__n) -> (A α__1 … α__n) -> Prop`,
+ or equivalently, :n:`Aeq: forall α__1 … α__n, relation (A α__1 … α__n)`.
+
+ :n:`@one_term__A` and :n:`@one_term__Aeq` must be typeable under the context
+ :token:`binder`\s. In practice, the :token:`binder`\s usually correspond to the :n:`α`\s
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
@@ -189,16 +196,16 @@ Adding new relations and morphisms
To use this command, you need to first import the module ``Setoid`` using
the command ``Require Import Setoid``.
-.. cmd:: Add Relation
+.. cmd:: Add Relation @one_term @one_term {? reflexivity proved by @one_term } {? symmetry proved by @one_term } {? transitivity proved by @one_term } as @ident
- In case the carrier and relations are not parametric, one can use this command
+ If the carrier and relations are not parametric, use this command
instead, whose syntax is the same except there is no local context.
The proofs of reflexivity, symmetry and transitivity can be omitted if
the relation is not an equivalence relation. The proofs must be
instances of the corresponding relation definitions: e.g. the proof of
reflexivity must have a type convertible to
- :g:`reflexive (A t1 ... tn) (Aeq t′ 1 …t′ n)`.
+ :g:`reflexive (A t1 … tn) (Aeq t′ 1 … t′ n)`.
Each proof may refer to the introduced variables as well.
.. example:: Parametric relation
@@ -219,10 +226,10 @@ 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 {* @binder } : (@ident {+ @term__1}) with signature @term__2 as @ident
+.. cmd:: Add Parametric Morphism {* @binder } : @one_term with signature @term as @ident
- This command declares a parametric morphism :n:`@ident {+ @term__1}` of
- signature :n:`@term__2`. The final identifier :token:`ident` gives a unique
+ Declares a parametric morphism :n:`@one_term` of
+ signature :n:`@term`. 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
@@ -525,12 +532,13 @@ counterparts when the relation involved is not Leibniz equality.
Notice, however, that using the prefixed tactics it is possible to
pass additional arguments such as ``using relation``.
-.. tacv:: setoid_reflexivity
- setoid_symmetry {? in @ident}
- setoid_transitivity
- setoid_rewrite {? @orientation} @term {? at @occurrences} {? in @ident}
- setoid_replace @term with @term {? using relation @term} {? in @ident} {? by @ltac_expr3}
- :name: setoid_reflexivity; setoid_symmetry; setoid_transitivity; setoid_rewrite; setoid_replace
+.. tacn:: setoid_reflexivity
+ setoid_symmetry {? in @ident }
+ setoid_transitivity @one_term
+ setoid_rewrite {? {| -> | <- } } @one_term {? with @bindings } {? at @occurrences } {? in @ident }
+ setoid_rewrite {? {| -> | <- } } @one_term {? with @bindings } in @ident at @occurrences
+ setoid_replace @one_term with @one_term {? using relation @one_term } {? in @ident } {? at {+ @int_or_var } } {? by @ltac_expr3 }
+ :name: setoid_reflexivity; setoid_symmetry; setoid_transitivity; setoid_rewrite; _; setoid_replace
The ``using relation`` arguments cannot be passed to the unprefixed form.
The latter argument tells the tactic what parametric relation should
@@ -553,34 +561,35 @@ system up to user defined equalities.
Printing relations and morphisms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. cmd:: Print Instances
+Use the :cmd:`Print Instances` command with the class names ``Reflexive``, ``Symmetric``
+or ``Transitive`` to print registered reflexive, symmetric or transitive relations and
+with the class name ``Proper`` to print morphisms.
- This command can be used to show the list of currently
- registered ``Reflexive`` (using ``Print Instances Reflexive``), ``Symmetric``
- or ``Transitive`` relations, Equivalences, PreOrders, PERs, and Morphisms
- (implemented as ``Proper`` instances). When the rewriting tactics refuse
- to replace a term in a context because the latter is not a composition
- of morphisms, the :cmd:`Print Instances` command can be useful to understand
- what additional morphisms should be registered.
+When rewriting tactics refuse
+to replace a term in a context because the latter is not a composition
+of morphisms, this command can be useful to understand
+what additional morphisms should be registered.
.. _deprecated_syntax_for_generalized_rewriting:
Deprecated syntax and backward incompatibilities
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. cmd:: Add Setoid @qualid__1 @qualid__2 @qualid__3 as @ident
+.. cmd:: Add Setoid @one_term__carrier @one_term__congruence @one_term__proofs as @ident
This command for declaring setoids and morphisms is also accepted due
to backward compatibility reasons.
- Here :n:`@qualid__2` is a congruence relation without parameters, :n:`@qualid__1` is its carrier
- and :n:`@qualid__3` is an object of type (:n:`Setoid_Theory @qualid__1 @qualid__2`) (i.e. a record
+ Here :n:`@one_term__congruence` is a congruence relation without parameters,
+ :n:`@one_term__carrier` is its carrier and :n:`@one_term__proofs` is an object
+ of type (:n:`Setoid_Theory @one_term__carrier @one_term__congruence`) (i.e. a record
packing together the reflexivity, symmetry and transitivity lemmas).
Notice that the syntax is not completely backward compatible since the
identifier was not required.
-.. cmd:: Add Morphism @ident : @ident
- :name: Add Morphism
+.. cmd:: Add Morphism @one_term : @ident
+ Add Morphism @one_term with signature @term as @ident
+ :name: Add Morphism; _
This command is restricted to the declaration of morphisms
without parameters. It is not fully backward compatible since the
@@ -590,11 +599,10 @@ Deprecated syntax and backward incompatibilities
bi-implication in place of a simple implication. In practice, porting
an old development to the new semantics is usually quite simple.
-.. cmd:: Declare Morphism @ident : @ident
+.. cmd:: Declare Morphism @one_term : @ident
:name: Declare Morphism
- This commands is to be used in a module type to declare a parameter that
- is a morphism.
+ Declares a parameter in a module type that is a morphism.
Notice that several limitations of the old implementation have been
lifted. In particular, it is now possible to declare several relations
diff --git a/doc/sphinx/addendum/implicit-coercions.rst b/doc/sphinx/addendum/implicit-coercions.rst
index dafa510ade..0f0ccd6a20 100644
--- a/doc/sphinx/addendum/implicit-coercions.rst
+++ b/doc/sphinx/addendum/implicit-coercions.rst
@@ -8,7 +8,7 @@ Implicit Coercions
General Presentation
---------------------
-This section describes the inheritance mechanism of |Coq|. In |Coq| with
+This section describes the inheritance mechanism of Coq. In Coq with
inheritance, we are not interested in adding any expressive power to
our theory, but only convenience. Given a term, possibly not typable,
we are interested in the problem of determining if it can be well
@@ -125,10 +125,16 @@ term consists of the successive application of its coercions.
Declaring Coercions
-------------------------
-.. cmd:: Coercion @qualid : @class >-> @class
+.. cmd:: Coercion @reference : @class >-> @class
+ Coercion @ident {? @univ_decl } @def_body
- Declares the construction denoted by :token:`qualid` as a coercion between
- the two given classes.
+ :name: Coercion; _
+
+ The first form declares the construction denoted by :token:`reference` as a coercion between
+ the two given classes. The second form defines :token:`ident`
+ just like :cmd:`Definition` :n:`@ident {? @univ_decl } @def_body`
+ and then declares :token:`ident` as a coercion between it source and its target.
+ Both forms support the :attr:`local` attribute, which makes the coercion local to the current section.
.. exn:: @qualid not declared.
:undocumented:
@@ -174,21 +180,6 @@ Declaring Coercions
circular. When a new circular coercion path is not convertible with the
identity function, it will be reported as ambiguous.
- .. cmdv:: Local Coercion @qualid : @class >-> @class
-
- Declares the construction denoted by :token:`qualid` as a coercion local to
- the current section.
-
- .. cmdv:: Coercion @ident := @term {? @type }
-
- This defines :token:`ident` just like :n:`Definition @ident := term {? @type }`,
- and then declares :token:`ident` as a coercion between it source and its target.
-
- .. cmdv:: Local Coercion @ident := @term {? @type }
-
- This defines :token:`ident` just like :n:`Let @ident := @term {? @type }`,
- and then declares :token:`ident` as a coercion between it source and its target.
-
Some objects can be declared as coercions when they are defined.
This applies to :ref:`assumptions<gallina-assumptions>` and
constructors of :ref:`inductive types and record fields<gallina-inductive-definitions>`.
@@ -205,13 +196,11 @@ Use :n:`:>` instead of :n:`:` before the
function with type :g:`forall (x₁:T₁)..(xₙ:Tₙ)(y:C x₁..xₙ),D t₁..tₘ`,
and we declare it as an identity coercion between ``C`` and ``D``.
+ This command supports the :attr:`local` attribute, which makes the coercion local to the current section.
+
.. exn:: @class must be a transparent constant.
:undocumented:
- .. cmdv:: Local Identity Coercion @ident : @ident >-> @ident
-
- Same as :cmd:`Identity Coercion` but locally to the current section.
-
.. cmd:: SubClass @ident_decl @def_body
:name: SubClass
@@ -223,9 +212,7 @@ Use :n:`:>` instead of :n:`:` before the
:n:`Definition @ident := @type.`
:n:`Identity Coercion Id_@ident_@ident' : @ident >-> @ident'`.
- .. cmdv:: Local SubClass @ident_decl @def_body
-
- Same as before but locally to the current section.
+ This command supports the :attr:`local` attribute, which makes the coercion local to the current section.
Displaying Available Coercions
@@ -268,24 +255,15 @@ Classes as Records
.. index:: :> (coercion)
-We allow the definition of *Structures with Inheritance* (or classes as records)
-by extending the existing :cmd:`Record` macro. Its new syntax is:
-
-.. cmdv:: {| Record | Structure } {? >} @ident {* @binder } : @sort := {? @ident} { {+; @ident :{? >} @term } }
-
- The first identifier :token:`ident` is the name of the defined record and
- :token:`sort` is its type. The optional identifier after ``:=`` is the name
- of the constructor (it will be :n:`Build_@ident` if not given).
- The other identifiers are the names of the fields, and :token:`term`
- are their respective types. If ``:>`` is used instead of ``:`` in
- the declaration of a field, then the name of this field is automatically
- declared as a coercion from the record name to the class of this
- field type. Note that the fields always verify the uniform
- inheritance condition. If the optional ``>`` is given before the
- record name, then the constructor name is automatically declared as
- a coercion from the class of the last field type to the record name
- (this may fail if the uniform inheritance condition is not
- satisfied).
+*Structures with Inheritance* may be defined using the :cmd:`Record` command.
+
+Use `>` before the record name to declare the constructor name as
+a coercion from the class of the last field type to the record name
+(this may fail if the uniform inheritance condition is not
+satisfied). See :token:`record_definition`.
+
+Use `:>` in the field type to declare the field as a coercion from the record name
+to the class of the field type. See :token:`of_type`.
Coercions and Sections
----------------------
diff --git a/doc/sphinx/addendum/micromega.rst b/doc/sphinx/addendum/micromega.rst
index b3a33ffeea..fb9965e43a 100644
--- a/doc/sphinx/addendum/micromega.rst
+++ b/doc/sphinx/addendum/micromega.rst
@@ -1,6 +1,6 @@
.. _micromega:
-Micromega: tactics for solving arithmetic goals over ordered rings
+Micromega: solvers for arithmetic goals over ordered rings
==================================================================
:Authors: Frédéric Besson and Evgeny Makarov
@@ -25,8 +25,8 @@ tactics for solving arithmetic goals over :math:`\mathbb{Q}`,
``n`` is an optional integer limiting the proof search depth,
is an incomplete proof procedure for non-linear arithmetic.
It is based on John Harrison’s HOL Light
- driver to the external prover `csdp` [#csdp]_. Note that the `csdp` driver is
- generating a *proof cache* which makes it possible to rerun scripts
+ driver to the external prover `csdp` [#csdp]_. Note that the `csdp` driver
+ generates a *proof cache* which makes it possible to rerun scripts
even without `csdp`.
.. flag:: Simplex
@@ -250,7 +250,7 @@ proof by abstracting monomials by variables.
`psatz`: a proof procedure for non-linear arithmetic
----------------------------------------------------
-.. tacn:: psatz
+.. tacn:: psatz @one_term {? @int_or_var }
:name: psatz
This tactic explores the *Cone* by increasing degrees – hence the
@@ -300,48 +300,86 @@ obtain :math:`-1`. By Theorem :ref:`Psatz <psatz_thm>`, the goal is valid.
The :tacn:`zify` tactic can be extended with new types and operators by declaring and registering new typeclass instances using the following commands.
The typeclass declarations can be found in the module ``ZifyClasses`` and the default instances can be found in the module ``ZifyInst``.
-.. cmd:: Add Zify {| InjTyp | BinOp | UnOp |CstOp | BinRel | UnOpSpec | BinOpSpec } @qualid
+.. cmd:: Add Zify @add_zify @one_term
- This command registers an instance of one of the typeclasses among ``InjTyp``, ``BinOp``, ``UnOp``, ``CstOp``, ``BinRel``,
- ``UnOpSpec``, ``BinOpSpec``.
+ .. insertprodn add_zify add_zify
-.. cmd:: Show Zify {| InjTyp | BinOp | UnOp |CstOp | BinRel | UnOpSpec | BinOpSpec }
+ .. prodn::
+ add_zify ::= {| InjTyp | BinOp | UnOp | CstOp | BinRel | UnOpSpec | BinOpSpec }
+ | {| PropOp | PropBinOp | PropUOp | Saturate }
+
+ Registers an instance of the specified typeclass.
+
+.. cmd:: Show Zify @show_zify
+
+ .. insertprodn show_zify show_zify
+
+ .. prodn::
+ show_zify ::= {| InjTyp | BinOp | UnOp | CstOp | BinRel | UnOpSpec | BinOpSpec | Spec }
- The command prints the typeclass instances of one the typeclasses
- among ``InjTyp``, ``BinOp``, ``UnOp``, ``CstOp``, ``BinRel``,
- ``UnOpSpec``, ``BinOpSpec``. For instance, :cmd:`Show Zify` ``InjTyp``
+ Prints instances for the specified typeclass. For instance, :cmd:`Show Zify` ``InjTyp``
prints the list of types that supported by :tacn:`zify` i.e.,
:g:`Z`, :g:`nat`, :g:`positive` and :g:`N`.
.. cmd:: Show Zify Spec
.. deprecated:: 8.13
- Use instead either :cmd:`Show Zify` ``UnOpSpec`` or :cmd:`Show Zify` ``BinOpSpec``.
+ Use :cmd:`Show Zify` ``UnOpSpec`` or :cmd:`Show Zify` ``BinOpSpec`` instead.
+
+.. cmd:: Add InjTyp @one_term
+
+ .. deprecated:: 8.13
+ Use :cmd:`Add Zify` ``InjTyp`` instead.
+
+.. cmd:: Add BinOp @one_term
+
+ .. deprecated:: 8.13
+ Use :cmd:`Add Zify` ``BinOp`` instead.
+
+.. cmd:: Add BinOpSpec @one_term
+
+ .. deprecated:: 8.13
+ Use :cmd:`Add Zify` ``BinOpSpec`` instead.
+
+.. cmd:: Add UnOp @one_term
+
+ .. deprecated:: 8.13
+ Use :cmd:`Add Zify` ``UnOp`` instead.
+
+.. cmd:: Add UnOpSpec @one_term
+
+ .. deprecated:: 8.13
+ Use :cmd:`Add Zify` ``UnOpSpec`` instead.
+
+.. cmd:: Add CstOp @one_term
+
+ .. deprecated:: 8.13
+ Use :cmd:`Add Zify` ``CstOp`` instead.
-.. cmd:: Add InjTyp
+.. cmd:: Add BinRel @one_term
.. deprecated:: 8.13
- Use instead either :cmd:`Add Zify` ``InjTyp``.
+ Use :cmd:`Add Zify` ``BinRel`` instead.
-.. cmd:: Add BinOp
+.. cmd:: Add PropOp @one_term
.. deprecated:: 8.13
- Use instead either :cmd:`Add Zify` ``BinOp``.
+ Use :cmd:`Add Zify` ``PropOp`` instead.
-.. cmd:: Add UnOp
+.. cmd:: Add PropBinOp @one_term
.. deprecated:: 8.13
- Use instead either :cmd:`Add Zify` ``UnOp``.
+ Use :cmd:`Add Zify` ``PropBinOp`` instead.
-.. cmd:: Add CstOp
+.. cmd:: Add PropUOp @one_term
.. deprecated:: 8.13
- Use instead either :cmd:`Add Zify` ``CstOp``.
+ Use :cmd:`Add Zify` ``PropUOp`` instead.
-.. cmd:: Add BinRel
+.. cmd:: Add Saturate @one_term
.. deprecated:: 8.13
- Use instead either :cmd:`Add Zify` ``BinRel``.
+ Use :cmd:`Add Zify` ``Saturate`` instead.
diff --git a/doc/sphinx/addendum/miscellaneous-extensions.rst b/doc/sphinx/addendum/miscellaneous-extensions.rst
index 0e8660cb0e..7d30cae525 100644
--- a/doc/sphinx/addendum/miscellaneous-extensions.rst
+++ b/doc/sphinx/addendum/miscellaneous-extensions.rst
@@ -1,16 +1,16 @@
Program derivation
==================
-|Coq| comes with an extension called ``Derive``, which supports program
+Coq comes with an extension called ``Derive``, which supports program
derivation. Typically in the style of Bird and Meertens or derivations
of program refinements. To use the Derive extension it must first be
required with ``Require Coq.derive.Derive``. When the extension is loaded,
it provides the following command:
-.. cmd:: Derive @ident__1 SuchThat @type As @ident__2
+.. cmd:: Derive @ident__1 SuchThat @one_term As @ident__2
- :n:`@ident__1` can appear in :n:`@type`. This command opens a new proof
- presenting the user with a goal for :n:`@type` in which the name :n:`@ident__1` is
+ :n:`@ident__1` can appear in :n:`@one_term`. This command opens a new proof
+ presenting the user with a goal for :n:`@one_term` in which the name :n:`@ident__1` is
bound to an existential variable :g:`?x` (formally, there are other goals
standing for the existential variables but they are shelved, as
described in :tacn:`shelve`).
diff --git a/doc/sphinx/addendum/nsatz.rst b/doc/sphinx/addendum/nsatz.rst
index 8a64a7ed4b..7a2be3dcef 100644
--- a/doc/sphinx/addendum/nsatz.rst
+++ b/doc/sphinx/addendum/nsatz.rst
@@ -1,12 +1,20 @@
.. _nsatz_chapter:
-Nsatz: tactics for proving equalities in integral domains
+Nsatz: a solver for equalities in integral domains
===========================================================
:Author: Loïc Pottier
-.. tacn:: nsatz
- :name: nsatz
+
+To use the tactics described in this section, load the ``Nsatz`` module with the
+command ``Require Import Nsatz``. Alternatively, if you prefer not to transitively depend on the
+files that declare the axioms used to define the real numbers, you can
+``Require Import NsatzTactic`` instead; this will still allow
+:tacn:`nsatz` to solve goals defined about :math:`\mathbb{Z}`,
+:math:`\mathbb{Q}` and any user-registered rings.
+
+
+.. tacn:: nsatz {? with radicalmax := @one_term strategy := @one_term parameters := @one_term variables := @one_term }
This tactic is for solving goals of the form
@@ -32,13 +40,36 @@ Nsatz: tactics for proving equalities in integral domains
doing automatic introductions.
- You can load the ``Nsatz`` module with the command ``Require Import Nsatz``.
+ `radicalmax`
+ bound when searching for r such that
+ :math:`c (P−Q) r = \sum_{i=1..s} S_i (P i − Q i)`.
+ This argument must be of type `N` (binary natural numbers).
- Alternatively, if you prefer not to transitively depend on the
- files declaring the axioms used to define the real numbers, you can
- ``Require Import NsatzTactic`` instead; this will still allow
- :tacn:`nsatz` to solve goals defined about :math:`\mathbb{Z}`,
- :math:`\mathbb{Q}` and any user-registered rings.
+ `strategy`
+ gives the order on variables :math:`X_1,\ldots,X_n` and the strategy
+ used in Buchberger algorithm (see :cite:`sugar` for details):
+
+ * `strategy := 0%Z`: reverse lexicographic order and newest s-polynomial.
+ * `strategy := 1%Z`: reverse lexicographic order and sugar strategy.
+ * `strategy := 2%Z`: pure lexicographic order and newest s-polynomial.
+ * `strategy := 3%Z`: pure lexicographic order and sugar strategy.
+
+ `parameters`
+ a list of parameters of type `R`, containing the variables :math:`X_{i_1},\ldots,X_{i_k}` among
+ :math:`X_1,\ldots,X_n`. Computation will be performed with
+ rational fractions in these parameters, i.e. polynomials have
+ coefficients in :math:`R(X_{i_1},\ldots,X_{i_k})`. In this case, the coefficient
+ :math:`c` can be a nonconstant polynomial in :math:`X_{i_1},\ldots,X_{i_k}`, and the tactic
+ produces a goal which states that :math:`c` is not zero.
+
+ `variables`
+ a list of variables of type `R` in the decreasing order in
+ which they will be used in the Buchberger algorithm. If the list is empty,
+ then `lvar` is replaced by all the variables which are not in
+ `parameters`.
+
+ See the file `Nsatz.v <https://github.com/coq/coq/blob/master/test-suite/success/Nsatz.v>`_
+ for examples, especially in geometry.
More about `nsatz`
---------------------
@@ -63,32 +94,3 @@ Buchberger algorithm.
This computation is done after a step of *reification*, which is
performed using :ref:`typeclasses`.
-
-.. tacv:: nsatz with radicalmax:=@natural%N strategy:=@natural%Z parameters:=[{*, @ident}] variables:=[{*, @ident}]
-
- Most complete syntax for `nsatz`.
-
- * `radicalmax` is a bound when searching for r such that
- :math:`c (P−Q) r = \sum_{i=1..s} S_i (P i − Q i)`
-
- * `strategy` gives the order on variables :math:`X_1,\ldots,X_n` and the strategy
- used in Buchberger algorithm (see :cite:`sugar` for details):
-
- * strategy = 0: reverse lexicographic order and newest s-polynomial.
- * strategy = 1: reverse lexicographic order and sugar strategy.
- * strategy = 2: pure lexicographic order and newest s-polynomial.
- * strategy = 3: pure lexicographic order and sugar strategy.
-
- * `parameters` is the list of variables :math:`X_{i_1},\ldots,X_{i_k}` among
- :math:`X_1,\ldots,X_n` which are considered as parameters: computation will be performed with
- rational fractions in these variables, i.e. polynomials are considered
- with coefficients in :math:`R(X_{i_1},\ldots,X_{i_k})`. In this case, the coefficient
- :math:`c` can be a non constant polynomial in :math:`X_{i_1},\ldots,X_{i_k}`, and the tactic
- produces a goal which states that :math:`c` is not zero.
-
- * `variables` is the list of the variables in the decreasing order in
- which they will be used in the Buchberger algorithm. If `variables` = :g:`(@nil R)`,
- then `lvar` is replaced by all the variables which are not in
- `parameters`.
-
-See the test-suite file `Nsatz.v <https://github.com/coq/coq/blob/master/test-suite/success/Nsatz.v>`_ for many examples, especially in geometry.
diff --git a/doc/sphinx/addendum/omega.rst b/doc/sphinx/addendum/omega.rst
index e1b1ee8e8d..2b10f5671d 100644
--- a/doc/sphinx/addendum/omega.rst
+++ b/doc/sphinx/addendum/omega.rst
@@ -1,6 +1,6 @@
.. _omega_chapter:
-Omega: a solver for quantifier-free problems in Presburger Arithmetic
+Omega: a (deprecated) solver for arithmetic
=====================================================================
:Author: Pierre Crégut
diff --git a/doc/sphinx/addendum/parallel-proof-processing.rst b/doc/sphinx/addendum/parallel-proof-processing.rst
index 7a50748c51..e824ae152d 100644
--- a/doc/sphinx/addendum/parallel-proof-processing.rst
+++ b/doc/sphinx/addendum/parallel-proof-processing.rst
@@ -6,8 +6,8 @@ Asynchronous and Parallel Proof Processing
:Author: Enrico Tassi
This chapter explains how proofs can be asynchronously processed by
-|Coq|. This feature improves the reactivity of the system when used in
-interactive mode via |CoqIDE|. In addition, it allows |Coq| to take
+Coq. This feature improves the reactivity of the system when used in
+interactive mode via CoqIDE. In addition, it allows Coq to take
advantage of parallel hardware when used as a batch compiler by
decoupling the checking of statements and definitions from the
construction and checking of proofs objects.
@@ -20,13 +20,13 @@ This feature has some technical limitations that may make it
unsuitable for some use cases.
For example, in interactive mode, some errors coming from the kernel
-of |Coq| are signaled late. The type of errors belonging to this
+of Coq are signaled late. The type of errors belonging to this
category are universe inconsistencies.
At the time of writing, only opaque proofs (ending with ``Qed`` or
``Admitted``) can be processed asynchronously.
-Finally, asynchronous processing is disabled when running |CoqIDE| in
+Finally, asynchronous processing is disabled when running CoqIDE in
Windows. The current implementation of the feature is not stable on
Windows. It can be enabled, as described below at :ref:`interactive-mode`,
though doing so is not recommended.
@@ -34,12 +34,12 @@ though doing so is not recommended.
Proof annotations
----------------------
-To process a proof asynchronously |Coq| needs to know the precise
+To process a proof asynchronously Coq needs to know the precise
statement of the theorem without looking at the proof. This requires
some annotations if the theorem is proved inside a Section (see
Section :ref:`section-mechanism`).
-When a section ends, |Coq| looks at the proof object to decide which
+When a section ends, Coq looks at the proof object to decide which
section variables are actually used and hence have to be quantified in
the statement of the theorem. To avoid making the construction of
proofs mandatory when ending a section, one can start each proof with
@@ -58,7 +58,7 @@ variables used.
Automatic suggestion of proof annotations
`````````````````````````````````````````
-The :flag:`Suggest Proof Using` flag makes |Coq| suggest, when a ``Qed``
+The :flag:`Suggest Proof Using` flag makes Coq suggest, when a ``Qed``
command is processed, a correct proof annotation. It is up to the user
to modify the proof script accordingly.
@@ -66,17 +66,17 @@ to modify the proof script accordingly.
Proof blocks and error resilience
--------------------------------------
-|Coq| 8.6 introduced a mechanism for error resilience: in interactive
-mode |Coq| is able to completely check a document containing errors
+Coq 8.6 introduced a mechanism for error resilience: in interactive
+mode Coq is able to completely check a document containing errors
instead of bailing out at the first failure.
Two kind of errors are supported: errors occurring in vernacular
commands and errors occurring in proofs.
-To properly recover from a failing tactic, |Coq| needs to recognize the
+To properly recover from a failing tactic, Coq needs to recognize the
structure of the proof in order to confine the error to a sub proof.
Proof block detection is performed by looking at the syntax of the
-proof script (i.e. also looking at indentation). |Coq| comes with four
+proof script (i.e. also looking at indentation). Coq comes with four
kind of proof blocks, and an ML API to add new ones.
:curly: blocks are delimited by { and }, see Chapter :ref:`proofhandling`
@@ -92,13 +92,13 @@ Caveats
When a vernacular command fails the subsequent error messages may be
bogus, i.e. caused by the first error. Error resilience for vernacular
commands can be switched off by passing ``-async-proofs-command-error-resilience off``
-to |CoqIDE|.
+to CoqIDE.
An incorrect proof block detection can result into an incorrect error
recovery and hence in bogus errors. Proof block detection cannot be
precise for bullets or any other non well parenthesized proof
structure. Error resilience can be turned off or selectively activated
-for any set of block kind passing to |CoqIDE| one of the following
+for any set of block kind passing to CoqIDE one of the following
options:
- ``-async-proofs-tactic-error-resilience off``
@@ -113,13 +113,13 @@ Interactive mode
---------------------
At the time of writing the only user interface supporting asynchronous
-proof processing is |CoqIDE|.
+proof processing is CoqIDE.
-When |CoqIDE| is started, two |Coq| processes are created. The master one
+When CoqIDE is started, two Coq processes are created. The master one
follows the user, giving feedback as soon as possible by skipping
proofs, which are delegated to the worker process. The worker process,
whose state can be seen by clicking on the button in the lower right
-corner of the main |CoqIDE| window, asynchronously processes the proofs.
+corner of the main CoqIDE window, asynchronously processes the proofs.
If a proof contains an error, it is reported in red in the label of
the very same button, that can also be used to see the list of errors
and jump to the corresponding line.
@@ -137,14 +137,14 @@ Only then all the universe constraints are checked.
Caveats
```````
-The number of worker processes can be increased by passing |CoqIDE|
+The number of worker processes can be increased by passing CoqIDE
the ``-async-proofs-j n`` flag. Note that the memory consumption increases too,
since each worker requires the same amount of memory as the master
process. Also note that increasing the number of workers may reduce
the reactivity of the master process to user commands.
To disable this feature, one can pass the ``-async-proofs off`` flag to
-|CoqIDE|. Conversely, on Windows, where the feature is disabled by
+CoqIDE. Conversely, on Windows, where the feature is disabled by
default, pass the ``-async-proofs on`` flag to enable it.
Proofs that are known to take little time to process are not delegated
@@ -166,9 +166,9 @@ Batch mode
a ``Require``. Indeed, the loading of a nonempty ``.vos`` file is
assigned higher priority than the loading of a ``.vio`` file.
-When |Coq| is used as a batch compiler by running ``coqc``, it produces
+When Coq is used as a batch compiler by running ``coqc``, it produces
a ``.vo`` file for each ``.v`` file. A ``.vo`` file contains, among other
-things, theorem statements and proofs. Hence to produce a .vo |Coq|
+things, theorem statements and proofs. Hence to produce a .vo Coq
need to process all the proofs of the ``.v`` file.
The asynchronous processing of proofs can decouple the generation of a
@@ -224,7 +224,7 @@ heavy use of the ``Type`` hierarchy.
Limiting the number of parallel workers
--------------------------------------------
-Many |Coq| processes may run on the same computer, and each of them may
+Many Coq processes may run on the same computer, and each of them may
start many additional worker processes. The ``coqworkmgr`` utility lets
one limit the number of workers, globally.
@@ -232,9 +232,9 @@ The utility accepts the ``-j`` argument to specify the maximum number of
workers (defaults to 2). ``coqworkmgr`` automatically starts in the
background and prints an environment variable assignment
like ``COQWORKMGR_SOCKET=localhost:45634``. The user must set this variable
-in all the shells from which |Coq| processes will be started. If one
+in all the shells from which Coq processes will be started. If one
uses just one terminal running the bash shell, then
``export ‘coqworkmgr -j 4‘`` will do the job.
-After that, all |Coq| processes, e.g. ``coqide`` and ``coqc``, will respect the
+After that, all Coq processes, e.g. ``coqide`` and ``coqc``, will respect the
limit, globally.
diff --git a/doc/sphinx/addendum/program.rst b/doc/sphinx/addendum/program.rst
index c6a4b4fe1a..298ea4b4ab 100644
--- a/doc/sphinx/addendum/program.rst
+++ b/doc/sphinx/addendum/program.rst
@@ -8,34 +8,34 @@ Program
:Author: Matthieu Sozeau
We present here the |Program| tactic commands, used to build
-certified |Coq| programs, elaborating them from their algorithmic
+certified Coq programs, elaborating them from their algorithmic
skeleton and a rich specification :cite:`sozeau06`. It can be thought of as a
dual of :ref:`Extraction <extraction>`. The goal of |Program| is to
program as in a regular functional programming language whilst using
as rich a specification as desired and proving that the code meets the
-specification using the whole |Coq| proof apparatus. This is done using
+specification using the whole Coq proof apparatus. This is done using
a technique originating from the “Predicate subtyping” mechanism of
PVS :cite:`Rushby98`, which generates type checking conditions while typing a
term constrained to a particular type. Here we insert existential
variables in the term, which must be filled with proofs to get a
-complete |Coq| term. |Program| replaces the |Program| tactic by Catherine
+complete Coq term. |Program| replaces the |Program| tactic by Catherine
Parent :cite:`Parent95b` which had a similar goal but is no longer maintained.
-The languages available as input are currently restricted to |Coq|’s
+The languages available as input are currently restricted to Coq’s
term language, but may be extended to OCaml, Haskell and
-others in the future. We use the same syntax as |Coq| and permit to use
+others in the future. We use the same syntax as Coq and permit to use
implicit arguments and the existing coercion mechanism. Input terms
and types are typed in an extended system (Russell) and interpreted
-into |Coq| terms. The interpretation process may produce some proof
+into Coq terms. The interpretation process may produce some proof
obligations which need to be resolved to create the final term.
.. _elaborating-programs:
Elaborating programs
----------------------
+--------------------
-The main difference from |Coq| is that an object in a type :g:`T : Set` can
+The main difference from Coq is that an object in a type :g:`T : Set` can
be considered as an object of type :g:`{x : T | P}` for any well-formed
:g:`P : Prop`. If we go from :g:`T` to the subset of :g:`T` verifying property
:g:`P`, we must prove that the object under consideration verifies it. Russell
@@ -83,15 +83,15 @@ coercions.
.. flag:: Program Cases
- This controls the special treatment of pattern matching generating equalities
+ Controls the special treatment of pattern matching generating equalities
and disequalities when using |Program| (it is on by default). All
pattern-matches and let-patterns are handled using the standard algorithm
- of |Coq| (see :ref:`extendedpatternmatching`) when this flag is
+ of Coq (see :ref:`extendedpatternmatching`) when this flag is
deactivated.
.. flag:: Program Generalized Coercion
- This controls the coercion of general inductive types when using |Program|
+ Controls the coercion of general inductive types when using |Program|
(the flag is on by default). Coercion of subset types and pairs is still
active in this case.
@@ -104,19 +104,19 @@ coercions.
typechecking.
.. attr:: program
+ :name: program; Program
- This attribute allows to use the Program mode on a specific
+ Allows using the Program mode on a specific
definition. An alternative syntax is to use the legacy ``Program``
- prefix (cf. :n:`@legacy_attr`) as documented in the rest of this
- chapter.
+ prefix (cf. :n:`@legacy_attr`) as it is elsewhere in this chapter.
.. _syntactic_control:
Syntactic control over equalities
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To give more control over the generation of equalities, the
-type checker will fall back directly to |Coq|’s usual typing of dependent
+type checker will fall back directly to Coq’s usual typing of dependent
pattern matching if a ``return`` or ``in`` clause is specified. Likewise, the
if construct is not treated specially by |Program| so boolean tests in
the code are not automatically reflected in the obligations. One can
@@ -158,36 +158,20 @@ prove some goals to construct the final definitions.
Program Definition
~~~~~~~~~~~~~~~~~~
-.. cmd:: Program Definition @ident := @term
-
- This command types the value term in Russell and generates proof
- obligations. Once solved using the commands shown below, it binds the
- final |Coq| term to the name :n:`@ident` in the environment.
-
- .. exn:: @ident already exists.
- :name: @ident already exists. (Program Definition)
- :undocumented:
-
- .. cmdv:: Program Definition @ident : @type := @term
-
- It interprets the type :n:`@type`, potentially generating proof
- obligations to be resolved. Once done with them, we have a |Coq|
- type :n:`@type__0`. It then elaborates the preterm :n:`@term` into a |Coq|
- term :n:`@term__0`, checking that the type of :n:`@term__0` is coercible to
- :n:`@type__0`, and registers :n:`@ident` as being of type :n:`@type__0` once the
- set of obligations generated during the interpretation of :n:`@term__0`
- and the aforementioned coercion derivation are solved.
-
- .. exn:: In environment … the term: @term does not have type @type. Actually, it has type ...
- :undocumented:
+A :cmd:`Definition` command with the :attr:`program` attribute types
+the value term in Russell and generates proof
+obligations. Once solved using the commands shown below, it binds the
+final Coq term to the name :n:`@ident` in the environment.
- .. cmdv:: Program Definition @ident {* @binder } : @type := @term
+:n:`Program Definition @ident : @type := @term`
- This is equivalent to:
-
- :n:`Program Definition @ident : forall {* @binder }, @type := fun {* @binder } => @term`.
-
- .. TODO refer to production in alias
+Interprets the type :n:`@type`, potentially generating proof
+obligations to be resolved. Once done with them, we have a Coq
+type :n:`@type__0`. It then elaborates the preterm :n:`@term` into a Coq
+term :n:`@term__0`, checking that the type of :n:`@term__0` is coercible to
+:n:`@type__0`, and registers :n:`@ident` as being of type :n:`@type__0` once the
+set of obligations generated during the interpretation of :n:`@term__0`
+and the aforementioned coercion derivation are solved.
.. seealso:: Sections :ref:`vernac-controlling-the-reduction-strategies`, :tacn:`unfold`
@@ -196,20 +180,8 @@ Program Definition
Program Fixpoint
~~~~~~~~~~~~~~~~
-.. cmd:: Program Fixpoint @fix_definition {* with @fix_definition }
-
- The optional :n:`@fixannot` annotation can be one of:
-
- + :g:`measure f R` where :g:`f` is a value of type :g:`X` computed on
- any subset of the arguments and the optional term
- :g:`R` is a relation on :g:`X`. :g:`X` defaults to :g:`nat` and :g:`R`
- to :g:`lt`.
-
- + :g:`wf R x` which is equivalent to :g:`measure x R`.
-
- The structural fixpoint operator behaves just like the one of |Coq| (see
- :cmd:`Fixpoint`), except it may also generate obligations. It works
- with mutually recursive definitions too.
+A :cmd:`Fixpoint` command with the :attr:`program` attribute may also generate obligations. It works
+with mutually recursive definitions too. For example:
.. coqtop:: reset in
@@ -223,6 +195,17 @@ Program Fixpoint
| _ => O
end.
+The :cmd:`Fixpoint` command may include an optional :n:`@fixannot` annotation, which can be:
+
++ :g:`measure f R` where :g:`f` is a value of type :g:`X` computed on
+ any subset of the arguments and the optional term
+ :g:`R` is a relation on :g:`X`. :g:`X` defaults to :g:`nat` and :g:`R`
+ to :g:`lt`.
+
++ :g:`wf R x` which is equivalent to :g:`measure x R`.
+
+.. todo see https://github.com/coq/coq/pull/12936#discussion_r492747830
+
Here we have one obligation for each branch (branches for :g:`0` and
``(S 0)`` are automatically generated by the pattern matching
compilation algorithm).
@@ -246,8 +229,6 @@ using the syntax:
| _ => O
end.
-
-
.. caution:: When defining structurally recursive functions, the generated
obligations should have the prototype of the currently defined
functional in their context. In this case, the obligations should be
@@ -266,67 +247,70 @@ using the syntax:
Program Lemma
~~~~~~~~~~~~~
-.. cmd:: Program Lemma @ident : @type
-
- The Russell language can also be used to type statements of logical
- properties. It will generate obligations, try to solve them
- automatically and fail if some unsolved obligations remain. In this
- case, one can first define the lemma’s statement using :g:`Program
- Definition` and use it as the goal afterwards. Otherwise the proof
- will be started with the elaborated version as a goal. The
- :g:`Program` prefix can similarly be used as a prefix for
- :g:`Variable`, :g:`Hypothesis`, :g:`Axiom` etc.
+A :cmd:`Lemma` command with the :attr:`program` attribute uses the Russell
+language to type statements of logical
+properties. It generates obligations, tries to solve them
+automatically and fails if some unsolved obligations remain. In this
+case, one can first define the lemma’s statement using :cmd:`Definition`
+and use it as the goal afterwards. Otherwise the proof
+will be started with the elaborated version as a goal. The
+:attr:`Program` attribute can similarly be used with
+:cmd:`Variable`, :cmd:`Hypothesis`, :cmd:`Axiom` etc.
.. _solving_obligations:
Solving obligations
---------------------
+-------------------
The following commands are available to manipulate obligations. The
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 := @ltac_expr
+.. cmd:: Obligation Tactic := @ltac_expr
:name: Obligation Tactic
Sets the default obligation solving tactic applied to all obligations
automatically, whether to solve them or when starting to prove one,
- e.g. using :g:`Next`. :g:`Local` makes the setting last only for the current
- module. Inside sections, local is the default.
+ e.g. using :cmd:`Next Obligation`.
+
+ This command supports the :attr:`local` and :attr:`global` attributes.
+ :attr:`local` makes the setting last only for the current
+ module. :attr:`local` is the default inside sections while :attr:`global`
+ otherwise.
.. cmd:: Show Obligation Tactic
Displays the current default tactic.
-.. cmd:: Obligations {? of @ident}
+.. cmd:: Obligations {? of @ident }
Displays all remaining obligations.
-.. cmd:: Obligation @natural {? of @ident}
+.. cmd:: Obligation @natural {? of @ident } {? : @type {? with @ltac_expr } }
Start the proof of obligation :token:`natural`.
-.. cmd:: Next Obligation {? of @ident}
+.. cmd:: Next Obligation {? of @ident } {? with @ltac_expr }
Start the proof of the next unsolved obligation.
-.. cmd:: Solve Obligations {? {? of @ident} with @ltac_expr}
+.. cmd:: Solve Obligations {? of @ident } {? with @ltac_expr }
- Tries to solve each obligation of ``ident`` using the given ``tactic`` or the default one.
+ Tries to solve each obligation of :token:`ident` using the given :token:`ltac_expr` or the default one.
-.. cmd:: Solve All Obligations {? with @ltac_expr}
+.. cmd:: Solve All Obligations {? with @ltac_expr }
Tries to solve each obligation of every program using the given
tactic or the default one (useful for mutually recursive definitions).
-.. cmd:: Admit Obligations {? of @ident}
+.. cmd:: Admit Obligations {? of @ident }
- Admits all obligations (of ``ident``).
+ Admits all obligations (of :token:`ident`).
.. note:: Does not work with structurally recursive programs.
-.. cmd:: Preterm {? of @ident}
+.. cmd:: Preterm {? of @ident }
Shows the term that will be fed to the kernel once the obligations
are solved. Useful for debugging.
@@ -358,7 +342,7 @@ Frequently Asked Questions
.. exn:: Ill-formed recursive definition.
This error can happen when one tries to define a function by structural
- recursion on a subset object, which means the |Coq| function looks like:
+ recursion on a subset object, which means the Coq function looks like:
::
diff --git a/doc/sphinx/addendum/ring.rst b/doc/sphinx/addendum/ring.rst
index cda8a1b679..c93d621048 100644
--- a/doc/sphinx/addendum/ring.rst
+++ b/doc/sphinx/addendum/ring.rst
@@ -10,8 +10,8 @@
.. _theringandfieldtacticfamilies:
-The ring and field tactic families
-====================================
+ring and field: solvers for polynomial and rational equations
+=============================================================
:Author: Bruno Barras, Benjamin Grégoire, Assia Mahboubi, Laurent Théry [#f1]_
@@ -102,7 +102,7 @@ forget this paragraph and use the tactic according to your intuition.
Concrete usage in Coq
--------------------------
-.. tacn:: ring {? [ {+ @term } ] }
+.. tacn:: ring {? [ {+ @one_term } ] }
Solves polynomical equations of a ring
(or semiring) structure. It proceeds by normalizing both sides
@@ -110,14 +110,35 @@ Concrete usage in Coq
distributivity, constant propagation, rewriting of monomials) and
syntactically comparing the results.
-.. tacn:: ring_simplify {? [ {+ @term } ] } {+ @term } {? in @ident }
+ :n:`[ {+ @one_term } ]`
+ If specified, the tactic decides the equality of two terms modulo ring operations and
+ the equalities defined by the :token:`one_term`\s.
+ Each :token:`one_term` has to be a proof of some equality :g:`m = p`, where :g:`m`
+ is a monomial (after “abstraction”), :g:`p` a polynomial and :g:`=` is the
+ corresponding equality of the ring structure.
+
+.. tacn:: ring_simplify {? [ {+ @one_term } ] } {+ @one_term } {? in @ident }
Applies the normalization procedure described above to
- the given terms. The tactic then replaces all occurrences of the terms
- given in the conclusion of the goal by their normal forms. If no term
+ the given :token:`one_term`\s. The tactic then replaces all occurrences of the :token:`one_term`\s
+ given in the conclusion of the goal by their normal forms. If no :token:`one_term`
is given, then the conclusion should be an equation and both
sides are normalized. The tactic can also be applied in a hypothesis.
+ :n:`in @ident`
+ If specified, the tactic performs the simplification in the hypothesis named :token:`ident`.
+
+ .. note::
+
+ :n:`ring_simplify @one_term__1; ring_simplify @one_term__2` is not equivalent to
+ :n:`ring_simplify @one_term__1 @one_term__2`.
+
+ In the latter case the variables map is shared between the two :token:`one_term`\s, and
+ common subterm :g:`t` of :n:`@one_term__1` and :n:`@one_term__2`
+ will have the same associated variable number. So the first
+ alternative should be avoided for :token:`one_term`\s belonging to the same ring
+ theory.
+
The tactic must be loaded by ``Require Import Ring``. The ring structures
must be declared with the ``Add Ring`` command (see below). The ring of
booleans is predefined; if one wants to use the tactic on |nat| one must
@@ -147,31 +168,6 @@ Concrete usage in Coq
Abort.
-.. tacv:: ring [{* @term }]
-
- This tactic decides the equality of two terms modulo ring operations and
- the equalities defined by the :token:`term`\ s.
- Each :token:`term` has to be a proof of some equality :g:`m = p`, where :g:`m`
- is a monomial (after “abstraction”), :g:`p` a polynomial and :g:`=` the
- corresponding equality of the ring structure.
-
-.. tacv:: ring_simplify [{* @term }] {* @term } in @ident
-
- This tactic performs the simplification in the hypothesis named :token:`ident`.
-
-
-.. note::
-
- :n:`ring_simplify @term__1; ring_simplify @term__2` is not equivalent to
- :n:`ring_simplify @term__1 @term__2`.
-
- In the latter case the variables map is shared between the two terms, and
- common subterm :g:`t` of :n:`@term__1` and :n:`@term__2`
- will have the same associated variable number. So the first
- alternative should be avoided for terms belonging to the same ring
- theory.
-
-
Error messages:
@@ -386,7 +382,7 @@ The syntax for adding a new ring is
that, given a term, “abstracts” it into an object of type |N| whose
interpretation via ``Cp_phi`` (the evaluation function of power
coefficient) is the original term, or returns ``InitialRing.NotConstant``
- if not a constant coefficient (i.e. |L_tac| is the inverse function of
+ if not a constant coefficient (i.e. |Ltac| is the inverse function of
``Cp_phi``). See files ``plugins/ring/ZArithRing.v``
and ``plugins/ring/RealField.v`` for examples. By default the tactic
does not recognize power expressions as ring expressions.
@@ -433,7 +429,7 @@ How does it work?
The code of ``ring`` is a good example of a tactic written using *reflection*.
What is reflection? Basically, using it means that a part of a tactic is written
-in Gallina, Coq's language of terms, rather than |Ltac| or |OCaml|. From the
+in Gallina, Coq's language of terms, rather than |Ltac| or OCaml. From the
philosophical point of view, reflection is using the ability of the Calculus of
Constructions to speak and reason about itself. For the ``ring`` tactic we used
Coq as a programming language and also as a proof environment to build a tactic
@@ -495,7 +491,7 @@ its correctness w.r.t interpretation, that is:
So now, what is the scheme for a normalization proof? Let p be the
polynomial expression that the user wants to normalize. First a little
-piece of |ML| code guesses the type of `p`, the ring theory `T` to use, an
+piece of ML code guesses the type of `p`, the ring theory `T` to use, an
abstract polynomial `ap` and a variables map `v` such that `p` is |bdi|-
equivalent to `(PEeval v ap)`. Then we replace it by `(Pphi_dev v (norm ap))`,
using the main correctness theorem and we reduce it to a
@@ -515,15 +511,27 @@ application of the main correctness theorem to well-chosen arguments.
Dealing with fields
------------------------
-.. tacn:: field {? [ {+ @term } ] }
+.. tacn:: field {? [ {+ @one_term } ] }
- This tactic is an extension of the :tacn:`ring` tactic that deals with rational
+ An extension of the :tacn:`ring` tactic that deals with rational
expressions. Given a rational expression :math:`F = 0`. It first reduces the
expression `F` to a common denominator :math:`N/D = 0` where `N` and `D`
are two ring expressions. For example, if we take :math:`F = (1 − 1/x) x − x + 1`, this
gives :math:`N = (x − 1) x − x^2 + x` and :math:`D = x`. It then calls ring to solve
:math:`N = 0`.
+ :n:`[ {+ @one_term } ]`
+ If specified, the tactic decides the equality of two terms modulo
+ field operations and the equalities defined
+ by the :token:`one_term`\s. Each :token:`one_term` has to be a proof of some equality
+ :g:`m = p`, where :g:`m` is a monomial (after “abstraction”), :g:`p` a polynomial
+ and :g:`=` the corresponding equality of the field structure.
+
+ .. note::
+
+ Rewriting works with the equality :g:`m = p` only if :g:`p` is a polynomial since
+ rewriting is handled by the underlying ring tactic.
+
Note that :n:`field` also generates nonzero conditions for all the
denominators it encounters in the reduction. In our example, it
generates the condition :math:`x \neq 0`. These conditions appear as one subgoal
@@ -559,71 +567,49 @@ Dealing with fields
intros x y H H1; field [H1]; auto.
Abort.
-.. tacv:: field [{* @term}]
- This tactic decides the equality of two terms modulo
- field operations and the equalities defined
- by the :token:`term`\s. Each :token:`term` has to be a proof of some equality
- :g:`m = p`, where :g:`m` is a monomial (after “abstraction”), :g:`p` a polynomial
- and :g:`=` the corresponding equality of the field structure.
+.. example:: :tacn:`field` that generates side goals
-.. note::
+ .. coqtop:: reset all
- Rewriting works with the equality :g:`m = p` only if :g:`p` is a polynomial since
- rewriting is handled by the underlying ring tactic.
+ Require Import Reals.
+ Goal forall x y:R,
+ (x * y > 0)%R ->
+ (x * (1 / x + x / (x + y)))%R =
+ ((- 1 / y) * y * (- x * (x / (x + y)) - 1))%R.
-.. tacn:: field_simplify {? [ {+ @term } ] } {+ @term } {? in @ident }
+ intros; field.
+
+.. tacn:: field_simplify {? [ {+ @one_term__eq } ] } {+ @one_term } {? in @ident }
- performs the simplification in the conclusion of the
+ Performs the simplification in the conclusion of the
goal, :math:`F_1 = F_2` becomes :math:`N_1 / D_1 = N_2 / D_2`. A normalization step
(the same as the one for rings) is then applied to :math:`N_1`, :math:`D_1`,
:math:`N_2` and :math:`D_2`. This way, polynomials remain in factorized form during
fraction simplification. This yields smaller expressions when
reducing to the same denominator since common factors can be canceled.
-.. tacv:: field_simplify [{* @term }]
-
- This variant performs the simplification in the conclusion of the goal using the equalities
- defined by the :token:`term`\s.
-
-.. tacv:: field_simplify [{* @term }] {* @term }
-
- This variant performs the simplification in the terms :token:`term`\s of the conclusion of the goal
- using the equalities defined by :token:`term`\s inside the brackets.
-
-.. tacv:: field_simplify in @ident
-
- This variant performs the simplification in the assumption :token:`ident`.
-
-.. tacv:: field_simplify [{* @term }] in @ident
-
- This variant performs the simplification
- in the assumption :token:`ident` using the equalities defined by the :token:`term`\s.
-
-.. tacv:: field_simplify [{* @term }] {* @term } in @ident
-
- This variant performs the simplification in the :token:`term`\s of the
- assumption :token:`ident` using the
- equalities defined by the :token:`term`\s inside the brackets.
-
-.. tacn:: field_simplify_eq {? [ {+ @term } ] } {? in @ident }
-
- performs the simplification in the conclusion of
- the goal removing the denominator. :math:`F_1 = F_2` becomes :math:`N_1 D_2 = N_2 D_1`.
+ :n:`[ {+ @one_term__eq } ]`
+ Do simplification in the conclusion of the goal using the equalities
+ defined by these :token:`one_term`\s.
-.. tacv:: field_simplify_eq [ {* @term }]
+ :n:`{+ @one_term }`
+ Terms to simplify in the conclusion.
- This variant performs the simplification in
- the conclusion of the goal using the equalities defined by :token:`term`\s.
+ :n:`in @ident`
+ If specified, substitute in the hypothesis :n:`@ident` instead of the conclusion.
-.. tacv:: field_simplify_eq in @ident
+.. tacn:: field_simplify_eq {? [ {+ @one_term } ] } {? in @ident }
- This variant performs the simplification in the assumption :token:`ident`.
+ Performs the simplification in the conclusion of
+ the goal, removing the denominator. :math:`F_1 = F_2` becomes :math:`N_1 D_2 = N_2 D_1`.
-.. tacv:: field_simplify_eq [{* @term}] in @ident
+ :n:`[ {+ @one_term } ]`
+ Do simplification in the conclusion of the goal using the equalities
+ defined by these :token:`one_term`\s.
- This variant performs the simplification in the assumption :token:`ident`
- using the equalities defined by :token:`term`\s and removing the denominator.
+ :n:`in @ident`
+ If specified, simplify in the hypothesis :n:`@ident` instead of the conclusion.
Adding a new field structure
@@ -704,9 +690,9 @@ History of ring
First Samuel Boutin designed the tactic ``ACDSimpl``. This tactic did lot
of rewriting. But the proofs terms generated by rewriting were too big
-for |Coq|’s type checker. Let us see why:
+for Coq’s type checker. Let us see why:
-.. coqtop:: all
+.. coqtop:: reset all
Require Import ZArith.
Open Scope Z_scope.
@@ -724,7 +710,7 @@ was rewritten by Patrick Loiseleur: the new tactic does not any
more require ``ACDSimpl`` to compile and it makes use of |bdi|-reduction not
only to replace the rewriting steps, but also to achieve the
interleaving of computation and reasoning (see :ref:`discussion_reflection`). He also wrote
-some |ML| code for the ``Add Ring`` command that allows registering new rings dynamically.
+some ML code for the ``Add Ring`` command that allows registering new rings dynamically.
Proofs terms generated by ring are quite small, they are linear in the
number of :math:`\oplus` and :math:`\otimes` operations in the normalized terms. Type checking
@@ -767,12 +753,12 @@ tactics using reflection.
Another idea suggested by Benjamin Werner: reflection could be used to
couple an external tool (a rewriting program or a model checker)
-with |Coq|. We define (in |Coq|) a type of terms, a type of *traces*, and
+with Coq. We define (in Coq) a type of terms, a type of *traces*, and
prove a correctness theorem that states that *replaying traces* is safe
with respect to some interpretation. Then we let the external tool do every
computation (using side-effects, backtracking, exception, or others
features that are not available in pure lambda calculus) to produce
-the trace. Now we can check in |Coq| that the trace has the expected
+the trace. Now we can check in Coq that the trace has the expected
semantics by applying the correctness theorem.
diff --git a/doc/sphinx/addendum/sprop.rst b/doc/sphinx/addendum/sprop.rst
index 6c62ff3116..2b1f343e14 100644
--- a/doc/sphinx/addendum/sprop.rst
+++ b/doc/sphinx/addendum/sprop.rst
@@ -10,13 +10,13 @@ SProp (proof irrelevant propositions)
In particular, conversion checking through bytecode or native code
compilation currently does not understand proof irrelevance.
-This section describes the extension of |Coq| with definitionally
+This section describes the extension of Coq with definitionally
proof irrelevant propositions (types in the sort :math:`\SProp`, also
known as strict propositions) as described in
:cite:`Gilbert:POPL2019`.
Use of |SProp| may be disabled by passing ``-disallow-sprop`` to the
-|Coq| program or by turning the :flag:`Allow StrictProp` flag off.
+Coq program or by turning the :flag:`Allow StrictProp` flag off.
.. flag:: Allow StrictProp
:name: Allow StrictProp
diff --git a/doc/sphinx/addendum/type-classes.rst b/doc/sphinx/addendum/type-classes.rst
index d533470f22..2474c784b8 100644
--- a/doc/sphinx/addendum/type-classes.rst
+++ b/doc/sphinx/addendum/type-classes.rst
@@ -295,10 +295,29 @@ the Existing Instance command to achieve the same effect.
Summary of the commands
-----------------------
-.. cmd:: Class @inductive_definition {* with @inductive_definition }
+.. cmd:: Class @record_definition
+ Class @singleton_class_definition
- The :cmd:`Class` command is used to declare a typeclass with parameters
- :n:`{* @binder }` and fields the declared record fields.
+ .. insertprodn singleton_class_definition singleton_class_definition
+
+ .. prodn::
+ singleton_class_definition ::= {? > } @ident_decl {* @binder } {? : @sort } := @constructor
+
+ The first form declares a record and makes the record a typeclass with parameters
+ :n:`{* @binder }` and the listed record fields.
+
+ .. _singleton-class:
+
+ The second form declares a *singleton* class with a single method. This
+ singleton class is a so-called definitional class, represented simply
+ as a definition ``ident binders := term`` and whose instances are
+ themselves objects of this type. Definitional classes are not wrapped
+ inside records, and the trivial projection of an instance of such a
+ class is convertible to the instance itself. This can be useful to
+ make instances of existing objects easily and to reduce proof size by
+ not inserting useless projections. The class constant itself is
+ declared rigid during resolution so that the class abstraction is
+ maintained.
Like any command declaring a record, this command supports the
:attr:`universes(polymorphic)`, :attr:`universes(monomorphic)`,
@@ -306,22 +325,7 @@ Summary of the commands
:attr:`universes(cumulative)`, :attr:`universes(noncumulative)` and
:attr:`private(matching)` attributes.
- .. _singleton-class:
-
- .. cmdv:: Class @ident {* @binder } : {? @sort} := @ident : @term
-
- This variant declares a *singleton* class with a single method. This
- singleton class is a so-called definitional class, represented simply
- as a definition ``ident binders := term`` and whose instances are
- themselves objects of this type. Definitional classes are not wrapped
- inside records, and the trivial projection of an instance of such a
- class is convertible to the instance itself. This can be useful to
- make instances of existing objects easily and to reduce proof size by
- not inserting useless projections. The class constant itself is
- declared rigid during resolution so that the class abstraction is
- maintained.
-
- .. cmdv:: Existing Class @ident
+ .. cmd:: Existing Class @qualid
This variant declares a class from a previously declared constant or
inductive definition. No methods or instances are defined.
@@ -330,27 +334,34 @@ Summary of the commands
This command has no effect when used on a typeclass.
-.. cmd:: Instance @ident {* @binder } : @term__0 {+ @term} {? | @natural} := { {*; @field_def} }
+.. cmd:: Instance {? @ident_decl {* @binder } } : @type {? @hint_info } {? {| := %{ {* @field_def } %} | := @term } }
+
+ .. insertprodn hint_info one_pattern
+
+ .. prodn::
+ hint_info ::= %| {? @natural } {? @one_pattern }
+ one_pattern ::= @one_term
- This command is used to declare a typeclass instance named
- :token:`ident` of the class :n:`@term__0` with parameters :token:`term` and
+ Declares a typeclass instance named
+ :token:`ident_decl` of the class :n:`@type` with the specified parameters and with
fields defined by :token:`field_def`, where each field must be a declared field of
the class.
- An arbitrary context of :n:`{* @binder }` 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 :token:`natural` is not specified, it defaults to the number
- of non-dependent binders of the instance.
+ Adds one or more :token:`binder`\s to declare a parameterized instance. :token:`hint_info`
+ may be used to specify the hint priority, where 0 is the highest priority as for
+ :tacn:`auto` hints. If the priority is not specified, the default is the number
+ of non-dependent binders of the instance. If :token:`one_pattern` is given, terms
+ matching that pattern will trigger use of the instance. Otherwise,
+ use is triggered based on the conclusion of the type.
This command supports the :attr:`global` attribute that can be
used on instances declared in a section so that their
- generalization is automatically redeclared after the section is
+ generalization is automatically redeclared when the section is
closed.
Like :cmd:`Definition`, it also supports the :attr:`program`
attribute to switch the type checking to `Program` (chapter
- :ref:`programs`) and use the obligation mechanism to manage missing
+ :ref:`programs`) and to use the obligation mechanism to manage missing
fields.
Finally, it supports the lighter :attr:`refine` attribute:
@@ -362,67 +373,53 @@ Summary of the commands
to fill them. It works exactly as if no body had been given and
the :tacn:`refine` tactic has been used first.
- .. cmdv:: Instance @ident {* @binder } : forall {* @binder }, @term__0 {+ @term} {? | @natural } := @term
+ .. cmd:: Declare Instance @ident_decl {* @binder } : @term {? @hint_info }
- This syntax is used for declaration of singleton class instances or
- for directly giving an explicit term of type :n:`forall {* @binder }, @term__0
- {+ @term}`. One need not even mention the unique field name for
- singleton classes.
-
- .. cmdv:: Declare Instance
- :name: Declare Instance
-
- In a :cmd:`Module Type`, this command states that a corresponding concrete
+ In a :cmd:`Module Type`, declares that a corresponding concrete
instance should exist in any implementation of this :cmd:`Module Type`. This
is similar to the distinction between :cmd:`Parameter` vs. :cmd:`Definition`, or
between :cmd:`Declare Module` and :cmd:`Module`.
-Besides the :cmd:`Class` and :cmd:`Instance` vernacular commands, there are a
-few other commands related to typeclasses.
+ .. cmd:: Existing Instance @qualid {? @hint_info }
+ Existing Instances {+ @qualid } {? %| @natural }
+
+ Adds a constant whose type ends with
+ an applied typeclass to the instance database with an optional
+ priority :token:`natural`. 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`.
+
+ .. flag:: Instance Generalized Output
+
+ .. deprecated:: 8.13
-.. cmd:: Existing Instance {+ @ident} {? | @natural}
+ Disabled by default, this provides compatibility with Coq
+ version 8.12 and earlier.
- This command adds an arbitrary list of constants whose type ends with
- an applied typeclass to the instance database with an optional
- priority :token:`natural`. 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`.
+ When enabled, the type of the instance is implicitly generalized
+ over unbound and :ref:`generalizable <implicit-generalization>` variables as though surrounded by ``\`{}``.
-.. tacn:: typeclasses eauto
- :name: typeclasses eauto
+.. cmd:: Print Instances @reference
- This proof search tactic implements the resolution engine that is run
+ Shows the list of instances associated with the typeclass :token:`reference`.
+
+
+.. tacn:: typeclasses eauto {? bfs } {? @int_or_var } {? with {+ @ident } }
+
+ This proof search tactic uses the resolution engine that is run
implicitly during type checking. This tactic uses a different resolution
engine than :tacn:`eauto` and :tacn:`auto`. The main differences are the
following:
- + Contrary to :tacn:`eauto` and :tacn:`auto`, the resolution is done entirely in
- the new proof engine (as of Coq 8.6), meaning that backtracking is
+ + Unlike :tacn:`eauto` and :tacn:`auto`, the resolution is done entirely in
+ the proof engine, meaning that backtracking is
available among dependent subgoals, and shelving goals is supported.
``typeclasses eauto`` is a multi-goal tactic. It analyses the dependencies
between subgoals to avoid backtracking on subgoals that are entirely
independent.
- + When called with no arguments, ``typeclasses eauto`` uses
- the ``typeclass_instances`` database by default (instead of core).
- Dependent subgoals are automatically shelved, and shelved goals can
- remain after resolution ends (following the behavior of Coq 8.5).
-
- .. note::
- As of Coq 8.6, ``all:once (typeclasses eauto)`` faithfully
- mimics what happens during typeclass resolution when it is called
- during refinement/type inference, except that *only* declared class
- subgoals are considered at the start of resolution during type
- inference, while ``all`` can select non-class subgoals as well. It might
- move to ``all:typeclasses eauto`` in future versions when the
- refinement engine will be able to backtrack.
-
- + When called with specific databases (e.g. with), ``typeclasses eauto``
- allows shelved goals to remain at any point during search and treat
- typeclass goals like any other.
-
+ The transparency information of databases is used consistently for
all hints declared in them. It is always used when calling the
unifier. When considering local hypotheses, we use the transparent
@@ -446,26 +443,44 @@ few other commands related to typeclasses.
+ When considering local hypotheses, we use the union of all the modes
declared in the given databases.
- .. tacv:: typeclasses eauto @natural
+ + Use the :cmd:`Typeclasses eauto` command to customize the behavior of
+ this tactic.
- .. warning::
- The semantics for the limit :n:`@natural`
- is different than for auto. By default, if no limit is given, the
- search is unbounded. Contrary to :tacn:`auto`, introduction steps are
- counted, which might result in larger limits being necessary when
- searching with ``typeclasses eauto`` than with :tacn:`auto`.
+ :n:`@int_or_var`
+ Specifies the maximum depth of the search.
- .. tacv:: typeclasses eauto with {+ @ident}
+ .. warning::
+ The semantics for the limit :n:`@int_or_var`
+ are different than for :tacn:`auto`. By default, if no limit is given, the
+ search is unbounded. Unlike :tacn:`auto`, introduction steps count against
+ the limit, which might result in larger limits being necessary when
+ searching with :tacn:`typeclasses eauto` than with :tacn:`auto`.
+
+ :n:`with {+ @ident }`
+ Runs resolution with the specified hint databases. It treats
+ typeclass subgoals the same as other subgoals (no shelving of
+ non-typeclass goals in particular), while allowing shelved goals
+ to remain at any point during search.
+
+ When :n:`with` is not specified, :tacn:`typeclasses eauto` uses
+ the ``typeclass_instances`` database by default (instead of ``core``).
+ Dependent subgoals are automatically shelved, and shelved goals can
+ remain after resolution ends (following the behavior of Coq 8.5).
- This variant runs resolution with the given hint databases. It treats
- typeclass subgoals the same as other subgoals (no shelving of
- non-typeclass goals in particular).
+ .. note::
+ ``all:once (typeclasses eauto)`` faithfully
+ mimics what happens during typeclass resolution when it is called
+ during refinement/type inference, except that *only* declared class
+ subgoals are considered at the start of resolution during type
+ inference, while ``all`` can select non-class subgoals as well. It might
+ move to ``all:typeclasses eauto`` in future versions when the
+ refinement engine will be able to backtrack.
-.. tacn:: autoapply @term with @ident
+.. tacn:: autoapply @one_term with @ident
:name: autoapply
- The tactic ``autoapply`` applies a term using the transparency information
- of the hint database ident, and does *no* typeclass resolution. This can
+ The tactic ``autoapply`` applies :token:`one_term` using the transparency information
+ of the hint database :token:`ident`, and does *no* typeclass resolution. This can
be used in :cmd:`Hint Extern`’s for typeclass instances (in the hint
database ``typeclass_instances``) to allow backtracking on the typeclass
subgoals created by the lemma application, rather than doing typeclass
@@ -476,16 +491,16 @@ few other commands related to typeclasses.
Typeclasses Transparent, Typeclasses Opaque
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. cmd:: Typeclasses Transparent {+ @ident}
+.. cmd:: Typeclasses Transparent {+ @qualid }
- This command makes the identifiers transparent during typeclass
+ Makes :token:`qualid` transparent during typeclass
resolution.
- Shortcut for :n:`Hint Transparent {+ @ident } : typeclass_instances`.
+ A shortcut for :cmd:`Hint Transparent` :n:`{+ @qualid } : typeclass_instances`
-.. cmd:: Typeclasses Opaque {+ @ident}
+.. cmd:: Typeclasses Opaque {+ @qualid }
- Make the identifiers opaque for typeclass search.
- Shortcut for :n:`Hint Opaque {+ @ident } : typeclass_instances`.
+ Make :token:`qualid` opaque for typeclass search.
+ A shortcut for :cmd:`Hint Opaque` :n:`{+ @qualid } : typeclass_instances`.
It is useful when some constants prevent some unifications and make
resolution fail. It is also useful to declare constants which
@@ -517,7 +532,7 @@ Settings
.. flag:: Typeclasses Filtered Unification
- This flag, available since Coq 8.6 and off by default, switches the
+ This flag, which is off by default, switches the
hint application procedure to a filter-then-unify strategy. To apply a
hint, we first check that the goal *matches* syntactically the
inferred or specified pattern of the hint, and only then try to
@@ -601,22 +616,25 @@ Settings
of goals. Setting this option to 1 or 2 turns on the :flag:`Typeclasses Debug` flag; setting this
option to 0 turns that flag off.
-Typeclasses eauto `:=`
-~~~~~~~~~~~~~~~~~~~~~~
+Typeclasses eauto
+~~~~~~~~~~~~~~~~~
-.. cmd:: Typeclasses eauto := {? debug} {? {| (dfs) | (bfs) } } @natural
+.. cmd:: Typeclasses eauto := {? debug } {? ( {| bfs | dfs } ) } {? @natural }
:name: Typeclasses eauto
- This command allows more global customization of the typeclass
- resolution tactic. The semantics of the options are:
+ Allows more global customization of the :tacn:`typeclasses eauto` tactic.
+ The options are:
- + ``debug`` This sets the debug mode. In debug mode, the trace of
- successfully applied tactics is printed. The debug mode can also
+ ``debug``
+ Sets debug mode. In debug mode, a trace of
+ successfully applied tactics is printed. Debug mode can also
be set with :flag:`Typeclasses Debug`.
- + ``(dfs)``, ``(bfs)`` This sets the search strategy to depth-first
+ ``dfs``, ``bfs``
+ Sets the search strategy to depth-first
search (the default) or breadth-first search. The search strategy
can also be set with :flag:`Typeclasses Iterative Deepening`.
- + :token:`natural` This sets the depth limit of the search. The depth
- limit can also be set with :opt:`Typeclasses Depth`.
+ :token:`natural`
+ Sets the depth limit for the search. The limit can also be set with
+ :opt:`Typeclasses Depth`.
diff --git a/doc/sphinx/addendum/universe-polymorphism.rst b/doc/sphinx/addendum/universe-polymorphism.rst
index b0ef792bd1..064107d088 100644
--- a/doc/sphinx/addendum/universe-polymorphism.rst
+++ b/doc/sphinx/addendum/universe-polymorphism.rst
@@ -12,7 +12,7 @@ General Presentation
The status of Universe Polymorphism is experimental.
-This section describes the universe polymorphic extension of |Coq|.
+This section describes the universe polymorphic extension of Coq.
Universe polymorphism makes it possible to write generic definitions
making use of universes and reuse them at different and sometimes
incompatible universe levels.
@@ -123,6 +123,7 @@ Polymorphic, Monomorphic
-------------------------
.. attr:: universes(polymorphic)
+ :name: universes(polymorphic); Polymorphic
This attribute can be used to declare universe polymorphic
definitions and inductive types. There is also a legacy syntax
@@ -136,6 +137,7 @@ Polymorphic, Monomorphic
used.
.. attr:: universes(monomorphic)
+ :name: universes(monomorphic); Monomorphic
This attribute can be used to declare universe monomorphic
definitions and inductive types (i.e. global universe constraints
@@ -170,6 +172,7 @@ Cumulative, NonCumulative
-------------------------
.. attr:: universes(cumulative)
+ :name: universes(cumulative); Cumulative
Polymorphic inductive types, coinductive types, variants and
records can be declared cumulative using this attribute or the
@@ -200,6 +203,7 @@ Cumulative, NonCumulative
effect on *monomorphic* inductive definitions.
.. attr:: universes(noncumulative)
+ :name: universes(noncumulative); NonCumulative
Declares the inductive type as non-cumulative even if the
:flag:`Polymorphic Inductive Cumulativity` flag is on. There is
@@ -227,7 +231,7 @@ constraints by prefixing the level names with symbols.
Because inductive subtypings are only produced by comparing inductives
to themselves with universes changed, they amount to variance
information: each universe is either invariant, covariant or
-irrelevant (there are no contravariant subtypings in |Coq|),
+irrelevant (there are no contravariant subtypings in Coq),
respectively represented by the symbols `=`, `+` and `*`.
Here we see that :g:`list` binds an irrelevant universe, so any two
@@ -242,6 +246,7 @@ The following is an example of a record with non-trivial subtyping relation:
.. coqtop:: all
Polymorphic Cumulative Record packType := {pk : Type}.
+ About packType.
:g:`packType` binds a covariant universe, i.e.
@@ -250,6 +255,27 @@ The following is an example of a record with non-trivial subtyping relation:
E[Γ] ⊢ \mathsf{packType}@\{i\} =_{βδιζη}
\mathsf{packType}@\{j\}~\mbox{ whenever }~i ≤ j
+Specifying cumulativity
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The variance of the universe parameters for a cumulative inductive may be specified by the user.
+
+For the following type, universe ``a`` has its variance automatically
+inferred (it is irrelevant), ``b`` is required to be irrelevant,
+``c`` is covariant and ``d`` is invariant. With these annotations
+``c`` and ``d`` have less general variances than would be inferred.
+
+.. coqtop:: all
+
+ Polymorphic Cumulative Inductive Dummy@{a *b +c =d} : Prop := dummy.
+ About Dummy.
+
+Insufficiently restrictive variance annotations lead to errors:
+
+.. coqtop:: all
+
+ Fail Polymorphic Cumulative Record bad@{*a} := {p : Type@{a}}.
+
An example of a proof using cumulativity
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -276,7 +302,7 @@ An example of a proof using cumulativity
End down.
Cumulativity Weak Constraints
------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. flag:: Cumulativity Weak Constraints
@@ -379,34 +405,32 @@ Explicit Universes
| _
| @qualid
univ_decl ::= @%{ {* @ident } {? + } {? %| {*, @univ_constraint } {? + } } %}
+ cumul_univ_decl ::= @%{ {* {? {| = | + | * } } @ident } {? + } {? %| {*, @univ_constraint } {? + } } %}
univ_constraint ::= @universe_name {| < | = | <= } @universe_name
The syntax has been extended to allow users to explicitly bind names
to universes and explicitly instantiate polymorphic definitions.
-.. cmd:: Universe @ident
- Polymorphic Universe @ident
+.. cmd:: Universe {+ @ident }
- In the monorphic case, this command declares a new global universe
- named :token:`ident`, which can be referred to using its qualified name
- as well. Global universe names live in a separate namespace. The
- command supports the :attr:`universes(polymorphic)` attribute (or
- the ``Polymorphic`` prefix) only in sections, meaning the universe
- quantification will be discharged on each section definition
+ In the monomorphic case, declares new global universes
+ with the given names. Global universe names live in a separate namespace.
+ The command supports the :attr:`universes(polymorphic)` attribute (or
+ the ``Polymorphic`` legacy attribute) only in sections, meaning the universe
+ quantification will be discharged for each section definition
independently.
.. exn:: Polymorphic universes can only be declared inside sections, use Monomorphic Universe instead.
:undocumented:
-.. cmd:: Constraint @univ_constraint
- Polymorphic Constraint @univ_constraint
+.. cmd:: Constraint {+, @univ_constraint }
- This command declares a new constraint between named universes.
+ Declares new constraints between named universes.
- If consistent, the constraint is then enforced in the global
+ If consistent, the constraints are then enforced in the global
environment. Like :cmd:`Universe`, it can be used with the
:attr:`universes(polymorphic)` attribute (or the ``Polymorphic``
- prefix) in sections only to declare constraints discharged at
+ legacy attribute) in sections only to declare constraints discharged at
section closing time. One cannot declare a global constraint on
polymorphic universes.
@@ -473,7 +497,7 @@ mode, introduced universe names can be referred to in terms. Note that
local universe names shadow global universe names. During a proof, one
can use :cmd:`Show Universes` to display the current context of universes.
-It is possible to provide only some universe levels and let |Coq| infer the others
+It is possible to provide only some universe levels and let Coq infer the others
by adding a :g:`+` in the list of bound universe levels:
.. coqtop:: all
diff --git a/doc/sphinx/changes.rst b/doc/sphinx/changes.rst
index af66efa95e..de5dbe79cc 100644
--- a/doc/sphinx/changes.rst
+++ b/doc/sphinx/changes.rst
@@ -14,7 +14,7 @@ Version 8.12
Summary of changes
~~~~~~~~~~~~~~~~~~
-|Coq| version 8.12 integrates many usability improvements,
+Coq version 8.12 integrates many usability improvements,
in particular with respect to notations, scopes and implicit arguments,
along with many bug fixes and major improvements to the reference manual.
The main changes include:
@@ -59,7 +59,7 @@ Erik Martin-Dorel has maintained the `Coq Docker images
<https://hub.docker.com/r/coqorg/coq>`_ that are used in many Coq
projects for continuous integration.
-The OPAM repository for |Coq| packages has been maintained by
+The OPAM repository for Coq packages has been maintained by
Guillaume Claret, Karl Palmskog, Matthieu Sozeau and Enrico Tassi with
contributions from many users. A list of packages is available at
https://coq.inria.fr/opam/www/.
@@ -97,18 +97,18 @@ Laurent Théry, Ralf Treinen, Anton Trunov, Bernhard M. Wiedemann, Li-yao Xia,
Nickolai Zeldovich and Théo Zimmermann.
Many power users helped to improve the design of this new version via
-the GitHub issue and pull request system, the |Coq| development mailing list
+the GitHub issue and pull request system, the Coq development mailing list
coqdev@inria.fr, the coq-club@inria.fr mailing list, the `Discourse forum
<https://coq.discourse.group/>`_ and the new `Coq Zulip chat <http://coq.zulipchat.com>`_
(thanks to Cyril Cohen for organizing the move from Gitter).
Version 8.12's development spanned 6 months from the release of
-|Coq| 8.11.0. Emilio Jesus Gallego Arias and Théo Zimmermann are
+Coq 8.11.0. Emilio Jesus Gallego Arias and Théo Zimmermann are
the release managers of Coq 8.12. This release is the result of
~500 PRs merged, closing ~100 issues.
| Nantes, June 2020,
-| Matthieu Sozeau for the |Coq| development team
+| Matthieu Sozeau for the Coq development team
|
Changes in 8.12+beta1
@@ -800,7 +800,7 @@ Tools
<https://github.com/coq/coq/pull/12387>`_, by Jason Gross).
CoqIDE
-^^^^^^
+^^^^^^^^
- **Removed:**
"Tactic" menu from CoqIDE which had been unmaintained for a number of years
@@ -1141,9 +1141,6 @@ Infrastructure and dependencies
Changes in 8.12.0
~~~~~~~~~~~~~~~~~~~~~
-.. contents::
- :local:
-
**Notations**
- **Added:**
@@ -1216,13 +1213,136 @@ Changes in 8.12.0
modified in the meantime (`#12583 <https://github.com/coq/coq/pull/12583>`_,
fixes `#12582 <https://github.com/coq/coq/issues/12582>`_, by Jason Gross).
+Changes in 8.12.1
+~~~~~~~~~~~~~~~~~~~~~
+
+**Kernel**
+
+- **Fixed:** Incompleteness of conversion checking on problems
+ involving :ref:`eta-expansion` and :ref:`cumulative universe
+ polymorphic inductive types <cumulative>` (`#12738
+ <https://github.com/coq/coq/pull/12738>`_, fixes `#7015
+ <https://github.com/coq/coq/issues/7015>`_, by Gaëtan Gilbert).
+
+- **Fixed:**
+ Polymorphic side-effects inside monomorphic definitions were incorrectly
+ handled as not inlined. This allowed deriving an inconsistency
+ (`#13331 <https://github.com/coq/coq/pull/13331>`_,
+ fixes `#13330 <https://github.com/coq/coq/issues/13330>`_,
+ by Pierre-Marie Pédrot).
+
+**Notations**
+
+- **Fixed:**
+ Undetected collision between a lonely notation and a notation in
+ scope at printing time
+ (`#12946 <https://github.com/coq/coq/pull/12946>`_,
+ fixes the first part of `#12908 <https://github.com/coq/coq/issues/12908>`_,
+ by Hugo Herbelin).
+- **Fixed:**
+ Printing of notations in custom entries with
+ variables not mentioning an explicit level
+ (`#13026 <https://github.com/coq/coq/pull/13026>`_,
+ fixes `#12775 <https://github.com/coq/coq/issues/12775>`_
+ and `#13018 <https://github.com/coq/coq/issues/13018>`_,
+ by Hugo Herbelin).
+
+**Tactics**
+
+- **Added:**
+ :tacn:`replace` and :tacn:`inversion` support registration of a
+ :g:`core.identity`\-like equality in :g:`Type`, such as HoTT's :g:`path`
+ (`#12847 <https://github.com/coq/coq/pull/12847>`_,
+ partially fixes `#12846 <https://github.com/coq/coq/issues/12846>`_,
+ by Hugo Herbelin).
+- **Fixed:**
+ Anomaly with :tacn:`injection` involving artificial
+ dependencies disappearing by reduction
+ (`#12816 <https://github.com/coq/coq/pull/12816>`_,
+ fixes `#12787 <https://github.com/coq/coq/issues/12787>`_,
+ by Hugo Herbelin).
+
+**Tactic language**
+
+- **Fixed:**
+ Miscellaneous issues with locating tactic errors
+ (`#13247 <https://github.com/coq/coq/pull/13247>`_,
+ fixes `#12773 <https://github.com/coq/coq/issues/12773>`_
+ and `#12992 <https://github.com/coq/coq/issues/12992>`_,
+ by Hugo Herbelin).
+
+**SSReflect**
+
+- **Fixed:**
+ Regression in error reporting after :tacn:`case <case (ssreflect)>`.
+ A generic error message "Could not fill dependent hole in apply" was
+ reported for any error following :tacn:`case <case (ssreflect)>` or
+ :tacn:`elim <elim (ssreflect)>`
+ (`#12857 <https://github.com/coq/coq/pull/12857>`_,
+ fixes `#12837 <https://github.com/coq/coq/issues/12837>`_,
+ by Enrico Tassi).
+
+**Commands and options**
+
+- **Fixed:**
+ Failures of :cmd:`Search` in the presence of primitive projections
+ (`#13301 <https://github.com/coq/coq/pull/13301>`_,
+ fixes `#13298 <https://github.com/coq/coq/issues/13298>`_,
+ by Hugo Herbelin).
+- **Fixed:**
+ :cmd:`Search` supports filtering on parts of identifiers which are
+ not proper identifiers themselves, such as :n:`"1"`
+ (`#13351 <https://github.com/coq/coq/pull/13351>`_,
+ fixes `#13349 <https://github.com/coq/coq/issues/13349>`_,
+ by Hugo Herbelin).
+
+**Tools**
+
+- **Fixed:**
+ Special symbols now escaped in the index produced by coqdoc,
+ avoiding collision with the syntax of the output format
+ (`#12754 <https://github.com/coq/coq/pull/12754>`_,
+ fixes `#12752 <https://github.com/coq/coq/issues/12752>`_,
+ by Hugo Herbelin).
+- **Fixed:**
+ The `details` environment added in the 8.12 release can now be used
+ as advertised in the reference manual
+ (`#12772 <https://github.com/coq/coq/pull/12772>`_,
+ by Thomas Letan).
+- **Fixed:**
+ Targets such as ``print-pretty-timed`` in ``coq_makefile``\-made
+ ``Makefile``\s no longer error in rare cases where ``--output-sync`` is not
+ passed to make and the timing output gets interleaved in just the wrong way
+ (`#13063 <https://github.com/coq/coq/pull/13063>`_, fixes `#13062
+ <https://github.com/coq/coq/issues/13062>`_, by Jason Gross).
+
+**CoqIDE**
+
+- **Fixed:**
+ View menu "Display parentheses"
+ (`#12794 <https://github.com/coq/coq/pull/12794>`_ and `#13067 <https://github.com/coq/coq/pull/13067>`_,
+ fixes `#12793 <https://github.com/coq/coq/issues/12793>`_,
+ by Jean-Christophe Léchenet and Hugo Herbelin).
+
+**Infrastructure and dependencies**
+
+- **Added:**
+ Coq is now tested against OCaml 4.11.1
+ (`#12972 <https://github.com/coq/coq/pull/12972>`_,
+ by Emilio Jesus Gallego Arias).
+- **Fixed:**
+ The reference manual can now build with Sphinx 3
+ (`#13011 <https://github.com/coq/coq/pull/13011>`_,
+ fixes `#12332 <https://github.com/coq/coq/issues/12332>`_,
+ by Théo Zimmermann and Jim Fehrle).
+
Version 8.11
------------
Summary of changes
~~~~~~~~~~~~~~~~~~
-The main changes brought by |Coq| version 8.11 are:
+The main changes brought by Coq version 8.11 are:
- :ref:`Ltac2<811Ltac2>`, a new tactic language for writing more robust larger scale
tactics, with built-in support for datatypes and the multi-goal tactic monad.
@@ -1256,7 +1376,7 @@ also the warning message in the :ref:`corresponding chapter
<omega_chapter>`).
The ``dev/doc/critical-bugs`` file documents the known critical bugs
-of |Coq| and affected releases. See the `Changes in 8.11+beta1`_
+of Coq and affected releases. See the `Changes in 8.11+beta1`_
section and following sections for the detailed list of changes,
including potentially breaking changes marked with **Changed**.
@@ -1269,7 +1389,7 @@ Maxime Dénès, Emilio Jesús Gallego Arias, Gaëtan Gilbert, Michael
Soegtrop and Théo Zimmermann worked on maintaining and improving the
continuous integration system and package building infrastructure.
-The OPAM repository for |Coq| packages has been maintained by
+The OPAM repository for Coq packages has been maintained by
Guillaume Claret, Karl Palmskog, Matthieu Sozeau and Enrico Tassi with
contributions from many users. A list of packages is available at
https://coq.inria.fr/opam/www/.
@@ -1292,20 +1412,20 @@ Matthieu Sozeau, spanjel, Claude Stolze, Enrico Tassi, Laurent Théry,
James R. Wilcox, Xia Li-yao, Théo Zimmermann
Many power users helped to improve the design of the new features via
-the issue and pull request system, the |Coq| development mailing list,
+the issue and pull request system, the Coq development mailing list,
the coq-club@inria.fr mailing list or the `Discourse forum
<https://coq.discourse.group/>`_. It would be impossible to mention
exhaustively the names of everybody who to some extent influenced the
development.
-Version 8.11 is the sixth release of |Coq| developed on a time-based
+Version 8.11 is the sixth release of Coq developed on a time-based
development cycle. Its development spanned 3 months from the release of
-|Coq| 8.10. Pierre-Marie Pédrot is the release manager and maintainer of this
+Coq 8.10. Pierre-Marie Pédrot is the release manager and maintainer of this
release, assisted by Matthieu Sozeau. This release is the result of 2000+
commits and 300+ PRs merged, closing 75+ issues.
| Paris, November 2019,
-| Matthieu Sozeau for the |Coq| development team
+| Matthieu Sozeau for the Coq development team
|
@@ -1463,8 +1583,8 @@ Changes in 8.11+beta1
A simplification of parsing rules could cause a slight change of
parsing precedences for the very rare users who defined notations
with `constr` at level strictly between 100 and 200 and used these
- notations on the right-hand side of a cast operator (`:`, `:>`,
- `:>>`) (`#10963 <https://github.com/coq/coq/pull/10963>`_, by Théo
+ notations on the right-hand side of a cast operator (`:`, `<:`,
+ `<<:`) (`#10963 <https://github.com/coq/coq/pull/10963>`_, by Théo
Zimmermann, simplification initially noticed by Jim Fehrle).
**Tactics**
@@ -1957,7 +2077,7 @@ Version 8.10
Summary of changes
~~~~~~~~~~~~~~~~~~
-|Coq| version 8.10 contains two major new features: support for a native
+Coq version 8.10 contains two major new features: support for a native
fixed-precision integer type and a new sort :math:`\SProp` of strict
propositions. It is also the result of refinements and stabilization of
previous features, deprecations or removals of deprecated features,
@@ -2121,7 +2241,7 @@ the numerous changes to the implementation and improvements of
interfaces. The file provides guidelines on porting a plugin to the new
version and a plugin development tutorial originally made by Yves Bertot
is now in `doc/plugin_tutorial`. The ``dev/doc/critical-bugs`` file
-documents the known critical bugs of |Coq| and affected releases.
+documents the known critical bugs of Coq and affected releases.
The efficiency of the whole system has seen improvements thanks to
contributions from Gaëtan Gilbert, Pierre-Marie Pédrot, and Maxime Dénès.
@@ -2129,7 +2249,7 @@ contributions from Gaëtan Gilbert, Pierre-Marie Pédrot, and Maxime Dénès.
Maxime Dénès, Emilio Jesús Gallego Arias, Gaëtan Gilbert, Michael
Soegtrop, Théo Zimmermann worked on maintaining and improving the
continuous integration system and package building infrastructure.
-Coq is now continuously tested against OCaml trunk, in addition to the
+Coq is now continuously tested against the OCaml trunk, in addition to the
oldest supported and latest OCaml releases.
Coq's documentation for the development branch is now deployed
@@ -2138,7 +2258,7 @@ the ML API), https://coq.github.io/doc/master/refman (reference
manual), and https://coq.github.io/doc/master/stdlib (documentation of
the standard library). Similar links exist for the `v8.10` branch.
-The OPAM repository for |Coq| packages has been maintained by Guillaume
+The OPAM repository for Coq packages has been maintained by Guillaume
Melquiond, Matthieu Sozeau, Enrico Tassi (who migrated it to opam 2)
with contributions from many users. A list of packages is available at
https://coq.inria.fr/opam/www/.
@@ -2160,19 +2280,19 @@ Tassi, Laurent Théry, Kamil Trzciński, whitequark, Théo Winterhalter,
Xia Li-yao, Beta Ziliani and Théo Zimmermann.
Many power users helped to improve the design of the new features via
-the issue and pull request system, the |Coq| development mailing list,
+the issue and pull request system, the Coq development mailing list,
the coq-club@inria.fr mailing list or the new Discourse forum. It would
be impossible to mention exhaustively the names of everybody who to some
extent influenced the development.
-Version 8.10 is the fifth release of |Coq| developed on a time-based
+Version 8.10 is the fifth release of Coq developed on a time-based
development cycle. Its development spanned 6 months from the release of
-|Coq| 8.9. Vincent Laporte is the release manager and maintainer of this
+Coq 8.9. Vincent Laporte is the release manager and maintainer of this
release. This release is the result of ~2500 commits and ~650 PRs merged,
closing 150+ issues.
| Santiago de Chile, April 2019,
-| Matthieu Sozeau for the |Coq| development team
+| Matthieu Sozeau for the Coq development team
|
Other changes in 8.10+beta1
@@ -2761,7 +2881,7 @@ Version 8.9
Summary of changes
~~~~~~~~~~~~~~~~~~
-|Coq| version 8.9 contains the result of refinements and stabilization
+Coq version 8.9 contains the result of refinements and stabilization
of features and deprecations or removals of deprecated features,
cleanups of the internals of the system and API along with a few new
features. This release includes many user-visible changes, including
@@ -2779,7 +2899,7 @@ changes:
manual).
- Deprecated notations of the standard library will be removed in the
- next version of |Coq|, see the next subsection for a script to
+ next version of Coq, see the next subsection for a script to
ease porting, by Jason Gross and Jean-Christophe Léchenet.
- Added the :cmd:`Number Notation` command for registering decimal
@@ -2842,7 +2962,7 @@ changes:
- Tools: removed the ``gallina`` utility and the homebrewed ``Emacs`` mode.
-- Packaging: as in |Coq| 8.8.2, the Windows installer now includes many
+- Packaging: as in Coq 8.8.2, the Windows installer now includes many
more external packages that can be individually selected for
installation, by Michael Soegtrop.
@@ -2856,7 +2976,7 @@ interfaces. The file provides guidelines on porting a plugin to the new
version and a plugin development tutorial kept in sync with Coq was
introduced by Yves Bertot http://github.com/ybertot/plugin_tutorials.
The new ``dev/doc/critical-bugs`` file documents the known critical bugs
-of |Coq| and affected releases.
+of Coq and affected releases.
The efficiency of the whole system has seen improvements thanks to
contributions from Gaëtan Gilbert, Pierre-Marie Pédrot, and Maxime Dénès.
@@ -2865,7 +2985,7 @@ Maxime Dénès, Emilio Jesús Gallego Arias, Gaëtan Gilbert, Michael
Soegtrop, Théo Zimmermann worked on maintaining and improving the
continuous integration system.
-The OPAM repository for |Coq| packages has been maintained by Guillaume
+The OPAM repository for Coq packages has been maintained by Guillaume
Melquiond, Matthieu Sozeau, Enrico Tassi with contributions from many
users. A list of packages is available at https://coq.inria.fr/opam/www/.
@@ -2885,23 +3005,23 @@ Tassi, Laurent Théry, Anton Trunov, whitequark, Théo Winterhalter,
Zeimer, Beta Ziliani, Théo Zimmermann.
Many power users helped to improve the design of the new features via
-the issue and pull request system, the |Coq| development mailing list or
+the issue and pull request system, the Coq development mailing list or
the coq-club@inria.fr mailing list. It would be impossible to mention
exhaustively the names of everybody who to some extent influenced the
development.
-Version 8.9 is the fourth release of |Coq| developed on a time-based
+Version 8.9 is the fourth release of Coq developed on a time-based
development cycle. Its development spanned 7 months from the release of
-|Coq| 8.8. The development moved to a decentralized merging process
+Coq 8.8. The development moved to a decentralized merging process
during this cycle. Guillaume Melquiond was in charge of the release
process and is the maintainer of this release. This release is the
result of ~2,000 commits and ~500 PRs merged, closing 75+ issues.
-The |Coq| development team welcomed Vincent Laporte, a new |Coq|
-engineer working with Maxime Dénès in the |Coq| consortium.
+The Coq development team welcomed Vincent Laporte, a new Coq
+engineer working with Maxime Dénès in the Coq consortium.
| Paris, November 2018,
-| Matthieu Sozeau for the |Coq| development team
+| Matthieu Sozeau for the Coq development team
|
Details of changes in 8.9+beta1
@@ -3134,7 +3254,7 @@ Version 8.8
Summary of changes
~~~~~~~~~~~~~~~~~~
-|Coq| version 8.8 contains the result of refinements and stabilization of
+Coq version 8.8 contains the result of refinements and stabilization of
features and deprecations, cleanups of the internals of the system along
with a few new features. The main user visible changes are:
@@ -3196,12 +3316,12 @@ contributions from Gaëtan Gilbert, Pierre-Marie Pédrot, Maxime Dénès and
Matthieu Sozeau and performance issue tracking by Jason Gross and Paul
Steckler.
-The official wiki and the bugtracker of |Coq| migrated to the GitHub
+The official wiki and the bugtracker of Coq migrated to the GitHub
platform, thanks to the work of Pierre Letouzey and Théo
Zimmermann. Gaëtan Gilbert, Emilio Jesús Gallego Arias worked on
maintaining and improving the continuous integration system.
-The OPAM repository for |Coq| packages has been maintained by Guillaume
+The OPAM repository for Coq packages has been maintained by Guillaume
Melquiond, Matthieu Sozeau, Enrico Tassi with contributions from many
users. A list of packages is available at https://coq.inria.fr/opam/www/.
@@ -3216,26 +3336,26 @@ Clément Pit-Claudel, Matthew Ryan, Matt Quinn, Sigurd Schneider, Bernhard
Schommer, Michael Soegtrop, Matthieu Sozeau, Arnaud Spiwack, Paul Steckler,
Enrico Tassi, Anton Trunov, Martin Vassor, Vadim Zaliva and Théo Zimmermann.
-Version 8.8 is the third release of |Coq| developed on a time-based
+Version 8.8 is the third release of Coq developed on a time-based
development cycle. Its development spanned 6 months from the release of
-|Coq| 8.7 and was based on a public roadmap. The development process
+Coq 8.7 and was based on a public roadmap. The development process
was coordinated by Matthieu Sozeau. Maxime Dénès was in charge of the
release process. Théo Zimmermann is the maintainer of this release.
Many power users helped to improve the design of the new features via
-the bug tracker, the pull request system, the |Coq| development mailing
+the bug tracker, the pull request system, the Coq development mailing
list or the coq-club@inria.fr mailing list. Special thanks to the users who
contributed patches and intensive brain-storming and code reviews,
starting with Jason Gross, Ralf Jung, Robbert Krebbers and Amin Timany.
It would however be impossible to mention exhaustively the names
of everybody who to some extent influenced the development.
-The |Coq| consortium, an organization directed towards users and
+The Coq consortium, an organization directed towards users and
supporters of the system, is now running and employs Maxime Dénès.
The contacts of the Coq Consortium are Yves Bertot and Maxime Dénès.
| Santiago de Chile, March 2018,
-| Matthieu Sozeau for the |Coq| development team
+| Matthieu Sozeau for the Coq development team
|
Details of changes in 8.8+beta1
@@ -3501,7 +3621,7 @@ Version 8.7
Summary of changes
~~~~~~~~~~~~~~~~~~
-|Coq| version 8.7 contains the result of refinements, stabilization of features
+Coq version 8.7 contains the result of refinements, stabilization of features
and cleanups of the internals of the system along with a few new features. The
main user visible changes are:
@@ -3520,7 +3640,7 @@ main user visible changes are:
and the extensibility of generated Makefiles, and to make ``_CoqProject`` files
more palatable to IDEs by Enrico Tassi.
-|Coq| 8.7 involved a large amount of work on cleaning and speeding up the code
+Coq 8.7 involved a large amount of work on cleaning and speeding up the code
base, notably the work of Pierre-Marie Pédrot on making the tactic-level system
insensitive to existential variable expansion, providing a safer API to plugin
writers and making the code more robust. The ``dev/doc/changes.txt`` file
@@ -3540,7 +3660,7 @@ Thomas Sibut-Pinote and Hugo Herbelin added support for side effect hooks in
cbv, cbn and simpl. The side effects are provided via a plugin available at
https://github.com/herbelin/reduction-effects/.
-The BigN, BigZ, BigQ libraries are no longer part of the |Coq| standard library,
+The BigN, BigZ, BigQ libraries are no longer part of the Coq standard library,
they are now provided by a separate repository https://github.com/coq/bignums,
maintained by Pierre Letouzey.
@@ -3554,7 +3674,7 @@ others, documented in the next subsection file.
The mathematical proof language/declarative mode plugin was removed from the
archive.
-The OPAM repository for |Coq| packages has been maintained by Guillaume Melquiond,
+The OPAM repository for Coq packages has been maintained by Guillaume Melquiond,
Matthieu Sozeau, Enrico Tassi with contributions from many users. A list of
packages is available at https://coq.inria.fr/opam/www/.
@@ -3579,29 +3699,29 @@ Maxime Dénès, who was also in charge of the release process. Théo Zimmermann
the maintainer of this release.
Many power users helped to improve the design of the new features via the bug
-tracker, the pull request system, the |Coq| development mailing list or the
+tracker, the pull request system, the Coq development mailing list or the
Coq-Club mailing list. Special thanks to the users who contributed patches and
intensive brain-storming and code reviews, starting with Jason Gross, Ralf Jung,
Robbert Krebbers, Xavier Leroy, Clément Pit–Claudel and Gabriel Scherer. It
would however be impossible to mention exhaustively the names of everybody who
to some extent influenced the development.
-Version 8.7 is the second release of |Coq| developed on a time-based development
-cycle. Its development spanned 9 months from the release of |Coq| 8.6 and was
+Version 8.7 is the second release of Coq developed on a time-based development
+cycle. Its development spanned 9 months from the release of Coq 8.6 and was
based on a public road-map. It attracted many external contributions. Code
reviews and continuous integration testing were systematically used before
integration of new features, with an important focus given to compatibility and
-performance issues, resulting in a hopefully more robust release than |Coq| 8.6
+performance issues, resulting in a hopefully more robust release than Coq 8.6
while maintaining compatibility.
-|Coq| Enhancement Proposals (CEPs for short) and open pull request discussions
+Coq Enhancement Proposals (CEPs for short) and open pull request discussions
were used to discuss publicly the new features.
-The |Coq| consortium, an organization directed towards users and supporters of the
+The Coq consortium, an organization directed towards users and supporters of the
system, is now upcoming and will rely on Inria’s newly created Foundation.
| Paris, August 2017,
-| Matthieu Sozeau and the |Coq| development team
+| Matthieu Sozeau and the Coq development team
|
Potential compatibility issues
@@ -3871,9 +3991,9 @@ over 100 contributions integrated. The main user visible changes are:
- A new, faster state-of-the-art universe constraint checker, by
Jacques-Henri Jourdan.
-- In |CoqIDE| and other asynchronous interfaces, more fine-grained
+- In CoqIDE and other asynchronous interfaces, more fine-grained
asynchronous processing and error reporting by Enrico Tassi, making
- |Coq| capable of recovering from errors and continue processing the
+ Coq capable of recovering from errors and continue processing the
document.
- More access to the proof engine features from Ltac: goal management
@@ -3920,7 +4040,7 @@ Matthieu Sozeau. The minimization algorithm has been improved by
Matthieu Sozeau.
The unifier has been improved by Hugo Herbelin and Matthieu Sozeau,
-fixing some incompatibilities introduced in |Coq| 8.5. Unification
+fixing some incompatibilities introduced in Coq 8.5. Unification
constraints can now be left floating around and be seen by the user
thanks to a new option. The Keyed Unification mode has been improved by
Matthieu Sozeau.
@@ -3943,19 +4063,19 @@ the pretty-printing and user interface communication components.
Frédéric Besson maintained the micromega tactic.
-The OPAM repository for |Coq| packages has been maintained by Guillaume
+The OPAM repository for Coq packages has been maintained by Guillaume
Claret, Guillaume Melquiond, Matthieu Sozeau, Enrico Tassi and others. A
list of packages is now available at https://coq.inria.fr/opam/www/.
Packaging tools and software development kits were prepared by Michael
Soegtrop with the help of Maxime Dénès and Enrico Tassi for Windows, and
Maxime Dénès and Matthieu Sozeau for MacOS X. Packages are now regularly
-built on the continuous integration server. |Coq| now comes with a META
+built on the continuous integration server. Coq now comes with a META
file usable with ocamlfind, contributed by Emilio Jesús Gallego Arias,
Gregory Malecha, and Matthieu Sozeau.
Matej Košík maintained and greatly improved the continuous integration
-setup and the testing of |Coq| contributions. He also contributed many API
+setup and the testing of Coq contributions. He also contributed many API
improvements and code cleanups throughout the system.
The contributors for this version are Bruno Barras, C.J. Bell, Yves
@@ -3972,7 +4092,7 @@ coordinated by Hugo Herbelin and Matthieu Sozeau with the help of Maxime
Dénès, who was also in charge of the release process.
Many power users helped to improve the design of the new features via
-the bug tracker, the pull request system, the |Coq| development mailing
+the bug tracker, the pull request system, the Coq development mailing
list or the Coq-Club mailing list. Special thanks to the users who
contributed patches and intensive brain-storming and code reviews,
starting with Cyril Cohen, Jason Gross, Robbert Krebbers, Jonathan
@@ -3981,23 +4101,23 @@ Scherer and Beta Ziliani. It would however be impossible to mention
exhaustively the names of everybody who to some extent influenced the
development.
-Version 8.6 is the first release of |Coq| developed on a time-based
+Version 8.6 is the first release of Coq developed on a time-based
development cycle. Its development spanned 10 months from the release of
Coq 8.5 and was based on a public roadmap. To date, it contains more
-external contributions than any previous |Coq| system. Code reviews were
+external contributions than any previous Coq system. Code reviews were
systematically done before integration of new features, with an
important focus given to compatibility and performance issues, resulting
-in a hopefully more robust release than |Coq| 8.5.
+in a hopefully more robust release than Coq 8.5.
Coq Enhancement Proposals (CEPs for short) were introduced by Enrico
Tassi to provide more visibility and a discussion period on new
features, they are publicly available https://github.com/coq/ceps.
Started during this period, an effort is led by Yves Bertot and Maxime
-Dénès to put together a |Coq| consortium.
+Dénès to put together a Coq consortium.
| Paris, November 2016,
-| Matthieu Sozeau and the |Coq| development team
+| Matthieu Sozeau and the Coq development team
|
Potential sources of incompatibilities
@@ -4252,7 +4372,7 @@ the backtracking behavior of tactics. Multiple goal handling paves the
way for smarter automation tactics. It is currently used for simple goal
manipulation such as goal reordering.
-The way |Coq| processes a document in batch and interactive mode has been
+The way Coq processes a document in batch and interactive mode has been
redesigned by Enrico Tassi with help from Bruno Barras. Opaque proofs,
the text between Proof and Qed, can be processed asynchronously,
decoupling the checking of definitions and statements from the checking
@@ -4265,12 +4385,12 @@ already Required. All .vio files can be turned into complete .vo files
in parallel. The same infrastructure also allows terminating tactics to
be run in parallel on a set of goals via the ``par:`` goal selector.
-|CoqIDE| was modified to cope with asynchronous checking of the document.
-Its source code was also made separate from that of |Coq|, so that |CoqIDE|
+CoqIDE was modified to cope with asynchronous checking of the document.
+Its source code was also made separate from that of Coq, so that CoqIDE
no longer has a special status among user interfaces, paving the way for
-decoupling its release cycle from that of |Coq| in the future.
+decoupling its release cycle from that of Coq in the future.
-Carst Tankink developed a |Coq| back-end for user interfaces built on
+Carst Tankink developed a Coq back-end for user interfaces built on
Makarius Wenzel’s Prover IDE framework (PIDE), like PIDE/jEdit (with
help from Makarius Wenzel) or PIDE/Coqoon (with help from Alexander
Faithfull and Jesper Bengtson). The development of such features was
@@ -4304,7 +4424,7 @@ principles such as propositional extensionality and univalence, thanks
to Maxime Dénès and Bruno Barras. To ensure compatibility with the
univalence axiom, a new flag ``-indices-matter`` has been implemented,
taking into account the universe levels of indices when computing the
-levels of inductive types. This supports using |Coq| as a tool to explore
+levels of inductive types. This supports using Coq as a tool to explore
the relations between homotopy theory and type theory.
Maxime Dénès and Benjamin Grégoire developed an implementation of
@@ -4334,13 +4454,13 @@ Matthieu Sozeau. Error messages for unification and type inference
failures have been improved by Hugo Herbelin, Pierre-Marie Pédrot and
Arnaud Spiwack.
-Pierre Courtieu contributed new features for using |Coq| through Proof
+Pierre Courtieu contributed new features for using Coq through Proof
General and for better interactive experience (bullets, Search, etc).
The efficiency of the whole system has been significantly improved
thanks to contributions from Pierre-Marie Pédrot.
-A distribution channel for |Coq| packages using the OPAM tool has been
+A distribution channel for Coq packages using the OPAM tool has been
initiated by Thomas Braibant and developed by Guillaume Claret, with
contributions by Enrico Tassi and feedback from Hugo Herbelin.
@@ -4357,7 +4477,7 @@ Jonathan Leivent, Greg Malecha, Clément Pit-Claudel, Marc Lasson, Lionel
Rieg. It would however be impossible to mention with precision all names
of people who to some extent influenced the development.
-Version 8.5 is one of the most important releases of |Coq|. Its development
+Version 8.5 is one of the most important releases of Coq. Its development
spanned over about 3 years and a half with about one year of
beta-testing. General maintenance during part or whole of this period
has been done by Pierre Boutillier, Pierre Courtieu, Maxime Dénès, Hugo
@@ -4369,7 +4489,7 @@ Mahboubi, Jean-Marc Notin, Yann Régis-Gianas, François Ripault, Carst
Tankink. Maxime Dénès coordinated the release process.
| Paris, January 2015, revised December 2015,
-| Hugo Herbelin, Matthieu Sozeau and the |Coq| development team
+| Hugo Herbelin, Matthieu Sozeau and the Coq development team
|
Potential sources of incompatibilities
@@ -5158,7 +5278,7 @@ Other bugfixes
- #4503: mixing universe polymorphic and monomorphic variables and definitions in sections is unsupported.
- #4519: oops, global shadowed local universe level bindings.
- #4506: Anomaly: File "pretyping/indrec.ml", line 169, characters 14-20: Assertion failed.
-- #4548: Coqide crashes when going back one command
+- #4548: CoqIDE crashes when going back one command
Details of changes in 8.5pl2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -5273,7 +5393,7 @@ Summary of changes
Coq version 8.4 contains the result of three long-term projects: a new
modular library of arithmetic by Pierre Letouzey, a new proof engine by
-Arnaud Spiwack and a new communication protocol for |CoqIDE| by Vincent
+Arnaud Spiwack and a new communication protocol for CoqIDE by Vincent
Gross.
The new modular library of arithmetic extends, generalizes and unifies
@@ -5295,14 +5415,14 @@ goals simultaneously, for reordering goals, all features which are
planned for the next release. The new proof engine forced Pierre Letouzey
to reimplement info and Show Script differently.
-Before version 8.4, |CoqIDE| was linked to |Coq| with the graphical
-interface living in a separate thread. From version 8.4, |CoqIDE| is a
-separate process communicating with |Coq| through a textual channel. This
-allows for a more robust interfacing, the ability to interrupt |Coq|
+Before version 8.4, CoqIDE was linked to Coq with the graphical
+interface living in a separate thread. From version 8.4, CoqIDE is a
+separate process communicating with Coq through a textual channel. This
+allows for a more robust interfacing, the ability to interrupt Coq
without interrupting the interface, and the ability to manage several
sessions in parallel. Relying on the infrastructure work made by Vincent
Gross, Pierre Letouzey, Pierre Boutillier and Pierre-Marie Pédrot
-contributed many various refinements of |CoqIDE|.
+contributed many various refinements of CoqIDE.
Coq 8.4 also comes with a bunch of various smaller-scale changes
and improvements regarding the different components of the system.
@@ -5313,7 +5433,7 @@ addition of :math:`\eta`-conversion is justified by the confidence that
the formulation of the Calculus of Inductive Constructions based on
typed equality (such as the one considered in Lee and Werner to build a
set-theoretic model of CIC :cite:`LeeWerner11`) is
-applicable to the concrete implementation of |Coq|.
+applicable to the concrete implementation of Coq.
The underlying logic benefited also from a refinement of the guard
condition for fixpoints by Pierre Boutillier, the point being that it is
@@ -5394,7 +5514,7 @@ Coq through Proof General.
The Dp plugin has been removed. Use the plugin provided with Why 3
instead (http://why3.lri.fr/).
-Under the hood, the |Coq| architecture benefited from improvements in
+Under the hood, the Coq architecture benefited from improvements in
terms of efficiency and robustness, especially regarding universes
management and existential variables management, thanks to Pierre
Letouzey and Yann Régis-Gianas with contributions from Stéphane Glondu
@@ -5703,19 +5823,19 @@ Extraction
CoqIDE
-- Coqide now runs coqtop as separated process, making it more robust:
+- CoqIDE now runs coqtop as separated process, making it more robust:
coqtop subprocess can be interrupted, or even killed and relaunched
(cf button "Restart Coq", ex-"Go to Start"). For allowing such
interrupts, the Windows version of coqide now requires Windows >= XP
SP1.
-- The communication between CoqIDE and Coqtop is now done via a dialect
+- The communication between CoqIDE and coqtop is now done via a dialect
of XML (DOC TODO).
- The backtrack engine of CoqIDE has been reworked, it now uses the
"Backtrack" command similarly to Proof General.
-- The Coqide parsing of sentences has be reworked and now supports
+- The CoqIDE parsing of sentences has be reworked and now supports
tactic delimitation via { }.
-- Coqide now accepts the Abort command (wish #2357).
-- Coqide can read coq_makefile files as "project file" and use it to
+- CoqIDE now accepts the Abort command (wish #2357).
+- CoqIDE can read coq_makefile files as "project file" and use it to
set automatically options to send to coqtop.
- Preference files have moved to $XDG_CONFIG_HOME/coq and accelerators
are not stored as a list anymore.
@@ -5785,7 +5905,7 @@ Module System
CoqIDE
-- Coqide now supports the "Restart" command, and "Undo" (with a warning).
+- CoqIDE now supports the "Restart" command, and "Undo" (with a warning).
Better support for "Abort".
Details of changes in 8.4
@@ -5887,8 +6007,8 @@ more robust basis.
Though invisible from outside, Arnaud Spiwack improved the general
process of management of existential variables. Pierre Letouzey and
-Stéphane Glondu improved the compilation scheme of the |Coq| archive.
-Vincent Gross provided support to |CoqIDE|. Jean-Marc Notin provided
+Stéphane Glondu improved the compilation scheme of the Coq archive.
+Vincent Gross provided support to CoqIDE. Jean-Marc Notin provided
support for benchmarking and archiving.
Many users helped by reporting problems, providing patches, suggesting
@@ -6258,16 +6378,16 @@ Summary of changes
Coq version 8.2 adds new features, new libraries and improves on many
various aspects.
-Regarding the language of |Coq|, the main novelty is the introduction by
+Regarding the language of Coq, the main novelty is the introduction by
Matthieu Sozeau of a package of commands providing Haskell-style typeclasses.
Typeclasses, which come with a few convenient features such as
type-based resolution of implicit arguments, play a new landmark role
-in the architecture of |Coq| with respect to automation. For
+in the architecture of Coq with respect to automation. For
instance, thanks to typeclass support, Matthieu Sozeau could
implement a new resolution-based version of the tactics dedicated to
rewriting on arbitrary transitive relations.
-Another major improvement of |Coq| 8.2 is the evolution of the arithmetic
+Another major improvement of Coq 8.2 is the evolution of the arithmetic
libraries and of the tools associated to them. Benjamin Grégoire and
Laurent Théry contributed a modular library for building arbitrarily
large integers from bounded integers while Evgeny Makarov contributed a
@@ -6291,7 +6411,7 @@ Arnaud Spiwack developed a library of 31-bits machine integers and,
relying on Benjamin Grégoire and Laurent Théry’s library, delivered a
library of unbounded integers in base :math:`2^{31}`. As importantly, he
developed a notion of “retro-knowledge” so as to safely extend the
-kernel-located bytecode-based efficient evaluation algorithm of |Coq|
+kernel-located bytecode-based efficient evaluation algorithm of Coq
version 8.1 to use 31-bits machine arithmetic for efficiently computing
with the library of integers he developed.
@@ -6323,16 +6443,16 @@ the Scheme command and of injection.
Bruno Barras implemented the ``coqchk`` tool: this is a stand-alone
type checker that can be used to certify .vo files. Especially, as this
verifier runs in a separate process, it is granted not to be “hijacked”
-by virtually malicious extensions added to |Coq|.
+by virtually malicious extensions added to Coq.
Yves Bertot, Jean-Christophe Filliâtre, Pierre Courtieu and Julien
Forest acted as maintainers of features they implemented in previous
-versions of |Coq|.
+versions of Coq.
-Julien Narboux contributed to |CoqIDE|. Nicolas Tabareau made the
+Julien Narboux contributed to CoqIDE. Nicolas Tabareau made the
adaptation of the interface of the old “setoid rewrite” tactic to the
-new version. Lionel Mamane worked on the interaction between |Coq| and its
-external interfaces. With Samuel Mimram, he also helped making |Coq|
+new version. Lionel Mamane worked on the interaction between Coq and its
+external interfaces. With Samuel Mimram, he also helped making Coq
compatible with recent software tools. Russell O’Connor, Cezary
Kaliszyk, Milad Niqui contributed to improve the libraries of integers,
rational, and real numbers. We also thank many users and partners for
@@ -6823,7 +6943,7 @@ Extraction
not happen anymore.
- The command Extract Inductive has now a syntax for infix notations. This
- allows in particular to map Coq lists and pairs onto Caml ones:
+ allows in particular to map Coq lists and pairs onto OCaml ones:
+ Extract Inductive list => list [ "[]" "(::)" ].
+ Extract Inductive prod => "(*)" [ "(,)" ].
@@ -6886,7 +7006,7 @@ Summary of changes
Coq version 8.1 adds various new functionalities.
Benjamin Grégoire implemented an alternative algorithm to check the
-convertibility of terms in the |Coq| type checker. This alternative
+convertibility of terms in the Coq type checker. This alternative
algorithm works by compilation to an efficient bytecode that is
interpreted in an abstract machine similar to Xavier Leroy’s ZINC
machine. Convertibility is performed by comparing the normal forms. This
@@ -6916,7 +7036,7 @@ Claudio Sacerdoti Coen added new tactic features.
Hugo Herbelin implemented matching on disjunctive patterns.
-New mechanisms made easier the communication between |Coq| and external
+New mechanisms made easier the communication between Coq and external
provers. Nicolas Ayache and Jean-Christophe Filliâtre implemented
connections with the provers cvcl, Simplify and zenon. Hugo Herbelin
implemented an experimental protocol for calling external tools from the
@@ -6930,7 +7050,7 @@ unresolved implicit has been implemented by Hugo Herbelin.
Laurent Théry’s contribution on strings and Pierre Letouzey and
Jean-Christophe Filliâtre’s contribution on finite maps have been
-integrated to the |Coq| standard library. Pierre Letouzey developed a
+integrated to the Coq standard library. Pierre Letouzey developed a
library about finite sets “à la Objective Caml”. With Jean-Marc Notin,
he extended the library on lists. Pierre Letouzey’s contribution on
rational numbers has been integrated and extended.
@@ -7180,7 +7300,7 @@ Tools
- Tool coq_makefile now removes custom targets that are file names in
"make clean"
- New environment variable COQREMOTEBROWSER to set the command invoked
- to start the remote browser both in Coq and coqide. Standard syntax:
+ to start the remote browser both in Coq and CoqIDE. Standard syntax:
"%s" is the placeholder for the URL.
Details of changes in 8.1gamma
@@ -7256,7 +7376,7 @@ Version 8.0
Summary of changes
~~~~~~~~~~~~~~~~~~
-Coq version 8 is a major revision of the |Coq| proof assistant. First, the
+Coq version 8 is a major revision of the Coq proof assistant. First, the
underlying logic is slightly different. The so-called *impredicativity*
of the sort Set has been dropped. The main reason is that it is
inconsistent with the principle of description which is quite a useful
@@ -7285,7 +7405,7 @@ main motivations were
Together with the revision of the concrete syntax, a new mechanism of
*notation scopes* permits to reuse the same symbols (typically +,
-, \*, /, <, <=) in various mathematical theories without any
-ambiguities for |Coq|, leading to a largely improved readability of |Coq|
+ambiguities for Coq, leading to a largely improved readability of Coq
scripts. New commands to easily add new symbols are also provided.
Coming with the new syntax of terms, a slight reform of the tactic
@@ -7295,29 +7415,29 @@ easier to use and to remember.
Thirdly, a restructuring and uniformization of the standard library of
Coq has been performed. There is now just one Leibniz equality usable
-for all the different kinds of |Coq| objects. Also, the set of real
+for all the different kinds of Coq objects. Also, the set of real
numbers now lies at the same level as the sets of natural and integer
numbers. Finally, the names of the standard properties of numbers now
follow a standard pattern and the symbolic notations for the standard
definitions as well.
-The fourth point is the release of |CoqIDE|, a new graphical gtk2-based
-interface fully integrated with |Coq|. Close in style to the Proof General
-Emacs interface, it is faster and its integration with |Coq| makes
+The fourth point is the release of CoqIDE, a new graphical gtk2-based
+interface fully integrated with Coq. Close in style to the Proof General
+Emacs interface, it is faster and its integration with Coq makes
interactive developments more friendly. All mathematical Unicode symbols
-are usable within |CoqIDE|.
+are usable within CoqIDE.
-Finally, the module system of |Coq| completes the picture of |Coq| version
+Finally, the module system of Coq completes the picture of Coq version
8.0. Though released with an experimental status in the previous version
7.4, it should be considered as a salient feature of the new version.
-Besides, |Coq| comes with its load of novelties and improvements: new or
+Besides, Coq comes with its load of novelties and improvements: new or
improved tactics (including a new tactic for solving first-order
statements), new management commands, extended libraries.
Bruno Barras and Hugo Herbelin have been the main contributors of the
reflection and the implementation of the new syntax. The smart automatic
-translator from old to new syntax released with |Coq| is also their work
+translator from old to new syntax released with Coq is also their work
with contributions by Olivier Desmettre.
Hugo Herbelin is the main designer and implementer of the notion of
@@ -7330,21 +7450,21 @@ Pierre Corbineau is the main designer and implementer of the new tactic
for solving first-order statements in presence of inductive types. He is
also the maintainer of the non-domain specific automation tactics.
-Benjamin Monate is the developer of the |CoqIDE| graphical interface with
+Benjamin Monate is the developer of the CoqIDE graphical interface with
contributions by Jean-Christophe Filliâtre, Pierre Letouzey, Claude
Marché and Bruno Barras.
-Claude Marché coordinated the edition of the Reference Manual for |Coq|
+Claude Marché coordinated the edition of the Reference Manual for Coq
V8.0.
Pierre Letouzey and Jacek Chrząszcz respectively maintained the
-extraction tool and module system of |Coq|.
+extraction tool and module system of Coq.
Jean-Christophe Filliâtre, Pierre Letouzey, Hugo Herbelin and other
contributors from Sophia-Antipolis and Nijmegen participated in
extending the library.
-Julien Narboux built a NSIS-based automatic |Coq| installation tool for
+Julien Narboux built a NSIS-based automatic Coq installation tool for
the Windows platform.
Hugo Herbelin and Christine Paulin coordinated the development which was
diff --git a/doc/sphinx/conf.py b/doc/sphinx/conf.py
index a8a574c861..75ac2a76cd 100755
--- a/doc/sphinx/conf.py
+++ b/doc/sphinx/conf.py
@@ -183,9 +183,7 @@ todo_include_todos = False
nitpicky = True
nitpick_ignore = [ ('token', token) for token in [
- 'collection',
'tactic',
- 'bindings',
'induction_clause',
'conversion',
'where',
diff --git a/doc/sphinx/history.rst b/doc/sphinx/history.rst
index 02821613cc..c5ef92a1bf 100644
--- a/doc/sphinx/history.rst
+++ b/doc/sphinx/history.rst
@@ -1,8 +1,8 @@
.. _history:
---------------------
+----------------------
Early history of Coq
---------------------
+----------------------
Historical roots
----------------
@@ -17,7 +17,7 @@ verified mathematical proofs, and the *program extractor* which
synthesizes computer programs obeying their formal specifications,
written as logical assertions in the language.
-The logical language used by |Coq| is a variety of type theory, called the
+The logical language used by Coq is a variety of type theory, called the
*Calculus of Inductive Constructions*. Without going back to Leibniz and
Boole, we can date the creation of what is now called mathematical logic
to the work of Frege and Peano at the turn of the century. The discovery
@@ -108,7 +108,7 @@ modules, automatically generated from a consistency proof of their
formal specifications. We are however still far from being able to use
this methodology in a smooth interaction with the standard tools from
software engineering, i.e. compilers, linkers, run-time systems taking
-advantage of special hardware, debuggers, and the like. We hope that |Coq|
+advantage of special hardware, debuggers, and the like. We hope that Coq
can be of use to researchers interested in experimenting with this new
methodology.
@@ -154,7 +154,7 @@ manipulation of windows, menus, mouse-sensitive buttons, and other
widgets. This system (Version 5.6) was released in 1991.
Coq was ported to the new implementation Caml-light of X. Leroy and D.
-Doligez by D. de Rauglaudre (Version 5.7) in 1992. A new version of |Coq|
+Doligez by D. de Rauglaudre (Version 5.7) in 1992. A new version of Coq
was then coordinated by C. Murthy, with new tools designed by C. Parent
to prove properties of ML programs (this methodology is dual to program
extraction) and a new user-interaction loop. This system (Version 5.8)
@@ -163,9 +163,9 @@ by Y. Bertot from the Croap project from INRIA-Sophia-Antipolis.
In parallel, G. Dowek and H. Herbelin developed a new proof engine,
allowing the general manipulation of existential variables consistently
-with dependent types in an experimental version of |Coq| (V5.9).
+with dependent types in an experimental version of Coq (V5.9).
-The version V5.10 of |Coq| is based on a generic system for manipulating
+The version V5.10 of Coq is based on a generic system for manipulating
terms with binding operators due to Chet Murthy. A new proof engine
allows the parallel development of partial proofs for independent
subgoals. The structure of these proof trees is a mixed representation
@@ -519,14 +519,14 @@ Versions 6
Version 6.1
~~~~~~~~~~~
-The present version 6.1 of |Coq| is based on the V5.10 architecture. It
+The present version 6.1 of Coq is based on the V5.10 architecture. It
was ported to the new language Objective Caml by Bruno Barras. The
underlying framework has slightly changed and allows more conversions
between sorts.
The new version provides powerful tools for easier developments.
-Cristina Cornes designed an extension of the |Coq| syntax to allow
+Cristina Cornes designed an extension of the Coq syntax to allow
definition of terms using a powerful pattern matching analysis in the
style of ML programs.
@@ -539,13 +539,13 @@ written.
Yann Coscoy designed a command which explains a proof term using natural
language. Pierre Crégut built a new tactic which solves problems in
quantifier-free Presburger Arithmetic. Both functionalities have been
-integrated to the |Coq| system by Hugo Herbelin.
+integrated to the Coq system by Hugo Herbelin.
Samuel Boutin designed a tactic for simplification of commutative rings
using a canonical set of rewriting rules and equality modulo
associativity and commutativity.
-Finally the organisation of the |Coq| distribution has been supervised by
+Finally the organisation of the Coq distribution has been supervised by
Jean-Christophe Filliâtre with the help of Judicaël Courant and Bruno
Barras.
@@ -556,21 +556,21 @@ Barras.
Version 6.2
~~~~~~~~~~~
-In version 6.2 of |Coq|, the parsing is done using camlp4, a preprocessor
+In version 6.2 of Coq, the parsing is done using camlp4, a preprocessor
and pretty-printer for CAML designed by Daniel de Rauglaudre at INRIA.
-Daniel de Rauglaudre made the first adaptation of |Coq| for camlp4, this
-work was continued by Bruno Barras who also changed the structure of |Coq|
+Daniel de Rauglaudre made the first adaptation of Coq for camlp4, this
+work was continued by Bruno Barras who also changed the structure of Coq
abstract syntax trees and the primitives to manipulate them. The result
of these changes is a faster parsing procedure with greatly improved
syntax-error messages. The user-interface to introduce grammar or
pretty-printing rules has also changed.
Eduardo Giménez redesigned the internal tactic libraries, giving uniform
-names to Caml functions corresponding to |Coq| tactic names.
+names to Caml functions corresponding to Coq tactic names.
Bruno Barras wrote new, more efficient reduction functions.
-Hugo Herbelin introduced more uniform notations in the |Coq| specification
+Hugo Herbelin introduced more uniform notations in the Coq specification
language: the definitions by fixpoints and pattern matching have a more
readable syntax. Patrick Loiseleur introduced user-friendly notations
for arithmetic expressions.
@@ -586,10 +586,10 @@ a proof term with holes as a proof scheme.
David Delahaye designed the tool to search an object in the library
given its type (up to isomorphism).
-Henri Laulhère produced the |Coq| distribution for the Windows
+Henri Laulhère produced the Coq distribution for the Windows
environment.
-Finally, Hugo Herbelin was the main coordinator of the |Coq| documentation
+Finally, Hugo Herbelin was the main coordinator of the Coq documentation
with principal contributions by Bruno Barras, David Delahaye,
Jean-Christophe Filliâtre, Eduardo Giménez, Hugo Herbelin and Patrick
Loiseleur.
@@ -639,7 +639,7 @@ Summary of changes
The version V7 is a new implementation started in September 1999 by
Jean-Christophe Filliâtre. This is a major revision with respect to the
-internal architecture of the system. The |Coq| version 7.0 was distributed
+internal architecture of the system. The Coq version 7.0 was distributed
in March 2001, version 7.1 in September 2001, version 7.2 in January
2002, version 7.3 in May 2002 and version 7.4 in February 2003.
@@ -653,13 +653,13 @@ Hugo Herbelin introduced a new structure of terms with local
definitions. He introduced “qualified” names, wrote a new
pattern matching compilation algorithm and designed a more compact
algorithm for checking the logical consistency of universes. He
-contributed to the simplification of |Coq| internal structures and the
+contributed to the simplification of Coq internal structures and the
optimisation of the system. He added basic tactics for forward reasoning
and coercions in patterns.
David Delahaye introduced a new language for tactics. General tactics
using pattern matching on goals and context can directly be written from
-the |Coq| toplevel. He also provided primitives for the design of
+the Coq toplevel. He also provided primitives for the design of
user-defined tactics in Caml.
Micaela Mayero contributed the library on real numbers. Olivier
@@ -668,16 +668,16 @@ square, square roots, finite sums, Chasles property and basic plane
geometry.
Jean-Christophe Filliâtre and Pierre Letouzey redesigned a new
-extraction procedure from |Coq| terms to Caml or Haskell programs. This
+extraction procedure from Coq terms to Caml or Haskell programs. This
new extraction procedure, unlike the one implemented in previous version
-of |Coq| is able to handle all terms in the Calculus of Inductive
+of Coq is able to handle all terms in the Calculus of Inductive
Constructions, even involving universes and strong elimination. P.
Letouzey adapted user contributions to extract ML programs when it was
sensible. Jean-Christophe Filliâtre wrote ``coqdoc``, a documentation
-tool for |Coq| libraries usable from version 7.2.
+tool for Coq libraries usable from version 7.2.
Bruno Barras improved the efficiency of the reduction algorithm and the
-confidence level in the correctness of |Coq| critical type checking
+confidence level in the correctness of Coq critical type checking
algorithm.
Yves Bertot designed the ``SearchPattern`` and ``SearchRewrite`` tools
@@ -696,7 +696,7 @@ real numbers.
Pierre Crégut developed a new, reflection-based version of the Omega
decision procedure.
-Claudio Sacerdoti Coen designed an XML output for the |Coq| modules to be
+Claudio Sacerdoti Coen designed an XML output for the Coq modules to be
used in the Hypertextual Electronic Library of Mathematics (HELM cf
http://www.cs.unibo.it/helm).
@@ -706,13 +706,13 @@ contributed by Jean Goubault was integrated in the basic theories.
Pierre Courtieu developed a command and a tactic to reason on the
inductive structure of recursively defined functions.
-Jacek Chrząszcz designed and implemented the module system of |Coq| whose
+Jacek Chrząszcz designed and implemented the module system of Coq whose
foundations are in Judicaël Courant’s PhD thesis.
The development was coordinated by C. Paulin.
Many discussions within the Démons team and the LogiCal project
-influenced significantly the design of |Coq| especially with J. Courant,
+influenced significantly the design of Coq especially with J. Courant,
J. Duprat, J. Goubault, A. Miquel, C. Marché, B. Monate and B. Werner.
Intensive users suggested improvements of the system : Y. Bertot, L.
@@ -1171,7 +1171,7 @@ Incompatibilities
- New naming strategy for NewInduction/NewDestruct may affect 7.1 compatibility
- Extra parentheses may exceptionally be needed in tactic definitions.
-- Coq extensions written in Ocaml need to be updated (see dev/changements.txt
+- Coq extensions written in OCaml need to be updated (see dev/changements.txt
for a description of the main changes in the interface files of V7.2)
- New behaviour of Intuition/Tauto may exceptionally lead to incompatibilities
diff --git a/doc/sphinx/introduction.rst b/doc/sphinx/introduction.rst
index b059fb4069..06a677d837 100644
--- a/doc/sphinx/introduction.rst
+++ b/doc/sphinx/introduction.rst
@@ -1,4 +1,4 @@
-This is the reference manual of |Coq|. Coq is an interactive theorem
+This is the reference manual of Coq. Coq is an interactive theorem
prover. It lets you formalize mathematical concepts and then helps
you interactively generate machine-checked proofs of theorems.
Machine checking gives users much more confidence that the proofs are
diff --git a/doc/sphinx/language/cic.rst b/doc/sphinx/language/cic.rst
index f1ed64e52a..85b04f6df0 100644
--- a/doc/sphinx/language/cic.rst
+++ b/doc/sphinx/language/cic.rst
@@ -1,7 +1,7 @@
Typing rules
====================================
-The underlying formal language of |Coq| is a *Calculus of Inductive
+The underlying formal language of Coq is a *Calculus of Inductive
Constructions* (|Cic|) whose inference rules are presented in this
chapter. The history of this formalism as well as pointers to related
work are provided in a separate chapter; see *Credits*.
@@ -33,7 +33,7 @@ the following rules.
#. variables, hereafter ranged over by letters :math:`x`, :math:`y`, etc., are terms
#. constants, hereafter ranged over by letters :math:`c`, :math:`d`, etc., are terms.
#. if :math:`x` is a variable and :math:`T`, :math:`U` are terms then
- :math:`∀ x:T,~U` (:g:`forall x:T, U` in |Coq| concrete syntax) is a term.
+ :math:`∀ x:T,~U` (:g:`forall x:T, U` in Coq concrete syntax) is a term.
If :math:`x` occurs in :math:`U`, :math:`∀ x:T,~U` reads as
“for all :math:`x` of type :math:`T`, :math:`U`”.
As :math:`U` depends on :math:`x`, one says that :math:`∀ x:T,~U` is
@@ -43,11 +43,11 @@ the following rules.
written: :math:`T \rightarrow U`.
#. if :math:`x` is a variable and :math:`T`, :math:`u` are terms then
:math:`λ x:T .~u` (:g:`fun x:T => u`
- in |Coq| concrete syntax) is a term. This is a notation for the
+ in Coq concrete syntax) is a term. This is a notation for the
λ-abstraction of λ-calculus :cite:`Bar81`. The term :math:`λ x:T .~u` is a function
which maps elements of :math:`T` to the expression :math:`u`.
#. if :math:`t` and :math:`u` are terms then :math:`(t~u)` is a term
- (:g:`t u` in |Coq| concrete
+ (:g:`t u` in Coq concrete
syntax). The term :math:`(t~u)` reads as “:math:`t` applied to :math:`u`”.
#. if :math:`x` is a variable, and :math:`t`, :math:`T` and :math:`u` are
terms then :math:`\letin{x}{t:T}{u}` is
@@ -91,10 +91,10 @@ Let us assume that ``mult`` is a function of type :math:`\nat→\nat→\nat` and
predicate of type :math:`\nat→\nat→ \Prop`. The λ-abstraction can serve to build
“ordinary” functions as in :math:`λ x:\nat.~(\kw{mult}~x~x)` (i.e.
:g:`fun x:nat => mult x x`
-in |Coq| notation) but may build also predicates over the natural
+in Coq notation) but may build also predicates over the natural
numbers. For instance :math:`λ x:\nat.~(\kw{eqnat}~x~0)`
(i.e. :g:`fun x:nat => eqnat x 0`
-in |Coq| notation) will represent the predicate of one variable :math:`x` which
+in Coq notation) will represent the predicate of one variable :math:`x` which
asserts the equality of :math:`x` with :math:`0`. This predicate has type
:math:`\nat → \Prop`
and it can be applied to any expression of type :math:`\nat`, say :math:`t`, to give an
@@ -524,7 +524,7 @@ One can consequently derive the following property.
The Calculus of Inductive Constructions with impredicative Set
-----------------------------------------------------------------
-|Coq| can be used as a type checker for the Calculus of Inductive
+Coq can be used as a type checker for the Calculus of Inductive
Constructions with an impredicative sort :math:`\Set` by using the compiler
option ``-impredicative-set``. For example, using the ordinary `coqtop`
command, the following is rejected,
diff --git a/doc/sphinx/language/coq-library.rst b/doc/sphinx/language/coq-library.rst
index 485dfd964d..d061ed41f1 100644
--- a/doc/sphinx/language/coq-library.rst
+++ b/doc/sphinx/language/coq-library.rst
@@ -1,28 +1,28 @@
.. _thecoqlibrary:
-The |Coq| library
+The Coq library
=================
.. index::
single: Theories
-The |Coq| library has two parts:
+The Coq library has two parts:
* The :gdef:`prelude`: definitions and theorems for
the most commonly used elementary logical notions and
- data types. |Coq| normally loads these files automatically when it starts.
+ data types. Coq normally loads these files automatically when it starts.
* The :gdef:`standard library`: general-purpose libraries with
definitions and theorems for sets, lists, sorting,
arithmetic, etc. To use these files, users must load them explicitly
with the ``Require`` command (see :ref:`compiled-files`)
-There are also many libraries provided by |Coq| users' community.
+There are also many libraries provided by Coq users' community.
These libraries and developments are available
for download at http://coq.inria.fr (see :ref:`userscontributions`).
-This chapter briefly reviews the |Coq| libraries whose contents can
+This chapter briefly reviews the Coq libraries whose contents can
also be browsed at http://coq.inria.fr/stdlib/.
@@ -32,9 +32,9 @@ The prelude
-----------
This section lists the basic notions and results which are directly
-available in the standard |Coq| system. Most of these constructions
+available in the standard Coq system. Most of these constructions
are defined in the ``Prelude`` module in directory ``theories/Init``
-in the |Coq| root directory; this includes the modules
+in the Coq root directory; this includes the modules
``Notations``,
``Logic``,
``Datatypes``,
@@ -92,7 +92,7 @@ Notation Precedence Associativity
Logic
~~~~~
-The basic library of |Coq| comes with the definitions of standard
+The basic library of Coq comes with the definitions of standard
(intuitionistic) logical connectives (they are defined as inductive
constructions). They are equipped with an appealing syntax enriching the
subclass :token:`form` of the syntactic class :token:`term`. The constructs
@@ -767,7 +767,7 @@ the modules they provide are compiled at installation time. So they
are directly accessible with the command ``Require`` (see
Section :ref:`compiled-files`).
-The different modules of the |Coq| standard library are documented
+The different modules of the Coq standard library are documented
online at https://coq.inria.fr/stdlib.
Peano’s arithmetic (nat)
diff --git a/doc/sphinx/language/core/assumptions.rst b/doc/sphinx/language/core/assumptions.rst
index 41e1c30f0d..e029068630 100644
--- a/doc/sphinx/language/core/assumptions.rst
+++ b/doc/sphinx/language/core/assumptions.rst
@@ -141,8 +141,8 @@ has type :n:`@type`.
of_type ::= {| : | :> } @type
These commands bind one or more :n:`@ident`\(s) to specified :n:`@type`\(s) as their specifications in
- the global context. The fact asserted by the :n:`@type` (or, equivalently, the existence
- of an object of this type) is accepted as a postulate.
+ the global context. The fact asserted by :n:`@type` (or, equivalently, the existence
+ of an object of this type) is accepted as a postulate. They accept the :attr:`program` attribute.
:cmd:`Axiom`, :cmd:`Conjecture`, :cmd:`Parameter` and their plural forms
are equivalent. They can take the :attr:`local` :term:`attribute`,
@@ -155,6 +155,10 @@ has type :n:`@type`.
is closed, the :n:`@ident`\(s) become undefined and every object depending on them will be explicitly
parameterized (i.e., the variables are *discharged*). See Section :ref:`section-mechanism`.
+ :n:`:>`
+ If specified, :token:`ident_decl` is automatically
+ declared as a coercion to the class of its type. See :ref:`coercions`.
+
The :n:`Inline` clause is only relevant inside functors. See :cmd:`Module`.
.. example:: Simple assumptions
diff --git a/doc/sphinx/language/core/basic.rst b/doc/sphinx/language/core/basic.rst
index 45bdc019ac..5406da38a1 100644
--- a/doc/sphinx/language/core/basic.rst
+++ b/doc/sphinx/language/core/basic.rst
@@ -10,7 +10,7 @@ manual. Then, we present the essential vocabulary necessary to read
the rest of the manual. Other terms are defined throughout the manual.
The reader may refer to the :ref:`glossary index <glossary_index>`
for a complete list of defined terms. Finally, we describe the various types of
-settings that |Coq| provides.
+settings that Coq provides.
Syntax and lexical conventions
------------------------------
@@ -21,7 +21,7 @@ Syntax conventions
~~~~~~~~~~~~~~~~~~
The syntax described in this documentation is equivalent to that
-accepted by the |Coq| parser, but the grammar has been edited
+accepted by the Coq parser, but the grammar has been edited
to improve readability and presentation.
In the grammar presented in this manual, the terminal symbols are
@@ -49,13 +49,13 @@ graphically using the following kinds of blocks:
`Precedence levels
<https://en.wikipedia.org/wiki/Order_of_operations>`_ that are
-implemented in the |Coq| parser are shown in the documentation by
+implemented in the Coq parser are shown in the documentation by
appending the level to the nonterminal name (as in :n:`@term100` or
:n:`@ltac_expr3`).
.. note::
- |Coq| uses an extensible parser. Plugins and the :ref:`notation
+ Coq uses an extensible parser. Plugins and the :ref:`notation
system <syntax-extensions-and-notation-scopes>` can extend the
syntax at run time. Some notations are defined in the :term:`prelude`,
which is loaded by default. The documented grammar doesn't include
@@ -71,8 +71,8 @@ appending the level to the nonterminal name (as in :n:`@term100` or
Given the complexity of these parsing rules, it would be extremely
difficult to create an external program that can properly parse a
- |Coq| document. Therefore, tool writers are advised to delegate
- parsing to |Coq|, by communicating with it, for instance through
+ Coq document. Therefore, tool writers are advised to delegate
+ parsing to Coq, by communicating with it, for instance through
`SerAPI <https://github.com/ejgallego/coq-serapi>`_.
.. seealso:: :cmd:`Print Grammar`
@@ -113,7 +113,7 @@ Identifiers
Numbers
Numbers are sequences of digits with an optional fractional part
- and exponent, optionally preceded by a minus sign. Hexadecimal numerals
+ and exponent, optionally preceded by a minus sign. Hexadecimal numbers
start with ``0x`` or ``0X``. :n:`@bigint` are integers;
numbers without fractional nor exponent parts. :n:`@bignat` are non-negative
integers. Underscores embedded in the digits are ignored, for example
@@ -172,7 +172,7 @@ Other tokens
(even when starting Coq with the `-noinit` command-line flag)::
! #[ % & ' ( () ) * + , - ->
- . .( .. ... / : ::= := :> :>> ; < <+ <- <:
+ . .( .. ... / : ::= := :> ; < <+ <- <:
<<: <= = => > >-> >= ? @ @{ [ ] _
`( `{ { {| | }
@@ -195,7 +195,7 @@ Essential vocabulary
--------------------
This section presents the most essential notions to understand the
-rest of the |Coq| manual: :term:`terms <term>` and :term:`types
+rest of the Coq manual: :term:`terms <term>` and :term:`types
<type>` on the one hand, :term:`commands <command>` and :term:`tactics
<tactic>` on the other hand.
@@ -203,14 +203,14 @@ rest of the |Coq| manual: :term:`terms <term>` and :term:`types
term
- Terms are the basic expressions of |Coq|. Terms can represent
+ Terms are the basic expressions of Coq. Terms can represent
mathematical expressions, propositions and proofs, but also
executable programs and program types.
Here is the top-level syntax of terms. Each of the listed
constructs is presented in a dedicated section. Some of these
constructs (like :n:`@term_forall_or_fun`) are part of the core
- language that the kernel of |Coq| understands and are therefore
+ language that the kernel of Coq understands and are therefore
described in :ref:`this chapter <core-language>`, while
others (like :n:`@term_if`) are language extensions that are
presented in :ref:`the next chapter <extensions>`.
@@ -256,18 +256,18 @@ rest of the |Coq| manual: :term:`terms <term>` and :term:`types
type
- To be valid and accepted by the |Coq| kernel, a term needs an
+ To be valid and accepted by the Coq kernel, a term needs an
associated type. We express this relationship by “:math:`x` *of
type* :math:`T`”, which we write as “:math:`x:T`”. Informally,
“:math:`x:T`” can be thought as “:math:`x` *belongs to*
:math:`T`”.
- The |Coq| kernel is a type checker: it verifies that a term has
+ The Coq kernel is a type checker: it verifies that a term has
the expected type by applying a set of typing rules (see
:ref:`Typing-rules`). If that's indeed the case, we say that the
term is :gdef:`well-typed`.
- A special feature of the |Coq| language is that types can depend
+ A special feature of the Coq language is that types can depend
on terms (we say that the language is `dependently-typed
<https://en.wikipedia.org/wiki/Dependent_type>`_). Because of
this, types and terms share a common syntax. All types are terms,
@@ -289,13 +289,13 @@ rest of the |Coq| manual: :term:`terms <term>` and :term:`types
mathematics alternative to the standard `"set theory"
<https://en.wikipedia.org/wiki/Set_theory>`_: we call such
logical foundations `"type theories"
- <https://en.wikipedia.org/wiki/Type_theory>`_. |Coq| is based on
+ <https://en.wikipedia.org/wiki/Type_theory>`_. Coq is based on
the Calculus of Inductive Constructions, which is a particular
instance of type theory.
sentence
- |Coq| documents are made of a series of sentences that contain
+ Coq documents are made of a series of sentences that contain
:term:`commands <command>` or :term:`tactics <tactic>`, generally
terminated with a period and optionally decorated with
:term:`attributes <attribute>`.
@@ -315,7 +315,7 @@ rest of the |Coq| manual: :term:`terms <term>` and :term:`types
command
- A :production:`command` can be used to modify the state of a |Coq|
+ A :production:`command` can be used to modify the state of a Coq
document, for instance by declaring a new object, or to get
information about the current state.
@@ -325,16 +325,16 @@ rest of the |Coq| manual: :term:`terms <term>` and :term:`types
boldface label "Command:". Commands are listed in the
:ref:`command_index`. Example:
- .. cmd:: Comments {* @string }
+ .. cmd:: Comments {* {| @one_term | @string | @natural } }
- This command prints "Comments ok" and does not change anything
- to the state of the document.
+ Prints "Comments ok" and does not change
+ the state of the document.
tactic
Tactics specify how to transform the current proof state as a
step in creating a proof. They are syntactically valid only when
- |Coq| is in proof mode, such as after a :cmd:`Theorem` command
+ Coq is in proof mode, such as after a :cmd:`Theorem` command
and before any subsequent proof-terminating command such as
:cmd:`Qed`. See :ref:`proofhandling` for more on proof mode.
@@ -346,10 +346,10 @@ rest of the |Coq| manual: :term:`terms <term>` and :term:`types
Settings
--------
-There are several mechanisms for changing the behavior of |Coq|. The
+There are several mechanisms for changing the behavior of Coq. The
:term:`attribute` mechanism is used to modify the behavior of a single
:term:`sentence`. The :term:`flag`, :term:`option` and :term:`table`
-mechanisms are used to modify the behavior of |Coq| more globally in a
+mechanisms are used to modify the behavior of Coq more globally in a
document or project.
.. _attributes:
@@ -420,7 +420,7 @@ boldface label "Attribute:". Attributes are listed in the
Flags, Options and Tables
~~~~~~~~~~~~~~~~~~~~~~~~~
-The following types of settings can be used to change the behavior of |Coq| in
+The following types of settings can be used to change the behavior of Coq in
subsequent commands and tactics (see :ref:`set_unset_scope_qualifiers` for a
more precise description of the scope of these settings):
@@ -463,10 +463,10 @@ they appear after a boldface label. They are listed in the
This warning message can be raised by :cmd:`Set` and
:cmd:`Unset` when :n:`@setting_name` is unknown. It is a
warning rather than an error because this helps library authors
- produce |Coq| code that is compatible with several |Coq| versions.
+ produce Coq code that is compatible with several Coq versions.
To preserve the same behavior, they may need to set some
compatibility flags or options that did not exist in previous
- |Coq| versions.
+ Coq versions.
.. cmd:: Unset @setting_name
:name: Unset
diff --git a/doc/sphinx/language/core/coinductive.rst b/doc/sphinx/language/core/coinductive.rst
index c034b7f302..3e2ecdc0f0 100644
--- a/doc/sphinx/language/core/coinductive.rst
+++ b/doc/sphinx/language/core/coinductive.rst
@@ -28,8 +28,8 @@ More information on co-inductive definitions can be found in
This command supports the :attr:`universes(polymorphic)`,
:attr:`universes(monomorphic)`, :attr:`universes(template)`,
:attr:`universes(notemplate)`, :attr:`universes(cumulative)`,
- :attr:`universes(noncumulative)` and :attr:`private(matching)`
- attributes.
+ :attr:`universes(noncumulative)`, :attr:`private(matching)`
+ and :attr:`using` attributes.
.. example::
diff --git a/doc/sphinx/language/core/conversion.rst b/doc/sphinx/language/core/conversion.rst
index 6b031cfea3..7395b12339 100644
--- a/doc/sphinx/language/core/conversion.rst
+++ b/doc/sphinx/language/core/conversion.rst
@@ -85,7 +85,7 @@ reduction is called δ-reduction and shows as follows.
ζ-reduction
~~~~~~~~~~~
-|Coq| allows also to remove local definitions occurring in terms by
+Coq allows also to remove local definitions occurring in terms by
replacing the defined variable by its value. The declaration being
destroyed, this reduction differs from δ-reduction. It is called
ζ-reduction and shows as follows.
diff --git a/doc/sphinx/language/core/definitions.rst b/doc/sphinx/language/core/definitions.rst
index 42203d9d65..79489c85f6 100644
--- a/doc/sphinx/language/core/definitions.rst
+++ b/doc/sphinx/language/core/definitions.rst
@@ -13,15 +13,18 @@ Let-in definitions
.. prodn::
term_let ::= let @name {? : @type } := @term in @term
| let @name {+ @binder } {? : @type } := @term in @term
- | let ( {*, @name } ) {? {? as @name } return @term100 } := @term in @term
- | let ' @pattern := @term {? return @term100 } in @term
- | let ' @pattern in @pattern := @term return @term100 in @term
+ | @destructuring_let
-:n:`let @ident := @term in @term’`
-denotes the local binding of :n:`@term` to the variable
-:n:`@ident` in :n:`@term`’. There is a syntactic sugar for let-in
-definition of functions: :n:`let @ident {+ @binder} := @term in @term’`
-stands for :n:`let @ident := fun {+ @binder} => @term in @term’`.
+:n:`let @ident := @term__1 in @term__2` represents the local binding of
+the variable :n:`@ident` to the value :n:`@term__1` in :n:`@term__2`.
+
+:n:`let @ident {+ @binder} := @term__1 in @term__2` is an abbreviation
+for :n:`let @ident := fun {+ @binder} => @term__1 in @term__2`.
+
+.. seealso::
+
+ Extensions of the `let ... in ...` syntax are described in
+ :ref:`irrefutable-patterns`.
.. index::
single: ... : ... (type cast)
@@ -87,8 +90,8 @@ Section :ref:`typing-rules`.
computation on :n:`@term`.
These commands also support the :attr:`universes(polymorphic)`,
- :attr:`universes(monomorphic)`, :attr:`program` and
- :attr:`canonical` attributes.
+ :attr:`universes(monomorphic)`, :attr:`program` (see :ref:`program_definition`),
+ :attr:`canonical` and :attr:`using` attributes.
If :n:`@term` is omitted, :n:`@type` is required and Coq enters proof editing mode.
This can be used to define a term incrementally, in particular by relying on the :tacn:`refine` tactic.
@@ -140,6 +143,8 @@ Chapter :ref:`Tactics`. The basic assertion command is:
validated, the proof is generalized into a proof of :n:`forall {* @binder }, @type` and
the theorem is bound to the name :n:`@ident` in the environment.
+ These commands accept the :attr:`program` attribute. See :ref:`program_lemma`.
+
Forms using the :n:`with` clause are useful for theorems that are proved by simultaneous induction
over a mutually inductive assumption, or that assert mutually dependent
statements in some mutual co-inductive type. It is equivalent to
@@ -157,6 +162,8 @@ Chapter :ref:`Tactics`. The basic assertion command is:
correct at some time of the interactive development of a proof, use the
command :cmd:`Guarded`.
+ This command accepts the :attr:`using` attribute.
+
.. exn:: The term @term has type @type which should be Set, Prop or Type.
:undocumented:
diff --git a/doc/sphinx/language/core/inductive.rst b/doc/sphinx/language/core/inductive.rst
index 39b154de8d..ad7d6f3963 100644
--- a/doc/sphinx/language/core/inductive.rst
+++ b/doc/sphinx/language/core/inductive.rst
@@ -8,13 +8,14 @@ Inductive types
.. cmd:: Inductive @inductive_definition {* with @inductive_definition }
- .. insertprodn inductive_definition constructor
+ .. insertprodn inductive_definition cumul_ident_decl
.. prodn::
- inductive_definition ::= {? > } @ident_decl {* @binder } {? %| {* @binder } } {? : @type } {? := {? @constructors_or_record } } {? @decl_notations }
+ inductive_definition ::= {? > } @cumul_ident_decl {* @binder } {? %| {* @binder } } {? : @type } {? := {? @constructors_or_record } } {? @decl_notations }
constructors_or_record ::= {? %| } {+| @constructor }
| {? @ident } %{ {*; @record_field } {? ; } %}
constructor ::= @ident {* @binder } {? @of_type }
+ cumul_ident_decl ::= @ident {? @cumul_univ_decl }
This command defines one or more
inductive types and its constructors. Coq generates destructors
@@ -342,9 +343,9 @@ Recursive functions: fix
.. insertprodn term_fix fixannot
.. prodn::
- term_fix ::= let fix @fix_body in @term
- | fix @fix_body {? {+ with @fix_body } for @ident }
- fix_body ::= @ident {* @binder } {? @fixannot } {? : @type } := @term
+ term_fix ::= let fix @fix_decl in @term
+ | fix @fix_decl {? {+ with @fix_decl } for @ident }
+ fix_decl ::= @ident {* @binder } {? @fixannot } {? : @type } := @term
fixannot ::= %{ struct @ident %}
| %{ wf @one_term @ident %}
| %{ measure @one_term {? @ident } {? @one_term } %}
@@ -361,7 +362,11 @@ syntax: :n:`let fix @ident {* @binder } := @term in` stands for
Some options of :n:`@fixannot` are only supported in specific constructs. :n:`fix` and :n:`let fix`
only support the :n:`struct` option, while :n:`wf` and :n:`measure` are only supported in
-commands such as :cmd:`Function` and :cmd:`Program Fixpoint`.
+commands such as :cmd:`Fixpoint` (with the :attr:`program` attribute) and :cmd:`Function`.
+
+.. todo explanation of struct: see text above at the Fixpoint command, also
+ see https://github.com/coq/coq/pull/12936#discussion_r510716268 and above.
+ Consider whether to move the grammar for fixannot elsewhere
.. _Fixpoint:
@@ -379,7 +384,7 @@ constructions.
.. prodn::
fix_definition ::= @ident_decl {* @binder } {? @fixannot } {? : @type } {? := @term } {? @decl_notations }
- This command allows defining functions by pattern matching over inductive
+ Allows defining functions by pattern matching over inductive
objects using a fixed point construction. The meaning of this declaration is
to define :n:`@ident` as a recursive function with arguments specified by
the :n:`@binder`\s such that :n:`@ident` applied to arguments
@@ -388,6 +393,8 @@ constructions.
consequently :n:`forall {* @binder }, @type` and its value is equivalent
to :n:`fun {* @binder } => @term`.
+ This command accepts the :attr:`program` attribute.
+
To be accepted, a :cmd:`Fixpoint` definition has to satisfy syntactical
constraints on a special argument called the decreasing argument. They
are needed to ensure that the :cmd:`Fixpoint` definition always terminates.
@@ -399,7 +406,7 @@ constructions.
that satisfies the decreasing condition.
:cmd:`Fixpoint` without the :attr:`program` attribute does not support the
- :n:`wf` or :n:`measure` clauses of :n:`@fixannot`.
+ :n:`wf` or :n:`measure` clauses of :n:`@fixannot`. See :ref:`program_fixpoint`.
The :n:`with` clause allows simultaneously defining several mutual fixpoints.
It is especially useful when defining functions over mutually defined
@@ -410,6 +417,8 @@ constructions.
In this case, the proof should be terminated with :cmd:`Defined` in order to define a constant
for which the computational behavior is relevant. See :ref:`proof-editing-mode`.
+ This command accepts the :attr:`using` attribute.
+
.. note::
+ Some fixpoints may have several arguments that fit as decreasing
@@ -544,7 +553,7 @@ the sort of the inductive type :math:`t` (not to be confused with :math:`\Sort`
\end{array}
\right]}
- which corresponds to the result of the |Coq| declaration:
+ which corresponds to the result of the Coq declaration:
.. coqtop:: in reset
@@ -565,7 +574,7 @@ the sort of the inductive type :math:`t` (not to be confused with :math:`\Sort`
\consf &:& \tree → \forest → \forest\\
\end{array}\right]}
- which corresponds to the result of the |Coq| declaration:
+ which corresponds to the result of the Coq declaration:
.. coqtop:: in
@@ -588,7 +597,7 @@ the sort of the inductive type :math:`t` (not to be confused with :math:`\Sort`
\oddS &:& ∀ n,~\even~n → \odd~(\nS~n)
\end{array}\right]}
- which corresponds to the result of the |Coq| declaration:
+ which corresponds to the result of the Coq declaration:
.. coqtop:: in
@@ -1091,7 +1100,7 @@ Conversion is preserved as any (partial) instance :math:`I_j~q_1 … q_r` or
template polymorphic, even if the :flag:`Auto Template
Polymorphism` flag is on.
-In practice, the rule **Ind-Family** is used by |Coq| only when all the
+In practice, the rule **Ind-Family** is used by Coq only when all the
inductive types of the inductive definition are declared with an arity
whose sort is in the Type hierarchy. Then, the polymorphism is over
the parameters whose type is an arity of sort in the Type hierarchy.
@@ -1229,7 +1238,7 @@ at the computational level it implements a generic operator for doing
primitive recursion over the structure.
But this operator is rather tedious to implement and use. We choose in
-this version of |Coq| to factorize the operator for primitive recursion
+this version of Coq to factorize the operator for primitive recursion
into two more primitive operations as was first suggested by Th.
Coquand in :cite:`Coq92`. One is the definition by pattern matching. The
second one is a definition by guarded fixpoints.
@@ -1244,7 +1253,7 @@ The basic idea of this operator is that we have an object :math:`m` in an
inductive type :math:`I` and we want to prove a property which possibly
depends on :math:`m`. For this, it is enough to prove the property for
:math:`m = (c_i~u_1 … u_{p_i} )` for each constructor of :math:`I`.
-The |Coq| term for this proof
+The Coq term for this proof
will be written:
.. math::
@@ -1259,7 +1268,7 @@ Actually, for type checking a :math:`\Match…\with…\kwend` expression we also
to know the predicate :math:`P` to be proved by case analysis. In the general
case where :math:`I` is an inductively defined :math:`n`-ary relation, :math:`P` is a predicate
over :math:`n+1` arguments: the :math:`n` first ones correspond to the arguments of :math:`I`
-(parameters excluded), and the last one corresponds to object :math:`m`. |Coq|
+(parameters excluded), and the last one corresponds to object :math:`m`. Coq
can sometimes infer this predicate but sometimes not. The concrete
syntax for describing this predicate uses the :math:`\as…\In…\return`
construction. For instance, let us assume that :math:`I` is an unary predicate
diff --git a/doc/sphinx/language/core/modules.rst b/doc/sphinx/language/core/modules.rst
index 866104d5d1..54252689e1 100644
--- a/doc/sphinx/language/core/modules.rst
+++ b/doc/sphinx/language/core/modules.rst
@@ -864,17 +864,17 @@ Libraries and qualified names
Names of libraries
~~~~~~~~~~~~~~~~~~
-The theories developed in |Coq| are stored in *library files* which are
+The theories developed in Coq are stored in *library files* which are
hierarchically classified into *libraries* and *sublibraries*. To
express this hierarchy, library names are represented by qualified
identifiers qualid, i.e. as list of identifiers separated by dots (see
:ref:`qualified-names`). For instance, the library file ``Mult`` of the standard
-|Coq| library ``Arith`` is named ``Coq.Arith.Mult``. The identifier that starts
+Coq library ``Arith`` is named ``Coq.Arith.Mult``. The identifier that starts
the name of a library is called a *library root*. All library files of
-the standard library of |Coq| have the reserved root |Coq| but library
-filenames based on other roots can be obtained by using |Coq| commands
+the standard library of Coq have the reserved root Coq but library
+filenames based on other roots can be obtained by using Coq commands
(coqc, coqtop, coqdep, …) options ``-Q`` or ``-R`` (see :ref:`command-line-options`).
-Also, when an interactive |Coq| session starts, a library of root ``Top`` is
+Also, when an interactive Coq session starts, a library of root ``Top`` is
started, unless option ``-top`` or ``-notop`` is set (see :ref:`command-line-options`).
.. _qualified-names:
@@ -897,7 +897,7 @@ followed by the sequence of submodules names encapsulating the
construction and ended by the proper name of the construction.
Typically, the absolute name ``Coq.Init.Logic.eq`` denotes Leibniz’
equality defined in the module Logic in the sublibrary ``Init`` of the
-standard library of |Coq|.
+standard library of Coq.
The proper name that ends the name of a construction is the short name
(or sometimes base name) of the construction (for instance, the short
@@ -906,7 +906,7 @@ name is a *partially qualified name* (e.g. ``Logic.eq`` is a partially
qualified name for ``Coq.Init.Logic.eq``). Especially, the short name of a
construction is its shortest partially qualified name.
-|Coq| does not accept two constructions (definition, theorem, …) with
+Coq does not accept two constructions (definition, theorem, …) with
the same absolute name but different constructions can have the same
short name (or even same partially qualified names as soon as the full
names are different).
@@ -916,14 +916,14 @@ names also applies to library filenames.
**Visibility**
-|Coq| maintains a table called the name table which maps partially qualified
+Coq maintains a table called the name table which maps partially qualified
names of constructions to absolute names. This table is updated by the
commands :cmd:`Require`, :cmd:`Import` and :cmd:`Export` and
also each time a new declaration is added to the context. An absolute
name is called visible from a given short or partially qualified name
when this latter name is enough to denote it. This means that the
short or partially qualified name is mapped to the absolute name in
-|Coq| name table. Definitions with the :attr:`local` attribute are only accessible with
+Coq name table. Definitions with the :attr:`local` attribute are only accessible with
their fully qualified name (see :ref:`gallina-definitions`).
It may happen that a visible name is hidden by the short name or a
@@ -953,13 +953,13 @@ accessible, absolute names can never be hidden.
Libraries and filesystem
~~~~~~~~~~~~~~~~~~~~~~~~
-.. note:: The questions described here have been subject to redesign in |Coq| 8.5.
- Former versions of |Coq| use the same terminology to describe slightly different things.
+.. note:: The questions described here have been subject to redesign in Coq 8.5.
+ Former versions of Coq use the same terminology to describe slightly different things.
Compiled files (``.vo`` and ``.vio``) store sub-libraries. In order to refer
-to them inside |Coq|, a translation from file-system names to |Coq| names
+to them inside Coq, a translation from file-system names to Coq names
is needed. In this translation, names in the file system are called
-*physical* paths while |Coq| names are contrastingly called *logical*
+*physical* paths while Coq names are contrastingly called *logical*
names.
A logical prefix Lib can be associated with a physical path using
@@ -967,7 +967,7 @@ the command line option ``-Q`` `path` ``Lib``. All subfolders of path are
recursively associated to the logical path ``Lib`` extended with the
corresponding suffix coming from the physical path. For instance, the
folder ``path/fOO/Bar`` maps to ``Lib.fOO.Bar``. Subdirectories corresponding
-to invalid |Coq| identifiers are skipped, and, by convention,
+to invalid Coq identifiers are skipped, and, by convention,
subdirectories named ``CVS`` or ``_darcs`` are skipped too.
Thanks to this mechanism, ``.vo`` files are made available through the
@@ -979,7 +979,7 @@ its logical name, so that an error is issued if it is loaded with the
wrong loadpath afterwards.
Some folders have a special status and are automatically put in the
-path. |Coq| commands associate automatically a logical path to files in
+path. Coq commands associate automatically a logical path to files in
the repository trees rooted at the directory from where the command is
launched, ``coqlib/user-contrib/``, the directories listed in the
``$COQPATH``, ``${XDG_DATA_HOME}/coq/`` and ``${XDG_DATA_DIRS}/coq/``
@@ -1001,12 +1001,12 @@ of the ``Require`` command can be used to bypass the implicit shortening
by providing an absolute root to the required file (see :ref:`compiled-files`).
There also exists another independent loadpath mechanism attached to
-OCaml object files (``.cmo`` or ``.cmxs``) rather than |Coq| object
+OCaml object files (``.cmo`` or ``.cmxs``) rather than Coq object
files as described above. The OCaml loadpath is managed using
the option ``-I`` `path` (in the OCaml world, there is neither a
notion of logical name prefix nor a way to access files in
subdirectories of path). See the command :cmd:`Declare ML Module` in
:ref:`compiled-files` to understand the need of the OCaml loadpath.
-See :ref:`command-line-options` for a more general view over the |Coq| command
+See :ref:`command-line-options` for a more general view over the Coq command
line options.
diff --git a/doc/sphinx/language/core/primitive.rst b/doc/sphinx/language/core/primitive.rst
index 48647deeff..4505fc4b4d 100644
--- a/doc/sphinx/language/core/primitive.rst
+++ b/doc/sphinx/language/core/primitive.rst
@@ -46,7 +46,7 @@ applications of these primitive operations.
The extraction of these primitives can be customized similarly to the extraction
of regular axioms (see :ref:`extraction`). Nonetheless, the :g:`ExtrOCamlInt63`
module can be used when extracting to OCaml: it maps the Coq primitives to types
-and functions of a :g:`Uint63` module. Said OCaml module is not produced by
+and functions of a :g:`Uint63` module. That OCaml module is not produced by
extraction. Instead, it has to be provided by the user (if they want to compile
or execute the extracted code). For instance, an implementation of this module
can be taken from the kernel of Coq.
diff --git a/doc/sphinx/language/core/records.rst b/doc/sphinx/language/core/records.rst
index b2099b8636..e6df3ee9f5 100644
--- a/doc/sphinx/language/core/records.rst
+++ b/doc/sphinx/language/core/records.rst
@@ -18,7 +18,7 @@ expressions. In this sense, the :cmd:`Record` construction allows defining
.. insertprodn record_definition field_def
.. prodn::
- record_definition ::= {? > } @ident_decl {* @binder } {? : @type } {? @ident } %{ {*; @record_field } {? ; } %} {? @decl_notations }
+ record_definition ::= {? > } @ident_decl {* @binder } {? : @sort } {? := {? @ident } %{ {*; @record_field } {? ; } %} }
record_field ::= {* #[ {*, @attribute } ] } @name {? @field_body } {? %| @natural } {? @decl_notations }
field_body ::= {* @binder } @of_type
| {* @binder } @of_type := @term
@@ -26,19 +26,28 @@ expressions. In this sense, the :cmd:`Record` construction allows defining
term_record ::= %{%| {*; @field_def } {? ; } %|%}
field_def ::= @qualid {* @binder } := @term
-
Each :n:`@record_definition` defines a record named by :n:`@ident_decl`.
The constructor name is given by :n:`@ident`.
If the constructor name is not specified, then the default name :n:`Build_@ident` is used,
where :n:`@ident` is the record name.
- If :n:`@type` is
- omitted, the default type is :math:`\Type`. The identifiers inside the brackets are the field names.
- The type of each field :n:`@ident` is :n:`forall {* @binder }, @type`.
+ If :token:`sort` is omitted, the default sort is Type.
Notice that the type of an identifier can depend on a previously-given identifier. Thus the
order of the fields is important. :n:`@binder` parameters may be applied to the record as a whole
or to individual fields.
+ .. todo
+ "Record foo2:Prop := { a }." gives the error "Cannot infer this placeholder of type "Type",
+ while "Record foo2:Prop := { a:Type }." gives the output "foo2 is defined.
+ a cannot be defined because it is informative and foo2 is not."
+ Your thoughts?
+
+ :n:`{? > }`
+ If provided, the constructor name is automatically declared as
+ a coercion from the class of the last field type to the record name
+ (this may fail if the uniform inheritance condition is not
+ satisfied). See :ref:`coercions`.
+
Notations can be attached to fields using the :n:`@decl_notations` annotation.
:cmd:`Record` and :cmd:`Structure` are synonyms.
@@ -76,7 +85,7 @@ Let us now see the work done by the ``Record`` macro. First the macro
generates a variant type definition with just one constructor:
:n:`Variant @ident {* @binder } : @sort := @ident__0 {* @binder }`.
-To build an object of type :token:`ident`, one should provide the constructor
+To build an object of type :token:`ident`, provide the constructor
:n:`@ident__0` with the appropriate number of terms filling the fields of the record.
.. example::
diff --git a/doc/sphinx/language/core/variants.rst b/doc/sphinx/language/core/variants.rst
index 2904250e41..645986be9c 100644
--- a/doc/sphinx/language/core/variants.rst
+++ b/doc/sphinx/language/core/variants.rst
@@ -29,6 +29,7 @@ Private (matching) inductive types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. attr:: private(matching)
+ :name: private(matching); Private
This attribute can be used to forbid the use of the :g:`match`
construct on objects of this inductive type outside of the module
diff --git a/doc/sphinx/language/extensions/arguments-command.rst b/doc/sphinx/language/extensions/arguments-command.rst
index 0ae9fab7ab..2460461ede 100644
--- a/doc/sphinx/language/extensions/arguments-command.rst
+++ b/doc/sphinx/language/extensions/arguments-command.rst
@@ -86,6 +86,7 @@ Setting properties of a function's arguments
the parameter name used in the function definition). Unless `rename` is specified,
the list of :n:`@name`\s must be a prefix of the formal parameters, including all implicit
arguments. `_` can be used to skip over a formal parameter.
+ The construct :n:`@name {? % @scope }` declares :n:`@name` as non-implicit if `clear implicits` is specified or at least one other name is declared implicit in the same list of :n:`@name`\s.
:token:`scope` can be either a scope name or its delimiting key. See :ref:`binding_to_scope`.
`clear implicits`
@@ -181,7 +182,7 @@ Manual declaration of implicit arguments
Automatic declaration of implicit arguments
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The ":n:`default implicits`" :token:`args_modifier` clause tells |Coq| to automatically determine the
+ The ":n:`default implicits`" :token:`args_modifier` clause tells Coq to automatically determine the
implicit arguments of the object.
Auto-detection is governed by flags specifying whether strict,
diff --git a/doc/sphinx/language/extensions/canonical.rst b/doc/sphinx/language/extensions/canonical.rst
index bfda8befff..48120503af 100644
--- a/doc/sphinx/language/extensions/canonical.rst
+++ b/doc/sphinx/language/extensions/canonical.rst
@@ -196,7 +196,7 @@ We amend that by equipping ``nat`` with a comparison relation.
Check 3 == 3.
Eval compute in 3 == 4.
-This last test shows that |Coq| is now not only able to type check ``3 == 3``,
+This last test shows that Coq is now not only able to type check ``3 == 3``,
but also that the infix relation was bound to the ``nat_eq`` relation.
This relation is selected whenever ``==`` is used on terms of type nat.
This can be read in the line declaring the canonical structure
@@ -223,7 +223,7 @@ example work:
Fail Check forall (e : EQ.type) (a b : EQ.obj e), (a, b) == (a, b).
-The error message is telling that |Coq| has no idea on how to compare
+The error message is telling that Coq has no idea on how to compare
pairs of objects. The following construction is telling Coq exactly
how to do that.
@@ -241,7 +241,7 @@ how to do that.
Check forall n m : nat, (3, 4) == (n, m).
-Thanks to the ``pair_EQty`` declaration, |Coq| is able to build a comparison
+Thanks to the ``pair_EQty`` declaration, Coq is able to build a comparison
relation for pairs whenever it is able to build a comparison relation
for each component of the pair. The declaration associates to the key ``*``
(the type constructor of pairs) the canonical comparison
@@ -290,7 +290,7 @@ As before we register a canonical ``LE`` class for ``nat``.
Canonical Structure nat_LEty : LE.type := LE.Pack nat nat_LEcl.
-And we enable |Coq| to relate pair of terms with ``<=``.
+And we enable Coq to relate pair of terms with ``<=``.
.. coqtop:: all
@@ -355,10 +355,10 @@ theory of this new class.
The problem is that the two classes ``LE`` and ``LEQ`` are not yet related by
-a subclass relation. In other words |Coq| does not see that an object of
+a subclass relation. In other words Coq does not see that an object of
the ``LEQ`` class is also an object of the ``LE`` class.
-The following two constructions tell |Coq| how to canonically build the
+The following two constructions tell Coq how to canonically build the
``LE.type`` and ``EQ.type`` structure given an ``LEQ.type`` structure on the same
type.
@@ -413,7 +413,7 @@ setting to any concrete instate of the algebraic structure.
Abort.
-Again one has to tell |Coq| that the type ``nat`` is in the ``LEQ`` class, and
+Again one has to tell Coq that the type ``nat`` is in the ``LEQ`` class, and
how the type constructor ``*`` interacts with the ``LEQ`` class. In the
following proofs are omitted for brevity.
@@ -468,7 +468,7 @@ Note that no direct proof of ``n <= m -> m <= n -> n == m`` is provided by
the user for ``n`` and m of type ``nat * nat``. What the user provides is a
proof of this statement for ``n`` and ``m`` of type ``nat`` and a proof that the
pair constructor preserves this property. The combination of these two
-facts is a simple form of proof search that |Coq| performs automatically
+facts is a simple form of proof search that Coq performs automatically
while inferring canonical structures.
Compact declaration of Canonical Structures
@@ -507,7 +507,7 @@ instances: ``[find e | EQ.obj e ~ T | "is not an EQ.type" ]``. It should be
read as: “find a class e such that its objects have type T or fail
with message "T is not an EQ.type"”.
-The other utilities are used to ask |Coq| to solve a specific unification
+The other utilities are used to ask Coq to solve a specific unification
problem, that will in turn require the inference of some canonical structures.
They are explained in more details in :cite:`CSwcu`.
@@ -532,7 +532,7 @@ The object ``Pack`` takes a type ``T`` (the key) and a mixin ``m``. It infers al
the other pieces of the class ``LEQ`` and declares them as canonical
values associated to the ``T`` key. All in all, the only new piece of
information we add in the ``LEQ`` class is the mixin, all the rest is
-already canonical for ``T`` and hence can be inferred by |Coq|.
+already canonical for ``T`` and hence can be inferred by Coq.
``Pack`` is a notation, hence it is not type checked at the time of its
declaration. It will be type checked when it is used, an in that case ``T`` is
diff --git a/doc/sphinx/language/extensions/evars.rst b/doc/sphinx/language/extensions/evars.rst
index 20f4310d13..fd9695e270 100644
--- a/doc/sphinx/language/extensions/evars.rst
+++ b/doc/sphinx/language/extensions/evars.rst
@@ -13,7 +13,7 @@ Existential variables
| ?[ ?@ident ]
| ?@ident {? @%{ {+; @ident := @term } %} }
-|Coq| terms can include existential variables that represent unknown
+Coq terms can include existential variables that represent unknown
subterms that are eventually replaced with actual subterms.
Existential variables are generated in place of unsolved implicit
diff --git a/doc/sphinx/language/extensions/implicit-arguments.rst b/doc/sphinx/language/extensions/implicit-arguments.rst
index f8375e93ce..23ba5f703a 100644
--- a/doc/sphinx/language/extensions/implicit-arguments.rst
+++ b/doc/sphinx/language/extensions/implicit-arguments.rst
@@ -146,7 +146,7 @@ by replacing it with `_`.
.. exn:: Cannot infer a term for this placeholder.
:name: Cannot infer a term for this placeholder. (Casual use of implicit arguments)
- |Coq| was not able to deduce an instantiation of a “_”.
+ Coq was not able to deduce an instantiation of a “_”.
.. _declare-implicit-args:
@@ -290,8 +290,8 @@ Controlling contextual implicit arguments
.. flag:: Contextual Implicit
- By default, |Coq| does not automatically set implicit the contextual
- implicit arguments. You can turn this flag on to tell |Coq| to also
+ By default, Coq does not automatically set implicit the contextual
+ implicit arguments. You can turn this flag on to tell Coq to also
infer contextual implicit argument.
.. _controlling-rev-pattern-implicit-args:
@@ -301,8 +301,8 @@ Controlling reversible-pattern implicit arguments
.. flag:: Reversible Pattern Implicit
- By default, |Coq| does not automatically set implicit the reversible-pattern
- implicit arguments. You can turn this flag on to tell |Coq| to also infer
+ By default, Coq does not automatically set implicit the reversible-pattern
+ implicit arguments. You can turn this flag on to tell Coq to also infer
reversible-pattern implicit argument.
.. _controlling-insertion-implicit-args:
diff --git a/doc/sphinx/language/extensions/match.rst b/doc/sphinx/language/extensions/match.rst
index c36b9deef3..8e62c2af13 100644
--- a/doc/sphinx/language/extensions/match.rst
+++ b/doc/sphinx/language/extensions/match.rst
@@ -5,7 +5,7 @@ Extended pattern matching
:Authors: Cristina Cornes and Hugo Herbelin
-This section describes the full form of pattern matching in |Coq| terms.
+This section describes the full form of pattern matching in Coq terms.
.. |rhs| replace:: right hand sides
@@ -86,6 +86,13 @@ Pattern-matching on terms inhabiting inductive type having only one
constructor can be alternatively written using :g:`let … in …`
constructions. There are two variants of them.
+.. insertprodn destructuring_let destructuring_let
+
+.. prodn::
+ destructuring_let ::= let ( {*, @name } ) {? {? as @name } return @term100 } := @term in @term
+ | let ' @pattern := @term {? return @term100 } in @term
+ | let ' @pattern in @pattern := @term return @term100 in @term
+
First destructuring let syntax
++++++++++++++++++++++++++++++
@@ -187,10 +194,10 @@ Printing nested patterns
pattern matching into a single pattern matching over a nested
pattern.
- When this flag is on (default), |Coq|’s printer tries to do such
+ When this flag is on (default), Coq’s printer tries to do such
limited re-factorization.
- Turning it off tells |Coq| to print only simple pattern matching problems
- in the same way as the |Coq| kernel handles them.
+ Turning it off tells Coq to print only simple pattern matching problems
+ in the same way as the Coq kernel handles them.
Factorization of clauses with same right-hand side
@@ -200,7 +207,7 @@ Factorization of clauses with same right-hand side
When several patterns share the same right-hand side, it is additionally
possible to share the clauses using disjunctive patterns. Assuming that the
- printing matching mode is on, this flag (on by default) tells |Coq|'s
+ printing matching mode is on, this flag (on by default) tells Coq's
printer to try to do this kind of factorization.
Use of a default clause
@@ -212,7 +219,7 @@ Use of a default clause
arguments of the patterns, yet an extra factorization is possible: the
disjunction of patterns can be replaced with a `_` default clause. Assuming that
the printing matching mode and the factorization mode are on, this flag (on by
- default) tells |Coq|'s printer to use a default clause when relevant.
+ default) tells Coq's printer to use a default clause when relevant.
Printing of wildcard patterns
++++++++++++++++++++++++++++++
@@ -234,7 +241,7 @@ Printing of the elimination predicate
In most of the cases, the type of the result of a matched term is
mechanically synthesizable. Especially, if the result type does not
depend of the matched term. When this flag is on (default),
- the result type is not printed when |Coq| knows that it can re-
+ the result type is not printed when Coq knows that it can re-
synthesize it.
@@ -290,6 +297,43 @@ This example emphasizes what the printing settings offer.
Print snd.
+Conventions about unused pattern-matching variables
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Pattern-matching variables that are not used on the right-hand side of ``=>`` are
+considered the sign of a potential error. For instance, it could
+result from an undetected mispelled constant constructor. By default,
+a warning is issued in such situations.
+
+.. warn:: Unused variable @ident catches more than one case.
+
+ This indicates that an unused pattern variable :token:`ident`
+ occurs in a pattern-matching clause used to complete at least two
+ cases of the pattern-matching problem.
+
+ The warning can be deactivated by using a variable name starting
+ with ``_`` or by setting ``Set Warnings
+ "-unused-pattern-matching-variable"``.
+
+ Here is an example where the warning is activated.
+
+ .. example::
+
+ .. coqtop:: none
+
+ Set Warnings "-unused-pattern-matching-variable".
+
+ .. coqtop:: all
+
+ Definition is_zero (o : option nat) := match o with
+ | Some 0 => true
+ | x => false
+ end.
+
+ .. coqtop:: none
+
+ Set Warnings "+unused-pattern-matching-variable".
+
Patterns
--------
diff --git a/doc/sphinx/practical-tools/coq-commands.rst b/doc/sphinx/practical-tools/coq-commands.rst
index ec182ce08f..d20a82e6c0 100644
--- a/doc/sphinx/practical-tools/coq-commands.rst
+++ b/doc/sphinx/practical-tools/coq-commands.rst
@@ -1,13 +1,13 @@
.. _thecoqcommands:
-The |Coq| commands
+The Coq commands
====================
-There are three |Coq| commands:
+There are three Coq commands:
-+ ``coqtop``: the |Coq| toplevel (interactive mode);
-+ ``coqc``: the |Coq| compiler (batch compilation);
-+ ``coqchk``: the |Coq| checker (validation of compiled libraries).
++ ``coqtop``: the Coq toplevel (interactive mode);
++ ``coqc``: the Coq compiler (batch compilation);
++ ``coqchk``: the Coq checker (validation of compiled libraries).
The options are (basically) the same for the first two commands, and
@@ -19,11 +19,11 @@ roughly described below. You can also look at the ``man`` pages of
Interactive use (coqtop)
------------------------
-In the interactive mode, also known as the |Coq| toplevel, the user can
-develop his theories and proofs step by step. The |Coq| toplevel is run
+In the interactive mode, also known as the Coq toplevel, the user can
+develop his theories and proofs step by step. The Coq toplevel is run
by the command ``coqtop``.
-There are two different binary images of |Coq|: the byte-code one and the
+There are two different binary images of Coq: the byte-code one and the
native-code one (if OCaml provides a native-code compiler for
your platform, which is supposed in the following). By default,
``coqtop`` executes the native-code version; run ``coqtop.byte`` to get
@@ -31,7 +31,7 @@ the byte-code version.
The byte-code toplevel is based on an OCaml toplevel (to
allow dynamic linking of tactics). You can switch to the OCaml toplevel
-with the command ``Drop.``, and come back to the |Coq|
+with the command ``Drop.``, and come back to the Coq
toplevel with the command ``Coqloop.loop();;``.
.. flag:: Coqtop Exit On Error
@@ -48,7 +48,7 @@ vernacular file named *file*.v, and tries to compile it into a
.. caution::
- The name *file* should be a regular |Coq| identifier as defined in Section :ref:`lexical-conventions`.
+ The name *file* should be a regular Coq identifier as defined in Section :ref:`lexical-conventions`.
It should contain only letters, digits or underscores (_). For example ``/bar/foo/toto.v`` is valid,
but ``/bar/foo/to-to.v`` is not.
@@ -59,7 +59,7 @@ Customization at launch time
By resource file
~~~~~~~~~~~~~~~~~~~~~~~
-When |Coq| is launched, with either ``coqtop`` or ``coqc``, the
+When Coq is launched, with either ``coqtop`` or ``coqc``, the
resource file ``$XDG_CONFIG_HOME/coq/coqrc.xxx``, if it exists, will
be implicitly prepended to any document read by Coq, whether it is an
interactive session or a file to compile. Here, ``$XDG_CONFIG_HOME``
@@ -73,7 +73,7 @@ You can also specify an arbitrary name for the resource file
(see option ``-init-file`` below).
The resource file may contain, for instance, ``Add LoadPath`` commands to add
-directories to the load path of |Coq|. It is possible to skip the
+directories to the load path of Coq. It is possible to skip the
loading of the resource file with the option ``-q``.
.. _customization-by-environment-variables:
@@ -82,10 +82,10 @@ By environment variables
~~~~~~~~~~~~~~~~~~~~~~~~~
``$COQPATH`` can be used to specify the load path. It is a list of directories separated by
-``:`` (``;`` on Windows). |Coq| will also honor ``$XDG_DATA_HOME`` and
+``:`` (``;`` on Windows). Coq will also honor ``$XDG_DATA_HOME`` and
``$XDG_DATA_DIRS`` (see Section :ref:`libraries-and-filesystem`).
-Some |Coq| commands call other |Coq| commands. In this case, they look for
+Some Coq commands call other Coq commands. In this case, they look for
the commands in directory specified by ``$COQBIN``. If this variable is
not set, they look for the commands in the executable path.
@@ -115,7 +115,7 @@ can be used to specify certain runtime and memory usage parameters. In most cas
experimenting with these settings will likely not cause a significant performance difference
and should be harmless.
-If the variable is not set, |Coq| uses the
+If the variable is not set, Coq uses the
`default values <https://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html#TYPEcontrol>`_,
except that ``space_overhead`` is set to 120 and ``minor_heap_size`` is set to 32Mwords
(256MB with 64-bit executables or 128MB with 32-bit executables).
@@ -140,14 +140,14 @@ and ``coqtop``, unless stated otherwise:
:ref:`names-of-libraries` and the
command Declare ML Module Section :ref:`compiled-files`.
:-Q *directory* *dirpath*: Add physical path *directory* to the list of
- directories where |Coq| looks for a file and bind it to the logical
+ directories where Coq looks for a file and bind it to the logical
directory *dirpath*. The subdirectory structure of *directory* is
- recursively available from |Coq| using absolute names (extending the
+ recursively available from Coq using absolute names (extending the
:n:`@dirpath` prefix) (see Section :ref:`qualified-names`). Note that only those
subdirectories and files which obey the lexical conventions of what is
an :n:`@ident` are taken into account. Conversely, the
underlying file systems or operating systems may be more restrictive
- than |Coq|. While Linux’s ext4 file system supports any |Coq| recursive
+ than Coq. While Linux’s ext4 file system supports any Coq recursive
layout (within the limit of 255 bytes per filename), the default on
NTFS (Windows) or HFS+ (MacOS X) file systems is on the contrary to
disallow two files differing only in the case in the same directory.
@@ -155,7 +155,7 @@ and ``coqtop``, unless stated otherwise:
.. seealso:: Section :ref:`names-of-libraries`.
:-R *directory* *dirpath*: Do as ``-Q`` *directory* *dirpath* but make the
subdirectory structure of *directory* recursively visible so that the
- recursive contents of physical *directory* is available from |Coq| using
+ recursive contents of physical *directory* is available from Coq using
short or partially qualified names.
.. seealso:: Section :ref:`names-of-libraries`.
@@ -172,12 +172,12 @@ and ``coqtop``, unless stated otherwise:
loading the default resource file from the standard configuration
directories.
:-q: Do not to load the default resource file.
-:-l *file*, -load-vernac-source *file*: Load and execute the |Coq|
+:-l *file*, -load-vernac-source *file*: Load and execute the Coq
script from *file.v*.
:-lv *file*, -load-vernac-source-verbose *file*: Load and execute the
- |Coq| script from *file.v*. Write its contents to the standard output as
+ Coq script from *file.v*. Write its contents to the standard output as
it is executed.
-:-load-vernac-object *qualid*: Load |Coq| compiled library :n:`@qualid`. This
+:-load-vernac-object *qualid*: Load Coq compiled library :n:`@qualid`. This
is equivalent to running :cmd:`Require` :n:`@qualid`.
.. _interleave-command-line:
@@ -191,27 +191,27 @@ and ``coqtop``, unless stated otherwise:
:cmd:`Unset` commands will be executed in the order specified on
the command-line.
-:-rfrom *dirpath* *qualid*: Load |Coq| compiled library :n:`@qualid`.
+:-rfrom *dirpath* *qualid*: Load Coq compiled library :n:`@qualid`.
This is equivalent to running :cmd:`From <From … Require>`
:n:`@dirpath` :cmd:`Require <From … Require>` :n:`@qualid`.
See the :ref:`note above <interleave-command-line>` regarding the order
of command-line options.
-:-ri *qualid*, -require-import *qualid*: Load |Coq| compiled library :n:`@qualid` and import it.
+:-ri *qualid*, -require-import *qualid*: Load Coq compiled library :n:`@qualid` and import it.
This is equivalent to running :cmd:`Require Import` :n:`@qualid`.
See the :ref:`note above <interleave-command-line>` regarding the order
of command-line options.
-:-re *qualid*, -require-export *qualid*: Load |Coq| compiled library :n:`@qualid` and transitively import it.
+:-re *qualid*, -require-export *qualid*: Load Coq compiled library :n:`@qualid` and transitively import it.
This is equivalent to running :cmd:`Require Export` :n:`@qualid`.
See the :ref:`note above <interleave-command-line>` regarding the order
of command-line options.
:-rifrom *dirpath* *qualid*, -require-import-from *dirpath* *qualid*:
- Load |Coq| compiled library :n:`@qualid` and import it. This is
+ Load Coq compiled library :n:`@qualid` and import it. This is
equivalent to running :cmd:`From <From … Require>` :n:`@dirpath`
:cmd:`Require Import <From … Require>` :n:`@qualid`. See the
:ref:`note above <interleave-command-line>` regarding the order of
command-line options.
:-refrom *dirpath* *qualid*, -require-export-from *dirpath* *qualid*:
- Load |Coq| compiled library :n:`@qualid` and transitively import it.
+ Load Coq compiled library :n:`@qualid` and transitively import it.
This is equivalent to running :cmd:`From <From … Require>`
:n:`@dirpath` :cmd:`Require Export <From … Require>` :n:`@qualid`.
See the :ref:`note above <interleave-command-line>` regarding the
@@ -219,11 +219,11 @@ and ``coqtop``, unless stated otherwise:
:-batch: Exit just after argument parsing. Available for ``coqtop`` only.
:-verbose: Output the content of the input file as it is compiled.
This option is available for ``coqc`` only.
-:-vos: Indicate |Coq| to skip the processing of opaque proofs
+:-vos: Indicate Coq to skip the processing of opaque proofs
(i.e., proofs ending with :cmd:`Qed` or :cmd:`Admitted`), output a ``.vos`` files
instead of a ``.vo`` file, and to load ``.vos`` files instead of ``.vo`` files
when interpreting :cmd:`Require` commands.
-:-vok: Indicate |Coq| to check a file completely, to load ``.vos`` files instead
+:-vok: Indicate Coq to check a file completely, to load ``.vos`` files instead
of ``.vo`` files when interpreting :cmd:`Require` commands, and to output an empty
``.vok`` files upon success instead of writing a ``.vo`` file.
:-w (all|none|w₁,…,wₙ): Configure the display of warnings. This
@@ -241,7 +241,7 @@ and ``coqtop``, unless stated otherwise:
syntax/definitions/notations.
:-emacs, -ide-slave: Start a special toplevel to communicate with a
specific IDE.
-:-impredicative-set: Change the logical theory of |Coq| by declaring the
+:-impredicative-set: Change the logical theory of Coq by declaring the
sort :g:`Set` impredicative.
.. warning::
@@ -249,7 +249,7 @@ and ``coqtop``, unless stated otherwise:
This is known to be inconsistent with some
standard axioms of classical mathematics such as the functional
axiom of choice or the principle of description.
-:-type-in-type: Collapse the universe hierarchy of |Coq|.
+:-type-in-type: Collapse the universe hierarchy of Coq.
.. warning:: This makes the logic inconsistent.
:-mangle-names *ident*: *Experimental.* Do not depend on this option. Replace
@@ -285,16 +285,16 @@ and ``coqtop``, unless stated otherwise:
:-no-glob: Disable the dumping of references for global names.
:-image *file*: Set the binary image to be used by ``coqc`` to be *file*
instead of the standard one. Not of general use.
-:-bindir *directory*: Set the directory containing |Coq| binaries to be
+:-bindir *directory*: Set the directory containing Coq binaries to be
used by ``coqc``. It is equivalent to doing export COQBIN= *directory*
before launching ``coqc``.
-:-where: Print the location of |Coq|’s standard library and exit.
-:-config: Print the locations of |Coq|’s binaries, dependencies, and
+:-where: Print the location of Coq’s standard library and exit.
+:-config: Print the locations of Coq’s binaries, dependencies, and
libraries, then exit.
:-filteropts: Print the list of command line arguments that `coqtop` has
recognized as options and exit.
-:-v: Print |Coq|’s version and exit.
-:-list-tags: Print the highlight tags known by |Coq| as well as their
+:-v: Print Coq’s version and exit.
+:-list-tags: Print the highlight tags known by Coq as well as their
currently associated color and exit.
:-h, --help: Print a short usage and exit.
@@ -401,7 +401,7 @@ within a section.
.. warn:: You should use the “Proof using [...].” syntax instead of “Proof.” to enable skipping this proof which is located inside a section. Give as argument to “Proof using” the list of section variables that are not needed to typecheck the statement but that are required by the proof.
- If |Coq| is invoked using the ``-vos`` option, whenever it finds the
+ If Coq is invoked using the ``-vos`` option, whenever it finds the
command ``Proof.`` inside a section, it will compile the proof, that is,
refuse to skip it, and it will raise a warning. To disable the warning, one
may pass the flag ``-w -proof-without-using-in-section``.
@@ -412,7 +412,7 @@ When compiling a file ``foo.v`` using ``coqc`` in the standard way (i.e., withou
``-vos`` nor ``-vok``), an empty file ``foo.vos`` and an empty file ``foo.vok``
are created in addition to the regular output file ``foo.vo``.
If ``coqc`` is subsequently invoked on some other file ``bar.v`` using option
-``-vos`` or ``-vok``, and that ``bar.v`` requires ``foo.v``, if |Coq| finds an
+``-vos`` or ``-vok``, and that ``bar.v`` requires ``foo.v``, if Coq finds an
empty file ``foo.vos``, then it will load ``foo.vo`` instead of ``foo.vos``.
The purpose of this feature is to allow users to benefit from the ``-vos``
diff --git a/doc/sphinx/practical-tools/coqide.rst b/doc/sphinx/practical-tools/coqide.rst
index 42e752841d..c239797cc2 100644
--- a/doc/sphinx/practical-tools/coqide.rst
+++ b/doc/sphinx/practical-tools/coqide.rst
@@ -2,7 +2,7 @@
.. _coqintegrateddevelopmentenvironment:
-|Coq| Integrated Development Environment
+Coq Integrated Development Environment
========================================
The Coq Integrated Development Environment is a graphical tool, to be
@@ -10,19 +10,19 @@ used as a user-friendly replacement to `coqtop`. Its main purpose is to
allow the user to navigate forward and backward into a Coq vernacular
file, executing corresponding commands or undoing them respectively.
-|CoqIDE| is run by typing the command `coqide` on the command line.
+CoqIDE is run by typing the command `coqide` on the command line.
Without argument, the main screen is displayed with an “unnamed
buffer”, and with a filename as argument, another buffer displaying
the contents of that file. Additionally, `coqide` accepts the same
options as `coqtop`, given in :ref:`thecoqcommands`, the ones having obviously
-no meaning for |CoqIDE| being ignored.
+no meaning for CoqIDE being ignored.
.. _coqide_mainscreen:
.. image:: ../_static/coqide.png
- :alt: |CoqIDE| main screen
+ :alt: CoqIDE main screen
-A sample |CoqIDE| main screen, while navigating into a file `Fermat.v`,
+A sample CoqIDE main screen, while navigating into a file `Fermat.v`,
is shown in the figure :ref:`CoqIDE main screen <coqide_mainscreen>`.
At the top is a menu bar, and a tool bar
below it. The large window on the left is displaying the various
@@ -43,7 +43,7 @@ is the one where Coq commands are currently executed.
Buffers may be edited as in any text editor, and classical basic
editing commands (Copy/Paste, …) are available in the *Edit* menu.
-|CoqIDE| offers only basic editing commands, so if you need more complex
+CoqIDE offers only basic editing commands, so if you need more complex
editing commands, you may launch your favorite text editor on the
current buffer, using the *Edit/External Editor* menu.
@@ -74,7 +74,7 @@ and use the goto button. Unlike with `coqtop`, you should never use
There are two additional buttons for navigation within the running buffer. The
"down" button with a line goes directly to the end; the "up" button with a line
goes back to the beginning. The handling of errors when using the go-to-the-end
-button depends on whether |Coq| is running in asynchronous mode or not (see
+button depends on whether Coq is running in asynchronous mode or not (see
Chapter :ref:`asynchronousandparallelproofprocessing`). If it is not running in that mode, execution
stops as soon as an error is found. Otherwise, execution continues, and the
error is marked with an underline in the error foreground color, with a
@@ -86,12 +86,12 @@ If you ever try to execute a command that runs for a long time
and would like to abort it before it terminates, you may
use the interrupt button (the white cross on a red circle).
-There are other buttons on the |CoqIDE| toolbar: a button to save the running
+There are other buttons on the CoqIDE toolbar: a button to save the running
buffer; a button to close the current buffer (an "X"); buttons to switch among
buffers (left and right arrows); an "information" button; and a "gears" button.
-The "gears" button submits proof terms to the |Coq| kernel for type checking.
-When |Coq| uses asynchronous processing (see Chapter :ref:`asynchronousandparallelproofprocessing`),
+The "gears" button submits proof terms to the Coq kernel for type checking.
+When Coq uses asynchronous processing (see Chapter :ref:`asynchronousandparallelproofprocessing`),
proofs may have been completed without kernel-checking of generated proof terms.
The presence of unchecked proof terms is indicated by ``Qed`` statements that
have a subdued *being-processed* color (light blue by default), rather than the
@@ -114,11 +114,11 @@ Queries
------------
.. image:: ../_static/coqide-queries.png
- :alt: |CoqIDE| queries
+ :alt: CoqIDE queries
We call *query* any vernacular command that does not change the current state,
such as ``Check``, ``Search``, etc. To run such commands interactively, without
-writing them in scripts, |CoqIDE| offers a *query pane*. The query pane can be
+writing them in scripts, CoqIDE offers a *query pane*. The query pane can be
displayed on demand by using the ``View`` menu, or using the shortcut ``F1``.
Queries can also be performed by selecting a particular phrase, then choosing an
item from the ``Queries`` menu. The response then appears in the message window.
@@ -148,12 +148,12 @@ The first section is for selecting the text font used for scripts,
goal and message windows.
The second and third sections are for controlling colors and style of
-the three main buffers. A predefined |Coq| highlighting style as well
+the three main buffers. A predefined Coq highlighting style as well
as standard |GtkSourceView| styles are available. Other styles can be
added e.g. in ``$HOME/.local/share/gtksourceview-3.0/styles/`` (see
the general documentation about |GtkSourceView| for the various
possibilities). Note that the style of the rest of graphical part of
-Coqide is not under the control of |GtkSourceView| but of GTK+ and
+CoqIDE is not under the control of |GtkSourceView| but of GTK+ and
governed by files such as ``settings.ini`` and ``gtk.css`` in
``$XDG_CONFIG_HOME/gtk-3.0`` or files in
``$HOME/.themes/NameOfTheme/gtk-3.0``, as well as the environment
@@ -169,7 +169,7 @@ 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
-third party, |CoqIDE| may read it again for you. Note that in the case
+third party, CoqIDE may read it again for you. Note that in the case
you edited that same file, you will be prompted to choose to either
discard your changes or not. The File charset encoding choice is
described below in :ref:`character-encoding-saved-files`.
@@ -196,9 +196,9 @@ still edit this configuration file by hand, but this is more involved.
Using Unicode symbols
--------------------------
-|CoqIDE| is based on GTK+ and inherits from it support for Unicode in
+CoqIDE is based on GTK+ and inherits from it support for Unicode in
its text windows. Consequently a large set of symbols is available for
-notations. Furthermore, |CoqIDE| conveniently provides a simple way to
+notations. Furthermore, CoqIDE conveniently provides a simple way to
input Unicode characters.
@@ -220,8 +220,8 @@ mathematical symbols ∀ and ∃, you may define:
There exists a small set of such notations already defined, in the
file `utf8.v` of Coq library, so you may enable them just by
-``Require Import Unicode.Utf8`` inside |CoqIDE|, or equivalently,
-by starting |CoqIDE| with ``coqide -l utf8``.
+``Require Import Unicode.Utf8`` inside CoqIDE, or equivalently,
+by starting CoqIDE with ``coqide -l utf8``.
However, there are some issues when using such Unicode symbols: you of
course need to use a character font which supports them. In the Fonts
@@ -255,7 +255,7 @@ Custom bindings may be added, as explained further on.
.. note::
It remains possible to input non-ASCII symbols using system-wide
- approaches independent of |CoqIDE|.
+ approaches independent of CoqIDE.
Adding custom bindings
@@ -286,7 +286,7 @@ Similarly, the above settings ensure than ``\l`` resolves to ``\le``,
and that ``\la`` resolves to ``\lambda``.
It can be useful to work with per-project binding files. For this purpose
-|CoqIDE| accepts a command line argument of the form
+CoqIDE accepts a command line argument of the form
``-unicode-bindings file1,file2,...,fileN``.
Each of the file tokens provided may consists of one of:
@@ -320,7 +320,7 @@ related to the way files are saved.
If you have no need to exchange files with non UTF-8 aware
applications, it is better to choose the UTF-8 encoding, since it
guarantees that your files will be read again without problems. (This
-is because when |CoqIDE| reads a file, it tries to automatically detect
+is because when CoqIDE reads a file, it tries to automatically detect
its character encoding.)
If you choose something else than UTF-8, then missing characters will
diff --git a/doc/sphinx/practical-tools/utilities.rst b/doc/sphinx/practical-tools/utilities.rst
index daae46ad11..ec3689bbbe 100644
--- a/doc/sphinx/practical-tools/utilities.rst
+++ b/doc/sphinx/practical-tools/utilities.rst
@@ -9,7 +9,7 @@ beside proof development, tactics writing or documentation.
Using Coq as a library
-----------------------
+------------------------
In previous versions, ``coqmktop`` was used to build custom
toplevels - for example for better debugging or custom static
@@ -34,7 +34,7 @@ For example, to statically link |Ltac|, you can just do:
and similarly for other plugins.
-Building a |Coq| project
+Building a Coq project
------------------------
As of today it is possible to build Coq projects using two tools:
@@ -44,11 +44,11 @@ As of today it is possible to build Coq projects using two tools:
.. _coq_makefile:
-Building a |Coq| project with coq_makefile
+Building a Coq project with coq_makefile
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The majority of |Coq| projects are very similar: a collection of ``.v``
-files and eventually some ``.ml`` ones (a |Coq| plugin). The main piece of
+The majority of Coq projects are very similar: a collection of ``.v``
+files and eventually some ``.ml`` ones (a Coq plugin). The main piece of
metadata needed in order to build the project are the command line
options to ``coqc`` (e.g. ``-R``, ``Q``, ``-I``, see :ref:`command
line options <command-line-options>`). Collecting the list of files
@@ -74,11 +74,11 @@ to literally pass an argument ``foo`` to ``coqc``: in the
example, this allows to pass the two-word option ``-w all`` (see
:ref:`command line options <command-line-options>`).
-|CoqIDE|, Proof-General and VSCoq all
-understand ``_CoqProject`` files and can be used to invoke |Coq| with the desired options.
+CoqIDE, Proof-General and VSCoq all
+understand ``_CoqProject`` files and can be used to invoke Coq with the desired options.
The ``coq_makefile`` utility can be used to set up a build infrastructure
-for the |Coq| project based on makefiles. The recommended way of
+for the Coq project based on makefiles. The recommended way of
invoking ``coq_makefile`` is the following one:
::
@@ -91,14 +91,14 @@ Such command generates the following files:
CoqMakefile
is a makefile for ``GNU Make`` with targets to build the project
(e.g. generate .vo or .html files from .v or compile .ml* files)
- and install it in the ``user-contrib`` directory where the |Coq|
+ and install it in the ``user-contrib`` directory where the Coq
library is installed. Run ``make`` with the ``-f CoqMakefile``
option to use ``CoqMakefile``.
CoqMakefile.conf
contains make variables assignments that reflect
the contents of the ``_CoqProject`` file as well as the path relevant to
- |Coq|.
+ Coq.
An optional file ``CoqMakefile.local`` can be provided by the user in order to
@@ -111,11 +111,11 @@ The extensions of the files listed in ``_CoqProject`` is used in order to
decide how to build them. In particular:
-+ |Coq| files must use the ``.v`` extension
-+ |OCaml| files must use the ``.ml`` or ``.mli`` extension
-+ |OCaml| files that require pre processing for syntax
++ Coq files must use the ``.v`` extension
++ OCaml files must use the ``.ml`` or ``.mli`` extension
++ OCaml files that require pre processing for syntax
extensions (like ``VERNAC EXTEND``) must use the ``.mlg`` extension
-+ In order to generate a plugin one has to list all |OCaml|
++ In order to generate a plugin one has to list all OCaml
modules (i.e. ``Baz`` for ``baz.ml``) in a ``.mlpack`` file (or ``.mllib``
file).
@@ -145,7 +145,7 @@ Here we describe only few of them.
passed to the OCaml compiler on building or linking of modules. Eg:
``-package yojson``.
:CAMLFLAGS:
- can be used to specify additional flags to the |OCaml|
+ can be used to specify additional flags to the OCaml
compiler, like ``-bin-annot`` or ``-w``....
:OCAMLWARN:
it contains a default of ``-warn-error +a-3``, useful to modify
@@ -524,7 +524,7 @@ Precompiling for ``native_compute``
+++++++++++++++++++++++++++++++++++
To compile files for ``native_compute``, one can use the
-``-native-compiler yes`` option of |Coq|, for instance by putting the
+``-native-compiler yes`` option of Coq, for instance by putting the
following in a :ref:`coqmakefilelocal` file:
::
@@ -555,7 +555,7 @@ of installing the extra ``.coq-native`` directories.
This requires all dependencies to be themselves compiled with
``-native-compiler yes``.
-Building a |Coq| project with Dune
+Building a Coq project with Dune
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. note::
@@ -575,7 +575,7 @@ for your files. This involves adding a ``dune-project`` and
``pkg.opam`` file to the root (``pkg.opam`` can be empty or generated
by Dune itself), and then providing ``dune`` files in the directories
your ``.v`` files are placed. For the experimental version "0.1" of
-the Coq Dune language, |Coq| library stanzas look like:
+the Coq Dune language, Coq library stanzas look like:
.. code:: scheme
@@ -642,14 +642,14 @@ Computing Module dependencies
-----------------------------
In order to compute module dependencies (to be used by ``make`` or
-``dune``), |Coq| provides the ``coqdep`` tool.
+``dune``), Coq provides the ``coqdep`` tool.
-``coqdep`` computes inter-module dependencies for |Coq|
+``coqdep`` computes inter-module dependencies for Coq
programs, and prints the dependencies on the standard output in a
format readable by make. When a directory is given as argument, it is
recursively looked at.
-Dependencies of |Coq| modules are computed by looking at ``Require``
+Dependencies of Coq modules are computed by looking at ``Require``
commands (``Require``, ``Require Export``, ``Require Import``), but also at the
command ``Declare ML Module``.
@@ -659,20 +659,20 @@ Both Dune and ``coq_makefile`` use ``coqdep`` to compute the
dependencies among the files part of a Coq project.
Embedded Coq phrases inside |Latex| documents
----------------------------------------------
+-----------------------------------------------
When writing documentation about a proof development, one may want
-to insert |Coq| phrases inside a |Latex| document, possibly together
+to insert Coq phrases inside a |Latex| document, possibly together
with the corresponding answers of the system. We provide a mechanical
-way to process such |Coq| phrases embedded in |Latex| files: the ``coq-tex``
-filter. This filter extracts |Coq| phrases embedded in |Latex| files,
+way to process such Coq phrases embedded in |Latex| files: the ``coq-tex``
+filter. This filter extracts Coq phrases embedded in |Latex| files,
evaluates them, and insert the outcome of the evaluation after each
phrase.
-Starting with a file ``file.tex`` containing |Coq| phrases, the ``coq-tex``
+Starting with a file ``file.tex`` containing Coq phrases, the ``coq-tex``
filter produces a file named ``file.v.tex`` with the Coq outcome.
-There are options to produce the |Coq| parts in smaller font, italic,
+There are options to produce the Coq parts in smaller font, italic,
between horizontal rules, etc. See the man page of ``coq-tex`` for more
details.
diff --git a/doc/sphinx/proof-engine/ltac.rst b/doc/sphinx/proof-engine/ltac.rst
index f18569c7fd..6464f085b8 100644
--- a/doc/sphinx/proof-engine/ltac.rst
+++ b/doc/sphinx/proof-engine/ltac.rst
@@ -60,7 +60,7 @@ The constructs in :token:`ltac_expr` are :term:`left associative`.
ltac_expr3 ::= @l3_tactic
| @ltac_expr2
ltac_expr2 ::= @ltac_expr1 + {| @ltac_expr2 | @binder_tactic }
- | @ltac_expr1 || {| @ltac_expr2 | @binder_tactic }
+ | @ltac_expr1 %|| {| @ltac_expr2 | @binder_tactic }
| @l2_tactic
| @ltac_expr1
ltac_expr1 ::= @tactic_value
@@ -161,7 +161,7 @@ Syntactic values
Provides a way to use the syntax and semantics of a grammar nonterminal as a
value in an :token:`ltac_expr`. The table below describes the most useful of
these. You can see the others by running ":cmd:`Print Grammar` `tactic`" and
-examining the part at the end under "Entry tactic:tactic_arg".
+examining the part at the end under "Entry tactic:tactic_value".
:token:`ident`
name of a grammar nonterminal listed in the table
@@ -729,7 +729,7 @@ First tactic to make progress: ||
Yet another way of branching without backtracking is the following
structure:
-.. tacn:: @ltac_expr1 || {| @ltac_expr2 | @binder_tactic }
+.. tacn:: @ltac_expr1 %|| {| @ltac_expr2 | @binder_tactic }
:name: || (first tactic making progress)
:n:`@ltac_expr1 || @ltac_expr2` is
@@ -879,7 +879,8 @@ Print/identity tactic: idtac
.. tacn:: idtac {* {| @ident | @string | @natural } }
:name: idtac
- Leaves the proof unchanged and prints the given tokens. Strings and integers are printed
+ Leaves the proof unchanged and prints the given tokens. :token:`String<string>`\s
+ and :token:`natural`\s are printed
literally. If :token:`ident` is an |Ltac| variable, its contents are printed; if not, it
is an error.
@@ -888,7 +889,7 @@ Print/identity tactic: idtac
Failing
~~~~~~~
-.. tacn:: {| fail | gfail } {? @int_or_var } {* {| @ident | @string | @integer } }
+.. tacn:: {| fail | gfail } {? @int_or_var } {* {| @ident | @string | @natural } }
:name: fail; gfail
:tacn:`fail` is the always-failing tactic: it does not solve any
@@ -919,7 +920,7 @@ Failing
the call to :tacn:`fail` :n:`@natural` is not enclosed in a :n:`+` construct,
respecting the algebraic identity.
- :n:`{* {| @ident | @string | @integer } }`
+ :n:`{* {| @ident | @string | @natural } }`
The given tokens are used for printing the failure message. If :token:`ident`
is an |Ltac| variable, its contents are printed; if not, it is an error.
@@ -937,7 +938,7 @@ Failing
.. todo the example is too long; could show the Goal True. Proof. once and hide the Aborts
to shorten it. And add a line of text before each subexample. Perhaps add some very short
- explanations/generalizations (eg gfail always fails; "tac; fail" succeeds but "fail." alone
+ explanations/generalizations (e.g. gfail always fails; "tac; fail" succeeds but "fail." alone
fails.
.. coqtop:: reset all fail
@@ -1352,8 +1353,8 @@ Pattern matching on goals and hypotheses: match goal
.. insertprodn goal_pattern match_hyp
.. prodn::
- goal_pattern ::= {*, @match_hyp } |- @match_pattern
- | [ {*, @match_hyp } |- @match_pattern ]
+ goal_pattern ::= {*, @match_hyp } %|- @match_pattern
+ | [ {*, @match_hyp } %|- @match_pattern ]
| _
match_hyp ::= @name : @match_pattern
| @name := @match_pattern
@@ -1488,7 +1489,7 @@ Examples:
match_context_rule ::= [ {*, @match_hyp } |- @match_pattern ] => @ltac_expr
match_hyp ::= | @name := {? [ @match_pattern ] : } @match_pattern
-.. todo PR The following items (up to numgoals) are part of "value_tactic". I'd like to make
+.. todo The following items (up to numgoals) are part of "value_tactic". I'd like to make
this a subsection and explain that they all return values. How do I get a 5th-level section title?
Filling a term context
@@ -1522,7 +1523,7 @@ produce subgoals but generates a term to be used in tactic expressions:
Generating fresh hypothesis names
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Tactics sometimes need to generate new names for hypothesis. Letting |Coq|
+Tactics sometimes need to generate new names for hypothesis. Letting Coq
choose a name with the intro tactic is not so good since it is
very awkward to retrieve that name. The following
expression returns an identifier:
@@ -1729,6 +1730,8 @@ Defining |Ltac| symbols
|Ltac| toplevel definitions are made as follows:
+.. index:: ::=
+
.. cmd:: Ltac @tacdef_body {* with @tacdef_body }
:name: Ltac
@@ -1753,10 +1756,15 @@ Defining |Ltac| symbols
Defines a user-defined symbol, but gives an error if the symbol has already
been defined.
-.. todo apparent inconsistency: "Ltac intros := idtac" seems like it redefines/hides an existing tactic,
- but in fact it creates a tactic which can only be called by it's qualified name. This is true in general
- of tactic notations. The only way to overwrite most primitive tactics, and any user-defined tactic
- notation, is with another tactic notation.
+ .. todo apparent inconsistency:
+
+ "Ltac intros := idtac" seems like it redefines/hides an
+ existing tactic, but in fact it creates a tactic which can
+ only be called by its qualified name. This is true in
+ general of tactic notations. The only way to overwrite most
+ primitive tactics, and any user-defined tactic notation, is
+ with another tactic notation.
+
.. exn:: There is already an Ltac named @qualid
:undocumented:
@@ -1766,7 +1774,8 @@ Defining |Ltac| symbols
do not count as user-defined tactics for `::=`. If :attr:`local` is not
specified, the redefinition applies across module boundaries.
- .. exn: There is no Ltac named @qualid
+ .. exn:: There is no Ltac named @qualid
+ :undocumented:
:n:`{* with @tacdef_body }`
Permits definition of mutually recursive tactics.
diff --git a/doc/sphinx/proof-engine/ltac2.rst b/doc/sphinx/proof-engine/ltac2.rst
index 773e393eb6..a46f4fb894 100644
--- a/doc/sphinx/proof-engine/ltac2.rst
+++ b/doc/sphinx/proof-engine/ltac2.rst
@@ -3,8 +3,8 @@
Ltac2
=====
-The Ltac tactic language is probably one of the ingredients of the success of
-Coq, yet it is at the same time its Achilles' heel. Indeed, Ltac:
+The |Ltac| tactic language is probably one of the ingredients of the success of
+Coq, yet it is at the same time its Achilles' heel. Indeed, |Ltac|:
- has often unclear semantics
- is very non-uniform due to organic growth
@@ -38,7 +38,6 @@ Current limitations include:
- Printing functions are limited and awkward to use. Only a few data types are
printable.
- Deep pattern matching and matching on tuples don't work.
- - If statements on Ltac2 boolean values
- A convenient way to build terms with casts through the low-level API. Because the
cast type is opaque, building terms with casts currently requires an awkward construction like the
following, which also incurs extra overhead to repeat typechecking for each
@@ -228,7 +227,7 @@ One can define new types with the following commands.
:name: Ltac2 external
Declares abstract terms. Frequently, these declare OCaml functions
- defined in |Coq| and give their type information. They can also declare
+ defined in Coq and give their type information. They can also declare
data structures from OCaml. This command has no use for the end user.
APIs
@@ -345,12 +344,10 @@ Ltac2 Definitions
.. coqtop:: all
- Ltac2 mutable rec f b := match b with true => 0 | _ => f true end.
- Ltac2 Set f := fun b =>
- match b with true => 1 | _ => f true end.
+ Ltac2 mutable rec f b := if b then 0 else f true.
+ Ltac2 Set f := fun b => if b then 1 else f true.
Ltac2 Eval (f false).
- Ltac2 Set f as oldf := fun b =>
- match b with true => 2 | _ => oldf false end.
+ Ltac2 Set f as oldf := fun b => if b then 2 else oldf false.
Ltac2 Eval (f false).
In the definition, the `f` in the body is resolved statically
@@ -537,7 +534,7 @@ aware of bound variables and must use heuristics to decide whether a variable
is a proper one or referring to something in the Ltac context.
Likewise, in Ltac1, constr parsing is implicit, so that ``foo 0`` is
-not ``foo`` applied to the Ltac integer expression ``0`` (Ltac does have a
+not ``foo`` applied to the Ltac integer expression ``0`` (|Ltac| does have a
notion of integers, though it is not first-class), but rather the Coq term
:g:`Datatypes.O`.
@@ -565,7 +562,7 @@ Built-in quotations
| ltac1 : ( @ltac1_expr_in_env )
| ltac1val : ( @ltac1_expr_in_env )
ltac1_expr_in_env ::= @ltac_expr
- | {* @ident } |- @ltac_expr
+ | {* @ident } %|- @ltac_expr
The current implementation recognizes the following built-in quotations:
@@ -981,7 +978,7 @@ Match over goals
.. prodn::
goal_match_list ::= {? %| } {+| @gmatch_rule }
gmatch_rule ::= @gmatch_pattern => @ltac2_expr
- gmatch_pattern ::= [ {*, @gmatch_hyp_pattern } |- @ltac2_match_pattern ]
+ gmatch_pattern ::= [ {*, @gmatch_hyp_pattern } %|- @ltac2_match_pattern ]
gmatch_hyp_pattern ::= @name : @ltac2_match_pattern
Matches over goals, similar to Ltac1 :tacn:`match goal`.
@@ -1149,6 +1146,13 @@ Match on values
| @tac2pat1 , {*, @tac2pat1 }
| @tac2pat1
+.. tacn:: if @ltac2_expr5__test then @ltac2_expr5__then else @ltac2_expr5__else
+ :name: if-then-else (Ltac2)
+
+ Equivalent to a :tacn:`match <match (Ltac2)>` on a boolean value. If the
+ :n:`@ltac2_expr5__test` evaluates to true, :n:`@ltac2_expr5__then`
+ is evaluated. Otherwise :n:`@ltac2_expr5__else` is evaluated.
+
.. note::
For now, deep pattern matching is not implemented.
@@ -1182,7 +1186,7 @@ Notations
into the right-hand side. The right-hand side is typechecked when the notation is used,
not when it is defined. In the following example, `x` is the formal parameter name and
`constr` is its :ref:`syntactic class<syntactic_classes>`. `print` and `of_constr` are
- functions provided by |Coq| through `Message.v`.
+ functions provided by Coq through `Message.v`.
.. todo "print" doesn't seem to pay attention to "Set Printing All"
@@ -1281,7 +1285,7 @@ Abbreviations
Defining tactics
~~~~~~~~~~~~~~~~
-Built-in tactics (those defined in OCaml code in the |Coq| executable) and Ltac1 tactics,
+Built-in tactics (those defined in OCaml code in the Coq executable) and Ltac1 tactics,
which are defined in `.v` files, must be defined through notations. (Ltac2 tactics can be
defined with :cmd:`Ltac2`.
@@ -1289,7 +1293,7 @@ Notations for many but not all built-in tactics are defined in `Notations.v`, wh
loaded with Ltac2. The Ltac2 syntax for these tactics is often identical or very similar to the
tactic syntax described in other chapters of this documentation. These notations rely on tactic functions
declared in `Std.v`. Functions corresponding to some built-in tactics may not yet be defined in the
-|Coq| executable or declared in `Std.v`. Adding them may require code changes to |Coq| or defining
+Coq executable or declared in `Std.v`. Adding them may require code changes to Coq or defining
workarounds through Ltac1 (described below).
Two examples of syntax differences:
@@ -1321,7 +1325,7 @@ Syntactic classes
~~~~~~~~~~~~~~~~~
The simplest syntactic classes in Ltac2 notations represent individual nonterminals
-from the |Coq| grammar. Only a few selected nonterminals are available as syntactic classes.
+from the Coq grammar. Only a few selected nonterminals are available as syntactic classes.
In addition, there are metasyntactic operations for describing
more complex syntax, such as making an item optional or representing a list of items.
When parsing, each syntactic class expression returns a value that's bound to a name in the
@@ -1598,8 +1602,8 @@ Here is the syntax for the :n:`q_*` nonterminals:
ltac2_clause ::= in @ltac2_in_clause
| at @ltac2_occs_nums
ltac2_in_clause ::= * {? @ltac2_occs }
- | * |- {? @ltac2_concl_occ }
- | {*, @ltac2_hypident_occ } {? |- {? @ltac2_concl_occ } }
+ | * %|- {? @ltac2_concl_occ }
+ | {*, @ltac2_hypident_occ } {? %|- {? @ltac2_concl_occ } }
.. insertprodn q_occurrences ltac2_hypident
@@ -1629,7 +1633,7 @@ Here is the syntax for the :n:`q_*` nonterminals:
.. insertprodn ltac2_oriented_rewriter ltac2_rewriter
.. prodn::
- ltac2_oriented_rewriter ::= {| -> | <- } @ltac2_rewriter
+ ltac2_oriented_rewriter ::= {? {| -> | <- } } @ltac2_rewriter
ltac2_rewriter ::= {? @natural } {? {| ? | ! } } @ltac2_constr_with_bindings
.. insertprodn ltac2_for_each_goal ltac2_goal_tactics
diff --git a/doc/sphinx/proof-engine/proof-handling.rst b/doc/sphinx/proof-engine/proof-handling.rst
index edd93f2266..7f5aacbfdb 100644
--- a/doc/sphinx/proof-engine/proof-handling.rst
+++ b/doc/sphinx/proof-engine/proof-handling.rst
@@ -1,914 +1,5 @@
-.. _proofhandling:
+:orphan:
--------------------
- Proof handling
--------------------
+.. raw:: html
-In |Coq|’s proof editing mode all top-level commands documented in
-Chapter :ref:`vernacularcommands` remain available and the user has access to specialized
-commands dealing with proof development pragmas documented in this
-section. They can also use some other specialized commands called
-*tactics*. They are the very tools allowing the user to deal with
-logical reasoning. They are documented in Chapter :ref:`tactics`.
-
-Coq user interfaces usually have a way of marking whether the user has
-switched to proof editing mode. For instance, in coqtop the prompt ``Coq <``   is changed into
-:n:`@ident <`   where :token:`ident` is the declared name of the theorem currently edited.
-
-At each stage of a proof development, one has a list of goals to
-prove. Initially, the list consists only in the theorem itself. After
-having applied some tactics, the list of goals contains the subgoals
-generated by the tactics.
-
-To each subgoal is associated a number of hypotheses called the *local context*
-of the goal. Initially, the local context contains the local variables and
-hypotheses of the current section (see Section :ref:`gallina-assumptions`) and
-the local variables and hypotheses of the theorem statement. It is enriched by
-the use of certain tactics (see e.g. :tacn:`intro`).
-
-When a proof is completed, the message ``Proof completed`` is displayed.
-One can then register this proof as a defined constant in the
-environment. Because there exists a correspondence between proofs and
-terms of λ-calculus, known as the *Curry-Howard isomorphism*
-:cite:`How80,Bar81,Gir89,H89`, |Coq| stores proofs as terms of |Cic|. Those
-terms are called *proof terms*.
-
-
-.. exn:: No focused proof.
-
- Coq raises this error message when one attempts to use a proof editing command
- out of the proof editing mode.
-
-.. _proof-editing-mode:
-
-Entering and leaving proof editing mode
----------------------------------------
-
-The proof editing mode is entered by asserting a statement, which typically is
-the assertion of a theorem using an assertion command like :cmd:`Theorem`. The
-list of assertion commands is given in :ref:`Assertions`. The command
-:cmd:`Goal` can also be used.
-
-.. cmd:: Goal @form
-
- This is intended for quick assertion of statements, without knowing in
- advance which name to give to the assertion, typically for quick
- testing of the provability of a statement. If the proof of the
- statement is eventually completed and validated, the statement is then
- bound to the name ``Unnamed_thm`` (or a variant of this name not already
- used for another statement).
-
-.. cmd:: Qed
-
- This command is available in interactive editing proof mode when the
- proof is completed. Then :cmd:`Qed` extracts a proof term from the proof
- script, switches back to Coq top-level and attaches the extracted
- proof term to the declared name of the original goal. This name is
- added to the environment as an opaque constant.
-
- .. exn:: Attempt to save an incomplete proof.
- :undocumented:
-
- .. note::
-
- Sometimes an error occurs when building the proof term, because
- tactics do not enforce completely the term construction
- constraints.
-
- The user should also be aware of the fact that since the
- proof term is completely rechecked at this point, one may have to wait
- a while when the proof is large. In some exceptional cases one may
- even incur a memory overflow.
-
-.. cmd:: Defined
-
- Same as :cmd:`Qed`, except the proof is made *transparent*, which means
- that its content can be explicitly used for type checking and that it can be
- unfolded in conversion tactics (see :ref:`performingcomputations`,
- :cmd:`Opaque`, :cmd:`Transparent`).
-
-.. cmd:: Save @ident
- :name: Save
-
- Saves a completed proof with the name :token:`ident`.
-
-.. cmd:: Admitted
-
- This command is available in interactive editing mode to give up
- the current proof and declare the initial goal as an axiom.
-
-.. cmd:: Abort
-
- This command cancels the current proof development, switching back to
- the previous proof development, or to the |Coq| toplevel if no other
- proof was edited.
-
- .. exn:: No focused proof (No proof-editing in progress).
- :undocumented:
-
- .. cmdv:: Abort @ident
-
- Aborts the editing of the proof named :token:`ident` (in case you have
- nested proofs).
-
- .. seealso:: :flag:`Nested Proofs Allowed`
-
- .. cmdv:: Abort All
-
- Aborts all current goals.
-
-.. cmd:: Proof @term
- :name: Proof `term`
-
- This command applies in proof editing mode. It is equivalent to
- :n:`exact @term. Qed.`
- That is, you have to give the full proof in one gulp, as a
- proof term (see Section :ref:`applyingtheorems`).
-
- .. warning::
-
- Use of this command is discouraged. In particular, it
- doesn't work in Proof General because it must
- immediately follow the command that opened proof mode, but
- Proof General inserts :cmd:`Unset` :flag:`Silent` before it (see
- `Proof General issue #498
- <https://github.com/ProofGeneral/PG/issues/498>`_).
-
-.. cmd:: Proof
-
- Is a no-op which is useful to delimit the sequence of tactic commands
- which start a proof, after a :cmd:`Theorem` command. It is a good practice to
- use :cmd:`Proof` as an opening parenthesis, closed in the script with a
- closing :cmd:`Qed`.
-
- .. seealso:: :cmd:`Proof with`
-
-.. cmd:: Proof using {+ @ident }
-
- This command applies in proof editing mode. It declares the set of
- section variables (see :ref:`gallina-assumptions`) used by the proof.
- At :cmd:`Qed` time, the
- system will assert that the set of section variables actually used in
- the proof is a subset of the declared one.
-
- The set of declared variables is closed under type dependency. For
- example, if ``T`` is a variable and ``a`` is a variable of type
- ``T``, then the commands ``Proof using a`` and ``Proof using T a``
- are equivalent.
-
- The set of declared variables always includes the variables used by
- the statement. In other words ``Proof using e`` is equivalent to
- ``Proof using Type + e`` for any declaration expression ``e``.
-
- .. cmdv:: Proof using {+ @ident } with @tactic
-
- Combines in a single line :cmd:`Proof with` and :cmd:`Proof using`.
-
- .. seealso:: :ref:`tactics-implicit-automation`
-
- .. cmdv:: Proof using All
-
- Use all section variables.
-
- .. cmdv:: Proof using {? Type }
-
- Use only section variables occurring in the statement.
-
- .. cmdv:: Proof using Type*
-
- The ``*`` operator computes the forward transitive closure. E.g. if the
- variable ``H`` has type ``p < 5`` then ``H`` is in ``p*`` since ``p`` occurs in the type
- of ``H``. ``Type*`` is the forward transitive closure of the entire set of
- section variables occurring in the statement.
-
- .. cmdv:: Proof using -({+ @ident })
-
- Use all section variables except the list of :token:`ident`.
-
- .. cmdv:: Proof using @collection__1 + @collection__2
-
- Use section variables from the union of both collections.
- See :ref:`nameaset` to know how to form a named collection.
-
- .. cmdv:: Proof using @collection__1 - @collection__2
-
- Use section variables which are in the first collection but not in the
- second one.
-
- .. cmdv:: Proof using @collection - ({+ @ident })
-
- Use section variables which are in the first collection but not in the
- list of :token:`ident`.
-
- .. cmdv:: Proof using @collection *
-
- Use section variables in the forward transitive closure of the collection.
- The ``*`` operator binds stronger than ``+`` and ``-``.
-
-
-Proof using options
-```````````````````
-
-The following options modify the behavior of ``Proof using``.
-
-
-.. opt:: Default Proof Using "@collection"
- :name: Default Proof Using
-
- Use :n:`@collection` as the default ``Proof using`` value. E.g. ``Set Default
- Proof Using "a b"`` will complete all ``Proof`` commands not followed by a
- ``using`` part with ``using a b``.
-
-
-.. flag:: Suggest Proof Using
-
- When :cmd:`Qed` is performed, suggest a ``using`` annotation if the user did not
- provide one.
-
-.. _`nameaset`:
-
-Name a set of section hypotheses for ``Proof using``
-````````````````````````````````````````````````````
-
-.. cmd:: Collection @ident := @collection
-
- This can be used to name a set of section
- hypotheses, with the purpose of making ``Proof using`` annotations more
- compact.
-
- .. example::
-
- Define the collection named ``Some`` containing ``x``, ``y`` and ``z``::
-
- Collection Some := x y z.
-
- Define the collection named ``Fewer`` containing only ``x`` and ``y``::
-
- Collection Fewer := Some - z
-
- Define the collection named ``Many`` containing the set union or set
- difference of ``Fewer`` and ``Some``::
-
- Collection Many := Fewer + Some
- Collection Many := Fewer - Some
-
- Define the collection named ``Many`` containing the set difference of
- ``Fewer`` and the unnamed collection ``x y``::
-
- Collection Many := Fewer - (x y)
-
-
-
-.. cmd:: Existential @natural := @term
-
- This command instantiates an existential variable. :token:`natural` is an index in
- the list of uninstantiated existential variables displayed by :cmd:`Show Existentials`.
-
- This command is intended to be used to instantiate existential
- variables when the proof is completed but some uninstantiated
- existential variables remain. To instantiate existential variables
- during proof edition, you should use the tactic :tacn:`instantiate`.
-
-.. cmd:: Grab Existential Variables
-
- This command can be run when a proof has no more goal to be solved but
- has remaining uninstantiated existential variables. It takes every
- uninstantiated existential variable and turns it into a goal.
-
-Proof modes
-```````````
-
-When entering proof mode through commands such as :cmd:`Goal` and :cmd:`Proof`,
-|Coq| picks by default the |Ltac| mode. Nonetheless, there exist other proof modes
-shipped in the standard |Coq| installation, and furthermore some plugins define
-their own proof modes. The default proof mode used when opening a proof can
-be changed using the following option.
-
-.. opt:: Default Proof Mode @string
- :name: Default Proof Mode
-
- Select the proof mode to use when starting a proof. Depending on the proof
- mode, various syntactic constructs are allowed when writing an interactive
- proof. The possible option values are listed below.
-
- - "Classic": this is the default. It activates the |Ltac| language to interact
- with the proof, and also allows vernacular commands.
-
- - "Noedit": this proof mode only allows vernacular commands. No tactic
- language is activated at all. This is the default when the prelude is not
- loaded, e.g. through the `-noinit` option for `coqc`.
-
- - "Ltac2": this proof mode is made available when requiring the Ltac2
- library, and is set to be the default when it is imported. It allows
- to use the Ltac2 language, as well as vernacular commands.
-
- - Some external plugins also define their own proof mode, which can be
- activated via this command.
-
-Navigation in the proof tree
---------------------------------
-
-.. cmd:: Undo
-
- This command cancels the effect of the last command. Thus, it
- backtracks one step.
-
-.. cmdv:: Undo @natural
-
- Repeats Undo :token:`natural` times.
-
-.. cmdv:: Restart
- :name: Restart
-
- This command restores the proof editing process to the original goal.
-
- .. exn:: No focused proof to restart.
- :undocumented:
-
-.. cmd:: Focus
-
- This focuses the attention on the first subgoal to prove and the
- printing of the other subgoals is suspended until the focused subgoal
- is solved or unfocused. This is useful when there are many current
- subgoals which clutter your screen.
-
- .. deprecated:: 8.8
-
- Prefer the use of bullets or focusing brackets (see below).
-
-.. cmdv:: Focus @natural
-
- This focuses the attention on the :token:`natural` th subgoal to prove.
-
- .. deprecated:: 8.8
-
- Prefer the use of focusing brackets with a goal selector (see below).
-
-.. cmd:: Unfocus
-
- This command restores to focus the goal that were suspended by the
- last :cmd:`Focus` command.
-
- .. deprecated:: 8.8
-
-.. cmd:: Unfocused
-
- Succeeds if the proof is fully unfocused, fails if there are some
- goals out of focus.
-
-.. _curly-braces:
-
-.. index:: {
- }
-
-.. cmd:: {| %{ | %} }
-
- The command ``{`` (without a terminating period) focuses on the first
- goal, much like :cmd:`Focus` does, however, the subproof can only be
- unfocused when it has been fully solved ( *i.e.* when there is no
- focused goal left). Unfocusing is then handled by ``}`` (again, without a
- terminating period). See also an example in the next section.
-
- Note that when a focused goal is proved a message is displayed
- together with a suggestion about the right bullet or ``}`` to unfocus it
- or focus the next one.
-
- .. cmdv:: @natural: %{
-
- This focuses on the :token:`natural`\-th subgoal to prove.
-
- .. cmdv:: [@ident]: %{
-
- This focuses on the named goal :token:`ident`.
-
- .. note::
-
- Goals are just existential variables and existential variables do not
- get a name by default. You can give a name to a goal by using :n:`refine ?[@ident]`.
- You may also wrap this in an Ltac-definition like:
-
- .. coqtop:: in
-
- Ltac name_goal name := refine ?[name].
-
- .. seealso:: :ref:`existential-variables`
-
- .. example::
-
- This first example uses the Ltac definition above, and the named goals
- only serve for documentation.
-
- .. coqtop:: all
-
- Goal forall n, n + 0 = n.
- Proof.
- induction n; [ name_goal base | name_goal step ].
- [base]: {
-
- .. coqtop:: all
-
- reflexivity.
-
- .. coqtop:: in
-
- }
-
- .. coqtop:: all
-
- [step]: {
-
- .. coqtop:: all
-
- simpl.
- f_equal.
- assumption.
- }
- Qed.
-
- This can also be a way of focusing on a shelved goal, for instance:
-
- .. coqtop:: all
-
- Goal exists n : nat, n = n.
- eexists ?[x].
- reflexivity.
- [x]: exact 0.
- Qed.
-
- .. exn:: This proof is focused, but cannot be unfocused this way.
-
- You are trying to use ``}`` but the current subproof has not been fully solved.
-
- .. exn:: No such goal (@natural).
- :undocumented:
-
- .. exn:: No such goal (@ident).
- :undocumented:
-
- .. exn:: Brackets do not support multi-goal selectors.
-
- Brackets are used to focus on a single goal given either by its position
- or by its name if it has one.
-
- .. seealso:: The error messages about bullets below.
-
-.. _bullets:
-
-Bullets
-```````
-
-Alternatively to ``{`` and ``}``, proofs can be structured with bullets. The
-use of a bullet ``b`` for the first time focuses on the first goal ``g``, the
-same bullet cannot be used again until the proof of ``g`` is completed,
-then it is mandatory to focus the next goal with ``b``. The consequence is
-that ``g`` and all goals present when ``g`` was focused are focused with the
-same bullet ``b``. See the example below.
-
-Different bullets can be used to nest levels. The scope of bullet does
-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 ::= {| {+ - } | {+ + } | {+ * } }
-
-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
-or focus the next one.
-
-.. note::
-
- In Proof General (``Emacs`` interface to |Coq|), you must use
- bullets with the priority ordering shown above to have a correct
- indentation. For example ``-`` must be the outer bullet and ``**`` the inner
- one in the example below.
-
-The following example script illustrates all these features:
-
-.. example::
-
- .. coqtop:: all
-
- Goal (((True /\ True) /\ True) /\ True) /\ True.
- Proof.
- split.
- - split.
- + split.
- ** { split.
- - trivial.
- - trivial.
- }
- ** trivial.
- + trivial.
- - assert True.
- { trivial. }
- assumption.
- Qed.
-
-.. exn:: Wrong bullet @bullet__1: Current bullet @bullet__2 is not finished.
-
- Before using bullet :n:`@bullet__1` again, you should first finish proving
- the current focused goal.
- Note that :n:`@bullet__1` and :n:`@bullet__2` may be the same.
-
-.. exn:: Wrong bullet @bullet__1: Bullet @bullet__2 is mandatory here.
-
- You must put :n:`@bullet__2` to focus on the next goal. No other bullet is
- allowed here.
-
-.. exn:: No such goal. Focus next goal with bullet @bullet.
-
- You tried to apply a tactic but no goals were under focus.
- Using :n:`@bullet` is mandatory here.
-
-.. FIXME: the :noindex: below works around a Sphinx issue.
- (https://github.com/sphinx-doc/sphinx/issues/4979)
- It should be removed once that issue is fixed.
-
-.. exn:: No such goal. Try unfocusing with %}.
- :noindex:
-
- You just finished a goal focused by ``{``, you must unfocus it with ``}``.
-
-Mandatory Bullets
-`````````````````
-
-Using :opt:`Default Goal Selector` with the ``!`` selector forces
-tactic scripts to keep focus to exactly one goal (e.g. using bullets)
-or use explicit goal selectors.
-
-Set Bullet Behavior
-```````````````````
-.. opt:: Bullet Behavior {| "None" | "Strict Subproofs" }
- :name: Bullet Behavior
-
- This option controls the bullet behavior and can take two possible values:
-
- - "None": this makes bullets inactive.
- - "Strict Subproofs": this makes bullets active (this is the default behavior).
-
-.. _requestinginformation:
-
-Requesting information
-----------------------
-
-
-.. cmd:: Show
-
- This command displays the current goals.
-
- .. exn:: No focused proof.
- :undocumented:
-
- .. cmdv:: Show @natural
-
- Displays only the :token:`natural`\-th subgoal.
-
- .. exn:: No such goal.
- :undocumented:
-
- .. cmdv:: Show @ident
-
- Displays the named goal :token:`ident`. This is useful in
- particular to display a shelved goal but only works if the
- corresponding existential variable has been named by the user
- (see :ref:`existential-variables`) as in the following example.
-
- .. example::
-
- .. coqtop:: all abort
-
- Goal exists n, n = 0.
- eexists ?[n].
- Show n.
-
- .. cmdv:: Show Proof {? Diffs {? removed } }
- :name: Show Proof
-
- Displays the proof term generated by the tactics
- that have been applied so far. If the proof is incomplete, the term
- will contain holes, which correspond to subterms which are still to be
- constructed. Each hole is an existential variable, which appears as a
- question mark followed by an identifier.
-
- Specifying “Diffs” highlights the difference between the
- current and previous proof step. By default, the command shows the
- output once with additions highlighted. Including “removed” shows
- the output twice: once showing removals and once showing additions.
- It does not examine the :opt:`Diffs` option. See :ref:`showing_proof_diffs`.
-
- .. cmdv:: Show Conjectures
- :name: Show Conjectures
-
- It prints the list of the names of all the
- theorems that are currently being proved. As it is possible to start
- proving a previous lemma during the proof of a theorem, this list may
- contain several names.
-
- .. cmdv:: Show Intro
- :name: Show Intro
-
- If the current goal begins by at least one product,
- this command prints the name of the first product, as it would be
- generated by an anonymous :tacn:`intro`. The aim of this command is to ease
- the writing of more robust scripts. For example, with an appropriate
- Proof General macro, it is possible to transform any anonymous :tacn:`intro`
- into a qualified one such as ``intro y13``. In the case of a non-product
- goal, it prints nothing.
-
- .. cmdv:: Show Intros
- :name: Show Intros
-
- This command is similar to the previous one, it
- simulates the naming process of an :tacn:`intros`.
-
- .. cmdv:: Show Existentials
- :name: Show Existentials
-
- Displays all open goals / existential variables in the current proof
- along with the type and the context of each variable.
-
- .. cmdv:: Show Match @ident
-
- This variant displays a template of the Gallina
- ``match`` construct with a branch for each constructor of the type
- :token:`ident`
-
- .. example::
-
- .. coqtop:: all
-
- Show Match nat.
-
- .. exn:: Unknown inductive type.
- :undocumented:
-
- .. cmdv:: Show Universes
- :name: Show Universes
-
- It displays the set of all universe constraints and
- its normalized form at the current stage of the proof, useful for
- debugging universe inconsistencies.
-
- .. cmdv:: Show Goal @natural at @natural
- :name: Show Goal
-
- This command is only available in coqtop. Displays a goal at a
- proof state using the goal ID number and the proof state ID number.
- It is primarily for use by tools such as Prooftree that need to fetch
- goal history in this way. Prooftree is a tool for visualizing a proof
- as a tree that runs in Proof General.
-
-.. cmd:: Guarded
-
- Some tactics (e.g. :tacn:`refine`) allow to build proofs using
- fixpoint or co-fixpoint constructions. Due to the incremental nature
- of interactive proof construction, the check of the termination (or
- guardedness) of the recursive calls in the fixpoint or cofixpoint
- constructions is postponed to the time of the completion of the proof.
-
- The command :cmd:`Guarded` allows checking if the guard condition for
- fixpoint and cofixpoint is violated at some time of the construction
- of the proof without having to wait the completion of the proof.
-
-.. _showing_diffs:
-
-Showing differences between proof steps
----------------------------------------
-
-Coq can automatically highlight the differences between successive proof steps
-and between values in some error messages. Coq can also highlight differences
-in the proof term.
-For example, the following screenshots of CoqIDE and coqtop show the application
-of the same :tacn:`intros` tactic. The tactic creates two new hypotheses, highlighted in green.
-The conclusion is entirely in pale green because although it’s changed, no tokens were added
-to it. The second screenshot uses the "removed" option, so it shows the conclusion a
-second time with the old text, with deletions marked in red. Also, since the hypotheses are
-new, no line of old text is shown for them.
-
-.. comment screenshot produced with:
- Inductive ev : nat -> Prop :=
- | ev_0 : ev 0
- | ev_SS : forall n : nat, ev n -> ev (S (S n)).
-
- Fixpoint double (n:nat) :=
- match n with
- | O => O
- | S n' => S (S (double n'))
- end.
-
- Goal forall n, ev n -> exists k, n = double k.
- intros n E.
-
-..
-
- .. image:: ../_static/diffs-coqide-on.png
- :alt: |CoqIDE| with Set Diffs on
-
-..
-
- .. image:: ../_static/diffs-coqide-removed.png
- :alt: |CoqIDE| with Set Diffs removed
-
-..
-
- .. image:: ../_static/diffs-coqtop-on3.png
- :alt: coqtop with Set Diffs on
-
-This image shows an error message with diff highlighting in CoqIDE:
-
-..
-
- .. image:: ../_static/diffs-error-message.png
- :alt: |CoqIDE| error message with diffs
-
-How to enable diffs
-```````````````````
-
-.. opt:: Diffs {| "on" | "off" | "removed" }
- :name: Diffs
-
- The “on” setting highlights added tokens in green, while the “removed” setting
- additionally reprints items with removed tokens in red. Unchanged tokens in
- modified items are shown with pale green or red. Diffs in error messages
- use red and green for the compared values; they appear regardless of the setting.
- (Colors are user-configurable.)
-
-For coqtop, showing diffs can be enabled when starting coqtop with the
-``-diffs on|off|removed`` command-line option or by setting the :opt:`Diffs` option
-within Coq. You will need to provide the ``-color on|auto`` command-line option when
-you start coqtop in either case.
-
-Colors for coqtop can be configured by setting the ``COQ_COLORS`` environment
-variable. See section :ref:`customization-by-environment-variables`. Diffs
-use the tags ``diff.added``, ``diff.added.bg``, ``diff.removed`` and ``diff.removed.bg``.
-
-In CoqIDE, diffs should be enabled from the ``View`` menu. Don’t use the ``Set Diffs``
-command in CoqIDE. You can change the background colors shown for diffs from the
-``Edit | Preferences | Tags`` panel by changing the settings for the ``diff.added``,
-``diff.added.bg``, ``diff.removed`` and ``diff.removed.bg`` tags. This panel also
-lets you control other attributes of the highlights, such as the foreground
-color, bold, italic, underline and strikeout.
-
-As of June 2019, Proof General can also display Coq-generated proof diffs automatically.
-Please see the PG documentation section
-"`Showing Proof Diffs" <https://proofgeneral.github.io/doc/master/userman/Coq-Proof-General#Showing-Proof-Diffs>`_)
-for details.
-
-How diffs are calculated
-````````````````````````
-
-Diffs are calculated as follows:
-
-1. Select the old proof state to compare to, which is the proof state before
- the last tactic that changed the proof. Changes that only affect the view
- of the proof, such as ``all: swap 1 2``, are ignored.
-
-2. For each goal in the new proof state, determine what old goal to compare
- it to—the one it is derived from or is the same as. Match the hypotheses by
- name (order is ignored), handling compacted items specially.
-
-3. For each hypothesis and conclusion (the “items”) in each goal, pass
- them as strings to the lexer to break them into tokens. Then apply the
- Myers diff algorithm :cite:`Myers` on the tokens and add appropriate highlighting.
-
-Notes:
-
-* Aside from the highlights, output for the "on" option should be identical
- to the undiffed output.
-* Goals completed in the last proof step will not be shown even with the
- "removed" setting.
-
-.. comment The following screenshots show diffs working with multiple goals and with compacted
- hypotheses. In the first one, notice that the goal ``P 1`` is not highlighted at
- all after the split because it has not changed.
-
- .. todo: Use this script and remove the screenshots when COQ_COLORS
- works for coqtop in sphinx
- .. coqtop:: none
-
- Set Diffs "on".
- Parameter P : nat -> Prop.
- Goal P 1 /\ P 2 /\ P 3.
-
- .. coqtop:: out
-
- split.
-
- .. coqtop:: all abort
-
- 2: split.
-
- ..
-
- .. coqtop:: none
-
- Set Diffs "on".
- Goal forall n m : nat, n + m = m + n.
- Set Diffs "on".
-
- .. coqtop:: out
-
- intros n.
-
- .. coqtop:: all abort
-
- intros m.
-
-This screen shot shows the result of applying a :tacn:`split` tactic that replaces one goal
-with 2 goals. Notice that the goal ``P 1`` is not highlighted at all after
-the split because it has not changed.
-
-..
-
- .. image:: ../_static/diffs-coqide-multigoal.png
- :alt: coqide with Set Diffs on with multiple goals
-
-Diffs may appear like this after applying a :tacn:`intro` tactic that results
-in a compacted hypotheses:
-
-..
-
- .. image:: ../_static/diffs-coqide-compacted.png
- :alt: coqide with Set Diffs on with compacted hypotheses
-
-.. _showing_proof_diffs:
-
-"Show Proof" differences
-````````````````````````
-
-To show differences in the proof term:
-
-- In coqtop and Proof General, use the :cmd:`Show Proof` `Diffs` command.
-
-- In CoqIDE, position the cursor on or just after a tactic to compare the proof term
- after the tactic with the proof term before the tactic, then select
- `View / Show Proof` from the menu or enter the associated key binding.
- Differences will be shown applying the current `Show Diffs` setting
- from the `View` menu. If the current setting is `Don't show diffs`, diffs
- will not be shown.
-
- Output with the "added and removed" option looks like this:
-
- ..
-
- .. image:: ../_static/diffs-show-proof.png
- :alt: coqide with Set Diffs on with compacted hypotheses
-
-Controlling the effect of proof editing commands
-------------------------------------------------
-
-
-.. opt:: Hyps Limit @natural
- :name: Hyps Limit
-
- This option controls the maximum number of hypotheses displayed in goals
- after the application of a tactic. All the hypotheses remain usable
- in the proof development.
- When unset, it goes back to the default mode which is to print all
- available hypotheses.
-
-
-.. flag:: Nested Proofs Allowed
-
- When turned on (it is off by default), this flag enables support for nested
- proofs: a new assertion command can be inserted before the current proof is
- finished, in which case Coq will temporarily switch to the proof of this
- *nested lemma*. When the proof of the nested lemma is finished (with :cmd:`Qed`
- or :cmd:`Defined`), its statement will be made available (as if it had been
- proved before starting the previous proof) and Coq will switch back to the
- proof of the previous assertion.
-
-.. flag:: Printing Goal Names
-
- When turned on, the name of the goal is printed in interactive
- proof mode, which can be useful in cases of cross references
- between goals.
-
-Controlling memory usage
-------------------------
-
-.. cmd:: Print Debug GC
-
- Prints heap usage statistics, which are values from the `stat` type of the `Gc` module
- described
- `here <https://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html#TYPEstat>`_
- in the OCaml documentation.
- The `live_words`, `heap_words` and `top_heap_words` values give the basic information.
- Words are 8 bytes or 4 bytes, respectively, for 64- and 32-bit executables.
-
-When experiencing high memory usage the following commands can be used
-to force |Coq| to optimize some of its internal data structures.
-
-.. cmd:: Optimize Proof
-
- Shrink the data structure used to represent the current proof.
-
-
-.. cmd:: Optimize Heap
-
- Perform a heap compaction. This is generally an expensive operation.
- See: `OCaml Gc.compact <http://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html#VALcompact>`_
- There is also an analogous tactic :tacn:`optimize_heap`.
-
-Memory usage parameters can be set through the :ref:`OCAMLRUNPARAM <OCAMLRUNPARAM>`
-environment variable.
+ <meta http-equiv="refresh" content="0;URL=../proofs/writing-proofs/proof-mode.html">
diff --git a/doc/sphinx/proof-engine/ssreflect-proof-language.rst b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
index ca50a02562..07c2d268c6 100644
--- a/doc/sphinx/proof-engine/ssreflect-proof-language.rst
+++ b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
@@ -13,12 +13,12 @@ Introduction
This chapter describes a set of tactics known as |SSR| originally
designed to provide support for the so-called *small scale reflection*
proof methodology. Despite the original purpose this set of tactic is
-of general interest and is available in |Coq| starting from version 8.7.
+of general interest and is available in Coq starting from version 8.7.
|SSR| was developed independently of the tactics described in
Chapter :ref:`tactics`. Indeed the scope of the tactics part of |SSR| largely
overlaps with the standard set of tactics. Eventually the overlap will
-be reduced in future releases of |Coq|.
+be reduced in future releases of Coq.
Proofs written in |SSR| typically look quite different from the
ones written using only tactics as per Chapter :ref:`tactics`. We try to
@@ -112,7 +112,7 @@ Compatibility issues
~~~~~~~~~~~~~~~~~~~~
Requiring the above modules creates an environment which is mostly
-compatible with the rest of |Coq|, up to a few discrepancies:
+compatible with the rest of Coq, up to a few discrepancies:
+ New keywords (``is``) might clash with variable, constant, tactic or
@@ -124,11 +124,11 @@ compatible with the rest of |Coq|, up to a few discrepancies:
+ Identifiers with both leading and trailing ``_``, such as ``_x_``, are
reserved by |SSR| and cannot appear in scripts.
+ The extensions to the :tacn:`rewrite` tactic are partly incompatible with those
- available in current versions of |Coq|; in particular: ``rewrite .. in
+ available in current versions of Coq; in particular: ``rewrite .. in
(type of k)`` or ``rewrite .. in *`` or any other variant of :tacn:`rewrite`
will not work, and the |SSR| syntax and semantics for occurrence selection
and rule chaining is different. Use an explicit rewrite direction
- (``rewrite <- …`` or ``rewrite -> …``) to access the |Coq| rewrite tactic.
+ (``rewrite <- …`` or ``rewrite -> …``) to access the Coq rewrite tactic.
+ New symbols (``//``, ``/=``, ``//=``) might clash with adjacent
existing symbols.
This can be avoided by inserting white spaces.
@@ -176,16 +176,16 @@ compatible with the rest of |Coq|, up to a few discrepancies:
create such identifiers. Disabling the flag generates a warning instead,
increasing compatibility with other parts of Coq.
-|Gallina| extensions
+Gallina extensions
--------------------
Small-scale reflection makes an extensive use of the programming
-subset of |Gallina|, |Coq|’s logical specification language. This subset
+subset of Gallina, Coq’s logical specification language. This subset
is quite suited to the description of functions on representations,
because it closely follows the well-established design of the ML
programming language. The |SSR| extension provides three additions
-to |Gallina|, for pattern assignment, pattern testing, and polymorphism;
-these mitigate minor but annoying discrepancies between |Gallina| and
+to Gallina, for pattern assignment, pattern testing, and polymorphism;
+these mitigate minor but annoying discrepancies between Gallina and
ML.
@@ -199,7 +199,7 @@ irrefutable pattern matching, that is, destructuring assignment:
term += let: @pattern := @term in @term
Note the colon ``:`` after the ``let`` keyword, which avoids any ambiguity
-with a function definition or |Coq|’s basic destructuring let. The let:
+with a function definition or Coq’s basic destructuring let. The let:
construct differs from the latter in that
@@ -237,7 +237,7 @@ construct differs from the latter in that
The ``let:`` construct is just (more legible) notation for the primitive
-|Gallina| expression :n:`match @term with @pattern => @term end`.
+Gallina expression :n:`match @term with @pattern => @term end`.
The |SSR| destructuring assignment supports all the dependent
match annotations; the full syntax is
@@ -294,10 +294,10 @@ example, the null and all list function(al)s can be defined as follows:
The pattern conditional also provides a notation for destructuring
assignment with a refutable pattern, adapted to the pure functional
-setting of |Gallina|, which lacks a ``Match_Failure`` exception.
+setting of Gallina, which lacks a ``Match_Failure`` exception.
Like ``let:`` above, the ``if…is`` construct is just (more legible) notation
-for the primitive |Gallina| expression
+for the primitive Gallina expression
:n:`match @term with @pattern => @term | _ => @term end`.
Similarly, it will always be displayed as the expansion of this form
@@ -355,15 +355,15 @@ Note that :token:`pattern` eventually binds variables in the third
Parametric polymorphism
~~~~~~~~~~~~~~~~~~~~~~~
-Unlike ML, polymorphism in core |Gallina| is explicit: the type
+Unlike ML, polymorphism in core Gallina is explicit: the type
parameters of polymorphic functions must be declared explicitly, and
-supplied at each point of use. However, |Coq| provides two features to
+supplied at each point of use. However, Coq provides two features to
suppress redundant parameters:
+ Sections are used to provide (possibly implicit) parameters for a
set of definitions.
-+ Implicit arguments declarations are used to tell |Coq| to use type
++ Implicit arguments declarations are used to tell Coq to use type
inference to deduce some parameters from the context at each point of
call.
@@ -392,11 +392,11 @@ expressions such as
Definition all_null (s : list T) := all (@null T) s.
Unfortunately, such higher-order expressions are quite frequent in
-representation functions, especially those which use |Coq|'s
+representation functions, especially those which use Coq's
``Structures`` to emulate Haskell typeclasses.
-Therefore, |SSR| provides a variant of |Coq|’s implicit argument
-declaration, which causes |Coq| to fill in some implicit parameters at
+Therefore, |SSR| provides a variant of Coq’s implicit argument
+declaration, which causes Coq to fill in some implicit parameters at
each point of use, e.g., the above definition can be written:
.. example::
@@ -432,7 +432,7 @@ The syntax of the new declaration is
As these prenex implicit arguments are ubiquitous and have often large
display strings, it is strongly recommended to change the default
- display settings of |Coq| so that they are not printed (except after
+ display settings of Coq so that they are not printed (except after
a ``Set Printing All`` command). All |SSR| library files thus start
with the incantation
@@ -957,7 +957,7 @@ context. This is essential in the context of an interactive
development environment (IDE), because it facilitates navigating the
proof, allowing to instantly "jump back" to the point at which a
questionable assumption was added, and to find relevant assumptions by
-browsing the pruned context. While novice or casual |Coq| users may find
+browsing the pruned context. While novice or casual Coq users may find
the automatic name selection feature convenient, the usage of such a
feature severely undermines the readability and maintainability of
proof scripts, much like automatic variable declaration in programming
@@ -973,7 +973,7 @@ the foundation of the |SSR| proof language.
Bookkeeping
~~~~~~~~~~~
-During the course of a proof |Coq| always present the user with a
+During the course of a proof Coq always present the user with a
*sequent* whose general form is::
ci : Ti
@@ -1015,7 +1015,7 @@ are *ordered*, but *unnamed*: the display names of variables may
change at any time because of α-conversion.
Similarly, basic deductive steps such as apply can only operate on the
-goal because the |Gallina| terms that control their action (e.g., the
+goal because the Gallina terms that control their action (e.g., the
type of the lemma used by ``apply``) only provide unnamed bound variables.
[#2]_ Since the proof script can only refer directly to the context, it
must constantly shift declarations from the goal to the context and
@@ -1083,7 +1083,7 @@ simultaneously renames ``m`` and ``le_m_n`` into ``p`` and ``le_n_p``,
respectively, by first turning them into unnamed variables, then
turning these variables back into constants and facts.
-Furthermore, |SSR| redefines the basic |Coq| tactics ``case``, ``elim``,
+Furthermore, |SSR| redefines the basic Coq tactics ``case``, ``elim``,
and ``apply`` so that they can take better advantage of
``:`` and ``=>``. In there
|SSR| variants, these tactic operate on the first variable or
@@ -1421,7 +1421,7 @@ Therefore this tactic changes any goal ``G`` into
forall n n0 : nat, n = n0 -> G.
-where the name ``n0`` is picked by the |Coq| display function, and assuming
+where the name ``n0`` is picked by the Coq display function, and assuming
``n`` appeared only in ``G``.
Finally, note that a discharge operation generalizes defined constants
@@ -1647,7 +1647,10 @@ Notations can be used to name tactics, for example
Notation "'myop'" := (ltac:(my ltac code)) : ssripat_scope.
lets one write just ``/myop`` in the intro pattern. Note the scope
-annotation: views are interpreted opening the ``ssripat`` scope.
+annotation: views are interpreted opening the ``ssripat`` scope. We
+provide the following ltac views: ``/[dup]`` to duplicate the top of
+the stack, ``/[swap]`` to swap the two first elements and ``/[apply]``
+to apply the top of the stack to the next.
Intro patterns
``````````````
@@ -1927,7 +1930,7 @@ When the top assumption of a goal has an inductive type, two specific
operations are possible: the case analysis performed by the :tacn:`case`
tactic, and the application of an induction principle, performed by
the :tacn:`elim` tactic. When this top assumption has an inductive type, which
-is moreover an instance of a type family, |Coq| may need help from the
+is moreover an instance of a type family, Coq may need help from the
user to specify which occurrences of the parameters of the type should
be substituted.
@@ -2055,7 +2058,7 @@ Control flow
Indentation and bullets
~~~~~~~~~~~~~~~~~~~~~~~
-A linear development of |Coq| scripts gives little information on the
+A linear development of Coq scripts gives little information on the
structure of the proof. In addition, replaying a proof after some
changes in the statement to be proved will usually not display
information to distinguish between the various branches of case
@@ -3391,7 +3394,7 @@ rewrite operations prescribed by the rules on the current goal.
Indeed rule ``eqab`` is the first to apply among the ones
gathered in the tuple passed to the rewrite tactic. This multirule
- ``(eqab, eqac)`` is actually a |Coq| term and we can name it with a
+ ``(eqab, eqac)`` is actually a Coq term and we can name it with a
definition:
.. coqtop:: all
@@ -3529,11 +3532,11 @@ Anyway this tactic is *not* equivalent to
lemma that was used, while the latter requires you prove the quantified
form.
-When |SSR| rewrite fails on standard |Coq| licit rewrite
+When |SSR| rewrite fails on standard Coq licit rewrite
````````````````````````````````````````````````````````
In a few cases, the |SSR| rewrite tactic fails rewriting some
-redexes which standard |Coq| successfully rewrites. There are two main
+redexes which standard Coq successfully rewrites. There are two main
cases:
@@ -3550,7 +3553,7 @@ cases:
Lemma fubar (x : unit) : (let u := x in u) = tt.
-+ The standard rewrite tactic provided by |Coq| uses a different algorithm
++ The standard rewrite tactic provided by Coq uses a different algorithm
to find instances of the rewrite rule.
.. example::
@@ -3953,7 +3956,7 @@ together with “term tagging” operations.
The first one uses auxiliary definitions to introduce a provably equal
copy of any term t. However this copy is (on purpose) *not
-convertible* to t in the |Coq| system [#8]_. The job is done by the
+convertible* to t in the Coq system [#8]_. The job is done by the
following construction:
.. coqdoc::
@@ -4542,7 +4545,7 @@ is a synonym for:
elim x using V; clear x; intro y.
where ``x`` is a variable in the context, ``y`` a fresh name and ``V``
-any second order lemma; |SSR| relaxes the syntactic restrictions of the |Coq|
+any second order lemma; |SSR| relaxes the syntactic restrictions of the Coq
``elim``. The first pattern following ``:`` can be a ``_`` wildcard if the
conclusion of the view ``V`` specifies a pattern for its last argument
(e.g., if ``V`` is a functional induction lemma generated by the
@@ -4590,7 +4593,7 @@ generation (see section :ref:`generation_of_equations_ssr`).
elim/last_ind_list E : l=> [| u v]; last first.
-User-provided eliminators (potentially generated with |Coq|’s ``Function``
+User-provided eliminators (potentially generated with Coq’s ``Function``
command) can be combined with the type family switches described
in section :ref:`type_families_ssr`.
Consider an eliminator ``foo_ind`` of type:
@@ -4982,8 +4985,8 @@ distinction between logical propositions and boolean values. On the
one hand, logical propositions are objects of *sort* ``Prop`` which is
the carrier of intuitionistic reasoning. Logical connectives in
``Prop`` are *types*, which give precise information on the structure
-of their proofs; this information is automatically exploited by |Coq|
-tactics. For example, |Coq| knows that a proof of ``A \/ B`` is
+of their proofs; this information is automatically exploited by Coq
+tactics. For example, Coq knows that a proof of ``A \/ B`` is
either a proof of ``A`` or a proof of ``B``. The tactics ``left`` and
``right`` change the goal ``A \/ B`` to ``A`` and ``B``, respectively;
dually, the tactic ``case`` reduces the goal ``A \/ B => G`` to two
@@ -5042,7 +5045,7 @@ mechanism:
Coercion is_true (b : bool) := b = true.
-This allows any boolean formula ``b`` to be used in a context where |Coq|
+This allows any boolean formula ``b`` to be used in a context where Coq
would expect a proposition, e.g., after ``Lemma … :``. It is then
interpreted as ``(is_true b)``, i.e., the proposition ``b = true``. Coercions
are elided by the pretty-printer, so they are essentially transparent
@@ -5077,9 +5080,9 @@ proposition ``b1 /\ b2`` hides two coercions. The conjunction of
Expressing logical equivalences through this family of inductive types
makes possible to take benefit from *rewritable equations* associated
-to the case analysis of |Coq|’s inductive types.
+to the case analysis of Coq’s inductive types.
-Since the equivalence predicate is defined in |Coq| as:
+Since the equivalence predicate is defined in Coq as:
.. coqdoc::
@@ -5573,7 +5576,7 @@ Natural number
.. prodn:: nat_or_ident ::= {| @natural | @ident }
-where :token:`ident` is an Ltac variable denoting a standard |Coq| number
+where :token:`ident` is an Ltac variable denoting a standard Coq number
(should not be the name of a tactic which can be followed by a
bracket ``[``, like ``do``, ``have``,…)
@@ -5724,11 +5727,11 @@ respectively.
local function definition
-.. tacv:: pose fix @fix_body
+.. tacv:: pose fix @fix_decl
local fix definition
-.. tacv:: pose cofix @fix_body
+.. tacv:: pose cofix @fix_decl
local cofix definition
@@ -5823,6 +5826,6 @@ Settings
.. [#8] This is an implementation feature: there is no such obstruction
in the metatheory
.. [#9] The current state of the proof shall be displayed by the Show
- Proof command of |Coq| proof mode.
+ Proof command of Coq proof mode.
.. [#10] A simple proof context entry is a naked identifier (i.e. not between
parentheses) designating a context entry that is not a section variable.
diff --git a/doc/sphinx/proof-engine/tactics.rst b/doc/sphinx/proof-engine/tactics.rst
index 4b1f312105..26a56005c1 100644
--- a/doc/sphinx/proof-engine/tactics.rst
+++ b/doc/sphinx/proof-engine/tactics.rst
@@ -86,42 +86,36 @@ specified, the default selector is used.
Although other selectors are available, only ``all``, ``!`` or a
single natural number are valid default goal selectors.
-.. _bindingslist:
+.. _bindings:
-Bindings list
-~~~~~~~~~~~~~
+Bindings
+~~~~~~~~
-Tactics that take a term as an argument may also support a bindings list
+Tactics that take a term as an argument may also accept :token:`bindings`
to instantiate some parameters of the term by name or position.
-The general form of a term with a bindings list is
-:n:`@term with @bindings_list` where :token:`bindings_list` can take two different forms:
+The general form of a term with :token:`bindings` is
+:n:`@term__tac with @bindings` where :token:`bindings` can take two different forms:
-.. _bindings_list_grammar:
+ .. insertprodn bindings bindings
.. prodn::
- ref ::= @ident
- | @natural
- bindings_list ::= {+ (@ref := @term) }
- | {+ @term }
-
-+ In a bindings list of the form :n:`{+ (@ref:= @term)}`, :n:`@ref` is either an
- :n:`@ident` or a :n:`@natural`. The references are determined according to the type of
- :n:`@term`. If :n:`@ref` is an identifier, this identifier has to be bound in the
- type of :n:`@term` and the binding provides the tactic with an instance for the
- parameter of this name. If :n:`@ref` is a number ``n``, it refers to
- the ``n``-th non dependent premise of the :n:`@term`, as determined by the type
- of :n:`@term`.
+ bindings ::= {+ ( {| @ident | @natural } := @term ) }
+ | {+ @one_term }
+
++ In the first form, if an :token:`ident` is specified, it must be bound in the
+ type of :n:`@term` and provides the tactic with an instance for the
+ parameter of this name. If a :token:`natural` is specified, it refers to
+ the ``n``-th non dependent premise of :n:`@term__tac`.
.. exn:: No such binder.
:undocumented:
-+ A bindings list can also be a simple list of terms :n:`{* @term}`.
- In that case the references to which these terms correspond are
- determined by the tactic. In case of :tacn:`induction`, :tacn:`destruct`, :tacn:`elim`
- and :tacn:`case`, the terms have to
- provide instances for all the dependent products in the type of term while in
++ In the second form, the interpretation of the :token:`one_term`\s depend on which
+ tactic they appear in. For :tacn:`induction`, :tacn:`destruct`, :tacn:`elim`
+ and :tacn:`case`, the :token:`one_term`\s
+ provide instances for all the dependent products in the type of :n:`@term__tac` while in
the case of :tacn:`apply`, or of :tacn:`constructor` and its variants, only instances
- for the dependent products that are not bound in the conclusion of the type
+ for the dependent products that are not bound in the conclusion of :n:`@term__tac`
are required.
.. exn:: Not the right number of missing arguments.
@@ -274,7 +268,7 @@ These patterns can be used when the hypothesis is an equality:
For :n:`intros @intropattern_list`, controls how to handle a
conjunctive pattern that doesn't give enough simple patterns to match
- all the arguments in the constructor. If set (the default), |Coq| generates
+ all the arguments in the constructor. If set (the default), Coq generates
additional names to match the number of arguments.
Unsetting the flag will put the additional hypotheses in the goal instead, behavior that is more
similar to |SSR|'s intro patterns.
@@ -682,11 +676,11 @@ Applying theorems
.. exn:: Not the right number of missing arguments.
:undocumented:
- .. tacv:: apply @term with @bindings_list
+ .. tacv:: apply @term with @bindings
This also provides apply with values for instantiating premises. Here, variables
are referred by names and non-dependent products by increasing numbers (see
- :ref:`bindings list <bindingslist>`).
+ :ref:`bindings`).
.. tacv:: apply {+, @term}
@@ -747,8 +741,8 @@ Applying theorems
tactics that backtrack often. Moreover, it does not traverse tuples as :tacn:`apply`
does.
- .. tacv:: {? simple} apply {+, @term {? with @bindings_list}}
- {? simple} eapply {+, @term {? with @bindings_list}}
+ .. tacv:: {? simple} apply {+, @term {? with @bindings}}
+ {? simple} eapply {+, @term {? with @bindings}}
:name: simple apply; simple eapply
This summarizes the different syntaxes for :tacn:`apply` and :tacn:`eapply`.
@@ -888,18 +882,18 @@ Applying theorems
This applies each :token:`term` in sequence in :token:`ident`.
- .. tacv:: apply {+, @term with @bindings_list} in @ident
+ .. tacv:: apply {+, @term with @bindings} in @ident
This does the same but uses the bindings in each :n:`(@ident := @term)` to
instantiate the parameters of the corresponding type of :token:`term`
- (see :ref:`bindings list <bindingslist>`).
+ (see :ref:`bindings`).
- .. tacv:: eapply {+, @term {? with @bindings_list } } in @ident
+ .. tacv:: eapply {+, @term {? with @bindings } } in @ident
This works as :tacn:`apply … in` but turns unresolved bindings into
existential variables, if any, instead of failing.
- .. tacv:: apply {+, @term {? with @bindings_list } } in @ident as @simple_intropattern
+ .. tacv:: apply {+, @term {? with @bindings } } in @ident as @simple_intropattern
:name: apply … in … as
This works as :tacn:`apply … in` then applies the :token:`simple_intropattern`
@@ -911,8 +905,8 @@ Applying theorems
only on subterms that contain no variables to instantiate and does not
traverse tuples. See :ref:`the corresponding example <simple_apply_ex>`.
- .. tacv:: {? simple} apply {+, @term {? with @bindings_list}} in @ident {? as @simple_intropattern}
- {? simple} eapply {+, @term {? with @bindings_list}} in @ident {? as @simple_intropattern}
+ .. tacv:: {? simple} apply {+, @term {? with @bindings}} in @ident {? as @simple_intropattern}
+ {? simple} eapply {+, @term {? with @bindings}} in @ident {? as @simple_intropattern}
This summarizes the different syntactic variants of :n:`apply @term in @ident`
and :n:`eapply @term in @ident`.
@@ -938,48 +932,48 @@ Applying theorems
:g:`constructor n` where ``n`` is the number of constructors of the head
of the goal.
- .. tacv:: constructor @natural with @bindings_list
+ .. tacv:: constructor @natural with @bindings
Let ``c`` be the i-th constructor of :g:`I`, then
- :n:`constructor i with @bindings_list` is equivalent to
- :n:`intros; apply c with @bindings_list`.
+ :n:`constructor i with @bindings` is equivalent to
+ :n:`intros; apply c with @bindings`.
.. warning::
- The terms in the :token:`bindings_list` are checked in the context
+ The terms in :token:`bindings` are checked in the context
where constructor is executed and not in the context where :tacn:`apply`
is executed (the introductions are not taken into account).
- .. tacv:: split {? with @bindings_list }
+ .. tacv:: split {? with @bindings }
:name: split
This applies only if :g:`I` has a single constructor. It is then
- equivalent to :n:`constructor 1 {? with @bindings_list }`. It is
+ equivalent to :n:`constructor 1 {? with @bindings }`. It is
typically used in the case of a conjunction :math:`A \wedge B`.
- .. tacv:: exists @bindings_list
+ .. tacv:: exists @bindings
:name: exists
This applies only if :g:`I` has a single constructor. It is then equivalent
- to :n:`intros; constructor 1 with @bindings_list.` It is typically used in
+ to :n:`intros; constructor 1 with @bindings.` It is typically used in
the case of an existential quantification :math:`\exists x, P(x).`
- .. tacv:: exists {+, @bindings_list }
+ .. tacv:: exists {+, @bindings }
- This iteratively applies :n:`exists @bindings_list`.
+ This iteratively applies :n:`exists @bindings`.
.. exn:: Not an inductive goal with 1 constructor.
:undocumented:
- .. tacv:: left {? with @bindings_list }
- right {? with @bindings_list }
+ .. tacv:: left {? with @bindings }
+ right {? with @bindings }
:name: left; right
These tactics apply only if :g:`I` has two constructors, for
instance in the case of a disjunction :math:`A \vee B`.
Then, they are respectively equivalent to
- :n:`constructor 1 {? with @bindings_list }` and
- :n:`constructor 2 {? with @bindings_list }`.
+ :n:`constructor 1 {? with @bindings }` and
+ :n:`constructor 2 {? with @bindings }`.
.. exn:: Not an inductive goal with 2 constructors.
:undocumented:
@@ -1518,13 +1512,13 @@ Controlling the proof flow
list of remaining subgoal to prove.
.. tacv:: specialize (@ident {* @term}) {? as @simple_intropattern}
- specialize @ident with @bindings_list {? as @simple_intropattern}
+ specialize @ident with @bindings {? as @simple_intropattern}
:name: specialize; _
This tactic works on local hypothesis :n:`@ident`. The
premises of this hypothesis (either universal quantifications or
non-dependent implications) are instantiated by concrete terms coming either
- from arguments :n:`{* @term}` or from a :ref:`bindings list <bindingslist>`.
+ from arguments :n:`{* @term}` or from :ref:`bindings`.
In the first form the application to :n:`{* @term}` can be partial. The
first form is equivalent to :n:`assert (@ident := @ident {* @term})`. In the
second form, instantiation elements can also be partial. In this case the
@@ -1767,7 +1761,7 @@ analysis on inductive or co-inductive objects (see :ref:`inductive-definitions`)
by :token:`naming_intropattern` (see :tacn:`intros`),
in particular ``?`` can be used to let Coq generate a fresh name.
- .. tacv:: destruct @term with @bindings_list
+ .. tacv:: destruct @term with @bindings
This behaves like :n:`destruct @term` providing explicit instances for
the dependent premises of the type of :token:`term`.
@@ -1781,9 +1775,9 @@ analysis on inductive or co-inductive objects (see :ref:`inductive-definitions`)
are left as existential variables to be inferred later, in the same way
as :tacn:`eapply` does.
- .. tacv:: destruct @term using @term {? with @bindings_list }
+ .. tacv:: destruct @term using @term {? with @bindings }
- This is synonym of :n:`induction @term using @term {? with @bindings_list }`.
+ This is synonym of :n:`induction @term using @term {? with @bindings }`.
.. tacv:: destruct @term in @goal_occurrences
@@ -1792,8 +1786,8 @@ analysis on inductive or co-inductive objects (see :ref:`inductive-definitions`)
clause is an occurrence clause whose syntax and behavior is described
in :ref:`occurrences sets <occurrencessets>`.
- .. tacv:: destruct @term {? with @bindings_list } {? as @or_and_intropattern_loc } {? eqn:@naming_intropattern } {? using @term {? with @bindings_list } } {? in @goal_occurrences }
- edestruct @term {? with @bindings_list } {? as @or_and_intropattern_loc } {? eqn:@naming_intropattern } {? using @term {? with @bindings_list } } {? in @goal_occurrences }
+ .. tacv:: destruct @term {? with @bindings } {? as @or_and_intropattern_loc } {? eqn:@naming_intropattern } {? using @term {? with @bindings } } {? in @goal_occurrences }
+ edestruct @term {? with @bindings } {? as @or_and_intropattern_loc } {? eqn:@naming_intropattern } {? using @term {? with @bindings } } {? in @goal_occurrences }
These are the general forms of :tacn:`destruct` and :tacn:`edestruct`.
They combine the effects of the ``with``, ``as``, ``eqn:``, ``using``,
@@ -1806,15 +1800,15 @@ analysis on inductive or co-inductive objects (see :ref:`inductive-definitions`)
recursion. It behaves as :n:`elim @term` but using a case-analysis
elimination principle and not a recursive one.
-.. tacv:: case @term with @bindings_list
+.. tacv:: case @term with @bindings
- Analogous to :n:`elim @term with @bindings_list` above.
+ Analogous to :n:`elim @term with @bindings` above.
-.. tacv:: ecase @term {? with @bindings_list }
+.. tacv:: ecase @term {? with @bindings }
:name: ecase
In case the type of :n:`@term` has dependent premises, or dependent premises
- whose values are not inferable from the :n:`with @bindings_list` clause,
+ whose values are not inferable from the :n:`with @bindings` clause,
:n:`ecase` turns them into existential variables to be resolved later on.
.. tacv:: simple destruct @ident
@@ -1906,10 +1900,10 @@ analysis on inductive or co-inductive objects (see :ref:`inductive-definitions`)
:n:`(p`:sub:`1` :n:`, ... , p`:sub:`n` :n:`)` can be used instead of
:n:`[ p`:sub:`1` :n:`... p`:sub:`n` :n:`]`.
-.. tacv:: induction @term with @bindings_list
+.. tacv:: induction @term with @bindings
This behaves like :tacn:`induction` providing explicit instances for the
- premises of the type of :n:`term` (see :ref:`bindings list <bindingslist>`).
+ premises of the type of :n:`term` (see :ref:`bindings`).
.. tacv:: einduction @term
:name: einduction
@@ -1926,7 +1920,7 @@ analysis on inductive or co-inductive objects (see :ref:`inductive-definitions`)
It does not expect the conclusion of the type of the first :n:`@term` to be
inductive.
-.. tacv:: induction @term using @term with @bindings_list
+.. tacv:: induction @term using @term with @bindings
This behaves as :tacn:`induction … using …` but also providing instances
for the premises of the type of the second :n:`@term`.
@@ -1954,8 +1948,8 @@ analysis on inductive or co-inductive objects (see :ref:`inductive-definitions`)
induction y in x |- *.
Show 2.
-.. tacv:: induction @term with @bindings_list as @or_and_intropattern_loc using @term with @bindings_list in @goal_occurrences
- einduction @term with @bindings_list as @or_and_intropattern_loc using @term with @bindings_list in @goal_occurrences
+.. tacv:: induction @term with @bindings as @or_and_intropattern_loc using @term with @bindings in @goal_occurrences
+ einduction @term with @bindings as @or_and_intropattern_loc using @term with @bindings in @goal_occurrences
These are the most general forms of :tacn:`induction` and :tacn:`einduction`. It combines the
effects of the with, as, using, and in clauses.
@@ -1978,11 +1972,11 @@ analysis on inductive or co-inductive objects (see :ref:`inductive-definitions`)
products, the tactic tries to find an instance for which the elimination
lemma applies and fails otherwise.
-.. tacv:: elim @term with @bindings_list
+.. tacv:: elim @term with @bindings
:name: elim … with
Allows to give explicit instances to the premises of the type of :n:`@term`
- (see :ref:`bindings list <bindingslist>`).
+ (see :ref:`bindings`).
.. tacv:: eelim @term
:name: eelim
@@ -1991,15 +1985,15 @@ analysis on inductive or co-inductive objects (see :ref:`inductive-definitions`)
existential variables to be resolved later on.
.. tacv:: elim @term using @term
- elim @term using @term with @bindings_list
+ elim @term using @term with @bindings
Allows the user to give explicitly an induction principle :n:`@term` that
is not the standard one for the underlying inductive type of :n:`@term`. The
- :n:`@bindings_list` clause allows instantiating premises of the type of
+ :n:`@bindings` clause allows instantiating premises of the type of
:n:`@term`.
-.. tacv:: elim @term with @bindings_list using @term with @bindings_list
- eelim @term with @bindings_list using @term with @bindings_list
+.. tacv:: elim @term with @bindings using @term with @bindings
+ eelim @term with @bindings using @term with @bindings
These are the most general forms of :tacn:`elim` and :tacn:`eelim`. It combines the
effects of the ``using`` clause and of the two uses of the ``with`` clause.
@@ -2148,13 +2142,13 @@ and an explanation of the underlying technique.
:n:`discriminate @ident` where :n:`@ident` is the identifier for the last
introduced hypothesis.
-.. tacv:: discriminate @term with @bindings_list
+.. tacv:: discriminate @term with @bindings
This does the same thing as :n:`discriminate @term` but using the given
bindings to instantiate parameters or hypotheses of :n:`@term`.
.. tacv:: ediscriminate @natural
- ediscriminate @term {? with @bindings_list}
+ ediscriminate @term {? with @bindings}
:name: ediscriminate; _
This works the same as :tacn:`discriminate` but if the type of :token:`term`, or the
@@ -2212,7 +2206,7 @@ and an explanation of the underlying technique.
different types :g:`(P t`:sub:`1` :g:`... t`:sub:`n` :g:`)` and
:g:`(P u`:sub:`1` :g:`... u`:sub:`n` :sub:`)`. If :g:`t`:sub:`1` and
:g:`u`:sub:`1` are the same and have for type an inductive type for which a decidable
- equality has been declared using the command :cmd:`Scheme Equality`
+ equality has been declared using :cmd:`Scheme` :n:`Equality ...`
(see :ref:`proofschemes-induction-principles`),
the use of a sigma type is avoided.
@@ -2237,13 +2231,13 @@ and an explanation of the underlying technique.
:n:`injection @ident` where :n:`@ident` is the identifier for the last
introduced hypothesis.
- .. tacv:: injection @term with @bindings_list
+ .. tacv:: injection @term with @bindings
This does the same as :n:`injection @term` but using the given bindings to
instantiate parameters or hypotheses of :n:`@term`.
.. tacv:: einjection @natural
- einjection @term {? with @bindings_list}
+ einjection @term {? with @bindings}
:name: einjection; _
This works the same as :n:`injection` but if the type of :n:`@term`, or the
@@ -2258,10 +2252,10 @@ and an explanation of the underlying technique.
.. exn:: goal does not satisfy the expected preconditions.
:undocumented:
- .. tacv:: injection @term {? with @bindings_list} as {+ @simple_intropattern}
+ .. tacv:: injection @term {? with @bindings} as {+ @simple_intropattern}
injection @natural as {+ @simple_intropattern}
injection as {+ @simple_intropattern}
- einjection @term {? with @bindings_list} as {+ @simple_intropattern}
+ einjection @term {? with @bindings} as {+ @simple_intropattern}
einjection @natural as {+ @simple_intropattern}
einjection as {+ @simple_intropattern}
@@ -2273,10 +2267,10 @@ and an explanation of the underlying technique.
to the number of new equalities. The original equality is erased if it
corresponds to a hypothesis.
- .. tacv:: injection @term {? with @bindings_list} as @injection_intropattern
+ .. tacv:: injection @term {? with @bindings} as @injection_intropattern
injection @natural as @injection_intropattern
injection as @injection_intropattern
- einjection @term {? with @bindings_list} as @injection_intropattern
+ einjection @term {? with @bindings} as @injection_intropattern
einjection @natural as @injection_intropattern
einjection as @injection_intropattern
@@ -2669,1760 +2663,6 @@ and an explanation of the underlying technique.
simultaneously proved are respectively :g:`forall binder ... binder, type`
The identifiers :n:`@ident` are the names of the coinduction hypotheses.
-.. _rewritingexpressions:
-
-Rewriting expressions
----------------------
-
-These tactics use the equality :g:`eq:forall A:Type, A->A->Prop` defined in
-file ``Logic.v`` (see :ref:`coq-library-logic`). The notation for :g:`eq T t u` is
-simply :g:`t=u` dropping the implicit type of :g:`t` and :g:`u`.
-
-.. tacn:: rewrite @term
- :name: rewrite
-
- This tactic applies to any goal. The type of :token:`term` must have the form
-
- ``forall (x``:sub:`1` ``:A``:sub:`1` ``) ... (x``:sub:`n` ``:A``:sub:`n` ``), eq term``:sub:`1` ``term``:sub:`2` ``.``
-
- where :g:`eq` is the Leibniz equality or a registered setoid equality.
-
- Then :n:`rewrite @term` finds the first subterm matching `term`\ :sub:`1` in the goal,
- resulting in instances `term`:sub:`1`' and `term`:sub:`2`' and then
- replaces every occurrence of `term`:subscript:`1`' by `term`:subscript:`2`'.
- Hence, some of the variables :g:`x`\ :sub:`i` are solved by unification,
- and some of the types :g:`A`\ :sub:`1`:g:`, ..., A`\ :sub:`n` become new
- subgoals.
-
- .. exn:: The @term provided does not end with an equation.
- :undocumented:
-
- .. exn:: Tactic generated a subgoal identical to the original goal. This happens if @term does not occur in the goal.
- :undocumented:
-
- .. tacv:: rewrite -> @term
-
- Is equivalent to :n:`rewrite @term`
-
- .. tacv:: rewrite <- @term
-
- Uses the equality :n:`@term`:sub:`1` :n:`= @term` :sub:`2` from right to left
-
- .. tacv:: rewrite @term in @goal_occurrences
-
- Analogous to :n:`rewrite @term` but rewriting is done following
- the clause :token:`goal_occurrences`. For instance:
-
- + :n:`rewrite H in H'` will rewrite `H` in the hypothesis
- ``H'`` instead of the current goal.
- + :n:`rewrite H in H' at 1, H'' at - 2 |- *` means
- :n:`rewrite H; rewrite H in H' at 1; rewrite H in H'' at - 2.`
- In particular a failure will happen if any of these three simpler tactics
- fails.
- + :n:`rewrite H in * |-` will do :n:`rewrite H in H'` for all hypotheses
- :g:`H'` different from :g:`H`.
- A success will happen as soon as at least one of these simpler tactics succeeds.
- + :n:`rewrite H in *` is a combination of :n:`rewrite H` and :n:`rewrite H in * |-`
- that succeeds if at least one of these two tactics succeeds.
-
- Orientation :g:`->` or :g:`<-` can be inserted before the :token:`term` to rewrite.
-
- .. tacv:: rewrite @term at @occurrences
-
- Rewrite only the given :token:`occurrences` of :token:`term`. Occurrences are
- specified from left to right as for pattern (:tacn:`pattern`). The rewrite is
- always performed using setoid rewriting, even for Leibniz’s equality, so one
- has to ``Import Setoid`` to use this variant.
-
- .. tacv:: rewrite @term by @tactic
-
- Use tactic to completely solve the side-conditions arising from the
- :tacn:`rewrite`.
-
- .. tacv:: rewrite {+, @orientation @term} {? in @ident }
-
- Is equivalent to the `n` successive tactics :n:`{+; rewrite @term}`, each one
- working on the first subgoal generated by the previous one. An :production:`orientation`
- ``->`` or ``<-`` can be inserted before each :token:`term` to rewrite. One
- unique clause can be added at the end after the keyword in; it will then
- affect all rewrite operations.
-
- In all forms of rewrite described above, a :token:`term` to rewrite can be
- immediately prefixed by one of the following modifiers:
-
- + `?` : the tactic :n:`rewrite ?@term` performs the rewrite of :token:`term` as many
- times as possible (perhaps zero time). This form never fails.
- + :n:`@natural?` : works similarly, except that it will do at most :token:`natural` rewrites.
- + `!` : works as `?`, except that at least one rewrite should succeed, otherwise
- the tactic fails.
- + :n:`@natural!` (or simply :n:`@natural`) : precisely :token:`natural` rewrites of :token:`term` will be done,
- leading to failure if these :token:`natural` rewrites are not possible.
-
- .. tacv:: erewrite @term
- :name: erewrite
-
- This tactic works as :n:`rewrite @term` but turning
- unresolved bindings into existential variables, if any, instead of
- failing. It has the same variants as :tacn:`rewrite` has.
-
- .. flag:: Keyed Unification
-
- Makes higher-order unification used by :tacn:`rewrite` rely on a set of keys to drive
- unification. The subterms, considered as rewriting candidates, must start with
- the same key as the left- or right-hand side of the lemma given to rewrite, and the arguments
- are then unified up to full reduction.
-
-.. tacn:: replace @term with @term’
- :name: replace
-
- This tactic applies to any goal. It replaces all free occurrences of :n:`@term`
- in the current goal with :n:`@term’` and generates an equality :n:`@term = @term’`
- as a subgoal. This equality is automatically solved if it occurs among
- the assumptions, or if its symmetric form occurs. It is equivalent to
- :n:`cut @term = @term’; [intro H`:sub:`n` :n:`; rewrite <- H`:sub:`n` :n:`; clear H`:sub:`n`:n:`|| assumption || symmetry; try assumption]`.
-
- .. exn:: Terms do not have convertible types.
- :undocumented:
-
- .. tacv:: replace @term with @term’ by @tactic
-
- This acts as :n:`replace @term with @term’` but applies :token:`tactic` to solve the generated
- subgoal :n:`@term = @term’`.
-
- .. tacv:: replace @term
-
- Replaces :n:`@term` with :n:`@term’` using the first assumption whose type has
- the form :n:`@term = @term’` or :n:`@term’ = @term`.
-
- .. tacv:: replace -> @term
-
- Replaces :n:`@term` with :n:`@term’` using the first assumption whose type has
- the form :n:`@term = @term’`
-
- .. tacv:: replace <- @term
-
- Replaces :n:`@term` with :n:`@term’` using the first assumption whose type has
- the form :n:`@term’ = @term`
-
- .. tacv:: replace @term {? with @term} in @goal_occurrences {? by @tactic}
- replace -> @term in @goal_occurrences
- replace <- @term in @goal_occurrences
-
- Acts as before but the replacements take place in the specified clauses
- (:token:`goal_occurrences`) (see :ref:`performingcomputations`) and not
- only in the conclusion of the goal. The clause argument must not contain
- any ``type of`` nor ``value of``.
-
-.. tacn:: subst @ident
- :name: subst
-
- This tactic applies to a goal that has :n:`@ident` in its context and (at
- least) one hypothesis, say :g:`H`, of type :n:`@ident = t` or :n:`t = @ident`
- with :n:`@ident` not occurring in :g:`t`. Then it replaces :n:`@ident` by
- :g:`t` everywhere in the goal (in the hypotheses and in the conclusion) and
- clears :n:`@ident` and :g:`H` from the context.
-
- If :n:`@ident` is a local definition of the form :n:`@ident := t`, it is also
- unfolded and cleared.
-
- If :n:`@ident` is a section variable it is expected to have no
- indirect occurrences in the goal, i.e. that no global declarations
- implicitly depending on the section variable must be present in the
- goal.
-
- .. note::
- + When several hypotheses have the form :n:`@ident = t` or :n:`t = @ident`, the
- first one is used.
-
- + If :g:`H` is itself dependent in the goal, it is replaced by the proof of
- reflexivity of equality.
-
- .. tacv:: subst {+ @ident}
-
- This is equivalent to :n:`subst @ident`:sub:`1`:n:`; ...; subst @ident`:sub:`n`.
-
- .. tacv:: subst
-
- This applies :tacn:`subst` repeatedly from top to bottom to all hypotheses of the
- context for which an equality of the form :n:`@ident = t` or :n:`t = @ident`
- or :n:`@ident := t` exists, with :n:`@ident` not occurring in
- ``t`` and :n:`@ident` not a section variable with indirect
- dependencies in the goal.
-
- .. flag:: Regular Subst Tactic
-
- This flag controls the behavior of :tacn:`subst`. When it is
- activated (it is by default), :tacn:`subst` also deals with the following corner cases:
-
- + A context with ordered hypotheses :n:`@ident`:sub:`1` :n:`= @ident`:sub:`2`
- and :n:`@ident`:sub:`1` :n:`= t`, or :n:`t′ = @ident`:sub:`1`` with `t′` not
- a variable, and no other hypotheses of the form :n:`@ident`:sub:`2` :n:`= u`
- or :n:`u = @ident`:sub:`2`; without the flag, a second call to
- subst would be necessary to replace :n:`@ident`:sub:`2` by `t` or
- `t′` respectively.
- + The presence of a recursive equation which without the flag would
- be a cause of failure of :tacn:`subst`.
- + A context with cyclic dependencies as with hypotheses :n:`@ident`:sub:`1` :n:`= f @ident`:sub:`2`
- and :n:`@ident`:sub:`2` :n:`= g @ident`:sub:`1` which without the
- flag would be a cause of failure of :tacn:`subst`.
-
- Additionally, it prevents a local definition such as :n:`@ident := t` to be
- unfolded which otherwise it would exceptionally unfold in configurations
- containing hypotheses of the form :n:`@ident = u`, or :n:`u′ = @ident`
- with `u′` not a variable. Finally, it preserves the initial order of
- hypotheses, which without the flag it may break.
- default.
-
- .. exn:: Cannot find any non-recursive equality over :n:`@ident`.
- :undocumented:
-
- .. exn:: Section variable :n:`@ident` occurs implicitly in global declaration :n:`@qualid` present in hypothesis :n:`@ident`.
- Section variable :n:`@ident` occurs implicitly in global declaration :n:`@qualid` present in the conclusion.
-
- Raised when the variable is a section variable with indirect
- dependencies in the goal.
-
-
-.. tacn:: stepl @term
- :name: stepl
-
- This tactic is for chaining rewriting steps. It assumes a goal of the
- form :n:`R @term @term` where ``R`` is a binary relation and relies on a
- database of lemmas of the form :g:`forall x y z, R x y -> eq x z -> R z y`
- where `eq` is typically a setoid equality. The application of :n:`stepl @term`
- then replaces the goal by :n:`R @term @term` and adds a new goal stating
- :n:`eq @term @term`.
-
- .. cmd:: Declare Left Step @term
-
- Adds :n:`@term` to the database used by :tacn:`stepl`.
-
- This tactic is especially useful for parametric setoids which are not accepted
- as regular setoids for :tacn:`rewrite` and :tacn:`setoid_replace` (see
- :ref:`Generalizedrewriting`).
-
- .. tacv:: stepl @term by @tactic
-
- This applies :n:`stepl @term` then applies :token:`tactic` to the second goal.
-
- .. tacv:: stepr @term by @tactic
- :name: stepr
-
- This behaves as :tacn:`stepl` but on the right-hand-side of the binary
- relation. Lemmas are expected to be of the form
- :g:`forall x y z, R x y -> eq y z -> R x z`.
-
- .. cmd:: Declare Right Step @term
-
- Adds :n:`@term` to the database used by :tacn:`stepr`.
-
-
-.. tacn:: change @term
- :name: change
-
- This tactic applies to any goal. It implements the rule ``Conv`` given in
- :ref:`subtyping-rules`. :g:`change U` replaces the current goal `T`
- with `U` providing that `U` is well-formed and that `T` and `U` are
- convertible.
-
- .. exn:: Not convertible.
- :undocumented:
-
- .. tacv:: change @term with @term’
-
- This replaces the occurrences of :n:`@term` by :n:`@term’` in the current goal.
- The term :n:`@term` and :n:`@term’` must be convertible.
-
- .. tacv:: change @term at {+ @natural} with @term’
-
- This replaces the occurrences numbered :n:`{+ @natural}` of :n:`@term` by :n:`@term’`
- in the current goal. The terms :n:`@term` and :n:`@term’` must be convertible.
-
- .. exn:: Too few occurrences.
- :undocumented:
-
- .. tacv:: change @term {? {? at {+ @natural}} with @term} in @ident
-
- This applies the :tacn:`change` tactic not to the goal but to the hypothesis :n:`@ident`.
-
- .. tacv:: now_show @term
-
- This is a synonym of :n:`change @term`. It can be used to
- make some proof steps explicit when refactoring a proof script
- to make it readable.
-
- .. seealso:: :ref:`Performing computations <performingcomputations>`
-
-.. _performingcomputations:
-
-Performing computations
----------------------------
-
-.. insertprodn red_expr pattern_occ
-
-.. prodn::
- red_expr ::= red
- | hnf
- | simpl {? @delta_flag } {? @ref_or_pattern_occ }
- | cbv {? @strategy_flag }
- | cbn {? @strategy_flag }
- | lazy {? @strategy_flag }
- | compute {? @delta_flag }
- | vm_compute {? @ref_or_pattern_occ }
- | native_compute {? @ref_or_pattern_occ }
- | unfold {+, @unfold_occ }
- | fold {+ @one_term }
- | pattern {+, @pattern_occ }
- | @ident
- delta_flag ::= {? - } [ {+ @reference } ]
- strategy_flag ::= {+ @red_flag }
- | @delta_flag
- red_flag ::= beta
- | iota
- | match
- | fix
- | cofix
- | zeta
- | delta {? @delta_flag }
- ref_or_pattern_occ ::= @reference {? at @occs_nums }
- | @one_term {? at @occs_nums }
- occs_nums ::= {+ {| @natural | @ident } }
- | - {| @natural | @ident } {* @int_or_var }
- int_or_var ::= @integer
- | @ident
- unfold_occ ::= @reference {? at @occs_nums }
- pattern_occ ::= @one_term {? at @occs_nums }
-
-This set of tactics implements different specialized usages of the
-tactic :tacn:`change`.
-
-All conversion tactics (including :tacn:`change`) can be parameterized by the
-parts of the goal where the conversion can occur. This is done using
-*goal clauses* which consists in a list of hypotheses and, optionally,
-of a reference to the conclusion of the goal. For defined hypothesis
-it is possible to specify if the conversion should occur on the type
-part, the body part or both (default).
-
-Goal clauses are written after a conversion tactic (tactics :tacn:`set`,
-:tacn:`rewrite`, :tacn:`replace` and :tacn:`autorewrite` also use goal
-clauses) and are introduced by the keyword `in`. If no goal clause is
-provided, the default is to perform the conversion only in the
-conclusion.
-
-The syntax and description of the various goal clauses is the
-following:
-
-+ :n:`in {+ @ident} |-` only in hypotheses :n:`{+ @ident}`
-+ :n:`in {+ @ident} |- *` in hypotheses :n:`{+ @ident}` and in the
- conclusion
-+ :n:`in * |-` in every hypothesis
-+ :n:`in *` (equivalent to in :n:`* |- *`) everywhere
-+ :n:`in (type of @ident) (value of @ident) ... |-` in type part of
- :n:`@ident`, in the value part of :n:`@ident`, etc.
-
-For backward compatibility, the notation :n:`in {+ @ident}` performs
-the conversion in hypotheses :n:`{+ @ident}`.
-
-.. tacn:: cbv {? @strategy_flag }
- lazy {? @strategy_flag }
- :name: cbv; lazy
-
- These parameterized reduction tactics apply to any goal and perform
- the normalization of the goal according to the specified flags. In
- correspondence with the kinds of reduction considered in Coq namely
- :math:`\beta` (reduction of functional application), :math:`\delta`
- (unfolding of transparent constants, see :ref:`vernac-controlling-the-reduction-strategies`),
- :math:`\iota` (reduction of
- pattern matching over a constructed term, and unfolding of :g:`fix` and
- :g:`cofix` expressions) and :math:`\zeta` (contraction of local definitions), the
- flags are either ``beta``, ``delta``, ``match``, ``fix``, ``cofix``,
- ``iota`` or ``zeta``. The ``iota`` flag is a shorthand for ``match``, ``fix``
- and ``cofix``. The ``delta`` flag itself can be refined into
- :n:`delta [ {+ @qualid} ]` or :n:`delta - [ {+ @qualid} ]`, restricting in the first
- case the constants to unfold to the constants listed, and restricting in the
- second case the constant to unfold to all but the ones explicitly mentioned.
- Notice that the ``delta`` flag does not apply to variables bound by a let-in
- construction inside the :n:`@term` itself (use here the ``zeta`` flag). In
- any cases, opaque constants are not unfolded (see :ref:`vernac-controlling-the-reduction-strategies`).
-
- Normalization according to the flags is done by first evaluating the
- head of the expression into a *weak-head* normal form, i.e. until the
- evaluation is blocked by a variable (or an opaque constant, or an
- axiom), as e.g. in :g:`x u1 ... un` , or :g:`match x with ... end`, or
- :g:`(fix f x {struct x} := ...) x`, or is a constructed form (a
- :math:`\lambda`-expression, a constructor, a cofixpoint, an inductive type, a
- product type, a sort), or is a redex that the flags prevent to reduce. Once a
- weak-head normal form is obtained, subterms are recursively reduced using the
- same strategy.
-
- Reduction to weak-head normal form can be done using two strategies:
- *lazy* (``lazy`` tactic), or *call-by-value* (``cbv`` tactic). The lazy
- strategy is a call-by-need strategy, with sharing of reductions: the
- arguments of a function call are weakly evaluated only when necessary,
- and if an argument is used several times then it is weakly computed
- only once. This reduction is efficient for reducing expressions with
- dead code. For instance, the proofs of a proposition :g:`exists x. P(x)`
- reduce to a pair of a witness :g:`t`, and a proof that :g:`t` satisfies the
- predicate :g:`P`. Most of the time, :g:`t` may be computed without computing
- the proof of :g:`P(t)`, thanks to the lazy strategy.
-
- The call-by-value strategy is the one used in ML languages: the
- arguments of a function call are systematically weakly evaluated
- first. Despite the lazy strategy always performs fewer reductions than
- the call-by-value strategy, the latter is generally more efficient for
- evaluating purely computational expressions (i.e. with little dead code).
-
-.. tacv:: compute
- cbv
- :name: compute; _
-
- These are synonyms for ``cbv beta delta iota zeta``.
-
-.. tacv:: lazy
-
- This is a synonym for ``lazy beta delta iota zeta``.
-
-.. tacv:: compute [ {+ @qualid} ]
- cbv [ {+ @qualid} ]
-
- These are synonyms of :n:`cbv beta delta {+ @qualid} iota zeta`.
-
-.. tacv:: compute - [ {+ @qualid} ]
- cbv - [ {+ @qualid} ]
-
- These are synonyms of :n:`cbv beta delta -{+ @qualid} iota zeta`.
-
-.. tacv:: lazy [ {+ @qualid} ]
- lazy - [ {+ @qualid} ]
-
- These are respectively synonyms of :n:`lazy beta delta {+ @qualid} iota zeta`
- and :n:`lazy beta delta -{+ @qualid} iota zeta`.
-
-.. tacv:: vm_compute
- :name: vm_compute
-
- This tactic evaluates the goal using the optimized call-by-value evaluation
- bytecode-based virtual machine described in :cite:`CompiledStrongReduction`.
- This algorithm is dramatically more efficient than the algorithm used for the
- :tacn:`cbv` tactic, but it cannot be fine-tuned. It is especially interesting for
- full evaluation of algebraic objects. This includes the case of
- reflection-based tactics.
-
-.. tacv:: native_compute
- :name: native_compute
-
- This tactic evaluates the goal by compilation to OCaml as described
- in :cite:`FullReduction`. If Coq is running in native code, it can be
- typically two to five times faster than :tacn:`vm_compute`. Note however that the
- compilation cost is higher, so it is worth using only for intensive
- computations.
-
- .. flag:: NativeCompute Timing
-
- This flag causes all calls to the native compiler to print
- timing information for the conversion to native code,
- compilation, execution, and reification phases of native
- compilation. Timing is printed in units of seconds of
- wall-clock time.
-
- .. flag:: NativeCompute Profiling
-
- On Linux, if you have the ``perf`` profiler installed, this flag makes
- it possible to profile :tacn:`native_compute` evaluations.
-
- .. opt:: NativeCompute Profile Filename @string
- :name: NativeCompute Profile Filename
-
- This option specifies the profile output; the default is
- ``native_compute_profile.data``. The actual filename used
- will contain extra characters to avoid overwriting an existing file; that
- filename is reported to the user.
- That means you can individually profile multiple uses of
- :tacn:`native_compute` in a script. From the Linux command line, run ``perf report``
- on the profile file to see the results. Consult the ``perf`` documentation
- for more details.
-
-.. flag:: Debug Cbv
-
- This flag makes :tacn:`cbv` (and its derivative :tacn:`compute`) print
- information about the constants it encounters and the unfolding decisions it
- makes.
-
-.. tacn:: red
- :name: red
-
- This tactic applies to a goal that has the form::
-
- forall (x:T1) ... (xk:Tk), T
-
- with :g:`T` :math:`\beta`:math:`\iota`:math:`\zeta`-reducing to :g:`c t`:sub:`1` :g:`... t`:sub:`n` and :g:`c` a
- constant. If :g:`c` is transparent then it replaces :g:`c` with its
- definition (say :g:`t`) and then reduces
- :g:`(t t`:sub:`1` :g:`... t`:sub:`n` :g:`)` according to :math:`\beta`:math:`\iota`:math:`\zeta`-reduction rules.
-
-.. exn:: Not reducible.
- :undocumented:
-
-.. exn:: No head constant to reduce.
- :undocumented:
-
-.. tacn:: hnf
- :name: hnf
-
- This tactic applies to any goal. It replaces the current goal with its
- head normal form according to the :math:`\beta`:math:`\delta`:math:`\iota`:math:`\zeta`-reduction rules, i.e. it
- reduces the head of the goal until it becomes a product or an
- irreducible term. All inner :math:`\beta`:math:`\iota`-redexes are also reduced.
- The behavior of both :tacn:`hnf` can be tuned using the :cmd:`Arguments` command.
-
- Example: The term :g:`fun n : nat => S n + S n` is not reduced by :n:`hnf`.
-
-.. note::
- The :math:`\delta` rule only applies to transparent constants (see :ref:`vernac-controlling-the-reduction-strategies`
- on transparency and opacity).
-
-.. tacn:: cbn
- simpl
- :name: cbn; simpl
-
- These tactics apply to any goal. They try to reduce a term to
- something still readable instead of fully normalizing it. They perform
- a sort of strong normalization with two key differences:
-
- + They unfold a constant if and only if it leads to a :math:`\iota`-reduction,
- i.e. reducing a match or unfolding a fixpoint.
- + While reducing a constant unfolding to (co)fixpoints, the tactics
- use the name of the constant the (co)fixpoint comes from instead of
- the (co)fixpoint definition in recursive calls.
-
- The :tacn:`cbn` tactic is claimed to be a more principled, faster and more
- predictable replacement for :tacn:`simpl`.
-
- The :tacn:`cbn` tactic accepts the same flags as :tacn:`cbv` and
- :tacn:`lazy`. The behavior of both :tacn:`simpl` and :tacn:`cbn`
- can be tuned using the :cmd:`Arguments` command.
-
- .. todo add "See <subsection about controlling the behavior of reduction strategies>"
- to TBA section
-
- Notice that only transparent constants whose name can be reused in the
- recursive calls are possibly unfolded by :tacn:`simpl`. For instance a
- constant defined by :g:`plus' := plus` is possibly unfolded and reused in
- the recursive calls, but a constant such as :g:`succ := plus (S O)` is
- never unfolded. This is the main difference between :tacn:`simpl` and :tacn:`cbn`.
- The tactic :tacn:`cbn` reduces whenever it will be able to reuse it or not:
- :g:`succ t` is reduced to :g:`S t`.
-
-.. tacv:: cbn [ {+ @qualid} ]
- cbn - [ {+ @qualid} ]
-
- These are respectively synonyms of :n:`cbn beta delta [ {+ @qualid} ] iota zeta`
- and :n:`cbn beta delta - [ {+ @qualid} ] iota zeta` (see :tacn:`cbn`).
-
-.. tacv:: simpl @pattern
-
- This applies :tacn:`simpl` only to the subterms matching
- :n:`@pattern` in the current goal.
-
-.. tacv:: simpl @pattern at {+ @natural}
-
- This applies :tacn:`simpl` only to the :n:`{+ @natural}` occurrences of the subterms
- matching :n:`@pattern` in the current goal.
-
- .. exn:: Too few occurrences.
- :undocumented:
-
-.. tacv:: simpl @qualid
- simpl @string
-
- This applies :tacn:`simpl` only to the applicative subterms whose head occurrence
- is the unfoldable constant :n:`@qualid` (the constant can be referred to by
- its notation using :n:`@string` if such a notation exists).
-
-.. tacv:: simpl @qualid at {+ @natural}
- simpl @string at {+ @natural}
-
- This applies :tacn:`simpl` only to the :n:`{+ @natural}` applicative subterms whose
- head occurrence is :n:`@qualid` (or :n:`@string`).
-
-.. flag:: Debug RAKAM
-
- This flag makes :tacn:`cbn` print various debugging information.
- ``RAKAM`` is the Refolding Algebraic Krivine Abstract Machine.
-
-.. tacn:: unfold @qualid
- :name: unfold
-
- This tactic applies to any goal. The argument qualid must denote a
- defined transparent constant or local definition (see
- :ref:`gallina-definitions` and
- :ref:`vernac-controlling-the-reduction-strategies`). The tactic
- :tacn:`unfold` applies the :math:`\delta` rule to each occurrence
- of the constant to which :n:`@qualid` refers in the current goal
- and then replaces it with its :math:`\beta\iota\zeta`-normal form.
- Use the general reduction tactics if you want to avoid this final
- reduction, for instance :n:`cbv delta [@qualid]`.
-
- .. exn:: Cannot coerce @qualid to an evaluable reference.
-
- This error is frequent when trying to unfold something that has
- defined as an inductive type (or constructor) and not as a
- definition.
-
- .. example::
-
- .. coqtop:: abort all fail
-
- Goal 0 <= 1.
- unfold le.
-
- This error can also be raised if you are trying to unfold
- something that has been marked as opaque.
-
- .. example::
-
- .. coqtop:: abort all fail
-
- Opaque Nat.add.
- Goal 1 + 0 = 1.
- unfold Nat.add.
-
- .. tacv:: unfold @qualid in @goal_occurrences
-
- Replaces :n:`@qualid` in hypothesis (or hypotheses) designated
- by :token:`goal_occurrences` with its definition and replaces
- the hypothesis with its :math:`\beta`:math:`\iota` normal form.
-
- .. tacv:: unfold {+, @qualid}
-
- Replaces :n:`{+, @qualid}` with their definitions and replaces
- the current goal with its :math:`\beta`:math:`\iota` normal
- form.
-
- .. tacv:: unfold {+, @qualid at @occurrences }
-
- The list :token:`occurrences` specify the occurrences of
- :n:`@qualid` to be unfolded. Occurrences are located from left
- to right.
-
- .. exn:: Bad occurrence number of @qualid.
- :undocumented:
-
- .. exn:: @qualid does not occur.
- :undocumented:
-
- .. tacv:: unfold @string
-
- If :n:`@string` denotes the discriminating symbol of a notation
- (e.g. "+") or an expression defining a notation (e.g. `"_ +
- _"`), and this notation denotes an application whose head symbol
- is an unfoldable constant, then the tactic unfolds it.
-
- .. tacv:: unfold @string%@ident
-
- This is variant of :n:`unfold @string` where :n:`@string` gets
- its interpretation from the scope bound to the delimiting key
- :token:`ident` instead of its default interpretation (see
- :ref:`Localinterpretationrulesfornotations`).
-
- .. tacv:: unfold {+, {| @qualid | @string{? %@ident } } {? at @occurrences } } {? in @goal_occurrences }
-
- This is the most general form.
-
-.. tacn:: fold @term
- :name: fold
-
- This tactic applies to any goal. The term :n:`@term` is reduced using the
- :tacn:`red` tactic. Every occurrence of the resulting :n:`@term` in the goal is
- then replaced by :n:`@term`. This tactic is particularly useful when a fixpoint
- definition has been wrongfully unfolded, making the goal very hard to read.
- On the other hand, when an unfolded function applied to its argument has been
- reduced, the :tacn:`fold` tactic won't do anything.
-
- .. example::
-
- .. coqtop:: all abort
-
- Goal ~0=0.
- unfold not.
- Fail progress fold not.
- pattern (0 = 0).
- fold not.
-
- .. tacv:: fold {+ @term}
-
- Equivalent to :n:`fold @term ; ... ; fold @term`.
-
-.. tacn:: pattern @term
- :name: pattern
-
- This command applies to any goal. The argument :n:`@term` must be a free
- subterm of the current goal. The command pattern performs :math:`\beta`-expansion
- (the inverse of :math:`\beta`-reduction) of the current goal (say :g:`T`) by
-
- + replacing all occurrences of :n:`@term` in :g:`T` with a fresh variable
- + abstracting this variable
- + applying the abstracted goal to :n:`@term`
-
- For instance, if the current goal :g:`T` is expressible as
- :math:`\varphi`:g:`(t)` where the notation captures all the instances of :g:`t`
- in :math:`\varphi`:g:`(t)`, then :n:`pattern t` transforms it into
- :g:`(fun x:A =>` :math:`\varphi`:g:`(x)) t`. This tactic can be used, for
- instance, when the tactic ``apply`` fails on matching.
-
-.. tacv:: pattern @term at {+ @natural}
-
- Only the occurrences :n:`{+ @natural}` of :n:`@term` are considered for
- :math:`\beta`-expansion. Occurrences are located from left to right.
-
-.. tacv:: pattern @term at - {+ @natural}
-
- All occurrences except the occurrences of indexes :n:`{+ @natural }`
- of :n:`@term` are considered for :math:`\beta`-expansion. Occurrences are located from
- left to right.
-
-.. tacv:: pattern {+, @term}
-
- Starting from a goal :math:`\varphi`:g:`(t`:sub:`1` :g:`... t`:sub:`m`:g:`)`,
- the tactic :n:`pattern t`:sub:`1`:n:`, ..., t`:sub:`m` generates the
- equivalent goal
- :g:`(fun (x`:sub:`1`:g:`:A`:sub:`1`:g:`) ... (x`:sub:`m` :g:`:A`:sub:`m` :g:`) =>`:math:`\varphi`:g:`(x`:sub:`1` :g:`... x`:sub:`m` :g:`)) t`:sub:`1` :g:`... t`:sub:`m`.
- If :g:`t`:sub:`i` occurs in one of the generated types :g:`A`:sub:`j` these
- occurrences will also be considered and possibly abstracted.
-
-.. tacv:: pattern {+, @term at {+ @natural}}
-
- This behaves as above but processing only the occurrences :n:`{+ @natural}` of
- :n:`@term` starting from :n:`@term`.
-
-.. tacv:: pattern {+, @term {? at {? -} {+, @natural}}}
-
- This is the most general syntax that combines the different variants.
-
-.. tacn:: with_strategy @strategy_level_or_var [ {+ @reference } ] @ltac_expr3
- :name: with_strategy
-
- Executes :token:`ltac_expr3`, applying the alternate unfolding
- behavior that the :cmd:`Strategy` command controls, but only for
- :token:`ltac_expr3`. This can be useful for guarding calls to
- reduction in tactic automation to ensure that certain constants are
- never unfolded by tactics like :tacn:`simpl` and :tacn:`cbn` or to
- ensure that unfolding does not fail.
-
- .. example::
-
- .. coqtop:: all reset abort
-
- Opaque id.
- Goal id 10 = 10.
- Fail unfold id.
- with_strategy transparent [id] unfold id.
-
- .. warning::
-
- Use this tactic with care, as effects do not persist past the
- end of the proof script. Notably, this fine-tuning of the
- conversion strategy is not in effect during :cmd:`Qed` nor
- :cmd:`Defined`, so this tactic is most useful either in
- combination with :tacn:`abstract`, which will check the proof
- early while the fine-tuning is still in effect, or to guard
- calls to conversion in tactic automation to ensure that, e.g.,
- :tacn:`unfold` does not fail just because the user made a
- constant :cmd:`Opaque`.
-
- This can be illustrated with the following example involving the
- factorial function.
-
- .. coqtop:: in reset
-
- Fixpoint fact (n : nat) : nat :=
- match n with
- | 0 => 1
- | S n' => n * fact n'
- end.
-
- Suppose now that, for whatever reason, we want in general to
- unfold the :g:`id` function very late during conversion:
-
- .. coqtop:: in
-
- Strategy 1000 [id].
-
- If we try to prove :g:`id (fact n) = fact n` by
- :tacn:`reflexivity`, it will now take time proportional to
- :math:`n!`, because |Coq| will keep unfolding :g:`fact` and
- :g:`*` and :g:`+` before it unfolds :g:`id`, resulting in a full
- computation of :g:`fact n` (in unary, because we are using
- :g:`nat`), which takes time :math:`n!`. We can see this cross
- the relevant threshold at around :math:`n = 9`:
-
- .. coqtop:: all abort
-
- Goal True.
- Time assert (id (fact 8) = fact 8) by reflexivity.
- Time assert (id (fact 9) = fact 9) by reflexivity.
-
- Note that behavior will be the same if you mark :g:`id` as
- :g:`Opaque` because while most reduction tactics refuse to
- unfold :g:`Opaque` constants, conversion treats :g:`Opaque` as
- merely a hint to unfold this constant last.
-
- We can get around this issue by using :tacn:`with_strategy`:
-
- .. coqtop:: all
-
- Goal True.
- Fail Timeout 1 assert (id (fact 100) = fact 100) by reflexivity.
- Time assert (id (fact 100) = fact 100) by with_strategy -1 [id] reflexivity.
-
- However, when we go to close the proof, we will run into
- trouble, because the reduction strategy changes are local to the
- tactic passed to :tacn:`with_strategy`.
-
- .. coqtop:: all abort fail
-
- exact I.
- Timeout 1 Defined.
-
- We can fix this issue by using :tacn:`abstract`:
-
- .. coqtop:: all
-
- Goal True.
- Time assert (id (fact 100) = fact 100) by with_strategy -1 [id] abstract reflexivity.
- exact I.
- Time Defined.
-
- On small examples this sort of behavior doesn't matter, but
- because |Coq| is a super-linear performance domain in so many
- places, unless great care is taken, tactic automation using
- :tacn:`with_strategy` may not be robustly performant when
- scaling the size of the input.
-
- .. warning::
-
- In much the same way this tactic does not play well with
- :cmd:`Qed` and :cmd:`Defined` without using :tacn:`abstract` as
- an intermediary, this tactic does not play well with ``coqchk``,
- even when used with :tacn:`abstract`, due to the inability of
- tactics to persist information about conversion hints in the
- proof term. See `#12200
- <https://github.com/coq/coq/issues/12200>`_ for more details.
-
-Conversion tactics applied to hypotheses
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. tacn:: @tactic in {+, @ident}
-
- Applies :token:`tactic` (any of the conversion tactics listed in this
- section) to the hypotheses :n:`{+ @ident}`.
-
- If :token:`ident` is a local definition, then :token:`ident` can be replaced by
- :n:`type of @ident` to address not the body but the type of the local
- definition.
-
- Example: :n:`unfold not in (type of H1) (type of H3)`.
-
-.. exn:: No such hypothesis: @ident.
- :undocumented:
-
-
-.. _automation:
-
-Automation
-----------
-
-.. tacn:: auto
- :name: auto
-
- This tactic implements a Prolog-like resolution procedure to solve the
- current goal. It first tries to solve the goal using the :tacn:`assumption`
- tactic, then it reduces the goal to an atomic one using :tacn:`intros` and
- introduces the newly generated hypotheses as hints. Then it looks at
- the list of tactics associated to the head symbol of the goal and
- tries to apply one of them (starting from the tactics with lower
- cost). This process is recursively applied to the generated subgoals.
-
- By default, :tacn:`auto` only uses the hypotheses of the current goal and
- the hints of the database named ``core``.
-
- .. warning::
-
- :tacn:`auto` uses a weaker version of :tacn:`apply` that is closer to
- :tacn:`simple apply` so it is expected that sometimes :tacn:`auto` will
- fail even if applying manually one of the hints would succeed.
-
- .. tacv:: auto @natural
-
- Forces the search depth to be :token:`natural`. The maximal search depth
- is 5 by default.
-
- .. tacv:: auto with {+ @ident}
-
- Uses the hint databases :n:`{+ @ident}` in addition to the database ``core``.
-
- .. note::
-
- Use the fake database `nocore` if you want to *not* use the `core`
- database.
-
- .. tacv:: auto with *
-
- Uses all existing hint databases. Using this variant is highly discouraged
- in finished scripts since it is both slower and less robust than the variant
- where the required databases are explicitly listed.
-
- .. seealso::
- :ref:`The Hints Databases for auto and eauto <thehintsdatabasesforautoandeauto>` for the list of
- pre-defined databases and the way to create or extend a database.
-
- .. tacv:: auto using {+ @qualid__i} {? with {+ @ident } }
-
- Uses lemmas :n:`@qualid__i` in addition to hints. If :n:`@qualid` is an
- inductive type, it is the collection of its constructors which are added
- as hints.
-
- .. note::
-
- The hints passed through the `using` clause are used in the same
- way as if they were passed through a hint database. Consequently,
- they use a weaker version of :tacn:`apply` and :n:`auto using @qualid`
- may fail where :n:`apply @qualid` succeeds.
-
- Given that this can be seen as counter-intuitive, it could be useful
- to have an option to use full-blown :tacn:`apply` for lemmas passed
- through the `using` clause. Contributions welcome!
-
- .. tacv:: info_auto
-
- Behaves like :tacn:`auto` but shows the tactics it uses to solve the goal. This
- variant is very useful for getting a better understanding of automation, or
- to know what lemmas/assumptions were used.
-
- .. tacv:: debug auto
- :name: debug auto
-
- Behaves like :tacn:`auto` but shows the tactics it tries to solve the goal,
- including failing paths.
-
- .. tacv:: {? info_}auto {? @natural} {? using {+ @qualid}} {? with {+ @ident}}
-
- This is the most general form, combining the various options.
-
-.. tacv:: trivial
- :name: trivial
-
- This tactic is a restriction of :tacn:`auto` that is not recursive
- and tries only hints that cost `0`. Typically it solves trivial
- equalities like :g:`X=X`.
-
- .. tacv:: trivial with {+ @ident}
- trivial with *
- trivial using {+ @qualid}
- debug trivial
- info_trivial
- {? info_}trivial {? using {+ @qualid}} {? with {+ @ident}}
- :name: _; _; _; debug trivial; info_trivial; _
- :undocumented:
-
-.. note::
- :tacn:`auto` and :tacn:`trivial` either solve completely the goal or
- else succeed without changing the goal. Use :g:`solve [ auto ]` and
- :g:`solve [ trivial ]` if you would prefer these tactics to fail when
- they do not manage to solve the goal.
-
-.. flag:: Info Auto
- Debug Auto
- Info Trivial
- Debug Trivial
-
- These flags enable printing of informative or debug information for
- the :tacn:`auto` and :tacn:`trivial` tactics.
-
-.. tacn:: eauto
- :name: eauto
-
- This tactic generalizes :tacn:`auto`. While :tacn:`auto` does not try
- resolution hints which would leave existential variables in the goal,
- :tacn:`eauto` does try them (informally speaking, it internally uses a tactic
- close to :tacn:`simple eapply` instead of a tactic close to :tacn:`simple apply`
- in the case of :tacn:`auto`). As a consequence, :tacn:`eauto`
- can solve such a goal:
-
- .. example::
-
- .. coqtop:: all
-
- Hint Resolve ex_intro : core.
- Goal forall P:nat -> Prop, P 0 -> exists n, P n.
- eauto.
-
- Note that ``ex_intro`` should be declared as a hint.
-
-
- .. tacv:: {? info_}eauto {? @natural} {? using {+ @qualid}} {? with {+ @ident}}
-
- The various options for :tacn:`eauto` are the same as for :tacn:`auto`.
-
- :tacn:`eauto` also obeys the following flags:
-
- .. flag:: Info Eauto
- Debug Eauto
- :undocumented:
-
- .. seealso:: :ref:`The Hints Databases for auto and eauto <thehintsdatabasesforautoandeauto>`
-
-
-.. tacn:: autounfold with {+ @ident}
- :name: autounfold
-
- This tactic unfolds constants that were declared through a :cmd:`Hint Unfold`
- in the given databases.
-
-.. tacv:: autounfold with {+ @ident} in @goal_occurrences
-
- Performs the unfolding in the given clause (:token:`goal_occurrences`).
-
-.. tacv:: autounfold with *
-
- Uses the unfold hints declared in all the hint databases.
-
-.. tacn:: autorewrite with {+ @ident}
- :name: autorewrite
-
- 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
- it fails. Once all the rules have been processed, if the main subgoal has
- progressed (e.g., if it is distinct from the initial main goal) then the rules
- of this base are processed again. If the main subgoal has not progressed then
- the next base is processed. For the bases, the behavior is exactly similar to
- the processing of the rewriting rules.
-
- The rewriting rule bases are built with the :cmd:`Hint Rewrite`
- command.
-
-.. warning::
-
- This tactic may loop if you build non terminating rewriting systems.
-
-.. tacv:: autorewrite with {+ @ident} using @tactic
-
- Performs, in the same way, all the rewritings of the bases :n:`{+ @ident}`
- applying tactic to the main subgoal after each rewriting step.
-
-.. tacv:: autorewrite with {+ @ident} in @qualid
-
- Performs all the rewritings in hypothesis :n:`@qualid`.
-
-.. tacv:: autorewrite with {+ @ident} in @qualid using @tactic
-
- Performs all the rewritings in hypothesis :n:`@qualid` applying :n:`@tactic`
- to the main subgoal after each rewriting step.
-
-.. tacv:: autorewrite with {+ @ident} in @goal_occurrences
-
- Performs all the rewriting in the clause :n:`@goal_occurrences`.
-
-.. seealso::
-
- :ref:`Hint-Rewrite <hintrewrite>` for feeding the database of lemmas used by
- :tacn:`autorewrite` and :tacn:`autorewrite` for examples showing the use of this tactic.
-
-.. tacn:: easy
- :name: easy
-
- This tactic tries to solve the current goal by a number of standard closing steps.
- In particular, it tries to close the current goal using the closing tactics
- :tacn:`trivial`, :tacn:`reflexivity`, :tacn:`symmetry`, :tacn:`contradiction`
- and :tacn:`inversion` of hypothesis.
- If this fails, it tries introducing variables and splitting and-hypotheses,
- using the closing tactics afterwards, and splitting the goal using
- :tacn:`split` and recursing.
-
- This tactic solves goals that belong to many common classes; in particular, many cases of
- unsatisfiable hypotheses, and simple equality goals are usually solved by this tactic.
-
-.. tacv:: now @tactic
- :name: now
-
- Run :n:`@tactic` followed by :tacn:`easy`. This is a notation for :n:`@tactic; easy`.
-
-Controlling automation
---------------------------
-
-.. _thehintsdatabasesforautoandeauto:
-
-The hints databases for auto and eauto
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The hints for :tacn:`auto` and :tacn:`eauto` are stored in databases. Each database
-maps head symbols to a list of hints.
-
-.. cmd:: Print Hint @ident
-
- Use this command
- to display the hints associated to the head symbol :n:`@ident`
- (see :ref:`Print Hint <printhint>`). Each hint has a cost that is a nonnegative
- integer, and an optional pattern. The hints with lower cost are tried first. A
- hint is tried by :tacn:`auto` when the conclusion of the current goal matches its
- pattern or when it has no pattern.
-
-Creating Hint databases
-```````````````````````
-
-One can optionally declare a hint database using the command
-:cmd:`Create HintDb`. If a hint is added to an unknown database, it will be
-automatically created.
-
-.. cmd:: Create HintDb @ident {? discriminated}
-
- This command creates a new database named :n:`@ident`. The database is
- implemented by a Discrimination Tree (DT) that serves as an index of
- all the lemmas. The DT can use transparency information to decide if a
- constant should be indexed or not
- (c.f. :ref:`The hints databases for auto and eauto <thehintsdatabasesforautoandeauto>`),
- making the retrieval more efficient. The legacy implementation (the default one
- for new databases) uses the DT only on goals without existentials (i.e., :tacn:`auto`
- goals), for non-Immediate hints and does not make use of transparency
- hints, putting more work on the unification that is run after
- retrieval (it keeps a list of the lemmas in case the DT is not used).
- The new implementation enabled by the discriminated option makes use
- of DTs in all cases and takes transparency information into account.
- However, the order in which hints are retrieved from the DT may differ
- from the order in which they were inserted, making this implementation
- observationally different from the legacy one.
-
-.. cmd:: Hint @hint_definition : {+ @ident}
-
- The general command to add a hint to some databases :n:`{+ @ident}`.
-
- This command supports the :attr:`local`, :attr:`global` and :attr:`export`
- locality attributes. When no locality is explictly given, the
- command is :attr:`local` inside a section and :attr:`global` otherwise.
-
- + :attr:`local` hints are never visible from other modules, even if they
- require or import the current module. Inside a section, the :attr:`local`
- attribute is useless since hints do not survive anyway to the closure of
- sections.
-
- + :attr:`export` are visible from other modules when they import the current
- module. Requiring it is not enough. This attribute is only effective for
- the :cmd:`Hint Resolve`, :cmd:`Hint Immediate`, :cmd:`Hint Unfold` and
- :cmd:`Hint Extern` variants of the command.
-
- + :attr:`global` hints are made available by merely requiring the current
- module.
-
- The various possible :production:`hint_definition`\s are given below.
-
- .. cmdv:: Hint @hint_definition
-
- No database name is given: the hint is registered in the ``core`` database.
-
- .. deprecated:: 8.10
-
- .. cmdv:: Hint Resolve @qualid {? | {? @natural} {? @pattern}} : @ident
- :name: Hint Resolve
-
- This command adds :n:`simple apply @qualid` to the hint list with the head
- symbol of the type of :n:`@qualid`. The cost of that hint is the number of
- subgoals generated by :n:`simple apply @qualid` or :n:`@natural` if specified. The
- associated :n:`@pattern` is inferred from the conclusion of the type of
- :n:`@qualid` or the given :n:`@pattern` if specified. In case the inferred type
- of :n:`@qualid` does not start with a product the tactic added in the hint list
- is :n:`exact @qualid`. In case this type can however be reduced to a type
- starting with a product, the tactic :n:`simple apply @qualid` is also stored in
- the hints list. If the inferred type of :n:`@qualid` contains a dependent
- quantification on a variable which occurs only in the premisses of the type
- and not in its conclusion, no instance could be inferred for the variable by
- unification with the goal. In this case, the hint is added to the hint list
- of :tacn:`eauto` instead of the hint list of auto and a warning is printed. A
- typical example of a hint that is used only by :tacn:`eauto` is a transitivity
- lemma.
-
- .. exn:: @qualid cannot be used as a hint
-
- The head symbol of the type of :n:`@qualid` is a bound variable
- such that this tactic cannot be associated to a constant.
-
- .. cmdv:: Hint Resolve {+ @qualid} : @ident
-
- Adds each :n:`Hint Resolve @qualid`.
-
- .. cmdv:: Hint Resolve -> @qualid : @ident
-
- Adds the left-to-right implication of an equivalence as a hint (informally
- the hint will be used as :n:`apply <- @qualid`, although as mentioned
- before, the tactic actually used is a restricted version of
- :tacn:`apply`).
-
- .. cmdv:: Hint Resolve <- @qualid
-
- Adds the right-to-left implication of an equivalence as a hint.
-
- .. cmdv:: Hint Immediate @qualid : @ident
- :name: Hint Immediate
-
- This command adds :n:`simple apply @qualid; trivial` to the hint list associated
- with the head symbol of the type of :n:`@ident` in the given database. This
- tactic will fail if all the subgoals generated by :n:`simple apply @qualid` are
- not solved immediately by the :tacn:`trivial` tactic (which only tries tactics
- with cost 0).This command is useful for theorems such as the symmetry of
- equality or :g:`n+1=m+1 -> n=m` that we may like to introduce with a limited
- use in order to avoid useless proof-search. The cost of this tactic (which
- never generates subgoals) is always 1, so that it is not used by :tacn:`trivial`
- itself.
-
- .. exn:: @qualid cannot be used as a hint
- :undocumented:
-
- .. cmdv:: Hint Immediate {+ @qualid} : @ident
-
- Adds each :n:`Hint Immediate @qualid`.
-
- .. cmdv:: Hint Constructors @qualid : @ident
- :name: Hint Constructors
-
- If :token:`qualid` is an inductive type, this command adds all its constructors as
- hints of type ``Resolve``. Then, when the conclusion of current goal has the form
- :n:`(@qualid ...)`, :tacn:`auto` will try to apply each constructor.
-
- .. exn:: @qualid is not an inductive type
- :undocumented:
-
- .. cmdv:: Hint Constructors {+ @qualid} : @ident
-
- Extends the previous command for several inductive types.
-
- .. cmdv:: Hint Unfold @qualid : @ident
- :name: Hint Unfold
-
- This adds the tactic :n:`unfold @qualid` to the hint list that will only be
- used when the head constant of the goal is :token:`qualid`.
- Its cost is 4.
-
- .. cmdv:: Hint Unfold {+ @qualid}
-
- Extends the previous command for several defined constants.
-
- .. cmdv:: Hint Transparent {+ @qualid} : @ident
- Hint Opaque {+ @qualid} : @ident
- :name: Hint Transparent; Hint Opaque
-
- This adds transparency hints to the database, making :n:`@qualid`
- transparent or opaque constants during resolution. This information is used
- during unification of the goal with any lemma in the database and inside the
- discrimination network to relax or constrain it in the case of discriminated
- databases.
-
- .. 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
- hints in the database for all constants or all variables,
- overwriting the existing settings of opacity. It is advised
- to use this just after a :cmd:`Create HintDb` command.
-
- .. cmdv:: Hint Extern @natural {? @pattern} => @tactic : @ident
- :name: Hint Extern
-
- This hint type is to extend :tacn:`auto` with tactics other than :tacn:`apply` and
- :tacn:`unfold`. For that, we must specify a cost, an optional :n:`@pattern` and a
- :n:`@tactic` to execute.
-
- .. example::
-
- .. coqtop:: in
-
- Hint Extern 4 (~(_ = _)) => discriminate : core.
-
- Now, when the head of the goal is a disequality, ``auto`` will try
- discriminate if it does not manage to solve the goal with hints with a
- cost less than 4.
-
- One can even use some sub-patterns of the pattern in
- the tactic script. A sub-pattern is a question mark followed by an
- identifier, like ``?X1`` or ``?X2``. Here is an example:
-
- .. example::
-
- .. coqtop:: reset all
-
- Require Import List.
- Hint Extern 5 ({?X1 = ?X2} + {?X1 <> ?X2}) => generalize X1, X2; decide equality : eqdec.
- Goal forall a b:list (nat * nat), {a = b} + {a <> b}.
- Info 1 auto with eqdec.
-
- .. cmdv:: Hint Cut @regexp : @ident
- :name: Hint Cut
-
- .. warning::
-
- These hints currently only apply to typeclass proof search and the
- :tacn:`typeclasses eauto` tactic.
-
- This command can be used to cut the proof-search tree according to a regular
- expression matching paths to be cut. The grammar for regular expressions is
- the following. Beware, there is no operator precedence during parsing, one can
- check with :cmd:`Print HintDb` to verify the current cut expression:
-
- .. prodn::
- regexp ::= @ident (hint or instance identifier)
- | _ (any hint)
- | @regexp | @regexp (disjunction)
- | @regexp @regexp (sequence)
- | @regexp * (Kleene star)
- | emp (empty)
- | eps (epsilon)
- | ( @regexp )
-
- The `emp` regexp does not match any search path while `eps`
- matches the empty path. During proof search, the path of
- successive successful hints on a search branch is recorded, as a
- list of identifiers for the hints (note that :cmd:`Hint Extern`\’s do not have
- an associated identifier).
- Before applying any hint :n:`@ident` the current path `p` extended with
- :n:`@ident` is matched against the current cut expression `c` associated to
- the hint database. If matching succeeds, the hint is *not* applied. The
- 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
- :name: Hint Mode
-
- This sets an optional mode of use of the identifier :n:`@qualid`. When
- proof-search faces a goal that ends in an application of :n:`@qualid` to
- arguments :n:`@term ... @term`, the mode tells if the hints associated to
- :n:`@qualid` can be applied or not. A mode specification is a list of n ``+``,
- ``!`` or ``-`` items that specify if an argument of the identifier is to be
- treated as an input (``+``), if its head only is an input (``!``) or an output
- (``-``) of the identifier. For a mode to match a list of arguments, input
- terms and input heads *must not* contain existential variables or be
- existential variables respectively, while outputs can be any term. Multiple
- modes can be declared for a single identifier, in that case only one mode
- needs to match the arguments for the hints to be applied. The head of a term
- is understood here as the applicative head, or the match or projection
- scrutinee’s head, recursively, casts being ignored. :cmd:`Hint Mode` is
- especially useful for typeclasses, when one does not want to support default
- instances and avoid ambiguity in general. Setting a parameter of a class as an
- input forces proof-search to be driven by that index of the class, with ``!``
- giving more flexibility by allowing existentials to still appear deeper in the
- index but not at its head.
-
- .. note::
-
- + One can use a :cmd:`Hint Extern` with no pattern to do
- pattern matching on hypotheses using ``match goal with``
- inside the tactic.
-
- + If you want to add hints such as :cmd:`Hint Transparent`,
- :cmd:`Hint Cut`, or :cmd:`Hint Mode`, for typeclass
- resolution, do not forget to put them in the
- ``typeclass_instances`` hint database.
-
-
-Hint databases defined in the Coq standard library
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Several hint databases are defined in the Coq standard library. The
-actual content of a database is the collection of hints declared
-to belong to this database in each of the various modules currently
-loaded. Especially, requiring new modules may extend the database.
-At Coq startup, only the core database is nonempty and can be used.
-
-:core: This special database is automatically used by ``auto``, except when
- pseudo-database ``nocore`` is given to ``auto``. The core database
- contains only basic lemmas about negation, conjunction, and so on.
- Most of the hints in this database come from the Init and Logic directories.
-
-:arith: This database contains all lemmas about Peano’s arithmetic proved in the
- directories Init and Arith.
-
-:zarith: contains lemmas about binary signed integers from the
- directories theories/ZArith. The database also contains
- high-cost hints that call :tacn:`lia` on equations and
- inequalities in ``nat`` or ``Z``.
-
-:bool: contains lemmas about booleans, mostly from directory theories/Bool.
-
-:datatypes: is for lemmas about lists, streams and so on that are mainly proved
- in the Lists subdirectory.
-
-:sets: contains lemmas about sets and relations from the directories Sets and
- Relations.
-
-:typeclass_instances: contains all the typeclass instances declared in the
- environment, including those used for ``setoid_rewrite``,
- from the Classes directory.
-
-:fset: internal database for the implementation of the ``FSets`` library.
-
-:ordered_type: lemmas about ordered types (as defined in the legacy ``OrderedType`` module),
- mainly used in the ``FSets`` and ``FMaps`` libraries.
-
-You are advised not to put your own hints in the core database, but
-use one or several databases specific to your development.
-
-.. _removehints:
-
-.. cmd:: Remove Hints {+ @term} : {+ @ident}
-
- This command removes the hints associated to terms :n:`{+ @term}` in databases
- :n:`{+ @ident}`.
-
-.. _printhint:
-
-.. cmd:: Print Hint
-
- This command displays all hints that apply to the current goal. It
- fails if no proof is being edited, while the two variants can be used
- at every moment.
-
-**Variants:**
-
-
-.. cmd:: Print Hint @ident
-
- This command displays only tactics associated with :n:`@ident` in the hints
- list. This is independent of the goal being edited, so this command will not
- fail if no goal is being edited.
-
-.. cmd:: Print Hint *
-
- This command displays all declared hints.
-
-.. cmd:: Print HintDb @ident
-
- This command displays all hints from database :n:`@ident`.
-
-.. _hintrewrite:
-
-.. cmd:: Hint Rewrite {+ @term} : {+ @ident}
-
- This vernacular command adds the terms :n:`{+ @term}` (their types must be
- equalities) in the rewriting bases :n:`{+ @ident}` with the default orientation
- (left to right). Notice that the rewriting bases are distinct from the :tacn:`auto`
- hint bases and that :tacn:`auto` does not take them into account.
-
- This command is synchronous with the section mechanism (see :ref:`section-mechanism`):
- when closing a section, all aliases created by ``Hint Rewrite`` in that
- section are lost. Conversely, when loading a module, all ``Hint Rewrite``
- declarations at the global level of that module are loaded.
-
-**Variants:**
-
-.. cmd:: Hint Rewrite -> {+ @term} : {+ @ident}
-
- This is strictly equivalent to the command above (we only make explicit the
- orientation which otherwise defaults to ->).
-
-.. cmd:: Hint Rewrite <- {+ @term} : {+ @ident}
-
- Adds the rewriting rules :n:`{+ @term}` with a right-to-left orientation in
- the bases :n:`{+ @ident}`.
-
-.. cmd:: Hint Rewrite {+ @term} using @tactic : {+ @ident}
-
- When the rewriting rules :n:`{+ @term}` in :n:`{+ @ident}` will be used, the
- tactic ``tactic`` will be applied to the generated subgoals, the main subgoal
- excluded.
-
-.. cmd:: Print Rewrite HintDb @ident
-
- This command displays all rewrite hints contained in :n:`@ident`.
-
-Hint locality
-~~~~~~~~~~~~~
-
-Hints provided by the ``Hint`` commands are erased when closing a section.
-Conversely, all hints of a module ``A`` that are not defined inside a
-section (and not defined with option ``Local``) become available when the
-module ``A`` is required (using e.g. ``Require A.``).
-
-As of today, hints only have a binary behavior regarding locality, as
-described above: either they disappear at the end of a section scope,
-or they remain global forever. This causes a scalability issue,
-because hints coming from an unrelated part of the code may badly
-influence another development. It can be mitigated to some extent
-thanks to the :cmd:`Remove Hints` command,
-but this is a mere workaround and has some limitations (for instance, external
-hints cannot be removed).
-
-A proper way to fix this issue is to bind the hints to their module scope, as
-for most of the other objects Coq uses. Hints should only be made available when
-the module they are defined in is imported, not just required. It is very
-difficult to change the historical behavior, as it would break a lot of scripts.
-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" }
- :name: Loose Hint Behavior
-
- This option accepts three values, which control the behavior of hints w.r.t.
- :cmd:`Import`:
-
- - "Lax": this is the default, and corresponds to the historical behavior,
- that is, hints defined outside of a section have a global scope.
-
- - "Warn": outputs a warning when a non-imported hint is used. Note that this
- is an over-approximation, because a hint may be triggered by a run that
- will eventually fail and backtrack, resulting in the hint not being
- actually useful for the proof.
-
- - "Strict": changes the behavior of an unloaded hint to a immediate fail
- tactic, allowing to emulate an import-scoped hint mechanism.
-
-.. _tactics-implicit-automation:
-
-Setting implicit automation tactics
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. cmd:: Proof with @tactic
-
- This command may be used to start a proof. It defines a default tactic
- to be used each time a tactic command ``tactic``:sub:`1` is ended by ``...``.
- In this case the tactic command typed by the user is equivalent to
- ``tactic``:sub:`1` ``;tactic``.
-
- .. seealso:: :cmd:`Proof` in :ref:`proof-editing-mode`.
-
-
- .. cmdv:: Proof with @tactic using {+ @ident}
-
- Combines in a single line ``Proof with`` and ``Proof using``, see :ref:`proof-editing-mode`
-
- .. cmdv:: Proof using {+ @ident} with @tactic
-
- Combines in a single line ``Proof with`` and ``Proof using``, see :ref:`proof-editing-mode`
-
-.. _decisionprocedures:
-
-Decision procedures
--------------------
-
-.. tacn:: tauto
- :name: tauto
-
- This tactic implements a decision procedure for intuitionistic propositional
- calculus based on the contraction-free sequent calculi LJT* of Roy Dyckhoff
- :cite:`Dyc92`. Note that :tacn:`tauto` succeeds on any instance of an
- intuitionistic tautological proposition. :tacn:`tauto` unfolds negations and
- logical equivalence but does not unfold any other definition.
-
-.. example::
-
- The following goal can be proved by :tacn:`tauto` whereas :tacn:`auto` would
- fail:
-
- .. coqtop:: reset all
-
- Goal forall (x:nat) (P:nat -> Prop), x = 0 \/ P x -> x <> 0 -> P x.
- intros.
- tauto.
-
-Moreover, if it has nothing else to do, :tacn:`tauto` performs introductions.
-Therefore, the use of :tacn:`intros` in the previous proof is unnecessary.
-:tacn:`tauto` can for instance for:
-
-.. example::
-
- .. coqtop:: reset all
-
- Goal forall (A:Prop) (P:nat -> Prop), A \/ (forall x:nat, ~ A -> P x) -> forall x:nat, ~ A -> P x.
- tauto.
-
-.. note::
- In contrast, :tacn:`tauto` cannot solve the following goal
- :g:`Goal forall (A:Prop) (P:nat -> Prop), A \/ (forall x:nat, ~ A -> P x) ->`
- :g:`forall x:nat, ~ ~ (A \/ P x).`
- because :g:`(forall x:nat, ~ A -> P x)` cannot be treated as atomic and
- an instantiation of `x` is necessary.
-
-.. tacv:: dtauto
- :name: dtauto
-
- While :tacn:`tauto` recognizes inductively defined connectives isomorphic to
- the standard connectives ``and``, ``prod``, ``or``, ``sum``, ``False``,
- ``Empty_set``, ``unit``, ``True``, :tacn:`dtauto` also recognizes all inductive
- types with one constructor and no indices, i.e. record-style connectives.
-
-.. tacn:: intuition @tactic
- :name: intuition
-
- The tactic :tacn:`intuition` takes advantage of the search-tree built by the
- decision procedure involved in the tactic :tacn:`tauto`. It uses this
- information to generate a set of subgoals equivalent to the original one (but
- simpler than it) and applies the tactic :n:`@tactic` to them :cite:`Mun94`. If
- this tactic fails on some goals then :tacn:`intuition` fails. In fact,
- :tacn:`tauto` is simply :g:`intuition fail`.
-
- .. example::
-
- For instance, the tactic :g:`intuition auto` applied to the goal::
-
- (forall (x:nat), P x) /\ B -> (forall (y:nat), P y) /\ P O \/ B /\ P O
-
- internally replaces it by the equivalent one::
-
- (forall (x:nat), P x), B |- P O
-
- and then uses :tacn:`auto` which completes the proof.
-
-Originally due to César Muñoz, these tactics (:tacn:`tauto` and
-:tacn:`intuition`) have been completely re-engineered by David Delahaye using
-mainly the tactic language (see :ref:`ltac`). The code is
-now much shorter and a significant increase in performance has been noticed.
-The general behavior with respect to dependent types, unfolding and
-introductions has slightly changed to get clearer semantics. This may lead to
-some incompatibilities.
-
-.. tacv:: intuition
-
- Is equivalent to :g:`intuition auto with *`.
-
-.. tacv:: dintuition
- :name: dintuition
-
- While :tacn:`intuition` recognizes inductively defined connectives
- isomorphic to the standard connectives ``and``, ``prod``, ``or``, ``sum``, ``False``,
- ``Empty_set``, ``unit``, ``True``, :tacn:`dintuition` also recognizes all inductive
- types with one constructor and no indices, i.e. record-style connectives.
-
-.. flag:: Intuition Negation Unfolding
-
- Controls whether :tacn:`intuition` unfolds inner negations which do not need
- to be unfolded. This flag is on by default.
-
-.. tacn:: rtauto
- :name: rtauto
-
- The :tacn:`rtauto` tactic solves propositional tautologies similarly to what
- :tacn:`tauto` does. The main difference is that the proof term is built using a
- reflection scheme applied to a sequent calculus proof of the goal. The search
- procedure is also implemented using a different technique.
-
- Users should be aware that this difference may result in faster proof-search
- but slower proof-checking, and :tacn:`rtauto` might not solve goals that
- :tacn:`tauto` would be able to solve (e.g. goals involving universal
- quantifiers).
-
- Note that this tactic is only available after a ``Require Import Rtauto``.
-
-.. tacn:: firstorder
- :name: firstorder
-
- The tactic :tacn:`firstorder` is an experimental extension of :tacn:`tauto` to
- first- order reasoning, written by Pierre Corbineau. It is not restricted to
- usual logical connectives but instead may reason about any first-order class
- inductive definition.
-
-.. opt:: Firstorder Solver @tactic
- :name: Firstorder Solver
-
- The default tactic used by :tacn:`firstorder` when no rule applies is
- :g:`auto with core`, it can be reset locally or globally using this option.
-
- .. cmd:: Print Firstorder Solver
-
- Prints the default tactic used by :tacn:`firstorder` when no rule applies.
-
-.. tacv:: firstorder @tactic
-
- Tries to solve the goal with :n:`@tactic` when no logical rule may apply.
-
-.. tacv:: firstorder using {+ @qualid}
-
- .. deprecated:: 8.3
-
- Use the syntax below instead (with commas).
-
-.. tacv:: firstorder using {+, @qualid}
-
- Adds lemmas :n:`{+, @qualid}` to the proof-search environment. If :n:`@qualid`
- refers to an inductive type, it is the collection of its constructors which are
- added to the proof-search environment.
-
-.. tacv:: firstorder with {+ @ident}
-
- Adds lemmas from :tacn:`auto` hint bases :n:`{+ @ident}` to the proof-search
- environment.
-
-.. tacv:: firstorder @tactic using {+, @qualid} with {+ @ident}
-
- This combines the effects of the different variants of :tacn:`firstorder`.
-
-.. opt:: Firstorder Depth @natural
- :name: Firstorder Depth
-
- This option controls the proof-search depth bound.
-
-.. tacn:: congruence
- :name: congruence
-
- The tactic :tacn:`congruence`, by Pierre Corbineau, implements the standard
- Nelson and Oppen congruence closure algorithm, which is a decision procedure
- for ground equalities with uninterpreted symbols. It also includes
- constructor theory (see :tacn:`injection` and :tacn:`discriminate`). If the goal
- is a non-quantified equality, congruence tries to prove it with non-quantified
- equalities in the context. Otherwise it tries to infer a discriminable equality
- from those in the context. Alternatively, congruence tries to prove that a
- hypothesis is equal to the goal or to the negation of another hypothesis.
-
- :tacn:`congruence` is also able to take advantage of hypotheses stating
- quantified equalities, but you have to provide a bound for the number of extra
- equalities generated that way. Please note that one of the sides of the
- equality must contain all the quantified variables in order for congruence to
- match against it.
-
-.. example::
-
- .. coqtop:: reset all
-
- Theorem T (A:Type) (f:A -> A) (g: A -> A -> A) a b: a=(f a) -> (g b (f a))=(f (f a)) -> (g a b)=(f (g b a)) -> (g a b)=a.
- intros.
- congruence.
- Qed.
-
- Theorem inj (A:Type) (f:A -> A * A) (a c d: A) : f = pair a -> Some (f c) = Some (f d) -> c=d.
- intros.
- congruence.
- Qed.
-
-.. tacv:: congruence @natural
-
- Tries to add at most :token:`natural` instances of hypotheses stating quantified equalities
- to the problem in order to solve it. A bigger value of :token:`natural` does not make
- success slower, only failure. You might consider adding some lemmas as
- hypotheses using assert in order for :tacn:`congruence` to use them.
-
-.. tacv:: congruence with {+ @term}
- :name: congruence with
-
- Adds :n:`{+ @term}` to the pool of terms used by :tacn:`congruence`. This helps
- in case you have partially applied constructors in your goal.
-
-.. exn:: I don’t know how to handle dependent equality.
-
- The decision procedure managed to find a proof of the goal or of a
- discriminable equality but this proof could not be built in Coq because of
- dependently-typed functions.
-
-.. exn:: Goal is solvable by congruence but some arguments are missing. Try congruence with {+ @term}, replacing metavariables by arbitrary terms.
-
- The decision procedure could solve the goal with the provision that additional
- arguments are supplied for some partially applied constructors. Any term of an
- appropriate type will allow the tactic to successfully solve the goal. Those
- additional arguments can be given to congruence by filling in the holes in the
- terms given in the error message, using the :tacn:`congruence with` variant described above.
-
-.. flag:: Congruence Verbose
-
- This flag makes :tacn:`congruence` print debug information.
-
Checking properties of terms
----------------------------
@@ -4600,13 +2840,13 @@ symbol :g:`=`.
:n:`simplify_eq @ident` where :n:`@ident` is the identifier for the last
introduced hypothesis.
-.. tacv:: simplify_eq @term with @bindings_list
+.. tacv:: simplify_eq @term with @bindings
This does the same as :n:`simplify_eq @term` but using the given bindings to
instantiate parameters or hypotheses of :n:`@term`.
.. tacv:: esimplify_eq @natural
- esimplify_eq @term {? with @bindings_list}
+ esimplify_eq @term {? with @bindings}
:name: esimplify_eq; _
This works the same as :tacn:`simplify_eq` but if the type of :n:`@term`, or the
@@ -4653,189 +2893,6 @@ using the ``Require Import`` command.
Use :tacn:`classical_right` to prove the right part of the disjunction with
the assumption that the negation of left part holds.
-.. _tactics-automating:
-
-Automating
-------------
-
-
-.. tacn:: btauto
- :name: btauto
-
- The tactic :tacn:`btauto` implements a reflexive solver for boolean
- tautologies. It solves goals of the form :g:`t = u` where `t` and `u` are
- constructed over the following grammar:
-
- .. prodn::
- btauto_term ::= @ident
- | true
- | false
- | orb @btauto_term @btauto_term
- | andb @btauto_term @btauto_term
- | xorb @btauto_term @btauto_term
- | negb @btauto_term
- | if @btauto_term then @btauto_term else @btauto_term
-
- Whenever the formula supplied is not a tautology, it also provides a
- counter-example.
-
- Internally, it uses a system very similar to the one of the ring
- tactic.
-
- Note that this tactic is only available after a ``Require Import Btauto``.
-
- .. exn:: Cannot recognize a boolean equality.
-
- The goal is not of the form :g:`t = u`. Especially note that :tacn:`btauto`
- doesn't introduce variables into the context on its own.
-
-.. tacv:: field
- field_simplify {* @term}
- field_simplify_eq
-
- The field tactic is built on the same ideas as ring: this is a
- reflexive tactic that solves or simplifies equations in a field
- structure. The main idea is to reduce a field expression (which is an
- extension of ring expressions with the inverse and division
- operations) to a fraction made of two polynomial expressions.
-
- Tactic :n:`field` is used to solve subgoals, whereas :n:`field_simplify {+ @term}`
- replaces the provided terms by their reduced fraction.
- :n:`field_simplify_eq` applies when the conclusion is an equation: it
- simplifies both hand sides and multiplies so as to cancel
- denominators. So it produces an equation without division nor inverse.
-
- All of these 3 tactics may generate a subgoal in order to prove that
- denominators are different from zero.
-
- See :ref:`Theringandfieldtacticfamilies` for more information on the tactic and how to
- declare new field structures. All declared field structures can be
- printed with the Print Fields command.
-
-.. example::
-
- .. coqtop:: reset all
-
- Require Import Reals.
- Goal forall x y:R,
- (x * y > 0)%R ->
- (x * (1 / x + x / (x + y)))%R =
- ((- 1 / y) * y * (- x * (x / (x + y)) - 1))%R.
-
- intros; field.
-
-.. seealso::
-
- File plugins/ring/RealField.v for an example of instantiation,
- theory theories/Reals for many examples of use of field.
-
-Non-logical tactics
-------------------------
-
-
-.. tacn:: cycle @integer
- :name: cycle
-
- Reorders the selected goals so that the first :n:`@integer` goals appear after the
- other selected goals.
- If :n:`@integer` is negative, it puts the last :n:`@integer` goals at the
- beginning of the list.
- The tactic is only useful with a goal selector, most commonly `all:`.
- Note that other selectors reorder goals; `1,3: cycle 1` is not equivalent
- to `all: cycle 1`. See :tacn:`… : … (goal selector)`.
-
-.. example::
-
- .. 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.
- all: cycle -3.
-
-.. tacn:: swap @integer @integer
- :name: swap
-
- Exchanges the position of the specified goals.
- Negative values for :n:`@integer` indicate counting goals
- backward from the end of the list of selected goals. Goals are indexed from 1.
- The tactic is only useful with a goal selector, most commonly `all:`.
- Note that other selectors reorder goals; `1,3: swap 1 3` is not equivalent
- to `all: swap 1 3`. See :tacn:`… : … (goal selector)`.
-
-.. example::
-
- .. coqtop:: all abort
-
- Goal P 1 /\ P 2 /\ P 3 /\ P 4 /\ P 5.
- repeat split.
- all: swap 1 3.
- all: swap 1 -1.
-
-.. tacn:: revgoals
- :name: revgoals
-
- Reverses the order of the selected goals. The tactic is only useful with a goal
- selector, most commonly `all :`. Note that other selectors reorder goals;
- `1,3: revgoals` is not equivalent to `all: revgoals`. See :tacn:`… : … (goal selector)`.
-
- .. example::
-
- .. coqtop:: all abort
-
- Goal P 1 /\ P 2 /\ P 3 /\ P 4 /\ P 5.
- repeat split.
- all: revgoals.
-
-.. tacn:: shelve
- :name: shelve
-
- This tactic moves all goals under focus to a shelf. While on the
- shelf, goals will not be focused on. They can be solved by
- unification, or they can be called back into focus with the command
- :cmd:`Unshelve`.
-
- .. tacv:: shelve_unifiable
- :name: shelve_unifiable
-
- Shelves only the goals under focus that are mentioned in other goals.
- Goals that appear in the type of other goals can be solved by unification.
-
- .. example::
-
- .. coqtop:: all abort
-
- Goal exists n, n=0.
- refine (ex_intro _ _ _).
- all: shelve_unifiable.
- reflexivity.
-
-.. cmd:: Unshelve
-
- This command moves all the goals on the shelf (see :tacn:`shelve`)
- from the shelf into focus, by appending them to the end of the current
- list of focused goals.
-
-.. tacn:: unshelve @tactic
- :name: unshelve
-
- Performs :n:`@tactic`, then unshelves existential variables added to the
- shelf by the execution of :n:`@tactic`, prepending them to the current goal.
-
-.. tacn:: give_up
- :name: give_up
-
- This tactic removes the focused goals from the proof. They are not
- solved, and cannot be solved later in the proof. As the goals are not
- solved, the proof cannot be closed.
-
- The ``give_up`` tactic can be used while editing a proof, to choose to
- write the proof script in a non-sequential order.
-
Delaying solving unification constraints
----------------------------------------
diff --git a/doc/sphinx/proof-engine/vernacular-commands.rst b/doc/sphinx/proof-engine/vernacular-commands.rst
index 6c07253bce..86d1d25745 100644
--- a/doc/sphinx/proof-engine/vernacular-commands.rst
+++ b/doc/sphinx/proof-engine/vernacular-commands.rst
@@ -133,7 +133,7 @@ to accessible objects. (see Section :ref:`invocation-of-tactics`).
.. prodn::
search_item ::= {? {| head | hyp | concl | headhyp | headconcl } : } @string {? % @scope_key }
- | {? {| head | hyp | concl | headhyp | headconcl } : } @one_term
+ | {? {| head | hyp | concl | headhyp | headconcl } : } @one_pattern
| is : @logical_kind
Searched objects can be filtered by patterns, by the constants they
@@ -141,9 +141,9 @@ to accessible objects. (see Section :ref:`invocation-of-tactics`).
names.
The location of the pattern or constant within a term
- :n:`@one_term`
+ :n:`@one_pattern`
Search for objects whose type contains a subterm matching the
- pattern :n:`@one_term`. Holes of the pattern are indicated by
+ pattern :n:`@one_pattern`. Holes of the pattern are indicated by
`_` or :n:`?@ident`. If the same :n:`?@ident` occurs more than
once in the pattern, all occurrences in the subterm must be
identical. See :ref:`this example <search-pattern>`.
@@ -312,7 +312,7 @@ to accessible objects. (see Section :ref:`invocation-of-tactics`).
Search is:Instance [ Reflexive | Symmetric ].
-.. cmd:: SearchHead @one_term {? {| inside | outside } {+ @qualid } }
+.. cmd:: SearchHead @one_pattern {? {| inside | outside } {+ @qualid } }
.. deprecated:: 8.12
@@ -320,8 +320,8 @@ to accessible objects. (see Section :ref:`invocation-of-tactics`).
Displays the name and type of all hypotheses of the
selected goal (if any) and theorems of the current context that have the
- form :n:`{? forall {* @binder }, } {* P__i -> } C` where :n:`@one_term`
- matches a subterm of `C` in head position. For example, a :n:`@one_term` of `f _ b`
+ form :n:`{? forall {* @binder }, } {* P__i -> } C` where :n:`@one_pattern`
+ matches a subterm of `C` in head position. For example, a :n:`@one_pattern` of `f _ b`
matches `f a b`, which is a subterm of `C` in head position when `C` is `f a b c`.
See :cmd:`Search` for an explanation of the `inside`/`outside` clauses.
@@ -337,12 +337,12 @@ to accessible objects. (see Section :ref:`invocation-of-tactics`).
SearchHead le.
SearchHead (@eq bool).
-.. cmd:: SearchPattern @one_term {? {| inside | outside } {+ @qualid } }
+.. cmd:: SearchPattern @one_pattern {? {| inside | outside } {+ @qualid } }
Displays the name and type of all hypotheses of the
selected goal (if any) and theorems of the current context
ending with :n:`{? forall {* @binder }, } {* P__i -> } C` that match the pattern
- :n:`@one_term`.
+ :n:`@one_pattern`.
See :cmd:`Search` for an explanation of the `inside`/`outside` clauses.
@@ -362,11 +362,11 @@ to accessible objects. (see Section :ref:`invocation-of-tactics`).
SearchPattern (?X1 + _ = _ + ?X1).
-.. cmd:: SearchRewrite @one_term {? {| inside | outside } {+ @qualid } }
+.. cmd:: SearchRewrite @one_pattern {? {| inside | outside } {+ @qualid } }
Displays the name and type of all hypotheses of the
selected goal (if any) and theorems of the current context that have the form
- :n:`{? forall {* @binder }, } {* P__i -> } LHS = RHS` where :n:`@one_term`
+ :n:`{? forall {* @binder }, } {* P__i -> } LHS = RHS` where :n:`@one_pattern`
matches either `LHS` or `RHS`.
See :cmd:`Search` for an explanation of the `inside`/`outside` clauses.
@@ -433,7 +433,7 @@ Requests to the environment
reference ::= @qualid
| @string {? % @scope_key }
- Displays the full name of objects from |Coq|'s various qualified namespaces such as terms,
+ Displays the full name of objects from Coq's various qualified namespaces such as terms,
modules and Ltac, thereby showing the module they are defined in. It also displays notation definitions.
:n:`@qualid`
@@ -491,7 +491,7 @@ Printing flags
.. flag:: Fast Name Printing
- When turned on, |Coq| uses an asymptotically faster algorithm for the
+ When turned on, Coq uses an asymptotically faster algorithm for the
generation of unambiguous names of bound variables while printing terms.
While faster, it is also less clever and results in a typically less elegant
display, e.g. it will generate more names rather than reusing certain names
@@ -504,12 +504,12 @@ Printing flags
Loading files
-----------------
-|Coq| offers the possibility of loading different parts of a whole
+Coq offers the possibility of loading different parts of a whole
development stored in separate files. Their contents will be loaded as
if they were entered from the keyboard. This means that the loaded
-files are text files containing sequences of commands for |Coq|’s
-toplevel. This kind of file is called a *script* for |Coq|. The standard
-(and default) extension of |Coq|’s script files is .v.
+files are text files containing sequences of commands for Coq’s
+toplevel. This kind of file is called a *script* for Coq. The standard
+(and default) extension of Coq’s script files is .v.
.. cmd:: Load {? Verbose } {| @string | @ident }
@@ -521,7 +521,7 @@ toplevel. This kind of file is called a *script* for |Coq|. The standard
If :n:`@string` is specified, it must specify a complete filename.
`~` and .. abbreviations are
- allowed as well as shell variables. If no extension is specified, |Coq|
+ allowed as well as shell variables. If no extension is specified, Coq
will use the default extension ``.v``.
Files loaded this way can't leave proofs open, nor can :cmd:`Load`
@@ -531,7 +531,7 @@ toplevel. This kind of file is called a *script* for |Coq|. The standard
:cmd:`Require` loads `.vo` files that were previously
compiled from `.v` files.
- :n:`Verbose` displays the |Coq| output for each command and tactic
+ :n:`Verbose` displays the Coq output for each command and tactic
in the loaded file, as if the commands and tactics were entered interactively.
.. exn:: Can’t find file @ident on loadpath.
@@ -556,14 +556,14 @@ file is a particular case of a module called a *library file*.
.. cmd:: Require {? {| Import | Export } } {+ @qualid }
:name: Require; Require Import; Require Export
- Loads compiled modules into the |Coq| environment. For each :n:`@qualid`, which has the form
+ Loads compiled modules into the Coq environment. For each :n:`@qualid`, which has the form
:n:`{* @ident__prefix . } @ident`, the command searches for the logical name represented
by the :n:`@ident__prefix`\s and loads the compiled file :n:`@ident.vo` from the associated
filesystem directory.
The process is applied recursively to all the loaded files;
if they contain :cmd:`Require` commands, those commands are executed as well.
- The compiled files must have been compiled with the same version of |Coq|.
+ The compiled files must have been compiled with the same version of Coq.
The compiled files are neither replayed nor rechecked.
* :n:`Import` - additionally does an :cmd:`Import` on the loaded module, making components defined
@@ -606,15 +606,15 @@ file is a particular case of a module called a *library file*.
The command tried to load library file :n:`@ident`.vo that
depends on some specific version of library :n:`@qualid` which is not the
- one already loaded in the current |Coq| session. Probably :n:`@ident.v` was
+ one already loaded in the current Coq session. Probably :n:`@ident.v` was
not properly recompiled with the last version of the file containing
module :token:`qualid`.
.. exn:: Bad magic number.
The file :n:`@ident.vo` was found but either it is not a
- |Coq| compiled module, or it was compiled with an incompatible
- version of |Coq|.
+ Coq compiled module, or it was compiled with an incompatible
+ version of Coq.
.. exn:: The file @ident.vo contains library @qualid__1 and not library @qualid__2.
@@ -633,15 +633,16 @@ file is a particular case of a module called a *library file*.
.. cmd:: Print Libraries
This command displays the list of library files loaded in the
- current |Coq| session.
+ current Coq session.
.. cmd:: Declare ML Module {+ @string }
This commands dynamically loads OCaml compiled code from
a :n:`.mllib` file.
It is used to load plugins dynamically. The
- files must be accessible in the current OCaml loadpath (see the
- command :cmd:`Add ML Path`). The :n:`.mllib` suffix may be omitted.
+ files must be accessible in the current OCaml loadpath (see
+ :ref:`command line option <command-line-options>` :n:`-I` and command :cmd:`Add ML Path`). The
+ :n:`.mllib` suffix may be omitted.
This command is reserved for plugin developers, who should provide
a .v file containing the command. Users of the plugins will then generally
@@ -666,7 +667,7 @@ file is a particular case of a module called a *library file*.
Loadpath
------------
-Loadpaths are preferably managed using |Coq| command line options (see
+Loadpaths are preferably managed using Coq command line options (see
Section :ref:`libraries-and-filesystem`) but there remain vernacular commands to manage them
for practical purposes. Such commands are only meant to be issued in
the toplevel, and using them in source files is discouraged.
@@ -703,33 +704,35 @@ the toplevel, and using them in source files is discouraged.
This command is equivalent to the command line option
:n:`-R @string @dirpath`. It adds the physical directory string and all its
- subdirectories to the current |Coq| loadpath.
+ subdirectories to the current Coq loadpath.
.. cmd:: Remove LoadPath @string
- This command removes the path :n:`@string` from the current |Coq| loadpath.
+ This command removes the path :n:`@string` from the current Coq loadpath.
.. cmd:: Print LoadPath {? @dirpath }
- This command displays the current |Coq| loadpath. If :n:`@dirpath` is specified,
+ This command displays the current Coq loadpath. If :n:`@dirpath` is specified,
displays only the paths that extend that prefix.
.. cmd:: Add ML Path @string
- This command adds the path :n:`@string` to the current OCaml
- loadpath (cf. :cmd:`Declare ML Module`).
-
+ Equivalent to the :ref:`command line option <command-line-options>`
+ :n:`-I @string`. Adds the path :n:`@string` to the current OCaml
+ loadpath (cf. :cmd:`Declare ML Module`). It is for
+ convenience, such as for use in an interactive session, and it
+ is not exported to compiled files. For separation of concerns with
+ respect to the relocability of files, we recommend using
+ :n:`-I @string`.
.. cmd:: Print ML Path
- This command displays the current OCaml loadpath. This
- command makes sense only under the bytecode version of ``coqtop``, i.e.
- using option ``-byte``
- (cf. :cmd:`Declare ML Module`).
-
+ Displays the current OCaml loadpath, as provided by
+ the :ref:`command line option <command-line-options>` :n:`-I @string` or by the command :cmd:`Add
+ ML Path` `@string` (cf. :cmd:`Declare ML Module`).
.. _backtracking_subsection:
@@ -789,13 +792,13 @@ Quitting and debugging
.. cmd:: Quit
- Causes |Coq| to exit. Valid only in coqtop.
+ Causes Coq to exit. Valid only in coqtop.
.. cmd:: Drop
This command temporarily enters the OCaml toplevel.
- It is a debug facility used by |Coq|’s implementers. Valid only in the
+ It is a debug facility used by Coq’s implementers. Valid only in the
bytecode version of coqtop.
The OCaml command:
@@ -804,10 +807,10 @@ Quitting and debugging
#use "include";;
adds the right loadpaths and loads some toplevel printers for all
- abstract types of |Coq|- section_path, identifiers, terms, judgments, ….
+ abstract types of Coq- section_path, identifiers, terms, judgments, ….
You can also use the file base_include instead, that loads only the
pretty-printers for section_paths and identifiers. You can return back
- to |Coq| with the command:
+ to Coq with the command:
::
@@ -815,9 +818,9 @@ Quitting and debugging
.. warning::
- #. It only works with the bytecode version of |Coq| (i.e. `coqtop.byte`,
+ #. It only works with the bytecode version of Coq (i.e. `coqtop.byte`,
see Section `interactive-use`).
- #. You must have compiled |Coq| from the source package and set the
+ #. You must have compiled Coq from the source package and set the
environment variable COQTOP to the root of your copy of the sources
(see Section `customization-by-environment-variables`).
@@ -961,7 +964,7 @@ Controlling the reduction strategies and the conversion algorithm
----------------------------------------------------------------------
-|Coq| provides reduction strategies that the tactics can invoke and two
+Coq provides reduction strategies that the tactics can invoke and two
different algorithms to check the convertibility of types. The first
conversion algorithm lazily compares applicative terms while the other
is a brute-force but efficient algorithm that first normalizes the
@@ -980,21 +983,16 @@ described first.
This command has an effect on unfoldable constants, i.e. on constants
defined by :cmd:`Definition` or :cmd:`Let` (with an explicit body), or by a command
- assimilated to a definition such as :cmd:`Fixpoint`, :cmd:`Program Definition`, etc,
+ associated with a definition such as :cmd:`Fixpoint`, etc,
or by a proof ended by :cmd:`Defined`. The command tells not to unfold the
constants in the :n:`@reference` sequence in tactics using δ-conversion (unfolding
a constant is replacing it by its definition).
- :cmd:`Opaque` has also an effect on the conversion algorithm of |Coq|, telling
- it to delay the unfolding of a constant as much as possible when |Coq|
+ :cmd:`Opaque` has also an effect on the conversion algorithm of Coq, telling
+ it to delay the unfolding of a constant as much as possible when Coq
has to check the conversion (see Section :ref:`conversion-rules`) of two distinct
applied constants.
- .. seealso::
-
- Sections :ref:`performingcomputations`, :ref:`tactics-automating`,
- :ref:`proof-editing-mode`
-
.. cmd:: Transparent {+ @reference }
This command accepts the :attr:`global` attribute. By default, the scope
@@ -1015,10 +1013,7 @@ described first.
There is no constant named :n:`@qualid` in the environment.
- .. seealso::
-
- Sections :ref:`performingcomputations`,
- :ref:`tactics-automating`, :ref:`proof-editing-mode`
+.. seealso:: :ref:`performingcomputations` and :ref:`proof-editing-mode`
.. _vernac-strategy:
@@ -1231,7 +1226,7 @@ in support libraries of plug-ins.
.. _exposing-constants-to-ocaml-libraries:
Exposing constants to OCaml libraries
-`````````````````````````````````````
+```````````````````````````````````````
.. cmd:: Register @qualid__1 as @qualid__2
@@ -1268,8 +1263,8 @@ Registering primitive operations
.. cmd:: Primitive @ident_decl {? : @term } := #@ident
Makes the primitive type or primitive operator :n:`#@ident` defined in OCaml
- accessible in |Coq| commands and tactics.
- For internal use by implementors of |Coq|'s standard library or standard library
+ accessible in Coq commands and tactics.
+ For internal use by implementors of Coq's standard library or standard library
replacements. No space is allowed after the `#`. Invalid values give a syntax
error.
diff --git a/doc/sphinx/proofs/automatic-tactics/auto.rst b/doc/sphinx/proofs/automatic-tactics/auto.rst
new file mode 100644
index 0000000000..cc4ab76502
--- /dev/null
+++ b/doc/sphinx/proofs/automatic-tactics/auto.rst
@@ -0,0 +1,689 @@
+.. _automation:
+
+=========================
+Programmable proof search
+=========================
+
+.. tacn:: auto
+ :name: auto
+
+ This tactic implements a Prolog-like resolution procedure to solve the
+ current goal. It first tries to solve the goal using the :tacn:`assumption`
+ tactic, then it reduces the goal to an atomic one using :tacn:`intros` and
+ introduces the newly generated hypotheses as hints. Then it looks at
+ the list of tactics associated to the head symbol of the goal and
+ tries to apply one of them (starting from the tactics with lower
+ cost). This process is recursively applied to the generated subgoals.
+
+ By default, :tacn:`auto` only uses the hypotheses of the current goal and
+ the hints of the database named ``core``.
+
+ .. warning::
+
+ :tacn:`auto` uses a weaker version of :tacn:`apply` that is closer to
+ :tacn:`simple apply` so it is expected that sometimes :tacn:`auto` will
+ fail even if applying manually one of the hints would succeed.
+
+ .. tacv:: auto @natural
+
+ Forces the search depth to be :token:`natural`. The maximal search depth
+ is 5 by default.
+
+ .. tacv:: auto with {+ @ident}
+
+ Uses the hint databases :n:`{+ @ident}` in addition to the database ``core``.
+
+ .. note::
+
+ Use the fake database `nocore` if you want to *not* use the `core`
+ database.
+
+ .. tacv:: auto with *
+
+ Uses all existing hint databases. Using this variant is highly discouraged
+ in finished scripts since it is both slower and less robust than the variant
+ where the required databases are explicitly listed.
+
+ .. seealso::
+ :ref:`The Hints Databases for auto and eauto <thehintsdatabasesforautoandeauto>` for the list of
+ pre-defined databases and the way to create or extend a database.
+
+ .. tacv:: auto using {+ @qualid__i} {? with {+ @ident } }
+
+ Uses lemmas :n:`@qualid__i` in addition to hints. If :n:`@qualid` is an
+ inductive type, it is the collection of its constructors which are added
+ as hints.
+
+ .. note::
+
+ The hints passed through the `using` clause are used in the same
+ way as if they were passed through a hint database. Consequently,
+ they use a weaker version of :tacn:`apply` and :n:`auto using @qualid`
+ may fail where :n:`apply @qualid` succeeds.
+
+ Given that this can be seen as counter-intuitive, it could be useful
+ to have an option to use full-blown :tacn:`apply` for lemmas passed
+ through the `using` clause. Contributions welcome!
+
+ .. tacv:: info_auto
+
+ Behaves like :tacn:`auto` but shows the tactics it uses to solve the goal. This
+ variant is very useful for getting a better understanding of automation, or
+ to know what lemmas/assumptions were used.
+
+ .. tacv:: debug auto
+ :name: debug auto
+
+ Behaves like :tacn:`auto` but shows the tactics it tries to solve the goal,
+ including failing paths.
+
+ .. tacv:: {? info_}auto {? @natural} {? using {+ @qualid}} {? with {+ @ident}}
+
+ This is the most general form, combining the various options.
+
+.. tacv:: trivial
+ :name: trivial
+
+ This tactic is a restriction of :tacn:`auto` that is not recursive
+ and tries only hints that cost `0`. Typically it solves trivial
+ equalities like :g:`X=X`.
+
+ .. tacv:: trivial with {+ @ident}
+ trivial with *
+ trivial using {+ @qualid}
+ debug trivial
+ info_trivial
+ {? info_}trivial {? using {+ @qualid}} {? with {+ @ident}}
+ :name: _; _; _; debug trivial; info_trivial; _
+ :undocumented:
+
+.. note::
+ :tacn:`auto` and :tacn:`trivial` either solve completely the goal or
+ else succeed without changing the goal. Use :g:`solve [ auto ]` and
+ :g:`solve [ trivial ]` if you would prefer these tactics to fail when
+ they do not manage to solve the goal.
+
+.. flag:: Info Auto
+ Debug Auto
+ Info Trivial
+ Debug Trivial
+
+ These flags enable printing of informative or debug information for
+ the :tacn:`auto` and :tacn:`trivial` tactics.
+
+.. tacn:: eauto
+ :name: eauto
+
+ This tactic generalizes :tacn:`auto`. While :tacn:`auto` does not try
+ resolution hints which would leave existential variables in the goal,
+ :tacn:`eauto` does try them (informally speaking, it internally uses a tactic
+ close to :tacn:`simple eapply` instead of a tactic close to :tacn:`simple apply`
+ in the case of :tacn:`auto`). As a consequence, :tacn:`eauto`
+ can solve such a goal:
+
+ .. example::
+
+ .. coqtop:: none
+
+ Set Warnings "-deprecated-hint-without-locality".
+
+ .. coqtop:: all
+
+ Hint Resolve ex_intro : core.
+ Goal forall P:nat -> Prop, P 0 -> exists n, P n.
+ eauto.
+
+ Note that ``ex_intro`` should be declared as a hint.
+
+
+ .. tacv:: {? info_}eauto {? @natural} {? using {+ @qualid}} {? with {+ @ident}}
+
+ The various options for :tacn:`eauto` are the same as for :tacn:`auto`.
+
+ :tacn:`eauto` also obeys the following flags:
+
+ .. flag:: Info Eauto
+ Debug Eauto
+ :undocumented:
+
+ .. seealso:: :ref:`The Hints Databases for auto and eauto <thehintsdatabasesforautoandeauto>`
+
+
+.. tacn:: autounfold with {+ @ident}
+ :name: autounfold
+
+ This tactic unfolds constants that were declared through a :cmd:`Hint Unfold`
+ in the given databases.
+
+.. tacv:: autounfold with {+ @ident} in @goal_occurrences
+
+ Performs the unfolding in the given clause (:token:`goal_occurrences`).
+
+.. tacv:: autounfold with *
+
+ Uses the unfold hints declared in all the hint databases.
+
+.. tacn:: autorewrite with {+ @ident}
+ :name: autorewrite
+
+ 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
+ it fails. Once all the rules have been processed, if the main subgoal has
+ progressed (e.g., if it is distinct from the initial main goal) then the rules
+ of this base are processed again. If the main subgoal has not progressed then
+ the next base is processed. For the bases, the behavior is exactly similar to
+ the processing of the rewriting rules.
+
+ The rewriting rule bases are built with the :cmd:`Hint Rewrite`
+ command.
+
+.. warning::
+
+ This tactic may loop if you build non terminating rewriting systems.
+
+.. tacv:: autorewrite with {+ @ident} using @tactic
+
+ Performs, in the same way, all the rewritings of the bases :n:`{+ @ident}`
+ applying tactic to the main subgoal after each rewriting step.
+
+.. tacv:: autorewrite with {+ @ident} in @qualid
+
+ Performs all the rewritings in hypothesis :n:`@qualid`.
+
+.. tacv:: autorewrite with {+ @ident} in @qualid using @tactic
+
+ Performs all the rewritings in hypothesis :n:`@qualid` applying :n:`@tactic`
+ to the main subgoal after each rewriting step.
+
+.. tacv:: autorewrite with {+ @ident} in @goal_occurrences
+
+ Performs all the rewriting in the clause :n:`@goal_occurrences`.
+
+.. seealso::
+
+ :ref:`Hint-Rewrite <hintrewrite>` for feeding the database of lemmas used by
+ :tacn:`autorewrite` and :tacn:`autorewrite` for examples showing the use of this tactic.
+
+.. tacn:: easy
+ :name: easy
+
+ This tactic tries to solve the current goal by a number of standard closing steps.
+ In particular, it tries to close the current goal using the closing tactics
+ :tacn:`trivial`, :tacn:`reflexivity`, :tacn:`symmetry`, :tacn:`contradiction`
+ and :tacn:`inversion` of hypothesis.
+ If this fails, it tries introducing variables and splitting and-hypotheses,
+ using the closing tactics afterwards, and splitting the goal using
+ :tacn:`split` and recursing.
+
+ This tactic solves goals that belong to many common classes; in particular, many cases of
+ unsatisfiable hypotheses, and simple equality goals are usually solved by this tactic.
+
+.. tacv:: now @tactic
+ :name: now
+
+ Run :n:`@tactic` followed by :tacn:`easy`. This is a notation for :n:`@tactic; easy`.
+
+Controlling automation
+--------------------------
+
+.. _thehintsdatabasesforautoandeauto:
+
+The hints databases for auto and eauto
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The hints for :tacn:`auto` and :tacn:`eauto` are stored in databases. Each database
+maps head symbols to a list of hints.
+
+.. cmd:: Print Hint @ident
+
+ Use this command
+ to display the hints associated to the head symbol :n:`@ident`
+ (see :ref:`Print Hint <printhint>`). Each hint has a cost that is a nonnegative
+ integer, and an optional pattern. The hints with lower cost are tried first. A
+ hint is tried by :tacn:`auto` when the conclusion of the current goal matches its
+ pattern or when it has no pattern.
+
+Creating Hint databases
+```````````````````````
+
+One can optionally declare a hint database using the command
+:cmd:`Create HintDb`. If a hint is added to an unknown database, it will be
+automatically created.
+
+.. cmd:: Create HintDb @ident {? discriminated}
+
+ This command creates a new database named :n:`@ident`. The database is
+ implemented by a Discrimination Tree (DT) that serves as an index of
+ all the lemmas. The DT can use transparency information to decide if a
+ constant should be indexed or not
+ (c.f. :ref:`The hints databases for auto and eauto <thehintsdatabasesforautoandeauto>`),
+ making the retrieval more efficient. The legacy implementation (the default one
+ for new databases) uses the DT only on goals without existentials (i.e., :tacn:`auto`
+ goals), for non-Immediate hints and does not make use of transparency
+ hints, putting more work on the unification that is run after
+ retrieval (it keeps a list of the lemmas in case the DT is not used).
+ The new implementation enabled by the discriminated option makes use
+ of DTs in all cases and takes transparency information into account.
+ However, the order in which hints are retrieved from the DT may differ
+ from the order in which they were inserted, making this implementation
+ observationally different from the legacy one.
+
+.. cmd:: Hint @hint_definition : {+ @ident}
+
+ The general command to add a hint to some databases :n:`{+ @ident}`.
+
+ This command supports the :attr:`local`, :attr:`global` and :attr:`export`
+ locality attributes. When no locality is explictly given, the
+ command is :attr:`local` inside a section and :attr:`global` otherwise.
+
+ + :attr:`local` hints are never visible from other modules, even if they
+ require or import the current module. Inside a section, the :attr:`local`
+ attribute is useless since hints do not survive anyway to the closure of
+ sections.
+
+ + :attr:`export` are visible from other modules when they import the current
+ module. Requiring it is not enough.
+
+ + :attr:`global` hints are made available by merely requiring the current
+ module.
+
+ .. deprecated:: 8.13
+
+ The default value for hint locality is scheduled to change in a future
+ release. For the time being, adding hints outside of sections without
+ specifying an explicit locality is therefore triggering a deprecation
+ warning. It is recommended to use :attr:`export` whenever possible
+
+ The various possible :production:`hint_definition`\s are given below.
+
+ .. cmdv:: Hint @hint_definition
+
+ No database name is given: the hint is registered in the ``core`` database.
+
+ .. deprecated:: 8.10
+
+ .. cmdv:: Hint Resolve @qualid {? | {? @natural} {? @pattern}} : @ident
+ :name: Hint Resolve
+
+ This command adds :n:`simple apply @qualid` to the hint list with the head
+ symbol of the type of :n:`@qualid`. The cost of that hint is the number of
+ subgoals generated by :n:`simple apply @qualid` or :n:`@natural` if specified. The
+ associated :n:`@pattern` is inferred from the conclusion of the type of
+ :n:`@qualid` or the given :n:`@pattern` if specified. In case the inferred type
+ of :n:`@qualid` does not start with a product the tactic added in the hint list
+ is :n:`exact @qualid`. In case this type can however be reduced to a type
+ starting with a product, the tactic :n:`simple apply @qualid` is also stored in
+ the hints list. If the inferred type of :n:`@qualid` contains a dependent
+ quantification on a variable which occurs only in the premisses of the type
+ and not in its conclusion, no instance could be inferred for the variable by
+ unification with the goal. In this case, the hint is added to the hint list
+ of :tacn:`eauto` instead of the hint list of auto and a warning is printed. A
+ typical example of a hint that is used only by :tacn:`eauto` is a transitivity
+ lemma.
+
+ .. exn:: @qualid cannot be used as a hint
+
+ The head symbol of the type of :n:`@qualid` is a bound variable
+ such that this tactic cannot be associated to a constant.
+
+ .. cmdv:: Hint Resolve {+ @qualid} : @ident
+
+ Adds each :n:`Hint Resolve @qualid`.
+
+ .. cmdv:: Hint Resolve -> @qualid : @ident
+
+ Adds the left-to-right implication of an equivalence as a hint (informally
+ the hint will be used as :n:`apply <- @qualid`, although as mentioned
+ before, the tactic actually used is a restricted version of
+ :tacn:`apply`).
+
+ .. cmdv:: Hint Resolve <- @qualid
+
+ Adds the right-to-left implication of an equivalence as a hint.
+
+ .. cmdv:: Hint Immediate @qualid : @ident
+ :name: Hint Immediate
+
+ This command adds :n:`simple apply @qualid; trivial` to the hint list associated
+ with the head symbol of the type of :n:`@ident` in the given database. This
+ tactic will fail if all the subgoals generated by :n:`simple apply @qualid` are
+ not solved immediately by the :tacn:`trivial` tactic (which only tries tactics
+ with cost 0).This command is useful for theorems such as the symmetry of
+ equality or :g:`n+1=m+1 -> n=m` that we may like to introduce with a limited
+ use in order to avoid useless proof-search. The cost of this tactic (which
+ never generates subgoals) is always 1, so that it is not used by :tacn:`trivial`
+ itself.
+
+ .. exn:: @qualid cannot be used as a hint
+ :undocumented:
+
+ .. cmdv:: Hint Immediate {+ @qualid} : @ident
+
+ Adds each :n:`Hint Immediate @qualid`.
+
+ .. cmdv:: Hint Constructors @qualid : @ident
+ :name: Hint Constructors
+
+ If :token:`qualid` is an inductive type, this command adds all its constructors as
+ hints of type ``Resolve``. Then, when the conclusion of current goal has the form
+ :n:`(@qualid ...)`, :tacn:`auto` will try to apply each constructor.
+
+ .. exn:: @qualid is not an inductive type
+ :undocumented:
+
+ .. cmdv:: Hint Constructors {+ @qualid} : @ident
+
+ Extends the previous command for several inductive types.
+
+ .. cmdv:: Hint Unfold @qualid : @ident
+ :name: Hint Unfold
+
+ This adds the tactic :n:`unfold @qualid` to the hint list that will only be
+ used when the head constant of the goal is :token:`qualid`.
+ Its cost is 4.
+
+ .. cmdv:: Hint Unfold {+ @qualid}
+
+ Extends the previous command for several defined constants.
+
+ .. cmdv:: Hint Transparent {+ @qualid} : @ident
+ Hint Opaque {+ @qualid} : @ident
+ :name: Hint Transparent; Hint Opaque
+
+ This adds transparency hints to the database, making :n:`@qualid`
+ transparent or opaque constants during resolution. This information is used
+ during unification of the goal with any lemma in the database and inside the
+ discrimination network to relax or constrain it in the case of discriminated
+ databases.
+
+ .. 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
+ hints in the database for all constants or all variables,
+ overwriting the existing settings of opacity. It is advised
+ to use this just after a :cmd:`Create HintDb` command.
+
+ .. cmdv:: Hint Extern @natural {? @pattern} => @tactic : @ident
+ :name: Hint Extern
+
+ This hint type is to extend :tacn:`auto` with tactics other than :tacn:`apply` and
+ :tacn:`unfold`. For that, we must specify a cost, an optional :n:`@pattern` and a
+ :n:`@tactic` to execute.
+
+ .. example::
+
+ .. coqtop:: none
+
+ Set Warnings "-deprecated-hint-without-locality".
+
+ .. coqtop:: in
+
+ Hint Extern 4 (~(_ = _)) => discriminate : core.
+
+ Now, when the head of the goal is a disequality, ``auto`` will try
+ discriminate if it does not manage to solve the goal with hints with a
+ cost less than 4.
+
+ One can even use some sub-patterns of the pattern in
+ the tactic script. A sub-pattern is a question mark followed by an
+ identifier, like ``?X1`` or ``?X2``. Here is an example:
+
+ .. example::
+
+ .. coqtop:: reset none
+
+ Set Warnings "-deprecated-hint-without-locality".
+
+ .. coqtop:: all
+
+ Require Import List.
+ Hint Extern 5 ({?X1 = ?X2} + {?X1 <> ?X2}) => generalize X1, X2; decide equality : eqdec.
+ Goal forall a b:list (nat * nat), {a = b} + {a <> b}.
+ Info 1 auto with eqdec.
+
+ .. cmdv:: Hint Cut @regexp : @ident
+ :name: Hint Cut
+
+ .. warning::
+
+ These hints currently only apply to typeclass proof search and the
+ :tacn:`typeclasses eauto` tactic.
+
+ This command can be used to cut the proof-search tree according to a regular
+ expression matching paths to be cut. The grammar for regular expressions is
+ the following. Beware, there is no operator precedence during parsing, one can
+ check with :cmd:`Print HintDb` to verify the current cut expression:
+
+ .. prodn::
+ regexp ::= @ident (hint or instance identifier)
+ | _ (any hint)
+ | @regexp | @regexp (disjunction)
+ | @regexp @regexp (sequence)
+ | @regexp * (Kleene star)
+ | emp (empty)
+ | eps (epsilon)
+ | ( @regexp )
+
+ The `emp` regexp does not match any search path while `eps`
+ matches the empty path. During proof search, the path of
+ successive successful hints on a search branch is recorded, as a
+ list of identifiers for the hints (note that :cmd:`Hint Extern`\’s do not have
+ an associated identifier).
+ Before applying any hint :n:`@ident` the current path `p` extended with
+ :n:`@ident` is matched against the current cut expression `c` associated to
+ the hint database. If matching succeeds, the hint is *not* applied. The
+ 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
+ :name: Hint Mode
+
+ This sets an optional mode of use of the identifier :n:`@qualid`. When
+ proof-search faces a goal that ends in an application of :n:`@qualid` to
+ arguments :n:`@term ... @term`, the mode tells if the hints associated to
+ :n:`@qualid` can be applied or not. A mode specification is a list of n ``+``,
+ ``!`` or ``-`` items that specify if an argument of the identifier is to be
+ treated as an input (``+``), if its head only is an input (``!``) or an output
+ (``-``) of the identifier. For a mode to match a list of arguments, input
+ terms and input heads *must not* contain existential variables or be
+ existential variables respectively, while outputs can be any term. Multiple
+ modes can be declared for a single identifier, in that case only one mode
+ needs to match the arguments for the hints to be applied. The head of a term
+ is understood here as the applicative head, or the match or projection
+ scrutinee’s head, recursively, casts being ignored. :cmd:`Hint Mode` is
+ especially useful for typeclasses, when one does not want to support default
+ instances and avoid ambiguity in general. Setting a parameter of a class as an
+ input forces proof-search to be driven by that index of the class, with ``!``
+ giving more flexibility by allowing existentials to still appear deeper in the
+ index but not at its head.
+
+ .. note::
+
+ + One can use a :cmd:`Hint Extern` with no pattern to do
+ pattern matching on hypotheses using ``match goal with``
+ inside the tactic.
+
+ + If you want to add hints such as :cmd:`Hint Transparent`,
+ :cmd:`Hint Cut`, or :cmd:`Hint Mode`, for typeclass
+ resolution, do not forget to put them in the
+ ``typeclass_instances`` hint database.
+
+
+Hint databases defined in the Coq standard library
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Several hint databases are defined in the Coq standard library. The
+actual content of a database is the collection of hints declared
+to belong to this database in each of the various modules currently
+loaded. Especially, requiring new modules may extend the database.
+At Coq startup, only the core database is nonempty and can be used.
+
+:core: This special database is automatically used by ``auto``, except when
+ pseudo-database ``nocore`` is given to ``auto``. The core database
+ contains only basic lemmas about negation, conjunction, and so on.
+ Most of the hints in this database come from the Init and Logic directories.
+
+:arith: This database contains all lemmas about Peano’s arithmetic proved in the
+ directories Init and Arith.
+
+:zarith: contains lemmas about binary signed integers from the
+ directories theories/ZArith. The database also contains
+ high-cost hints that call :tacn:`lia` on equations and
+ inequalities in ``nat`` or ``Z``.
+
+:bool: contains lemmas about booleans, mostly from directory theories/Bool.
+
+:datatypes: is for lemmas about lists, streams and so on that are mainly proved
+ in the Lists subdirectory.
+
+:sets: contains lemmas about sets and relations from the directories Sets and
+ Relations.
+
+:typeclass_instances: contains all the typeclass instances declared in the
+ environment, including those used for ``setoid_rewrite``,
+ from the Classes directory.
+
+:fset: internal database for the implementation of the ``FSets`` library.
+
+:ordered_type: lemmas about ordered types (as defined in the legacy ``OrderedType`` module),
+ mainly used in the ``FSets`` and ``FMaps`` libraries.
+
+You are advised not to put your own hints in the core database, but
+use one or several databases specific to your development.
+
+.. _removehints:
+
+.. cmd:: Remove Hints {+ @term} : {+ @ident}
+
+ This command removes the hints associated to terms :n:`{+ @term}` in databases
+ :n:`{+ @ident}`.
+
+.. _printhint:
+
+.. cmd:: Print Hint
+
+ This command displays all hints that apply to the current goal. It
+ fails if no proof is being edited, while the two variants can be used
+ at every moment.
+
+**Variants:**
+
+
+.. cmd:: Print Hint @ident
+
+ This command displays only tactics associated with :n:`@ident` in the hints
+ list. This is independent of the goal being edited, so this command will not
+ fail if no goal is being edited.
+
+.. cmd:: Print Hint *
+
+ This command displays all declared hints.
+
+.. cmd:: Print HintDb @ident
+
+ This command displays all hints from database :n:`@ident`.
+
+.. _hintrewrite:
+
+.. cmd:: Hint Rewrite {+ @term} : {+ @ident}
+
+ This vernacular command adds the terms :n:`{+ @term}` (their types must be
+ equalities) in the rewriting bases :n:`{+ @ident}` with the default orientation
+ (left to right). Notice that the rewriting bases are distinct from the :tacn:`auto`
+ hint bases and that :tacn:`auto` does not take them into account.
+
+ This command is synchronous with the section mechanism (see :ref:`section-mechanism`):
+ when closing a section, all aliases created by ``Hint Rewrite`` in that
+ section are lost. Conversely, when loading a module, all ``Hint Rewrite``
+ declarations at the global level of that module are loaded.
+
+**Variants:**
+
+.. cmd:: Hint Rewrite -> {+ @term} : {+ @ident}
+
+ This is strictly equivalent to the command above (we only make explicit the
+ orientation which otherwise defaults to ->).
+
+.. cmd:: Hint Rewrite <- {+ @term} : {+ @ident}
+
+ Adds the rewriting rules :n:`{+ @term}` with a right-to-left orientation in
+ the bases :n:`{+ @ident}`.
+
+.. cmd:: Hint Rewrite {? {| -> | <- } } {+ @one_term } {? using @ltac_expr } {? : {* @ident } }
+
+ When the rewriting rules :n:`{+ @term}` in :n:`{+ @ident}` will be used, the
+ tactic ``tactic`` will be applied to the generated subgoals, the main subgoal
+ excluded.
+
+.. cmd:: Print Rewrite HintDb @ident
+
+ This command displays all rewrite hints contained in :n:`@ident`.
+
+Hint locality
+~~~~~~~~~~~~~
+
+Hints provided by the ``Hint`` commands are erased when closing a section.
+Conversely, all hints of a module ``A`` that are not defined inside a
+section (and not defined with option ``Local``) become available when the
+module ``A`` is required (using e.g. ``Require A.``).
+
+As of today, hints only have a binary behavior regarding locality, as
+described above: either they disappear at the end of a section scope,
+or they remain global forever. This causes a scalability issue,
+because hints coming from an unrelated part of the code may badly
+influence another development. It can be mitigated to some extent
+thanks to the :cmd:`Remove Hints` command,
+but this is a mere workaround and has some limitations (for instance, external
+hints cannot be removed).
+
+A proper way to fix this issue is to bind the hints to their module scope, as
+for most of the other objects Coq uses. Hints should only be made available when
+the module they are defined in is imported, not just required. It is very
+difficult to change the historical behavior, as it would break a lot of scripts.
+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" }
+ :name: Loose Hint Behavior
+
+ This option accepts three values, which control the behavior of hints w.r.t.
+ :cmd:`Import`:
+
+ - "Lax": this is the default, and corresponds to the historical behavior,
+ that is, hints defined outside of a section have a global scope.
+
+ - "Warn": outputs a warning when a non-imported hint is used. Note that this
+ is an over-approximation, because a hint may be triggered by a run that
+ will eventually fail and backtrack, resulting in the hint not being
+ actually useful for the proof.
+
+ - "Strict": changes the behavior of an unloaded hint to a immediate fail
+ tactic, allowing to emulate an import-scoped hint mechanism.
+
+.. _tactics-implicit-automation:
+
+Setting implicit automation tactics
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. cmd:: Proof with @tactic
+
+ This command may be used to start a proof. It defines a default tactic
+ to be used each time a tactic command ``tactic``:sub:`1` is ended by ``...``.
+ In this case the tactic command typed by the user is equivalent to
+ ``tactic``:sub:`1` ``;tactic``.
+
+ .. seealso:: :cmd:`Proof` in :ref:`proof-editing-mode`.
+
+
+ .. cmdv:: Proof with @tactic using {+ @ident}
+
+ Combines in a single line ``Proof with`` and ``Proof using``, see :ref:`proof-editing-mode`
+
+ .. cmdv:: Proof using {+ @ident} with @tactic
+
+ Combines in a single line ``Proof with`` and ``Proof using``, see :ref:`proof-editing-mode`
diff --git a/doc/sphinx/proofs/automatic-tactics/index.rst b/doc/sphinx/proofs/automatic-tactics/index.rst
index a219770c69..c3712b109d 100644
--- a/doc/sphinx/proofs/automatic-tactics/index.rst
+++ b/doc/sphinx/proofs/automatic-tactics/index.rst
@@ -1,20 +1,22 @@
.. _automatic-tactics:
=====================================================
-Built-in decision procedures and programmable tactics
+Automatic solvers and programmable tactics
=====================================================
Some tactics are largely automated and are able to solve complex
-goals. This chapter presents both some decision procedures that can
-be used to solve some specific categories of goals, and some
-programmable tactics, that the user can instrument to handle some
+goals. This chapter presents both built-in solvers that can
+be used on specific categories of goals and
+programmable tactics that the user can instrument to handle
complex goals in new domains.
.. toctree::
:maxdepth: 1
+ logic
../../addendum/omega
../../addendum/micromega
../../addendum/ring
../../addendum/nsatz
+ auto
../../addendum/generalized-rewriting
diff --git a/doc/sphinx/proofs/automatic-tactics/logic.rst b/doc/sphinx/proofs/automatic-tactics/logic.rst
new file mode 100644
index 0000000000..5aaded2726
--- /dev/null
+++ b/doc/sphinx/proofs/automatic-tactics/logic.rst
@@ -0,0 +1,228 @@
+.. _decisionprocedures:
+
+==============================
+Solvers for logic and equality
+==============================
+
+.. tacn:: tauto
+
+ This tactic implements a decision procedure for intuitionistic propositional
+ calculus based on the contraction-free sequent calculi LJT* of Roy Dyckhoff
+ :cite:`Dyc92`. Note that :tacn:`tauto` succeeds on any instance of an
+ intuitionistic tautological proposition. :tacn:`tauto` unfolds negations and
+ logical equivalence but does not unfold any other definition.
+
+ .. example::
+
+ The following goal can be proved by :tacn:`tauto` whereas :tacn:`auto` would
+ fail:
+
+ .. coqtop:: reset all
+
+ Goal forall (x:nat) (P:nat -> Prop), x = 0 \/ P x -> x <> 0 -> P x.
+ intros.
+ tauto.
+
+ Moreover, if it has nothing else to do, :tacn:`tauto` performs introductions.
+ Therefore, the use of :tacn:`intros` in the previous proof is unnecessary.
+ :tacn:`tauto` can for instance for:
+
+ .. example::
+
+ .. coqtop:: reset all
+
+ Goal forall (A:Prop) (P:nat -> Prop), A \/ (forall x:nat, ~ A -> P x) -> forall x:nat, ~ A -> P x.
+ tauto.
+
+ .. note::
+ In contrast, :tacn:`tauto` cannot solve the following goal
+ :g:`Goal forall (A:Prop) (P:nat -> Prop), A \/ (forall x:nat, ~ A -> P x) ->`
+ :g:`forall x:nat, ~ ~ (A \/ P x).`
+ because :g:`(forall x:nat, ~ A -> P x)` cannot be treated as atomic and
+ an instantiation of `x` is necessary.
+
+ .. tacn:: dtauto
+
+ While :tacn:`tauto` recognizes inductively defined connectives isomorphic to
+ the standard connectives ``and``, ``prod``, ``or``, ``sum``, ``False``,
+ ``Empty_set``, ``unit`` and ``True``, :tacn:`dtauto` also recognizes all inductive
+ types with one constructor and no indices, i.e. record-style connectives.
+
+.. todo would be nice to explain/discuss the various types of flags
+ that define the differences between these tactics. See Tauto.v/tauto.ml.
+
+.. tacn:: intuition {? @ltac_expr }
+
+ Uses the search tree built by the decision procedure for :tacn:`tauto`
+ to generate a set of subgoals equivalent to the original one (but
+ simpler than it) and applies :n:`@ltac_expr` to them :cite:`Mun94`. If
+ :n:`@ltac_expr` is not specified, it defaults to :n:`auto with *`
+ If :n:`@ltac_expr` fails on some goals then :tacn:`intuition` fails. In fact,
+ :tacn:`tauto` is simply :g:`intuition fail`.
+
+ :tacn:`intuition` recognizes inductively defined connectives
+ isomorphic to the standard connectives ``and``, ``prod``, ``or``, ``sum``, ``False``,
+ ``Empty_set``, ``unit`` and ``True``.
+
+ .. example::
+
+ For instance, the tactic :g:`intuition auto` applied to the goal::
+
+ (forall (x:nat), P x) /\ B -> (forall (y:nat), P y) /\ P O \/ B /\ P O
+
+ internally replaces it by the equivalent one::
+
+ (forall (x:nat), P x), B |- P O
+
+ and then uses :tacn:`auto` which completes the proof.
+
+ .. tacn:: dintuition {? @ltac_expr }
+
+ In addition to the inductively defined connectives recognized by :tacn:`intuition`,
+ :tacn:`dintuition` also recognizes all inductive
+ types with one constructor and no indices, i.e. record-style connectives.
+
+ .. flag:: Intuition Negation Unfolding
+
+ Controls whether :tacn:`intuition` unfolds inner negations which do not need
+ to be unfolded. The flag is on by default.
+
+.. tacn:: rtauto
+
+ Solves propositional tautologies similarly to
+ :tacn:`tauto`, but the proof term is built using a
+ reflection scheme applied to a sequent calculus proof of the goal. The search
+ procedure is also implemented using a different technique.
+
+ Users should be aware that this difference may result in faster proof search
+ but slower proof checking, and :tacn:`rtauto` might not solve goals that
+ :tacn:`tauto` would be able to solve (e.g. goals involving universal
+ quantifiers).
+
+ Note that this tactic is only available after a ``Require Import Rtauto``.
+
+.. tacn:: firstorder {? @ltac_expr } {? using {+, @qualid } } {? with {+ @ident } }
+
+ An experimental extension of :tacn:`tauto` to
+ first-order reasoning. It is not restricted to
+ usual logical connectives but instead can reason about any first-order class
+ inductive definition.
+
+ :token:`ltac_expr`
+ Tries to solve the goal with :token:`ltac_expr` when no logical rule applies.
+ If unspecified, the tactic uses the default from the :opt:`Firstorder Solver`
+ option.
+
+ :n:`using {+, @qualid }`
+ Adds the lemmas :n:`{+, @qualid }` to the proof search environment. If :n:`@qualid`
+ refers to an inductive type, its constructors are
+ added to the proof search environment.
+
+ :n:`with {+ @ident }`
+ Adds lemmas from :tacn:`auto` hint bases :n:`{+ @ident }` to the proof search
+ environment.
+
+ .. opt:: Firstorder Solver @ltac_expr
+
+ The default tactic used by :tacn:`firstorder` when no rule applies in
+ :g:`auto with core`. It can be set locally or globally using this option.
+
+ .. cmd:: Print Firstorder Solver
+
+ Prints the default tactic used by :tacn:`firstorder` when no rule applies.
+
+ .. opt:: Firstorder Depth @natural
+
+ Controls the proof search depth bound.
+
+.. tacn:: congruence {? @natural } {? with {+ @one_term } }
+
+ :token:`natural`
+ Specifies the maximum number of hypotheses stating quantified equalities that may be added
+ to the problem in order to solve it. The default is 1000.
+
+ :n:`{? with {+ @one_term } }`
+ Adds :n:`{+ @one_term }` to the pool of terms used by :tacn:`congruence`. This helps
+ in case you have partially applied constructors in your goal.
+
+ Implements the standard
+ Nelson and Oppen congruence closure algorithm, which is a decision procedure
+ for ground equalities with uninterpreted symbols. It also includes
+ constructor theory (see :tacn:`injection` and :tacn:`discriminate`). If the goal
+ is a non-quantified equality, congruence tries to prove it with non-quantified
+ equalities in the context. Otherwise it tries to infer a discriminable equality
+ from those in the context. Alternatively, congruence tries to prove that a
+ hypothesis is equal to the goal or to the negation of another hypothesis.
+
+ :tacn:`congruence` is also able to take advantage of hypotheses stating
+ quantified equalities, but you have to provide a bound for the number of extra
+ equalities generated that way. Please note that one of the sides of the
+ equality must contain all the quantified variables in order for congruence to
+ match against it.
+
+ Increasing the maximum number of hypotheses may solve
+ problems that would have failed with a smaller value. It will make failures slower but it
+ won't make successes found with the smaller value any slower.
+ You may want to use :tacn:`assert` to add some lemmas as
+ hypotheses so that :tacn:`congruence` can use them.
+
+ .. example::
+
+ .. coqtop:: reset all
+
+ Theorem T (A:Type) (f:A -> A) (g: A -> A -> A) a b: a=(f a) -> (g b (f a))=(f (f a)) -> (g a b)=(f (g b a)) -> (g a b)=a.
+ intros.
+ congruence.
+ Qed.
+
+ Theorem inj (A:Type) (f:A -> A * A) (a c d: A) : f = pair a -> Some (f c) = Some (f d) -> c=d.
+ intros.
+ congruence.
+ Qed.
+
+ .. exn:: I don’t know how to handle dependent equality.
+
+ The decision procedure managed to find a proof of the goal or of a
+ discriminable equality but this proof could not be built in Coq because of
+ dependently-typed functions.
+
+ .. exn:: Goal is solvable by congruence but some arguments are missing. Try congruence with {+ @term}, replacing metavariables by arbitrary terms.
+
+ The decision procedure could solve the goal with the provision that additional
+ arguments are supplied for some partially applied constructors. Any term of an
+ appropriate type will allow the tactic to successfully solve the goal. Those
+ additional arguments can be given to congruence by filling in the holes in the
+ terms given in the error message, using the `with` clause.
+
+ .. flag:: Congruence Verbose
+
+ Makes :tacn:`congruence` print debug information.
+
+.. tacn:: btauto
+
+ The tactic :tacn:`btauto` implements a reflexive solver for boolean
+ tautologies. It solves goals of the form :g:`t = u` where `t` and `u` are
+ constructed over the following grammar:
+
+ .. prodn::
+ btauto_term ::= @ident
+ | true
+ | false
+ | orb @btauto_term @btauto_term
+ | andb @btauto_term @btauto_term
+ | xorb @btauto_term @btauto_term
+ | negb @btauto_term
+ | if @btauto_term then @btauto_term else @btauto_term
+
+ Whenever the formula supplied is not a tautology, it also provides a
+ counter-example.
+
+ Internally, it uses a system very similar to the one of the ring
+ tactic.
+
+ Note that this tactic is only available after a ``Require Import Btauto``.
+
+ .. exn:: Cannot recognize a boolean equality.
+
+ The goal is not of the form :g:`t = u`. Especially note that :tacn:`btauto`
+ doesn't introduce variables into the context on its own.
diff --git a/doc/sphinx/proofs/writing-proofs/index.rst b/doc/sphinx/proofs/writing-proofs/index.rst
index a279a5957f..7724d7433c 100644
--- a/doc/sphinx/proofs/writing-proofs/index.rst
+++ b/doc/sphinx/proofs/writing-proofs/index.rst
@@ -1,8 +1,8 @@
.. _writing-proofs:
-==============
-Writing proofs
-==============
+===================
+Basic proof writing
+===================
Coq is an interactive theorem prover, or proof assistant, which means
that proofs can be constructed interactively through a dialog between
@@ -27,8 +27,9 @@ flavors of tactics, including the SSReflect proof language.
.. toctree::
:maxdepth: 1
- ../../proof-engine/proof-handling
+ proof-mode
../../proof-engine/tactics
+ rewriting
../../proof-engine/ssreflect-proof-language
../../proof-engine/detailed-tactic-examples
../../user-extensions/proof-schemes
diff --git a/doc/sphinx/proofs/writing-proofs/proof-mode.rst b/doc/sphinx/proofs/writing-proofs/proof-mode.rst
new file mode 100644
index 0000000000..40d032543f
--- /dev/null
+++ b/doc/sphinx/proofs/writing-proofs/proof-mode.rst
@@ -0,0 +1,1043 @@
+.. _proofhandling:
+
+-------------------
+ Proof handling
+-------------------
+
+In Coq’s proof editing mode all top-level commands documented in
+Chapter :ref:`vernacularcommands` remain available and the user has access to specialized
+commands dealing with proof development pragmas documented in this
+section. They can also use some other specialized commands called
+*tactics*. They are the very tools allowing the user to deal with
+logical reasoning. They are documented in Chapter :ref:`tactics`.
+
+Coq user interfaces usually have a way of marking whether the user has
+switched to proof editing mode. For instance, in coqtop the prompt ``Coq <``   is changed into
+:n:`@ident <`   where :token:`ident` is the declared name of the theorem currently edited.
+
+At each stage of a proof development, one has a list of goals to
+prove. Initially, the list consists only in the theorem itself. After
+having applied some tactics, the list of goals contains the subgoals
+generated by the tactics.
+
+To each subgoal is associated a number of hypotheses called the *local context*
+of the goal. Initially, the local context contains the local variables and
+hypotheses of the current section (see Section :ref:`gallina-assumptions`) and
+the local variables and hypotheses of the theorem statement. It is enriched by
+the use of certain tactics (see e.g. :tacn:`intro`).
+
+When a proof is completed, the message ``Proof completed`` is displayed.
+One can then register this proof as a defined constant in the
+environment. Because there exists a correspondence between proofs and
+terms of λ-calculus, known as the *Curry-Howard isomorphism*
+:cite:`How80,Bar81,Gir89,H89`, Coq stores proofs as terms of |Cic|. Those
+terms are called *proof terms*.
+
+
+.. exn:: No focused proof.
+
+ Coq raises this error message when one attempts to use a proof editing command
+ out of the proof editing mode.
+
+.. _proof-editing-mode:
+
+Entering and leaving proof editing mode
+---------------------------------------
+
+The proof editing mode is entered by asserting a statement, which typically is
+the assertion of a theorem using an assertion command like :cmd:`Theorem`. The
+list of assertion commands is given in :ref:`Assertions`. The command
+:cmd:`Goal` can also be used.
+
+.. cmd:: Goal @type
+
+ This is intended for quick assertion of statements, without knowing in
+ advance which name to give to the assertion, typically for quick
+ testing of the provability of a statement. If the proof of the
+ statement is eventually completed and validated, the statement is then
+ bound to the name ``Unnamed_thm`` (or a variant of this name not already
+ used for another statement).
+
+.. cmd:: Qed
+
+ This command is available in interactive editing proof mode when the
+ proof is completed. Then :cmd:`Qed` extracts a proof term from the proof
+ script, switches back to Coq top-level and attaches the extracted
+ proof term to the declared name of the original goal. The name is
+ added to the environment as an opaque constant.
+
+ .. exn:: Attempt to save an incomplete proof.
+ :undocumented:
+
+ .. note::
+
+ Sometimes an error occurs when building the proof term, because
+ tactics do not enforce completely the term construction
+ constraints.
+
+ The user should also be aware of the fact that since the
+ proof term is completely rechecked at this point, one may have to wait
+ a while when the proof is large. In some exceptional cases one may
+ even incur a memory overflow.
+
+.. cmd:: Save @ident
+ :name: Save
+
+ Saves a completed proof with the name :token:`ident`, which
+ overrides any name provided by the :cmd:`Theorem` command or
+ its variants.
+
+.. cmd:: Defined {? @ident }
+
+ Similar to :cmd:`Qed` and :cmd:`Save`, except the proof is made *transparent*, which means
+ that its content can be explicitly used for type checking and that it can be
+ unfolded in conversion tactics (see :ref:`performingcomputations`,
+ :cmd:`Opaque`, :cmd:`Transparent`). If :token:`ident` is specified,
+ the proof is defined with the given name, which overrides any name
+ provided by the :cmd:`Theorem` command or its variants.
+
+.. cmd:: Admitted
+
+ This command is available in interactive editing mode to give up
+ the current proof and declare the initial goal as an axiom.
+
+.. cmd:: Abort {? {| All | @ident } }
+
+ Cancels the current proof development, switching back to
+ the previous proof development, or to the Coq toplevel if no other
+ proof was being edited.
+
+ :n:`@ident`
+ Aborts editing the proof named :n:`@ident` for use when you have
+ nested proofs. See also :flag:`Nested Proofs Allowed`.
+
+ :n:`All`
+ Aborts all current proofs.
+
+ .. exn:: No focused proof (No proof-editing in progress).
+ :undocumented:
+
+.. cmd:: Proof @term
+ :name: Proof `term`
+
+ This command applies in proof editing mode. It is equivalent to
+ :n:`exact @term. Qed.`
+ That is, you have to give the full proof in one gulp, as a
+ proof term (see Section :ref:`applyingtheorems`).
+
+ .. warning::
+
+ Use of this command is discouraged. In particular, it
+ doesn't work in Proof General because it must
+ immediately follow the command that opened proof mode, but
+ Proof General inserts :cmd:`Unset` :flag:`Silent` before it (see
+ `Proof General issue #498
+ <https://github.com/ProofGeneral/PG/issues/498>`_).
+
+.. cmd:: Proof
+
+ Is a no-op which is useful to delimit the sequence of tactic commands
+ which start a proof, after a :cmd:`Theorem` command. It is a good practice to
+ use :cmd:`Proof` as an opening parenthesis, closed in the script with a
+ closing :cmd:`Qed`.
+
+ .. seealso:: :cmd:`Proof with`
+
+.. cmd:: Proof using @section_var_expr {? with @ltac_expr }
+
+ .. insertprodn section_var_expr starred_ident_ref
+
+ .. prodn::
+ section_var_expr ::= {* @starred_ident_ref }
+ | {? - } @section_var_expr50
+ section_var_expr50 ::= @section_var_expr0 - @section_var_expr0
+ | @section_var_expr0 + @section_var_expr0
+ | @section_var_expr0
+ section_var_expr0 ::= @starred_ident_ref
+ | ( @section_var_expr ) {? * }
+ starred_ident_ref ::= @ident {? * }
+ | Type {? * }
+ | All
+
+ Opens proof editing mode, declaring the set of
+ section variables (see :ref:`gallina-assumptions`) used by the proof.
+ At :cmd:`Qed` time, the
+ system verifies that the set of section variables used in
+ the proof is a subset of the declared one.
+
+ The set of declared variables is closed under type dependency. For
+ example, if ``T`` is a variable and ``a`` is a variable of type
+ ``T``, then the commands ``Proof using a`` and ``Proof using T a``
+ are equivalent.
+
+ The set of declared variables always includes the variables used by
+ the statement. In other words ``Proof using e`` is equivalent to
+ ``Proof using Type + e`` for any declaration expression ``e``.
+
+ :n:`- @section_var_expr50`
+ Use all section variables except those specified by :n:`@section_var_expr50`
+
+ :n:`@section_var_expr0 + @section_var_expr0`
+ Use section variables from the union of both collections.
+ See :ref:`nameaset` to see how to form a named collection.
+
+ :n:`@section_var_expr0 - @section_var_expr0`
+ Use section variables which are in the first collection but not in the
+ second one.
+
+ :n:`{? * }`
+ Use the transitive closure of the specified collection.
+
+ :n:`Type`
+ Use only section variables occurring in the statement. Specifying :n:`*`
+ uses the forward transitive closure of all the section variables occurring
+ in the statement. For example, if the variable ``H`` has type ``p < 5`` then
+ ``H`` is in ``p*`` since ``p`` occurs in the type of ``H``.
+
+ :n:`All`
+ Use all section variables.
+
+ .. seealso:: :ref:`tactics-implicit-automation`
+
+.. attr:: using
+
+ This attribute can be applied to the :cmd:`Definition`, :cmd:`Example`,
+ :cmd:`Fixpoint` and :cmd:`CoFixpoint` commands as well as to :cmd:`Lemma` and
+ its variants. It takes
+ a :n:`@section_var_expr`, in quotes, as its value. This is equivalent to
+ specifying the same :n:`@section_var_expr` in
+ :cmd:`Proof using`.
+
+ .. example::
+
+ .. coqtop:: all
+
+ Section Test.
+ Variable n : nat.
+ Hypothesis Hn : n <> 0.
+
+ #[using="Hn"]
+ Lemma example : 0 < n.
+
+ .. coqtop:: in
+
+ Abort.
+ End Test.
+
+
+Proof using options
+```````````````````
+
+The following options modify the behavior of ``Proof using``.
+
+
+.. opt:: Default Proof Using "@section_var_expr"
+ :name: Default Proof Using
+
+ Use :n:`@section_var_expr` as the default ``Proof using`` value. E.g. ``Set Default
+ Proof Using "a b"`` will complete all ``Proof`` commands not followed by a
+ ``using`` part with ``using a b``.
+
+
+.. flag:: Suggest Proof Using
+
+ When :cmd:`Qed` is performed, suggest a ``using`` annotation if the user did not
+ provide one.
+
+.. _`nameaset`:
+
+Name a set of section hypotheses for ``Proof using``
+````````````````````````````````````````````````````
+
+.. cmd:: Collection @ident := @section_var_expr
+
+ This can be used to name a set of section
+ hypotheses, with the purpose of making ``Proof using`` annotations more
+ compact.
+
+ .. example::
+
+ Define the collection named ``Some`` containing ``x``, ``y`` and ``z``::
+
+ Collection Some := x y z.
+
+ Define the collection named ``Fewer`` containing only ``x`` and ``y``::
+
+ Collection Fewer := Some - z
+
+ Define the collection named ``Many`` containing the set union or set
+ difference of ``Fewer`` and ``Some``::
+
+ Collection Many := Fewer + Some
+ Collection Many := Fewer - Some
+
+ Define the collection named ``Many`` containing the set difference of
+ ``Fewer`` and the unnamed collection ``x y``::
+
+ Collection Many := Fewer - (x y)
+
+
+
+.. cmd:: Existential @natural {? : @type } := @term
+
+ This command instantiates an existential variable. :token:`natural` is an index in
+ the list of uninstantiated existential variables displayed by :cmd:`Show Existentials`.
+
+ This command is intended to be used to instantiate existential
+ variables when the proof is completed but some uninstantiated
+ existential variables remain. To instantiate existential variables
+ during proof edition, you should use the tactic :tacn:`instantiate`.
+
+ .. deprecated:: 8.13
+
+.. cmd:: Grab Existential Variables
+
+ This command can be run when a proof has no more goal to be solved but
+ has remaining uninstantiated existential variables. It takes every
+ uninstantiated existential variable and turns it into a goal.
+
+ .. deprecated:: 8.13
+
+ Use :cmd:`Unshelve` instead.
+
+Proof modes
+```````````
+
+When entering proof mode through commands such as :cmd:`Goal` and :cmd:`Proof`,
+Coq picks by default the |Ltac| mode. Nonetheless, there exist other proof modes
+shipped in the standard Coq installation, and furthermore some plugins define
+their own proof modes. The default proof mode used when opening a proof can
+be changed using the following option.
+
+.. opt:: Default Proof Mode @string
+
+ Select the proof mode to use when starting a proof. Depending on the proof
+ mode, various syntactic constructs are allowed when writing an interactive
+ proof. All proof modes support vernacular commands; the proof mode determines
+ which tactic language and set of tactic definitions are available. The
+ possible option values are:
+
+ `"Classic"`
+ Activates the |Ltac| language and the tactics with the syntax documented
+ in this manual.
+ Some tactics are not available until the associated plugin is loaded,
+ such as `SSR` or `micromega`.
+ This proof mode is set when the :term:`prelude` is loaded.
+
+ `"Noedit"`
+ No tactic
+ language is activated at all. This is the default when the :term:`prelude`
+ is not loaded, e.g. through the `-noinit` option for `coqc`.
+
+ `"Ltac2"`
+ Activates the Ltac2 language and the Ltac2-specific variants of the documented
+ tactics.
+ This value is only available after :cmd:`Requiring <Require>` Ltac2.
+ :cmd:`Importing <Import>` Ltac2 sets this mode.
+
+ Some external plugins also define their own proof mode, which can be
+ activated with this command.
+
+Navigation in the proof tree
+--------------------------------
+
+.. cmd:: Undo {? {? To } @natural }
+
+ Cancels the effect of the last :token:`natural` commands or tactics.
+ The :n:`To @natural` form goes back to the specified state number.
+ If :token:`natural` is not specified, the command goes back one command or tactic.
+
+.. cmd:: Restart
+
+ Restores the proof editing process to the original goal.
+
+ .. exn:: No focused proof to restart.
+ :undocumented:
+
+.. cmd:: Focus {? @natural }
+
+ Focuses the attention on the first subgoal to prove or, if :token:`natural` is
+ specified, the :token:`natural`\-th. The
+ printing of the other subgoals is suspended until the focused subgoal
+ is solved or unfocused.
+
+ .. deprecated:: 8.8
+
+ Prefer the use of bullets or focusing brackets with a goal selector (see below).
+
+.. cmd:: Unfocus
+
+ This command restores to focus the goal that were suspended by the
+ last :cmd:`Focus` command.
+
+ .. deprecated:: 8.8
+
+.. cmd:: Unfocused
+
+ Succeeds if the proof is fully unfocused, fails if there are some
+ goals out of focus.
+
+.. _curly-braces:
+
+.. index:: {
+ }
+
+.. todo: :name: "{"; "}" doesn't work, nor does :name: left curly bracket; right curly bracket,
+ hence the verbose names
+
+.. tacn:: {? {| @natural | [ @ident ] } : } %{
+ %}
+
+ .. todo
+ See https://github.com/coq/coq/issues/12004 and
+ https://github.com/coq/coq/issues/12825.
+
+ ``{`` (without a terminating period) focuses on the first
+ goal. The subproof can only be
+ unfocused when it has been fully solved (*i.e.*, when there is no
+ focused goal left). Unfocusing is then handled by ``}`` (again, without a
+ terminating period). See also an example in the next section.
+
+ Note that when a focused goal is proved a message is displayed
+ together with a suggestion about the right bullet or ``}`` to unfocus it
+ or focus the next one.
+
+ :n:`@natural:`
+ Focuses on the :token:`natural`\-th subgoal to prove.
+
+ :n:`[ @ident ]: %{`
+ Focuses on the named goal :token:`ident`.
+
+ .. note::
+
+ Goals are just existential variables and existential variables do not
+ get a name by default. You can give a name to a goal by using :n:`refine ?[@ident]`.
+ You may also wrap this in an Ltac-definition like:
+
+ .. coqtop:: in
+
+ Ltac name_goal name := refine ?[name].
+
+ .. seealso:: :ref:`existential-variables`
+
+ .. example::
+
+ This first example uses the Ltac definition above, and the named goals
+ only serve for documentation.
+
+ .. coqtop:: all
+
+ Goal forall n, n + 0 = n.
+ Proof.
+ induction n; [ name_goal base | name_goal step ].
+ [base]: {
+
+ .. coqtop:: all
+
+ reflexivity.
+
+ .. coqtop:: in
+
+ }
+
+ .. coqtop:: all
+
+ [step]: {
+
+ .. coqtop:: all
+
+ simpl.
+ f_equal.
+ assumption.
+ }
+ Qed.
+
+ This can also be a way of focusing on a shelved goal, for instance:
+
+ .. coqtop:: all
+
+ Goal exists n : nat, n = n.
+ eexists ?[x].
+ reflexivity.
+ [x]: exact 0.
+ Qed.
+
+ .. exn:: This proof is focused, but cannot be unfocused this way.
+
+ You are trying to use ``}`` but the current subproof has not been fully solved.
+
+ .. exn:: No such goal (@natural).
+ :undocumented:
+
+ .. exn:: No such goal (@ident).
+ :undocumented:
+
+ .. exn:: Brackets do not support multi-goal selectors.
+
+ Brackets are used to focus on a single goal given either by its position
+ or by its name if it has one.
+
+ .. seealso:: The error messages for bullets below.
+
+.. _bullets:
+
+Bullets
+```````
+
+Alternatively, proofs can be structured with bullets instead of ``{`` and ``}``. The
+use of a bullet ``b`` for the first time focuses on the first goal ``g``, the
+same bullet cannot be used again until the proof of ``g`` is completed,
+then it is mandatory to focus the next goal with ``b``. The consequence is
+that ``g`` and all goals present when ``g`` was focused are focused with the
+same bullet ``b``. See the example below.
+
+Different bullets can be used to nest levels. The scope of bullet does
+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 ::= {| {+ - } | {+ + } | {+ * } }
+
+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
+or focus the next one.
+
+.. note::
+
+ In Proof General (``Emacs`` interface to Coq), you must use
+ bullets with the priority ordering shown above to have a correct
+ indentation. For example ``-`` must be the outer bullet and ``**`` the inner
+ one in the example below.
+
+The following example script illustrates all these features:
+
+.. example::
+
+ .. coqtop:: all
+
+ Goal (((True /\ True) /\ True) /\ True) /\ True.
+ Proof.
+ split.
+ - split.
+ + split.
+ ** { split.
+ - trivial.
+ - trivial.
+ }
+ ** trivial.
+ + trivial.
+ - assert True.
+ { trivial. }
+ assumption.
+ Qed.
+
+.. exn:: Wrong bullet @bullet__1: Current bullet @bullet__2 is not finished.
+
+ Before using bullet :n:`@bullet__1` again, you should first finish proving
+ the current focused goal.
+ Note that :n:`@bullet__1` and :n:`@bullet__2` may be the same.
+
+.. exn:: Wrong bullet @bullet__1: Bullet @bullet__2 is mandatory here.
+
+ You must put :n:`@bullet__2` to focus on the next goal. No other bullet is
+ allowed here.
+
+.. exn:: No such goal. Focus next goal with bullet @bullet.
+
+ You tried to apply a tactic but no goals were under focus.
+ Using :n:`@bullet` is mandatory here.
+
+.. FIXME: the :noindex: below works around a Sphinx issue.
+ (https://github.com/sphinx-doc/sphinx/issues/4979)
+ It should be removed once that issue is fixed.
+
+.. exn:: No such goal. Try unfocusing with %}.
+ :noindex:
+
+ You just finished a goal focused by ``{``, you must unfocus it with ``}``.
+
+Mandatory Bullets
+~~~~~~~~~~~~~~~~~
+
+Using :opt:`Default Goal Selector` with the ``!`` selector forces
+tactic scripts to keep focus to exactly one goal (e.g. using bullets)
+or use explicit goal selectors.
+
+Set Bullet Behavior
+~~~~~~~~~~~~~~~~~~~
+
+.. opt:: Bullet Behavior {| "None" | "Strict Subproofs" }
+ :name: Bullet Behavior
+
+ This option controls the bullet behavior and can take two possible values:
+
+ - "None": this makes bullets inactive.
+ - "Strict Subproofs": this makes bullets active (this is the default behavior).
+
+Modifying the order of goals
+````````````````````````````
+
+.. tacn:: cycle @integer
+ :name: cycle
+
+ Reorders the selected goals so that the first :n:`@integer` goals appear after the
+ other selected goals.
+ If :n:`@integer` is negative, it puts the last :n:`@integer` goals at the
+ beginning of the list.
+ The tactic is only useful with a goal selector, most commonly `all:`.
+ Note that other selectors reorder goals; `1,3: cycle 1` is not equivalent
+ to `all: cycle 1`. See :tacn:`… : … (goal selector)`.
+
+.. example::
+
+ .. 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.
+ all: cycle -3.
+
+.. tacn:: swap @integer @integer
+ :name: swap
+
+ Exchanges the position of the specified goals.
+ Negative values for :n:`@integer` indicate counting goals
+ backward from the end of the list of selected goals. Goals are indexed from 1.
+ The tactic is only useful with a goal selector, most commonly `all:`.
+ Note that other selectors reorder goals; `1,3: swap 1 3` is not equivalent
+ to `all: swap 1 3`. See :tacn:`… : … (goal selector)`.
+
+.. example::
+
+ .. coqtop:: all abort
+
+ Goal P 1 /\ P 2 /\ P 3 /\ P 4 /\ P 5.
+ repeat split.
+ all: swap 1 3.
+ all: swap 1 -1.
+
+.. tacn:: revgoals
+ :name: revgoals
+
+ Reverses the order of the selected goals. The tactic is only useful with a goal
+ selector, most commonly `all :`. Note that other selectors reorder goals;
+ `1,3: revgoals` is not equivalent to `all: revgoals`. See :tacn:`… : … (goal selector)`.
+
+ .. example::
+
+ .. coqtop:: all abort
+
+ Goal P 1 /\ P 2 /\ P 3 /\ P 4 /\ P 5.
+ repeat split.
+ all: revgoals.
+
+Postponing the proof of some goals
+``````````````````````````````````
+
+.. tacn:: shelve
+ :name: shelve
+
+ This tactic moves all goals under focus to a shelf. While on the
+ shelf, goals will not be focused on. They can be solved by
+ unification, or they can be called back into focus with the command
+ :cmd:`Unshelve`.
+
+ .. tacv:: shelve_unifiable
+ :name: shelve_unifiable
+
+ Shelves only the goals under focus that are mentioned in other goals.
+ Goals that appear in the type of other goals can be solved by unification.
+
+ .. example::
+
+ .. coqtop:: all abort
+
+ Goal exists n, n=0.
+ refine (ex_intro _ _ _).
+ all: shelve_unifiable.
+ reflexivity.
+
+.. cmd:: Unshelve
+
+ This command moves all the goals on the shelf (see :tacn:`shelve`)
+ from the shelf into focus, by appending them to the end of the current
+ list of focused goals.
+
+.. tacn:: unshelve @tactic
+ :name: unshelve
+
+ Performs :n:`@tactic`, then unshelves existential variables added to the
+ shelf by the execution of :n:`@tactic`, prepending them to the current goal.
+
+.. tacn:: give_up
+ :name: give_up
+
+ This tactic removes the focused goals from the proof. They are not
+ solved, and cannot be solved later in the proof. As the goals are not
+ solved, the proof cannot be closed.
+
+ The ``give_up`` tactic can be used while editing a proof, to choose to
+ write the proof script in a non-sequential order.
+
+.. _requestinginformation:
+
+Requesting information
+----------------------
+
+
+.. cmd:: Show {? {| @ident | @natural } }
+
+ Displays the current goals.
+
+ :n:`@natural`
+ Display only the :token:`natural`\-th subgoal.
+
+ :n:`@ident`
+ Displays the named goal :token:`ident`. This is useful in
+ particular to display a shelved goal but only works if the
+ corresponding existential variable has been named by the user
+ (see :ref:`existential-variables`) as in the following example.
+
+ .. example::
+
+ .. coqtop:: all abort
+
+ Goal exists n, n = 0.
+ eexists ?[n].
+ Show n.
+
+ .. exn:: No focused proof.
+ :undocumented:
+
+ .. exn:: No such goal.
+ :undocumented:
+
+.. cmd:: Show Proof {? Diffs {? removed } }
+
+ Displays the proof term generated by the tactics
+ that have been applied so far. If the proof is incomplete, the term
+ will contain holes, which correspond to subterms which are still to be
+ constructed. Each hole is an existential variable, which appears as a
+ question mark followed by an identifier.
+
+ Specifying “Diffs” highlights the difference between the
+ current and previous proof step. By default, the command shows the
+ output once with additions highlighted. Including “removed” shows
+ the output twice: once showing removals and once showing additions.
+ It does not examine the :opt:`Diffs` option. See :ref:`showing_proof_diffs`.
+
+.. cmd:: Show Conjectures
+
+ Prints the names of all the
+ theorems that are currently being proved. As it is possible to start
+ proving a previous lemma during the proof of a theorem, there may
+ be multiple names.
+
+.. cmd:: Show Intro
+
+ If the current goal begins by at least one product,
+ prints the name of the first product as it would be
+ generated by an anonymous :tacn:`intro`. The aim of this command is to ease
+ the writing of more robust scripts. For example, with an appropriate
+ Proof General macro, it is possible to transform any anonymous :tacn:`intro`
+ into a qualified one such as ``intro y13``. In the case of a non-product
+ goal, it prints nothing.
+
+.. cmd:: Show Intros
+
+ Similar to the previous command.
+ Simulates the naming process of :tacn:`intros`.
+
+.. cmd:: Show Existentials
+
+ Displays all open goals / existential variables in the current proof
+ along with the type and the context of each variable.
+
+.. cmd:: Show Match @qualid
+
+ Displays a template of the Gallina :token:`match<term_match>`
+ construct with a branch for each constructor of the type
+ :token:`qualid`. This is used internally by
+ `company-coq <https://github.com/cpitclaudel/company-coq>`_.
+
+ .. example::
+
+ .. coqtop:: all
+
+ Show Match nat.
+
+ .. exn:: Unknown inductive type.
+ :undocumented:
+
+.. cmd:: Show Universes
+
+ Displays the set of all universe constraints and
+ its normalized form at the current stage of the proof, useful for
+ debugging universe inconsistencies.
+
+.. cmd:: Show Goal @natural at @natural
+
+ Available in coqtop. Displays a goal at a
+ proof state using the goal ID number and the proof state ID number.
+ It is primarily for use by tools such as Prooftree that need to fetch
+ goal history in this way. Prooftree is a tool for visualizing a proof
+ as a tree that runs in Proof General.
+
+.. cmd:: Guarded
+
+ Some tactics (e.g. :tacn:`refine`) allow to build proofs using
+ fixpoint or co-fixpoint constructions. Due to the incremental nature
+ of interactive proof construction, the check of the termination (or
+ guardedness) of the recursive calls in the fixpoint or cofixpoint
+ constructions is postponed to the time of the completion of the proof.
+
+ The command :cmd:`Guarded` allows checking if the guard condition for
+ fixpoint and cofixpoint is violated at some time of the construction
+ of the proof without having to wait the completion of the proof.
+
+.. _showing_diffs:
+
+Showing differences between proof steps
+---------------------------------------
+
+Coq can automatically highlight the differences between successive proof steps
+and between values in some error messages. Coq can also highlight differences
+in the proof term.
+For example, the following screenshots of CoqIDE and coqtop show the application
+of the same :tacn:`intros` tactic. The tactic creates two new hypotheses, highlighted in green.
+The conclusion is entirely in pale green because although it’s changed, no tokens were added
+to it. The second screenshot uses the "removed" option, so it shows the conclusion a
+second time with the old text, with deletions marked in red. Also, since the hypotheses are
+new, no line of old text is shown for them.
+
+.. comment screenshot produced with:
+ Inductive ev : nat -> Prop :=
+ | ev_0 : ev 0
+ | ev_SS : forall n : nat, ev n -> ev (S (S n)).
+
+ Fixpoint double (n:nat) :=
+ match n with
+ | O => O
+ | S n' => S (S (double n'))
+ end.
+
+ Goal forall n, ev n -> exists k, n = double k.
+ intros n E.
+
+..
+
+ .. image:: ../../_static/diffs-coqide-on.png
+ :alt: CoqIDE with Set Diffs on
+
+..
+
+ .. image:: ../../_static/diffs-coqide-removed.png
+ :alt: CoqIDE with Set Diffs removed
+
+..
+
+ .. image:: ../../_static/diffs-coqtop-on3.png
+ :alt: coqtop with Set Diffs on
+
+This image shows an error message with diff highlighting in CoqIDE:
+
+..
+
+ .. image:: ../../_static/diffs-error-message.png
+ :alt: CoqIDE error message with diffs
+
+How to enable diffs
+```````````````````
+
+.. opt:: Diffs {| "on" | "off" | "removed" }
+ :name: Diffs
+
+ The “on” setting highlights added tokens in green, while the “removed” setting
+ additionally reprints items with removed tokens in red. Unchanged tokens in
+ modified items are shown with pale green or red. Diffs in error messages
+ use red and green for the compared values; they appear regardless of the setting.
+ (Colors are user-configurable.)
+
+For coqtop, showing diffs can be enabled when starting coqtop with the
+``-diffs on|off|removed`` command-line option or by setting the :opt:`Diffs` option
+within Coq. You will need to provide the ``-color on|auto`` command-line option when
+you start coqtop in either case.
+
+Colors for coqtop can be configured by setting the ``COQ_COLORS`` environment
+variable. See section :ref:`customization-by-environment-variables`. Diffs
+use the tags ``diff.added``, ``diff.added.bg``, ``diff.removed`` and ``diff.removed.bg``.
+
+In CoqIDE, diffs should be enabled from the ``View`` menu. Don’t use the ``Set Diffs``
+command in CoqIDE. You can change the background colors shown for diffs from the
+``Edit | Preferences | Tags`` panel by changing the settings for the ``diff.added``,
+``diff.added.bg``, ``diff.removed`` and ``diff.removed.bg`` tags. This panel also
+lets you control other attributes of the highlights, such as the foreground
+color, bold, italic, underline and strikeout.
+
+Proof General can also display Coq-generated proof diffs automatically.
+Please see the PG documentation section
+"`Showing Proof Diffs" <https://proofgeneral.github.io/doc/master/userman/Coq-Proof-General#Showing-Proof-Diffs>`_)
+for details.
+
+How diffs are calculated
+````````````````````````
+
+Diffs are calculated as follows:
+
+1. Select the old proof state to compare to, which is the proof state before
+ the last tactic that changed the proof. Changes that only affect the view
+ of the proof, such as ``all: swap 1 2``, are ignored.
+
+2. For each goal in the new proof state, determine what old goal to compare
+ it to—the one it is derived from or is the same as. Match the hypotheses by
+ name (order is ignored), handling compacted items specially.
+
+3. For each hypothesis and conclusion (the “items”) in each goal, pass
+ them as strings to the lexer to break them into tokens. Then apply the
+ Myers diff algorithm :cite:`Myers` on the tokens and add appropriate highlighting.
+
+Notes:
+
+* Aside from the highlights, output for the "on" option should be identical
+ to the undiffed output.
+* Goals completed in the last proof step will not be shown even with the
+ "removed" setting.
+
+.. comment The following screenshots show diffs working with multiple goals and with compacted
+ hypotheses. In the first one, notice that the goal ``P 1`` is not highlighted at
+ all after the split because it has not changed.
+
+ .. todo: Use this script and remove the screenshots when COQ_COLORS
+ works for coqtop in sphinx
+ .. coqtop:: none
+
+ Set Diffs "on".
+ Parameter P : nat -> Prop.
+ Goal P 1 /\ P 2 /\ P 3.
+
+ .. coqtop:: out
+
+ split.
+
+ .. coqtop:: all abort
+
+ 2: split.
+
+ ..
+
+ .. coqtop:: none
+
+ Set Diffs "on".
+ Goal forall n m : nat, n + m = m + n.
+ Set Diffs "on".
+
+ .. coqtop:: out
+
+ intros n.
+
+ .. coqtop:: all abort
+
+ intros m.
+
+This screen shot shows the result of applying a :tacn:`split` tactic that replaces one goal
+with 2 goals. Notice that the goal ``P 1`` is not highlighted at all after
+the split because it has not changed.
+
+..
+
+ .. image:: ../../_static/diffs-coqide-multigoal.png
+ :alt: coqide with Set Diffs on with multiple goals
+
+Diffs may appear like this after applying a :tacn:`intro` tactic that results
+in a compacted hypotheses:
+
+..
+
+ .. image:: ../../_static/diffs-coqide-compacted.png
+ :alt: coqide with Set Diffs on with compacted hypotheses
+
+.. _showing_proof_diffs:
+
+"Show Proof" differences
+````````````````````````
+
+To show differences in the proof term:
+
+- In coqtop and Proof General, use the :cmd:`Show Proof` `Diffs` command.
+
+- In CoqIDE, position the cursor on or just after a tactic to compare the proof term
+ after the tactic with the proof term before the tactic, then select
+ `View / Show Proof` from the menu or enter the associated key binding.
+ Differences will be shown applying the current `Show Diffs` setting
+ from the `View` menu. If the current setting is `Don't show diffs`, diffs
+ will not be shown.
+
+ Output with the "added and removed" option looks like this:
+
+ ..
+
+ .. image:: ../../_static/diffs-show-proof.png
+ :alt: coqide with Set Diffs on with compacted hypotheses
+
+Controlling the effect of proof editing commands
+------------------------------------------------
+
+
+.. opt:: Hyps Limit @natural
+ :name: Hyps Limit
+
+ This option controls the maximum number of hypotheses displayed in goals
+ after the application of a tactic. All the hypotheses remain usable
+ in the proof development.
+ When unset, it goes back to the default mode which is to print all
+ available hypotheses.
+
+
+.. flag:: Nested Proofs Allowed
+
+ When turned on (it is off by default), this flag enables support for nested
+ proofs: a new assertion command can be inserted before the current proof is
+ finished, in which case Coq will temporarily switch to the proof of this
+ *nested lemma*. When the proof of the nested lemma is finished (with :cmd:`Qed`
+ or :cmd:`Defined`), its statement will be made available (as if it had been
+ proved before starting the previous proof) and Coq will switch back to the
+ proof of the previous assertion.
+
+.. flag:: Printing Goal Names
+
+ When turned on, the name of the goal is printed in interactive
+ proof mode, which can be useful in cases of cross references
+ between goals.
+
+Controlling memory usage
+------------------------
+
+.. cmd:: Print Debug GC
+
+ Prints heap usage statistics, which are values from the `stat` type of the `Gc` module
+ described
+ `here <https://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html#TYPEstat>`_
+ in the OCaml documentation.
+ The `live_words`, `heap_words` and `top_heap_words` values give the basic information.
+ Words are 8 bytes or 4 bytes, respectively, for 64- and 32-bit executables.
+
+When experiencing high memory usage the following commands can be used
+to force Coq to optimize some of its internal data structures.
+
+.. cmd:: Optimize Proof
+
+ Shrink the data structure used to represent the current proof.
+
+
+.. cmd:: Optimize Heap
+
+ Perform a heap compaction. This is generally an expensive operation.
+ See: `OCaml Gc.compact <http://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html#VALcompact>`_
+ There is also an analogous tactic :tacn:`optimize_heap`.
+
+Memory usage parameters can be set through the :ref:`OCAMLRUNPARAM <OCAMLRUNPARAM>`
+environment variable.
diff --git a/doc/sphinx/proofs/writing-proofs/rewriting.rst b/doc/sphinx/proofs/writing-proofs/rewriting.rst
new file mode 100644
index 0000000000..f3f69a2fdc
--- /dev/null
+++ b/doc/sphinx/proofs/writing-proofs/rewriting.rst
@@ -0,0 +1,857 @@
+=================================
+Term rewriting and simplification
+=================================
+
+.. _rewritingexpressions:
+
+Rewriting expressions
+---------------------
+
+These tactics use the equality :g:`eq:forall A:Type, A->A->Prop` defined in
+file ``Logic.v`` (see :ref:`coq-library-logic`). The notation for :g:`eq T t u` is
+simply :g:`t=u` dropping the implicit type of :g:`t` and :g:`u`.
+
+.. tacn:: rewrite @term
+ :name: rewrite
+
+ This tactic applies to any goal. The type of :token:`term` must have the form
+
+ ``forall (x``:sub:`1` ``:A``:sub:`1` ``) ... (x``:sub:`n` ``:A``:sub:`n` ``), eq term``:sub:`1` ``term``:sub:`2` ``.``
+
+ where :g:`eq` is the Leibniz equality or a registered setoid equality.
+
+ Then :n:`rewrite @term` finds the first subterm matching `term`\ :sub:`1` in the goal,
+ resulting in instances `term`:sub:`1`' and `term`:sub:`2`' and then
+ replaces every occurrence of `term`:subscript:`1`' by `term`:subscript:`2`'.
+ Hence, some of the variables :g:`x`\ :sub:`i` are solved by unification,
+ and some of the types :g:`A`\ :sub:`1`:g:`, ..., A`\ :sub:`n` become new
+ subgoals.
+
+ .. exn:: The @term provided does not end with an equation.
+ :undocumented:
+
+ .. exn:: Tactic generated a subgoal identical to the original goal. This happens if @term does not occur in the goal.
+ :undocumented:
+
+ .. tacv:: rewrite -> @term
+
+ Is equivalent to :n:`rewrite @term`
+
+ .. tacv:: rewrite <- @term
+
+ Uses the equality :n:`@term`:sub:`1` :n:`= @term` :sub:`2` from right to left
+
+ .. tacv:: rewrite @term in @goal_occurrences
+
+ Analogous to :n:`rewrite @term` but rewriting is done following
+ the clause :token:`goal_occurrences`. For instance:
+
+ + :n:`rewrite H in H'` will rewrite `H` in the hypothesis
+ ``H'`` instead of the current goal.
+ + :n:`rewrite H in H' at 1, H'' at - 2 |- *` means
+ :n:`rewrite H; rewrite H in H' at 1; rewrite H in H'' at - 2.`
+ In particular a failure will happen if any of these three simpler tactics
+ fails.
+ + :n:`rewrite H in * |-` will do :n:`rewrite H in H'` for all hypotheses
+ :g:`H'` different from :g:`H`.
+ A success will happen as soon as at least one of these simpler tactics succeeds.
+ + :n:`rewrite H in *` is a combination of :n:`rewrite H` and :n:`rewrite H in * |-`
+ that succeeds if at least one of these two tactics succeeds.
+
+ Orientation :g:`->` or :g:`<-` can be inserted before the :token:`term` to rewrite.
+
+ .. tacv:: rewrite @term at @occurrences
+
+ Rewrite only the given :token:`occurrences` of :token:`term`. Occurrences are
+ specified from left to right as for pattern (:tacn:`pattern`). The rewrite is
+ always performed using setoid rewriting, even for Leibniz’s equality, so one
+ has to ``Import Setoid`` to use this variant.
+
+ .. tacv:: rewrite @term by @tactic
+
+ Use tactic to completely solve the side-conditions arising from the
+ :tacn:`rewrite`.
+
+ .. tacv:: rewrite {+, @orientation @term} {? in @ident }
+
+ Is equivalent to the `n` successive tactics :n:`{+; rewrite @term}`, each one
+ working on the first subgoal generated by the previous one. An :production:`orientation`
+ ``->`` or ``<-`` can be inserted before each :token:`term` to rewrite. One
+ unique clause can be added at the end after the keyword in; it will then
+ affect all rewrite operations.
+
+ In all forms of rewrite described above, a :token:`term` to rewrite can be
+ immediately prefixed by one of the following modifiers:
+
+ + `?` : the tactic :n:`rewrite ?@term` performs the rewrite of :token:`term` as many
+ times as possible (perhaps zero time). This form never fails.
+ + :n:`@natural?` : works similarly, except that it will do at most :token:`natural` rewrites.
+ + `!` : works as `?`, except that at least one rewrite should succeed, otherwise
+ the tactic fails.
+ + :n:`@natural!` (or simply :n:`@natural`) : precisely :token:`natural` rewrites of :token:`term` will be done,
+ leading to failure if these :token:`natural` rewrites are not possible.
+
+ .. tacv:: erewrite @term
+ :name: erewrite
+
+ This tactic works as :n:`rewrite @term` but turning
+ unresolved bindings into existential variables, if any, instead of
+ failing. It has the same variants as :tacn:`rewrite` has.
+
+ .. flag:: Keyed Unification
+
+ Makes higher-order unification used by :tacn:`rewrite` rely on a set of keys to drive
+ unification. The subterms, considered as rewriting candidates, must start with
+ the same key as the left- or right-hand side of the lemma given to rewrite, and the arguments
+ are then unified up to full reduction.
+
+.. tacn:: replace @term with @term’
+ :name: replace
+
+ This tactic applies to any goal. It replaces all free occurrences of :n:`@term`
+ in the current goal with :n:`@term’` and generates an equality :n:`@term = @term’`
+ as a subgoal. This equality is automatically solved if it occurs among
+ the assumptions, or if its symmetric form occurs. It is equivalent to
+ :n:`cut @term = @term’; [intro H`:sub:`n` :n:`; rewrite <- H`:sub:`n` :n:`; clear H`:sub:`n`:n:`|| assumption || symmetry; try assumption]`.
+
+ .. exn:: Terms do not have convertible types.
+ :undocumented:
+
+ .. tacv:: replace @term with @term’ by @tactic
+
+ This acts as :n:`replace @term with @term’` but applies :token:`tactic` to solve the generated
+ subgoal :n:`@term = @term’`.
+
+ .. tacv:: replace @term
+
+ Replaces :n:`@term` with :n:`@term’` using the first assumption whose type has
+ the form :n:`@term = @term’` or :n:`@term’ = @term`.
+
+ .. tacv:: replace -> @term
+
+ Replaces :n:`@term` with :n:`@term’` using the first assumption whose type has
+ the form :n:`@term = @term’`
+
+ .. tacv:: replace <- @term
+
+ Replaces :n:`@term` with :n:`@term’` using the first assumption whose type has
+ the form :n:`@term’ = @term`
+
+ .. tacv:: replace @term {? with @term} in @goal_occurrences {? by @tactic}
+ replace -> @term in @goal_occurrences
+ replace <- @term in @goal_occurrences
+
+ Acts as before but the replacements take place in the specified clauses
+ (:token:`goal_occurrences`) (see :ref:`performingcomputations`) and not
+ only in the conclusion of the goal. The clause argument must not contain
+ any ``type of`` nor ``value of``.
+
+.. tacn:: subst @ident
+ :name: subst
+
+ This tactic applies to a goal that has :n:`@ident` in its context and (at
+ least) one hypothesis, say :g:`H`, of type :n:`@ident = t` or :n:`t = @ident`
+ with :n:`@ident` not occurring in :g:`t`. Then it replaces :n:`@ident` by
+ :g:`t` everywhere in the goal (in the hypotheses and in the conclusion) and
+ clears :n:`@ident` and :g:`H` from the context.
+
+ If :n:`@ident` is a local definition of the form :n:`@ident := t`, it is also
+ unfolded and cleared.
+
+ If :n:`@ident` is a section variable it is expected to have no
+ indirect occurrences in the goal, i.e. that no global declarations
+ implicitly depending on the section variable must be present in the
+ goal.
+
+ .. note::
+ + When several hypotheses have the form :n:`@ident = t` or :n:`t = @ident`, the
+ first one is used.
+
+ + If :g:`H` is itself dependent in the goal, it is replaced by the proof of
+ reflexivity of equality.
+
+ .. tacv:: subst {+ @ident}
+
+ This is equivalent to :n:`subst @ident`:sub:`1`:n:`; ...; subst @ident`:sub:`n`.
+
+ .. tacv:: subst
+
+ This applies :tacn:`subst` repeatedly from top to bottom to all hypotheses of the
+ context for which an equality of the form :n:`@ident = t` or :n:`t = @ident`
+ or :n:`@ident := t` exists, with :n:`@ident` not occurring in
+ ``t`` and :n:`@ident` not a section variable with indirect
+ dependencies in the goal.
+
+ .. flag:: Regular Subst Tactic
+
+ This flag controls the behavior of :tacn:`subst`. When it is
+ activated (it is by default), :tacn:`subst` also deals with the following corner cases:
+
+ + A context with ordered hypotheses :n:`@ident`:sub:`1` :n:`= @ident`:sub:`2`
+ and :n:`@ident`:sub:`1` :n:`= t`, or :n:`t′ = @ident`:sub:`1`` with `t′` not
+ a variable, and no other hypotheses of the form :n:`@ident`:sub:`2` :n:`= u`
+ or :n:`u = @ident`:sub:`2`; without the flag, a second call to
+ subst would be necessary to replace :n:`@ident`:sub:`2` by `t` or
+ `t′` respectively.
+ + The presence of a recursive equation which without the flag would
+ be a cause of failure of :tacn:`subst`.
+ + A context with cyclic dependencies as with hypotheses :n:`@ident`:sub:`1` :n:`= f @ident`:sub:`2`
+ and :n:`@ident`:sub:`2` :n:`= g @ident`:sub:`1` which without the
+ flag would be a cause of failure of :tacn:`subst`.
+
+ Additionally, it prevents a local definition such as :n:`@ident := t` to be
+ unfolded which otherwise it would exceptionally unfold in configurations
+ containing hypotheses of the form :n:`@ident = u`, or :n:`u′ = @ident`
+ with `u′` not a variable. Finally, it preserves the initial order of
+ hypotheses, which without the flag it may break.
+ default.
+
+ .. exn:: Cannot find any non-recursive equality over :n:`@ident`.
+ :undocumented:
+
+ .. exn:: Section variable :n:`@ident` occurs implicitly in global declaration :n:`@qualid` present in hypothesis :n:`@ident`.
+ Section variable :n:`@ident` occurs implicitly in global declaration :n:`@qualid` present in the conclusion.
+
+ Raised when the variable is a section variable with indirect
+ dependencies in the goal.
+
+
+.. tacn:: stepl @term
+ :name: stepl
+
+ This tactic is for chaining rewriting steps. It assumes a goal of the
+ form :n:`R @term @term` where ``R`` is a binary relation and relies on a
+ database of lemmas of the form :g:`forall x y z, R x y -> eq x z -> R z y`
+ where `eq` is typically a setoid equality. The application of :n:`stepl @term`
+ then replaces the goal by :n:`R @term @term` and adds a new goal stating
+ :n:`eq @term @term`.
+
+ .. cmd:: Declare Left Step @term
+
+ Adds :n:`@term` to the database used by :tacn:`stepl`.
+
+ This tactic is especially useful for parametric setoids which are not accepted
+ as regular setoids for :tacn:`rewrite` and :tacn:`setoid_replace` (see
+ :ref:`Generalizedrewriting`).
+
+ .. tacv:: stepl @term by @tactic
+
+ This applies :n:`stepl @term` then applies :token:`tactic` to the second goal.
+
+ .. tacv:: stepr @term by @tactic
+ :name: stepr
+
+ This behaves as :tacn:`stepl` but on the right-hand-side of the binary
+ relation. Lemmas are expected to be of the form
+ :g:`forall x y z, R x y -> eq y z -> R x z`.
+
+ .. cmd:: Declare Right Step @term
+
+ Adds :n:`@term` to the database used by :tacn:`stepr`.
+
+
+.. tacn:: change @term
+ :name: change
+
+ This tactic applies to any goal. It implements the rule ``Conv`` given in
+ :ref:`subtyping-rules`. :g:`change U` replaces the current goal `T`
+ with `U` providing that `U` is well-formed and that `T` and `U` are
+ convertible.
+
+ .. exn:: Not convertible.
+ :undocumented:
+
+ .. tacv:: change @term with @term’
+
+ This replaces the occurrences of :n:`@term` by :n:`@term’` in the current goal.
+ The term :n:`@term` and :n:`@term’` must be convertible.
+
+ .. tacv:: change @term at {+ @natural} with @term’
+
+ This replaces the occurrences numbered :n:`{+ @natural}` of :n:`@term` by :n:`@term’`
+ in the current goal. The terms :n:`@term` and :n:`@term’` must be convertible.
+
+ .. exn:: Too few occurrences.
+ :undocumented:
+
+ .. tacv:: change @term {? {? at {+ @natural}} with @term} in @ident
+
+ This applies the :tacn:`change` tactic not to the goal but to the hypothesis :n:`@ident`.
+
+ .. tacv:: now_show @term
+
+ This is a synonym of :n:`change @term`. It can be used to
+ make some proof steps explicit when refactoring a proof script
+ to make it readable.
+
+ .. seealso:: :ref:`Performing computations <performingcomputations>`
+
+.. _performingcomputations:
+
+Performing computations
+---------------------------
+
+.. insertprodn red_expr pattern_occ
+
+.. prodn::
+ red_expr ::= red
+ | hnf
+ | simpl {? @delta_flag } {? @ref_or_pattern_occ }
+ | cbv {? @strategy_flag }
+ | cbn {? @strategy_flag }
+ | lazy {? @strategy_flag }
+ | compute {? @delta_flag }
+ | vm_compute {? @ref_or_pattern_occ }
+ | native_compute {? @ref_or_pattern_occ }
+ | unfold {+, @unfold_occ }
+ | fold {+ @one_term }
+ | pattern {+, @pattern_occ }
+ | @ident
+ delta_flag ::= {? - } [ {+ @reference } ]
+ strategy_flag ::= {+ @red_flag }
+ | @delta_flag
+ red_flag ::= beta
+ | iota
+ | match
+ | fix
+ | cofix
+ | zeta
+ | delta {? @delta_flag }
+ ref_or_pattern_occ ::= @reference {? at @occs_nums }
+ | @one_term {? at @occs_nums }
+ occs_nums ::= {+ {| @natural | @ident } }
+ | - {| @natural | @ident } {* @int_or_var }
+ int_or_var ::= @integer
+ | @ident
+ unfold_occ ::= @reference {? at @occs_nums }
+ pattern_occ ::= @one_term {? at @occs_nums }
+
+This set of tactics implements different specialized usages of the
+tactic :tacn:`change`.
+
+All conversion tactics (including :tacn:`change`) can be parameterized by the
+parts of the goal where the conversion can occur. This is done using
+*goal clauses* which consists in a list of hypotheses and, optionally,
+of a reference to the conclusion of the goal. For defined hypothesis
+it is possible to specify if the conversion should occur on the type
+part, the body part or both (default).
+
+Goal clauses are written after a conversion tactic (tactics :tacn:`set`,
+:tacn:`rewrite`, :tacn:`replace` and :tacn:`autorewrite` also use goal
+clauses) and are introduced by the keyword `in`. If no goal clause is
+provided, the default is to perform the conversion only in the
+conclusion.
+
+The syntax and description of the various goal clauses is the
+following:
+
++ :n:`in {+ @ident} |-` only in hypotheses :n:`{+ @ident}`
++ :n:`in {+ @ident} |- *` in hypotheses :n:`{+ @ident}` and in the
+ conclusion
++ :n:`in * |-` in every hypothesis
++ :n:`in *` (equivalent to in :n:`* |- *`) everywhere
++ :n:`in (type of @ident) (value of @ident) ... |-` in type part of
+ :n:`@ident`, in the value part of :n:`@ident`, etc.
+
+For backward compatibility, the notation :n:`in {+ @ident}` performs
+the conversion in hypotheses :n:`{+ @ident}`.
+
+.. tacn:: cbv {? @strategy_flag }
+ lazy {? @strategy_flag }
+ :name: cbv; lazy
+
+ These parameterized reduction tactics apply to any goal and perform
+ the normalization of the goal according to the specified flags. In
+ correspondence with the kinds of reduction considered in Coq namely
+ :math:`\beta` (reduction of functional application), :math:`\delta`
+ (unfolding of transparent constants, see :ref:`vernac-controlling-the-reduction-strategies`),
+ :math:`\iota` (reduction of
+ pattern matching over a constructed term, and unfolding of :g:`fix` and
+ :g:`cofix` expressions) and :math:`\zeta` (contraction of local definitions), the
+ flags are either ``beta``, ``delta``, ``match``, ``fix``, ``cofix``,
+ ``iota`` or ``zeta``. The ``iota`` flag is a shorthand for ``match``, ``fix``
+ and ``cofix``. The ``delta`` flag itself can be refined into
+ :n:`delta [ {+ @qualid} ]` or :n:`delta - [ {+ @qualid} ]`, restricting in the first
+ case the constants to unfold to the constants listed, and restricting in the
+ second case the constant to unfold to all but the ones explicitly mentioned.
+ Notice that the ``delta`` flag does not apply to variables bound by a let-in
+ construction inside the :n:`@term` itself (use here the ``zeta`` flag). In
+ any cases, opaque constants are not unfolded (see :ref:`vernac-controlling-the-reduction-strategies`).
+
+ Normalization according to the flags is done by first evaluating the
+ head of the expression into a *weak-head* normal form, i.e. until the
+ evaluation is blocked by a variable (or an opaque constant, or an
+ axiom), as e.g. in :g:`x u1 ... un` , or :g:`match x with ... end`, or
+ :g:`(fix f x {struct x} := ...) x`, or is a constructed form (a
+ :math:`\lambda`-expression, a constructor, a cofixpoint, an inductive type, a
+ product type, a sort), or is a redex that the flags prevent to reduce. Once a
+ weak-head normal form is obtained, subterms are recursively reduced using the
+ same strategy.
+
+ Reduction to weak-head normal form can be done using two strategies:
+ *lazy* (``lazy`` tactic), or *call-by-value* (``cbv`` tactic). The lazy
+ strategy is a call-by-need strategy, with sharing of reductions: the
+ arguments of a function call are weakly evaluated only when necessary,
+ and if an argument is used several times then it is weakly computed
+ only once. This reduction is efficient for reducing expressions with
+ dead code. For instance, the proofs of a proposition :g:`exists x. P(x)`
+ reduce to a pair of a witness :g:`t`, and a proof that :g:`t` satisfies the
+ predicate :g:`P`. Most of the time, :g:`t` may be computed without computing
+ the proof of :g:`P(t)`, thanks to the lazy strategy.
+
+ The call-by-value strategy is the one used in ML languages: the
+ arguments of a function call are systematically weakly evaluated
+ first. Despite the lazy strategy always performs fewer reductions than
+ the call-by-value strategy, the latter is generally more efficient for
+ evaluating purely computational expressions (i.e. with little dead code).
+
+.. tacv:: compute
+ cbv
+ :name: compute; _
+
+ These are synonyms for ``cbv beta delta iota zeta``.
+
+.. tacv:: lazy
+
+ This is a synonym for ``lazy beta delta iota zeta``.
+
+.. tacv:: compute [ {+ @qualid} ]
+ cbv [ {+ @qualid} ]
+
+ These are synonyms of :n:`cbv beta delta {+ @qualid} iota zeta`.
+
+.. tacv:: compute - [ {+ @qualid} ]
+ cbv - [ {+ @qualid} ]
+
+ These are synonyms of :n:`cbv beta delta -{+ @qualid} iota zeta`.
+
+.. tacv:: lazy [ {+ @qualid} ]
+ lazy - [ {+ @qualid} ]
+
+ These are respectively synonyms of :n:`lazy beta delta {+ @qualid} iota zeta`
+ and :n:`lazy beta delta -{+ @qualid} iota zeta`.
+
+.. tacv:: vm_compute
+ :name: vm_compute
+
+ This tactic evaluates the goal using the optimized call-by-value evaluation
+ bytecode-based virtual machine described in :cite:`CompiledStrongReduction`.
+ This algorithm is dramatically more efficient than the algorithm used for the
+ :tacn:`cbv` tactic, but it cannot be fine-tuned. It is especially interesting for
+ full evaluation of algebraic objects. This includes the case of
+ reflection-based tactics.
+
+.. tacv:: native_compute
+ :name: native_compute
+
+ This tactic evaluates the goal by compilation to OCaml as described
+ in :cite:`FullReduction`. If Coq is running in native code, it can be
+ typically two to five times faster than :tacn:`vm_compute`. Note however that the
+ compilation cost is higher, so it is worth using only for intensive
+ computations.
+
+ .. flag:: NativeCompute Timing
+
+ This flag causes all calls to the native compiler to print
+ timing information for the conversion to native code,
+ compilation, execution, and reification phases of native
+ compilation. Timing is printed in units of seconds of
+ wall-clock time.
+
+ .. flag:: NativeCompute Profiling
+
+ On Linux, if you have the ``perf`` profiler installed, this flag makes
+ it possible to profile :tacn:`native_compute` evaluations.
+
+ .. opt:: NativeCompute Profile Filename @string
+ :name: NativeCompute Profile Filename
+
+ This option specifies the profile output; the default is
+ ``native_compute_profile.data``. The actual filename used
+ will contain extra characters to avoid overwriting an existing file; that
+ filename is reported to the user.
+ That means you can individually profile multiple uses of
+ :tacn:`native_compute` in a script. From the Linux command line, run ``perf report``
+ on the profile file to see the results. Consult the ``perf`` documentation
+ for more details.
+
+.. flag:: Debug Cbv
+
+ This flag makes :tacn:`cbv` (and its derivative :tacn:`compute`) print
+ information about the constants it encounters and the unfolding decisions it
+ makes.
+
+.. tacn:: red
+ :name: red
+
+ This tactic applies to a goal that has the form::
+
+ forall (x:T1) ... (xk:Tk), T
+
+ with :g:`T` :math:`\beta`:math:`\iota`:math:`\zeta`-reducing to :g:`c t`:sub:`1` :g:`... t`:sub:`n` and :g:`c` a
+ constant. If :g:`c` is transparent then it replaces :g:`c` with its
+ definition (say :g:`t`) and then reduces
+ :g:`(t t`:sub:`1` :g:`... t`:sub:`n` :g:`)` according to :math:`\beta`:math:`\iota`:math:`\zeta`-reduction rules.
+
+.. exn:: Not reducible.
+ :undocumented:
+
+.. exn:: No head constant to reduce.
+ :undocumented:
+
+.. tacn:: hnf
+ :name: hnf
+
+ This tactic applies to any goal. It replaces the current goal with its
+ head normal form according to the :math:`\beta`:math:`\delta`:math:`\iota`:math:`\zeta`-reduction rules, i.e. it
+ reduces the head of the goal until it becomes a product or an
+ irreducible term. All inner :math:`\beta`:math:`\iota`-redexes are also reduced.
+ The behavior of both :tacn:`hnf` can be tuned using the :cmd:`Arguments` command.
+
+ Example: The term :g:`fun n : nat => S n + S n` is not reduced by :n:`hnf`.
+
+.. note::
+ The :math:`\delta` rule only applies to transparent constants (see :ref:`vernac-controlling-the-reduction-strategies`
+ on transparency and opacity).
+
+.. tacn:: cbn
+ simpl
+ :name: cbn; simpl
+
+ These tactics apply to any goal. They try to reduce a term to
+ something still readable instead of fully normalizing it. They perform
+ a sort of strong normalization with two key differences:
+
+ + They unfold a constant if and only if it leads to a :math:`\iota`-reduction,
+ i.e. reducing a match or unfolding a fixpoint.
+ + While reducing a constant unfolding to (co)fixpoints, the tactics
+ use the name of the constant the (co)fixpoint comes from instead of
+ the (co)fixpoint definition in recursive calls.
+
+ The :tacn:`cbn` tactic is claimed to be a more principled, faster and more
+ predictable replacement for :tacn:`simpl`.
+
+ The :tacn:`cbn` tactic accepts the same flags as :tacn:`cbv` and
+ :tacn:`lazy`. The behavior of both :tacn:`simpl` and :tacn:`cbn`
+ can be tuned using the :cmd:`Arguments` command.
+
+ .. todo add "See <subsection about controlling the behavior of reduction strategies>"
+ to TBA section
+
+ Notice that only transparent constants whose name can be reused in the
+ recursive calls are possibly unfolded by :tacn:`simpl`. For instance a
+ constant defined by :g:`plus' := plus` is possibly unfolded and reused in
+ the recursive calls, but a constant such as :g:`succ := plus (S O)` is
+ never unfolded. This is the main difference between :tacn:`simpl` and :tacn:`cbn`.
+ The tactic :tacn:`cbn` reduces whenever it will be able to reuse it or not:
+ :g:`succ t` is reduced to :g:`S t`.
+
+.. tacv:: cbn [ {+ @qualid} ]
+ cbn - [ {+ @qualid} ]
+
+ These are respectively synonyms of :n:`cbn beta delta [ {+ @qualid} ] iota zeta`
+ and :n:`cbn beta delta - [ {+ @qualid} ] iota zeta` (see :tacn:`cbn`).
+
+.. tacv:: simpl @pattern
+
+ This applies :tacn:`simpl` only to the subterms matching
+ :n:`@pattern` in the current goal.
+
+.. tacv:: simpl @pattern at {+ @natural}
+
+ This applies :tacn:`simpl` only to the :n:`{+ @natural}` occurrences of the subterms
+ matching :n:`@pattern` in the current goal.
+
+ .. exn:: Too few occurrences.
+ :undocumented:
+
+.. tacv:: simpl @qualid
+ simpl @string
+
+ This applies :tacn:`simpl` only to the applicative subterms whose head occurrence
+ is the unfoldable constant :n:`@qualid` (the constant can be referred to by
+ its notation using :n:`@string` if such a notation exists).
+
+.. tacv:: simpl @qualid at {+ @natural}
+ simpl @string at {+ @natural}
+
+ This applies :tacn:`simpl` only to the :n:`{+ @natural}` applicative subterms whose
+ head occurrence is :n:`@qualid` (or :n:`@string`).
+
+.. flag:: Debug RAKAM
+
+ This flag makes :tacn:`cbn` print various debugging information.
+ ``RAKAM`` is the Refolding Algebraic Krivine Abstract Machine.
+
+.. tacn:: unfold @qualid
+ :name: unfold
+
+ This tactic applies to any goal. The argument qualid must denote a
+ defined transparent constant or local definition (see
+ :ref:`gallina-definitions` and
+ :ref:`vernac-controlling-the-reduction-strategies`). The tactic
+ :tacn:`unfold` applies the :math:`\delta` rule to each occurrence
+ of the constant to which :n:`@qualid` refers in the current goal
+ and then replaces it with its :math:`\beta\iota\zeta`-normal form.
+ Use the general reduction tactics if you want to avoid this final
+ reduction, for instance :n:`cbv delta [@qualid]`.
+
+ .. exn:: Cannot coerce @qualid to an evaluable reference.
+
+ This error is frequent when trying to unfold something that has
+ defined as an inductive type (or constructor) and not as a
+ definition.
+
+ .. example::
+
+ .. coqtop:: abort all fail
+
+ Goal 0 <= 1.
+ unfold le.
+
+ This error can also be raised if you are trying to unfold
+ something that has been marked as opaque.
+
+ .. example::
+
+ .. coqtop:: abort all fail
+
+ Opaque Nat.add.
+ Goal 1 + 0 = 1.
+ unfold Nat.add.
+
+ .. tacv:: unfold @qualid in @goal_occurrences
+
+ Replaces :n:`@qualid` in hypothesis (or hypotheses) designated
+ by :token:`goal_occurrences` with its definition and replaces
+ the hypothesis with its :math:`\beta`:math:`\iota` normal form.
+
+ .. tacv:: unfold {+, @qualid}
+
+ Replaces :n:`{+, @qualid}` with their definitions and replaces
+ the current goal with its :math:`\beta`:math:`\iota` normal
+ form.
+
+ .. tacv:: unfold {+, @qualid at @occurrences }
+
+ The list :token:`occurrences` specify the occurrences of
+ :n:`@qualid` to be unfolded. Occurrences are located from left
+ to right.
+
+ .. exn:: Bad occurrence number of @qualid.
+ :undocumented:
+
+ .. exn:: @qualid does not occur.
+ :undocumented:
+
+ .. tacv:: unfold @string
+
+ If :n:`@string` denotes the discriminating symbol of a notation
+ (e.g. "+") or an expression defining a notation (e.g. `"_ +
+ _"`), and this notation denotes an application whose head symbol
+ is an unfoldable constant, then the tactic unfolds it.
+
+ .. tacv:: unfold @string%@ident
+
+ This is variant of :n:`unfold @string` where :n:`@string` gets
+ its interpretation from the scope bound to the delimiting key
+ :token:`ident` instead of its default interpretation (see
+ :ref:`Localinterpretationrulesfornotations`).
+
+ .. tacv:: unfold {+, {| @qualid | @string{? %@ident } } {? at @occurrences } } {? in @goal_occurrences }
+
+ This is the most general form.
+
+.. tacn:: fold @term
+ :name: fold
+
+ This tactic applies to any goal. The term :n:`@term` is reduced using the
+ :tacn:`red` tactic. Every occurrence of the resulting :n:`@term` in the goal is
+ then replaced by :n:`@term`. This tactic is particularly useful when a fixpoint
+ definition has been wrongfully unfolded, making the goal very hard to read.
+ On the other hand, when an unfolded function applied to its argument has been
+ reduced, the :tacn:`fold` tactic won't do anything.
+
+ .. example::
+
+ .. coqtop:: all abort
+
+ Goal ~0=0.
+ unfold not.
+ Fail progress fold not.
+ pattern (0 = 0).
+ fold not.
+
+ .. tacv:: fold {+ @term}
+
+ Equivalent to :n:`fold @term ; ... ; fold @term`.
+
+.. tacn:: pattern @term
+ :name: pattern
+
+ This command applies to any goal. The argument :n:`@term` must be a free
+ subterm of the current goal. The command pattern performs :math:`\beta`-expansion
+ (the inverse of :math:`\beta`-reduction) of the current goal (say :g:`T`) by
+
+ + replacing all occurrences of :n:`@term` in :g:`T` with a fresh variable
+ + abstracting this variable
+ + applying the abstracted goal to :n:`@term`
+
+ For instance, if the current goal :g:`T` is expressible as
+ :math:`\varphi`:g:`(t)` where the notation captures all the instances of :g:`t`
+ in :math:`\varphi`:g:`(t)`, then :n:`pattern t` transforms it into
+ :g:`(fun x:A =>` :math:`\varphi`:g:`(x)) t`. This tactic can be used, for
+ instance, when the tactic ``apply`` fails on matching.
+
+.. tacv:: pattern @term at {+ @natural}
+
+ Only the occurrences :n:`{+ @natural}` of :n:`@term` are considered for
+ :math:`\beta`-expansion. Occurrences are located from left to right.
+
+.. tacv:: pattern @term at - {+ @natural}
+
+ All occurrences except the occurrences of indexes :n:`{+ @natural }`
+ of :n:`@term` are considered for :math:`\beta`-expansion. Occurrences are located from
+ left to right.
+
+.. tacv:: pattern {+, @term}
+
+ Starting from a goal :math:`\varphi`:g:`(t`:sub:`1` :g:`... t`:sub:`m`:g:`)`,
+ the tactic :n:`pattern t`:sub:`1`:n:`, ..., t`:sub:`m` generates the
+ equivalent goal
+ :g:`(fun (x`:sub:`1`:g:`:A`:sub:`1`:g:`) ... (x`:sub:`m` :g:`:A`:sub:`m` :g:`) =>`:math:`\varphi`:g:`(x`:sub:`1` :g:`... x`:sub:`m` :g:`)) t`:sub:`1` :g:`... t`:sub:`m`.
+ If :g:`t`:sub:`i` occurs in one of the generated types :g:`A`:sub:`j` these
+ occurrences will also be considered and possibly abstracted.
+
+.. tacv:: pattern {+, @term at {+ @natural}}
+
+ This behaves as above but processing only the occurrences :n:`{+ @natural}` of
+ :n:`@term` starting from :n:`@term`.
+
+.. tacv:: pattern {+, @term {? at {? -} {+, @natural}}}
+
+ This is the most general syntax that combines the different variants.
+
+.. tacn:: with_strategy @strategy_level_or_var [ {+ @reference } ] @ltac_expr3
+ :name: with_strategy
+
+ Executes :token:`ltac_expr3`, applying the alternate unfolding
+ behavior that the :cmd:`Strategy` command controls, but only for
+ :token:`ltac_expr3`. This can be useful for guarding calls to
+ reduction in tactic automation to ensure that certain constants are
+ never unfolded by tactics like :tacn:`simpl` and :tacn:`cbn` or to
+ ensure that unfolding does not fail.
+
+ .. example::
+
+ .. coqtop:: all reset abort
+
+ Opaque id.
+ Goal id 10 = 10.
+ Fail unfold id.
+ with_strategy transparent [id] unfold id.
+
+ .. warning::
+
+ Use this tactic with care, as effects do not persist past the
+ end of the proof script. Notably, this fine-tuning of the
+ conversion strategy is not in effect during :cmd:`Qed` nor
+ :cmd:`Defined`, so this tactic is most useful either in
+ combination with :tacn:`abstract`, which will check the proof
+ early while the fine-tuning is still in effect, or to guard
+ calls to conversion in tactic automation to ensure that, e.g.,
+ :tacn:`unfold` does not fail just because the user made a
+ constant :cmd:`Opaque`.
+
+ This can be illustrated with the following example involving the
+ factorial function.
+
+ .. coqtop:: in reset
+
+ Fixpoint fact (n : nat) : nat :=
+ match n with
+ | 0 => 1
+ | S n' => n * fact n'
+ end.
+
+ Suppose now that, for whatever reason, we want in general to
+ unfold the :g:`id` function very late during conversion:
+
+ .. coqtop:: in
+
+ Strategy 1000 [id].
+
+ If we try to prove :g:`id (fact n) = fact n` by
+ :tacn:`reflexivity`, it will now take time proportional to
+ :math:`n!`, because Coq will keep unfolding :g:`fact` and
+ :g:`*` and :g:`+` before it unfolds :g:`id`, resulting in a full
+ computation of :g:`fact n` (in unary, because we are using
+ :g:`nat`), which takes time :math:`n!`. We can see this cross
+ the relevant threshold at around :math:`n = 9`:
+
+ .. coqtop:: all abort
+
+ Goal True.
+ Time assert (id (fact 8) = fact 8) by reflexivity.
+ Time assert (id (fact 9) = fact 9) by reflexivity.
+
+ Note that behavior will be the same if you mark :g:`id` as
+ :g:`Opaque` because while most reduction tactics refuse to
+ unfold :g:`Opaque` constants, conversion treats :g:`Opaque` as
+ merely a hint to unfold this constant last.
+
+ We can get around this issue by using :tacn:`with_strategy`:
+
+ .. coqtop:: all
+
+ Goal True.
+ Fail Timeout 1 assert (id (fact 100) = fact 100) by reflexivity.
+ Time assert (id (fact 100) = fact 100) by with_strategy -1 [id] reflexivity.
+
+ However, when we go to close the proof, we will run into
+ trouble, because the reduction strategy changes are local to the
+ tactic passed to :tacn:`with_strategy`.
+
+ .. coqtop:: all abort fail
+
+ exact I.
+ Timeout 1 Defined.
+
+ We can fix this issue by using :tacn:`abstract`:
+
+ .. coqtop:: all
+
+ Goal True.
+ Time assert (id (fact 100) = fact 100) by with_strategy -1 [id] abstract reflexivity.
+ exact I.
+ Time Defined.
+
+ On small examples this sort of behavior doesn't matter, but
+ because Coq is a super-linear performance domain in so many
+ places, unless great care is taken, tactic automation using
+ :tacn:`with_strategy` may not be robustly performant when
+ scaling the size of the input.
+
+ .. warning::
+
+ In much the same way this tactic does not play well with
+ :cmd:`Qed` and :cmd:`Defined` without using :tacn:`abstract` as
+ an intermediary, this tactic does not play well with ``coqchk``,
+ even when used with :tacn:`abstract`, due to the inability of
+ tactics to persist information about conversion hints in the
+ proof term. See `#12200
+ <https://github.com/coq/coq/issues/12200>`_ for more details.
+
+Conversion tactics applied to hypotheses
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. tacn:: @tactic in {+, @ident}
+
+ Applies :token:`tactic` (any of the conversion tactics listed in this
+ section) to the hypotheses :n:`{+ @ident}`.
+
+ If :token:`ident` is a local definition, then :token:`ident` can be replaced by
+ :n:`type of @ident` to address not the body but the type of the local
+ definition.
+
+ Example: :n:`unfold not in (type of H1) (type of H3)`.
diff --git a/doc/sphinx/refman-preamble.rst b/doc/sphinx/refman-preamble.rst
index 05e665a43b..32d3e87e68 100644
--- a/doc/sphinx/refman-preamble.rst
+++ b/doc/sphinx/refman-preamble.rst
@@ -15,15 +15,9 @@
.. |c_i| replace:: `c`\ :math:`_{i}`
.. |c_n| replace:: `c`\ :math:`_{n}`
.. |Cic| replace:: CIC
-.. |Coq| replace:: :smallcaps:`Coq`
-.. |CoqIDE| replace:: :smallcaps:`CoqIDE`
.. |eq_beta_delta_iota_zeta| replace:: `=`\ :math:`_{\beta\delta\iota\zeta}`
-.. |Gallina| replace:: :smallcaps:`Gallina`
.. |Latex| replace:: :smallcaps:`LaTeX`
-.. |L_tac| replace:: `L`:sub:`tac`
.. |Ltac| replace:: `L`:sub:`tac`
-.. |ML| replace:: :smallcaps:`ML`
-.. |OCaml| replace:: :smallcaps:`OCaml`
.. |p_1| replace:: `p`\ :math:`_{1}`
.. |p_i| replace:: `p`\ :math:`_{i}`
.. |p_n| replace:: `p`\ :math:`_{n}`
diff --git a/doc/sphinx/user-extensions/proof-schemes.rst b/doc/sphinx/user-extensions/proof-schemes.rst
index 8e23e61018..f9d4864492 100644
--- a/doc/sphinx/user-extensions/proof-schemes.rst
+++ b/doc/sphinx/user-extensions/proof-schemes.rst
@@ -8,35 +8,36 @@ Proof schemes
Generation of induction principles with ``Scheme``
--------------------------------------------------------
-The ``Scheme`` command is a high-level tool for generating automatically
-(possibly mutual) induction principles for given types and sorts. Its
-syntax follows the schema:
+.. cmd:: Scheme {? @ident := } @scheme_kind {* with {? @ident := } @scheme_kind }
-.. cmd:: Scheme @ident__1 := Induction for @ident__2 Sort @sort {* with @ident__i := Induction for @ident__j Sort @sort}
+ .. insertprodn scheme_kind sort_family
- This command is a high-level tool for generating automatically
+ .. prodn::
+ scheme_kind ::= Equality for @reference
+ | {| Induction | Minimality | Elimination | Case } for @reference Sort @sort_family
+ sort_family ::= Set
+ | Prop
+ | SProp
+ | Type
+
+ A high-level tool for automatically generating
(possibly mutual) induction principles for given types and sorts.
- Each :n:`@ident__j` is a different inductive type identifier belonging to
+ Each :n:`@reference` is a different inductive type identifier belonging to
the same package of mutual inductive definitions.
- The command generates the :n:`@ident__i`\s to be mutually recursive
- definitions. Each term :n:`@ident__i` proves a general principle of mutual
- induction for objects in type :n:`@ident__j`.
-
-.. cmdv:: Scheme @ident := Minimality for @ident Sort @sort {* with @ident := Minimality for @ident' Sort @sort}
-
- Same as before but defines a non-dependent elimination principle more
- natural in case of inductively defined relations.
+ The command generates the :n:`@ident`\s as mutually recursive
+ definitions. Each term :n:`@ident` proves a general principle of mutual
+ induction for objects in type :n:`@reference`.
-.. cmdv:: Scheme Equality for @ident
- :name: Scheme Equality
+ :n:`@ident`
+ The name of the scheme. If not provided, the scheme name will be determined automatically
+ from the sorts involved.
- Tries to generate a Boolean equality and a proof of the decidability of the usual equality. If `ident`
- involves some other inductive types, their equality has to be defined first.
+ :n:`Minimality for @reference Sort @sort_family`
+ Defines a non-dependent elimination principle more natural for inductively defined relations.
-.. cmdv:: Scheme Induction for @ident Sort @sort {* with Induction for @ident Sort @sort}
-
- If you do not provide the name of the schemes, they will be automatically computed from the
- sorts involved (works also with Minimality).
+ :n:`Equality for @reference`
+ Tries to generate a Boolean equality and a proof of the decidability of the usual equality.
+ If :token:`reference` involves other inductive types, their equality has to be defined first.
.. example::
@@ -138,13 +139,13 @@ Automatic declaration of schemes
Combined Scheme
~~~~~~~~~~~~~~~~~~~~~~
-.. cmd:: Combined Scheme @ident from {+, @ident__i}
+.. cmd:: Combined Scheme @ident__def from {+, @ident }
This command is a tool for combining induction principles generated
by the :cmd:`Scheme` command.
- Each :n:`@ident__i` is a different inductive principle that must belong
+ Each :n:`@ident` is a different inductive principle that must belong
to the same package of mutual inductive principle definitions.
- This command generates :n:`@ident` to be the conjunction of the
+ This command generates :n:`@ident__def` as the conjunction of the
principles: it is built from the common premises of the principles
and concluded by the conjunction of their conclusions.
In the case where all the inductive principles used are in sort
@@ -197,32 +198,30 @@ Combined Scheme
Generation of inversion principles with ``Derive`` ``Inversion``
-----------------------------------------------------------------
-.. cmd:: Derive Inversion @ident with @ident Sort @sort
- Derive Inversion @ident with (forall {* @binder }, @ident @term) Sort @sort
+.. cmd:: Derive Inversion @ident with @one_term {? Sort @sort_family }
- This command generates an inversion principle for the
- :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 :n:`{* @binder }` 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 {* @binder }, @ident @term`.
- When applied, it is equivalent to having inverted the instance with the
- tactic :g:`inversion`.
+ Generates an inversion lemma for the
+ :tacn:`inversion ... using ...` tactic. :token:`ident` is the name
+ of the generated lemma. :token:`one_term` should be in the form
+ :token:`qualid` or :n:`(forall {+ @binder }, @qualid @term)` where
+ :token:`qualid` is the name of an inductive
+ predicate and :n:`{+ @binder }` binds the variables occurring in the term
+ :token:`term`. The lemma is generated for the sort
+ :token:`sort_family` corresponding to :token:`one_term`.
+ Applying the lemma is equivalent to inverting the instance with the
+ :tacn:`inversion` tactic.
-.. cmdv:: Derive Inversion_clear @ident with @ident Sort @sort
- Derive Inversion_clear @ident with (forall {* @binder }, @ident @term) Sort @sort
+.. cmd:: Derive Inversion_clear @ident with @one_term {? Sort @sort_family }
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 @ident Sort @sort
- Derive Dependent Inversion @ident with (forall {* @binder }, @ident @term) Sort @sort
+.. cmd:: Derive Dependent Inversion @ident with @one_term Sort @sort_family
When applied, it is equivalent to having inverted the instance with
the tactic `dependent inversion`.
-.. cmdv:: Derive Dependent Inversion_clear @ident with @ident Sort @sort
- Derive Dependent Inversion_clear @ident with (forall {* @binder }, @ident @term) Sort @sort
+.. cmd:: Derive Dependent Inversion_clear @ident with @one_term Sort @sort_family
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 d6db305300..f36767b207 100644
--- a/doc/sphinx/user-extensions/syntax-extensions.rst
+++ b/doc/sphinx/user-extensions/syntax-extensions.rst
@@ -13,7 +13,7 @@ The main commands to provide custom symbolic notations for terms are
variant of :cmd:`Notation` which does not modify the parser; this provides a
form of :ref:`abbreviation <Abbreviations>`. It is
sometimes expected that the same symbolic notation has different meanings in
-different contexts; to achieve this form of overloading, |Coq| offers a notion
+different contexts; to achieve this form of overloading, Coq offers a notion
of :ref:`notation scopes <Scopes>`.
The main command to provide custom notations for tactics is :cmd:`Tactic Notation`.
@@ -226,7 +226,7 @@ Coq printer. For example:
However, printing, especially pretty-printing, also requires some
care. We may want specific indentations, line breaks, alignment if on
-several lines, etc. For pretty-printing, |Coq| relies on |ocaml|
+several lines, etc. For pretty-printing, Coq relies on OCaml
formatting library, which provides indentation and automatic line
breaks depending on page width by means of *formatting boxes*.
@@ -385,8 +385,8 @@ a :token:`decl_notations` clause after the definition of the (co)inductive type
(co)recursive term (or after the definition of each of them in case of mutual
definitions). The exact syntax is given by :n:`@decl_notation` for inductive,
co-inductive, recursive and corecursive definitions and in :ref:`record-types`
-for records. Note that only syntax modifiers that do not require to add or
-change a parsing rule are accepted.
+for records. Note that only syntax modifiers that do not require adding or
+changing a parsing rule are accepted.
.. insertprodn decl_notations decl_notation
@@ -444,7 +444,7 @@ Displaying information about notations
This command doesn't display all nonterminals of the grammar. For example,
productions shown by `Print Grammar tactic` refer to nonterminals `tactic_then_locality`
- and `tactic_then_gen` which are not shown and can't be printed.
+ and `for_each_goal` which are not shown and can't be printed.
Most of the grammar in the documentation was updated in 8.12 to make it accurate and
readable. This was done using a new developer tool that extracts the grammar from the
@@ -454,7 +454,7 @@ Displaying information about notations
definition where the nonterminal was referenced. This command shows the original grammar,
so it won't exactly match the documentation.
- The |Coq| parser is based on Camlp5. The documentation for
+ The Coq parser is based on Camlp5. The documentation for
`Extensible grammars <http://camlp5.github.io/doc/htmlc/grammars.html>`_ is the
most relevant but it assumes considerable knowledge. Here are the essentials:
@@ -477,16 +477,16 @@ Displaying information about notations
such as `1+2*3` in the usual way as `1+(2*3)`. However, most nonterminals have a single level.
For example, this output from `Print Grammar tactic` shows the first 3 levels for
- `tactic_expr`, designated as "5", "4" and "3". Level 3 is right-associative,
+ `ltac_expr`, designated as "5", "4" and "3". Level 3 is right-associative,
which applies to the productions within it, such as the `try` construct::
- Entry tactic_expr is
+ Entry ltac_expr is
[ "5" RIGHTA
[ binder_tactic ]
| "4" LEFTA
[ SELF; ";"; binder_tactic
| SELF; ";"; SELF
- | SELF; ";"; tactic_then_locality; tactic_then_gen; "]" ]
+ | SELF; ";"; tactic_then_locality; for_each_goal; "]" ]
| "3" RIGHTA
[ IDENT "try"; SELF
:
@@ -510,7 +510,7 @@ Displaying information about notations
The output for `Print Grammar constr` includes :cmd:`Notation` definitions,
which are dynamically added to the grammar at run time.
- For example, in the definition for `operconstr`, the production on the second line shown
+ For example, in the definition for `term`, the production on the second line shown
here is defined by a :cmd:`Reserved Notation` command in `Notations.v`::
| "50" LEFTA
@@ -521,7 +521,7 @@ Displaying information about notations
The file
`doc/tools/docgram/fullGrammar <http://github.com/coq/coq/blob/master/doc/tools/docgram/fullGrammar>`_
in the source tree extracts the full grammar for
- |Coq| (not including notations and tactic notations defined in `*.v` files nor some optionally-loaded plugins)
+ Coq (not including notations and tactic notations defined in `*.v` files nor some optionally-loaded plugins)
in a single file with minor changes to handle nonterminals using multiple levels (described in
`doc/tools/docgram/README.md <http://github.com/coq/coq/blob/master/doc/tools/docgram/README.md>`_).
This is complete and much easier to read than the grammar source files.
@@ -1167,7 +1167,7 @@ Global interpretation rules for notations
At any time, the interpretation of a notation for a term is done within
a *stack* of notation scopes and lonely notations. If a
-notation is defined in multiple scopes, |Coq| uses the interpretation from
+notation is defined in multiple scopes, Coq uses the interpretation from
the most recently opened notation scope or declared lonely notation.
Note that "stack" is a misleading name. Each scope or lonely notation can only appear in
@@ -1309,7 +1309,7 @@ recognized to be a ``Funclass`` instance, i.e., of type :g:`forall x:A, B` or
.. _notation-scopes:
Notation scopes used in the standard library of Coq
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We give an overview of the scopes used in the standard library of Coq.
For a complete list of notations in each scope, use the commands :cmd:`Print
@@ -1386,7 +1386,7 @@ Scopes` or :cmd:`Print Scope`.
``char_scope``
This scope includes interpretation for all strings of the form ``"c"``
where :g:`c` is an ASCII character, or of the form ``"nnn"`` where nnn is
- a three-digits number (possibly with leading 0's), or of the form
+ a three-digit number (possibly with leading 0s), or of the form
``""""``. Their respective denotations are the ASCII code of :g:`c`, the
decimal ASCII code ``nnn``, or the ascii code of the character ``"`` (i.e.
the ASCII code 34), all of them being represented in the type :g:`ascii`.
@@ -1553,16 +1553,18 @@ numbers (see :ref:`datatypes`).
Number notations
~~~~~~~~~~~~~~~~
-.. cmd:: Number Notation @qualid__type @qualid__parse @qualid__print : @scope_name {? @numeral_modifier }
+.. cmd:: Number Notation @qualid__type @qualid__parse @qualid__print {? ( {+, @number_modifier } ) } : @scope_name
:name: Number Notation
- .. insertprodn numeral_modifier numeral_modifier
+ .. insertprodn number_modifier number_string_via
.. prodn::
- numeral_modifier ::= ( warning after @bignat )
- | ( abstract after @bignat )
+ number_modifier ::= warning after @bignat
+ | abstract after @bignat
+ | @number_string_via
+ number_string_via ::= via @qualid mapping [ {+, {| @qualid => @qualid | [ @qualid ] => @qualid } } ]
- This command allows the user to customize the way numeral literals
+ This command allows the user to customize the way number literals
are parsed and printed.
:n:`@qualid__type`
@@ -1571,32 +1573,32 @@ Number notations
parsing and printing functions, respectively. The parsing function
:n:`@qualid__parse` should have one of the following types:
- * :n:`Numeral.int -> @qualid__type`
- * :n:`Numeral.int -> option @qualid__type`
- * :n:`Numeral.uint -> @qualid__type`
- * :n:`Numeral.uint -> option @qualid__type`
+ * :n:`Number.int -> @qualid__type`
+ * :n:`Number.int -> option @qualid__type`
+ * :n:`Number.uint -> @qualid__type`
+ * :n:`Number.uint -> option @qualid__type`
* :n:`Z -> @qualid__type`
* :n:`Z -> option @qualid__type`
- * :n:`Numeral.numeral -> @qualid__type`
- * :n:`Numeral.numeral -> option @qualid__type`
+ * :n:`Number.number -> @qualid__type`
+ * :n:`Number.number -> option @qualid__type`
And the printing function :n:`@qualid__print` should have one of the
following types:
- * :n:`@qualid__type -> Numeral.int`
- * :n:`@qualid__type -> option Numeral.int`
- * :n:`@qualid__type -> Numeral.uint`
- * :n:`@qualid__type -> option Numeral.uint`
+ * :n:`@qualid__type -> Number.int`
+ * :n:`@qualid__type -> option Number.int`
+ * :n:`@qualid__type -> Number.uint`
+ * :n:`@qualid__type -> option Number.uint`
* :n:`@qualid__type -> Z`
* :n:`@qualid__type -> option Z`
- * :n:`@qualid__type -> Numeral.numeral`
- * :n:`@qualid__type -> option Numeral.numeral`
+ * :n:`@qualid__type -> Number.number`
+ * :n:`@qualid__type -> option Number.number`
.. deprecated:: 8.12
- Numeral notations on :g:`Decimal.uint`, :g:`Decimal.int` and
- :g:`Decimal.decimal` are replaced respectively by numeral
- notations on :g:`Numeral.uint`, :g:`Numeral.int` and
- :g:`Numeral.numeral`.
+ Number notations on :g:`Decimal.uint`, :g:`Decimal.int` and
+ :g:`Decimal.decimal` are replaced respectively by number
+ notations on :g:`Number.uint`, :g:`Number.int` and
+ :g:`Number.number`.
When parsing, the application of the parsing function
:n:`@qualid__parse` to the number will be fully reduced, and universes
@@ -1606,7 +1608,44 @@ Number notations
function application, constructors, inductive type families,
sorts, and primitive integers) will be considered for printing.
- :n:`( warning after @bignat )`
+ .. _number-string-via:
+
+ :n:`via @qualid__ind mapping [ {+, @qualid__constant => @qualid__constructor } ]`
+ When using this option, :n:`@qualid__type` no
+ longer needs to be an inductive type and is instead mapped to the
+ inductive type :n:`@qualid__ind` according to the provided
+ list of pairs, whose first component :n:`@qualid__constant` is a
+ constant of type :n:`@qualid__type`
+ (or a function of type :n:`{* _ -> } @qualid__type`) and the second a
+ constructor of type :n:`@qualid__ind`. The type
+ :n:`@qualid__type` is then replaced by :n:`@qualid__ind` in the
+ above parser and printer types.
+
+ When :n:`@qualid__constant` is surrounded by square brackets,
+ all the implicit arguments of :n:`@qualid__constant` (whether maximally inserted or not) are ignored
+ when translating to :n:`@qualid__constructor` (i.e., before
+ applying :n:`@qualid__print`) and replaced with implicit
+ argument holes :g:`_` when translating from
+ :n:`@qualid__constructor` to :n:`@qualid__constant` (after
+ :n:`@qualid__parse`). See below for an :ref:`example <example-number-notation-implicit-args>`.
+
+ .. note::
+ The implicit status of the arguments is considered
+ only at notation declaration time, any further
+ modification of this status has no impact
+ on the previously declared notations.
+
+ .. note::
+ In case of multiple implicit options (for instance
+ :g:`Arguments eq_refl {A}%type_scope {x}, [_] _`), an
+ argument is considered implicit when it is implicit in any of the
+ options.
+
+ .. note::
+ To use a :token:`sort` as the target type :n:`@qualid__type`, use an :ref:`abbreviation <Abbreviations>`
+ as in the :ref:`example below <example-number-notation-non-inductive>`.
+
+ :n:`warning after @bignat`
displays a warning message about a possible stack
overflow when calling :n:`@qualid__parse` to parse a literal larger than :n:`@bignat`.
@@ -1616,11 +1655,11 @@ Number notations
with :n:`(warning after @bignat)`, this warning is emitted when
parsing a number greater than or equal to :token:`bignat`.
- :n:`( abstract after @bignat )`
+ :n:`abstract after @bignat`
returns :n:`(@qualid__parse m)` when parsing a literal
:n:`m` that's greater than :n:`@bignat` rather than reducing it to a normal form.
Here :g:`m` will be a
- :g:`Numeral.int`, :g:`Numeral.uint`, :g:`Z` or :g:`Numeral.numeral`, depending on the
+ :g:`Number.int`, :g:`Number.uint`, :g:`Z` or :g:`Number.number`, depending on the
type of the parsing function :n:`@qualid__parse`. This allows for a
more compact representation of literals in types such as :g:`nat`,
and limits parse failures due to stack overflow. Note that a
@@ -1642,76 +1681,94 @@ Number notations
As noted above, the :n:`(abstract after @natural)` directive has no
effect when :n:`@qualid__parse` lands in an :g:`option` type.
+ .. exn:: 'via' and 'abstract' cannot be used together.
+
+ With the :n:`abstract after` option, the parser function
+ :n:`@qualid__parse` does not reduce large numbers to a normal form,
+ which prevents doing the translation given in the :n:`mapping` list.
+
.. exn:: Cannot interpret this number as a value of type @type
- The numeral notation registered for :token:`type` does not support
+ The number notation registered for :token:`type` does not support
the given number. This error is given when the interpretation
function returns :g:`None`, or if the interpretation is registered
only for integers or non-negative integers, and the given number
has a fractional or exponent part or is negative.
- .. exn:: @qualid__parse should go from Numeral.int to @type or (option @type). Instead of Numeral.int, the types Numeral.uint or Z or Int63.int or Numeral.numeral could be used (you may need to require BinNums or Numeral or Int63 first).
+ .. exn:: @qualid__parse should go from Number.int to @type or (option @type). Instead of Number.int, the types Number.uint or Z or Int63.int or Number.number could be used (you may need to require BinNums or Number or Int63 first).
The parsing function given to the :cmd:`Number Notation`
vernacular is not of the right type.
- .. exn:: @qualid__print should go from @type to Numeral.int or (option Numeral.int). Instead of Numeral.int, the types Numeral.uint or Z or Int63.int or Numeral.numeral could be used (you may need to require BinNums or Numeral or Int63 first).
+ .. exn:: @qualid__print should go from @type to Number.int or (option Number.int). Instead of Number.int, the types Number.uint or Z or Int63.int or Number.number could be used (you may need to require BinNums or Number or Int63 first).
The printing function given to the :cmd:`Number Notation`
vernacular is not of the right type.
- .. exn:: Unexpected term @term while parsing a numeral notation.
+ .. exn:: Unexpected term @term while parsing a number notation.
Parsing functions must always return ground terms, made up of
- applications of constructors, inductive types, and primitive
+ function application, constructors, inductive type families, sorts and primitive
integers. Parsing functions may not return terms containing
axioms, bare (co)fixpoints, lambdas, etc.
- .. exn:: Unexpected non-option term @term while parsing a numeral notation.
+ .. exn:: Unexpected non-option term @term while parsing a number notation.
Parsing functions expected to return an :g:`option` must always
return a concrete :g:`Some` or :g:`None` when applied to a
concrete number expressed as a (hexa)decimal. They may not return
opaque constants.
+ .. exn:: Multiple 'via' options.
+
+ At most one :g:`via` option can be given.
+
+ .. exn:: Multiple 'warning after' or 'abstract after' options.
+
+ At most one :g:`warning after` or :g:`abstract after` option can be given.
+
.. _string-notations:
String notations
~~~~~~~~~~~~~~~~
-.. cmd:: String Notation @qualid @qualid__parse @qualid__print : @scope_name
+.. cmd:: String Notation @qualid__type @qualid__parse @qualid__print {? ( @number_string_via ) } : @scope_name
:name: String Notation
Allows the user to customize how strings are parsed and printed.
- The token :n:`@qualid` should be the name of an inductive type,
- while :n:`@qualid__parse` and :n:`@qualid__print` should be the names of the
- parsing and printing functions, respectively. The parsing function
- :n:`@qualid__parse` should have one of the following types:
+ :n:`@qualid__type`
+ the name of an inductive type,
+ while :n:`@qualid__parse` and :n:`@qualid__print` should be the names of the
+ parsing and printing functions, respectively. The parsing function
+ :n:`@qualid__parse` should have one of the following types:
- * :n:`Byte.byte -> @qualid`
- * :n:`Byte.byte -> option @qualid`
- * :n:`list Byte.byte -> @qualid`
- * :n:`list Byte.byte -> option @qualid`
+ * :n:`Byte.byte -> @qualid__type`
+ * :n:`Byte.byte -> option @qualid__type`
+ * :n:`list Byte.byte -> @qualid__type`
+ * :n:`list Byte.byte -> option @qualid__type`
- The printing function :n:`@qualid__print` should have one of the
- following types:
+ The printing function :n:`@qualid__print` should have one of the
+ following types:
- * :n:`@qualid -> Byte.byte`
- * :n:`@qualid -> option Byte.byte`
- * :n:`@qualid -> list Byte.byte`
- * :n:`@qualid -> option (list Byte.byte)`
+ * :n:`@qualid__type -> Byte.byte`
+ * :n:`@qualid__type -> option Byte.byte`
+ * :n:`@qualid__type -> list Byte.byte`
+ * :n:`@qualid__type -> option (list Byte.byte)`
- When parsing, the application of the parsing function
- :n:`@qualid__parse` to the string will be fully reduced, and universes
- of the resulting term will be refreshed.
+ When parsing, the application of the parsing function
+ :n:`@qualid__parse` to the string will be fully reduced, and universes
+ of the resulting term will be refreshed.
- Note that only fully-reduced ground terms (terms containing only
- function application, constructors, inductive type families,
- sorts, and primitive integers) will be considered for printing.
+ Note that only fully-reduced ground terms (terms containing only
+ function application, constructors, inductive type families,
+ sorts, and primitive integers) will be considered for printing.
+
+ :n:`via @qualid__ind mapping [ {+, @qualid__constant => @qualid__constructor } ]`
+ works as for :ref:`number notations above <number-string-via>`.
- .. exn:: Cannot interpret this string as a value of type @type
+ .. exn:: Cannot interpret this string as a value of type @type
The string notation registered for :token:`type` does not support
the given string. This error is given when the interpretation
@@ -1730,7 +1787,7 @@ String notations
.. exn:: Unexpected term @term while parsing a string notation.
Parsing functions must always return ground terms, made up of
- applications of constructors, inductive types, and primitive
+ function application, constructors, inductive type families, sorts and primitive
integers. Parsing functions may not return terms containing
axioms, bare (co)fixpoints, lambdas, etc.
@@ -1741,16 +1798,37 @@ String notations
concrete string expressed as a decimal. They may not return
opaque constants.
-The following errors apply to both string and numeral notations:
+.. note::
+ Number or string notations for parameterized inductive types can be
+ added by declaring an :ref:`abbreviation <Abbreviations>` for the
+ inductive which instantiates all parameters. See :ref:`example below <example-string-notation-parameterized-inductive>`.
+
+The following errors apply to both string and number notations:
.. exn:: @type is not an inductive type.
- String and numeral notations can only be declared for inductive types with no
- arguments.
+ String and number notations can only be declared for inductive types.
+ Declare string or numeral notations for non-inductive types using :n:`@number_string_via`.
+
+ .. exn:: @qualid was already mapped to @qualid and cannot be remapped to @qualid
+
+ Duplicates are not allowed in the :n:`mapping` list.
+
+ .. exn:: Missing mapping for constructor @qualid
+
+ A mapping should be provided for :n:`@qualid` in the :n:`mapping` list.
+
+ .. warn:: @type was already mapped to @type, mapping it also to @type might yield ill typed terms when using the notation.
+
+ Two pairs in the :n:`mapping` list associate types that might be incompatible.
+
+ .. warn:: Type of @qualid seems incompatible with the type of @qualid. Expected type is: @type instead of @type. This might yield ill typed terms when using the notation.
+
+ A mapping given in the :n:`mapping` list associates a constant with a seemingly incompatible constructor.
.. exn:: Cannot interpret in @scope_name because @qualid could not be found in the current environment.
- The inductive type used to register the string or numeral notation is no
+ The inductive type used to register the string or number notation is no
longer available in the environment. Most likely, this is because
the notation was declared inside a functor for an
inductive type inside the functor. This use case is not currently
@@ -1779,6 +1857,198 @@ The following errors apply to both string and numeral notations:
.. todo note on "single qualified identifiers" https://github.com/coq/coq/pull/11718#discussion_r415076703
+.. example:: Number Notation for radix 3
+
+ The following example parses and prints natural numbers
+ whose digits are :g:`0`, :g:`1` or :g:`2` as terms of the following
+ inductive type encoding radix 3 numbers.
+
+ .. coqtop:: in reset
+
+ Inductive radix3 : Set :=
+ | x0 : radix3
+ | x3 : radix3 -> radix3
+ | x3p1 : radix3 -> radix3
+ | x3p2 : radix3 -> radix3.
+
+ We first define a parsing function
+
+ .. coqtop:: in
+
+ Definition of_uint_dec (u : Decimal.uint) : option radix3 :=
+ let fix f u := match u with
+ | Decimal.Nil => Some x0
+ | Decimal.D0 u => match f u with Some u => Some (x3 u) | None => None end
+ | Decimal.D1 u => match f u with Some u => Some (x3p1 u) | None => None end
+ | Decimal.D2 u => match f u with Some u => Some (x3p2 u) | None => None end
+ | _ => None end in
+ f (Decimal.rev u).
+ Definition of_uint (u : Number.uint) : option radix3 :=
+ match u with Number.UIntDecimal u => of_uint_dec u | Number.UIntHexadecimal _ => None end.
+
+ and a printing function
+
+ .. coqtop:: in
+
+ Definition to_uint_dec (x : radix3) : Decimal.uint :=
+ let fix f x := match x with
+ | x0 => Decimal.Nil
+ | x3 x => Decimal.D0 (f x)
+ | x3p1 x => Decimal.D1 (f x)
+ | x3p2 x => Decimal.D2 (f x) end in
+ Decimal.rev (f x).
+ Definition to_uint (x : radix3) : Number.uint := Number.UIntDecimal (to_uint_dec x).
+
+ before declaring the notation
+
+ .. coqtop:: in
+
+ Declare Scope radix3_scope.
+ Open Scope radix3_scope.
+ Number Notation radix3 of_uint to_uint : radix3_scope.
+
+ We can check the printer
+
+ .. coqtop:: all
+
+ Check x3p2 (x3p1 x0).
+
+ and the parser
+
+ .. coqtop:: all
+
+ Set Printing All.
+ Check 120.
+
+ Digits other than :g:`0`, :g:`1` and :g:`2` are rejected.
+
+ .. coqtop:: all fail
+
+ Check 3.
+
+.. _example-number-notation-non-inductive:
+
+.. example:: Number Notation for a non inductive type
+
+ The following example encodes the terms in the form :g:`sum unit ( ... (sum unit unit) ... )`
+ as the number of units in the term. For instance :g:`sum unit (sum unit unit)`
+ is encoded as :g:`3` while :g:`unit` is :g:`1` and :g:`0` stands for :g:`Empty_set`.
+ The inductive :g:`I` will be used as :n:`@qualid__ind`.
+
+ .. coqtop:: in reset
+
+ Inductive I := Iempty : I | Iunit : I | Isum : I -> I -> I.
+
+ We then define :n:`@qualid__parse` and :n:`@qualid__print`
+
+ .. coqtop:: in
+
+ Definition of_uint (x : Number.uint) : I :=
+ let fix f n := match n with
+ | O => Iempty | S O => Iunit
+ | S n => Isum Iunit (f n) end in
+ f (Nat.of_num_uint x).
+
+ Definition to_uint (x : I) : Number.uint :=
+ let fix f i := match i with
+ | Iempty => O | Iunit => 1
+ | Isum i1 i2 => f i1 + f i2 end in
+ Nat.to_num_uint (f x).
+
+ Inductive sum (A : Set) (B : Set) : Set := pair : A -> B -> sum A B.
+
+ the number notation itself
+
+ .. coqtop:: in
+
+ Notation nSet := Set (only parsing).
+ Number Notation nSet of_uint to_uint (via I
+ mapping [Empty_set => Iempty, unit => Iunit, sum => Isum]) : type_scope.
+
+ and check the printer
+
+ .. coqtop:: all
+
+ Local Open Scope type_scope.
+ Check sum unit (sum unit unit).
+
+ and the parser
+
+ .. coqtop:: all
+
+ Set Printing All.
+ Check 3.
+
+.. _example-number-notation-implicit-args:
+
+.. example:: Number Notation with implicit arguments
+
+ The following example parses and prints natural numbers between
+ :g:`0` and :g:`n-1` as terms of type :g:`Fin.t n`.
+
+ .. coqtop:: all reset
+
+ Require Import Vector.
+ Print Fin.t.
+
+ Note the implicit arguments of :g:`Fin.F1` and :g:`Fin.FS`,
+ which won't appear in the corresponding inductive type.
+
+ .. coqtop:: in
+
+ Inductive I := I1 : I | IS : I -> I.
+
+ Definition of_uint (x : Number.uint) : I :=
+ let fix f n := match n with O => I1 | S n => IS (f n) end in
+ f (Nat.of_num_uint x).
+
+ Definition to_uint (x : I) : Number.uint :=
+ let fix f i := match i with I1 => O | IS n => S (f n) end in
+ Nat.to_num_uint (f x).
+
+ Declare Scope fin_scope.
+ Delimit Scope fin_scope with fin.
+ Local Open Scope fin_scope.
+ Number Notation Fin.t of_uint to_uint (via I
+ mapping [[Fin.F1] => I1, [Fin.FS] => IS]) : fin_scope.
+
+ Now :g:`2` is parsed as :g:`Fin.FS (Fin.FS Fin.F1)`, that is
+ :g:`@Fin.FS _ (@Fin.FS _ (@Fin.F1 _))`.
+
+ .. coqtop:: all
+
+ Check 2.
+
+ which can be of type :g:`Fin.t 3` (numbers :g:`0`, :g:`1` and :g:`2`)
+
+ .. coqtop:: all
+
+ Check 2 : Fin.t 3.
+
+ but cannot be of type :g:`Fin.t 2` (only :g:`0` and :g:`1`)
+
+ .. coqtop:: all fail
+
+ Check 2 : Fin.t 2.
+
+.. _example-string-notation-parameterized-inductive:
+
+.. example:: String Notation with a parameterized inductive type
+
+ The parameter :g:`Byte.byte` for the parameterized inductive type
+ :g:`list` is given through an :ref:`abbreviation <Abbreviations>`.
+
+ .. coqtop:: in reset
+
+ Notation string := (list Byte.byte) (only parsing).
+ Definition id_string := @id string.
+
+ String Notation string id_string id_string : list_scope.
+
+ .. coqtop:: all
+
+ Check "abc"%list.
+
.. _TacticNotation:
Tactic Notations
@@ -1894,12 +2164,12 @@ Tactic notations allow customizing the syntax of tactics.
- :tacn:`unfold`, :tacn:`with_strategy`
* - ``constr``
- - :token:`term`
+ - :token:`one_term`
- a term
- :tacn:`exact`
* - ``uconstr``
- - :token:`term`
+ - :token:`one_term`
- an untyped term
- :tacn:`refine`
diff --git a/doc/sphinx/using/libraries/funind.rst b/doc/sphinx/using/libraries/funind.rst
index 738d64bfc3..93571ecebb 100644
--- a/doc/sphinx/using/libraries/funind.rst
+++ b/doc/sphinx/using/libraries/funind.rst
@@ -169,13 +169,24 @@ terminating functions.
Tactics
-------
-.. tacn:: functional induction (@qualid {+ @term})
+.. tacn:: functional induction @term {? using @one_term {? with @bindings } } {? as @simple_intropattern }
:name: functional induction
- The tactic functional induction performs case analysis and induction
- following the definition of a function. It makes use of a principle
+ Performs case analysis and induction following the definition of a function
+ :token:`qualid`, which must be fully applied to its arguments as part of
+ :token:`term`. It uses a principle
generated by :cmd:`Function` or :cmd:`Functional Scheme`.
Note that this tactic is only available after a ``Require Import FunInd``.
+ See the :cmd:`Function` command.
+
+ :n:`using @one_term`
+ Specifies the induction principle (aka elimination scheme).
+
+ :n:`with @bindings`
+ Specifies the arguments of the induction principle.
+
+ :n:`as @simple_intropattern`
+ Provides names for the introduced variables.
.. example::
@@ -189,15 +200,6 @@ Tactics
Qed.
.. note::
- :n:`(@qualid {+ @term})` must be a correct full application
- of :n:`@qualid`. In particular, the rules for implicit arguments are the
- same as usual. For example use :n:`@@qualid` if you want to write implicit
- arguments explicitly.
-
- .. note::
- Parentheses around :n:`@qualid {+ @term}` are not mandatory and can be skipped.
-
- .. note::
:n:`functional induction (f x1 x2 x3)` is actually a wrapper for
:n:`induction x1, x2, x3, (f x1 x2 x3) using @qualid` followed by a cleaning
phase, where :n:`@qualid` is the induction principle registered for :g:`f`
@@ -218,22 +220,27 @@ Tactics
.. exn:: Not the right number of induction arguments.
:undocumented:
- .. tacv:: functional induction (@qualid {+ @term}) as @simple_intropattern using @term with @bindings_list
-
- Similarly to :tacn:`induction` and :tacn:`elim`, this allows giving
- explicitly the name of the introduced variables, the induction principle, and
- the values of dependent premises of the elimination scheme, including
- *predicates* for mutual induction when :n:`@qualid` is part of a mutually
- recursive definition.
-
-.. tacn:: functional inversion @ident
+.. tacn:: functional inversion {| @ident | @natural } {? @qualid }
:name: functional inversion
- :tacn:`functional inversion` is a tactic that performs inversion on hypothesis
- :n:`@ident` of the form :n:`@qualid {+ @term} = @term` or :n:`@term = @qualid
- {+ @term}` where :n:`@qualid` must have been defined using :cmd:`Function`.
+ Performs inversion on hypothesis
+ :n:`@ident` of the form :n:`@qualid {+ @term} = @term` or
+ :n:`@term = @qualid {+ @term}` when :n:`@qualid` is defined using :cmd:`Function`.
Note that this tactic is only available after a ``Require Import FunInd``.
+ :n:`@natural`
+ Does the same thing as :n:`intros until @natural` followed by
+ :n:`functional inversion @ident` where :token:`ident` is the
+ identifier for the last introduced hypothesis.
+
+ :n:`@qualid`
+ If the hypothesis :token:`ident` (or :token:`natural`) has a type of the form
+ :n:`@qualid__1 {+ @term__i } = @qualid__2 {+ @term__j }` where
+ :n:`@qualid__1` and :n:`@qualid__2` are valid candidates to
+ functional inversion, this variant allows choosing which :token:`qualid`
+ is inverted.
+
+
.. exn:: Hypothesis @ident must contain at least one Function.
:undocumented:
@@ -242,39 +249,26 @@ Tactics
This error may be raised when some inversion lemma failed to be generated by
Function.
-
- .. tacv:: functional inversion @natural
-
- This does the same thing as :n:`intros until @natural` followed by
- :n:`functional inversion @ident` where :token:`ident` is the
- identifier for the last introduced hypothesis.
-
- .. tacv:: functional inversion @ident @qualid
- functional inversion @natural @qualid
-
- If the hypothesis :token:`ident` (or :token:`natural`) has a type of the form
- :n:`@qualid__1 {+ @term__i } = @qualid__2 {+ @term__j }` where
- :n:`@qualid__1` and :n:`@qualid__2` are valid candidates to
- functional inversion, this variant allows choosing which :token:`qualid`
- is inverted.
-
.. _functional-scheme:
Generation of induction principles with ``Functional`` ``Scheme``
-----------------------------------------------------------------
-.. cmd:: Functional Scheme @ident__0 := Induction for @ident' Sort @sort {* with @ident__i := Induction for @ident__i' Sort @sort}
+.. cmd:: Functional Scheme @func_scheme_def {* with @func_scheme_def }
+
+ .. insertprodn func_scheme_def func_scheme_def
+
+ .. prodn::
+ func_scheme_def ::= @ident := Induction for @qualid Sort @sort_family
+
+ An experimental high-level tool that
+ automatically generates induction principles corresponding to functions that
+ may be mutually recursive. The command generates an
+ induction principle named :n:`@ident` for each given function named :n:`@qualid`.
+ The :n:`@qualid`\s must be given in the same order as when they were defined.
- This command is a high-level experimental tool for
- generating automatically induction principles corresponding to
- (possibly mutually recursive) functions. First, it must be made
- available via ``Require Import FunInd``.
- Each :n:`@ident__i` is a different mutually defined function
- name (the names must be in the same order as when they were defined). This
- command generates the induction principle for each :n:`@ident__i`, following
- the recursive structure and case analyses of the corresponding function
- :n:`@ident__i'`.
+ Note the command must be made available via :cmd:`Require Import` ``FunInd``.
.. warning::
diff --git a/doc/sphinx/using/libraries/writing.rst b/doc/sphinx/using/libraries/writing.rst
index 325ea2af60..917edf0774 100644
--- a/doc/sphinx/using/libraries/writing.rst
+++ b/doc/sphinx/using/libraries/writing.rst
@@ -1,5 +1,5 @@
Writing Coq libraries and plugins
-=================================
+===================================
This section presents the part of the Coq language that is useful only
to library and plugin authors. A tutorial for writing Coq plugins is
diff --git a/doc/sphinx/using/tools/coqdoc.rst b/doc/sphinx/using/tools/coqdoc.rst
index 9ac3d2adda..b68b2ed2a7 100644
--- a/doc/sphinx/using/tools/coqdoc.rst
+++ b/doc/sphinx/using/tools/coqdoc.rst
@@ -2,14 +2,14 @@
.. _coqdoc:
-Documenting |Coq| files with coqdoc
+Documenting Coq files with coqdoc
-----------------------------------
-coqdoc is a documentation tool for the proof assistant |Coq|, similar to
+coqdoc is a documentation tool for the proof assistant Coq, similar to
``javadoc`` or ``ocamldoc``. The task of coqdoc is
-#. to produce a nice |Latex| and/or HTML document from |Coq| source files,
+#. to produce a nice |Latex| and/or HTML document from Coq source files,
readable for a human and not only for the proof assistant;
#. to help the user navigate his own (or third-party) sources.
@@ -18,9 +18,9 @@ coqdoc is a documentation tool for the proof assistant |Coq|, similar to
Principles
~~~~~~~~~~
-Documentation is inserted into |Coq| files as *special comments*. Thus
+Documentation is inserted into Coq files as *special comments*. Thus
your files will compile as usual, whether you use coqdoc or not. coqdoc
-presupposes that the given |Coq| files are well-formed (at least
+presupposes that the given Coq files are well-formed (at least
lexically). Documentation starts with ``(**``, followed by a space, and
ends with ``*)``. The documentation format is inspired by Todd
A. Coram’s *Almost Free Text (AFT)* tool: it is mainly ``ASCII`` text with
@@ -29,10 +29,10 @@ shouldn’t fail, whatever the input is. But remember: “garbage in,
garbage out”.
-|Coq| material inside documentation.
+Coq material inside documentation.
++++++++++++++++++++++++++++++++++++
-|Coq| material is quoted between the delimiters ``[`` and ``]``. Square brackets
+Coq material is quoted between the delimiters ``[`` and ``]``. Square brackets
may be nested, the inner ones being understood as being part of the
quoted code (thus you can quote a term like ``fun x => u`` by writing ``[fun
x => u]``). Inside quotations, the code is pretty-printed in the same
@@ -46,7 +46,7 @@ Pretty-printing.
++++++++++++++++
coqdoc uses different faces for identifiers and keywords. The pretty-
-printing of |Coq| tokens (identifiers or symbols) can be controlled
+printing of Coq tokens (identifiers or symbols) can be controlled
using one of the following commands:
::
@@ -63,7 +63,7 @@ or
(** printing *token* $...LATEX math...$ #...html...# *)
-It gives the |Latex| and HTML texts to be produced for the given |Coq|
+It gives the |Latex| and HTML texts to be produced for the given Coq
token. Either the |Latex| or the HTML rule may be omitted, causing the
default pretty-printing to be used for this token.
@@ -91,7 +91,7 @@ commands.
The recognition of tokens is done by a (``ocaml``) lex
automaton and thus applies the longest-match rule. For instance, `->~`
- is recognized as a single token, where |Coq| sees two tokens. It is the
+ is recognized as a single token, where Coq sees two tokens. It is the
responsibility of the user to insert space between tokens *or* to give
pretty-printing rules for the possible combinations, e.g.
@@ -200,6 +200,14 @@ at the beginning of a line.
if n <= 1 then 1 else n * fact (n-1)
>>
+Verbatim material on a single line is also possible (assuming that
+``>>`` is not part of the text to be presented as verbatim).
+
+.. example::
+
+ ::
+
+ Here is the corresponding caml expression: << fact (n-1) >>
Hyperlinks
@@ -217,7 +225,7 @@ Then invoke coqdoc or ``coqdoc --glob-from file`` to tell coqdoc to look
for name resolutions in the file ``file`` (it will look in ``file.glob``
by default).
-Identifiers from the |Coq| standard library are linked to the Coq website
+Identifiers from the Coq standard library are linked to the Coq website
`<http://coq.inria.fr/library/>`_. This behavior can be changed
using command line options ``--no-externals`` and ``--coqlib``; see below.
@@ -280,12 +288,12 @@ Usage
coqdoc is invoked on a shell command line as follows:
``coqdoc <options and files>``.
Any command line argument which is not an option is considered to be a
-file (even if it starts with a ``-``). |Coq| files are identified by the
+file (even if it starts with a ``-``). Coq files are identified by the
suffixes ``.v`` and ``.g`` and |Latex| files by the suffix ``.tex``.
:HTML output: This is the default output format. One HTML file is created for
- each |Coq| file given on the command line, together with a file
+ each Coq file given on the command line, together with a file
``index.html`` (unless ``option-no-index is passed``). The HTML pages use a
style sheet named ``style.css``. Such a file is distributed with coqdoc.
:|Latex| output: A single |Latex| file is created, on standard
@@ -295,7 +303,7 @@ suffixes ``.v`` and ``.g`` and |Latex| files by the suffix ``.tex``.
document . DVI and PostScript can be produced directly with the
options ``-dvi`` and ``-ps`` respectively.
:TEXmacs output: To translate the input files to TEXmacs format,
- to be used by the TEXmacs |Coq| interface.
+ to be used by the TEXmacs Coq interface.
@@ -357,18 +365,18 @@ Command line options
**Hyperlink options**
- :--glob-from file: Make references using |Coq| globalizations from file
+ :--glob-from file: Make references using Coq globalizations from file
file. (Such globalizations are obtained with Coq option ``-dump-glob``).
- :--no-externals: Do not insert links to the |Coq| standard library.
+ :--no-externals: Do not insert links to the Coq standard library.
:--external url coqdir: Use given URL for linking references whose
name starts with prefix ``coqdir``.
:--coqlib url: Set base URL for the Coq standard library (default is
`<http://coq.inria.fr/library/>`_). This is equivalent to ``--external url
Coq``.
- :-R dir coqdir: Recursively map physical directory dir to |Coq| logical
- directory ``coqdir`` (similarly to |Coq| option ``-R``).
- :-Q dir coqdir: Map physical directory dir to |Coq| logical
- directory ``coqdir`` (similarly to |Coq| option ``-Q``).
+ :-R dir coqdir: Recursively map physical directory dir to Coq logical
+ directory ``coqdir`` (similarly to Coq option ``-R``).
+ :-Q dir coqdir: Map physical directory dir to Coq logical
+ directory ``coqdir`` (similarly to Coq option ``-Q``).
.. note::
@@ -420,7 +428,7 @@ Command line options
:--plain-comments: Do not interpret comments, simply copy them as
plain-text.
:--interpolate: Use the globalization information to typeset
- identifiers appearing in |Coq| escapings inside comments.
+ identifiers appearing in Coq escapings inside comments.
**Language options**
diff --git a/doc/stdlib/hidden-files b/doc/stdlib/hidden-files
index 4d2972ef8f..e4f0967794 100644
--- a/doc/stdlib/hidden-files
+++ b/doc/stdlib/hidden-files
@@ -1,3 +1,4 @@
+theories/Init/Numeral.v
theories/btauto/Algebra.v
theories/btauto/Btauto.v
theories/btauto/Reflect.v
diff --git a/doc/stdlib/index-list.html.template b/doc/stdlib/index-list.html.template
index 7c1328916b..7201dc6a0e 100644
--- a/doc/stdlib/index-list.html.template
+++ b/doc/stdlib/index-list.html.template
@@ -22,7 +22,7 @@ through the <tt>Require Import</tt> command.</p>
theories/Init/Nat.v
theories/Init/Decimal.v
theories/Init/Hexadecimal.v
- theories/Init/Numeral.v
+ theories/Init/Number.v
theories/Init/Peano.v
theories/Init/Specif.v
theories/Init/Tactics.v
@@ -238,6 +238,7 @@ through the <tt>Require Import</tt> command.</p>
theories/Numbers/DecimalN.v
theories/Numbers/DecimalZ.v
theories/Numbers/DecimalQ.v
+ theories/Numbers/DecimalR.v
theories/Numbers/DecimalString.v
theories/Numbers/HexadecimalFacts.v
theories/Numbers/HexadecimalNat.v
@@ -245,6 +246,7 @@ through the <tt>Require Import</tt> command.</p>
theories/Numbers/HexadecimalN.v
theories/Numbers/HexadecimalZ.v
theories/Numbers/HexadecimalQ.v
+ theories/Numbers/HexadecimalR.v
theories/Numbers/HexadecimalString.v
</dd>
@@ -704,7 +706,6 @@ through the <tt>Require Import</tt> command.</p>
</dt>
<dd>
theories/Compat/AdmitAxiom.v
- theories/Compat/Coq810.v
theories/Compat/Coq811.v
theories/Compat/Coq812.v
theories/Compat/Coq813.v
diff --git a/doc/tools/coqrst/notations/TacticNotations.g b/doc/tools/coqrst/notations/TacticNotations.g
index f29c69eeaf..70107eba46 100644
--- a/doc/tools/coqrst/notations/TacticNotations.g
+++ b/doc/tools/coqrst/notations/TacticNotations.g
@@ -43,7 +43,8 @@ LGROUP: '{+' | '{*' | '{?';
LBRACE: '{';
RBRACE: '}';
// todo: need a cleaner way to escape the 3-character strings here
-ESCAPED: '%{' | '%}' | '%|' | '`%{' | '@%{';
+ESCAPED: '%{' | '%}' | '%|' | '`%{' | '@%{' |
+ '%|-' | '%|->' | '%||' | '%|||' | '%||||'; // for SSR
PIPE: '|';
ATOM: '@' | '_' | ~[@_{}| ]+;
ID: '@' ('_'? [a-zA-Z0-9])+;
diff --git a/doc/tools/coqrst/notations/TacticNotationsLexer.py b/doc/tools/coqrst/notations/TacticNotationsLexer.py
index 7bda849010..a7ad55ad34 100644
--- a/doc/tools/coqrst/notations/TacticNotationsLexer.py
+++ b/doc/tools/coqrst/notations/TacticNotationsLexer.py
@@ -8,35 +8,40 @@ import sys
def serializedATN():
with StringIO() as buf:
buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\f")
- buf.write("S\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("f\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\3\6\3\6\3\6\3\6\3\6\3\6\5\6\63\n\6\3\7\3")
- buf.write("\7\3\b\3\b\6\b9\n\b\r\b\16\b:\5\b=\n\b\3\t\3\t\5\tA\n")
- buf.write("\t\3\t\6\tD\n\t\r\t\16\tE\3\n\3\n\3\n\6\nK\n\n\r\n\16")
- buf.write("\nL\3\13\6\13P\n\13\r\13\16\13Q\2\2\f\3\3\5\4\7\5\t\6")
- buf.write("\13\7\r\b\17\t\21\n\23\13\25\f\3\2\5\4\2BBaa\6\2\"\"B")
- buf.write("Baa}\177\5\2\62;C\\c|\2^\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3")
- buf.write("\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2")
- buf.write("\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\3\27\3\2\2\2")
- buf.write("\5 \3\2\2\2\7\"\3\2\2\2\t$\3\2\2\2\13\62\3\2\2\2\r\64")
- buf.write("\3\2\2\2\17<\3\2\2\2\21>\3\2\2\2\23G\3\2\2\2\25O\3\2\2")
- buf.write("\2\27\30\7}\2\2\30\31\7~\2\2\31\4\3\2\2\2\32\33\7}\2\2")
- buf.write("\33!\7-\2\2\34\35\7}\2\2\35!\7,\2\2\36\37\7}\2\2\37!\7")
- buf.write("A\2\2 \32\3\2\2\2 \34\3\2\2\2 \36\3\2\2\2!\6\3\2\2\2\"")
- buf.write("#\7}\2\2#\b\3\2\2\2$%\7\177\2\2%\n\3\2\2\2&\'\7\'\2\2")
- buf.write("\'\63\7}\2\2()\7\'\2\2)\63\7\177\2\2*+\7\'\2\2+\63\7~")
- buf.write("\2\2,-\7b\2\2-.\7\'\2\2.\63\7}\2\2/\60\7B\2\2\60\61\7")
- buf.write("\'\2\2\61\63\7}\2\2\62&\3\2\2\2\62(\3\2\2\2\62*\3\2\2")
- buf.write("\2\62,\3\2\2\2\62/\3\2\2\2\63\f\3\2\2\2\64\65\7~\2\2\65")
- buf.write("\16\3\2\2\2\66=\t\2\2\2\679\n\3\2\28\67\3\2\2\29:\3\2")
- buf.write("\2\2:8\3\2\2\2:;\3\2\2\2;=\3\2\2\2<\66\3\2\2\2<8\3\2\2")
- buf.write("\2=\20\3\2\2\2>C\7B\2\2?A\7a\2\2@?\3\2\2\2@A\3\2\2\2A")
- buf.write("B\3\2\2\2BD\t\4\2\2C@\3\2\2\2DE\3\2\2\2EC\3\2\2\2EF\3")
- buf.write("\2\2\2F\22\3\2\2\2GH\7a\2\2HJ\7a\2\2IK\t\4\2\2JI\3\2\2")
- buf.write("\2KL\3\2\2\2LJ\3\2\2\2LM\3\2\2\2M\24\3\2\2\2NP\7\"\2\2")
- buf.write("ON\3\2\2\2PQ\3\2\2\2QO\3\2\2\2QR\3\2\2\2R\26\3\2\2\2\13")
- buf.write("\2 \62:<@ELQ\2")
+ buf.write("\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3")
+ buf.write("\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6")
+ buf.write("\3\6\5\6F\n\6\3\7\3\7\3\b\3\b\6\bL\n\b\r\b\16\bM\5\bP")
+ buf.write("\n\b\3\t\3\t\5\tT\n\t\3\t\6\tW\n\t\r\t\16\tX\3\n\3\n\3")
+ buf.write("\n\6\n^\n\n\r\n\16\n_\3\13\6\13c\n\13\r\13\16\13d\2\2")
+ buf.write("\f\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\3\2\5")
+ buf.write("\4\2BBaa\6\2\"\"BBaa}\177\5\2\62;C\\c|\2v\2\3\3\2\2\2")
+ buf.write("\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r")
+ buf.write("\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3")
+ buf.write("\2\2\2\3\27\3\2\2\2\5 \3\2\2\2\7\"\3\2\2\2\t$\3\2\2\2")
+ buf.write("\13E\3\2\2\2\rG\3\2\2\2\17O\3\2\2\2\21Q\3\2\2\2\23Z\3")
+ buf.write("\2\2\2\25b\3\2\2\2\27\30\7}\2\2\30\31\7~\2\2\31\4\3\2")
+ buf.write("\2\2\32\33\7}\2\2\33!\7-\2\2\34\35\7}\2\2\35!\7,\2\2\36")
+ buf.write("\37\7}\2\2\37!\7A\2\2 \32\3\2\2\2 \34\3\2\2\2 \36\3\2")
+ buf.write("\2\2!\6\3\2\2\2\"#\7}\2\2#\b\3\2\2\2$%\7\177\2\2%\n\3")
+ buf.write("\2\2\2&\'\7\'\2\2\'F\7}\2\2()\7\'\2\2)F\7\177\2\2*+\7")
+ buf.write("\'\2\2+F\7~\2\2,-\7b\2\2-.\7\'\2\2.F\7}\2\2/\60\7B\2\2")
+ buf.write("\60\61\7\'\2\2\61F\7}\2\2\62\63\7\'\2\2\63\64\7~\2\2\64")
+ buf.write("F\7/\2\2\65\66\7\'\2\2\66\67\7~\2\2\678\7/\2\28F\7@\2")
+ buf.write("\29:\7\'\2\2:;\7~\2\2;F\7~\2\2<=\7\'\2\2=>\7~\2\2>?\7")
+ buf.write("~\2\2?F\7~\2\2@A\7\'\2\2AB\7~\2\2BC\7~\2\2CD\7~\2\2DF")
+ buf.write("\7~\2\2E&\3\2\2\2E(\3\2\2\2E*\3\2\2\2E,\3\2\2\2E/\3\2")
+ buf.write("\2\2E\62\3\2\2\2E\65\3\2\2\2E9\3\2\2\2E<\3\2\2\2E@\3\2")
+ buf.write("\2\2F\f\3\2\2\2GH\7~\2\2H\16\3\2\2\2IP\t\2\2\2JL\n\3\2")
+ buf.write("\2KJ\3\2\2\2LM\3\2\2\2MK\3\2\2\2MN\3\2\2\2NP\3\2\2\2O")
+ buf.write("I\3\2\2\2OK\3\2\2\2P\20\3\2\2\2QV\7B\2\2RT\7a\2\2SR\3")
+ buf.write("\2\2\2ST\3\2\2\2TU\3\2\2\2UW\t\4\2\2VS\3\2\2\2WX\3\2\2")
+ buf.write("\2XV\3\2\2\2XY\3\2\2\2Y\22\3\2\2\2Z[\7a\2\2[]\7a\2\2\\")
+ buf.write("^\t\4\2\2]\\\3\2\2\2^_\3\2\2\2_]\3\2\2\2_`\3\2\2\2`\24")
+ buf.write("\3\2\2\2ac\7\"\2\2ba\3\2\2\2cd\3\2\2\2db\3\2\2\2de\3\2")
+ buf.write("\2\2e\26\3\2\2\2\13\2 EMOSX_d\2")
return buf.getvalue()
diff --git a/doc/tools/docgram/README.md b/doc/tools/docgram/README.md
index 4d38955fa8..6c507e1d57 100644
--- a/doc/tools/docgram/README.md
+++ b/doc/tools/docgram/README.md
@@ -42,7 +42,7 @@ for documentation purposes:
First, nonterminals that use levels (`"5" RIGHTA` below) are modified, for example:
```
- tactic_expr:
+ ltac_expr:
[ "5" RIGHTA
[ te = binder_tactic -> { te } ]
[ "4" ...
@@ -179,6 +179,8 @@ grammar with its productions and removing the non-terminal. Each should appear
as a separate production. (Doesn't work recursively; splicing for both
`A: [ | B ]` and `B: [ | C ]` must be done in separate SPLICE operations.)
+`OPTINREF` - applies the local `OPTINREF` edit to every nonterminal
+
`EXPAND` - expands LIST0, LIST1, LIST* ... SEP and OPT constructs into
new non-terminals
diff --git a/doc/tools/docgram/common.edit_mlg b/doc/tools/docgram/common.edit_mlg
index 1e9be8dded..4c1956d172 100644
--- a/doc/tools/docgram/common.edit_mlg
+++ b/doc/tools/docgram/common.edit_mlg
@@ -19,7 +19,8 @@ lglob: [
]
hint: [
-| "Extern" natural OPT constr_pattern "=>" tactic
+| REPLACE "Extern" natural OPT Constr.constr_pattern "=>" Pltac.tactic
+| WITH "Extern" natural OPT constr_pattern "=>" tactic
]
(* todo: does ARGUMENT EXTEND make the symbol global? It is in both extraargs and extratactics *)
@@ -28,19 +29,12 @@ strategy_level_or_var: [
| strategy_level
]
-operconstr0: [
-| "ltac" ":" "(" tactic_expr5 ")"
-]
-
EXTRAARGS_natural: [ | DELETENT ]
EXTRAARGS_lconstr: [ | DELETENT ]
EXTRAARGS_strategy_level: [ | DELETENT ]
-G_LTAC_hint: [ | DELETENT ]
-G_LTAC_operconstr0: [ | DELETENT ]
-G_REWRITE_binders: [
+binders: [
| DELETE Pcoq.Constr.binders
-| binders
]
G_TACTIC_in_clause: [
@@ -50,7 +44,6 @@ G_TACTIC_in_clause: [
]
SPLICE: [
-| G_REWRITE_binders
| G_TACTIC_in_clause
]
@@ -86,38 +79,44 @@ RENAME: [
| G_LTAC2_eqn_ipat ltac2_eqn_ipat
| G_LTAC2_conversion ltac2_conversion
| G_LTAC2_oriented_rewriter ltac2_oriented_rewriter
-| G_LTAC2_tactic_then_gen ltac2_tactic_then_gen
+| G_LTAC2_for_each_goal ltac2_for_each_goal
| G_LTAC2_tactic_then_last ltac2_tactic_then_last
| G_LTAC2_as_name ltac2_as_name
| G_LTAC2_as_ipat ltac2_as_ipat
| G_LTAC2_by_tactic ltac2_by_tactic
| G_LTAC2_match_list ltac2_match_list
+| G_SSRMATCHING_cpattern ssr_one_term_pattern
]
-(* renames to eliminate qualified names
- put other renames at the end *)
+(* Renames to eliminate qualified names.
+ Put other renames at the end *)
RENAME: [
(* map missing names for rhs *)
| Constr.constr term
| Constr.global global
| Constr.lconstr lconstr
-| Constr.lconstr_pattern cpattern
+| Constr.cpattern cpattern
| G_vernac.query_command query_command
-| G_vernac.section_subset_expr section_subset_expr
+| G_vernac.section_subset_expr section_var_expr
| Prim.ident ident
| Prim.reference reference
+| Prim.string string
+| Prim.integer integer
+| Prim.qualid qualid
+| Prim.natural natural
| Pvernac.Vernac_.main_entry vernac_control
| Tactic.tactic tactic
+| Pltac.ltac_expr ltac_expr5
(* SSR *)
+| Pcoq.Constr.constr term
+| Prim.identref ident
(*
| G_vernac.def_body def_body
-| Pcoq.Constr.constr term
| Prim.by_notation by_notation
-| Prim.identref ident
| Prim.natural natural
*)
-| Vernac.rec_definition rec_definition
+| Vernac.fix_definition fix_definition
(* todo: hmm, rename adds 1 prodn to closed_binder?? *)
| Constr.closed_binder closed_binder
]
@@ -152,11 +151,16 @@ DELETE: [
| test_array_closing
(* SSR *)
-(* | ssr_null_entry *)
-(*
+| ssr_null_entry
| ssrtermkind (* todo: rename as "test..." *)
-| term_annotation (* todo: rename as "test..." *)
+| ssrdoarg (* todo: this and the next one should be removed from the grammar? *)
+| ssrseqdir
+| ssrindex
+| ssrintrosarg
+| ssrtclarg
+| term_annotation (* todo: what is this? *)
| test_idcomma
+| test_ident_no_do
| test_nohidden
| test_not_ssrslashnum
| test_ssr_rw_syntax
@@ -167,10 +171,6 @@ DELETE: [
| test_ssrslashnum01
| test_ssrslashnum10
| test_ssrslashnum11
-| test_ident_no_do
-| ssrdoarg (* todo: this and the next one should be removed from the grammar? *)
-| ssrseqdir
-*)
(* unused *)
| constr_comma_sequence'
@@ -178,52 +178,38 @@ DELETE: [
| constr_may_eval
]
-(* ssrintrosarg: [ | DELETENT ] *)
-
(* additional nts to be spliced *)
-hyp: [
-| var
-]
-
tactic_then_last: [
-| REPLACE "|" LIST0 ( OPT tactic_expr5 ) SEP "|"
-| WITH LIST0 ( "|" ( OPT tactic_expr5 ) )
+| REPLACE "|" LIST0 ( OPT ltac_expr5 ) SEP "|"
+| WITH LIST0 ( "|" ( OPT ltac_expr5 ) )
]
goal_tactics: [
-| LIST0 ( OPT tactic_expr5 ) SEP "|"
+| LIST0 ( OPT ltac_expr5 ) SEP "|"
]
-tactic_then_gen: [ | DELETENT ]
+for_each_goal: [ | DELETENT ]
-tactic_then_gen: [
+for_each_goal: [
| goal_tactics
-| OPT ( goal_tactics "|" ) OPT tactic_expr5 ".." OPT ( "|" goal_tactics )
-]
-
-tactic_then_last: [
-| OPTINREF
+| OPT ( goal_tactics "|" ) OPT ltac_expr5 ".." OPT ( "|" goal_tactics )
]
ltac2_tactic_then_last: [
-| REPLACE "|" LIST0 ( OPT tac2expr6 ) SEP "|" (* Ltac2 plugin *)
-| WITH LIST0 ( "|" OPT tac2expr6 ) TAG Ltac2
+| REPLACE "|" LIST0 ( OPT ltac2_expr6 ) SEP "|" (* Ltac2 plugin *)
+| WITH LIST0 ( "|" OPT ltac2_expr6 ) TAG Ltac2
]
ltac2_goal_tactics: [
-| LIST0 ( OPT tac2expr6 ) SEP "|" TAG Ltac2
+| LIST0 ( OPT ltac2_expr6 ) SEP "|" TAG Ltac2
]
-ltac2_tactic_then_gen: [ | DELETENT ]
+ltac2_for_each_goal: [ | DELETENT ]
-ltac2_tactic_then_gen: [
+ltac2_for_each_goal: [
| ltac2_goal_tactics TAG Ltac2
-| OPT ( ltac2_goal_tactics "|" ) OPT tac2expr6 ".." OPT ( "|" ltac2_goal_tactics ) TAG Ltac2
-]
-
-ltac2_tactic_then_last: [
-| OPTINREF
+| OPT ( ltac2_goal_tactics "|" ) OPT ltac2_expr6 ".." OPT ( "|" ltac2_goal_tactics ) TAG Ltac2
]
reference: [ | DELETENT ]
@@ -261,60 +247,70 @@ let_type_cstr: [
| type_cstr
]
-(* rename here because we want to use "return_type" for something else *)
-RENAME: [
-| return_type as_return_type
-]
-
case_item: [
-| REPLACE operconstr100 OPT [ "as" name ] OPT [ "in" pattern200 ]
-| WITH operconstr100 OPT ("as" name) OPT [ "in" pattern200 ]
+| REPLACE term100 OPT [ "as" name ] OPT [ "in" pattern200 ]
+| WITH term100 OPT ("as" name) OPT [ "in" pattern200 ]
]
binder_constr: [
-| MOVETO term_forall_or_fun "forall" open_binders "," operconstr200
-| MOVETO term_forall_or_fun "fun" open_binders "=>" operconstr200
-| MOVETO term_let "let" name binders let_type_cstr ":=" operconstr200 "in" operconstr200
-| MOVETO term_if "if" operconstr200 as_return_type "then" operconstr200 "else" operconstr200
-| MOVETO term_fix "let" "fix" fix_decl "in" operconstr200
-| MOVETO term_cofix "let" "cofix" cofix_decl "in" operconstr200
-| MOVETO term_let "let" [ "(" LIST0 name SEP "," ")" | "()" ] as_return_type ":=" operconstr200 "in" operconstr200
-| MOVETO term_let "let" "'" pattern200 ":=" operconstr200 "in" operconstr200
-| MOVETO term_let "let" "'" pattern200 ":=" operconstr200 case_type "in" operconstr200
-| MOVETO term_let "let" "'" pattern200 "in" pattern200 ":=" operconstr200 case_type "in" operconstr200
+| MOVETO term_forall_or_fun "forall" open_binders "," term200
+| MOVETO term_forall_or_fun "fun" open_binders "=>" term200
+| MOVETO term_let "let" name binders let_type_cstr ":=" term200 "in" term200
+(*| MOVETO term_let "let" ":" ssr_mpat ":=" lconstr "in" lconstr TAG SSR *)
+| DELETE "let" ":" ssr_mpat ":=" lconstr "in" lconstr TAG SSR (* todo: restore for ssr *)
+| REPLACE "let" ":" ssr_mpat "in" pattern200 ":=" lconstr ssr_rtype "in" lconstr (* ssr plugin *)
+| WITH "let" ":" ssr_mpat OPT ( "in" pattern200 ) ":=" lconstr ssr_rtype "in" lconstr TAG SSR
+| DELETE "let" ":" ssr_mpat ":=" lconstr ssr_rtype "in" lconstr (* SSR plugin *)
+| DELETE "let" ":" ssr_mpat OPT ( "in" pattern200 ) ":=" lconstr ssr_rtype "in" lconstr TAG SSR (* todo: restore for SSR *)
+(*| MOVETO term_let "let" ":" ssr_mpat OPT ( "in" pattern200 ) ":=" lconstr ssr_rtype "in" lconstr TAG SSR*)
+| MOVETO term_if "if" term200 as_return_type "then" term200 "else" term200
+| REPLACE "if" term200 "is" ssr_dthen ssr_else
+| WITH "if" term200 [ "is" | "isn't" ] ssr_dthen ssr_else TAG SSR
+| DELETE "if" term200 "isn't" ssr_dthen ssr_else
+| DELETE "if" term200 [ "is" | "isn't" ] ssr_dthen ssr_else TAG SSR (* todo: restore for SSR *)
+| MOVETO term_fix "let" "fix" fix_decl "in" term200
+| MOVETO term_cofix "let" "cofix" cofix_body "in" term200
+| MOVETO term_let "let" [ "(" LIST0 name SEP "," ")" | "()" ] as_return_type ":=" term200 "in" term200
+| MOVETO term_let "let" "'" pattern200 ":=" term200 "in" term200
+| MOVETO term_let "let" "'" pattern200 ":=" term200 case_type "in" term200
+| MOVETO term_let "let" "'" pattern200 "in" pattern200 ":=" term200 case_type "in" term200
| MOVETO term_fix "fix" fix_decls
| MOVETO term_cofix "cofix" cofix_decls
]
term_let: [
-| REPLACE "let" name binders let_type_cstr ":=" operconstr200 "in" operconstr200
-| WITH "let" name let_type_cstr ":=" operconstr200 "in" operconstr200
-| "let" name LIST1 binder let_type_cstr ":=" operconstr200 "in" operconstr200
+| REPLACE "let" name binders let_type_cstr ":=" term200 "in" term200
+| WITH "let" name let_type_cstr ":=" term200 "in" term200
+| "let" name LIST1 binder let_type_cstr ":=" term200 "in" term200
(* Don't need to document that "( )" is equivalent to "()" *)
-| REPLACE "let" [ "(" LIST0 name SEP "," ")" | "()" ] as_return_type ":=" operconstr200 "in" operconstr200
-| WITH "let" "(" LIST0 name SEP "," ")" as_return_type ":=" operconstr200 "in" operconstr200
-| REPLACE "let" "'" pattern200 ":=" operconstr200 "in" operconstr200
-| WITH "let" "'" pattern200 ":=" operconstr200 OPT case_type "in" operconstr200
-| DELETE "let" "'" pattern200 ":=" operconstr200 case_type "in" operconstr200
+| REPLACE "let" [ "(" LIST0 name SEP "," ")" | "()" ] as_return_type ":=" term200 "in" term200
+| WITH "let" "(" LIST0 name SEP "," ")" as_return_type ":=" term200 "in" term200
+| MOVETO destructuring_let "let" "(" LIST0 name SEP "," ")" as_return_type ":=" term200 "in" term200
+| REPLACE "let" "'" pattern200 ":=" term200 "in" term200
+| WITH "let" "'" pattern200 ":=" term200 OPT case_type "in" term200
+| DELETE "let" "'" pattern200 ":=" term200 case_type "in" term200
+| MOVETO destructuring_let "let" "'" pattern200 ":=" term200 OPT case_type "in" term200
+| MOVETO destructuring_let "let" "'" pattern200 "in" pattern200 ":=" term200 case_type "in" term200
]
atomic_constr: [
-| MOVETO qualid_annotated global univ_instance
+| MOVETO qualid_annotated global univ_annot
| MOVETO primitive_notations NUMBER
| MOVETO primitive_notations string
| MOVETO term_evar "_"
-| REPLACE "?" "[" ident "]"
-| WITH "?[" ident "]"
-| MOVETO term_evar "?[" ident "]"
+| REPLACE "?" "[" identref "]"
+| WITH "?[" identref "]"
+| MOVETO term_evar "?[" identref "]"
| REPLACE "?" "[" pattern_ident "]"
| WITH "?[" pattern_ident "]"
| MOVETO term_evar "?[" pattern_ident "]"
| MOVETO term_evar pattern_ident evar_instance
]
-tactic_expr0: [
-| REPLACE "[" ">" tactic_then_gen "]"
-| WITH "[>" tactic_then_gen "]"
+ltac_expr0: [
+| REPLACE "[" ">" for_each_goal "]"
+| WITH "[>" for_each_goal "]"
+| DELETE ssrparentacarg
]
(* lexer token *)
@@ -341,68 +337,68 @@ scope_delimiter: [
]
type: [
-| operconstr200
+| term200
]
-operconstr100: [
-| REPLACE operconstr99 "<:" operconstr200
-| WITH operconstr99 "<:" type
-| MOVETO term_cast operconstr99 "<:" type
-| REPLACE operconstr99 "<<:" operconstr200
-| WITH operconstr99 "<<:" type
-| MOVETO term_cast operconstr99 "<<:" type
-| REPLACE operconstr99 ":" operconstr200
-| WITH operconstr99 ":" type
-| MOVETO term_cast operconstr99 ":" type
-| MOVETO term_cast operconstr99 ":>"
+term100: [
+| REPLACE term99 "<:" term200
+| WITH term99 "<:" type
+| MOVETO term_cast term99 "<:" type
+| REPLACE term99 "<<:" term200
+| WITH term99 "<<:" type
+| MOVETO term_cast term99 "<<:" type
+| REPLACE term99 ":" term200
+| WITH term99 ":" type
+| MOVETO term_cast term99 ":" type
+| MOVETO term_cast term99 ":>"
]
constr: [
-| REPLACE "@" global univ_instance
+| REPLACE "@" global univ_annot
| WITH "@" qualid_annotated
| MOVETO term_explicit "@" qualid_annotated
]
-operconstr10: [
+term10: [
(* Separate this LIST0 in the nonempty and the empty case *)
(* The empty case is covered by constr *)
-| REPLACE "@" global univ_instance LIST0 operconstr9
-| WITH "@" qualid_annotated LIST1 operconstr9
-| REPLACE operconstr9
+| REPLACE "@" global univ_annot LIST0 term9
+| WITH "@" qualid_annotated LIST1 term9
+| REPLACE term9
| WITH constr
-| MOVETO term_application operconstr9 LIST1 appl_arg
-| MOVETO term_application "@" qualid_annotated LIST1 operconstr9
+| MOVETO term_application term9 LIST1 arg
+| MOVETO term_application "@" qualid_annotated LIST1 term9
(* fixme: add in as a prodn somewhere *)
-| MOVETO dangling_pattern_extension_rule "@" pattern_identref LIST1 identref
+| MOVETO dangling_pattern_extension_rule "@" pattern_ident LIST1 identref
| DELETE dangling_pattern_extension_rule
]
-operconstr9: [
+term9: [
(* @Zimmi48: Special token .. is for use in the Notation command. (see bug_3304.v) *)
-| DELETE ".." operconstr0 ".."
+| DELETE ".." term0 ".."
]
-operconstr1: [
-| REPLACE operconstr0 ".(" global LIST0 appl_arg ")"
-| WITH operconstr0 ".(" global LIST0 appl_arg ")" (* huh? *)
-| REPLACE operconstr0 "%" IDENT
-| WITH operconstr0 "%" scope_key
-| MOVETO term_scope operconstr0 "%" scope_key
-| MOVETO term_projection operconstr0 ".(" global LIST0 appl_arg ")"
-| MOVETO term_projection operconstr0 ".(" "@" global LIST0 ( operconstr9 ) ")"
+term1: [
+| REPLACE term0 ".(" global LIST0 arg ")"
+| WITH term0 ".(" global LIST0 arg ")" (* huh? *)
+| REPLACE term0 "%" IDENT
+| WITH term0 "%" scope_key
+| MOVETO term_scope term0 "%" scope_key
+| MOVETO term_projection term0 ".(" global LIST0 arg ")"
+| MOVETO term_projection term0 ".(" "@" global LIST0 ( term9 ) ")"
]
-operconstr0: [
+term0: [
(* @Zimmi48: This rule is a hack, according to Hugo, and should not be shown in the manual. *)
| DELETE "{" binder_constr "}"
| REPLACE "{|" record_declaration bar_cbrace
| WITH "{|" LIST0 field_def SEP ";" OPT ";" bar_cbrace
| MOVETO term_record "{|" LIST0 field_def SEP ";" OPT ";" bar_cbrace
-| MOVETO term_generalizing "`{" operconstr200 "}"
-| MOVETO term_generalizing "`(" operconstr200 ")"
-| MOVETO term_ltac "ltac" ":" "(" tactic_expr5 ")"
-| REPLACE "[" "|" array_elems "|" lconstr type_cstr "|" "]" univ_instance
-| WITH "[|" array_elems "|" lconstr type_cstr "|]" univ_instance
+| MOVETO term_generalizing "`{" term200 "}"
+| MOVETO term_generalizing "`(" term200 ")"
+| MOVETO term_ltac "ltac" ":" "(" ltac_expr5 ")"
+| REPLACE "[" "|" array_elems "|" lconstr type_cstr "|" "]" univ_annot
+| WITH "[|" array_elems "|" lconstr type_cstr "|]" univ_annot
]
fix_decls: [
@@ -412,9 +408,9 @@ fix_decls: [
]
cofix_decls: [
-| DELETE cofix_decl
-| REPLACE cofix_decl "with" LIST1 cofix_decl SEP "with" "for" identref
-| WITH cofix_decl OPT ( LIST1 ( "with" cofix_decl ) "for" identref )
+| DELETE cofix_body
+| REPLACE cofix_body "with" LIST1 cofix_body SEP "with" "for" identref
+| WITH cofix_body OPT ( LIST1 ( "with" cofix_body ) "for" identref )
]
fields_def: [
@@ -478,6 +474,7 @@ closed_binder: [
| MOVETO generalizing_binder "`(" LIST1 typeclass_constraint SEP "," ")"
| MOVETO generalizing_binder "`{" LIST1 typeclass_constraint SEP "," "}"
| MOVETO generalizing_binder "`[" LIST1 typeclass_constraint SEP "," "]"
+| DELETE [ "of" | "&" ] term99 (* todo: remove for SSR *)
]
name_colon: [
@@ -485,11 +482,11 @@ name_colon: [
]
typeclass_constraint: [
-| EDIT ADD_OPT "!" operconstr200
-| REPLACE "{" name "}" ":" [ "!" | ] operconstr200
-| WITH "{" name "}" ":" OPT "!" operconstr200
-| REPLACE name ":" [ "!" | ] operconstr200
-| WITH name ":" OPT "!" operconstr200
+| EDIT ADD_OPT "!" term200
+| REPLACE "{" name "}" ":" [ "!" | ] term200
+| WITH "{" name "}" ":" OPT "!" term200
+| REPLACE name ":" [ "!" | ] term200
+| WITH name ":" OPT "!" term200
]
(* ?? From the grammar, Prim.name seems to be only "_" but ident is also accepted "*)
@@ -535,17 +532,15 @@ eqn: [
| WITH LIST1 [ LIST1 pattern100 SEP "," ] SEP "|" "=>" lconstr
]
-universe_increment: [
-| OPTINREF
-]
-
-evar_instance: [
-| OPTINREF
-]
-
(* No constructor syntax, OPT [ "|" binders ] is not supported for Record *)
record_definition: [
-| opt_coercion ident_decl binders OPT [ ":" type ] OPT [ identref ] "{" record_fields "}" decl_notations
+| opt_coercion ident_decl binders OPT [ ":" sort ] OPT ( ":=" OPT [ identref ] "{" record_fields "}" )
+]
+
+(* No mutual recursion, no inductive classes, type must be a sort *)
+(* constructor is optional but "Class record_definition" covers that case *)
+singleton_class_definition: [
+| opt_coercion ident_decl binders OPT [ ":" sort ] ":=" constructor
]
(* No record syntax, opt_coercion not supported for Variant, := ... required *)
@@ -562,15 +557,16 @@ gallina: [
| "CoInductive" inductive_definition LIST0 ( "with" inductive_definition )
| "Variant" variant_definition LIST0 ( "with" variant_definition )
| [ "Record" | "Structure" ] record_definition LIST0 ( "with" record_definition )
-| "Class" inductive_definition LIST0 ( "with" inductive_definition )
-| REPLACE "Fixpoint" LIST1 rec_definition SEP "with"
-| WITH "Fixpoint" rec_definition LIST0 ( "with" rec_definition )
-| REPLACE "Let" "Fixpoint" LIST1 rec_definition SEP "with"
-| WITH "Let" "Fixpoint" rec_definition LIST0 ( "with" rec_definition )
-| REPLACE "CoFixpoint" LIST1 corec_definition SEP "with"
-| WITH "CoFixpoint" corec_definition LIST0 ( "with" corec_definition )
-| REPLACE "Let" "CoFixpoint" LIST1 corec_definition SEP "with"
-| WITH "Let" "CoFixpoint" corec_definition LIST0 ( "with" corec_definition )
+| "Class" record_definition
+| "Class" singleton_class_definition
+| REPLACE "Fixpoint" LIST1 fix_definition SEP "with"
+| WITH "Fixpoint" fix_definition LIST0 ( "with" fix_definition )
+| REPLACE "Let" "Fixpoint" LIST1 fix_definition SEP "with"
+| WITH "Let" "Fixpoint" fix_definition LIST0 ( "with" fix_definition )
+| REPLACE "CoFixpoint" LIST1 cofix_definition SEP "with"
+| WITH "CoFixpoint" cofix_definition LIST0 ( "with" cofix_definition )
+| REPLACE "Let" "CoFixpoint" LIST1 cofix_definition SEP "with"
+| WITH "Let" "CoFixpoint" cofix_definition LIST0 ( "with" cofix_definition )
| REPLACE "Scheme" LIST1 scheme SEP "with"
| WITH "Scheme" scheme LIST0 ( "with" scheme )
]
@@ -579,10 +575,6 @@ finite_token: [
| DELETENT
]
-constructor_list_or_record_decl: [
-| OPTINREF
-]
-
record_fields: [
| REPLACE record_field ";" record_fields
| WITH LIST0 record_field SEP ";" OPT ";"
@@ -598,11 +590,6 @@ inline: [
| REPLACE "Inline" "(" natural ")"
| WITH "Inline" OPT ( "(" natural ")" )
| DELETE "Inline"
-| OPTINREF
-]
-
-univ_instance: [
-| OPTINREF
]
univ_decl: [
@@ -610,18 +597,14 @@ univ_decl: [
| WITH "@{" LIST0 identref OPT "+" OPT [ "|" LIST0 univ_constraint SEP "," OPT "+" ] "}"
]
-of_type_with_opt_coercion: [
+of_type: [
| DELETENT
]
-of_type_with_opt_coercion: [
+of_type: [
| [ ":" | ":>" ] type
]
-attribute_value: [
-| OPTINREF
-]
-
def_body: [
| DELETE binders ":=" reduce lconstr
| REPLACE binders ":" lconstr ":=" reduce lconstr
@@ -630,14 +613,6 @@ def_body: [
| WITH LIST0 binder ":" type
]
-reduce: [
-| OPTINREF
-]
-
-occs: [
-| OPTINREF
-]
-
delta_flag: [
| REPLACE "-" "[" LIST1 smart_global "]"
| WITH OPT "-" "[" LIST1 smart_global "]"
@@ -651,15 +626,6 @@ ltac2_delta_flag: [
ltac2_branches: [
| EDIT ADD_OPT "|" LIST1 branch SEP "|" (* Ltac2 plugin *)
-| OPTINREF
-]
-
-RENAME: [
-| red_flag ltac2_red_flag
-| red_flags red_flag
-]
-
-RENAME: [
]
strategy_flag: [
@@ -668,7 +634,6 @@ strategy_flag: [
(*| REPLACE LIST1 red_flags
| WITH LIST1 red_flag*)
| (* empty *)
-| OPTINREF
]
filtered_import: [
@@ -677,25 +642,19 @@ filtered_import: [
| DELETE global
]
-functor_app_annot: [
-| OPTINREF
-]
-
is_module_expr: [
| REPLACE ":=" module_expr_inl LIST0 ext_module_expr
| WITH ":=" LIST1 module_expr_inl SEP "<+"
-| OPTINREF
]
is_module_type: [
| REPLACE ":=" module_type_inl LIST0 ext_module_type
| WITH ":=" LIST1 module_type_inl SEP "<+"
-| OPTINREF
]
gallina_ext: [
-| REPLACE "Arguments" smart_global LIST0 argument_spec_block OPT [ "," LIST1 [ LIST0 more_implicits_block ] SEP "," ] OPT [ ":" LIST1 arguments_modifier SEP "," ]
-| WITH "Arguments" smart_global LIST0 argument_spec_block LIST0 [ "," LIST0 more_implicits_block ] OPT [ ":" LIST1 arguments_modifier SEP "," ]
+| REPLACE "Arguments" smart_global LIST0 arg_specs OPT [ "," LIST1 [ LIST0 implicits_alt ] SEP "," ] OPT [ ":" LIST1 args_modifier SEP "," ]
+| WITH "Arguments" smart_global LIST0 arg_specs LIST0 [ "," LIST0 implicits_alt ] OPT [ ":" LIST1 args_modifier SEP "," ]
| REPLACE "Implicit" "Type" reserv_list
| WITH "Implicit" [ "Type" | "Types" ] reserv_list
| DELETE "Implicit" "Types" reserv_list
@@ -713,6 +672,10 @@ gallina_ext: [
| REPLACE "Coercion" by_notation ":" class_rawexpr ">->" class_rawexpr
| WITH "Coercion" smart_global ":" class_rawexpr ">->" class_rawexpr
+(* semantically restricted per https://github.com/coq/coq/pull/12936#discussion_r492705820 *)
+| REPLACE "Coercion" global OPT univ_decl def_body
+| WITH "Coercion" ident OPT univ_decl def_body
+
| REPLACE "Include" "Type" module_type_inl LIST0 ext_module_type
| WITH "Include" "Type" LIST1 module_type_inl SEP "<+"
@@ -720,21 +683,17 @@ gallina_ext: [
| WITH "Generalizable" [ [ "Variable" | "Variables" ] LIST1 identref | "All" "Variables" | "No" "Variables" ]
(* don't show Export for Set, Unset *)
-| REPLACE "Export" "Set" option_table option_setting
-| WITH "Set" option_table option_setting
-| REPLACE "Export" "Unset" option_table
-| WITH "Unset" option_table
-| REPLACE "Instance" instance_name ":" operconstr200 hint_info [ ":=" "{" record_declaration "}" | ":=" lconstr | ]
-| WITH "Instance" instance_name ":" operconstr200 hint_info OPT [ ":=" "{" record_declaration "}" | ":=" lconstr ]
+| REPLACE "Export" "Set" setting_name option_setting
+| WITH "Set" setting_name option_setting
+| REPLACE "Export" "Unset" setting_name
+| WITH "Unset" setting_name
+| REPLACE "Instance" instance_name ":" term200 hint_info [ ":=" "{" record_declaration "}" | ":=" lconstr | ]
+| WITH "Instance" instance_name ":" type hint_info OPT [ ":=" "{" record_declaration "}" | ":=" lconstr ]
| REPLACE "From" global "Require" export_token LIST1 global
| WITH "From" dirpath "Require" export_token LIST1 global
]
-export_token: [
-| OPTINREF
-]
-
(* lexer stuff *)
LEFTQMARK: [
| "?"
@@ -787,6 +746,7 @@ subsequent_letter: [
ident: [
| DELETE IDENT
+| DELETE IDENT (* 2nd copy from SSR *)
| first_letter LIST0 subsequent_letter
]
@@ -815,92 +775,97 @@ DELETE: [
| tactic_then_locality
]
-tactic_expr5: [
-(* make these look consistent with use of binder_tactic in other tactic_expr* *)
+ltac_expr5: [
+(* make these look consistent with use of binder_tactic in other ltac_expr* *)
| DELETE binder_tactic
-| DELETE tactic_expr4
-| [ tactic_expr4 | binder_tactic ]
+| DELETE ltac_expr4
+| [ ltac_expr4 | binder_tactic ]
]
ltac_constructs: [
(* repeated in main ltac grammar - need to create a COPY edit *)
-| tactic_expr3 ";" [ tactic_expr3 | binder_tactic ]
-| tactic_expr3 ";" "[" tactic_then_gen "]"
+| ltac_expr3 ";" [ ltac_expr3 | binder_tactic ]
+| ltac_expr3 ";" "[" for_each_goal "]"
-| tactic_expr1 "+" [ tactic_expr2 | binder_tactic ]
-| tactic_expr1 "||" [ tactic_expr2 | binder_tactic ]
+| ltac_expr1 "+" [ ltac_expr2 | binder_tactic ]
+| ltac_expr1 "||" [ ltac_expr2 | binder_tactic ]
-(* | qualid LIST0 tactic_arg add later due renaming tactic_arg *)
+(* | qualid LIST0 tactic_value add later due renaming tactic_value *)
-| "[>" tactic_then_gen "]"
-| toplevel_selector tactic_expr5
+| "[>" for_each_goal "]"
+| toplevel_selector ltac_expr5
]
-tactic_expr4: [
-| REPLACE tactic_expr3 ";" tactic_then_gen "]"
-| WITH tactic_expr3 ";" "[" tactic_then_gen "]"
-| REPLACE tactic_expr3 ";" binder_tactic
-| WITH tactic_expr3 ";" [ tactic_expr3 | binder_tactic ]
-| DELETE tactic_expr3 ";" tactic_expr3
+ltac_expr4: [
+| REPLACE ltac_expr3 ";" for_each_goal "]"
+| WITH ltac_expr3 ";" "[" for_each_goal "]"
+| REPLACE ltac_expr3 ";" binder_tactic
+| WITH ltac_expr3 ";" [ ltac_expr3 | binder_tactic ]
+| DELETE ltac_expr3 ";" ltac_expr3
+| MOVETO simple_tactic ltac_expr5 ";" "first" ssr_first_else TAG SSR
+| MOVETO simple_tactic ltac_expr5 ";" "first" ssrseqarg TAG SSR
+| MOVETO simple_tactic ltac_expr5 ";" "last" ssrseqarg TAG SSR
+| DELETE simple_tactic
]
l3_tactic: [ ]
-tactic_expr3: [
-| DELETE "abstract" tactic_expr2
-| REPLACE "abstract" tactic_expr2 "using" ident
-| WITH "abstract" tactic_expr2 OPT ( "using" ident )
+ltac_expr3: [
+| DELETE "abstract" ltac_expr2
+| REPLACE "abstract" ltac_expr2 "using" ident
+| WITH "abstract" ltac_expr2 OPT ( "using" ident )
| l3_tactic
+| EDIT "do" ADD_OPT int_or_var ssrmmod ssrdotac ssrclauses TAG SSR
| MOVEALLBUT ltac_builtins
| l3_tactic
-| tactic_expr2
+| ltac_expr2
]
l2_tactic: [ ]
-tactic_expr2: [
-| REPLACE tactic_expr1 "+" binder_tactic
-| WITH tactic_expr1 "+" [ tactic_expr2 | binder_tactic ]
-| DELETE tactic_expr1 "+" tactic_expr2
-| REPLACE tactic_expr1 "||" binder_tactic
-| WITH tactic_expr1 "||" [ tactic_expr2 | binder_tactic ]
-| DELETE tactic_expr1 "||" tactic_expr2
-| MOVETO ltac_builtins "tryif" tactic_expr5 "then" tactic_expr5 "else" tactic_expr2
+ltac_expr2: [
+| REPLACE ltac_expr1 "+" binder_tactic
+| WITH ltac_expr1 "+" [ ltac_expr2 | binder_tactic ]
+| DELETE ltac_expr1 "+" ltac_expr2
+| REPLACE ltac_expr1 "||" binder_tactic
+| WITH ltac_expr1 "||" [ ltac_expr2 | binder_tactic ]
+| DELETE ltac_expr1 "||" ltac_expr2
+| MOVETO ltac_builtins "tryif" ltac_expr5 "then" ltac_expr5 "else" ltac_expr2
| l2_tactic
| DELETE ltac_builtins
]
l1_tactic: [ ]
-tactic_expr1: [
+ltac_expr1: [
| EDIT match_key ADD_OPT "reverse" "goal" "with" match_context_list "end"
| MOVETO simple_tactic match_key OPT "reverse" "goal" "with" match_context_list "end"
-| MOVETO simple_tactic match_key tactic_expr5 "with" match_list "end"
+| MOVETO simple_tactic match_key ltac_expr5 "with" match_list "end"
| REPLACE failkw [ int_or_var | ] LIST0 message_token
| WITH failkw OPT int_or_var LIST0 message_token
-| REPLACE reference LIST0 tactic_arg_compat
-| WITH reference LIST1 tactic_arg_compat
+| REPLACE reference LIST0 tactic_arg
+| WITH reference LIST1 tactic_arg
| l1_tactic
| DELETE simple_tactic
| MOVEALLBUT ltac_builtins
| l1_tactic
-| tactic_arg
-| reference LIST1 tactic_arg_compat
-| tactic_expr0
+| tactic_value
+| reference LIST1 tactic_arg
+| ltac_expr0
]
(* split match_context_rule *)
goal_pattern: [
-| LIST0 match_hyps SEP "," "|-" match_pattern
-| "[" LIST0 match_hyps SEP "," "|-" match_pattern "]"
+| LIST0 match_hyp SEP "," "|-" match_pattern
+| "[" LIST0 match_hyp SEP "," "|-" match_pattern "]"
| "_"
]
match_context_rule: [
-| DELETE LIST0 match_hyps SEP "," "|-" match_pattern "=>" tactic_expr5
-| DELETE "[" LIST0 match_hyps SEP "," "|-" match_pattern "]" "=>" tactic_expr5
-| DELETE "_" "=>" tactic_expr5
-| goal_pattern "=>" tactic_expr5
+| DELETE LIST0 match_hyp SEP "," "|-" match_pattern "=>" ltac_expr5
+| DELETE "[" LIST0 match_hyp SEP "," "|-" match_pattern "]" "=>" ltac_expr5
+| DELETE "_" "=>" ltac_expr5
+| goal_pattern "=>" ltac_expr5
]
match_context_list: [
@@ -913,10 +878,10 @@ match_list: [
match_rule: [
(* redundant; match_pattern -> term -> _ *)
-| DELETE "_" "=>" tactic_expr5
+| DELETE "_" "=>" ltac_expr5
]
-selector_body: [
+selector: [
| REPLACE range_selector_or_nth (* depends on whether range_selector_or_nth is deleted first *)
| WITH LIST1 range_selector SEP ","
]
@@ -1083,8 +1048,8 @@ simple_tactic: [
| EDIT "psatz_R" ADD_OPT int_or_var tactic
| EDIT "psatz_Q" ADD_OPT int_or_var tactic
| EDIT "psatz_Z" ADD_OPT int_or_var tactic
-| REPLACE "subst" LIST1 var
-| WITH "subst" OPT ( LIST1 var )
+| REPLACE "subst" LIST1 hyp
+| WITH "subst" LIST0 hyp
| DELETE "subst"
| DELETE "congruence"
| DELETE "congruence" natural
@@ -1095,10 +1060,55 @@ simple_tactic: [
| REPLACE "show" "ltac" "profile" "cutoff" integer
| WITH "show" "ltac" "profile" OPT [ "cutoff" integer | string ]
| DELETE "show" "ltac" "profile" string
-(* perversely, the mlg uses "tactic3" instead of "tactic_expr3" *)
+(* perversely, the mlg uses "tactic3" instead of "ltac_expr3" *)
| DELETE "transparent_abstract" tactic3
| REPLACE "transparent_abstract" tactic3 "using" ident
-| WITH "transparent_abstract" tactic_expr3 OPT ( "using" ident )
+| WITH "transparent_abstract" ltac_expr3 OPT ( "using" ident )
+| "typeclasses" "eauto" OPT "bfs" OPT int_or_var OPT ( "with" LIST1 preident )
+| DELETE "typeclasses" "eauto" "bfs" OPT int_or_var "with" LIST1 preident
+| DELETE "typeclasses" "eauto" OPT int_or_var "with" LIST1 preident
+| DELETE "typeclasses" "eauto" "bfs" OPT int_or_var
+| DELETE "typeclasses" "eauto" OPT int_or_var
+(* in Tactic Notation: *)
+| "setoid_replace" constr "with" constr OPT ( "using" "relation" constr ) OPT ( "in" hyp )
+ OPT ( "at" LIST1 int_or_var ) OPT ( "by" ltac_expr3 )
+| REPLACE "apply" ssrapplyarg (* SSR plugin *)
+| WITH "apply" OPT ssrapplyarg TAG SSR
+| DELETE "apply"
+| REPLACE "elim" ssrarg ssrclauses (* SSR plugin *)
+| WITH "elim" OPT ( ssrarg ssrclauses ) TAG SSR
+| DELETE "elim" (* SSR plugin *)
+| REPLACE "case" ssrcasearg ssrclauses (* SSR plugin *)
+| WITH "case" OPT ( ssrcasearg ssrclauses ) TAG SSR
+| DELETE "case" (* SSR plugin *)
+| REPLACE "under" ssrrwarg ssrintros_ne "do" ssrhint3arg (* SSR plugin *)
+| WITH "under" ssrrwarg OPT ssrintros_ne OPT ( "do" ssrhint3arg ) TAG SSR
+| DELETE "under" ssrrwarg (* SSR plugin *)
+| DELETE "under" ssrrwarg ssrintros_ne (* SSR plugin *)
+| DELETE "under" ssrrwarg "do" ssrhint3arg (* SSR plugin *)
+| REPLACE "move" ssrmovearg ssrrpat (* SSR plugin *)
+| WITH "move" OPT ( OPT ssrmovearg ssrrpat ) TAG SSR
+| DELETE "move" ssrrpat (* SSR plugin *)
+| DELETE "move" (* SSR plugin *)
+| REPLACE "suff" "have" ssrhpats_nobs ssrhavefwd (* SSR plugin *)
+| WITH [ "suff" | "suffices" ] OPT ( "have" ssrhpats_nobs ) ssrhavefwd TAG SSR
+| DELETE "suffices" "have" ssrhpats_nobs ssrhavefwd (* SSR plugin *)
+| REPLACE "suff" ssrsufffwd (* SSR plugin *)
+| WITH [ "suff" | "suffices" ] ssrsufffwd TAG SSR
+| DELETE "suffices" ssrsufffwd (* SSR plugin *)
+| REPLACE "have" "suff" ssrhpats_nobs ssrhavefwd (* SSR plugin *)
+| WITH "have" [ "suff" | "suffices" ] ssrhpats_nobs ssrhavefwd TAG SSR
+| DELETE "have" "suffices" ssrhpats_nobs ssrhavefwd (* SSR plugin *)
+| REPLACE "gen" "have" ssrclear ssr_idcomma ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
+| WITH [ "gen" | "generally" ] "have" ssrclear ssr_idcomma ssrhpats_nobs ssrwlogfwd ssrhint TAG SSR
+| DELETE "generally" "have" ssrclear ssr_idcomma ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
+| REPLACE "wlog" "suff" ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
+| WITH [ "wlog" | "without loss" ] OPT [ "suff" | "suffices" ] ssrhpats_nobs ssrwlogfwd ssrhint TAG SSR
+| DELETE "wlog" "suffices" ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
+| DELETE "wlog" ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
+| DELETE "without" "loss" ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
+| DELETE "without" "loss" "suff" ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
+| DELETE "without" "loss" "suffices" ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
]
(* todo: don't use DELETENT for this *)
@@ -1130,14 +1140,31 @@ printable: [
| INSERTALL "Print"
]
+add_zify: [
+| [ "InjTyp" | "BinOp" | "UnOp" | "CstOp" | "BinRel" | "UnOpSpec" | "BinOpSpec" ] TAG Micromega
+| [ "PropOp" | "PropBinOp" | "PropUOp" | "Saturate" ]TAG Micromega
+]
+
+show_zify: [
+| [ "InjTyp" | "BinOp" | "UnOp" | "CstOp" | "BinRel" | "UnOpSpec" | "BinOpSpec" | "Spec" ] TAG Micromega
+]
+
+scheme_kind: [
+| DELETE "Induction" "for" smart_global "Sort" sort_family
+| DELETE "Minimality" "for" smart_global "Sort" sort_family
+| DELETE "Elimination" "for" smart_global "Sort" sort_family
+| DELETE "Case" "for" smart_global "Sort" sort_family
+| [ "Induction" | "Minimality" | "Elimination" | "Case" ] "for" smart_global "Sort" sort_family
+]
+
command: [
| REPLACE "Print" printable
| WITH printable
| "SubClass" ident_decl def_body
| REPLACE "Ltac" LIST1 ltac_tacdef_body SEP "with"
| WITH "Ltac" ltac_tacdef_body LIST0 ( "with" ltac_tacdef_body )
-| REPLACE "Function" LIST1 function_rec_definition_loc SEP "with" (* funind plugin *)
-| WITH "Function" function_rec_definition_loc LIST0 ( "with" function_rec_definition_loc ) (* funind plugin *)
+| REPLACE "Function" LIST1 function_fix_definition SEP "with" (* funind plugin *)
+| WITH "Function" function_fix_definition LIST0 ( "with" function_fix_definition ) (* funind plugin *)
| REPLACE "Functional" "Scheme" LIST1 fun_scheme_arg SEP "with" (* funind plugin *)
| WITH "Functional" "Scheme" fun_scheme_arg LIST0 ( "with" fun_scheme_arg ) (* funind plugin *)
| DELETE "Cd"
@@ -1148,16 +1175,16 @@ command: [
| WITH "Back" OPT natural
| REPLACE "Load" [ "Verbose" | ] [ ne_string | IDENT ]
| WITH "Load" OPT "Verbose" [ ne_string | IDENT ]
-| DELETE "Unset" option_table
-| REPLACE "Set" option_table option_setting
-| WITH OPT "Export" "Set" option_table (* set flag *)
-| REPLACE "Test" option_table "for" LIST1 table_value
-| WITH "Test" option_table OPT ( "for" LIST1 table_value )
-| DELETE "Test" option_table
+| DELETE "Unset" setting_name
+| REPLACE "Set" setting_name option_setting
+| WITH OPT "Export" "Set" setting_name (* set flag *)
+| REPLACE "Test" setting_name "for" LIST1 table_value
+| WITH "Test" setting_name OPT ( "for" LIST1 table_value )
+| DELETE "Test" setting_name
(* hide the fact that table names are limited to 2 IDENTs *)
| REPLACE "Add" IDENT IDENT LIST1 table_value
-| WITH "Add" option_table LIST1 table_value
+| WITH "Add" setting_name LIST1 table_value
| DELETE "Add" IDENT LIST1 table_value
| DELETE "Add" "Parametric" "Relation" binders ":" constr constr "reflexivity" "proved" "by" constr "symmetry" "proved" "by" constr "as" ident
| DELETE "Add" "Parametric" "Relation" binders ":" constr constr "reflexivity" "proved" "by" constr "as" ident
@@ -1202,7 +1229,7 @@ command: [
| WITH "Next" "Obligation" OPT ( "of" ident ) withtac
| DELETE "Next" "Obligation" withtac
| REPLACE "Obligation" natural "of" ident ":" lglob withtac
-| WITH "Obligation" natural OPT ( "of" ident ) OPT ( ":" lglob withtac )
+| WITH "Obligation" natural OPT ( "of" ident ) OPT ( ":" type withtac )
| DELETE "Obligation" natural "of" ident withtac
| DELETE "Obligation" natural ":" lglob withtac
| DELETE "Obligation" natural withtac
@@ -1215,7 +1242,7 @@ command: [
(* hide the fact that table names are limited to 2 IDENTs *)
| REPLACE "Remove" IDENT IDENT LIST1 table_value
-| WITH "Remove" option_table LIST1 table_value
+| WITH "Remove" setting_name LIST1 table_value
| DELETE "Remove" IDENT LIST1 table_value
| DELETE "Restore" "State" IDENT
| DELETE "Restore" "State" ne_string
@@ -1232,13 +1259,14 @@ command: [
| REPLACE "Solve" "All" "Obligations" "with" tactic
| WITH "Solve" "All" "Obligations" OPT ( "with" tactic )
| DELETE "Solve" "All" "Obligations"
+| DELETE "Solve" "Obligations" "of" ident "with" tactic
+| DELETE "Solve" "Obligations" "of" ident
+| DELETE "Solve" "Obligations" "with" tactic
+| DELETE "Solve" "Obligations"
+| "Solve" "Obligations" OPT ( "of" ident ) OPT ( "with" tactic )
| REPLACE "Solve" "Obligation" natural "of" ident "with" tactic
| WITH "Solve" "Obligation" natural OPT ( "of" ident ) "with" tactic
-| DELETE "Solve" "Obligations"
| DELETE "Solve" "Obligation" natural "with" tactic
-| REPLACE "Solve" "Obligations" "of" ident "with" tactic
-| WITH "Solve" "Obligations" OPT ( OPT ( "of" ident ) "with" tactic )
-| DELETE "Solve" "Obligations" "with" tactic
| DELETE "Undo"
| DELETE "Undo" natural
| REPLACE "Undo" "To" natural
@@ -1261,16 +1289,38 @@ command: [
| WITH "Declare" "Scope" scope_name
(* odd that these are in command while other notation-related ones are in syntax *)
-| REPLACE "Numeral" "Notation" reference reference reference ":" ident numnotoption
-| WITH "Numeral" "Notation" reference reference reference ":" scope_name numnotoption
-| REPLACE "String" "Notation" reference reference reference ":" ident
-| WITH "String" "Notation" reference reference reference ":" scope_name
+| REPLACE "Number" "Notation" reference reference reference OPT number_options ":" ident
+| WITH "Number" "Notation" reference reference reference OPT number_options ":" scope_name
+| REPLACE "Numeral" "Notation" reference reference reference ":" ident deprecated_number_modifier
+| WITH "Numeral" "Notation" reference reference reference ":" scope_name deprecated_number_modifier
+| REPLACE "String" "Notation" reference reference reference OPT string_option ":" ident
+| WITH "String" "Notation" reference reference reference OPT string_option ":" scope_name
| DELETE "Ltac2" ltac2_entry (* was split up *)
-]
-
-option_setting: [
-| OPTINREF
+| DELETE "Add" "Zify" "InjTyp" constr (* micromega plugin *)
+| DELETE "Add" "Zify" "BinOp" constr (* micromega plugin *)
+| DELETE "Add" "Zify" "UnOp" constr (* micromega plugin *)
+| DELETE "Add" "Zify" "CstOp" constr (* micromega plugin *)
+| DELETE "Add" "Zify" "BinRel" constr (* micromega plugin *)
+| DELETE "Add" "Zify" "PropOp" constr (* micromega plugin *)
+| DELETE "Add" "Zify" "PropBinOp" constr (* micromega plugin *)
+| DELETE "Add" "Zify" "PropUOp" constr (* micromega plugin *)
+| DELETE "Add" "Zify" "BinOpSpec" constr (* micromega plugin *)
+| DELETE "Add" "Zify" "UnOpSpec" constr (* micromega plugin *)
+| DELETE "Add" "Zify" "Saturate" constr (* micromega plugin *)
+| "Add" "Zify" add_zify constr TAG Micromega
+
+| DELETE "Show" "Zify" "InjTyp" (* micromega plugin *)
+| DELETE "Show" "Zify" "BinOp" (* micromega plugin *)
+| DELETE "Show" "Zify" "UnOp" (* micromega plugin *)
+| DELETE "Show" "Zify" "CstOp" (* micromega plugin *)
+| DELETE "Show" "Zify" "BinRel" (* micromega plugin *)
+| DELETE "Show" "Zify" "UnOpSpec" (* micromega plugin *)
+| DELETE "Show" "Zify" "BinOpSpec" (* micromega plugin *)
+(* keep this one | "Show" "Zify" "Spec" (* micromega plugin *)*)
+| "Show" "Zify" show_zify TAG Micromega
+| REPLACE "Goal" lconstr
+| WITH "Goal" type
]
syntax: [
@@ -1298,7 +1348,7 @@ syntax_modifier: [
| WITH LIST1 IDENT SEP "," "at" level
]
-syntax_extension_type: [
+explicit_subentry: [
| REPLACE "strict" "pattern" "at" "level" natural
| WITH "strict" "pattern" OPT ( "at" "level" natural )
| DELETE "strict" "pattern"
@@ -1308,31 +1358,27 @@ syntax_extension_type: [
| DELETE "constr" (* covered by another prod *)
]
-numnotoption: [
-| OPTINREF
-]
-
binder_tactic: [
-| REPLACE "let" [ "rec" | ] LIST1 let_clause SEP "with" "in" tactic_expr5
-| WITH "let" OPT "rec" let_clause LIST0 ( "with" let_clause ) "in" tactic_expr5
+| REPLACE "let" [ "rec" | ] LIST1 let_clause SEP "with" "in" ltac_expr5
+| WITH "let" OPT "rec" let_clause LIST0 ( "with" let_clause ) "in" ltac_expr5
| MOVEALLBUT ltac_builtins
]
-record_binder_body: [
-| REPLACE binders of_type_with_opt_coercion lconstr
-| WITH binders of_type_with_opt_coercion
-| REPLACE binders of_type_with_opt_coercion lconstr ":=" lconstr
-| WITH binders of_type_with_opt_coercion ":=" lconstr
+field_body: [
+| REPLACE binders of_type lconstr
+| WITH binders of_type
+| REPLACE binders of_type lconstr ":=" lconstr
+| WITH binders of_type ":=" lconstr
]
-simple_assum_coe: [
-| REPLACE LIST1 ident_decl of_type_with_opt_coercion lconstr
-| WITH LIST1 ident_decl of_type_with_opt_coercion
+assumpt: [
+| REPLACE LIST1 ident_decl of_type lconstr
+| WITH LIST1 ident_decl of_type
]
constructor_type: [
-| REPLACE binders [ of_type_with_opt_coercion lconstr | ]
-| WITH binders OPT of_type_with_opt_coercion
+| REPLACE binders [ of_type lconstr | ]
+| WITH binders OPT of_type
]
(* todo: is this really correct? Search for "Pvernac.register_proof_mode" *)
@@ -1376,12 +1422,12 @@ legacy_attr: [
sentence: [ ] (* productions defined below *)
-rec_definition: [
+fix_definition: [
| REPLACE ident_decl binders_fixannot type_cstr OPT [ ":=" lconstr ] decl_notations
| WITH ident_decl binders_fixannot type_cstr OPT [ ":=" lconstr ] decl_notations
]
-corec_definition: [
+cofix_definition: [
| REPLACE ident_decl binders type_cstr OPT [ ":=" lconstr ] decl_notations
| WITH ident_decl binders type_cstr OPT [ ":=" lconstr ] decl_notations
]
@@ -1389,16 +1435,15 @@ corec_definition: [
type_cstr: [
| REPLACE ":" lconstr
| WITH ":" type
-| OPTINREF
]
inductive_definition: [
| REPLACE opt_coercion ident_decl binders OPT [ "|" binders ] OPT [ ":" lconstr ] opt_constructors_or_fields decl_notations
-| WITH opt_coercion ident_decl binders OPT [ "|" binders ] OPT [ ":" type ] opt_constructors_or_fields decl_notations
+| WITH opt_coercion ident_decl binders OPT [ "|" binders ] OPT [ ":" type ] opt_constructors_or_fields decl_notations
]
(* note that constructor -> identref constructor_type *)
-constructor_list_or_record_decl: [
+constructors_or_record: [
| DELETE "|" LIST1 constructor SEP "|"
| REPLACE identref constructor_type "|" LIST1 constructor SEP "|"
| WITH OPT "|" LIST1 constructor SEP "|"
@@ -1409,15 +1454,11 @@ constructor_list_or_record_decl: [
]
record_binder: [
-| REPLACE name record_binder_body
-| WITH name OPT record_binder_body
+| REPLACE name field_body
+| WITH name OPT field_body
| DELETE name
]
-at_level_opt: [
-| OPTINREF
-]
-
query_command: [
| REPLACE "Eval" red_expr "in" lconstr "."
| WITH "Eval" red_expr "in" lconstr
@@ -1452,10 +1493,6 @@ vernac_toplevel: [
| DELETE vernac_control
]
-in_or_out_modules: [
-| OPTINREF
-]
-
vernac_control: [
(* replacing vernac_control with command is cheating a little;
they can't refer to the vernac_toplevel commands.
@@ -1471,90 +1508,8 @@ vernac_control: [
| DELETE decorated_vernac
]
-orient: [
-| OPTINREF
-]
-
-in_hyp_as: [
-| OPTINREF
-]
-
-as_name: [
-| OPTINREF
-]
-
-hloc: [
-| OPTINREF
-]
-
-as_or_and_ipat: [
-| OPTINREF
-]
-
-hintbases: [
-| OPTINREF
-]
-
-as_ipat: [
-| OPTINREF
-]
-
-auto_using: [
-| OPTINREF
-]
-
-with_bindings: [
-| OPTINREF
-]
-
-eqn_ipat: [
-| OPTINREF
-]
-
-withtac: [
-| OPTINREF
-]
-
of_module_type: [
| (* empty *)
-| OPTINREF
-]
-
-
-clause_dft_all: [
-| OPTINREF
-]
-
-opt_clause: [
-| OPTINREF
-]
-
-with_names: [
-| OPTINREF
-]
-
-in_hyp_list: [
-| OPTINREF
-]
-
-struct_annot: [
-| OPTINREF
-]
-
-firstorder_using: [
-| OPTINREF
-]
-
-fun_ind_using: [
-| OPTINREF
-]
-
-by_arg_tac: [
-| OPTINREF
-]
-
-by_tactic: [
-| OPTINREF
]
rewriter: [
@@ -1577,7 +1532,7 @@ ltac2_rewriter: [
| OPT natural OPT [ "?" | "!" ] ltac2_constr_with_bindings
]
-tac2expr0: [
+ltac2_expr0: [
| DELETE "(" ")"
]
@@ -1601,31 +1556,10 @@ record_declaration: [
fields_def: [ | DELETENT ]
-hint_info: [
-| OPTINREF
-]
-
-debug: [
-| OPTINREF
-]
-
-eauto_search_strategy: [
-| OPTINREF
-]
-
-
constr_body: [
| DELETE ":=" lconstr
| REPLACE ":" lconstr ":=" lconstr
-| WITH OPT ( ":" lconstr ) ":=" lconstr
-]
-
-opt_hintbases: [
-| OPTINREF
-]
-
-opthints: [
-| OPTINREF
+| WITH OPT ( ":" type ) ":=" lconstr
]
scheme: [
@@ -1634,10 +1568,6 @@ scheme: [
| WITH OPT ( identref ":=" ) scheme_kind
]
-instance_name: [
-| OPTINREF
-]
-
simple_reserv: [
| REPLACE LIST1 identref ":" lconstr
| WITH LIST1 identref ":" type
@@ -1656,22 +1586,9 @@ ltac2_in_clause: [
| DELETE LIST0 ltac2_hypident_occ SEP "," (* Ltac2 plugin *)
]
-concl_occ: [
-| OPTINREF
-]
-
-opt_coercion: [
-| OPTINREF
-]
-
-opt_constructors_or_fields: [
-| OPTINREF
-]
-
decl_notations: [
| REPLACE "where" LIST1 decl_notation SEP decl_sep
| WITH "where" decl_notation LIST0 (decl_sep decl_notation )
-| OPTINREF
]
module_expr: [
@@ -1732,15 +1649,6 @@ decl_notation: [
| WITH ne_lstring ":=" constr syntax_modifiers OPT [ ":" scope_name ]
]
-syntax_modifiers: [
-| OPTINREF
-]
-
-
-only_parsing: [
-| OPTINREF
-]
-
ltac_production_item: [
| REPLACE ident "(" ident OPT ltac_production_sep ")"
| WITH ident OPT ( "(" ident OPT ltac_production_sep ")" )
@@ -1754,9 +1662,9 @@ input_fun: [
]
let_clause: [
-| DELETE identref ":=" tactic_expr5
-| REPLACE "_" ":=" tactic_expr5
-| WITH name ":=" tactic_expr5
+| DELETE identref ":=" ltac_expr5
+| REPLACE "_" ":=" ltac_expr5
+| WITH name ":=" ltac_expr5
]
tactic_mode: [
@@ -1769,13 +1677,20 @@ tactic_mode: [
| ltac_info tactic
| MOVETO command ltac_info tactic
| DELETE command
+| REPLACE OPT toplevel_selector "{"
+(* semantically restricted *)
+| WITH OPT ( [ natural | "[" ident "]" ] ":" ) "{"
+| MOVETO simple_tactic OPT ( [ natural | "[" ident "]" ] ":" ) "{"
+| DELETE simple_tactic
]
-sexpr: [
+tactic_mode: [ | DELETENT ]
+
+ltac2_scope: [
| REPLACE syn_node (* Ltac2 plugin *)
| WITH name TAG Ltac2
-| REPLACE syn_node "(" LIST1 sexpr SEP "," ")" (* Ltac2 plugin *)
-| WITH name "(" LIST1 sexpr SEP "," ")" TAG Ltac2
+| REPLACE syn_node "(" LIST1 ltac2_scope SEP "," ")" (* Ltac2 plugin *)
+| WITH name "(" LIST1 ltac2_scope SEP "," ")" TAG Ltac2
]
syn_node: [ | DELETENT ]
@@ -1785,7 +1700,7 @@ RENAME: [
]
toplevel_selector: [
-| selector_body
+| selector
| "all"
| "!"
(* par is accepted even though it's not in the .mlg *)
@@ -1793,7 +1708,7 @@ toplevel_selector: [
]
toplevel_selector_temp: [
-| DELETE selector_body ":"
+| DELETE selector ":"
| DELETE "all" ":"
| DELETE "!" ":"
| toplevel_selector ":"
@@ -1834,7 +1749,7 @@ query_command: [ ] (* re-add as a placeholder *)
sentence: [
| OPT attributes command "."
| OPT attributes OPT ( natural ":" ) query_command "."
-| OPT attributes OPT ( toplevel_selector ":" ) tactic_expr5 [ "." | "..." ]
+| OPT attributes OPT ( toplevel_selector ":" ) ltac_expr5 [ "." | "..." ]
| control_command
]
@@ -1855,30 +1770,33 @@ ltac_defined_tactics: [
| "lra"
| "nia"
| "nra"
+| "over" TAG SSR
| "split_Rabs"
| "split_Rmult"
| "tauto"
-| "time_constr" tactic_expr5
+| "time_constr" ltac_expr5
| "zify"
]
(* todo: need careful review; assume that "[" ... "]" are literals *)
tactic_notation_tactics: [
-| "assert_fails" tactic_expr3
-| "assert_succeeds" tactic_expr3
-| "field" OPT ( "[" LIST1 operconstr200 "]" )
-| "field_simplify" OPT ( "[" LIST1 operconstr200 "]" ) LIST1 operconstr200 OPT ( "in" ident )
-| "field_simplify_eq" OPT ( "[" LIST1 operconstr200 "]" ) OPT ( "in" ident )
-| "intuition" OPT tactic_expr5
-| "nsatz" OPT ( "with" "radicalmax" ":=" operconstr200 "strategy" ":=" operconstr200 "parameters" ":=" operconstr200 "variables" ":=" operconstr200 )
-| "psatz" operconstr200 OPT int_or_var
-| "ring" OPT ( "[" LIST1 operconstr200 "]" )
-| "ring_simplify" OPT ( "[" LIST1 operconstr200 "]" ) LIST1 operconstr200 OPT ( "in" ident ) (* todo: ident was "hyp", worth keeping? *)
+| "assert_fails" ltac_expr3
+| "assert_succeeds" ltac_expr3
+| "dintuition" OPT ltac_expr5
+| "dtauto"
+| "field" OPT ( "[" LIST1 constr "]" )
+| "field_simplify" OPT ( "[" LIST1 constr "]" ) LIST1 constr OPT ( "in" ident )
+| "field_simplify_eq" OPT ( "[" LIST1 constr "]" ) OPT ( "in" ident )
+| "intuition" OPT ltac_expr5 (* todo: Not too keen on things like "with_power_flags" in tauto.ml, not easy to follow *)
+| "nsatz" OPT ( "with" "radicalmax" ":=" constr "strategy" ":=" constr "parameters" ":=" constr "variables" ":=" constr )
+| "psatz" constr OPT int_or_var
+| "ring" OPT ( "[" LIST1 constr "]" )
+| "ring_simplify" OPT ( "[" LIST1 constr "]" ) LIST1 constr OPT ( "in" ident ) (* todo: ident was "hyp", worth keeping? *)
]
(* defined in OCaml outside of mlgs *)
-tactic_arg: [
-| "uconstr" ":" "(" operconstr200 ")"
+tactic_value: [
+| "uconstr" ":" "(" term200 ")"
| MOVEALLBUT simple_tactic
]
@@ -1886,10 +1804,6 @@ nonterminal: [ ]
value_tactic: [ ]
-RENAME: [
-| tactic_arg tactic_value
-]
-
syn_value: [
| IDENT; ":" "(" nonterminal ")"
]
@@ -1908,8 +1822,8 @@ ltac2_match_key: [
]
ltac2_constructs: [
-| ltac2_match_key tac2expr6 "with" ltac2_match_list "end"
-| ltac2_match_key OPT "reverse" "goal" "with" gmatch_list "end"
+| ltac2_match_key ltac2_expr6 "with" ltac2_match_list "end"
+| ltac2_match_key OPT "reverse" "goal" "with" goal_match_list "end"
]
simple_tactic: [
@@ -1921,9 +1835,9 @@ simple_tactic: [
]
tacdef_body: [
-| REPLACE global LIST1 input_fun ltac_def_kind tactic_expr5
-| WITH global LIST0 input_fun ltac_def_kind tactic_expr5
-| DELETE global ltac_def_kind tactic_expr5
+| REPLACE global LIST1 input_fun ltac_def_kind ltac_expr5
+| WITH global LIST0 input_fun ltac_def_kind ltac_expr5
+| DELETE global ltac_def_kind ltac_expr5
]
tac2def_typ: [
@@ -1975,10 +1889,6 @@ DELETE: [
| test_ltac1_env
]
-mut_flag: [
-| OPTINREF
-]
-
rec_flag: [
| OPTINREF
]
@@ -1993,19 +1903,7 @@ SPLICE: [
| ltac2_orient
]
-tac2typ_prm: [
-| OPTINREF
-]
-
-tac2type_body: [
-| OPTINREF
-]
-
-atomic_tac2pat: [
-| OPTINREF
-]
-
-tac2expr0: [
+ltac2_expr0: [
(*
| DELETE "(" ")" (* covered by "()" prodn *)
| REPLACE "{" [ | LIST1 tac2rec_fieldexpr OPT ";" ] "}"
@@ -2018,13 +1916,13 @@ tac2expr0: [
use LIST1? *)
SPLICE: [
-| tac2expr4
+| ltac2_expr4
]
-tac2expr3: [
-| REPLACE tac2expr2 "," LIST1 tac2expr2 SEP "," (* Ltac2 plugin *)
-| WITH LIST1 tac2expr2 SEP "," TAG Ltac2
-| DELETE tac2expr2 (* Ltac2 plugin *)
+ltac2_expr3: [
+| REPLACE ltac2_expr2 "," LIST1 ltac2_expr2 SEP "," (* Ltac2 plugin *)
+| WITH LIST1 ltac2_expr2 SEP "," TAG Ltac2
+| DELETE ltac2_expr2 (* Ltac2 plugin *)
]
tac2rec_fieldexprs: [
@@ -2032,7 +1930,6 @@ tac2rec_fieldexprs: [
| DELETE tac2rec_fieldexpr ";"
| DELETE tac2rec_fieldexpr
| LIST1 tac2rec_fieldexpr OPT ";"
-| OPTINREF
]
tac2rec_fields: [
@@ -2040,7 +1937,6 @@ tac2rec_fields: [
| DELETE tac2rec_field ";"
| DELETE tac2rec_field
| LIST1 tac2rec_field SEP ";" OPT ";" TAG Ltac2
-| OPTINREF
]
(* todo: weird productions, ints only after an initial "-"??:
@@ -2054,46 +1950,6 @@ ltac2_occs_nums: [
| WITH OPT "-" LIST1 nat_or_anti TAG Ltac2
]
-syn_level: [
-| OPTINREF
-]
-
-ltac2_delta_flag: [
-| OPTINREF
-]
-
-ltac2_occs: [
-| OPTINREF
-]
-
-ltac2_concl_occ: [
-| OPTINREF
-]
-
-ltac2_with_bindings: [
-| OPTINREF
-]
-
-ltac2_as_or_and_ipat: [
-| OPTINREF
-]
-
-ltac2_eqn_ipat: [
-| OPTINREF
-]
-
-ltac2_as_name: [
-| OPTINREF
-]
-
-ltac2_as_ipat: [
-| OPTINREF
-]
-
-ltac2_by_tactic: [
-| OPTINREF
-]
-
ltac2_entry: [
| REPLACE tac2def_typ (* Ltac2 plugin *)
| WITH "Ltac2" tac2def_typ
@@ -2105,7 +1961,7 @@ ltac2_entry: [
| WITH "Ltac2" tac2def_val
| REPLACE tac2def_ext (* Ltac2 plugin *)
| WITH "Ltac2" tac2def_ext
-| "Ltac2" "Notation" [ string | lident ] ":=" tac2expr6 TAG Ltac2 (* variant *)
+| "Ltac2" "Notation" [ string | lident ] ":=" ltac2_expr6 TAG Ltac2 (* variant *)
| MOVEALLBUT command
(* todo: MOVEALLBUT should ignore tag on "but" prodns *)
]
@@ -2128,34 +1984,23 @@ SPLICE: [
| tac2def_ext
| tac2def_syn
| tac2def_mut
-| mut_flag
| rec_flag
| locident
-| syn_level
-| tac2rec_fieldexprs
-| tac2type_body
| tac2alg_constructors
-| tac2rec_fields
| ltac2_binder
| branch
| anti
]
-tac2expr5: [
-| REPLACE "let" OPT "rec" LIST1 ltac2_let_clause SEP "with" "in" tac2expr6 (* Ltac2 plugin *)
-| WITH "let" OPT "rec" ltac2_let_clause LIST0 ( "with" ltac2_let_clause ) "in" tac2expr6 TAG Ltac2
-| MOVETO simple_tactic "match" tac2expr5 "with" OPT ltac2_branches "end" (* Ltac2 plugin *)
+ltac2_expr5: [
+| REPLACE "let" OPT "rec" LIST1 ltac2_let_clause SEP "with" "in" ltac2_expr6 (* Ltac2 plugin *)
+| WITH "let" OPT "rec" ltac2_let_clause LIST0 ( "with" ltac2_let_clause ) "in" ltac2_expr6 TAG Ltac2
+| MOVETO simple_tactic "match" ltac2_expr5 "with" ltac2_branches "end" (* Ltac2 plugin *)
+| MOVETO simple_tactic "if" ltac2_expr5 "then" ltac2_expr5 "else" ltac2_expr5 (* Ltac2 plugin *)
| DELETE simple_tactic
]
-RENAME: [
-| Prim.string string
-| Prim.integer integer
-| Prim.qualid qualid
-| Prim.natural natural
-]
-
-gmatch_list: [
+goal_match_list: [
| EDIT ADD_OPT "|" LIST1 gmatch_rule SEP "|" (* Ltac2 plugin *)
]
@@ -2190,8 +2035,358 @@ q_clause: [
]
ltac2_induction_clause: [
-| REPLACE ltac2_destruction_arg OPT ltac2_as_or_and_ipat OPT ltac2_eqn_ipat OPT clause (* Ltac2 plugin *)
-| WITH ltac2_destruction_arg OPT ltac2_as_or_and_ipat OPT ltac2_eqn_ipat OPT ltac2_clause TAG Ltac2
+| REPLACE ltac2_destruction_arg ltac2_as_or_and_ipat ltac2_eqn_ipat OPT clause (* Ltac2 plugin *)
+| WITH ltac2_destruction_arg ltac2_as_or_and_ipat ltac2_eqn_ipat OPT ltac2_clause TAG Ltac2
+]
+
+starredidentref: [
+| EDIT identref ADD_OPT "*"
+| EDIT "Type" ADD_OPT "*"
+| "All"
+]
+
+ssexpr0: [
+| DELETE "(" LIST0 starredidentref ")"
+| DELETE "(" LIST0 starredidentref ")" "*"
+| DELETE "(" ssexpr35 ")"
+| DELETE "(" ssexpr35 ")" "*"
+| "(" section_subset_expr ")" OPT "*"
+]
+
+ssexpr35: [
+| EDIT ADD_OPT "-" ssexpr50
+]
+
+simple_binding: [
+| REPLACE "(" ident ":=" lconstr ")"
+| WITH "(" [ ident | natural ] ":=" lconstr ")"
+| DELETE "(" natural ":=" lconstr ")"
+]
+
+
+subprf: [
+| MOVEALLBUT simple_tactic
+| "{" (* should be removed. See https://github.com/coq/coq/issues/12004 *)
+]
+
+ltac2_expr: [
+| DELETE _ltac2_expr
+]
+
+ssrfwdview: [
+| REPLACE "/" ast_closure_term ssrfwdview (* SSR plugin *)
+| WITH LIST1 ( "/" ast_closure_term ) TAG SSR
+| DELETE "/" ast_closure_term (* SSR plugin *)
+]
+
+ssrfwd: [
+| REPLACE ":" ast_closure_lterm ":=" ast_closure_lterm (* SSR plugin *)
+| WITH OPT ( ":" ast_closure_lterm ) ":=" ast_closure_lterm TAG SSR
+| DELETE ":=" ast_closure_lterm (* SSR plugin *)
+]
+
+ssrsetfwd: [
+| REPLACE ":" ast_closure_lterm ":=" "{" ssrocc "}" cpattern (* SSR plugin *)
+| WITH OPT ( ":" ast_closure_lterm ) ":=" [ "{" ssrocc "}" cpattern | lcpattern ] TAG SSR
+| DELETE ":" ast_closure_lterm ":=" lcpattern (* SSR plugin *)
+| DELETE ":=" "{" ssrocc "}" cpattern (* SSR plugin *)
+| DELETE ":=" lcpattern (* SSR plugin *)
+]
+
+
+(* per @gares *)
+ssrdgens: [
+| REPLACE ":" ssrgen ssrdgens_tl (* SSR plugin *)
+| WITH ":" ssrgen OPT ( "/" ssrgen ) TAG SSR
+]
+
+ssrdgens_tl: [ | DELETENT ]
+
+ssrgen: [
+| REPLACE ssrdocc cpattern (* SSR plugin *)
+| WITH cpattern LIST0 [ LIST1 ident | cpattern ] TAG SSR
+| DELETE cpattern (* SSR plugin *)
+]
+
+OPTINREF: [ ]
+
+ssrortacs: [
+| EDIT ssrtacarg "|" ADD_OPT ssrortacs (* ssr plugin *)
+| EDIT "|" ADD_OPT ssrortacs (* ssr plugin *)
+| EDIT ADD_OPT ssrtacarg "|" OPT ssrortacs
+]
+
+ssrocc: [
+| REPLACE natural LIST0 natural (* SSR plugin *)
+| WITH [ natural | "+" | "-" ] LIST0 natural TAG SSR
+| DELETE "-" LIST0 natural (* SSR plugin *)
+| DELETE "+" LIST0 natural (* SSR plugin *)
+]
+
+ssripat: [
+| DELETE ssrdocc "->" (* SSR plugin *)
+| DELETE ssrdocc "<-" (* SSR plugin *)
+| REPLACE ssrdocc (* SSR plugin *)
+| WITH ssrdocc OPT [ "->" | "<-" ] TAG SSR
+| DELETE "->" (* SSR plugin *)
+| DELETE "<-" (* SSR plugin *)
+| DELETE "-/" "=" (* SSR plugin *)
+| DELETE "-/" "/" (* SSR plugin *)
+| DELETE "-/" integer "/" (* SSR plugin *)
+| DELETE "-/" integer "/=" (* SSR plugin *)
+| REPLACE "-/" integer "/" integer "=" (* SSR plugin *)
+| WITH "-/" integer [ "/=" | "/" | "/" integer "=" ] TAG SSR
+| DELETE "-/" "/=" (* SSR plugin *)
+| DELETE "-//" "=" (* SSR plugin *)
+| DELETE "[" ":" LIST0 ident "]" (* SSR plugin *)
+]
+
+ssrsimpl_ne: [
+| DELETE "/" natural "/" "=" (* SSR plugin *)
+(* parsed but not supported per @gares *)
+| DELETE "/" natural "/" (* SSR plugin *)
+| DELETE "/" natural "=" (* SSR plugin *)
+| DELETE "//" natural "=" (* SSR plugin *)
+]
+
+hat: [
+| DELETE "^" "~" ident (* SSR plugin *)
+| DELETE "^" "~" natural (* SSR plugin *)
+]
+
+ssriorpat: [
+| ssripats OPT ( [ "|" | "|-" ] ssriorpat ) TAG SSR
+| DELETE OPT ssripats "|" ssriorpat (* SSR plugin *)
+| DELETE OPT ssripats "|-" ">" ssriorpat (* SSR plugin *)
+| DELETE OPT ssripats "|-" ssriorpat (* SSR plugin *)
+(* "|->" | "||" | "|||" | "||||" are parsing hacks *)
+| DELETE OPT ssripats "|->" ssriorpat (* SSR plugin *)
+| DELETE OPT ssripats "||" ssriorpat (* SSR plugin *)
+| DELETE OPT ssripats "|||" ssriorpat (* SSR plugin *)
+| DELETE OPT ssripats "||||" ssriorpat (* SSR plugin *)
+| DELETE OPT ssripats (* SSR plugin *)
+]
+
+ssrbinder: [
+| REPLACE "(" ssrbvar LIST1 ssrbvar ":" lconstr ")" (* SSR plugin *)
+| WITH "(" LIST1 ssrbvar ":" lconstr ")" TAG SSR
+| REPLACE "(" ssrbvar ":" lconstr ":=" lconstr ")" (* SSR plugin *)
+| WITH "(" ssrbvar OPT ( ":" lconstr ) OPT ( ":=" lconstr ) ")" TAG SSR
+| DELETE "(" ssrbvar ")" (* SSR plugin *)
+| DELETE "(" ssrbvar ":" lconstr ")" (* SSR plugin *)
+| DELETE "(" ssrbvar ":=" lconstr ")" (* SSR plugin *)
+]
+
+ssrhavefwd: [
+| REPLACE ":" ast_closure_lterm ":=" ast_closure_lterm (* SSR plugin *)
+| WITH ":" ast_closure_lterm ":=" OPT ast_closure_lterm TAG SSR
+| DELETE ":" ast_closure_lterm ":=" (* SSR plugin *)
+| DELETE ":=" ast_closure_lterm (* SSR plugin *)
+]
+
+ssrmult_ne: [
+| EDIT ADD_OPT natural ssrmmod TAG SSR
+]
+
+rpattern: [
+| REPLACE lconstr "in" lconstr "in" lconstr (* SSR plugin *)
+| WITH OPT ( OPT ( OPT ( OPT lconstr "in" ) lconstr ) "in" ) lconstr TAG SSR
+| DELETE lconstr (* SSR plugin *)
+| DELETE "in" lconstr (* SSR plugin *)
+| DELETE lconstr "in" lconstr (* SSR plugin *)
+| DELETE "in" lconstr "in" lconstr (* SSR plugin *)
+]
+
+ssrrule_ne: [
+| DELETE ssrsimpl_ne (* SSR plugin *)
+| REPLACE [ "/" ssrterm | ssrterm | ssrsimpl_ne ] (* SSR plugin *)
+| WITH [ OPT "/" ssrterm | ssrsimpl_ne ] TAG SSR
+]
+
+ssrunlockarg: [
+| REPLACE "{" ssrocc "}" ssrterm (* SSR plugin *)
+| WITH OPT ( "{" ssrocc "}" ) ssrterm TAG SSR
+| DELETE ssrterm (* SSR plugin *)
+]
+
+ssrclauses: [
+| REPLACE "in" ssrclausehyps "|-" "*" (* SSR plugin *)
+| WITH "in" ssrclausehyps OPT "|-" OPT "*" TAG SSR
+| DELETE "in" ssrclausehyps "|-" (* SSR plugin *)
+| DELETE "in" ssrclausehyps "*" (* SSR plugin *)
+| DELETE "in" ssrclausehyps (* SSR plugin *)
+| REPLACE "in" "|-" "*" (* SSR plugin *)
+| WITH "in" [ "*" | "*" "|-" | "|-" "*" ] TAG SSR
+| DELETE "in" "*" (* SSR plugin *)
+| DELETE "in" "*" "|-" (* SSR plugin *)
+]
+
+ssrclausehyps: [
+| REPLACE ssrwgen "," ssrclausehyps (* SSR plugin *)
+| WITH ssrwgen LIST0 ( OPT "," ssrwgen ) TAG SSR
+| DELETE ssrwgen ssrclausehyps (* SSR plugin *)
+| DELETE ssrwgen (* SSR plugin *)
+]
+
+ssrwgen: [
+| DELETE ssrhoi_hyp (* SSR plugin *)
+| REPLACE "@" ssrhoi_hyp (* SSR plugin *)
+| WITH OPT "@" ssrhoi_hyp TAG SSR
+| REPLACE "(" ssrhoi_id ":=" lcpattern ")" (* SSR plugin *)
+| WITH "(" ssrhoi_id OPT ( ":=" lcpattern ) ")" TAG SSR
+| DELETE "(" ssrhoi_id ")" (* SSR plugin *)
+| DELETE "(" "@" ssrhoi_id ":=" lcpattern ")" (* SSR plugin *)
+]
+
+ssrcongrarg: [
+| REPLACE natural constr ssrdgens (* SSR plugin *)
+| WITH OPT natural constr OPT ssrdgens TAG SSR
+| DELETE natural constr (* SSR plugin *)
+| DELETE constr ssrdgens (* SSR plugin *)
+| DELETE constr (* SSR plugin *)
+]
+
+ssrviewpos: [
+| DELETE "for" "apply" "/" "/" (* SSR plugin *)
+]
+
+ssrhintref: [
+| REPLACE constr "|" natural (* SSR plugin *)
+| WITH constr OPT ( "|" natural ) TAG SSR
+| DELETE constr (* SSR plugin *)
+]
+
+ssr_search_arg: [
+| REPLACE "-" ssr_search_item OPT ssr_search_arg (* SSR plugin *)
+| WITH LIST1 ( "-" ssr_search_item ) TAG SSR
+| DELETE ssr_search_item OPT ssr_search_arg (* SSR plugin *)
+]
+
+ssr_search_item: [
+| DELETE string (* SSR plugin *)
+| REPLACE string "%" preident (* SSR plugin *)
+| WITH string OPT ( "%" preident ) TAG SSR
+]
+
+modloc: [
+| REPLACE "-" global (* SSR plugin *)
+| WITH OPT "-" global TAG SSR
+| DELETE global
+]
+
+ssrmmod: [
+| DELETE LEFTQMARK (* SSR plugin *) (* duplicate *)
+]
+
+clear_switch: [
+| "{" LIST0 ident "}"
+]
+
+ssrrwocc: [
+| REPLACE "{" LIST0 ssrhyp "}" (* SSR plugin *)
+| WITH clear_switch
+]
+
+ssrrwarg: [
+| EDIT "{" ADD_OPT ssrocc "}" OPT ssrpattern_squarep ssrrule_ne TAG SSR
+| REPLACE "{" LIST1 ssrhyp "}" ssrpattern_ne_squarep ssrrule_ne (* SSR plugin *)
+| WITH OPT ( OPT ( "{" LIST1 ssrhyp "}" ) ssrpattern_ne_squarep ) ssrrule_ne TAG SSR
+| DELETE ssrpattern_ne_squarep ssrrule_ne (* SSR plugin *)
+| DELETE ssrrule_ne (* SSR plugin *)
+]
+
+ssrpattern_squarep: [ (* fix inconsistency *)
+| REPLACE "[" rpattern "]" (* SSR plugin *)
+| WITH ssrpattern_ne_squarep TAG SSR
+]
+
+ssripats_ne: [
+| REPLACE ssripat OPT ssripats (* SSR plugin *)
+| WITH LIST1 ssripat TAG SSR
+]
+
+ssripats: [ (* fix inconsistency *)
+| REPLACE ssripat OPT ssripats (* SSR plugin *)
+| WITH ssripats_ne TAG SSR
+]
+
+lcpattern: [
+(* per @gares *)
+| DELETE "Qed" lconstr
+]
+
+ssrapplyarg: [
+| EDIT ADD_OPT ssrbwdview ":" ssragen OPT ssragens OPT ssrintros TAG SSR
+]
+
+constr_with_bindings_arg: [
+| EDIT ADD_OPT ">" constr_with_bindings TAG SSR
+]
+
+destruction_arg: [
+| DELETE constr_with_bindings
+]
+
+ssrhintarg: [
+| EDIT "[" ADD_OPT ssrortacs "]" TAG SSR
+]
+
+
+ssrhint3arg: [
+| EDIT "[" ADD_OPT ssrortacs "]" TAG SSR
+]
+
+
+ssr_first: [
+| DELETE ssr_first ssrintros_ne (* SSR plugin *)
+| REPLACE "[" LIST0 ltac_expr5 SEP "|" "]" (* SSR plugin *)
+| WITH "[" LIST0 ltac_expr5 SEP "|" "]" LIST0 ssrintros_ne TAG SSR
+]
+
+ssr_first_else: [
+| EDIT ssr_first ADD_OPT ssrorelse TAG SSR
+]
+
+ssrseqarg: [
+| EDIT ADD_OPT ssrseqidx ssrswap TAG SSR
+]
+
+ssr_dpat: [
+| REPLACE ssr_mpat "in" pattern200 ssr_rtype (* SSR plugin *)
+| WITH ssr_mpat OPT ( OPT ( "in" pattern200 ) ssr_rtype ) TAG SSR
+| DELETE ssr_mpat ssr_rtype (* SSR plugin *)
+| DELETE ssr_mpat (* SSR plugin *)
+]
+
+ssr_one_term_pattern: [
+| DELETE "Qed" constr
+]
+
+ssrarg: [
+| EDIT ADD_OPT ssrfwdview OPT ssreqid ssrdgens OPT ssrintros (* SSR plugin *)
+]
+
+ssragen: [
+| REPLACE "{" LIST1 ssrhyp "}" ssrterm (* SSR plugin *)
+| WITH OPT ( "{" LIST1 ssrhyp "}" ) ssrterm TAG SSR
+| DELETE ssrterm (* SSR plugin *)
+]
+
+ssrbinder: [
+| REPLACE [ "of" | "&" ] term99 (* SSR plugin *)
+| WITH "of" term99 TAG SSR
+| "&" term99 TAG SSR
+]
+
+firstorder_rhs: [
+| DELETE OPT firstorder_using
+| DELETE "with" LIST1 preident
+| REPLACE OPT firstorder_using "with" LIST1 preident
+| WITH OPT firstorder_using OPT ( "with" LIST1 preident )
+]
+
+attribute: [
+| DELETE "using" OPT attr_value
]
SPLICE: [
@@ -2204,7 +2399,6 @@ SPLICE: [
| NUMBER
| STRING
| hyp
-| var
| identref
| pattern_ident
| constr_eval (* splices as multiple prods *)
@@ -2214,10 +2408,10 @@ SPLICE: [
| ltac_selector
| Constr.ident
| attribute_list
-| operconstr99
-| operconstr90
-| operconstr9
-| operconstr8
+| term99
+| term90
+| term9
+| term8
| pattern200
| pattern99
| pattern90
@@ -2230,18 +2424,16 @@ SPLICE: [
| bar_cbrace
| lconstr
-(*
+(* SSR *)
| ast_closure_term
| ast_closure_lterm
| ident_no_do
| ssrterm
| ssrtacarg
| ssrtac3arg
-| ssrtclarg
| ssrhyp
| ssrhoi_hyp
| ssrhoi_id
-| ssrindex
| ssrhpats
| ssrhpats_nobs
| ssrfwdid
@@ -2256,19 +2448,41 @@ SPLICE: [
| ssrcofixfwd
| ssrfixfwd
| ssrhavefwdwbinders
-| ssripats_ne
| ssrparentacarg
| ssrposefwd
-*)
-
+| ssrstruct
+| ssrrpat
+| ssrhint
+| ssrpattern_squarep
+| ssrhintref
+| ssr_search_item
+| ssr_modlocs
+| modloc
+| ssrexactarg
+| ssrclear
+| ssrmult
+| ssripats
+| ssrintros
+| ssrrule
+| ssrpattern_squarep
+| ssrcongrarg
+| ssrdotac
+| ssrunlockarg
+| ssr_search_arg
+| ssrortacarg
+| ssrsetfwd
+| ssr_idcomma
+| ssr_dthen
+| ssr_else
+| ssr_rtype
+| ssreqid
| preident
| lpar_id_coloneq
| binders
| casted_constr
| check_module_types
-| constr_pattern
| decl_sep
-| function_rec_definition_loc (* loses funind annotation *)
+| function_fix_definition (* loses funind annotation *)
| glob
| glob_constr_with_bindings
| id_or_meta
@@ -2286,7 +2500,6 @@ SPLICE: [
| decorated_vernac
| ext_module_expr
| ext_module_type
-| pattern_identref
| test
| binder_constr
| atomic_constr
@@ -2354,7 +2567,6 @@ SPLICE: [
| intropatterns
| instance_name
| failkw
-| selector
| ne_in_or_out_modules
| search_queries
| locatable
@@ -2377,95 +2589,79 @@ SPLICE: [
| refglobals (* Ltac2 *)
| syntax_modifiers
| array_elems
-| ltac2_expr
| G_LTAC2_input_fun
| ltac2_simple_intropattern_closed
| ltac2_with_bindings
+| int_or_id
+| fun_ind_using
+| with_names
+| eauto_search_strategy_name
+| constr_with_bindings
+| simple_binding
+| ssexpr35 (* strange in mlg, ssexpr50 is after this *)
+| number_string_mapping
+| number_options
+| string_option
+| tac2type_body
+| tac2rec_fields
+| mut_flag
+| tac2rec_fieldexprs
+| syn_level
+| firstorder_rhs
+| firstorder_using
] (* end SPLICE *)
RENAME: [
| tactic3 ltac_expr3 (* todo: can't figure out how this gets mapped by coqpp *)
| tactic1 ltac_expr1 (* todo: can't figure out how this gets mapped by coqpp *)
| tactic0 ltac_expr0 (* todo: can't figure out how this gets mapped by coqpp *)
-| ltac1_expr ltac_expr
-| tactic_expr5 ltac_expr
-| tactic_expr4 ltac_expr4
-| tactic_expr3 ltac_expr3
-| tactic_expr2 ltac_expr2
-| tactic_expr1 ltac_expr1
-| tactic_expr0 ltac_expr0
+| ltac_expr5 ltac_expr
(* | nonsimple_intropattern intropattern (* ltac2 *) *)
-| operconstr200 term (* historical name *)
-| operconstr100 term100
-| operconstr10 term10
-| operconstr1 term1
-| operconstr0 term0
+| term200 term
| pattern100 pattern
-| match_constr term_match
(*| impl_ident_tail impl_ident*)
-| ssexpr35 ssexpr (* strange in mlg, ssexpr50 is after this *)
-
-| tactic_then_gen for_each_goal
-| ltac2_tactic_then_gen ltac2_for_each_goal
-| selector_body selector
-| match_hyps match_hyp
+| ssexpr50 section_var_expr50
+| ssexpr0 section_var_expr0
+| section_subset_expr section_var_expr
+| fun_scheme_arg func_scheme_def
| BULLET bullet
-| fix_decl fix_body
-| cofix_decl cofix_body
-(* todo: it's confusing that Constr.constr and constr are different things *)
-| constr one_term
-| appl_arg arg
-| rec_definition fix_definition
-| corec_definition cofix_definition
-| univ_instance univ_annot
-| simple_assum_coe assumpt
-| of_type_with_opt_coercion of_type
-| attribute_value attr_value
-| constructor_list_or_record_decl constructors_or_record
-| record_binder_body field_body
-| class_rawexpr class
-| smart_global reference
+| constr one_term (* many, many, many *)
+| class_rawexpr class (* OCaml reserved word *)
+| smart_global reference (* many, many *)
(*
| searchabout_query search_item
*)
-| option_table setting_name
-| argument_spec_block arg_specs
-| more_implicits_block implicits_alt
-| arguments_modifier args_modifier
-| constr_as_binder_kind binder_interp
-| syntax_extension_type explicit_subentry
-| numnotoption numeral_modifier
-| tactic_arg_compat tactic_arg
-| lconstr_pattern cpattern
-| Pltac.tactic ltac_expr
-| sexpr ltac2_scope
-| tac2type5 ltac2_type
-| tac2type2 ltac2_type2
-| tac2type1 ltac2_type1
-| tac2type0 ltac2_type0
-| typ_param ltac2_typevar
-| tac2expr6 ltac2_expr
-| tac2expr5 ltac2_expr5
-| tac2expr3 ltac2_expr3
-| tac2expr2 ltac2_expr2
-| tac2expr1 ltac2_expr1
-| tac2expr0 ltac2_expr0
-| gmatch_list goal_match_list
+| Pltac.tactic ltac_expr (* many uses in EXTENDs *)
+| ltac2_type5 ltac2_type
+| ltac2_expr6 ltac2_expr
+| starredidentref starred_ident_ref
+| ssrocc ssr_occurrences
+| ssrsimpl_ne s_item
+| ssrclear_ne ssrclear
+| ssrmult_ne mult
+| ssripats_ne ssripats
+| ssrrule_ne r_item
+| ssrintros_ne ssrintros
+| ssrpattern_ne_squarep ssrpattern_squarep
+| ssrrwarg rewrite_item
+| ssrrwocc occ_or_clear
+| rpattern rewrite_pattern
+| ssripat i_item
+| ssrwgen gen_item
+| ssrfwd ssrdefbody
+| ssrclauses ssr_in
+| ssrcpat ssrblockpat
+| constr_pattern one_pattern
]
simple_tactic: [
-(* due to renaming of tactic_arg; Use LIST1 for function application *)
+(* due to renaming of tactic_value; Use LIST1 for function application *)
| qualid LIST1 tactic_arg
]
-(* todo: doesn't work if up above... maybe because 'clause' doesn't exist? *)
-clause_dft_concl: [
-| OPTINREF
-]
-
SPLICE: [
| gallina
| gallina_ext
@@ -2479,7 +2675,7 @@ SPLICE: [
| ltac_defined_tactics
| tactic_notation_tactics
]
-(* todo: ssrreflect*.rst ref to fix_body is incorrect *)
+(* todo: ssrreflect*.rst ref to fix_decl is incorrect *)
REACHABLE: [
| command
@@ -2518,17 +2714,7 @@ NOTINRSTS: [
| q_constr_matching
| q_goal_matching
-(* todo: figure these out
-(*Warning: editedGrammar: Undefined symbol 'ltac1_expr' *)
-| dangling_pattern_extension_rule
-| vernac_aux
-| subprf
-| tactic_mode
-| tac2expr_in_env (* no refs *)
-| tac2mode (* no refs *)
-| ltac_use_default (* from tac2mode *)
-| tacticals
-*)
+
]
REACHABLE: [
diff --git a/doc/tools/docgram/doc_grammar.ml b/doc/tools/docgram/doc_grammar.ml
index 177abe53fc..92a745c863 100644
--- a/doc/tools/docgram/doc_grammar.ml
+++ b/doc/tools/docgram/doc_grammar.ml
@@ -12,12 +12,14 @@ open Coqpp_parser
open Coqpp_ast
let exit_code = ref 0
+let error_count = ref 0
let show_warn = ref true
let fprintf = Printf.fprintf
let error s =
exit_code := 1;
+ incr error_count;
Printf.eprintf "Error: ";
Printf.eprintf s
@@ -309,6 +311,11 @@ let rec output_prodn = function
| "{|" -> "%{%|"
| "`{" -> "`%{"
| "@{" -> "@%{"
+ | "|-" -> "%|-"
+ | "|->" -> "%|->"
+ | "||" -> "%||"
+ | "|||" -> "%|||"
+ | "||||" -> "%||||"
| "{"
| "}"
| "|" -> "%" ^ s
@@ -354,10 +361,9 @@ and prod_to_prodn prod = String.concat " " (prod_to_prodn_r prod)
let get_tag file prod =
List.fold_left (fun rv sym ->
match sym with
- (* todo: temporarily limited to Ltac2 tags in prodn when not in ltac2.rst *)
- | Sedit2 ("TAG", s2)
- when (s2 = "Ltac2" || s2 = "not Ltac2") &&
- file <> "doc/sphinx/proof-engine/ltac2.rst" -> " " ^ s2
+ (* todo: only Ltac2 and SSR for now, outside of their main chapters *)
+ | Sedit2 ("TAG", "Ltac2") when file <> "doc/sphinx/proof-engine/ltac2.rst" -> " Ltac2"
+ | Sedit2 ("TAG", "SSR") when file <> "doc/sphinx/proof-engine/ssreflect-proof-language.rst" -> " SSR"
| _ -> rv
) "" prod
@@ -538,12 +544,11 @@ let autoloaded_mlgs = [ (* in the order they are loaded by Coq *)
"plugins/ltac/g_eqdecide.mlg";
"plugins/ltac/g_tactic.mlg";
"plugins/ltac/g_ltac.mlg";
- "plugins/syntax/g_string.mlg";
"plugins/btauto/g_btauto.mlg";
"plugins/rtauto/g_rtauto.mlg";
"plugins/cc/g_congruence.mlg";
"plugins/firstorder/g_ground.mlg";
- "plugins/syntax/g_numeral.mlg";
+ "plugins/syntax/g_number_string.mlg";
]
@@ -555,6 +560,10 @@ let level_regex = Str.regexp "[a-zA-Z0-9_]*$"
let get_plugin_name file =
if file = "user-contrib/Ltac2/g_ltac2.mlg" then
"Ltac2"
+ (* todo: would be better if g_search.mlg has an "ssr" prefix *)
+ else if List.mem file ["plugins/ssr/ssrparser.mlg"; "plugins/ssr/ssrvernac.mlg";
+ "plugins/ssrmatching/g_ssrmatching.mlg"; "plugins/ssrsearch/g_search.mlg"] then
+ "SSR"
else if Str.string_match plugin_regex file 0 then
Str.matched_group 1 file
else
@@ -564,12 +573,12 @@ let read_mlg g is_edit ast file level_renames symdef_map =
let res = ref [] in
let locals = ref StringSet.empty in
let dup_renames = ref StringMap.empty in
- let add_prods nt prods =
+ let add_prods nt prods gramext_globals =
if not is_edit then
- if NTMap.mem nt !g.map && nt <> "command" && nt <> "simple_tactic" then begin
+ if NTMap.mem nt !g.map && not (List.mem nt gramext_globals) && nt <> "command" && nt <> "simple_tactic" then begin
let new_name = String.uppercase_ascii (Filename.remove_extension (Filename.basename file)) ^ "_" ^ nt in
dup_renames := StringMap.add nt new_name !dup_renames;
- Printf.printf "** dup sym %s -> %s in %s\n" nt new_name file
+ if false then Printf.printf "** dup local sym %s -> %s in %s\n" nt new_name file
end;
add_symdef nt file symdef_map;
let plugin = get_plugin_name file in
@@ -590,11 +599,12 @@ let read_mlg g is_edit ast file level_renames symdef_map =
| Some s -> s
| None -> ""
in
+ let gramext_globals = ref grammar_ext.gramext_globals in
List.iter (fun ent ->
let len = List.length ent.gentry_rules in
List.iteri (fun i rule ->
let nt = ent.gentry_name in
- if not (List.mem nt grammar_ext.gramext_globals) then
+ if not (List.mem nt !gramext_globals) then
locals := StringSet.add nt !locals;
let level = (get_label rule.grule_label) in
let level = if level <> "" then level else
@@ -625,8 +635,11 @@ let read_mlg g is_edit ast file level_renames symdef_map =
if cur_level <> nt && i+1 < len then
edited @ [[Snterm next_level]]
else
- edited in
- add_prods cur_level prods_to_add)
+ edited
+ in
+ if cur_level <> nt && List.mem nt !gramext_globals then
+ gramext_globals := cur_level :: !gramext_globals;
+ add_prods cur_level prods_to_add !gramext_globals)
ent.gentry_rules
) grammar_ext.gramext_entries
@@ -636,16 +649,16 @@ let read_mlg g is_edit ast file level_renames symdef_map =
| Some c -> String.trim c.code
in
add_prods node
- (List.map (fun r -> cvt_ext r.vernac_toks) vernac_ext.vernacext_rules)
+ (List.map (fun r -> cvt_ext r.vernac_toks) vernac_ext.vernacext_rules) []
| VernacArgumentExt vernac_argument_ext ->
add_prods vernac_argument_ext.vernacargext_name
- (List.map (fun r -> cvt_ext r.tac_toks) vernac_argument_ext.vernacargext_rules)
+ (List.map (fun r -> cvt_ext r.tac_toks) vernac_argument_ext.vernacargext_rules) []
| TacticExt tactic_ext ->
add_prods "simple_tactic"
- (List.map (fun r -> cvt_ext r.tac_toks) tactic_ext.tacext_rules)
+ (List.map (fun r -> cvt_ext r.tac_toks) tactic_ext.tacext_rules) []
| ArgumentExt argument_ext ->
add_prods argument_ext.argext_name
- (List.map (fun r -> cvt_ext r.tac_toks) argument_ext.argext_rules)
+ (List.map (fun r -> cvt_ext r.tac_toks) argument_ext.argext_rules) []
| _ -> ()
in
@@ -1191,6 +1204,15 @@ let edit_all_prods g op eprods =
| "DELETE" -> do_it op eprods 1; true
| "SPLICE" -> do_it op eprods 1; true
| "MERGE" -> do_it op eprods 2; true
+ | "OPTINREF" ->
+ List.iter (fun nt ->
+ let prods = NTMap.find nt !g.map in
+ if has_match [] prods then begin
+ let prods' = remove_prod [] prods nt in
+ g_update_prods g nt prods';
+ global_repl g [(Snterm nt)] [(Sopt (Snterm nt))]
+ end)
+ !g.order; true
| "EXPAND" ->
if List.length eprods > 1 || List.length (List.hd eprods) <> 0 then
error "'EXPAND:' expects a single empty production\n";
@@ -1727,6 +1749,7 @@ let open_temp_bin file =
let match_cmd_regex = Str.regexp "[a-zA-Z0-9_ ]+"
let match_subscripts = Str.regexp "__[a-zA-Z0-9]+"
+let remove_subscrs str = Str.global_replace match_subscripts "" str
let find_longest_match prods str =
let get_pfx str = String.trim (if Str.string_match match_cmd_regex str 0 then Str.matched_string str else "") in
@@ -1740,7 +1763,6 @@ let find_longest_match prods str =
in
aux 0
in
- let remove_subscrs str = Str.global_replace match_subscripts "" str in
let slen = String.length str in
let str_pfx = get_pfx str in
@@ -1895,25 +1917,18 @@ let process_rst g file args seen tac_prods cmd_prods =
(* "doc/sphinx/proof-engine/ssreflect-proof-language.rst"]*)
(* in*)
- let cmd_replace_files = [
- "doc/sphinx/language/core/records.rst";
- "doc/sphinx/language/core/sections.rst";
- "doc/sphinx/language/extensions/implicit-arguments.rst";
- "doc/sphinx/language/extensions/arguments-command.rst";
- "doc/sphinx/language/gallina-extensions.rst";
- "doc/sphinx/language/gallina-specification-language.rst";
- "doc/sphinx/language/using/libraries/funind.rst";
- "doc/sphinx/proof-engine/ltac.rst";
- "doc/sphinx/proof-engine/ltac2.rst";
- "doc/sphinx/proof-engine/vernacular-commands.rst";
- "doc/sphinx/user-extensions/syntax-extensions.rst";
- "doc/sphinx/proof-engine/vernacular-commands.rst"
+ let cmd_exclude_files = [
+ "doc/sphinx/proof-engine/ssreflect-proof-language.rst";
+ "doc/sphinx/proofs/automatic-tactics/auto.rst";
+ "doc/sphinx/proofs/writing-proofs/rewriting.rst";
+ "doc/sphinx/proofs/writing-proofs/proof-mode.rst";
+ "doc/sphinx/proof-engine/tactics.rst";
]
in
let save_n_get_more direc pfx first_rhs seen_map prods =
let replace rhs prods =
- if StringSet.is_empty prods || not (List.mem file cmd_replace_files) then
+ if StringSet.is_empty prods || (List.mem file cmd_exclude_files) then
rhs (* no change *)
else
let mtch, multi, best = find_longest_match prods rhs in
@@ -1921,12 +1936,15 @@ let process_rst g file args seen tac_prods cmd_prods =
if mtch = rhs then
rhs (* no change *)
else if mtch = "" then begin
- warn "%s line %d: NO MATCH `%s`\n" file !linenum rhs;
- if best <> "" then
- warn "%s line %d: BEST `%s`\n" file !linenum best;
+ error "%s line %d: NO MATCH for `%s`\n" file !linenum rhs;
+ if best <> "" then begin
+ Printf.eprintf " closest match is: `%s`\n" best;
+ Printf.eprintf " Please update the rst manually while preserving any subscripts, e.g. 'NT__sub'\n"
+ end;
rhs
end else if multi then begin
- warn "%s line %d: MULTIMATCH `%s`\n" file !linenum rhs;
+ error "%s line %d: MULTIPLE MATCHES for `%s`\n" file !linenum rhs;
+ Printf.eprintf " Please update the rst manually while preserving any subscripts, e.g. 'NT__sub'\n";
rhs
end else
mtch (* update cmd/tacn *)
@@ -1939,7 +1957,7 @@ let process_rst g file args seen tac_prods cmd_prods =
fprintf new_rst "%s%s\n" pfx (replace first_rhs prods);
- map := NTMap.add first_rhs (file, !linenum) !map;
+ map := NTMap.add (remove_subscrs first_rhs) (file, !linenum) !map;
while
let nextline = getline() in
ignore (Str.string_match contin_regex nextline 0);
@@ -2015,10 +2033,11 @@ let report_omitted_prods g seen label split =
(if first = "" then nt else first), nt, n + 1, total + 1)
("", "", 0, 0) !g.order in
maybe_warn first last n;
-(* List.iter (fun nt ->
- if not (NTMap.mem nt seen || (List.mem nt included)) then
- warn "%s %s not included in .rst files\n" "Nonterminal" nt)
- !g.order;*)
+ Printf.printf "\n\n";
+ NTMap.iter (fun nt _ ->
+ if not (NTMap.mem nt seen || (List.mem nt included)) then
+ warn "%s %s not included in .rst files\n" "Nonterminal" nt)
+ !g.map;
if total <> 0 then
Printf.eprintf "TOTAL %ss not included = %d\n" label total
@@ -2081,13 +2100,11 @@ let process_grammar args =
print_in_order out g `MLG !g.order StringSet.empty;
close_out out;
finish_with_file (dir "orderedGrammar") args;
- check_singletons g
+(* check_singletons g*)
(* print_dominated g*)
- end;
- let seen = ref { nts=NTMap.empty; tacs=NTMap.empty; tacvs=NTMap.empty; cmds=NTMap.empty; cmdvs=NTMap.empty } in
- let args = { args with no_update = false } in (* always update rsts in place for now *)
- if !exit_code = 0 then begin
+ let seen = ref { nts=NTMap.empty; tacs=NTMap.empty; tacvs=NTMap.empty; cmds=NTMap.empty; cmdvs=NTMap.empty } in
+ let args = { args with no_update = false } in (* always update rsts in place for now *)
let plist nt =
let list = (List.map (fun t -> String.trim (prod_to_prodn t))
(NTMap.find nt !g.map)) in
@@ -2098,7 +2115,6 @@ let process_grammar args =
report_omitted_prods g !seen.nts "Nonterminal" "";
let out = open_out (dir "updated_rsts") in
close_out out;
- end;
(*
if args.check_tacs then
@@ -2107,7 +2123,6 @@ let process_grammar args =
report_omitted_prods cmd_list !seen.cmds "Command" "\n ";
*)
- if !exit_code = 0 then begin
(* generate report on cmds or tacs *)
let cmdReport outfile cmdStr cmd_nts cmds cmdvs =
let rstCmds = StringSet.of_list (List.map (fun b -> let c, _ = b in c) (NTMap.bindings cmds)) in
@@ -2116,7 +2131,7 @@ let process_grammar args =
StringSet.union set (StringSet.of_list (List.map (fun p -> String.trim (prod_to_prodn p)) (NTMap.find nt !prodn_gram.map)))
) StringSet.empty cmd_nts in
let allCmds = StringSet.union rstCmdvs (StringSet.union rstCmds gramCmds) in
- let out = open_temp_bin (dir outfile) in
+ let out = open_out_bin (dir outfile) in
StringSet.iter (fun c ->
let rsts = StringSet.mem c rstCmds in
let gram = StringSet.mem c gramCmds in
@@ -2130,7 +2145,6 @@ let process_grammar args =
fprintf out "%s%s %s\n" pfx var c)
allCmds;
close_out out;
- finish_with_file (dir outfile) args;
Printf.printf "# %s in rsts, gram, total = %d %d %d\n" cmdStr (StringSet.cardinal gramCmds)
(StringSet.cardinal rstCmds) (StringSet.cardinal allCmds);
in
@@ -2142,17 +2156,16 @@ let process_grammar args =
let tac_nts = ["simple_tactic"] in
if args.check_tacs then
- cmdReport "prodnTactics" "tacs" tac_nts !seen.tacs !seen.tacvs
- end;
+ cmdReport "prodnTactics" "tacs" tac_nts !seen.tacs !seen.tacvs;
- (* generate prodnGrammar for reference *)
- if !exit_code = 0 && not args.verify then begin
- let out = open_temp_bin (dir "prodnGrammar") in
- print_in_order out prodn_gram `PRODN !prodn_gram.order StringSet.empty;
- close_out out;
- finish_with_file (dir "prodnGrammar") args
- end
- end
+ (* generate prodnGrammar for reference *)
+ if not args.verify then begin
+ let out = open_out_bin (dir "prodnGrammar") in
+ print_in_order out prodn_gram `PRODN !prodn_gram.order StringSet.empty;
+ close_out out;
+ end
+ end (* if !exit_code = 0 *)
+ end (* if not args.fullGrammar *)
let parse_args () =
let suffix_regex = Str.regexp ".*\\.\\([a-z]+\\)$" in
@@ -2182,5 +2195,7 @@ let () =
if !exit_code = 0 then begin
process_grammar args
end;
+ if !error_count > 0 then
+ Printf.eprintf "%d error(s)\n" !error_count;
exit !exit_code
(*with _ -> Printexc.print_backtrace stdout; exit 1*)
diff --git a/doc/tools/docgram/dune b/doc/tools/docgram/dune
index 2a7b283f55..1c07d00d4f 100644
--- a/doc/tools/docgram/dune
+++ b/doc/tools/docgram/dune
@@ -12,7 +12,6 @@
(glob_files %{project_root}/parsing/*.mlg)
(glob_files %{project_root}/toplevel/*.mlg)
(glob_files %{project_root}/vernac/*.mlg)
- ; All plugins except SSReflect for now (mimicking what is done in Makefile.doc)
(glob_files %{project_root}/plugins/btauto/*.mlg)
(glob_files %{project_root}/plugins/cc/*.mlg)
(glob_files %{project_root}/plugins/derive/*.mlg)
@@ -23,8 +22,11 @@
(glob_files %{project_root}/plugins/micromega/*.mlg)
(glob_files %{project_root}/plugins/nsatz/*.mlg)
(glob_files %{project_root}/plugins/omega/*.mlg)
- (glob_files %{project_root}/plugins/rtauto/*.mlg)
(glob_files %{project_root}/plugins/ring/*.mlg)
+ (glob_files %{project_root}/plugins/rtauto/*.mlg)
+ (glob_files %{project_root}/plugins/ssr/*.mlg)
+ (glob_files %{project_root}/plugins/ssrmatching/*.mlg)
+ (glob_files %{project_root}/plugins/ssrsearch/*.mlg)
(glob_files %{project_root}/plugins/syntax/*.mlg)
(glob_files %{project_root}/user-contrib/Ltac2/*.mlg)
; Sphinx files
diff --git a/doc/tools/docgram/fullGrammar b/doc/tools/docgram/fullGrammar
index 73641976e3..033ece04de 100644
--- a/doc/tools/docgram/fullGrammar
+++ b/doc/tools/docgram/fullGrammar
@@ -17,7 +17,7 @@ constr_pattern: [
| constr
]
-lconstr_pattern: [
+cpattern: [
| lconstr
]
@@ -58,67 +58,68 @@ universe: [
]
lconstr: [
-| operconstr200
+| term200
]
constr: [
-| operconstr8
-| "@" global univ_instance
+| term8
+| "@" global univ_annot
]
-operconstr200: [
+term200: [
| binder_constr
-| operconstr100
+| term100
]
-operconstr100: [
-| operconstr99 "<:" operconstr200
-| operconstr99 "<<:" operconstr200
-| operconstr99 ":" operconstr200
-| operconstr99 ":>"
-| operconstr99
+term100: [
+| term99 "<:" term200
+| term99 "<<:" term200
+| term99 ":" term200
+| term99 ":>"
+| term99
]
-operconstr99: [
-| operconstr90
+term99: [
+| term90
]
-operconstr90: [
-| operconstr10
+term90: [
+| term10
]
-operconstr10: [
-| operconstr9 LIST1 appl_arg
-| "@" global univ_instance LIST0 operconstr9
-| "@" pattern_identref LIST1 identref
-| operconstr9
+term10: [
+| term9 LIST1 arg
+| "@" global univ_annot LIST0 term9
+| "@" pattern_ident LIST1 identref
+| term9
]
-operconstr9: [
-| ".." operconstr0 ".."
-| operconstr8
+term9: [
+| ".." term0 ".."
+| term8
]
-operconstr8: [
-| operconstr1
+term8: [
+| term1
]
-operconstr1: [
-| operconstr0 ".(" global LIST0 appl_arg ")"
-| operconstr0 ".(" "@" global LIST0 ( operconstr9 ) ")"
-| operconstr0 "%" IDENT
-| operconstr0
+term1: [
+| term0 ".(" global LIST0 arg ")"
+| term0 ".(" "@" global LIST0 ( term9 ) ")"
+| term0 "%" IDENT
+| term0
]
-operconstr0: [
+term0: [
| atomic_constr
-| match_constr
-| "(" operconstr200 ")"
+| term_match
+| "(" term200 ")"
| "{|" record_declaration bar_cbrace
| "{" binder_constr "}"
-| "`{" operconstr200 "}"
-| test_array_opening "[" "|" array_elems "|" lconstr type_cstr test_array_closing "|" "]" univ_instance
-| "`(" operconstr200 ")"
+| "`{" term200 "}"
+| test_array_opening "[" "|" array_elems "|" lconstr type_cstr test_array_closing "|" "]" univ_annot
+| "`(" term200 ")"
+| "ltac" ":" "(" Pltac.ltac_expr ")"
]
array_elems: [
@@ -140,38 +141,43 @@ field_def: [
]
binder_constr: [
-| "forall" open_binders "," operconstr200
-| "fun" open_binders "=>" operconstr200
-| "let" name binders let_type_cstr ":=" operconstr200 "in" operconstr200
-| "let" "fix" fix_decl "in" operconstr200
-| "let" "cofix" cofix_decl "in" operconstr200
-| "let" [ "(" LIST0 name SEP "," ")" | "()" ] return_type ":=" operconstr200 "in" operconstr200
-| "let" "'" pattern200 ":=" operconstr200 "in" operconstr200
-| "let" "'" pattern200 ":=" operconstr200 case_type "in" operconstr200
-| "let" "'" pattern200 "in" pattern200 ":=" operconstr200 case_type "in" operconstr200
-| "if" operconstr200 return_type "then" operconstr200 "else" operconstr200
+| "forall" open_binders "," term200
+| "fun" open_binders "=>" term200
+| "let" name binders let_type_cstr ":=" term200 "in" term200
+| "let" "fix" fix_decl "in" term200
+| "let" "cofix" cofix_body "in" term200
+| "let" [ "(" LIST0 name SEP "," ")" | "()" ] as_return_type ":=" term200 "in" term200
+| "let" "'" pattern200 ":=" term200 "in" term200
+| "let" "'" pattern200 ":=" term200 case_type "in" term200
+| "let" "'" pattern200 "in" pattern200 ":=" term200 case_type "in" term200
+| "if" term200 as_return_type "then" term200 "else" term200
| "fix" fix_decls
| "cofix" cofix_decls
+| "if" term200 "is" ssr_dthen ssr_else (* SSR plugin *)
+| "if" term200 "isn't" ssr_dthen ssr_else (* SSR plugin *)
+| "let" ":" ssr_mpat ":=" lconstr "in" lconstr (* SSR plugin *)
+| "let" ":" ssr_mpat ":=" lconstr ssr_rtype "in" lconstr (* SSR plugin *)
+| "let" ":" ssr_mpat "in" pattern200 ":=" lconstr ssr_rtype "in" lconstr (* SSR plugin *)
]
-appl_arg: [
-| test_lpar_id_coloneq "(" ident ":=" lconstr ")"
-| operconstr9
+arg: [
+| test_lpar_id_coloneq "(" identref ":=" lconstr ")"
+| term9
]
atomic_constr: [
-| global univ_instance
+| global univ_annot
| sort
| NUMBER
| string
| "_"
-| "?" "[" ident "]"
+| "?" "[" identref "]"
| "?" "[" pattern_ident "]"
| pattern_ident evar_instance
]
inst: [
-| ident ":=" lconstr
+| identref ":=" lconstr
]
evar_instance: [
@@ -179,7 +185,7 @@ evar_instance: [
|
]
-univ_instance: [
+univ_annot: [
| "@{" LIST0 universe_level "}"
|
]
@@ -198,31 +204,31 @@ fix_decls: [
]
cofix_decls: [
-| cofix_decl
-| cofix_decl "with" LIST1 cofix_decl SEP "with" "for" identref
+| cofix_body
+| cofix_body "with" LIST1 cofix_body SEP "with" "for" identref
]
fix_decl: [
-| identref binders_fixannot type_cstr ":=" operconstr200
+| identref binders_fixannot type_cstr ":=" term200
]
-cofix_decl: [
-| identref binders type_cstr ":=" operconstr200
+cofix_body: [
+| identref binders type_cstr ":=" term200
]
-match_constr: [
+term_match: [
| "match" LIST1 case_item SEP "," OPT case_type "with" branches "end"
]
case_item: [
-| operconstr100 OPT [ "as" name ] OPT [ "in" pattern200 ]
+| term100 OPT [ "as" name ] OPT [ "in" pattern200 ]
]
case_type: [
-| "return" operconstr100
+| "return" term100
]
-return_type: [
+as_return_type: [
| OPT [ OPT [ "as" name ] case_type ]
]
@@ -253,7 +259,7 @@ pattern200: [
]
pattern100: [
-| pattern99 ":" operconstr200
+| pattern99 ":" term200
| pattern99
]
@@ -308,6 +314,7 @@ open_binders: [
binders: [
| LIST0 binder
+| Pcoq.Constr.binders
]
binder: [
@@ -332,13 +339,14 @@ closed_binder: [
| "`{" LIST1 typeclass_constraint SEP "," "}"
| "`[" LIST1 typeclass_constraint SEP "," "]"
| "'" pattern0
+| [ "of" | "&" ] term99 (* SSR plugin *)
]
typeclass_constraint: [
-| "!" operconstr200
-| "{" name "}" ":" [ "!" | ] operconstr200
-| test_name_colon name ":" [ "!" | ] operconstr200
-| operconstr200
+| "!" term200
+| "{" name "}" ":" [ "!" | ] term200
+| test_name_colon name ":" [ "!" | ] term200
+| term200
]
type_cstr: [
@@ -362,16 +370,12 @@ pattern_ident: [
| LEFTQMARK ident
]
-pattern_identref: [
-| pattern_ident
-]
-
-var: [
+identref: [
| ident
]
-identref: [
-| ident
+hyp: [
+| identref
]
field: [
@@ -510,7 +514,7 @@ command: [
| "Remove" "Hints" LIST1 global opt_hintbases
| "Hint" hint opt_hintbases
| "Comments" LIST0 comment
-| "Declare" "Instance" ident_decl binders ":" operconstr200 hint_info
+| "Declare" "Instance" ident_decl binders ":" term200 hint_info
| "Declare" "Scope" IDENT
| "Pwd"
| "Cd"
@@ -529,13 +533,13 @@ command: [
| "Print" "Namespace" dirpath
| "Inspect" natural
| "Add" "ML" "Path" ne_string
-| "Set" option_table option_setting
-| "Unset" option_table
-| "Print" "Table" option_table
+| "Set" setting_name option_setting
+| "Unset" setting_name
+| "Print" "Table" setting_name
| "Add" IDENT IDENT LIST1 table_value
| "Add" IDENT LIST1 table_value
-| "Test" option_table "for" LIST1 table_value
-| "Test" option_table
+| "Test" setting_name "for" LIST1 table_value
+| "Test" setting_name
| "Remove" IDENT IDENT LIST1 table_value
| "Remove" IDENT LIST1 table_value
| "Write" "State" IDENT
@@ -573,7 +577,7 @@ command: [
| "Show" "Extraction" (* extraction plugin *)
| "Set" "Firstorder" "Solver" tactic
| "Print" "Firstorder" "Solver"
-| "Function" LIST1 function_rec_definition_loc SEP "with" (* funind plugin *)
+| "Function" LIST1 function_fix_definition SEP "with" (* funind plugin *)
| "Functional" "Scheme" LIST1 fun_scheme_arg SEP "with" (* funind plugin *)
| "Functional" "Case" fun_scheme_arg (* funind plugin *)
| "Generate" "graph" "for" reference (* funind plugin *)
@@ -596,9 +600,9 @@ command: [
| "Optimize" "Proof"
| "Optimize" "Heap"
| "Hint" "Cut" "[" hints_path "]" opthints
-| "Typeclasses" "Transparent" LIST0 reference
-| "Typeclasses" "Opaque" LIST0 reference
-| "Typeclasses" "eauto" ":=" debug eauto_search_strategy OPT integer
+| "Typeclasses" "Transparent" LIST1 reference
+| "Typeclasses" "Opaque" LIST1 reference
+| "Typeclasses" "eauto" ":=" debug eauto_search_strategy OPT natural
| "Proof" "with" Pltac.tactic OPT [ "using" G_vernac.section_subset_expr ]
| "Proof" "using" G_vernac.section_subset_expr OPT [ "with" Pltac.tactic ]
| "Tactic" "Notation" OPT ltac_tactic_level LIST1 ltac_production_item ":=" tactic
@@ -615,6 +619,7 @@ command: [
| "Solve" "Obligation" natural "of" ident "with" tactic
| "Solve" "Obligation" natural "with" tactic
| "Solve" "Obligations" "of" ident "with" tactic
+| "Solve" "Obligations" "of" ident
| "Solve" "Obligations" "with" tactic
| "Solve" "Obligations"
| "Solve" "All" "Obligations" "with" tactic
@@ -635,20 +640,20 @@ command: [
| "Add" "Relation" constr constr "reflexivity" "proved" "by" constr "transitivity" "proved" "by" constr "as" ident
| "Add" "Relation" constr constr "reflexivity" "proved" "by" constr "symmetry" "proved" "by" constr "transitivity" "proved" "by" constr "as" ident
| "Add" "Relation" constr constr "transitivity" "proved" "by" constr "as" ident
-| "Add" "Parametric" "Relation" G_REWRITE_binders ":" constr constr "reflexivity" "proved" "by" constr "symmetry" "proved" "by" constr "as" ident
-| "Add" "Parametric" "Relation" G_REWRITE_binders ":" constr constr "reflexivity" "proved" "by" constr "as" ident
-| "Add" "Parametric" "Relation" G_REWRITE_binders ":" constr constr "as" ident
-| "Add" "Parametric" "Relation" G_REWRITE_binders ":" constr constr "symmetry" "proved" "by" constr "as" ident
-| "Add" "Parametric" "Relation" G_REWRITE_binders ":" constr constr "symmetry" "proved" "by" constr "transitivity" "proved" "by" constr "as" ident
-| "Add" "Parametric" "Relation" G_REWRITE_binders ":" constr constr "reflexivity" "proved" "by" constr "transitivity" "proved" "by" constr "as" ident
-| "Add" "Parametric" "Relation" G_REWRITE_binders ":" constr constr "reflexivity" "proved" "by" constr "symmetry" "proved" "by" constr "transitivity" "proved" "by" constr "as" ident
-| "Add" "Parametric" "Relation" G_REWRITE_binders ":" constr constr "transitivity" "proved" "by" constr "as" ident
+| "Add" "Parametric" "Relation" binders ":" constr constr "reflexivity" "proved" "by" constr "symmetry" "proved" "by" constr "as" ident
+| "Add" "Parametric" "Relation" binders ":" constr constr "reflexivity" "proved" "by" constr "as" ident
+| "Add" "Parametric" "Relation" binders ":" constr constr "as" ident
+| "Add" "Parametric" "Relation" binders ":" constr constr "symmetry" "proved" "by" constr "as" ident
+| "Add" "Parametric" "Relation" binders ":" constr constr "symmetry" "proved" "by" constr "transitivity" "proved" "by" constr "as" ident
+| "Add" "Parametric" "Relation" binders ":" constr constr "reflexivity" "proved" "by" constr "transitivity" "proved" "by" constr "as" ident
+| "Add" "Parametric" "Relation" binders ":" constr constr "reflexivity" "proved" "by" constr "symmetry" "proved" "by" constr "transitivity" "proved" "by" constr "as" ident
+| "Add" "Parametric" "Relation" binders ":" constr constr "transitivity" "proved" "by" constr "as" ident
| "Add" "Setoid" constr constr constr "as" ident
-| "Add" "Parametric" "Setoid" G_REWRITE_binders ":" constr constr constr "as" ident
+| "Add" "Parametric" "Setoid" binders ":" constr constr constr "as" ident
| "Add" "Morphism" constr ":" ident
| "Declare" "Morphism" constr ":" ident
| "Add" "Morphism" constr "with" "signature" lconstr "as" ident
-| "Add" "Parametric" "Morphism" G_REWRITE_binders ":" constr "with" "signature" lconstr "as" ident
+| "Add" "Parametric" "Morphism" binders ":" constr "with" "signature" lconstr "as" ident
| "Print" "Rewrite" "HintDb" preident
| "Reset" "Ltac" "Profile"
| "Show" "Ltac" "Profile"
@@ -689,11 +694,15 @@ command: [
| "Print" "Rings" (* ring plugin *)
| "Add" "Field" ident ":" constr OPT field_mods (* ring plugin *)
| "Print" "Fields" (* ring plugin *)
-| "Number" "Notation" reference reference reference ":" ident numnotoption
-| "Numeral" "Notation" reference reference reference ":" ident numnotoption
-| "String" "Notation" reference reference reference ":" ident
+| "Prenex" "Implicits" LIST1 global (* SSR plugin *)
+| "Print" "Hint" "View" ssrviewpos (* SSR plugin *)
+| "Hint" "View" ssrviewposspc LIST1 ssrhintref (* SSR plugin *)
+| "Search" ssr_search_arg ssr_modlocs (* SSR plugin *)
+| "Number" "Notation" reference reference reference OPT number_options ":" ident
+| "Numeral" "Notation" reference reference reference ":" ident deprecated_number_modifier
+| "String" "Notation" reference reference reference OPT string_option ":" ident
| "Ltac2" ltac2_entry (* Ltac2 plugin *)
-| "Ltac2" "Eval" ltac2_expr (* Ltac2 plugin *)
+| "Ltac2" "Eval" ltac2_expr6 (* Ltac2 plugin *)
| "Print" "Ltac2" reference (* Ltac2 plugin *)
]
@@ -716,6 +725,7 @@ hint: [
| "Mode" global mode
| "Unfold" LIST1 global
| "Constructors" LIST1 global
+| "Extern" natural OPT Constr.constr_pattern "=>" Pltac.tactic
]
constr_body: [
@@ -748,10 +758,11 @@ attribute_list: [
]
attribute: [
-| ident attribute_value
+| ident attr_value
+| "using" attr_value
]
-attribute_value: [
+attr_value: [
| "=" string
| "(" attribute_list ")"
|
@@ -798,10 +809,10 @@ gallina: [
| def_token ident_decl def_body
| "Let" ident_decl def_body
| finite_token LIST1 inductive_definition SEP "with"
-| "Fixpoint" LIST1 rec_definition SEP "with"
-| "Let" "Fixpoint" LIST1 rec_definition SEP "with"
-| "CoFixpoint" LIST1 corec_definition SEP "with"
-| "Let" "CoFixpoint" LIST1 corec_definition SEP "with"
+| "Fixpoint" LIST1 fix_definition SEP "with"
+| "Let" "Fixpoint" LIST1 fix_definition SEP "with"
+| "CoFixpoint" LIST1 cofix_definition SEP "with"
+| "Let" "CoFixpoint" LIST1 cofix_definition SEP "with"
| "Scheme" LIST1 scheme SEP "with"
| "Combined" "Scheme" identref "from" LIST1 identref SEP ","
| "Register" global "as" qualid
@@ -900,7 +911,7 @@ decl_notations: [
]
opt_constructors_or_fields: [
-| ":=" constructor_list_or_record_decl
+| ":=" constructors_or_record
|
]
@@ -908,7 +919,7 @@ inductive_definition: [
| opt_coercion ident_decl binders OPT [ "|" binders ] OPT [ ":" lconstr ] opt_constructors_or_fields decl_notations
]
-constructor_list_or_record_decl: [
+constructors_or_record: [
| "|" LIST1 constructor SEP "|"
| identref constructor_type "|" LIST1 constructor SEP "|"
| identref constructor_type
@@ -922,11 +933,11 @@ opt_coercion: [
|
]
-rec_definition: [
+fix_definition: [
| ident_decl binders_fixannot type_cstr OPT [ ":=" lconstr ] decl_notations
]
-corec_definition: [
+cofix_definition: [
| ident_decl binders type_cstr OPT [ ":=" lconstr ] decl_notations
]
@@ -953,39 +964,39 @@ record_fields: [
|
]
-record_binder_body: [
-| binders of_type_with_opt_coercion lconstr
-| binders of_type_with_opt_coercion lconstr ":=" lconstr
+field_body: [
+| binders of_type lconstr
+| binders of_type lconstr ":=" lconstr
| binders ":=" lconstr
]
record_binder: [
| name
-| name record_binder_body
+| name field_body
]
assum_list: [
| LIST1 assum_coe
-| simple_assum_coe
+| assumpt
]
assum_coe: [
-| "(" simple_assum_coe ")"
+| "(" assumpt ")"
]
-simple_assum_coe: [
-| LIST1 ident_decl of_type_with_opt_coercion lconstr
+assumpt: [
+| LIST1 ident_decl of_type lconstr
]
constructor_type: [
-| binders [ of_type_with_opt_coercion lconstr | ]
+| binders [ of_type lconstr | ]
]
constructor: [
| identref constructor_type
]
-of_type_with_opt_coercion: [
+of_type: [
| ":>"
| ":" ">"
| ":"
@@ -1014,16 +1025,17 @@ gallina_ext: [
| "Coercion" global ":" class_rawexpr ">->" class_rawexpr
| "Coercion" by_notation ":" class_rawexpr ">->" class_rawexpr
| "Context" LIST1 binder
-| "Instance" instance_name ":" operconstr200 hint_info [ ":=" "{" record_declaration "}" | ":=" lconstr | ]
+| "Instance" instance_name ":" term200 hint_info [ ":=" "{" record_declaration "}" | ":=" lconstr | ]
| "Existing" "Instance" global hint_info
| "Existing" "Instances" LIST1 global OPT [ "|" natural ]
| "Existing" "Class" global
-| "Arguments" smart_global LIST0 argument_spec_block OPT [ "," LIST1 [ LIST0 more_implicits_block ] SEP "," ] OPT [ ":" LIST1 arguments_modifier SEP "," ]
+| "Arguments" smart_global LIST0 arg_specs OPT [ "," LIST1 [ LIST0 implicits_alt ] SEP "," ] OPT [ ":" LIST1 args_modifier SEP "," ]
| "Implicit" "Type" reserv_list
| "Implicit" "Types" reserv_list
| "Generalizable" [ "All" "Variables" | "No" "Variables" | [ "Variable" | "Variables" ] LIST1 identref ]
-| "Export" "Set" option_table option_setting
-| "Export" "Unset" option_table
+| "Export" "Set" setting_name option_setting
+| "Export" "Unset" setting_name
+| "Import" "Prenex" "Implicits" (* SSR plugin *)
]
filtered_import: [
@@ -1145,7 +1157,7 @@ ssexpr0: [
| "(" ssexpr35 ")" "*"
]
-arguments_modifier: [
+args_modifier: [
| "simpl" "nomatch"
| "simpl" "never"
| "default" "implicits"
@@ -1167,7 +1179,7 @@ argument_spec: [
| OPT "!" name OPT scope_delimiter
]
-argument_spec_block: [
+arg_specs: [
| argument_spec
| "/"
| "&"
@@ -1176,7 +1188,7 @@ argument_spec_block: [
| "{" LIST1 argument_spec "}" OPT scope_delimiter
]
-more_implicits_block: [
+implicits_alt: [
| name
| "[" LIST1 name "]"
| "{" LIST1 name "}"
@@ -1285,7 +1297,7 @@ table_value: [
| STRING
]
-option_table: [
+setting_name: [
| LIST1 IDENT
]
@@ -1394,9 +1406,9 @@ syntax_modifier: [
| "only" "parsing"
| "format" STRING OPT STRING
| IDENT; "," LIST1 IDENT SEP "," "at" level
-| IDENT; "at" level OPT constr_as_binder_kind
-| IDENT constr_as_binder_kind
-| IDENT syntax_extension_type
+| IDENT; "at" level OPT binder_interp
+| IDENT binder_interp
+| IDENT explicit_subentry
]
syntax_modifiers: [
@@ -1404,19 +1416,19 @@ syntax_modifiers: [
|
]
-syntax_extension_type: [
+explicit_subentry: [
| "ident"
| "global"
| "bigint"
| "binder"
| "constr"
-| "constr" at_level_opt OPT constr_as_binder_kind
+| "constr" at_level_opt OPT binder_interp
| "pattern"
| "pattern" "at" "level" natural
| "strict" "pattern"
| "strict" "pattern" "at" "level" natural
| "closed" "binder"
-| "custom" IDENT at_level_opt OPT constr_as_binder_kind
+| "custom" IDENT at_level_opt OPT binder_interp
]
at_level_opt: [
@@ -1424,7 +1436,7 @@ at_level_opt: [
|
]
-constr_as_binder_kind: [
+binder_interp: [
| "as" "ident"
| "as" "pattern"
| "as" "strict" "pattern"
@@ -1551,7 +1563,7 @@ simple_tactic: [
| "notypeclasses" "refine" uconstr
| "simple" "notypeclasses" "refine" uconstr
| "solve_constraints"
-| "subst" LIST1 var
+| "subst" LIST1 hyp
| "subst"
| "simple" "subst"
| "evar" test_lpar_id_colon "(" ident ":" lconstr ")"
@@ -1611,6 +1623,7 @@ simple_tactic: [
| "debug" "eauto" OPT int_or_var OPT int_or_var auto_using hintbases
| "info_eauto" OPT int_or_var OPT int_or_var auto_using hintbases
| "dfs" "eauto" OPT int_or_var auto_using hintbases
+| "bfs" "eauto" OPT int_or_var auto_using hintbases
| "autounfold" hintbases clause_dft_concl
| "autounfold_one" hintbases "in" hyp
| "autounfold_one" hintbases
@@ -1619,6 +1632,7 @@ simple_tactic: [
| "convert_concl_no_check" constr
| "typeclasses" "eauto" "bfs" OPT int_or_var "with" LIST1 preident
| "typeclasses" "eauto" OPT int_or_var "with" LIST1 preident
+| "typeclasses" "eauto" "bfs" OPT int_or_var
| "typeclasses" "eauto" OPT int_or_var
| "head_of_constr" ident constr
| "not_evar" constr
@@ -1745,6 +1759,51 @@ simple_tactic: [
| "ring_lookup" tactic0 "[" LIST0 constr "]" LIST1 constr (* ring plugin *)
| "field_lookup" tactic "[" LIST0 constr "]" LIST1 constr (* ring plugin *)
| "rtauto"
+| "by" ssrhintarg (* SSR plugin *)
+| "clear" natural (* SSR plugin *)
+| "move" ssrmovearg ssrrpat (* SSR plugin *)
+| "move" ssrmovearg ssrclauses (* SSR plugin *)
+| "move" ssrrpat (* SSR plugin *)
+| "move" (* SSR plugin *)
+| "case" ssrcasearg ssrclauses (* SSR plugin *)
+| "case" (* SSR plugin *)
+| "elim" ssrarg ssrclauses (* SSR plugin *)
+| "elim" (* SSR plugin *)
+| "apply" ssrapplyarg (* SSR plugin *)
+| "apply" (* SSR plugin *)
+| "exact" ssrexactarg (* SSR plugin *)
+| "exact" (* SSR plugin *)
+| "exact" "<:" lconstr (* SSR plugin *)
+| "congr" ssrcongrarg (* SSR plugin *)
+| "ssrinstancesofruleL2R" ssrterm (* SSR plugin *)
+| "ssrinstancesofruleR2L" ssrterm (* SSR plugin *)
+| "rewrite" ssrrwargs ssrclauses (* SSR plugin *)
+| "unlock" ssrunlockargs ssrclauses (* SSR plugin *)
+| "pose" ssrfixfwd (* SSR plugin *)
+| "pose" ssrcofixfwd (* SSR plugin *)
+| "pose" ssrfwdid ssrposefwd (* SSR plugin *)
+| "set" ssrfwdid ssrsetfwd ssrclauses (* SSR plugin *)
+| "abstract" ssrdgens (* SSR plugin *)
+| "have" ssrhavefwdwbinders (* SSR plugin *)
+| "have" "suff" ssrhpats_nobs ssrhavefwd (* SSR plugin *)
+| "have" "suffices" ssrhpats_nobs ssrhavefwd (* SSR plugin *)
+| "suff" "have" ssrhpats_nobs ssrhavefwd (* SSR plugin *)
+| "suffices" "have" ssrhpats_nobs ssrhavefwd (* SSR plugin *)
+| "suff" ssrsufffwd (* SSR plugin *)
+| "suffices" ssrsufffwd (* SSR plugin *)
+| "wlog" ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
+| "wlog" "suff" ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
+| "wlog" "suffices" ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
+| "without" "loss" ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
+| "without" "loss" "suff" ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
+| "without" "loss" "suffices" ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
+| "gen" "have" ssrclear ssr_idcomma ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
+| "generally" "have" ssrclear ssr_idcomma ssrhpats_nobs ssrwlogfwd ssrhint (* SSR plugin *)
+| "under" ssrrwarg (* SSR plugin *)
+| "under" ssrrwarg ssrintros_ne (* SSR plugin *)
+| "under" ssrrwarg ssrintros_ne "do" ssrhint3arg (* SSR plugin *)
+| "under" ssrrwarg "do" ssrhint3arg (* SSR plugin *)
+| "ssrinstancesoftpat" G_SSRMATCHING_cpattern (* SSR plugin *)
]
mlname: [
@@ -1765,9 +1824,7 @@ language: [
]
firstorder_using: [
-| "using" reference
-| "using" reference "," LIST1 reference SEP ","
-| "using" reference reference LIST0 reference
+| "using" LIST1 reference SEP ","
|
]
@@ -1791,8 +1848,8 @@ auto_using': [
| (* funind plugin *)
]
-function_rec_definition_loc: [
-| Vernac.rec_definition (* funind plugin *)
+function_fix_definition: [
+| Vernac.fix_definition (* funind plugin *)
]
fun_scheme_arg: [
@@ -1811,7 +1868,7 @@ EXTRAARGS_natural: [
occurrences: [
| LIST1 integer
-| var
+| hyp
]
glob: [
@@ -1851,6 +1908,10 @@ by_arg_tac: [
in_clause: [
| in_clause'
+| "*" occs
+| "*" "|-" concl_occ
+| LIST0 hypident_occ SEP "," "|-" concl_occ
+| LIST0 hypident_occ SEP ","
]
test_lpar_id_colon: [
@@ -1925,16 +1986,16 @@ eauto_search_strategy: [
]
tactic_then_last: [
-| "|" LIST0 ( OPT tactic_expr5 ) SEP "|"
+| "|" LIST0 ( OPT ltac_expr5 ) SEP "|"
|
]
-tactic_then_gen: [
-| tactic_expr5 "|" tactic_then_gen
-| tactic_expr5 ".." tactic_then_last
+for_each_goal: [
+| ltac_expr5 "|" for_each_goal
+| ltac_expr5 ".." tactic_then_last
| ".." tactic_then_last
-| tactic_expr5
-| "|" tactic_then_gen
+| ltac_expr5
+| "|" for_each_goal
|
]
@@ -1942,61 +2003,70 @@ tactic_then_locality: [
| "[" OPT ">"
]
-tactic_expr5: [
+ltac_expr5: [
| binder_tactic
-| tactic_expr4
-]
-
-tactic_expr4: [
-| tactic_expr3 ";" binder_tactic
-| tactic_expr3 ";" tactic_expr3
-| tactic_expr3 ";" tactic_then_locality tactic_then_gen "]"
-| tactic_expr3
-]
-
-tactic_expr3: [
-| "try" tactic_expr3
-| "do" int_or_var tactic_expr3
-| "timeout" int_or_var tactic_expr3
-| "time" OPT string tactic_expr3
-| "repeat" tactic_expr3
-| "progress" tactic_expr3
-| "once" tactic_expr3
-| "exactly_once" tactic_expr3
-| "infoH" tactic_expr3
-| "abstract" tactic_expr2
-| "abstract" tactic_expr2 "using" ident
-| selector tactic_expr3
-| tactic_expr2
-]
-
-tactic_expr2: [
-| tactic_expr1 "+" binder_tactic
-| tactic_expr1 "+" tactic_expr2
-| "tryif" tactic_expr5 "then" tactic_expr5 "else" tactic_expr2
-| tactic_expr1 "||" binder_tactic
-| tactic_expr1 "||" tactic_expr2
-| tactic_expr1
-]
-
-tactic_expr1: [
+| ltac_expr4
+]
+
+ltac_expr4: [
+| ltac_expr3 ";" binder_tactic
+| ltac_expr3 ";" ltac_expr3
+| ltac_expr3 ";" tactic_then_locality for_each_goal "]"
+| ltac_expr3
+| ltac_expr5 ";" "first" ssr_first_else (* SSR plugin *)
+| ltac_expr5 ";" "first" ssrseqarg (* SSR plugin *)
+| ltac_expr5 ";" "last" ssrseqarg (* SSR plugin *)
+]
+
+ltac_expr3: [
+| "try" ltac_expr3
+| "do" int_or_var ltac_expr3
+| "timeout" int_or_var ltac_expr3
+| "time" OPT string ltac_expr3
+| "repeat" ltac_expr3
+| "progress" ltac_expr3
+| "once" ltac_expr3
+| "exactly_once" ltac_expr3
+| "infoH" ltac_expr3
+| "abstract" ltac_expr2
+| "abstract" ltac_expr2 "using" ident
+| "only" selector ":" ltac_expr3
+| ltac_expr2
+| "do" ssrmmod ssrdotac ssrclauses (* SSR plugin *)
+| "do" ssrortacarg ssrclauses (* SSR plugin *)
+| "do" int_or_var ssrmmod ssrdotac ssrclauses (* SSR plugin *)
+| "abstract" ssrdgens (* SSR plugin *)
+]
+
+ltac_expr2: [
+| ltac_expr1 "+" binder_tactic
+| ltac_expr1 "+" ltac_expr2
+| "tryif" ltac_expr5 "then" ltac_expr5 "else" ltac_expr2
+| ltac_expr1 "||" binder_tactic
+| ltac_expr1 "||" ltac_expr2
+| ltac_expr1
+]
+
+ltac_expr1: [
| match_key "goal" "with" match_context_list "end"
| match_key "reverse" "goal" "with" match_context_list "end"
-| match_key tactic_expr5 "with" match_list "end"
-| "first" "[" LIST0 tactic_expr5 SEP "|" "]"
-| "solve" "[" LIST0 tactic_expr5 SEP "|" "]"
+| match_key ltac_expr5 "with" match_list "end"
+| "first" "[" LIST0 ltac_expr5 SEP "|" "]"
+| "solve" "[" LIST0 ltac_expr5 SEP "|" "]"
| "idtac" LIST0 message_token
| failkw [ int_or_var | ] LIST0 message_token
| simple_tactic
-| tactic_arg
-| reference LIST0 tactic_arg_compat
-| tactic_expr0
+| tactic_value
+| reference LIST0 tactic_arg
+| ltac_expr0
+| ltac_expr5 ssrintros_ne (* SSR plugin *)
]
-tactic_expr0: [
-| "(" tactic_expr5 ")"
-| "[" ">" tactic_then_gen "]"
+ltac_expr0: [
+| "(" ltac_expr5 ")"
+| "[" ">" for_each_goal "]"
| tactic_atom
+| ssrparentacarg (* SSR plugin *)
]
failkw: [
@@ -2005,17 +2075,17 @@ failkw: [
]
binder_tactic: [
-| "fun" LIST1 input_fun "=>" tactic_expr5
-| "let" [ "rec" | ] LIST1 let_clause SEP "with" "in" tactic_expr5
+| "fun" LIST1 input_fun "=>" ltac_expr5
+| "let" [ "rec" | ] LIST1 let_clause SEP "with" "in" ltac_expr5
]
-tactic_arg_compat: [
-| tactic_arg
+tactic_arg: [
+| tactic_value
| Constr.constr
| "()"
]
-tactic_arg: [
+tactic_value: [
| constr_eval
| "fresh" LIST0 fresh_id
| "type_term" uconstr
@@ -2056,26 +2126,26 @@ input_fun: [
]
let_clause: [
-| identref ":=" tactic_expr5
-| "_" ":=" tactic_expr5
-| identref LIST1 input_fun ":=" tactic_expr5
+| identref ":=" ltac_expr5
+| "_" ":=" ltac_expr5
+| identref LIST1 input_fun ":=" ltac_expr5
]
match_pattern: [
-| "context" OPT Constr.ident "[" Constr.lconstr_pattern "]"
-| Constr.lconstr_pattern
+| "context" OPT Constr.ident "[" Constr.cpattern "]"
+| Constr.cpattern
]
-match_hyps: [
+match_hyp: [
| name ":" match_pattern
| name ":=" "[" match_pattern "]" ":" match_pattern
| name ":=" match_pattern
]
match_context_rule: [
-| LIST0 match_hyps SEP "," "|-" match_pattern "=>" tactic_expr5
-| "[" LIST0 match_hyps SEP "," "|-" match_pattern "]" "=>" tactic_expr5
-| "_" "=>" tactic_expr5
+| LIST0 match_hyp SEP "," "|-" match_pattern "=>" ltac_expr5
+| "[" LIST0 match_hyp SEP "," "|-" match_pattern "]" "=>" ltac_expr5
+| "_" "=>" ltac_expr5
]
match_context_list: [
@@ -2084,8 +2154,8 @@ match_context_list: [
]
match_rule: [
-| match_pattern "=>" tactic_expr5
-| "_" "=>" tactic_expr5
+| match_pattern "=>" ltac_expr5
+| "_" "=>" ltac_expr5
]
match_list: [
@@ -2105,12 +2175,12 @@ ltac_def_kind: [
]
tacdef_body: [
-| Constr.global LIST1 input_fun ltac_def_kind tactic_expr5
-| Constr.global ltac_def_kind tactic_expr5
+| Constr.global LIST1 input_fun ltac_def_kind ltac_expr5
+| Constr.global ltac_def_kind ltac_expr5
]
tactic: [
-| tactic_expr5
+| ltac_expr5
]
range_selector: [
@@ -2123,17 +2193,13 @@ range_selector_or_nth: [
| natural OPT [ "," LIST1 range_selector SEP "," ]
]
-selector_body: [
+selector: [
| range_selector_or_nth
| test_bracket_ident "[" ident "]"
]
-selector: [
-| "only" selector_body ":"
-]
-
toplevel_selector: [
-| selector_body ":"
+| selector ":"
| "!" ":"
| "all" ":"
]
@@ -2145,14 +2211,6 @@ tactic_mode: [
| "par" ":" OPT ltac_info tactic ltac_use_default
]
-G_LTAC_hint: [
-| "Extern" natural OPT Constr.constr_pattern "=>" Pltac.tactic
-]
-
-G_LTAC_operconstr0: [
-| "ltac" ":" "(" Pltac.tactic_expr ")"
-]
-
ltac_selector: [
| toplevel_selector
]
@@ -2223,10 +2281,6 @@ rewstrategy: [
| "fold" constr
]
-G_REWRITE_binders: [
-| Pcoq.Constr.binders
-]
-
int_or_var: [
| integer
| identref
@@ -2329,7 +2383,7 @@ intropattern: [
]
simple_intropattern: [
-| simple_intropattern_closed LIST0 [ "%" operconstr0 ]
+| simple_intropattern_closed LIST0 [ "%" term0 ]
]
simple_intropattern_closed: [
@@ -2358,7 +2412,7 @@ with_bindings: [
|
]
-red_flags: [
+red_flag: [
| "beta"
| "iota"
| "match"
@@ -2375,7 +2429,7 @@ delta_flag: [
]
strategy_flag: [
-| LIST1 red_flags
+| LIST1 red_flag
| delta_flag
]
@@ -2399,32 +2453,27 @@ hypident: [
| id_or_meta
| "(" "type" "of" id_or_meta ")"
| "(" "value" "of" id_or_meta ")"
+| "(" "type" "of" Prim.identref ")" (* SSR plugin *)
+| "(" "value" "of" Prim.identref ")" (* SSR plugin *)
]
hypident_occ: [
| hypident occs
]
-G_TACTIC_in_clause: [
-| "*" occs
-| "*" "|-" concl_occ
-| LIST0 hypident_occ SEP "," "|-" concl_occ
-| LIST0 hypident_occ SEP ","
-]
-
clause_dft_concl: [
-| "in" G_TACTIC_in_clause
+| "in" in_clause
| occs
|
]
clause_dft_all: [
-| "in" G_TACTIC_in_clause
+| "in" in_clause
|
]
opt_clause: [
-| "in" G_TACTIC_in_clause
+| "in" in_clause
| "at" occs_nums
|
]
@@ -2502,7 +2551,7 @@ as_name: [
]
by_tactic: [
-| "by" tactic_expr3
+| "by" ltac_expr3
|
]
@@ -2555,12 +2604,630 @@ field_mods: [
| "(" LIST1 field_mod SEP "," ")" (* ring plugin *)
]
-numnotoption: [
+ssrtacarg: [
+| ltac_expr5 (* SSR plugin *)
+]
+
+ssrtac3arg: [
+| ltac_expr3 (* SSR plugin *)
+]
+
+ssrtclarg: [
+| ssrtacarg (* SSR plugin *)
+]
+
+ssrhyp: [
+| ident (* SSR plugin *)
+]
+
+ssrhoi_hyp: [
+| ident (* SSR plugin *)
+]
+
+ssrhoi_id: [
+| ident (* SSR plugin *)
+]
+
+ssrsimpl_ne: [
+| "//=" (* SSR plugin *)
+| "/=" (* SSR plugin *)
+| test_ssrslashnum11 "/" natural "/" natural "=" (* SSR plugin *)
+| test_ssrslashnum10 "/" natural "/" (* SSR plugin *)
+| test_ssrslashnum10 "/" natural "=" (* SSR plugin *)
+| test_ssrslashnum10 "/" natural "/=" (* SSR plugin *)
+| test_ssrslashnum10 "/" natural "/" "=" (* SSR plugin *)
+| test_ssrslashnum01 "//" natural "=" (* SSR plugin *)
+| test_ssrslashnum00 "//" (* SSR plugin *)
+]
+
+ssrclear_ne: [
+| "{" LIST1 ssrhyp "}" (* SSR plugin *)
+]
+
+ssrclear: [
+| ssrclear_ne (* SSR plugin *)
+| (* SSR plugin *)
+]
+
+ssrindex: [
+]
+
+ssrocc: [
+| natural LIST0 natural (* SSR plugin *)
+| "-" LIST0 natural (* SSR plugin *)
+| "+" LIST0 natural (* SSR plugin *)
+]
+
+ssrmmod: [
+| "!" (* SSR plugin *)
+| LEFTQMARK (* SSR plugin *)
+| "?" (* SSR plugin *)
+]
+
+ssrmult_ne: [
+| natural ssrmmod (* SSR plugin *)
+| ssrmmod (* SSR plugin *)
+]
+
+ssrmult: [
+| ssrmult_ne (* SSR plugin *)
+| (* SSR plugin *)
+]
+
+ssrdocc: [
+| "{" ssrocc "}" (* SSR plugin *)
+| "{" LIST0 ssrhyp "}" (* SSR plugin *)
+]
+
+ssrterm: [
+| ssrtermkind Pcoq.Constr.constr (* SSR plugin *)
+]
+
+ast_closure_term: [
+| term_annotation constr (* SSR plugin *)
+]
+
+ast_closure_lterm: [
+| term_annotation lconstr (* SSR plugin *)
+]
+
+ssrbwdview: [
+| test_not_ssrslashnum "/" Pcoq.Constr.constr (* SSR plugin *)
+| test_not_ssrslashnum "/" Pcoq.Constr.constr ssrbwdview (* SSR plugin *)
+]
+
+ssrfwdview: [
+| test_not_ssrslashnum "/" ast_closure_term (* SSR plugin *)
+| test_not_ssrslashnum "/" ast_closure_term ssrfwdview (* SSR plugin *)
+]
+
+ident_no_do: [
+| test_ident_no_do IDENT (* SSR plugin *)
+]
+
+ssripat: [
+| "_" (* SSR plugin *)
+| "*" (* SSR plugin *)
+| ">" (* SSR plugin *)
+| ident_no_do (* SSR plugin *)
+| "?" (* SSR plugin *)
+| "+" (* SSR plugin *)
+| "++" (* SSR plugin *)
+| ssrsimpl_ne (* SSR plugin *)
+| ssrdocc "->" (* SSR plugin *)
+| ssrdocc "<-" (* SSR plugin *)
+| ssrdocc (* SSR plugin *)
+| "->" (* SSR plugin *)
+| "<-" (* SSR plugin *)
+| "-" (* SSR plugin *)
+| "-/" "=" (* SSR plugin *)
+| "-/=" (* SSR plugin *)
+| "-/" "/" (* SSR plugin *)
+| "-//" (* SSR plugin *)
+| "-/" integer "/" (* SSR plugin *)
+| "-/" "/=" (* SSR plugin *)
+| "-//" "=" (* SSR plugin *)
+| "-//=" (* SSR plugin *)
+| "-/" integer "/=" (* SSR plugin *)
+| "-/" integer "/" integer "=" (* SSR plugin *)
+| ssrfwdview (* SSR plugin *)
+| "[" ":" LIST0 ident "]" (* SSR plugin *)
+| "[:" LIST0 ident "]" (* SSR plugin *)
+| ssrcpat (* SSR plugin *)
+]
+
+ssripats: [
+| ssripat ssripats (* SSR plugin *)
+| (* SSR plugin *)
+]
+
+ssriorpat: [
+| ssripats "|" ssriorpat (* SSR plugin *)
+| ssripats "|-" ">" ssriorpat (* SSR plugin *)
+| ssripats "|-" ssriorpat (* SSR plugin *)
+| ssripats "|->" ssriorpat (* SSR plugin *)
+| ssripats "||" ssriorpat (* SSR plugin *)
+| ssripats "|||" ssriorpat (* SSR plugin *)
+| ssripats "||||" ssriorpat (* SSR plugin *)
+| ssripats (* SSR plugin *)
+]
+
+ssrcpat: [
+| test_nohidden "[" hat "]" (* SSR plugin *)
+| test_nohidden "[" ssriorpat "]" (* SSR plugin *)
+| test_nohidden "[=" ssriorpat "]" (* SSR plugin *)
+]
+
+hat: [
+| "^" ident (* SSR plugin *)
+| "^" "~" ident (* SSR plugin *)
+| "^" "~" natural (* SSR plugin *)
+| "^~" ident (* SSR plugin *)
+| "^~" natural (* SSR plugin *)
+]
+
+ssripats_ne: [
+| ssripat ssripats (* SSR plugin *)
+]
+
+ssrhpats: [
+| ssripats (* SSR plugin *)
+]
+
+ssrhpats_wtransp: [
+| ssripats (* SSR plugin *)
+| ssripats "@" ssripats (* SSR plugin *)
+]
+
+ssrhpats_nobs: [
+| ssripats (* SSR plugin *)
+]
+
+ssrrpat: [
+| "->" (* SSR plugin *)
+| "<-" (* SSR plugin *)
+]
+
+ssrintros_ne: [
+| "=>" ssripats_ne (* SSR plugin *)
+]
+
+ssrintros: [
+| ssrintros_ne (* SSR plugin *)
+| (* SSR plugin *)
+]
+
+ssrintrosarg: [
+]
+
+ssrfwdid: [
+| test_ssrfwdid Prim.ident (* SSR plugin *)
+]
+
+ssrortacs: [
+| ssrtacarg "|" ssrortacs (* SSR plugin *)
+| ssrtacarg "|" (* SSR plugin *)
+| ssrtacarg (* SSR plugin *)
+| "|" ssrortacs (* SSR plugin *)
+| "|" (* SSR plugin *)
+]
+
+ssrhintarg: [
+| "[" "]" (* SSR plugin *)
+| "[" ssrortacs "]" (* SSR plugin *)
+| ssrtacarg (* SSR plugin *)
+]
+
+ssrhint3arg: [
+| "[" "]" (* SSR plugin *)
+| "[" ssrortacs "]" (* SSR plugin *)
+| ssrtac3arg (* SSR plugin *)
+]
+
+ssrortacarg: [
+| "[" ssrortacs "]" (* SSR plugin *)
+]
+
+ssrhint: [
+| (* SSR plugin *)
+| "by" ssrhintarg (* SSR plugin *)
+]
+
+ssrwgen: [
+| ssrclear_ne (* SSR plugin *)
+| ssrhoi_hyp (* SSR plugin *)
+| "@" ssrhoi_hyp (* SSR plugin *)
+| "(" ssrhoi_id ":=" lcpattern ")" (* SSR plugin *)
+| "(" ssrhoi_id ")" (* SSR plugin *)
+| "(@" ssrhoi_id ":=" lcpattern ")" (* SSR plugin *)
+| "(" "@" ssrhoi_id ":=" lcpattern ")" (* SSR plugin *)
+]
+
+ssrclausehyps: [
+| ssrwgen "," ssrclausehyps (* SSR plugin *)
+| ssrwgen ssrclausehyps (* SSR plugin *)
+| ssrwgen (* SSR plugin *)
+]
+
+ssrclauses: [
+| "in" ssrclausehyps "|-" "*" (* SSR plugin *)
+| "in" ssrclausehyps "|-" (* SSR plugin *)
+| "in" ssrclausehyps "*" (* SSR plugin *)
+| "in" ssrclausehyps (* SSR plugin *)
+| "in" "|-" "*" (* SSR plugin *)
+| "in" "*" (* SSR plugin *)
+| "in" "*" "|-" (* SSR plugin *)
+| (* SSR plugin *)
+]
+
+ssrfwd: [
+| ":=" ast_closure_lterm (* SSR plugin *)
+| ":" ast_closure_lterm ":=" ast_closure_lterm (* SSR plugin *)
+]
+
+ssrbvar: [
+| ident (* SSR plugin *)
+| "_" (* SSR plugin *)
+]
+
+ssrbinder: [
+| ssrbvar (* SSR plugin *)
+| "(" ssrbvar ")" (* SSR plugin *)
+| "(" ssrbvar ":" lconstr ")" (* SSR plugin *)
+| "(" ssrbvar LIST1 ssrbvar ":" lconstr ")" (* SSR plugin *)
+| "(" ssrbvar ":" lconstr ":=" lconstr ")" (* SSR plugin *)
+| "(" ssrbvar ":=" lconstr ")" (* SSR plugin *)
+| [ "of" | "&" ] term99 (* SSR plugin *)
+]
+
+ssrstruct: [
+| "{" "struct" ident "}" (* SSR plugin *)
+| (* SSR plugin *)
+]
+
+ssrposefwd: [
+| LIST0 ssrbinder ssrfwd (* SSR plugin *)
+]
+
+ssrfixfwd: [
+| "fix" ssrbvar LIST0 ssrbinder ssrstruct ssrfwd (* SSR plugin *)
+]
+
+ssrcofixfwd: [
+| "cofix" ssrbvar LIST0 ssrbinder ssrfwd (* SSR plugin *)
+]
+
+ssrsetfwd: [
+| ":" ast_closure_lterm ":=" "{" ssrocc "}" cpattern (* SSR plugin *)
+| ":" ast_closure_lterm ":=" lcpattern (* SSR plugin *)
+| ":=" "{" ssrocc "}" cpattern (* SSR plugin *)
+| ":=" lcpattern (* SSR plugin *)
+]
+
+ssrhavefwd: [
+| ":" ast_closure_lterm ssrhint (* SSR plugin *)
+| ":" ast_closure_lterm ":=" ast_closure_lterm (* SSR plugin *)
+| ":" ast_closure_lterm ":=" (* SSR plugin *)
+| ":=" ast_closure_lterm (* SSR plugin *)
+]
+
+ssrhavefwdwbinders: [
+| ssrhpats_wtransp LIST0 ssrbinder ssrhavefwd (* SSR plugin *)
+]
+
+ssrdoarg: [
+]
+
+ssrseqarg: [
+| ssrswap (* SSR plugin *)
+| ssrseqidx ssrortacarg OPT ssrorelse (* SSR plugin *)
+| ssrseqidx ssrswap (* SSR plugin *)
+| ltac_expr3 (* SSR plugin *)
+]
+
+ssrseqidx: [
+| test_ssrseqvar Prim.ident (* SSR plugin *)
+| Prim.natural (* SSR plugin *)
+]
+
+ssrswap: [
+| "first" (* SSR plugin *)
+| "last" (* SSR plugin *)
+]
+
+ssrorelse: [
+| "||" ltac_expr2 (* SSR plugin *)
+]
+
+Prim.ident: [
+| IDENT ssr_null_entry (* SSR plugin *)
+]
+
+ssrparentacarg: [
+| "(" ltac_expr5 ")" (* SSR plugin *)
+]
+
+ssrdotac: [
+| ltac_expr3 (* SSR plugin *)
+| ssrortacarg (* SSR plugin *)
+]
+
+ssrseqdir: [
+]
+
+ssr_first: [
+| ssr_first ssrintros_ne (* SSR plugin *)
+| "[" LIST0 ltac_expr5 SEP "|" "]" (* SSR plugin *)
+]
+
+ssr_first_else: [
+| ssr_first ssrorelse (* SSR plugin *)
+| ssr_first (* SSR plugin *)
+]
+
+ssrgen: [
+| ssrdocc cpattern (* SSR plugin *)
+| cpattern (* SSR plugin *)
+]
+
+ssrdgens_tl: [
+| "{" LIST1 ssrhyp "}" cpattern ssrdgens_tl (* SSR plugin *)
+| "{" LIST1 ssrhyp "}" (* SSR plugin *)
+| "{" ssrocc "}" cpattern ssrdgens_tl (* SSR plugin *)
+| "/" ssrdgens_tl (* SSR plugin *)
+| cpattern ssrdgens_tl (* SSR plugin *)
+| (* SSR plugin *)
+]
+
+ssrdgens: [
+| ":" ssrgen ssrdgens_tl (* SSR plugin *)
+]
+
+ssreqid: [
+| test_ssreqid ssreqpat (* SSR plugin *)
+| test_ssreqid (* SSR plugin *)
+]
+
+ssreqpat: [
+| Prim.ident (* SSR plugin *)
+| "_" (* SSR plugin *)
+| "?" (* SSR plugin *)
+| "+" (* SSR plugin *)
+| ssrdocc "->" (* SSR plugin *)
+| ssrdocc "<-" (* SSR plugin *)
+| "->" (* SSR plugin *)
+| "<-" (* SSR plugin *)
+]
+
+ssrarg: [
+| ssrfwdview ssreqid ssrdgens ssrintros (* SSR plugin *)
+| ssrfwdview ssrclear ssrintros (* SSR plugin *)
+| ssreqid ssrdgens ssrintros (* SSR plugin *)
+| ssrclear_ne ssrintros (* SSR plugin *)
+| ssrintros_ne (* SSR plugin *)
+]
+
+ssrmovearg: [
+| ssrarg (* SSR plugin *)
+]
+
+ssrcasearg: [
+| ssrarg (* SSR plugin *)
+]
+
+ssragen: [
+| "{" LIST1 ssrhyp "}" ssrterm (* SSR plugin *)
+| ssrterm (* SSR plugin *)
+]
+
+ssragens: [
+| "{" LIST1 ssrhyp "}" ssrterm ssragens (* SSR plugin *)
+| "{" LIST1 ssrhyp "}" (* SSR plugin *)
+| ssrterm ssragens (* SSR plugin *)
+| (* SSR plugin *)
+]
+
+ssrapplyarg: [
+| ":" ssragen ssragens ssrintros (* SSR plugin *)
+| ssrclear_ne ssrintros (* SSR plugin *)
+| ssrintros_ne (* SSR plugin *)
+| ssrbwdview ":" ssragen ssragens ssrintros (* SSR plugin *)
+| ssrbwdview ssrclear ssrintros (* SSR plugin *)
+]
+
+ssrexactarg: [
+| ":" ssragen ssragens (* SSR plugin *)
+| ssrbwdview ssrclear (* SSR plugin *)
+| ssrclear_ne (* SSR plugin *)
+]
+
+ssrcongrarg: [
+| natural constr ssrdgens (* SSR plugin *)
+| natural constr (* SSR plugin *)
+| constr ssrdgens (* SSR plugin *)
+| constr (* SSR plugin *)
+]
+
+ssrrwocc: [
+| "{" LIST0 ssrhyp "}" (* SSR plugin *)
+| "{" ssrocc "}" (* SSR plugin *)
+| (* SSR plugin *)
+]
+
+ssrrule_ne: [
+| test_not_ssrslashnum [ "/" ssrterm | ssrterm | ssrsimpl_ne ] (* SSR plugin *)
+| ssrsimpl_ne (* SSR plugin *)
+]
+
+ssrrule: [
+| ssrrule_ne (* SSR plugin *)
+| (* SSR plugin *)
+]
+
+ssrpattern_squarep: [
+| "[" rpattern "]" (* SSR plugin *)
+| (* SSR plugin *)
+]
+
+ssrpattern_ne_squarep: [
+| "[" rpattern "]" (* SSR plugin *)
+]
+
+ssrrwarg: [
+| "-" ssrmult ssrrwocc ssrpattern_squarep ssrrule_ne (* SSR plugin *)
+| "-/" ssrterm (* SSR plugin *)
+| ssrmult_ne ssrrwocc ssrpattern_squarep ssrrule_ne (* SSR plugin *)
+| "{" LIST1 ssrhyp "}" ssrpattern_ne_squarep ssrrule_ne (* SSR plugin *)
+| "{" LIST1 ssrhyp "}" ssrrule (* SSR plugin *)
+| "{" ssrocc "}" ssrpattern_squarep ssrrule_ne (* SSR plugin *)
+| "{" "}" ssrpattern_squarep ssrrule_ne (* SSR plugin *)
+| ssrpattern_ne_squarep ssrrule_ne (* SSR plugin *)
+| ssrrule_ne (* SSR plugin *)
+]
+
+ssrrwargs: [
+| test_ssr_rw_syntax LIST1 ssrrwarg (* SSR plugin *)
+]
+
+ssrunlockarg: [
+| "{" ssrocc "}" ssrterm (* SSR plugin *)
+| ssrterm (* SSR plugin *)
+]
+
+ssrunlockargs: [
+| LIST0 ssrunlockarg (* SSR plugin *)
+]
+
+ssrsufffwd: [
+| ssrhpats LIST0 ssrbinder ":" ast_closure_lterm ssrhint (* SSR plugin *)
+]
+
+ssrwlogfwd: [
+| ":" LIST0 ssrwgen "/" ast_closure_lterm (* SSR plugin *)
+]
+
+ssr_idcomma: [
+| (* SSR plugin *)
+| test_idcomma [ IDENT | "_" ] "," (* SSR plugin *)
+]
+
+ssr_rtype: [
+| "return" term100 (* SSR plugin *)
+]
+
+ssr_mpat: [
+| pattern200 (* SSR plugin *)
+]
+
+ssr_dpat: [
+| ssr_mpat "in" pattern200 ssr_rtype (* SSR plugin *)
+| ssr_mpat ssr_rtype (* SSR plugin *)
+| ssr_mpat (* SSR plugin *)
+]
+
+ssr_dthen: [
+| ssr_dpat "then" lconstr (* SSR plugin *)
+]
+
+ssr_elsepat: [
+| "else" (* SSR plugin *)
+]
+
+ssr_else: [
+| ssr_elsepat lconstr (* SSR plugin *)
+]
+
+ssrhintref: [
+| constr (* SSR plugin *)
+| constr "|" natural (* SSR plugin *)
+]
+
+ssrviewpos: [
+| "for" "move" "/" (* SSR plugin *)
+| "for" "apply" "/" (* SSR plugin *)
+| "for" "apply" "/" "/" (* SSR plugin *)
+| "for" "apply" "//" (* SSR plugin *)
+| (* SSR plugin *)
+]
+
+ssrviewposspc: [
+| ssrviewpos (* SSR plugin *)
+]
+
+rpattern: [
+| lconstr (* SSR plugin *)
+| "in" lconstr (* SSR plugin *)
+| lconstr "in" lconstr (* SSR plugin *)
+| "in" lconstr "in" lconstr (* SSR plugin *)
+| lconstr "in" lconstr "in" lconstr (* SSR plugin *)
+| lconstr "as" lconstr "in" lconstr (* SSR plugin *)
+]
+
+G_SSRMATCHING_cpattern: [
+| "Qed" constr (* SSR plugin *)
+| ssrtermkind constr (* SSR plugin *)
+]
+
+lcpattern: [
+| "Qed" lconstr (* SSR plugin *)
+| ssrtermkind lconstr (* SSR plugin *)
+]
+
+ssrpatternarg: [
+| rpattern (* SSR plugin *)
+]
+
+ssr_search_item: [
+| string (* SSR plugin *)
+| string "%" preident (* SSR plugin *)
+| constr_pattern (* SSR plugin *)
+]
+
+ssr_search_arg: [
+| "-" ssr_search_item ssr_search_arg (* SSR plugin *)
+| ssr_search_item ssr_search_arg (* SSR plugin *)
+| (* SSR plugin *)
+]
+
+ssr_modlocs: [
+| (* SSR plugin *)
+| "in" LIST1 modloc (* SSR plugin *)
+]
+
+modloc: [
+| "-" global (* SSR plugin *)
+| global (* SSR plugin *)
+]
+
+deprecated_number_modifier: [
|
| "(" "warning" "after" bignat ")"
| "(" "abstract" "after" bignat ")"
]
+number_string_mapping: [
+| reference "=>" reference
+| "[" reference "]" "=>" reference
+]
+
+number_string_via: [
+| "via" reference "mapping" "[" LIST1 number_string_mapping SEP "," "]"
+]
+
+number_modifier: [
+| "warning" "after" bignat
+| "abstract" "after" bignat
+| number_string_via
+]
+
+number_options: [
+| "(" LIST1 number_modifier SEP "," ")"
+]
+
+string_option: [
+| "(" number_string_via ")"
+]
+
tac2pat1: [
| Prim.qualid LIST1 tac2pat0 (* Ltac2 plugin *)
| Prim.qualid (* Ltac2 plugin *)
@@ -2578,50 +3245,51 @@ tac2pat0: [
atomic_tac2pat: [
| (* Ltac2 plugin *)
-| tac2pat1 ":" tac2type5 (* Ltac2 plugin *)
+| tac2pat1 ":" ltac2_type5 (* Ltac2 plugin *)
| tac2pat1 "," LIST0 tac2pat1 SEP "," (* Ltac2 plugin *)
| tac2pat1 (* Ltac2 plugin *)
]
-tac2expr6: [
-| tac2expr5 ";" tac2expr6 (* Ltac2 plugin *)
-| tac2expr5 (* Ltac2 plugin *)
+ltac2_expr6: [
+| ltac2_expr5 ";" ltac2_expr6 (* Ltac2 plugin *)
+| ltac2_expr5 (* Ltac2 plugin *)
]
-tac2expr5: [
-| "fun" LIST1 G_LTAC2_input_fun "=>" tac2expr6 (* Ltac2 plugin *)
-| "let" rec_flag LIST1 G_LTAC2_let_clause SEP "with" "in" tac2expr6 (* Ltac2 plugin *)
-| "match" tac2expr5 "with" G_LTAC2_branches "end" (* Ltac2 plugin *)
-| tac2expr4 (* Ltac2 plugin *)
+ltac2_expr5: [
+| "fun" LIST1 G_LTAC2_input_fun "=>" ltac2_expr6 (* Ltac2 plugin *)
+| "let" rec_flag LIST1 G_LTAC2_let_clause SEP "with" "in" ltac2_expr6 (* Ltac2 plugin *)
+| "match" ltac2_expr5 "with" G_LTAC2_branches "end" (* Ltac2 plugin *)
+| "if" ltac2_expr5 "then" ltac2_expr5 "else" ltac2_expr5 (* Ltac2 plugin *)
+| ltac2_expr4 (* Ltac2 plugin *)
]
-tac2expr4: [
-| tac2expr3 (* Ltac2 plugin *)
+ltac2_expr4: [
+| ltac2_expr3 (* Ltac2 plugin *)
]
-tac2expr3: [
-| tac2expr2 "," LIST1 tac2expr2 SEP "," (* Ltac2 plugin *)
-| tac2expr2 (* Ltac2 plugin *)
+ltac2_expr3: [
+| ltac2_expr2 "," LIST1 ltac2_expr2 SEP "," (* Ltac2 plugin *)
+| ltac2_expr2 (* Ltac2 plugin *)
]
-tac2expr2: [
-| tac2expr1 "::" tac2expr2 (* Ltac2 plugin *)
-| tac2expr1 (* Ltac2 plugin *)
+ltac2_expr2: [
+| ltac2_expr1 "::" ltac2_expr2 (* Ltac2 plugin *)
+| ltac2_expr1 (* Ltac2 plugin *)
]
-tac2expr1: [
-| tac2expr0 LIST1 tac2expr0 (* Ltac2 plugin *)
-| tac2expr0 ".(" Prim.qualid ")" (* Ltac2 plugin *)
-| tac2expr0 ".(" Prim.qualid ")" ":=" tac2expr5 (* Ltac2 plugin *)
-| tac2expr0 (* Ltac2 plugin *)
+ltac2_expr1: [
+| ltac2_expr0 LIST1 ltac2_expr0 (* Ltac2 plugin *)
+| ltac2_expr0 ".(" Prim.qualid ")" (* Ltac2 plugin *)
+| ltac2_expr0 ".(" Prim.qualid ")" ":=" ltac2_expr5 (* Ltac2 plugin *)
+| ltac2_expr0 (* Ltac2 plugin *)
]
-tac2expr0: [
-| "(" tac2expr6 ")" (* Ltac2 plugin *)
-| "(" tac2expr6 ":" tac2type5 ")" (* Ltac2 plugin *)
+ltac2_expr0: [
+| "(" ltac2_expr6 ")" (* Ltac2 plugin *)
+| "(" ltac2_expr6 ":" ltac2_type5 ")" (* Ltac2 plugin *)
| "()" (* Ltac2 plugin *)
| "(" ")" (* Ltac2 plugin *)
-| "[" LIST0 tac2expr5 SEP ";" "]" (* Ltac2 plugin *)
+| "[" LIST0 ltac2_expr5 SEP ";" "]" (* Ltac2 plugin *)
| "{" tac2rec_fieldexprs "}" (* Ltac2 plugin *)
| G_LTAC2_tactic_atom (* Ltac2 plugin *)
]
@@ -2633,7 +3301,7 @@ G_LTAC2_branches: [
]
branch: [
-| tac2pat1 "=>" tac2expr6 (* Ltac2 plugin *)
+| tac2pat1 "=>" ltac2_expr6 (* Ltac2 plugin *)
]
rec_flag: [
@@ -2646,7 +3314,7 @@ mut_flag: [
| (* Ltac2 plugin *)
]
-typ_param: [
+ltac2_typevar: [
| "'" Prim.ident (* Ltac2 plugin *)
]
@@ -2660,48 +3328,48 @@ G_LTAC2_tactic_atom: [
| "constr" ":" "(" Constr.lconstr ")" (* Ltac2 plugin *)
| "open_constr" ":" "(" Constr.lconstr ")" (* Ltac2 plugin *)
| "ident" ":" "(" lident ")" (* Ltac2 plugin *)
-| "pattern" ":" "(" Constr.lconstr_pattern ")" (* Ltac2 plugin *)
+| "pattern" ":" "(" Constr.cpattern ")" (* Ltac2 plugin *)
| "reference" ":" "(" globref ")" (* Ltac2 plugin *)
| "ltac1" ":" "(" ltac1_expr_in_env ")" (* Ltac2 plugin *)
| "ltac1val" ":" "(" ltac1_expr_in_env ")" (* Ltac2 plugin *)
]
ltac1_expr_in_env: [
-| test_ltac1_env LIST0 locident "|-" ltac1_expr (* Ltac2 plugin *)
-| ltac1_expr (* Ltac2 plugin *)
+| test_ltac1_env LIST0 locident "|-" ltac_expr5 (* Ltac2 plugin *)
+| ltac_expr5 (* Ltac2 plugin *)
]
tac2expr_in_env: [
-| test_ltac1_env LIST0 locident "|-" tac2expr6 (* Ltac2 plugin *)
-| tac2expr6 (* Ltac2 plugin *)
+| test_ltac1_env LIST0 locident "|-" ltac2_expr6 (* Ltac2 plugin *)
+| ltac2_expr6 (* Ltac2 plugin *)
]
G_LTAC2_let_clause: [
-| let_binder ":=" tac2expr6 (* Ltac2 plugin *)
+| let_binder ":=" ltac2_expr6 (* Ltac2 plugin *)
]
let_binder: [
| LIST1 G_LTAC2_input_fun (* Ltac2 plugin *)
]
-tac2type5: [
-| tac2type2 "->" tac2type5 (* Ltac2 plugin *)
-| tac2type2 (* Ltac2 plugin *)
+ltac2_type5: [
+| ltac2_type2 "->" ltac2_type5 (* Ltac2 plugin *)
+| ltac2_type2 (* Ltac2 plugin *)
]
-tac2type2: [
-| tac2type1 "*" LIST1 tac2type1 SEP "*" (* Ltac2 plugin *)
-| tac2type1 (* Ltac2 plugin *)
+ltac2_type2: [
+| ltac2_type1 "*" LIST1 ltac2_type1 SEP "*" (* Ltac2 plugin *)
+| ltac2_type1 (* Ltac2 plugin *)
]
-tac2type1: [
-| tac2type0 Prim.qualid (* Ltac2 plugin *)
-| tac2type0 (* Ltac2 plugin *)
+ltac2_type1: [
+| ltac2_type0 Prim.qualid (* Ltac2 plugin *)
+| ltac2_type0 (* Ltac2 plugin *)
]
-tac2type0: [
-| "(" LIST1 tac2type5 SEP "," ")" OPT Prim.qualid (* Ltac2 plugin *)
-| typ_param (* Ltac2 plugin *)
+ltac2_type0: [
+| "(" LIST1 ltac2_type5 SEP "," ")" OPT Prim.qualid (* Ltac2 plugin *)
+| ltac2_typevar (* Ltac2 plugin *)
| "_" (* Ltac2 plugin *)
| Prim.qualid (* Ltac2 plugin *)
]
@@ -2720,7 +3388,7 @@ G_LTAC2_input_fun: [
]
tac2def_body: [
-| G_LTAC2_binder LIST0 G_LTAC2_input_fun ":=" tac2expr6 (* Ltac2 plugin *)
+| G_LTAC2_binder LIST0 G_LTAC2_input_fun ":=" ltac2_expr6 (* Ltac2 plugin *)
]
tac2def_val: [
@@ -2728,11 +3396,11 @@ tac2def_val: [
]
tac2def_mut: [
-| "Set" Prim.qualid OPT [ "as" locident ] ":=" tac2expr6 (* Ltac2 plugin *)
+| "Set" Prim.qualid OPT [ "as" locident ] ":=" ltac2_expr6 (* Ltac2 plugin *)
]
tac2typ_knd: [
-| tac2type5 (* Ltac2 plugin *)
+| ltac2_type5 (* Ltac2 plugin *)
| "[" ".." "]" (* Ltac2 plugin *)
| "[" tac2alg_constructors "]" (* Ltac2 plugin *)
| "{" tac2rec_fields "}" (* Ltac2 plugin *)
@@ -2745,7 +3413,7 @@ tac2alg_constructors: [
tac2alg_constructor: [
| Prim.ident (* Ltac2 plugin *)
-| Prim.ident "(" LIST0 tac2type5 SEP "," ")" (* Ltac2 plugin *)
+| Prim.ident "(" LIST0 ltac2_type5 SEP "," ")" (* Ltac2 plugin *)
]
tac2rec_fields: [
@@ -2756,7 +3424,7 @@ tac2rec_fields: [
]
tac2rec_field: [
-| mut_flag Prim.ident ":" tac2type5 (* Ltac2 plugin *)
+| mut_flag Prim.ident ":" ltac2_type5 (* Ltac2 plugin *)
]
tac2rec_fieldexprs: [
@@ -2767,13 +3435,13 @@ tac2rec_fieldexprs: [
]
tac2rec_fieldexpr: [
-| Prim.qualid ":=" tac2expr1 (* Ltac2 plugin *)
+| Prim.qualid ":=" ltac2_expr1 (* Ltac2 plugin *)
]
tac2typ_prm: [
| (* Ltac2 plugin *)
-| typ_param (* Ltac2 plugin *)
-| "(" LIST1 typ_param SEP "," ")" (* Ltac2 plugin *)
+| ltac2_typevar (* Ltac2 plugin *)
+| "(" LIST1 ltac2_typevar SEP "," ")" (* Ltac2 plugin *)
]
tac2typ_def: [
@@ -2791,7 +3459,7 @@ tac2def_typ: [
]
tac2def_ext: [
-| "@" "external" locident ":" tac2type5 ":=" Prim.string Prim.string (* Ltac2 plugin *)
+| "@" "external" locident ":" ltac2_type5 ":=" Prim.string Prim.string (* Ltac2 plugin *)
]
syn_node: [
@@ -2799,11 +3467,11 @@ syn_node: [
| Prim.ident (* Ltac2 plugin *)
]
-sexpr: [
+ltac2_scope: [
| Prim.string (* Ltac2 plugin *)
| Prim.integer (* Ltac2 plugin *)
| syn_node (* Ltac2 plugin *)
-| syn_node "(" LIST1 sexpr SEP "," ")" (* Ltac2 plugin *)
+| syn_node "(" LIST1 ltac2_scope SEP "," ")" (* Ltac2 plugin *)
]
syn_level: [
@@ -2812,7 +3480,7 @@ syn_level: [
]
tac2def_syn: [
-| "Notation" LIST1 sexpr syn_level ":=" tac2expr6 (* Ltac2 plugin *)
+| "Notation" LIST1 ltac2_scope syn_level ":=" ltac2_expr6 (* Ltac2 plugin *)
]
lident: [
@@ -3030,28 +3698,28 @@ q_rewriting: [
]
G_LTAC2_tactic_then_last: [
-| "|" LIST0 ( OPT tac2expr6 ) SEP "|" (* Ltac2 plugin *)
+| "|" LIST0 ( OPT ltac2_expr6 ) SEP "|" (* Ltac2 plugin *)
| (* Ltac2 plugin *)
]
-G_LTAC2_tactic_then_gen: [
-| tac2expr6 "|" G_LTAC2_tactic_then_gen (* Ltac2 plugin *)
-| tac2expr6 ".." G_LTAC2_tactic_then_last (* Ltac2 plugin *)
+G_LTAC2_for_each_goal: [
+| ltac2_expr6 "|" G_LTAC2_for_each_goal (* Ltac2 plugin *)
+| ltac2_expr6 ".." G_LTAC2_tactic_then_last (* Ltac2 plugin *)
| ".." G_LTAC2_tactic_then_last (* Ltac2 plugin *)
-| tac2expr6 (* Ltac2 plugin *)
-| "|" G_LTAC2_tactic_then_gen (* Ltac2 plugin *)
+| ltac2_expr6 (* Ltac2 plugin *)
+| "|" G_LTAC2_for_each_goal (* Ltac2 plugin *)
| (* Ltac2 plugin *)
]
q_dispatch: [
-| G_LTAC2_tactic_then_gen (* Ltac2 plugin *)
+| G_LTAC2_for_each_goal (* Ltac2 plugin *)
]
q_occurrences: [
| G_LTAC2_occs (* Ltac2 plugin *)
]
-red_flag: [
+ltac2_red_flag: [
| "beta" (* Ltac2 plugin *)
| "iota" (* Ltac2 plugin *)
| "match" (* Ltac2 plugin *)
@@ -3082,7 +3750,7 @@ G_LTAC2_delta_flag: [
]
G_LTAC2_strategy_flag: [
-| LIST1 red_flag (* Ltac2 plugin *)
+| LIST1 ltac2_red_flag (* Ltac2 plugin *)
| G_LTAC2_delta_flag (* Ltac2 plugin *)
]
@@ -3100,12 +3768,12 @@ q_hintdb: [
]
G_LTAC2_match_pattern: [
-| "context" OPT Prim.ident "[" Constr.lconstr_pattern "]" (* Ltac2 plugin *)
-| Constr.lconstr_pattern (* Ltac2 plugin *)
+| "context" OPT Prim.ident "[" Constr.cpattern "]" (* Ltac2 plugin *)
+| Constr.cpattern (* Ltac2 plugin *)
]
G_LTAC2_match_rule: [
-| G_LTAC2_match_pattern "=>" tac2expr6 (* Ltac2 plugin *)
+| G_LTAC2_match_pattern "=>" ltac2_expr6 (* Ltac2 plugin *)
]
G_LTAC2_match_list: [
@@ -3126,16 +3794,16 @@ gmatch_pattern: [
]
gmatch_rule: [
-| gmatch_pattern "=>" tac2expr6 (* Ltac2 plugin *)
+| gmatch_pattern "=>" ltac2_expr6 (* Ltac2 plugin *)
]
-gmatch_list: [
+goal_match_list: [
| LIST1 gmatch_rule SEP "|" (* Ltac2 plugin *)
| "|" LIST1 gmatch_rule SEP "|" (* Ltac2 plugin *)
]
q_goal_matching: [
-| gmatch_list (* Ltac2 plugin *)
+| goal_match_list (* Ltac2 plugin *)
]
move_location: [
@@ -3169,7 +3837,7 @@ G_LTAC2_as_ipat: [
]
G_LTAC2_by_tactic: [
-| "by" tac2expr6 (* Ltac2 plugin *)
+| "by" ltac2_expr6 (* Ltac2 plugin *)
| (* Ltac2 plugin *)
]
@@ -3192,11 +3860,11 @@ ltac2_entry: [
]
ltac2_expr: [
-| tac2expr6 (* Ltac2 plugin *)
+| _ltac2_expr (* Ltac2 plugin *)
]
tac2mode: [
-| ltac2_expr ltac_use_default (* Ltac2 plugin *)
+| ltac2_expr6 ltac_use_default (* Ltac2 plugin *)
| G_vernac.query_command (* Ltac2 plugin *)
]
diff --git a/doc/tools/docgram/orderedGrammar b/doc/tools/docgram/orderedGrammar
index 61befe9f1f..dfd3a18908 100644
--- a/doc/tools/docgram/orderedGrammar
+++ b/doc/tools/docgram/orderedGrammar
@@ -3,10 +3,6 @@ doc_grammar will modify this file to add/remove nonterminals and productions
to match editedGrammar, which will remove comments. Not compiled into Coq *)
DOC_GRAMMAR
-tactic_mode: [
-| OPT ( toplevel_selector ":" ) "{"
-]
-
term: [
| term_forall_or_fun
| term_let
@@ -178,10 +174,129 @@ subsequent_letter: [
| [ first_letter | digit | "'" | unicode_id_part ]
]
-firstorder_rhs: [
-| OPT firstorder_using
-| "with" LIST1 ident
-| OPT firstorder_using "with" LIST1 ident
+ssrarg: [
+| OPT ssrfwdview OPT ssreqpat ssrdgens OPT ssrintros
+| ssrfwdview OPT ssrclear OPT ssrintros (* SSR plugin *)
+| ssrclear OPT ssrintros (* SSR plugin *)
+| ssrintros (* SSR plugin *)
+]
+
+ssreqpat: [
+| ident (* SSR plugin *)
+| "_" (* SSR plugin *)
+| "?" (* SSR plugin *)
+| "+" (* SSR plugin *)
+| ssrdocc "->" (* SSR plugin *)
+| ssrdocc "<-" (* SSR plugin *)
+| "->" (* SSR plugin *)
+| "<-" (* SSR plugin *)
+]
+
+ssrapplyarg: [
+| ssrclear OPT ssrintros (* SSR plugin *)
+| ssrintros (* SSR plugin *)
+| OPT ssrbwdview ":" ssragen OPT ssragens OPT ssrintros (* SSR plugin *)
+| ssrbwdview OPT ssrclear OPT ssrintros (* SSR plugin *)
+]
+
+ssragen: [
+| OPT ( "{" LIST1 ident "}" ) term (* SSR plugin *)
+]
+
+ssragens: [
+| "{" LIST1 ident "}" term OPT ssragens (* SSR plugin *)
+| "{" LIST1 ident "}" (* SSR plugin *)
+| term OPT ssragens (* SSR plugin *)
+]
+
+ssrintros: [
+| "=>" ssripats (* SSR plugin *)
+]
+
+ssrbwdview: [
+| "/" term (* SSR plugin *)
+| "/" term ssrbwdview (* SSR plugin *)
+]
+
+ssrdgens: [
+| ":" ssrgen OPT ( "/" ssrgen ) (* SSR plugin *)
+]
+
+ssrgen: [
+| cpattern LIST0 [ LIST1 ident | cpattern ] (* SSR plugin *)
+]
+
+rewrite_item: [
+| "-" OPT mult OPT occ_or_clear OPT ssrpattern_squarep r_item (* SSR plugin *)
+| mult OPT occ_or_clear OPT ssrpattern_squarep r_item (* SSR plugin *)
+| "-/" term (* SSR plugin *)
+| OPT ( OPT ( "{" LIST1 ident "}" ) ssrpattern_squarep ) r_item (* SSR plugin *)
+| "{" LIST1 ident "}" OPT r_item (* SSR plugin *)
+| "{" OPT ssr_occurrences "}" OPT ssrpattern_squarep r_item (* SSR plugin *)
+]
+
+occ_or_clear: [
+| clear_switch
+| "{" ssr_occurrences "}" (* SSR plugin *)
+]
+
+clear_switch: [
+| "{" LIST0 ident "}"
+]
+
+ssr_occurrences: [
+| [ natural | "+" | "-" ] LIST0 natural (* SSR plugin *)
+]
+
+r_item: [
+| [ OPT "/" term | s_item ] (* SSR plugin *)
+]
+
+ssrpattern_squarep: [
+| "[" rewrite_pattern "]" (* SSR plugin *)
+]
+
+rewrite_pattern: [
+| OPT ( OPT ( OPT ( OPT term "in" ) term ) "in" ) term (* SSR plugin *)
+| term "as" term "in" term (* SSR plugin *)
+]
+
+ssr_in: [
+| "in" ssrclausehyps OPT "|-" OPT "*" (* SSR plugin *)
+| "in" [ "*" | "*" "|-" | "|-" "*" ] (* SSR plugin *)
+]
+
+ssrclausehyps: [
+| gen_item LIST0 ( OPT "," gen_item ) (* SSR plugin *)
+]
+
+gen_item: [
+| ssrclear (* SSR plugin *)
+| OPT "@" ident (* SSR plugin *)
+| "(" ident OPT ( ":=" lcpattern ) ")" (* SSR plugin *)
+| "(@" ident ":=" lcpattern ")" (* SSR plugin *)
+]
+
+ssrclear: [
+| "{" LIST1 ident "}" (* SSR plugin *)
+]
+
+lcpattern: [
+| term
+]
+
+ssrsufffwd: [
+| OPT ssripats LIST0 ssrbinder ":" term OPT ( "by" ssrhintarg ) (* SSR plugin *)
+]
+
+ssrviewpos: [
+| "for" "move" "/" (* SSR plugin *)
+| "for" "apply" "/" (* SSR plugin *)
+| "for" "apply" "//" (* SSR plugin *)
+]
+
+ssr_one_term_pattern: [
+| one_term (* SSR plugin *)
]
where: [
@@ -191,6 +306,15 @@ where: [
| "before" ident
]
+add_zify: [
+| [ "InjTyp" | "BinOp" | "UnOp" | "CstOp" | "BinRel" | "UnOpSpec" | "BinOpSpec" ] (* Micromega plugin *)
+| [ "PropOp" | "PropBinOp" | "PropUOp" | "Saturate" ] (* Micromega plugin *)
+]
+
+show_zify: [
+| [ "InjTyp" | "BinOp" | "UnOp" | "CstOp" | "BinRel" | "UnOpSpec" | "BinOpSpec" | "Spec" ] (* Micromega plugin *)
+]
+
REACHABLE: [
| command
| simple_tactic
@@ -310,16 +434,20 @@ univ_decl: [
| "@{" LIST0 ident OPT "+" OPT [ "|" LIST0 univ_constraint SEP "," OPT "+" ] "}"
]
+cumul_univ_decl: [
+| "@{" LIST0 ( OPT [ "=" | "+" | "*" ] ident ) OPT "+" OPT [ "|" LIST0 univ_constraint SEP "," OPT "+" ] "}"
+]
+
univ_constraint: [
| universe_name [ "<" | "=" | "<=" ] universe_name
]
term_fix: [
-| "let" "fix" fix_body "in" term
-| "fix" fix_body OPT ( LIST1 ( "with" fix_body ) "for" ident )
+| "let" "fix" fix_decl "in" term
+| "fix" fix_decl OPT ( LIST1 ( "with" fix_decl ) "for" ident )
]
-fix_body: [
+fix_decl: [
| ident LIST0 binder OPT fixannot OPT ( ":" type ) ":=" term
]
@@ -342,9 +470,17 @@ term_if: [
| "if" term OPT [ OPT [ "as" name ] "return" term100 ] "then" term "else" term
]
+ssr_dpat: [
+| pattern OPT ( OPT ( "in" pattern ) "return" term100 ) (* SSR plugin *)
+]
+
term_let: [
| "let" name OPT ( ":" type ) ":=" term "in" term
| "let" name LIST1 binder OPT ( ":" type ) ":=" term "in" term
+| destructuring_let
+]
+
+destructuring_let: [
| "let" "(" LIST0 name SEP "," ")" OPT [ OPT [ "as" name ] "return" term100 ] ":=" term "in" term
| "let" "'" pattern ":=" term OPT ( "return" term100 ) "in" term
| "let" "'" pattern "in" pattern ":=" term "return" term100 "in" term
@@ -448,9 +584,7 @@ vernac_aux: [
]
subprf: [
-| bullet
| "{"
-| "}"
]
fix_definition: [
@@ -538,8 +672,12 @@ variant_definition: [
| ident_decl LIST0 binder OPT [ "|" LIST0 binder ] OPT [ ":" type ] ":=" OPT "|" LIST1 constructor SEP "|" OPT decl_notations
]
+singleton_class_definition: [
+| OPT ">" ident_decl LIST0 binder OPT [ ":" sort ] ":=" constructor
+]
+
record_definition: [
-| OPT ">" ident_decl LIST0 binder OPT [ ":" type ] OPT ident "{" LIST0 record_field SEP ";" OPT ";" "}" OPT decl_notations
+| OPT ">" ident_decl LIST0 binder OPT [ ":" sort ] OPT ( ":=" OPT ident "{" LIST0 record_field SEP ";" OPT ";" "}" )
]
record_field: [
@@ -561,7 +699,7 @@ field_def: [
]
inductive_definition: [
-| OPT ">" ident_decl LIST0 binder OPT [ "|" LIST0 binder ] OPT [ ":" type ] OPT ( ":=" OPT constructors_or_record ) OPT decl_notations
+| OPT ">" cumul_ident_decl LIST0 binder OPT [ "|" LIST0 binder ] OPT [ ":" type ] OPT ( ":=" OPT constructors_or_record ) OPT decl_notations
]
constructors_or_record: [
@@ -573,6 +711,10 @@ constructor: [
| ident LIST0 binder OPT of_type
]
+cumul_ident_decl: [
+| ident OPT cumul_univ_decl
+]
+
filtered_import: [
| qualid OPT [ "(" LIST1 ( qualid OPT [ "(" ".." ")" ] ) SEP "," ")" ]
]
@@ -582,11 +724,8 @@ cofix_definition: [
]
scheme_kind: [
-| "Induction" "for" reference "Sort" sort_family
-| "Minimality" "for" reference "Sort" sort_family
-| "Elimination" "for" reference "Sort" sort_family
-| "Case" "for" reference "Sort" sort_family
| "Equality" "for" reference
+| [ "Induction" | "Minimality" | "Elimination" | "Case" ] "for" reference "Sort" sort_family
]
sort_family: [
@@ -597,7 +736,11 @@ sort_family: [
]
hint_info: [
-| "|" OPT natural OPT one_term
+| "|" OPT natural OPT one_pattern
+]
+
+one_pattern: [
+| one_term
]
module_binder: [
@@ -714,7 +857,7 @@ simple_reserv: [
]
command: [
-| "Goal" term
+| "Goal" type
| "Pwd"
| "Cd" OPT string
| "Load" OPT "Verbose" [ string | ident ]
@@ -723,6 +866,8 @@ command: [
| "Locate" "Term" reference
| "Locate" "Module" qualid
| "Info" natural ltac_expr
+| "Add" "Zify" add_zify one_term (* Micromega plugin *)
+| "Show" "Zify" show_zify (* Micromega plugin *)
| "Locate" "Ltac" qualid
| "Locate" "Library" qualid
| "Locate" "File" string
@@ -798,7 +943,7 @@ command: [
| "Extraction" "NoInline" LIST1 qualid (* extraction plugin *)
| "Print" "Extraction" "Inline" (* extraction plugin *)
| "Reset" "Extraction" "Inline" (* extraction plugin *)
-| "Extraction" "Implicit" qualid "[" LIST0 int_or_id "]" (* extraction plugin *)
+| "Extraction" "Implicit" qualid "[" LIST0 [ ident | integer ] "]" (* extraction plugin *)
| "Extraction" "Blacklist" LIST1 ident (* extraction plugin *)
| "Print" "Extraction" "Blacklist" (* extraction plugin *)
| "Reset" "Extraction" "Blacklist" (* extraction plugin *)
@@ -810,7 +955,7 @@ command: [
| "Proof" "Mode" string
| "Proof" term
| "Abort" OPT [ "All" | ident ]
-| "Existential" natural OPT ( ":" term ) ":=" term
+| "Existential" natural OPT ( ":" type ) ":=" term
| "Admitted"
| "Qed"
| "Save" ident
@@ -835,10 +980,10 @@ command: [
| "Comments" LIST0 [ one_term | string | natural ]
| "Declare" "Instance" ident_decl LIST0 binder ":" term OPT hint_info
| "Declare" "Scope" scope_name
-| "Obligation" natural OPT ( "of" ident ) OPT ( ":" term OPT ( "with" ltac_expr ) )
+| "Obligation" natural OPT ( "of" ident ) OPT ( ":" type OPT ( "with" ltac_expr ) )
| "Next" "Obligation" OPT ( "of" ident ) OPT ( "with" ltac_expr )
| "Solve" "Obligation" natural OPT ( "of" ident ) "with" ltac_expr
-| "Solve" "Obligations" OPT ( OPT ( "of" ident ) "with" ltac_expr )
+| "Solve" "Obligations" OPT ( "of" ident ) OPT ( "with" ltac_expr )
| "Solve" "All" "Obligations" OPT ( "with" ltac_expr )
| "Admit" "Obligations" OPT ( "of" ident )
| "Obligation" "Tactic" ":=" ltac_expr
@@ -862,17 +1007,6 @@ command: [
| "Reset" "Ltac" "Profile"
| "Show" "Ltac" "Profile" OPT [ "CutOff" integer | string ]
| "Show" "Lia" "Profile" (* micromega plugin *)
-| "Add" "Zify" "InjTyp" one_term (* micromega plugin *)
-| "Add" "Zify" "BinOp" one_term (* micromega plugin *)
-| "Add" "Zify" "UnOp" one_term (* micromega plugin *)
-| "Add" "Zify" "CstOp" one_term (* micromega plugin *)
-| "Add" "Zify" "BinRel" one_term (* micromega plugin *)
-| "Add" "Zify" "PropOp" one_term (* micromega plugin *)
-| "Add" "Zify" "PropBinOp" one_term (* micromega plugin *)
-| "Add" "Zify" "PropUOp" one_term (* micromega plugin *)
-| "Add" "Zify" "BinOpSpec" one_term (* micromega plugin *)
-| "Add" "Zify" "UnOpSpec" one_term (* micromega plugin *)
-| "Add" "Zify" "Saturate" one_term (* micromega plugin *)
| "Add" "InjTyp" one_term (* micromega plugin *)
| "Add" "BinOp" one_term (* micromega plugin *)
| "Add" "UnOp" one_term (* micromega plugin *)
@@ -884,25 +1018,21 @@ command: [
| "Add" "BinOpSpec" one_term (* micromega plugin *)
| "Add" "UnOpSpec" one_term (* micromega plugin *)
| "Add" "Saturate" one_term (* micromega plugin *)
-| "Show" "Zify" "InjTyp" (* micromega plugin *)
-| "Show" "Zify" "BinOp" (* micromega plugin *)
-| "Show" "Zify" "UnOp" (* micromega plugin *)
-| "Show" "Zify" "CstOp" (* micromega plugin *)
-| "Show" "Zify" "BinRel" (* micromega plugin *)
-| "Show" "Zify" "UnOpSpec" (* micromega plugin *)
-| "Show" "Zify" "BinOpSpec" (* micromega plugin *)
| "Show" "Zify" "Spec" (* micromega plugin *)
| "Add" "Ring" ident ":" one_term OPT ( "(" LIST1 ring_mod SEP "," ")" ) (* ring plugin *)
| "Print" "Rings" (* ring plugin *)
| "Add" "Field" ident ":" one_term OPT ( "(" LIST1 field_mod SEP "," ")" ) (* ring plugin *)
| "Print" "Fields" (* ring plugin *)
-| "Number" "Notation" qualid qualid qualid ":" ident OPT numeral_modifier
| "Hint" "Cut" "[" hints_path "]" OPT ( ":" LIST1 ident )
-| "Typeclasses" "Transparent" LIST0 qualid
-| "Typeclasses" "Opaque" LIST0 qualid
-| "Typeclasses" "eauto" ":=" OPT "debug" OPT ( "(" eauto_search_strategy_name ")" ) OPT integer
-| "Proof" "with" ltac_expr OPT [ "using" section_subset_expr ]
-| "Proof" "using" section_subset_expr OPT [ "with" ltac_expr ]
+| "Prenex" "Implicits" LIST1 qualid (* SSR plugin *)
+| "Print" "Hint" "View" OPT ssrviewpos (* SSR plugin *)
+| "Hint" "View" OPT ssrviewpos LIST1 ( one_term OPT ( "|" natural ) ) (* SSR plugin *)
+| "Search" OPT LIST1 ( "-" [ string OPT ( "%" ident ) | one_pattern ] ) OPT ( "in" LIST1 ( OPT "-" qualid ) ) (* SSR plugin *)
+| "Typeclasses" "Transparent" LIST1 qualid
+| "Typeclasses" "Opaque" LIST1 qualid
+| "Typeclasses" "eauto" ":=" OPT "debug" OPT ( "(" [ "bfs" | "dfs" ] ")" ) OPT natural
+| "Proof" "with" ltac_expr OPT [ "using" section_var_expr ]
+| "Proof" "using" section_var_expr OPT [ "with" ltac_expr ]
| "Tactic" "Notation" OPT ( "(" "at" "level" natural ")" ) LIST1 ltac_production_item ":=" ltac_expr
| "Print" "Rewrite" "HintDb" ident
| "Print" "Ltac" qualid
@@ -911,8 +1041,8 @@ command: [
| "Set" "Firstorder" "Solver" ltac_expr
| "Print" "Firstorder" "Solver"
| "Function" fix_definition LIST0 ( "with" fix_definition )
-| "Functional" "Scheme" fun_scheme_arg LIST0 ( "with" fun_scheme_arg )
-| "Functional" "Case" fun_scheme_arg (* funind plugin *)
+| "Functional" "Scheme" func_scheme_def LIST0 ( "with" func_scheme_def )
+| "Functional" "Case" func_scheme_def (* funind plugin *)
| "Generate" "graph" "for" qualid (* funind plugin *)
| "Hint" "Rewrite" OPT [ "->" | "<-" ] LIST1 one_term OPT ( "using" ltac_expr ) OPT ( ":" LIST0 ident )
| "Derive" "Inversion_clear" ident "with" one_term OPT ( "Sort" sort_family )
@@ -921,8 +1051,9 @@ command: [
| "Derive" "Dependent" "Inversion_clear" ident "with" one_term "Sort" sort_family
| "Declare" "Left" "Step" one_term
| "Declare" "Right" "Step" one_term
-| "Numeral" "Notation" qualid qualid qualid ":" scope_name OPT numeral_modifier
-| "String" "Notation" qualid qualid qualid ":" scope_name
+| "Number" "Notation" qualid qualid qualid OPT ( "(" LIST1 number_modifier SEP "," ")" ) ":" scope_name
+| "Numeral" "Notation" qualid qualid qualid ":" scope_name OPT deprecated_number_modifier
+| "String" "Notation" qualid qualid qualid OPT ( "(" number_string_via ")" ) ":" scope_name
| "SubClass" ident_decl def_body
| thm_token ident_decl LIST0 binder ":" type LIST0 [ "with" ident_decl LIST0 binder ":" type ]
| assumption_token OPT ( "Inline" OPT ( "(" natural ")" ) ) [ LIST1 ( "(" assumpt ")" ) | assumpt ]
@@ -944,13 +1075,14 @@ command: [
| "CoInductive" inductive_definition LIST0 ( "with" inductive_definition )
| "Variant" variant_definition LIST0 ( "with" variant_definition )
| [ "Record" | "Structure" ] record_definition LIST0 ( "with" record_definition )
-| "Class" inductive_definition LIST0 ( "with" inductive_definition )
+| "Class" record_definition
+| "Class" singleton_class_definition
| "Module" OPT [ "Import" | "Export" ] ident LIST0 module_binder OPT of_module_type OPT ( ":=" LIST1 module_expr_inl SEP "<+" )
| "Module" "Type" ident LIST0 module_binder LIST0 ( "<:" module_type_inl ) OPT ( ":=" LIST1 module_type_inl SEP "<+" )
| "Declare" "Module" OPT [ "Import" | "Export" ] ident LIST0 module_binder ":" module_type_inl
| "Section" ident
| "End" ident
-| "Collection" ident ":=" section_subset_expr
+| "Collection" ident ":=" section_var_expr
| "Require" OPT [ "Import" | "Export" ] LIST1 qualid
| "From" dirpath "Require" OPT [ "Import" | "Export" ] LIST1 qualid
| "Import" LIST1 filtered_import
@@ -962,11 +1094,11 @@ command: [
| "Strategy" LIST1 [ strategy_level "[" LIST1 reference "]" ]
| "Canonical" OPT "Structure" ident_decl def_body
| "Canonical" OPT "Structure" reference
-| "Coercion" qualid OPT univ_decl def_body
+| "Coercion" ident OPT univ_decl def_body
| "Identity" "Coercion" ident ":" class ">->" class
| "Coercion" reference ":" class ">->" class
| "Context" LIST1 binder
-| "Instance" OPT ( ident_decl LIST0 binder ) ":" term OPT hint_info OPT [ ":=" "{" LIST0 field_def "}" | ":=" term ]
+| "Instance" OPT ( ident_decl LIST0 binder ) ":" type OPT hint_info OPT [ ":=" "{" LIST0 field_def "}" | ":=" term ]
| "Existing" "Instance" qualid OPT hint_info
| "Existing" "Instances" LIST1 qualid OPT [ "|" natural ]
| "Existing" "Class" qualid
@@ -975,6 +1107,7 @@ command: [
| "Generalizable" [ [ "Variable" | "Variables" ] LIST1 ident | "All" "Variables" | "No" "Variables" ]
| "Set" setting_name OPT [ integer | string ]
| "Unset" setting_name
+| "Import" "Prenex" "Implicits" (* SSR plugin *)
| "Open" "Scope" scope
| "Close" "Scope" scope
| "Delimit" "Scope" scope_name "with" scope_key
@@ -990,9 +1123,9 @@ command: [
| "Compute" term
| "Check" term
| "About" reference OPT univ_name_list
-| "SearchHead" one_term OPT ( [ "inside" | "outside" ] LIST1 qualid )
-| "SearchPattern" one_term OPT ( [ "inside" | "outside" ] LIST1 qualid )
-| "SearchRewrite" one_term OPT ( [ "inside" | "outside" ] LIST1 qualid )
+| "SearchHead" one_pattern OPT ( [ "inside" | "outside" ] LIST1 qualid )
+| "SearchPattern" one_pattern OPT ( [ "inside" | "outside" ] LIST1 qualid )
+| "SearchRewrite" one_pattern OPT ( [ "inside" | "outside" ] LIST1 qualid )
| "Search" LIST1 ( search_query ) OPT ( [ "inside" | "outside" ] LIST1 qualid )
| "Ltac2" OPT "mutable" OPT "rec" tac2def_body LIST0 ( "with" tac2def_body )
| "Ltac2" "Type" OPT "rec" tac2typ_def LIST0 ( "with" tac2typ_def )
@@ -1012,35 +1145,26 @@ command: [
| "Show" "Goal" natural "at" natural
]
-section_subset_expr: [
-| LIST0 starredidentref
-| ssexpr
-]
-
-ssexpr: [
-| "-" ssexpr50
-| ssexpr50
+section_var_expr: [
+| LIST0 starred_ident_ref
+| OPT "-" section_var_expr50
]
-ssexpr50: [
-| ssexpr0 "-" ssexpr0
-| ssexpr0 "+" ssexpr0
-| ssexpr0
+section_var_expr50: [
+| section_var_expr0 "-" section_var_expr0
+| section_var_expr0 "+" section_var_expr0
+| section_var_expr0
]
-ssexpr0: [
-| starredidentref
-| "(" LIST0 starredidentref ")"
-| "(" LIST0 starredidentref ")" "*"
-| "(" ssexpr ")"
-| "(" ssexpr ")" "*"
+section_var_expr0: [
+| starred_ident_ref
+| "(" section_var_expr ")" OPT "*"
]
-starredidentref: [
-| ident
-| ident "*"
-| "Type"
-| "Type" "*"
+starred_ident_ref: [
+| ident OPT "*"
+| "Type" OPT "*"
+| "All"
]
dirpath: [
@@ -1059,7 +1183,7 @@ search_query: [
search_item: [
| OPT ( [ "head" | "hyp" | "concl" | "headhyp" | "headconcl" ] ":" ) string OPT ( "%" scope_key )
-| OPT ( [ "head" | "hyp" | "concl" | "headhyp" | "headconcl" ] ":" ) one_term
+| OPT ( [ "head" | "hyp" | "concl" | "headhyp" | "headconcl" ] ":" ) one_pattern
| "is" ":" logical_kind
]
@@ -1088,7 +1212,7 @@ hint: [
| "Mode" qualid LIST1 [ "+" | "!" | "-" ]
| "Unfold" LIST1 qualid
| "Constructors" LIST1 qualid
-| "Extern" natural OPT one_term "=>" ltac_expr
+| "Extern" natural OPT one_pattern "=>" ltac_expr
]
tacdef_body: [
@@ -1137,13 +1261,11 @@ lident: [
destruction_arg: [
| natural
-| constr_with_bindings
| constr_with_bindings_arg
]
constr_with_bindings_arg: [
-| ">" constr_with_bindings
-| constr_with_bindings
+| OPT ">" one_term OPT ( "with" bindings ) (* SSR plugin *)
]
clause_dft_concl: [
@@ -1163,8 +1285,8 @@ hypident_occ: [
hypident: [
| ident
-| "(" "type" "of" ident ")"
-| "(" "value" "of" ident ")"
+| "(" "type" "of" ident ")" (* SSR plugin *)
+| "(" "value" "of" ident ")" (* SSR plugin *)
]
concl_occ: [
@@ -1262,11 +1384,6 @@ qhyp: [
| lident (* Ltac2 plugin *)
]
-int_or_id: [
-| ident
-| integer (* extraction plugin *)
-]
-
language: [
| "OCaml" (* extraction plugin *)
| "Haskell" (* extraction plugin *)
@@ -1274,10 +1391,6 @@ language: [
| "JSON" (* extraction plugin *)
]
-fun_scheme_arg: [
-| ident ":=" "Induction" "for" qualid "Sort" sort_family (* funind plugin *)
-]
-
ring_mod: [
| "decidable" one_term (* ring plugin *)
| "abstract" (* ring plugin *)
@@ -1298,11 +1411,133 @@ field_mod: [
| "completeness" one_term (* ring plugin *)
]
-numeral_modifier: [
+ssrmmod: [
+| "!" (* SSR plugin *)
+| "?" (* SSR plugin *)
+]
+
+mult: [
+| OPT natural ssrmmod (* SSR plugin *)
+]
+
+ssrwlogfwd: [
+| ":" LIST0 gen_item "/" term (* SSR plugin *)
+]
+
+ssrhintarg: [
+| "[" OPT ssrortacs "]" (* SSR plugin *)
+| ltac_expr (* SSR plugin *)
+]
+
+ssrortacs: [
+| OPT ltac_expr "|" OPT ssrortacs
+| ltac_expr (* SSR plugin *)
+]
+
+ssrhint3arg: [
+| "[" OPT ssrortacs "]" (* SSR plugin *)
+| ltac_expr3 (* SSR plugin *)
+]
+
+ssrdefbody: [
+| OPT ( ":" term ) ":=" term (* SSR plugin *)
+]
+
+i_item: [
+| "_" (* SSR plugin *)
+| "*" (* SSR plugin *)
+| ">" (* SSR plugin *)
+| ident
+| "?" (* SSR plugin *)
+| "+" (* SSR plugin *)
+| "++" (* SSR plugin *)
+| s_item (* SSR plugin *)
+| ssrdocc OPT [ "->" | "<-" ] (* SSR plugin *)
+| "-" (* SSR plugin *)
+| "-/=" (* SSR plugin *)
+| "-//" (* SSR plugin *)
+| "-//=" (* SSR plugin *)
+| "-/" integer [ "/=" | "/" | "/" integer "=" ] (* SSR plugin *)
+| ssrfwdview (* SSR plugin *)
+| "[:" LIST0 ident "]" (* SSR plugin *)
+| ssrblockpat (* SSR plugin *)
+]
+
+ssrhpats_wtransp: [
+| OPT ssripats (* SSR plugin *)
+| OPT ssripats "@" OPT ssripats (* SSR plugin *)
+]
+
+ssripats: [
+| LIST1 i_item (* SSR plugin *)
+]
+
+s_item: [
+| "//" (* SSR plugin *)
+| "/=" (* SSR plugin *)
+| "//=" (* SSR plugin *)
+| "/" natural "/" natural "=" (* SSR plugin *)
+| "/" natural "/=" (* SSR plugin *)
+]
+
+ssrdocc: [
+| "{" ssr_occurrences "}" (* SSR plugin *)
+| "{" LIST0 ident "}" (* SSR plugin *)
+]
+
+ssrfwdview: [
+| LIST1 ( "/" one_term ) (* SSR plugin *)
+]
+
+hat: [
+| "^" ident (* SSR plugin *)
+| "^~" ident (* SSR plugin *)
+| "^~" natural (* SSR plugin *)
+]
+
+ssriorpat: [
+| ssripats OPT ( [ "|" | "|-" ] ssriorpat ) (* SSR plugin *)
+]
+
+ssrblockpat: [
+| "[" hat "]" (* SSR plugin *)
+| "[" ssriorpat "]" (* SSR plugin *)
+| "[=" ssriorpat "]" (* SSR plugin *)
+]
+
+ssrbinder: [
+| ssrbvar (* SSR plugin *)
+| "(" LIST1 ssrbvar ":" term ")" (* SSR plugin *)
+| "(" ssrbvar OPT ( ":" term ) OPT ( ":=" term ) ")" (* SSR plugin *)
+| "of" term10 (* SSR plugin *)
+| "&" term10 (* SSR plugin *)
+]
+
+ssrbvar: [
+| ident (* SSR plugin *)
+| "_" (* SSR plugin *)
+]
+
+ssrhavefwd: [
+| ":" term OPT ( "by" ssrhintarg ) (* SSR plugin *)
+| ":" term ":=" OPT term (* SSR plugin *)
+]
+
+deprecated_number_modifier: [
| "(" "warning" "after" bignat ")"
| "(" "abstract" "after" bignat ")"
]
+number_modifier: [
+| "warning" "after" bignat
+| "abstract" "after" bignat
+| number_string_via
+]
+
+number_string_via: [
+| "via" qualid "mapping" "[" LIST1 [ qualid "=>" qualid | "[" qualid "]" "=>" qualid ] SEP "," "]"
+]
+
hints_path: [
| "(" hints_path ")"
| hints_path "*"
@@ -1314,11 +1549,6 @@ hints_path: [
| hints_path hints_path
]
-eauto_search_strategy_name: [
-| "bfs"
-| "dfs"
-]
-
class: [
| "Funclass"
| "Sortclass"
@@ -1390,7 +1620,7 @@ simple_tactic: [
| "eright" OPT ( "with" bindings )
| "constructor" OPT int_or_var OPT ( "with" bindings )
| "econstructor" OPT ( int_or_var OPT ( "with" bindings ) )
-| "specialize" constr_with_bindings OPT ( "as" simple_intropattern )
+| "specialize" one_term OPT ( "with" bindings ) OPT ( "as" simple_intropattern )
| "symmetry" OPT ( "in" in_clause )
| "split" OPT ( "with" bindings )
| "esplit" OPT ( "with" bindings )
@@ -1411,6 +1641,10 @@ simple_tactic: [
| "generalize" "dependent" one_term
| "replace" one_term "with" one_term OPT clause_dft_concl OPT ( "by" ltac_expr3 )
| "replace" OPT [ "->" | "<-" ] one_term OPT clause_dft_concl
+| "setoid_replace" one_term "with" one_term OPT ( "using" "relation" one_term ) OPT ( "in" ident ) OPT ( "at" LIST1 int_or_var ) OPT ( "by" ltac_expr3 )
+| OPT ( [ natural | "[" ident "]" ] ":" ) "{"
+| bullet
+| "}"
| "try" ltac_expr3
| "do" int_or_var ltac_expr3
| "timeout" int_or_var ltac_expr3
@@ -1422,11 +1656,14 @@ simple_tactic: [
| "infoH" ltac_expr3
| "abstract" ltac_expr2 OPT ( "using" ident )
| "only" selector ":" ltac_expr3
+| "do" "[" ssrortacs "]" OPT ssr_in (* SSR plugin *)
+| "do" OPT int_or_var ssrmmod [ ltac_expr3 | "[" ssrortacs "]" (* SSR plugin *) ] OPT ssr_in (* SSR plugin *)
| "tryif" ltac_expr "then" ltac_expr "else" ltac_expr2
| "first" "[" LIST0 ltac_expr SEP "|" "]"
| "solve" "[" LIST0 ltac_expr SEP "|" "]"
| "idtac" LIST0 [ ident | string | natural ]
| [ "fail" | "gfail" ] OPT int_or_var LIST0 [ ident | string | natural ]
+| ltac_expr ssrintros (* SSR plugin *)
| "fun" LIST1 name "=>" ltac_expr
| "eval" red_expr "in" term
| "context" ident "[" term "]"
@@ -1456,7 +1693,7 @@ simple_tactic: [
| "decompose" "sum" one_term
| "decompose" "record" one_term
| "absurd" one_term
-| "contradiction" OPT constr_with_bindings
+| "contradiction" OPT ( one_term OPT ( "with" bindings ) )
| "autorewrite" OPT "*" "with" LIST1 ident OPT clause_dft_concl OPT ( "using" ltac_expr )
| "rewrite" "*" OPT [ "->" | "<-" ] one_term OPT ( "in" ident ) OPT ( "at" occurrences OPT ( "by" ltac_expr3 ) )
| "rewrite" "*" OPT [ "->" | "<-" ] one_term "at" occurrences "in" ident OPT ( "by" ltac_expr3 )
@@ -1465,7 +1702,7 @@ simple_tactic: [
| "notypeclasses" "refine" one_term
| "simple" "notypeclasses" "refine" one_term
| "solve_constraints"
-| "subst" OPT ( LIST1 ident )
+| "subst" LIST0 ident
| "simple" "subst"
| "evar" "(" ident ":" term ")"
| "evar" one_term
@@ -1525,13 +1762,12 @@ simple_tactic: [
| "debug" "eauto" OPT int_or_var OPT int_or_var OPT auto_using OPT hintbases
| "info_eauto" OPT int_or_var OPT int_or_var OPT auto_using OPT hintbases
| "dfs" "eauto" OPT int_or_var OPT auto_using OPT hintbases
+| "bfs" "eauto" OPT int_or_var OPT auto_using OPT hintbases
| "autounfold" OPT hintbases OPT clause_dft_concl
| "autounfold_one" OPT hintbases OPT ( "in" ident )
| "unify" one_term one_term OPT ( "with" ident )
| "convert_concl_no_check" one_term
-| "typeclasses" "eauto" "bfs" OPT int_or_var "with" LIST1 ident
-| "typeclasses" "eauto" OPT int_or_var "with" LIST1 ident
-| "typeclasses" "eauto" OPT int_or_var
+| "typeclasses" "eauto" OPT "bfs" OPT int_or_var OPT ( "with" LIST1 ident )
| "head_of_constr" ident one_term
| "not_evar" one_term
| "is_ground" one_term
@@ -1540,9 +1776,9 @@ simple_tactic: [
| "progress_evars" ltac_expr
| "rewrite_strat" rewstrategy OPT ( "in" ident )
| "rewrite_db" ident OPT ( "in" ident )
-| "substitute" OPT [ "->" | "<-" ] constr_with_bindings
-| "setoid_rewrite" OPT [ "->" | "<-" ] constr_with_bindings OPT ( "at" occurrences ) OPT ( "in" ident )
-| "setoid_rewrite" OPT [ "->" | "<-" ] constr_with_bindings "in" ident "at" occurrences
+| "substitute" OPT [ "->" | "<-" ] one_term OPT ( "with" bindings )
+| "setoid_rewrite" OPT [ "->" | "<-" ] one_term OPT ( "with" bindings ) OPT ( "at" occurrences ) OPT ( "in" ident )
+| "setoid_rewrite" OPT [ "->" | "<-" ] one_term OPT ( "with" bindings ) "in" ident "at" occurrences
| "setoid_symmetry" OPT ( "in" ident )
| "setoid_reflexivity"
| "setoid_transitivity" one_term
@@ -1555,8 +1791,8 @@ simple_tactic: [
| "eapply" LIST1 constr_with_bindings_arg SEP "," OPT in_hyp_as
| "simple" "apply" LIST1 constr_with_bindings_arg SEP "," OPT in_hyp_as
| "simple" "eapply" LIST1 constr_with_bindings_arg SEP "," OPT in_hyp_as
-| "elim" constr_with_bindings_arg OPT ( "using" constr_with_bindings )
-| "eelim" constr_with_bindings_arg OPT ( "using" constr_with_bindings )
+| "elim" constr_with_bindings_arg OPT ( "using" one_term OPT ( "with" bindings ) )
+| "eelim" constr_with_bindings_arg OPT ( "using" one_term OPT ( "with" bindings ) )
| "case" induction_clause_list
| "ecase" induction_clause_list
| "fix" ident natural OPT ( "with" LIST1 fixdecl )
@@ -1616,11 +1852,11 @@ simple_tactic: [
| "rtauto"
| "congruence" OPT natural OPT ( "with" LIST1 one_term )
| "f_equal"
-| "firstorder" OPT ltac_expr firstorder_rhs
+| "firstorder" OPT ltac_expr OPT ( "using" LIST1 qualid SEP "," ) OPT ( "with" LIST1 ident )
| "gintuition" OPT ltac_expr
| "functional" "inversion" [ ident | natural ] OPT qualid (* funind plugin *)
-| "functional" "induction" term OPT fun_ind_using OPT with_names (* funind plugin *)
-| "soft" "functional" "induction" LIST1 one_term OPT fun_ind_using OPT with_names (* funind plugin *)
+| "functional" "induction" term OPT ( "using" one_term OPT ( "with" bindings ) ) OPT ( "as" simple_intropattern ) (* funind plugin *)
+| "soft" "functional" "induction" LIST1 one_term OPT ( "using" one_term OPT ( "with" bindings ) ) OPT ( "as" simple_intropattern ) (* funind plugin *)
| "psatz_Z" OPT int_or_var ltac_expr
| "xlia" ltac_expr (* micromega plugin *)
| "xnlia" ltac_expr (* micromega plugin *)
@@ -1643,12 +1879,47 @@ simple_tactic: [
| "protect_fv" string OPT ( "in" ident )
| "ring_lookup" ltac_expr0 "[" LIST0 one_term "]" LIST1 one_term (* ring plugin *)
| "field_lookup" ltac_expr "[" LIST0 one_term "]" LIST1 one_term (* ring plugin *)
+| "ring_lookup" ltac_expr0 "[" LIST0 one_term "]" LIST1 one_term (* ring plugin *)
+| "field_lookup" ltac_expr "[" LIST0 one_term "]" LIST1 one_term (* ring plugin *)
+| "by" ssrhintarg (* SSR plugin *)
+| "clear" natural (* SSR plugin *)
+| "move" OPT ( OPT ssrarg [ "->" | "<-" ] ) (* SSR plugin *)
+| "move" ssrarg OPT ssr_in (* SSR plugin *)
+| "case" OPT ( ssrarg OPT ssr_in ) (* SSR plugin *)
+| "elim" OPT ( ssrarg OPT ssr_in ) (* SSR plugin *)
+| "apply" OPT ssrapplyarg (* SSR plugin *)
+| "exact" [ ":" ssragen OPT ssragens | ssrbwdview OPT ssrclear | ssrclear ] (* SSR plugin *)
+| "exact" (* SSR plugin *)
+| "exact" "<:" term (* SSR plugin *)
+| "congr" OPT natural one_term OPT ssrdgens (* SSR plugin *)
+| "ssrinstancesofruleL2R" term (* SSR plugin *)
+| "ssrinstancesofruleR2L" term (* SSR plugin *)
+| "rewrite" LIST1 rewrite_item OPT ssr_in (* SSR plugin *)
+| "unlock" LIST0 ( OPT ( "{" ssr_occurrences "}" ) term ) OPT ssr_in (* SSR plugin *)
+| "pose" "fix" ssrbvar LIST0 ssrbinder OPT ( "{" "struct" ident "}" ) ssrdefbody (* SSR plugin *)
+| "pose" "cofix" ssrbvar LIST0 ssrbinder ssrdefbody (* SSR plugin *)
+| "pose" ident LIST0 ssrbinder ssrdefbody (* SSR plugin *)
+| "set" ident OPT ( ":" term ) ":=" [ "{" ssr_occurrences "}" cpattern | lcpattern ] OPT ssr_in (* SSR plugin *)
+| "abstract" ssrdgens (* SSR plugin *)
+| "have" ssrhpats_wtransp LIST0 ssrbinder ssrhavefwd (* SSR plugin *)
+| "have" [ "suff" | "suffices" ] OPT ssripats ssrhavefwd (* SSR plugin *)
+| [ "suff" | "suffices" ] OPT ( "have" OPT ssripats ) ssrhavefwd (* SSR plugin *)
+| [ "suff" | "suffices" ] ssrsufffwd (* SSR plugin *)
+| [ "wlog" | "without loss" ] OPT [ "suff" | "suffices" ] OPT ssripats ssrwlogfwd OPT ( "by" ssrhintarg ) (* SSR plugin *)
+| [ "gen" | "generally" ] "have" OPT ssrclear OPT ( [ ident | "_" ] "," ) OPT ssripats ssrwlogfwd OPT ( "by" ssrhintarg ) (* SSR plugin *)
+| "under" rewrite_item OPT ssrintros OPT ( "do" ssrhint3arg ) (* SSR plugin *)
+| "ssrinstancesoftpat" ssr_one_term_pattern (* SSR plugin *)
+| ltac_expr ";" "first" ssr_first_else (* SSR plugin *)
+| ltac_expr ";" "first" ssrseqarg (* SSR plugin *)
+| ltac_expr ";" "last" ssrseqarg (* SSR plugin *)
| match_key OPT "reverse" "goal" "with" OPT "|" LIST1 ( goal_pattern "=>" ltac_expr ) SEP "|" "end"
| match_key ltac_expr "with" OPT "|" LIST1 ( match_pattern "=>" ltac_expr ) SEP "|" "end"
| "classical_left"
| "classical_right"
| "contradict" ident
+| "dintuition" OPT ltac_expr
| "discrR"
+| "dtauto"
| "easy"
| "exfalso"
| "inversion_sigma"
@@ -1656,6 +1927,7 @@ simple_tactic: [
| "lra"
| "nia"
| "nra"
+| "over" (* SSR plugin *)
| "split_Rabs"
| "split_Rmult"
| "tauto"
@@ -1663,15 +1935,16 @@ simple_tactic: [
| "zify"
| "assert_fails" ltac_expr3
| "assert_succeeds" ltac_expr3
-| "field" OPT ( "[" LIST1 term "]" )
-| "field_simplify" OPT ( "[" LIST1 term "]" ) LIST1 term OPT ( "in" ident )
-| "field_simplify_eq" OPT ( "[" LIST1 term "]" ) OPT ( "in" ident )
+| "field" OPT ( "[" LIST1 one_term "]" )
+| "field_simplify" OPT ( "[" LIST1 one_term "]" ) LIST1 one_term OPT ( "in" ident )
+| "field_simplify_eq" OPT ( "[" LIST1 one_term "]" ) OPT ( "in" ident )
| "intuition" OPT ltac_expr
-| "nsatz" OPT ( "with" "radicalmax" ":=" term "strategy" ":=" term "parameters" ":=" term "variables" ":=" term )
-| "psatz" term OPT int_or_var
-| "ring" OPT ( "[" LIST1 term "]" )
-| "ring_simplify" OPT ( "[" LIST1 term "]" ) LIST1 term OPT ( "in" ident )
+| "nsatz" OPT ( "with" "radicalmax" ":=" one_term "strategy" ":=" one_term "parameters" ":=" one_term "variables" ":=" one_term )
+| "psatz" one_term OPT int_or_var
+| "ring" OPT ( "[" LIST1 one_term "]" )
+| "ring_simplify" OPT ( "[" LIST1 one_term "]" ) LIST1 one_term OPT ( "in" ident )
| "match" ltac2_expr5 "with" OPT ltac2_branches "end"
+| "if" ltac2_expr5 "then" ltac2_expr5 "else" ltac2_expr5
| qualid LIST1 tactic_arg
]
@@ -1705,20 +1978,25 @@ as_name: [
| "as" ident
]
+oriented_rewriter: [
+| OPT [ "->" | "<-" ] rewriter
+]
+
rewriter: [
| OPT natural OPT [ "?" | "!" ] constr_with_bindings_arg
]
-oriented_rewriter: [
-| OPT [ "->" | "<-" ] rewriter
+induction_clause_list: [
+| LIST1 induction_clause SEP "," OPT ( "using" one_term OPT ( "with" bindings ) ) OPT opt_clause
]
induction_clause: [
| destruction_arg OPT as_or_and_ipat OPT eqn_ipat OPT opt_clause
]
-induction_clause_list: [
-| LIST1 induction_clause SEP "," OPT ( "using" constr_with_bindings ) OPT opt_clause
+opt_clause: [
+| "in" in_clause
+| "at" occs_nums
]
auto_using: [
@@ -1764,13 +2042,8 @@ simple_intropattern_closed: [
| naming_intropattern
]
-simple_binding: [
-| "(" ident ":=" term ")"
-| "(" natural ":=" term ")"
-]
-
bindings: [
-| LIST1 simple_binding
+| LIST1 ( "(" [ ident | natural ] ":=" term ")" )
| LIST1 one_term
]
@@ -1862,7 +2135,7 @@ q_rewriting: [
]
ltac2_oriented_rewriter: [
-| [ "->" | "<-" ] ltac2_rewriter (* Ltac2 plugin *)
+| OPT [ "->" | "<-" ] ltac2_rewriter (* Ltac2 plugin *)
]
ltac2_rewriter: [
@@ -2148,9 +2421,9 @@ tac2mode: [
| "Compute" term
| "Check" term
| "About" reference OPT univ_name_list
-| "SearchHead" one_term OPT ( [ "inside" | "outside" ] LIST1 qualid )
-| "SearchPattern" one_term OPT ( [ "inside" | "outside" ] LIST1 qualid )
-| "SearchRewrite" one_term OPT ( [ "inside" | "outside" ] LIST1 qualid )
+| "SearchHead" one_pattern OPT ( [ "inside" | "outside" ] LIST1 qualid )
+| "SearchPattern" one_pattern OPT ( [ "inside" | "outside" ] LIST1 qualid )
+| "SearchRewrite" one_pattern OPT ( [ "inside" | "outside" ] LIST1 qualid )
| "Search" LIST1 ( search_query ) OPT ( [ "inside" | "outside" ] LIST1 qualid )
]
@@ -2158,11 +2431,6 @@ clause_dft_all: [
| "in" in_clause
]
-opt_clause: [
-| "in" in_clause
-| "at" occs_nums
-]
-
in_hyp_as: [
| "in" ident OPT as_ipat
]
@@ -2184,28 +2452,14 @@ cofixdecl: [
| "(" ident LIST0 simple_binder ":" term ")"
]
-constr_with_bindings: [
-| one_term OPT ( "with" bindings )
-]
-
conversion: [
| one_term
| one_term "with" one_term
| one_term "at" occs_nums "with" one_term
]
-firstorder_using: [
-| "using" qualid
-| "using" qualid "," LIST1 qualid SEP ","
-| "using" qualid qualid LIST0 qualid
-]
-
-fun_ind_using: [
-| "using" constr_with_bindings (* funind plugin *)
-]
-
-with_names: [
-| "as" simple_intropattern (* funind plugin *)
+func_scheme_def: [
+| ident ":=" "Induction" "for" qualid "Sort" sort_family (* funind plugin *)
]
occurrences: [
@@ -2309,6 +2563,34 @@ tactic_atom: [
| "()"
]
+ssrseqarg: [
+| ssrseqidx "[" ssrortacs "]" OPT ssrorelse (* SSR plugin *)
+| OPT ssrseqidx ssrswap (* SSR plugin *)
+| ltac_expr3 (* SSR plugin *)
+]
+
+ssrseqidx: [
+| ident (* SSR plugin *)
+| natural (* SSR plugin *)
+]
+
+ssrorelse: [
+| "||" ltac_expr2 (* SSR plugin *)
+]
+
+ssrswap: [
+| "first" (* SSR plugin *)
+| "last" (* SSR plugin *)
+]
+
+ssr_first_else: [
+| ssr_first OPT ssrorelse (* SSR plugin *)
+]
+
+ssr_first: [
+| "[" LIST0 ltac_expr SEP "|" "]" LIST0 ssrintros (* SSR plugin *)
+]
+
let_clause: [
| name ":=" ltac_expr
| ident LIST1 name ":=" ltac_expr