diff options
Diffstat (limited to 'doc/sphinx/language')
| -rw-r--r-- | doc/sphinx/language/cic.rst | 1845 | ||||
| -rw-r--r-- | doc/sphinx/language/coq-library.rst | 988 | ||||
| -rw-r--r-- | doc/sphinx/language/gallina-extensions.rst | 2358 | ||||
| -rw-r--r-- | doc/sphinx/language/module-system.rst | 459 |
4 files changed, 5650 insertions, 0 deletions
diff --git a/doc/sphinx/language/cic.rst b/doc/sphinx/language/cic.rst new file mode 100644 index 0000000000..7ed6524095 --- /dev/null +++ b/doc/sphinx/language/cic.rst @@ -0,0 +1,1845 @@ +.. include:: ../preamble.rst +.. include:: ../replaces.rst + +.. _calculusofinductiveconstructions: + + +Calculus of Inductive Constructions +==================================== + +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 T, P* ". The expression +“x of type T” is written :g:`x:T`. Informally, :g:`x:T` can be thought as +“x belongs to T”. + +The types of types are *sorts*. Types and sorts are themselves terms +so that terms, types and sorts are all components of a common +syntactic language of terms which is described in Section :ref:`terms` but, +first, we describe sorts. + + +.. _Sorts: + +Sorts +~~~~~~~~~~~ + +All sorts have a type and there is an infinite well-founded typing +hierarchy of sorts whose base sorts are :math:`\Prop` and :math:`\Set`. + +The sort :math:`\Prop` intends to be the type of logical propositions. If :math:`M` is a +logical proposition then it denotes the class of terms representing +proofs of :math:`M`. An object :math:`m` belonging to :math:`M` witnesses the fact that :math:`M` is +provable. An object of type :math:`\Prop` is called a proposition. + +The sort :math:`\Set` intends to be the type of small sets. This includes data +types such as booleans and naturals, but also products, subsets, and +function types over these data types. + +:math:`\Prop` and :math:`\Set` themselves can be manipulated as ordinary terms. +Consequently they also have a type. Because assuming simply that :math:`\Set` +has type :math:`\Set` leads to an inconsistent theory :cite:`Coq86`, the language of +|Cic| has infinitely many sorts. There are, in addition to :math:`\Set` and :math:`\Prop` +a hierarchy of universes :math:`\Type(i)` for any integer :math:`i`. + +Like :math:`\Set`, all of the sorts :math:`\Type(i)` contain small sets such as +booleans, natural numbers, as well as products, subsets and function +types over small sets. But, unlike :math:`\Set`, they also contain large sets, +namely the sorts :math:`\Set` and :math:`\Type(j)` for :math:`j<i`, and all products, subsets +and function types over these sorts. + +Formally, we call :math:`\Sort` the set of sorts which is defined by: + +.. math:: + + \Sort \equiv \{\Prop,\Set,\Type(i)\;|\; i~∈ ℕ\} + +Their properties, such as: :math:`\Prop:\Type(1)`, :math:`\Set:\Type(1)`, and +:math:`\Type(i):\Type(i+1)`, are defined in Section :ref:`subtyping-rules`. + +The user does not have to mention explicitly the index :math:`i` when +referring to the universe :math:`\Type(i)`. One only writes :math:`\Type`. The system +itself generates for each instance of :math:`\Type` a new index for the +universe and checks that the constraints between these indexes can be +solved. From the user point of view we consequently have :math:`\Type:\Type`. We +shall make precise in the typing rules the constraints between the +indices. + + +.. _Implementation-issues: + +**Implementation issues** In practice, the Type hierarchy is +implemented using *algebraic +universes*. An algebraic universe :math:`u` is either a variable (a qualified +identifier with a number) or a successor of an algebraic universe (an +expression :math:`u+1`), or an upper bound of algebraic universes (an +expression :math:`\max(u 1 ,...,u n )`), or the base universe (the expression +:math:`0`) which corresponds, in the arity of template polymorphic inductive +types (see Section +:ref:`well-formed-inductive-definitions`), +to the predicative sort :math:`\Set`. A graph of +constraints between the universe variables is maintained globally. To +ensure the existence of a mapping of the universes to the positive +integers, the graph of constraints must remain acyclic. Typing +expressions that violate the acyclicity of the graph of constraints +results in a Universe inconsistency error (see also Section +:ref:`TODO-2.10`). + + +.. _Terms: + +Terms +~~~~~ + + + +Terms are built from sorts, variables, constants, abstractions, +applications, local definitions, and products. From a syntactic point +of view, types cannot be distinguished from terms, except that they +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:`\Set`, :math:`\Prop`, :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 “t applied to u”. +#. if :g:`x` is a variable, and :math:`t`, :math:`T` and :math:`u` are + terms then :g:`let x:=t:T in 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 +:g:`λx:T. U` and :g:`∀ 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 \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-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-Prop + + \WTEG{T}{s} + s \in {\Sort} + \WTE{\Gamma::(x:T)}{U}{\Prop} + ----------------------------- + \WTEG{\forall~x:T,U}{\Prop} + +.. inference:: Prod-Set + + \WTEG{T}{s} + s \in \{\Prop, \Set\} + \WTE{\Gamma::(x:T)}{U}{\Set} + ---------------------------- + \WTEG{\forall~x:T,U}{\Set} + +.. inference:: Prod-Type + + \WTEG{T}{\Type(i)} + \WTE{\Gamma::(x:T)}{U}{\Type(i)} + -------------------------------- + \WTEG{\forall~x:T,U}{\Type(i)} + +.. inference:: Lam + + \WTEG{\forall~x:T,U}{s} + \WTE{\Gamma::(x:T)}{t}{U} + ------------------------------------ + \WTEG{\lb x:T\mto t}{\forall x:T, U} + +.. inference:: App + + \WTEG{t}{\forall~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}} + + + +**Remark**: **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. + + + +**Remark**: 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`). + + +.. _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. + + +.. _β-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 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`. + + +.. _ι-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`. + + +.. _δ-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 + + +.. _ζ-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}{t}~\triangleright_ζ~\subst{t}{x}{u} + + +.. _η-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`. + + +**Remark**: 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).` + + +.. _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, 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 u_2′ . We then write +:math:`E[Γ] ⊢ t_1 =_{βδιζη} t_2` . + +Apart from this we consider two instances of polymorphic and +cumulative (see Chapter :ref:`polymorphicuniverses`) inductive types +(see below) convertible + +.. math:: + E[Γ] ⊢ t~w_1 … w_m =_{βδιζη} t~w_1' … w_m' + +if we have subtypings (see below) in both directions, i.e., + +.. math:: + E[Γ] ⊢ t~w_1 … w_m ≤_{βδιζη} t~w_1' … w_m' + +and + +.. math:: + E[Γ] ⊢ t~w_1' … w_m' ≤_{βδιζη} t~w_1 … w_m. + +Furthermore, we consider + +.. math:: + E[Γ] ⊢ c~v_1 … v_m =_{βδιζη} c'~v_1' … v_m' + +convertible if + +.. math:: + E[Γ] ⊢ v_i =_{βδιζη} v_i' + +and we have that :math:`c` and :math:`c'` +are the same constructors of different instances of the same inductive +types (differing only in universe levels) such that + +.. math:: + E[Γ] ⊢ c~v_1 … v_m : t~w_1 … w_m + +and + +.. math:: + E[Γ] ⊢ c'~v_1' … v_m' : t'~ w_1' … w_m ' + +and we have + +.. math:: + E[Γ] ⊢ t~w_1 … w_m =_{βδιζη} t~w_1' … w_m'. + +The convertibility relation allows introducing a new typing rule which +says that two convertible well-formed types have the same inhabitants. + + +.. _subtyping-rules: + +Subtyping rules +------------------- + +At the moment, we did not take into account one rule between universes +which says that any term in a universe of index i is also a term in +the universe of index 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` +#. 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)}, \Sort)∈Γ_I` + and + :math:`(t' : ∀Γ_P' ,∀Γ_{\mathit{Arr}(t)}', \Sort')∈Γ_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_{n,1} … v_{n,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_{n,1}' … v_{n,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. + + +.. _inductive-definitions: + +Inductive Definitions +------------------------- + +Formally, we can represent any *inductive definition* as +:math:`\ind{p}{Γ_I}{Γ_C}` where: + ++ :math:`Γ_I` determines the names and types of inductive types; ++ :math:`Γ_C` determines the names and types of constructors of these + inductive types; ++ :math:`p` determines the number of parameters of these inductive types. + + +These inductive definitions, together with global assumptions and +global definitions, then form the global environment. Additionally, +for any :math:`p` there always exists :math:`Γ_P =[a_1 :A_1 ;…;a_p :A_p ]` such that +each :math:`T` in :math:`(t:T)∈Γ_I \cup Γ_C` can be written as: :math:`∀Γ_P , T'` where :math:`Γ_P` is +called the *context of parameters*. Furthermore, we must have that +each :math:`T` in :math:`(t:T)∈Γ_I` can be written as: :math:`∀Γ_P,∀Γ_{\mathit{Arr}(t)}, S` where +:math:`Γ_{\mathit{Arr}(t)}` is called the *Arity* of the inductive type t and :math:`S` is called +the sort of the inductive type t (not to be confused with :math:`\Sort` which is the set of sorts). + + +** Examples** The declaration for parameterized lists is: + +.. math:: + \ind{1}{[\List:\Set→\Set]}{\left[\begin{array}{rcl} + \Nil & : & \forall A:\Set,\List~A \\ + \cons & : & \forall A:\Set, A→ \List~A→ \List~A + \end{array} + \right]} + +which corresponds to the result of the |Coq| declaration: + +.. example:: + .. coqtop:: in + + Inductive list (A:Set) : Set := + | nil : list A + | cons : A -> list A -> list A. + +The declaration for a mutual inductive definition of tree and forest +is: + +.. math:: + \ind{~}{\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: + +.. example:: + .. coqtop:: in + + Inductive tree : Set := + | node : forest -> tree + with forest : Set := + | emptyf : forest + | consf : tree -> forest -> forest. + +The declaration for a mutual inductive definition of even and odd is: + +.. math:: + \ind{1}{\left[\begin{array}{rcl}\even&:&\nat → \Prop \\ + \odd&:&\nat → \Prop \end{array}\right]} + {\left[\begin{array}{rcl} + \evenO &:& \even~0\\ + \evenS &:& \forall n, \odd~n -> \even~(\kw{S}~n)\\ + \oddS &:& \forall n, \even~n -> \odd~(\kw{S}~n) + \end{array}\right]} + +which corresponds to the result of the |Coq| declaration: + +.. example:: + .. 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 E which +contains an inductive declaration. + +.. 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[Γ] ⊢ \even\_O : \even~O\\ + E[Γ] ⊢ \even\_S : \forall~n:\nat, \odd~n → \even~(S~n)\\ + E[Γ] ⊢ \odd\_S : \forall~n:\nat, \even~n → \odd~(S~n) + \end{array} + + + + +.. _Well-formed-inductive-definitions: + +Well-formed inductive definitions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We cannot accept any inductive declaration 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: + + +**Type is an Arity of Sort S.** +A type :math:`T` is an *arity of sort s* if it converts to the sort s or to a +product :math:`∀ x:T,U` with :math:`U` an arity of sort s. + +.. example:: + + :math:`A→\Set` is an arity of sort :math:`\Set`. :math:`∀ A:\Prop,A→ \Prop` is an arity of sort + :math:`\Prop`. + + +**Type is an Arity.** +A type :math:`T` is an *arity* if there is a :math:`s∈ \Sort` such that :math:`T` is an arity of +sort s. + + +.. example:: + + :math:`A→ Set` and :math:`∀ A:\Prop,A→ \Prop` are arities. + + +**Type of Constructor of I.** +We say that T is a *type of constructor of 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 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`. + + +**Occurs Strictly Positively.** +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 declaration 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 Condition.** +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 definition 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` + + +For instance, if one considers the type + +.. example:: + .. coqtop:: all + + Module TreeExample. + Inductive tree (A:Type) : Type := + | leaf : tree A + | node : A -> (nat -> tree A) -> tree A. + End TreeExample. + +:: + + [TODO Note: This commentary does not seem to correspond to the + preceding example. Instead it is referring to the first example + in Inductive Definitions section. It seems we should either + delete the preceding example and refer the the example above of + type `list A`, or else we should rewrite the commentary below.] + + Then every instantiated constructor of list A satisfies the nested positivity + condition for list + │ + ├─ concerning type list A of constructor nil: + │ Type list A of constructor nil satisfies the positivity condition for list + │ because list does not appear in any (real) arguments of the type of that + | constructor (primarily because list does not have any (real) + | arguments) ... (bullet 1) + │ + ╰─ concerning type ∀ A → list A → list A of constructor cons: + Type ∀ A : Type, A → list A → list A of constructor cons + satisfies the positivity condition for list because: + │ + ├─ list occurs only strictly positively in Type ... (bullet 3) + │ + ├─ list occurs only strictly positively in A ... (bullet 3) + │ + ├─ list occurs only strictly positively in list A ... (bullet 4) + │ + ╰─ list satisfies the positivity condition for list 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[Γ_P ] ⊢ A_j : s_j' )_{j=1… k} + (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 +sortProp but may fail to define inductive definition on sort Set and +generate constraints between universes for inductive definitions in +the Type hierarchy. + + +**Examples**. 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)`. + +.. example:: + .. coqtop:: in + + Inductive exProp (P:Prop->Prop) : Prop := + | exP_intro : forall X:Prop, P X -> exProp P. + +The same definition on Set is not allowed and fails: + +.. example:: + .. 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 Type. The exType inductive definition has type +:math:`(\Type(i)→\Prop)→\Type(j)` with the constraint that the parameter :math:`X` of :math:`\kw{exT_intro}` +has type :math:`\Type(k)` with :math:`k<j` and :math:`k≤ i`. + +.. example:: + .. coqtop:: all + + Inductive exType (P:Type->Prop) : Type := + exT_intro : forall X:Type, P X -> exType P. + + + +.. _Template-polymorphism: + +**Template polymorphism.** +Inductive types declared in Type are polymorphic over their arguments +in Type. If :math:`A` is an arity of some sort and s is a sort, we write :math:`A_{/s}` +for the arity obtained from :math:`A` by replacing its sort with 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 such that all eliminations, to + :math:`\Prop`, :math:`\Set` and :math:`\Type(j)`, are allowed + (see Section 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}`. + +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 paragraph 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** is just to avoid to recompute the allowed elimination +sorts at each instance of a pattern-matching (see section 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 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). + +Remark: 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 :g:`A:Set` exists in the local context, +we want to build a function length of type :g:`list A -> nat` which computes +the length of the list, so such that :g:`(length (nil A)) = O` and :g:`(length +(cons A a l)) = (S (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 definition 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 :g:`∀ l:list A,(has_length A l +(length l))` it is enough to prove: + + ++ :g:`(has_length A (nil A) (length (nil A)))` ++ :g:`∀ a:A, ∀ l:list A, (has_length A l (length l)) →` + :g:`(has_length A (cons A a l) (length (cons A a l)))` + + +which given the conversion equalities satisfied by length is the same +as proving: + + ++ :g:`(has_length A (nil A) O)` ++ :g:`∀ a:A, ∀ l:list A, (has_length A l (length l)) →` + :g:`(has_length A (cons A a l) (S (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. + + +.. _The-match…with-end-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 \endkw + +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…\endkw` expression we also need +to know the predicate 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~\endkw + +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 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. + + +.. _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 definitions 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 elimination, is the one when predicate :math:`P` is also of +sort :math:`\Prop`. + +.. inference:: Prop + + ~ + --------------- + [I:Prop|I→Prop] + + +: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 definition of type :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 give 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 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 an 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. + + +.. _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:`p` 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~p_1\ldots p_r\ t_1 \ldots t_p)\}^P &\equiv (P~t_1\ldots ~t_p~c) \\ + \{c:\forall~x:T,C\}^P &\equiv \forall~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:: + \begin{eqnarray*} + P & = & \lambda~l~.~P^\prime\\ + f_1 & = & t_1\\ + f_2 & = & \lambda~(hd:\nat)~.~\lambda~(tl:\List~\nat)~.~t_2 + \end{eqnarray*} + +According to the definition: + +.. math:: + \{(\kw{nil}~\nat)\}^P ≡ \{(\kw{nil}~\nat) : (\List~\nat)\}^P ≡ (P~(\kw{nil}~\nat)) + +.. math:: + + \begin{array}{rl} + \{(\kw{cons}~\nat)\}^P & ≡\{(\kw{cons}~\nat) : (\nat→\List~\nat→\List~\nat)\}^P \\ + & ≡∀ n:\nat, \{(\kw{cons}~\nat~n) : \List~\nat→\List~\nat)\}^P \\ + & ≡∀ n:\nat, ∀ l:\List~\nat, \{(\kw{cons}~\nat~n~l) : \List~\nat)\}^P \\ + & ≡∀ n:\nat, ∀ l:\List~\nat,(P~(\kw{cons}~\nat~n~l)). + \end{array} + +Given some :math:`P` then :math:`\{(\kw{nil}~\nat)\}^P` represents the expected type of :math:`f_1` , +and :math:`\{(\kw{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 : {(\kw{nil} ~\nat)}^P \\ + E[Γ] ⊢ f_2 : {(\kw{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_n ) \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 Γ_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~O)→(∀ n:\nat, (P~n)→(P~(\kw{S}~n)))→ ∀ n:\nat, (P~n) + +can be represented by the term: + +.. math:: + \begin{array}{l} + λ P:\nat→\Prop. λ f:(P~O). λ g:(∀ n:\nat, (P~n)→(P~(S~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 definition. 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_r :T_r, (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 type an inductive definition 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 + definition :math:`I_p` part of the inductive declaration 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_k :B_k , (I~a_1 … a_k )` + and can consequently be written :math:`λ y_1 :B_1' . … λ y_k :B_k'. g_i`. (:math:`B_i'` is + obtained from :math:`B_i` by substituting parameters 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 y. + + +The following definitions are correct, we enter them using the ``Fixpoint`` +command as described in Section :ref:`TODO-1.3.4` 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:: + \def\plus{\mathsf{plus}} + \def\tri{\triangleright_\iota} + \begin{eqnarray*} + \plus~(\nS~(\nS~\nO))~(\nS~\nO) & \tri & \nS~(\plus~(\nS~\nO)~(\nS~\nO))\\ + & \tri & \nS~(\nS~(\plus~\nO~(\nS~\nO)))\\ + & \tri & \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:`TODO-13.1`. + + +.. _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)}}{Γ{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 Construction 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 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 (exSet). + +There should be restrictions on the eliminations which can be +performed on such definitions. The eliminations rules in the +impredicative system for sort 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/coq-library.rst b/doc/sphinx/language/coq-library.rst new file mode 100644 index 0000000000..29053d6a57 --- /dev/null +++ b/doc/sphinx/language/coq-library.rst @@ -0,0 +1,988 @@ +.. include:: ../replaces.rst + +.. _thecoqlibrary: + +The |Coq| library +================= + +:Source: https://coq.inria.fr/distrib/current/refman/stdlib.html +:Converted by: Pierre Letouzey + +.. index:: + single: Theories + + +The |Coq| library is structured into two parts: + + * **The initial library**: it contains elementary logical notions and + data-types. It constitutes the basic state of the system directly + available when running |Coq|; + + * **The standard library**: general-purpose libraries containing various + developments of |Coq| axiomatizations about sets, lists, sorting, + arithmetic, etc. This library comes with the system and its modules + are directly accessible through the ``Require`` command (see + Section :ref:`TODO-6.5.1-Require`); + +In addition, user-provided libraries or developments are provided by +|Coq| users' community. These libraries and developments are available +for download at http://coq.inria.fr (see +Section :ref:`userscontributions`). + +This chapter briefly reviews the |Coq| libraries whose contents can +also be browsed at http://coq.inria.fr/stdlib. + + + + +The basic library +----------------- + +This section lists the basic notions and results which are directly +available in the standard |Coq| system. Most of these constructions +are defined in the ``Prelude`` module in directory ``theories/Init`` +at the |Coq| root directory; this includes the modules +``Notations``, +``Logic``, +``Datatypes``, +``Specif``, +``Peano``, +``Wf`` and +``Tactics``. +Module ``Logic_Type`` also makes it in the initial state. + + +Notations +~~~~~~~~~ + +This module defines the parsing and pretty-printing of many symbols +(infixes, prefixes, etc.). However, it does not assign a meaning to +these notations. The purpose of this is to define and fix once for all +the precedence and associativity of very common notations. The main +notations fixed in the initial state are : + +================ ============ =============== +Notation Precedence Associativity +================ ============ =============== +``_ -> _`` 99 right +``_ <-> _`` 95 no +``_ \/ _`` 85 right +``_ /\ _`` 80 right +``~ _`` 75 right +``_ = _`` 70 no +``_ = _ = _`` 70 no +``_ = _ :> _`` 70 no +``_ <> _`` 70 no +``_ <> _ :> _`` 70 no +``_ < _`` 70 no +``_ > _`` 70 no +``_ <= _`` 70 no +``_ >= _`` 70 no +``_ < _ < _`` 70 no +``_ < _ <= _`` 70 no +``_ <= _ < _`` 70 no +``_ <= _ <= _`` 70 no +``_ + _`` 50 left +``_ || _`` 50 left +``_ - _`` 50 left +``_ * _`` 40 left +``_ _`` 40 left +``_ / _`` 40 left +``- _`` 35 right +``/ _`` 35 right +``_ ^ _`` 30 right +================ ============ =============== + +Logic +~~~~~ + +The basic library of |Coq| comes with the definitions of standard +(intuitionistic) logical connectives (they are defined as inductive +constructions). They are equipped with an appealing syntax enriching the +subclass `form` of the syntactic class `term`. The syntax of `form` +is shown below: + +.. /!\ Please keep the blanks in the lines below, experimentally they produce + a nice last column. Or even better, find a proper way to do this! + +.. productionlist:: + form : True (True) + : | False (False) + : | ~ `form` (not) + : | `form` /\ `form` (and) + : | `form` \/ `form` (or) + : | `form` -> `form` (primitive implication) + : | `form` <-> `form` (iff) + : | forall `ident` : `type`, `form` (primitive for all) + : | exists `ident` [: `specif`], `form` (ex) + : | exists2 `ident` [: `specif`], `form` & `form` (ex2) + : | `term` = `term` (eq) + : | `term` = `term` :> `specif` (eq) + +.. note:: + + Implication is not defined but primitive (it is a non-dependent + product of a proposition over another proposition). There is also a + primitive universal quantification (it is a dependent product over a + proposition). The primitive universal quantification allows both + first-order and higher-order quantification. + +Propositional Connectives ++++++++++++++++++++++++++ + +.. index:: + single: Connectives + single: True (term) + single: I (term) + single: False (term) + single: not (term) + single: and (term) + single: conj (term) + single: proj1 (term) + single: proj2 (term) + single: or (term) + single: or_introl (term) + single: or_intror (term) + single: iff (term) + single: IF_then_else (term) + +First, we find propositional calculus connectives: + +.. coqtop:: in + + Inductive True : Prop := I. + Inductive False : Prop := . + Definition not (A: Prop) := A -> False. + Inductive and (A B:Prop) : Prop := conj (_:A) (_:B). + Section Projections. + Variables A B : Prop. + Theorem proj1 : A /\ B -> A. + Theorem proj2 : A /\ B -> B. + End Projections. + Inductive or (A B:Prop) : Prop := + | or_introl (_:A) + | or_intror (_:B). + Definition iff (P Q:Prop) := (P -> Q) /\ (Q -> P). + Definition IF_then_else (P Q R:Prop) := P /\ Q \/ ~ P /\ R. + +Quantifiers ++++++++++++ + +.. index:: + single: Quantifiers + single: all (term) + single: ex (term) + single: exists (term) + single: ex_intro (term) + single: ex2 (term) + single: exists2 (term) + single: ex_intro2 (term) + +Then we find first-order quantifiers: + +.. coqtop:: in + + Definition all (A:Set) (P:A -> Prop) := forall x:A, P x. + Inductive ex (A: Set) (P:A -> Prop) : Prop := + ex_intro (x:A) (_:P x). + Inductive ex2 (A:Set) (P Q:A -> Prop) : Prop := + ex_intro2 (x:A) (_:P x) (_:Q x). + +The following abbreviations are allowed: + +====================== ======================================= +``exists x:A, P`` ``ex A (fun x:A => P)`` +``exists x, P`` ``ex _ (fun x => P)`` +``exists2 x:A, P & Q`` ``ex2 A (fun x:A => P) (fun x:A => Q)`` +``exists2 x, P & Q`` ``ex2 _ (fun x => P) (fun x => Q)`` +====================== ======================================= + +The type annotation ``:A`` can be omitted when ``A`` can be +synthesized by the system. + +Equality +++++++++ + +.. index:: + single: Equality + single: eq (term) + single: eq_refl (term) + +Then, we find equality, defined as an inductive relation. That is, +given a type ``A`` and an ``x`` of type ``A``, the +predicate :g:`(eq A x)` is the smallest one which contains ``x``. +This definition, due to Christine Paulin-Mohring, is equivalent to +define ``eq`` as the smallest reflexive relation, and it is also +equivalent to Leibniz' equality. + +.. coqtop:: in + + Inductive eq (A:Type) (x:A) : A -> Prop := + eq_refl : eq A x x. + +Lemmas +++++++ + +Finally, a few easy lemmas are provided. + +.. index:: + single: absurd (term) + single: eq_sym (term) + single: eq_trans (term) + single: f_equal (term) + single: sym_not_eq (term) + single: eq_ind_r (term) + single: eq_rec_r (term) + single: eq_rect (term) + single: eq_rect_r (term) + +.. coqtop:: in + + Theorem absurd : forall A C:Prop, A -> ~ A -> C. + Section equality. + Variables A B : Type. + Variable f : A -> B. + Variables x y z : A. + Theorem eq_sym : x = y -> y = x. + Theorem eq_trans : x = y -> y = z -> x = z. + Theorem f_equal : x = y -> f x = f y. + Theorem not_eq_sym : x <> y -> y <> x. + End equality. + Definition eq_ind_r : + forall (A:Type) (x:A) (P:A->Prop), P x -> forall y:A, y = x -> P y. + Definition eq_rec_r : + forall (A:Type) (x:A) (P:A->Set), P x -> forall y:A, y = x -> P y. + Definition eq_rect_r : + forall (A:Type) (x:A) (P:A->Type), P x -> forall y:A, y = x -> P y. + Hint Immediate eq_sym not_eq_sym : core. + +.. index:: + single: f_equal2 ... f_equal5 (term) + +The theorem ``f_equal`` is extended to functions with two to five +arguments. The theorem are names ``f_equal2``, ``f_equal3``, +``f_equal4`` and ``f_equal5``. +For instance ``f_equal3`` is defined the following way. + +.. coqtop:: in + + Theorem f_equal3 : + forall (A1 A2 A3 B:Type) (f:A1 -> A2 -> A3 -> B) + (x1 y1:A1) (x2 y2:A2) (x3 y3:A3), + x1 = y1 -> x2 = y2 -> x3 = y3 -> f x1 x2 x3 = f y1 y2 y3. + +.. _datatypes: + +Datatypes +~~~~~~~~~ + +.. index:: + single: Datatypes + +In the basic library, we find in ``Datatypes.v`` the definition +of the basic data-types of programming, +defined as inductive constructions over the sort ``Set``. Some of +them come with a special syntax shown below (this syntax table is common with +the next section :ref:`specification`): + +.. productionlist:: + specif : `specif` * `specif` (prod) + : | `specif` + `specif` (sum) + : | `specif` + { `specif` } (sumor) + : | { `specif` } + { `specif` } (sumbool) + : | { `ident` : `specif` | `form` } (sig) + : | { `ident` : `specif` | `form` & `form` } (sig2) + : | { `ident` : `specif` & `specif` } (sigT) + : | { `ident` : `specif` & `specif` & `specif` } (sigT2) + term : (`term`, `term`) (pair) + + +Programming ++++++++++++ + +.. index:: + single: Programming + single: unit (term) + single: tt (term) + single: bool (term) + single: true (term) + single: false (term) + single: nat (term) + single: O (term) + single: S (term) + single: option (term) + single: Some (term) + single: None (term) + single: identity (term) + single: refl_identity (term) + +.. coqtop:: in + + Inductive unit : Set := tt. + Inductive bool : Set := true | false. + Inductive nat : Set := O | S (n:nat). + Inductive option (A:Set) : Set := Some (_:A) | None. + Inductive identity (A:Type) (a:A) : A -> Type := + refl_identity : identity A a a. + +Note that zero is the letter ``O``, and *not* the numeral ``0``. + +The predicate ``identity`` is logically +equivalent to equality but it lives in sort ``Type``. +It is mainly maintained for compatibility. + +We then define the disjoint sum of ``A+B`` of two sets ``A`` and +``B``, and their product ``A*B``. + +.. index:: + single: sum (term) + single: A+B (term) + single: + (term) + single: inl (term) + single: inr (term) + single: prod (term) + single: A*B (term) + single: * (term) + single: pair (term) + single: fst (term) + single: snd (term) + +.. coqtop:: in + + Inductive sum (A B:Set) : Set := inl (_:A) | inr (_:B). + Inductive prod (A B:Set) : Set := pair (_:A) (_:B). + Section projections. + Variables A B : Set. + Definition fst (H: prod A B) := match H with + | pair _ _ x y => x + end. + Definition snd (H: prod A B) := match H with + | pair _ _ x y => y + end. + End projections. + +Some operations on ``bool`` are also provided: ``andb`` (with +infix notation ``&&``), ``orb`` (with +infix notation ``||``), ``xorb``, ``implb`` and ``negb``. + +.. _specification: + +Specification +~~~~~~~~~~~~~ + +The following notions defined in module ``Specif.v`` allow to build new data-types and specifications. +They are available with the syntax shown in the previous section :ref:`datatypes`. + +For instance, given :g:`A:Type` and :g:`P:A->Prop`, the construct +:g:`{x:A | P x}` (in abstract syntax :g:`(sig A P)`) is a +``Type``. We may build elements of this set as :g:`(exist x p)` +whenever we have a witness :g:`x:A` with its justification +:g:`p:P x`. + +From such a :g:`(exist x p)` we may in turn extract its witness +:g:`x:A` (using an elimination construct such as ``match``) but +*not* its justification, which stays hidden, like in an abstract +data-type. In technical terms, one says that ``sig`` is a *weak +(dependent) sum*. A variant ``sig2`` with two predicates is also +provided. + +.. index:: + single: {x:A | P x} (term) + single: sig (term) + single: exist (term) + single: sig2 (term) + single: exist2 (term) + +.. coqtop:: in + + Inductive sig (A:Set) (P:A -> Prop) : Set := exist (x:A) (_:P x). + Inductive sig2 (A:Set) (P Q:A -> Prop) : Set := + exist2 (x:A) (_:P x) (_:Q x). + +A *strong (dependent) sum* :g:`{x:A & P x}` may be also defined, +when the predicate ``P`` is now defined as a +constructor of types in ``Type``. + +.. index:: + single: {x:A & P x} (term) + single: sigT (term) + single: existT (term) + single: sigT2 (term) + single: existT2 (term) + single: projT1 (term) + single: projT2 (term) + +.. coqtop:: in + + Inductive sigT (A:Type) (P:A -> Type) : Type := existT (x:A) (_:P x). + Section Projections2. + Variable A : Type. + Variable P : A -> Type. + Definition projT1 (H:sigT A P) := let (x, h) := H in x. + Definition projT2 (H:sigT A P) := + match H return P (projT1 H) with + existT _ _ x h => h + end. + End Projections2. + Inductive sigT2 (A: Type) (P Q:A -> Type) : Type := + existT2 (x:A) (_:P x) (_:Q x). + +A related non-dependent construct is the constructive sum +:g:`{A}+{B}` of two propositions ``A`` and ``B``. + +.. index:: + single: sumbool (term) + single: left (term) + single: right (term) + single: {A}+{B} (term) + +.. coqtop:: in + + Inductive sumbool (A B:Prop) : Set := left (_:A) | right (_:B). + +This ``sumbool`` construct may be used as a kind of indexed boolean +data-type. An intermediate between ``sumbool`` and ``sum`` is +the mixed ``sumor`` which combines :g:`A:Set` and :g:`B:Prop` +in the construction :g:`A+{B}` in ``Set``. + +.. index:: + single: sumor (term) + single: inleft (term) + single: inright (term) + single: A+{B} (term) + +.. coqtop:: in + + Inductive sumor (A:Set) (B:Prop) : Set := + | inleft (_:A) + | inright (_:B). + +We may define variants of the axiom of choice, like in Martin-Löf's +Intuitionistic Type Theory. + +.. index:: + single: Choice (term) + single: Choice2 (term) + single: bool_choice (term) + +.. coqtop:: in + + Lemma Choice : + forall (S S':Set) (R:S -> S' -> Prop), + (forall x:S, {y : S' | R x y}) -> + {f : S -> S' | forall z:S, R z (f z)}. + Lemma Choice2 : + forall (S S':Set) (R:S -> S' -> Set), + (forall x:S, {y : S' & R x y}) -> + {f : S -> S' & forall z:S, R z (f z)}. + Lemma bool_choice : + forall (S:Set) (R1 R2:S -> Prop), + (forall x:S, {R1 x} + {R2 x}) -> + {f : S -> bool | + forall x:S, f x = true /\ R1 x \/ f x = false /\ R2 x}. + +The next construct builds a sum between a data-type :g:`A:Type` and +an exceptional value encoding errors: + +.. index:: + single: Exc (term) + single: value (term) + single: error (term) + +.. coqtop:: in + + Definition Exc := option. + Definition value := Some. + Definition error := None. + +This module ends with theorems, relating the sorts ``Set`` or +``Type`` and ``Prop`` in a way which is consistent with the +realizability interpretation. + +.. index:: + single: False_rect (term) + single: False_rec (term) + single: eq_rect (term) + single: absurd_set (term) + single: and_rect (term) + +.. coqtop:: in + + Definition except := False_rec. + Theorem absurd_set : forall (A:Prop) (C:Set), A -> ~ A -> C. + Theorem and_rect2 : + forall (A B:Prop) (P:Type), (A -> B -> P) -> A /\ B -> P. + + +Basic Arithmetics +~~~~~~~~~~~~~~~~~ + +The basic library includes a few elementary properties of natural +numbers, together with the definitions of predecessor, addition and +multiplication, in module ``Peano.v``. It also +provides a scope ``nat_scope`` gathering standard notations for +common operations (``+``, ``*``) and a decimal notation for +numbers, allowing for instance to write ``3`` for :g:`S (S (S O)))`. This also works on +the left hand side of a ``match`` expression (see for example +section :ref:`TODO-refine-example`). This scope is opened by default. + +.. example:: + + The following example is not part of the standard library, but it + shows the usage of the notations: + + .. coqtop:: in + + Fixpoint even (n:nat) : bool := + match n with + | 0 => true + | 1 => false + | S (S n) => even n + end. + +.. index:: + single: eq_S (term) + single: pred (term) + single: pred_Sn (term) + single: eq_add_S (term) + single: not_eq_S (term) + single: IsSucc (term) + single: O_S (term) + single: n_Sn (term) + single: plus (term) + single: plus_n_O (term) + single: plus_n_Sm (term) + single: mult (term) + single: mult_n_O (term) + single: mult_n_Sm (term) + +Now comes the content of module ``Peano``: + +.. coqtop:: in + + Theorem eq_S : forall x y:nat, x = y -> S x = S y. + Definition pred (n:nat) : nat := + match n with + | 0 => 0 + | S u => u + end. + Theorem pred_Sn : forall m:nat, m = pred (S m). + Theorem eq_add_S : forall n m:nat, S n = S m -> n = m. + Hint Immediate eq_add_S : core. + Theorem not_eq_S : forall n m:nat, n <> m -> S n <> S m. + Definition IsSucc (n:nat) : Prop := + match n with + | 0 => False + | S p => True + end. + Theorem O_S : forall n:nat, 0 <> S n. + Theorem n_Sn : forall n:nat, n <> S n. + Fixpoint plus (n m:nat) {struct n} : nat := + match n with + | 0 => m + | S p => S (p + m) + end + where "n + m" := (plus n m) : nat_scope. + Lemma plus_n_O : forall n:nat, n = n + 0. + Lemma plus_n_Sm : forall n m:nat, S (n + m) = n + S m. + Fixpoint mult (n m:nat) {struct n} : nat := + match n with + | 0 => 0 + | S p => m + p * m + end + where "n * m" := (mult n m) : nat_scope. + Lemma mult_n_O : forall n:nat, 0 = n * 0. + Lemma mult_n_Sm : forall n m:nat, n * m + n = n * (S m). + + +Finally, it gives the definition of the usual orderings ``le``, +``lt``, ``ge`` and ``gt``. + +.. index:: + single: le (term) + single: le_n (term) + single: le_S (term) + single: lt (term) + single: ge (term) + single: gt (term) + +.. coqtop:: in + + Inductive le (n:nat) : nat -> Prop := + | le_n : le n n + | le_S : forall m:nat, n <= m -> n <= (S m). + where "n <= m" := (le n m) : nat_scope. + Definition lt (n m:nat) := S n <= m. + Definition ge (n m:nat) := m <= n. + Definition gt (n m:nat) := m < n. + +Properties of these relations are not initially known, but may be +required by the user from modules ``Le`` and ``Lt``. Finally, +``Peano`` gives some lemmas allowing pattern-matching, and a double +induction principle. + +.. index:: + single: nat_case (term) + single: nat_double_ind (term) + +.. coqtop:: in + + Theorem nat_case : + forall (n:nat) (P:nat -> Prop), + P 0 -> (forall m:nat, P (S m)) -> P n. + Theorem nat_double_ind : + forall R:nat -> nat -> Prop, + (forall n:nat, R 0 n) -> + (forall n:nat, R (S n) 0) -> + (forall n m:nat, R n m -> R (S n) (S m)) -> forall n m:nat, R n m. + + +Well-founded recursion +~~~~~~~~~~~~~~~~~~~~~~ + +The basic library contains the basics of well-founded recursion and +well-founded induction, in module ``Wf.v``. + +.. index:: + single: Well foundedness + single: Recursion + single: Well founded induction + single: Acc (term) + single: Acc_inv (term) + single: Acc_rect (term) + single: well_founded (term) + +.. coqtop:: in + + Section Well_founded. + Variable A : Type. + Variable R : A -> A -> Prop. + Inductive Acc (x:A) : Prop := + Acc_intro : (forall y:A, R y x -> Acc y) -> Acc x. + Lemma Acc_inv x : Acc x -> forall y:A, R y x -> Acc y. + Definition well_founded := forall a:A, Acc a. + Hypothesis Rwf : well_founded. + Theorem well_founded_induction : + forall P:A -> Set, + (forall x:A, (forall y:A, R y x -> P y) -> P x) -> forall a:A, P a. + Theorem well_founded_ind : + forall P:A -> Prop, + (forall x:A, (forall y:A, R y x -> P y) -> P x) -> forall a:A, P a. + +The automatically generated scheme ``Acc_rect`` +can be used to define functions by fixpoints using +well-founded relations to justify termination. Assuming +extensionality of the functional used for the recursive call, the +fixpoint equation can be proved. + +.. index:: + single: Fix_F (term) + single: fix_eq (term) + single: Fix_F_inv (term) + single: Fix_F_eq (term) + +.. coqtop:: in + + Section FixPoint. + Variable P : A -> Type. + Variable F : forall x:A, (forall y:A, R y x -> P y) -> P x. + Fixpoint Fix_F (x:A) (r:Acc x) {struct r} : P x := + F x (fun (y:A) (p:R y x) => Fix_F y (Acc_inv x r y p)). + Definition Fix (x:A) := Fix_F x (Rwf x). + Hypothesis F_ext : + forall (x:A) (f g:forall y:A, R y x -> P y), + (forall (y:A) (p:R y x), f y p = g y p) -> F x f = F x g. + Lemma Fix_F_eq : + forall (x:A) (r:Acc x), + F x (fun (y:A) (p:R y x) => Fix_F y (Acc_inv x r y p)) = Fix_F x r. + Lemma Fix_F_inv : forall (x:A) (r s:Acc x), Fix_F x r = Fix_F x s. + Lemma fix_eq : forall x:A, Fix x = F x (fun (y:A) (p:R y x) => Fix y). + End FixPoint. + End Well_founded. + +Accessing the Type level +~~~~~~~~~~~~~~~~~~~~~~~~ + +The basic library includes the definitions of the counterparts of some data-types and logical +quantifiers at the ``Type``: level: negation, pair, and properties +of ``identity``. This is the module ``Logic_Type.v``. + +.. index:: + single: notT (term) + single: prodT (term) + single: pairT (term) + +.. coqtop:: in + + Definition notT (A:Type) := A -> False. + Inductive prodT (A B:Type) : Type := pairT (_:A) (_:B). + +At the end, it defines data-types at the ``Type`` level. + +Tactics +~~~~~~~ + +A few tactics defined at the user level are provided in the initial +state, in module ``Tactics.v``. They are listed at +http://coq.inria.fr/stdlib, in paragraph ``Init``, link ``Tactics``. + + +The standard library +-------------------- + +Survey +~~~~~~ + +The rest of the standard library is structured into the following +subdirectories: + + * **Logic** : Classical logic and dependent equality + * **Arith** : Basic Peano arithmetic + * **PArith** : Basic positive integer arithmetic + * **NArith** : Basic binary natural number arithmetic + * **ZArith** : Basic relative integer arithmetic + * **Numbers** : Various approaches to natural, integer and cyclic numbers (currently axiomatically and on top of 2^31 binary words) + * **Bool** : Booleans (basic functions and results) + * **Lists** : Monomorphic and polymorphic lists (basic functions and results), Streams (infinite sequences defined with co-inductive types) + * **Sets** : Sets (classical, constructive, finite, infinite, power set, etc.) + * **FSets** : Specification and implementations of finite sets and finite maps (by lists and by AVL trees) + * **Reals** : Axiomatization of real numbers (classical, basic functions, integer part, fractional part, limit, derivative, Cauchy series, power series and results,...) + * **Relations** : Relations (definitions and basic results) + * **Sorting** : Sorted list (basic definitions and heapsort correctness) + * **Strings** : 8-bits characters and strings + * **Wellfounded** : Well-founded relations (basic results) + + +These directories belong to the initial load path of the system, and +the modules they provide are compiled at installation time. So they +are directly accessible with the command ``Require`` (see +Section :ref:`TODO-6.5.1-Require`). + +The different modules of the |Coq| standard library are documented +online at http://coq.inria.fr/stdlib. + +Peano’s arithmetic (nat) +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. index:: + single: Peano's arithmetic + single: nat_scope + +While in the initial state, many operations and predicates of Peano's +arithmetic are defined, further operations and results belong to other +modules. For instance, the decidability of the basic predicates are +defined here. This is provided by requiring the module ``Arith``. + +The following table describes the notations available in scope +``nat_scope`` : + +=============== =================== +Notation Interpretation +=============== =================== +``_ < _`` ``lt`` +``_ <= _`` ``le`` +``_ > _`` ``gt`` +``_ >= _`` ``ge`` +``x < y < z`` ``x < y /\ y < z`` +``x < y <= z`` ``x < y /\ y <= z`` +``x <= y < z`` ``x <= y /\ y < z`` +``x <= y <= z`` ``x <= y /\ y <= z`` +``_ + _`` ``plus`` +``_ - _`` ``minus`` +``_ * _`` ``mult`` +=============== =================== + + +Notations for integer arithmetics +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. index:: + single: Arithmetical notations + single: + (term) + single: * (term) + single: - (term) + singel: / (term) + single: <= (term) + single: >= (term) + single: < (term) + single: > (term) + single: ?= (term) + single: mod (term) + + +The following table describes the syntax of expressions +for integer arithmetics. It is provided by requiring and opening the module ``ZArith`` and opening scope ``Z_scope``. +It specifies how notations are interpreted and, when not +already reserved, the precedence and associativity. + +=============== ==================== ========== ============= +Notation Interpretation Precedence Associativity +=============== ==================== ========== ============= +``_ < _`` ``Z.lt`` +``_ <= _`` ``Z.le`` +``_ > _`` ``Z.gt`` +``_ >= _`` ``Z.ge`` +``x < y < z`` ``x < y /\ y < z`` +``x < y <= z`` ``x < y /\ y <= z`` +``x <= y < z`` ``x <= y /\ y < z`` +``x <= y <= z`` ``x <= y /\ y <= z`` +``_ ?= _`` ``Z.compare`` 70 no +``_ + _`` ``Z.add`` +``_ - _`` ``Z.sub`` +``_ * _`` ``Z.mul`` +``_ / _`` ``Z.div`` +``_ mod _`` ``Z.modulo`` 40 no +``- _`` ``Z.opp`` +``_ ^ _`` ``Z.pow`` +=============== ==================== ========== ============= + + +.. example:: + .. coqtop:: all reset + + Require Import ZArith. + Check (2 + 3)%Z. + Open Scope Z_scope. + Check 2 + 3. + + +Real numbers library +~~~~~~~~~~~~~~~~~~~~ + +Notations for real numbers +++++++++++++++++++++++++++ + +This is provided by requiring and opening the module ``Reals`` and +opening scope ``R_scope``. This set of notations is very similar to +the notation for integer arithmetics. The inverse function was added. + +=============== =================== +Notation Interpretation +=============== =================== +``_ < _`` ``Rlt`` +``_ <= _`` ``Rle`` +``_ > _`` ``Rgt`` +``_ >= _`` ``Rge`` +``x < y < z`` ``x < y /\ y < z`` +``x < y <= z`` ``x < y /\ y <= z`` +``x <= y < z`` ``x <= y /\ y < z`` +``x <= y <= z`` ``x <= y /\ y <= z`` +``_ + _`` ``Rplus`` +``_ - _`` ``Rminus`` +``_ * _`` ``Rmult`` +``_ / _`` ``Rdiv`` +``- _`` ``Ropp`` +``/ _`` ``Rinv`` +``_ ^ _`` ``pow`` +=============== =================== + +.. example:: + .. coqtop:: all reset + + Require Import Reals. + Check (2 + 3)%R. + Open Scope R_scope. + Check 2 + 3. + +Some tactics for real numbers ++++++++++++++++++++++++++++++ + +In addition to the powerful ``ring``, ``field`` and ``fourier`` +tactics (see Chapter :ref:`tactics`), there are also: + +.. tacn:: discrR + :name: discrR + + Proves that two real integer constants are different. + +.. example:: + .. coqtop:: all reset + + Require Import DiscrR. + Open Scope R_scope. + Goal 5 <> 0. + discrR. + +.. tacn:: split_Rabs + :name: split_Rabs + + Allows unfolding the ``Rabs`` constant and splits corresponding conjunctions. + +.. example:: + .. coqtop:: all reset + + Require Import Reals. + Open Scope R_scope. + Goal forall x:R, x <= Rabs x. + intro; split_Rabs. + +.. tacn:: split_Rmult + :name: split_Rmult + + Splits a condition that a product is non null into subgoals + corresponding to the condition on each operand of the product. + +.. example:: + .. coqtop:: all reset + + Require Import Reals. + Open Scope R_scope. + Goal forall x y z:R, x * y * z <> 0. + intros; split_Rmult. + +These tactics has been written with the tactic language Ltac +described in Chapter :ref:`thetacticlanguage`. + + +List library +~~~~~~~~~~~~ + +.. index:: + single: Notations for lists + single: length (term) + single: head (term) + single: tail (term) + single: app (term) + single: rev (term) + single: nth (term) + single: map (term) + single: flat_map (term) + single: fold_left (term) + single: fold_right (term) + +Some elementary operations on polymorphic lists are defined here. +They can be accessed by requiring module ``List``. + +It defines the following notions: + + * ``length`` + * ``head`` : first element (with default) + * ``tail`` : all but first element + * ``app`` : concatenation + * ``rev`` : reverse + * ``nth`` : accessing n-th element (with default) + * ``map`` : applying a function + * ``flat_map`` : applying a function returning lists + * ``fold_left`` : iterator (from head to tail) + * ``fold_right`` : iterator (from tail to head) + +The following table shows notations available when opening scope ``list_scope``. + +========== ============== ========== ============= +Notation Interpretation Precedence Associativity +========== ============== ========== ============= +``_ ++ _`` ``app`` 60 right +``_ :: _`` ``cons`` 60 right +========== ============== ========== ============= + +.. _userscontributions: + +Users’ contributions +-------------------- + +Numerous users' contributions have been collected and are available at +URL http://coq.inria.fr/opam/www/. On this web page, you have a list +of all contributions with informations (author, institution, quick +description, etc.) and the possibility to download them one by one. +You will also find informations on how to submit a new +contribution. diff --git a/doc/sphinx/language/gallina-extensions.rst b/doc/sphinx/language/gallina-extensions.rst new file mode 100644 index 0000000000..68066faa30 --- /dev/null +++ b/doc/sphinx/language/gallina-extensions.rst @@ -0,0 +1,2358 @@ +.. include:: ../replaces.rst + +.. _extensionsofgallina: + +Extensions of |Gallina| +======================= + +|Gallina| is the kernel language of |Coq|. We describe here extensions of +|Gallina|’s syntax. + +.. _record-types: + +Record types +---------------- + +The ``Record`` construction is a macro allowing the definition of +records as is done in many programming languages. Its syntax is +described in the grammar below. In fact, the ``Record`` macro is more general +than the usual record types, since it allows also for “manifest” +expressions. In this sense, the ``Record`` construction allows defining +“signatures”. + +.. _record_grammar: + + .. productionlist:: `sentence` + record : `record_keyword` ident [binders] [: sort] := [ident] { [`field` ; … ; `field`] }. + record_keyword : Record | Inductive | CoInductive + field : name [binders] : type [ where notation ] + : | name [binders] [: term] := term + +In the expression: + +.. cmd:: Record @ident {* @param } {? : @sort} := {? @ident} { {*; @ident {* @binder } : @term } }. + +the first identifier `ident` is the name of the defined record and `sort` is its +type. The optional identifier following ``:=`` is the name of its constructor. If it is omitted, +the default name ``Build_``\ `ident`, where `ident` is the record name, is used. If `sort` is +omitted, the default sort is `\Type`. The identifiers inside the brackets are the names of +fields. For a given field `ident`, its type is :g:`forall binder …, term`. +Remark that the type of a particular identifier may depend on a previously-given identifier. Thus the +order of the fields is important. Finally, each `param` is a parameter of the record. + +More generally, a record may have explicitly defined (a.k.a. manifest) +fields. For instance, we might have:: + + Record ident param : sort := { ident₁ : type₁ ; ident₂ := term₂ ; ident₃ : type₃ }. + +in which case the correctness of |type_3| may rely on the instance |term_2| of |ident_2| and |term_2| in turn +may depend on |ident_1|. + +.. example:: + + .. coqtop:: reset all + + Record Rat : Set := mkRat + {sign : bool; + top : nat; + bottom : nat; + Rat_bottom_cond : 0 <> bottom; + Rat_irred_cond : + forall x y z:nat, (x * y) = top /\ (x * z) = bottom -> x = 1}. + +Remark here that the fields ``Rat_bottom_cond`` depends on the field ``bottom`` and ``Rat_irred_cond`` +depends on both ``top`` and ``bottom``. + +Let us now see the work done by the ``Record`` macro. First the macro +generates a variant type definition with just one constructor: + +.. cmd:: Variant @ident {* @params} : @sort := @ident {* (@ident : @term_1)}. + +To build an object of type `ident`, one should provide the constructor +|ident_0| with the appropriate number of terms filling the fields of the record. + +.. example:: Let us define the rational :math:`1/2`: + + .. coqtop:: in + + Theorem one_two_irred : forall x y z:nat, x * y = 1 /\ x * z = 2 -> x = 1. + Admitted. + + Definition half := mkRat true 1 2 (O_S 1) one_two_irred. + Check half. + +.. _record-named-fields-grammar: + + .. productionlist:: + term : {| [`field_def` ; … ; `field_def`] |} + field_def : name [binders] := `term` + +Alternatively, the following syntax allows creating objects by using named fields, as +shown in this grammar. The fields do not have to be in any particular order, nor do they have +to be all present if the missing ones can be inferred or prompted for +(see :ref:`programs`). + +.. coqtop:: all + + Definition half' := + {| sign := true; + Rat_bottom_cond := O_S 1; + Rat_irred_cond := one_two_irred |}. + +This syntax can be disabled globally for printing by + +.. cmd:: Unset Printing Records. + +For a given type, one can override this using either + +.. cmd:: Add Printing Record @ident. + +to get record syntax or + +.. cmd:: Add Printing Constructor @ident. + +to get constructor syntax. + +This syntax can also be used for pattern matching. + +.. coqtop:: all + + Eval compute in ( + match half with + | {| sign := true; top := n |} => n + | _ => 0 + end). + +The macro generates also, when it is possible, the projection +functions for destructuring an object of type `\ident`. These +projection functions are given the names of the corresponding +fields. If a field is named `_` then no projection is built +for it. In our example: + +.. coqtop:: all + + Eval compute in top half. + Eval compute in bottom half. + Eval compute in Rat_bottom_cond half. + +An alternative syntax for projections based on a dot notation is +available: + +.. coqtop:: all + + Eval compute in half.(top). + +It can be activated for printing with + +.. cmd:: Set Printing Projections. + +.. example:: + + .. coqtop:: all + + Set Printing Projections. + Check top half. + +.. _record_projections_grammar: + + .. productionlist:: terms + term : term `.` ( qualid ) + : | term `.` ( qualid arg … arg ) + : | term `.` ( @`qualid` `term` … `term` ) + + Syntax of Record projections + +The corresponding grammar rules are given in the preceding grammar. When `qualid` +denotes a projection, the syntax `term.(qualid)` is equivalent to `qualid term`, +the syntax `term.(qualid` |arg_1| |arg_n| `)` to `qualid` |arg_1| `…` |arg_n| `term`, +and the syntax `term.(@qualid` |term_1| |term_n| `)` to `@qualid` |term_1| `…` |term_n| `term`. +In each case, `term` is the object projected and the +other arguments are the parameters of the inductive type. + +.. note::. Records defined with the ``Record`` keyword are not allowed to be + recursive (references to the record's name in the type of its field + raises an error). To define recursive records, one can use the ``Inductive`` + and ``CoInductive`` keywords, resulting in an inductive or co-inductive record. + A *caveat*, however, is that records cannot appear in mutually inductive + (or co-inductive) definitions. + +.. note:: Induction schemes are automatically generated for inductive records. + Automatic generation of induction schemes for non-recursive records + defined with the ``Record`` keyword can be activated with the + ``Nonrecursive Elimination Schemes`` option (see :ref:`TODO-13.1.1-nonrecursive-elimination-schemes`). + +.. note::``Structure`` is a synonym of the keyword ``Record``. + +.. warn:: @ident cannot be defined. + + It can happen that the definition of a projection is impossible. + This message is followed by an explanation of this impossibility. + There may be three reasons: + + #. The name `ident` already exists in the environment (see Section :ref:`TODO-1.3.1-axioms`). + #. The body of `ident` uses an incorrect elimination for + `ident` (see Sections :ref:`TODO-1.3.4-fixpoint` and :ref:`TODO-4.5.3-case-expr`). + #. The type of the projections `ident` depends on previous + projections which themselves could not be defined. + +.. exn:: Records declared with the keyword Record or Structure cannot be recursive. + + The record name `ident` appears in the type of its fields, but uses + the keyword ``Record``. Use the keyword ``Inductive`` or ``CoInductive`` instead. + +.. exn:: Cannot handle mutually (co)inductive records. + + Records cannot be defined as part of mutually inductive (or + co-inductive) definitions, whether with records only or mixed with + standard definitions. + +During the definition of the one-constructor inductive definition, all +the errors of inductive definitions, as described in Section +:ref:`TODO-1.3.3-inductive-definitions`, may also occur. + +**See also** Coercions and records in Section :ref:`TODO-18.9-coercions-and-records` of the chapter devoted to coercions. + +.. _primitive_projections: + +Primitive Projections +~~~~~~~~~~~~~~~~~~~~~ + +The option ``Set Primitive Projections`` turns on the use of primitive +projections when defining subsequent records (even through the ``Inductive`` +and ``CoInductive`` commands). Primitive projections +extended the Calculus of Inductive Constructions with a new binary +term constructor `r.(p)` representing a primitive projection `p` applied +to a record object `r` (i.e., primitive projections are always applied). +Even if the record type has parameters, these do not appear at +applications of the projection, considerably reducing the sizes of +terms when manipulating parameterized records and typechecking time. +On the user level, primitive projections can be used as a replacement +for the usual defined ones, although there are a few notable differences. + +The internally omitted parameters can be reconstructed at printing time +even though they are absent in the actual AST manipulated by the kernel. This +can be obtained by setting the ``Printing Primitive Projection Parameters`` +flag. Another compatibility printing can be activated thanks to the +``Printing Primitive Projection Compatibility`` option which governs the +printing of pattern-matching over primitive records. + +Primitive Record Types +++++++++++++++++++++++ + +When the ``Set Primitive Projections`` option is on, definitions of +record types change meaning. When a type is declared with primitive +projections, its :g:`match` construct is disabled (see :ref:`primitive_projections` though). +To eliminate the (co-)inductive type, one must use its defined primitive projections. + +For compatibility, the parameters still appear to the user when +printing terms even though they are absent in the actual AST +manipulated by the kernel. This can be changed by unsetting the +``Printing Primitive Projection Parameters`` flag. Further compatibility +printing can be deactivated thanks to the ``Printing Primitive Projection +Compatibility`` option which governs the printing of pattern-matching +over primitive records. + +There are currently two ways to introduce primitive records types: + +#. Through the ``Record`` command, in which case the type has to be + non-recursive. The defined type enjoys eta-conversion definitionally, + that is the generalized form of surjective pairing for records: + `r` ``= Build_``\ `R` ``(``\ `r`\ ``.(``\ |p_1|\ ``) …`` `r`\ ``.(``\ |p_n|\ ``))``. + Eta-conversion allows to define dependent elimination for these types as well. +#. Through the ``Inductive`` and ``CoInductive`` commands, when + the body of the definition is a record declaration of the form + ``Build_``\ `R` ``{`` |p_1| ``:`` |t_1|\ ``; … ;`` |p_n| ``:`` |t_n| ``}``. + In this case the types can be recursive and eta-conversion is disallowed. These kind of record types + differ from their traditional versions in the sense that dependent + elimination is not available for them and only non-dependent case analysis + can be defined. + +Reduction ++++++++++ + +The basic reduction rule of a primitive projection is +|p_i| ``(Build_``\ `R` |t_1| … |t_n|\ ``)`` :math:`{\rightarrow_{\iota}}` |t_i|. +However, to take the :math:`{\delta}` flag into +account, projections can be in two states: folded or unfolded. An +unfolded primitive projection application obeys the rule above, while +the folded version delta-reduces to the unfolded version. This allows to +precisely mimic the usual unfolding rules of constants. Projections +obey the usual ``simpl`` flags of the ``Arguments`` command in particular. +There is currently no way to input unfolded primitive projections at the +user-level, and one must use the ``Printing Primitive Projection Compatibility`` +to display unfolded primitive projections as matches and distinguish them from folded ones. + + +Compatibility Projections and :g:`match` +++++++++++++++++++++++++++++++++++++++++ + +To ease compatibility with ordinary record types, each primitive +projection is also defined as a ordinary constant taking parameters and +an object of the record type as arguments, and whose body is an +application of the unfolded primitive projection of the same name. These +constants are used when elaborating partial applications of the +projection. One can distinguish them from applications of the primitive +projection if the ``Printing Primitive Projection Parameters`` option +is off: For a primitive projection application, parameters are printed +as underscores while for the compatibility projections they are printed +as usual. + +Additionally, user-written :g:`match` constructs on primitive records +are desugared into substitution of the projections, they cannot be +printed back as :g:`match` constructs. + +Variants and extensions of :g:`match` +------------------------------------- + +.. _extended pattern-matching: + +Multiple and nested pattern-matching +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The basic version of :g:`match` allows pattern-matching on simple +patterns. As an extension, multiple nested patterns or disjunction of +patterns are allowed, as in ML-like languages. + +The extension just acts as a macro that is expanded during parsing +into a sequence of match on simple patterns. Especially, a +construction defined using the extended match is generally printed +under its expanded form (see ``Set Printing Matching`` in :ref:`controlling-match-pp`). + +See also: :ref:`extended pattern-matching`. + + +Pattern-matching on boolean values: the if expression +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For inductive types with exactly two constructors and for pattern-matching +expressions that do not depend on the arguments of the constructors, it is possible +to use a ``if … then … else`` notation. For instance, the definition + +.. coqtop:: all + + Definition not (b:bool) := + match b with + | true => false + | false => true + end. + +can be alternatively written + +.. coqtop:: reset all + + Definition not (b:bool) := if b then false else true. + +More generally, for an inductive type with constructors |C_1| and |C_2|, +we have the following equivalence + +:: + + if term [dep_ret_type] then term₁ else term₂ ≡ + match term [dep_ret_type] with + | C₁ _ … _ => term₁ + | C₂ _ … _ => term₂ + end + +.. example:: + + .. coqtop:: all + + Check (fun x (H:{x=0}+{x<>0}) => + match H with + | left _ => true + | right _ => false + end). + +Notice that the printing uses the :g:`if` syntax because `sumbool` is +declared as such (see :ref:`controlling-match-pp`). + + +Irrefutable patterns: the destructuring let variants +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Pattern-matching on terms inhabiting inductive type having only one +constructor can be alternatively written using :g:`let … in …` +constructions. There are two variants of them. + + +First destructuring let syntax +++++++++++++++++++++++++++++++ + +The expression :g:`let (`\ |ident_1|:g:`, … ,` |ident_n|\ :g:`) :=` |term_0|\ :g:`in` |term_1| performs +case analysis on |term_0| which must be in an inductive type with one +constructor having itself :math:`n` arguments. Variables |ident_1| … |ident_n| are +bound to the :math:`n` arguments of the constructor in expression |term_1|. For +instance, the definition + +.. coqtop:: reset all + + Definition fst (A B:Set) (H:A * B) := match H with + | pair x y => x + end. + +can be alternatively written + +.. coqtop:: reset all + + Definition fst (A B:Set) (p:A * B) := let (x, _) := p in x. + +Notice that reduction is different from regular :g:`let … in …` +construction since it happens only if |term_0| is in constructor form. +Otherwise, the reduction is blocked. + +The pretty-printing of a definition by matching on a irrefutable +pattern can either be done using :g:`match` or the :g:`let` construction +(see Section :ref:`controlling-match-pp`). + +If term inhabits an inductive type with one constructor `C`, we have an +equivalence between + +:: + + let (ident₁, …, identₙ) [dep_ret_type] := term in term' + +and + +:: + + match term [dep_ret_type] with + C ident₁ … identₙ => term' + end + + +Second destructuring let syntax ++++++++++++++++++++++++++++++++ + +Another destructuring let syntax is available for inductive types with +one constructor by giving an arbitrary pattern instead of just a tuple +for all the arguments. For example, the preceding example can be +written: + +.. coqtop:: reset all + + Definition fst (A B:Set) (p:A*B) := let 'pair x _ := p in x. + +This is useful to match deeper inside tuples and also to use notations +for the pattern, as the syntax :g:`let ’p := t in b` allows arbitrary +patterns to do the deconstruction. For example: + +.. coqtop:: all + + Definition deep_tuple (A:Set) (x:(A*A)*(A*A)) : A*A*A*A := + let '((a,b), (c, d)) := x in (a,b,c,d). + + Notation " x 'With' p " := (exist _ x p) (at level 20). + + Definition proj1_sig' (A:Set) (P:A->Prop) (t:{ x:A | P x }) : A := + let 'x With p := t in x. + +When printing definitions which are written using this construct it +takes precedence over let printing directives for the datatype under +consideration (see Section :ref:`controlling-match-pp`). + + +.. _controlling-match-pp: + +Controlling pretty-printing of match expressions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following commands give some control over the pretty-printing +of :g:`match` expressions. + +Printing nested patterns ++++++++++++++++++++++++++ + +The Calculus of Inductive Constructions knows pattern-matching only +over simple patterns. It is however convenient to re-factorize nested +pattern-matching into a single pattern-matching over a nested +pattern. |Coq|’s printer tries to do such limited re-factorization. + +.. cmd:: Set Printing Matching. + +This tells |Coq| to try to use nested patterns. This is the default +behavior. + +.. cmd:: Unset Printing Matching. + +This tells |Coq| to print only simple pattern-matching problems in the +same way as the |Coq| kernel handles them. + +.. cmd:: Test Printing Matching. + +This tells if the printing matching mode is on or off. The default is +on. + +Factorization of clauses with same right-hand side +++++++++++++++++++++++++++++++++++++++++++++++++++ + +When several patterns share the same right-hand side, it is additionally +possible to share the clauses using disjunctive patterns. Assuming that the +printing matching mode is on, whether |Coq|'s printer shall try to do this kind +of factorization is governed by the following commands: + +.. cmd:: Set Printing Factorizable Match Patterns. + +This tells |Coq|'s printer to try to use disjunctive patterns. This is the +default behavior. + +.. cmd:: Unset Printing Factorizable Match Patterns. + +This tells |Coq|'s printer not to try to use disjunctive patterns. + +.. cmd:: Test Printing Factorizable Match Patterns. + +This tells if the factorization of clauses with same right-hand side is on or +off. + +Use of a default clause ++++++++++++++++++++++++ + +When several patterns share the same right-hand side which do not depend on the +arguments of the patterns, yet an extra factorization is possible: the +disjunction of patterns can be replaced with a `_` default clause. Assuming that +the printing matching mode and the factorization mode are on, whether |Coq|'s +printer shall try to use a default clause is governed by the following commands: + +.. cmd:: Set Printing Allow Default Clause. + +This tells |Coq|'s printer to use a default clause when relevant. This is the +default behavior. + +.. cmd:: Unset Printing Allow Default Clause. + +This tells |Coq|'s printer not to use a default clause. + +.. cmd:: Test Printing Allow Default Clause. + +This tells if the use of a default clause is allowed. + +Printing of wildcard patterns +++++++++++++++++++++++++++++++ + +Some variables in a pattern may not occur in the right-hand side of +the pattern-matching clause. There are options to control the display +of these variables. + +.. cmd:: Set Printing Wildcard. + +The variables having no occurrences in the right-hand side of the +pattern-matching clause are just printed using the wildcard symbol +“_”. + +.. cmd:: Unset Printing Wildcard. + +The variables, even useless, are printed using their usual name. But +some non-dependent variables have no name. These ones are still +printed using a “_”. + +.. cmd:: Test Printing Wildcard. + +This tells if the wildcard printing mode is on or off. The default is +to print wildcard for useless variables. + + +Printing of the elimination predicate ++++++++++++++++++++++++++++++++++++++ + +In most of the cases, the type of the result of a matched term is +mechanically synthesizable. Especially, if the result type does not +depend of the matched term. + +.. cmd:: Set Printing Synth. + +The result type is not printed when |Coq| knows that it can re- +synthesize it. + +.. cmd:: Unset Printing Synth. + +This forces the result type to be always printed. + +.. cmd:: Test Printing Synth. + +This tells if the non-printing of synthesizable types is on or off. +The default is to not print synthesizable types. + + +Printing matching on irrefutable patterns +++++++++++++++++++++++++++++++++++++++++++ + +If an inductive type has just one constructor, pattern-matching can be +written using the first destructuring let syntax. + +.. cmd:: Add Printing Let @ident. + + This adds `ident` to the list of inductive types for which pattern-matching + is written using a let expression. + +.. cmd:: Remove Printing Let @ident. + + This removes ident from this list. Note that removing an inductive + type from this list has an impact only for pattern-matching written + using :g:`match`. Pattern-matching explicitly written using a destructuring + :g:`let` are not impacted. + +.. cmd:: Test Printing Let for @ident. + + This tells if `ident` belongs to the list. + +.. cmd:: Print Table Printing Let. + + This prints the list of inductive types for which pattern-matching is + written using a let expression. + + The list of inductive types for which pattern-matching is written + using a :g:`let` expression is managed synchronously. This means that it is + sensitive to the command ``Reset``. + + +Printing matching on booleans ++++++++++++++++++++++++++++++ + +If an inductive type is isomorphic to the boolean type, pattern-matching +can be written using ``if`` … ``then`` … ``else`` …: + +.. cmd:: Add Printing If @ident. + + This adds ident to the list of inductive types for which pattern-matching is + written using an if expression. + +.. cmd:: Remove Printing If @ident. + + This removes ident from this list. + +.. cmd:: Test Printing If for @ident. + + This tells if ident belongs to the list. + +.. cmd:: Print Table Printing If. + + This prints the list of inductive types for which pattern-matching is + written using an if expression. + +The list of inductive types for which pattern-matching is written +using an ``if`` expression is managed synchronously. This means that it is +sensitive to the command ``Reset``. + +This example emphasizes what the printing options offer. + +.. example:: + + .. coqtop:: all + + Definition snd (A B:Set) (H:A * B) := match H with + | pair x y => y + end. + + Test Printing Let for prod. + + Print snd. + + Remove Printing Let prod. + + Unset Printing Synth. + + Unset Printing Wildcard. + + Print snd. + +.. _advanced-recursive-functions: + +Advanced recursive functions +---------------------------- + +The following experimental command is available when the ``FunInd`` library has been loaded via ``Require Import FunInd``: + +.. cmd:: Function @ident {* @binder} { @decrease_annot } : @type := @term. + +This command can be seen as a generalization of ``Fixpoint``. It is actually a wrapper +for several ways of defining a function *and other useful related +objects*, namely: an induction principle that reflects the recursive +structure of the function (see Section :ref:`TODO-8.5.5-functional-induction`) and its fixpoint equality. +The meaning of this declaration is to define a function ident, +similarly to ``Fixpoint`. Like in ``Fixpoint``, the decreasing argument must +be given (unless the function is not recursive), but it might not +necessarily be *structurally* decreasing. The point of the {} annotation +is to name the decreasing argument *and* to describe which kind of +decreasing criteria must be used to ensure termination of recursive +calls. + +The ``Function`` construction also enjoys the ``with`` extension to define +mutually recursive definitions. However, this feature does not work +for non structurally recursive functions. + +See the documentation of functional induction (:ref:`TODO-8.5.5-functional-induction`) +and ``Functional Scheme`` (:ref:`TODO-13.2-functional-scheme`) for how to use +the induction principle to easily reason about the function. + +Remark: To obtain the right principle, it is better to put rigid +parameters of the function as first arguments. For example it is +better to define plus like this: + +.. coqtop:: reset none + + Require Import FunInd. + +.. coqtop:: all + + Function plus (m n : nat) {struct n} : nat := + match n with + | 0 => m + | S p => S (plus m p) + end. + +than like this: + +.. coqtop:: reset all + + Function plus (n m : nat) {struct n} : nat := + match n with + | 0 => m + | S p => S (plus p m) + end. + + +*Limitations* + +|term_0| must be built as a *pure pattern-matching tree* (:g:`match … with`) +with applications only *at the end* of each branch. + +Function does not support partial application of the function being +defined. Thus, the following example cannot be accepted due to the +presence of partial application of `wrong` in the body of +`wrong` : + +.. coqtop:: all + + Fail Function wrong (C:nat) : nat := + List.hd 0 (List.map wrong (C::nil)). + +For now, dependent cases are not treated for non structurally +terminating functions. + +.. exn:: The recursive argument must be specified +.. exn:: No argument name @ident +.. exn:: Cannot use mutual definition with well-founded recursion or measure + +.. warn:: Cannot define graph for @ident + + The generation of the graph relation (`R_ident`) used to compute the induction scheme of ident + raised a typing error. Only `ident` is defined; the induction scheme + will not be generated. This error happens generally when: + + - the definition uses pattern matching on dependent types, + which ``Function`` cannot deal with yet. + - the definition is not a *pattern-matching tree* as explained above. + +.. warn:: Cannot define principle(s) for @ident + + The generation of the graph relation (`R_ident`) succeeded but the induction principle + could not be built. Only `ident` is defined. Please report. + +.. warn:: Cannot build functional inversion principle + + `functional inversion` will not be available for the function. + +See also: :ref:`TODO-13.2-generating-ind-principles` and ref:`TODO-8.5.5-functional-induction` + +Depending on the ``{…}`` annotation, different definition mechanisms are +used by ``Function``. A more precise description is given below. + +.. cmdv:: Function @ident {* @binder } : @type := @term + + Defines the not recursive function `ident` as if declared with `Definition`. Moreover + the following are defined: + + + `ident_rect`, `ident_rec` and `ident_ind`, which reflect the pattern + matching structure of `term` (see the documentation of :ref:`TODO-1.3.3-Inductive`); + + The inductive `R_ident` corresponding to the graph of `ident` (silently); + + `ident_complete` and `ident_correct` which are inversion information + linking the function and its graph. + +.. cmdv:: Function @ident {* @binder } { struct @ident } : @type := @term + + Defines the structural recursive function `ident` as if declared with ``Fixpoint``. Moreover the following are defined: + + + The same objects as above; + + The fixpoint equation of `ident`: `ident_equation`. + +.. cmdv:: Function @ident {* @binder } { measure @term @ident } : @type := @term +.. cmdv:: Function @ident {* @binder } { wf @term @ident } : @type := @term + + Defines a recursive function by well-founded recursion. The module ``Recdef`` + of the standard library must be loaded for this feature. The ``{}`` + annotation is mandatory and must be one of the following: + + + ``{measure`` `term` `ident` ``}`` with `ident` being the decreasing argument + and `term` being a function from type of `ident` to ``nat`` for which + value on the decreasing argument decreases (for the ``lt`` order on ``nat``) + at each recursive call of `term`. Parameters of the function are + bound in `term`\ ; + + ``{wf`` `term` `ident` ``}`` with `ident` being the decreasing argument and + `term` an ordering relation on the type of `ident` (i.e. of type + `T`\ :math:`_{\sf ident}` → `T`\ :math:`_{\sf ident}` → ``Prop``) for which the decreasing argument + decreases at each recursive call of `term`. The order must be well-founded. + Parameters of the function are bound in `term`. + + Depending on the annotation, the user is left with some proof + obligations that will be used to define the function. These proofs + are: proofs that each recursive call is actually decreasing with + respect to the given criteria, and (if the criteria is `wf`) a proof + that the ordering relation is well-founded. Once proof obligations are + discharged, the following objects are defined: + + + The same objects as with the struct; + + The lemma `ident`\ :math:`_{\sf tcc}` which collects all proof obligations in one + property; + + The lemmas `ident`\ :math:`_{\sf terminate}` and `ident`\ :math:`_{\sf F}` which is needed to be inlined + during extraction of ident. + + The way this recursive function is defined is the subject of several + papers by Yves Bertot and Antonia Balaa on the one hand, and Gilles + Barthe, Julien Forest, David Pichardie, and Vlad Rusu on the other + hand. Remark: Proof obligations are presented as several subgoals + belonging to a Lemma `ident`\ :math:`_{\sf tcc}`. + + +Section mechanism +----------------- + +The sectioning mechanism can be used to to organize a proof in +structured sections. Then local declarations become available (see +Section :ref:`TODO-1.3.2-Definitions`). + + +.. cmd:: Section @ident. + + This command is used to open a section named `ident`. + + +.. cmd:: End @ident. + + This command closes the section named `ident`. After closing of the + section, the local declarations (variables and local definitions) get + *discharged*, meaning that they stop being visible and that all global + objects defined in the section are generalized with respect to the + variables and local definitions they each depended on in the section. + + .. example:: + + .. coqtop:: all + + Section s1. + + Variables x y : nat. + + Let y' := y. + + Definition x' := S x. + + Definition x'' := x' + y'. + + Print x'. + + End s1. + + Print x'. + + Print x''. + + Notice the difference between the value of `x’` and `x’’` inside section + `s1` and outside. + + .. exn:: This is not the last opened section + +**Remarks:** + +#. Most commands, like ``Hint``, ``Notation``, option management, … which + appear inside a section are canceled when the section is closed. + + +Module system +------------- + +The module system provides a way of packaging related elements +together, as well as a means of massive abstraction. + + .. productionlist:: modules + module_type : qualid + : | `module_type` with Definition qualid := term + : | `module_type` with Module qualid := qualid + : | qualid qualid … qualid + : | !qualid qualid … qualid + module_binding : ( [Import|Export] ident … ident : module_type ) + module_bindings : `module_binding` … `module_binding` + module_expression : qualid … qualid + : | !qualid … qualid + + Syntax of modules + +In the syntax of module application, the ! prefix indicates that any +`Inline` directive in the type of the functor arguments will be ignored +(see :ref:`named_module_type` below). + + +.. cmd:: Module @ident. + + This command is used to start an interactive module named `ident`. + +.. cmdv:: Module @ident {* @module_binding}. + + Starts an interactive functor with + parameters given by module_bindings. + +.. cmdv:: Module @ident : @module_type. + + Starts an interactive module specifying its module type. + +.. cmdv:: Module @ident {* @module_binding} : @module_type. + + Starts an interactive functor with parameters given by the list of `module binding`, and output module + type `module_type`. + +.. cmdv:: Module @ident <: {+<: @module_type }. + + Starts an interactive module satisfying each `module_type`. + + .. cmdv:: Module @ident {* @module_binding} <: {+<; @module_type }. + + Starts an interactive functor with parameters given by the list of `module_binding`. The output module type + is verified against each `module_type`. + +.. cmdv:: Module [ Import | Export ]. + + Behaves like ``Module``, but automatically imports or exports the module. + +Reserved commands inside an interactive module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. cmd:: Include @module. + + Includes the content of module in the current + interactive module. Here module can be a module expression or a module + type expression. If module is a high-order module or module type + expression then the system tries to instantiate module by the current + interactive module. + +.. cmd:: Include {+<+ @module}. + + is a shortcut for the commands ``Include`` `module` for each `module`. + +.. cmd:: End @ident. + + This command closes the interactive module `ident`. If the module type + was given the content of the module is matched against it and an error + is signaled if the matching fails. If the module is basic (is not a + functor) its components (constants, inductive types, submodules etc.) + are now available through the dot notation. + + .. exn:: No such label @ident + + .. exn:: Signature components for label @ident do not match + + .. exn:: This is not the last opened module + +.. cmd:: Module @ident := @module_expression. + + This command defines the module identifier `ident` to be equal + to `module_expression`. + + .. cmdv:: Module @ident {* @module_binding} := @module_expression. + + Defines a functor with parameters given by the list of `module_binding` and body `module_expression`. + + .. cmdv:: Module @ident {* @module_binding} : @module_type := @module_expression. + + Defines a functor with parameters given by the list of `module_binding` (possibly none), and output module type `module_type`, + with body `module_expression`. + + .. cmdv:: Module @ident {* @module_binding} <: {+<: @module_type} := @module_expression. + + Defines a functor with parameters given by module_bindings (possibly none) with body `module_expression`. + The body is checked against each |module_type_i|. + + .. cmdv:: Module @ident {* @module_binding} := {+<+ @module_expression}. + + is equivalent to an interactive module where each `module_expression` is included. + +.. _named_module_type: + +.. cmd:: Module Type @ident. + +This command is used to start an interactive module type `ident`. + + .. cmdv:: Module Type @ident {* @module_binding}. + + Starts an interactive functor type with parameters given by `module_bindings`. + + +Reserved commands inside an interactive module type: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. cmd:: Include @module. + + Same as ``Include`` inside a module. + +.. cmd:: Include {+<+ @module}. + + is a shortcut for the command ``Include`` `module` for each `module`. + +.. cmd:: @assumption_keyword Inline @assums. + + The instance of this assumption will be automatically expanded at functor application, except when + this functor application is prefixed by a ``!`` annotation. + +.. cmd:: End @ident. + + This command closes the interactive module type `ident`. + + .. exn:: This is not the last opened module type + +.. cmd:: Module Type @ident := @module_type. + + Defines a module type `ident` equal to `module_type`. + + .. cmdv:: Module Type @ident {* @module_binding} := @module_type. + + Defines a functor type `ident` specifying functors taking arguments `module_bindings` and + returning `module_type`. + + .. cmdv:: Module Type @ident {* @module_binding} := {+<+ @module_type }. + + is equivalent to an interactive module type were each `module_type` is included. + +.. cmd:: Declare Module @ident : @module_type. + + Declares a module `ident` of type `module_type`. + + .. cmdv:: Declare Module @ident {* @module_binding} : @module_type. + + Declares a functor with parameters given by the list of `module_binding` and output module type + `module_type`. + +.. example:: + + Let us define a simple module. + + .. coqtop:: all + + Module M. + + Definition T := nat. + + Definition x := 0. + + Definition y : bool. + + exact true. + + Defined. + + End M. + +Inside a module one can define constants, prove theorems and do any +other things that can be done in the toplevel. Components of a closed +module can be accessed using the dot notation: + +.. coqtop:: all + + Print M.x. + +A simple module type: + +.. coqtop:: all + + Module Type SIG. + + Parameter T : Set. + + Parameter x : T. + + End SIG. + +Now we can create a new module from M, giving it a less precise +specification: the y component is dropped as well as the body of x. + +.. coqtop:: all + + Module N : SIG with Definition T := nat := M. + + Print N.T. + + Print N.x. + + Fail Print N.y. + +.. reset to remove N (undo in last coqtop block doesn't seem to do that), invisibly redefine M, SIG +.. coqtop:: none reset + + Module M. + + Definition T := nat. + + Definition x := 0. + + Definition y : bool. + + exact true. + + Defined. + + End M. + + Module Type SIG. + + Parameter T : Set. + + Parameter x : T. + + End SIG. + +The definition of ``N`` using the module type expression ``SIG`` with +``Definition T := nat`` is equivalent to the following one: + +.. coqtop:: all + + Module Type SIG'. + + Definition T : Set := nat. + + Parameter x : T. + + End SIG'. + + Module N : SIG' := M. + +If we just want to be sure that the our implementation satisfies a +given module type without restricting the interface, we can use a +transparent constraint + +.. coqtop:: all + + Module P <: SIG := M. + + Print P.y. + +Now let us create a functor, i.e. a parametric module + +.. coqtop:: all + + Module Two (X Y: SIG). + + Definition T := (X.T * Y.T)%type. + + Definition x := (X.x, Y.x). + + End Two. + +and apply it to our modules and do some computations: + +.. coqtop:: all + + Module Q := Two M N. + + Eval compute in (fst Q.x + snd Q.x). + +In the end, let us define a module type with two sub-modules, sharing +some of the fields and give one of its possible implementations: + +.. coqtop:: all + + Module Type SIG2. + + Declare Module M1 : SIG. + + Module M2 <: SIG. + + Definition T := M1.T. + + Parameter x : T. + + End M2. + + End SIG2. + + Module Mod <: SIG2. + + Module M1. + + Definition T := nat. + + Definition x := 1. + + End M1. + + Module M2 := M. + + End Mod. + +Notice that ``M`` is a correct body for the component ``M2`` since its ``T`` +component is equal ``nat`` and hence ``M1.T`` as specified. + +**Remarks:** + +#. Modules and module types can be nested components of each other. +#. One can have sections inside a module or a module type, but not a + module or a module type inside a section. +#. Commands like ``Hint`` or ``Notation`` can also appear inside modules and + module types. Note that in case of a module definition like: + +:: + + Module N : SIG := M. + +or:: + + Module N : SIG. … End N. + +hints and the like valid for ``N`` are not those defined in ``M`` (or the module body) but the ones defined +in ``SIG``. + + +.. _import_qualid: + +.. cmd:: Import @qualid. + + If `qualid` denotes a valid basic module (i.e. its module type is a + signature), makes its components available by their short names. + +.. example:: + + .. coqtop:: reset all + + Module Mod. + + Definition T:=nat. + + Check T. + + End Mod. + + Check Mod.T. + + Fail Check T. + + Import Mod. + + Check T. + +Some features defined in modules are activated only when a module is +imported. This is for instance the case of notations (see :ref:`TODO-12.1-Notations`). + +Declarations made with the Local flag are never imported by theImport +command. Such declarations are only accessible through their fully +qualified name. + +.. example:: + + .. coqtop:: all + + Module A. + + Module B. + + Local Definition T := nat. + + End B. + + End A. + + Import A. + + Fail Check B.T. + + .. cmdv:: Export @qualid + + When the module containing the command Export qualid + is imported, qualid is imported as well. + + .. exn:: @qualid is not a module + + .. warn:: Trying to mask the absolute name @qualid! + +.. cmd:: Print Module @ident. + + Prints the module type and (optionally) the body of the module `ident`. + +.. cmd:: Print Module Type @ident. + + Prints the module type corresponding to `ident`. + +.. opt:: Short Module Printing + + This option (off by default) disables the printing of the types of fields, + leaving only their names, for the commands ``Print Module`` and ``Print Module Type``. + +.. cmd:: Locate Module @qualid. + + Prints the full name of the module `qualid`. + +Libraries and qualified names +--------------------------------- + +Names of libraries +~~~~~~~~~~~~~~~~~~ + +The theories developed in |Coq| are stored in *library files* which are +hierarchically classified into *libraries* and *sublibraries*. To +express this hierarchy, library names are represented by qualified +identifiers qualid, i.e. as list of identifiers separated by dots (see +:ref:`TODO-1.2.3-identifiers`). For instance, the library file ``Mult`` of the standard +|Coq| library ``Arith`` is named ``Coq.Arith.Mult``. The identifier that starts +the name of a library is called a *library root*. All library files of +the standard library of |Coq| have the reserved root |Coq| but library +file names based on other roots can be obtained by using |Coq| commands +(coqc, coqtop, coqdep, …) options ``-Q`` or ``-R`` (see :ref:`TODO-14.3.3-command-line-options`). +Also, when an interactive |Coq| session starts, a library of root ``Top`` is +started, unless option ``-top`` or ``-notop`` is set (see :ref:`TODO-14.3.3-command-line-options`). + + +Qualified names +~~~~~~~~~~~~~~~ + +Library files are modules which possibly contain submodules which +eventually contain constructions (axioms, parameters, definitions, +lemmas, theorems, remarks or facts). The *absolute name*, or *full +name*, of a construction in some library file is a qualified +identifier starting with the logical name of the library file, +followed by the sequence of submodules names encapsulating the +construction and ended by the proper name of the construction. +Typically, the absolute name ``Coq.Init.Logic.eq`` denotes Leibniz’ +equality defined in the module Logic in the sublibrary ``Init`` of the +standard library of |Coq|. + +The proper name that ends the name of a construction is the short name +(or sometimes base name) of the construction (for instance, the short +name of ``Coq.Init.Logic.eq`` is ``eq``). Any partial suffix of the absolute +name is a *partially qualified name* (e.g. ``Logic.eq`` is a partially +qualified name for ``Coq.Init.Logic.eq``). Especially, the short name of a +construction is its shortest partially qualified name. + +|Coq| does not accept two constructions (definition, theorem, …) with +the same absolute name but different constructions can have the same +short name (or even same partially qualified names as soon as the full +names are different). + +Notice that the notion of absolute, partially qualified and short +names also applies to library file names. + +**Visibility** + +|Coq| maintains a table called the name table which maps partially qualified +names of constructions to absolute names. This table is updated by the +commands ``Require`` (see :ref:`TODO-6.5.1-Require`), Import and Export (see :ref:`import_qualid`) and +also each time a new declaration is added to the context. An absolute +name is called visible from a given short or partially qualified name +when this latter name is enough to denote it. This means that the +short or partially qualified name is mapped to the absolute name in +|Coq| name table. Definitions flagged as Local are only accessible with +their fully qualified name (see :ref:`TODO-1.3.2-definitions`). + +It may happen that a visible name is hidden by the short name or a +qualified name of another construction. In this case, the name that +has been hidden must be referred to using one more level of +qualification. To ensure that a construction always remains +accessible, absolute names can never be hidden. + +.. example:: + + .. coqtop:: all + + Check 0. + + Definition nat := bool. + + Check 0. + + Check Datatypes.nat. + + Locate nat. + +See also: Command Locate in :ref:`TODO-6.3.10-locate-qualid` and Locate Library in +:ref:`TODO-6.6.11-locate-library`. + + +Libraries and filesystem +~~~~~~~~~~~~~~~~~~~~~~~~ + +Please note that the questions described here have been subject to +redesign in |Coq| v8.5. Former versions of |Coq| use the same terminology +to describe slightly different things. + +Compiled files (``.vo`` and ``.vio``) store sub-libraries. In order to refer +to them inside |Coq|, a translation from file-system names to |Coq| names +is needed. In this translation, names in the file system are called +*physical* paths while |Coq| names are contrastingly called *logical* +names. + +A logical prefix Lib can be associated to a physical pathpath using +the command line option ``-Q`` `path` ``Lib``. All subfolders of path are +recursively associated to the logical path ``Lib`` extended with the +corresponding suffix coming from the physical path. For instance, the +folder ``path/fOO/Bar`` maps to ``Lib.fOO.Bar``. Subdirectories corresponding +to invalid |Coq| identifiers are skipped, and, by convention, +subdirectories named ``CVS`` or ``_darcs`` are skipped too. + +Thanks to this mechanism, .vo files are made available through the +logical name of the folder they are in, extended with their own +basename. For example, the name associated to the file +``path/fOO/Bar/File.vo`` is ``Lib.fOO.Bar.File``. The same caveat applies for +invalid identifiers. When compiling a source file, the ``.vo`` file stores +its logical name, so that an error is issued if it is loaded with the +wrong loadpath afterwards. + +Some folders have a special status and are automatically put in the +path. |Coq| commands associate automatically a logical path to files in +the repository trees rooted at the directory from where the command is +launched, coqlib/user-contrib/, the directories listed in the +`$COQPATH`, `${XDG_DATA_HOME}/coq/` and `${XDG_DATA_DIRS}/coq/` +environment variables (see`http://standards.freedesktop.org/basedir- +spec/basedir-spec-latest.html`_) with the same physical-to-logical +translation and with an empty logical prefix. + +The command line option ``-R`` is a variant of ``-Q`` which has the strictly +same behavior regarding loadpaths, but which also makes the +corresponding ``.vo`` files available through their short names in a way +not unlike the ``Import`` command (see :ref:`import_qualid`). For instance, ``-R`` `path` ``Lib`` +associates to the ``filepath/fOO/Bar/File.vo`` the logical name +``Lib.fOO.Bar.File``, but allows this file to be accessed through the +short names ``fOO.Bar.File,Bar.File`` and ``File``. If several files with +identical base name are present in different subdirectories of a +recursive loadpath, which of these files is found first may be system- +dependent and explicit qualification is recommended. The ``From`` argument +of the ``Require`` command can be used to bypass the implicit shortening +by providing an absolute root to the required file (see :ref:`TODO-6.5.1-require-qualid`). + +There also exists another independent loadpath mechanism attached to +OCaml object files (``.cmo`` or ``.cmxs``) rather than |Coq| object +files as described above. The OCaml loadpath is managed using +the option ``-I`` `path` (in the OCaml world, there is neither a +notion of logical name prefix nor a way to access files in +subdirectories of path). See the command ``Declare`` ``ML`` ``Module`` in +:ref:`TODO-6.5-compiled-files` to understand the need of the OCaml loadpath. + +See :ref:`TODO-14.3.3-command-line-options` for a more general view over the |Coq| command +line options. + + +Implicit arguments +------------------ + +An implicit argument of a function is an argument which can be +inferred from contextual knowledge. There are different kinds of +implicit arguments that can be considered implicit in different ways. +There are also various commands to control the setting or the +inference of implicit arguments. + + +The different kinds of implicit arguments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Implicit arguments inferable from the knowledge of other arguments of a function +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The first kind of implicit arguments covers the arguments that are +inferable from the knowledge of the type of other arguments of the +function, or of the type of the surrounding context of the +application. Especially, such implicit arguments correspond to +parameters dependent in the type of the function. Typical implicit +arguments are the type arguments in polymorphic functions. There are +several kinds of such implicit arguments. + +**Strict Implicit Arguments** + +An implicit argument can be either strict or non strict. An implicit +argument is said to be *strict* if, whatever the other arguments of the +function are, it is still inferable from the type of some other +argument. Technically, an implicit argument is strict if it +corresponds to a parameter which is not applied to a variable which +itself is another parameter of the function (since this parameter may +erase its arguments), not in the body of a match, and not itself +applied or matched against patterns (since the original form of the +argument can be lost by reduction). + +For instance, the first argument of +:: + + cons: forall A:Set, A -> list A -> list A + +in module ``List.v`` is strict because :g:`list` is an inductive type and :g:`A` +will always be inferable from the type :g:`list A` of the third argument of +:g:`cons`. On the contrary, the second argument of a term of type +:: + + forall P:nat->Prop, forall n:nat, P n -> ex nat P + +is implicit but not strict, since it can only be inferred from the +type :g:`P n` of the third argument and if :g:`P` is, e.g., :g:`fun _ => True`, it +reduces to an expression where ``n`` does not occur any longer. The first +argument :g:`P` is implicit but not strict either because it can only be +inferred from :g:`P n` and :g:`P` is not canonically inferable from an arbitrary +:g:`n` and the normal form of :g:`P n`. Consider, e.g., that :g:`n` is :math:`0` and the third +argument has type :g:`True`, then any :g:`P` of the form +:: + + fun n => match n with 0 => True | _ => anything end + +would be a solution of the inference problem. + +**Contextual Implicit Arguments** + +An implicit argument can be *contextual* or not. An implicit argument +is said *contextual* if it can be inferred only from the knowledge of +the type of the context of the current expression. For instance, the +only argument of:: + + nil : forall A:Set, list A` + +is contextual. Similarly, both arguments of a term of type:: + + forall P:nat->Prop, forall n:nat, P n \/ n = 0 + +are contextual (moreover, :g:`n` is strict and :g:`P` is not). + +**Reversible-Pattern Implicit Arguments** + +There is another class of implicit arguments that can be reinferred +unambiguously if all the types of the remaining arguments are known. +This is the class of implicit arguments occurring in the type of +another argument in position of reversible pattern, which means it is +at the head of an application but applied only to uninstantiated +distinct variables. Such an implicit argument is called *reversible- +pattern implicit argument*. A typical example is the argument :g:`P` of +nat_rec in +:: + + nat_rec : forall P : nat -> Set, P 0 -> + (forall n : nat, P n -> P (S n)) -> forall x : nat, P x + +(:g:`P` is reinferable by abstracting over :g:`n` in the type :g:`P n`). + +See :ref:`controlling-rev-pattern-implicit-args` for the automatic declaration of reversible-pattern +implicit arguments. + +Implicit arguments inferable by resolution +++++++++++++++++++++++++++++++++++++++++++ + +This corresponds to a class of non-dependent implicit arguments that +are solved based on the structure of their type only. + + +Maximal or non maximal insertion of implicit arguments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In case a function is partially applied, and the next argument to be +applied is an implicit argument, two disciplines are applicable. In +the first case, the function is considered to have no arguments +furtherly: one says that the implicit argument is not maximally +inserted. In the second case, the function is considered to be +implicitly applied to the implicit arguments it is waiting for: one +says that the implicit argument is maximally inserted. + +Each implicit argument can be declared to have to be inserted +maximally or non maximally. This can be governed argument per argument +by the command ``Implicit Arguments`` (see Section :ref:`declare-implicit-args`) or globally by the +command ``Set Maximal Implicit Insertion`` (see Section :ref:`controlling-insertion-implicit-args`). +See also :ref:`displaying-implicit-args`. + + +Casual use of implicit arguments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In a given expression, if it is clear that some argument of a function +can be inferred from the type of the other arguments, the user can +force the given argument to be guessed by replacing it by “_”. If +possible, the correct argument will be automatically generated. + +.. exn:: Cannot infer a term for this placeholder. + + |Coq| was not able to deduce an instantiation of a “_”. + +.. _declare-implicit-args: + +Declaration of implicit arguments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In case one wants that some arguments of a given object (constant, +inductive types, constructors, assumptions, local or not) are always +inferred by |Coq|, one may declare once and for all which are the +expected implicit arguments of this object. There are two ways to do +this, *a priori* and *a posteriori*. + + +Implicit Argument Binders ++++++++++++++++++++++++++ + +In the first setting, one wants to explicitly give the implicit +arguments of a declared object as part of its definition. To do this, +one has to surround the bindings of implicit arguments by curly +braces: + +.. coqtop:: all + + Definition id {A : Type} (x : A) : A := x. + +This automatically declares the argument A of id as a maximally +inserted implicit argument. One can then do as-if the argument was +absent in every situation but still be able to specify it if needed: + +.. coqtop:: all + + Definition compose {A B C} (g : B -> C) (f : A -> B) := fun x => g (f x). + + Goal forall A, compose id id = id (A:=A). + + +The syntax is supported in all top-level definitions: +``Definition``, ``Fixpoint``, ``Lemma`` and so on. For (co-)inductive datatype +declarations, the semantics are the following: an inductive parameter +declared as an implicit argument need not be repeated in the inductive +definition but will become implicit for the constructors of the +inductive only, not the inductive type itself. For example: + +.. coqtop:: all + + Inductive list {A : Type} : Type := + | nil : list + | cons : A -> list -> list. + + Print list. + +One can always specify the parameter if it is not uniform using the +usual implicit arguments disambiguation syntax. + + +Declaring Implicit Arguments +++++++++++++++++++++++++++++ + +To set implicit arguments *a posteriori*, one can use the command: + +.. cmd:: Arguments @qualid {* @possibly_bracketed_ident }. + +where the list of `possibly_bracketed_ident` is a prefix of the list of +arguments of `qualid` where the ones to be declared implicit are +surrounded by square brackets and the ones to be declared as maximally +inserted implicits are surrounded by curly braces. + +After the above declaration is issued, implicit arguments can just +(and have to) be skipped in any expression involving an application +of `qualid`. + +Implicit arguments can be cleared with the following syntax: + +.. cmd:: Arguments @qualid : clear implicits. + +.. cmdv:: Global Arguments @qualid {* @possibly_bracketed_ident } + + Says to recompute the implicit arguments of + `qualid` after ending of the current section if any, enforcing the + implicit arguments known from inside the section to be the ones + declared by the command. + +.. cmdv:: Local Arguments @qualid {* @possibly_bracketed_ident }. + + When in a module, tell not to activate the + implicit arguments ofqualid declared by this command to contexts that + require the module. + +.. cmdv:: {? Global | Local } Arguments @qualid {*, {+ @possibly_bracketed_ident } }. + + For names of constants, inductive types, + constructors, lemmas which can only be applied to a fixed number of + arguments (this excludes for instance constants whose type is + polymorphic), multiple implicit arguments declarations can be given. + Depending on the number of arguments qualid is applied to in practice, + the longest applicable list of implicit arguments is used to select + which implicit arguments are inserted. For printing, the omitted + arguments are the ones of the longest list of implicit arguments of + the sequence. + +.. example:: + + .. coqtop:: reset all + + Inductive list (A:Type) : Type := + | nil : list A + | cons : A -> list A -> list A. + + Check (cons nat 3 (nil nat)). + + Arguments cons [A] _ _. + + Arguments nil [A]. + + Check (cons 3 nil). + + Fixpoint map (A B:Type) (f:A->B) (l:list A) : list B := match l with nil => nil | cons a t => cons (f a) (map A B f t) end. + + Fixpoint length (A:Type) (l:list A) : nat := match l with nil => 0 | cons _ m => S (length A m) end. + + Arguments map [A B] f l. + + Arguments length {A} l. (* A has to be maximally inserted *) + + Check (fun l:list (list nat) => map length l). + + Arguments map [A B] f l, [A] B f l, A B f l. + + Check (fun l => map length l = map (list nat) nat length l). + +Remark: To know which are the implicit arguments of an object, use the +command ``Print Implicit`` (see :ref:`displaying-implicit-args`). + + +Automatic declaration of implicit arguments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +|Coq| can also automatically detect what are the implicit arguments of a +defined object. The command is just + +.. cmd:: Arguments @qualid : default implicits. + +The auto-detection is governed by options telling if strict, +contextual, or reversible-pattern implicit arguments must be +considered or not (see :ref:`controlling-strict-implicit-args`, :ref:`controlling-strict-implicit-args`, +:ref:`controlling-rev-pattern-implicit-args`, and also :ref:`controlling-insertion-implicit-args`). + +.. cmdv:: Global Arguments @qualid : default implicits + + Tell to recompute the + implicit arguments of qualid after ending of the current section if + any. + +.. cmdv:: Local Arguments @qualid : default implicits + + When in a module, tell not to activate the implicit arguments of `qualid` computed by this + declaration to contexts that requires the module. + +.. example:: + + .. coqtop:: reset all + + Inductive list (A:Set) : Set := + | nil : list A + | cons : A -> list A -> list A. + + Arguments cons : default implicits. + + Print Implicit cons. + + Arguments nil : default implicits. + + Print Implicit nil. + + Set Contextual Implicit. + + Arguments nil : default implicits. + + Print Implicit nil. + +The computation of implicit arguments takes account of the unfolding +of constants. For instance, the variable ``p`` below has type +``(Transitivity R)`` which is reducible to +``forall x,y:U, R x y -> forall z:U, R y z -> R x z``. As the variables ``x``, ``y`` and ``z`` +appear strictly in the body of the type, they are implicit. + +.. coqtop:: reset none + + Set Warnings "-local-declaration". + +.. coqtop:: all + + Variable X : Type. + + Definition Relation := X -> X -> Prop. + + Definition Transitivity (R:Relation) := forall x y:X, R x y -> forall z:X, R y z -> R x z. + + Variables (R : Relation) (p : Transitivity R). + + Arguments p : default implicits. + + Print p. + + Print Implicit p. + + Variables (a b c : X) (r1 : R a b) (r2 : R b c). + + Check (p r1 r2). + + +Mode for automatic declaration of implicit arguments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In case one wants to systematically declare implicit the arguments +detectable as such, one may switch to the automatic declaration of +implicit arguments mode by using the command: + +.. cmd:: Set Implicit Arguments. + +Conversely, one may unset the mode by using ``Unset Implicit Arguments``. +The mode is off by default. Auto-detection of implicit arguments is +governed by options controlling whether strict and contextual implicit +arguments have to be considered or not. + +.. _controlling-strict-implicit-args: + +Controlling strict implicit arguments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When the mode for automatic declaration of implicit arguments is on, +the default is to automatically set implicit only the strict implicit +arguments plus, for historical reasons, a small subset of the non-strict +implicit arguments. To relax this constraint and to set +implicit all non strict implicit arguments by default, use the command: + +.. cmd:: Unset Strict Implicit. + +Conversely, use the command ``Set Strict Implicit`` to restore the +original mode that declares implicit only the strict implicit +arguments plus a small subset of the non strict implicit arguments. + +In the other way round, to capture exactly the strict implicit +arguments and no more than the strict implicit arguments, use the +command + +.. cmd:: Set Strongly Strict Implicit. + +Conversely, use the command ``Unset Strongly Strict Implicit`` to let the +option “Strict Implicit” decide what to do. + +Remark: In versions of |Coq| prior to version 8.0, the default was to +declare the strict implicit arguments as implicit. + +.. _controlling-contextual-implicit-args: + +Controlling contextual implicit arguments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +By default, |Coq| does not automatically set implicit the contextual +implicit arguments. To tell |Coq| to infer also contextual implicit +argument, use command + +.. cmd:: Set Contextual Implicit. + +Conversely, use command ``Unset Contextual Implicit`` to unset the +contextual implicit mode. + +.. _controlling-rev-pattern-implicit-args: + +Controlling reversible-pattern implicit arguments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +By default, |Coq| does not automatically set implicit the reversible-pattern +implicit arguments. To tell |Coq| to infer also reversible- +pattern implicit argument, use command + +.. cmd:: Set Reversible Pattern Implicit. + +Conversely, use command ``Unset Reversible Pattern Implicit`` to unset the +reversible-pattern implicit mode. + +.. _controlling-insertion-implicit-args: + +Controlling the insertion of implicit arguments not followed by explicit arguments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Implicit arguments can be declared to be automatically inserted when a +function is partially applied and the next argument of the function is +an implicit one. In case the implicit arguments are automatically +declared (with the command ``Set Implicit Arguments``), the command + +.. cmd:: Set Maximal Implicit Insertion. + +is used to tell to declare the implicit arguments with a maximal +insertion status. By default, automatically declared implicit +arguments are not declared to be insertable maximally. To restore the +default mode for maximal insertion, use the command + +.. cmd:: Unset Maximal Implicit Insertion. + +Explicit applications +~~~~~~~~~~~~~~~~~~~~~ + +In presence of non-strict or contextual argument, or in presence of +partial applications, the synthesis of implicit arguments may fail, so +one may have to give explicitly certain implicit arguments of an +application. The syntax for this is ``(`` `ident` ``:=`` `term` ``)`` where `ident` is the +name of the implicit argument and term is its corresponding explicit +term. Alternatively, one can locally deactivate the hiding of implicit +arguments of a function by using the notation `@qualid` |term_1| … |term_n|. +This syntax extension is given in the following grammar: + +.. _explicit_app_grammar: + + .. productionlist:: explicit_apps + term : @ qualid term … `term` + : | @ qualid + : | qualid `argument` … `argument` + argument : `term` + : | (ident := `term`) + + Syntax for explicitly giving implicit arguments + +.. example:: (continued) + + .. coqtop:: all + + Check (p r1 (z:=c)). + + Check (p (x:=a) (y:=b) r1 (z:=c) r2). + + +Renaming implicit arguments +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Implicit arguments names can be redefined using the following syntax: + +.. cmd:: Arguments @qualid {* @name} : @rename. + +With the assert flag, ``Arguments`` can be used to assert that a given +object has the expected number of arguments and that these arguments +are named as expected. + +.. example:: (continued) + +.. coqtop:: all + + Arguments p [s t] _ [u] _: rename. + + Check (p r1 (u:=c)). + + Check (p (s:=a) (t:=b) r1 (u:=c) r2). + + Fail Arguments p [s t] _ [w] _ : assert. + +.. _displaying-implicit-args: + +Displaying what the implicit arguments are +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To display the implicit arguments associated to an object, and to know +if each of them is to be used maximally or not, use the command + +.. cmd:: Print Implicit @qualid. + +Explicit displaying of implicit arguments for pretty-printing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +By default the basic pretty-printing rules hide the inferable implicit +arguments of an application. To force printing all implicit arguments, +use command + +.. cmd:: Set Printing Implicit. + +Conversely, to restore the hiding of implicit arguments, use command + +.. cmd:: Unset Printing Implicit. + +By default the basic pretty-printing rules display the implicit +arguments that are not detected as strict implicit arguments. This +“defensive” mode can quickly make the display cumbersome so this can +be deactivated by using the command + +.. cmd:: Unset Printing Implicit Defensive. + +Conversely, to force the display of non strict arguments, use command + +.. cmd:: Set Printing Implicit Defensive. + +See also: ``Set Printing All`` in :ref:`printing_constructions_full`. + +Interaction with subtyping +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When an implicit argument can be inferred from the type of more than +one of the other arguments, then only the type of the first of these +arguments is taken into account, and not an upper type of all of them. +As a consequence, the inference of the implicit argument of “=” fails +in + +.. coqtop:: all + + Fail Check nat = Prop. + +but succeeds in + +.. coqtop:: all + + Check Prop = nat. + + +Deactivation of implicit arguments for parsing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use of implicit arguments can be deactivated by issuing the command: + +.. cmd:: Set Parsing Explicit. + +In this case, all arguments of constants, inductive types, +constructors, etc, including the arguments declared as implicit, have +to be given as if none arguments were implicit. By symmetry, this also +affects printing. To restore parsing and normal printing of implicit +arguments, use: + +.. cmd:: Unset Parsing Explicit. + +Canonical structures +~~~~~~~~~~~~~~~~~~~~ + +A canonical structure is an instance of a record/structure type that +can be used to solve unification problems involving a projection +applied to an unknown structure instance (an implicit argument) and a +value. The complete documentation of canonical structures can be found +in :ref:`canonicalstructures`; here only a simple example is given. + +Assume that `qualid` denotes an object ``(Build_struc`` |c_1| … |c_n| ``)`` in the +structure *struct* of which the fields are |x_1|, …, |x_n|. Assume that +`qualid` is declared as a canonical structure using the command + +.. cmd:: Canonical Structure @qualid. + +Then, each time an equation of the form ``(``\ |x_i| ``_)`` |eq_beta_delta_iota_zeta| |c_i| has to be +solved during the type-checking process, `qualid` is used as a solution. +Otherwise said, `qualid` is canonically used to extend the field |c_i| +into a complete structure built on |c_i|. + +Canonical structures are particularly useful when mixed with coercions +and strict implicit arguments. Here is an example. + +.. coqtop:: all + + Require Import Relations. + + Require Import EqNat. + + Set Implicit Arguments. + + Unset Strict Implicit. + + Structure Setoid : Type := {Carrier :> Set; Equal : relation Carrier; + Prf_equiv : equivalence Carrier Equal}. + + Definition is_law (A B:Setoid) (f:A -> B) := forall x y:A, Equal x y -> Equal (f x) (f y). + + Axiom eq_nat_equiv : equivalence nat eq_nat. + + Definition nat_setoid : Setoid := Build_Setoid eq_nat_equiv. + + Canonical Structure nat_setoid. + +Thanks to ``nat_setoid`` declared as canonical, the implicit arguments ``A`` +and ``B`` can be synthesized in the next statement. + +.. coqtop:: all + + Lemma is_law_S : is_law S. + +Remark: If a same field occurs in several canonical structure, then +only the structure declared first as canonical is considered. + +.. cmdv:: Canonical Structure @ident := @term : @type. + +.. cmdv:: Canonical Structure @ident := @term. + +.. cmdv:: Canonical Structure @ident : @type := @term. + +These are equivalent to a regular definition of `ident` followed by the declaration +``Canonical Structure`` `ident`. + +See also: more examples in user contribution category (Rocq/ALGEBRA). + + +Print Canonical Projections. +++++++++++++++++++++++++++++ + +This displays the list of global names that are components of some +canonical structure. For each of them, the canonical structure of +which it is a projection is indicated. For instance, the above example +gives the following output: + +.. coqtop:: all + + Print Canonical Projections. + + +Implicit types of variables +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +It is possible to bind variable names to a given type (e.g. in a +development using arithmetic, it may be convenient to bind the names `n` +or `m` to the type ``nat`` of natural numbers). The command for that is + +.. cmd:: Implicit Types {+ @ident } : @type. + +The effect of the command is to automatically set the type of bound +variables starting with `ident` (either `ident` itself or `ident` followed by +one or more single quotes, underscore or digits) to be `type` (unless +the bound variable is already declared with an explicit type in which +case, this latter type is considered). + +.. example:: + + .. coqtop:: all + + Require Import List. + + Implicit Types m n : nat. + + Lemma cons_inj_nat : forall m n l, n :: l = m :: l -> n = m. + + intros m n. + + Lemma cons_inj_bool : forall (m n:bool) l, n :: l = m :: l -> n = m. + +.. cmdv:: Implicit Type @ident : @type. + + This is useful for declaring the implicit type of a single variable. + +.. cmdv:: Implicit Types {+ ( {+ @ident } : @term ) } + + Adds blocks of implicit types with different specifications. + +.. _implicit-generalization: + +Implicit generalization +~~~~~~~~~~~~~~~~~~~~~~~ + +.. index:: `{ } +.. index:: `( ) + +Implicit generalization is an automatic elaboration of a statement +with free variables into a closed statement where these variables are +quantified explicitly. Implicit generalization is done inside binders +starting with a \` and terms delimited by \`{ } and \`( ), always +introducing maximally inserted implicit arguments for the generalized +variables. Inside implicit generalization delimiters, free variables +in the current context are automatically quantified using a product or +a lambda abstraction to generate a closed term. In the following +statement for example, the variables n and m are automatically +generalized and become explicit arguments of the lemma as we are using +\`( ): + +.. coqtop:: all + + Generalizable All Variables. + + Lemma nat_comm : `(n = n + 0). + +One can control the set of generalizable identifiers with +the ``Generalizable`` vernacular command to avoid unexpected +generalizations when mistyping identifiers. There are several commands +that specify which variables should be generalizable. + +.. cmd:: Generalizable All Variables. + + All variables are candidate for + generalization if they appear free in the context under a + generalization delimiter. This may result in confusing errors in case + of typos. In such cases, the context will probably contain some + unexpected generalized variable. + +.. cmd:: Generalizable No Variables. + + Disable implicit generalization entirely. This is the default behavior. + +.. cmd:: Generalizable (Variable | Variables) {+ @ident }. + + Allow generalization of the given identifiers only. Calling this command multiple times + adds to the allowed identifiers. + +.. cmd:: Global Generalizable. + + Allows exporting the choice of generalizable variables. + +One can also use implicit generalization for binders, in which case +the generalized variables are added as binders and set maximally +implicit. + +.. coqtop:: all + + Definition id `(x : A) : A := x. + + Print id. + +The generalizing binders \`{ } and \`( ) work similarly to their +explicit counterparts, only binding the generalized variables +implicitly, as maximally-inserted arguments. In these binders, the +binding name for the bound object is optional, whereas the type is +mandatory, dually to regular binders. + + +Coercions +--------- + +Coercions can be used to implicitly inject terms from one *class* in +which they reside into another one. A *class* is either a sort +(denoted by the keyword ``Sortclass``), a product type (denoted by the +keyword ``Funclass``), or a type constructor (denoted by its name), e.g. +an inductive type or any constant with a type of the form +``forall (`` |x_1| : |A_1| ) … ``(``\ |x_n| : |A_n|\ ``)``, `s` where `s` is a sort. + +Then the user is able to apply an object that is not a function, but +can be coerced to a function, and more generally to consider that a +term of type ``A`` is of type ``B`` provided that there is a declared coercion +between ``A`` and ``B``. The main command is + +.. cmd:: Coercion @qualid : @class >-> @class. + +which declares the construction denoted by qualid as a coercion +between the two given classes. + +More details and examples, and a description of the commands related +to coercions are provided in :ref:`implicitcoercions`. + +.. _printing_constructions_full: + +Printing constructions in full +------------------------------ + +Coercions, implicit arguments, the type of pattern-matching, but also +notations (see :ref:`syntaxextensionsandinterpretationscopes`) can obfuscate the behavior of some +tactics (typically the tactics applying to occurrences of subterms are +sensitive to the implicit arguments). The command + +.. cmd:: Set Printing All. + +deactivates all high-level printing features such as coercions, +implicit arguments, returned type of pattern-matching, notations and +various syntactic sugar for pattern-matching or record projections. +Otherwise said, ``Set Printing All`` includes the effects of the commands +``Set Printing Implicit``, ``Set Printing Coercions``, ``Set Printing Synth``, +``Unset Printing Projections``, and ``Unset Printing Notations``. To reactivate +the high-level printing features, use the command + +.. cmd:: Unset Printing All. + +Printing universes +------------------ + +The following command: + +.. cmd:: Set Printing Universes. + +activates the display of the actual level of each occurrence of ``Type``. +See :ref:`TODO-4.1.1-sorts` for details. This wizard option, in combination +with ``Set Printing All`` (see :ref:`printing_constructions_full`) can help to diagnose failures +to unify terms apparently identical but internally different in the +Calculus of Inductive Constructions. To reactivate the display of the +actual level of the occurrences of Type, use + +.. cmd:: Unset Printing Universes. + +The constraints on the internal level of the occurrences of Type +(see :ref:`TODO-4.1.1-sorts`) can be printed using the command + +.. cmd:: Print {? Sorted} Universes. + +If the optional ``Sorted`` option is given, each universe will be made +equivalent to a numbered label reflecting its level (with a linear +ordering) in the universe hierarchy. + +This command also accepts an optional output filename: + +.. cmd:: Print {? Sorted} Universes @string. + +If `string` ends in ``.dot`` or ``.gv``, the constraints are printed in the DOT +language, and can be processed by Graphviz tools. The format is +unspecified if `string` doesn’t end in ``.dot`` or ``.gv``. + + +Existential variables +--------------------- + +|Coq| terms can include existential variables which represents unknown +subterms to eventually be replaced by actual subterms. + +Existential variables are generated in place of unsolvable implicit +arguments or “_” placeholders when using commands such as ``Check`` (see +Section :ref:`TODO-6.3.1-check`) or when using tactics such as ``refine`` (see Section +:ref:`TODO-8.2.3-refine`), as well as in place of unsolvable instances when using +tactics such that ``eapply`` (see Section :ref:`TODO-8.2.4-apply`). An existential +variable is defined in a context, which is the context of variables of +the placeholder which generated the existential variable, and a type, +which is the expected type of the placeholder. + +As a consequence of typing constraints, existential variables can be +duplicated in such a way that they possibly appear in different +contexts than their defining context. Thus, any occurrence of a given +existential variable comes with an instance of its original context. +In the simple case, when an existential variable denotes the +placeholder which generated it, or is used in the same context as the +one in which it was generated, the context is not displayed and the +existential variable is represented by “?” followed by an identifier. + +.. coqtop:: all + + Parameter identity : forall (X:Set), X -> X. + + Check identity _ _. + + Check identity _ (fun x => _). + +In the general case, when an existential variable ``?``\ `ident` appears +outside of its context of definition, its instance, written under the +form + +| ``{`` :n:`{*; @ident:=@term}` ``}`` + +is appending to its name, indicating how the variables of its defining context are instantiated. +The variables of the context of the existential variables which are +instantiated by themselves are not written, unless the flag ``Printing Existential Instances`` +is on (see Section :ref:`explicit-display-existentials`), and this is why an +existential variable used in the same context as its context of definition is written with no instance. + +.. coqtop:: all + + Check (fun x y => _) 0 1. + + Set Printing Existential Instances. + + Check (fun x y => _) 0 1. + +Existential variables can be named by the user upon creation using +the syntax ``?``\ `ident`. This is useful when the existential +variable needs to be explicitly handled later in the script (e.g. +with a named-goal selector, see :ref:`TODO-9.2-goal-selectors`). + +.. _explicit-display-existentials: + +Explicit displaying of existential instances for pretty-printing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The command: + +.. cmd:: Set Printing Existential Instances. + +activates the full display of how the context of an existential +variable is instantiated at each of the occurrences of the existential +variable. + +To deactivate the full display of the instances of existential +variables, use + +.. cmd:: Unset Printing Existential Instances. + +Solving existential variables using tactics +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Instead of letting the unification engine try to solve an existential +variable by itself, one can also provide an explicit hole together +with a tactic to solve it. Using the syntax ``ltac:(``\ `tacexpr`\ ``)``, the user +can put a tactic anywhere a term is expected. The order of resolution +is not specified and is implementation-dependent. The inner tactic may +use any variable defined in its scope, including repeated alternations +between variables introduced by term binding as well as those +introduced by tactic binding. The expression `tacexpr` can be any tactic +expression as described in :ref:`thetacticlanguage`. + +.. coqtop:: all + + Definition foo (x : nat) : nat := ltac:(exact x). + +This construction is useful when one wants to define complicated terms +using highly automated tactics without resorting to writing the proof-term +by means of the interactive proof engine. + +This mechanism is comparable to the ``Declare Implicit Tactic`` command +defined at :ref:`TODO-8.9.7-implicit-automation`, except that the used +tactic is local to each hole instead of being declared globally. diff --git a/doc/sphinx/language/module-system.rst b/doc/sphinx/language/module-system.rst new file mode 100644 index 0000000000..e6a6736654 --- /dev/null +++ b/doc/sphinx/language/module-system.rst @@ -0,0 +1,459 @@ +.. include:: ../preamble.rst +.. include:: ../replaces.rst + +.. _themodulesystem: + +The Module System +================= + +The module system extends the Calculus of Inductive Constructions +providing a convenient way to structure large developments as well as +a means of massive abstraction. + + +Modules and module types +---------------------------- + +**Access path.** An access path is denoted by :math:`p` and can be +either a module variable :math:`X` or, if :math:`p′` is an access path +and :math:`id` an identifier, then :math:`p′.id` is an access path. + + +**Structure element.** A structure element is denoted by :math:`e` and +is either a definition of a constant, an assumption, a definition of +an inductive, a definition of a module, an alias of a module or a module +type abbreviation. + + +**Structure expression.** A structure expression is denoted by :math:`S` and can be: + ++ an access path :math:`p` ++ a plain structure :math:`\Struct~e ; … ; e~\End` ++ a functor :math:`\Functor(X:S)~S′`, where :math:`X` is a module variable, :math:`S` and :math:`S′` are + structure expressions ++ an application :math:`S~p`, where :math:`S` is a structure expression and :math:`p` an + access path ++ a refined structure :math:`S~\with~p := p`′ or :math:`S~\with~p := t:T` where :math:`S` is a + structure expression, :math:`p` and :math:`p′` are access paths, :math:`t` is a term and :math:`T` is + the type of :math:`t`. + +**Module definition.** A module definition is written :math:`\Mod{X}{S}{S'}` +and consists of a module variable :math:`X`, a module type +:math:`S` which can be any structure expression and optionally a +module implementation :math:`S′` which can be any structure expression +except a refined structure. + + +**Module alias.** A module alias is written :math:`\ModA{X}{p}` +and consists of a module variable :math:`X` and a module path +:math:`p`. + +**Module type abbreviation.** +A module type abbreviation is written :math:`\ModType{Y}{S}`, +where :math:`Y` is an identifier and :math:`S` is any structure +expression . + + +Typing Modules +------------------ + +In order to introduce the typing system we first slightly extend the syntactic +class of terms and environments given in section :ref:`The-terms`. The +environments, apart from definitions of constants and inductive types now also +hold any other structure elements. Terms, apart from variables, constants and +complex terms, include also access paths. + +We also need additional typing judgments: + + ++ :math:`\WFT{E}{S}`, denoting that a structure :math:`S` is well-formed, ++ :math:`\WTM{E}{p}{S}`, denoting that the module pointed by :math:`p` has type :math:`S` in + environment :math:`E`. ++ :math:`\WEV{E}{S}{\ovl{S}}`, denoting that a structure :math:`S` is evaluated to a + structure :math:`S` in weak head normal form. ++ :math:`\WS{E}{S_1}{S_2}` , denoting that a structure :math:`S_1` is a subtype of a + structure :math:`S_2`. ++ :math:`\WS{E}{e_1}{e_2}` , denoting that a structure element e_1 is more + precise than a structure element e_2. + +The rules for forming structures are the following: + +.. inference:: WF-STR + + \WF{E;E′}{} + ------------------------ + \WFT{E}{ \Struct~E′ ~\End} + +.. inference:: WF-FUN + + \WFT{E; \ModS{X}{S}}{ \ovl{S′} } + -------------------------- + \WFT{E}{ \Functor(X:S)~S′} + + +Evaluation of structures to weak head normal form: + +.. inference:: WEVAL-APP + + \begin{array}{c} + \WEV{E}{S}{\Functor(X:S_1 )~S_2}~~~~~\WEV{E}{S_1}{\ovl{S_1}} \\ + \WTM{E}{p}{S_3}~~~~~ \WS{E}{S_3}{\ovl{S_1}} + \end{array} + -------------------------- + \WEV{E}{S~p}{S_2 \{p/X,t_1 /p_1 .c_1 ,…,t_n /p_n.c_n \}} + + +In the last rule, :math:`\{t_1 /p_1 .c_1 ,…,t_n /p_n .c_n \}` is the resulting +substitution from the inlining mechanism. We substitute in :math:`S` the +inlined fields :math:`p_i .c_i` from :math:`\ModS{X}{S_1 }` by the corresponding delta- +reduced term :math:`t_i` in :math:`p`. + +.. inference:: WEVAL-WITH-MOD + + \begin{array}{c} + E[] ⊢ S \lra \Struct~e_1 ;…;e_i ; \ModS{X}{S_1 };e_{i+2} ;… ;e_n ~\End \\ + E;e_1 ;…;e_i [] ⊢ S_1 \lra \ovl{S_1} ~~~~~~ + E[] ⊢ p : S_2 \\ + E;e_1 ;…;e_i [] ⊢ S_2 <: \ovl{S_1} + \end{array} + ---------------------------------- + \begin{array}{c} + \WEV{E}{S~\with~x := p}{}\\ + \Struct~e_1 ;…;e_i ; \ModA{X}{p};e_{i+2} \{p/X\} ;…;e_n \{p/X\} ~\End + \end{array} + +.. inference:: WEVAL-WITH-MOD-REC + + \begin{array}{c} + \WEV{E}{S}{\Struct~e_1 ;…;e_i ; \ModS{X_1}{S_1 };e_{i+2} ;… ;e_n ~\End} \\ + \WEV{E;e_1 ;…;e_i }{S_1~\with~p := p_1}{\ovl{S_2}} + \end{array} + -------------------------- + \begin{array}{c} + \WEV{E}{S~\with~X_1.p := p_1}{} \\ + \Struct~e_1 ;…;e_i ; \ModS{X}{\ovl{S_2}};e_{i+2} \{p_1 /X_1.p\} ;…;e_n \{p_1 /X_1.p\} ~\End + \end{array} + +.. inference:: WEVAL-WITH-DEF + + \begin{array}{c} + \WEV{E}{S}{\Struct~e_1 ;…;e_i ;\Assum{}{c}{T_1};e_{i+2} ;… ;e_n ~\End} \\ + \WS{E;e_1 ;…;e_i }{Def()(c:=t:T)}{\Assum{}{c}{T_1}} + \end{array} + -------------------------- + \begin{array}{c} + \WEV{E}{S~\with~c := t:T}{} \\ + \Struct~e_1 ;…;e_i ;Def()(c:=t:T);e_{i+2} ;… ;e_n ~\End + \end{array} + +.. inference:: WEVAL-WITH-DEF-REC + + \begin{array}{c} + \WEV{E}{S}{\Struct~e_1 ;…;e_i ; \ModS{X_1 }{S_1 };e_{i+2} ;… ;e_n ~\End} \\ + \WEV{E;e_1 ;…;e_i }{S_1~\with~p := p_1}{\ovl{S_2}} + \end{array} + -------------------------- + \begin{array}{c} + \WEV{E}{S~\with~X_1.p := t:T}{} \\ + \Struct~e_1 ;…;e_i ; \ModS{X}{\ovl{S_2} };e_{i+2} ;… ;e_n ~\End + \end{array} + +.. inference:: WEVAL-PATH-MOD1 + + \begin{array}{c} + \WEV{E}{p}{\Struct~e_1 ;…;e_i ; \Mod{X}{S}{S_1};e_{i+2} ;… ;e_n End} \\ + \WEV{E;e_1 ;…;e_i }{S}{\ovl{S}} + \end{array} + -------------------------- + E[] ⊢ p.X \lra \ovl{S} + +.. inference:: WEVAL-PATH-MOD2 + + \WF{E}{} + \Mod{X}{S}{S_1}∈ E + \WEV{E}{S}{\ovl{S}} + -------------------------- + \WEV{E}{X}{\ovl{S}} + +.. inference:: WEVAL-PATH-ALIAS1 + + \begin{array}{c} + \WEV{E}{p}{~\Struct~e_1 ;…;e_i ; \ModA{X}{p_1};e_{i+2} ;… ;e_n End} \\ + \WEV{E;e_1 ;…;e_i }{p_1}{\ovl{S}} + \end{array} + -------------------------- + \WEV{E}{p.X}{\ovl{S}} + +.. inference:: WEVAL-PATH-ALIAS2 + + \WF{E}{} + \ModA{X}{p_1 }∈ E + \WEV{E}{p_1}{\ovl{S}} + -------------------------- + \WEV{E}{X}{\ovl{S}} + +.. inference:: WEVAL-PATH-TYPE1 + + \begin{array}{c} + \WEV{E}{p}{~\Struct~e_1 ;…;e_i ; \ModType{Y}{S};e_{i+2} ;… ;e_n End} \\ + \WEV{E;e_1 ;…;e_i }{S}{\ovl{S}} + \end{array} + -------------------------- + \WEV{E}{p.Y}{\ovl{S}} + +.. inference:: WEVAL-PATH-TYPE2 + + \WF{E}{} + \ModType{Y}{S}∈ E + \WEV{E}{S}{\ovl{S}} + -------------------------- + \WEV{E}{Y}{\ovl{S}} + + +Rules for typing module: + +.. inference:: MT-EVAL + + \WEV{E}{p}{\ovl{S}} + -------------------------- + E[] ⊢ p : \ovl{S} + +.. inference:: MT-STR + + E[] ⊢ p : S + -------------------------- + E[] ⊢ p : S/p + + +The last rule, called strengthening is used to make all module fields +manifestly equal to themselves. The notation :math:`S/p` has the following +meaning: + + ++ if :math:`S\lra~\Struct~e_1 ;…;e_n ~\End` then :math:`S/p=~\Struct~e_1 /p;…;e_n /p ~\End` + where :math:`e/p` is defined as follows (note that opaque definitions are processed + as assumptions): + + + :math:`\Def{}{c}{t}{T}/p = \Def{}{c}{t}{T}` + + :math:`\Assum{}{c}{U}/p = \Def{}{c}{p.c}{U}` + + :math:`\ModS{X}{S}/p = \ModA{X}{p.X}` + + :math:`\ModA{X}{p′}/p = \ModA{X}{p′}` + + :math:`\Ind{}{Γ_P}{Γ_C}{Γ_I}/p = \Indp{}{Γ_P}{Γ_C}{Γ_I}{p}` + + :math:`\Indpstr{}{Γ_P}{Γ_C}{Γ_I}{p'}{p} = \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'}` + ++ if :math:`S \lra \Functor(X:S′)~S″` then :math:`S/p=S` + + +The notation :math:`\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}` +denotes an inductive definition that is definitionally equal to the +inductive definition in the module denoted by the path :math:`p`. All rules +which have :math:`\Ind{}{Γ_P}{Γ_C}{Γ_I}` as premises are also valid for +:math:`\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}`. We give the formation rule for +:math:`\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}` +below as well as the equality rules on inductive types and +constructors. + +The module subtyping rules: + +.. inference:: MSUB-STR + + \begin{array}{c} + \WS{E;e_1 ;…;e_n }{e_{σ(i)}}{e'_i ~\for~ i=1..m} \\ + σ : \{1… m\} → \{1… n\} ~\injective + \end{array} + -------------------------- + \WS{E}{\Struct~e_1 ;…;e_n ~\End}{~\Struct~e'_1 ;…;e'_m ~\End} + +.. inference:: MSUB-FUN + + \WS{E}{\ovl{S_1'}}{\ovl{S_1}} + \WS{E; \ModS{X}{S_1'}}{\ovl{S_2}}{\ovl{S_2'}} + -------------------------- + E[] ⊢ \Functor(X:S_1 ) S_2 <: \Functor(X:S_1') S_2' + + +Structure element subtyping rules: + +.. inference:: ASSUM-ASSUM + + E[] ⊢ T_1 ≤_{βδιζη} T_2 + -------------------------- + \WS{E}{\Assum{}{c}{T_1 }}{\Assum{}{c}{T_2 }} + +.. inference:: DEF-ASSUM + + E[] ⊢ T_1 ≤_{βδιζη} T_2 + -------------------------- + \WS{E}{\Def{}{c}{t}{T_1 }}{\Assum{}{c}{T_2 }} + +.. inference:: ASSUM-DEF + + E[] ⊢ T_1 ≤_{βδιζη} T_2 + E[] ⊢ c =_{βδιζη} t_2 + -------------------------- + \WS{E}{\Assum{}{c}{T_1 }}{\Def{}{c}{t_2 }{T_2 }} + +.. inference:: DEF-DEF + + E[] ⊢ T_1 ≤_{βδιζη} T_2 + E[] ⊢ t_1 =_{βδιζη} t_2 + -------------------------- + \WS{E}{\Def{}{c}{t_1 }{T_1 }}{\Def{}{c}{t_2 }{T_2 }} + +.. inference:: IND-IND + + E[] ⊢ Γ_P =_{βδιζη} Γ_P' + E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C' + E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I' + -------------------------- + \WS{E}{\ind{Γ_P}{Γ_C}{Γ_I}}{\ind{Γ_P'}{Γ_C'}{Γ_I'}} + +.. inference:: INDP-IND + + E[] ⊢ Γ_P =_{βδιζη} Γ_P' + E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C' + E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I' + -------------------------- + \WS{E}{\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}}{\ind{Γ_P'}{Γ_C'}{Γ_I'}} + +.. inference:: INDP-INDP + + \begin{array}{c} + E[] ⊢ Γ_P =_{βδιζη} Γ_P' + E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C' \\ + E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I' + E[] ⊢ p =_{βδιζη} p' + \end{array} + -------------------------- + \WS{E}{\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}}{\Indp{}{Γ_P'}{Γ_C'}{Γ_I'}{p'}} + +.. inference:: MOD-MOD + + \WS{E}{S_1}{S_2} + -------------------------- + \WS{E}{\ModS{X}{S_1 }}{\ModS{X}{S_2 }} + +.. inference:: ALIAS-MOD + + E[] ⊢ p : S_1 + \WS{E}{S_1}{S_2} + -------------------------- + \WS{E}{\ModA{X}{p}}{\ModS{X}{S_2 }} + +.. inference:: MOD-ALIAS + + E[] ⊢ p : S_2 + \WS{E}{S_1}{S_2} + E[] ⊢ X =_{βδιζη} p + -------------------------- + \WS{E}{\ModS{X}{S_1 }}{\ModA{X}{p}} + +.. inference:: ALIAS-ALIAS + + E[] ⊢ p_1 =_{βδιζη} p_2 + -------------------------- + \WS{E}{\ModA{X}{p_1 }}{\ModA{X}{p_2 }} + +.. inference:: MODTYPE-MODTYPE + + \WS{E}{S_1}{S_2} + \WS{E}{S_2}{S_1} + -------------------------- + \WS{E}{\ModType{Y}{S_1 }}{\ModType{Y}{S_2 }} + + +New environment formation rules + + +.. inference:: WF-MOD1 + + \WF{E}{} + \WFT{E}{S} + -------------------------- + WF(E; \ModS{X}{S})[] + +.. inference:: WF-MOD2 + + \WS{E}{S_2}{S_1} + \WF{E}{} + \WFT{E}{S_1} + \WFT{E}{S_2} + -------------------------- + \WF{E; \Mod{X}{S_1}{S_2}}{} + +.. inference:: WF-ALIAS + + \WF{E}{} + E[] ⊢ p : S + -------------------------- + \WF{E, \ModA{X}{p}}{} + +.. inference:: WF-MODTYPE + + \WF{E}{} + \WFT{E}{S} + -------------------------- + \WF{E, \ModType{Y}{S}}{} + +.. inference:: WF-IND + + \begin{array}{c} + \WF{E;\ind{Γ_P}{Γ_C}{Γ_I}}{} \\ + E[] ⊢ p:~\Struct~e_1 ;…;e_n ;\ind{Γ_P'}{Γ_C'}{Γ_I'};… ~\End : \\ + E[] ⊢ \ind{Γ_P'}{Γ_C'}{Γ_I'} <: \ind{Γ_P}{Γ_C}{Γ_I} + \end{array} + -------------------------- + \WF{E; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p} }{} + + +Component access rules + + +.. inference:: ACC-TYPE1 + + E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Assum{}{c}{T};… ~\End + -------------------------- + E[Γ] ⊢ p.c : T + +.. inference:: ACC-TYPE2 + + E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Def{}{c}{t}{T};… ~\End + -------------------------- + E[Γ] ⊢ p.c : T + +Notice that the following rule extends the delta rule defined in section :ref:`Conversion-rules` + +.. inference:: ACC-DELTA + + E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Def{}{c}{t}{U};… ~\End + -------------------------- + E[Γ] ⊢ p.c \triangleright_δ t + +In the rules below we assume +:math:`Γ_P` is :math:`[p_1 :P_1 ;…;p_r :P_r ]`, +:math:`Γ_I` is :math:`[I_1 :A_1 ;…;I_k :A_k ]`, +and :math:`Γ_C` is :math:`[c_1 :C_1 ;…;c_n :C_n ]`. + +.. inference:: ACC-IND1 + + E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\ind{Γ_P}{Γ_C}{Γ_I};… ~\End + -------------------------- + E[Γ] ⊢ p.I_j : (p_1 :P_1 )…(p_r :P_r )A_j + +.. inference:: ACC-IND2 + + E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\ind{Γ_P}{Γ_C}{Γ_I};… ~\End + -------------------------- + E[Γ] ⊢ p.c_m : (p_1 :P_1 )…(p_r :P_r )C_m I_j (I_j~p_1 …p_r )_{j=1… k} + +.. inference:: ACC-INDP1 + + E[] ⊢ p :~\Struct~e_1 ;…;e_i ; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'} ;… ~\End + -------------------------- + E[] ⊢ p.I_i \triangleright_δ p'.I_i + +.. inference:: ACC-INDP2 + + E[] ⊢ p :~\Struct~e_1 ;…;e_i ; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'} ;… ~\End + -------------------------- + E[] ⊢ p.c_i \triangleright_δ p'.c_i |
