aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Pit-Claudel2020-05-15 15:07:06 -0400
committerClément Pit-Claudel2020-05-15 15:07:06 -0400
commit2111994285a21df662c232fa5acfd60e8a640795 (patch)
tree5f922cc39fce8bc77bb06d5aa947fdaac4162787
parent03e0aa5ee57b3b539b0fa34be2e1a02a2803b0be (diff)
parent836668d0cf29eeebbbbad20a5073a83bf64a7bae (diff)
Merge PR #12239: Split Gallina, Gallina ext and most of CIC chapters into multiple pages.
Reviewed-by: jfehrle
-rw-r--r--doc/sphinx/addendum/implicit-coercions.rst2
-rw-r--r--doc/sphinx/addendum/universe-polymorphism.rst46
-rw-r--r--doc/sphinx/language/cic.rst1532
-rw-r--r--doc/sphinx/language/core/assumptions.rst186
-rw-r--r--doc/sphinx/language/core/coinductive.rst201
-rw-r--r--doc/sphinx/language/core/conversion.rst212
-rw-r--r--doc/sphinx/language/core/definitions.rst204
-rw-r--r--doc/sphinx/language/core/index.rst13
-rw-r--r--doc/sphinx/language/core/inductive.rst1722
-rw-r--r--doc/sphinx/language/core/modules.rst1012
-rw-r--r--doc/sphinx/language/core/primitive.rst107
-rw-r--r--doc/sphinx/language/core/sorts.rst99
-rw-r--r--doc/sphinx/language/core/variants.rst202
-rw-r--r--doc/sphinx/language/extensions/arguments-command.rst2
-rw-r--r--doc/sphinx/language/extensions/canonical.rst (renamed from doc/sphinx/addendum/canonical-structures.rst)151
-rw-r--r--doc/sphinx/language/extensions/evars.rst112
-rw-r--r--doc/sphinx/language/extensions/implicit-arguments.rst121
-rw-r--r--doc/sphinx/language/extensions/index.rst6
-rw-r--r--doc/sphinx/language/extensions/match.rst (renamed from doc/sphinx/addendum/extended-pattern-matching.rst)283
-rw-r--r--doc/sphinx/language/gallina-extensions.rst1114
-rw-r--r--doc/sphinx/language/gallina-specification-language.rst1452
-rw-r--r--doc/sphinx/language/module-system.rst456
-rw-r--r--doc/sphinx/proof-engine/ltac.rst5
-rw-r--r--doc/sphinx/proof-engine/tactics.rst35
-rw-r--r--doc/sphinx/proof-engine/vernacular-commands.rst30
-rw-r--r--doc/sphinx/user-extensions/syntax-extensions.rst25
26 files changed, 4627 insertions, 4703 deletions
diff --git a/doc/sphinx/addendum/implicit-coercions.rst b/doc/sphinx/addendum/implicit-coercions.rst
index a6dc15da55..5d257c7370 100644
--- a/doc/sphinx/addendum/implicit-coercions.rst
+++ b/doc/sphinx/addendum/implicit-coercions.rst
@@ -1,4 +1,4 @@
-.. _implicitcoercions:
+.. _coercions:
Implicit Coercions
====================
diff --git a/doc/sphinx/addendum/universe-polymorphism.rst b/doc/sphinx/addendum/universe-polymorphism.rst
index 2958d866ac..12fd038fb6 100644
--- a/doc/sphinx/addendum/universe-polymorphism.rst
+++ b/doc/sphinx/addendum/universe-polymorphism.rst
@@ -365,6 +365,21 @@ it is an atomic universe (i.e. not an algebraic max() universe).
Explicit Universes
-------------------
+.. insertprodn universe_name univ_constraint
+
+.. prodn::
+ universe_name ::= @qualid
+ | Set
+ | Prop
+ univ_annot ::= @%{ {* @universe_level } %}
+ universe_level ::= Set
+ | Prop
+ | Type
+ | _
+ | @qualid
+ 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.
@@ -403,6 +418,37 @@ to universes and explicitly instantiate polymorphic definitions.
.. exn:: Polymorphic universe constraints can only be declared inside sections, use Monomorphic Constraint instead
:undocumented:
+.. _printing-universes:
+
+Printing universes
+------------------
+
+.. flag:: Printing Universes
+
+ Turn this flag on to activate the display of the actual level of each
+ occurrence of :g:`Type`. See :ref:`Sorts` for details. This wizard flag, in
+ combination with :flag:`Printing All` can help to diagnose failures to unify
+ terms apparently identical but internally different in the Calculus of Inductive
+ Constructions.
+
+.. cmd:: Print {? Sorted } Universes {? Subgraph ( {* @qualid } ) } {? @string }
+ :name: Print Universes
+
+ This command can be used to print the constraints on the internal level
+ of the occurrences of :math:`\Type` (see :ref:`Sorts`).
+
+ The :n:`Subgraph` clause limits the printed graph to the requested names (adjusting
+ constraints to preserve the implied transitive constraints between
+ kept universes).
+
+ The :n:`Sorted` clause makes each universe
+ equivalent to a numbered label reflecting its level (with a linear
+ ordering) in the universe hierarchy.
+
+ :n:`@string` is an optional output filename.
+ If :n:`@string` ends in ``.dot`` or ``.gv``, the constraints are printed in the DOT
+ language, and can be processed by Graphviz tools. The format is
+ unspecified if `string` doesn’t end in ``.dot`` or ``.gv``.
Polymorphic definitions
~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/doc/sphinx/language/cic.rst b/doc/sphinx/language/cic.rst
index b125d21a3c..768c83150e 100644
--- a/doc/sphinx/language/cic.rst
+++ b/doc/sphinx/language/cic.rst
@@ -1,7 +1,4 @@
-.. _calculusofinductiveconstructions:
-
-
-Calculus of Inductive Constructions
+Typing rules
====================================
The underlying formal language of |Coq| is a *Calculus of Inductive
@@ -24,95 +21,6 @@ to a type and takes the form “*for all x of type* :math:`T`, :math:`P`”. The
“:math:`x` *of type* :math:`T`” is written “:math:`x:T`”. Informally, “:math:`x:T`” can be thought as
“:math:`x` *belongs to* :math:`T`”.
-The types of types are called :gdef:`sort`\s. Types and sorts are themselves terms
-so that terms, types and sorts are all components of a common
-syntactic language of terms which is described in Section :ref:`terms`. But
-first, we describe sorts.
-
-
-.. _Sorts:
-
-Sorts
-~~~~~~~~~~~
-
-All sorts have a type and there is an infinite well-founded typing
-hierarchy of sorts whose base sorts are :math:`\SProp`, :math:`\Prop`
-and :math:`\Set`.
-
-The sort :math:`\Prop` intends to be the type of logical propositions. If :math:`M` is a
-logical proposition then it denotes the class of terms representing
-proofs of :math:`M`. An object :math:`m` belonging to :math:`M` witnesses the fact that :math:`M` is
-provable. An object of type :math:`\Prop` is called a proposition.
-
-The sort :math:`\SProp` is like :math:`\Prop` but the propositions in
-:math:`\SProp` are known to have irrelevant proofs (all proofs are
-equal). Objects of type :math:`\SProp` are called strict propositions.
-See :ref:`sprop` for information about using
-:math:`\SProp`, and :cite:`Gilbert:POPL2019` for meta theoretical
-considerations.
-
-The sort :math:`\Set` intends to be the type of small sets. This includes data
-types such as booleans and naturals, but also products, subsets, and
-function types over these data types.
-
-:math:`\SProp`, :math:`\Prop` and :math:`\Set` themselves can be manipulated as ordinary terms.
-Consequently they also have a type. Because assuming simply that :math:`\Set`
-has type :math:`\Set` leads to an inconsistent theory :cite:`Coq86`, the language of
-|Cic| has infinitely many sorts. There are, in addition to the base sorts,
-a hierarchy of universes :math:`\Type(i)` for any integer :math:`i ≥ 1`.
-
-Like :math:`\Set`, all of the sorts :math:`\Type(i)` contain small sets such as
-booleans, natural numbers, as well as products, subsets and function
-types over small sets. But, unlike :math:`\Set`, they also contain large sets,
-namely the sorts :math:`\Set` and :math:`\Type(j)` for :math:`j<i`, and all products, subsets
-and function types over these sorts.
-
-Formally, we call :math:`\Sort` the set of sorts which is defined by:
-
-.. math::
-
- \Sort \equiv \{\SProp,\Prop,\Set,\Type(i)\;|\; i~∈ ℕ\}
-
-Their properties, such as: :math:`\Prop:\Type(1)`, :math:`\Set:\Type(1)`, and
-:math:`\Type(i):\Type(i+1)`, are defined in Section :ref:`subtyping-rules`.
-
-The user does not have to mention explicitly the index :math:`i` when
-referring to the universe :math:`\Type(i)`. One only writes :math:`\Type`. The system
-itself generates for each instance of :math:`\Type` a new index for the
-universe and checks that the constraints between these indexes can be
-solved. From the user point of view we consequently have :math:`\Type:\Type`. We
-shall make precise in the typing rules the constraints between the
-indices.
-
-
-.. _Implementation-issues:
-
-**Implementation issues** In practice, the Type hierarchy is
-implemented using *algebraic
-universes*. An algebraic universe :math:`u` is either a variable (a qualified
-identifier with a number) or a successor of an algebraic universe (an
-expression :math:`u+1`), or an upper bound of algebraic universes (an
-expression :math:`\max(u_1 ,...,u_n )`), or the base universe (the expression
-:math:`0`) which corresponds, in the arity of template polymorphic inductive
-types (see Section
-:ref:`well-formed-inductive-definitions`),
-to the predicative sort :math:`\Set`. A graph of
-constraints between the universe variables is maintained globally. To
-ensure the existence of a mapping of the universes to the positive
-integers, the graph of constraints must remain acyclic. Typing
-expressions that violate the acyclicity of the graph of constraints
-results in a Universe inconsistency error.
-
-.. seealso:: Section :ref:`printing-universes`.
-
-
-.. _Terms:
-
-Terms
-~~~~~
-
-
-
Terms are built from sorts, variables, constants, abstractions,
applications, local definitions, and products. From a syntactic point
of view, types cannot be distinguished from terms, except that they
@@ -411,221 +319,6 @@ following rules.
:math:`x` may be used in a conversion rule
(see Section :ref:`Conversion-rules`).
-
-.. _Conversion-rules:
-
-Conversion rules
---------------------
-
-In |Cic|, there is an internal reduction mechanism. In particular, it
-can decide if two programs are *intentionally* equal (one says
-*convertible*). Convertibility is described in this section.
-
-
-.. _beta-reduction:
-
-β-reduction
-~~~~~~~~~~~
-
-We want to be able to identify some terms as we can identify the
-application of a function to a given argument with its result. For
-instance the identity function over a given type :math:`T` can be written
-:math:`λx:T.~x`. In any global environment :math:`E` and local context
-:math:`Γ`, we want to identify any object :math:`a` (of type
-:math:`T`) with the application :math:`((λ x:T.~x)~a)`. We define for
-this a *reduction* (or a *conversion*) rule we call :math:`β`:
-
-.. math::
-
- E[Γ] ⊢ ((λx:T.~t)~u)~\triangleright_β~\subst{t}{x}{u}
-
-We say that :math:`\subst{t}{x}{u}` is the *β-contraction* of
-:math:`((λx:T.~t)~u)` and, conversely, that :math:`((λ x:T.~t)~u)` is the
-*β-expansion* of :math:`\subst{t}{x}{u}`.
-
-According to β-reduction, terms of the *Calculus of Inductive
-Constructions* enjoy some fundamental properties such as confluence,
-strong normalization, subject reduction. These results are
-theoretically of great importance but we will not detail them here and
-refer the interested reader to :cite:`Coq85`.
-
-
-.. _iota-reduction:
-
-ι-reduction
-~~~~~~~~~~~
-
-A specific conversion rule is associated to the inductive objects in
-the global environment. We shall give later on (see Section
-:ref:`Well-formed-inductive-definitions`) the precise rules but it
-just says that a destructor applied to an object built from a
-constructor behaves as expected. This reduction is called ι-reduction
-and is more precisely studied in :cite:`Moh93,Wer94`.
-
-
-.. _delta-reduction:
-
-δ-reduction
-~~~~~~~~~~~
-
-We may have variables defined in local contexts or constants defined
-in the global environment. It is legal to identify such a reference
-with its value, that is to expand (or unfold) it into its value. This
-reduction is called δ-reduction and shows as follows.
-
-.. inference:: Delta-Local
-
- \WFE{\Gamma}
- (x:=t:T) ∈ Γ
- --------------
- E[Γ] ⊢ x~\triangleright_Δ~t
-
-.. inference:: Delta-Global
-
- \WFE{\Gamma}
- (c:=t:T) ∈ E
- --------------
- E[Γ] ⊢ c~\triangleright_δ~t
-
-
-.. _zeta-reduction:
-
-ζ-reduction
-~~~~~~~~~~~
-
-|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.
-
-.. inference:: Zeta
-
- \WFE{\Gamma}
- \WTEG{u}{U}
- \WTE{\Gamma::(x:=u:U)}{t}{T}
- --------------
- E[Γ] ⊢ \letin{x}{u:U}{t}~\triangleright_ζ~\subst{t}{x}{u}
-
-
-.. _eta-expansion:
-
-η-expansion
-~~~~~~~~~~~
-
-Another important concept is η-expansion. It is legal to identify any
-term :math:`t` of functional type :math:`∀ x:T,~U` with its so-called η-expansion
-
-.. math::
- λx:T.~(t~x)
-
-for :math:`x` an arbitrary variable name fresh in :math:`t`.
-
-
-.. note::
-
- We deliberately do not define η-reduction:
-
- .. math::
- λ x:T.~(t~x)~\not\triangleright_η~t
-
- This is because, in general, the type of :math:`t` need not to be convertible
- to the type of :math:`λ x:T.~(t~x)`. E.g., if we take :math:`f` such that:
-
- .. math::
- f ~:~ ∀ x:\Type(2),~\Type(1)
-
- then
-
- .. math::
- λ x:\Type(1).~(f~x) ~:~ ∀ x:\Type(1),~\Type(1)
-
- We could not allow
-
- .. math::
- λ x:\Type(1).~(f~x) ~\triangleright_η~ f
-
- because the type of the reduced term :math:`∀ x:\Type(2),~\Type(1)` would not be
- convertible to the type of the original term :math:`∀ x:\Type(1),~\Type(1)`.
-
-.. _proof-irrelevance:
-
-Proof Irrelevance
-~~~~~~~~~~~~~~~~~
-
-It is legal to identify any two terms whose common type is a strict
-proposition :math:`A : \SProp`. Terms in a strict propositions are
-therefore called *irrelevant*.
-
-.. _convertibility:
-
-Convertibility
-~~~~~~~~~~~~~~
-
-Let us write :math:`E[Γ] ⊢ t \triangleright u` for the contextual closure of the
-relation :math:`t` reduces to :math:`u` in the global environment
-:math:`E` and local context :math:`Γ` with one of the previous
-reductions β, δ, ι or ζ.
-
-We say that two terms :math:`t_1` and :math:`t_2` are
-*βδιζη-convertible*, or simply *convertible*, or *equivalent*, in the
-global environment :math:`E` and local context :math:`Γ` iff there
-exist terms :math:`u_1` and :math:`u_2` such that :math:`E[Γ] ⊢ t_1 \triangleright
-… \triangleright u_1` and :math:`E[Γ] ⊢ t_2 \triangleright … \triangleright u_2` and either :math:`u_1` and
-:math:`u_2` are identical up to irrelevant subterms, or they are convertible up to η-expansion,
-i.e. :math:`u_1` is :math:`λ x:T.~u_1'` and :math:`u_2 x` is
-recursively convertible to :math:`u_1'`, or, symmetrically,
-:math:`u_2` is :math:`λx:T.~u_2'`
-and :math:`u_1 x` is recursively convertible to :math:`u_2'`. We then write
-:math:`E[Γ] ⊢ t_1 =_{βδιζη} t_2`.
-
-Apart from this we consider two instances of polymorphic and
-cumulative (see Chapter :ref:`polymorphicuniverses`) inductive types
-(see below) convertible
-
-.. math::
- E[Γ] ⊢ t~w_1 … w_m =_{βδιζη} t~w_1' … w_m'
-
-if we have subtypings (see below) in both directions, i.e.,
-
-.. math::
- E[Γ] ⊢ t~w_1 … w_m ≤_{βδιζη} t~w_1' … w_m'
-
-and
-
-.. math::
- E[Γ] ⊢ t~w_1' … w_m' ≤_{βδιζη} t~w_1 … w_m.
-
-Furthermore, we consider
-
-.. math::
- E[Γ] ⊢ c~v_1 … v_m =_{βδιζη} c'~v_1' … v_m'
-
-convertible if
-
-.. math::
- E[Γ] ⊢ v_i =_{βδιζη} v_i'
-
-and we have that :math:`c` and :math:`c'`
-are the same constructors of different instances of the same inductive
-types (differing only in universe levels) such that
-
-.. math::
- E[Γ] ⊢ c~v_1 … v_m : t~w_1 … w_m
-
-and
-
-.. math::
- E[Γ] ⊢ c'~v_1' … v_m' : t'~ w_1' … w_m '
-
-and we have
-
-.. math::
- E[Γ] ⊢ t~w_1 … w_m =_{βδιζη} t~w_1' … w_m'.
-
-The convertibility relation allows introducing a new typing rule which
-says that two convertible well-formed types have the same inhabitants.
-
-
.. _subtyping-rules:
Subtyping rules
@@ -728,1219 +421,6 @@ normal form must not be confused with the normal form since some :math:`u_i`
can be reducible. Similar notions of head-normal forms involving δ, ι
and ζ reductions or any combination of those can also be defined.
-
-.. _inductive-definitions:
-
-Inductive Definitions
--------------------------
-
-Formally, we can represent any *inductive definition* as
-:math:`\ind{p}{Γ_I}{Γ_C}` where:
-
-+ :math:`Γ_I` determines the names and types of inductive types;
-+ :math:`Γ_C` determines the names and types of constructors of these
- inductive types;
-+ :math:`p` determines the number of parameters of these inductive types.
-
-
-These inductive definitions, together with global assumptions and
-global definitions, then form the global environment. Additionally,
-for any :math:`p` there always exists :math:`Γ_P =[a_1 :A_1 ;~…;~a_p :A_p ]` such that
-each :math:`T` in :math:`(t:T)∈Γ_I \cup Γ_C` can be written as: :math:`∀Γ_P , T'` where :math:`Γ_P` is
-called the *context of parameters*. Furthermore, we must have that
-each :math:`T` in :math:`(t:T)∈Γ_I` can be written as: :math:`∀Γ_P,∀Γ_{\mathit{Arr}(t)}, S` where
-:math:`Γ_{\mathit{Arr}(t)}` is called the *Arity* of the inductive type :math:`t` and :math:`S` is called
-the sort of the inductive type :math:`t` (not to be confused with :math:`\Sort` which is the set of sorts).
-
-.. example::
-
- The declaration for parameterized lists is:
-
- .. math::
- \ind{1}{[\List:\Set→\Set]}{\left[\begin{array}{rcl}
- \Nil & : & ∀ A:\Set,~\List~A \\
- \cons & : & ∀ A:\Set,~A→ \List~A→ \List~A
- \end{array}
- \right]}
-
- which corresponds to the result of the |Coq| declaration:
-
- .. coqtop:: in
-
- Inductive list (A:Set) : Set :=
- | nil : list A
- | cons : A -> list A -> list A.
-
-.. example::
-
- The declaration for a mutual inductive definition of tree and forest
- is:
-
- .. math::
- \ind{0}{\left[\begin{array}{rcl}\tree&:&\Set\\\forest&:&\Set\end{array}\right]}
- {\left[\begin{array}{rcl}
- \node &:& \forest → \tree\\
- \emptyf &:& \forest\\
- \consf &:& \tree → \forest → \forest\\
- \end{array}\right]}
-
- which corresponds to the result of the |Coq| declaration:
-
- .. coqtop:: in
-
- Inductive tree : Set :=
- | node : forest -> tree
- with forest : Set :=
- | emptyf : forest
- | consf : tree -> forest -> forest.
-
-.. example::
-
- The declaration for a mutual inductive definition of even and odd is:
-
- .. math::
- \ind{0}{\left[\begin{array}{rcl}\even&:&\nat → \Prop \\
- \odd&:&\nat → \Prop \end{array}\right]}
- {\left[\begin{array}{rcl}
- \evenO &:& \even~0\\
- \evenS &:& ∀ n,~\odd~n → \even~(\nS~n)\\
- \oddS &:& ∀ n,~\even~n → \odd~(\nS~n)
- \end{array}\right]}
-
- which corresponds to the result of the |Coq| declaration:
-
- .. coqtop:: in
-
- Inductive even : nat -> Prop :=
- | even_O : even 0
- | even_S : forall n, odd n -> even (S n)
- with odd : nat -> Prop :=
- | odd_S : forall n, even n -> odd (S n).
-
-
-
-.. _Types-of-inductive-objects:
-
-Types of inductive objects
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-We have to give the type of constants in a global environment :math:`E` which
-contains an inductive definition.
-
-.. inference:: Ind
-
- \WFE{Γ}
- \ind{p}{Γ_I}{Γ_C} ∈ E
- (a:A)∈Γ_I
- ---------------------
- E[Γ] ⊢ a : A
-
-.. inference:: Constr
-
- \WFE{Γ}
- \ind{p}{Γ_I}{Γ_C} ∈ E
- (c:C)∈Γ_C
- ---------------------
- E[Γ] ⊢ c : C
-
-.. example::
-
- Provided that our environment :math:`E` contains inductive definitions we showed before,
- these two inference rules above enable us to conclude that:
-
- .. math::
- \begin{array}{l}
- E[Γ] ⊢ \even : \nat→\Prop\\
- E[Γ] ⊢ \odd : \nat→\Prop\\
- E[Γ] ⊢ \evenO : \even~\nO\\
- E[Γ] ⊢ \evenS : ∀ n:\nat,~\odd~n → \even~(\nS~n)\\
- E[Γ] ⊢ \oddS : ∀ n:\nat,~\even~n → \odd~(\nS~n)
- \end{array}
-
-
-
-
-.. _Well-formed-inductive-definitions:
-
-Well-formed inductive definitions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-We cannot accept any inductive definition because some of them lead
-to inconsistent systems. We restrict ourselves to definitions which
-satisfy a syntactic criterion of positivity. Before giving the formal
-rules, we need a few definitions:
-
-Arity of a given sort
-+++++++++++++++++++++
-
-A type :math:`T` is an *arity of sort* :math:`s` if it converts to the sort :math:`s` or to a
-product :math:`∀ x:T,~U` with :math:`U` an arity of sort :math:`s`.
-
-.. example::
-
- :math:`A→\Set` is an arity of sort :math:`\Set`. :math:`∀ A:\Prop,~A→ \Prop` is an arity of sort
- :math:`\Prop`.
-
-
-Arity
-+++++
-A type :math:`T` is an *arity* if there is a :math:`s∈ \Sort` such that :math:`T` is an arity of
-sort :math:`s`.
-
-
-.. example::
-
- :math:`A→ \Set` and :math:`∀ A:\Prop,~A→ \Prop` are arities.
-
-
-Type of constructor
-+++++++++++++++++++
-We say that :math:`T` is a *type of constructor of* :math:`I` in one of the following
-two cases:
-
-+ :math:`T` is :math:`(I~t_1 … t_n )`
-+ :math:`T` is :math:`∀ x:U,~T'` where :math:`T'` is also a type of constructor of :math:`I`
-
-.. example::
-
- :math:`\nat` and :math:`\nat→\nat` are types of constructor of :math:`\nat`.
- :math:`∀ A:\Type,~\List~A` and :math:`∀ A:\Type,~A→\List~A→\List~A` are types of constructor of :math:`\List`.
-
-.. _positivity:
-
-Positivity Condition
-++++++++++++++++++++
-
-The type of constructor :math:`T` will be said to *satisfy the positivity
-condition* for a constant :math:`X` in the following cases:
-
-+ :math:`T=(X~t_1 … t_n )` and :math:`X` does not occur free in any :math:`t_i`
-+ :math:`T=∀ x:U,~V` and :math:`X` occurs only strictly positively in :math:`U` and the type :math:`V`
- satisfies the positivity condition for :math:`X`.
-
-Strict positivity
-+++++++++++++++++
-
-The constant :math:`X` *occurs strictly positively* in :math:`T` in the following
-cases:
-
-
-+ :math:`X` does not occur in :math:`T`
-+ :math:`T` converts to :math:`(X~t_1 … t_n )` and :math:`X` does not occur in any of :math:`t_i`
-+ :math:`T` converts to :math:`∀ x:U,~V` and :math:`X` does not occur in type :math:`U` but occurs
- strictly positively in type :math:`V`
-+ :math:`T` converts to :math:`(I~a_1 … a_m~t_1 … t_p )` where :math:`I` is the name of an
- inductive definition of the form
-
- .. math::
- \ind{m}{I:A}{c_1 :∀ p_1 :P_1 ,… ∀p_m :P_m ,~C_1 ;~…;~c_n :∀ p_1 :P_1 ,… ∀p_m :P_m ,~C_n}
-
- (in particular, it is
- not mutually defined and it has :math:`m` parameters) and :math:`X` does not occur in
- any of the :math:`t_i`, and the (instantiated) types of constructor
- :math:`\subst{C_i}{p_j}{a_j}_{j=1… m}` of :math:`I` satisfy the nested positivity condition for :math:`X`
-
-Nested Positivity
-+++++++++++++++++
-
-The type of constructor :math:`T` of :math:`I` *satisfies the nested positivity
-condition* for a constant :math:`X` in the following cases:
-
-+ :math:`T=(I~b_1 … b_m~u_1 … u_p)`, :math:`I` is an inductive type with :math:`m`
- parameters and :math:`X` does not occur in any :math:`u_i`
-+ :math:`T=∀ x:U,~V` and :math:`X` occurs only strictly positively in :math:`U` and the type :math:`V`
- satisfies the nested positivity condition for :math:`X`
-
-
-.. example::
-
- For instance, if one considers the following variant of a tree type
- branching over the natural numbers:
-
- .. coqtop:: in
-
- Inductive nattree (A:Type) : Type :=
- | leaf : nattree A
- | natnode : A -> (nat -> nattree A) -> nattree A.
-
- Then every instantiated constructor of ``nattree A`` satisfies the nested positivity
- condition for ``nattree``:
-
- + Type ``nattree A`` of constructor ``leaf`` satisfies the positivity condition for
- ``nattree`` because ``nattree`` does not appear in any (real) arguments of the
- type of that constructor (primarily because ``nattree`` does not have any (real)
- arguments) ... (bullet 1)
-
- + Type ``A → (nat → nattree A) → nattree A`` of constructor ``natnode`` satisfies the
- positivity condition for ``nattree`` because:
-
- - ``nattree`` occurs only strictly positively in ``A`` ... (bullet 1)
-
- - ``nattree`` occurs only strictly positively in ``nat → nattree A`` ... (bullet 3 + 2)
-
- - ``nattree`` satisfies the positivity condition for ``nattree A`` ... (bullet 1)
-
-.. _Correctness-rules:
-
-Correctness rules
-+++++++++++++++++
-
-We shall now describe the rules allowing the introduction of a new
-inductive definition.
-
-Let :math:`E` be a global environment and :math:`Γ_P`, :math:`Γ_I`, :math:`Γ_C` be contexts
-such that :math:`Γ_I` is :math:`[I_1 :∀ Γ_P ,A_1 ;~…;~I_k :∀ Γ_P ,A_k]`, and
-:math:`Γ_C` is :math:`[c_1:∀ Γ_P ,C_1 ;~…;~c_n :∀ Γ_P ,C_n ]`. Then
-
-.. inference:: W-Ind
-
- \WFE{Γ_P}
- (E[Γ_I ;Γ_P ] ⊢ C_i : s_{q_i} )_{i=1… n}
- ------------------------------------------
- \WF{E;~\ind{p}{Γ_I}{Γ_C}}{}
-
-
-provided that the following side conditions hold:
-
- + :math:`k>0` and all of :math:`I_j` and :math:`c_i` are distinct names for :math:`j=1… k` and :math:`i=1… n`,
- + :math:`p` is the number of parameters of :math:`\ind{p}{Γ_I}{Γ_C}` and :math:`Γ_P` is the
- context of parameters,
- + for :math:`j=1… k` we have that :math:`A_j` is an arity of sort :math:`s_j` and :math:`I_j ∉ E`,
- + for :math:`i=1… n` we have that :math:`C_i` is a type of constructor of :math:`I_{q_i}` which
- satisfies the positivity condition for :math:`I_1 … I_k` and :math:`c_i ∉ E`.
-
-One can remark that there is a constraint between the sort of the
-arity of the inductive type and the sort of the type of its
-constructors which will always be satisfied for the impredicative
-sorts :math:`\SProp` and :math:`\Prop` but may fail to define
-inductive type on sort :math:`\Set` and generate constraints
-between universes for inductive types in the Type hierarchy.
-
-
-.. example::
-
- It is well known that the existential quantifier can be encoded as an
- inductive definition. The following declaration introduces the
- second-order existential quantifier :math:`∃ X.P(X)`.
-
- .. coqtop:: in
-
- Inductive exProp (P:Prop->Prop) : Prop :=
- | exP_intro : forall X:Prop, P X -> exProp P.
-
- The same definition on :math:`\Set` is not allowed and fails:
-
- .. coqtop:: all
-
- Fail Inductive exSet (P:Set->Prop) : Set :=
- exS_intro : forall X:Set, P X -> exSet P.
-
- It is possible to declare the same inductive definition in the
- universe :math:`\Type`. The :g:`exType` inductive definition has type
- :math:`(\Type(i)→\Prop)→\Type(j)` with the constraint that the parameter :math:`X` of :math:`\kw{exT}_{\kw{intro}}`
- has type :math:`\Type(k)` with :math:`k<j` and :math:`k≤ i`.
-
- .. coqtop:: all
-
- Inductive exType (P:Type->Prop) : Type :=
- exT_intro : forall X:Type, P X -> exType P.
-
-
-.. example:: Negative occurrence (first example)
-
- The following inductive definition is rejected because it does not
- satisfy the positivity condition:
-
- .. coqtop:: all
-
- Fail Inductive I : Prop := not_I_I (not_I : I -> False) : I.
-
- If we were to accept such definition, we could derive a
- contradiction from it (we can test this by disabling the
- :flag:`Positivity Checking` flag):
-
- .. coqtop:: none
-
- Unset Positivity Checking.
- Inductive I : Prop := not_I_I (not_I : I -> False) : I.
- Set Positivity Checking.
-
- .. coqtop:: all
-
- Definition I_not_I : I -> ~ I := fun i =>
- match i with not_I_I not_I => not_I end.
-
- .. coqtop:: in
-
- Lemma contradiction : False.
- Proof.
- enough (I /\ ~ I) as [] by contradiction.
- split.
- - apply not_I_I.
- intro.
- now apply I_not_I.
- - intro.
- now apply I_not_I.
- Qed.
-
-.. example:: Negative occurrence (second example)
-
- Here is another example of an inductive definition which is
- rejected because it does not satify the positivity condition:
-
- .. coqtop:: all
-
- Fail Inductive Lam := lam (_ : Lam -> Lam).
-
- Again, if we were to accept it, we could derive a contradiction
- (this time through a non-terminating recursive function):
-
- .. coqtop:: none
-
- Unset Positivity Checking.
- Inductive Lam := lam (_ : Lam -> Lam).
- Set Positivity Checking.
-
- .. coqtop:: all
-
- Fixpoint infinite_loop l : False :=
- match l with lam x => infinite_loop (x l) end.
-
- Check infinite_loop (lam (@id Lam)) : False.
-
-.. example:: Non strictly positive occurrence
-
- It is less obvious why inductive type definitions with occurences
- that are positive but not strictly positive are harmful.
- We will see that in presence of an impredicative type they
- are unsound:
-
- .. coqtop:: all
-
- Fail Inductive A: Type := introA: ((A -> Prop) -> Prop) -> A.
-
- If we were to accept this definition we could derive a contradiction
- by creating an injective function from :math:`A → \Prop` to :math:`A`.
-
- This function is defined by composing the injective constructor of
- the type :math:`A` with the function :math:`λx. λz. z = x` injecting
- any type :math:`T` into :math:`T → \Prop`.
-
- .. coqtop:: none
-
- Unset Positivity Checking.
- Inductive A: Type := introA: ((A -> Prop) -> Prop) -> A.
- Set Positivity Checking.
-
- .. coqtop:: all
-
- Definition f (x: A -> Prop): A := introA (fun z => z = x).
-
- .. coqtop:: in
-
- Lemma f_inj: forall x y, f x = f y -> x = y.
- Proof.
- unfold f; intros ? ? H; injection H.
- set (F := fun z => z = y); intro HF.
- symmetry; replace (y = x) with (F y).
- + unfold F; reflexivity.
- + rewrite <- HF; reflexivity.
- Qed.
-
- The type :math:`A → \Prop` can be understood as the powerset
- of the type :math:`A`. To derive a contradiction from the
- injective function :math:`f` we use Cantor's classic diagonal
- argument.
-
- .. coqtop:: all
-
- Definition d: A -> Prop := fun x => exists s, x = f s /\ ~s x.
- Definition fd: A := f d.
-
- .. coqtop:: in
-
- Lemma cantor: (d fd) <-> ~(d fd).
- Proof.
- split.
- + intros [s [H1 H2]]; unfold fd in H1.
- replace d with s.
- * assumption.
- * apply f_inj; congruence.
- + intro; exists d; tauto.
- Qed.
-
- Lemma bad: False.
- Proof.
- pose cantor; tauto.
- Qed.
-
- This derivation was first presented by Thierry Coquand and Christine
- Paulin in :cite:`CP90`.
-
-.. _Template-polymorphism:
-
-Template polymorphism
-+++++++++++++++++++++
-
-Inductive types can be made polymorphic over the universes introduced by
-their parameters in :math:`\Type`, if the minimal inferred sort of the
-inductive declarations either mention some of those parameter universes
-or is computed to be :math:`\Prop` or :math:`\Set`.
-
-If :math:`A` is an arity of some sort and :math:`s` is a sort, we write :math:`A_{/s}`
-for the arity obtained from :math:`A` by replacing its sort with :math:`s`.
-Especially, if :math:`A` is well-typed in some global environment and local
-context, then :math:`A_{/s}` is typable by typability of all products in the
-Calculus of Inductive Constructions. The following typing rule is
-added to the theory.
-
-Let :math:`\ind{p}{Γ_I}{Γ_C}` be an inductive definition. Let
-:math:`Γ_P = [p_1 :P_1 ;~…;~p_p :P_p ]` be its context of parameters,
-:math:`Γ_I = [I_1:∀ Γ_P ,A_1 ;~…;~I_k :∀ Γ_P ,A_k ]` its context of definitions and
-:math:`Γ_C = [c_1 :∀ Γ_P ,C_1 ;~…;~c_n :∀ Γ_P ,C_n]` its context of constructors,
-with :math:`c_i` a constructor of :math:`I_{q_i}`. Let :math:`m ≤ p` be the length of the
-longest prefix of parameters such that the :math:`m` first arguments of all
-occurrences of all :math:`I_j` in all :math:`C_k` (even the occurrences in the
-hypotheses of :math:`C_k`) are exactly applied to :math:`p_1 … p_m` (:math:`m` is the number
-of *recursively uniform parameters* and the :math:`p−m` remaining parameters
-are the *recursively non-uniform parameters*). Let :math:`q_1 , …, q_r`, with
-:math:`0≤ r≤ m`, be a (possibly) partial instantiation of the recursively
-uniform parameters of :math:`Γ_P`. We have:
-
-.. inference:: Ind-Family
-
- \left\{\begin{array}{l}
- \ind{p}{Γ_I}{Γ_C} \in E\\
- (E[] ⊢ q_l : P'_l)_{l=1\ldots r}\\
- (E[] ⊢ P'_l ≤_{βδιζη} \subst{P_l}{p_u}{q_u}_{u=1\ldots l-1})_{l=1\ldots r}\\
- 1 \leq j \leq k
- \end{array}
- \right.
- -----------------------------
- E[] ⊢ I_j~q_1 … q_r :∀ [p_{r+1} :P_{r+1} ;~…;~p_p :P_p], (A_j)_{/s_j}
-
-provided that the following side conditions hold:
-
- + :math:`Γ_{P′}` is the context obtained from :math:`Γ_P` by replacing each :math:`P_l` that is
- an arity with :math:`P_l'` for :math:`1≤ l ≤ r` (notice that :math:`P_l` arity implies :math:`P_l'`
- arity since :math:`E[] ⊢ P_l' ≤_{βδιζη} \subst{P_l}{p_u}{q_u}_{u=1\ldots l-1}`);
- + there are sorts :math:`s_i`, for :math:`1 ≤ i ≤ k` such that, for
- :math:`Γ_{I'} = [I_1 :∀ Γ_{P'} ,(A_1)_{/s_1} ;~…;~I_k :∀ Γ_{P'} ,(A_k)_{/s_k}]`
- we have :math:`(E[Γ_{I′} ;Γ_{P′}] ⊢ C_i : s_{q_i})_{i=1… n}` ;
- + the sorts :math:`s_i` are all introduced by the inductive
- declaration and have no universe constraints beside being greater
- than or equal to :math:`\Prop`, and such that all
- eliminations, to :math:`\Prop`, :math:`\Set` and :math:`\Type(j)`,
- are allowed (see Section :ref:`Destructors`).
-
-
-Notice that if :math:`I_j~q_1 … q_r` is typable using the rules **Ind-Const** and
-**App**, then it is typable using the rule **Ind-Family**. Conversely, the
-extended theory is not stronger than the theory without **Ind-Family**. We
-get an equiconsistency result by mapping each :math:`\ind{p}{Γ_I}{Γ_C}`
-occurring into a given derivation into as many different inductive
-types and constructors as the number of different (partial)
-replacements of sorts, needed for this derivation, in the parameters
-that are arities (this is possible because :math:`\ind{p}{Γ_I}{Γ_C}` well-formed
-implies that :math:`\ind{p}{Γ_{I'}}{Γ_{C'}}` is well-formed and has the
-same allowed eliminations, where :math:`Γ_{I′}` is defined as above and
-:math:`Γ_{C′} = [c_1 :∀ Γ_{P′} ,C_1 ;~…;~c_n :∀ Γ_{P′} ,C_n ]`). That is, the changes in the
-types of each partial instance :math:`q_1 … q_r` can be characterized by the
-ordered sets of arity sorts among the types of parameters, and to each
-signature is associated a new inductive definition with fresh names.
-Conversion is preserved as any (partial) instance :math:`I_j~q_1 … q_r` or
-:math:`C_i~q_1 … q_r` is mapped to the names chosen in the specific instance of
-:math:`\ind{p}{Γ_I}{Γ_C}`.
-
-.. warning::
-
- The restriction that sorts are introduced by the inductive
- declaration prevents inductive types declared in sections to be
- template-polymorphic on universes introduced previously in the
- section: they cannot parameterize over the universes introduced with
- section variables that become parameters at section closing time, as
- these may be shared with other definitions from the same section
- which can impose constraints on them.
-
-.. flag:: Auto Template Polymorphism
-
- This flag, enabled by default, makes every inductive type declared
- at level :math:`\Type` (without annotations or hiding it behind a
- definition) template polymorphic if possible.
-
- This can be prevented using the :attr:`universes(notemplate)`
- attribute.
-
- Template polymorphism and full universe polymorphism (see Chapter
- :ref:`polymorphicuniverses`) are incompatible, so if the latter is
- enabled (through the :flag:`Universe Polymorphism` flag or the
- :attr:`universes(polymorphic)` attribute) it will prevail over
- automatic template polymorphism.
-
-.. warn:: Automatically declaring @ident as template polymorphic.
-
- Warning ``auto-template`` can be used (it is off by default) to
- find which types are implicitly declared template polymorphic by
- :flag:`Auto Template Polymorphism`.
-
- An inductive type can be forced to be template polymorphic using
- the :attr:`universes(template)` attribute: in this case, the
- warning is not emitted.
-
-.. attr:: universes(template)
-
- This attribute can be used to explicitly declare an inductive type
- as template polymorphic, whether the :flag:`Auto Template
- Polymorphism` flag is on or off.
-
- .. exn:: template and polymorphism not compatible
-
- This attribute cannot be used in a full universe polymorphic
- context, i.e. if the :flag:`Universe Polymorphism` flag is on or
- if the :attr:`universes(polymorphic)` attribute is used.
-
- .. exn:: Ill-formed template inductive declaration: not polymorphic on any universe.
-
- The attribute was used but the inductive definition does not
- satisfy the criterion to be template polymorphic.
-
-.. attr:: universes(notemplate)
-
- This attribute can be used to prevent an inductive type to be
- 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
-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.
-The sorts :math:`s_j` are chosen canonically so that each :math:`s_j` is minimal with
-respect to the hierarchy :math:`\Prop ⊂ \Set_p ⊂ \Type` where :math:`\Set_p` is predicative
-:math:`\Set`. More precisely, an empty or small singleton inductive definition
-(i.e. an inductive definition of which all inductive types are
-singleton – see Section :ref:`Destructors`) is set in :math:`\Prop`, a small non-singleton
-inductive type is set in :math:`\Set` (even in case :math:`\Set` is impredicative – see
-Section The-Calculus-of-Inductive-Construction-with-impredicative-Set_),
-and otherwise in the Type hierarchy.
-
-Note that the side-condition about allowed elimination sorts in the rule
-**Ind-Family** avoids to recompute the allowed elimination sorts at each
-instance of a pattern matching (see Section :ref:`Destructors`). As an
-example, let us consider the following definition:
-
-.. example::
-
- .. coqtop:: in
-
- Inductive option (A:Type) : Type :=
- | None : option A
- | Some : A -> option A.
-
-As the definition is set in the Type hierarchy, it is used
-polymorphically over its parameters whose types are arities of a sort
-in the Type hierarchy. Here, the parameter :math:`A` has this property, hence,
-if :g:`option` is applied to a type in :math:`\Set`, the result is in :math:`\Set`. Note that
-if :g:`option` is applied to a type in :math:`\Prop`, then, the result is not set in
-:math:`\Prop` but in :math:`\Set` still. This is because :g:`option` is not a singleton type
-(see Section :ref:`Destructors`) and it would lose the elimination to :math:`\Set` and :math:`\Type`
-if set in :math:`\Prop`.
-
-.. example::
-
- .. coqtop:: all
-
- Check (fun A:Set => option A).
- Check (fun A:Prop => option A).
-
-Here is another example.
-
-.. example::
-
- .. coqtop:: in
-
- Inductive prod (A B:Type) : Type := pair : A -> B -> prod A B.
-
-As :g:`prod` is a singleton type, it will be in :math:`\Prop` if applied twice to
-propositions, in :math:`\Set` if applied twice to at least one type in :math:`\Set` and
-none in :math:`\Type`, and in :math:`\Type` otherwise. In all cases, the three kind of
-eliminations schemes are allowed.
-
-.. example::
-
- .. coqtop:: all
-
- Check (fun A:Set => prod A).
- Check (fun A:Prop => prod A A).
- Check (fun (A:Prop) (B:Set) => prod A B).
- Check (fun (A:Type) (B:Prop) => prod A B).
-
-.. note::
- Template polymorphism used to be called “sort-polymorphism of
- inductive types” before universe polymorphism
- (see Chapter :ref:`polymorphicuniverses`) was introduced.
-
-
-.. _Destructors:
-
-Destructors
-~~~~~~~~~~~~~~~~~
-
-The specification of inductive definitions with arities and
-constructors is quite natural. But we still have to say how to use an
-object in an inductive type.
-
-This problem is rather delicate. There are actually several different
-ways to do that. Some of them are logically equivalent but not always
-equivalent from the computational point of view or from the user point
-of view.
-
-From the computational point of view, we want to be able to define a
-function whose domain is an inductively defined type by using a
-combination of case analysis over the possible constructors of the
-object and recursion.
-
-Because we need to keep a consistent theory and also we prefer to keep
-a strongly normalizing reduction, we cannot accept any sort of
-recursion (even terminating). So the basic idea is to restrict
-ourselves to primitive recursive functions and functionals.
-
-For instance, assuming a parameter :math:`A:\Set` exists in the local context,
-we want to build a function :math:`\length` of type :math:`\List~A → \nat` which computes
-the length of the list, such that :math:`(\length~(\Nil~A)) = \nO` and
-:math:`(\length~(\cons~A~a~l)) = (\nS~(\length~l))`.
-We want these equalities to be
-recognized implicitly and taken into account in the conversion rule.
-
-From the logical point of view, we have built a type family by giving
-a set of constructors. We want to capture the fact that we do not have
-any other way to build an object in this type. So when trying to prove
-a property about an object :math:`m` in an inductive type it is enough
-to enumerate all the cases where :math:`m` starts with a different
-constructor.
-
-In case the inductive definition is effectively a recursive one, we
-want to capture the extra property that we have built the smallest
-fixed point of this recursive equation. This says that we are only
-manipulating finite objects. This analysis provides induction
-principles. For instance, in order to prove
-:math:`∀ l:\List~A,~(\kw{has}\_\kw{length}~A~l~(\length~l))` it is enough to prove:
-
-
-+ :math:`(\kw{has}\_\kw{length}~A~(\Nil~A)~(\length~(\Nil~A)))`
-+ :math:`∀ a:A,~∀ l:\List~A,~(\kw{has}\_\kw{length}~A~l~(\length~l)) →`
- :math:`(\kw{has}\_\kw{length}~A~(\cons~A~a~l)~(\length~(\cons~A~a~l)))`
-
-
-which given the conversion equalities satisfied by :math:`\length` is the same
-as proving:
-
-
-+ :math:`(\kw{has}\_\kw{length}~A~(\Nil~A)~\nO)`
-+ :math:`∀ a:A,~∀ l:\List~A,~(\kw{has}\_\kw{length}~A~l~(\length~l)) →`
- :math:`(\kw{has}\_\kw{length}~A~(\cons~A~a~l)~(\nS~(\length~l)))`
-
-
-One conceptually simple way to do that, following the basic scheme
-proposed by Martin-Löf in his Intuitionistic Type Theory, is to
-introduce for each inductive definition an elimination operator. At
-the logical level it is a proof of the usual induction principle and
-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
-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.
-
-
-.. _match-construction:
-
-The match ... with ... end construction
-+++++++++++++++++++++++++++++++++++++++
-
-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
-will be written:
-
-.. math::
- \Match~m~\with~(c_1~x_{11} ... x_{1p_1} ) ⇒ f_1 | … | (c_n~x_{n1} ... x_{np_n} ) ⇒ f_n~\kwend
-
-In this expression, if :math:`m` eventually happens to evaluate to
-:math:`(c_i~u_1 … u_{p_i})` then the expression will behave as specified in its :math:`i`-th branch
-and it will reduce to :math:`f_i` where the :math:`x_{i1} …x_{ip_i}` are replaced by the
-:math:`u_1 … u_{p_i}` according to the ι-reduction.
-
-Actually, for type checking a :math:`\Match…\with…\kwend` expression we also need
-to know the predicate :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|
-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
-with one parameter and one argument. The predicate is made explicit
-using the syntax:
-
-.. math::
- \Match~m~\as~x~\In~I~\_~a~\return~P~\with~
- (c_1~x_{11} ... x_{1p_1} ) ⇒ f_1 | …
- | (c_n~x_{n1} ... x_{np_n} ) ⇒ f_n~\kwend
-
-The :math:`\as` part can be omitted if either the result type does not depend
-on :math:`m` (non-dependent elimination) or :math:`m` is a variable (in this case, :math:`m`
-can occur in :math:`P` where it is considered a bound variable). The :math:`\In` part
-can be omitted if the result type does not depend on the arguments
-of :math:`I`. Note that the arguments of :math:`I` corresponding to parameters *must*
-be :math:`\_`, because the result type is not generalized to all possible
-values of the parameters. The other arguments of :math:`I` (sometimes called
-indices in the literature) have to be variables (:math:`a` above) and these
-variables can occur in :math:`P`. The expression after :math:`\In` must be seen as an
-*inductive type pattern*. Notice that expansion of implicit arguments
-and notations apply to this pattern. For the purpose of presenting the
-inference rules, we use a more compact notation:
-
-.. math::
- \case(m,(λ a x . P), λ x_{11} ... x_{1p_1} . f_1~| … |~λ x_{n1} ...x_{np_n} . f_n )
-
-
-.. _Allowed-elimination-sorts:
-
-**Allowed elimination sorts.** An important question for building the typing rule for :math:`\Match` is what
-can be the type of :math:`λ a x . P` with respect to the type of :math:`m`. If :math:`m:I`
-and :math:`I:A` and :math:`λ a x . P : B` then by :math:`[I:A|B]` we mean that one can use
-:math:`λ a x . P` with :math:`m` in the above match-construct.
-
-
-.. _cic_notations:
-
-**Notations.** The :math:`[I:A|B]` is defined as the smallest relation satisfying the
-following rules: We write :math:`[I|B]` for :math:`[I:A|B]` where :math:`A` is the type of :math:`I`.
-
-The case of inductive types in sorts :math:`\Set` or :math:`\Type` is simple.
-There is no restriction on the sort of the predicate to be eliminated.
-
-.. inference:: Prod
-
- [(I~x):A′|B′]
- -----------------------
- [I:∀ x:A,~A′|∀ x:A,~B′]
-
-
-.. inference:: Set & Type
-
- s_1 ∈ \{\Set,\Type(j)\}
- s_2 ∈ \Sort
- ----------------
- [I:s_1 |I→ s_2 ]
-
-
-The case of Inductive definitions of sort :math:`\Prop` is a bit more
-complicated, because of our interpretation of this sort. The only
-harmless allowed eliminations, are the ones when predicate :math:`P`
-is also of sort :math:`\Prop` or is of the morally smaller sort
-:math:`\SProp`.
-
-.. inference:: Prop
-
- s ∈ \{\SProp,\Prop\}
- --------------------
- [I:\Prop|I→s]
-
-
-:math:`\Prop` is the type of logical propositions, the proofs of properties :math:`P` in
-:math:`\Prop` could not be used for computation and are consequently ignored by
-the extraction mechanism. Assume :math:`A` and :math:`B` are two propositions, and the
-logical disjunction :math:`A ∨ B` is defined inductively by:
-
-.. example::
-
- .. coqtop:: in
-
- Inductive or (A B:Prop) : Prop :=
- or_introl : A -> or A B | or_intror : B -> or A B.
-
-
-The following definition which computes a boolean value by case over
-the proof of :g:`or A B` is not accepted:
-
-.. example::
-
- .. coqtop:: all
-
- Fail Definition choice (A B: Prop) (x:or A B) :=
- match x with or_introl _ _ a => true | or_intror _ _ b => false end.
-
-From the computational point of view, the structure of the proof of
-:g:`(or A B)` in this term is needed for computing the boolean value.
-
-In general, if :math:`I` has type :math:`\Prop` then :math:`P` cannot have type :math:`I→\Set`, because
-it will mean to build an informative proof of type :math:`(P~m)` doing a case
-analysis over a non-computational object that will disappear in the
-extracted program. But the other way is safe with respect to our
-interpretation we can have :math:`I` a computational object and :math:`P` a
-non-computational one, it just corresponds to proving a logical property
-of a computational object.
-
-In the same spirit, elimination on :math:`P` of type :math:`I→\Type` cannot be allowed
-because it trivially implies the elimination on :math:`P` of type :math:`I→ \Set` by
-cumulativity. It also implies that there are two proofs of the same
-property which are provably different, contradicting the
-proof-irrelevance property which is sometimes a useful axiom:
-
-.. example::
-
- .. coqtop:: all
-
- Axiom proof_irrelevance : forall (P : Prop) (x y : P), x=y.
-
-The elimination of an inductive type of sort :math:`\Prop` on a predicate
-:math:`P` of type :math:`I→ \Type` leads to a paradox when applied to impredicative
-inductive definition like the second-order existential quantifier
-:g:`exProp` defined above, because it gives access to the two projections on
-this type.
-
-
-.. _Empty-and-singleton-elimination:
-
-**Empty and singleton elimination.** There are special inductive definitions in
-:math:`\Prop` for which more eliminations are allowed.
-
-.. inference:: Prop-extended
-
- I~\kw{is an empty or singleton definition}
- s ∈ \Sort
- -------------------------------------
- [I:\Prop|I→ s]
-
-A *singleton definition* has only one constructor and all the
-arguments of this constructor have type :math:`\Prop`. In that case, there is a
-canonical way to interpret the informative extraction on an object in
-that type, such that the elimination on any sort :math:`s` is legal. Typical
-examples are the conjunction of non-informative propositions and the
-equality. If there is a hypothesis :math:`h:a=b` in the local context, it can
-be used for rewriting not only in logical propositions but also in any
-type.
-
-.. example::
-
- .. coqtop:: all
-
- Print eq_rec.
- Require Extraction.
- Extraction eq_rec.
-
-An empty definition has no constructors, in that case also,
-elimination on any sort is allowed.
-
-.. _Eliminaton-for-SProp:
-
-Inductive types in :math:`\SProp` must have no constructors (i.e. be
-empty) to be eliminated to produce relevant values.
-
-Note that thanks to proof irrelevance elimination functions can be
-produced for other types, for instance the elimination for a unit type
-is the identity.
-
-.. _Type-of-branches:
-
-**Type of branches.**
-Let :math:`c` be a term of type :math:`C`, we assume :math:`C` is a type of constructor for an
-inductive type :math:`I`. Let :math:`P` be a term that represents the property to be
-proved. We assume :math:`r` is the number of parameters and :math:`s` is the number of
-arguments.
-
-We define a new type :math:`\{c:C\}^P` which represents the type of the branch
-corresponding to the :math:`c:C` constructor.
-
-.. math::
- \begin{array}{ll}
- \{c:(I~q_1\ldots q_r\ t_1 \ldots t_s)\}^P &\equiv (P~t_1\ldots ~t_s~c) \\
- \{c:∀ x:T,~C\}^P &\equiv ∀ x:T,~\{(c~x):C\}^P
- \end{array}
-
-We write :math:`\{c\}^P` for :math:`\{c:C\}^P` with :math:`C` the type of :math:`c`.
-
-
-.. example::
-
- The following term in concrete syntax::
-
- match t as l return P' with
- | nil _ => t1
- | cons _ hd tl => t2
- end
-
-
- can be represented in abstract syntax as
-
- .. math::
- \case(t,P,f_1 | f_2 )
-
- where
-
- .. math::
- :nowrap:
-
- \begin{eqnarray*}
- P & = & λ l.~P^\prime\\
- f_1 & = & t_1\\
- f_2 & = & λ (hd:\nat).~λ (tl:\List~\nat).~t_2
- \end{eqnarray*}
-
- According to the definition:
-
- .. math::
- \{(\Nil~\nat)\}^P ≡ \{(\Nil~\nat) : (\List~\nat)\}^P ≡ (P~(\Nil~\nat))
-
- .. math::
-
- \begin{array}{rl}
- \{(\cons~\nat)\}^P & ≡\{(\cons~\nat) : (\nat→\List~\nat→\List~\nat)\}^P \\
- & ≡∀ n:\nat,~\{(\cons~\nat~n) : (\List~\nat→\List~\nat)\}^P \\
- & ≡∀ n:\nat,~∀ l:\List~\nat,~\{(\cons~\nat~n~l) : (\List~\nat)\}^P \\
- & ≡∀ n:\nat,~∀ l:\List~\nat,~(P~(\cons~\nat~n~l)).
- \end{array}
-
- Given some :math:`P` then :math:`\{(\Nil~\nat)\}^P` represents the expected type of :math:`f_1`,
- and :math:`\{(\cons~\nat)\}^P` represents the expected type of :math:`f_2`.
-
-
-.. _Typing-rule:
-
-**Typing rule.**
-Our very general destructor for inductive definition enjoys the
-following typing rule
-
-.. inference:: match
-
- \begin{array}{l}
- E[Γ] ⊢ c : (I~q_1 … q_r~t_1 … t_s ) \\
- E[Γ] ⊢ P : B \\
- [(I~q_1 … q_r)|B] \\
- (E[Γ] ⊢ f_i : \{(c_{p_i}~q_1 … q_r)\}^P)_{i=1… l}
- \end{array}
- ------------------------------------------------
- E[Γ] ⊢ \case(c,P,f_1 |… |f_l ) : (P~t_1 … t_s~c)
-
-provided :math:`I` is an inductive type in a
-definition :math:`\ind{r}{Γ_I}{Γ_C}` with :math:`Γ_C = [c_1 :C_1 ;~…;~c_n :C_n ]` and
-:math:`c_{p_1} … c_{p_l}` are the only constructors of :math:`I`.
-
-
-
-.. example::
-
- Below is a typing rule for the term shown in the previous example:
-
- .. inference:: list example
-
- \begin{array}{l}
- E[Γ] ⊢ t : (\List ~\nat) \\
- E[Γ] ⊢ P : B \\
- [(\List ~\nat)|B] \\
- E[Γ] ⊢ f_1 : \{(\Nil ~\nat)\}^P \\
- E[Γ] ⊢ f_2 : \{(\cons ~\nat)\}^P
- \end{array}
- ------------------------------------------------
- E[Γ] ⊢ \case(t,P,f_1 |f_2 ) : (P~t)
-
-
-.. _Definition-of-ι-reduction:
-
-**Definition of ι-reduction.**
-We still have to define the ι-reduction in the general case.
-
-An ι-redex is a term of the following form:
-
-.. math::
- \case((c_{p_i}~q_1 … q_r~a_1 … a_m ),P,f_1 |… |f_l )
-
-with :math:`c_{p_i}` the :math:`i`-th constructor of the inductive type :math:`I` with :math:`r`
-parameters.
-
-The ι-contraction of this term is :math:`(f_i~a_1 … a_m )` leading to the
-general reduction rule:
-
-.. math::
- \case((c_{p_i}~q_1 … q_r~a_1 … a_m ),P,f_1 |… |f_l ) \triangleright_ι (f_i~a_1 … a_m )
-
-
-.. _Fixpoint-definitions:
-
-Fixpoint definitions
-~~~~~~~~~~~~~~~~~~~~
-
-The second operator for elimination is fixpoint definition. This
-fixpoint may involve several mutually recursive definitions. The basic
-concrete syntax for a recursive set of mutually recursive declarations
-is (with :math:`Γ_i` contexts):
-
-.. math::
- \fix~f_1 (Γ_1 ) :A_1 :=t_1~\with … \with~f_n (Γ_n ) :A_n :=t_n
-
-
-The terms are obtained by projections from this set of declarations
-and are written
-
-.. math::
- \fix~f_1 (Γ_1 ) :A_1 :=t_1~\with … \with~f_n (Γ_n ) :A_n :=t_n~\for~f_i
-
-In the inference rules, we represent such a term by
-
-.. math::
- \Fix~f_i\{f_1 :A_1':=t_1' … f_n :A_n':=t_n'\}
-
-with :math:`t_i'` (resp. :math:`A_i'`) representing the term :math:`t_i` abstracted (resp.
-generalized) with respect to the bindings in the context :math:`Γ_i`, namely
-:math:`t_i'=λ Γ_i . t_i` and :math:`A_i'=∀ Γ_i , A_i`.
-
-
-Typing rule
-+++++++++++
-
-The typing rule is the expected one for a fixpoint.
-
-.. inference:: Fix
-
- (E[Γ] ⊢ A_i : s_i )_{i=1… n}
- (E[Γ;~f_1 :A_1 ;~…;~f_n :A_n ] ⊢ t_i : A_i )_{i=1… n}
- -------------------------------------------------------
- E[Γ] ⊢ \Fix~f_i\{f_1 :A_1 :=t_1 … f_n :A_n :=t_n \} : A_i
-
-
-Any fixpoint definition cannot be accepted because non-normalizing
-terms allow proofs of absurdity. The basic scheme of recursion that
-should be allowed is the one needed for defining primitive recursive
-functionals. In that case the fixpoint enjoys a special syntactic
-restriction, namely one of the arguments belongs to an inductive type,
-the function starts with a case analysis and recursive calls are done
-on variables coming from patterns and representing subterms. For
-instance in the case of natural numbers, a proof of the induction
-principle of type
-
-.. math::
- ∀ P:\nat→\Prop,~(P~\nO)→(∀ n:\nat,~(P~n)→(P~(\nS~n)))→ ∀ n:\nat,~(P~n)
-
-can be represented by the term:
-
-.. math::
- \begin{array}{l}
- λ P:\nat→\Prop.~λ f:(P~\nO).~λ g:(∀ n:\nat,~(P~n)→(P~(\nS~n))).\\
- \Fix~h\{h:∀ n:\nat,~(P~n):=λ n:\nat.~\case(n,P,f | λp:\nat.~(g~p~(h~p)))\}
- \end{array}
-
-Before accepting a fixpoint definition as being correctly typed, we
-check that the definition is “guarded”. A precise analysis of this
-notion can be found in :cite:`Gim94`. The first stage is to precise on which
-argument the fixpoint will be decreasing. The type of this argument
-should be an inductive type. For doing this, the syntax of
-fixpoints is extended and becomes
-
-.. math::
- \Fix~f_i\{f_1/k_1 :A_1:=t_1 … f_n/k_n :A_n:=t_n\}
-
-
-where :math:`k_i` are positive integers. Each :math:`k_i` represents the index of
-parameter of :math:`f_i`, on which :math:`f_i` is decreasing. Each :math:`A_i` should be a
-type (reducible to a term) starting with at least :math:`k_i` products
-:math:`∀ y_1 :B_1 ,~… ∀ y_{k_i} :B_{k_i} ,~A_i'` and :math:`B_{k_i}` an inductive type.
-
-Now in the definition :math:`t_i`, if :math:`f_j` occurs then it should be applied to
-at least :math:`k_j` arguments and the :math:`k_j`-th argument should be
-syntactically recognized as structurally smaller than :math:`y_{k_i}`.
-
-The definition of being structurally smaller is a bit technical. One
-needs first to define the notion of *recursive arguments of a
-constructor*. For an inductive definition :math:`\ind{r}{Γ_I}{Γ_C}`, if the
-type of a constructor :math:`c` has the form
-:math:`∀ p_1 :P_1 ,~… ∀ p_r :P_r,~∀ x_1:T_1,~… ∀ x_m :T_m,~(I_j~p_1 … p_r~t_1 … t_s )`,
-then the recursive
-arguments will correspond to :math:`T_i` in which one of the :math:`I_l` occurs.
-
-The main rules for being structurally smaller are the following.
-Given a variable :math:`y` of an inductively defined type in a declaration
-:math:`\ind{r}{Γ_I}{Γ_C}` where :math:`Γ_I` is :math:`[I_1 :A_1 ;~…;~I_k :A_k]`, and :math:`Γ_C` is
-:math:`[c_1 :C_1 ;~…;~c_n :C_n ]`, the terms structurally smaller than :math:`y` are:
-
-
-+ :math:`(t~u)` and :math:`λ x:U .~t` when :math:`t` is structurally smaller than :math:`y`.
-+ :math:`\case(c,P,f_1 … f_n)` when each :math:`f_i` is structurally smaller than :math:`y`.
- If :math:`c` is :math:`y` or is structurally smaller than :math:`y`, its type is an inductive
- type :math:`I_p` part of the inductive definition corresponding to :math:`y`.
- Each :math:`f_i` corresponds to a type of constructor
- :math:`C_q ≡ ∀ p_1 :P_1 ,~…,∀ p_r :P_r ,~∀ y_1 :B_1 ,~… ∀ y_m :B_m ,~(I_p~p_1 … p_r~t_1 … t_s )`
- and can consequently be written :math:`λ y_1 :B_1' .~… λ y_m :B_m'.~g_i`. (:math:`B_i'` is
- obtained from :math:`B_i` by substituting parameters for variables) the variables
- :math:`y_j` occurring in :math:`g_i` corresponding to recursive arguments :math:`B_i` (the
- ones in which one of the :math:`I_l` occurs) are structurally smaller than :math:`y`.
-
-
-The following definitions are correct, we enter them using the :cmd:`Fixpoint`
-command and show the internal representation.
-
-.. example::
-
- .. coqtop:: all
-
- Fixpoint plus (n m:nat) {struct n} : nat :=
- match n with
- | O => m
- | S p => S (plus p m)
- end.
-
- Print plus.
- Fixpoint lgth (A:Set) (l:list A) {struct l} : nat :=
- match l with
- | nil _ => O
- | cons _ a l' => S (lgth A l')
- end.
- Print lgth.
- Fixpoint sizet (t:tree) : nat := let (f) := t in S (sizef f)
- with sizef (f:forest) : nat :=
- match f with
- | emptyf => O
- | consf t f => plus (sizet t) (sizef f)
- end.
- Print sizet.
-
-.. _Reduction-rule:
-
-Reduction rule
-++++++++++++++
-
-Let :math:`F` be the set of declarations:
-:math:`f_1 /k_1 :A_1 :=t_1 …f_n /k_n :A_n:=t_n`.
-The reduction for fixpoints is:
-
-.. math::
- (\Fix~f_i \{F\}~a_1 …a_{k_i}) ~\triangleright_ι~ \subst{t_i}{f_k}{\Fix~f_k \{F\}}_{k=1… n} ~a_1 … a_{k_i}
-
-when :math:`a_{k_i}` starts with a constructor. This last restriction is needed
-in order to keep strong normalization and corresponds to the reduction
-for primitive recursive operators. The following reductions are now
-possible:
-
-.. math::
- :nowrap:
-
- \begin{eqnarray*}
- \plus~(\nS~(\nS~\nO))~(\nS~\nO)~& \trii & \nS~(\plus~(\nS~\nO)~(\nS~\nO))\\
- & \trii & \nS~(\nS~(\plus~\nO~(\nS~\nO)))\\
- & \trii & \nS~(\nS~(\nS~\nO))\\
- \end{eqnarray*}
-
-.. _Mutual-induction:
-
-**Mutual induction**
-
-The principles of mutual induction can be automatically generated
-using the Scheme command described in Section :ref:`proofschemes-induction-principles`.
-
-
.. _Admissible-rules-for-global-environments:
Admissible rules for global environments
@@ -2039,16 +519,6 @@ One can consequently derive the following property.
\WF{E;E′}{Γ}
-.. _Co-inductive-types:
-
-Co-inductive types
-----------------------
-
-The implementation contains also co-inductive definitions, which are
-types inhabited by infinite objects. More information on co-inductive
-definitions can be found in :cite:`Gimenez95b,Gim98,GimCas05`.
-
-
.. _The-Calculus-of-Inductive-Construction-with-impredicative-Set:
The Calculus of Inductive Constructions with impredicative Set
diff --git a/doc/sphinx/language/core/assumptions.rst b/doc/sphinx/language/core/assumptions.rst
new file mode 100644
index 0000000000..9943e0aa76
--- /dev/null
+++ b/doc/sphinx/language/core/assumptions.rst
@@ -0,0 +1,186 @@
+Functions and assumptions
+=========================
+
+.. _binders:
+
+Binders
+-------
+
+.. insertprodn open_binders binder
+
+.. prodn::
+ open_binders ::= {+ @name } : @term
+ | {+ @binder }
+ name ::= _
+ | @ident
+ binder ::= @name
+ | ( {+ @name } : @type )
+ | ( @name {? : @type } := @term )
+ | @implicit_binders
+ | @generalizing_binder
+ | ( @name : @type %| @term )
+ | ' @pattern0
+
+Various constructions such as :g:`fun`, :g:`forall`, :g:`fix` and :g:`cofix`
+*bind* variables. A binding is represented by an identifier. If the binding
+variable is not used in the expression, the identifier can be replaced by the
+symbol :g:`_`. When the type of a bound variable cannot be synthesized by the
+system, it can be specified with the notation :n:`(@ident : @type)`. There is also
+a notation for a sequence of binding variables sharing the same type:
+:n:`({+ @ident} : @type)`. A
+binder can also be any pattern prefixed by a quote, e.g. :g:`'(x,y)`.
+
+Some constructions allow the binding of a variable to value. This is
+called a “let-binder”. The entry :n:`@binder` of the grammar accepts
+either an assumption binder as defined above or a let-binder. The notation in
+the latter case is :n:`(@ident := @term)`. In a let-binder, only one
+variable can be introduced at the same time. It is also possible to give
+the type of the variable as follows:
+:n:`(@ident : @type := @term)`.
+
+Lists of :n:`@binder`\s are allowed. In the case of :g:`fun` and :g:`forall`,
+it is intended that at least one binder of the list is an assumption otherwise
+fun and forall gets identical. Moreover, parentheses can be omitted in
+the case of a single sequence of bindings sharing the same type (e.g.:
+:g:`fun (x y z : A) => t` can be shortened in :g:`fun x y z : A => t`).
+
+.. index:: fun ... => ...
+
+Abstractions: fun
+-----------------
+
+.. insertprodn term_forall_or_fun term_forall_or_fun
+
+.. prodn::
+ term_forall_or_fun ::= forall @open_binders , @term
+ | fun @open_binders => @term
+
+The expression :n:`fun @ident : @type => @term` defines the
+*abstraction* of the variable :n:`@ident`, of type :n:`@type`, over the term
+:n:`@term`. It denotes a function of the variable :n:`@ident` that evaluates to
+the expression :n:`@term` (e.g. :g:`fun x : A => x` denotes the identity
+function on type :g:`A`). The keyword :g:`fun` can be followed by several
+binders as given in Section :ref:`binders`. Functions over
+several variables are equivalent to an iteration of one-variable
+functions. For instance the expression
+:n:`fun {+ @ident__i } : @type => @term`
+denotes the same function as :n:`{+ fun @ident__i : @type => } @term`. If
+a let-binder occurs in
+the list of binders, it is expanded to a let-in definition (see
+Section :ref:`let-in`).
+
+.. index:: forall
+
+Products: forall
+----------------
+
+The expression :n:`forall @ident : @type, @term` denotes the
+*product* of the variable :n:`@ident` of type :n:`@type`, over the term :n:`@term`.
+As for abstractions, :g:`forall` is followed by a binder list, and products
+over several variables are equivalent to an iteration of one-variable
+products. Note that :n:`@term` is intended to be a type.
+
+If the variable :n:`@ident` occurs in :n:`@term`, the product is called
+*dependent product*. The intention behind a dependent product
+:g:`forall x : A, B` is twofold. It denotes either
+the universal quantification of the variable :g:`x` of type :g:`A`
+in the proposition :g:`B` or the functional dependent product from
+:g:`A` to :g:`B` (a construction usually written
+:math:`\Pi_{x:A}.B` in set theory).
+
+Non dependent product types have a special notation: :g:`A -> B` stands for
+:g:`forall _ : A, B`. The *non dependent product* is used both to denote
+the propositional implication and function types.
+
+Applications
+------------
+
+.. insertprodn term_application arg
+
+.. prodn::
+ term_application ::= @term1 {+ @arg }
+ | @ @qualid_annotated {+ @term1 }
+ arg ::= ( @ident := @term )
+ | @term1
+
+:n:`@term__fun @term` denotes applying the function :n:`@term__fun` to :token:`term`.
+
+:n:`@term__fun {+ @term__i }` denotes applying
+:n:`@term__fun` to the arguments :n:`@term__i`. It is
+equivalent to :n:`( … ( @term__fun @term__1 ) … ) @term__n`:
+associativity is to the left.
+
+The notation :n:`(@ident := @term)` for arguments is used for making
+explicit the value of implicit arguments (see
+Section :ref:`explicit-applications`).
+
+.. _gallina-assumptions:
+
+Assumptions
+-----------
+
+Assumptions extend the environment with axioms, parameters, hypotheses
+or variables. An assumption binds an :n:`@ident` to a :n:`@type`. It is accepted
+by Coq if and only if this :n:`@type` is a correct type in the environment
+preexisting the declaration and if :n:`@ident` was not previously defined in
+the same module. This :n:`@type` is considered to be the type (or
+specification, or statement) assumed by :n:`@ident` and we say that :n:`@ident`
+has type :n:`@type`.
+
+.. _Axiom:
+
+.. cmd:: @assumption_token {? Inline {? ( @num ) } } {| {+ ( @assumpt ) } | @assumpt }
+ :name: Axiom; Axioms; Conjecture; Conjectures; Hypothesis; Hypotheses; Parameter; Parameters; Variable; Variables
+
+ .. insertprodn assumption_token of_type
+
+ .. prodn::
+ assumption_token ::= {| Axiom | Axioms }
+ | {| Conjecture | Conjectures }
+ | {| Parameter | Parameters }
+ | {| Hypothesis | Hypotheses }
+ | {| Variable | Variables }
+ assumpt ::= {+ @ident_decl } @of_type
+ ident_decl ::= @ident {? @univ_decl }
+ 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.
+
+ :cmd:`Axiom`, :cmd:`Conjecture`, :cmd:`Parameter` and their plural forms
+ are equivalent. They can take the :attr:`local` :term:`attribute`,
+ which makes the defined :n:`@ident`\s accessible by :cmd:`Import` and its variants
+ only through their fully qualified names.
+
+ Similarly, :cmd:`Hypothesis`, :cmd:`Variable` and their plural forms are equivalent. Outside
+ of a section, these are equivalent to :n:`Local Parameter`. Inside a section, the
+ :n:`@ident`\s defined are only accessible within the section. When the current section
+ 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`.
+
+ The :n:`Inline` clause is only relevant inside functors. See :cmd:`Module`.
+
+.. example:: Simple assumptions
+
+ .. coqtop:: reset in
+
+ Parameter X Y : Set.
+ Parameter (R : X -> Y -> Prop) (S : Y -> X -> Prop).
+ Axiom R_S_inv : forall x y, R x y <-> S y x.
+
+.. exn:: @ident already exists.
+ :name: @ident already exists. (Axiom)
+ :undocumented:
+
+.. warn:: @ident is declared as a local axiom
+
+ Warning generated when using :cmd:`Variable` or its equivalent
+ instead of :n:`Local Parameter` or its equivalent.
+
+.. note::
+ We advise using the commands :cmd:`Axiom`, :cmd:`Conjecture` and
+ :cmd:`Hypothesis` (and their plural forms) for logical postulates (i.e. when
+ the assertion :n:`@type` is of sort :g:`Prop`), and to use the commands
+ :cmd:`Parameter` and :cmd:`Variable` (and their plural forms) in other cases
+ (corresponding to the declaration of an abstract object of the given type).
diff --git a/doc/sphinx/language/core/coinductive.rst b/doc/sphinx/language/core/coinductive.rst
new file mode 100644
index 0000000000..c034b7f302
--- /dev/null
+++ b/doc/sphinx/language/core/coinductive.rst
@@ -0,0 +1,201 @@
+Co-inductive types and co-recursive functions
+=============================================
+
+.. _coinductive-types:
+
+Co-inductive types
+------------------
+
+The objects of an inductive type are well-founded with respect to the
+constructors of the type. In other words, such objects contain only a
+*finite* number of constructors. Co-inductive types arise from relaxing
+this condition, and admitting types whose objects contain an infinity of
+constructors. Infinite objects are introduced by a non-ending (but
+effective) process of construction, defined in terms of the constructors
+of the type.
+
+More information on co-inductive definitions can be found in
+:cite:`Gimenez95b,Gim98,GimCas05`.
+
+.. cmd:: CoInductive @inductive_definition {* with @inductive_definition }
+
+ This command introduces a co-inductive type.
+ The syntax of the command is the same as the command :cmd:`Inductive`.
+ No principle of induction is derived from the definition of a co-inductive
+ type, since such principles only make sense for inductive types.
+ For co-inductive types, the only elimination principle is case analysis.
+
+ 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.
+
+.. example::
+
+ The type of infinite sequences of natural numbers, usually called streams,
+ is an example of a co-inductive type.
+
+ .. coqtop:: in
+
+ CoInductive Stream : Set := Seq : nat -> Stream -> Stream.
+
+ The usual destructors on streams :g:`hd:Stream->nat` and :g:`tl:Str->Str`
+ can be defined as follows:
+
+ .. coqtop:: in
+
+ Definition hd (x:Stream) := let (a,s) := x in a.
+ Definition tl (x:Stream) := let (a,s) := x in s.
+
+Definitions of co-inductive predicates and blocks of mutually
+co-inductive definitions are also allowed.
+
+.. example::
+
+ The extensional equality on streams is an example of a co-inductive type:
+
+ .. coqtop:: in
+
+ CoInductive EqSt : Stream -> Stream -> Prop :=
+ eqst : forall s1 s2:Stream,
+ hd s1 = hd s2 -> EqSt (tl s1) (tl s2) -> EqSt s1 s2.
+
+ In order to prove the extensional equality of two streams :g:`s1` and :g:`s2`
+ we have to construct an infinite proof of equality, that is, an infinite
+ object of type :g:`(EqSt s1 s2)`. We will see how to introduce infinite
+ objects in Section :ref:`cofixpoint`.
+
+Caveat
+~~~~~~
+
+The ability to define co-inductive types by constructors, hereafter called
+*positive co-inductive types*, is known to break subject reduction. The story is
+a bit long: this is due to dependent pattern-matching which implies
+propositional η-equality, which itself would require full η-conversion for
+subject reduction to hold, but full η-conversion is not acceptable as it would
+make type checking undecidable.
+
+Since the introduction of primitive records in Coq 8.5, an alternative
+presentation is available, called *negative co-inductive types*. This consists
+in defining a co-inductive type as a primitive record type through its
+projections. Such a technique is akin to the *co-pattern* style that can be
+found in e.g. Agda, and preserves subject reduction.
+
+The above example can be rewritten in the following way.
+
+.. coqtop:: none
+
+ Reset Stream.
+
+.. coqtop:: all
+
+ Set Primitive Projections.
+ CoInductive Stream : Set := Seq { hd : nat; tl : Stream }.
+ CoInductive EqSt (s1 s2: Stream) : Prop := eqst {
+ eqst_hd : hd s1 = hd s2;
+ eqst_tl : EqSt (tl s1) (tl s2);
+ }.
+
+Some properties that hold over positive streams are lost when going to the
+negative presentation, typically when they imply equality over streams.
+For instance, propositional η-equality is lost when going to the negative
+presentation. It is nonetheless logically consistent to recover it through an
+axiom.
+
+.. coqtop:: all
+
+ Axiom Stream_eta : forall s: Stream, s = Seq (hd s) (tl s).
+
+More generally, as in the case of positive coinductive types, it is consistent
+to further identify extensional equality of coinductive types with propositional
+equality:
+
+.. coqtop:: all
+
+ Axiom Stream_ext : forall (s1 s2: Stream), EqSt s1 s2 -> s1 = s2.
+
+As of Coq 8.9, it is now advised to use negative co-inductive types rather than
+their positive counterparts.
+
+.. seealso::
+ :ref:`primitive_projections` for more information about negative
+ records and primitive projections.
+
+.. index::
+ single: cofix
+
+Co-recursive functions: cofix
+-----------------------------
+
+.. insertprodn term_cofix cofix_body
+
+.. prodn::
+ term_cofix ::= let cofix @cofix_body in @term
+ | cofix @cofix_body {? {+ with @cofix_body } for @ident }
+ cofix_body ::= @ident {* @binder } {? : @type } := @term
+
+The expression
+":n:`cofix @ident__1 @binder__1 : @type__1 with … with @ident__n @binder__n : @type__n for @ident__i`"
+denotes the :math:`i`-th component of a block of terms defined by a mutual guarded
+co-recursion. It is the local counterpart of the :cmd:`CoFixpoint` command. When
+:math:`n=1`, the ":n:`for @ident__i`" clause is omitted.
+
+.. _cofixpoint:
+
+Top-level definitions of co-recursive functions
+-----------------------------------------------
+
+.. cmd:: CoFixpoint @cofix_definition {* with @cofix_definition }
+
+ .. insertprodn cofix_definition cofix_definition
+
+ .. prodn::
+ cofix_definition ::= @ident_decl {* @binder } {? : @type } {? := @term } {? @decl_notations }
+
+ This command introduces a method for constructing an infinite object of a
+ coinductive type. For example, the stream containing all natural numbers can
+ be introduced applying the following method to the number :g:`O` (see
+ Section :ref:`coinductive-types` for the definition of :g:`Stream`, :g:`hd`
+ and :g:`tl`):
+
+ .. coqtop:: all
+
+ CoFixpoint from (n:nat) : Stream := Seq n (from (S n)).
+
+ Unlike recursive definitions, there is no decreasing argument in a
+ co-recursive definition. To be admissible, a method of construction must
+ provide at least one extra constructor of the infinite object for each
+ iteration. A syntactical guard condition is imposed on co-recursive
+ definitions in order to ensure this: each recursive call in the
+ definition must be protected by at least one constructor, and only by
+ constructors. That is the case in the former definition, where the single
+ recursive call of :g:`from` is guarded by an application of :g:`Seq`.
+ On the contrary, the following recursive function does not satisfy the
+ guard condition:
+
+ .. coqtop:: all
+
+ Fail CoFixpoint filter (p:nat -> bool) (s:Stream) : Stream :=
+ if p (hd s) then Seq (hd s) (filter p (tl s)) else filter p (tl s).
+
+ The elimination of co-recursive definition is done lazily, i.e. the
+ definition is expanded only when it occurs at the head of an application
+ which is the argument of a case analysis expression. In any other
+ context, it is considered as a canonical expression which is completely
+ evaluated. We can test this using the command :cmd:`Eval`, which computes
+ the normal forms of a term:
+
+ .. coqtop:: all
+
+ Eval compute in (from 0).
+ Eval compute in (hd (from 0)).
+ Eval compute in (tl (from 0)).
+
+ As in the :cmd:`Fixpoint` command, the :n:`with` clause allows simultaneously
+ defining several mutual cofixpoints.
+
+ 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`.
diff --git a/doc/sphinx/language/core/conversion.rst b/doc/sphinx/language/core/conversion.rst
new file mode 100644
index 0000000000..0f27b65107
--- /dev/null
+++ b/doc/sphinx/language/core/conversion.rst
@@ -0,0 +1,212 @@
+.. _Conversion-rules:
+
+Conversion rules
+--------------------
+
+In |Cic|, there is an internal reduction mechanism. In particular, it
+can decide if two programs are *intentionally* equal (one says
+*convertible*). Convertibility is described in this section.
+
+
+.. _beta-reduction:
+
+β-reduction
+~~~~~~~~~~~
+
+We want to be able to identify some terms as we can identify the
+application of a function to a given argument with its result. For
+instance the identity function over a given type :math:`T` can be written
+:math:`λx:T.~x`. In any global environment :math:`E` and local context
+:math:`Γ`, we want to identify any object :math:`a` (of type
+:math:`T`) with the application :math:`((λ x:T.~x)~a)`. We define for
+this a *reduction* (or a *conversion*) rule we call :math:`β`:
+
+.. math::
+
+ E[Γ] ⊢ ((λx:T.~t)~u)~\triangleright_β~\subst{t}{x}{u}
+
+We say that :math:`\subst{t}{x}{u}` is the *β-contraction* of
+:math:`((λx:T.~t)~u)` and, conversely, that :math:`((λ x:T.~t)~u)` is the
+*β-expansion* of :math:`\subst{t}{x}{u}`.
+
+According to β-reduction, terms of the *Calculus of Inductive
+Constructions* enjoy some fundamental properties such as confluence,
+strong normalization, subject reduction. These results are
+theoretically of great importance but we will not detail them here and
+refer the interested reader to :cite:`Coq85`.
+
+
+.. _iota-reduction:
+
+ι-reduction
+~~~~~~~~~~~
+
+A specific conversion rule is associated to the inductive objects in
+the global environment. We shall give later on (see Section
+:ref:`Well-formed-inductive-definitions`) the precise rules but it
+just says that a destructor applied to an object built from a
+constructor behaves as expected. This reduction is called ι-reduction
+and is more precisely studied in :cite:`Moh93,Wer94`.
+
+
+.. _delta-reduction:
+
+δ-reduction
+~~~~~~~~~~~
+
+We may have variables defined in local contexts or constants defined
+in the global environment. It is legal to identify such a reference
+with its value, that is to expand (or unfold) it into its value. This
+reduction is called δ-reduction and shows as follows.
+
+.. inference:: Delta-Local
+
+ \WFE{\Gamma}
+ (x:=t:T) ∈ Γ
+ --------------
+ E[Γ] ⊢ x~\triangleright_Δ~t
+
+.. inference:: Delta-Global
+
+ \WFE{\Gamma}
+ (c:=t:T) ∈ E
+ --------------
+ E[Γ] ⊢ c~\triangleright_δ~t
+
+
+.. _zeta-reduction:
+
+ζ-reduction
+~~~~~~~~~~~
+
+|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.
+
+.. inference:: Zeta
+
+ \WFE{\Gamma}
+ \WTEG{u}{U}
+ \WTE{\Gamma::(x:=u:U)}{t}{T}
+ --------------
+ E[Γ] ⊢ \letin{x}{u:U}{t}~\triangleright_ζ~\subst{t}{x}{u}
+
+
+.. _eta-expansion:
+
+η-expansion
+~~~~~~~~~~~
+
+Another important concept is η-expansion. It is legal to identify any
+term :math:`t` of functional type :math:`∀ x:T,~U` with its so-called η-expansion
+
+.. math::
+ λx:T.~(t~x)
+
+for :math:`x` an arbitrary variable name fresh in :math:`t`.
+
+
+.. note::
+
+ We deliberately do not define η-reduction:
+
+ .. math::
+ λ x:T.~(t~x)~\not\triangleright_η~t
+
+ This is because, in general, the type of :math:`t` need not to be convertible
+ to the type of :math:`λ x:T.~(t~x)`. E.g., if we take :math:`f` such that:
+
+ .. math::
+ f ~:~ ∀ x:\Type(2),~\Type(1)
+
+ then
+
+ .. math::
+ λ x:\Type(1).~(f~x) ~:~ ∀ x:\Type(1),~\Type(1)
+
+ We could not allow
+
+ .. math::
+ λ x:\Type(1).~(f~x) ~\triangleright_η~ f
+
+ because the type of the reduced term :math:`∀ x:\Type(2),~\Type(1)` would not be
+ convertible to the type of the original term :math:`∀ x:\Type(1),~\Type(1)`.
+
+.. _proof-irrelevance:
+
+Proof Irrelevance
+~~~~~~~~~~~~~~~~~
+
+It is legal to identify any two terms whose common type is a strict
+proposition :math:`A : \SProp`. Terms in a strict propositions are
+therefore called *irrelevant*.
+
+.. _convertibility:
+
+Convertibility
+~~~~~~~~~~~~~~
+
+Let us write :math:`E[Γ] ⊢ t \triangleright u` for the contextual closure of the
+relation :math:`t` reduces to :math:`u` in the global environment
+:math:`E` and local context :math:`Γ` with one of the previous
+reductions β, δ, ι or ζ.
+
+We say that two terms :math:`t_1` and :math:`t_2` are
+*βδιζη-convertible*, or simply *convertible*, or *equivalent*, in the
+global environment :math:`E` and local context :math:`Γ` iff there
+exist terms :math:`u_1` and :math:`u_2` such that :math:`E[Γ] ⊢ t_1 \triangleright
+… \triangleright u_1` and :math:`E[Γ] ⊢ t_2 \triangleright … \triangleright u_2` and either :math:`u_1` and
+:math:`u_2` are identical up to irrelevant subterms, or they are convertible up to η-expansion,
+i.e. :math:`u_1` is :math:`λ x:T.~u_1'` and :math:`u_2 x` is
+recursively convertible to :math:`u_1'`, or, symmetrically,
+:math:`u_2` is :math:`λx:T.~u_2'`
+and :math:`u_1 x` is recursively convertible to :math:`u_2'`. We then write
+:math:`E[Γ] ⊢ t_1 =_{βδιζη} t_2`.
+
+Apart from this we consider two instances of polymorphic and
+cumulative (see Chapter :ref:`polymorphicuniverses`) inductive types
+(see below) convertible
+
+.. math::
+ E[Γ] ⊢ t~w_1 … w_m =_{βδιζη} t~w_1' … w_m'
+
+if we have subtypings (see below) in both directions, i.e.,
+
+.. math::
+ E[Γ] ⊢ t~w_1 … w_m ≤_{βδιζη} t~w_1' … w_m'
+
+and
+
+.. math::
+ E[Γ] ⊢ t~w_1' … w_m' ≤_{βδιζη} t~w_1 … w_m.
+
+Furthermore, we consider
+
+.. math::
+ E[Γ] ⊢ c~v_1 … v_m =_{βδιζη} c'~v_1' … v_m'
+
+convertible if
+
+.. math::
+ E[Γ] ⊢ v_i =_{βδιζη} v_i'
+
+and we have that :math:`c` and :math:`c'`
+are the same constructors of different instances of the same inductive
+types (differing only in universe levels) such that
+
+.. math::
+ E[Γ] ⊢ c~v_1 … v_m : t~w_1 … w_m
+
+and
+
+.. math::
+ E[Γ] ⊢ c'~v_1' … v_m' : t'~ w_1' … w_m '
+
+and we have
+
+.. math::
+ E[Γ] ⊢ t~w_1 … w_m =_{βδιζη} t~w_1' … w_m'.
+
+The convertibility relation allows introducing a new typing rule which
+says that two convertible well-formed types have the same inhabitants.
diff --git a/doc/sphinx/language/core/definitions.rst b/doc/sphinx/language/core/definitions.rst
new file mode 100644
index 0000000000..0e637e5aa3
--- /dev/null
+++ b/doc/sphinx/language/core/definitions.rst
@@ -0,0 +1,204 @@
+Definitions
+===========
+
+.. index:: let ... := ... (term)
+
+.. _let-in:
+
+Let-in definitions
+------------------
+
+.. insertprodn term_let term_let
+
+.. 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
+
+: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’`.
+
+.. index::
+ single: ... : ... (type cast)
+ single: ... <: ...
+ single: ... <<: ...
+
+Type cast
+---------
+
+.. insertprodn term_cast term_cast
+
+.. prodn::
+ term_cast ::= @term10 <: @term
+ | @term10 <<: @term
+ | @term10 : @term
+ | @term10 :>
+
+The expression :n:`@term : @type` is a type cast expression. It enforces
+the type of :n:`@term` to be :n:`@type`.
+
+:n:`@term <: @type` locally sets up the virtual machine for checking that
+:n:`@term` has type :n:`@type`.
+
+:n:`@term <<: @type` uses native compilation for checking that :n:`@term`
+has type :n:`@type`.
+
+.. _gallina-definitions:
+
+Top-level definitions
+---------------------
+
+Definitions extend the environment with associations of names to terms.
+A definition can be seen as a way to give a meaning to a name or as a
+way to abbreviate a term. In any case, the name can later be replaced at
+any time by its definition.
+
+The operation of unfolding a name into its definition is called
+:math:`\delta`-conversion (see Section :ref:`delta-reduction`). A
+definition is accepted by the system if and only if the defined term is
+well-typed in the current context of the definition and if the name is
+not already used. The name defined by the definition is called a
+*constant* and the term it refers to is its *body*. A definition has a
+type which is the type of its body.
+
+A formal presentation of constants and environments is given in
+Section :ref:`typing-rules`.
+
+.. cmd:: {| Definition | Example } @ident_decl @def_body
+ :name: Definition; Example
+
+ .. insertprodn def_body reduce
+
+ .. prodn::
+ def_body ::= {* @binder } {? : @type } := {? @reduce } @term
+ | {* @binder } : @type
+ reduce ::= Eval @red_expr in
+
+ These commands bind :n:`@term` to the name :n:`@ident` in the environment,
+ provided that :n:`@term` is well-typed. They can take the :attr:`local` :term:`attribute`,
+ which makes the defined :n:`@ident` accessible by :cmd:`Import` and its variants
+ only through their fully qualified names.
+ If :n:`@reduce` is present then :n:`@ident` is bound to the result of the specified
+ computation on :n:`@term`.
+
+ These commands also support the :attr:`universes(polymorphic)`,
+ :attr:`universes(monomorphic)`, :attr:`program` and
+ :attr:`canonical` 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.
+ 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`.
+
+ The form :n:`Definition @ident : @type := @term` checks that the type of :n:`@term`
+ is definitionally equal to :n:`@type`, and registers :n:`@ident` as being of type
+ :n:`@type`, and bound to value :n:`@term`.
+
+ The form :n:`Definition @ident {* @binder } : @type := @term` is equivalent to
+ :n:`Definition @ident : forall {* @binder }, @type := fun {* @binder } => @term`.
+
+ .. seealso:: :cmd:`Opaque`, :cmd:`Transparent`, :tacn:`unfold`.
+
+ .. exn:: @ident already exists.
+ :name: @ident already exists. (Definition)
+ :undocumented:
+
+ .. exn:: The term @term has type @type while it is expected to have type @type'.
+ :undocumented:
+
+.. _Assertions:
+
+Assertions and proofs
+---------------------
+
+An assertion states a proposition (or a type) of which the proof (or an
+inhabitant of the type) is interactively built using tactics. The interactive
+proof mode is described in Chapter :ref:`proofhandling` and the tactics in
+Chapter :ref:`Tactics`. The basic assertion command is:
+
+.. cmd:: @thm_token @ident_decl {* @binder } : @type {* with @ident_decl {* @binder } : @type }
+ :name: Theorem; Lemma; Fact; Remark; Corollary; Proposition; Property
+
+ .. insertprodn thm_token thm_token
+
+ .. prodn::
+ thm_token ::= Theorem
+ | Lemma
+ | Fact
+ | Remark
+ | Corollary
+ | Proposition
+ | Property
+
+ After the statement is asserted, Coq needs a proof. Once a proof of
+ :n:`@type` under the assumptions represented by :n:`@binder`\s is given and
+ 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.
+
+ 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
+ :cmd:`Fixpoint` or :cmd:`CoFixpoint` but using tactics to build the proof of
+ the statements (or the body of the specification, depending on the point of
+ view). The inductive or co-inductive types on which the induction or
+ coinduction has to be done is assumed to be non ambiguous and is guessed by
+ the system.
+
+ Like in a :cmd:`Fixpoint` or :cmd:`CoFixpoint` definition, the induction hypotheses
+ have to be used on *structurally smaller* arguments (for a :cmd:`Fixpoint`) or
+ be *guarded by a constructor* (for a :cmd:`CoFixpoint`). The verification that
+ recursive proof arguments are correct is done only at the time of registering
+ the lemma in the environment. To know if the use of induction hypotheses is
+ correct at some time of the interactive development of a proof, use the
+ command :cmd:`Guarded`.
+
+ .. exn:: The term @term has type @type which should be Set, Prop or Type.
+ :undocumented:
+
+ .. exn:: @ident already exists.
+ :name: @ident already exists. (Theorem)
+
+ The name you provided is already defined. You have then to choose
+ another name.
+
+ .. exn:: Nested proofs are not allowed unless you turn the Nested Proofs Allowed flag on.
+
+ You are asserting a new statement while already being in proof editing mode.
+ This feature, called nested proofs, is disabled by default.
+ To activate it, turn the :flag:`Nested Proofs Allowed` flag on.
+
+Proofs start with the keyword :cmd:`Proof`. Then Coq enters the proof editing mode
+until the proof is completed. In proof editing mode, the user primarily enters
+tactics, which are described in chapter :ref:`Tactics`. The user may also enter
+commands to manage the proof editing mode. They are described in Chapter
+:ref:`proofhandling`.
+
+When the proof is complete, use the :cmd:`Qed` command so the kernel verifies
+the proof and adds it to the environment.
+
+.. note::
+
+ #. Several statements can be simultaneously asserted provided the
+ :flag:`Nested Proofs Allowed` flag was turned on.
+
+ #. Not only other assertions but any vernacular command can be given
+ while in the process of proving a given assertion. In this case, the
+ command is understood as if it would have been given before the
+ statements still to be proved. Nonetheless, this practice is discouraged
+ and may stop working in future versions.
+
+ #. Proofs ended by :cmd:`Qed` are declared opaque. Their content cannot be
+ unfolded (see :ref:`performingcomputations`), thus
+ realizing some form of *proof-irrelevance*. To be able to unfold a
+ proof, the proof should be ended by :cmd:`Defined`.
+
+ #. :cmd:`Proof` is recommended but can currently be omitted. On the opposite
+ side, :cmd:`Qed` (or :cmd:`Defined`) is mandatory to validate a proof.
+
+ #. One can also use :cmd:`Admitted` in place of :cmd:`Qed` to turn the
+ current asserted statement into an axiom and exit the proof editing mode.
diff --git a/doc/sphinx/language/core/index.rst b/doc/sphinx/language/core/index.rst
index 5e83672463..de780db267 100644
--- a/doc/sphinx/language/core/index.rst
+++ b/doc/sphinx/language/core/index.rst
@@ -34,10 +34,17 @@ will have to check their output.
:maxdepth: 1
basic
- ../gallina-specification-language
+ sorts
+ assumptions
+ definitions
+ conversion
../cic
+ variants
records
+ inductive
+ coinductive
+ sections
+ modules
+ primitive
../../addendum/universe-polymorphism
../../addendum/sprop
- sections
- ../module-system
diff --git a/doc/sphinx/language/core/inductive.rst b/doc/sphinx/language/core/inductive.rst
new file mode 100644
index 0000000000..4cdfba146a
--- /dev/null
+++ b/doc/sphinx/language/core/inductive.rst
@@ -0,0 +1,1722 @@
+Inductive types and recursive functions
+=======================================
+
+.. _gallina-inductive-definitions:
+
+Inductive types
+---------------
+
+.. cmd:: Inductive @inductive_definition {* with @inductive_definition }
+
+ .. insertprodn inductive_definition constructor
+
+ .. prodn::
+ inductive_definition ::= {? > } @ident_decl {* @binder } {? %| {* @binder } } {? : @type } {? := {? @constructors_or_record } } {? @decl_notations }
+ constructors_or_record ::= {? %| } {+| @constructor }
+ | {? @ident } %{ {*; @record_field } %}
+ constructor ::= @ident {* @binder } {? @of_type }
+
+ This command defines one or more
+ inductive types and its constructors. Coq generates destructors
+ depending on the universe that the inductive type belongs to.
+
+ The destructors are named :n:`@ident`\ ``_rect``, :n:`@ident`\ ``_ind``,
+ :n:`@ident`\ ``_rec`` and :n:`@ident`\ ``_sind``, which
+ respectively correspond to elimination principles on :g:`Type`, :g:`Prop`,
+ :g:`Set` and :g:`SProp`. The type of the destructors
+ expresses structural induction/recursion principles over objects of
+ type :n:`@ident`. The constant :n:`@ident`\ ``_ind`` is always
+ generated, whereas :n:`@ident`\ ``_rec`` and :n:`@ident`\ ``_rect``
+ may be impossible to derive (for example, when :n:`@ident` is a
+ proposition).
+
+ 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.
+
+ Mutually inductive types can be defined by including multiple :n:`@inductive_definition`\s.
+ The :n:`@ident`\s are simultaneously added to the environment before the types of constructors are checked.
+ Each :n:`@ident` can be used independently thereafter.
+ See :ref:`mutually_inductive_types`.
+
+ If the entire inductive definition is parameterized with :n:`@binder`\s, the parameters correspond
+ to a local context in which the entire set of inductive declarations is interpreted.
+ For this reason, the parameters must be strictly the same for each inductive type.
+ See :ref:`parametrized-inductive-types`.
+
+ Constructor :n:`@ident`\s can come with :n:`@binder`\s, in which case
+ the actual type of the constructor is :n:`forall {* @binder }, @type`.
+
+ .. exn:: Non strictly positive occurrence of @ident in @type.
+
+ The types of the constructors have to satisfy a *positivity condition*
+ (see Section :ref:`positivity`). This condition ensures the soundness of
+ the inductive definition. The positivity checking can be disabled using
+ the :flag:`Positivity Checking` flag (see :ref:`controlling-typing-flags`).
+
+ .. exn:: The conclusion of @type is not valid; it must be built from @ident.
+
+ The conclusion of the type of the constructors must be the inductive type
+ :n:`@ident` being defined (or :n:`@ident` applied to arguments in
+ the case of annotated inductive types — cf. next section).
+
+The following subsections show examples of simple inductive types,
+simple annotated inductive types, simple parametric inductive types,
+mutually inductive types and private (matching) inductive types.
+
+.. _simple-inductive-types:
+
+Simple inductive types
+~~~~~~~~~~~~~~~~~~~~~~
+
+A simple inductive type belongs to a universe that is a simple :n:`@sort`.
+
+.. example::
+
+ The set of natural numbers is defined as:
+
+ .. coqtop:: reset all
+
+ Inductive nat : Set :=
+ | O : nat
+ | S : nat -> nat.
+
+ The type nat is defined as the least :g:`Set` containing :g:`O` and closed by
+ the :g:`S` constructor. The names :g:`nat`, :g:`O` and :g:`S` are added to the
+ environment.
+
+ This definition generates four elimination principles:
+ :g:`nat_rect`, :g:`nat_ind`, :g:`nat_rec` and :g:`nat_sind`. The type of :g:`nat_ind` is:
+
+ .. coqtop:: all
+
+ Check nat_ind.
+
+ This is the well known structural induction principle over natural
+ numbers, i.e. the second-order form of Peano’s induction principle. It
+ allows proving universal properties of natural numbers (:g:`forall
+ n:nat, P n`) by induction on :g:`n`.
+
+ The types of :g:`nat_rect`, :g:`nat_rec` and :g:`nat_sind` are similar, except that they
+ apply to, respectively, :g:`(P:nat->Type)`, :g:`(P:nat->Set)` and :g:`(P:nat->SProp)`. They correspond to
+ primitive induction principles (allowing dependent types) respectively
+ over sorts ```Type``, ``Set`` and ``SProp``.
+
+In the case where inductive types don't have annotations (the next section
+gives an example of annotations), a constructor can be defined
+by giving the type of its arguments alone.
+
+.. example::
+
+ .. coqtop:: reset none
+
+ Reset nat.
+
+ .. coqtop:: in
+
+ Inductive nat : Set := O | S (_:nat).
+
+Simple annotated inductive types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In annotated inductive types, the universe where the inductive type
+is defined is no longer a simple :n:`@sort`, but what is called an arity,
+which is a type whose conclusion is a :n:`@sort`.
+
+.. example::
+
+ As an example of annotated inductive types, let us define the
+ :g:`even` predicate:
+
+ .. coqtop:: all
+
+ Inductive even : nat -> Prop :=
+ | even_0 : even O
+ | even_SS : forall n:nat, even n -> even (S (S n)).
+
+ The type :g:`nat->Prop` means that :g:`even` is a unary predicate (inductively
+ defined) over natural numbers. The type of its two constructors are the
+ defining clauses of the predicate :g:`even`. The type of :g:`even_ind` is:
+
+ .. coqtop:: all
+
+ Check even_ind.
+
+ From a mathematical point of view, this asserts that the natural numbers satisfying
+ the predicate :g:`even` are exactly in the smallest set of naturals satisfying the
+ clauses :g:`even_0` or :g:`even_SS`. This is why, when we want to prove any
+ predicate :g:`P` over elements of :g:`even`, it is enough to prove it for :g:`O`
+ and to prove that if any natural number :g:`n` satisfies :g:`P` its double
+ successor :g:`(S (S n))` satisfies also :g:`P`. This is analogous to the
+ structural induction principle we got for :g:`nat`.
+
+.. _parametrized-inductive-types:
+
+Parameterized inductive types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In the previous example, each constructor introduces a different
+instance of the predicate :g:`even`. In some cases, all the constructors
+introduce the same generic instance of the inductive definition, in
+which case, instead of an annotation, we use a context of parameters
+which are :n:`@binder`\s shared by all the constructors of the definition.
+
+Parameters differ from inductive type annotations in that the
+conclusion of each type of constructor invokes the inductive type with
+the same parameter values of its specification.
+
+.. example::
+
+ A typical example is the definition of polymorphic lists:
+
+ .. coqtop:: all
+
+ Inductive list (A:Set) : Set :=
+ | nil : list A
+ | cons : A -> list A -> list A.
+
+ In the type of :g:`nil` and :g:`cons`, we write ":g:`list A`" and not
+ just ":g:`list`". The constructors :g:`nil` and :g:`cons` have these types:
+
+ .. coqtop:: all
+
+ Check nil.
+ Check cons.
+
+ Observe that the destructors are also quantified with :g:`(A:Set)`, for example:
+
+ .. coqtop:: all
+
+ Check list_ind.
+
+ Once again, the types of the constructor arguments and of the conclusion can be omitted:
+
+ .. coqtop:: none
+
+ Reset list.
+
+ .. coqtop:: in
+
+ Inductive list (A:Set) : Set := nil | cons (_:A) (_:list A).
+
+.. note::
+ + The constructor type can
+ recursively invoke the inductive definition on an argument which is not
+ the parameter itself.
+
+ One can define :
+
+ .. coqtop:: all
+
+ Inductive list2 (A:Set) : Set :=
+ | nil2 : list2 A
+ | cons2 : A -> list2 (A*A) -> list2 A.
+
+ that can also be written by specifying only the type of the arguments:
+
+ .. coqtop:: all reset
+
+ Inductive list2 (A:Set) : Set :=
+ | nil2
+ | cons2 (_:A) (_:list2 (A*A)).
+
+ But the following definition will give an error:
+
+ .. coqtop:: all
+
+ Fail Inductive listw (A:Set) : Set :=
+ | nilw : listw (A*A)
+ | consw : A -> listw (A*A) -> listw (A*A).
+
+ because the conclusion of the type of constructors should be :g:`listw A`
+ in both cases.
+
+ + A parameterized inductive definition can be defined using annotations
+ instead of parameters but it will sometimes give a different (bigger)
+ sort for the inductive definition and will produce a less convenient
+ rule for case elimination.
+
+.. flag:: Uniform Inductive Parameters
+
+ When this flag is set (it is off by default),
+ inductive definitions are abstracted over their parameters
+ before type checking constructors, allowing to write:
+
+ .. coqtop:: all
+
+ Set Uniform Inductive Parameters.
+ Inductive list3 (A:Set) : Set :=
+ | nil3 : list3
+ | cons3 : A -> list3 -> list3.
+
+ This behavior is essentially equivalent to starting a new section
+ and using :cmd:`Context` to give the uniform parameters, like so
+ (cf. :ref:`section-mechanism`):
+
+ .. coqtop:: all reset
+
+ Section list3.
+ Context (A:Set).
+ Inductive list3 : Set :=
+ | nil3 : list3
+ | cons3 : A -> list3 -> list3.
+ End list3.
+
+ For finer control, you can use a ``|`` between the uniform and
+ the non-uniform parameters:
+
+ .. coqtop:: in reset
+
+ Inductive Acc {A:Type} (R:A->A->Prop) | (x:A) : Prop
+ := Acc_in : (forall y, R y x -> Acc y) -> Acc x.
+
+ The flag can then be seen as deciding whether the ``|`` is at the
+ beginning (when the flag is unset) or at the end (when it is set)
+ of the parameters when not explicitly given.
+
+.. seealso::
+ Section :ref:`inductive-definitions` and the :tacn:`induction` tactic.
+
+.. _mutually_inductive_types:
+
+Mutually defined inductive types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. example:: Mutually defined inductive types
+
+ A typical example of mutually inductive data types is trees and
+ forests. We assume two types :g:`A` and :g:`B` that are given as variables. The types can
+ be declared like this:
+
+ .. coqtop:: in
+
+ Parameters A B : Set.
+
+ Inductive tree : Set := node : A -> forest -> tree
+
+ with forest : Set :=
+ | leaf : B -> forest
+ | cons : tree -> forest -> forest.
+
+ This declaration automatically generates eight induction principles. They are not the most
+ general principles, but they correspond to each inductive part seen as a single inductive definition.
+
+ To illustrate this point on our example, here are the types of :g:`tree_rec`
+ and :g:`forest_rec`.
+
+ .. coqtop:: all
+
+ Check tree_rec.
+
+ Check forest_rec.
+
+ Assume we want to parameterize our mutual inductive definitions with the
+ two type variables :g:`A` and :g:`B`, the declaration should be
+ done as follows:
+
+ .. coqdoc::
+
+ Inductive tree (A B:Set) : Set := node : A -> forest A B -> tree A B
+
+ with forest (A B:Set) : Set :=
+ | leaf : B -> forest A B
+ | cons : tree A B -> forest A B -> forest A B.
+
+ Assume we define an inductive definition inside a section
+ (cf. :ref:`section-mechanism`). When the section is closed, the variables
+ declared in the section and occurring free in the declaration are added as
+ parameters to the inductive definition.
+
+.. seealso::
+ A generic command :cmd:`Scheme` is useful to build automatically various
+ mutual induction principles.
+
+.. index::
+ single: fix
+
+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
+ fixannot ::= %{ struct @ident %}
+ | %{ wf @one_term @ident %}
+ | %{ measure @one_term {? @ident } {? @one_term } %}
+
+
+The expression ":n:`fix @ident__1 @binder__1 : @type__1 := @term__1 with … with @ident__n @binder__n : @type__n := @term__n for @ident__i`" denotes the
+:math:`i`-th component of a block of functions defined by mutual structural
+recursion. It is the local counterpart of the :cmd:`Fixpoint` command. When
+:math:`n=1`, the ":n:`for @ident__i`" clause is omitted.
+
+The association of a single fixpoint and a local definition have a special
+syntax: :n:`let fix @ident {* @binder } := @term in` stands for
+:n:`let @ident := fix @ident {* @binder } := @term in`. The same applies for co-fixpoints.
+
+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`.
+
+.. _Fixpoint:
+
+Top-level recursive functions
+-----------------------------
+
+This section describes the primitive form of definition by recursion over
+inductive objects. See the :cmd:`Function` command for more advanced
+constructions.
+
+.. cmd:: Fixpoint @fix_definition {* with @fix_definition }
+
+ .. insertprodn fix_definition fix_definition
+
+ .. prodn::
+ fix_definition ::= @ident_decl {* @binder } {? @fixannot } {? : @type } {? := @term } {? @decl_notations }
+
+ This command 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
+ corresponding to these :n:`@binder`\s has type :n:`@type`, and is
+ equivalent to the expression :n:`@term`. The type of :n:`@ident` is
+ consequently :n:`forall {* @binder }, @type` and its value is equivalent
+ to :n:`fun {* @binder } => @term`.
+
+ 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.
+ The point of the :n:`{struct @ident}` annotation (see :n:`@fixannot`) is to
+ let the user tell the system which argument decreases along the recursive calls.
+
+ The :n:`{struct @ident}` annotation may be left implicit, in which case the
+ system successively tries arguments from left to right until it finds one
+ 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`.
+
+ The :n:`with` clause allows simultaneously defining several mutual fixpoints.
+ It is especially useful when defining functions over mutually defined
+ inductive types. Example: :ref:`Mutual Fixpoints<example_mutual_fixpoints>`.
+
+ 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`.
+
+ .. note::
+
+ + Some fixpoints may have several arguments that fit as decreasing
+ arguments, and this choice influences the reduction of the fixpoint.
+ Hence an explicit annotation must be used if the leftmost decreasing
+ argument is not the desired one. Writing explicit annotations can also
+ speed up type checking of large mutual fixpoints.
+
+ + In order to keep the strong normalization property, the fixed point
+ reduction will only be performed when the argument in position of the
+ decreasing argument (which type should be in an inductive definition)
+ starts with a constructor.
+
+
+ .. example::
+
+ One can define the addition function as :
+
+ .. coqtop:: all
+
+ Fixpoint add (n m:nat) {struct n} : nat :=
+ match n with
+ | O => m
+ | S p => S (add p m)
+ end.
+
+ The match operator matches a value (here :g:`n`) with the various
+ constructors of its (inductive) type. The remaining arguments give the
+ respective values to be returned, as functions of the parameters of the
+ corresponding constructor. Thus here when :g:`n` equals :g:`O` we return
+ :g:`m`, and when :g:`n` equals :g:`(S p)` we return :g:`(S (add p m))`.
+
+ The match operator is formally described in
+ Section :ref:`match-construction`.
+ The system recognizes that in the inductive call :g:`(add p m)` the first
+ argument actually decreases because it is a *pattern variable* coming
+ from :g:`match n with`.
+
+ .. example::
+
+ The following definition is not correct and generates an error message:
+
+ .. coqtop:: all
+
+ Fail Fixpoint wrongplus (n m:nat) {struct n} : nat :=
+ match m with
+ | O => n
+ | S p => S (wrongplus n p)
+ end.
+
+ because the declared decreasing argument :g:`n` does not actually
+ decrease in the recursive call. The function computing the addition over
+ the second argument should rather be written:
+
+ .. coqtop:: all
+
+ Fixpoint plus (n m:nat) {struct m} : nat :=
+ match m with
+ | O => n
+ | S p => S (plus n p)
+ end.
+
+ .. example::
+
+ The recursive call may not only be on direct subterms of the recursive
+ variable :g:`n` but also on a deeper subterm and we can directly write
+ the function :g:`mod2` which gives the remainder modulo 2 of a natural
+ number.
+
+ .. coqtop:: all
+
+ Fixpoint mod2 (n:nat) : nat :=
+ match n with
+ | O => O
+ | S p => match p with
+ | O => S O
+ | S q => mod2 q
+ end
+ end.
+
+.. _example_mutual_fixpoints:
+
+ .. example:: Mutual fixpoints
+
+ The size of trees and forests can be defined the following way:
+
+ .. coqtop:: all
+
+ Fixpoint tree_size (t:tree) : nat :=
+ match t with
+ | node a f => S (forest_size f)
+ end
+ with forest_size (f:forest) : nat :=
+ match f with
+ | leaf b => 1
+ | cons t f' => (tree_size t + forest_size f')
+ end.
+
+.. extracted from CIC chapter
+
+.. _inductive-definitions:
+
+Theory of inductive definitions
+-------------------------------
+
+Formally, we can represent any *inductive definition* as
+:math:`\ind{p}{Γ_I}{Γ_C}` where:
+
++ :math:`Γ_I` determines the names and types of inductive types;
++ :math:`Γ_C` determines the names and types of constructors of these
+ inductive types;
++ :math:`p` determines the number of parameters of these inductive types.
+
+
+These inductive definitions, together with global assumptions and
+global definitions, then form the global environment. Additionally,
+for any :math:`p` there always exists :math:`Γ_P =[a_1 :A_1 ;~…;~a_p :A_p ]` such that
+each :math:`T` in :math:`(t:T)∈Γ_I \cup Γ_C` can be written as: :math:`∀Γ_P , T'` where :math:`Γ_P` is
+called the *context of parameters*. Furthermore, we must have that
+each :math:`T` in :math:`(t:T)∈Γ_I` can be written as: :math:`∀Γ_P,∀Γ_{\mathit{Arr}(t)}, S` where
+:math:`Γ_{\mathit{Arr}(t)}` is called the *Arity* of the inductive type :math:`t` and :math:`S` is called
+the sort of the inductive type :math:`t` (not to be confused with :math:`\Sort` which is the set of sorts).
+
+.. example::
+
+ The declaration for parameterized lists is:
+
+ .. math::
+ \ind{1}{[\List:\Set→\Set]}{\left[\begin{array}{rcl}
+ \Nil & : & ∀ A:\Set,~\List~A \\
+ \cons & : & ∀ A:\Set,~A→ \List~A→ \List~A
+ \end{array}
+ \right]}
+
+ which corresponds to the result of the |Coq| declaration:
+
+ .. coqtop:: in reset
+
+ Inductive list (A:Set) : Set :=
+ | nil : list A
+ | cons : A -> list A -> list A.
+
+.. example::
+
+ The declaration for a mutual inductive definition of tree and forest
+ is:
+
+ .. math::
+ \ind{0}{\left[\begin{array}{rcl}\tree&:&\Set\\\forest&:&\Set\end{array}\right]}
+ {\left[\begin{array}{rcl}
+ \node &:& \forest → \tree\\
+ \emptyf &:& \forest\\
+ \consf &:& \tree → \forest → \forest\\
+ \end{array}\right]}
+
+ which corresponds to the result of the |Coq| declaration:
+
+ .. coqtop:: in
+
+ Inductive tree : Set :=
+ | node : forest -> tree
+ with forest : Set :=
+ | emptyf : forest
+ | consf : tree -> forest -> forest.
+
+.. example::
+
+ The declaration for a mutual inductive definition of even and odd is:
+
+ .. math::
+ \ind{0}{\left[\begin{array}{rcl}\even&:&\nat → \Prop \\
+ \odd&:&\nat → \Prop \end{array}\right]}
+ {\left[\begin{array}{rcl}
+ \evenO &:& \even~0\\
+ \evenS &:& ∀ n,~\odd~n → \even~(\nS~n)\\
+ \oddS &:& ∀ n,~\even~n → \odd~(\nS~n)
+ \end{array}\right]}
+
+ which corresponds to the result of the |Coq| declaration:
+
+ .. coqtop:: in
+
+ Inductive even : nat -> Prop :=
+ | even_O : even 0
+ | even_S : forall n, odd n -> even (S n)
+ with odd : nat -> Prop :=
+ | odd_S : forall n, even n -> odd (S n).
+
+
+
+.. _Types-of-inductive-objects:
+
+Types of inductive objects
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We have to give the type of constants in a global environment :math:`E` which
+contains an inductive definition.
+
+.. inference:: Ind
+
+ \WFE{Γ}
+ \ind{p}{Γ_I}{Γ_C} ∈ E
+ (a:A)∈Γ_I
+ ---------------------
+ E[Γ] ⊢ a : A
+
+.. inference:: Constr
+
+ \WFE{Γ}
+ \ind{p}{Γ_I}{Γ_C} ∈ E
+ (c:C)∈Γ_C
+ ---------------------
+ E[Γ] ⊢ c : C
+
+.. example::
+
+ Provided that our environment :math:`E` contains inductive definitions we showed before,
+ these two inference rules above enable us to conclude that:
+
+ .. math::
+ \begin{array}{l}
+ E[Γ] ⊢ \even : \nat→\Prop\\
+ E[Γ] ⊢ \odd : \nat→\Prop\\
+ E[Γ] ⊢ \evenO : \even~\nO\\
+ E[Γ] ⊢ \evenS : ∀ n:\nat,~\odd~n → \even~(\nS~n)\\
+ E[Γ] ⊢ \oddS : ∀ n:\nat,~\even~n → \odd~(\nS~n)
+ \end{array}
+
+
+
+
+.. _Well-formed-inductive-definitions:
+
+Well-formed inductive definitions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We cannot accept any inductive definition because some of them lead
+to inconsistent systems. We restrict ourselves to definitions which
+satisfy a syntactic criterion of positivity. Before giving the formal
+rules, we need a few definitions:
+
+Arity of a given sort
++++++++++++++++++++++
+
+A type :math:`T` is an *arity of sort* :math:`s` if it converts to the sort :math:`s` or to a
+product :math:`∀ x:T,~U` with :math:`U` an arity of sort :math:`s`.
+
+.. example::
+
+ :math:`A→\Set` is an arity of sort :math:`\Set`. :math:`∀ A:\Prop,~A→ \Prop` is an arity of sort
+ :math:`\Prop`.
+
+
+Arity
++++++
+A type :math:`T` is an *arity* if there is a :math:`s∈ \Sort` such that :math:`T` is an arity of
+sort :math:`s`.
+
+
+.. example::
+
+ :math:`A→ \Set` and :math:`∀ A:\Prop,~A→ \Prop` are arities.
+
+
+Type of constructor
++++++++++++++++++++
+We say that :math:`T` is a *type of constructor of* :math:`I` in one of the following
+two cases:
+
++ :math:`T` is :math:`(I~t_1 … t_n )`
++ :math:`T` is :math:`∀ x:U,~T'` where :math:`T'` is also a type of constructor of :math:`I`
+
+.. example::
+
+ :math:`\nat` and :math:`\nat→\nat` are types of constructor of :math:`\nat`.
+ :math:`∀ A:\Type,~\List~A` and :math:`∀ A:\Type,~A→\List~A→\List~A` are types of constructor of :math:`\List`.
+
+.. _positivity:
+
+Positivity Condition
+++++++++++++++++++++
+
+The type of constructor :math:`T` will be said to *satisfy the positivity
+condition* for a constant :math:`X` in the following cases:
+
++ :math:`T=(X~t_1 … t_n )` and :math:`X` does not occur free in any :math:`t_i`
++ :math:`T=∀ x:U,~V` and :math:`X` occurs only strictly positively in :math:`U` and the type :math:`V`
+ satisfies the positivity condition for :math:`X`.
+
+Strict positivity
++++++++++++++++++
+
+The constant :math:`X` *occurs strictly positively* in :math:`T` in the following
+cases:
+
+
++ :math:`X` does not occur in :math:`T`
++ :math:`T` converts to :math:`(X~t_1 … t_n )` and :math:`X` does not occur in any of :math:`t_i`
++ :math:`T` converts to :math:`∀ x:U,~V` and :math:`X` does not occur in type :math:`U` but occurs
+ strictly positively in type :math:`V`
++ :math:`T` converts to :math:`(I~a_1 … a_m~t_1 … t_p )` where :math:`I` is the name of an
+ inductive definition of the form
+
+ .. math::
+ \ind{m}{I:A}{c_1 :∀ p_1 :P_1 ,… ∀p_m :P_m ,~C_1 ;~…;~c_n :∀ p_1 :P_1 ,… ∀p_m :P_m ,~C_n}
+
+ (in particular, it is
+ not mutually defined and it has :math:`m` parameters) and :math:`X` does not occur in
+ any of the :math:`t_i`, and the (instantiated) types of constructor
+ :math:`\subst{C_i}{p_j}{a_j}_{j=1… m}` of :math:`I` satisfy the nested positivity condition for :math:`X`
+
+Nested Positivity
++++++++++++++++++
+
+The type of constructor :math:`T` of :math:`I` *satisfies the nested positivity
+condition* for a constant :math:`X` in the following cases:
+
++ :math:`T=(I~b_1 … b_m~u_1 … u_p)`, :math:`I` is an inductive type with :math:`m`
+ parameters and :math:`X` does not occur in any :math:`u_i`
++ :math:`T=∀ x:U,~V` and :math:`X` occurs only strictly positively in :math:`U` and the type :math:`V`
+ satisfies the nested positivity condition for :math:`X`
+
+
+.. example::
+
+ For instance, if one considers the following variant of a tree type
+ branching over the natural numbers:
+
+ .. coqtop:: in
+
+ Inductive nattree (A:Type) : Type :=
+ | leaf : nattree A
+ | natnode : A -> (nat -> nattree A) -> nattree A.
+
+ Then every instantiated constructor of ``nattree A`` satisfies the nested positivity
+ condition for ``nattree``:
+
+ + Type ``nattree A`` of constructor ``leaf`` satisfies the positivity condition for
+ ``nattree`` because ``nattree`` does not appear in any (real) arguments of the
+ type of that constructor (primarily because ``nattree`` does not have any (real)
+ arguments) ... (bullet 1)
+
+ + Type ``A → (nat → nattree A) → nattree A`` of constructor ``natnode`` satisfies the
+ positivity condition for ``nattree`` because:
+
+ - ``nattree`` occurs only strictly positively in ``A`` ... (bullet 1)
+
+ - ``nattree`` occurs only strictly positively in ``nat → nattree A`` ... (bullet 3 + 2)
+
+ - ``nattree`` satisfies the positivity condition for ``nattree A`` ... (bullet 1)
+
+.. _Correctness-rules:
+
+Correctness rules
++++++++++++++++++
+
+We shall now describe the rules allowing the introduction of a new
+inductive definition.
+
+Let :math:`E` be a global environment and :math:`Γ_P`, :math:`Γ_I`, :math:`Γ_C` be contexts
+such that :math:`Γ_I` is :math:`[I_1 :∀ Γ_P ,A_1 ;~…;~I_k :∀ Γ_P ,A_k]`, and
+:math:`Γ_C` is :math:`[c_1:∀ Γ_P ,C_1 ;~…;~c_n :∀ Γ_P ,C_n ]`. Then
+
+.. inference:: W-Ind
+
+ \WFE{Γ_P}
+ (E[Γ_I ;Γ_P ] ⊢ C_i : s_{q_i} )_{i=1… n}
+ ------------------------------------------
+ \WF{E;~\ind{p}{Γ_I}{Γ_C}}{}
+
+
+provided that the following side conditions hold:
+
+ + :math:`k>0` and all of :math:`I_j` and :math:`c_i` are distinct names for :math:`j=1… k` and :math:`i=1… n`,
+ + :math:`p` is the number of parameters of :math:`\ind{p}{Γ_I}{Γ_C}` and :math:`Γ_P` is the
+ context of parameters,
+ + for :math:`j=1… k` we have that :math:`A_j` is an arity of sort :math:`s_j` and :math:`I_j ∉ E`,
+ + for :math:`i=1… n` we have that :math:`C_i` is a type of constructor of :math:`I_{q_i}` which
+ satisfies the positivity condition for :math:`I_1 … I_k` and :math:`c_i ∉ E`.
+
+One can remark that there is a constraint between the sort of the
+arity of the inductive type and the sort of the type of its
+constructors which will always be satisfied for the impredicative
+sorts :math:`\SProp` and :math:`\Prop` but may fail to define
+inductive type on sort :math:`\Set` and generate constraints
+between universes for inductive types in the Type hierarchy.
+
+
+.. example::
+
+ It is well known that the existential quantifier can be encoded as an
+ inductive definition. The following declaration introduces the
+ second-order existential quantifier :math:`∃ X.P(X)`.
+
+ .. coqtop:: in
+
+ Inductive exProp (P:Prop->Prop) : Prop :=
+ | exP_intro : forall X:Prop, P X -> exProp P.
+
+ The same definition on :math:`\Set` is not allowed and fails:
+
+ .. coqtop:: all
+
+ Fail Inductive exSet (P:Set->Prop) : Set :=
+ exS_intro : forall X:Set, P X -> exSet P.
+
+ It is possible to declare the same inductive definition in the
+ universe :math:`\Type`. The :g:`exType` inductive definition has type
+ :math:`(\Type(i)→\Prop)→\Type(j)` with the constraint that the parameter :math:`X` of :math:`\kw{exT}_{\kw{intro}}`
+ has type :math:`\Type(k)` with :math:`k<j` and :math:`k≤ i`.
+
+ .. coqtop:: all
+
+ Inductive exType (P:Type->Prop) : Type :=
+ exT_intro : forall X:Type, P X -> exType P.
+
+
+.. example:: Negative occurrence (first example)
+
+ The following inductive definition is rejected because it does not
+ satisfy the positivity condition:
+
+ .. coqtop:: all
+
+ Fail Inductive I : Prop := not_I_I (not_I : I -> False) : I.
+
+ If we were to accept such definition, we could derive a
+ contradiction from it (we can test this by disabling the
+ :flag:`Positivity Checking` flag):
+
+ .. coqtop:: none
+
+ Unset Positivity Checking.
+ Inductive I : Prop := not_I_I (not_I : I -> False) : I.
+ Set Positivity Checking.
+
+ .. coqtop:: all
+
+ Definition I_not_I : I -> ~ I := fun i =>
+ match i with not_I_I not_I => not_I end.
+
+ .. coqtop:: in
+
+ Lemma contradiction : False.
+ Proof.
+ enough (I /\ ~ I) as [] by contradiction.
+ split.
+ - apply not_I_I.
+ intro.
+ now apply I_not_I.
+ - intro.
+ now apply I_not_I.
+ Qed.
+
+.. example:: Negative occurrence (second example)
+
+ Here is another example of an inductive definition which is
+ rejected because it does not satify the positivity condition:
+
+ .. coqtop:: all
+
+ Fail Inductive Lam := lam (_ : Lam -> Lam).
+
+ Again, if we were to accept it, we could derive a contradiction
+ (this time through a non-terminating recursive function):
+
+ .. coqtop:: none
+
+ Unset Positivity Checking.
+ Inductive Lam := lam (_ : Lam -> Lam).
+ Set Positivity Checking.
+
+ .. coqtop:: all
+
+ Fixpoint infinite_loop l : False :=
+ match l with lam x => infinite_loop (x l) end.
+
+ Check infinite_loop (lam (@id Lam)) : False.
+
+.. example:: Non strictly positive occurrence
+
+ It is less obvious why inductive type definitions with occurences
+ that are positive but not strictly positive are harmful.
+ We will see that in presence of an impredicative type they
+ are unsound:
+
+ .. coqtop:: all
+
+ Fail Inductive A: Type := introA: ((A -> Prop) -> Prop) -> A.
+
+ If we were to accept this definition we could derive a contradiction
+ by creating an injective function from :math:`A → \Prop` to :math:`A`.
+
+ This function is defined by composing the injective constructor of
+ the type :math:`A` with the function :math:`λx. λz. z = x` injecting
+ any type :math:`T` into :math:`T → \Prop`.
+
+ .. coqtop:: none
+
+ Unset Positivity Checking.
+ Inductive A: Type := introA: ((A -> Prop) -> Prop) -> A.
+ Set Positivity Checking.
+
+ .. coqtop:: all
+
+ Definition f (x: A -> Prop): A := introA (fun z => z = x).
+
+ .. coqtop:: in
+
+ Lemma f_inj: forall x y, f x = f y -> x = y.
+ Proof.
+ unfold f; intros ? ? H; injection H.
+ set (F := fun z => z = y); intro HF.
+ symmetry; replace (y = x) with (F y).
+ + unfold F; reflexivity.
+ + rewrite <- HF; reflexivity.
+ Qed.
+
+ The type :math:`A → \Prop` can be understood as the powerset
+ of the type :math:`A`. To derive a contradiction from the
+ injective function :math:`f` we use Cantor's classic diagonal
+ argument.
+
+ .. coqtop:: all
+
+ Definition d: A -> Prop := fun x => exists s, x = f s /\ ~s x.
+ Definition fd: A := f d.
+
+ .. coqtop:: in
+
+ Lemma cantor: (d fd) <-> ~(d fd).
+ Proof.
+ split.
+ + intros [s [H1 H2]]; unfold fd in H1.
+ replace d with s.
+ * assumption.
+ * apply f_inj; congruence.
+ + intro; exists d; tauto.
+ Qed.
+
+ Lemma bad: False.
+ Proof.
+ pose cantor; tauto.
+ Qed.
+
+ This derivation was first presented by Thierry Coquand and Christine
+ Paulin in :cite:`CP90`.
+
+.. _Template-polymorphism:
+
+Template polymorphism
++++++++++++++++++++++
+
+Inductive types can be made polymorphic over the universes introduced by
+their parameters in :math:`\Type`, if the minimal inferred sort of the
+inductive declarations either mention some of those parameter universes
+or is computed to be :math:`\Prop` or :math:`\Set`.
+
+If :math:`A` is an arity of some sort and :math:`s` is a sort, we write :math:`A_{/s}`
+for the arity obtained from :math:`A` by replacing its sort with :math:`s`.
+Especially, if :math:`A` is well-typed in some global environment and local
+context, then :math:`A_{/s}` is typable by typability of all products in the
+Calculus of Inductive Constructions. The following typing rule is
+added to the theory.
+
+Let :math:`\ind{p}{Γ_I}{Γ_C}` be an inductive definition. Let
+:math:`Γ_P = [p_1 :P_1 ;~…;~p_p :P_p ]` be its context of parameters,
+:math:`Γ_I = [I_1:∀ Γ_P ,A_1 ;~…;~I_k :∀ Γ_P ,A_k ]` its context of definitions and
+:math:`Γ_C = [c_1 :∀ Γ_P ,C_1 ;~…;~c_n :∀ Γ_P ,C_n]` its context of constructors,
+with :math:`c_i` a constructor of :math:`I_{q_i}`. Let :math:`m ≤ p` be the length of the
+longest prefix of parameters such that the :math:`m` first arguments of all
+occurrences of all :math:`I_j` in all :math:`C_k` (even the occurrences in the
+hypotheses of :math:`C_k`) are exactly applied to :math:`p_1 … p_m` (:math:`m` is the number
+of *recursively uniform parameters* and the :math:`p−m` remaining parameters
+are the *recursively non-uniform parameters*). Let :math:`q_1 , …, q_r`, with
+:math:`0≤ r≤ m`, be a (possibly) partial instantiation of the recursively
+uniform parameters of :math:`Γ_P`. We have:
+
+.. inference:: Ind-Family
+
+ \left\{\begin{array}{l}
+ \ind{p}{Γ_I}{Γ_C} \in E\\
+ (E[] ⊢ q_l : P'_l)_{l=1\ldots r}\\
+ (E[] ⊢ P'_l ≤_{βδιζη} \subst{P_l}{p_u}{q_u}_{u=1\ldots l-1})_{l=1\ldots r}\\
+ 1 \leq j \leq k
+ \end{array}
+ \right.
+ -----------------------------
+ E[] ⊢ I_j~q_1 … q_r :∀ [p_{r+1} :P_{r+1} ;~…;~p_p :P_p], (A_j)_{/s_j}
+
+provided that the following side conditions hold:
+
+ + :math:`Γ_{P′}` is the context obtained from :math:`Γ_P` by replacing each :math:`P_l` that is
+ an arity with :math:`P_l'` for :math:`1≤ l ≤ r` (notice that :math:`P_l` arity implies :math:`P_l'`
+ arity since :math:`E[] ⊢ P_l' ≤_{βδιζη} \subst{P_l}{p_u}{q_u}_{u=1\ldots l-1}`);
+ + there are sorts :math:`s_i`, for :math:`1 ≤ i ≤ k` such that, for
+ :math:`Γ_{I'} = [I_1 :∀ Γ_{P'} ,(A_1)_{/s_1} ;~…;~I_k :∀ Γ_{P'} ,(A_k)_{/s_k}]`
+ we have :math:`(E[Γ_{I′} ;Γ_{P′}] ⊢ C_i : s_{q_i})_{i=1… n}` ;
+ + the sorts :math:`s_i` are all introduced by the inductive
+ declaration and have no universe constraints beside being greater
+ than or equal to :math:`\Prop`, and such that all
+ eliminations, to :math:`\Prop`, :math:`\Set` and :math:`\Type(j)`,
+ are allowed (see Section :ref:`Destructors`).
+
+
+Notice that if :math:`I_j~q_1 … q_r` is typable using the rules **Ind-Const** and
+**App**, then it is typable using the rule **Ind-Family**. Conversely, the
+extended theory is not stronger than the theory without **Ind-Family**. We
+get an equiconsistency result by mapping each :math:`\ind{p}{Γ_I}{Γ_C}`
+occurring into a given derivation into as many different inductive
+types and constructors as the number of different (partial)
+replacements of sorts, needed for this derivation, in the parameters
+that are arities (this is possible because :math:`\ind{p}{Γ_I}{Γ_C}` well-formed
+implies that :math:`\ind{p}{Γ_{I'}}{Γ_{C'}}` is well-formed and has the
+same allowed eliminations, where :math:`Γ_{I′}` is defined as above and
+:math:`Γ_{C′} = [c_1 :∀ Γ_{P′} ,C_1 ;~…;~c_n :∀ Γ_{P′} ,C_n ]`). That is, the changes in the
+types of each partial instance :math:`q_1 … q_r` can be characterized by the
+ordered sets of arity sorts among the types of parameters, and to each
+signature is associated a new inductive definition with fresh names.
+Conversion is preserved as any (partial) instance :math:`I_j~q_1 … q_r` or
+:math:`C_i~q_1 … q_r` is mapped to the names chosen in the specific instance of
+:math:`\ind{p}{Γ_I}{Γ_C}`.
+
+.. warning::
+
+ The restriction that sorts are introduced by the inductive
+ declaration prevents inductive types declared in sections to be
+ template-polymorphic on universes introduced previously in the
+ section: they cannot parameterize over the universes introduced with
+ section variables that become parameters at section closing time, as
+ these may be shared with other definitions from the same section
+ which can impose constraints on them.
+
+.. flag:: Auto Template Polymorphism
+
+ This flag, enabled by default, makes every inductive type declared
+ at level :math:`\Type` (without annotations or hiding it behind a
+ definition) template polymorphic if possible.
+
+ This can be prevented using the :attr:`universes(notemplate)`
+ attribute.
+
+ Template polymorphism and full universe polymorphism (see Chapter
+ :ref:`polymorphicuniverses`) are incompatible, so if the latter is
+ enabled (through the :flag:`Universe Polymorphism` flag or the
+ :attr:`universes(polymorphic)` attribute) it will prevail over
+ automatic template polymorphism.
+
+.. warn:: Automatically declaring @ident as template polymorphic.
+
+ Warning ``auto-template`` can be used (it is off by default) to
+ find which types are implicitly declared template polymorphic by
+ :flag:`Auto Template Polymorphism`.
+
+ An inductive type can be forced to be template polymorphic using
+ the :attr:`universes(template)` attribute: in this case, the
+ warning is not emitted.
+
+.. attr:: universes(template)
+
+ This attribute can be used to explicitly declare an inductive type
+ as template polymorphic, whether the :flag:`Auto Template
+ Polymorphism` flag is on or off.
+
+ .. exn:: template and polymorphism not compatible
+
+ This attribute cannot be used in a full universe polymorphic
+ context, i.e. if the :flag:`Universe Polymorphism` flag is on or
+ if the :attr:`universes(polymorphic)` attribute is used.
+
+ .. exn:: Ill-formed template inductive declaration: not polymorphic on any universe.
+
+ The attribute was used but the inductive definition does not
+ satisfy the criterion to be template polymorphic.
+
+.. attr:: universes(notemplate)
+
+ This attribute can be used to prevent an inductive type to be
+ 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
+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.
+The sorts :math:`s_j` are chosen canonically so that each :math:`s_j` is minimal with
+respect to the hierarchy :math:`\Prop ⊂ \Set_p ⊂ \Type` where :math:`\Set_p` is predicative
+:math:`\Set`. More precisely, an empty or small singleton inductive definition
+(i.e. an inductive definition of which all inductive types are
+singleton – see Section :ref:`Destructors`) is set in :math:`\Prop`, a small non-singleton
+inductive type is set in :math:`\Set` (even in case :math:`\Set` is impredicative – see
+:ref:`The-Calculus-of-Inductive-Construction-with-impredicative-Set`),
+and otherwise in the Type hierarchy.
+
+Note that the side-condition about allowed elimination sorts in the rule
+**Ind-Family** avoids to recompute the allowed elimination sorts at each
+instance of a pattern matching (see Section :ref:`Destructors`). As an
+example, let us consider the following definition:
+
+.. example::
+
+ .. coqtop:: in
+
+ Inductive option (A:Type) : Type :=
+ | None : option A
+ | Some : A -> option A.
+
+As the definition is set in the Type hierarchy, it is used
+polymorphically over its parameters whose types are arities of a sort
+in the Type hierarchy. Here, the parameter :math:`A` has this property, hence,
+if :g:`option` is applied to a type in :math:`\Set`, the result is in :math:`\Set`. Note that
+if :g:`option` is applied to a type in :math:`\Prop`, then, the result is not set in
+:math:`\Prop` but in :math:`\Set` still. This is because :g:`option` is not a singleton type
+(see Section :ref:`Destructors`) and it would lose the elimination to :math:`\Set` and :math:`\Type`
+if set in :math:`\Prop`.
+
+.. example::
+
+ .. coqtop:: all
+
+ Check (fun A:Set => option A).
+ Check (fun A:Prop => option A).
+
+Here is another example.
+
+.. example::
+
+ .. coqtop:: in
+
+ Inductive prod (A B:Type) : Type := pair : A -> B -> prod A B.
+
+As :g:`prod` is a singleton type, it will be in :math:`\Prop` if applied twice to
+propositions, in :math:`\Set` if applied twice to at least one type in :math:`\Set` and
+none in :math:`\Type`, and in :math:`\Type` otherwise. In all cases, the three kind of
+eliminations schemes are allowed.
+
+.. example::
+
+ .. coqtop:: all
+
+ Check (fun A:Set => prod A).
+ Check (fun A:Prop => prod A A).
+ Check (fun (A:Prop) (B:Set) => prod A B).
+ Check (fun (A:Type) (B:Prop) => prod A B).
+
+.. note::
+ Template polymorphism used to be called “sort-polymorphism of
+ inductive types” before universe polymorphism
+ (see Chapter :ref:`polymorphicuniverses`) was introduced.
+
+
+.. _Destructors:
+
+Destructors
+~~~~~~~~~~~~~~~~~
+
+The specification of inductive definitions with arities and
+constructors is quite natural. But we still have to say how to use an
+object in an inductive type.
+
+This problem is rather delicate. There are actually several different
+ways to do that. Some of them are logically equivalent but not always
+equivalent from the computational point of view or from the user point
+of view.
+
+From the computational point of view, we want to be able to define a
+function whose domain is an inductively defined type by using a
+combination of case analysis over the possible constructors of the
+object and recursion.
+
+Because we need to keep a consistent theory and also we prefer to keep
+a strongly normalizing reduction, we cannot accept any sort of
+recursion (even terminating). So the basic idea is to restrict
+ourselves to primitive recursive functions and functionals.
+
+For instance, assuming a parameter :math:`A:\Set` exists in the local context,
+we want to build a function :math:`\length` of type :math:`\List~A → \nat` which computes
+the length of the list, such that :math:`(\length~(\Nil~A)) = \nO` and
+:math:`(\length~(\cons~A~a~l)) = (\nS~(\length~l))`.
+We want these equalities to be
+recognized implicitly and taken into account in the conversion rule.
+
+From the logical point of view, we have built a type family by giving
+a set of constructors. We want to capture the fact that we do not have
+any other way to build an object in this type. So when trying to prove
+a property about an object :math:`m` in an inductive type it is enough
+to enumerate all the cases where :math:`m` starts with a different
+constructor.
+
+In case the inductive definition is effectively a recursive one, we
+want to capture the extra property that we have built the smallest
+fixed point of this recursive equation. This says that we are only
+manipulating finite objects. This analysis provides induction
+principles. For instance, in order to prove
+:math:`∀ l:\List~A,~(\kw{has}\_\kw{length}~A~l~(\length~l))` it is enough to prove:
+
+
++ :math:`(\kw{has}\_\kw{length}~A~(\Nil~A)~(\length~(\Nil~A)))`
++ :math:`∀ a:A,~∀ l:\List~A,~(\kw{has}\_\kw{length}~A~l~(\length~l)) →`
+ :math:`(\kw{has}\_\kw{length}~A~(\cons~A~a~l)~(\length~(\cons~A~a~l)))`
+
+
+which given the conversion equalities satisfied by :math:`\length` is the same
+as proving:
+
+
++ :math:`(\kw{has}\_\kw{length}~A~(\Nil~A)~\nO)`
++ :math:`∀ a:A,~∀ l:\List~A,~(\kw{has}\_\kw{length}~A~l~(\length~l)) →`
+ :math:`(\kw{has}\_\kw{length}~A~(\cons~A~a~l)~(\nS~(\length~l)))`
+
+
+One conceptually simple way to do that, following the basic scheme
+proposed by Martin-Löf in his Intuitionistic Type Theory, is to
+introduce for each inductive definition an elimination operator. At
+the logical level it is a proof of the usual induction principle and
+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
+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.
+
+
+.. _match-construction:
+
+The match ... with ... end construction
++++++++++++++++++++++++++++++++++++++++
+
+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
+will be written:
+
+.. math::
+ \Match~m~\with~(c_1~x_{11} ... x_{1p_1} ) ⇒ f_1 | … | (c_n~x_{n1} ... x_{np_n} ) ⇒ f_n~\kwend
+
+In this expression, if :math:`m` eventually happens to evaluate to
+:math:`(c_i~u_1 … u_{p_i})` then the expression will behave as specified in its :math:`i`-th branch
+and it will reduce to :math:`f_i` where the :math:`x_{i1} …x_{ip_i}` are replaced by the
+:math:`u_1 … u_{p_i}` according to the ι-reduction.
+
+Actually, for type checking a :math:`\Match…\with…\kwend` expression we also need
+to know the predicate :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|
+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
+with one parameter and one argument. The predicate is made explicit
+using the syntax:
+
+.. math::
+ \Match~m~\as~x~\In~I~\_~a~\return~P~\with~
+ (c_1~x_{11} ... x_{1p_1} ) ⇒ f_1 | …
+ | (c_n~x_{n1} ... x_{np_n} ) ⇒ f_n~\kwend
+
+The :math:`\as` part can be omitted if either the result type does not depend
+on :math:`m` (non-dependent elimination) or :math:`m` is a variable (in this case, :math:`m`
+can occur in :math:`P` where it is considered a bound variable). The :math:`\In` part
+can be omitted if the result type does not depend on the arguments
+of :math:`I`. Note that the arguments of :math:`I` corresponding to parameters *must*
+be :math:`\_`, because the result type is not generalized to all possible
+values of the parameters. The other arguments of :math:`I` (sometimes called
+indices in the literature) have to be variables (:math:`a` above) and these
+variables can occur in :math:`P`. The expression after :math:`\In` must be seen as an
+*inductive type pattern*. Notice that expansion of implicit arguments
+and notations apply to this pattern. For the purpose of presenting the
+inference rules, we use a more compact notation:
+
+.. math::
+ \case(m,(λ a x . P), λ x_{11} ... x_{1p_1} . f_1~| … |~λ x_{n1} ...x_{np_n} . f_n )
+
+
+.. _Allowed-elimination-sorts:
+
+**Allowed elimination sorts.** An important question for building the typing rule for :math:`\Match` is what
+can be the type of :math:`λ a x . P` with respect to the type of :math:`m`. If :math:`m:I`
+and :math:`I:A` and :math:`λ a x . P : B` then by :math:`[I:A|B]` we mean that one can use
+:math:`λ a x . P` with :math:`m` in the above match-construct.
+
+
+.. _cic_notations:
+
+**Notations.** The :math:`[I:A|B]` is defined as the smallest relation satisfying the
+following rules: We write :math:`[I|B]` for :math:`[I:A|B]` where :math:`A` is the type of :math:`I`.
+
+The case of inductive types in sorts :math:`\Set` or :math:`\Type` is simple.
+There is no restriction on the sort of the predicate to be eliminated.
+
+.. inference:: Prod
+
+ [(I~x):A′|B′]
+ -----------------------
+ [I:∀ x:A,~A′|∀ x:A,~B′]
+
+
+.. inference:: Set & Type
+
+ s_1 ∈ \{\Set,\Type(j)\}
+ s_2 ∈ \Sort
+ ----------------
+ [I:s_1 |I→ s_2 ]
+
+
+The case of Inductive definitions of sort :math:`\Prop` is a bit more
+complicated, because of our interpretation of this sort. The only
+harmless allowed eliminations, are the ones when predicate :math:`P`
+is also of sort :math:`\Prop` or is of the morally smaller sort
+:math:`\SProp`.
+
+.. inference:: Prop
+
+ s ∈ \{\SProp,\Prop\}
+ --------------------
+ [I:\Prop|I→s]
+
+
+:math:`\Prop` is the type of logical propositions, the proofs of properties :math:`P` in
+:math:`\Prop` could not be used for computation and are consequently ignored by
+the extraction mechanism. Assume :math:`A` and :math:`B` are two propositions, and the
+logical disjunction :math:`A ∨ B` is defined inductively by:
+
+.. example::
+
+ .. coqtop:: in
+
+ Inductive or (A B:Prop) : Prop :=
+ or_introl : A -> or A B | or_intror : B -> or A B.
+
+
+The following definition which computes a boolean value by case over
+the proof of :g:`or A B` is not accepted:
+
+.. example::
+
+ .. coqtop:: all
+
+ Fail Definition choice (A B: Prop) (x:or A B) :=
+ match x with or_introl _ _ a => true | or_intror _ _ b => false end.
+
+From the computational point of view, the structure of the proof of
+:g:`(or A B)` in this term is needed for computing the boolean value.
+
+In general, if :math:`I` has type :math:`\Prop` then :math:`P` cannot have type :math:`I→\Set`, because
+it will mean to build an informative proof of type :math:`(P~m)` doing a case
+analysis over a non-computational object that will disappear in the
+extracted program. But the other way is safe with respect to our
+interpretation we can have :math:`I` a computational object and :math:`P` a
+non-computational one, it just corresponds to proving a logical property
+of a computational object.
+
+In the same spirit, elimination on :math:`P` of type :math:`I→\Type` cannot be allowed
+because it trivially implies the elimination on :math:`P` of type :math:`I→ \Set` by
+cumulativity. It also implies that there are two proofs of the same
+property which are provably different, contradicting the
+proof-irrelevance property which is sometimes a useful axiom:
+
+.. example::
+
+ .. coqtop:: all
+
+ Axiom proof_irrelevance : forall (P : Prop) (x y : P), x=y.
+
+The elimination of an inductive type of sort :math:`\Prop` on a predicate
+:math:`P` of type :math:`I→ \Type` leads to a paradox when applied to impredicative
+inductive definition like the second-order existential quantifier
+:g:`exProp` defined above, because it gives access to the two projections on
+this type.
+
+
+.. _Empty-and-singleton-elimination:
+
+**Empty and singleton elimination.** There are special inductive definitions in
+:math:`\Prop` for which more eliminations are allowed.
+
+.. inference:: Prop-extended
+
+ I~\kw{is an empty or singleton definition}
+ s ∈ \Sort
+ -------------------------------------
+ [I:\Prop|I→ s]
+
+A *singleton definition* has only one constructor and all the
+arguments of this constructor have type :math:`\Prop`. In that case, there is a
+canonical way to interpret the informative extraction on an object in
+that type, such that the elimination on any sort :math:`s` is legal. Typical
+examples are the conjunction of non-informative propositions and the
+equality. If there is a hypothesis :math:`h:a=b` in the local context, it can
+be used for rewriting not only in logical propositions but also in any
+type.
+
+.. example::
+
+ .. coqtop:: all
+
+ Print eq_rec.
+ Require Extraction.
+ Extraction eq_rec.
+
+An empty definition has no constructors, in that case also,
+elimination on any sort is allowed.
+
+.. _Eliminaton-for-SProp:
+
+Inductive types in :math:`\SProp` must have no constructors (i.e. be
+empty) to be eliminated to produce relevant values.
+
+Note that thanks to proof irrelevance elimination functions can be
+produced for other types, for instance the elimination for a unit type
+is the identity.
+
+.. _Type-of-branches:
+
+**Type of branches.**
+Let :math:`c` be a term of type :math:`C`, we assume :math:`C` is a type of constructor for an
+inductive type :math:`I`. Let :math:`P` be a term that represents the property to be
+proved. We assume :math:`r` is the number of parameters and :math:`s` is the number of
+arguments.
+
+We define a new type :math:`\{c:C\}^P` which represents the type of the branch
+corresponding to the :math:`c:C` constructor.
+
+.. math::
+ \begin{array}{ll}
+ \{c:(I~q_1\ldots q_r\ t_1 \ldots t_s)\}^P &\equiv (P~t_1\ldots ~t_s~c) \\
+ \{c:∀ x:T,~C\}^P &\equiv ∀ x:T,~\{(c~x):C\}^P
+ \end{array}
+
+We write :math:`\{c\}^P` for :math:`\{c:C\}^P` with :math:`C` the type of :math:`c`.
+
+
+.. example::
+
+ The following term in concrete syntax::
+
+ match t as l return P' with
+ | nil _ => t1
+ | cons _ hd tl => t2
+ end
+
+
+ can be represented in abstract syntax as
+
+ .. math::
+ \case(t,P,f_1 | f_2 )
+
+ where
+
+ .. math::
+ :nowrap:
+
+ \begin{eqnarray*}
+ P & = & λ l.~P^\prime\\
+ f_1 & = & t_1\\
+ f_2 & = & λ (hd:\nat).~λ (tl:\List~\nat).~t_2
+ \end{eqnarray*}
+
+ According to the definition:
+
+ .. math::
+ \{(\Nil~\nat)\}^P ≡ \{(\Nil~\nat) : (\List~\nat)\}^P ≡ (P~(\Nil~\nat))
+
+ .. math::
+
+ \begin{array}{rl}
+ \{(\cons~\nat)\}^P & ≡\{(\cons~\nat) : (\nat→\List~\nat→\List~\nat)\}^P \\
+ & ≡∀ n:\nat,~\{(\cons~\nat~n) : (\List~\nat→\List~\nat)\}^P \\
+ & ≡∀ n:\nat,~∀ l:\List~\nat,~\{(\cons~\nat~n~l) : (\List~\nat)\}^P \\
+ & ≡∀ n:\nat,~∀ l:\List~\nat,~(P~(\cons~\nat~n~l)).
+ \end{array}
+
+ Given some :math:`P` then :math:`\{(\Nil~\nat)\}^P` represents the expected type of :math:`f_1`,
+ and :math:`\{(\cons~\nat)\}^P` represents the expected type of :math:`f_2`.
+
+
+.. _Typing-rule:
+
+**Typing rule.**
+Our very general destructor for inductive definition enjoys the
+following typing rule
+
+.. inference:: match
+
+ \begin{array}{l}
+ E[Γ] ⊢ c : (I~q_1 … q_r~t_1 … t_s ) \\
+ E[Γ] ⊢ P : B \\
+ [(I~q_1 … q_r)|B] \\
+ (E[Γ] ⊢ f_i : \{(c_{p_i}~q_1 … q_r)\}^P)_{i=1… l}
+ \end{array}
+ ------------------------------------------------
+ E[Γ] ⊢ \case(c,P,f_1 |… |f_l ) : (P~t_1 … t_s~c)
+
+provided :math:`I` is an inductive type in a
+definition :math:`\ind{r}{Γ_I}{Γ_C}` with :math:`Γ_C = [c_1 :C_1 ;~…;~c_n :C_n ]` and
+:math:`c_{p_1} … c_{p_l}` are the only constructors of :math:`I`.
+
+
+
+.. example::
+
+ Below is a typing rule for the term shown in the previous example:
+
+ .. inference:: list example
+
+ \begin{array}{l}
+ E[Γ] ⊢ t : (\List ~\nat) \\
+ E[Γ] ⊢ P : B \\
+ [(\List ~\nat)|B] \\
+ E[Γ] ⊢ f_1 : \{(\Nil ~\nat)\}^P \\
+ E[Γ] ⊢ f_2 : \{(\cons ~\nat)\}^P
+ \end{array}
+ ------------------------------------------------
+ E[Γ] ⊢ \case(t,P,f_1 |f_2 ) : (P~t)
+
+
+.. _Definition-of-ι-reduction:
+
+**Definition of ι-reduction.**
+We still have to define the ι-reduction in the general case.
+
+An ι-redex is a term of the following form:
+
+.. math::
+ \case((c_{p_i}~q_1 … q_r~a_1 … a_m ),P,f_1 |… |f_l )
+
+with :math:`c_{p_i}` the :math:`i`-th constructor of the inductive type :math:`I` with :math:`r`
+parameters.
+
+The ι-contraction of this term is :math:`(f_i~a_1 … a_m )` leading to the
+general reduction rule:
+
+.. math::
+ \case((c_{p_i}~q_1 … q_r~a_1 … a_m ),P,f_1 |… |f_l ) \triangleright_ι (f_i~a_1 … a_m )
+
+
+.. _Fixpoint-definitions:
+
+Fixpoint definitions
+~~~~~~~~~~~~~~~~~~~~
+
+The second operator for elimination is fixpoint definition. This
+fixpoint may involve several mutually recursive definitions. The basic
+concrete syntax for a recursive set of mutually recursive declarations
+is (with :math:`Γ_i` contexts):
+
+.. math::
+ \fix~f_1 (Γ_1 ) :A_1 :=t_1~\with … \with~f_n (Γ_n ) :A_n :=t_n
+
+
+The terms are obtained by projections from this set of declarations
+and are written
+
+.. math::
+ \fix~f_1 (Γ_1 ) :A_1 :=t_1~\with … \with~f_n (Γ_n ) :A_n :=t_n~\for~f_i
+
+In the inference rules, we represent such a term by
+
+.. math::
+ \Fix~f_i\{f_1 :A_1':=t_1' … f_n :A_n':=t_n'\}
+
+with :math:`t_i'` (resp. :math:`A_i'`) representing the term :math:`t_i` abstracted (resp.
+generalized) with respect to the bindings in the context :math:`Γ_i`, namely
+:math:`t_i'=λ Γ_i . t_i` and :math:`A_i'=∀ Γ_i , A_i`.
+
+
+Typing rule
++++++++++++
+
+The typing rule is the expected one for a fixpoint.
+
+.. inference:: Fix
+
+ (E[Γ] ⊢ A_i : s_i )_{i=1… n}
+ (E[Γ;~f_1 :A_1 ;~…;~f_n :A_n ] ⊢ t_i : A_i )_{i=1… n}
+ -------------------------------------------------------
+ E[Γ] ⊢ \Fix~f_i\{f_1 :A_1 :=t_1 … f_n :A_n :=t_n \} : A_i
+
+
+Any fixpoint definition cannot be accepted because non-normalizing
+terms allow proofs of absurdity. The basic scheme of recursion that
+should be allowed is the one needed for defining primitive recursive
+functionals. In that case the fixpoint enjoys a special syntactic
+restriction, namely one of the arguments belongs to an inductive type,
+the function starts with a case analysis and recursive calls are done
+on variables coming from patterns and representing subterms. For
+instance in the case of natural numbers, a proof of the induction
+principle of type
+
+.. math::
+ ∀ P:\nat→\Prop,~(P~\nO)→(∀ n:\nat,~(P~n)→(P~(\nS~n)))→ ∀ n:\nat,~(P~n)
+
+can be represented by the term:
+
+.. math::
+ \begin{array}{l}
+ λ P:\nat→\Prop.~λ f:(P~\nO).~λ g:(∀ n:\nat,~(P~n)→(P~(\nS~n))).\\
+ \Fix~h\{h:∀ n:\nat,~(P~n):=λ n:\nat.~\case(n,P,f | λp:\nat.~(g~p~(h~p)))\}
+ \end{array}
+
+Before accepting a fixpoint definition as being correctly typed, we
+check that the definition is “guarded”. A precise analysis of this
+notion can be found in :cite:`Gim94`. The first stage is to precise on which
+argument the fixpoint will be decreasing. The type of this argument
+should be an inductive type. For doing this, the syntax of
+fixpoints is extended and becomes
+
+.. math::
+ \Fix~f_i\{f_1/k_1 :A_1:=t_1 … f_n/k_n :A_n:=t_n\}
+
+
+where :math:`k_i` are positive integers. Each :math:`k_i` represents the index of
+parameter of :math:`f_i`, on which :math:`f_i` is decreasing. Each :math:`A_i` should be a
+type (reducible to a term) starting with at least :math:`k_i` products
+:math:`∀ y_1 :B_1 ,~… ∀ y_{k_i} :B_{k_i} ,~A_i'` and :math:`B_{k_i}` an inductive type.
+
+Now in the definition :math:`t_i`, if :math:`f_j` occurs then it should be applied to
+at least :math:`k_j` arguments and the :math:`k_j`-th argument should be
+syntactically recognized as structurally smaller than :math:`y_{k_i}`.
+
+The definition of being structurally smaller is a bit technical. One
+needs first to define the notion of *recursive arguments of a
+constructor*. For an inductive definition :math:`\ind{r}{Γ_I}{Γ_C}`, if the
+type of a constructor :math:`c` has the form
+:math:`∀ p_1 :P_1 ,~… ∀ p_r :P_r,~∀ x_1:T_1,~… ∀ x_m :T_m,~(I_j~p_1 … p_r~t_1 … t_s )`,
+then the recursive
+arguments will correspond to :math:`T_i` in which one of the :math:`I_l` occurs.
+
+The main rules for being structurally smaller are the following.
+Given a variable :math:`y` of an inductively defined type in a declaration
+:math:`\ind{r}{Γ_I}{Γ_C}` where :math:`Γ_I` is :math:`[I_1 :A_1 ;~…;~I_k :A_k]`, and :math:`Γ_C` is
+:math:`[c_1 :C_1 ;~…;~c_n :C_n ]`, the terms structurally smaller than :math:`y` are:
+
+
++ :math:`(t~u)` and :math:`λ x:U .~t` when :math:`t` is structurally smaller than :math:`y`.
++ :math:`\case(c,P,f_1 … f_n)` when each :math:`f_i` is structurally smaller than :math:`y`.
+ If :math:`c` is :math:`y` or is structurally smaller than :math:`y`, its type is an inductive
+ type :math:`I_p` part of the inductive definition corresponding to :math:`y`.
+ Each :math:`f_i` corresponds to a type of constructor
+ :math:`C_q ≡ ∀ p_1 :P_1 ,~…,∀ p_r :P_r ,~∀ y_1 :B_1 ,~… ∀ y_m :B_m ,~(I_p~p_1 … p_r~t_1 … t_s )`
+ and can consequently be written :math:`λ y_1 :B_1' .~… λ y_m :B_m'.~g_i`. (:math:`B_i'` is
+ obtained from :math:`B_i` by substituting parameters for variables) the variables
+ :math:`y_j` occurring in :math:`g_i` corresponding to recursive arguments :math:`B_i` (the
+ ones in which one of the :math:`I_l` occurs) are structurally smaller than :math:`y`.
+
+
+The following definitions are correct, we enter them using the :cmd:`Fixpoint`
+command and show the internal representation.
+
+.. example::
+
+ .. coqtop:: all
+
+ Fixpoint plus (n m:nat) {struct n} : nat :=
+ match n with
+ | O => m
+ | S p => S (plus p m)
+ end.
+
+ Print plus.
+ Fixpoint lgth (A:Set) (l:list A) {struct l} : nat :=
+ match l with
+ | nil _ => O
+ | cons _ a l' => S (lgth A l')
+ end.
+ Print lgth.
+ Fixpoint sizet (t:tree) : nat := let (f) := t in S (sizef f)
+ with sizef (f:forest) : nat :=
+ match f with
+ | emptyf => O
+ | consf t f => plus (sizet t) (sizef f)
+ end.
+ Print sizet.
+
+.. _Reduction-rule:
+
+Reduction rule
+++++++++++++++
+
+Let :math:`F` be the set of declarations:
+:math:`f_1 /k_1 :A_1 :=t_1 …f_n /k_n :A_n:=t_n`.
+The reduction for fixpoints is:
+
+.. math::
+ (\Fix~f_i \{F\}~a_1 …a_{k_i}) ~\triangleright_ι~ \subst{t_i}{f_k}{\Fix~f_k \{F\}}_{k=1… n} ~a_1 … a_{k_i}
+
+when :math:`a_{k_i}` starts with a constructor. This last restriction is needed
+in order to keep strong normalization and corresponds to the reduction
+for primitive recursive operators. The following reductions are now
+possible:
+
+.. math::
+ :nowrap:
+
+ \begin{eqnarray*}
+ \plus~(\nS~(\nS~\nO))~(\nS~\nO)~& \trii & \nS~(\plus~(\nS~\nO)~(\nS~\nO))\\
+ & \trii & \nS~(\nS~(\plus~\nO~(\nS~\nO)))\\
+ & \trii & \nS~(\nS~(\nS~\nO))\\
+ \end{eqnarray*}
+
+.. _Mutual-induction:
+
+**Mutual induction**
+
+The principles of mutual induction can be automatically generated
+using the Scheme command described in Section :ref:`proofschemes-induction-principles`.
diff --git a/doc/sphinx/language/core/modules.rst b/doc/sphinx/language/core/modules.rst
new file mode 100644
index 0000000000..29e703c223
--- /dev/null
+++ b/doc/sphinx/language/core/modules.rst
@@ -0,0 +1,1012 @@
+.. _themodulesystem:
+
+The Module System
+=================
+
+The module system extends the Calculus of Inductive Constructions
+providing a convenient way to structure large developments as well as
+a means of massive abstraction.
+
+
+Modules and module types
+----------------------------
+
+**Access path.** An access path is denoted by :math:`p` and can be
+either a module variable :math:`X` or, if :math:`p′` is an access path
+and :math:`id` an identifier, then :math:`p′.id` is an access path.
+
+
+**Structure element.** A structure element is denoted by :math:`e` and
+is either a definition of a constant, an assumption, a definition of
+an inductive, a definition of a module, an alias of a module or a module
+type abbreviation.
+
+
+**Structure expression.** A structure expression is denoted by :math:`S` and can be:
+
++ an access path :math:`p`
++ a plain structure :math:`\Struct~e ; … ; e~\End`
++ a functor :math:`\Functor(X:S)~S′`, where :math:`X` is a module variable, :math:`S` and :math:`S′` are
+ structure expressions
++ an application :math:`S~p`, where :math:`S` is a structure expression and :math:`p` an
+ access path
++ a refined structure :math:`S~\with~p := p`′ or :math:`S~\with~p := t:T` where :math:`S` is a
+ structure expression, :math:`p` and :math:`p′` are access paths, :math:`t` is a term and :math:`T` is
+ the type of :math:`t`.
+
+**Module definition.** A module definition is written :math:`\Mod{X}{S}{S'}`
+and consists of a module variable :math:`X`, a module type
+:math:`S` which can be any structure expression and optionally a
+module implementation :math:`S′` which can be any structure expression
+except a refined structure.
+
+
+**Module alias.** A module alias is written :math:`\ModA{X}{p}`
+and consists of a module variable :math:`X` and a module path
+:math:`p`.
+
+**Module type abbreviation.**
+A module type abbreviation is written :math:`\ModType{Y}{S}`,
+where :math:`Y` is an identifier and :math:`S` is any structure
+expression .
+
+.. extracted from Gallina extensions chapter
+
+Using modules
+-------------
+
+The module system provides a way of packaging related elements
+together, as well as a means of massive abstraction.
+
+
+.. cmd:: Module {? {| Import | Export } } @ident {* @module_binder } {? @of_module_type } {? := {+<+ @module_expr_inl } }
+
+ .. insertprodn module_binder module_expr_inl
+
+ .. prodn::
+ module_binder ::= ( {? {| Import | Export } } {+ @ident } : @module_type_inl )
+ module_type_inl ::= ! @module_type
+ | @module_type {? @functor_app_annot }
+ functor_app_annot ::= [ inline at level @num ]
+ | [ no inline ]
+ module_type ::= @qualid
+ | ( @module_type )
+ | @module_type @module_expr_atom
+ | @module_type with @with_declaration
+ with_declaration ::= Definition @qualid {? @univ_decl } := @term
+ | Module @qualid := @qualid
+ module_expr_atom ::= @qualid
+ | ( {+ @module_expr_atom } )
+ of_module_type ::= : @module_type_inl
+ | {* <: @module_type_inl }
+ module_expr_inl ::= ! {+ @module_expr_atom }
+ | {+ @module_expr_atom } {? @functor_app_annot }
+
+ Defines a module named :token:`ident`. See the examples :ref:`here<module_examples>`.
+
+ The :n:`Import` and :n:`Export` flags specify whether the module should be automatically
+ imported or exported.
+
+ Specifying :n:`{* @module_binder }` starts a functor with
+ parameters given by the :n:`@module_binder`\s. (A *functor* is a function
+ from modules to modules.)
+
+ :n:`@of_module_type` specifies the module type. :n:`{+ <: @module_type_inl }`
+ starts a module that satisfies each :n:`@module_type_inl`.
+
+ .. todo: would like to find a better term than "interactive", not very descriptive
+
+ :n:`:= {+<+ @module_expr_inl }` specifies the body of a module or functor
+ definition. If it's not specified, then the module is defined *interactively*,
+ meaning that the module is defined as a series of commands terminated with :cmd:`End`
+ instead of in a single :cmd:`Module` command.
+ Interactively defining the :n:`@module_expr_inl`\s in a series of
+ :cmd:`Include` commands is equivalent to giving them all in a single
+ non-interactive :cmd:`Module` command.
+
+ The ! prefix indicates that any assumption command (such as :cmd:`Axiom`) with an :n:`Inline` clause
+ in the type of the functor arguments will be ignored.
+
+ .. todo: What is an Inline directive? sb command but still unclear. Maybe referring to the
+ "inline" in functor_app_annot? or assumption_token Inline assum_list?
+
+.. cmd:: Module Type @ident {* @module_binder } {* <: @module_type_inl } {? := {+<+ @module_type_inl } }
+
+ Defines a module type named :n:`@ident`. See the example :ref:`here<example_def_simple_module_type>`.
+
+ Specifying :n:`{* @module_binder }` starts a functor type with
+ parameters given by the :n:`@module_binder`\s.
+
+ :n:`:= {+<+ @module_type_inl }` specifies the body of a module or functor type
+ definition. If it's not specified, then the module type is defined *interactively*,
+ meaning that the module type is defined as a series of commands terminated with :cmd:`End`
+ instead of in a single :cmd:`Module Type` command.
+ Interactively defining the :n:`@module_type_inl`\s in a series of
+ :cmd:`Include` commands is equivalent to giving them all in a single
+ non-interactive :cmd:`Module Type` command.
+
+.. _terminating_module:
+
+**Terminating an interactive module or module type definition**
+
+Interactive modules are terminated with the :cmd:`End` command, which
+is also used to terminate :ref:`Sections<section-mechanism>`.
+:n:`End @ident` closes the interactive module or module type :token:`ident`.
+If the module type was given, the command verifies that the content of the module
+matches the module type. If the module is not a
+functor, its components (constants, inductive types, submodules etc.)
+are now available through the dot notation.
+
+.. exn:: No such label @ident.
+ :undocumented:
+
+.. exn:: Signature components for label @ident do not match.
+ :undocumented:
+
+.. exn:: The field @ident is missing in @qualid.
+ :undocumented:
+
+.. |br| raw:: html
+
+ <br>
+
+.. note::
+
+ #. Interactive modules and module types can be nested.
+ #. Interactive modules and module types can't be defined inside of :ref:`sections<section-mechanism>`.
+ Sections can be defined inside of interactive modules and module types.
+ #. Hints and notations (:cmd:`Hint` and :cmd:`Notation` commands) can also appear inside interactive
+ modules and module types. Note that with module definitions like:
+
+ :n:`Module @ident__1 : @module_type := @ident__2.`
+
+ or
+
+ :n:`Module @ident__1 : @module_type.` |br|
+ :n:`Include @ident__2.` |br|
+ :n:`End @ident__1.`
+
+ hints and the like valid for :n:`@ident__1` are the ones defined in :n:`@module_type`
+ rather then those defined in :n:`@ident__2` (or the module body).
+ #. Within an interactive module type definition, the :cmd:`Parameter` command declares a
+ constant instead of definining a new axiom (which it does when not in a module type definition).
+ #. Assumptions such as :cmd:`Axiom` that include the :n:`Inline` clause will be automatically
+ expanded when the functor is applied, except when the function application is prefixed by ``!``.
+
+.. cmd:: Include @module_type_inl {* <+ @module_expr_inl }
+
+ Includes the content of module(s) in the current
+ interactive module. Here :n:`@module_type_inl` can be a module expression or a module
+ type expression. If it is a high-order module or module type
+ expression then the system tries to instantiate :n:`@module_type_inl` with the current
+ interactive module.
+
+ Including multiple modules is a single :cmd:`Include` is equivalent to including each module
+ in a separate :cmd:`Include` command.
+
+.. cmd:: Include Type {+<+ @module_type_inl }
+
+ .. deprecated:: 8.3
+
+ Use :cmd:`Include` instead.
+
+.. cmd:: Declare Module {? {| Import | Export } } @ident {* @module_binder } : @module_type_inl
+
+ Declares a module :token:`ident` of type :token:`module_type_inl`.
+
+ If :n:`@module_binder`\s are specified, declares a functor with parameters given by the list of
+ :token:`module_binder`\s.
+
+.. cmd:: Import {+ @filtered_import }
+
+ .. insertprodn filtered_import filtered_import
+
+ .. prodn::
+ filtered_import ::= @qualid {? ( {+, @qualid {? ( .. ) } } ) }
+
+ If :token:`qualid` denotes a valid basic module (i.e. its module type is a
+ signature), makes its components available by their short names.
+
+ .. example::
+
+ .. coqtop:: reset in
+
+ Module Mod.
+ Definition T:=nat.
+ Check T.
+ End Mod.
+ Check Mod.T.
+
+ .. coqtop:: all
+
+ Fail Check T.
+ Import Mod.
+ Check T.
+
+ Some features defined in modules are activated only when a module is
+ imported. This is for instance the case of notations (see :ref:`Notations`).
+
+ Declarations made with the :attr:`local` attribute are never imported by the :cmd:`Import`
+ command. Such declarations are only accessible through their fully
+ qualified name.
+
+ .. example::
+
+ .. coqtop:: in
+
+ Module A.
+ Module B.
+ Local Definition T := nat.
+ End B.
+ End A.
+ Import A.
+
+ .. coqtop:: all fail
+
+ Check B.T.
+
+ Appending a module name with a parenthesized list of names will
+ make only those names available with short names, not other names
+ defined in the module nor will it activate other features.
+
+ The names to import may be constants, inductive types and
+ constructors, and notation aliases (for instance, Ltac definitions
+ cannot be selectively imported). If they are from an inner module
+ to the one being imported, they must be prefixed by the inner path.
+
+ The name of an inductive type may also be followed by ``(..)`` to
+ import it, its constructors and its eliminators if they exist. For
+ this purpose "eliminator" means a constant in the same module whose
+ name is the inductive type's name suffixed by one of ``_sind``,
+ ``_ind``, ``_rec`` or ``_rect``.
+
+ .. example::
+
+ .. coqtop:: reset in
+
+ Module A.
+ Module B.
+ Inductive T := C.
+ Definition U := nat.
+ End B.
+ Definition Z := Prop.
+ End A.
+ Import A(B.T(..), Z).
+
+ .. coqtop:: all
+
+ Check B.T.
+ Check B.C.
+ Check Z.
+ Fail Check B.U.
+ Check A.B.U.
+
+.. cmd:: Export {+ @filtered_import }
+ :name: Export
+
+ Similar to :cmd:`Import`, except that when the module containing this command
+ is imported, the :n:`{+ @qualid }` are imported as well.
+
+ The selective import syntax also works with Export.
+
+ .. exn:: @qualid is not a module.
+ :undocumented:
+
+ .. warn:: Trying to mask the absolute name @qualid!
+ :undocumented:
+
+.. cmd:: Print Module @qualid
+
+ Prints the module type and (optionally) the body of the module :n:`@qualid`.
+
+.. cmd:: Print Module Type @qualid
+
+ Prints the module type corresponding to :n:`@qualid`.
+
+.. flag:: Short Module Printing
+
+ This flag (off by default) disables the printing of the types of fields,
+ leaving only their names, for the commands :cmd:`Print Module` and
+ :cmd:`Print Module Type`.
+
+.. _module_examples:
+
+Examples
+~~~~~~~~
+
+.. example:: Defining a simple module interactively
+
+ .. coqtop:: in
+
+ Module M.
+ Definition T := nat.
+ Definition x := 0.
+
+ .. coqtop:: all
+
+ Definition y : bool.
+ exact true.
+
+ .. coqtop:: in
+
+ Defined.
+ End M.
+
+Inside a module one can define constants, prove theorems and do anything
+else that can be done in the toplevel. Components of a closed
+module can be accessed using the dot notation:
+
+.. coqtop:: all
+
+ Print M.x.
+
+.. _example_def_simple_module_type:
+
+.. example:: Defining a simple module type interactively
+
+ .. coqtop:: in
+
+ Module Type SIG.
+ Parameter T : Set.
+ Parameter x : T.
+ End SIG.
+
+.. _example_filter_module:
+
+.. example:: Creating a new module that omits some items from an existing module
+
+ Since :n:`SIG`, the type of the new module :n:`N`, doesn't define :n:`y` or
+ give the body of :n:`x`, which are not included in :n:`N`.
+
+ .. coqtop:: all
+
+ Module N : SIG with Definition T := nat := M.
+ Print N.T.
+ Print N.x.
+ Fail Print N.y.
+
+ .. reset to remove N (undo in last coqtop block doesn't seem to do that), invisibly redefine M, SIG
+ .. coqtop:: none reset
+
+ Module M.
+ Definition T := nat.
+ Definition x := 0.
+ Definition y : bool.
+ exact true.
+ Defined.
+ End M.
+
+ Module Type SIG.
+ Parameter T : Set.
+ Parameter x : T.
+ End SIG.
+
+The definition of :g:`N` using the module type expression :g:`SIG` with
+:g:`Definition T := nat` is equivalent to the following one:
+
+.. coqtop:: in
+
+ Module Type SIG'.
+ Definition T : Set := nat.
+ Parameter x : T.
+ End SIG'.
+
+ Module N : SIG' := M.
+
+If we just want to be sure that our implementation satisfies a
+given module type without restricting the interface, we can use a
+transparent constraint
+
+.. coqtop:: in
+
+ Module P <: SIG := M.
+
+.. coqtop:: all
+
+ Print P.y.
+
+.. example:: Creating a functor (a module with parameters)
+
+ .. coqtop:: in
+
+ Module Two (X Y: SIG).
+ Definition T := (X.T * Y.T)%type.
+ Definition x := (X.x, Y.x).
+ End Two.
+
+ and apply it to our modules and do some computations:
+
+ .. coqtop:: in
+
+
+ Module Q := Two M N.
+
+ .. coqtop:: all
+
+ Eval compute in (fst Q.x + snd Q.x).
+
+.. example:: A module type with two sub-modules, sharing some fields
+
+ .. coqtop:: in
+
+ Module Type SIG2.
+ Declare Module M1 : SIG.
+ Module M2 <: SIG.
+ Definition T := M1.T.
+ Parameter x : T.
+ End M2.
+ End SIG2.
+
+ .. coqtop:: in
+
+ Module Mod <: SIG2.
+ Module M1.
+ Definition T := nat.
+ Definition x := 1.
+ End M1.
+ Module M2 := M.
+ End Mod.
+
+Notice that ``M`` is a correct body for the component ``M2`` since its ``T``
+component is ``nat`` as specified for ``M1.T``.
+
+Typing Modules
+------------------
+
+In order to introduce the typing system we first slightly extend the syntactic
+class of terms and environments given in section :ref:`The-terms`. The
+environments, apart from definitions of constants and inductive types now also
+hold any other structure elements. Terms, apart from variables, constants and
+complex terms, include also access paths.
+
+We also need additional typing judgments:
+
+
++ :math:`\WFT{E}{S}`, denoting that a structure :math:`S` is well-formed,
++ :math:`\WTM{E}{p}{S}`, denoting that the module pointed by :math:`p` has type :math:`S` in
+ environment :math:`E`.
++ :math:`\WEV{E}{S}{\ovl{S}}`, denoting that a structure :math:`S` is evaluated to a
+ structure :math:`S` in weak head normal form.
++ :math:`\WS{E}{S_1}{S_2}` , denoting that a structure :math:`S_1` is a subtype of a
+ structure :math:`S_2`.
++ :math:`\WS{E}{e_1}{e_2}` , denoting that a structure element e_1 is more
+ precise than a structure element e_2.
+
+The rules for forming structures are the following:
+
+.. inference:: WF-STR
+
+ \WF{E;E′}{}
+ ------------------------
+ \WFT{E}{ \Struct~E′ ~\End}
+
+.. inference:: WF-FUN
+
+ \WFT{E; \ModS{X}{S}}{ \ovl{S′} }
+ --------------------------
+ \WFT{E}{ \Functor(X:S)~S′}
+
+
+Evaluation of structures to weak head normal form:
+
+.. inference:: WEVAL-APP
+
+ \begin{array}{c}
+ \WEV{E}{S}{\Functor(X:S_1 )~S_2}~~~~~\WEV{E}{S_1}{\ovl{S_1}} \\
+ \WTM{E}{p}{S_3}~~~~~ \WS{E}{S_3}{\ovl{S_1}}
+ \end{array}
+ --------------------------
+ \WEV{E}{S~p}{S_2 \{p/X,t_1 /p_1 .c_1 ,…,t_n /p_n.c_n \}}
+
+
+In the last rule, :math:`\{t_1 /p_1 .c_1 ,…,t_n /p_n .c_n \}` is the resulting
+substitution from the inlining mechanism. We substitute in :math:`S` the
+inlined fields :math:`p_i .c_i` from :math:`\ModS{X}{S_1 }` by the corresponding delta-
+reduced term :math:`t_i` in :math:`p`.
+
+.. inference:: WEVAL-WITH-MOD
+
+ \begin{array}{c}
+ E[] ⊢ S \lra \Struct~e_1 ;…;e_i ; \ModS{X}{S_1 };e_{i+2} ;… ;e_n ~\End \\
+ E;e_1 ;…;e_i [] ⊢ S_1 \lra \ovl{S_1} ~~~~~~
+ E[] ⊢ p : S_2 \\
+ E;e_1 ;…;e_i [] ⊢ S_2 <: \ovl{S_1}
+ \end{array}
+ ----------------------------------
+ \begin{array}{c}
+ \WEV{E}{S~\with~x := p}{}\\
+ \Struct~e_1 ;…;e_i ; \ModA{X}{p};e_{i+2} \{p/X\} ;…;e_n \{p/X\} ~\End
+ \end{array}
+
+.. inference:: WEVAL-WITH-MOD-REC
+
+ \begin{array}{c}
+ \WEV{E}{S}{\Struct~e_1 ;…;e_i ; \ModS{X_1}{S_1 };e_{i+2} ;… ;e_n ~\End} \\
+ \WEV{E;e_1 ;…;e_i }{S_1~\with~p := p_1}{\ovl{S_2}}
+ \end{array}
+ --------------------------
+ \begin{array}{c}
+ \WEV{E}{S~\with~X_1.p := p_1}{} \\
+ \Struct~e_1 ;…;e_i ; \ModS{X}{\ovl{S_2}};e_{i+2} \{p_1 /X_1.p\} ;…;e_n \{p_1 /X_1.p\} ~\End
+ \end{array}
+
+.. inference:: WEVAL-WITH-DEF
+
+ \begin{array}{c}
+ \WEV{E}{S}{\Struct~e_1 ;…;e_i ;\Assum{}{c}{T_1};e_{i+2} ;… ;e_n ~\End} \\
+ \WS{E;e_1 ;…;e_i }{Def()(c:=t:T)}{\Assum{}{c}{T_1}}
+ \end{array}
+ --------------------------
+ \begin{array}{c}
+ \WEV{E}{S~\with~c := t:T}{} \\
+ \Struct~e_1 ;…;e_i ;Def()(c:=t:T);e_{i+2} ;… ;e_n ~\End
+ \end{array}
+
+.. inference:: WEVAL-WITH-DEF-REC
+
+ \begin{array}{c}
+ \WEV{E}{S}{\Struct~e_1 ;…;e_i ; \ModS{X_1 }{S_1 };e_{i+2} ;… ;e_n ~\End} \\
+ \WEV{E;e_1 ;…;e_i }{S_1~\with~p := p_1}{\ovl{S_2}}
+ \end{array}
+ --------------------------
+ \begin{array}{c}
+ \WEV{E}{S~\with~X_1.p := t:T}{} \\
+ \Struct~e_1 ;…;e_i ; \ModS{X}{\ovl{S_2} };e_{i+2} ;… ;e_n ~\End
+ \end{array}
+
+.. inference:: WEVAL-PATH-MOD1
+
+ \begin{array}{c}
+ \WEV{E}{p}{\Struct~e_1 ;…;e_i ; \Mod{X}{S}{S_1};e_{i+2} ;… ;e_n End} \\
+ \WEV{E;e_1 ;…;e_i }{S}{\ovl{S}}
+ \end{array}
+ --------------------------
+ E[] ⊢ p.X \lra \ovl{S}
+
+.. inference:: WEVAL-PATH-MOD2
+
+ \WF{E}{}
+ \Mod{X}{S}{S_1}∈ E
+ \WEV{E}{S}{\ovl{S}}
+ --------------------------
+ \WEV{E}{X}{\ovl{S}}
+
+.. inference:: WEVAL-PATH-ALIAS1
+
+ \begin{array}{c}
+ \WEV{E}{p}{~\Struct~e_1 ;…;e_i ; \ModA{X}{p_1};e_{i+2} ;… ;e_n End} \\
+ \WEV{E;e_1 ;…;e_i }{p_1}{\ovl{S}}
+ \end{array}
+ --------------------------
+ \WEV{E}{p.X}{\ovl{S}}
+
+.. inference:: WEVAL-PATH-ALIAS2
+
+ \WF{E}{}
+ \ModA{X}{p_1 }∈ E
+ \WEV{E}{p_1}{\ovl{S}}
+ --------------------------
+ \WEV{E}{X}{\ovl{S}}
+
+.. inference:: WEVAL-PATH-TYPE1
+
+ \begin{array}{c}
+ \WEV{E}{p}{~\Struct~e_1 ;…;e_i ; \ModType{Y}{S};e_{i+2} ;… ;e_n End} \\
+ \WEV{E;e_1 ;…;e_i }{S}{\ovl{S}}
+ \end{array}
+ --------------------------
+ \WEV{E}{p.Y}{\ovl{S}}
+
+.. inference:: WEVAL-PATH-TYPE2
+
+ \WF{E}{}
+ \ModType{Y}{S}∈ E
+ \WEV{E}{S}{\ovl{S}}
+ --------------------------
+ \WEV{E}{Y}{\ovl{S}}
+
+
+Rules for typing module:
+
+.. inference:: MT-EVAL
+
+ \WEV{E}{p}{\ovl{S}}
+ --------------------------
+ E[] ⊢ p : \ovl{S}
+
+.. inference:: MT-STR
+
+ E[] ⊢ p : S
+ --------------------------
+ E[] ⊢ p : S/p
+
+
+The last rule, called strengthening is used to make all module fields
+manifestly equal to themselves. The notation :math:`S/p` has the following
+meaning:
+
+
++ if :math:`S\lra~\Struct~e_1 ;…;e_n ~\End` then :math:`S/p=~\Struct~e_1 /p;…;e_n /p ~\End`
+ where :math:`e/p` is defined as follows (note that opaque definitions are processed
+ as assumptions):
+
+ + :math:`\Def{}{c}{t}{T}/p = \Def{}{c}{t}{T}`
+ + :math:`\Assum{}{c}{U}/p = \Def{}{c}{p.c}{U}`
+ + :math:`\ModS{X}{S}/p = \ModA{X}{p.X}`
+ + :math:`\ModA{X}{p′}/p = \ModA{X}{p′}`
+ + :math:`\Ind{}{Γ_P}{Γ_C}{Γ_I}/p = \Indp{}{Γ_P}{Γ_C}{Γ_I}{p}`
+ + :math:`\Indpstr{}{Γ_P}{Γ_C}{Γ_I}{p'}{p} = \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'}`
+
++ if :math:`S \lra \Functor(X:S′)~S″` then :math:`S/p=S`
+
+
+The notation :math:`\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}`
+denotes an inductive definition that is definitionally equal to the
+inductive definition in the module denoted by the path :math:`p`. All rules
+which have :math:`\Ind{}{Γ_P}{Γ_C}{Γ_I}` as premises are also valid for
+:math:`\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}`. We give the formation rule for
+:math:`\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}`
+below as well as the equality rules on inductive types and
+constructors.
+
+The module subtyping rules:
+
+.. inference:: MSUB-STR
+
+ \begin{array}{c}
+ \WS{E;e_1 ;…;e_n }{e_{σ(i)}}{e'_i ~\for~ i=1..m} \\
+ σ : \{1… m\} → \{1… n\} ~\injective
+ \end{array}
+ --------------------------
+ \WS{E}{\Struct~e_1 ;…;e_n ~\End}{~\Struct~e'_1 ;…;e'_m ~\End}
+
+.. inference:: MSUB-FUN
+
+ \WS{E}{\ovl{S_1'}}{\ovl{S_1}}
+ \WS{E; \ModS{X}{S_1'}}{\ovl{S_2}}{\ovl{S_2'}}
+ --------------------------
+ E[] ⊢ \Functor(X:S_1 ) S_2 <: \Functor(X:S_1') S_2'
+
+
+Structure element subtyping rules:
+
+.. inference:: ASSUM-ASSUM
+
+ E[] ⊢ T_1 ≤_{βδιζη} T_2
+ --------------------------
+ \WS{E}{\Assum{}{c}{T_1 }}{\Assum{}{c}{T_2 }}
+
+.. inference:: DEF-ASSUM
+
+ E[] ⊢ T_1 ≤_{βδιζη} T_2
+ --------------------------
+ \WS{E}{\Def{}{c}{t}{T_1 }}{\Assum{}{c}{T_2 }}
+
+.. inference:: ASSUM-DEF
+
+ E[] ⊢ T_1 ≤_{βδιζη} T_2
+ E[] ⊢ c =_{βδιζη} t_2
+ --------------------------
+ \WS{E}{\Assum{}{c}{T_1 }}{\Def{}{c}{t_2 }{T_2 }}
+
+.. inference:: DEF-DEF
+
+ E[] ⊢ T_1 ≤_{βδιζη} T_2
+ E[] ⊢ t_1 =_{βδιζη} t_2
+ --------------------------
+ \WS{E}{\Def{}{c}{t_1 }{T_1 }}{\Def{}{c}{t_2 }{T_2 }}
+
+.. inference:: IND-IND
+
+ E[] ⊢ Γ_P =_{βδιζη} Γ_P'
+ E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C'
+ E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I'
+ --------------------------
+ \WS{E}{\ind{Γ_P}{Γ_C}{Γ_I}}{\ind{Γ_P'}{Γ_C'}{Γ_I'}}
+
+.. inference:: INDP-IND
+
+ E[] ⊢ Γ_P =_{βδιζη} Γ_P'
+ E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C'
+ E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I'
+ --------------------------
+ \WS{E}{\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}}{\ind{Γ_P'}{Γ_C'}{Γ_I'}}
+
+.. inference:: INDP-INDP
+
+ \begin{array}{c}
+ E[] ⊢ Γ_P =_{βδιζη} Γ_P'
+ E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C' \\
+ E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I'
+ E[] ⊢ p =_{βδιζη} p'
+ \end{array}
+ --------------------------
+ \WS{E}{\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}}{\Indp{}{Γ_P'}{Γ_C'}{Γ_I'}{p'}}
+
+.. inference:: MOD-MOD
+
+ \WS{E}{S_1}{S_2}
+ --------------------------
+ \WS{E}{\ModS{X}{S_1 }}{\ModS{X}{S_2 }}
+
+.. inference:: ALIAS-MOD
+
+ E[] ⊢ p : S_1
+ \WS{E}{S_1}{S_2}
+ --------------------------
+ \WS{E}{\ModA{X}{p}}{\ModS{X}{S_2 }}
+
+.. inference:: MOD-ALIAS
+
+ E[] ⊢ p : S_2
+ \WS{E}{S_1}{S_2}
+ E[] ⊢ X =_{βδιζη} p
+ --------------------------
+ \WS{E}{\ModS{X}{S_1 }}{\ModA{X}{p}}
+
+.. inference:: ALIAS-ALIAS
+
+ E[] ⊢ p_1 =_{βδιζη} p_2
+ --------------------------
+ \WS{E}{\ModA{X}{p_1 }}{\ModA{X}{p_2 }}
+
+.. inference:: MODTYPE-MODTYPE
+
+ \WS{E}{S_1}{S_2}
+ \WS{E}{S_2}{S_1}
+ --------------------------
+ \WS{E}{\ModType{Y}{S_1 }}{\ModType{Y}{S_2 }}
+
+
+New environment formation rules
+
+
+.. inference:: WF-MOD1
+
+ \WF{E}{}
+ \WFT{E}{S}
+ --------------------------
+ WF(E; \ModS{X}{S})[]
+
+.. inference:: WF-MOD2
+
+ \WS{E}{S_2}{S_1}
+ \WF{E}{}
+ \WFT{E}{S_1}
+ \WFT{E}{S_2}
+ --------------------------
+ \WF{E; \Mod{X}{S_1}{S_2}}{}
+
+.. inference:: WF-ALIAS
+
+ \WF{E}{}
+ E[] ⊢ p : S
+ --------------------------
+ \WF{E, \ModA{X}{p}}{}
+
+.. inference:: WF-MODTYPE
+
+ \WF{E}{}
+ \WFT{E}{S}
+ --------------------------
+ \WF{E, \ModType{Y}{S}}{}
+
+.. inference:: WF-IND
+
+ \begin{array}{c}
+ \WF{E;\ind{Γ_P}{Γ_C}{Γ_I}}{} \\
+ E[] ⊢ p:~\Struct~e_1 ;…;e_n ;\ind{Γ_P'}{Γ_C'}{Γ_I'};… ~\End : \\
+ E[] ⊢ \ind{Γ_P'}{Γ_C'}{Γ_I'} <: \ind{Γ_P}{Γ_C}{Γ_I}
+ \end{array}
+ --------------------------
+ \WF{E; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p} }{}
+
+
+Component access rules
+
+
+.. inference:: ACC-TYPE1
+
+ E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Assum{}{c}{T};… ~\End
+ --------------------------
+ E[Γ] ⊢ p.c : T
+
+.. inference:: ACC-TYPE2
+
+ E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Def{}{c}{t}{T};… ~\End
+ --------------------------
+ E[Γ] ⊢ p.c : T
+
+Notice that the following rule extends the delta rule defined in section :ref:`Conversion-rules`
+
+.. inference:: ACC-DELTA
+
+ E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Def{}{c}{t}{U};… ~\End
+ --------------------------
+ E[Γ] ⊢ p.c \triangleright_δ t
+
+In the rules below we assume
+:math:`Γ_P` is :math:`[p_1 :P_1 ;…;p_r :P_r ]`,
+:math:`Γ_I` is :math:`[I_1 :A_1 ;…;I_k :A_k ]`,
+and :math:`Γ_C` is :math:`[c_1 :C_1 ;…;c_n :C_n ]`.
+
+.. inference:: ACC-IND1
+
+ E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\ind{Γ_P}{Γ_C}{Γ_I};… ~\End
+ --------------------------
+ E[Γ] ⊢ p.I_j : (p_1 :P_1 )…(p_r :P_r )A_j
+
+.. inference:: ACC-IND2
+
+ E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\ind{Γ_P}{Γ_C}{Γ_I};… ~\End
+ --------------------------
+ E[Γ] ⊢ p.c_m : (p_1 :P_1 )…(p_r :P_r )C_m I_j (I_j~p_1 …p_r )_{j=1… k}
+
+.. inference:: ACC-INDP1
+
+ E[] ⊢ p :~\Struct~e_1 ;…;e_i ; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'} ;… ~\End
+ --------------------------
+ E[] ⊢ p.I_i \triangleright_δ p'.I_i
+
+.. inference:: ACC-INDP2
+
+ E[] ⊢ p :~\Struct~e_1 ;…;e_i ; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'} ;… ~\End
+ --------------------------
+ E[] ⊢ p.c_i \triangleright_δ p'.c_i
+
+.. extracted from Gallina extensions chapter
+
+Libraries and qualified names
+---------------------------------
+
+.. _names-of-libraries:
+
+Names of libraries
+~~~~~~~~~~~~~~~~~~
+
+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
+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
+(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
+started, unless option ``-top`` or ``-notop`` is set (see :ref:`command-line-options`).
+
+.. _qualified-names:
+
+Qualified identifiers
+---------------------
+
+.. insertprodn qualid field_ident
+
+.. prodn::
+ qualid ::= @ident {* @field_ident }
+ field_ident ::= .@ident
+
+Library files are modules which possibly contain submodules which
+eventually contain constructions (axioms, parameters, definitions,
+lemmas, theorems, remarks or facts). The *absolute name*, or *full
+name*, of a construction in some library file is a qualified
+identifier starting with the logical name of the library file,
+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|.
+
+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
+name of ``Coq.Init.Logic.eq`` is ``eq``). Any partial suffix of the absolute
+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
+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).
+
+Notice that the notion of absolute, partially qualified and short
+names also applies to library filenames.
+
+**Visibility**
+
+|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
+their fully qualified name (see :ref:`gallina-definitions`).
+
+It may happen that a visible name is hidden by the short name or a
+qualified name of another construction. In this case, the name that
+has been hidden must be referred to using one more level of
+qualification. To ensure that a construction always remains
+accessible, absolute names can never be hidden.
+
+.. example::
+
+ .. coqtop:: all
+
+ Check 0.
+
+ Definition nat := bool.
+
+ Check 0.
+
+ Check Datatypes.nat.
+
+ Locate nat.
+
+.. seealso:: Commands :cmd:`Locate`.
+
+.. _libraries-and-filesystem:
+
+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.
+
+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
+is needed. In this translation, names in the file system are called
+*physical* paths while |Coq| names are contrastingly called *logical*
+names.
+
+A logical prefix Lib can be associated with a physical path using
+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,
+subdirectories named ``CVS`` or ``_darcs`` are skipped too.
+
+Thanks to this mechanism, ``.vo`` files are made available through the
+logical name of the folder they are in, extended with their own
+basename. For example, the name associated to the file
+``path/fOO/Bar/File.vo`` is ``Lib.fOO.Bar.File``. The same caveat applies for
+invalid identifiers. When compiling a source file, the ``.vo`` file stores
+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
+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/``
+environment variables (see `XDG base directory specification
+<http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_)
+with the same physical-to-logical translation and with an empty logical prefix.
+
+The command line option ``-R`` is a variant of ``-Q`` which has the strictly
+same behavior regarding loadpaths, but which also makes the
+corresponding ``.vo`` files available through their short names in a way
+similar to the :cmd:`Import` command. For instance, ``-R path Lib``
+associates to the file ``/path/fOO/Bar/File.vo`` the logical name
+``Lib.fOO.Bar.File``, but allows this file to be accessed through the
+short names ``fOO.Bar.File,Bar.File`` and ``File``. If several files with
+identical base name are present in different subdirectories of a
+recursive loadpath, which of these files is found first may be system-
+dependent and explicit qualification is recommended. The ``From`` argument
+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
+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
+line options.
diff --git a/doc/sphinx/language/core/primitive.rst b/doc/sphinx/language/core/primitive.rst
new file mode 100644
index 0000000000..dc8f131209
--- /dev/null
+++ b/doc/sphinx/language/core/primitive.rst
@@ -0,0 +1,107 @@
+Primitive objects
+=================
+
+.. _primitive-integers:
+
+Primitive Integers
+------------------
+
+The language of terms features 63-bit machine integers as values. The type of
+such a value is *axiomatized*; it is declared through the following sentence
+(excerpt from the :g:`Int63` module):
+
+.. coqdoc::
+
+ Primitive int := #int63_type.
+
+This type is equipped with a few operators, that must be similarly declared.
+For instance, equality of two primitive integers can be decided using the :g:`Int63.eqb` function,
+declared and specified as follows:
+
+.. coqdoc::
+
+ Primitive eqb := #int63_eq.
+ Notation "m '==' n" := (eqb m n) (at level 70, no associativity) : int63_scope.
+
+ Axiom eqb_correct : forall i j, (i == j)%int63 = true -> i = j.
+
+The complete set of such operators can be obtained looking at the :g:`Int63` module.
+
+These primitive declarations are regular axioms. As such, they must be trusted and are listed by the
+:g:`Print Assumptions` command, as in the following example.
+
+.. coqtop:: in reset
+
+ From Coq Require Import Int63.
+ Lemma one_minus_one_is_zero : (1 - 1 = 0)%int63.
+ Proof. apply eqb_correct; vm_compute; reflexivity. Qed.
+
+.. coqtop:: all
+
+ Print Assumptions one_minus_one_is_zero.
+
+The reduction machines (:tacn:`vm_compute`, :tacn:`native_compute`) implement
+dedicated, efficient, rules to reduce the 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
+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.
+
+Literal values (at type :g:`Int63.int`) are extracted to literal OCaml values
+wrapped into the :g:`Uint63.of_int` (resp. :g:`Uint63.of_int64`) constructor on
+64-bit (resp. 32-bit) platforms. Currently, this cannot be customized (see the
+function :g:`Uint63.compile` from the kernel).
+
+.. _primitive-floats:
+
+Primitive Floats
+----------------
+
+The language of terms features Binary64 floating-point numbers as values.
+The type of such a value is *axiomatized*; it is declared through the
+following sentence (excerpt from the :g:`PrimFloat` module):
+
+.. coqdoc::
+
+ Primitive float := #float64_type.
+
+This type is equipped with a few operators, that must be similarly declared.
+For instance, the product of two primitive floats can be computed using the
+:g:`PrimFloat.mul` function, declared and specified as follows:
+
+.. coqdoc::
+
+ Primitive mul := #float64_mul.
+ Notation "x * y" := (mul x y) : float_scope.
+
+ Axiom mul_spec : forall x y, Prim2SF (x * y)%float = SF64mul (Prim2SF x) (Prim2SF y).
+
+where :g:`Prim2SF` is defined in the :g:`FloatOps` module.
+
+The set of such operators is described in section :ref:`floats_library`.
+
+These primitive declarations are regular axioms. As such, they must be trusted, and are listed by the
+:g:`Print Assumptions` command.
+
+The reduction machines (:tacn:`vm_compute`, :tacn:`native_compute`) implement
+dedicated, efficient rules to reduce the applications of these primitive
+operations, using the floating-point processor operators that are assumed
+to comply with the IEEE 754 standard for floating-point arithmetic.
+
+The extraction of these primitives can be customized similarly to the extraction
+of regular axioms (see :ref:`extraction`). Nonetheless, the :g:`ExtrOCamlFloats`
+module can be used when extracting to OCaml: it maps the Coq primitives to types
+and functions of a :g:`Float64` module. Said 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.
+
+Literal values (of type :g:`Float64.t`) are extracted to literal OCaml
+values (of type :g:`float`) written in hexadecimal notation and
+wrapped into the :g:`Float64.of_float` constructor, e.g.:
+:g:`Float64.of_float (0x1p+0)`.
diff --git a/doc/sphinx/language/core/sorts.rst b/doc/sphinx/language/core/sorts.rst
new file mode 100644
index 0000000000..8307a02d6d
--- /dev/null
+++ b/doc/sphinx/language/core/sorts.rst
@@ -0,0 +1,99 @@
+.. index::
+ single: Set (sort)
+ single: SProp
+ single: Prop
+ single: Type
+
+.. _sorts:
+
+Sorts
+~~~~~~~~~~~
+
+.. insertprodn sort universe_expr
+
+.. prodn::
+ sort ::= Set
+ | Prop
+ | SProp
+ | Type
+ | Type @%{ _ %}
+ | Type @%{ @universe %}
+ universe ::= max ( {+, @universe_expr } )
+ | @universe_expr
+ universe_expr ::= @universe_name {? + @num }
+
+The types of types are called :gdef:`sort`\s.
+
+All sorts have a type and there is an infinite well-founded typing
+hierarchy of sorts whose base sorts are :math:`\SProp`, :math:`\Prop`
+and :math:`\Set`.
+
+The sort :math:`\Prop` intends to be the type of logical propositions. If :math:`M` is a
+logical proposition then it denotes the class of terms representing
+proofs of :math:`M`. An object :math:`m` belonging to :math:`M` witnesses the fact that :math:`M` is
+provable. An object of type :math:`\Prop` is called a proposition.
+We denote propositions by :n:`@form`.
+This constitutes a semantic subclass of the syntactic class :n:`@term`.
+
+The sort :math:`\SProp` is like :math:`\Prop` but the propositions in
+:math:`\SProp` are known to have irrelevant proofs (all proofs are
+equal). Objects of type :math:`\SProp` are called strict propositions.
+See :ref:`sprop` for information about using
+:math:`\SProp`, and :cite:`Gilbert:POPL2019` for meta theoretical
+considerations.
+
+The sort :math:`\Set` intends to be the type of small sets. This includes data
+types such as booleans and naturals, but also products, subsets, and
+function types over these data types.
+We denote specifications (program types) by :n:`@specif`.
+This constitutes a semantic subclass of the syntactic class :n:`@term`.
+
+:math:`\SProp`, :math:`\Prop` and :math:`\Set` themselves can be manipulated as ordinary terms.
+Consequently they also have a type. Because assuming simply that :math:`\Set`
+has type :math:`\Set` leads to an inconsistent theory :cite:`Coq86`, the language of
+|Cic| has infinitely many sorts. There are, in addition to the base sorts,
+a hierarchy of universes :math:`\Type(i)` for any integer :math:`i ≥ 1`.
+
+Like :math:`\Set`, all of the sorts :math:`\Type(i)` contain small sets such as
+booleans, natural numbers, as well as products, subsets and function
+types over small sets. But, unlike :math:`\Set`, they also contain large sets,
+namely the sorts :math:`\Set` and :math:`\Type(j)` for :math:`j<i`, and all products, subsets
+and function types over these sorts.
+
+Formally, we call :math:`\Sort` the set of sorts which is defined by:
+
+.. math::
+
+ \Sort \equiv \{\SProp,\Prop,\Set,\Type(i)\;|\; i~∈ ℕ\}
+
+Their properties, such as: :math:`\Prop:\Type(1)`, :math:`\Set:\Type(1)`, and
+:math:`\Type(i):\Type(i+1)`, are defined in Section :ref:`subtyping-rules`.
+
+The user does not have to mention explicitly the index :math:`i` when
+referring to the universe :math:`\Type(i)`. One only writes :math:`\Type`. The system
+itself generates for each instance of :math:`\Type` a new index for the
+universe and checks that the constraints between these indexes can be
+solved. From the user point of view we consequently have :math:`\Type:\Type`. We
+shall make precise in the typing rules the constraints between the
+indices.
+
+
+.. _Implementation-issues:
+
+**Implementation issues** In practice, the Type hierarchy is
+implemented using *algebraic
+universes*. An algebraic universe :math:`u` is either a variable (a qualified
+identifier with a number) or a successor of an algebraic universe (an
+expression :math:`u+1`), or an upper bound of algebraic universes (an
+expression :math:`\max(u_1 ,...,u_n )`), or the base universe (the expression
+:math:`0`) which corresponds, in the arity of template polymorphic inductive
+types (see Section
+:ref:`well-formed-inductive-definitions`),
+to the predicative sort :math:`\Set`. A graph of
+constraints between the universe variables is maintained globally. To
+ensure the existence of a mapping of the universes to the positive
+integers, the graph of constraints must remain acyclic. Typing
+expressions that violate the acyclicity of the graph of constraints
+results in a Universe inconsistency error.
+
+.. seealso:: :ref:`printing-universes`.
diff --git a/doc/sphinx/language/core/variants.rst b/doc/sphinx/language/core/variants.rst
new file mode 100644
index 0000000000..6d4676b3c4
--- /dev/null
+++ b/doc/sphinx/language/core/variants.rst
@@ -0,0 +1,202 @@
+Variants and the `match` construct
+==================================
+
+Variants
+--------
+
+.. cmd:: Variant @variant_definition {* with @variant_definition }
+
+ .. insertprodn variant_definition variant_definition
+
+ .. prodn::
+ variant_definition ::= @ident_decl {* @binder } {? %| {* @binder } } {? : @type } := {? %| } {+| @constructor } {? @decl_notations }
+
+ The :cmd:`Variant` command is similar to the :cmd:`Inductive` command, except
+ that it disallows recursive definition of types (for instance, lists cannot
+ be defined using :cmd:`Variant`). No induction scheme is generated for
+ this variant, unless the :flag:`Nonrecursive Elimination Schemes` flag is on.
+
+ 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.
+
+ .. exn:: The @num th argument of @ident must be @ident in @type.
+ :undocumented:
+
+Private (matching) inductive types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. attr:: private(matching)
+
+ This attribute can be used to forbid the use of the :g:`match`
+ construct on objects of this inductive type outside of the module
+ where it is defined. There is also a legacy syntax using the
+ ``Private`` prefix (cf. :n:`@legacy_attr`).
+
+ The main use case of private (matching) inductive types is to emulate
+ quotient types / higher-order inductive types in projects such as
+ the `HoTT library <https://github.com/HoTT/HoTT>`_.
+
+.. example::
+
+ .. coqtop:: all
+
+ Module Foo.
+ #[ private(matching) ] Inductive my_nat := my_O : my_nat | my_S : my_nat -> my_nat.
+ Check (fun x : my_nat => match x with my_O => true | my_S _ => false end).
+ End Foo.
+ Import Foo.
+ Fail Check (fun x : my_nat => match x with my_O => true | my_S _ => false end).
+
+.. index:: match ... with ...
+
+.. _match:
+
+Definition by cases: match
+--------------------------
+
+.. insertprodn term_match pattern0
+
+.. prodn::
+ term_match ::= match {+, @case_item } {? return @term100 } with {? %| } {*| @eqn } end
+ case_item ::= @term100 {? as @name } {? in @pattern }
+ eqn ::= {+| {+, @pattern } } => @term
+ pattern ::= @pattern10 : @term
+ | @pattern10
+ pattern10 ::= @pattern1 as @name
+ | @pattern1 {* @pattern1 }
+ | @ @qualid {* @pattern1 }
+ pattern1 ::= @pattern0 % @scope_key
+ | @pattern0
+ pattern0 ::= @qualid
+ | %{%| {* @qualid := @pattern } %|%}
+ | _
+ | ( {+| @pattern } )
+ | @numeral
+ | @string
+
+Objects of inductive types can be destructured by a case-analysis
+construction called *pattern matching* expression. A pattern matching
+expression is used to analyze the structure of an inductive object and
+to apply specific treatments accordingly.
+
+This paragraph describes the basic form of pattern matching. See
+Section :ref:`Mult-match` and Chapter :ref:`extendedpatternmatching` for the description
+of the general form. The basic form of pattern matching is characterized
+by a single :n:`@case_item` expression, an :n:`@eqn` restricted to a
+single :n:`@pattern` and :n:`@pattern` restricted to the form
+:n:`@qualid {* @ident}`.
+
+The expression
+:n:`match @term {? return @term100 } with {+| @pattern__i => @term__i } end` denotes a
+*pattern matching* over the term :n:`@term` (expected to be
+of an inductive type :math:`I`). The :n:`@term__i`
+are the *branches* of the pattern matching
+expression. Each :n:`@pattern__i` has the form :n:`@qualid @ident`
+where :n:`@qualid` must denote a constructor. There should be
+exactly one branch for every constructor of :math:`I`.
+
+The :n:`return @term100` clause gives the type returned by the whole match
+expression. There are several cases. In the *non dependent* case, all
+branches have the same type, and the :n:`return @term100` specifies that type.
+In this case, :n:`return @term100` can usually be omitted as it can be
+inferred from the type of the branches [1]_.
+
+In the *dependent* case, there are three subcases. In the first subcase,
+the type in each branch may depend on the exact value being matched in
+the branch. In this case, the whole pattern matching itself depends on
+the term being matched. This dependency of the term being matched in the
+return type is expressed with an :n:`@ident` clause where :n:`@ident`
+is dependent in the return type. For instance, in the following example:
+
+.. coqtop:: in
+
+ Inductive bool : Type := true : bool | false : bool.
+ Inductive eq (A:Type) (x:A) : A -> Prop := eq_refl : eq A x x.
+ Inductive or (A:Prop) (B:Prop) : Prop :=
+ | or_introl : A -> or A B
+ | or_intror : B -> or A B.
+
+ Definition bool_case (b:bool) : or (eq bool b true) (eq bool b false) :=
+ match b as x return or (eq bool x true) (eq bool x false) with
+ | true => or_introl (eq bool true true) (eq bool true false) (eq_refl bool true)
+ | false => or_intror (eq bool false true) (eq bool false false) (eq_refl bool false)
+ end.
+
+the branches have respective types ":g:`or (eq bool true true) (eq bool true false)`"
+and ":g:`or (eq bool false true) (eq bool false false)`" while the whole
+pattern matching expression has type ":g:`or (eq bool b true) (eq bool b false)`",
+the identifier :g:`b` being used to represent the dependency.
+
+.. note::
+
+ When the term being matched is a variable, the ``as`` clause can be
+ omitted and the term being matched can serve itself as binding name in
+ the return type. For instance, the following alternative definition is
+ accepted and has the same meaning as the previous one.
+
+ .. coqtop:: none
+
+ Reset bool_case.
+
+ .. coqtop:: in
+
+ Definition bool_case (b:bool) : or (eq bool b true) (eq bool b false) :=
+ match b return or (eq bool b true) (eq bool b false) with
+ | true => or_introl (eq bool true true) (eq bool true false) (eq_refl bool true)
+ | false => or_intror (eq bool false true) (eq bool false false) (eq_refl bool false)
+ end.
+
+The second subcase is only relevant for annotated inductive types such
+as the equality predicate (see Section :ref:`coq-equality`),
+the order predicate on natural numbers or the type of lists of a given
+length (see Section :ref:`matching-dependent`). In this configuration, the
+type of each branch can depend on the type dependencies specific to the
+branch and the whole pattern matching expression has a type determined
+by the specific dependencies in the type of the term being matched. This
+dependency of the return type in the annotations of the inductive type
+is expressed with a clause in the form
+:n:`in @qualid {+ _ } {+ @pattern }`, where
+
+- :n:`@qualid` is the inductive type of the term being matched;
+
+- the holes :n:`_` match the parameters of the inductive type: the
+ return type is not dependent on them.
+
+- each :n:`@pattern` matches the annotations of the
+ inductive type: the return type is dependent on them
+
+- in the basic case which we describe below, each :n:`@pattern`
+ is a name :n:`@ident`; see :ref:`match-in-patterns` for the
+ general case
+
+For instance, in the following example:
+
+.. coqtop:: in
+
+ Definition eq_sym (A:Type) (x y:A) (H:eq A x y) : eq A y x :=
+ match H in eq _ _ z return eq A z x with
+ | eq_refl _ _ => eq_refl A x
+ end.
+
+the type of the branch is :g:`eq A x x` because the third argument of
+:g:`eq` is :g:`x` in the type of the pattern :g:`eq_refl`. On the contrary, the
+type of the whole pattern matching expression has type :g:`eq A y x` because the
+third argument of eq is y in the type of H. This dependency of the case analysis
+in the third argument of :g:`eq` is expressed by the identifier :g:`z` in the
+return type.
+
+Finally, the third subcase is a combination of the first and second
+subcase. In particular, it only applies to pattern matching on terms in
+a type with annotations. For this third subcase, both the clauses ``as`` and
+``in`` are available.
+
+There are specific notations for case analysis on types with one or two
+constructors: ``if … then … else …`` and ``let (…,…) := … in …`` (see
+Sections :ref:`if-then-else` and :ref:`irrefutable-patterns`).
+
+.. [1]
+ Except if the inductive type is empty in which case there is no
+ equation that can be used to infer the return type.
diff --git a/doc/sphinx/language/extensions/arguments-command.rst b/doc/sphinx/language/extensions/arguments-command.rst
index 34a48b368b..85481043b2 100644
--- a/doc/sphinx/language/extensions/arguments-command.rst
+++ b/doc/sphinx/language/extensions/arguments-command.rst
@@ -109,7 +109,7 @@ Setting properties of a function's arguments
clears argument scopes of :n:`@smart_qualid`
`extra scopes`
defines extra argument scopes, to be used in case of coercion to ``Funclass``
- (see the :ref:`implicitcoercions` chapter) or with a computed type.
+ (see :ref:`coercions`) or with a computed type.
`simpl nomatch`
prevents performing a simplification step for :n:`@smart_qualid`
that would expose a match construct in the head position. See :ref:`Args_effect_on_unfolding`.
diff --git a/doc/sphinx/addendum/canonical-structures.rst b/doc/sphinx/language/extensions/canonical.rst
index b593b0cef1..f55f3c5495 100644
--- a/doc/sphinx/addendum/canonical-structures.rst
+++ b/doc/sphinx/language/extensions/canonical.rst
@@ -14,6 +14,128 @@ of another, complementary, use of canonical structures: advanced proof search.
This latter papers also presents many techniques one can employ to tune the
inference of canonical structures.
+ .. extracted from implicit arguments section
+
+.. _canonical-structure-declaration:
+
+Declaration of canonical structures
+-----------------------------------
+
+A canonical structure is an instance of a record/structure type that
+can be used to solve unification problems involving a projection
+applied to an unknown structure instance (an implicit argument) and a
+value. The complete documentation of canonical structures can be found
+in :ref:`canonicalstructures`; here only a simple example is given.
+
+.. cmd:: Canonical {? Structure } @smart_qualid
+ Canonical {? Structure } @ident_decl @def_body
+ :name: Canonical Structure; _
+
+ The first form of this command declares an existing :n:`@smart_qualid` as a
+ canonical instance of a structure (a record).
+
+ The second form defines a new constant as if the :cmd:`Definition` command
+ had been used, then declares it as a canonical instance as if the first
+ form had been used on the defined object.
+
+ This command supports the :attr:`local` attribute. When used, the
+ structure is canonical only within the :cmd:`Section` containing it.
+
+ Assume that :token:`qualid` denotes an object ``(Build_struct`` |c_1| … |c_n| ``)`` in the
+ structure :g:`struct` of which the fields are |x_1|, …, |x_n|.
+ Then, each time an equation of the form ``(``\ |x_i| ``_)`` |eq_beta_delta_iota_zeta| |c_i| has to be
+ solved during the type checking process, :token:`qualid` is used as a solution.
+ Otherwise said, :token:`qualid` is canonically used to extend the field |c_i|
+ into a complete structure built on |c_i|.
+
+ Canonical structures are particularly useful when mixed with coercions
+ and strict implicit arguments.
+
+ .. example::
+
+ Here is an example.
+
+ .. coqtop:: all reset
+
+ Require Import Relations.
+
+ Require Import EqNat.
+
+ Set Implicit Arguments.
+
+ Unset Strict Implicit.
+
+ Structure Setoid : Type := {Carrier :> Set; Equal : relation Carrier;
+ Prf_equiv : equivalence Carrier Equal}.
+
+ Definition is_law (A B:Setoid) (f:A -> B) := forall x y:A, Equal x y -> Equal (f x) (f y).
+
+ Axiom eq_nat_equiv : equivalence nat eq_nat.
+
+ Definition nat_setoid : Setoid := Build_Setoid eq_nat_equiv.
+
+ Canonical nat_setoid.
+
+ Thanks to :g:`nat_setoid` declared as canonical, the implicit arguments :g:`A`
+ and :g:`B` can be synthesized in the next statement.
+
+ .. coqtop:: all abort
+
+ Lemma is_law_S : is_law S.
+
+ .. note::
+ If a same field occurs in several canonical structures, then
+ only the structure declared first as canonical is considered.
+
+ .. attr:: canonical(false)
+
+ To prevent a field from being involved in the inference of
+ canonical instances, its declaration can be annotated with the
+ :attr:`canonical(false)` attribute (cf. the syntax of
+ :n:`@record_field`).
+
+ .. example::
+
+ For instance, when declaring the :g:`Setoid` structure above, the
+ :g:`Prf_equiv` field declaration could be written as follows.
+
+ .. coqdoc::
+
+ #[canonical(false)] Prf_equiv : equivalence Carrier Equal
+
+ See :ref:`canonicalstructures` for a more realistic example.
+
+.. attr:: canonical
+
+ This attribute can decorate a :cmd:`Definition` or :cmd:`Let` command.
+ It is equivalent to having a :cmd:`Canonical Structure` declaration just
+ after the command.
+
+.. cmd:: Print Canonical Projections {* @smart_qualid }
+
+ This displays the list of global names that are components of some
+ canonical structure. For each of them, the canonical structure of
+ which it is a projection is indicated. If constants are given as
+ its arguments, only the unification rules that involve or are
+ synthesized from simultaneously all given constants will be shown.
+
+ .. example::
+
+ For instance, the above example gives the following output:
+
+ .. coqtop:: all
+
+ Print Canonical Projections.
+
+ .. coqtop:: all
+
+ Print Canonical Projections nat.
+
+ .. note::
+
+ The last line in the first example would not show up if the
+ corresponding projection (namely :g:`Prf_equiv`) were annotated as not
+ canonical, as described above.
Notation overloading
-------------------------
@@ -22,8 +144,8 @@ We build an infix notation == for a comparison predicate. Such
notation will be overloaded, and its meaning will depend on the types
of the terms that are compared.
-.. coqtop:: all
-
+.. coqtop:: all reset
+
Module EQ.
Record class (T : Type) := Class { cmp : T -> T -> Prop }.
Structure type := Pack { obj : Type; class_of : class obj }.
@@ -54,7 +176,7 @@ The following line tests that, when we assume a type ``e`` that is in
theEQ class, we can relate two of its objects with ``==``.
.. coqtop:: all
-
+
Import EQ.theory.
Check forall (e : EQ.type) (a b : EQ.obj e), a == b.
@@ -67,7 +189,7 @@ Still, no concrete type is in the ``EQ`` class.
We amend that by equipping ``nat`` with a comparison relation.
.. coqtop:: all
-
+
Definition nat_eq (x y : nat) := Nat.compare x y = Eq.
Definition nat_EQcl : EQ.class nat := EQ.Class nat_eq.
Canonical Structure nat_EQty : EQ.type := EQ.Pack nat nat_EQcl.
@@ -109,7 +231,7 @@ how to do that.
Definition pair_eq (e1 e2 : EQ.type) (x y : EQ.obj e1 * EQ.obj e2) :=
fst x == fst y /\ snd x == snd y.
-
+
Definition pair_EQcl e1 e2 := EQ.Class (pair_eq e1 e2).
Canonical Structure pair_EQty (e1 e2 : EQ.type) : EQ.type :=
@@ -147,7 +269,7 @@ order relation, to which we associate the infix ``<=`` notation.
Arguments op {_} x y : simpl never.
Arguments Class {T} cmp.
-
+
Module theory.
Notation "x <= y" := (op x y) (at level 70).
@@ -203,7 +325,7 @@ We need to define a new class that inherits from both ``EQ`` and ``LE``.
Record mixin (e : EQ.type) (le : EQ.obj e -> EQ.obj e -> Prop) :=
Mixin { compat : forall x y : EQ.obj e, le x y /\ le y x <-> x == y }.
-
+
Record class T := Class {
EQ_class : EQ.class T;
LE_class : LE.class T;
@@ -249,7 +371,7 @@ type.
Definition to_LE (e : type) : LE.type :=
LE.Pack (obj e) (LE_class _ (class_of e)).
-
+
Canonical Structure to_LE.
We can now formulate out first theorem on the objects of the ``LEQ``
@@ -259,7 +381,7 @@ structure.
Lemma lele_eq (e : type) (x y : obj e) : x <= y -> y <= x -> x == y.
- now intros; apply (compat _ _ (extra _ (class_of e)) x y); split.
+ now intros; apply (compat _ _ (extra _ (class_of e)) x y); split.
Qed.
@@ -280,14 +402,14 @@ setting to any concrete instate of the algebraic structure.
Example test_algebraic (n m : nat) : n <= m -> m <= n -> n == m.
- Fail apply (lele_eq n m).
+ Fail apply (lele_eq n m).
Abort.
Example test_algebraic2 (l1 l2 : LEQ.type) (n m : LEQ.obj l1 * LEQ.obj l2) :
n <= m -> m <= n -> n == m.
- Fail apply (lele_eq n m).
+ Fail apply (lele_eq n m).
Abort.
@@ -332,14 +454,14 @@ subsection we show how to make them more compact.
Example test_algebraic (n m : nat) : n <= m -> m <= n -> n == m.
- now apply (lele_eq n m).
+ now apply (lele_eq n m).
Qed.
Example test_algebraic2 (n m : nat * nat) : n <= m -> m <= n -> n == m.
now apply (lele_eq n m). Qed.
-
+
End Add_instance_attempt.
Note that no direct proof of ``n <= m -> m <= n -> n == m`` is provided by
@@ -424,7 +546,7 @@ The declaration of canonical instances can now be way more compact:
.. coqtop:: all
Canonical Structure nat_LEQty := Eval hnf in Pack nat nat_LEQmx.
-
+
Canonical Structure pair_LEQty (l1 l2 : LEQ.type) :=
Eval hnf in Pack (LEQ.obj l1 * LEQ.obj l2) (pair_LEQmx l1 l2).
@@ -434,4 +556,3 @@ the message).
.. coqtop:: all
Fail Canonical Structure err := Eval hnf in Pack bool nat_LEQmx.
-
diff --git a/doc/sphinx/language/extensions/evars.rst b/doc/sphinx/language/extensions/evars.rst
new file mode 100644
index 0000000000..40e0898871
--- /dev/null
+++ b/doc/sphinx/language/extensions/evars.rst
@@ -0,0 +1,112 @@
+.. extracted from Gallina extensions chapter
+
+.. _existential-variables:
+
+Existential variables
+---------------------
+
+.. insertprodn term_evar term_evar
+
+.. prodn::
+ term_evar ::= _
+ | ?[ @ident ]
+ | ?[ ?@ident ]
+ | ?@ident {? @%{ {+; @ident := @term } %} }
+
+|Coq| terms can include existential variables which represents unknown
+subterms to eventually be replaced by actual subterms.
+
+Existential variables are generated in place of unsolvable implicit
+arguments or “_” placeholders when using commands such as ``Check`` (see
+Section :ref:`requests-to-the-environment`) or when using tactics such as
+:tacn:`refine`, as well as in place of unsolvable instances when using
+tactics such that :tacn:`eapply`. An existential
+variable is defined in a context, which is the context of variables of
+the placeholder which generated the existential variable, and a type,
+which is the expected type of the placeholder.
+
+As a consequence of typing constraints, existential variables can be
+duplicated in such a way that they possibly appear in different
+contexts than their defining context. Thus, any occurrence of a given
+existential variable comes with an instance of its original context.
+In the simple case, when an existential variable denotes the
+placeholder which generated it, or is used in the same context as the
+one in which it was generated, the context is not displayed and the
+existential variable is represented by “?” followed by an identifier.
+
+.. coqtop:: all
+
+ Parameter identity : forall (X:Set), X -> X.
+
+ Check identity _ _.
+
+ Check identity _ (fun x => _).
+
+In the general case, when an existential variable :n:`?@ident` appears
+outside of its context of definition, its instance, written under the
+form :n:`{ {*; @ident := @term} }` is appending to its name, indicating
+how the variables of its defining context are instantiated.
+The variables of the context of the existential variables which are
+instantiated by themselves are not written, unless the :flag:`Printing Existential Instances` flag
+is on (see Section :ref:`explicit-display-existentials`), and this is why an
+existential variable used in the same context as its context of definition is written with no instance.
+
+.. coqtop:: all
+
+ Check (fun x y => _) 0 1.
+
+ Set Printing Existential Instances.
+
+ Check (fun x y => _) 0 1.
+
+Existential variables can be named by the user upon creation using
+the syntax :n:`?[@ident]`. This is useful when the existential
+variable needs to be explicitly handled later in the script (e.g.
+with a named-goal selector, see :ref:`goal-selectors`).
+
+.. extracted from Gallina chapter
+
+.. index:: _
+
+Inferable subterms
+~~~~~~~~~~~~~~~~~~
+
+Expressions often contain redundant pieces of information. Subterms that can be
+automatically inferred by Coq can be replaced by the symbol ``_`` and Coq will
+guess the missing piece of information.
+
+.. extracted from Gallina extensions chapter
+
+.. _explicit-display-existentials:
+
+Explicit displaying of existential instances for pretty-printing
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. flag:: Printing Existential Instances
+
+ This flag (off by default) activates the full display of how the
+ context of an existential variable is instantiated at each of the
+ occurrences of the existential variable.
+
+.. _tactics-in-terms:
+
+Solving existential variables using tactics
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Instead of letting the unification engine try to solve an existential
+variable by itself, one can also provide an explicit hole together
+with a tactic to solve it. Using the syntax ``ltac:(``\ `tacexpr`\ ``)``, the user
+can put a tactic anywhere a term is expected. The order of resolution
+is not specified and is implementation-dependent. The inner tactic may
+use any variable defined in its scope, including repeated alternations
+between variables introduced by term binding as well as those
+introduced by tactic binding. The expression `tacexpr` can be any tactic
+expression as described in :ref:`ltac`.
+
+.. coqtop:: all
+
+ Definition foo (x : nat) : nat := ltac:(exact x).
+
+This construction is useful when one wants to define complicated terms
+using highly automated tactics without resorting to writing the proof-term
+by means of the interactive proof engine.
diff --git a/doc/sphinx/language/extensions/implicit-arguments.rst b/doc/sphinx/language/extensions/implicit-arguments.rst
index 73b1b65097..b4f7fe0846 100644
--- a/doc/sphinx/language/extensions/implicit-arguments.rst
+++ b/doc/sphinx/language/extensions/implicit-arguments.rst
@@ -466,127 +466,6 @@ function.
Check (id 1).
Check (id' nat 1).
-.. _canonical-structure-declaration:
-
-Canonical structures
-~~~~~~~~~~~~~~~~~~~~
-
-A canonical structure is an instance of a record/structure type that
-can be used to solve unification problems involving a projection
-applied to an unknown structure instance (an implicit argument) and a
-value. The complete documentation of canonical structures can be found
-in :ref:`canonicalstructures`; here only a simple example is given.
-
-.. cmd:: Canonical {? Structure } @smart_qualid
- Canonical {? Structure } @ident_decl @def_body
- :name: Canonical Structure; _
-
- The first form of this command declares an existing :n:`@smart_qualid` as a
- canonical instance of a structure (a record).
-
- The second form defines a new constant as if the :cmd:`Definition` command
- had been used, then declares it as a canonical instance as if the first
- form had been used on the defined object.
-
- This command supports the :attr:`local` attribute. When used, the
- structure is canonical only within the :cmd:`Section` containing it.
-
- Assume that :token:`qualid` denotes an object ``(Build_struct`` |c_1| … |c_n| ``)`` in the
- structure :g:`struct` of which the fields are |x_1|, …, |x_n|.
- Then, each time an equation of the form ``(``\ |x_i| ``_)`` |eq_beta_delta_iota_zeta| |c_i| has to be
- solved during the type checking process, :token:`qualid` is used as a solution.
- Otherwise said, :token:`qualid` is canonically used to extend the field |c_i|
- into a complete structure built on |c_i|.
-
- Canonical structures are particularly useful when mixed with coercions
- and strict implicit arguments.
-
- .. example::
-
- Here is an example.
-
- .. coqtop:: all reset
-
- Require Import Relations.
-
- Require Import EqNat.
-
- Set Implicit Arguments.
-
- Unset Strict Implicit.
-
- Structure Setoid : Type := {Carrier :> Set; Equal : relation Carrier;
- Prf_equiv : equivalence Carrier Equal}.
-
- Definition is_law (A B:Setoid) (f:A -> B) := forall x y:A, Equal x y -> Equal (f x) (f y).
-
- Axiom eq_nat_equiv : equivalence nat eq_nat.
-
- Definition nat_setoid : Setoid := Build_Setoid eq_nat_equiv.
-
- Canonical nat_setoid.
-
- Thanks to :g:`nat_setoid` declared as canonical, the implicit arguments :g:`A`
- and :g:`B` can be synthesized in the next statement.
-
- .. coqtop:: all abort
-
- Lemma is_law_S : is_law S.
-
- .. note::
- If a same field occurs in several canonical structures, then
- only the structure declared first as canonical is considered.
-
- .. attr:: canonical(false)
-
- To prevent a field from being involved in the inference of
- canonical instances, its declaration can be annotated with the
- :attr:`canonical(false)` attribute (cf. the syntax of
- :n:`@record_field`).
-
- .. example::
-
- For instance, when declaring the :g:`Setoid` structure above, the
- :g:`Prf_equiv` field declaration could be written as follows.
-
- .. coqdoc::
-
- #[canonical(false)] Prf_equiv : equivalence Carrier Equal
-
- See :ref:`canonicalstructures` for a more realistic example.
-
-.. attr:: canonical
-
- This attribute can decorate a :cmd:`Definition` or :cmd:`Let` command.
- It is equivalent to having a :cmd:`Canonical Structure` declaration just
- after the command.
-
-.. cmd:: Print Canonical Projections {* @smart_qualid }
-
- This displays the list of global names that are components of some
- canonical structure. For each of them, the canonical structure of
- which it is a projection is indicated. If constants are given as
- its arguments, only the unification rules that involve or are
- synthesized from simultaneously all given constants will be shown.
-
- .. example::
-
- For instance, the above example gives the following output:
-
- .. coqtop:: all
-
- Print Canonical Projections.
-
- .. coqtop:: all
-
- Print Canonical Projections nat.
-
- .. note::
-
- The last line in the first example would not show up if the
- corresponding projection (namely :g:`Prf_equiv`) were annotated as not
- canonical, as described above.
-
Implicit types of variables
~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/doc/sphinx/language/extensions/index.rst b/doc/sphinx/language/extensions/index.rst
index fc2ce03093..ed207ca743 100644
--- a/doc/sphinx/language/extensions/index.rst
+++ b/doc/sphinx/language/extensions/index.rst
@@ -16,13 +16,13 @@ language presented in the :ref:`previous chapter <core-language>`.
.. toctree::
:maxdepth: 1
- ../gallina-extensions
+ evars
implicit-arguments
- ../../addendum/extended-pattern-matching
+ match
../../user-extensions/syntax-extensions
arguments-command
../../addendum/implicit-coercions
../../addendum/type-classes
- ../../addendum/canonical-structures
+ canonical
../../addendum/program
../../proof-engine/vernacular-commands
diff --git a/doc/sphinx/addendum/extended-pattern-matching.rst b/doc/sphinx/language/extensions/match.rst
index 8ec51e45ba..028d0aaf57 100644
--- a/doc/sphinx/addendum/extended-pattern-matching.rst
+++ b/doc/sphinx/language/extensions/match.rst
@@ -9,10 +9,287 @@ This section describes the full form of pattern matching in |Coq| terms.
.. |rhs| replace:: right hand sides
+.. extracted from Gallina extensions chapter
+
+Variants and extensions of :g:`match`
+-------------------------------------
+
+.. _mult-match:
+
+Multiple and nested pattern matching
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The basic version of :g:`match` allows pattern matching on simple
+patterns. As an extension, multiple nested patterns or disjunction of
+patterns are allowed, as in ML-like languages
+(cf. :ref:`multiple-patterns` and :ref:`nested-patterns`).
+
+The extension just acts as a macro that is expanded during parsing
+into a sequence of match on simple patterns. Especially, a
+construction defined using the extended match is generally printed
+under its expanded form (see :flag:`Printing Matching`).
+
+.. _if-then-else:
+
+Pattern-matching on boolean values: the if expression
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. insertprodn term_if term_if
+
+.. prodn::
+ term_if ::= if @term {? {? as @name } return @term100 } then @term else @term
+
+For inductive types with exactly two constructors and for pattern matching
+expressions that do not depend on the arguments of the constructors, it is possible
+to use a ``if … then … else`` notation. For instance, the definition
+
+.. coqtop:: all
+
+ Definition not (b:bool) :=
+ match b with
+ | true => false
+ | false => true
+ end.
+
+can be alternatively written
+
+.. coqtop:: reset all
+
+ Definition not (b:bool) := if b then false else true.
+
+More generally, for an inductive type with constructors :n:`@ident__1`
+and :n:`@ident__2`, the following terms are equal:
+
+:n:`if @term__0 {? {? as @name } return @term } then @term__1 else @term__2`
+
+:n:`match @term__0 {? {? as @name } return @term } with | @ident__1 {* _ } => @term__1 | @ident__2 {* _ } => @term__2 end`
+
+.. example::
+
+ .. coqtop:: all
+
+ Check (fun x (H:{x=0}+{x<>0}) =>
+ match H with
+ | left _ => true
+ | right _ => false
+ end).
+
+Notice that the printing uses the :g:`if` syntax because :g:`sumbool` is
+declared as such (see :ref:`controlling-match-pp`).
+
+.. _irrefutable-patterns:
+
+Irrefutable patterns: the destructuring let variants
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+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.
+
+
+First destructuring let syntax
+++++++++++++++++++++++++++++++
+
+The expression :n:`let ( {*, @ident__i } ) := @term__0 in @term__1`
+performs case analysis on :n:`@term__0` whose type must be an
+inductive type with exactly one constructor. The number of variables
+:n:`@ident__i` must correspond to the number of arguments of this
+contrustor. Then, in :n:`@term__1`, these variables are bound to the
+arguments of the constructor in :n:`@term__0`. For instance, the
+definition
+
+.. coqtop:: reset all
+
+ Definition fst (A B:Set) (H:A * B) := match H with
+ | pair x y => x
+ end.
+
+can be alternatively written
+
+.. coqtop:: reset all
+
+ Definition fst (A B:Set) (p:A * B) := let (x, _) := p in x.
+
+Notice that reduction is different from regular :g:`let … in …`
+construction since it happens only if :n:`@term__0` is in constructor form.
+Otherwise, the reduction is blocked.
+
+The pretty-printing of a definition by matching on a irrefutable
+pattern can either be done using :g:`match` or the :g:`let` construction
+(see Section :ref:`controlling-match-pp`).
+
+If term inhabits an inductive type with one constructor `C`, we have an
+equivalence between
+
+::
+
+ let (ident₁, …, identₙ) [dep_ret_type] := term in term'
+
+and
+
+::
+
+ match term [dep_ret_type] with
+ C ident₁ … identₙ => term'
+ end
+
+
+Second destructuring let syntax
++++++++++++++++++++++++++++++++
+
+Another destructuring let syntax is available for inductive types with
+one constructor by giving an arbitrary pattern instead of just a tuple
+for all the arguments. For example, the preceding example can be
+written:
+
+.. coqtop:: reset all
+
+ Definition fst (A B:Set) (p:A*B) := let 'pair x _ := p in x.
+
+This is useful to match deeper inside tuples and also to use notations
+for the pattern, as the syntax :g:`let ’p := t in b` allows arbitrary
+patterns to do the deconstruction. For example:
+
+.. coqtop:: all
+
+ Definition deep_tuple (A:Set) (x:(A*A)*(A*A)) : A*A*A*A :=
+ let '((a,b), (c, d)) := x in (a,b,c,d).
+
+ Notation " x 'With' p " := (exist _ x p) (at level 20).
+
+ Definition proj1_sig' (A:Set) (P:A->Prop) (t:{ x:A | P x }) : A :=
+ let 'x With p := t in x.
+
+When printing definitions which are written using this construct it
+takes precedence over let printing directives for the datatype under
+consideration (see Section :ref:`controlling-match-pp`).
+
+
+.. _controlling-match-pp:
+
+Controlling pretty-printing of match expressions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following commands give some control over the pretty-printing
+of :g:`match` expressions.
+
+Printing nested patterns
++++++++++++++++++++++++++
+
+.. flag:: Printing Matching
+
+ The Calculus of Inductive Constructions knows pattern matching only
+ over simple patterns. It is however convenient to re-factorize nested
+ pattern matching into a single pattern matching over a nested
+ pattern.
+
+ 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.
+
+
+Factorization of clauses with same right-hand side
+++++++++++++++++++++++++++++++++++++++++++++++++++
+
+.. flag:: Printing Factorizable Match Patterns
+
+ 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
+ printer to try to do this kind of factorization.
+
+Use of a default clause
++++++++++++++++++++++++
+
+.. flag:: Printing Allow Match Default Clause
+
+ When several patterns share the same right-hand side which do not depend on the
+ 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.
+
+Printing of wildcard patterns
+++++++++++++++++++++++++++++++
+
+.. flag:: Printing Wildcard
+
+ Some variables in a pattern may not occur in the right-hand side of
+ the pattern matching clause. When this flag is on (default), the
+ variables having no occurrences in the right-hand side of the
+ pattern matching clause are just printed using the wildcard symbol
+ “_”.
+
+
+Printing of the elimination predicate
++++++++++++++++++++++++++++++++++++++
+
+.. flag:: Printing Synth
+
+ 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-
+ synthesize it.
+
+
+Printing matching on irrefutable patterns
+++++++++++++++++++++++++++++++++++++++++++
+
+If an inductive type has just one constructor, pattern matching can be
+written using the first destructuring let syntax.
+
+.. table:: Printing Let @qualid
+ :name: Printing Let
+
+ Specifies a set of qualids for which pattern matching is displayed using a let expression.
+ Note that this only applies to pattern matching instances entered with :g:`match`.
+ It doesn't affect pattern matching explicitly entered with a destructuring
+ :g:`let`.
+ Use the :cmd:`Add` and :cmd:`Remove` commands to update this set.
+
+
+Printing matching on booleans
++++++++++++++++++++++++++++++
+
+If an inductive type is isomorphic to the boolean type, pattern matching
+can be written using ``if`` … ``then`` … ``else`` …. This table controls
+which types are written this way:
+
+.. table:: Printing If @qualid
+ :name: Printing If
+
+ Specifies a set of qualids for which pattern matching is displayed using
+ ``if`` … ``then`` … ``else`` …. Use the :cmd:`Add` and :cmd:`Remove`
+ commands to update this set.
+
+This example emphasizes what the printing settings offer.
+
+.. example::
+
+ .. coqtop:: all
+
+ Definition snd (A B:Set) (H:A * B) := match H with
+ | pair x y => y
+ end.
+
+ Test Printing Let for prod.
+
+ Print snd.
+
+ Remove Printing Let prod.
+
+ Unset Printing Synth.
+
+ Unset Printing Wildcard.
+
+ Print snd.
+
Patterns
--------
-The full syntax of :g:`match` is presented in section :ref:`term`.
+The full syntax of `match` is presented in :ref:`match`.
Identifiers in patterns are either constructor names or variables. Any
identifier that is not the constructor of an inductive or co-inductive
type is considered to be a variable. A variable name cannot occur more
@@ -68,6 +345,8 @@ by:
end
end.
+.. _multiple-patterns:
+
Multiple patterns
-----------------
@@ -110,6 +389,8 @@ We can also use :n:`as @ident` to associate a name to a sub-pattern:
| S n', S m' => S (max n' m')
end.
+.. _nested-patterns:
+
Nested patterns
---------------
diff --git a/doc/sphinx/language/gallina-extensions.rst b/doc/sphinx/language/gallina-extensions.rst
deleted file mode 100644
index 5b78280edc..0000000000
--- a/doc/sphinx/language/gallina-extensions.rst
+++ /dev/null
@@ -1,1114 +0,0 @@
-.. _extensionsofgallina:
-
-Extensions of |Gallina|
-=======================
-
-|Gallina| is the kernel language of |Coq|. We describe here extensions of
-|Gallina|’s syntax.
-
-Variants and extensions of :g:`match`
--------------------------------------
-
-.. _mult-match:
-
-Multiple and nested pattern matching
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The basic version of :g:`match` allows pattern matching on simple
-patterns. As an extension, multiple nested patterns or disjunction of
-patterns are allowed, as in ML-like languages.
-
-The extension just acts as a macro that is expanded during parsing
-into a sequence of match on simple patterns. Especially, a
-construction defined using the extended match is generally printed
-under its expanded form (see :flag:`Printing Matching`).
-
-.. seealso:: :ref:`extendedpatternmatching`.
-
-.. _if-then-else:
-
-Pattern-matching on boolean values: the if expression
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. insertprodn term_if term_if
-
-.. prodn::
- term_if ::= if @term {? {? as @name } return @term100 } then @term else @term
-
-For inductive types with exactly two constructors and for pattern matching
-expressions that do not depend on the arguments of the constructors, it is possible
-to use a ``if … then … else`` notation. For instance, the definition
-
-.. coqtop:: all
-
- Definition not (b:bool) :=
- match b with
- | true => false
- | false => true
- end.
-
-can be alternatively written
-
-.. coqtop:: reset all
-
- Definition not (b:bool) := if b then false else true.
-
-More generally, for an inductive type with constructors :n:`@ident__1`
-and :n:`@ident__2`, the following terms are equal:
-
-:n:`if @term__0 {? {? as @name } return @term } then @term__1 else @term__2`
-
-:n:`match @term__0 {? {? as @name } return @term } with | @ident__1 {* _ } => @term__1 | @ident__2 {* _ } => @term__2 end`
-
-.. example::
-
- .. coqtop:: all
-
- Check (fun x (H:{x=0}+{x<>0}) =>
- match H with
- | left _ => true
- | right _ => false
- end).
-
-Notice that the printing uses the :g:`if` syntax because :g:`sumbool` is
-declared as such (see :ref:`controlling-match-pp`).
-
-.. _irrefutable-patterns:
-
-Irrefutable patterns: the destructuring let variants
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-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.
-
-
-First destructuring let syntax
-++++++++++++++++++++++++++++++
-
-The expression :n:`let ( {*, @ident__i } ) := @term__0 in @term__1`
-performs case analysis on :n:`@term__0` whose type must be an
-inductive type with exactly one constructor. The number of variables
-:n:`@ident__i` must correspond to the number of arguments of this
-contrustor. Then, in :n:`@term__1`, these variables are bound to the
-arguments of the constructor in :n:`@term__0`. For instance, the
-definition
-
-.. coqtop:: reset all
-
- Definition fst (A B:Set) (H:A * B) := match H with
- | pair x y => x
- end.
-
-can be alternatively written
-
-.. coqtop:: reset all
-
- Definition fst (A B:Set) (p:A * B) := let (x, _) := p in x.
-
-Notice that reduction is different from regular :g:`let … in …`
-construction since it happens only if :n:`@term__0` is in constructor form.
-Otherwise, the reduction is blocked.
-
-The pretty-printing of a definition by matching on a irrefutable
-pattern can either be done using :g:`match` or the :g:`let` construction
-(see Section :ref:`controlling-match-pp`).
-
-If term inhabits an inductive type with one constructor `C`, we have an
-equivalence between
-
-::
-
- let (ident₁, …, identₙ) [dep_ret_type] := term in term'
-
-and
-
-::
-
- match term [dep_ret_type] with
- C ident₁ … identₙ => term'
- end
-
-
-Second destructuring let syntax
-+++++++++++++++++++++++++++++++
-
-Another destructuring let syntax is available for inductive types with
-one constructor by giving an arbitrary pattern instead of just a tuple
-for all the arguments. For example, the preceding example can be
-written:
-
-.. coqtop:: reset all
-
- Definition fst (A B:Set) (p:A*B) := let 'pair x _ := p in x.
-
-This is useful to match deeper inside tuples and also to use notations
-for the pattern, as the syntax :g:`let ’p := t in b` allows arbitrary
-patterns to do the deconstruction. For example:
-
-.. coqtop:: all
-
- Definition deep_tuple (A:Set) (x:(A*A)*(A*A)) : A*A*A*A :=
- let '((a,b), (c, d)) := x in (a,b,c,d).
-
- Notation " x 'With' p " := (exist _ x p) (at level 20).
-
- Definition proj1_sig' (A:Set) (P:A->Prop) (t:{ x:A | P x }) : A :=
- let 'x With p := t in x.
-
-When printing definitions which are written using this construct it
-takes precedence over let printing directives for the datatype under
-consideration (see Section :ref:`controlling-match-pp`).
-
-
-.. _controlling-match-pp:
-
-Controlling pretty-printing of match expressions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following commands give some control over the pretty-printing
-of :g:`match` expressions.
-
-Printing nested patterns
-+++++++++++++++++++++++++
-
-.. flag:: Printing Matching
-
- The Calculus of Inductive Constructions knows pattern matching only
- over simple patterns. It is however convenient to re-factorize nested
- pattern matching into a single pattern matching over a nested
- pattern.
-
- 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.
-
-
-Factorization of clauses with same right-hand side
-++++++++++++++++++++++++++++++++++++++++++++++++++
-
-.. flag:: Printing Factorizable Match Patterns
-
- 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
- printer to try to do this kind of factorization.
-
-Use of a default clause
-+++++++++++++++++++++++
-
-.. flag:: Printing Allow Match Default Clause
-
- When several patterns share the same right-hand side which do not depend on the
- 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.
-
-Printing of wildcard patterns
-++++++++++++++++++++++++++++++
-
-.. flag:: Printing Wildcard
-
- Some variables in a pattern may not occur in the right-hand side of
- the pattern matching clause. When this flag is on (default), the
- variables having no occurrences in the right-hand side of the
- pattern matching clause are just printed using the wildcard symbol
- “_”.
-
-
-Printing of the elimination predicate
-+++++++++++++++++++++++++++++++++++++
-
-.. flag:: Printing Synth
-
- 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-
- synthesize it.
-
-
-Printing matching on irrefutable patterns
-++++++++++++++++++++++++++++++++++++++++++
-
-If an inductive type has just one constructor, pattern matching can be
-written using the first destructuring let syntax.
-
-.. table:: Printing Let @qualid
- :name: Printing Let
-
- Specifies a set of qualids for which pattern matching is displayed using a let expression.
- Note that this only applies to pattern matching instances entered with :g:`match`.
- It doesn't affect pattern matching explicitly entered with a destructuring
- :g:`let`.
- Use the :cmd:`Add` and :cmd:`Remove` commands to update this set.
-
-
-Printing matching on booleans
-+++++++++++++++++++++++++++++
-
-If an inductive type is isomorphic to the boolean type, pattern matching
-can be written using ``if`` … ``then`` … ``else`` …. This table controls
-which types are written this way:
-
-.. table:: Printing If @qualid
- :name: Printing If
-
- Specifies a set of qualids for which pattern matching is displayed using
- ``if`` … ``then`` … ``else`` …. Use the :cmd:`Add` and :cmd:`Remove`
- commands to update this set.
-
-This example emphasizes what the printing settings offer.
-
-.. example::
-
- .. coqtop:: all
-
- Definition snd (A B:Set) (H:A * B) := match H with
- | pair x y => y
- end.
-
- Test Printing Let for prod.
-
- Print snd.
-
- Remove Printing Let prod.
-
- Unset Printing Synth.
-
- Unset Printing Wildcard.
-
- Print snd.
-
-Module system
--------------
-
-The module system provides a way of packaging related elements
-together, as well as a means of massive abstraction.
-
-
-.. cmd:: Module {? {| Import | Export } } @ident {* @module_binder } {? @of_module_type } {? := {+<+ @module_expr_inl } }
-
- .. insertprodn module_binder module_expr_inl
-
- .. prodn::
- module_binder ::= ( {? {| Import | Export } } {+ @ident } : @module_type_inl )
- module_type_inl ::= ! @module_type
- | @module_type {? @functor_app_annot }
- functor_app_annot ::= [ inline at level @num ]
- | [ no inline ]
- module_type ::= @qualid
- | ( @module_type )
- | @module_type @module_expr_atom
- | @module_type with @with_declaration
- with_declaration ::= Definition @qualid {? @univ_decl } := @term
- | Module @qualid := @qualid
- module_expr_atom ::= @qualid
- | ( {+ @module_expr_atom } )
- of_module_type ::= : @module_type_inl
- | {* <: @module_type_inl }
- module_expr_inl ::= ! {+ @module_expr_atom }
- | {+ @module_expr_atom } {? @functor_app_annot }
-
- Defines a module named :token:`ident`. See the examples :ref:`here<module_examples>`.
-
- The :n:`Import` and :n:`Export` flags specify whether the module should be automatically
- imported or exported.
-
- Specifying :n:`{* @module_binder }` starts a functor with
- parameters given by the :n:`@module_binder`\s. (A *functor* is a function
- from modules to modules.)
-
- :n:`@of_module_type` specifies the module type. :n:`{+ <: @module_type_inl }`
- starts a module that satisfies each :n:`@module_type_inl`.
-
- .. todo: would like to find a better term than "interactive", not very descriptive
-
- :n:`:= {+<+ @module_expr_inl }` specifies the body of a module or functor
- definition. If it's not specified, then the module is defined *interactively*,
- meaning that the module is defined as a series of commands terminated with :cmd:`End`
- instead of in a single :cmd:`Module` command.
- Interactively defining the :n:`@module_expr_inl`\s in a series of
- :cmd:`Include` commands is equivalent to giving them all in a single
- non-interactive :cmd:`Module` command.
-
- The ! prefix indicates that any assumption command (such as :cmd:`Axiom`) with an :n:`Inline` clause
- in the type of the functor arguments will be ignored.
-
- .. todo: What is an Inline directive? sb command but still unclear. Maybe referring to the
- "inline" in functor_app_annot? or assumption_token Inline assum_list?
-
-.. cmd:: Module Type @ident {* @module_binder } {* <: @module_type_inl } {? := {+<+ @module_type_inl } }
-
- Defines a module type named :n:`@ident`. See the example :ref:`here<example_def_simple_module_type>`.
-
- Specifying :n:`{* @module_binder }` starts a functor type with
- parameters given by the :n:`@module_binder`\s.
-
- :n:`:= {+<+ @module_type_inl }` specifies the body of a module or functor type
- definition. If it's not specified, then the module type is defined *interactively*,
- meaning that the module type is defined as a series of commands terminated with :cmd:`End`
- instead of in a single :cmd:`Module Type` command.
- Interactively defining the :n:`@module_type_inl`\s in a series of
- :cmd:`Include` commands is equivalent to giving them all in a single
- non-interactive :cmd:`Module Type` command.
-
-.. _terminating_module:
-
-**Terminating an interactive module or module type definition**
-
-Interactive modules are terminated with the :cmd:`End` command, which
-is also used to terminate :ref:`Sections<section-mechanism>`.
-:n:`End @ident` closes the interactive module or module type :token:`ident`.
-If the module type was given, the command verifies that the content of the module
-matches the module type. If the module is not a
-functor, its components (constants, inductive types, submodules etc.)
-are now available through the dot notation.
-
-.. exn:: No such label @ident.
- :undocumented:
-
-.. exn:: Signature components for label @ident do not match.
- :undocumented:
-
-.. exn:: The field @ident is missing in @qualid.
- :undocumented:
-
-.. |br| raw:: html
-
- <br>
-
-.. note::
-
- #. Interactive modules and module types can be nested.
- #. Interactive modules and module types can't be defined inside of :ref:`sections<section-mechanism>`.
- Sections can be defined inside of interactive modules and module types.
- #. Hints and notations (:cmd:`Hint` and :cmd:`Notation` commands) can also appear inside interactive
- modules and module types. Note that with module definitions like:
-
- :n:`Module @ident__1 : @module_type := @ident__2.`
-
- or
-
- :n:`Module @ident__1 : @module_type.` |br|
- :n:`Include @ident__2.` |br|
- :n:`End @ident__1.`
-
- hints and the like valid for :n:`@ident__1` are the ones defined in :n:`@module_type`
- rather then those defined in :n:`@ident__2` (or the module body).
- #. Within an interactive module type definition, the :cmd:`Parameter` command declares a
- constant instead of definining a new axiom (which it does when not in a module type definition).
- #. Assumptions such as :cmd:`Axiom` that include the :n:`Inline` clause will be automatically
- expanded when the functor is applied, except when the function application is prefixed by ``!``.
-
-.. cmd:: Include @module_type_inl {* <+ @module_expr_inl }
-
- Includes the content of module(s) in the current
- interactive module. Here :n:`@module_type_inl` can be a module expression or a module
- type expression. If it is a high-order module or module type
- expression then the system tries to instantiate :n:`@module_type_inl` with the current
- interactive module.
-
- Including multiple modules is a single :cmd:`Include` is equivalent to including each module
- in a separate :cmd:`Include` command.
-
-.. cmd:: Include Type {+<+ @module_type_inl }
-
- .. deprecated:: 8.3
-
- Use :cmd:`Include` instead.
-
-.. cmd:: Declare Module {? {| Import | Export } } @ident {* @module_binder } : @module_type_inl
-
- Declares a module :token:`ident` of type :token:`module_type_inl`.
-
- If :n:`@module_binder`\s are specified, declares a functor with parameters given by the list of
- :token:`module_binder`\s.
-
-.. cmd:: Import {+ @filtered_import }
-
- .. insertprodn filtered_import filtered_import
-
- .. prodn::
- filtered_import ::= @qualid {? ( {+, @qualid {? ( .. ) } } ) }
-
- If :token:`qualid` denotes a valid basic module (i.e. its module type is a
- signature), makes its components available by their short names.
-
- .. example::
-
- .. coqtop:: reset in
-
- Module Mod.
- Definition T:=nat.
- Check T.
- End Mod.
- Check Mod.T.
-
- .. coqtop:: all
-
- Fail Check T.
- Import Mod.
- Check T.
-
- Some features defined in modules are activated only when a module is
- imported. This is for instance the case of notations (see :ref:`Notations`).
-
- Declarations made with the :attr:`local` attribute are never imported by the :cmd:`Import`
- command. Such declarations are only accessible through their fully
- qualified name.
-
- .. example::
-
- .. coqtop:: in
-
- Module A.
- Module B.
- Local Definition T := nat.
- End B.
- End A.
- Import A.
-
- .. coqtop:: all fail
-
- Check B.T.
-
- Appending a module name with a parenthesized list of names will
- make only those names available with short names, not other names
- defined in the module nor will it activate other features.
-
- The names to import may be constants, inductive types and
- constructors, and notation aliases (for instance, Ltac definitions
- cannot be selectively imported). If they are from an inner module
- to the one being imported, they must be prefixed by the inner path.
-
- The name of an inductive type may also be followed by ``(..)`` to
- import it, its constructors and its eliminators if they exist. For
- this purpose "eliminator" means a constant in the same module whose
- name is the inductive type's name suffixed by one of ``_sind``,
- ``_ind``, ``_rec`` or ``_rect``.
-
- .. example::
-
- .. coqtop:: reset in
-
- Module A.
- Module B.
- Inductive T := C.
- Definition U := nat.
- End B.
- Definition Z := Prop.
- End A.
- Import A(B.T(..), Z).
-
- .. coqtop:: all
-
- Check B.T.
- Check B.C.
- Check Z.
- Fail Check B.U.
- Check A.B.U.
-
-.. cmd:: Export {+ @filtered_import }
- :name: Export
-
- Similar to :cmd:`Import`, except that when the module containing this command
- is imported, the :n:`{+ @qualid }` are imported as well.
-
- The selective import syntax also works with Export.
-
- .. exn:: @qualid is not a module.
- :undocumented:
-
- .. warn:: Trying to mask the absolute name @qualid!
- :undocumented:
-
-.. cmd:: Print Module @qualid
-
- Prints the module type and (optionally) the body of the module :n:`@qualid`.
-
-.. cmd:: Print Module Type @qualid
-
- Prints the module type corresponding to :n:`@qualid`.
-
-.. flag:: Short Module Printing
-
- This flag (off by default) disables the printing of the types of fields,
- leaving only their names, for the commands :cmd:`Print Module` and
- :cmd:`Print Module Type`.
-
-.. _module_examples:
-
-Examples
-~~~~~~~~
-
-.. example:: Defining a simple module interactively
-
- .. coqtop:: in
-
- Module M.
- Definition T := nat.
- Definition x := 0.
-
- .. coqtop:: all
-
- Definition y : bool.
- exact true.
-
- .. coqtop:: in
-
- Defined.
- End M.
-
-Inside a module one can define constants, prove theorems and do anything
-else that can be done in the toplevel. Components of a closed
-module can be accessed using the dot notation:
-
-.. coqtop:: all
-
- Print M.x.
-
-.. _example_def_simple_module_type:
-
-.. example:: Defining a simple module type interactively
-
- .. coqtop:: in
-
- Module Type SIG.
- Parameter T : Set.
- Parameter x : T.
- End SIG.
-
-.. _example_filter_module:
-
-.. example:: Creating a new module that omits some items from an existing module
-
- Since :n:`SIG`, the type of the new module :n:`N`, doesn't define :n:`y` or
- give the body of :n:`x`, which are not included in :n:`N`.
-
- .. coqtop:: all
-
- Module N : SIG with Definition T := nat := M.
- Print N.T.
- Print N.x.
- Fail Print N.y.
-
- .. reset to remove N (undo in last coqtop block doesn't seem to do that), invisibly redefine M, SIG
- .. coqtop:: none reset
-
- Module M.
- Definition T := nat.
- Definition x := 0.
- Definition y : bool.
- exact true.
- Defined.
- End M.
-
- Module Type SIG.
- Parameter T : Set.
- Parameter x : T.
- End SIG.
-
-The definition of :g:`N` using the module type expression :g:`SIG` with
-:g:`Definition T := nat` is equivalent to the following one:
-
-.. coqtop:: in
-
- Module Type SIG'.
- Definition T : Set := nat.
- Parameter x : T.
- End SIG'.
-
- Module N : SIG' := M.
-
-If we just want to be sure that our implementation satisfies a
-given module type without restricting the interface, we can use a
-transparent constraint
-
-.. coqtop:: in
-
- Module P <: SIG := M.
-
-.. coqtop:: all
-
- Print P.y.
-
-.. example:: Creating a functor (a module with parameters)
-
- .. coqtop:: in
-
- Module Two (X Y: SIG).
- Definition T := (X.T * Y.T)%type.
- Definition x := (X.x, Y.x).
- End Two.
-
- and apply it to our modules and do some computations:
-
- .. coqtop:: in
-
-
- Module Q := Two M N.
-
- .. coqtop:: all
-
- Eval compute in (fst Q.x + snd Q.x).
-
-.. example:: A module type with two sub-modules, sharing some fields
-
- .. coqtop:: in
-
- Module Type SIG2.
- Declare Module M1 : SIG.
- Module M2 <: SIG.
- Definition T := M1.T.
- Parameter x : T.
- End M2.
- End SIG2.
-
- .. coqtop:: in
-
- Module Mod <: SIG2.
- Module M1.
- Definition T := nat.
- Definition x := 1.
- End M1.
- Module M2 := M.
- End Mod.
-
-Notice that ``M`` is a correct body for the component ``M2`` since its ``T``
-component is ``nat`` as specified for ``M1.T``.
-
-Libraries and qualified names
----------------------------------
-
-.. _names-of-libraries:
-
-Names of libraries
-~~~~~~~~~~~~~~~~~~
-
-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:`gallina-identifiers`). For instance, the library file ``Mult`` of the standard
-|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
-(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
-started, unless option ``-top`` or ``-notop`` is set (see :ref:`command-line-options`).
-
-.. _qualified-names:
-
-Qualified names
-~~~~~~~~~~~~~~~
-
-Library files are modules which possibly contain submodules which
-eventually contain constructions (axioms, parameters, definitions,
-lemmas, theorems, remarks or facts). The *absolute name*, or *full
-name*, of a construction in some library file is a qualified
-identifier starting with the logical name of the library file,
-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|.
-
-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
-name of ``Coq.Init.Logic.eq`` is ``eq``). Any partial suffix of the absolute
-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
-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).
-
-Notice that the notion of absolute, partially qualified and short
-names also applies to library filenames.
-
-**Visibility**
-
-|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
-their fully qualified name (see :ref:`gallina-definitions`).
-
-It may happen that a visible name is hidden by the short name or a
-qualified name of another construction. In this case, the name that
-has been hidden must be referred to using one more level of
-qualification. To ensure that a construction always remains
-accessible, absolute names can never be hidden.
-
-.. example::
-
- .. coqtop:: all
-
- Check 0.
-
- Definition nat := bool.
-
- Check 0.
-
- Check Datatypes.nat.
-
- Locate nat.
-
-.. seealso:: Commands :cmd:`Locate`.
-
-.. _libraries-and-filesystem:
-
-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.
-
-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
-is needed. In this translation, names in the file system are called
-*physical* paths while |Coq| names are contrastingly called *logical*
-names.
-
-A logical prefix Lib can be associated with a physical path using
-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,
-subdirectories named ``CVS`` or ``_darcs`` are skipped too.
-
-Thanks to this mechanism, ``.vo`` files are made available through the
-logical name of the folder they are in, extended with their own
-basename. For example, the name associated to the file
-``path/fOO/Bar/File.vo`` is ``Lib.fOO.Bar.File``. The same caveat applies for
-invalid identifiers. When compiling a source file, the ``.vo`` file stores
-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
-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/``
-environment variables (see `XDG base directory specification
-<http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_)
-with the same physical-to-logical translation and with an empty logical prefix.
-
-The command line option ``-R`` is a variant of ``-Q`` which has the strictly
-same behavior regarding loadpaths, but which also makes the
-corresponding ``.vo`` files available through their short names in a way
-similar to the :cmd:`Import` command. For instance, ``-R path Lib``
-associates to the file ``/path/fOO/Bar/File.vo`` the logical name
-``Lib.fOO.Bar.File``, but allows this file to be accessed through the
-short names ``fOO.Bar.File,Bar.File`` and ``File``. If several files with
-identical base name are present in different subdirectories of a
-recursive loadpath, which of these files is found first may be system-
-dependent and explicit qualification is recommended. The ``From`` argument
-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
-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
-line options.
-
-.. _Coercions:
-
-Coercions
----------
-
-Coercions can be used to implicitly inject terms from one *class* in
-which they reside into another one. A *class* is either a sort
-(denoted by the keyword ``Sortclass``), a product type (denoted by the
-keyword ``Funclass``), or a type constructor (denoted by its name), e.g.
-an inductive type or any constant with a type of the form
-:n:`forall {+ @binder }, @sort`.
-
-Then the user is able to apply an object that is not a function, but
-can be coerced to a function, and more generally to consider that a
-term of type ``A`` is of type ``B`` provided that there is a declared coercion
-between ``A`` and ``B``.
-
-More details and examples, and a description of the commands related
-to coercions are provided in :ref:`implicitcoercions`.
-
-.. _printing_constructions_full:
-
-Printing constructions in full
-------------------------------
-
-.. flag:: Printing All
-
- Coercions, implicit arguments, the type of pattern matching, but also
- notations (see :ref:`syntax-extensions-and-notation-scopes`) can obfuscate the behavior of some
- tactics (typically the tactics applying to occurrences of subterms are
- sensitive to the implicit arguments). Turning this flag on
- deactivates all high-level printing features such as coercions,
- implicit arguments, returned type of pattern matching, notations and
- various syntactic sugar for pattern matching or record projections.
- Otherwise said, :flag:`Printing All` includes the effects of the flags
- :flag:`Printing Implicit`, :flag:`Printing Coercions`, :flag:`Printing Synth`,
- :flag:`Printing Projections`, and :flag:`Printing Notations`. To reactivate
- the high-level printing features, use the command ``Unset Printing All``.
-
- .. note:: In some cases, setting :flag:`Printing All` may display terms
- that are so big they become very hard to read. One technique to work around
- this is use :cmd:`Undelimit Scope` and/or :cmd:`Close Scope` to turn off the
- printing of notations bound to particular scope(s). This can be useful when
- notations in a given scope are getting in the way of understanding
- a goal, but turning off all notations with :flag:`Printing All` would make
- the goal unreadable.
-
- .. see a contrived example here: https://github.com/coq/coq/pull/11718#discussion_r415481854
-
-.. _printing-universes:
-
-Printing universes
-------------------
-
-.. flag:: Printing Universes
-
- Turn this flag on to activate the display of the actual level of each
- occurrence of :g:`Type`. See :ref:`Sorts` for details. This wizard flag, in
- combination with :flag:`Printing All` can help to diagnose failures to unify
- terms apparently identical but internally different in the Calculus of Inductive
- Constructions.
-
-.. cmd:: Print {? Sorted } Universes {? Subgraph ( {* @qualid } ) } {? @string }
- :name: Print Universes
-
- This command can be used to print the constraints on the internal level
- of the occurrences of :math:`\Type` (see :ref:`Sorts`).
-
- The :n:`Subgraph` clause limits the printed graph to the requested names (adjusting
- constraints to preserve the implied transitive constraints between
- kept universes).
-
- The :n:`Sorted` clause makes each universe
- equivalent to a numbered label reflecting its level (with a linear
- ordering) in the universe hierarchy.
-
- :n:`@string` is an optional output filename.
- If :n:`@string` ends in ``.dot`` or ``.gv``, the constraints are printed in the DOT
- language, and can be processed by Graphviz tools. The format is
- unspecified if `string` doesn’t end in ``.dot`` or ``.gv``.
-
-.. _existential-variables:
-
-Existential variables
----------------------
-
-.. insertprodn term_evar term_evar
-
-.. prodn::
- term_evar ::= _
- | ?[ @ident ]
- | ?[ ?@ident ]
- | ?@ident {? @%{ {+; @ident := @term } %} }
-
-|Coq| terms can include existential variables which represents unknown
-subterms to eventually be replaced by actual subterms.
-
-Existential variables are generated in place of unsolvable implicit
-arguments or “_” placeholders when using commands such as ``Check`` (see
-Section :ref:`requests-to-the-environment`) or when using tactics such as
-:tacn:`refine`, as well as in place of unsolvable instances when using
-tactics such that :tacn:`eapply`. An existential
-variable is defined in a context, which is the context of variables of
-the placeholder which generated the existential variable, and a type,
-which is the expected type of the placeholder.
-
-As a consequence of typing constraints, existential variables can be
-duplicated in such a way that they possibly appear in different
-contexts than their defining context. Thus, any occurrence of a given
-existential variable comes with an instance of its original context.
-In the simple case, when an existential variable denotes the
-placeholder which generated it, or is used in the same context as the
-one in which it was generated, the context is not displayed and the
-existential variable is represented by “?” followed by an identifier.
-
-.. coqtop:: all
-
- Parameter identity : forall (X:Set), X -> X.
-
- Check identity _ _.
-
- Check identity _ (fun x => _).
-
-In the general case, when an existential variable :n:`?@ident` appears
-outside of its context of definition, its instance, written under the
-form :n:`{ {*; @ident := @term} }` is appending to its name, indicating
-how the variables of its defining context are instantiated.
-The variables of the context of the existential variables which are
-instantiated by themselves are not written, unless the :flag:`Printing Existential Instances` flag
-is on (see Section :ref:`explicit-display-existentials`), and this is why an
-existential variable used in the same context as its context of definition is written with no instance.
-
-.. coqtop:: all
-
- Check (fun x y => _) 0 1.
-
- Set Printing Existential Instances.
-
- Check (fun x y => _) 0 1.
-
-Existential variables can be named by the user upon creation using
-the syntax :n:`?[@ident]`. This is useful when the existential
-variable needs to be explicitly handled later in the script (e.g.
-with a named-goal selector, see :ref:`goal-selectors`).
-
-.. _explicit-display-existentials:
-
-Explicit displaying of existential instances for pretty-printing
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. flag:: Printing Existential Instances
-
- This flag (off by default) activates the full display of how the
- context of an existential variable is instantiated at each of the
- occurrences of the existential variable.
-
-.. _tactics-in-terms:
-
-Solving existential variables using tactics
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Instead of letting the unification engine try to solve an existential
-variable by itself, one can also provide an explicit hole together
-with a tactic to solve it. Using the syntax ``ltac:(``\ `tacexpr`\ ``)``, the user
-can put a tactic anywhere a term is expected. The order of resolution
-is not specified and is implementation-dependent. The inner tactic may
-use any variable defined in its scope, including repeated alternations
-between variables introduced by term binding as well as those
-introduced by tactic binding. The expression `tacexpr` can be any tactic
-expression as described in :ref:`ltac`.
-
-.. coqtop:: all
-
- Definition foo (x : nat) : nat := ltac:(exact x).
-
-This construction is useful when one wants to define complicated terms
-using highly automated tactics without resorting to writing the proof-term
-by means of the interactive proof engine.
-
-.. _primitive-integers:
-
-Primitive Integers
-------------------
-
-The language of terms features 63-bit machine integers as values. The type of
-such a value is *axiomatized*; it is declared through the following sentence
-(excerpt from the :g:`Int63` module):
-
-.. coqdoc::
-
- Primitive int := #int63_type.
-
-This type is equipped with a few operators, that must be similarly declared.
-For instance, equality of two primitive integers can be decided using the :g:`Int63.eqb` function,
-declared and specified as follows:
-
-.. coqdoc::
-
- Primitive eqb := #int63_eq.
- Notation "m '==' n" := (eqb m n) (at level 70, no associativity) : int63_scope.
-
- Axiom eqb_correct : forall i j, (i == j)%int63 = true -> i = j.
-
-The complete set of such operators can be obtained looking at the :g:`Int63` module.
-
-These primitive declarations are regular axioms. As such, they must be trusted and are listed by the
-:g:`Print Assumptions` command, as in the following example.
-
-.. coqtop:: in reset
-
- From Coq Require Import Int63.
- Lemma one_minus_one_is_zero : (1 - 1 = 0)%int63.
- Proof. apply eqb_correct; vm_compute; reflexivity. Qed.
-
-.. coqtop:: all
-
- Print Assumptions one_minus_one_is_zero.
-
-The reduction machines (:tacn:`vm_compute`, :tacn:`native_compute`) implement
-dedicated, efficient, rules to reduce the 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
-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.
-
-Literal values (at type :g:`Int63.int`) are extracted to literal OCaml values
-wrapped into the :g:`Uint63.of_int` (resp. :g:`Uint63.of_int64`) constructor on
-64-bit (resp. 32-bit) platforms. Currently, this cannot be customized (see the
-function :g:`Uint63.compile` from the kernel).
-
-.. _primitive-floats:
-
-Primitive Floats
-----------------
-
-The language of terms features Binary64 floating-point numbers as values.
-The type of such a value is *axiomatized*; it is declared through the
-following sentence (excerpt from the :g:`PrimFloat` module):
-
-.. coqdoc::
-
- Primitive float := #float64_type.
-
-This type is equipped with a few operators, that must be similarly declared.
-For instance, the product of two primitive floats can be computed using the
-:g:`PrimFloat.mul` function, declared and specified as follows:
-
-.. coqdoc::
-
- Primitive mul := #float64_mul.
- Notation "x * y" := (mul x y) : float_scope.
-
- Axiom mul_spec : forall x y, Prim2SF (x * y)%float = SF64mul (Prim2SF x) (Prim2SF y).
-
-where :g:`Prim2SF` is defined in the :g:`FloatOps` module.
-
-The set of such operators is described in section :ref:`floats_library`.
-
-These primitive declarations are regular axioms. As such, they must be trusted, and are listed by the
-:g:`Print Assumptions` command.
-
-The reduction machines (:tacn:`vm_compute`, :tacn:`native_compute`) implement
-dedicated, efficient rules to reduce the applications of these primitive
-operations, using the floating-point processor operators that are assumed
-to comply with the IEEE 754 standard for floating-point arithmetic.
-
-The extraction of these primitives can be customized similarly to the extraction
-of regular axioms (see :ref:`extraction`). Nonetheless, the :g:`ExtrOCamlFloats`
-module can be used when extracting to OCaml: it maps the Coq primitives to types
-and functions of a :g:`Float64` module. Said 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.
-
-Literal values (of type :g:`Float64.t`) are extracted to literal OCaml
-values (of type :g:`float`) written in hexadecimal notation and
-wrapped into the :g:`Float64.of_float` constructor, e.g.:
-:g:`Float64.of_float (0x1p+0)`.
diff --git a/doc/sphinx/language/gallina-specification-language.rst b/doc/sphinx/language/gallina-specification-language.rst
deleted file mode 100644
index 353bed1b3d..0000000000
--- a/doc/sphinx/language/gallina-specification-language.rst
+++ /dev/null
@@ -1,1452 +0,0 @@
-.. _gallinaspecificationlanguage:
-
-------------------------------------
- The Gallina specification language
-------------------------------------
-
-This chapter describes Gallina, the specification language of Coq. It allows
-developing mathematical theories and to prove specifications of programs. The
-theories are built from axioms, hypotheses, parameters, lemmas, theorems and
-definitions of constants, functions, predicates and sets.
-
-.. _term:
-
-Terms
-=====
-
-.. _gallina-identifiers:
-
-Qualified identifiers and simple identifiers
---------------------------------------------
-
-.. insertprodn qualid field_ident
-
-.. prodn::
- qualid ::= @ident {* @field_ident }
- field_ident ::= .@ident
-
-*Qualified identifiers* (:n:`@qualid`) denote *global constants*
-(definitions, lemmas, theorems, remarks or facts), *global variables*
-(parameters or axioms), *inductive types* or *constructors of inductive
-types*. *Simple identifiers* (or shortly :n:`@ident`) are a syntactic subset
-of qualified identifiers. Identifiers may also denote *local variables*,
-while qualified identifiers do not.
-
-Field identifiers, written :n:`@field_ident`, are identifiers prefixed by
-`.` (dot) with no blank between the dot and the identifier.
-
-
-Numerals and strings
---------------------
-
-.. insertprodn primitive_notations primitive_notations
-
-.. prodn::
- primitive_notations ::= @numeral
- | @string
-
-Numerals and strings have no predefined semantics in the calculus. They are
-merely notations that can be bound to objects through the notation mechanism
-(see Chapter :ref:`syntax-extensions-and-notation-scopes` for details).
-Initially, numerals are bound to Peano’s representation of natural
-numbers (see :ref:`datatypes`).
-
-.. note::
-
- Negative integers are not at the same level as :n:`@num`, for this
- would make precedence unnatural.
-
-.. index::
- single: Set (sort)
- single: SProp
- single: Prop
- single: Type
-
-Sorts
------
-
-.. insertprodn sort univ_constraint
-
-.. prodn::
- sort ::= Set
- | Prop
- | SProp
- | Type
- | Type @%{ _ %}
- | Type @%{ @universe %}
- universe ::= max ( {+, @universe_expr } )
- | @universe_expr
- universe_expr ::= @universe_name {? + @num }
- universe_name ::= @qualid
- | Set
- | Prop
- univ_annot ::= @%{ {* @universe_level } %}
- universe_level ::= Set
- | Prop
- | Type
- | _
- | @qualid
- univ_decl ::= @%{ {* @ident } {? + } {? %| {*, @univ_constraint } {? + } } %}
- univ_constraint ::= @universe_name {| < | = | <= } @universe_name
-
-There are four sorts :g:`SProp`, :g:`Prop`, :g:`Set` and :g:`Type`.
-
-- :g:`SProp` is the universe of *definitionally irrelevant
- propositions* (also called *strict propositions*).
-
-- :g:`Prop` is the universe of *logical propositions*. The logical propositions
- themselves are typing the proofs. We denote propositions by :n:`@form`.
- This constitutes a semantic subclass of the syntactic class :n:`@term`.
-
-- :g:`Set` is the universe of *program types* or *specifications*. The
- specifications themselves are typing the programs. We denote
- specifications by :n:`@specif`. This constitutes a semantic subclass of
- the syntactic class :n:`@term`.
-
-- :g:`Type` is the type of sorts.
-
-More on sorts can be found in Section :ref:`sorts`.
-
-.. _binders:
-
-Binders
--------
-
-.. insertprodn open_binders binder
-
-.. prodn::
- open_binders ::= {+ @name } : @term
- | {+ @binder }
- name ::= _
- | @ident
- binder ::= @name
- | ( {+ @name } : @type )
- | ( @name {? : @type } := @term )
- | @implicit_binders
- | @generalizing_binder
- | ( @name : @type %| @term )
- | ' @pattern0
-
-Various constructions such as :g:`fun`, :g:`forall`, :g:`fix` and :g:`cofix`
-*bind* variables. A binding is represented by an identifier. If the binding
-variable is not used in the expression, the identifier can be replaced by the
-symbol :g:`_`. When the type of a bound variable cannot be synthesized by the
-system, it can be specified with the notation :n:`(@ident : @type)`. There is also
-a notation for a sequence of binding variables sharing the same type:
-:n:`({+ @ident} : @type)`. A
-binder can also be any pattern prefixed by a quote, e.g. :g:`'(x,y)`.
-
-Some constructions allow the binding of a variable to value. This is
-called a “let-binder”. The entry :n:`@binder` of the grammar accepts
-either an assumption binder as defined above or a let-binder. The notation in
-the latter case is :n:`(@ident := @term)`. In a let-binder, only one
-variable can be introduced at the same time. It is also possible to give
-the type of the variable as follows:
-:n:`(@ident : @type := @term)`.
-
-Lists of :n:`@binder`\s are allowed. In the case of :g:`fun` and :g:`forall`,
-it is intended that at least one binder of the list is an assumption otherwise
-fun and forall gets identical. Moreover, parentheses can be omitted in
-the case of a single sequence of bindings sharing the same type (e.g.:
-:g:`fun (x y z : A) => t` can be shortened in :g:`fun x y z : A => t`).
-
-.. index:: fun ... => ...
-
-Abstractions: fun
------------------
-
-The expression :n:`fun @ident : @type => @term` defines the
-*abstraction* of the variable :n:`@ident`, of type :n:`@type`, over the term
-:n:`@term`. It denotes a function of the variable :n:`@ident` that evaluates to
-the expression :n:`@term` (e.g. :g:`fun x : A => x` denotes the identity
-function on type :g:`A`). The keyword :g:`fun` can be followed by several
-binders as given in Section :ref:`binders`. Functions over
-several variables are equivalent to an iteration of one-variable
-functions. For instance the expression
-:n:`fun {+ @ident__i } : @type => @term`
-denotes the same function as :n:`{+ fun @ident__i : @type => } @term`. If
-a let-binder occurs in
-the list of binders, it is expanded to a let-in definition (see
-Section :ref:`let-in`).
-
-.. index:: forall
-
-Products: forall
-----------------
-
-.. insertprodn term_forall_or_fun term_forall_or_fun
-
-.. prodn::
- term_forall_or_fun ::= forall @open_binders , @term
- | fun @open_binders => @term
-
-The expression :n:`forall @ident : @type, @term` denotes the
-*product* of the variable :n:`@ident` of type :n:`@type`, over the term :n:`@term`.
-As for abstractions, :g:`forall` is followed by a binder list, and products
-over several variables are equivalent to an iteration of one-variable
-products. Note that :n:`@term` is intended to be a type.
-
-If the variable :n:`@ident` occurs in :n:`@term`, the product is called
-*dependent product*. The intention behind a dependent product
-:g:`forall x : A, B` is twofold. It denotes either
-the universal quantification of the variable :g:`x` of type :g:`A`
-in the proposition :g:`B` or the functional dependent product from
-:g:`A` to :g:`B` (a construction usually written
-:math:`\Pi_{x:A}.B` in set theory).
-
-Non dependent product types have a special notation: :g:`A -> B` stands for
-:g:`forall _ : A, B`. The *non dependent product* is used both to denote
-the propositional implication and function types.
-
-Applications
-------------
-
-.. insertprodn term_application arg
-
-.. prodn::
- term_application ::= @term1 {+ @arg }
- | @ @qualid_annotated {+ @term1 }
- arg ::= ( @ident := @term )
- | @term1
-
-:n:`@term__fun @term` denotes applying the function :n:`@term__fun` to :token:`term`.
-
-:n:`@term__fun {+ @term__i }` denotes applying
-:n:`@term__fun` to the arguments :n:`@term__i`. It is
-equivalent to :n:`( … ( @term__fun @term__1 ) … ) @term__n`:
-associativity is to the left.
-
-The notation :n:`(@ident := @term)` for arguments is used for making
-explicit the value of implicit arguments (see
-Section :ref:`explicit-applications`).
-
-.. index::
- single: ... : ... (type cast)
- single: ... <: ...
- single: ... <<: ...
-
-Type cast
----------
-
-.. insertprodn term_cast term_cast
-
-.. prodn::
- term_cast ::= @term10 <: @term
- | @term10 <<: @term
- | @term10 : @term
- | @term10 :>
-
-The expression :n:`@term : @type` is a type cast expression. It enforces
-the type of :n:`@term` to be :n:`@type`.
-
-:n:`@term <: @type` locally sets up the virtual machine for checking that
-:n:`@term` has type :n:`@type`.
-
-:n:`@term <<: @type` uses native compilation for checking that :n:`@term`
-has type :n:`@type`.
-
-.. index:: _
-
-Inferable subterms
-------------------
-
-Expressions often contain redundant pieces of information. Subterms that can be
-automatically inferred by Coq can be replaced by the symbol ``_`` and Coq will
-guess the missing piece of information.
-
-.. index:: let ... := ... (term)
-
-.. _let-in:
-
-Let-in definitions
-------------------
-
-.. insertprodn term_let term_let
-
-.. 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
-
-: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’`.
-
-.. index:: match ... with ...
-
-Definition by cases: match
---------------------------
-
-.. insertprodn term_match pattern0
-
-.. prodn::
- term_match ::= match {+, @case_item } {? return @term100 } with {? %| } {*| @eqn } end
- case_item ::= @term100 {? as @name } {? in @pattern }
- eqn ::= {+| {+, @pattern } } => @term
- pattern ::= @pattern10 : @term
- | @pattern10
- pattern10 ::= @pattern1 as @name
- | @pattern1 {* @pattern1 }
- | @ @qualid {* @pattern1 }
- pattern1 ::= @pattern0 % @scope_key
- | @pattern0
- pattern0 ::= @qualid
- | %{%| {* @qualid := @pattern } %|%}
- | _
- | ( {+| @pattern } )
- | @numeral
- | @string
-
-Objects of inductive types can be destructured by a case-analysis
-construction called *pattern matching* expression. A pattern matching
-expression is used to analyze the structure of an inductive object and
-to apply specific treatments accordingly.
-
-This paragraph describes the basic form of pattern matching. See
-Section :ref:`Mult-match` and Chapter :ref:`extendedpatternmatching` for the description
-of the general form. The basic form of pattern matching is characterized
-by a single :n:`@case_item` expression, an :n:`@eqn` restricted to a
-single :n:`@pattern` and :n:`@pattern` restricted to the form
-:n:`@qualid {* @ident}`.
-
-The expression
-:n:`match @term {? return @term100 } with {+| @pattern__i => @term__i } end` denotes a
-*pattern matching* over the term :n:`@term` (expected to be
-of an inductive type :math:`I`). The :n:`@term__i`
-are the *branches* of the pattern matching
-expression. Each :n:`@pattern__i` has the form :n:`@qualid @ident`
-where :n:`@qualid` must denote a constructor. There should be
-exactly one branch for every constructor of :math:`I`.
-
-The :n:`return @term100` clause gives the type returned by the whole match
-expression. There are several cases. In the *non dependent* case, all
-branches have the same type, and the :n:`return @term100` specifies that type.
-In this case, :n:`return @term100` can usually be omitted as it can be
-inferred from the type of the branches [1]_.
-
-In the *dependent* case, there are three subcases. In the first subcase,
-the type in each branch may depend on the exact value being matched in
-the branch. In this case, the whole pattern matching itself depends on
-the term being matched. This dependency of the term being matched in the
-return type is expressed with an :n:`@ident` clause where :n:`@ident`
-is dependent in the return type. For instance, in the following example:
-
-.. coqtop:: in
-
- Inductive bool : Type := true : bool | false : bool.
- Inductive eq (A:Type) (x:A) : A -> Prop := eq_refl : eq A x x.
- Inductive or (A:Prop) (B:Prop) : Prop :=
- | or_introl : A -> or A B
- | or_intror : B -> or A B.
-
- Definition bool_case (b:bool) : or (eq bool b true) (eq bool b false) :=
- match b as x return or (eq bool x true) (eq bool x false) with
- | true => or_introl (eq bool true true) (eq bool true false) (eq_refl bool true)
- | false => or_intror (eq bool false true) (eq bool false false) (eq_refl bool false)
- end.
-
-the branches have respective types ":g:`or (eq bool true true) (eq bool true false)`"
-and ":g:`or (eq bool false true) (eq bool false false)`" while the whole
-pattern matching expression has type ":g:`or (eq bool b true) (eq bool b false)`",
-the identifier :g:`b` being used to represent the dependency.
-
-.. note::
-
- When the term being matched is a variable, the ``as`` clause can be
- omitted and the term being matched can serve itself as binding name in
- the return type. For instance, the following alternative definition is
- accepted and has the same meaning as the previous one.
-
- .. coqtop:: none
-
- Reset bool_case.
-
- .. coqtop:: in
-
- Definition bool_case (b:bool) : or (eq bool b true) (eq bool b false) :=
- match b return or (eq bool b true) (eq bool b false) with
- | true => or_introl (eq bool true true) (eq bool true false) (eq_refl bool true)
- | false => or_intror (eq bool false true) (eq bool false false) (eq_refl bool false)
- end.
-
-The second subcase is only relevant for annotated inductive types such
-as the equality predicate (see Section :ref:`coq-equality`),
-the order predicate on natural numbers or the type of lists of a given
-length (see Section :ref:`matching-dependent`). In this configuration, the
-type of each branch can depend on the type dependencies specific to the
-branch and the whole pattern matching expression has a type determined
-by the specific dependencies in the type of the term being matched. This
-dependency of the return type in the annotations of the inductive type
-is expressed with a clause in the form
-:n:`in @qualid {+ _ } {+ @pattern }`, where
-
-- :n:`@qualid` is the inductive type of the term being matched;
-
-- the holes :n:`_` match the parameters of the inductive type: the
- return type is not dependent on them.
-
-- each :n:`@pattern` matches the annotations of the
- inductive type: the return type is dependent on them
-
-- in the basic case which we describe below, each :n:`@pattern`
- is a name :n:`@ident`; see :ref:`match-in-patterns` for the
- general case
-
-For instance, in the following example:
-
-.. coqtop:: in
-
- Definition eq_sym (A:Type) (x y:A) (H:eq A x y) : eq A y x :=
- match H in eq _ _ z return eq A z x with
- | eq_refl _ _ => eq_refl A x
- end.
-
-the type of the branch is :g:`eq A x x` because the third argument of
-:g:`eq` is :g:`x` in the type of the pattern :g:`eq_refl`. On the contrary, the
-type of the whole pattern matching expression has type :g:`eq A y x` because the
-third argument of eq is y in the type of H. This dependency of the case analysis
-in the third argument of :g:`eq` is expressed by the identifier :g:`z` in the
-return type.
-
-Finally, the third subcase is a combination of the first and second
-subcase. In particular, it only applies to pattern matching on terms in
-a type with annotations. For this third subcase, both the clauses ``as`` and
-``in`` are available.
-
-There are specific notations for case analysis on types with one or two
-constructors: ``if … then … else …`` and ``let (…,…) := … in …`` (see
-Sections :ref:`if-then-else` and :ref:`irrefutable-patterns`).
-
-.. index::
- single: fix
- single: cofix
-
-Recursive and co-recursive functions: fix and cofix
----------------------------------------------------
-
-.. 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
- fixannot ::= %{ struct @ident %}
- | %{ wf @one_term @ident %}
- | %{ measure @one_term {? @ident } {? @one_term } %}
-
-
-The expression ":n:`fix @ident__1 @binder__1 : @type__1 := @term__1 with … with @ident__n @binder__n : @type__n := @term__n for @ident__i`" denotes the
-:math:`i`-th component of a block of functions defined by mutual structural
-recursion. It is the local counterpart of the :cmd:`Fixpoint` command. When
-:math:`n=1`, the ":n:`for @ident__i`" clause is omitted.
-
-The association of a single fixpoint and a local definition have a special
-syntax: :n:`let fix @ident {* @binder } := @term in` stands for
-:n:`let @ident := fix @ident {* @binder } := @term in`. The same applies for co-fixpoints.
-
-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`.
-
-.. insertprodn term_cofix cofix_body
-
-.. prodn::
- term_cofix ::= let cofix @cofix_body in @term
- | cofix @cofix_body {? {+ with @cofix_body } for @ident }
- cofix_body ::= @ident {* @binder } {? : @type } := @term
-
-The expression
-":n:`cofix @ident__1 @binder__1 : @type__1 with … with @ident__n @binder__n : @type__n for @ident__i`"
-denotes the :math:`i`-th component of a block of terms defined by a mutual guarded
-co-recursion. It is the local counterpart of the :cmd:`CoFixpoint` command. When
-:math:`n=1`, the ":n:`for @ident__i`" clause is omitted.
-
-.. _vernacular:
-
-The Vernacular
-==============
-
-.. _gallina-assumptions:
-
-Assumptions
------------
-
-Assumptions extend the environment with axioms, parameters, hypotheses
-or variables. An assumption binds an :n:`@ident` to a :n:`@type`. It is accepted
-by Coq if and only if this :n:`@type` is a correct type in the environment
-preexisting the declaration and if :n:`@ident` was not previously defined in
-the same module. This :n:`@type` is considered to be the type (or
-specification, or statement) assumed by :n:`@ident` and we say that :n:`@ident`
-has type :n:`@type`.
-
-.. _Axiom:
-
-.. cmd:: @assumption_token {? Inline {? ( @num ) } } {| {+ ( @assumpt ) } | @assumpt }
- :name: Axiom; Axioms; Conjecture; Conjectures; Hypothesis; Hypotheses; Parameter; Parameters; Variable; Variables
-
- .. insertprodn assumption_token of_type
-
- .. prodn::
- assumption_token ::= {| Axiom | Axioms }
- | {| Conjecture | Conjectures }
- | {| Parameter | Parameters }
- | {| Hypothesis | Hypotheses }
- | {| Variable | Variables }
- assumpt ::= {+ @ident_decl } @of_type
- ident_decl ::= @ident {? @univ_decl }
- 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.
-
- :cmd:`Axiom`, :cmd:`Conjecture`, :cmd:`Parameter` and their plural forms
- are equivalent. They can take the :attr:`local` :term:`attribute`,
- which makes the defined :n:`@ident`\s accessible by :cmd:`Import` and its variants
- only through their fully qualified names.
-
- Similarly, :cmd:`Hypothesis`, :cmd:`Variable` and their plural forms are equivalent. Outside
- of a section, these are equivalent to :n:`Local Parameter`. Inside a section, the
- :n:`@ident`\s defined are only accessible within the section. When the current section
- 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`.
-
- The :n:`Inline` clause is only relevant inside functors. See :cmd:`Module`.
-
-.. example:: Simple assumptions
-
- .. coqtop:: reset in
-
- Parameter X Y : Set.
- Parameter (R : X -> Y -> Prop) (S : Y -> X -> Prop).
- Axiom R_S_inv : forall x y, R x y <-> S y x.
-
-.. exn:: @ident already exists.
- :name: @ident already exists. (Axiom)
- :undocumented:
-
-.. warn:: @ident is declared as a local axiom
-
- Warning generated when using :cmd:`Variable` or its equivalent
- instead of :n:`Local Parameter` or its equivalent.
-
-.. note::
- We advise using the commands :cmd:`Axiom`, :cmd:`Conjecture` and
- :cmd:`Hypothesis` (and their plural forms) for logical postulates (i.e. when
- the assertion :n:`@type` is of sort :g:`Prop`), and to use the commands
- :cmd:`Parameter` and :cmd:`Variable` (and their plural forms) in other cases
- (corresponding to the declaration of an abstract object of the given type).
-
-.. _gallina-definitions:
-
-Definitions
------------
-
-Definitions extend the environment with associations of names to terms.
-A definition can be seen as a way to give a meaning to a name or as a
-way to abbreviate a term. In any case, the name can later be replaced at
-any time by its definition.
-
-The operation of unfolding a name into its definition is called
-:math:`\delta`-conversion (see Section :ref:`delta-reduction`). A
-definition is accepted by the system if and only if the defined term is
-well-typed in the current context of the definition and if the name is
-not already used. The name defined by the definition is called a
-*constant* and the term it refers to is its *body*. A definition has a
-type which is the type of its body.
-
-A formal presentation of constants and environments is given in
-Section :ref:`typing-rules`.
-
-.. cmd:: {| Definition | Example } @ident_decl @def_body
- :name: Definition; Example
-
- .. insertprodn def_body def_body
-
- .. prodn::
- def_body ::= {* @binder } {? : @type } := {? @reduce } @term
- | {* @binder } : @type
-
- These commands bind :n:`@term` to the name :n:`@ident` in the environment,
- provided that :n:`@term` is well-typed. They can take the :attr:`local` :term:`attribute`,
- which makes the defined :n:`@ident` accessible by :cmd:`Import` and its variants
- only through their fully qualified names.
- If :n:`@reduce` is present then :n:`@ident` is bound to the result of the specified
- computation on :n:`@term`.
-
- These commands also support the :attr:`universes(polymorphic)`,
- :attr:`universes(monomorphic)`, :attr:`program` and
- :attr:`canonical` 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.
- 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`.
-
- The form :n:`Definition @ident : @type := @term` checks that the type of :n:`@term`
- is definitionally equal to :n:`@type`, and registers :n:`@ident` as being of type
- :n:`@type`, and bound to value :n:`@term`.
-
- The form :n:`Definition @ident {* @binder } : @type := @term` is equivalent to
- :n:`Definition @ident : forall {* @binder }, @type := fun {* @binder } => @term`.
-
- .. seealso:: :cmd:`Opaque`, :cmd:`Transparent`, :tacn:`unfold`.
-
- .. exn:: @ident already exists.
- :name: @ident already exists. (Definition)
- :undocumented:
-
- .. exn:: The term @term has type @type while it is expected to have type @type'.
- :undocumented:
-
-.. _gallina-inductive-definitions:
-
-Inductive types
----------------
-
-.. cmd:: Inductive @inductive_definition {* with @inductive_definition }
-
- .. insertprodn inductive_definition constructor
-
- .. prodn::
- inductive_definition ::= {? > } @ident_decl {* @binder } {? %| {* @binder } } {? : @type } {? := {? @constructors_or_record } } {? @decl_notations }
- constructors_or_record ::= {? %| } {+| @constructor }
- | {? @ident } %{ {*; @record_field } %}
- constructor ::= @ident {* @binder } {? @of_type }
-
- This command defines one or more
- inductive types and its constructors. Coq generates destructors
- depending on the universe that the inductive type belongs to.
-
- The destructors are named :n:`@ident`\ ``_rect``, :n:`@ident`\ ``_ind``,
- :n:`@ident`\ ``_rec`` and :n:`@ident`\ ``_sind``, which
- respectively correspond to elimination principles on :g:`Type`, :g:`Prop`,
- :g:`Set` and :g:`SProp`. The type of the destructors
- expresses structural induction/recursion principles over objects of
- type :n:`@ident`. The constant :n:`@ident`\ ``_ind`` is always
- generated, whereas :n:`@ident`\ ``_rec`` and :n:`@ident`\ ``_rect``
- may be impossible to derive (for example, when :n:`@ident` is a
- proposition).
-
- 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.
-
- Mutually inductive types can be defined by including multiple :n:`@inductive_definition`\s.
- The :n:`@ident`\s are simultaneously added to the environment before the types of constructors are checked.
- Each :n:`@ident` can be used independently thereafter.
- See :ref:`mutually_inductive_types`.
-
- If the entire inductive definition is parameterized with :n:`@binder`\s, the parameters correspond
- to a local context in which the entire set of inductive declarations is interpreted.
- For this reason, the parameters must be strictly the same for each inductive type.
- See :ref:`parametrized-inductive-types`.
-
- Constructor :n:`@ident`\s can come with :n:`@binder`\s, in which case
- the actual type of the constructor is :n:`forall {* @binder }, @type`.
-
- .. exn:: Non strictly positive occurrence of @ident in @type.
-
- The types of the constructors have to satisfy a *positivity condition*
- (see Section :ref:`positivity`). This condition ensures the soundness of
- the inductive definition. The positivity checking can be disabled using
- the :flag:`Positivity Checking` flag (see :ref:`controlling-typing-flags`).
-
- .. exn:: The conclusion of @type is not valid; it must be built from @ident.
-
- The conclusion of the type of the constructors must be the inductive type
- :n:`@ident` being defined (or :n:`@ident` applied to arguments in
- the case of annotated inductive types — cf. next section).
-
-The following subsections show examples of simple inductive types,
-simple annotated inductive types, simple parametric inductive types,
-mutually inductive types and private (matching) inductive types.
-
-.. _simple-inductive-types:
-
-Simple inductive types
-~~~~~~~~~~~~~~~~~~~~~~
-
-A simple inductive type belongs to a universe that is a simple :n:`@sort`.
-
-.. example::
-
- The set of natural numbers is defined as:
-
- .. coqtop:: reset all
-
- Inductive nat : Set :=
- | O : nat
- | S : nat -> nat.
-
- The type nat is defined as the least :g:`Set` containing :g:`O` and closed by
- the :g:`S` constructor. The names :g:`nat`, :g:`O` and :g:`S` are added to the
- environment.
-
- This definition generates four elimination principles:
- :g:`nat_rect`, :g:`nat_ind`, :g:`nat_rec` and :g:`nat_sind`. The type of :g:`nat_ind` is:
-
- .. coqtop:: all
-
- Check nat_ind.
-
- This is the well known structural induction principle over natural
- numbers, i.e. the second-order form of Peano’s induction principle. It
- allows proving universal properties of natural numbers (:g:`forall
- n:nat, P n`) by induction on :g:`n`.
-
- The types of :g:`nat_rect`, :g:`nat_rec` and :g:`nat_sind` are similar, except that they
- apply to, respectively, :g:`(P:nat->Type)`, :g:`(P:nat->Set)` and :g:`(P:nat->SProp)`. They correspond to
- primitive induction principles (allowing dependent types) respectively
- over sorts ```Type``, ``Set`` and ``SProp``.
-
-In the case where inductive types don't have annotations (the next section
-gives an example of annotations), a constructor can be defined
-by giving the type of its arguments alone.
-
-.. example::
-
- .. coqtop:: reset none
-
- Reset nat.
-
- .. coqtop:: in
-
- Inductive nat : Set := O | S (_:nat).
-
-Simple annotated inductive types
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-In annotated inductive types, the universe where the inductive type
-is defined is no longer a simple :n:`@sort`, but what is called an arity,
-which is a type whose conclusion is a :n:`@sort`.
-
-.. example::
-
- As an example of annotated inductive types, let us define the
- :g:`even` predicate:
-
- .. coqtop:: all
-
- Inductive even : nat -> Prop :=
- | even_0 : even O
- | even_SS : forall n:nat, even n -> even (S (S n)).
-
- The type :g:`nat->Prop` means that :g:`even` is a unary predicate (inductively
- defined) over natural numbers. The type of its two constructors are the
- defining clauses of the predicate :g:`even`. The type of :g:`even_ind` is:
-
- .. coqtop:: all
-
- Check even_ind.
-
- From a mathematical point of view, this asserts that the natural numbers satisfying
- the predicate :g:`even` are exactly in the smallest set of naturals satisfying the
- clauses :g:`even_0` or :g:`even_SS`. This is why, when we want to prove any
- predicate :g:`P` over elements of :g:`even`, it is enough to prove it for :g:`O`
- and to prove that if any natural number :g:`n` satisfies :g:`P` its double
- successor :g:`(S (S n))` satisfies also :g:`P`. This is analogous to the
- structural induction principle we got for :g:`nat`.
-
-.. _parametrized-inductive-types:
-
-Parameterized inductive types
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-In the previous example, each constructor introduces a different
-instance of the predicate :g:`even`. In some cases, all the constructors
-introduce the same generic instance of the inductive definition, in
-which case, instead of an annotation, we use a context of parameters
-which are :n:`@binder`\s shared by all the constructors of the definition.
-
-Parameters differ from inductive type annotations in that the
-conclusion of each type of constructor invokes the inductive type with
-the same parameter values of its specification.
-
-.. example::
-
- A typical example is the definition of polymorphic lists:
-
- .. coqtop:: all
-
- Inductive list (A:Set) : Set :=
- | nil : list A
- | cons : A -> list A -> list A.
-
- In the type of :g:`nil` and :g:`cons`, we write ":g:`list A`" and not
- just ":g:`list`". The constructors :g:`nil` and :g:`cons` have these types:
-
- .. coqtop:: all
-
- Check nil.
- Check cons.
-
- Observe that the destructors are also quantified with :g:`(A:Set)`, for example:
-
- .. coqtop:: all
-
- Check list_ind.
-
- Once again, the types of the constructor arguments and of the conclusion can be omitted:
-
- .. coqtop:: none
-
- Reset list.
-
- .. coqtop:: in
-
- Inductive list (A:Set) : Set := nil | cons (_:A) (_:list A).
-
-.. note::
- + The constructor type can
- recursively invoke the inductive definition on an argument which is not
- the parameter itself.
-
- One can define :
-
- .. coqtop:: all
-
- Inductive list2 (A:Set) : Set :=
- | nil2 : list2 A
- | cons2 : A -> list2 (A*A) -> list2 A.
-
- that can also be written by specifying only the type of the arguments:
-
- .. coqtop:: all reset
-
- Inductive list2 (A:Set) : Set :=
- | nil2
- | cons2 (_:A) (_:list2 (A*A)).
-
- But the following definition will give an error:
-
- .. coqtop:: all
-
- Fail Inductive listw (A:Set) : Set :=
- | nilw : listw (A*A)
- | consw : A -> listw (A*A) -> listw (A*A).
-
- because the conclusion of the type of constructors should be :g:`listw A`
- in both cases.
-
- + A parameterized inductive definition can be defined using annotations
- instead of parameters but it will sometimes give a different (bigger)
- sort for the inductive definition and will produce a less convenient
- rule for case elimination.
-
-.. flag:: Uniform Inductive Parameters
-
- When this flag is set (it is off by default),
- inductive definitions are abstracted over their parameters
- before type checking constructors, allowing to write:
-
- .. coqtop:: all
-
- Set Uniform Inductive Parameters.
- Inductive list3 (A:Set) : Set :=
- | nil3 : list3
- | cons3 : A -> list3 -> list3.
-
- This behavior is essentially equivalent to starting a new section
- and using :cmd:`Context` to give the uniform parameters, like so
- (cf. :ref:`section-mechanism`):
-
- .. coqtop:: all reset
-
- Section list3.
- Context (A:Set).
- Inductive list3 : Set :=
- | nil3 : list3
- | cons3 : A -> list3 -> list3.
- End list3.
-
- For finer control, you can use a ``|`` between the uniform and
- the non-uniform parameters:
-
- .. coqtop:: in reset
-
- Inductive Acc {A:Type} (R:A->A->Prop) | (x:A) : Prop
- := Acc_in : (forall y, R y x -> Acc y) -> Acc x.
-
- The flag can then be seen as deciding whether the ``|`` is at the
- beginning (when the flag is unset) or at the end (when it is set)
- of the parameters when not explicitly given.
-
-.. seealso::
- Section :ref:`inductive-definitions` and the :tacn:`induction` tactic.
-
-.. _mutually_inductive_types:
-
-Mutually defined inductive types
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. example:: Mutually defined inductive types
-
- A typical example of mutually inductive data types is trees and
- forests. We assume two types :g:`A` and :g:`B` that are given as variables. The types can
- be declared like this:
-
- .. coqtop:: in
-
- Parameters A B : Set.
-
- Inductive tree : Set := node : A -> forest -> tree
-
- with forest : Set :=
- | leaf : B -> forest
- | cons : tree -> forest -> forest.
-
- This declaration automatically generates eight induction principles. They are not the most
- general principles, but they correspond to each inductive part seen as a single inductive definition.
-
- To illustrate this point on our example, here are the types of :g:`tree_rec`
- and :g:`forest_rec`.
-
- .. coqtop:: all
-
- Check tree_rec.
-
- Check forest_rec.
-
- Assume we want to parameterize our mutual inductive definitions with the
- two type variables :g:`A` and :g:`B`, the declaration should be
- done as follows:
-
- .. coqdoc::
-
- Inductive tree (A B:Set) : Set := node : A -> forest A B -> tree A B
-
- with forest (A B:Set) : Set :=
- | leaf : B -> forest A B
- | cons : tree A B -> forest A B -> forest A B.
-
- Assume we define an inductive definition inside a section
- (cf. :ref:`section-mechanism`). When the section is closed, the variables
- declared in the section and occurring free in the declaration are added as
- parameters to the inductive definition.
-
-.. seealso::
- A generic command :cmd:`Scheme` is useful to build automatically various
- mutual induction principles.
-
-Private (matching) inductive types
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. attr:: private(matching)
-
- This attribute can be used to forbid the use of the :g:`match`
- construct on objects of this inductive type outside of the module
- where it is defined. There is also a legacy syntax using the
- ``Private`` prefix (cf. :n:`@legacy_attr`).
-
- The main use case of private (matching) inductive types is to emulate
- quotient types / higher-order inductive types in projects such as
- the `HoTT library <https://github.com/HoTT/HoTT>`_.
-
-.. example::
-
- .. coqtop:: all
-
- Module Foo.
- #[ private(matching) ] Inductive my_nat := my_O : my_nat | my_S : my_nat -> my_nat.
- Check (fun x : my_nat => match x with my_O => true | my_S _ => false end).
- End Foo.
- Import Foo.
- Fail Check (fun x : my_nat => match x with my_O => true | my_S _ => false end).
-
-Variants
-~~~~~~~~
-
-.. cmd:: Variant @variant_definition {* with @variant_definition }
-
- .. insertprodn variant_definition variant_definition
-
- .. prodn::
- variant_definition ::= @ident_decl {* @binder } {? %| {* @binder } } {? : @type } := {? %| } {+| @constructor } {? @decl_notations }
-
- The :cmd:`Variant` command is similar to the :cmd:`Inductive` command, except
- that it disallows recursive definition of types (for instance, lists cannot
- be defined using :cmd:`Variant`). No induction scheme is generated for
- this variant, unless the :flag:`Nonrecursive Elimination Schemes` flag is on.
-
- 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.
-
- .. exn:: The @num th argument of @ident must be @ident in @type.
- :undocumented:
-
-.. _coinductive-types:
-
-Co-inductive types
-------------------
-
-The objects of an inductive type are well-founded with respect to the
-constructors of the type. In other words, such objects contain only a
-*finite* number of constructors. Co-inductive types arise from relaxing
-this condition, and admitting types whose objects contain an infinity of
-constructors. Infinite objects are introduced by a non-ending (but
-effective) process of construction, defined in terms of the constructors
-of the type.
-
-.. cmd:: CoInductive @inductive_definition {* with @inductive_definition }
-
- This command introduces a co-inductive type.
- The syntax of the command is the same as the command :cmd:`Inductive`.
- No principle of induction is derived from the definition of a co-inductive
- type, since such principles only make sense for inductive types.
- For co-inductive types, the only elimination principle is case analysis.
-
- 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.
-
-.. example::
-
- The type of infinite sequences of natural numbers, usually called streams,
- is an example of a co-inductive type.
-
- .. coqtop:: in
-
- CoInductive Stream : Set := Seq : nat -> Stream -> Stream.
-
- The usual destructors on streams :g:`hd:Stream->nat` and :g:`tl:Str->Str`
- can be defined as follows:
-
- .. coqtop:: in
-
- Definition hd (x:Stream) := let (a,s) := x in a.
- Definition tl (x:Stream) := let (a,s) := x in s.
-
-Definitions of co-inductive predicates and blocks of mutually
-co-inductive definitions are also allowed.
-
-.. example::
-
- The extensional equality on streams is an example of a co-inductive type:
-
- .. coqtop:: in
-
- CoInductive EqSt : Stream -> Stream -> Prop :=
- eqst : forall s1 s2:Stream,
- hd s1 = hd s2 -> EqSt (tl s1) (tl s2) -> EqSt s1 s2.
-
- In order to prove the extensional equality of two streams :g:`s1` and :g:`s2`
- we have to construct an infinite proof of equality, that is, an infinite
- object of type :g:`(EqSt s1 s2)`. We will see how to introduce infinite
- objects in Section :ref:`cofixpoint`.
-
-Caveat
-~~~~~~
-
-The ability to define co-inductive types by constructors, hereafter called
-*positive co-inductive types*, is known to break subject reduction. The story is
-a bit long: this is due to dependent pattern-matching which implies
-propositional η-equality, which itself would require full η-conversion for
-subject reduction to hold, but full η-conversion is not acceptable as it would
-make type checking undecidable.
-
-Since the introduction of primitive records in Coq 8.5, an alternative
-presentation is available, called *negative co-inductive types*. This consists
-in defining a co-inductive type as a primitive record type through its
-projections. Such a technique is akin to the *co-pattern* style that can be
-found in e.g. Agda, and preserves subject reduction.
-
-The above example can be rewritten in the following way.
-
-.. coqtop:: none
-
- Reset Stream.
-
-.. coqtop:: all
-
- Set Primitive Projections.
- CoInductive Stream : Set := Seq { hd : nat; tl : Stream }.
- CoInductive EqSt (s1 s2: Stream) : Prop := eqst {
- eqst_hd : hd s1 = hd s2;
- eqst_tl : EqSt (tl s1) (tl s2);
- }.
-
-Some properties that hold over positive streams are lost when going to the
-negative presentation, typically when they imply equality over streams.
-For instance, propositional η-equality is lost when going to the negative
-presentation. It is nonetheless logically consistent to recover it through an
-axiom.
-
-.. coqtop:: all
-
- Axiom Stream_eta : forall s: Stream, s = Seq (hd s) (tl s).
-
-More generally, as in the case of positive coinductive types, it is consistent
-to further identify extensional equality of coinductive types with propositional
-equality:
-
-.. coqtop:: all
-
- Axiom Stream_ext : forall (s1 s2: Stream), EqSt s1 s2 -> s1 = s2.
-
-As of Coq 8.9, it is now advised to use negative co-inductive types rather than
-their positive counterparts.
-
-.. seealso::
- :ref:`primitive_projections` for more information about negative
- records and primitive projections.
-
-
-Definition of recursive functions
----------------------------------
-
-Definition of functions by recursion over inductive objects
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This section describes the primitive form of definition by recursion over
-inductive objects. See the :cmd:`Function` command for more advanced
-constructions.
-
-.. _Fixpoint:
-
-.. cmd:: Fixpoint @fix_definition {* with @fix_definition }
-
- .. insertprodn fix_definition fix_definition
-
- .. prodn::
- fix_definition ::= @ident_decl {* @binder } {? @fixannot } {? : @type } {? := @term } {? @decl_notations }
-
- This command 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
- corresponding to these :n:`@binder`\s has type :n:`@type`, and is
- equivalent to the expression :n:`@term`. The type of :n:`@ident` is
- consequently :n:`forall {* @binder }, @type` and its value is equivalent
- to :n:`fun {* @binder } => @term`.
-
- 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.
- The point of the :n:`{struct @ident}` annotation (see :n:`@fixannot`) is to
- let the user tell the system which argument decreases along the recursive calls.
-
- The :n:`{struct @ident}` annotation may be left implicit, in which case the
- system successively tries arguments from left to right until it finds one
- 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`.
-
- The :n:`with` clause allows simultaneously defining several mutual fixpoints.
- It is especially useful when defining functions over mutually defined
- inductive types. Example: :ref:`Mutual Fixpoints<example_mutual_fixpoints>`.
-
- 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`.
-
- .. note::
-
- + Some fixpoints may have several arguments that fit as decreasing
- arguments, and this choice influences the reduction of the fixpoint.
- Hence an explicit annotation must be used if the leftmost decreasing
- argument is not the desired one. Writing explicit annotations can also
- speed up type checking of large mutual fixpoints.
-
- + In order to keep the strong normalization property, the fixed point
- reduction will only be performed when the argument in position of the
- decreasing argument (which type should be in an inductive definition)
- starts with a constructor.
-
-
- .. example::
-
- One can define the addition function as :
-
- .. coqtop:: all
-
- Fixpoint add (n m:nat) {struct n} : nat :=
- match n with
- | O => m
- | S p => S (add p m)
- end.
-
- The match operator matches a value (here :g:`n`) with the various
- constructors of its (inductive) type. The remaining arguments give the
- respective values to be returned, as functions of the parameters of the
- corresponding constructor. Thus here when :g:`n` equals :g:`O` we return
- :g:`m`, and when :g:`n` equals :g:`(S p)` we return :g:`(S (add p m))`.
-
- The match operator is formally described in
- Section :ref:`match-construction`.
- The system recognizes that in the inductive call :g:`(add p m)` the first
- argument actually decreases because it is a *pattern variable* coming
- from :g:`match n with`.
-
- .. example::
-
- The following definition is not correct and generates an error message:
-
- .. coqtop:: all
-
- Fail Fixpoint wrongplus (n m:nat) {struct n} : nat :=
- match m with
- | O => n
- | S p => S (wrongplus n p)
- end.
-
- because the declared decreasing argument :g:`n` does not actually
- decrease in the recursive call. The function computing the addition over
- the second argument should rather be written:
-
- .. coqtop:: all
-
- Fixpoint plus (n m:nat) {struct m} : nat :=
- match m with
- | O => n
- | S p => S (plus n p)
- end.
-
- .. example::
-
- The recursive call may not only be on direct subterms of the recursive
- variable :g:`n` but also on a deeper subterm and we can directly write
- the function :g:`mod2` which gives the remainder modulo 2 of a natural
- number.
-
- .. coqtop:: all
-
- Fixpoint mod2 (n:nat) : nat :=
- match n with
- | O => O
- | S p => match p with
- | O => S O
- | S q => mod2 q
- end
- end.
-
-.. _example_mutual_fixpoints:
-
- .. example:: Mutual fixpoints
-
- The size of trees and forests can be defined the following way:
-
- .. coqtop:: all
-
- Fixpoint tree_size (t:tree) : nat :=
- match t with
- | node a f => S (forest_size f)
- end
- with forest_size (f:forest) : nat :=
- match f with
- | leaf b => 1
- | cons t f' => (tree_size t + forest_size f')
- end.
-
-.. _cofixpoint:
-
-Definitions of recursive objects in co-inductive types
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. cmd:: CoFixpoint @cofix_definition {* with @cofix_definition }
-
- .. insertprodn cofix_definition cofix_definition
-
- .. prodn::
- cofix_definition ::= @ident_decl {* @binder } {? : @type } {? := @term } {? @decl_notations }
-
- This command introduces a method for constructing an infinite object of a
- coinductive type. For example, the stream containing all natural numbers can
- be introduced applying the following method to the number :g:`O` (see
- Section :ref:`coinductive-types` for the definition of :g:`Stream`, :g:`hd`
- and :g:`tl`):
-
- .. coqtop:: all
-
- CoFixpoint from (n:nat) : Stream := Seq n (from (S n)).
-
- Unlike recursive definitions, there is no decreasing argument in a
- co-recursive definition. To be admissible, a method of construction must
- provide at least one extra constructor of the infinite object for each
- iteration. A syntactical guard condition is imposed on co-recursive
- definitions in order to ensure this: each recursive call in the
- definition must be protected by at least one constructor, and only by
- constructors. That is the case in the former definition, where the single
- recursive call of :g:`from` is guarded by an application of :g:`Seq`.
- On the contrary, the following recursive function does not satisfy the
- guard condition:
-
- .. coqtop:: all
-
- Fail CoFixpoint filter (p:nat -> bool) (s:Stream) : Stream :=
- if p (hd s) then Seq (hd s) (filter p (tl s)) else filter p (tl s).
-
- The elimination of co-recursive definition is done lazily, i.e. the
- definition is expanded only when it occurs at the head of an application
- which is the argument of a case analysis expression. In any other
- context, it is considered as a canonical expression which is completely
- evaluated. We can test this using the command :cmd:`Eval`, which computes
- the normal forms of a term:
-
- .. coqtop:: all
-
- Eval compute in (from 0).
- Eval compute in (hd (from 0)).
- Eval compute in (tl (from 0)).
-
- As in the :cmd:`Fixpoint` command, the :n:`with` clause allows simultaneously
- defining several mutual cofixpoints.
-
- 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`.
-
-.. _Computations:
-
-Computations
-------------
-
-.. insertprodn reduce pattern_occ
-
-.. prodn::
- reduce ::= Eval @red_expr in
- 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 ::= {? - } [ {+ @smart_qualid } ]
- strategy_flag ::= {+ @red_flags }
- | @delta_flag
- red_flags ::= beta
- | iota
- | match
- | fix
- | cofix
- | zeta
- | delta {? @delta_flag }
- ref_or_pattern_occ ::= @smart_qualid {? at @occs_nums }
- | @one_term {? at @occs_nums }
- occs_nums ::= {+ {| @num | @ident } }
- | - {| @num | @ident } {* @int_or_var }
- int_or_var ::= @int
- | @ident
- unfold_occ ::= @smart_qualid {? at @occs_nums }
- pattern_occ ::= @one_term {? at @occs_nums }
-
-See :ref:`Conversion-rules`.
-
-.. todo:: Add text here
-
-.. _Assertions:
-
-Assertions and proofs
----------------------
-
-An assertion states a proposition (or a type) of which the proof (or an
-inhabitant of the type) is interactively built using tactics. The interactive
-proof mode is described in Chapter :ref:`proofhandling` and the tactics in
-Chapter :ref:`Tactics`. The basic assertion command is:
-
-.. cmd:: @thm_token @ident_decl {* @binder } : @type {* with @ident_decl {* @binder } : @type }
- :name: Theorem; Lemma; Fact; Remark; Corollary; Proposition; Property
-
- .. insertprodn thm_token thm_token
-
- .. prodn::
- thm_token ::= Theorem
- | Lemma
- | Fact
- | Remark
- | Corollary
- | Proposition
- | Property
-
- After the statement is asserted, Coq needs a proof. Once a proof of
- :n:`@type` under the assumptions represented by :n:`@binder`\s is given and
- 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.
-
- 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
- :cmd:`Fixpoint` or :cmd:`CoFixpoint` but using tactics to build the proof of
- the statements (or the body of the specification, depending on the point of
- view). The inductive or co-inductive types on which the induction or
- coinduction has to be done is assumed to be non ambiguous and is guessed by
- the system.
-
- Like in a :cmd:`Fixpoint` or :cmd:`CoFixpoint` definition, the induction hypotheses
- have to be used on *structurally smaller* arguments (for a :cmd:`Fixpoint`) or
- be *guarded by a constructor* (for a :cmd:`CoFixpoint`). The verification that
- recursive proof arguments are correct is done only at the time of registering
- the lemma in the environment. To know if the use of induction hypotheses is
- correct at some time of the interactive development of a proof, use the
- command :cmd:`Guarded`.
-
- .. exn:: The term @term has type @type which should be Set, Prop or Type.
- :undocumented:
-
- .. exn:: @ident already exists.
- :name: @ident already exists. (Theorem)
-
- The name you provided is already defined. You have then to choose
- another name.
-
- .. exn:: Nested proofs are not allowed unless you turn the Nested Proofs Allowed flag on.
-
- You are asserting a new statement while already being in proof editing mode.
- This feature, called nested proofs, is disabled by default.
- To activate it, turn the :flag:`Nested Proofs Allowed` flag on.
-
-Proofs start with the keyword :cmd:`Proof`. Then Coq enters the proof editing mode
-until the proof is completed. In proof editing mode, the user primarily enters
-tactics, which are described in chapter :ref:`Tactics`. The user may also enter
-commands to manage the proof editing mode. They are described in Chapter
-:ref:`proofhandling`.
-
-When the proof is complete, use the :cmd:`Qed` command so the kernel verifies
-the proof and adds it to the environment.
-
-.. note::
-
- #. Several statements can be simultaneously asserted provided the
- :flag:`Nested Proofs Allowed` flag was turned on.
-
- #. Not only other assertions but any vernacular command can be given
- while in the process of proving a given assertion. In this case, the
- command is understood as if it would have been given before the
- statements still to be proved. Nonetheless, this practice is discouraged
- and may stop working in future versions.
-
- #. Proofs ended by :cmd:`Qed` are declared opaque. Their content cannot be
- unfolded (see :ref:`performingcomputations`), thus
- realizing some form of *proof-irrelevance*. To be able to unfold a
- proof, the proof should be ended by :cmd:`Defined`.
-
- #. :cmd:`Proof` is recommended but can currently be omitted. On the opposite
- side, :cmd:`Qed` (or :cmd:`Defined`) is mandatory to validate a proof.
-
- #. One can also use :cmd:`Admitted` in place of :cmd:`Qed` to turn the
- current asserted statement into an axiom and exit the proof editing mode.
-
-.. [1]
- Except if the inductive type is empty in which case there is no
- equation that can be used to infer the return type.
diff --git a/doc/sphinx/language/module-system.rst b/doc/sphinx/language/module-system.rst
deleted file mode 100644
index 15fee91245..0000000000
--- a/doc/sphinx/language/module-system.rst
+++ /dev/null
@@ -1,456 +0,0 @@
-.. _themodulesystem:
-
-The Module System
-=================
-
-The module system extends the Calculus of Inductive Constructions
-providing a convenient way to structure large developments as well as
-a means of massive abstraction.
-
-
-Modules and module types
-----------------------------
-
-**Access path.** An access path is denoted by :math:`p` and can be
-either a module variable :math:`X` or, if :math:`p′` is an access path
-and :math:`id` an identifier, then :math:`p′.id` is an access path.
-
-
-**Structure element.** A structure element is denoted by :math:`e` and
-is either a definition of a constant, an assumption, a definition of
-an inductive, a definition of a module, an alias of a module or a module
-type abbreviation.
-
-
-**Structure expression.** A structure expression is denoted by :math:`S` and can be:
-
-+ an access path :math:`p`
-+ a plain structure :math:`\Struct~e ; … ; e~\End`
-+ a functor :math:`\Functor(X:S)~S′`, where :math:`X` is a module variable, :math:`S` and :math:`S′` are
- structure expressions
-+ an application :math:`S~p`, where :math:`S` is a structure expression and :math:`p` an
- access path
-+ a refined structure :math:`S~\with~p := p`′ or :math:`S~\with~p := t:T` where :math:`S` is a
- structure expression, :math:`p` and :math:`p′` are access paths, :math:`t` is a term and :math:`T` is
- the type of :math:`t`.
-
-**Module definition.** A module definition is written :math:`\Mod{X}{S}{S'}`
-and consists of a module variable :math:`X`, a module type
-:math:`S` which can be any structure expression and optionally a
-module implementation :math:`S′` which can be any structure expression
-except a refined structure.
-
-
-**Module alias.** A module alias is written :math:`\ModA{X}{p}`
-and consists of a module variable :math:`X` and a module path
-:math:`p`.
-
-**Module type abbreviation.**
-A module type abbreviation is written :math:`\ModType{Y}{S}`,
-where :math:`Y` is an identifier and :math:`S` is any structure
-expression .
-
-
-Typing Modules
-------------------
-
-In order to introduce the typing system we first slightly extend the syntactic
-class of terms and environments given in section :ref:`The-terms`. The
-environments, apart from definitions of constants and inductive types now also
-hold any other structure elements. Terms, apart from variables, constants and
-complex terms, include also access paths.
-
-We also need additional typing judgments:
-
-
-+ :math:`\WFT{E}{S}`, denoting that a structure :math:`S` is well-formed,
-+ :math:`\WTM{E}{p}{S}`, denoting that the module pointed by :math:`p` has type :math:`S` in
- environment :math:`E`.
-+ :math:`\WEV{E}{S}{\ovl{S}}`, denoting that a structure :math:`S` is evaluated to a
- structure :math:`S` in weak head normal form.
-+ :math:`\WS{E}{S_1}{S_2}` , denoting that a structure :math:`S_1` is a subtype of a
- structure :math:`S_2`.
-+ :math:`\WS{E}{e_1}{e_2}` , denoting that a structure element e_1 is more
- precise than a structure element e_2.
-
-The rules for forming structures are the following:
-
-.. inference:: WF-STR
-
- \WF{E;E′}{}
- ------------------------
- \WFT{E}{ \Struct~E′ ~\End}
-
-.. inference:: WF-FUN
-
- \WFT{E; \ModS{X}{S}}{ \ovl{S′} }
- --------------------------
- \WFT{E}{ \Functor(X:S)~S′}
-
-
-Evaluation of structures to weak head normal form:
-
-.. inference:: WEVAL-APP
-
- \begin{array}{c}
- \WEV{E}{S}{\Functor(X:S_1 )~S_2}~~~~~\WEV{E}{S_1}{\ovl{S_1}} \\
- \WTM{E}{p}{S_3}~~~~~ \WS{E}{S_3}{\ovl{S_1}}
- \end{array}
- --------------------------
- \WEV{E}{S~p}{S_2 \{p/X,t_1 /p_1 .c_1 ,…,t_n /p_n.c_n \}}
-
-
-In the last rule, :math:`\{t_1 /p_1 .c_1 ,…,t_n /p_n .c_n \}` is the resulting
-substitution from the inlining mechanism. We substitute in :math:`S` the
-inlined fields :math:`p_i .c_i` from :math:`\ModS{X}{S_1 }` by the corresponding delta-
-reduced term :math:`t_i` in :math:`p`.
-
-.. inference:: WEVAL-WITH-MOD
-
- \begin{array}{c}
- E[] ⊢ S \lra \Struct~e_1 ;…;e_i ; \ModS{X}{S_1 };e_{i+2} ;… ;e_n ~\End \\
- E;e_1 ;…;e_i [] ⊢ S_1 \lra \ovl{S_1} ~~~~~~
- E[] ⊢ p : S_2 \\
- E;e_1 ;…;e_i [] ⊢ S_2 <: \ovl{S_1}
- \end{array}
- ----------------------------------
- \begin{array}{c}
- \WEV{E}{S~\with~x := p}{}\\
- \Struct~e_1 ;…;e_i ; \ModA{X}{p};e_{i+2} \{p/X\} ;…;e_n \{p/X\} ~\End
- \end{array}
-
-.. inference:: WEVAL-WITH-MOD-REC
-
- \begin{array}{c}
- \WEV{E}{S}{\Struct~e_1 ;…;e_i ; \ModS{X_1}{S_1 };e_{i+2} ;… ;e_n ~\End} \\
- \WEV{E;e_1 ;…;e_i }{S_1~\with~p := p_1}{\ovl{S_2}}
- \end{array}
- --------------------------
- \begin{array}{c}
- \WEV{E}{S~\with~X_1.p := p_1}{} \\
- \Struct~e_1 ;…;e_i ; \ModS{X}{\ovl{S_2}};e_{i+2} \{p_1 /X_1.p\} ;…;e_n \{p_1 /X_1.p\} ~\End
- \end{array}
-
-.. inference:: WEVAL-WITH-DEF
-
- \begin{array}{c}
- \WEV{E}{S}{\Struct~e_1 ;…;e_i ;\Assum{}{c}{T_1};e_{i+2} ;… ;e_n ~\End} \\
- \WS{E;e_1 ;…;e_i }{Def()(c:=t:T)}{\Assum{}{c}{T_1}}
- \end{array}
- --------------------------
- \begin{array}{c}
- \WEV{E}{S~\with~c := t:T}{} \\
- \Struct~e_1 ;…;e_i ;Def()(c:=t:T);e_{i+2} ;… ;e_n ~\End
- \end{array}
-
-.. inference:: WEVAL-WITH-DEF-REC
-
- \begin{array}{c}
- \WEV{E}{S}{\Struct~e_1 ;…;e_i ; \ModS{X_1 }{S_1 };e_{i+2} ;… ;e_n ~\End} \\
- \WEV{E;e_1 ;…;e_i }{S_1~\with~p := p_1}{\ovl{S_2}}
- \end{array}
- --------------------------
- \begin{array}{c}
- \WEV{E}{S~\with~X_1.p := t:T}{} \\
- \Struct~e_1 ;…;e_i ; \ModS{X}{\ovl{S_2} };e_{i+2} ;… ;e_n ~\End
- \end{array}
-
-.. inference:: WEVAL-PATH-MOD1
-
- \begin{array}{c}
- \WEV{E}{p}{\Struct~e_1 ;…;e_i ; \Mod{X}{S}{S_1};e_{i+2} ;… ;e_n End} \\
- \WEV{E;e_1 ;…;e_i }{S}{\ovl{S}}
- \end{array}
- --------------------------
- E[] ⊢ p.X \lra \ovl{S}
-
-.. inference:: WEVAL-PATH-MOD2
-
- \WF{E}{}
- \Mod{X}{S}{S_1}∈ E
- \WEV{E}{S}{\ovl{S}}
- --------------------------
- \WEV{E}{X}{\ovl{S}}
-
-.. inference:: WEVAL-PATH-ALIAS1
-
- \begin{array}{c}
- \WEV{E}{p}{~\Struct~e_1 ;…;e_i ; \ModA{X}{p_1};e_{i+2} ;… ;e_n End} \\
- \WEV{E;e_1 ;…;e_i }{p_1}{\ovl{S}}
- \end{array}
- --------------------------
- \WEV{E}{p.X}{\ovl{S}}
-
-.. inference:: WEVAL-PATH-ALIAS2
-
- \WF{E}{}
- \ModA{X}{p_1 }∈ E
- \WEV{E}{p_1}{\ovl{S}}
- --------------------------
- \WEV{E}{X}{\ovl{S}}
-
-.. inference:: WEVAL-PATH-TYPE1
-
- \begin{array}{c}
- \WEV{E}{p}{~\Struct~e_1 ;…;e_i ; \ModType{Y}{S};e_{i+2} ;… ;e_n End} \\
- \WEV{E;e_1 ;…;e_i }{S}{\ovl{S}}
- \end{array}
- --------------------------
- \WEV{E}{p.Y}{\ovl{S}}
-
-.. inference:: WEVAL-PATH-TYPE2
-
- \WF{E}{}
- \ModType{Y}{S}∈ E
- \WEV{E}{S}{\ovl{S}}
- --------------------------
- \WEV{E}{Y}{\ovl{S}}
-
-
-Rules for typing module:
-
-.. inference:: MT-EVAL
-
- \WEV{E}{p}{\ovl{S}}
- --------------------------
- E[] ⊢ p : \ovl{S}
-
-.. inference:: MT-STR
-
- E[] ⊢ p : S
- --------------------------
- E[] ⊢ p : S/p
-
-
-The last rule, called strengthening is used to make all module fields
-manifestly equal to themselves. The notation :math:`S/p` has the following
-meaning:
-
-
-+ if :math:`S\lra~\Struct~e_1 ;…;e_n ~\End` then :math:`S/p=~\Struct~e_1 /p;…;e_n /p ~\End`
- where :math:`e/p` is defined as follows (note that opaque definitions are processed
- as assumptions):
-
- + :math:`\Def{}{c}{t}{T}/p = \Def{}{c}{t}{T}`
- + :math:`\Assum{}{c}{U}/p = \Def{}{c}{p.c}{U}`
- + :math:`\ModS{X}{S}/p = \ModA{X}{p.X}`
- + :math:`\ModA{X}{p′}/p = \ModA{X}{p′}`
- + :math:`\Ind{}{Γ_P}{Γ_C}{Γ_I}/p = \Indp{}{Γ_P}{Γ_C}{Γ_I}{p}`
- + :math:`\Indpstr{}{Γ_P}{Γ_C}{Γ_I}{p'}{p} = \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'}`
-
-+ if :math:`S \lra \Functor(X:S′)~S″` then :math:`S/p=S`
-
-
-The notation :math:`\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}`
-denotes an inductive definition that is definitionally equal to the
-inductive definition in the module denoted by the path :math:`p`. All rules
-which have :math:`\Ind{}{Γ_P}{Γ_C}{Γ_I}` as premises are also valid for
-:math:`\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}`. We give the formation rule for
-:math:`\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}`
-below as well as the equality rules on inductive types and
-constructors.
-
-The module subtyping rules:
-
-.. inference:: MSUB-STR
-
- \begin{array}{c}
- \WS{E;e_1 ;…;e_n }{e_{σ(i)}}{e'_i ~\for~ i=1..m} \\
- σ : \{1… m\} → \{1… n\} ~\injective
- \end{array}
- --------------------------
- \WS{E}{\Struct~e_1 ;…;e_n ~\End}{~\Struct~e'_1 ;…;e'_m ~\End}
-
-.. inference:: MSUB-FUN
-
- \WS{E}{\ovl{S_1'}}{\ovl{S_1}}
- \WS{E; \ModS{X}{S_1'}}{\ovl{S_2}}{\ovl{S_2'}}
- --------------------------
- E[] ⊢ \Functor(X:S_1 ) S_2 <: \Functor(X:S_1') S_2'
-
-
-Structure element subtyping rules:
-
-.. inference:: ASSUM-ASSUM
-
- E[] ⊢ T_1 ≤_{βδιζη} T_2
- --------------------------
- \WS{E}{\Assum{}{c}{T_1 }}{\Assum{}{c}{T_2 }}
-
-.. inference:: DEF-ASSUM
-
- E[] ⊢ T_1 ≤_{βδιζη} T_2
- --------------------------
- \WS{E}{\Def{}{c}{t}{T_1 }}{\Assum{}{c}{T_2 }}
-
-.. inference:: ASSUM-DEF
-
- E[] ⊢ T_1 ≤_{βδιζη} T_2
- E[] ⊢ c =_{βδιζη} t_2
- --------------------------
- \WS{E}{\Assum{}{c}{T_1 }}{\Def{}{c}{t_2 }{T_2 }}
-
-.. inference:: DEF-DEF
-
- E[] ⊢ T_1 ≤_{βδιζη} T_2
- E[] ⊢ t_1 =_{βδιζη} t_2
- --------------------------
- \WS{E}{\Def{}{c}{t_1 }{T_1 }}{\Def{}{c}{t_2 }{T_2 }}
-
-.. inference:: IND-IND
-
- E[] ⊢ Γ_P =_{βδιζη} Γ_P'
- E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C'
- E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I'
- --------------------------
- \WS{E}{\ind{Γ_P}{Γ_C}{Γ_I}}{\ind{Γ_P'}{Γ_C'}{Γ_I'}}
-
-.. inference:: INDP-IND
-
- E[] ⊢ Γ_P =_{βδιζη} Γ_P'
- E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C'
- E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I'
- --------------------------
- \WS{E}{\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}}{\ind{Γ_P'}{Γ_C'}{Γ_I'}}
-
-.. inference:: INDP-INDP
-
- \begin{array}{c}
- E[] ⊢ Γ_P =_{βδιζη} Γ_P'
- E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C' \\
- E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I'
- E[] ⊢ p =_{βδιζη} p'
- \end{array}
- --------------------------
- \WS{E}{\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}}{\Indp{}{Γ_P'}{Γ_C'}{Γ_I'}{p'}}
-
-.. inference:: MOD-MOD
-
- \WS{E}{S_1}{S_2}
- --------------------------
- \WS{E}{\ModS{X}{S_1 }}{\ModS{X}{S_2 }}
-
-.. inference:: ALIAS-MOD
-
- E[] ⊢ p : S_1
- \WS{E}{S_1}{S_2}
- --------------------------
- \WS{E}{\ModA{X}{p}}{\ModS{X}{S_2 }}
-
-.. inference:: MOD-ALIAS
-
- E[] ⊢ p : S_2
- \WS{E}{S_1}{S_2}
- E[] ⊢ X =_{βδιζη} p
- --------------------------
- \WS{E}{\ModS{X}{S_1 }}{\ModA{X}{p}}
-
-.. inference:: ALIAS-ALIAS
-
- E[] ⊢ p_1 =_{βδιζη} p_2
- --------------------------
- \WS{E}{\ModA{X}{p_1 }}{\ModA{X}{p_2 }}
-
-.. inference:: MODTYPE-MODTYPE
-
- \WS{E}{S_1}{S_2}
- \WS{E}{S_2}{S_1}
- --------------------------
- \WS{E}{\ModType{Y}{S_1 }}{\ModType{Y}{S_2 }}
-
-
-New environment formation rules
-
-
-.. inference:: WF-MOD1
-
- \WF{E}{}
- \WFT{E}{S}
- --------------------------
- WF(E; \ModS{X}{S})[]
-
-.. inference:: WF-MOD2
-
- \WS{E}{S_2}{S_1}
- \WF{E}{}
- \WFT{E}{S_1}
- \WFT{E}{S_2}
- --------------------------
- \WF{E; \Mod{X}{S_1}{S_2}}{}
-
-.. inference:: WF-ALIAS
-
- \WF{E}{}
- E[] ⊢ p : S
- --------------------------
- \WF{E, \ModA{X}{p}}{}
-
-.. inference:: WF-MODTYPE
-
- \WF{E}{}
- \WFT{E}{S}
- --------------------------
- \WF{E, \ModType{Y}{S}}{}
-
-.. inference:: WF-IND
-
- \begin{array}{c}
- \WF{E;\ind{Γ_P}{Γ_C}{Γ_I}}{} \\
- E[] ⊢ p:~\Struct~e_1 ;…;e_n ;\ind{Γ_P'}{Γ_C'}{Γ_I'};… ~\End : \\
- E[] ⊢ \ind{Γ_P'}{Γ_C'}{Γ_I'} <: \ind{Γ_P}{Γ_C}{Γ_I}
- \end{array}
- --------------------------
- \WF{E; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p} }{}
-
-
-Component access rules
-
-
-.. inference:: ACC-TYPE1
-
- E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Assum{}{c}{T};… ~\End
- --------------------------
- E[Γ] ⊢ p.c : T
-
-.. inference:: ACC-TYPE2
-
- E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Def{}{c}{t}{T};… ~\End
- --------------------------
- E[Γ] ⊢ p.c : T
-
-Notice that the following rule extends the delta rule defined in section :ref:`Conversion-rules`
-
-.. inference:: ACC-DELTA
-
- E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Def{}{c}{t}{U};… ~\End
- --------------------------
- E[Γ] ⊢ p.c \triangleright_δ t
-
-In the rules below we assume
-:math:`Γ_P` is :math:`[p_1 :P_1 ;…;p_r :P_r ]`,
-:math:`Γ_I` is :math:`[I_1 :A_1 ;…;I_k :A_k ]`,
-and :math:`Γ_C` is :math:`[c_1 :C_1 ;…;c_n :C_n ]`.
-
-.. inference:: ACC-IND1
-
- E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\ind{Γ_P}{Γ_C}{Γ_I};… ~\End
- --------------------------
- E[Γ] ⊢ p.I_j : (p_1 :P_1 )…(p_r :P_r )A_j
-
-.. inference:: ACC-IND2
-
- E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\ind{Γ_P}{Γ_C}{Γ_I};… ~\End
- --------------------------
- E[Γ] ⊢ p.c_m : (p_1 :P_1 )…(p_r :P_r )C_m I_j (I_j~p_1 …p_r )_{j=1… k}
-
-.. inference:: ACC-INDP1
-
- E[] ⊢ p :~\Struct~e_1 ;…;e_i ; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'} ;… ~\End
- --------------------------
- E[] ⊢ p.I_i \triangleright_δ p'.I_i
-
-.. inference:: ACC-INDP2
-
- E[] ⊢ p :~\Struct~e_1 ;…;e_i ; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'} ;… ~\End
- --------------------------
- E[] ⊢ p.c_i \triangleright_δ p'.c_i
diff --git a/doc/sphinx/proof-engine/ltac.rst b/doc/sphinx/proof-engine/ltac.rst
index 90173d65bf..a21f7e545c 100644
--- a/doc/sphinx/proof-engine/ltac.rst
+++ b/doc/sphinx/proof-engine/ltac.rst
@@ -28,9 +28,8 @@ especially about its foundations, please refer to :cite:`Del00`.
Syntax
------
-The syntax of the tactic language is given below. See Chapter
-:ref:`gallinaspecificationlanguage` for a description of the BNF metasyntax used
-in these grammar rules. Various already defined entries will be used in this
+The syntax of the tactic language is given below.
+Various already defined entries will be used in this
chapter: entries :token:`num`, :token:`int`, :token:`ident`
:token:`qualid`, :token:`term`, :token:`cpattern` and :token:`tactic`
represent respectively natural and integer numbers,
diff --git a/doc/sphinx/proof-engine/tactics.rst b/doc/sphinx/proof-engine/tactics.rst
index ad799fbbcd..3fec940fad 100644
--- a/doc/sphinx/proof-engine/tactics.rst
+++ b/doc/sphinx/proof-engine/tactics.rst
@@ -2977,6 +2977,41 @@ simply :g:`t=u` dropping the implicit type of :g:`t` and :g:`u`.
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 ::= {? - } [ {+ @smart_qualid } ]
+ strategy_flag ::= {+ @red_flags }
+ | @delta_flag
+ red_flags ::= beta
+ | iota
+ | match
+ | fix
+ | cofix
+ | zeta
+ | delta {? @delta_flag }
+ ref_or_pattern_occ ::= @smart_qualid {? at @occs_nums }
+ | @one_term {? at @occs_nums }
+ occs_nums ::= {+ {| @num | @ident } }
+ | - {| @num | @ident } {* @int_or_var }
+ int_or_var ::= @int
+ | @ident
+ unfold_occ ::= @smart_qualid {? at @occs_nums }
+ pattern_occ ::= @one_term {? at @occs_nums }
+
This set of tactics implements different specialized usages of the
tactic :tacn:`change`.
diff --git a/doc/sphinx/proof-engine/vernacular-commands.rst b/doc/sphinx/proof-engine/vernacular-commands.rst
index 7191444bac..031abbe15c 100644
--- a/doc/sphinx/proof-engine/vernacular-commands.rst
+++ b/doc/sphinx/proof-engine/vernacular-commands.rst
@@ -747,6 +747,36 @@ Controlling display
after each tactic. The information is used by the Prooftree tool in Proof
General. (https://askra.de/software/prooftree)
+.. extracted from Gallina extensions chapter
+
+.. _printing_constructions_full:
+
+Printing constructions in full
+------------------------------
+
+.. flag:: Printing All
+
+ Coercions, implicit arguments, the type of pattern matching, but also
+ notations (see :ref:`syntax-extensions-and-notation-scopes`) can obfuscate the behavior of some
+ tactics (typically the tactics applying to occurrences of subterms are
+ sensitive to the implicit arguments). Turning this flag on
+ deactivates all high-level printing features such as coercions,
+ implicit arguments, returned type of pattern matching, notations and
+ various syntactic sugar for pattern matching or record projections.
+ Otherwise said, :flag:`Printing All` includes the effects of the flags
+ :flag:`Printing Implicit`, :flag:`Printing Coercions`, :flag:`Printing Synth`,
+ :flag:`Printing Projections`, and :flag:`Printing Notations`. To reactivate
+ the high-level printing features, use the command ``Unset Printing All``.
+
+ .. note:: In some cases, setting :flag:`Printing All` may display terms
+ that are so big they become very hard to read. One technique to work around
+ this is use :cmd:`Undelimit Scope` and/or :cmd:`Close Scope` to turn off the
+ printing of notations bound to particular scope(s). This can be useful when
+ notations in a given scope are getting in the way of understanding
+ a goal, but turning off all notations with :flag:`Printing All` would make
+ the goal unreadable.
+
+ .. see a contrived example here: https://github.com/coq/coq/pull/11718#discussion_r415481854
.. _vernac-controlling-the-reduction-strategies:
diff --git a/doc/sphinx/user-extensions/syntax-extensions.rst b/doc/sphinx/user-extensions/syntax-extensions.rst
index 60cd4c4ad8..955f2055e4 100644
--- a/doc/sphinx/user-extensions/syntax-extensions.rst
+++ b/doc/sphinx/user-extensions/syntax-extensions.rst
@@ -1429,10 +1429,31 @@ Abbreviations
Notation F p P := (force2 p (fun p => P)).
Check exists x y, F (x,y) (x >= 1 /\ y >= 2).
+.. extracted from Gallina chapter
+
+Numerals and strings
+--------------------
+
+.. insertprodn primitive_notations primitive_notations
+
+.. prodn::
+ primitive_notations ::= @numeral
+ | @string
+
+Numerals and strings have no predefined semantics in the calculus. They are
+merely notations that can be bound to objects through the notation mechanism.
+Initially, numerals are bound to Peano’s representation of natural
+numbers (see :ref:`datatypes`).
+
+.. note::
+
+ Negative integers are not at the same level as :n:`@num`, for this
+ would make precedence unnatural.
+
.. _numeral-notations:
Numeral notations
------------------
+~~~~~~~~~~~~~~~~~
.. cmd:: Numeral Notation @qualid @qualid__parse @qualid__print : @scope_name {? @numeral_modifier }
:name: Numeral Notation
@@ -1557,7 +1578,7 @@ Numeral notations
opaque constants.
String notations
------------------
+~~~~~~~~~~~~~~~~
.. cmd:: String Notation @qualid @qualid__parse @qualid__print : @scope_name
:name: String Notation