aboutsummaryrefslogtreecommitdiff
path: root/doc/sphinx/language/core
diff options
context:
space:
mode:
Diffstat (limited to 'doc/sphinx/language/core')
-rw-r--r--doc/sphinx/language/core/basic.rst520
-rw-r--r--doc/sphinx/language/core/index.rst32
-rw-r--r--doc/sphinx/language/core/records.rst315
-rw-r--r--doc/sphinx/language/core/sections.rst104
4 files changed, 958 insertions, 13 deletions
diff --git a/doc/sphinx/language/core/basic.rst b/doc/sphinx/language/core/basic.rst
new file mode 100644
index 0000000000..9473cc5a15
--- /dev/null
+++ b/doc/sphinx/language/core/basic.rst
@@ -0,0 +1,520 @@
+=============================
+Basic notions and conventions
+=============================
+
+This section provides some essential notions and conventions for reading
+the manual.
+
+We start by explaining the syntax and lexical conventions used in the
+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.
+
+Syntax and lexical conventions
+------------------------------
+
+Syntax conventions
+~~~~~~~~~~~~~~~~~~
+
+The syntax described in this documentation is equivalent to that
+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
+black (e.g. :n:`forall`), whereas the nonterminals are green, italic
+and hyperlinked (e.g. :n:`@term`). Some syntax is represented
+graphically using the following kinds of blocks:
+
+:n:`{? item }`
+ An optional item.
+
+:n:`{+ item }`
+ A list of one or more items.
+
+:n:`{* item }`
+ An optional list of items.
+
+:n:`{+s item}`
+ A list of one or more items separated by "s" (e.g. :n:`item__1 s item__2 s item__3`).
+
+:n:`{*s item}`
+ An optional list of items separated by "s".
+
+:n:`{| item__1 | item__2 | ... }`
+ Alternatives (either :n:`item__1` or :n:`item__2` or ...).
+
+`Precedence levels
+<https://en.wikipedia.org/wiki/Order_of_operations>`_ that are
+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
+ system <syntax-extensions-and-notation-scopes>` can extend the
+ syntax at run time. Some notations are defined in the prelude,
+ which is loaded by default. The documented grammar doesn't include
+ these notations. Precedence levels not used by the base grammar
+ are omitted from the documentation, even though they could still be
+ populated by notations or plugins.
+
+ Furthermore, some parsing rules are only activated in certain
+ contexts (:ref:`interactive proof mode <proofhandling>`,
+ :ref:`custom entries <custom-entries>`...).
+
+.. warning::
+
+ 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
+ `SerAPI <https://github.com/ejgallego/coq-serapi>`_.
+
+.. seealso:: :cmd:`Print Grammar`
+
+.. _lexical-conventions:
+
+Lexical conventions
+~~~~~~~~~~~~~~~~~~~
+
+Blanks
+ Space, newline and horizontal tab are considered blanks.
+ Blanks are ignored but they separate tokens.
+
+Comments
+ Comments are enclosed between ``(*`` and ``*)``. They can be nested.
+ They can contain any character. However, embedded :n:`@string` literals must be
+ correctly closed. Comments are treated as blanks.
+
+Identifiers
+ Identifiers, written :n:`@ident`, are sequences of letters, digits, ``_`` and
+ ``'``, that do not start with a digit or ``'``. That is, they are
+ recognized by the following grammar (except that the string ``_`` is reserved;
+ it is not a valid identifier):
+
+ .. insertprodn ident subsequent_letter
+
+ .. prodn::
+ ident ::= @first_letter {* @subsequent_letter }
+ first_letter ::= {| a .. z | A .. Z | _ | @unicode_letter }
+ subsequent_letter ::= {| @first_letter | @digit | ' | @unicode_id_part }
+
+ All characters are meaningful. In particular, identifiers are case-sensitive.
+ :production:`unicode_letter` non-exhaustively includes Latin,
+ Greek, Gothic, Cyrillic, Arabic, Hebrew, Georgian, Hangul, Hiragana
+ and Katakana characters, CJK ideographs, mathematical letter-like
+ symbols and non-breaking space. :production:`unicode_id_part`
+ non-exhaustively includes symbols for prime letters and subscripts.
+
+Numerals
+ Numerals are sequences of digits with an optional fractional part
+ and exponent, optionally preceded by a minus sign. :n:`@int` is an integer;
+ a numeral without fractional or exponent parts. :n:`@num` is a non-negative
+ integer. Underscores embedded in the digits are ignored, for example
+ ``1_000_000`` is the same as ``1000000``.
+
+ .. insertprodn numeral digit
+
+ .. prodn::
+ numeral ::= {+ @digit } {? . {+ @digit } } {? {| e | E } {? {| + | - } } {+ @digit } }
+ int ::= {? - } {+ @digit }
+ num ::= {+ @digit }
+ digit ::= 0 .. 9
+
+Strings
+ Strings begin and end with ``"`` (double quote). Use ``""`` to represent
+ a double quote character within a string. In the grammar, strings are
+ identified with :production:`string`.
+
+Keywords
+ The following character sequences are reserved keywords that cannot be
+ used as identifiers::
+
+ _ Axiom CoFixpoint Definition Fixpoint Hypothesis Parameter Prop
+ SProp Set Theorem Type Variable as at cofix discriminated else end
+ fix for forall fun if in let match return then where with
+
+ Note that notations and plugins may define additional keywords.
+
+Other tokens
+ The set of
+ tokens defined at any given time can vary because the :cmd:`Notation`
+ command can define new tokens. A :cmd:`Require` command may load more notation definitions,
+ while the end of a :cmd:`Section` may remove notations. Some notations
+ are defined in the standard library (see :ref:`thecoqlibrary`) and are generally
+ loaded automatically at startup time.
+
+ Here are the character sequences that |Coq| directly defines as tokens
+ without using :cmd:`Notation`::
+
+ ! #[ % & ' ( () (bfs) (dfs) ) * ** + , - ->
+ . .( .. ... / : ::= := :> :>> ; < <+ <- <:
+ <<: <= = => > >-> >= ? @ @{ [ [= ] _
+ `( `{ { {| | |- || }
+
+ When multiple tokens match the beginning of a sequence of characters,
+ the longest matching token is used.
+ Occasionally you may need to insert spaces to separate tokens. For example,
+ if ``~`` and ``~~`` are both defined as tokens, the inputs ``~ ~`` and
+ ``~~`` generate different tokens, whereas if `~~` is not defined, then the
+ two inputs are equivalent.
+
+Essential vocabulary
+--------------------
+
+This section presents the most essential notions to understand the
+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.
+
+.. glossary::
+
+ term
+
+ 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
+ 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>`.
+
+ .. insertprodn term qualid_annotated
+
+ .. prodn::
+ term ::= @term_forall_or_fun
+ | @term_let
+ | @term_if
+ | @term_fix
+ | @term_cofix
+ | @term100
+ term100 ::= @term_cast
+ | @term10
+ term10 ::= @term_application
+ | @one_term
+ one_term ::= @term_explicit
+ | @term1
+ term1 ::= @term_projection
+ | @term_scope
+ | @term0
+ term0 ::= @qualid_annotated
+ | @sort
+ | @primitive_notations
+ | @term_evar
+ | @term_match
+ | @term_record
+ | @term_generalizing
+ | @term_ltac
+ | ( @term )
+ qualid_annotated ::= @qualid {? @univ_annot }
+
+ .. note::
+
+ Many :term:`commands <command>` and :term:`tactics <tactic>`
+ use :n:`@one_term` (in the syntax of their arguments) rather
+ than :n:`@term`. The former need to be enclosed in
+ parentheses unless they're very simple, such as a single
+ identifier. This avoids confusing a space-separated list of
+ terms or identifiers with a :n:`@term_application`.
+
+ type
+
+ 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 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
+ 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,
+ but not all terms are types:
+
+ .. insertprodn type type
+
+ .. prodn::
+ type ::= @term
+
+ Intuitively, types may be viewed as sets containing terms. We
+ say that a type is :gdef:`inhabited` if it contains at least one
+ term (i.e. if we can find a term which is associated with this
+ type). We call such terms :gdef:`witness`\es. Note that deciding
+ whether a type is inhabited is `undecidable
+ <https://en.wikipedia.org/wiki/Undecidable_problem>`_.
+
+ Formally, types can be used to construct logical foundations for
+ 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
+ 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
+ :term:`commands <command>` or :term:`tactics <tactic>`, generally
+ terminated with a period and optionally decorated with
+ :term:`attributes <attribute>`.
+
+ .. insertprodn document sentence
+
+ .. prodn::
+ document ::= {* @sentence }
+ sentence ::= {? @attributes } @command .
+ | {? @attributes } {? @num : } @query_command .
+ | {? @attributes } {? @toplevel_selector } @ltac_expr {| . | ... }
+ | @control_command
+
+ :n:`@ltac_expr` syntax supports both simple and compound
+ :term:`tactics <tactic>`. For example: ``split`` is a simple
+ tactic while ``split; auto`` combines two simple tactics.
+
+ command
+
+ 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.
+
+ By convention, command names begin with uppercase letters.
+ Commands appear in the HTML documentation in blue or gray boxes
+ after the label "Command". In the pdf, they appear after the
+ boldface label "Command:". Commands are listed in the
+ :ref:`command_index`. Example:
+
+ .. cmd:: Comments {* @string }
+
+ This command prints "Comments ok" and does not change anything
+ to 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
+ and before any subsequent proof-terminating command such as
+ :cmd:`Qed`. See :ref:`proofhandling` for more on proof mode.
+
+ By convention, tactic names begin with lowercase letters. Tactic
+ appear in the HTML documentation in blue or gray boxes after the
+ label "Tactic". In the pdf, they appear after the boldface label
+ "Tactic:". Tactics are listed in the :ref:`tactic_index`.
+
+Settings
+--------
+
+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
+document or project.
+
+.. _attributes:
+
+Attributes
+~~~~~~~~~~
+
+An :gdef:`attribute` modifies the behavior of a single sentence.
+Syntactically, most commands and tactics can be decorated with
+attributes (cf. :n:`@sentence`), but attributes not supported by the
+command or tactic will trigger :warn:`This command does not support
+this attribute`.
+
+.. insertprodn attributes legacy_attr
+
+.. prodn::
+ attributes ::= {* #[ {*, @attribute } ] } {* @legacy_attr }
+ attribute ::= @ident {? @attr_value }
+ attr_value ::= = @string
+ | ( {*, @attribute } )
+ legacy_attr ::= {| Local | Global }
+ | {| Polymorphic | Monomorphic }
+ | {| Cumulative | NonCumulative }
+ | Private
+ | Program
+
+The order of top-level attributes doesn't affect their meaning. ``#[foo,bar]``, ``#[bar,foo]``,
+``#[foo]#[bar]`` and ``#[bar]#[foo]`` are equivalent.
+
+The legacy attributes (:n:`@legacy_attr`) provide an older, alternate syntax
+for certain attributes. They are equivalent to new attributes as follows:
+
+================ ================================
+Legacy attribute New attribute
+================ ================================
+`Local` :attr:`local`
+`Global` :attr:`global`
+`Polymorphic` :attr:`universes(polymorphic)`
+`Monomorphic` :attr:`universes(monomorphic)`
+`Cumulative` :attr:`universes(cumulative)`
+`NonCumulative` :attr:`universes(noncumulative)`
+`Private` :attr:`private(matching)`
+`Program` :attr:`program`
+================ ================================
+
+Attributes appear in the HTML documentation in blue or gray boxes
+after the label "Attribute". In the pdf, they appear after the
+boldface label "Attribute:". Attributes are listed in the
+:ref:`attribute_index`.
+
+.. warn:: This command does not support this attribute: @ident.
+ :name: This command does not support this attribute
+
+ This warning is configured to behave as an error by default. You
+ may turn it into a normal warning by using the :opt:`Warnings` option:
+
+ .. coqtop:: none
+
+ Set Silent.
+
+ .. coqtop:: all warn
+
+ Set Warnings "unsupported-attributes".
+ #[ foo ] Comments.
+
+.. _flags-options-tables:
+
+Flags, Options and Tables
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+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):
+
+* A :gdef:`flag` has a boolean value, such as :flag:`Universe Polymorphism`.
+* An :gdef:`option` generally has a numeric or string value, such as :opt:`Firstorder Depth`.
+* A :gdef:`table` contains a set of :token:`string`\s or :token:`qualid`\s.
+* In addition, some commands provide settings, such as :cmd:`Extraction Language`.
+
+.. FIXME Convert "Extraction Language" to an option.
+
+Flags, options and tables are identified by a series of identifiers, each with an initial
+capital letter.
+
+Flags, options and tables appear in the HTML documentation in blue or
+gray boxes after the labels "Flag", "Option" and "Table". In the pdf,
+they appear after a boldface label. They are listed in the
+:ref:`options_index`.
+
+.. cmd:: Set @setting_name {? {| @int | @string } }
+ :name: Set
+
+ .. insertprodn setting_name setting_name
+
+ .. prodn::
+ setting_name ::= {+ @ident }
+
+ If :n:`@setting_name` is a flag, no value may be provided; the flag
+ is set to on.
+ If :n:`@setting_name` is an option, a value of the appropriate type
+ must be provided; the option is set to the specified value.
+
+ This command supports the :attr:`local`, :attr:`global` and :attr:`export` attributes.
+ They are described :ref:`here <set_unset_scope_qualifiers>`.
+
+ .. warn:: There is no flag or option with this name: "@setting_name".
+
+ 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.
+ To preserve the same behavior, they may need to set some
+ compatibility flags or options that did not exist in previous
+ |Coq| versions.
+
+.. cmd:: Unset @setting_name
+ :name: Unset
+
+ If :n:`@setting_name` is a flag, it is set to off. If :n:`@setting_name` is an option, it is
+ set to its default value.
+
+ This command supports the :attr:`local`, :attr:`global` and :attr:`export` attributes.
+ They are described :ref:`here <set_unset_scope_qualifiers>`.
+
+.. cmd:: Add @setting_name {+ {| @qualid | @string } }
+
+ Adds the specified values to the table :n:`@setting_name`.
+
+.. cmd:: Remove @setting_name {+ {| @qualid | @string } }
+
+ Removes the specified value from the table :n:`@setting_name`.
+
+.. cmd:: Test @setting_name {? for {+ {| @qualid | @string } } }
+
+ If :n:`@setting_name` is a flag or option, prints its current value.
+ If :n:`@setting_name` is a table: if the `for` clause is specified, reports
+ whether the table contains each specified value, otherwise this is equivalent to
+ :cmd:`Print Table`. The `for` clause is not valid for flags and options.
+
+ .. exn:: There is no flag, option or table with this name: "@setting_name".
+
+ This error message is raised when calling the :cmd:`Test`
+ command (without the `for` clause), or the :cmd:`Print Table`
+ command, for an unknown :n:`@setting_name`.
+
+ .. exn:: There is no qualid-valued table with this name: "@setting_name".
+ There is no string-valued table with this name: "@setting_name".
+
+ These error messages are raised when calling the :cmd:`Add` or
+ :cmd:`Remove` commands, or the :cmd:`Test` command with the
+ `for` clause, if :n:`@setting_name` is unknown or does not have
+ the right type.
+
+.. cmd:: Print Options
+
+ Prints the current value of all flags and options, and the names of all tables.
+
+.. cmd:: Print Table @setting_name
+
+ Prints the values in the table :n:`@setting_name`.
+
+.. cmd:: Print Tables
+
+ A synonym for :cmd:`Print Options`.
+
+.. _set_unset_scope_qualifiers:
+
+Locality attributes supported by :cmd:`Set` and :cmd:`Unset`
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The :cmd:`Set` and :cmd:`Unset` commands support the :attr:`local`,
+:attr:`global` and :attr:`export` locality attributes:
+
+* no attribute: the original setting is *not* restored at the end of
+ the current module or section.
+* :attr:`local` (or alternatively, the ``Local`` prefix): the setting
+ is applied within the current module or section. The original value
+ of the setting is restored at the end of the current module or
+ section.
+* :attr:`export` (or alternatively, the ``Export`` prefix): similar to
+ :attr:`local`, the original value of the setting is restored at the
+ end of the current module or section. In addition, if the value is
+ set in a module, then :cmd:`Import`\-ing the module sets the option
+ or flag.
+* :attr:`global` (or alternatively, the ``Global`` prefix): the
+ original setting is *not* restored at the end of the current module
+ or section. In addition, if the value is set in a file, then
+ :cmd:`Require`\-ing the file sets the option.
+
+Newly opened modules and sections inherit the current settings.
+
+.. note::
+
+ We discourage using the :attr:`global` attribute with the :cmd:`Set` and
+ :cmd:`Unset` commands. If your goal is to define
+ project-wide settings, you should rather use the command-line
+ arguments ``-set`` and ``-unset`` for setting flags and options
+ (cf. :ref:`command-line-options`).
diff --git a/doc/sphinx/language/core/index.rst b/doc/sphinx/language/core/index.rst
index 07dcfff444..5e83672463 100644
--- a/doc/sphinx/language/core/index.rst
+++ b/doc/sphinx/language/core/index.rst
@@ -6,23 +6,26 @@ Core language
At the heart of the Coq proof assistant is the Coq kernel. While
users have access to a language with many convenient features such as
-notations, implicit arguments, etc. (that are presented in the
-:ref:`next chapter <extensions>`), such complex terms get translated
-down to a core language (the Calculus of Inductive Constructions) that
-the kernel understands, and which we present here. Furthermore, while
-users can build proofs interactively using tactics (see Chapter
+:ref:`notations <syntax-extensions-and-notation-scopes>`,
+:ref:`implicit arguments <ImplicitArguments>`, etc. (presented in the
+:ref:`next chapter <extensions>`), those features are translated into
+the core language (the Calculus of Inductive Constructions) that the
+kernel understands, which we present here. Furthermore, while users
+can build proofs interactively using tactics (see Chapter
:ref:`writing-proofs`), the role of these tactics is to incrementally
build a "proof term" which the kernel will verify. More precisely, a
-proof term is a term of the Calculus of Inductive Constructions whose
-type corresponds to a theorem statement. The kernel is a type checker
-which verifies that terms have their expected type.
+proof term is a :term:`term` of the Calculus of Inductive
+Constructions whose :term:`type` corresponds to a theorem statement.
+The kernel is a type checker which verifies that terms have their
+expected types.
-This separation between the kernel on the one hand and the elaboration
-engine and tactics on the other hand follows what is known as the "de
-Bruijn criterion" (keeping a small and well delimited trusted code
+This separation between the kernel on one hand and the
+:ref:`elaboration engine <extensions>` and :ref:`tactics
+<writing-proofs>` on the other follows what is known as the :gdef:`de
+Bruijn criterion` (keeping a small and well delimited trusted code
base within a proof assistant which can be much more complex). This
-separation makes it possible to reduce the trust in the whole system
-to trusting a smaller, critical component: the kernel. In particular,
+separation makes it necessary to trust only a smaller, critical
+component (the kernel) instead of the entire system. In particular,
users may rely on external plugins that provide advanced and complex
tactics without fear of these tactics being buggy, because the kernel
will have to check their output.
@@ -30,8 +33,11 @@ will have to check their output.
.. toctree::
:maxdepth: 1
+ basic
../gallina-specification-language
../cic
+ records
../../addendum/universe-polymorphism
../../addendum/sprop
+ sections
../module-system
diff --git a/doc/sphinx/language/core/records.rst b/doc/sphinx/language/core/records.rst
new file mode 100644
index 0000000000..0080f1d052
--- /dev/null
+++ b/doc/sphinx/language/core/records.rst
@@ -0,0 +1,315 @@
+.. _record-types:
+
+Record types
+----------------
+
+The :cmd:`Record` construction is a macro allowing the definition of
+records as is done in many programming languages. Its syntax is
+described in the grammar below. In fact, the :cmd:`Record` macro is more general
+than the usual record types, since it allows also for “manifest”
+expressions. In this sense, the :cmd:`Record` construction allows defining
+“signatures”.
+
+.. _record_grammar:
+
+.. cmd:: {| Record | Structure } @record_definition {* with @record_definition }
+ :name: Record; Structure
+
+ .. insertprodn record_definition field_def
+
+ .. prodn::
+ record_definition ::= {? > } @ident_decl {* @binder } {? : @type } {? @ident } %{ {*; @record_field } %} {? @decl_notations }
+ record_field ::= {* #[ {*, @attribute } ] } @name {? @field_body } {? %| @num } {? @decl_notations }
+ field_body ::= {* @binder } @of_type
+ | {* @binder } @of_type := @term
+ | {* @binder } := @term
+ 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`.
+ 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.
+
+ Notations can be attached to fields using the :n:`@decl_notations` annotation.
+
+ :cmd:`Record` and :cmd:`Structure` are synonyms.
+
+ 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.
+
+More generally, a record may have explicitly defined (a.k.a. manifest)
+fields. For instance, we might have:
+:n:`Record @ident {* @binder } : @sort := { @ident__1 : @type__1 ; @ident__2 := @term__2 ; @ident__3 : @type__3 }`.
+in which case the correctness of :n:`@type__3` may rely on the instance :n:`@term__2` of :n:`@ident__2` and :n:`@term__2` may in turn depend on :n:`@ident__1`.
+
+.. example::
+
+ The set of rational numbers may be defined as:
+
+ .. coqtop:: reset all
+
+ Record Rat : Set := mkRat
+ { sign : bool
+ ; top : nat
+ ; bottom : nat
+ ; Rat_bottom_cond : 0 <> bottom
+ ; Rat_irred_cond :
+ forall x y z:nat, (x * y) = top /\ (x * z) = bottom -> x = 1
+ }.
+
+ Note here that the fields ``Rat_bottom_cond`` depends on the field ``bottom``
+ and ``Rat_irred_cond`` depends on both ``top`` and ``bottom``.
+
+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
+:n:`@ident__0` with the appropriate number of terms filling the fields of the record.
+
+.. example::
+
+ Let us define the rational :math:`1/2`:
+
+ .. coqtop:: in
+
+ Theorem one_two_irred : forall x y z:nat, x * y = 1 /\ x * z = 2 -> x = 1.
+ Admitted.
+
+ Definition half := mkRat true 1 2 (O_S 1) one_two_irred.
+ Check half.
+
+Alternatively, the following syntax allows creating objects by using named fields, as
+shown in this grammar. The fields do not have to be in any particular order, nor do they have
+to be all present if the missing ones can be inferred or prompted for
+(see :ref:`programs`).
+
+.. coqtop:: all
+
+ Definition half' :=
+ {| sign := true;
+ Rat_bottom_cond := O_S 1;
+ Rat_irred_cond := one_two_irred |}.
+
+The following settings let you control the display format for types:
+
+.. flag:: Printing Records
+
+ If set, use the record syntax (shown above) as the default display format.
+
+You can override the display format for specified types by adding entries to these tables:
+
+.. table:: Printing Record @qualid
+ :name: Printing Record
+
+ Specifies a set of qualids which are displayed as records. Use the
+ :cmd:`Add` and :cmd:`Remove` commands to update the set of qualids.
+
+.. table:: Printing Constructor @qualid
+ :name: Printing Constructor
+
+ Specifies a set of qualids which are displayed as constructors. Use the
+ :cmd:`Add` and :cmd:`Remove` commands to update the set of qualids.
+
+This syntax can also be used for pattern matching.
+
+.. coqtop:: all
+
+ Eval compute in (
+ match half with
+ | {| sign := true; top := n |} => n
+ | _ => 0
+ end).
+
+The macro generates also, when it is possible, the projection
+functions for destructuring an object of type :token:`ident`. These
+projection functions are given the names of the corresponding
+fields. If a field is named `_` then no projection is built
+for it. In our example:
+
+.. coqtop:: all
+
+ Eval compute in top half.
+ Eval compute in bottom half.
+ Eval compute in Rat_bottom_cond half.
+
+An alternative syntax for projections based on a dot notation is
+available:
+
+.. coqtop:: all
+
+ Eval compute in half.(top).
+
+.. flag:: Printing Projections
+
+ This flag activates the dot notation for printing.
+
+ .. example::
+
+ .. coqtop:: all
+
+ Set Printing Projections.
+ Check top half.
+
+.. FIXME: move this to the main grammar in the spec chapter
+
+.. _record_projections_grammar:
+
+ .. insertprodn term_projection term_projection
+
+ .. prodn::
+ term_projection ::= @term0 .( @qualid {* @arg } )
+ | @term0 .( @ @qualid {* @term1 } )
+
+ Syntax of Record projections
+
+The corresponding grammar rules are given in the preceding grammar. When :token:`qualid`
+denotes a projection, the syntax :n:`@term0.(@qualid)` is equivalent to :n:`@qualid @term0`,
+the syntax :n:`@term0.(@qualid {+ @arg })` to :n:`@qualid {+ @arg } @term0`.
+and the syntax :n:`@term0.(@@qualid {+ @term0 })` to :n:`@@qualid {+ @term0 } @term0`.
+In each case, :token:`term0` is the object projected and the
+other arguments are the parameters of the inductive type.
+
+
+.. note:: Records defined with the ``Record`` keyword are not allowed to be
+ recursive (references to the record's name in the type of its field
+ raises an error). To define recursive records, one can use the ``Inductive``
+ and ``CoInductive`` keywords, resulting in an inductive or co-inductive record.
+ Definition of mutually inductive or co-inductive records are also allowed, as long
+ as all of the types in the block are records.
+
+.. note:: Induction schemes are automatically generated for inductive records.
+ Automatic generation of induction schemes for non-recursive records
+ defined with the ``Record`` keyword can be activated with the
+ :flag:`Nonrecursive Elimination Schemes` flag (see :ref:`proofschemes-induction-principles`).
+
+.. warn:: @ident cannot be defined.
+
+ It can happen that the definition of a projection is impossible.
+ This message is followed by an explanation of this impossibility.
+ There may be three reasons:
+
+ #. The name :token:`ident` already exists in the environment (see :cmd:`Axiom`).
+ #. The body of :token:`ident` uses an incorrect elimination for
+ :token:`ident` (see :cmd:`Fixpoint` and :ref:`Destructors`).
+ #. The type of the projections :token:`ident` depends on previous
+ projections which themselves could not be defined.
+
+.. exn:: Records declared with the keyword Record or Structure cannot be recursive.
+
+ The record name :token:`ident` appears in the type of its fields, but uses
+ the keyword ``Record``. Use the keyword ``Inductive`` or ``CoInductive`` instead.
+
+.. exn:: Cannot handle mutually (co)inductive records.
+
+ Records cannot be defined as part of mutually inductive (or
+ co-inductive) definitions, whether with records only or mixed with
+ standard definitions.
+
+During the definition of the one-constructor inductive definition, all
+the errors of inductive definitions, as described in Section
+:ref:`gallina-inductive-definitions`, may also occur.
+
+.. seealso:: Coercions and records in section :ref:`coercions-classes-as-records` of the chapter devoted to coercions.
+
+.. _primitive_projections:
+
+Primitive Projections
+~~~~~~~~~~~~~~~~~~~~~
+
+.. flag:: Primitive Projections
+
+ Turns on the use of primitive
+ projections when defining subsequent records (even through the ``Inductive``
+ and ``CoInductive`` commands). Primitive projections
+ extended the Calculus of Inductive Constructions with a new binary
+ term constructor `r.(p)` representing a primitive projection `p` applied
+ to a record object `r` (i.e., primitive projections are always applied).
+ Even if the record type has parameters, these do not appear
+ in the internal representation of
+ applications of the projection, considerably reducing the sizes of
+ terms when manipulating parameterized records and type checking time.
+ On the user level, primitive projections can be used as a replacement
+ for the usual defined ones, although there are a few notable differences.
+
+.. flag:: Printing Primitive Projection Parameters
+
+ This compatibility flag reconstructs internally omitted parameters at
+ printing time (even though they are absent in the actual AST manipulated
+ by the kernel).
+
+Primitive Record Types
+++++++++++++++++++++++
+
+When the :flag:`Primitive Projections` flag is on, definitions of
+record types change meaning. When a type is declared with primitive
+projections, its :g:`match` construct is disabled (see :ref:`primitive_projections` though).
+To eliminate the (co-)inductive type, one must use its defined primitive projections.
+
+.. The following paragraph is quite redundant with what is above
+
+For compatibility, the parameters still appear to the user when
+printing terms even though they are absent in the actual AST
+manipulated by the kernel. This can be changed by unsetting the
+:flag:`Printing Primitive Projection Parameters` flag.
+
+There are currently two ways to introduce primitive records types:
+
+#. Through the ``Record`` command, in which case the type has to be
+ non-recursive. The defined type enjoys eta-conversion definitionally,
+ that is the generalized form of surjective pairing for records:
+ `r` ``= Build_``\ `R` ``(``\ `r`\ ``.(``\ |p_1|\ ``) …`` `r`\ ``.(``\ |p_n|\ ``))``.
+ Eta-conversion allows to define dependent elimination for these types as well.
+#. Through the ``Inductive`` and ``CoInductive`` commands, when
+ the body of the definition is a record declaration of the form
+ ``Build_``\ `R` ``{`` |p_1| ``:`` |t_1|\ ``; … ;`` |p_n| ``:`` |t_n| ``}``.
+ In this case the types can be recursive and eta-conversion is disallowed. These kind of record types
+ differ from their traditional versions in the sense that dependent
+ elimination is not available for them and only non-dependent case analysis
+ can be defined.
+
+Reduction
++++++++++
+
+The basic reduction rule of a primitive projection is
+|p_i| ``(Build_``\ `R` |t_1| … |t_n|\ ``)`` :math:`{\rightarrow_{\iota}}` |t_i|.
+However, to take the :math:`{\delta}` flag into
+account, projections can be in two states: folded or unfolded. An
+unfolded primitive projection application obeys the rule above, while
+the folded version delta-reduces to the unfolded version. This allows to
+precisely mimic the usual unfolding rules of constants. Projections
+obey the usual ``simpl`` flags of the ``Arguments`` command in particular.
+There is currently no way to input unfolded primitive projections at the
+user-level, and there is no way to display unfolded projections differently
+from folded ones.
+
+
+Compatibility Projections and :g:`match`
+++++++++++++++++++++++++++++++++++++++++
+
+To ease compatibility with ordinary record types, each primitive
+projection is also defined as a ordinary constant taking parameters and
+an object of the record type as arguments, and whose body is an
+application of the unfolded primitive projection of the same name. These
+constants are used when elaborating partial applications of the
+projection. One can distinguish them from applications of the primitive
+projection if the :flag:`Printing Primitive Projection Parameters` flag
+is off: For a primitive projection application, parameters are printed
+as underscores while for the compatibility projections they are printed
+as usual.
+
+Additionally, user-written :g:`match` constructs on primitive records
+are desugared into substitution of the projections, they cannot be
+printed back as :g:`match` constructs.
diff --git a/doc/sphinx/language/core/sections.rst b/doc/sphinx/language/core/sections.rst
new file mode 100644
index 0000000000..df50dbafe3
--- /dev/null
+++ b/doc/sphinx/language/core/sections.rst
@@ -0,0 +1,104 @@
+.. _section-mechanism:
+
+Section mechanism
+-----------------
+
+Sections create local contexts which can be shared across multiple definitions.
+
+.. example::
+
+ Sections are opened by the :cmd:`Section` command, and closed by :cmd:`End`.
+
+ .. coqtop:: all
+
+ Section s1.
+
+ Inside a section, local parameters can be introduced using :cmd:`Variable`,
+ :cmd:`Hypothesis`, or :cmd:`Context` (there are also plural variants for
+ the first two).
+
+ .. coqtop:: all
+
+ Variables x y : nat.
+
+ The command :cmd:`Let` introduces section-wide :ref:`let-in`. These definitions
+ won't persist when the section is closed, and all persistent definitions which
+ depend on `y'` will be prefixed with `let y' := y in`.
+
+ .. coqtop:: in
+
+ Let y' := y.
+ Definition x' := S x.
+ Definition x'' := x' + y'.
+
+ .. coqtop:: all
+
+ Print x'.
+ Print x''.
+
+ End s1.
+
+ Print x'.
+ Print x''.
+
+ Notice the difference between the value of :g:`x'` and :g:`x''` inside section
+ :g:`s1` and outside.
+
+.. cmd:: Section @ident
+
+ This command is used to open a section named :token:`ident`.
+ Section names do not need to be unique.
+
+
+.. cmd:: End @ident
+
+ This command closes the section or module named :token:`ident`.
+ See :ref:`Terminating an interactive module or module type definition<terminating_module>`
+ for a description of its use with modules.
+
+ After closing the
+ section, the local declarations (variables and local definitions, see :cmd:`Variable`) are
+ *discharged*, meaning that they stop being visible and that all global
+ objects defined in the section are generalized with respect to the
+ variables and local definitions they each depended on in the section.
+
+ .. exn:: There is nothing to end.
+ :undocumented:
+
+ .. exn:: Last block to end has name @ident.
+ :undocumented:
+
+.. note::
+ Most commands, like :cmd:`Hint`, :cmd:`Notation`, option management, … which
+ appear inside a section are canceled when the section is closed.
+
+.. cmd:: Let @ident_decl @def_body
+ Let Fixpoint @fix_definition {* with @fix_definition }
+ Let CoFixpoint @cofix_definition {* with @cofix_definition }
+ :name: Let; Let Fixpoint; Let CoFixpoint
+
+ These commands behave like :cmd:`Definition`, :cmd:`Fixpoint` and :cmd:`CoFixpoint`, except that
+ the declared constant is local to the current section.
+ When the section is closed, all persistent
+ definitions and theorems within it that depend on the constant
+ will be wrapped with a :n:`@term_let` with the same declaration.
+
+ As for :cmd:`Definition`, :cmd:`Fixpoint` and :cmd:`CoFixpoint`,
+ 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.
+ 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`.
+
+.. cmd:: Context {+ @binder }
+
+ Declare variables in the context of the current section, like :cmd:`Variable`,
+ but also allowing implicit variables, :ref:`implicit-generalization`, and
+ let-binders.
+
+ .. coqdoc::
+
+ Context {A : Type} (a b : A).
+ Context `{EqDec A}.
+ Context (b' := b).
+
+.. seealso:: Section :ref:`binders`. Section :ref:`contexts` in chapter :ref:`typeclasses`.