aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/sphinx/language/cic.rst584
-rw-r--r--doc/sphinx/language/core/conversion.rst212
-rw-r--r--doc/sphinx/language/core/inductive.rst1724
-rw-r--r--doc/sphinx/language/core/variants.rst196
-rw-r--r--doc/sphinx/language/gallina-specification-language.rst1452
5 files changed, 2716 insertions, 1452 deletions
diff --git a/doc/sphinx/language/cic.rst b/doc/sphinx/language/cic.rst
new file mode 100644
index 0000000000..5f74958712
--- /dev/null
+++ b/doc/sphinx/language/cic.rst
@@ -0,0 +1,584 @@
+Typing rules
+====================================
+
+The underlying formal language of |Coq| is a *Calculus of Inductive
+Constructions* (|Cic|) whose inference rules are presented in this
+chapter. The history of this formalism as well as pointers to related
+work are provided in a separate chapter; see *Credits*.
+
+
+.. _The-terms:
+
+The terms
+-------------
+
+The expressions of the |Cic| are *terms* and all terms have a *type*.
+There are types for functions (or programs), there are atomic types
+(especially datatypes)... but also types for proofs and types for the
+types themselves. Especially, any object handled in the formalism must
+belong to a type. For instance, universal quantification is relative
+to a type and takes the form “*for all x of type* :math:`T`, :math:`P`”. The expression
+“: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`”.
+
+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
+cannot start by an abstraction or a constructor. More precisely the
+language of the *Calculus of Inductive Constructions* is built from
+the following rules.
+
+
+#. the sorts :math:`\SProp`, :math:`\Prop`, :math:`\Set`, :math:`\Type(i)` are terms.
+#. variables, hereafter ranged over by letters :math:`x`, :math:`y`, etc., are terms
+#. constants, hereafter ranged over by letters :math:`c`, :math:`d`, etc., are terms.
+#. if :math:`x` is a variable and :math:`T`, :math:`U` are terms then
+ :math:`∀ x:T,~U` (:g:`forall x:T, U` in |Coq| concrete syntax) is a term.
+ If :math:`x` occurs in :math:`U`, :math:`∀ x:T,~U` reads as
+ “for all :math:`x` of type :math:`T`, :math:`U`”.
+ As :math:`U` depends on :math:`x`, one says that :math:`∀ x:T,~U` is
+ a *dependent product*. If :math:`x` does not occur in :math:`U` then
+ :math:`∀ x:T,~U` reads as
+ “if :math:`T` then :math:`U`”. A *non dependent product* can be
+ written: :math:`T \rightarrow U`.
+#. if :math:`x` is a variable and :math:`T`, :math:`u` are terms then
+ :math:`λ x:T .~u` (:g:`fun x:T => u`
+ in |Coq| concrete syntax) is a term. This is a notation for the
+ λ-abstraction of λ-calculus :cite:`Bar81`. The term :math:`λ x:T .~u` is a function
+ which maps elements of :math:`T` to the expression :math:`u`.
+#. if :math:`t` and :math:`u` are terms then :math:`(t~u)` is a term
+ (:g:`t u` in |Coq| concrete
+ syntax). The term :math:`(t~u)` reads as “:math:`t` applied to :math:`u`”.
+#. if :math:`x` is a variable, and :math:`t`, :math:`T` and :math:`u` are
+ terms then :math:`\letin{x}{t:T}{u}` is
+ a term which denotes the term :math:`u` where the variable :math:`x` is locally bound
+ to :math:`t` of type :math:`T`. This stands for the common “let-in” construction of
+ functional programs such as ML or Scheme.
+
+
+
+.. _Free-variables:
+
+**Free variables.**
+The notion of free variables is defined as usual. In the expressions
+:math:`λx:T.~U` and :math:`∀ x:T,~U` the occurrences of :math:`x` in :math:`U` are bound.
+
+
+.. _Substitution:
+
+**Substitution.**
+The notion of substituting a term :math:`t` to free occurrences of a variable
+:math:`x` in a term :math:`u` is defined as usual. The resulting term is written
+:math:`\subst{u}{x}{t}`.
+
+
+.. _The-logical-vs-programming-readings:
+
+**The logical vs programming readings.**
+The constructions of the |Cic| can be used to express both logical and
+programming notions, accordingly to the Curry-Howard correspondence
+between proofs and programs, and between propositions and types
+:cite:`Cur58,How80,Bru72`.
+
+For instance, let us assume that :math:`\nat` is the type of natural numbers
+with zero element written :math:`0` and that :g:`True` is the always true
+proposition. Then :math:`→` is used both to denote :math:`\nat→\nat` which is the type
+of functions from :math:`\nat` to :math:`\nat`, to denote True→True which is an
+implicative proposition, to denote :math:`\nat →\Prop` which is the type of
+unary predicates over the natural numbers, etc.
+
+Let us assume that ``mult`` is a function of type :math:`\nat→\nat→\nat` and ``eqnat`` a
+predicate of type :math:`\nat→\nat→ \Prop`. The λ-abstraction can serve to build
+“ordinary” functions as in :math:`λ x:\nat.~(\kw{mult}~x~x)` (i.e.
+:g:`fun x:nat => mult x x`
+in |Coq| notation) but may build also predicates over the natural
+numbers. For instance :math:`λ x:\nat.~(\kw{eqnat}~x~0)`
+(i.e. :g:`fun x:nat => eqnat x 0`
+in |Coq| notation) will represent the predicate of one variable :math:`x` which
+asserts the equality of :math:`x` with :math:`0`. This predicate has type
+:math:`\nat → \Prop`
+and it can be applied to any expression of type :math:`\nat`, say :math:`t`, to give an
+object :math:`P~t` of type :math:`\Prop`, namely a proposition.
+
+Furthermore :g:`forall x:nat, P x` will represent the type of functions
+which associate to each natural number :math:`n` an object of type :math:`(P~n)` and
+consequently represent the type of proofs of the formula “:math:`∀ x.~P(x)`”.
+
+
+.. _Typing-rules:
+
+Typing rules
+----------------
+
+As objects of type theory, terms are subjected to *type discipline*.
+The well typing of a term depends on a global environment and a local
+context.
+
+
+.. _Local-context:
+
+**Local context.**
+A *local context* is an ordered list of *local declarations* of names
+which we call *variables*. The declaration of some variable :math:`x` is
+either a *local assumption*, written :math:`x:T` (:math:`T` is a type) or a *local
+definition*, written :math:`x:=t:T`. We use brackets to write local contexts.
+A typical example is :math:`[x:T;~y:=u:U;~z:V]`. Notice that the variables
+declared in a local context must be distinct. If :math:`Γ` is a local context
+that declares some :math:`x`, we
+write :math:`x ∈ Γ`. By writing :math:`(x:T) ∈ Γ` we mean that either :math:`x:T` is an
+assumption in :math:`Γ` or that there exists some :math:`t` such that :math:`x:=t:T` is a
+definition in :math:`Γ`. If :math:`Γ` defines some :math:`x:=t:T`, we also write :math:`(x:=t:T) ∈ Γ`.
+For the rest of the chapter, :math:`Γ::(y:T)` denotes the local context :math:`Γ`
+enriched with the local assumption :math:`y:T`. Similarly, :math:`Γ::(y:=t:T)` denotes
+the local context :math:`Γ` enriched with the local definition :math:`(y:=t:T)`. The
+notation :math:`[]` denotes the empty local context. By :math:`Γ_1 ; Γ_2` we mean
+concatenation of the local context :math:`Γ_1` and the local context :math:`Γ_2`.
+
+
+.. _Global-environment:
+
+**Global environment.**
+A *global environment* is an ordered list of *global declarations*.
+Global declarations are either *global assumptions* or *global
+definitions*, but also declarations of inductive objects. Inductive
+objects themselves declare both inductive or coinductive types and
+constructors (see Section :ref:`inductive-definitions`).
+
+A *global assumption* will be represented in the global environment as
+:math:`(c:T)` which assumes the name :math:`c` to be of some type :math:`T`. A *global
+definition* will be represented in the global environment as :math:`c:=t:T`
+which defines the name :math:`c` to have value :math:`t` and type :math:`T`. We shall call
+such names *constants*. For the rest of the chapter, the :math:`E;~c:T` denotes
+the global environment :math:`E` enriched with the global assumption :math:`c:T`.
+Similarly, :math:`E;~c:=t:T` denotes the global environment :math:`E` enriched with the
+global definition :math:`(c:=t:T)`.
+
+The rules for inductive definitions (see Section
+:ref:`inductive-definitions`) have to be considered as assumption
+rules to which the following definitions apply: if the name :math:`c`
+is declared in :math:`E`, we write :math:`c ∈ E` and if :math:`c:T` or
+:math:`c:=t:T` is declared in :math:`E`, we write :math:`(c : T) ∈ E`.
+
+
+.. _Typing-rules2:
+
+**Typing rules.**
+In the following, we define simultaneously two judgments. The first
+one :math:`\WTEG{t}{T}` means the term :math:`t` is well-typed and has type :math:`T` in the
+global environment :math:`E` and local context :math:`Γ`. The second judgment :math:`\WFE{Γ}`
+means that the global environment :math:`E` is well-formed and the local
+context :math:`Γ` is a valid local context in this global environment.
+
+A term :math:`t` is well typed in a global environment :math:`E` iff
+there exists a local context :math:`\Gamma` and a term :math:`T` such
+that the judgment :math:`\WTEG{t}{T}` can be derived from the
+following rules.
+
+.. inference:: W-Empty
+
+ ---------
+ \WF{[]}{}
+
+.. inference:: W-Local-Assum
+
+ \WTEG{T}{s}
+ s \in \Sort
+ x \not\in \Gamma % \cup E
+ -------------------------
+ \WFE{\Gamma::(x:T)}
+
+.. inference:: W-Local-Def
+
+ \WTEG{t}{T}
+ x \not\in \Gamma % \cup E
+ -------------------------
+ \WFE{\Gamma::(x:=t:T)}
+
+.. inference:: W-Global-Assum
+
+ \WTE{}{T}{s}
+ s \in \Sort
+ c \notin E
+ ------------
+ \WF{E;~c:T}{}
+
+.. inference:: W-Global-Def
+
+ \WTE{}{t}{T}
+ c \notin E
+ ---------------
+ \WF{E;~c:=t:T}{}
+
+.. inference:: Ax-SProp
+
+ \WFE{\Gamma}
+ ----------------------
+ \WTEG{\SProp}{\Type(1)}
+
+.. inference:: Ax-Prop
+
+ \WFE{\Gamma}
+ ----------------------
+ \WTEG{\Prop}{\Type(1)}
+
+.. inference:: Ax-Set
+
+ \WFE{\Gamma}
+ ---------------------
+ \WTEG{\Set}{\Type(1)}
+
+.. inference:: Ax-Type
+
+ \WFE{\Gamma}
+ ---------------------------
+ \WTEG{\Type(i)}{\Type(i+1)}
+
+.. inference:: Var
+
+ \WFE{\Gamma}
+ (x:T) \in \Gamma~~\mbox{or}~~(x:=t:T) \in \Gamma~\mbox{for some $t$}
+ --------------------------------------------------------------------
+ \WTEG{x}{T}
+
+.. inference:: Const
+
+ \WFE{\Gamma}
+ (c:T) \in E~~\mbox{or}~~(c:=t:T) \in E~\mbox{for some $t$}
+ ----------------------------------------------------------
+ \WTEG{c}{T}
+
+.. inference:: Prod-SProp
+
+ \WTEG{T}{s}
+ s \in {\Sort}
+ \WTE{\Gamma::(x:T)}{U}{\SProp}
+ -----------------------------
+ \WTEG{\forall~x:T,U}{\SProp}
+
+.. inference:: Prod-Prop
+
+ \WTEG{T}{s}
+ s \in \Sort
+ \WTE{\Gamma::(x:T)}{U}{\Prop}
+ -----------------------------
+ \WTEG{∀ x:T,~U}{\Prop}
+
+.. inference:: Prod-Set
+
+ \WTEG{T}{s}
+ s \in \{\SProp, \Prop, \Set\}
+ \WTE{\Gamma::(x:T)}{U}{\Set}
+ ----------------------------
+ \WTEG{∀ x:T,~U}{\Set}
+
+.. inference:: Prod-Type
+
+ \WTEG{T}{s}
+ s \in \{\SProp, \Type{i}\}
+ \WTE{\Gamma::(x:T)}{U}{\Type(i)}
+ --------------------------------
+ \WTEG{∀ x:T,~U}{\Type(i)}
+
+.. inference:: Lam
+
+ \WTEG{∀ x:T,~U}{s}
+ \WTE{\Gamma::(x:T)}{t}{U}
+ ------------------------------------
+ \WTEG{λ x:T\mto t}{∀ x:T,~U}
+
+.. inference:: App
+
+ \WTEG{t}{∀ x:U,~T}
+ \WTEG{u}{U}
+ ------------------------------
+ \WTEG{(t\ u)}{\subst{T}{x}{u}}
+
+.. inference:: Let
+
+ \WTEG{t}{T}
+ \WTE{\Gamma::(x:=t:T)}{u}{U}
+ -----------------------------------------
+ \WTEG{\letin{x}{t:T}{u}}{\subst{U}{x}{t}}
+
+
+
+.. note::
+
+ **Prod-Prop** and **Prod-Set** typing-rules make sense if we consider the
+ semantic difference between :math:`\Prop` and :math:`\Set`:
+
+ + All values of a type that has a sort :math:`\Set` are extractable.
+ + No values of a type that has a sort :math:`\Prop` are extractable.
+
+
+
+.. note::
+ We may have :math:`\letin{x}{t:T}{u}` well-typed without having
+ :math:`((λ x:T.~u)~t)` well-typed (where :math:`T` is a type of
+ :math:`t`). This is because the value :math:`t` associated to
+ :math:`x` may be used in a conversion rule
+ (see Section :ref:`Conversion-rules`).
+
+.. _subtyping-rules:
+
+Subtyping rules
+-------------------
+
+At the moment, we did not take into account one rule between universes
+which says that any term in a universe of index :math:`i` is also a term in
+the universe of index :math:`i+1` (this is the *cumulativity* rule of |Cic|).
+This property extends the equivalence relation of convertibility into
+a *subtyping* relation inductively defined by:
+
+
+#. if :math:`E[Γ] ⊢ t =_{βδιζη} u` then :math:`E[Γ] ⊢ t ≤_{βδιζη} u`,
+#. if :math:`i ≤ j` then :math:`E[Γ] ⊢ \Type(i) ≤_{βδιζη} \Type(j)`,
+#. for any :math:`i`, :math:`E[Γ] ⊢ \Set ≤_{βδιζη} \Type(i)`,
+#. :math:`E[Γ] ⊢ \Prop ≤_{βδιζη} \Set`, hence, by transitivity,
+ :math:`E[Γ] ⊢ \Prop ≤_{βδιζη} \Type(i)`, for any :math:`i`
+ (note: :math:`\SProp` is not related by cumulativity to any other term)
+#. if :math:`E[Γ] ⊢ T =_{βδιζη} U` and
+ :math:`E[Γ::(x:T)] ⊢ T' ≤_{βδιζη} U'` then
+ :math:`E[Γ] ⊢ ∀x:T,~T′ ≤_{βδιζη} ∀ x:U,~U′`.
+#. if :math:`\ind{p}{Γ_I}{Γ_C}` is a universe polymorphic and cumulative
+ (see Chapter :ref:`polymorphicuniverses`) inductive type (see below)
+ and
+ :math:`(t : ∀Γ_P ,∀Γ_{\mathit{Arr}(t)}, S)∈Γ_I`
+ and
+ :math:`(t' : ∀Γ_P' ,∀Γ_{\mathit{Arr}(t)}', S')∈Γ_I`
+ are two different instances of *the same* inductive type (differing only in
+ universe levels) with constructors
+
+ .. math::
+ [c_1 : ∀Γ_P ,∀ T_{1,1} … T_{1,n_1} ,~t~v_{1,1} … v_{1,m} ;~…;~
+ c_k : ∀Γ_P ,∀ T_{k,1} … T_{k,n_k} ,~t~v_{k,1} … v_{k,m} ]
+
+ and
+
+ .. math::
+ [c_1 : ∀Γ_P' ,∀ T_{1,1}' … T_{1,n_1}' ,~t'~v_{1,1}' … v_{1,m}' ;~…;~
+ c_k : ∀Γ_P' ,∀ T_{k,1}' … T_{k,n_k}' ,~t'~v_{k,1}' … v_{k,m}' ]
+
+ respectively then
+
+ .. math::
+ E[Γ] ⊢ t~w_1 … w_m ≤_{βδιζη} t'~w_1' … w_m'
+
+ (notice that :math:`t` and :math:`t'` are both
+ fully applied, i.e., they have a sort as a type) if
+
+ .. math::
+ E[Γ] ⊢ w_i =_{βδιζη} w_i'
+
+ for :math:`1 ≤ i ≤ m` and we have
+
+
+ .. math::
+ E[Γ] ⊢ T_{i,j} ≤_{βδιζη} T_{i,j}'
+
+ and
+
+ .. math::
+ E[Γ] ⊢ A_i ≤_{βδιζη} A_i'
+
+ where :math:`Γ_{\mathit{Arr}(t)} = [a_1 : A_1 ;~ … ;~a_l : A_l ]` and
+ :math:`Γ_{\mathit{Arr}(t)}' = [a_1 : A_1';~ … ;~a_l : A_l']`.
+
+
+The conversion rule up to subtyping is now exactly:
+
+.. inference:: Conv
+
+ E[Γ] ⊢ U : s
+ E[Γ] ⊢ t : T
+ E[Γ] ⊢ T ≤_{βδιζη} U
+ --------------
+ E[Γ] ⊢ t : U
+
+
+.. _Normal-form:
+
+**Normal form**. A term which cannot be any more reduced is said to be in *normal
+form*. There are several ways (or strategies) to apply the reduction
+rules. Among them, we have to mention the *head reduction* which will
+play an important role (see Chapter :ref:`tactics`). Any term :math:`t` can be written as
+:math:`λ x_1 :T_1 .~… λ x_k :T_k .~(t_0~t_1 … t_n )` where :math:`t_0` is not an
+application. We say then that :math:`t_0` is the *head of* :math:`t`. If we assume
+that :math:`t_0` is :math:`λ x:T.~u_0` then one step of β-head reduction of :math:`t` is:
+
+.. math::
+ λ x_1 :T_1 .~… λ x_k :T_k .~(λ x:T.~u_0~t_1 … t_n ) ~\triangleright~
+ λ (x_1 :T_1 )…(x_k :T_k ).~(\subst{u_0}{x}{t_1}~t_2 … t_n )
+
+Iterating the process of head reduction until the head of the reduced
+term is no more an abstraction leads to the *β-head normal form* of :math:`t`:
+
+.. math::
+ t \triangleright … \triangleright λ x_1 :T_1 .~…λ x_k :T_k .~(v~u_1 … u_m )
+
+where :math:`v` is not an abstraction (nor an application). Note that the head
+normal form must not be confused with the normal form since some :math:`u_i`
+can be reducible. Similar notions of head-normal forms involving δ, ι
+and ζ reductions or any combination of those can also be defined.
+
+.. _Admissible-rules-for-global-environments:
+
+Admissible rules for global environments
+--------------------------------------------
+
+From the original rules of the type system, one can show the
+admissibility of rules which change the local context of definition of
+objects in the global environment. We show here the admissible rules
+that are used in the discharge mechanism at the end of a section.
+
+
+.. _Abstraction:
+
+**Abstraction.**
+One can modify a global declaration by generalizing it over a
+previously assumed constant :math:`c`. For doing that, we need to modify the
+reference to the global declaration in the subsequent global
+environment and local context by explicitly applying this constant to
+the constant :math:`c`.
+
+Below, if :math:`Γ` is a context of the form :math:`[y_1 :A_1 ;~…;~y_n :A_n]`, we write
+:math:`∀x:U,~\subst{Γ}{c}{x}` to mean
+:math:`[y_1 :∀ x:U,~\subst{A_1}{c}{x};~…;~y_n :∀ x:U,~\subst{A_n}{c}{x}]`
+and :math:`\subst{E}{|Γ|}{|Γ|c}` to mean the parallel substitution
+:math:`E\{y_1 /(y_1~c)\}…\{y_n/(y_n~c)\}`.
+
+
+.. _First-abstracting-property:
+
+**First abstracting property:**
+
+.. math::
+ \frac{\WF{E;~c:U;~E′;~c′:=t:T;~E″}{Γ}}
+ {\WF{E;~c:U;~E′;~c′:=λ x:U.~\subst{t}{c}{x}:∀x:U,~\subst{T}{c}{x};~\subst{E″}{c′}{(c′~c)}}
+ {\subst{Γ}{c′}{(c′~c)}}}
+
+
+.. math::
+ \frac{\WF{E;~c:U;~E′;~c′:T;~E″}{Γ}}
+ {\WF{E;~c:U;~E′;~c′:∀ x:U,~\subst{T}{c}{x};~\subst{E″}{c′}{(c′~c)}}{\subst{Γ}{c′}{(c′~c)}}}
+
+.. math::
+ \frac{\WF{E;~c:U;~E′;~\ind{p}{Γ_I}{Γ_C};~E″}{Γ}}
+ {\WFTWOLINES{E;~c:U;~E′;~\ind{p+1}{∀ x:U,~\subst{Γ_I}{c}{x}}{∀ x:U,~\subst{Γ_C}{c}{x}};~
+ \subst{E″}{|Γ_I ;Γ_C |}{|Γ_I ;Γ_C | c}}
+ {\subst{Γ}{|Γ_I ;Γ_C|}{|Γ_I ;Γ_C | c}}}
+
+One can similarly modify a global declaration by generalizing it over
+a previously defined constant :math:`c`. Below, if :math:`Γ` is a context of the form
+:math:`[y_1 :A_1 ;~…;~y_n :A_n]`, we write :math:`\subst{Γ}{c}{u}` to mean
+:math:`[y_1 :\subst{A_1} {c}{u};~…;~y_n:\subst{A_n} {c}{u}]`.
+
+
+.. _Second-abstracting-property:
+
+**Second abstracting property:**
+
+.. math::
+ \frac{\WF{E;~c:=u:U;~E′;~c′:=t:T;~E″}{Γ}}
+ {\WF{E;~c:=u:U;~E′;~c′:=(\letin{x}{u:U}{\subst{t}{c}{x}}):\subst{T}{c}{u};~E″}{Γ}}
+
+.. math::
+ \frac{\WF{E;~c:=u:U;~E′;~c′:T;~E″}{Γ}}
+ {\WF{E;~c:=u:U;~E′;~c′:\subst{T}{c}{u};~E″}{Γ}}
+
+.. math::
+ \frac{\WF{E;~c:=u:U;~E′;~\ind{p}{Γ_I}{Γ_C};~E″}{Γ}}
+ {\WF{E;~c:=u:U;~E′;~\ind{p}{\subst{Γ_I}{c}{u}}{\subst{Γ_C}{c}{u}};~E″}{Γ}}
+
+.. _Pruning-the-local-context:
+
+**Pruning the local context.**
+If one abstracts or substitutes constants with the above rules then it
+may happen that some declared or defined constant does not occur any
+more in the subsequent global environment and in the local context.
+One can consequently derive the following property.
+
+
+.. _First-pruning-property:
+
+.. inference:: First pruning property:
+
+ \WF{E;~c:U;~E′}{Γ}
+ c~\kw{does not occur in}~E′~\kw{and}~Γ
+ --------------------------------------
+ \WF{E;E′}{Γ}
+
+
+.. _Second-pruning-property:
+
+.. inference:: Second pruning property:
+
+ \WF{E;~c:=u:U;~E′}{Γ}
+ c~\kw{does not occur in}~E′~\kw{and}~Γ
+ --------------------------------------
+ \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
+-----------------------------------------------------------------
+
+|Coq| can be used as a type checker for the Calculus of Inductive
+Constructions with an impredicative sort :math:`\Set` by using the compiler
+option ``-impredicative-set``. For example, using the ordinary `coqtop`
+command, the following is rejected,
+
+.. example::
+
+ .. coqtop:: all
+
+ Fail Definition id: Set := forall X:Set,X->X.
+
+while it will type check, if one uses instead the `coqtop`
+``-impredicative-set`` option..
+
+The major change in the theory concerns the rule for product formation
+in the sort :math:`\Set`, which is extended to a domain in any sort:
+
+.. inference:: ProdImp
+
+ E[Γ] ⊢ T : s
+ s ∈ \Sort
+ E[Γ::(x:T)] ⊢ U : \Set
+ ---------------------
+ E[Γ] ⊢ ∀ x:T,~U : \Set
+
+This extension has consequences on the inductive definitions which are
+allowed. In the impredicative system, one can build so-called *large
+inductive definitions* like the example of second-order existential
+quantifier (:g:`exSet`).
+
+There should be restrictions on the eliminations which can be
+performed on such definitions. The elimination rules in the
+impredicative system for sort :math:`\Set` become:
+
+
+
+.. inference:: Set1
+
+ s ∈ \{\Prop, \Set\}
+ -----------------
+ [I:\Set|I→ s]
+
+.. inference:: Set2
+
+ I~\kw{is a small inductive definition}
+ s ∈ \{\Type(i)\}
+ ----------------
+ [I:\Set|I→ s]
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/inductive.rst b/doc/sphinx/language/core/inductive.rst
new file mode 100644
index 0000000000..189e1008e8
--- /dev/null
+++ b/doc/sphinx/language/core/inductive.rst
@@ -0,0 +1,1724 @@
+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.
+
+.. [1]
+ Except if the inductive type is empty in which case there is no
+ equation that can be used to infer the return type.
+
+.. 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.
+
+.. _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
+
+ 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`.
diff --git a/doc/sphinx/language/core/variants.rst b/doc/sphinx/language/core/variants.rst
new file mode 100644
index 0000000000..315e97687b
--- /dev/null
+++ b/doc/sphinx/language/core/variants.rst
@@ -0,0 +1,196 @@
+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 ...
+
+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`).
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.