From 4342c9d1c83bb855426a67ae7f8d36d80ab0b972 Mon Sep 17 00:00:00 2001 From: Théo Zimmermann Date: Wed, 13 May 2020 23:43:27 +0200 Subject: Extract modules from Gallina ext. --- doc/sphinx/language/gallina-extensions.rst | 570 +---------------------------- 1 file changed, 1 insertion(+), 569 deletions(-) (limited to 'doc/sphinx') diff --git a/doc/sphinx/language/gallina-extensions.rst b/doc/sphinx/language/gallina-extensions.rst index 5b78280edc..ca045dc082 100644 --- a/doc/sphinx/language/gallina-extensions.rst +++ b/doc/sphinx/language/gallina-extensions.rst @@ -1,288 +1,4 @@ -.. _extensionsofgallina: - -Extensions of |Gallina| -======================= - -|Gallina| is the kernel language of |Coq|. We describe here extensions of -|Gallina|’s syntax. - -Variants and extensions of :g:`match` -------------------------------------- - -.. _mult-match: - -Multiple and nested pattern matching -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The basic version of :g:`match` allows pattern matching on simple -patterns. As an extension, multiple nested patterns or disjunction of -patterns are allowed, as in ML-like languages. - -The extension just acts as a macro that is expanded during parsing -into a sequence of match on simple patterns. Especially, a -construction defined using the extended match is generally printed -under its expanded form (see :flag:`Printing Matching`). - -.. seealso:: :ref:`extendedpatternmatching`. - -.. _if-then-else: - -Pattern-matching on boolean values: the if expression -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. insertprodn term_if term_if - -.. prodn:: - term_if ::= if @term {? {? as @name } return @term100 } then @term else @term - -For inductive types with exactly two constructors and for pattern matching -expressions that do not depend on the arguments of the constructors, it is possible -to use a ``if … then … else`` notation. For instance, the definition - -.. coqtop:: all - - Definition not (b:bool) := - match b with - | true => false - | false => true - end. - -can be alternatively written - -.. coqtop:: reset all - - Definition not (b:bool) := if b then false else true. - -More generally, for an inductive type with constructors :n:`@ident__1` -and :n:`@ident__2`, the following terms are equal: - -:n:`if @term__0 {? {? as @name } return @term } then @term__1 else @term__2` - -:n:`match @term__0 {? {? as @name } return @term } with | @ident__1 {* _ } => @term__1 | @ident__2 {* _ } => @term__2 end` - -.. example:: - - .. coqtop:: all - - Check (fun x (H:{x=0}+{x<>0}) => - match H with - | left _ => true - | right _ => false - end). - -Notice that the printing uses the :g:`if` syntax because :g:`sumbool` is -declared as such (see :ref:`controlling-match-pp`). - -.. _irrefutable-patterns: - -Irrefutable patterns: the destructuring let variants -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Pattern-matching on terms inhabiting inductive type having only one -constructor can be alternatively written using :g:`let … in …` -constructions. There are two variants of them. - - -First destructuring let syntax -++++++++++++++++++++++++++++++ - -The expression :n:`let ( {*, @ident__i } ) := @term__0 in @term__1` -performs case analysis on :n:`@term__0` whose type must be an -inductive type with exactly one constructor. The number of variables -:n:`@ident__i` must correspond to the number of arguments of this -contrustor. Then, in :n:`@term__1`, these variables are bound to the -arguments of the constructor in :n:`@term__0`. For instance, the -definition - -.. coqtop:: reset all - - Definition fst (A B:Set) (H:A * B) := match H with - | pair x y => x - end. - -can be alternatively written - -.. coqtop:: reset all - - Definition fst (A B:Set) (p:A * B) := let (x, _) := p in x. - -Notice that reduction is different from regular :g:`let … in …` -construction since it happens only if :n:`@term__0` is in constructor form. -Otherwise, the reduction is blocked. - -The pretty-printing of a definition by matching on a irrefutable -pattern can either be done using :g:`match` or the :g:`let` construction -(see Section :ref:`controlling-match-pp`). - -If term inhabits an inductive type with one constructor `C`, we have an -equivalence between - -:: - - let (ident₁, …, identₙ) [dep_ret_type] := term in term' - -and - -:: - - match term [dep_ret_type] with - C ident₁ … identₙ => term' - end - - -Second destructuring let syntax -+++++++++++++++++++++++++++++++ - -Another destructuring let syntax is available for inductive types with -one constructor by giving an arbitrary pattern instead of just a tuple -for all the arguments. For example, the preceding example can be -written: - -.. coqtop:: reset all - - Definition fst (A B:Set) (p:A*B) := let 'pair x _ := p in x. - -This is useful to match deeper inside tuples and also to use notations -for the pattern, as the syntax :g:`let ’p := t in b` allows arbitrary -patterns to do the deconstruction. For example: - -.. coqtop:: all - - Definition deep_tuple (A:Set) (x:(A*A)*(A*A)) : A*A*A*A := - let '((a,b), (c, d)) := x in (a,b,c,d). - - Notation " x 'With' p " := (exist _ x p) (at level 20). - - Definition proj1_sig' (A:Set) (P:A->Prop) (t:{ x:A | P x }) : A := - let 'x With p := t in x. - -When printing definitions which are written using this construct it -takes precedence over let printing directives for the datatype under -consideration (see Section :ref:`controlling-match-pp`). - - -.. _controlling-match-pp: - -Controlling pretty-printing of match expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The following commands give some control over the pretty-printing -of :g:`match` expressions. - -Printing nested patterns -+++++++++++++++++++++++++ - -.. flag:: Printing Matching - - The Calculus of Inductive Constructions knows pattern matching only - over simple patterns. It is however convenient to re-factorize nested - pattern matching into a single pattern matching over a nested - pattern. - - When this flag is on (default), |Coq|’s printer tries to do such - limited re-factorization. - Turning it off tells |Coq| to print only simple pattern matching problems - in the same way as the |Coq| kernel handles them. - - -Factorization of clauses with same right-hand side -++++++++++++++++++++++++++++++++++++++++++++++++++ - -.. flag:: Printing Factorizable Match Patterns - - When several patterns share the same right-hand side, it is additionally - possible to share the clauses using disjunctive patterns. Assuming that the - printing matching mode is on, this flag (on by default) tells |Coq|'s - printer to try to do this kind of factorization. - -Use of a default clause -+++++++++++++++++++++++ - -.. flag:: Printing Allow Match Default Clause - - When several patterns share the same right-hand side which do not depend on the - arguments of the patterns, yet an extra factorization is possible: the - disjunction of patterns can be replaced with a `_` default clause. Assuming that - the printing matching mode and the factorization mode are on, this flag (on by - default) tells |Coq|'s printer to use a default clause when relevant. - -Printing of wildcard patterns -++++++++++++++++++++++++++++++ - -.. flag:: Printing Wildcard - - Some variables in a pattern may not occur in the right-hand side of - the pattern matching clause. When this flag is on (default), the - variables having no occurrences in the right-hand side of the - pattern matching clause are just printed using the wildcard symbol - “_”. - - -Printing of the elimination predicate -+++++++++++++++++++++++++++++++++++++ - -.. flag:: Printing Synth - - In most of the cases, the type of the result of a matched term is - mechanically synthesizable. Especially, if the result type does not - depend of the matched term. When this flag is on (default), - the result type is not printed when |Coq| knows that it can re- - synthesize it. - - -Printing matching on irrefutable patterns -++++++++++++++++++++++++++++++++++++++++++ - -If an inductive type has just one constructor, pattern matching can be -written using the first destructuring let syntax. - -.. table:: Printing Let @qualid - :name: Printing Let - - Specifies a set of qualids for which pattern matching is displayed using a let expression. - Note that this only applies to pattern matching instances entered with :g:`match`. - It doesn't affect pattern matching explicitly entered with a destructuring - :g:`let`. - Use the :cmd:`Add` and :cmd:`Remove` commands to update this set. - - -Printing matching on booleans -+++++++++++++++++++++++++++++ - -If an inductive type is isomorphic to the boolean type, pattern matching -can be written using ``if`` … ``then`` … ``else`` …. This table controls -which types are written this way: - -.. table:: Printing If @qualid - :name: Printing If - - Specifies a set of qualids for which pattern matching is displayed using - ``if`` … ``then`` … ``else`` …. Use the :cmd:`Add` and :cmd:`Remove` - commands to update this set. - -This example emphasizes what the printing settings offer. - -.. example:: - - .. coqtop:: all - - Definition snd (A B:Set) (H:A * B) := match H with - | pair x y => y - end. - - Test Printing Let for prod. - - Print snd. - - Remove Printing Let prod. - - Unset Printing Synth. - - Unset Printing Wildcard. - - Print snd. - -Module system +Using modules ------------- The module system provides a way of packaging related elements @@ -828,287 +544,3 @@ subdirectories of path). See the command :cmd:`Declare ML Module` in See :ref:`command-line-options` for a more general view over the |Coq| command line options. - -.. _Coercions: - -Coercions ---------- - -Coercions can be used to implicitly inject terms from one *class* in -which they reside into another one. A *class* is either a sort -(denoted by the keyword ``Sortclass``), a product type (denoted by the -keyword ``Funclass``), or a type constructor (denoted by its name), e.g. -an inductive type or any constant with a type of the form -:n:`forall {+ @binder }, @sort`. - -Then the user is able to apply an object that is not a function, but -can be coerced to a function, and more generally to consider that a -term of type ``A`` is of type ``B`` provided that there is a declared coercion -between ``A`` and ``B``. - -More details and examples, and a description of the commands related -to coercions are provided in :ref:`implicitcoercions`. - -.. _printing_constructions_full: - -Printing constructions in full ------------------------------- - -.. flag:: Printing All - - Coercions, implicit arguments, the type of pattern matching, but also - notations (see :ref:`syntax-extensions-and-notation-scopes`) can obfuscate the behavior of some - tactics (typically the tactics applying to occurrences of subterms are - sensitive to the implicit arguments). Turning this flag on - deactivates all high-level printing features such as coercions, - implicit arguments, returned type of pattern matching, notations and - various syntactic sugar for pattern matching or record projections. - Otherwise said, :flag:`Printing All` includes the effects of the flags - :flag:`Printing Implicit`, :flag:`Printing Coercions`, :flag:`Printing Synth`, - :flag:`Printing Projections`, and :flag:`Printing Notations`. To reactivate - the high-level printing features, use the command ``Unset Printing All``. - - .. note:: In some cases, setting :flag:`Printing All` may display terms - that are so big they become very hard to read. One technique to work around - this is use :cmd:`Undelimit Scope` and/or :cmd:`Close Scope` to turn off the - printing of notations bound to particular scope(s). This can be useful when - notations in a given scope are getting in the way of understanding - a goal, but turning off all notations with :flag:`Printing All` would make - the goal unreadable. - - .. see a contrived example here: https://github.com/coq/coq/pull/11718#discussion_r415481854 - -.. _printing-universes: - -Printing universes ------------------- - -.. flag:: Printing Universes - - Turn this flag on to activate the display of the actual level of each - occurrence of :g:`Type`. See :ref:`Sorts` for details. This wizard flag, in - combination with :flag:`Printing All` can help to diagnose failures to unify - terms apparently identical but internally different in the Calculus of Inductive - Constructions. - -.. cmd:: Print {? Sorted } Universes {? Subgraph ( {* @qualid } ) } {? @string } - :name: Print Universes - - This command can be used to print the constraints on the internal level - of the occurrences of :math:`\Type` (see :ref:`Sorts`). - - The :n:`Subgraph` clause limits the printed graph to the requested names (adjusting - constraints to preserve the implied transitive constraints between - kept universes). - - The :n:`Sorted` clause makes each universe - equivalent to a numbered label reflecting its level (with a linear - ordering) in the universe hierarchy. - - :n:`@string` is an optional output filename. - If :n:`@string` ends in ``.dot`` or ``.gv``, the constraints are printed in the DOT - language, and can be processed by Graphviz tools. The format is - unspecified if `string` doesn’t end in ``.dot`` or ``.gv``. - -.. _existential-variables: - -Existential variables ---------------------- - -.. insertprodn term_evar term_evar - -.. prodn:: - term_evar ::= _ - | ?[ @ident ] - | ?[ ?@ident ] - | ?@ident {? @%{ {+; @ident := @term } %} } - -|Coq| terms can include existential variables which represents unknown -subterms to eventually be replaced by actual subterms. - -Existential variables are generated in place of unsolvable implicit -arguments or “_” placeholders when using commands such as ``Check`` (see -Section :ref:`requests-to-the-environment`) or when using tactics such as -:tacn:`refine`, as well as in place of unsolvable instances when using -tactics such that :tacn:`eapply`. An existential -variable is defined in a context, which is the context of variables of -the placeholder which generated the existential variable, and a type, -which is the expected type of the placeholder. - -As a consequence of typing constraints, existential variables can be -duplicated in such a way that they possibly appear in different -contexts than their defining context. Thus, any occurrence of a given -existential variable comes with an instance of its original context. -In the simple case, when an existential variable denotes the -placeholder which generated it, or is used in the same context as the -one in which it was generated, the context is not displayed and the -existential variable is represented by “?” followed by an identifier. - -.. coqtop:: all - - Parameter identity : forall (X:Set), X -> X. - - Check identity _ _. - - Check identity _ (fun x => _). - -In the general case, when an existential variable :n:`?@ident` appears -outside of its context of definition, its instance, written under the -form :n:`{ {*; @ident := @term} }` is appending to its name, indicating -how the variables of its defining context are instantiated. -The variables of the context of the existential variables which are -instantiated by themselves are not written, unless the :flag:`Printing Existential Instances` flag -is on (see Section :ref:`explicit-display-existentials`), and this is why an -existential variable used in the same context as its context of definition is written with no instance. - -.. coqtop:: all - - Check (fun x y => _) 0 1. - - Set Printing Existential Instances. - - Check (fun x y => _) 0 1. - -Existential variables can be named by the user upon creation using -the syntax :n:`?[@ident]`. This is useful when the existential -variable needs to be explicitly handled later in the script (e.g. -with a named-goal selector, see :ref:`goal-selectors`). - -.. _explicit-display-existentials: - -Explicit displaying of existential instances for pretty-printing -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. flag:: Printing Existential Instances - - This flag (off by default) activates the full display of how the - context of an existential variable is instantiated at each of the - occurrences of the existential variable. - -.. _tactics-in-terms: - -Solving existential variables using tactics -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Instead of letting the unification engine try to solve an existential -variable by itself, one can also provide an explicit hole together -with a tactic to solve it. Using the syntax ``ltac:(``\ `tacexpr`\ ``)``, the user -can put a tactic anywhere a term is expected. The order of resolution -is not specified and is implementation-dependent. The inner tactic may -use any variable defined in its scope, including repeated alternations -between variables introduced by term binding as well as those -introduced by tactic binding. The expression `tacexpr` can be any tactic -expression as described in :ref:`ltac`. - -.. coqtop:: all - - Definition foo (x : nat) : nat := ltac:(exact x). - -This construction is useful when one wants to define complicated terms -using highly automated tactics without resorting to writing the proof-term -by means of the interactive proof engine. - -.. _primitive-integers: - -Primitive Integers ------------------- - -The language of terms features 63-bit machine integers as values. The type of -such a value is *axiomatized*; it is declared through the following sentence -(excerpt from the :g:`Int63` module): - -.. coqdoc:: - - Primitive int := #int63_type. - -This type is equipped with a few operators, that must be similarly declared. -For instance, equality of two primitive integers can be decided using the :g:`Int63.eqb` function, -declared and specified as follows: - -.. coqdoc:: - - Primitive eqb := #int63_eq. - Notation "m '==' n" := (eqb m n) (at level 70, no associativity) : int63_scope. - - Axiom eqb_correct : forall i j, (i == j)%int63 = true -> i = j. - -The complete set of such operators can be obtained looking at the :g:`Int63` module. - -These primitive declarations are regular axioms. As such, they must be trusted and are listed by the -:g:`Print Assumptions` command, as in the following example. - -.. coqtop:: in reset - - From Coq Require Import Int63. - Lemma one_minus_one_is_zero : (1 - 1 = 0)%int63. - Proof. apply eqb_correct; vm_compute; reflexivity. Qed. - -.. coqtop:: all - - Print Assumptions one_minus_one_is_zero. - -The reduction machines (:tacn:`vm_compute`, :tacn:`native_compute`) implement -dedicated, efficient, rules to reduce the applications of these primitive -operations. - -The extraction of these primitives can be customized similarly to the extraction -of regular axioms (see :ref:`extraction`). Nonetheless, the :g:`ExtrOCamlInt63` -module can be used when extracting to OCaml: it maps the Coq primitives to types -and functions of a :g:`Uint63` module. Said OCaml module is not produced by -extraction. Instead, it has to be provided by the user (if they want to compile -or execute the extracted code). For instance, an implementation of this module -can be taken from the kernel of Coq. - -Literal values (at type :g:`Int63.int`) are extracted to literal OCaml values -wrapped into the :g:`Uint63.of_int` (resp. :g:`Uint63.of_int64`) constructor on -64-bit (resp. 32-bit) platforms. Currently, this cannot be customized (see the -function :g:`Uint63.compile` from the kernel). - -.. _primitive-floats: - -Primitive Floats ----------------- - -The language of terms features Binary64 floating-point numbers as values. -The type of such a value is *axiomatized*; it is declared through the -following sentence (excerpt from the :g:`PrimFloat` module): - -.. coqdoc:: - - Primitive float := #float64_type. - -This type is equipped with a few operators, that must be similarly declared. -For instance, the product of two primitive floats can be computed using the -:g:`PrimFloat.mul` function, declared and specified as follows: - -.. coqdoc:: - - Primitive mul := #float64_mul. - Notation "x * y" := (mul x y) : float_scope. - - Axiom mul_spec : forall x y, Prim2SF (x * y)%float = SF64mul (Prim2SF x) (Prim2SF y). - -where :g:`Prim2SF` is defined in the :g:`FloatOps` module. - -The set of such operators is described in section :ref:`floats_library`. - -These primitive declarations are regular axioms. As such, they must be trusted, and are listed by the -:g:`Print Assumptions` command. - -The reduction machines (:tacn:`vm_compute`, :tacn:`native_compute`) implement -dedicated, efficient rules to reduce the applications of these primitive -operations, using the floating-point processor operators that are assumed -to comply with the IEEE 754 standard for floating-point arithmetic. - -The extraction of these primitives can be customized similarly to the extraction -of regular axioms (see :ref:`extraction`). Nonetheless, the :g:`ExtrOCamlFloats` -module can be used when extracting to OCaml: it maps the Coq primitives to types -and functions of a :g:`Float64` module. Said OCaml module is not produced by -extraction. Instead, it has to be provided by the user (if they want to compile -or execute the extracted code). For instance, an implementation of this module -can be taken from the kernel of Coq. - -Literal values (of type :g:`Float64.t`) are extracted to literal OCaml -values (of type :g:`float`) written in hexadecimal notation and -wrapped into the :g:`Float64.of_float` constructor, e.g.: -:g:`Float64.of_float (0x1p+0)`. -- cgit v1.2.3 From b08947fbe6f9858ef193f48721d4997953c18223 Mon Sep 17 00:00:00 2001 From: Théo Zimmermann Date: Wed, 13 May 2020 23:44:01 +0200 Subject: Add to file on modules. --- doc/sphinx/language/core/modules.rst | 546 +++++++++++++++++++++++++++++ doc/sphinx/language/gallina-extensions.rst | 546 ----------------------------- 2 files changed, 546 insertions(+), 546 deletions(-) create mode 100644 doc/sphinx/language/core/modules.rst delete mode 100644 doc/sphinx/language/gallina-extensions.rst (limited to 'doc/sphinx') diff --git a/doc/sphinx/language/core/modules.rst b/doc/sphinx/language/core/modules.rst new file mode 100644 index 0000000000..ca045dc082 --- /dev/null +++ b/doc/sphinx/language/core/modules.rst @@ -0,0 +1,546 @@ +Using modules +------------- + +The module system provides a way of packaging related elements +together, as well as a means of massive abstraction. + + +.. cmd:: Module {? {| Import | Export } } @ident {* @module_binder } {? @of_module_type } {? := {+<+ @module_expr_inl } } + + .. insertprodn module_binder module_expr_inl + + .. prodn:: + module_binder ::= ( {? {| Import | Export } } {+ @ident } : @module_type_inl ) + module_type_inl ::= ! @module_type + | @module_type {? @functor_app_annot } + functor_app_annot ::= [ inline at level @num ] + | [ no inline ] + module_type ::= @qualid + | ( @module_type ) + | @module_type @module_expr_atom + | @module_type with @with_declaration + with_declaration ::= Definition @qualid {? @univ_decl } := @term + | Module @qualid := @qualid + module_expr_atom ::= @qualid + | ( {+ @module_expr_atom } ) + of_module_type ::= : @module_type_inl + | {* <: @module_type_inl } + module_expr_inl ::= ! {+ @module_expr_atom } + | {+ @module_expr_atom } {? @functor_app_annot } + + Defines a module named :token:`ident`. See the examples :ref:`here`. + + The :n:`Import` and :n:`Export` flags specify whether the module should be automatically + imported or exported. + + Specifying :n:`{* @module_binder }` starts a functor with + parameters given by the :n:`@module_binder`\s. (A *functor* is a function + from modules to modules.) + + :n:`@of_module_type` specifies the module type. :n:`{+ <: @module_type_inl }` + starts a module that satisfies each :n:`@module_type_inl`. + + .. todo: would like to find a better term than "interactive", not very descriptive + + :n:`:= {+<+ @module_expr_inl }` specifies the body of a module or functor + definition. If it's not specified, then the module is defined *interactively*, + meaning that the module is defined as a series of commands terminated with :cmd:`End` + instead of in a single :cmd:`Module` command. + Interactively defining the :n:`@module_expr_inl`\s in a series of + :cmd:`Include` commands is equivalent to giving them all in a single + non-interactive :cmd:`Module` command. + + The ! prefix indicates that any assumption command (such as :cmd:`Axiom`) with an :n:`Inline` clause + in the type of the functor arguments will be ignored. + + .. todo: What is an Inline directive? sb command but still unclear. Maybe referring to the + "inline" in functor_app_annot? or assumption_token Inline assum_list? + +.. cmd:: Module Type @ident {* @module_binder } {* <: @module_type_inl } {? := {+<+ @module_type_inl } } + + Defines a module type named :n:`@ident`. See the example :ref:`here`. + + Specifying :n:`{* @module_binder }` starts a functor type with + parameters given by the :n:`@module_binder`\s. + + :n:`:= {+<+ @module_type_inl }` specifies the body of a module or functor type + definition. If it's not specified, then the module type is defined *interactively*, + meaning that the module type is defined as a series of commands terminated with :cmd:`End` + instead of in a single :cmd:`Module Type` command. + Interactively defining the :n:`@module_type_inl`\s in a series of + :cmd:`Include` commands is equivalent to giving them all in a single + non-interactive :cmd:`Module Type` command. + +.. _terminating_module: + +**Terminating an interactive module or module type definition** + +Interactive modules are terminated with the :cmd:`End` command, which +is also used to terminate :ref:`Sections`. +:n:`End @ident` closes the interactive module or module type :token:`ident`. +If the module type was given, the command verifies that the content of the module +matches the module type. If the module is not a +functor, its components (constants, inductive types, submodules etc.) +are now available through the dot notation. + +.. exn:: No such label @ident. + :undocumented: + +.. exn:: Signature components for label @ident do not match. + :undocumented: + +.. exn:: The field @ident is missing in @qualid. + :undocumented: + +.. |br| raw:: html + +
+ +.. note:: + + #. Interactive modules and module types can be nested. + #. Interactive modules and module types can't be defined inside of :ref:`sections`. + Sections can be defined inside of interactive modules and module types. + #. Hints and notations (:cmd:`Hint` and :cmd:`Notation` commands) can also appear inside interactive + modules and module types. Note that with module definitions like: + + :n:`Module @ident__1 : @module_type := @ident__2.` + + or + + :n:`Module @ident__1 : @module_type.` |br| + :n:`Include @ident__2.` |br| + :n:`End @ident__1.` + + hints and the like valid for :n:`@ident__1` are the ones defined in :n:`@module_type` + rather then those defined in :n:`@ident__2` (or the module body). + #. Within an interactive module type definition, the :cmd:`Parameter` command declares a + constant instead of definining a new axiom (which it does when not in a module type definition). + #. Assumptions such as :cmd:`Axiom` that include the :n:`Inline` clause will be automatically + expanded when the functor is applied, except when the function application is prefixed by ``!``. + +.. cmd:: Include @module_type_inl {* <+ @module_expr_inl } + + Includes the content of module(s) in the current + interactive module. Here :n:`@module_type_inl` can be a module expression or a module + type expression. If it is a high-order module or module type + expression then the system tries to instantiate :n:`@module_type_inl` with the current + interactive module. + + Including multiple modules is a single :cmd:`Include` is equivalent to including each module + in a separate :cmd:`Include` command. + +.. cmd:: Include Type {+<+ @module_type_inl } + + .. deprecated:: 8.3 + + Use :cmd:`Include` instead. + +.. cmd:: Declare Module {? {| Import | Export } } @ident {* @module_binder } : @module_type_inl + + Declares a module :token:`ident` of type :token:`module_type_inl`. + + If :n:`@module_binder`\s are specified, declares a functor with parameters given by the list of + :token:`module_binder`\s. + +.. cmd:: Import {+ @filtered_import } + + .. insertprodn filtered_import filtered_import + + .. prodn:: + filtered_import ::= @qualid {? ( {+, @qualid {? ( .. ) } } ) } + + If :token:`qualid` denotes a valid basic module (i.e. its module type is a + signature), makes its components available by their short names. + + .. example:: + + .. coqtop:: reset in + + Module Mod. + Definition T:=nat. + Check T. + End Mod. + Check Mod.T. + + .. coqtop:: all + + Fail Check T. + Import Mod. + Check T. + + Some features defined in modules are activated only when a module is + imported. This is for instance the case of notations (see :ref:`Notations`). + + Declarations made with the :attr:`local` attribute are never imported by the :cmd:`Import` + command. Such declarations are only accessible through their fully + qualified name. + + .. example:: + + .. coqtop:: in + + Module A. + Module B. + Local Definition T := nat. + End B. + End A. + Import A. + + .. coqtop:: all fail + + Check B.T. + + Appending a module name with a parenthesized list of names will + make only those names available with short names, not other names + defined in the module nor will it activate other features. + + The names to import may be constants, inductive types and + constructors, and notation aliases (for instance, Ltac definitions + cannot be selectively imported). If they are from an inner module + to the one being imported, they must be prefixed by the inner path. + + The name of an inductive type may also be followed by ``(..)`` to + import it, its constructors and its eliminators if they exist. For + this purpose "eliminator" means a constant in the same module whose + name is the inductive type's name suffixed by one of ``_sind``, + ``_ind``, ``_rec`` or ``_rect``. + + .. example:: + + .. coqtop:: reset in + + Module A. + Module B. + Inductive T := C. + Definition U := nat. + End B. + Definition Z := Prop. + End A. + Import A(B.T(..), Z). + + .. coqtop:: all + + Check B.T. + Check B.C. + Check Z. + Fail Check B.U. + Check A.B.U. + +.. cmd:: Export {+ @filtered_import } + :name: Export + + Similar to :cmd:`Import`, except that when the module containing this command + is imported, the :n:`{+ @qualid }` are imported as well. + + The selective import syntax also works with Export. + + .. exn:: @qualid is not a module. + :undocumented: + + .. warn:: Trying to mask the absolute name @qualid! + :undocumented: + +.. cmd:: Print Module @qualid + + Prints the module type and (optionally) the body of the module :n:`@qualid`. + +.. cmd:: Print Module Type @qualid + + Prints the module type corresponding to :n:`@qualid`. + +.. flag:: Short Module Printing + + This flag (off by default) disables the printing of the types of fields, + leaving only their names, for the commands :cmd:`Print Module` and + :cmd:`Print Module Type`. + +.. _module_examples: + +Examples +~~~~~~~~ + +.. example:: Defining a simple module interactively + + .. coqtop:: in + + Module M. + Definition T := nat. + Definition x := 0. + + .. coqtop:: all + + Definition y : bool. + exact true. + + .. coqtop:: in + + Defined. + End M. + +Inside a module one can define constants, prove theorems and do anything +else that can be done in the toplevel. Components of a closed +module can be accessed using the dot notation: + +.. coqtop:: all + + Print M.x. + +.. _example_def_simple_module_type: + +.. example:: Defining a simple module type interactively + + .. coqtop:: in + + Module Type SIG. + Parameter T : Set. + Parameter x : T. + End SIG. + +.. _example_filter_module: + +.. example:: Creating a new module that omits some items from an existing module + + Since :n:`SIG`, the type of the new module :n:`N`, doesn't define :n:`y` or + give the body of :n:`x`, which are not included in :n:`N`. + + .. coqtop:: all + + Module N : SIG with Definition T := nat := M. + Print N.T. + Print N.x. + Fail Print N.y. + + .. reset to remove N (undo in last coqtop block doesn't seem to do that), invisibly redefine M, SIG + .. coqtop:: none reset + + Module M. + Definition T := nat. + Definition x := 0. + Definition y : bool. + exact true. + Defined. + End M. + + Module Type SIG. + Parameter T : Set. + Parameter x : T. + End SIG. + +The definition of :g:`N` using the module type expression :g:`SIG` with +:g:`Definition T := nat` is equivalent to the following one: + +.. coqtop:: in + + Module Type SIG'. + Definition T : Set := nat. + Parameter x : T. + End SIG'. + + Module N : SIG' := M. + +If we just want to be sure that our implementation satisfies a +given module type without restricting the interface, we can use a +transparent constraint + +.. coqtop:: in + + Module P <: SIG := M. + +.. coqtop:: all + + Print P.y. + +.. example:: Creating a functor (a module with parameters) + + .. coqtop:: in + + Module Two (X Y: SIG). + Definition T := (X.T * Y.T)%type. + Definition x := (X.x, Y.x). + End Two. + + and apply it to our modules and do some computations: + + .. coqtop:: in + + + Module Q := Two M N. + + .. coqtop:: all + + Eval compute in (fst Q.x + snd Q.x). + +.. example:: A module type with two sub-modules, sharing some fields + + .. coqtop:: in + + Module Type SIG2. + Declare Module M1 : SIG. + Module M2 <: SIG. + Definition T := M1.T. + Parameter x : T. + End M2. + End SIG2. + + .. coqtop:: in + + Module Mod <: SIG2. + Module M1. + Definition T := nat. + Definition x := 1. + End M1. + Module M2 := M. + End Mod. + +Notice that ``M`` is a correct body for the component ``M2`` since its ``T`` +component is ``nat`` as specified for ``M1.T``. + +Libraries and qualified names +--------------------------------- + +.. _names-of-libraries: + +Names of libraries +~~~~~~~~~~~~~~~~~~ + +The theories developed in |Coq| are stored in *library files* which are +hierarchically classified into *libraries* and *sublibraries*. To +express this hierarchy, library names are represented by qualified +identifiers qualid, i.e. as list of identifiers separated by dots (see +:ref:`gallina-identifiers`). For instance, the library file ``Mult`` of the standard +|Coq| library ``Arith`` is named ``Coq.Arith.Mult``. The identifier that starts +the name of a library is called a *library root*. All library files of +the standard library of |Coq| have the reserved root |Coq| but library +filenames based on other roots can be obtained by using |Coq| commands +(coqc, coqtop, coqdep, …) options ``-Q`` or ``-R`` (see :ref:`command-line-options`). +Also, when an interactive |Coq| session starts, a library of root ``Top`` is +started, unless option ``-top`` or ``-notop`` is set (see :ref:`command-line-options`). + +.. _qualified-names: + +Qualified names +~~~~~~~~~~~~~~~ + +Library files are modules which possibly contain submodules which +eventually contain constructions (axioms, parameters, definitions, +lemmas, theorems, remarks or facts). The *absolute name*, or *full +name*, of a construction in some library file is a qualified +identifier starting with the logical name of the library file, +followed by the sequence of submodules names encapsulating the +construction and ended by the proper name of the construction. +Typically, the absolute name ``Coq.Init.Logic.eq`` denotes Leibniz’ +equality defined in the module Logic in the sublibrary ``Init`` of the +standard library of |Coq|. + +The proper name that ends the name of a construction is the short name +(or sometimes base name) of the construction (for instance, the short +name of ``Coq.Init.Logic.eq`` is ``eq``). Any partial suffix of the absolute +name is a *partially qualified name* (e.g. ``Logic.eq`` is a partially +qualified name for ``Coq.Init.Logic.eq``). Especially, the short name of a +construction is its shortest partially qualified name. + +|Coq| does not accept two constructions (definition, theorem, …) with +the same absolute name but different constructions can have the same +short name (or even same partially qualified names as soon as the full +names are different). + +Notice that the notion of absolute, partially qualified and short +names also applies to library filenames. + +**Visibility** + +|Coq| maintains a table called the name table which maps partially qualified +names of constructions to absolute names. This table is updated by the +commands :cmd:`Require`, :cmd:`Import` and :cmd:`Export` and +also each time a new declaration is added to the context. An absolute +name is called visible from a given short or partially qualified name +when this latter name is enough to denote it. This means that the +short or partially qualified name is mapped to the absolute name in +|Coq| name table. Definitions with the :attr:`local` attribute are only accessible with +their fully qualified name (see :ref:`gallina-definitions`). + +It may happen that a visible name is hidden by the short name or a +qualified name of another construction. In this case, the name that +has been hidden must be referred to using one more level of +qualification. To ensure that a construction always remains +accessible, absolute names can never be hidden. + +.. example:: + + .. coqtop:: all + + Check 0. + + Definition nat := bool. + + Check 0. + + Check Datatypes.nat. + + Locate nat. + +.. seealso:: Commands :cmd:`Locate`. + +.. _libraries-and-filesystem: + +Libraries and filesystem +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. note:: The questions described here have been subject to redesign in |Coq| 8.5. + Former versions of |Coq| use the same terminology to describe slightly different things. + +Compiled files (``.vo`` and ``.vio``) store sub-libraries. In order to refer +to them inside |Coq|, a translation from file-system names to |Coq| names +is needed. In this translation, names in the file system are called +*physical* paths while |Coq| names are contrastingly called *logical* +names. + +A logical prefix Lib can be associated with a physical path using +the command line option ``-Q`` `path` ``Lib``. All subfolders of path are +recursively associated to the logical path ``Lib`` extended with the +corresponding suffix coming from the physical path. For instance, the +folder ``path/fOO/Bar`` maps to ``Lib.fOO.Bar``. Subdirectories corresponding +to invalid |Coq| identifiers are skipped, and, by convention, +subdirectories named ``CVS`` or ``_darcs`` are skipped too. + +Thanks to this mechanism, ``.vo`` files are made available through the +logical name of the folder they are in, extended with their own +basename. For example, the name associated to the file +``path/fOO/Bar/File.vo`` is ``Lib.fOO.Bar.File``. The same caveat applies for +invalid identifiers. When compiling a source file, the ``.vo`` file stores +its logical name, so that an error is issued if it is loaded with the +wrong loadpath afterwards. + +Some folders have a special status and are automatically put in the +path. |Coq| commands associate automatically a logical path to files in +the repository trees rooted at the directory from where the command is +launched, ``coqlib/user-contrib/``, the directories listed in the +``$COQPATH``, ``${XDG_DATA_HOME}/coq/`` and ``${XDG_DATA_DIRS}/coq/`` +environment variables (see `XDG base directory specification +`_) +with the same physical-to-logical translation and with an empty logical prefix. + +The command line option ``-R`` is a variant of ``-Q`` which has the strictly +same behavior regarding loadpaths, but which also makes the +corresponding ``.vo`` files available through their short names in a way +similar to the :cmd:`Import` command. For instance, ``-R path Lib`` +associates to the file ``/path/fOO/Bar/File.vo`` the logical name +``Lib.fOO.Bar.File``, but allows this file to be accessed through the +short names ``fOO.Bar.File,Bar.File`` and ``File``. If several files with +identical base name are present in different subdirectories of a +recursive loadpath, which of these files is found first may be system- +dependent and explicit qualification is recommended. The ``From`` argument +of the ``Require`` command can be used to bypass the implicit shortening +by providing an absolute root to the required file (see :ref:`compiled-files`). + +There also exists another independent loadpath mechanism attached to +OCaml object files (``.cmo`` or ``.cmxs``) rather than |Coq| object +files as described above. The OCaml loadpath is managed using +the option ``-I`` `path` (in the OCaml world, there is neither a +notion of logical name prefix nor a way to access files in +subdirectories of path). See the command :cmd:`Declare ML Module` in +:ref:`compiled-files` to understand the need of the OCaml loadpath. + +See :ref:`command-line-options` for a more general view over the |Coq| command +line options. diff --git a/doc/sphinx/language/gallina-extensions.rst b/doc/sphinx/language/gallina-extensions.rst deleted file mode 100644 index ca045dc082..0000000000 --- a/doc/sphinx/language/gallina-extensions.rst +++ /dev/null @@ -1,546 +0,0 @@ -Using modules -------------- - -The module system provides a way of packaging related elements -together, as well as a means of massive abstraction. - - -.. cmd:: Module {? {| Import | Export } } @ident {* @module_binder } {? @of_module_type } {? := {+<+ @module_expr_inl } } - - .. insertprodn module_binder module_expr_inl - - .. prodn:: - module_binder ::= ( {? {| Import | Export } } {+ @ident } : @module_type_inl ) - module_type_inl ::= ! @module_type - | @module_type {? @functor_app_annot } - functor_app_annot ::= [ inline at level @num ] - | [ no inline ] - module_type ::= @qualid - | ( @module_type ) - | @module_type @module_expr_atom - | @module_type with @with_declaration - with_declaration ::= Definition @qualid {? @univ_decl } := @term - | Module @qualid := @qualid - module_expr_atom ::= @qualid - | ( {+ @module_expr_atom } ) - of_module_type ::= : @module_type_inl - | {* <: @module_type_inl } - module_expr_inl ::= ! {+ @module_expr_atom } - | {+ @module_expr_atom } {? @functor_app_annot } - - Defines a module named :token:`ident`. See the examples :ref:`here`. - - The :n:`Import` and :n:`Export` flags specify whether the module should be automatically - imported or exported. - - Specifying :n:`{* @module_binder }` starts a functor with - parameters given by the :n:`@module_binder`\s. (A *functor* is a function - from modules to modules.) - - :n:`@of_module_type` specifies the module type. :n:`{+ <: @module_type_inl }` - starts a module that satisfies each :n:`@module_type_inl`. - - .. todo: would like to find a better term than "interactive", not very descriptive - - :n:`:= {+<+ @module_expr_inl }` specifies the body of a module or functor - definition. If it's not specified, then the module is defined *interactively*, - meaning that the module is defined as a series of commands terminated with :cmd:`End` - instead of in a single :cmd:`Module` command. - Interactively defining the :n:`@module_expr_inl`\s in a series of - :cmd:`Include` commands is equivalent to giving them all in a single - non-interactive :cmd:`Module` command. - - The ! prefix indicates that any assumption command (such as :cmd:`Axiom`) with an :n:`Inline` clause - in the type of the functor arguments will be ignored. - - .. todo: What is an Inline directive? sb command but still unclear. Maybe referring to the - "inline" in functor_app_annot? or assumption_token Inline assum_list? - -.. cmd:: Module Type @ident {* @module_binder } {* <: @module_type_inl } {? := {+<+ @module_type_inl } } - - Defines a module type named :n:`@ident`. See the example :ref:`here`. - - Specifying :n:`{* @module_binder }` starts a functor type with - parameters given by the :n:`@module_binder`\s. - - :n:`:= {+<+ @module_type_inl }` specifies the body of a module or functor type - definition. If it's not specified, then the module type is defined *interactively*, - meaning that the module type is defined as a series of commands terminated with :cmd:`End` - instead of in a single :cmd:`Module Type` command. - Interactively defining the :n:`@module_type_inl`\s in a series of - :cmd:`Include` commands is equivalent to giving them all in a single - non-interactive :cmd:`Module Type` command. - -.. _terminating_module: - -**Terminating an interactive module or module type definition** - -Interactive modules are terminated with the :cmd:`End` command, which -is also used to terminate :ref:`Sections`. -:n:`End @ident` closes the interactive module or module type :token:`ident`. -If the module type was given, the command verifies that the content of the module -matches the module type. If the module is not a -functor, its components (constants, inductive types, submodules etc.) -are now available through the dot notation. - -.. exn:: No such label @ident. - :undocumented: - -.. exn:: Signature components for label @ident do not match. - :undocumented: - -.. exn:: The field @ident is missing in @qualid. - :undocumented: - -.. |br| raw:: html - -
- -.. note:: - - #. Interactive modules and module types can be nested. - #. Interactive modules and module types can't be defined inside of :ref:`sections`. - Sections can be defined inside of interactive modules and module types. - #. Hints and notations (:cmd:`Hint` and :cmd:`Notation` commands) can also appear inside interactive - modules and module types. Note that with module definitions like: - - :n:`Module @ident__1 : @module_type := @ident__2.` - - or - - :n:`Module @ident__1 : @module_type.` |br| - :n:`Include @ident__2.` |br| - :n:`End @ident__1.` - - hints and the like valid for :n:`@ident__1` are the ones defined in :n:`@module_type` - rather then those defined in :n:`@ident__2` (or the module body). - #. Within an interactive module type definition, the :cmd:`Parameter` command declares a - constant instead of definining a new axiom (which it does when not in a module type definition). - #. Assumptions such as :cmd:`Axiom` that include the :n:`Inline` clause will be automatically - expanded when the functor is applied, except when the function application is prefixed by ``!``. - -.. cmd:: Include @module_type_inl {* <+ @module_expr_inl } - - Includes the content of module(s) in the current - interactive module. Here :n:`@module_type_inl` can be a module expression or a module - type expression. If it is a high-order module or module type - expression then the system tries to instantiate :n:`@module_type_inl` with the current - interactive module. - - Including multiple modules is a single :cmd:`Include` is equivalent to including each module - in a separate :cmd:`Include` command. - -.. cmd:: Include Type {+<+ @module_type_inl } - - .. deprecated:: 8.3 - - Use :cmd:`Include` instead. - -.. cmd:: Declare Module {? {| Import | Export } } @ident {* @module_binder } : @module_type_inl - - Declares a module :token:`ident` of type :token:`module_type_inl`. - - If :n:`@module_binder`\s are specified, declares a functor with parameters given by the list of - :token:`module_binder`\s. - -.. cmd:: Import {+ @filtered_import } - - .. insertprodn filtered_import filtered_import - - .. prodn:: - filtered_import ::= @qualid {? ( {+, @qualid {? ( .. ) } } ) } - - If :token:`qualid` denotes a valid basic module (i.e. its module type is a - signature), makes its components available by their short names. - - .. example:: - - .. coqtop:: reset in - - Module Mod. - Definition T:=nat. - Check T. - End Mod. - Check Mod.T. - - .. coqtop:: all - - Fail Check T. - Import Mod. - Check T. - - Some features defined in modules are activated only when a module is - imported. This is for instance the case of notations (see :ref:`Notations`). - - Declarations made with the :attr:`local` attribute are never imported by the :cmd:`Import` - command. Such declarations are only accessible through their fully - qualified name. - - .. example:: - - .. coqtop:: in - - Module A. - Module B. - Local Definition T := nat. - End B. - End A. - Import A. - - .. coqtop:: all fail - - Check B.T. - - Appending a module name with a parenthesized list of names will - make only those names available with short names, not other names - defined in the module nor will it activate other features. - - The names to import may be constants, inductive types and - constructors, and notation aliases (for instance, Ltac definitions - cannot be selectively imported). If they are from an inner module - to the one being imported, they must be prefixed by the inner path. - - The name of an inductive type may also be followed by ``(..)`` to - import it, its constructors and its eliminators if they exist. For - this purpose "eliminator" means a constant in the same module whose - name is the inductive type's name suffixed by one of ``_sind``, - ``_ind``, ``_rec`` or ``_rect``. - - .. example:: - - .. coqtop:: reset in - - Module A. - Module B. - Inductive T := C. - Definition U := nat. - End B. - Definition Z := Prop. - End A. - Import A(B.T(..), Z). - - .. coqtop:: all - - Check B.T. - Check B.C. - Check Z. - Fail Check B.U. - Check A.B.U. - -.. cmd:: Export {+ @filtered_import } - :name: Export - - Similar to :cmd:`Import`, except that when the module containing this command - is imported, the :n:`{+ @qualid }` are imported as well. - - The selective import syntax also works with Export. - - .. exn:: @qualid is not a module. - :undocumented: - - .. warn:: Trying to mask the absolute name @qualid! - :undocumented: - -.. cmd:: Print Module @qualid - - Prints the module type and (optionally) the body of the module :n:`@qualid`. - -.. cmd:: Print Module Type @qualid - - Prints the module type corresponding to :n:`@qualid`. - -.. flag:: Short Module Printing - - This flag (off by default) disables the printing of the types of fields, - leaving only their names, for the commands :cmd:`Print Module` and - :cmd:`Print Module Type`. - -.. _module_examples: - -Examples -~~~~~~~~ - -.. example:: Defining a simple module interactively - - .. coqtop:: in - - Module M. - Definition T := nat. - Definition x := 0. - - .. coqtop:: all - - Definition y : bool. - exact true. - - .. coqtop:: in - - Defined. - End M. - -Inside a module one can define constants, prove theorems and do anything -else that can be done in the toplevel. Components of a closed -module can be accessed using the dot notation: - -.. coqtop:: all - - Print M.x. - -.. _example_def_simple_module_type: - -.. example:: Defining a simple module type interactively - - .. coqtop:: in - - Module Type SIG. - Parameter T : Set. - Parameter x : T. - End SIG. - -.. _example_filter_module: - -.. example:: Creating a new module that omits some items from an existing module - - Since :n:`SIG`, the type of the new module :n:`N`, doesn't define :n:`y` or - give the body of :n:`x`, which are not included in :n:`N`. - - .. coqtop:: all - - Module N : SIG with Definition T := nat := M. - Print N.T. - Print N.x. - Fail Print N.y. - - .. reset to remove N (undo in last coqtop block doesn't seem to do that), invisibly redefine M, SIG - .. coqtop:: none reset - - Module M. - Definition T := nat. - Definition x := 0. - Definition y : bool. - exact true. - Defined. - End M. - - Module Type SIG. - Parameter T : Set. - Parameter x : T. - End SIG. - -The definition of :g:`N` using the module type expression :g:`SIG` with -:g:`Definition T := nat` is equivalent to the following one: - -.. coqtop:: in - - Module Type SIG'. - Definition T : Set := nat. - Parameter x : T. - End SIG'. - - Module N : SIG' := M. - -If we just want to be sure that our implementation satisfies a -given module type without restricting the interface, we can use a -transparent constraint - -.. coqtop:: in - - Module P <: SIG := M. - -.. coqtop:: all - - Print P.y. - -.. example:: Creating a functor (a module with parameters) - - .. coqtop:: in - - Module Two (X Y: SIG). - Definition T := (X.T * Y.T)%type. - Definition x := (X.x, Y.x). - End Two. - - and apply it to our modules and do some computations: - - .. coqtop:: in - - - Module Q := Two M N. - - .. coqtop:: all - - Eval compute in (fst Q.x + snd Q.x). - -.. example:: A module type with two sub-modules, sharing some fields - - .. coqtop:: in - - Module Type SIG2. - Declare Module M1 : SIG. - Module M2 <: SIG. - Definition T := M1.T. - Parameter x : T. - End M2. - End SIG2. - - .. coqtop:: in - - Module Mod <: SIG2. - Module M1. - Definition T := nat. - Definition x := 1. - End M1. - Module M2 := M. - End Mod. - -Notice that ``M`` is a correct body for the component ``M2`` since its ``T`` -component is ``nat`` as specified for ``M1.T``. - -Libraries and qualified names ---------------------------------- - -.. _names-of-libraries: - -Names of libraries -~~~~~~~~~~~~~~~~~~ - -The theories developed in |Coq| are stored in *library files* which are -hierarchically classified into *libraries* and *sublibraries*. To -express this hierarchy, library names are represented by qualified -identifiers qualid, i.e. as list of identifiers separated by dots (see -:ref:`gallina-identifiers`). For instance, the library file ``Mult`` of the standard -|Coq| library ``Arith`` is named ``Coq.Arith.Mult``. The identifier that starts -the name of a library is called a *library root*. All library files of -the standard library of |Coq| have the reserved root |Coq| but library -filenames based on other roots can be obtained by using |Coq| commands -(coqc, coqtop, coqdep, …) options ``-Q`` or ``-R`` (see :ref:`command-line-options`). -Also, when an interactive |Coq| session starts, a library of root ``Top`` is -started, unless option ``-top`` or ``-notop`` is set (see :ref:`command-line-options`). - -.. _qualified-names: - -Qualified names -~~~~~~~~~~~~~~~ - -Library files are modules which possibly contain submodules which -eventually contain constructions (axioms, parameters, definitions, -lemmas, theorems, remarks or facts). The *absolute name*, or *full -name*, of a construction in some library file is a qualified -identifier starting with the logical name of the library file, -followed by the sequence of submodules names encapsulating the -construction and ended by the proper name of the construction. -Typically, the absolute name ``Coq.Init.Logic.eq`` denotes Leibniz’ -equality defined in the module Logic in the sublibrary ``Init`` of the -standard library of |Coq|. - -The proper name that ends the name of a construction is the short name -(or sometimes base name) of the construction (for instance, the short -name of ``Coq.Init.Logic.eq`` is ``eq``). Any partial suffix of the absolute -name is a *partially qualified name* (e.g. ``Logic.eq`` is a partially -qualified name for ``Coq.Init.Logic.eq``). Especially, the short name of a -construction is its shortest partially qualified name. - -|Coq| does not accept two constructions (definition, theorem, …) with -the same absolute name but different constructions can have the same -short name (or even same partially qualified names as soon as the full -names are different). - -Notice that the notion of absolute, partially qualified and short -names also applies to library filenames. - -**Visibility** - -|Coq| maintains a table called the name table which maps partially qualified -names of constructions to absolute names. This table is updated by the -commands :cmd:`Require`, :cmd:`Import` and :cmd:`Export` and -also each time a new declaration is added to the context. An absolute -name is called visible from a given short or partially qualified name -when this latter name is enough to denote it. This means that the -short or partially qualified name is mapped to the absolute name in -|Coq| name table. Definitions with the :attr:`local` attribute are only accessible with -their fully qualified name (see :ref:`gallina-definitions`). - -It may happen that a visible name is hidden by the short name or a -qualified name of another construction. In this case, the name that -has been hidden must be referred to using one more level of -qualification. To ensure that a construction always remains -accessible, absolute names can never be hidden. - -.. example:: - - .. coqtop:: all - - Check 0. - - Definition nat := bool. - - Check 0. - - Check Datatypes.nat. - - Locate nat. - -.. seealso:: Commands :cmd:`Locate`. - -.. _libraries-and-filesystem: - -Libraries and filesystem -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. note:: The questions described here have been subject to redesign in |Coq| 8.5. - Former versions of |Coq| use the same terminology to describe slightly different things. - -Compiled files (``.vo`` and ``.vio``) store sub-libraries. In order to refer -to them inside |Coq|, a translation from file-system names to |Coq| names -is needed. In this translation, names in the file system are called -*physical* paths while |Coq| names are contrastingly called *logical* -names. - -A logical prefix Lib can be associated with a physical path using -the command line option ``-Q`` `path` ``Lib``. All subfolders of path are -recursively associated to the logical path ``Lib`` extended with the -corresponding suffix coming from the physical path. For instance, the -folder ``path/fOO/Bar`` maps to ``Lib.fOO.Bar``. Subdirectories corresponding -to invalid |Coq| identifiers are skipped, and, by convention, -subdirectories named ``CVS`` or ``_darcs`` are skipped too. - -Thanks to this mechanism, ``.vo`` files are made available through the -logical name of the folder they are in, extended with their own -basename. For example, the name associated to the file -``path/fOO/Bar/File.vo`` is ``Lib.fOO.Bar.File``. The same caveat applies for -invalid identifiers. When compiling a source file, the ``.vo`` file stores -its logical name, so that an error is issued if it is loaded with the -wrong loadpath afterwards. - -Some folders have a special status and are automatically put in the -path. |Coq| commands associate automatically a logical path to files in -the repository trees rooted at the directory from where the command is -launched, ``coqlib/user-contrib/``, the directories listed in the -``$COQPATH``, ``${XDG_DATA_HOME}/coq/`` and ``${XDG_DATA_DIRS}/coq/`` -environment variables (see `XDG base directory specification -`_) -with the same physical-to-logical translation and with an empty logical prefix. - -The command line option ``-R`` is a variant of ``-Q`` which has the strictly -same behavior regarding loadpaths, but which also makes the -corresponding ``.vo`` files available through their short names in a way -similar to the :cmd:`Import` command. For instance, ``-R path Lib`` -associates to the file ``/path/fOO/Bar/File.vo`` the logical name -``Lib.fOO.Bar.File``, but allows this file to be accessed through the -short names ``fOO.Bar.File,Bar.File`` and ``File``. If several files with -identical base name are present in different subdirectories of a -recursive loadpath, which of these files is found first may be system- -dependent and explicit qualification is recommended. The ``From`` argument -of the ``Require`` command can be used to bypass the implicit shortening -by providing an absolute root to the required file (see :ref:`compiled-files`). - -There also exists another independent loadpath mechanism attached to -OCaml object files (``.cmo`` or ``.cmxs``) rather than |Coq| object -files as described above. The OCaml loadpath is managed using -the option ``-I`` `path` (in the OCaml world, there is neither a -notion of logical name prefix nor a way to access files in -subdirectories of path). See the command :cmd:`Declare ML Module` in -:ref:`compiled-files` to understand the need of the OCaml loadpath. - -See :ref:`command-line-options` for a more general view over the |Coq| command -line options. -- cgit v1.2.3 From 38bc188db7c0f84e6e798046d85db1da65567ec2 Mon Sep 17 00:00:00 2001 From: Théo Zimmermann Date: Wed, 13 May 2020 23:44:58 +0200 Subject: Move file on modules in new location. --- doc/sphinx/language/core/modules.rst | 456 ++++++++++++++++++++++++++++++++++ doc/sphinx/language/module-system.rst | 456 ---------------------------------- 2 files changed, 456 insertions(+), 456 deletions(-) create mode 100644 doc/sphinx/language/core/modules.rst delete mode 100644 doc/sphinx/language/module-system.rst (limited to 'doc/sphinx') diff --git a/doc/sphinx/language/core/modules.rst b/doc/sphinx/language/core/modules.rst new file mode 100644 index 0000000000..e1c054db42 --- /dev/null +++ b/doc/sphinx/language/core/modules.rst @@ -0,0 +1,456 @@ +.. _themodulesystem: + +The Module System +================= + +The module system extends the Calculus of Inductive Constructions +providing a convenient way to structure large developments as well as +a means of massive abstraction. + + +Modules and module types +---------------------------- + +**Access path.** An access path is denoted by :math:`p` and can be +either a module variable :math:`X` or, if :math:`p′` is an access path +and :math:`id` an identifier, then :math:`p′.id` is an access path. + + +**Structure element.** A structure element is denoted by :math:`e` and +is either a definition of a constant, an assumption, a definition of +an inductive, a definition of a module, an alias of a module or a module +type abbreviation. + + +**Structure expression.** A structure expression is denoted by :math:`S` and can be: + ++ an access path :math:`p` ++ a plain structure :math:`\Struct~e ; … ; e~\End` ++ a functor :math:`\Functor(X:S)~S′`, where :math:`X` is a module variable, :math:`S` and :math:`S′` are + structure expressions ++ an application :math:`S~p`, where :math:`S` is a structure expression and :math:`p` an + access path ++ a refined structure :math:`S~\with~p := p`′ or :math:`S~\with~p := t:T` where :math:`S` is a + structure expression, :math:`p` and :math:`p′` are access paths, :math:`t` is a term and :math:`T` is + the type of :math:`t`. + +**Module definition.** A module definition is written :math:`\Mod{X}{S}{S'}` +and consists of a module variable :math:`X`, a module type +:math:`S` which can be any structure expression and optionally a +module implementation :math:`S′` which can be any structure expression +except a refined structure. + + +**Module alias.** A module alias is written :math:`\ModA{X}{p}` +and consists of a module variable :math:`X` and a module path +:math:`p`. + +**Module type abbreviation.** +A module type abbreviation is written :math:`\ModType{Y}{S}`, +where :math:`Y` is an identifier and :math:`S` is any structure +expression . + + +Typing Modules +------------------ + +In order to introduce the typing system we first slightly extend the syntactic +class of terms and environments given in section :ref:`The-terms`. The +environments, apart from definitions of constants and inductive types now also +hold any other structure elements. Terms, apart from variables, constants and +complex terms, include also access paths. + +We also need additional typing judgments: + + ++ :math:`\WFT{E}{S}`, denoting that a structure :math:`S` is well-formed, ++ :math:`\WTM{E}{p}{S}`, denoting that the module pointed by :math:`p` has type :math:`S` in + environment :math:`E`. ++ :math:`\WEV{E}{S}{\ovl{S}}`, denoting that a structure :math:`S` is evaluated to a + structure :math:`S` in weak head normal form. ++ :math:`\WS{E}{S_1}{S_2}` , denoting that a structure :math:`S_1` is a subtype of a + structure :math:`S_2`. ++ :math:`\WS{E}{e_1}{e_2}` , denoting that a structure element e_1 is more + precise than a structure element e_2. + +The rules for forming structures are the following: + +.. inference:: WF-STR + + \WF{E;E′}{} + ------------------------ + \WFT{E}{ \Struct~E′ ~\End} + +.. inference:: WF-FUN + + \WFT{E; \ModS{X}{S}}{ \ovl{S′} } + -------------------------- + \WFT{E}{ \Functor(X:S)~S′} + + +Evaluation of structures to weak head normal form: + +.. inference:: WEVAL-APP + + \begin{array}{c} + \WEV{E}{S}{\Functor(X:S_1 )~S_2}~~~~~\WEV{E}{S_1}{\ovl{S_1}} \\ + \WTM{E}{p}{S_3}~~~~~ \WS{E}{S_3}{\ovl{S_1}} + \end{array} + -------------------------- + \WEV{E}{S~p}{S_2 \{p/X,t_1 /p_1 .c_1 ,…,t_n /p_n.c_n \}} + + +In the last rule, :math:`\{t_1 /p_1 .c_1 ,…,t_n /p_n .c_n \}` is the resulting +substitution from the inlining mechanism. We substitute in :math:`S` the +inlined fields :math:`p_i .c_i` from :math:`\ModS{X}{S_1 }` by the corresponding delta- +reduced term :math:`t_i` in :math:`p`. + +.. inference:: WEVAL-WITH-MOD + + \begin{array}{c} + E[] ⊢ S \lra \Struct~e_1 ;…;e_i ; \ModS{X}{S_1 };e_{i+2} ;… ;e_n ~\End \\ + E;e_1 ;…;e_i [] ⊢ S_1 \lra \ovl{S_1} ~~~~~~ + E[] ⊢ p : S_2 \\ + E;e_1 ;…;e_i [] ⊢ S_2 <: \ovl{S_1} + \end{array} + ---------------------------------- + \begin{array}{c} + \WEV{E}{S~\with~x := p}{}\\ + \Struct~e_1 ;…;e_i ; \ModA{X}{p};e_{i+2} \{p/X\} ;…;e_n \{p/X\} ~\End + \end{array} + +.. inference:: WEVAL-WITH-MOD-REC + + \begin{array}{c} + \WEV{E}{S}{\Struct~e_1 ;…;e_i ; \ModS{X_1}{S_1 };e_{i+2} ;… ;e_n ~\End} \\ + \WEV{E;e_1 ;…;e_i }{S_1~\with~p := p_1}{\ovl{S_2}} + \end{array} + -------------------------- + \begin{array}{c} + \WEV{E}{S~\with~X_1.p := p_1}{} \\ + \Struct~e_1 ;…;e_i ; \ModS{X}{\ovl{S_2}};e_{i+2} \{p_1 /X_1.p\} ;…;e_n \{p_1 /X_1.p\} ~\End + \end{array} + +.. inference:: WEVAL-WITH-DEF + + \begin{array}{c} + \WEV{E}{S}{\Struct~e_1 ;…;e_i ;\Assum{}{c}{T_1};e_{i+2} ;… ;e_n ~\End} \\ + \WS{E;e_1 ;…;e_i }{Def()(c:=t:T)}{\Assum{}{c}{T_1}} + \end{array} + -------------------------- + \begin{array}{c} + \WEV{E}{S~\with~c := t:T}{} \\ + \Struct~e_1 ;…;e_i ;Def()(c:=t:T);e_{i+2} ;… ;e_n ~\End + \end{array} + +.. inference:: WEVAL-WITH-DEF-REC + + \begin{array}{c} + \WEV{E}{S}{\Struct~e_1 ;…;e_i ; \ModS{X_1 }{S_1 };e_{i+2} ;… ;e_n ~\End} \\ + \WEV{E;e_1 ;…;e_i }{S_1~\with~p := p_1}{\ovl{S_2}} + \end{array} + -------------------------- + \begin{array}{c} + \WEV{E}{S~\with~X_1.p := t:T}{} \\ + \Struct~e_1 ;…;e_i ; \ModS{X}{\ovl{S_2} };e_{i+2} ;… ;e_n ~\End + \end{array} + +.. inference:: WEVAL-PATH-MOD1 + + \begin{array}{c} + \WEV{E}{p}{\Struct~e_1 ;…;e_i ; \Mod{X}{S}{S_1};e_{i+2} ;… ;e_n End} \\ + \WEV{E;e_1 ;…;e_i }{S}{\ovl{S}} + \end{array} + -------------------------- + E[] ⊢ p.X \lra \ovl{S} + +.. inference:: WEVAL-PATH-MOD2 + + \WF{E}{} + \Mod{X}{S}{S_1}∈ E + \WEV{E}{S}{\ovl{S}} + -------------------------- + \WEV{E}{X}{\ovl{S}} + +.. inference:: WEVAL-PATH-ALIAS1 + + \begin{array}{c} + \WEV{E}{p}{~\Struct~e_1 ;…;e_i ; \ModA{X}{p_1};e_{i+2} ;… ;e_n End} \\ + \WEV{E;e_1 ;…;e_i }{p_1}{\ovl{S}} + \end{array} + -------------------------- + \WEV{E}{p.X}{\ovl{S}} + +.. inference:: WEVAL-PATH-ALIAS2 + + \WF{E}{} + \ModA{X}{p_1 }∈ E + \WEV{E}{p_1}{\ovl{S}} + -------------------------- + \WEV{E}{X}{\ovl{S}} + +.. inference:: WEVAL-PATH-TYPE1 + + \begin{array}{c} + \WEV{E}{p}{~\Struct~e_1 ;…;e_i ; \ModType{Y}{S};e_{i+2} ;… ;e_n End} \\ + \WEV{E;e_1 ;…;e_i }{S}{\ovl{S}} + \end{array} + -------------------------- + \WEV{E}{p.Y}{\ovl{S}} + +.. inference:: WEVAL-PATH-TYPE2 + + \WF{E}{} + \ModType{Y}{S}∈ E + \WEV{E}{S}{\ovl{S}} + -------------------------- + \WEV{E}{Y}{\ovl{S}} + + +Rules for typing module: + +.. inference:: MT-EVAL + + \WEV{E}{p}{\ovl{S}} + -------------------------- + E[] ⊢ p : \ovl{S} + +.. inference:: MT-STR + + E[] ⊢ p : S + -------------------------- + E[] ⊢ p : S/p + + +The last rule, called strengthening is used to make all module fields +manifestly equal to themselves. The notation :math:`S/p` has the following +meaning: + + ++ if :math:`S\lra~\Struct~e_1 ;…;e_n ~\End` then :math:`S/p=~\Struct~e_1 /p;…;e_n /p ~\End` + where :math:`e/p` is defined as follows (note that opaque definitions are processed + as assumptions): + + + :math:`\Def{}{c}{t}{T}/p = \Def{}{c}{t}{T}` + + :math:`\Assum{}{c}{U}/p = \Def{}{c}{p.c}{U}` + + :math:`\ModS{X}{S}/p = \ModA{X}{p.X}` + + :math:`\ModA{X}{p′}/p = \ModA{X}{p′}` + + :math:`\Ind{}{Γ_P}{Γ_C}{Γ_I}/p = \Indp{}{Γ_P}{Γ_C}{Γ_I}{p}` + + :math:`\Indpstr{}{Γ_P}{Γ_C}{Γ_I}{p'}{p} = \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'}` + ++ if :math:`S \lra \Functor(X:S′)~S″` then :math:`S/p=S` + + +The notation :math:`\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}` +denotes an inductive definition that is definitionally equal to the +inductive definition in the module denoted by the path :math:`p`. All rules +which have :math:`\Ind{}{Γ_P}{Γ_C}{Γ_I}` as premises are also valid for +:math:`\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}`. We give the formation rule for +:math:`\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}` +below as well as the equality rules on inductive types and +constructors. + +The module subtyping rules: + +.. inference:: MSUB-STR + + \begin{array}{c} + \WS{E;e_1 ;…;e_n }{e_{σ(i)}}{e'_i ~\for~ i=1..m} \\ + σ : \{1… m\} → \{1… n\} ~\injective + \end{array} + -------------------------- + \WS{E}{\Struct~e_1 ;…;e_n ~\End}{~\Struct~e'_1 ;…;e'_m ~\End} + +.. inference:: MSUB-FUN + + \WS{E}{\ovl{S_1'}}{\ovl{S_1}} + \WS{E; \ModS{X}{S_1'}}{\ovl{S_2}}{\ovl{S_2'}} + -------------------------- + E[] ⊢ \Functor(X:S_1 ) S_2 <: \Functor(X:S_1') S_2' + + +Structure element subtyping rules: + +.. inference:: ASSUM-ASSUM + + E[] ⊢ T_1 ≤_{βδιζη} T_2 + -------------------------- + \WS{E}{\Assum{}{c}{T_1 }}{\Assum{}{c}{T_2 }} + +.. inference:: DEF-ASSUM + + E[] ⊢ T_1 ≤_{βδιζη} T_2 + -------------------------- + \WS{E}{\Def{}{c}{t}{T_1 }}{\Assum{}{c}{T_2 }} + +.. inference:: ASSUM-DEF + + E[] ⊢ T_1 ≤_{βδιζη} T_2 + E[] ⊢ c =_{βδιζη} t_2 + -------------------------- + \WS{E}{\Assum{}{c}{T_1 }}{\Def{}{c}{t_2 }{T_2 }} + +.. inference:: DEF-DEF + + E[] ⊢ T_1 ≤_{βδιζη} T_2 + E[] ⊢ t_1 =_{βδιζη} t_2 + -------------------------- + \WS{E}{\Def{}{c}{t_1 }{T_1 }}{\Def{}{c}{t_2 }{T_2 }} + +.. inference:: IND-IND + + E[] ⊢ Γ_P =_{βδιζη} Γ_P' + E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C' + E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I' + -------------------------- + \WS{E}{\ind{Γ_P}{Γ_C}{Γ_I}}{\ind{Γ_P'}{Γ_C'}{Γ_I'}} + +.. inference:: INDP-IND + + E[] ⊢ Γ_P =_{βδιζη} Γ_P' + E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C' + E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I' + -------------------------- + \WS{E}{\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}}{\ind{Γ_P'}{Γ_C'}{Γ_I'}} + +.. inference:: INDP-INDP + + \begin{array}{c} + E[] ⊢ Γ_P =_{βδιζη} Γ_P' + E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C' \\ + E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I' + E[] ⊢ p =_{βδιζη} p' + \end{array} + -------------------------- + \WS{E}{\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}}{\Indp{}{Γ_P'}{Γ_C'}{Γ_I'}{p'}} + +.. inference:: MOD-MOD + + \WS{E}{S_1}{S_2} + -------------------------- + \WS{E}{\ModS{X}{S_1 }}{\ModS{X}{S_2 }} + +.. inference:: ALIAS-MOD + + E[] ⊢ p : S_1 + \WS{E}{S_1}{S_2} + -------------------------- + \WS{E}{\ModA{X}{p}}{\ModS{X}{S_2 }} + +.. inference:: MOD-ALIAS + + E[] ⊢ p : S_2 + \WS{E}{S_1}{S_2} + E[] ⊢ X =_{βδιζη} p + -------------------------- + \WS{E}{\ModS{X}{S_1 }}{\ModA{X}{p}} + +.. inference:: ALIAS-ALIAS + + E[] ⊢ p_1 =_{βδιζη} p_2 + -------------------------- + \WS{E}{\ModA{X}{p_1 }}{\ModA{X}{p_2 }} + +.. inference:: MODTYPE-MODTYPE + + \WS{E}{S_1}{S_2} + \WS{E}{S_2}{S_1} + -------------------------- + \WS{E}{\ModType{Y}{S_1 }}{\ModType{Y}{S_2 }} + + +New environment formation rules + + +.. inference:: WF-MOD1 + + \WF{E}{} + \WFT{E}{S} + -------------------------- + WF(E; \ModS{X}{S})[] + +.. inference:: WF-MOD2 + + \WS{E}{S_2}{S_1} + \WF{E}{} + \WFT{E}{S_1} + \WFT{E}{S_2} + -------------------------- + \WF{E; \Mod{X}{S_1}{S_2}}{} + +.. inference:: WF-ALIAS + + \WF{E}{} + E[] ⊢ p : S + -------------------------- + \WF{E, \ModA{X}{p}}{} + +.. inference:: WF-MODTYPE + + \WF{E}{} + \WFT{E}{S} + -------------------------- + \WF{E, \ModType{Y}{S}}{} + +.. inference:: WF-IND + + \begin{array}{c} + \WF{E;\ind{Γ_P}{Γ_C}{Γ_I}}{} \\ + E[] ⊢ p:~\Struct~e_1 ;…;e_n ;\ind{Γ_P'}{Γ_C'}{Γ_I'};… ~\End : \\ + E[] ⊢ \ind{Γ_P'}{Γ_C'}{Γ_I'} <: \ind{Γ_P}{Γ_C}{Γ_I} + \end{array} + -------------------------- + \WF{E; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p} }{} + + +Component access rules + + +.. inference:: ACC-TYPE1 + + E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Assum{}{c}{T};… ~\End + -------------------------- + E[Γ] ⊢ p.c : T + +.. inference:: ACC-TYPE2 + + E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Def{}{c}{t}{T};… ~\End + -------------------------- + E[Γ] ⊢ p.c : T + +Notice that the following rule extends the delta rule defined in section :ref:`Conversion-rules` + +.. inference:: ACC-DELTA + + E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Def{}{c}{t}{U};… ~\End + -------------------------- + E[Γ] ⊢ p.c \triangleright_δ t + +In the rules below we assume +:math:`Γ_P` is :math:`[p_1 :P_1 ;…;p_r :P_r ]`, +:math:`Γ_I` is :math:`[I_1 :A_1 ;…;I_k :A_k ]`, +and :math:`Γ_C` is :math:`[c_1 :C_1 ;…;c_n :C_n ]`. + +.. inference:: ACC-IND1 + + E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\ind{Γ_P}{Γ_C}{Γ_I};… ~\End + -------------------------- + E[Γ] ⊢ p.I_j : (p_1 :P_1 )…(p_r :P_r )A_j + +.. inference:: ACC-IND2 + + E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\ind{Γ_P}{Γ_C}{Γ_I};… ~\End + -------------------------- + E[Γ] ⊢ p.c_m : (p_1 :P_1 )…(p_r :P_r )C_m I_j (I_j~p_1 …p_r )_{j=1… k} + +.. inference:: ACC-INDP1 + + E[] ⊢ p :~\Struct~e_1 ;…;e_i ; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'} ;… ~\End + -------------------------- + E[] ⊢ p.I_i \triangleright_δ p'.I_i + +.. inference:: ACC-INDP2 + + E[] ⊢ p :~\Struct~e_1 ;…;e_i ; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'} ;… ~\End + -------------------------- + E[] ⊢ p.c_i \triangleright_δ p'.c_i diff --git a/doc/sphinx/language/module-system.rst b/doc/sphinx/language/module-system.rst deleted file mode 100644 index 15fee91245..0000000000 --- a/doc/sphinx/language/module-system.rst +++ /dev/null @@ -1,456 +0,0 @@ -.. _themodulesystem: - -The Module System -================= - -The module system extends the Calculus of Inductive Constructions -providing a convenient way to structure large developments as well as -a means of massive abstraction. - - -Modules and module types ----------------------------- - -**Access path.** An access path is denoted by :math:`p` and can be -either a module variable :math:`X` or, if :math:`p′` is an access path -and :math:`id` an identifier, then :math:`p′.id` is an access path. - - -**Structure element.** A structure element is denoted by :math:`e` and -is either a definition of a constant, an assumption, a definition of -an inductive, a definition of a module, an alias of a module or a module -type abbreviation. - - -**Structure expression.** A structure expression is denoted by :math:`S` and can be: - -+ an access path :math:`p` -+ a plain structure :math:`\Struct~e ; … ; e~\End` -+ a functor :math:`\Functor(X:S)~S′`, where :math:`X` is a module variable, :math:`S` and :math:`S′` are - structure expressions -+ an application :math:`S~p`, where :math:`S` is a structure expression and :math:`p` an - access path -+ a refined structure :math:`S~\with~p := p`′ or :math:`S~\with~p := t:T` where :math:`S` is a - structure expression, :math:`p` and :math:`p′` are access paths, :math:`t` is a term and :math:`T` is - the type of :math:`t`. - -**Module definition.** A module definition is written :math:`\Mod{X}{S}{S'}` -and consists of a module variable :math:`X`, a module type -:math:`S` which can be any structure expression and optionally a -module implementation :math:`S′` which can be any structure expression -except a refined structure. - - -**Module alias.** A module alias is written :math:`\ModA{X}{p}` -and consists of a module variable :math:`X` and a module path -:math:`p`. - -**Module type abbreviation.** -A module type abbreviation is written :math:`\ModType{Y}{S}`, -where :math:`Y` is an identifier and :math:`S` is any structure -expression . - - -Typing Modules ------------------- - -In order to introduce the typing system we first slightly extend the syntactic -class of terms and environments given in section :ref:`The-terms`. The -environments, apart from definitions of constants and inductive types now also -hold any other structure elements. Terms, apart from variables, constants and -complex terms, include also access paths. - -We also need additional typing judgments: - - -+ :math:`\WFT{E}{S}`, denoting that a structure :math:`S` is well-formed, -+ :math:`\WTM{E}{p}{S}`, denoting that the module pointed by :math:`p` has type :math:`S` in - environment :math:`E`. -+ :math:`\WEV{E}{S}{\ovl{S}}`, denoting that a structure :math:`S` is evaluated to a - structure :math:`S` in weak head normal form. -+ :math:`\WS{E}{S_1}{S_2}` , denoting that a structure :math:`S_1` is a subtype of a - structure :math:`S_2`. -+ :math:`\WS{E}{e_1}{e_2}` , denoting that a structure element e_1 is more - precise than a structure element e_2. - -The rules for forming structures are the following: - -.. inference:: WF-STR - - \WF{E;E′}{} - ------------------------ - \WFT{E}{ \Struct~E′ ~\End} - -.. inference:: WF-FUN - - \WFT{E; \ModS{X}{S}}{ \ovl{S′} } - -------------------------- - \WFT{E}{ \Functor(X:S)~S′} - - -Evaluation of structures to weak head normal form: - -.. inference:: WEVAL-APP - - \begin{array}{c} - \WEV{E}{S}{\Functor(X:S_1 )~S_2}~~~~~\WEV{E}{S_1}{\ovl{S_1}} \\ - \WTM{E}{p}{S_3}~~~~~ \WS{E}{S_3}{\ovl{S_1}} - \end{array} - -------------------------- - \WEV{E}{S~p}{S_2 \{p/X,t_1 /p_1 .c_1 ,…,t_n /p_n.c_n \}} - - -In the last rule, :math:`\{t_1 /p_1 .c_1 ,…,t_n /p_n .c_n \}` is the resulting -substitution from the inlining mechanism. We substitute in :math:`S` the -inlined fields :math:`p_i .c_i` from :math:`\ModS{X}{S_1 }` by the corresponding delta- -reduced term :math:`t_i` in :math:`p`. - -.. inference:: WEVAL-WITH-MOD - - \begin{array}{c} - E[] ⊢ S \lra \Struct~e_1 ;…;e_i ; \ModS{X}{S_1 };e_{i+2} ;… ;e_n ~\End \\ - E;e_1 ;…;e_i [] ⊢ S_1 \lra \ovl{S_1} ~~~~~~ - E[] ⊢ p : S_2 \\ - E;e_1 ;…;e_i [] ⊢ S_2 <: \ovl{S_1} - \end{array} - ---------------------------------- - \begin{array}{c} - \WEV{E}{S~\with~x := p}{}\\ - \Struct~e_1 ;…;e_i ; \ModA{X}{p};e_{i+2} \{p/X\} ;…;e_n \{p/X\} ~\End - \end{array} - -.. inference:: WEVAL-WITH-MOD-REC - - \begin{array}{c} - \WEV{E}{S}{\Struct~e_1 ;…;e_i ; \ModS{X_1}{S_1 };e_{i+2} ;… ;e_n ~\End} \\ - \WEV{E;e_1 ;…;e_i }{S_1~\with~p := p_1}{\ovl{S_2}} - \end{array} - -------------------------- - \begin{array}{c} - \WEV{E}{S~\with~X_1.p := p_1}{} \\ - \Struct~e_1 ;…;e_i ; \ModS{X}{\ovl{S_2}};e_{i+2} \{p_1 /X_1.p\} ;…;e_n \{p_1 /X_1.p\} ~\End - \end{array} - -.. inference:: WEVAL-WITH-DEF - - \begin{array}{c} - \WEV{E}{S}{\Struct~e_1 ;…;e_i ;\Assum{}{c}{T_1};e_{i+2} ;… ;e_n ~\End} \\ - \WS{E;e_1 ;…;e_i }{Def()(c:=t:T)}{\Assum{}{c}{T_1}} - \end{array} - -------------------------- - \begin{array}{c} - \WEV{E}{S~\with~c := t:T}{} \\ - \Struct~e_1 ;…;e_i ;Def()(c:=t:T);e_{i+2} ;… ;e_n ~\End - \end{array} - -.. inference:: WEVAL-WITH-DEF-REC - - \begin{array}{c} - \WEV{E}{S}{\Struct~e_1 ;…;e_i ; \ModS{X_1 }{S_1 };e_{i+2} ;… ;e_n ~\End} \\ - \WEV{E;e_1 ;…;e_i }{S_1~\with~p := p_1}{\ovl{S_2}} - \end{array} - -------------------------- - \begin{array}{c} - \WEV{E}{S~\with~X_1.p := t:T}{} \\ - \Struct~e_1 ;…;e_i ; \ModS{X}{\ovl{S_2} };e_{i+2} ;… ;e_n ~\End - \end{array} - -.. inference:: WEVAL-PATH-MOD1 - - \begin{array}{c} - \WEV{E}{p}{\Struct~e_1 ;…;e_i ; \Mod{X}{S}{S_1};e_{i+2} ;… ;e_n End} \\ - \WEV{E;e_1 ;…;e_i }{S}{\ovl{S}} - \end{array} - -------------------------- - E[] ⊢ p.X \lra \ovl{S} - -.. inference:: WEVAL-PATH-MOD2 - - \WF{E}{} - \Mod{X}{S}{S_1}∈ E - \WEV{E}{S}{\ovl{S}} - -------------------------- - \WEV{E}{X}{\ovl{S}} - -.. inference:: WEVAL-PATH-ALIAS1 - - \begin{array}{c} - \WEV{E}{p}{~\Struct~e_1 ;…;e_i ; \ModA{X}{p_1};e_{i+2} ;… ;e_n End} \\ - \WEV{E;e_1 ;…;e_i }{p_1}{\ovl{S}} - \end{array} - -------------------------- - \WEV{E}{p.X}{\ovl{S}} - -.. inference:: WEVAL-PATH-ALIAS2 - - \WF{E}{} - \ModA{X}{p_1 }∈ E - \WEV{E}{p_1}{\ovl{S}} - -------------------------- - \WEV{E}{X}{\ovl{S}} - -.. inference:: WEVAL-PATH-TYPE1 - - \begin{array}{c} - \WEV{E}{p}{~\Struct~e_1 ;…;e_i ; \ModType{Y}{S};e_{i+2} ;… ;e_n End} \\ - \WEV{E;e_1 ;…;e_i }{S}{\ovl{S}} - \end{array} - -------------------------- - \WEV{E}{p.Y}{\ovl{S}} - -.. inference:: WEVAL-PATH-TYPE2 - - \WF{E}{} - \ModType{Y}{S}∈ E - \WEV{E}{S}{\ovl{S}} - -------------------------- - \WEV{E}{Y}{\ovl{S}} - - -Rules for typing module: - -.. inference:: MT-EVAL - - \WEV{E}{p}{\ovl{S}} - -------------------------- - E[] ⊢ p : \ovl{S} - -.. inference:: MT-STR - - E[] ⊢ p : S - -------------------------- - E[] ⊢ p : S/p - - -The last rule, called strengthening is used to make all module fields -manifestly equal to themselves. The notation :math:`S/p` has the following -meaning: - - -+ if :math:`S\lra~\Struct~e_1 ;…;e_n ~\End` then :math:`S/p=~\Struct~e_1 /p;…;e_n /p ~\End` - where :math:`e/p` is defined as follows (note that opaque definitions are processed - as assumptions): - - + :math:`\Def{}{c}{t}{T}/p = \Def{}{c}{t}{T}` - + :math:`\Assum{}{c}{U}/p = \Def{}{c}{p.c}{U}` - + :math:`\ModS{X}{S}/p = \ModA{X}{p.X}` - + :math:`\ModA{X}{p′}/p = \ModA{X}{p′}` - + :math:`\Ind{}{Γ_P}{Γ_C}{Γ_I}/p = \Indp{}{Γ_P}{Γ_C}{Γ_I}{p}` - + :math:`\Indpstr{}{Γ_P}{Γ_C}{Γ_I}{p'}{p} = \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'}` - -+ if :math:`S \lra \Functor(X:S′)~S″` then :math:`S/p=S` - - -The notation :math:`\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}` -denotes an inductive definition that is definitionally equal to the -inductive definition in the module denoted by the path :math:`p`. All rules -which have :math:`\Ind{}{Γ_P}{Γ_C}{Γ_I}` as premises are also valid for -:math:`\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}`. We give the formation rule for -:math:`\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}` -below as well as the equality rules on inductive types and -constructors. - -The module subtyping rules: - -.. inference:: MSUB-STR - - \begin{array}{c} - \WS{E;e_1 ;…;e_n }{e_{σ(i)}}{e'_i ~\for~ i=1..m} \\ - σ : \{1… m\} → \{1… n\} ~\injective - \end{array} - -------------------------- - \WS{E}{\Struct~e_1 ;…;e_n ~\End}{~\Struct~e'_1 ;…;e'_m ~\End} - -.. inference:: MSUB-FUN - - \WS{E}{\ovl{S_1'}}{\ovl{S_1}} - \WS{E; \ModS{X}{S_1'}}{\ovl{S_2}}{\ovl{S_2'}} - -------------------------- - E[] ⊢ \Functor(X:S_1 ) S_2 <: \Functor(X:S_1') S_2' - - -Structure element subtyping rules: - -.. inference:: ASSUM-ASSUM - - E[] ⊢ T_1 ≤_{βδιζη} T_2 - -------------------------- - \WS{E}{\Assum{}{c}{T_1 }}{\Assum{}{c}{T_2 }} - -.. inference:: DEF-ASSUM - - E[] ⊢ T_1 ≤_{βδιζη} T_2 - -------------------------- - \WS{E}{\Def{}{c}{t}{T_1 }}{\Assum{}{c}{T_2 }} - -.. inference:: ASSUM-DEF - - E[] ⊢ T_1 ≤_{βδιζη} T_2 - E[] ⊢ c =_{βδιζη} t_2 - -------------------------- - \WS{E}{\Assum{}{c}{T_1 }}{\Def{}{c}{t_2 }{T_2 }} - -.. inference:: DEF-DEF - - E[] ⊢ T_1 ≤_{βδιζη} T_2 - E[] ⊢ t_1 =_{βδιζη} t_2 - -------------------------- - \WS{E}{\Def{}{c}{t_1 }{T_1 }}{\Def{}{c}{t_2 }{T_2 }} - -.. inference:: IND-IND - - E[] ⊢ Γ_P =_{βδιζη} Γ_P' - E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C' - E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I' - -------------------------- - \WS{E}{\ind{Γ_P}{Γ_C}{Γ_I}}{\ind{Γ_P'}{Γ_C'}{Γ_I'}} - -.. inference:: INDP-IND - - E[] ⊢ Γ_P =_{βδιζη} Γ_P' - E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C' - E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I' - -------------------------- - \WS{E}{\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}}{\ind{Γ_P'}{Γ_C'}{Γ_I'}} - -.. inference:: INDP-INDP - - \begin{array}{c} - E[] ⊢ Γ_P =_{βδιζη} Γ_P' - E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C' \\ - E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I' - E[] ⊢ p =_{βδιζη} p' - \end{array} - -------------------------- - \WS{E}{\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}}{\Indp{}{Γ_P'}{Γ_C'}{Γ_I'}{p'}} - -.. inference:: MOD-MOD - - \WS{E}{S_1}{S_2} - -------------------------- - \WS{E}{\ModS{X}{S_1 }}{\ModS{X}{S_2 }} - -.. inference:: ALIAS-MOD - - E[] ⊢ p : S_1 - \WS{E}{S_1}{S_2} - -------------------------- - \WS{E}{\ModA{X}{p}}{\ModS{X}{S_2 }} - -.. inference:: MOD-ALIAS - - E[] ⊢ p : S_2 - \WS{E}{S_1}{S_2} - E[] ⊢ X =_{βδιζη} p - -------------------------- - \WS{E}{\ModS{X}{S_1 }}{\ModA{X}{p}} - -.. inference:: ALIAS-ALIAS - - E[] ⊢ p_1 =_{βδιζη} p_2 - -------------------------- - \WS{E}{\ModA{X}{p_1 }}{\ModA{X}{p_2 }} - -.. inference:: MODTYPE-MODTYPE - - \WS{E}{S_1}{S_2} - \WS{E}{S_2}{S_1} - -------------------------- - \WS{E}{\ModType{Y}{S_1 }}{\ModType{Y}{S_2 }} - - -New environment formation rules - - -.. inference:: WF-MOD1 - - \WF{E}{} - \WFT{E}{S} - -------------------------- - WF(E; \ModS{X}{S})[] - -.. inference:: WF-MOD2 - - \WS{E}{S_2}{S_1} - \WF{E}{} - \WFT{E}{S_1} - \WFT{E}{S_2} - -------------------------- - \WF{E; \Mod{X}{S_1}{S_2}}{} - -.. inference:: WF-ALIAS - - \WF{E}{} - E[] ⊢ p : S - -------------------------- - \WF{E, \ModA{X}{p}}{} - -.. inference:: WF-MODTYPE - - \WF{E}{} - \WFT{E}{S} - -------------------------- - \WF{E, \ModType{Y}{S}}{} - -.. inference:: WF-IND - - \begin{array}{c} - \WF{E;\ind{Γ_P}{Γ_C}{Γ_I}}{} \\ - E[] ⊢ p:~\Struct~e_1 ;…;e_n ;\ind{Γ_P'}{Γ_C'}{Γ_I'};… ~\End : \\ - E[] ⊢ \ind{Γ_P'}{Γ_C'}{Γ_I'} <: \ind{Γ_P}{Γ_C}{Γ_I} - \end{array} - -------------------------- - \WF{E; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p} }{} - - -Component access rules - - -.. inference:: ACC-TYPE1 - - E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Assum{}{c}{T};… ~\End - -------------------------- - E[Γ] ⊢ p.c : T - -.. inference:: ACC-TYPE2 - - E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Def{}{c}{t}{T};… ~\End - -------------------------- - E[Γ] ⊢ p.c : T - -Notice that the following rule extends the delta rule defined in section :ref:`Conversion-rules` - -.. inference:: ACC-DELTA - - E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Def{}{c}{t}{U};… ~\End - -------------------------- - E[Γ] ⊢ p.c \triangleright_δ t - -In the rules below we assume -:math:`Γ_P` is :math:`[p_1 :P_1 ;…;p_r :P_r ]`, -:math:`Γ_I` is :math:`[I_1 :A_1 ;…;I_k :A_k ]`, -and :math:`Γ_C` is :math:`[c_1 :C_1 ;…;c_n :C_n ]`. - -.. inference:: ACC-IND1 - - E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\ind{Γ_P}{Γ_C}{Γ_I};… ~\End - -------------------------- - E[Γ] ⊢ p.I_j : (p_1 :P_1 )…(p_r :P_r )A_j - -.. inference:: ACC-IND2 - - E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\ind{Γ_P}{Γ_C}{Γ_I};… ~\End - -------------------------- - E[Γ] ⊢ p.c_m : (p_1 :P_1 )…(p_r :P_r )C_m I_j (I_j~p_1 …p_r )_{j=1… k} - -.. inference:: ACC-INDP1 - - E[] ⊢ p :~\Struct~e_1 ;…;e_i ; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'} ;… ~\End - -------------------------- - E[] ⊢ p.I_i \triangleright_δ p'.I_i - -.. inference:: ACC-INDP2 - - E[] ⊢ p :~\Struct~e_1 ;…;e_i ; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'} ;… ~\End - -------------------------- - E[] ⊢ p.c_i \triangleright_δ p'.c_i -- cgit v1.2.3 From 03d36216d47e7e2d02d527f86bdcc3460c9f942d Mon Sep 17 00:00:00 2001 From: Théo Zimmermann Date: Wed, 13 May 2020 23:55:59 +0200 Subject: Extract evars from Gallina extensions. --- doc/sphinx/language/gallina-extensions.rst | 1017 ---------------------------- 1 file changed, 1017 deletions(-) (limited to 'doc/sphinx') diff --git a/doc/sphinx/language/gallina-extensions.rst b/doc/sphinx/language/gallina-extensions.rst index 5b78280edc..979a0a62e6 100644 --- a/doc/sphinx/language/gallina-extensions.rst +++ b/doc/sphinx/language/gallina-extensions.rst @@ -1,915 +1,3 @@ -.. _extensionsofgallina: - -Extensions of |Gallina| -======================= - -|Gallina| is the kernel language of |Coq|. We describe here extensions of -|Gallina|’s syntax. - -Variants and extensions of :g:`match` -------------------------------------- - -.. _mult-match: - -Multiple and nested pattern matching -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The basic version of :g:`match` allows pattern matching on simple -patterns. As an extension, multiple nested patterns or disjunction of -patterns are allowed, as in ML-like languages. - -The extension just acts as a macro that is expanded during parsing -into a sequence of match on simple patterns. Especially, a -construction defined using the extended match is generally printed -under its expanded form (see :flag:`Printing Matching`). - -.. seealso:: :ref:`extendedpatternmatching`. - -.. _if-then-else: - -Pattern-matching on boolean values: the if expression -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. insertprodn term_if term_if - -.. prodn:: - term_if ::= if @term {? {? as @name } return @term100 } then @term else @term - -For inductive types with exactly two constructors and for pattern matching -expressions that do not depend on the arguments of the constructors, it is possible -to use a ``if … then … else`` notation. For instance, the definition - -.. coqtop:: all - - Definition not (b:bool) := - match b with - | true => false - | false => true - end. - -can be alternatively written - -.. coqtop:: reset all - - Definition not (b:bool) := if b then false else true. - -More generally, for an inductive type with constructors :n:`@ident__1` -and :n:`@ident__2`, the following terms are equal: - -:n:`if @term__0 {? {? as @name } return @term } then @term__1 else @term__2` - -:n:`match @term__0 {? {? as @name } return @term } with | @ident__1 {* _ } => @term__1 | @ident__2 {* _ } => @term__2 end` - -.. example:: - - .. coqtop:: all - - Check (fun x (H:{x=0}+{x<>0}) => - match H with - | left _ => true - | right _ => false - end). - -Notice that the printing uses the :g:`if` syntax because :g:`sumbool` is -declared as such (see :ref:`controlling-match-pp`). - -.. _irrefutable-patterns: - -Irrefutable patterns: the destructuring let variants -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Pattern-matching on terms inhabiting inductive type having only one -constructor can be alternatively written using :g:`let … in …` -constructions. There are two variants of them. - - -First destructuring let syntax -++++++++++++++++++++++++++++++ - -The expression :n:`let ( {*, @ident__i } ) := @term__0 in @term__1` -performs case analysis on :n:`@term__0` whose type must be an -inductive type with exactly one constructor. The number of variables -:n:`@ident__i` must correspond to the number of arguments of this -contrustor. Then, in :n:`@term__1`, these variables are bound to the -arguments of the constructor in :n:`@term__0`. For instance, the -definition - -.. coqtop:: reset all - - Definition fst (A B:Set) (H:A * B) := match H with - | pair x y => x - end. - -can be alternatively written - -.. coqtop:: reset all - - Definition fst (A B:Set) (p:A * B) := let (x, _) := p in x. - -Notice that reduction is different from regular :g:`let … in …` -construction since it happens only if :n:`@term__0` is in constructor form. -Otherwise, the reduction is blocked. - -The pretty-printing of a definition by matching on a irrefutable -pattern can either be done using :g:`match` or the :g:`let` construction -(see Section :ref:`controlling-match-pp`). - -If term inhabits an inductive type with one constructor `C`, we have an -equivalence between - -:: - - let (ident₁, …, identₙ) [dep_ret_type] := term in term' - -and - -:: - - match term [dep_ret_type] with - C ident₁ … identₙ => term' - end - - -Second destructuring let syntax -+++++++++++++++++++++++++++++++ - -Another destructuring let syntax is available for inductive types with -one constructor by giving an arbitrary pattern instead of just a tuple -for all the arguments. For example, the preceding example can be -written: - -.. coqtop:: reset all - - Definition fst (A B:Set) (p:A*B) := let 'pair x _ := p in x. - -This is useful to match deeper inside tuples and also to use notations -for the pattern, as the syntax :g:`let ’p := t in b` allows arbitrary -patterns to do the deconstruction. For example: - -.. coqtop:: all - - Definition deep_tuple (A:Set) (x:(A*A)*(A*A)) : A*A*A*A := - let '((a,b), (c, d)) := x in (a,b,c,d). - - Notation " x 'With' p " := (exist _ x p) (at level 20). - - Definition proj1_sig' (A:Set) (P:A->Prop) (t:{ x:A | P x }) : A := - let 'x With p := t in x. - -When printing definitions which are written using this construct it -takes precedence over let printing directives for the datatype under -consideration (see Section :ref:`controlling-match-pp`). - - -.. _controlling-match-pp: - -Controlling pretty-printing of match expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The following commands give some control over the pretty-printing -of :g:`match` expressions. - -Printing nested patterns -+++++++++++++++++++++++++ - -.. flag:: Printing Matching - - The Calculus of Inductive Constructions knows pattern matching only - over simple patterns. It is however convenient to re-factorize nested - pattern matching into a single pattern matching over a nested - pattern. - - When this flag is on (default), |Coq|’s printer tries to do such - limited re-factorization. - Turning it off tells |Coq| to print only simple pattern matching problems - in the same way as the |Coq| kernel handles them. - - -Factorization of clauses with same right-hand side -++++++++++++++++++++++++++++++++++++++++++++++++++ - -.. flag:: Printing Factorizable Match Patterns - - When several patterns share the same right-hand side, it is additionally - possible to share the clauses using disjunctive patterns. Assuming that the - printing matching mode is on, this flag (on by default) tells |Coq|'s - printer to try to do this kind of factorization. - -Use of a default clause -+++++++++++++++++++++++ - -.. flag:: Printing Allow Match Default Clause - - When several patterns share the same right-hand side which do not depend on the - arguments of the patterns, yet an extra factorization is possible: the - disjunction of patterns can be replaced with a `_` default clause. Assuming that - the printing matching mode and the factorization mode are on, this flag (on by - default) tells |Coq|'s printer to use a default clause when relevant. - -Printing of wildcard patterns -++++++++++++++++++++++++++++++ - -.. flag:: Printing Wildcard - - Some variables in a pattern may not occur in the right-hand side of - the pattern matching clause. When this flag is on (default), the - variables having no occurrences in the right-hand side of the - pattern matching clause are just printed using the wildcard symbol - “_”. - - -Printing of the elimination predicate -+++++++++++++++++++++++++++++++++++++ - -.. flag:: Printing Synth - - In most of the cases, the type of the result of a matched term is - mechanically synthesizable. Especially, if the result type does not - depend of the matched term. When this flag is on (default), - the result type is not printed when |Coq| knows that it can re- - synthesize it. - - -Printing matching on irrefutable patterns -++++++++++++++++++++++++++++++++++++++++++ - -If an inductive type has just one constructor, pattern matching can be -written using the first destructuring let syntax. - -.. table:: Printing Let @qualid - :name: Printing Let - - Specifies a set of qualids for which pattern matching is displayed using a let expression. - Note that this only applies to pattern matching instances entered with :g:`match`. - It doesn't affect pattern matching explicitly entered with a destructuring - :g:`let`. - Use the :cmd:`Add` and :cmd:`Remove` commands to update this set. - - -Printing matching on booleans -+++++++++++++++++++++++++++++ - -If an inductive type is isomorphic to the boolean type, pattern matching -can be written using ``if`` … ``then`` … ``else`` …. This table controls -which types are written this way: - -.. table:: Printing If @qualid - :name: Printing If - - Specifies a set of qualids for which pattern matching is displayed using - ``if`` … ``then`` … ``else`` …. Use the :cmd:`Add` and :cmd:`Remove` - commands to update this set. - -This example emphasizes what the printing settings offer. - -.. example:: - - .. coqtop:: all - - Definition snd (A B:Set) (H:A * B) := match H with - | pair x y => y - end. - - Test Printing Let for prod. - - Print snd. - - Remove Printing Let prod. - - Unset Printing Synth. - - Unset Printing Wildcard. - - Print snd. - -Module system -------------- - -The module system provides a way of packaging related elements -together, as well as a means of massive abstraction. - - -.. cmd:: Module {? {| Import | Export } } @ident {* @module_binder } {? @of_module_type } {? := {+<+ @module_expr_inl } } - - .. insertprodn module_binder module_expr_inl - - .. prodn:: - module_binder ::= ( {? {| Import | Export } } {+ @ident } : @module_type_inl ) - module_type_inl ::= ! @module_type - | @module_type {? @functor_app_annot } - functor_app_annot ::= [ inline at level @num ] - | [ no inline ] - module_type ::= @qualid - | ( @module_type ) - | @module_type @module_expr_atom - | @module_type with @with_declaration - with_declaration ::= Definition @qualid {? @univ_decl } := @term - | Module @qualid := @qualid - module_expr_atom ::= @qualid - | ( {+ @module_expr_atom } ) - of_module_type ::= : @module_type_inl - | {* <: @module_type_inl } - module_expr_inl ::= ! {+ @module_expr_atom } - | {+ @module_expr_atom } {? @functor_app_annot } - - Defines a module named :token:`ident`. See the examples :ref:`here`. - - The :n:`Import` and :n:`Export` flags specify whether the module should be automatically - imported or exported. - - Specifying :n:`{* @module_binder }` starts a functor with - parameters given by the :n:`@module_binder`\s. (A *functor* is a function - from modules to modules.) - - :n:`@of_module_type` specifies the module type. :n:`{+ <: @module_type_inl }` - starts a module that satisfies each :n:`@module_type_inl`. - - .. todo: would like to find a better term than "interactive", not very descriptive - - :n:`:= {+<+ @module_expr_inl }` specifies the body of a module or functor - definition. If it's not specified, then the module is defined *interactively*, - meaning that the module is defined as a series of commands terminated with :cmd:`End` - instead of in a single :cmd:`Module` command. - Interactively defining the :n:`@module_expr_inl`\s in a series of - :cmd:`Include` commands is equivalent to giving them all in a single - non-interactive :cmd:`Module` command. - - The ! prefix indicates that any assumption command (such as :cmd:`Axiom`) with an :n:`Inline` clause - in the type of the functor arguments will be ignored. - - .. todo: What is an Inline directive? sb command but still unclear. Maybe referring to the - "inline" in functor_app_annot? or assumption_token Inline assum_list? - -.. cmd:: Module Type @ident {* @module_binder } {* <: @module_type_inl } {? := {+<+ @module_type_inl } } - - Defines a module type named :n:`@ident`. See the example :ref:`here`. - - Specifying :n:`{* @module_binder }` starts a functor type with - parameters given by the :n:`@module_binder`\s. - - :n:`:= {+<+ @module_type_inl }` specifies the body of a module or functor type - definition. If it's not specified, then the module type is defined *interactively*, - meaning that the module type is defined as a series of commands terminated with :cmd:`End` - instead of in a single :cmd:`Module Type` command. - Interactively defining the :n:`@module_type_inl`\s in a series of - :cmd:`Include` commands is equivalent to giving them all in a single - non-interactive :cmd:`Module Type` command. - -.. _terminating_module: - -**Terminating an interactive module or module type definition** - -Interactive modules are terminated with the :cmd:`End` command, which -is also used to terminate :ref:`Sections`. -:n:`End @ident` closes the interactive module or module type :token:`ident`. -If the module type was given, the command verifies that the content of the module -matches the module type. If the module is not a -functor, its components (constants, inductive types, submodules etc.) -are now available through the dot notation. - -.. exn:: No such label @ident. - :undocumented: - -.. exn:: Signature components for label @ident do not match. - :undocumented: - -.. exn:: The field @ident is missing in @qualid. - :undocumented: - -.. |br| raw:: html - -
- -.. note:: - - #. Interactive modules and module types can be nested. - #. Interactive modules and module types can't be defined inside of :ref:`sections`. - Sections can be defined inside of interactive modules and module types. - #. Hints and notations (:cmd:`Hint` and :cmd:`Notation` commands) can also appear inside interactive - modules and module types. Note that with module definitions like: - - :n:`Module @ident__1 : @module_type := @ident__2.` - - or - - :n:`Module @ident__1 : @module_type.` |br| - :n:`Include @ident__2.` |br| - :n:`End @ident__1.` - - hints and the like valid for :n:`@ident__1` are the ones defined in :n:`@module_type` - rather then those defined in :n:`@ident__2` (or the module body). - #. Within an interactive module type definition, the :cmd:`Parameter` command declares a - constant instead of definining a new axiom (which it does when not in a module type definition). - #. Assumptions such as :cmd:`Axiom` that include the :n:`Inline` clause will be automatically - expanded when the functor is applied, except when the function application is prefixed by ``!``. - -.. cmd:: Include @module_type_inl {* <+ @module_expr_inl } - - Includes the content of module(s) in the current - interactive module. Here :n:`@module_type_inl` can be a module expression or a module - type expression. If it is a high-order module or module type - expression then the system tries to instantiate :n:`@module_type_inl` with the current - interactive module. - - Including multiple modules is a single :cmd:`Include` is equivalent to including each module - in a separate :cmd:`Include` command. - -.. cmd:: Include Type {+<+ @module_type_inl } - - .. deprecated:: 8.3 - - Use :cmd:`Include` instead. - -.. cmd:: Declare Module {? {| Import | Export } } @ident {* @module_binder } : @module_type_inl - - Declares a module :token:`ident` of type :token:`module_type_inl`. - - If :n:`@module_binder`\s are specified, declares a functor with parameters given by the list of - :token:`module_binder`\s. - -.. cmd:: Import {+ @filtered_import } - - .. insertprodn filtered_import filtered_import - - .. prodn:: - filtered_import ::= @qualid {? ( {+, @qualid {? ( .. ) } } ) } - - If :token:`qualid` denotes a valid basic module (i.e. its module type is a - signature), makes its components available by their short names. - - .. example:: - - .. coqtop:: reset in - - Module Mod. - Definition T:=nat. - Check T. - End Mod. - Check Mod.T. - - .. coqtop:: all - - Fail Check T. - Import Mod. - Check T. - - Some features defined in modules are activated only when a module is - imported. This is for instance the case of notations (see :ref:`Notations`). - - Declarations made with the :attr:`local` attribute are never imported by the :cmd:`Import` - command. Such declarations are only accessible through their fully - qualified name. - - .. example:: - - .. coqtop:: in - - Module A. - Module B. - Local Definition T := nat. - End B. - End A. - Import A. - - .. coqtop:: all fail - - Check B.T. - - Appending a module name with a parenthesized list of names will - make only those names available with short names, not other names - defined in the module nor will it activate other features. - - The names to import may be constants, inductive types and - constructors, and notation aliases (for instance, Ltac definitions - cannot be selectively imported). If they are from an inner module - to the one being imported, they must be prefixed by the inner path. - - The name of an inductive type may also be followed by ``(..)`` to - import it, its constructors and its eliminators if they exist. For - this purpose "eliminator" means a constant in the same module whose - name is the inductive type's name suffixed by one of ``_sind``, - ``_ind``, ``_rec`` or ``_rect``. - - .. example:: - - .. coqtop:: reset in - - Module A. - Module B. - Inductive T := C. - Definition U := nat. - End B. - Definition Z := Prop. - End A. - Import A(B.T(..), Z). - - .. coqtop:: all - - Check B.T. - Check B.C. - Check Z. - Fail Check B.U. - Check A.B.U. - -.. cmd:: Export {+ @filtered_import } - :name: Export - - Similar to :cmd:`Import`, except that when the module containing this command - is imported, the :n:`{+ @qualid }` are imported as well. - - The selective import syntax also works with Export. - - .. exn:: @qualid is not a module. - :undocumented: - - .. warn:: Trying to mask the absolute name @qualid! - :undocumented: - -.. cmd:: Print Module @qualid - - Prints the module type and (optionally) the body of the module :n:`@qualid`. - -.. cmd:: Print Module Type @qualid - - Prints the module type corresponding to :n:`@qualid`. - -.. flag:: Short Module Printing - - This flag (off by default) disables the printing of the types of fields, - leaving only their names, for the commands :cmd:`Print Module` and - :cmd:`Print Module Type`. - -.. _module_examples: - -Examples -~~~~~~~~ - -.. example:: Defining a simple module interactively - - .. coqtop:: in - - Module M. - Definition T := nat. - Definition x := 0. - - .. coqtop:: all - - Definition y : bool. - exact true. - - .. coqtop:: in - - Defined. - End M. - -Inside a module one can define constants, prove theorems and do anything -else that can be done in the toplevel. Components of a closed -module can be accessed using the dot notation: - -.. coqtop:: all - - Print M.x. - -.. _example_def_simple_module_type: - -.. example:: Defining a simple module type interactively - - .. coqtop:: in - - Module Type SIG. - Parameter T : Set. - Parameter x : T. - End SIG. - -.. _example_filter_module: - -.. example:: Creating a new module that omits some items from an existing module - - Since :n:`SIG`, the type of the new module :n:`N`, doesn't define :n:`y` or - give the body of :n:`x`, which are not included in :n:`N`. - - .. coqtop:: all - - Module N : SIG with Definition T := nat := M. - Print N.T. - Print N.x. - Fail Print N.y. - - .. reset to remove N (undo in last coqtop block doesn't seem to do that), invisibly redefine M, SIG - .. coqtop:: none reset - - Module M. - Definition T := nat. - Definition x := 0. - Definition y : bool. - exact true. - Defined. - End M. - - Module Type SIG. - Parameter T : Set. - Parameter x : T. - End SIG. - -The definition of :g:`N` using the module type expression :g:`SIG` with -:g:`Definition T := nat` is equivalent to the following one: - -.. coqtop:: in - - Module Type SIG'. - Definition T : Set := nat. - Parameter x : T. - End SIG'. - - Module N : SIG' := M. - -If we just want to be sure that our implementation satisfies a -given module type without restricting the interface, we can use a -transparent constraint - -.. coqtop:: in - - Module P <: SIG := M. - -.. coqtop:: all - - Print P.y. - -.. example:: Creating a functor (a module with parameters) - - .. coqtop:: in - - Module Two (X Y: SIG). - Definition T := (X.T * Y.T)%type. - Definition x := (X.x, Y.x). - End Two. - - and apply it to our modules and do some computations: - - .. coqtop:: in - - - Module Q := Two M N. - - .. coqtop:: all - - Eval compute in (fst Q.x + snd Q.x). - -.. example:: A module type with two sub-modules, sharing some fields - - .. coqtop:: in - - Module Type SIG2. - Declare Module M1 : SIG. - Module M2 <: SIG. - Definition T := M1.T. - Parameter x : T. - End M2. - End SIG2. - - .. coqtop:: in - - Module Mod <: SIG2. - Module M1. - Definition T := nat. - Definition x := 1. - End M1. - Module M2 := M. - End Mod. - -Notice that ``M`` is a correct body for the component ``M2`` since its ``T`` -component is ``nat`` as specified for ``M1.T``. - -Libraries and qualified names ---------------------------------- - -.. _names-of-libraries: - -Names of libraries -~~~~~~~~~~~~~~~~~~ - -The theories developed in |Coq| are stored in *library files* which are -hierarchically classified into *libraries* and *sublibraries*. To -express this hierarchy, library names are represented by qualified -identifiers qualid, i.e. as list of identifiers separated by dots (see -:ref:`gallina-identifiers`). For instance, the library file ``Mult`` of the standard -|Coq| library ``Arith`` is named ``Coq.Arith.Mult``. The identifier that starts -the name of a library is called a *library root*. All library files of -the standard library of |Coq| have the reserved root |Coq| but library -filenames based on other roots can be obtained by using |Coq| commands -(coqc, coqtop, coqdep, …) options ``-Q`` or ``-R`` (see :ref:`command-line-options`). -Also, when an interactive |Coq| session starts, a library of root ``Top`` is -started, unless option ``-top`` or ``-notop`` is set (see :ref:`command-line-options`). - -.. _qualified-names: - -Qualified names -~~~~~~~~~~~~~~~ - -Library files are modules which possibly contain submodules which -eventually contain constructions (axioms, parameters, definitions, -lemmas, theorems, remarks or facts). The *absolute name*, or *full -name*, of a construction in some library file is a qualified -identifier starting with the logical name of the library file, -followed by the sequence of submodules names encapsulating the -construction and ended by the proper name of the construction. -Typically, the absolute name ``Coq.Init.Logic.eq`` denotes Leibniz’ -equality defined in the module Logic in the sublibrary ``Init`` of the -standard library of |Coq|. - -The proper name that ends the name of a construction is the short name -(or sometimes base name) of the construction (for instance, the short -name of ``Coq.Init.Logic.eq`` is ``eq``). Any partial suffix of the absolute -name is a *partially qualified name* (e.g. ``Logic.eq`` is a partially -qualified name for ``Coq.Init.Logic.eq``). Especially, the short name of a -construction is its shortest partially qualified name. - -|Coq| does not accept two constructions (definition, theorem, …) with -the same absolute name but different constructions can have the same -short name (or even same partially qualified names as soon as the full -names are different). - -Notice that the notion of absolute, partially qualified and short -names also applies to library filenames. - -**Visibility** - -|Coq| maintains a table called the name table which maps partially qualified -names of constructions to absolute names. This table is updated by the -commands :cmd:`Require`, :cmd:`Import` and :cmd:`Export` and -also each time a new declaration is added to the context. An absolute -name is called visible from a given short or partially qualified name -when this latter name is enough to denote it. This means that the -short or partially qualified name is mapped to the absolute name in -|Coq| name table. Definitions with the :attr:`local` attribute are only accessible with -their fully qualified name (see :ref:`gallina-definitions`). - -It may happen that a visible name is hidden by the short name or a -qualified name of another construction. In this case, the name that -has been hidden must be referred to using one more level of -qualification. To ensure that a construction always remains -accessible, absolute names can never be hidden. - -.. example:: - - .. coqtop:: all - - Check 0. - - Definition nat := bool. - - Check 0. - - Check Datatypes.nat. - - Locate nat. - -.. seealso:: Commands :cmd:`Locate`. - -.. _libraries-and-filesystem: - -Libraries and filesystem -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. note:: The questions described here have been subject to redesign in |Coq| 8.5. - Former versions of |Coq| use the same terminology to describe slightly different things. - -Compiled files (``.vo`` and ``.vio``) store sub-libraries. In order to refer -to them inside |Coq|, a translation from file-system names to |Coq| names -is needed. In this translation, names in the file system are called -*physical* paths while |Coq| names are contrastingly called *logical* -names. - -A logical prefix Lib can be associated with a physical path using -the command line option ``-Q`` `path` ``Lib``. All subfolders of path are -recursively associated to the logical path ``Lib`` extended with the -corresponding suffix coming from the physical path. For instance, the -folder ``path/fOO/Bar`` maps to ``Lib.fOO.Bar``. Subdirectories corresponding -to invalid |Coq| identifiers are skipped, and, by convention, -subdirectories named ``CVS`` or ``_darcs`` are skipped too. - -Thanks to this mechanism, ``.vo`` files are made available through the -logical name of the folder they are in, extended with their own -basename. For example, the name associated to the file -``path/fOO/Bar/File.vo`` is ``Lib.fOO.Bar.File``. The same caveat applies for -invalid identifiers. When compiling a source file, the ``.vo`` file stores -its logical name, so that an error is issued if it is loaded with the -wrong loadpath afterwards. - -Some folders have a special status and are automatically put in the -path. |Coq| commands associate automatically a logical path to files in -the repository trees rooted at the directory from where the command is -launched, ``coqlib/user-contrib/``, the directories listed in the -``$COQPATH``, ``${XDG_DATA_HOME}/coq/`` and ``${XDG_DATA_DIRS}/coq/`` -environment variables (see `XDG base directory specification -`_) -with the same physical-to-logical translation and with an empty logical prefix. - -The command line option ``-R`` is a variant of ``-Q`` which has the strictly -same behavior regarding loadpaths, but which also makes the -corresponding ``.vo`` files available through their short names in a way -similar to the :cmd:`Import` command. For instance, ``-R path Lib`` -associates to the file ``/path/fOO/Bar/File.vo`` the logical name -``Lib.fOO.Bar.File``, but allows this file to be accessed through the -short names ``fOO.Bar.File,Bar.File`` and ``File``. If several files with -identical base name are present in different subdirectories of a -recursive loadpath, which of these files is found first may be system- -dependent and explicit qualification is recommended. The ``From`` argument -of the ``Require`` command can be used to bypass the implicit shortening -by providing an absolute root to the required file (see :ref:`compiled-files`). - -There also exists another independent loadpath mechanism attached to -OCaml object files (``.cmo`` or ``.cmxs``) rather than |Coq| object -files as described above. The OCaml loadpath is managed using -the option ``-I`` `path` (in the OCaml world, there is neither a -notion of logical name prefix nor a way to access files in -subdirectories of path). See the command :cmd:`Declare ML Module` in -:ref:`compiled-files` to understand the need of the OCaml loadpath. - -See :ref:`command-line-options` for a more general view over the |Coq| command -line options. - -.. _Coercions: - -Coercions ---------- - -Coercions can be used to implicitly inject terms from one *class* in -which they reside into another one. A *class* is either a sort -(denoted by the keyword ``Sortclass``), a product type (denoted by the -keyword ``Funclass``), or a type constructor (denoted by its name), e.g. -an inductive type or any constant with a type of the form -:n:`forall {+ @binder }, @sort`. - -Then the user is able to apply an object that is not a function, but -can be coerced to a function, and more generally to consider that a -term of type ``A`` is of type ``B`` provided that there is a declared coercion -between ``A`` and ``B``. - -More details and examples, and a description of the commands related -to coercions are provided in :ref:`implicitcoercions`. - -.. _printing_constructions_full: - -Printing constructions in full ------------------------------- - -.. flag:: Printing All - - Coercions, implicit arguments, the type of pattern matching, but also - notations (see :ref:`syntax-extensions-and-notation-scopes`) can obfuscate the behavior of some - tactics (typically the tactics applying to occurrences of subterms are - sensitive to the implicit arguments). Turning this flag on - deactivates all high-level printing features such as coercions, - implicit arguments, returned type of pattern matching, notations and - various syntactic sugar for pattern matching or record projections. - Otherwise said, :flag:`Printing All` includes the effects of the flags - :flag:`Printing Implicit`, :flag:`Printing Coercions`, :flag:`Printing Synth`, - :flag:`Printing Projections`, and :flag:`Printing Notations`. To reactivate - the high-level printing features, use the command ``Unset Printing All``. - - .. note:: In some cases, setting :flag:`Printing All` may display terms - that are so big they become very hard to read. One technique to work around - this is use :cmd:`Undelimit Scope` and/or :cmd:`Close Scope` to turn off the - printing of notations bound to particular scope(s). This can be useful when - notations in a given scope are getting in the way of understanding - a goal, but turning off all notations with :flag:`Printing All` would make - the goal unreadable. - - .. see a contrived example here: https://github.com/coq/coq/pull/11718#discussion_r415481854 - -.. _printing-universes: - -Printing universes ------------------- - -.. flag:: Printing Universes - - Turn this flag on to activate the display of the actual level of each - occurrence of :g:`Type`. See :ref:`Sorts` for details. This wizard flag, in - combination with :flag:`Printing All` can help to diagnose failures to unify - terms apparently identical but internally different in the Calculus of Inductive - Constructions. - -.. cmd:: Print {? Sorted } Universes {? Subgraph ( {* @qualid } ) } {? @string } - :name: Print Universes - - This command can be used to print the constraints on the internal level - of the occurrences of :math:`\Type` (see :ref:`Sorts`). - - The :n:`Subgraph` clause limits the printed graph to the requested names (adjusting - constraints to preserve the implied transitive constraints between - kept universes). - - The :n:`Sorted` clause makes each universe - equivalent to a numbered label reflecting its level (with a linear - ordering) in the universe hierarchy. - - :n:`@string` is an optional output filename. - If :n:`@string` ends in ``.dot`` or ``.gv``, the constraints are printed in the DOT - language, and can be processed by Graphviz tools. The format is - unspecified if `string` doesn’t end in ``.dot`` or ``.gv``. - .. _existential-variables: Existential variables @@ -1007,108 +95,3 @@ expression as described in :ref:`ltac`. This construction is useful when one wants to define complicated terms using highly automated tactics without resorting to writing the proof-term by means of the interactive proof engine. - -.. _primitive-integers: - -Primitive Integers ------------------- - -The language of terms features 63-bit machine integers as values. The type of -such a value is *axiomatized*; it is declared through the following sentence -(excerpt from the :g:`Int63` module): - -.. coqdoc:: - - Primitive int := #int63_type. - -This type is equipped with a few operators, that must be similarly declared. -For instance, equality of two primitive integers can be decided using the :g:`Int63.eqb` function, -declared and specified as follows: - -.. coqdoc:: - - Primitive eqb := #int63_eq. - Notation "m '==' n" := (eqb m n) (at level 70, no associativity) : int63_scope. - - Axiom eqb_correct : forall i j, (i == j)%int63 = true -> i = j. - -The complete set of such operators can be obtained looking at the :g:`Int63` module. - -These primitive declarations are regular axioms. As such, they must be trusted and are listed by the -:g:`Print Assumptions` command, as in the following example. - -.. coqtop:: in reset - - From Coq Require Import Int63. - Lemma one_minus_one_is_zero : (1 - 1 = 0)%int63. - Proof. apply eqb_correct; vm_compute; reflexivity. Qed. - -.. coqtop:: all - - Print Assumptions one_minus_one_is_zero. - -The reduction machines (:tacn:`vm_compute`, :tacn:`native_compute`) implement -dedicated, efficient, rules to reduce the applications of these primitive -operations. - -The extraction of these primitives can be customized similarly to the extraction -of regular axioms (see :ref:`extraction`). Nonetheless, the :g:`ExtrOCamlInt63` -module can be used when extracting to OCaml: it maps the Coq primitives to types -and functions of a :g:`Uint63` module. Said OCaml module is not produced by -extraction. Instead, it has to be provided by the user (if they want to compile -or execute the extracted code). For instance, an implementation of this module -can be taken from the kernel of Coq. - -Literal values (at type :g:`Int63.int`) are extracted to literal OCaml values -wrapped into the :g:`Uint63.of_int` (resp. :g:`Uint63.of_int64`) constructor on -64-bit (resp. 32-bit) platforms. Currently, this cannot be customized (see the -function :g:`Uint63.compile` from the kernel). - -.. _primitive-floats: - -Primitive Floats ----------------- - -The language of terms features Binary64 floating-point numbers as values. -The type of such a value is *axiomatized*; it is declared through the -following sentence (excerpt from the :g:`PrimFloat` module): - -.. coqdoc:: - - Primitive float := #float64_type. - -This type is equipped with a few operators, that must be similarly declared. -For instance, the product of two primitive floats can be computed using the -:g:`PrimFloat.mul` function, declared and specified as follows: - -.. coqdoc:: - - Primitive mul := #float64_mul. - Notation "x * y" := (mul x y) : float_scope. - - Axiom mul_spec : forall x y, Prim2SF (x * y)%float = SF64mul (Prim2SF x) (Prim2SF y). - -where :g:`Prim2SF` is defined in the :g:`FloatOps` module. - -The set of such operators is described in section :ref:`floats_library`. - -These primitive declarations are regular axioms. As such, they must be trusted, and are listed by the -:g:`Print Assumptions` command. - -The reduction machines (:tacn:`vm_compute`, :tacn:`native_compute`) implement -dedicated, efficient rules to reduce the applications of these primitive -operations, using the floating-point processor operators that are assumed -to comply with the IEEE 754 standard for floating-point arithmetic. - -The extraction of these primitives can be customized similarly to the extraction -of regular axioms (see :ref:`extraction`). Nonetheless, the :g:`ExtrOCamlFloats` -module can be used when extracting to OCaml: it maps the Coq primitives to types -and functions of a :g:`Float64` module. Said OCaml module is not produced by -extraction. Instead, it has to be provided by the user (if they want to compile -or execute the extracted code). For instance, an implementation of this module -can be taken from the kernel of Coq. - -Literal values (of type :g:`Float64.t`) are extracted to literal OCaml -values (of type :g:`float`) written in hexadecimal notation and -wrapped into the :g:`Float64.of_float` constructor, e.g.: -:g:`Float64.of_float (0x1p+0)`. -- cgit v1.2.3 From 8a35af641d92d7a65e35a3838f9cbbef4e2b2c8b Mon Sep 17 00:00:00 2001 From: Théo Zimmermann Date: Wed, 13 May 2020 23:56:27 +0200 Subject: New file on existential variables. --- doc/sphinx/language/extensions/evars.rst | 97 ++++++++++++++++++++++++++++++ doc/sphinx/language/gallina-extensions.rst | 97 ------------------------------ 2 files changed, 97 insertions(+), 97 deletions(-) create mode 100644 doc/sphinx/language/extensions/evars.rst delete mode 100644 doc/sphinx/language/gallina-extensions.rst (limited to 'doc/sphinx') diff --git a/doc/sphinx/language/extensions/evars.rst b/doc/sphinx/language/extensions/evars.rst new file mode 100644 index 0000000000..979a0a62e6 --- /dev/null +++ b/doc/sphinx/language/extensions/evars.rst @@ -0,0 +1,97 @@ +.. _existential-variables: + +Existential variables +--------------------- + +.. insertprodn term_evar term_evar + +.. prodn:: + term_evar ::= _ + | ?[ @ident ] + | ?[ ?@ident ] + | ?@ident {? @%{ {+; @ident := @term } %} } + +|Coq| terms can include existential variables which represents unknown +subterms to eventually be replaced by actual subterms. + +Existential variables are generated in place of unsolvable implicit +arguments or “_” placeholders when using commands such as ``Check`` (see +Section :ref:`requests-to-the-environment`) or when using tactics such as +:tacn:`refine`, as well as in place of unsolvable instances when using +tactics such that :tacn:`eapply`. An existential +variable is defined in a context, which is the context of variables of +the placeholder which generated the existential variable, and a type, +which is the expected type of the placeholder. + +As a consequence of typing constraints, existential variables can be +duplicated in such a way that they possibly appear in different +contexts than their defining context. Thus, any occurrence of a given +existential variable comes with an instance of its original context. +In the simple case, when an existential variable denotes the +placeholder which generated it, or is used in the same context as the +one in which it was generated, the context is not displayed and the +existential variable is represented by “?” followed by an identifier. + +.. coqtop:: all + + Parameter identity : forall (X:Set), X -> X. + + Check identity _ _. + + Check identity _ (fun x => _). + +In the general case, when an existential variable :n:`?@ident` appears +outside of its context of definition, its instance, written under the +form :n:`{ {*; @ident := @term} }` is appending to its name, indicating +how the variables of its defining context are instantiated. +The variables of the context of the existential variables which are +instantiated by themselves are not written, unless the :flag:`Printing Existential Instances` flag +is on (see Section :ref:`explicit-display-existentials`), and this is why an +existential variable used in the same context as its context of definition is written with no instance. + +.. coqtop:: all + + Check (fun x y => _) 0 1. + + Set Printing Existential Instances. + + Check (fun x y => _) 0 1. + +Existential variables can be named by the user upon creation using +the syntax :n:`?[@ident]`. This is useful when the existential +variable needs to be explicitly handled later in the script (e.g. +with a named-goal selector, see :ref:`goal-selectors`). + +.. _explicit-display-existentials: + +Explicit displaying of existential instances for pretty-printing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. flag:: Printing Existential Instances + + This flag (off by default) activates the full display of how the + context of an existential variable is instantiated at each of the + occurrences of the existential variable. + +.. _tactics-in-terms: + +Solving existential variables using tactics +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Instead of letting the unification engine try to solve an existential +variable by itself, one can also provide an explicit hole together +with a tactic to solve it. Using the syntax ``ltac:(``\ `tacexpr`\ ``)``, the user +can put a tactic anywhere a term is expected. The order of resolution +is not specified and is implementation-dependent. The inner tactic may +use any variable defined in its scope, including repeated alternations +between variables introduced by term binding as well as those +introduced by tactic binding. The expression `tacexpr` can be any tactic +expression as described in :ref:`ltac`. + +.. coqtop:: all + + Definition foo (x : nat) : nat := ltac:(exact x). + +This construction is useful when one wants to define complicated terms +using highly automated tactics without resorting to writing the proof-term +by means of the interactive proof engine. diff --git a/doc/sphinx/language/gallina-extensions.rst b/doc/sphinx/language/gallina-extensions.rst deleted file mode 100644 index 979a0a62e6..0000000000 --- a/doc/sphinx/language/gallina-extensions.rst +++ /dev/null @@ -1,97 +0,0 @@ -.. _existential-variables: - -Existential variables ---------------------- - -.. insertprodn term_evar term_evar - -.. prodn:: - term_evar ::= _ - | ?[ @ident ] - | ?[ ?@ident ] - | ?@ident {? @%{ {+; @ident := @term } %} } - -|Coq| terms can include existential variables which represents unknown -subterms to eventually be replaced by actual subterms. - -Existential variables are generated in place of unsolvable implicit -arguments or “_” placeholders when using commands such as ``Check`` (see -Section :ref:`requests-to-the-environment`) or when using tactics such as -:tacn:`refine`, as well as in place of unsolvable instances when using -tactics such that :tacn:`eapply`. An existential -variable is defined in a context, which is the context of variables of -the placeholder which generated the existential variable, and a type, -which is the expected type of the placeholder. - -As a consequence of typing constraints, existential variables can be -duplicated in such a way that they possibly appear in different -contexts than their defining context. Thus, any occurrence of a given -existential variable comes with an instance of its original context. -In the simple case, when an existential variable denotes the -placeholder which generated it, or is used in the same context as the -one in which it was generated, the context is not displayed and the -existential variable is represented by “?” followed by an identifier. - -.. coqtop:: all - - Parameter identity : forall (X:Set), X -> X. - - Check identity _ _. - - Check identity _ (fun x => _). - -In the general case, when an existential variable :n:`?@ident` appears -outside of its context of definition, its instance, written under the -form :n:`{ {*; @ident := @term} }` is appending to its name, indicating -how the variables of its defining context are instantiated. -The variables of the context of the existential variables which are -instantiated by themselves are not written, unless the :flag:`Printing Existential Instances` flag -is on (see Section :ref:`explicit-display-existentials`), and this is why an -existential variable used in the same context as its context of definition is written with no instance. - -.. coqtop:: all - - Check (fun x y => _) 0 1. - - Set Printing Existential Instances. - - Check (fun x y => _) 0 1. - -Existential variables can be named by the user upon creation using -the syntax :n:`?[@ident]`. This is useful when the existential -variable needs to be explicitly handled later in the script (e.g. -with a named-goal selector, see :ref:`goal-selectors`). - -.. _explicit-display-existentials: - -Explicit displaying of existential instances for pretty-printing -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. flag:: Printing Existential Instances - - This flag (off by default) activates the full display of how the - context of an existential variable is instantiated at each of the - occurrences of the existential variable. - -.. _tactics-in-terms: - -Solving existential variables using tactics -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Instead of letting the unification engine try to solve an existential -variable by itself, one can also provide an explicit hole together -with a tactic to solve it. Using the syntax ``ltac:(``\ `tacexpr`\ ``)``, the user -can put a tactic anywhere a term is expected. The order of resolution -is not specified and is implementation-dependent. The inner tactic may -use any variable defined in its scope, including repeated alternations -between variables introduced by term binding as well as those -introduced by tactic binding. The expression `tacexpr` can be any tactic -expression as described in :ref:`ltac`. - -.. coqtop:: all - - Definition foo (x : nat) : nat := ltac:(exact x). - -This construction is useful when one wants to define complicated terms -using highly automated tactics without resorting to writing the proof-term -by means of the interactive proof engine. -- cgit v1.2.3 From e6fca95d9b73c16e5341e47045ba2811c6bee9a7 Mon Sep 17 00:00:00 2001 From: Théo Zimmermann Date: Wed, 13 May 2020 23:58:18 +0200 Subject: Extract extended pattern matching from Gallina extensions. --- doc/sphinx/language/gallina-extensions.rst | 839 ----------------------------- 1 file changed, 839 deletions(-) (limited to 'doc/sphinx') diff --git a/doc/sphinx/language/gallina-extensions.rst b/doc/sphinx/language/gallina-extensions.rst index 5b78280edc..193c799bc3 100644 --- a/doc/sphinx/language/gallina-extensions.rst +++ b/doc/sphinx/language/gallina-extensions.rst @@ -1,11 +1,3 @@ -.. _extensionsofgallina: - -Extensions of |Gallina| -======================= - -|Gallina| is the kernel language of |Coq|. We describe here extensions of -|Gallina|’s syntax. - Variants and extensions of :g:`match` ------------------------------------- @@ -281,834 +273,3 @@ This example emphasizes what the printing settings offer. Unset Printing Wildcard. Print snd. - -Module system -------------- - -The module system provides a way of packaging related elements -together, as well as a means of massive abstraction. - - -.. cmd:: Module {? {| Import | Export } } @ident {* @module_binder } {? @of_module_type } {? := {+<+ @module_expr_inl } } - - .. insertprodn module_binder module_expr_inl - - .. prodn:: - module_binder ::= ( {? {| Import | Export } } {+ @ident } : @module_type_inl ) - module_type_inl ::= ! @module_type - | @module_type {? @functor_app_annot } - functor_app_annot ::= [ inline at level @num ] - | [ no inline ] - module_type ::= @qualid - | ( @module_type ) - | @module_type @module_expr_atom - | @module_type with @with_declaration - with_declaration ::= Definition @qualid {? @univ_decl } := @term - | Module @qualid := @qualid - module_expr_atom ::= @qualid - | ( {+ @module_expr_atom } ) - of_module_type ::= : @module_type_inl - | {* <: @module_type_inl } - module_expr_inl ::= ! {+ @module_expr_atom } - | {+ @module_expr_atom } {? @functor_app_annot } - - Defines a module named :token:`ident`. See the examples :ref:`here`. - - The :n:`Import` and :n:`Export` flags specify whether the module should be automatically - imported or exported. - - Specifying :n:`{* @module_binder }` starts a functor with - parameters given by the :n:`@module_binder`\s. (A *functor* is a function - from modules to modules.) - - :n:`@of_module_type` specifies the module type. :n:`{+ <: @module_type_inl }` - starts a module that satisfies each :n:`@module_type_inl`. - - .. todo: would like to find a better term than "interactive", not very descriptive - - :n:`:= {+<+ @module_expr_inl }` specifies the body of a module or functor - definition. If it's not specified, then the module is defined *interactively*, - meaning that the module is defined as a series of commands terminated with :cmd:`End` - instead of in a single :cmd:`Module` command. - Interactively defining the :n:`@module_expr_inl`\s in a series of - :cmd:`Include` commands is equivalent to giving them all in a single - non-interactive :cmd:`Module` command. - - The ! prefix indicates that any assumption command (such as :cmd:`Axiom`) with an :n:`Inline` clause - in the type of the functor arguments will be ignored. - - .. todo: What is an Inline directive? sb command but still unclear. Maybe referring to the - "inline" in functor_app_annot? or assumption_token Inline assum_list? - -.. cmd:: Module Type @ident {* @module_binder } {* <: @module_type_inl } {? := {+<+ @module_type_inl } } - - Defines a module type named :n:`@ident`. See the example :ref:`here`. - - Specifying :n:`{* @module_binder }` starts a functor type with - parameters given by the :n:`@module_binder`\s. - - :n:`:= {+<+ @module_type_inl }` specifies the body of a module or functor type - definition. If it's not specified, then the module type is defined *interactively*, - meaning that the module type is defined as a series of commands terminated with :cmd:`End` - instead of in a single :cmd:`Module Type` command. - Interactively defining the :n:`@module_type_inl`\s in a series of - :cmd:`Include` commands is equivalent to giving them all in a single - non-interactive :cmd:`Module Type` command. - -.. _terminating_module: - -**Terminating an interactive module or module type definition** - -Interactive modules are terminated with the :cmd:`End` command, which -is also used to terminate :ref:`Sections`. -:n:`End @ident` closes the interactive module or module type :token:`ident`. -If the module type was given, the command verifies that the content of the module -matches the module type. If the module is not a -functor, its components (constants, inductive types, submodules etc.) -are now available through the dot notation. - -.. exn:: No such label @ident. - :undocumented: - -.. exn:: Signature components for label @ident do not match. - :undocumented: - -.. exn:: The field @ident is missing in @qualid. - :undocumented: - -.. |br| raw:: html - -
- -.. note:: - - #. Interactive modules and module types can be nested. - #. Interactive modules and module types can't be defined inside of :ref:`sections`. - Sections can be defined inside of interactive modules and module types. - #. Hints and notations (:cmd:`Hint` and :cmd:`Notation` commands) can also appear inside interactive - modules and module types. Note that with module definitions like: - - :n:`Module @ident__1 : @module_type := @ident__2.` - - or - - :n:`Module @ident__1 : @module_type.` |br| - :n:`Include @ident__2.` |br| - :n:`End @ident__1.` - - hints and the like valid for :n:`@ident__1` are the ones defined in :n:`@module_type` - rather then those defined in :n:`@ident__2` (or the module body). - #. Within an interactive module type definition, the :cmd:`Parameter` command declares a - constant instead of definining a new axiom (which it does when not in a module type definition). - #. Assumptions such as :cmd:`Axiom` that include the :n:`Inline` clause will be automatically - expanded when the functor is applied, except when the function application is prefixed by ``!``. - -.. cmd:: Include @module_type_inl {* <+ @module_expr_inl } - - Includes the content of module(s) in the current - interactive module. Here :n:`@module_type_inl` can be a module expression or a module - type expression. If it is a high-order module or module type - expression then the system tries to instantiate :n:`@module_type_inl` with the current - interactive module. - - Including multiple modules is a single :cmd:`Include` is equivalent to including each module - in a separate :cmd:`Include` command. - -.. cmd:: Include Type {+<+ @module_type_inl } - - .. deprecated:: 8.3 - - Use :cmd:`Include` instead. - -.. cmd:: Declare Module {? {| Import | Export } } @ident {* @module_binder } : @module_type_inl - - Declares a module :token:`ident` of type :token:`module_type_inl`. - - If :n:`@module_binder`\s are specified, declares a functor with parameters given by the list of - :token:`module_binder`\s. - -.. cmd:: Import {+ @filtered_import } - - .. insertprodn filtered_import filtered_import - - .. prodn:: - filtered_import ::= @qualid {? ( {+, @qualid {? ( .. ) } } ) } - - If :token:`qualid` denotes a valid basic module (i.e. its module type is a - signature), makes its components available by their short names. - - .. example:: - - .. coqtop:: reset in - - Module Mod. - Definition T:=nat. - Check T. - End Mod. - Check Mod.T. - - .. coqtop:: all - - Fail Check T. - Import Mod. - Check T. - - Some features defined in modules are activated only when a module is - imported. This is for instance the case of notations (see :ref:`Notations`). - - Declarations made with the :attr:`local` attribute are never imported by the :cmd:`Import` - command. Such declarations are only accessible through their fully - qualified name. - - .. example:: - - .. coqtop:: in - - Module A. - Module B. - Local Definition T := nat. - End B. - End A. - Import A. - - .. coqtop:: all fail - - Check B.T. - - Appending a module name with a parenthesized list of names will - make only those names available with short names, not other names - defined in the module nor will it activate other features. - - The names to import may be constants, inductive types and - constructors, and notation aliases (for instance, Ltac definitions - cannot be selectively imported). If they are from an inner module - to the one being imported, they must be prefixed by the inner path. - - The name of an inductive type may also be followed by ``(..)`` to - import it, its constructors and its eliminators if they exist. For - this purpose "eliminator" means a constant in the same module whose - name is the inductive type's name suffixed by one of ``_sind``, - ``_ind``, ``_rec`` or ``_rect``. - - .. example:: - - .. coqtop:: reset in - - Module A. - Module B. - Inductive T := C. - Definition U := nat. - End B. - Definition Z := Prop. - End A. - Import A(B.T(..), Z). - - .. coqtop:: all - - Check B.T. - Check B.C. - Check Z. - Fail Check B.U. - Check A.B.U. - -.. cmd:: Export {+ @filtered_import } - :name: Export - - Similar to :cmd:`Import`, except that when the module containing this command - is imported, the :n:`{+ @qualid }` are imported as well. - - The selective import syntax also works with Export. - - .. exn:: @qualid is not a module. - :undocumented: - - .. warn:: Trying to mask the absolute name @qualid! - :undocumented: - -.. cmd:: Print Module @qualid - - Prints the module type and (optionally) the body of the module :n:`@qualid`. - -.. cmd:: Print Module Type @qualid - - Prints the module type corresponding to :n:`@qualid`. - -.. flag:: Short Module Printing - - This flag (off by default) disables the printing of the types of fields, - leaving only their names, for the commands :cmd:`Print Module` and - :cmd:`Print Module Type`. - -.. _module_examples: - -Examples -~~~~~~~~ - -.. example:: Defining a simple module interactively - - .. coqtop:: in - - Module M. - Definition T := nat. - Definition x := 0. - - .. coqtop:: all - - Definition y : bool. - exact true. - - .. coqtop:: in - - Defined. - End M. - -Inside a module one can define constants, prove theorems and do anything -else that can be done in the toplevel. Components of a closed -module can be accessed using the dot notation: - -.. coqtop:: all - - Print M.x. - -.. _example_def_simple_module_type: - -.. example:: Defining a simple module type interactively - - .. coqtop:: in - - Module Type SIG. - Parameter T : Set. - Parameter x : T. - End SIG. - -.. _example_filter_module: - -.. example:: Creating a new module that omits some items from an existing module - - Since :n:`SIG`, the type of the new module :n:`N`, doesn't define :n:`y` or - give the body of :n:`x`, which are not included in :n:`N`. - - .. coqtop:: all - - Module N : SIG with Definition T := nat := M. - Print N.T. - Print N.x. - Fail Print N.y. - - .. reset to remove N (undo in last coqtop block doesn't seem to do that), invisibly redefine M, SIG - .. coqtop:: none reset - - Module M. - Definition T := nat. - Definition x := 0. - Definition y : bool. - exact true. - Defined. - End M. - - Module Type SIG. - Parameter T : Set. - Parameter x : T. - End SIG. - -The definition of :g:`N` using the module type expression :g:`SIG` with -:g:`Definition T := nat` is equivalent to the following one: - -.. coqtop:: in - - Module Type SIG'. - Definition T : Set := nat. - Parameter x : T. - End SIG'. - - Module N : SIG' := M. - -If we just want to be sure that our implementation satisfies a -given module type without restricting the interface, we can use a -transparent constraint - -.. coqtop:: in - - Module P <: SIG := M. - -.. coqtop:: all - - Print P.y. - -.. example:: Creating a functor (a module with parameters) - - .. coqtop:: in - - Module Two (X Y: SIG). - Definition T := (X.T * Y.T)%type. - Definition x := (X.x, Y.x). - End Two. - - and apply it to our modules and do some computations: - - .. coqtop:: in - - - Module Q := Two M N. - - .. coqtop:: all - - Eval compute in (fst Q.x + snd Q.x). - -.. example:: A module type with two sub-modules, sharing some fields - - .. coqtop:: in - - Module Type SIG2. - Declare Module M1 : SIG. - Module M2 <: SIG. - Definition T := M1.T. - Parameter x : T. - End M2. - End SIG2. - - .. coqtop:: in - - Module Mod <: SIG2. - Module M1. - Definition T := nat. - Definition x := 1. - End M1. - Module M2 := M. - End Mod. - -Notice that ``M`` is a correct body for the component ``M2`` since its ``T`` -component is ``nat`` as specified for ``M1.T``. - -Libraries and qualified names ---------------------------------- - -.. _names-of-libraries: - -Names of libraries -~~~~~~~~~~~~~~~~~~ - -The theories developed in |Coq| are stored in *library files* which are -hierarchically classified into *libraries* and *sublibraries*. To -express this hierarchy, library names are represented by qualified -identifiers qualid, i.e. as list of identifiers separated by dots (see -:ref:`gallina-identifiers`). For instance, the library file ``Mult`` of the standard -|Coq| library ``Arith`` is named ``Coq.Arith.Mult``. The identifier that starts -the name of a library is called a *library root*. All library files of -the standard library of |Coq| have the reserved root |Coq| but library -filenames based on other roots can be obtained by using |Coq| commands -(coqc, coqtop, coqdep, …) options ``-Q`` or ``-R`` (see :ref:`command-line-options`). -Also, when an interactive |Coq| session starts, a library of root ``Top`` is -started, unless option ``-top`` or ``-notop`` is set (see :ref:`command-line-options`). - -.. _qualified-names: - -Qualified names -~~~~~~~~~~~~~~~ - -Library files are modules which possibly contain submodules which -eventually contain constructions (axioms, parameters, definitions, -lemmas, theorems, remarks or facts). The *absolute name*, or *full -name*, of a construction in some library file is a qualified -identifier starting with the logical name of the library file, -followed by the sequence of submodules names encapsulating the -construction and ended by the proper name of the construction. -Typically, the absolute name ``Coq.Init.Logic.eq`` denotes Leibniz’ -equality defined in the module Logic in the sublibrary ``Init`` of the -standard library of |Coq|. - -The proper name that ends the name of a construction is the short name -(or sometimes base name) of the construction (for instance, the short -name of ``Coq.Init.Logic.eq`` is ``eq``). Any partial suffix of the absolute -name is a *partially qualified name* (e.g. ``Logic.eq`` is a partially -qualified name for ``Coq.Init.Logic.eq``). Especially, the short name of a -construction is its shortest partially qualified name. - -|Coq| does not accept two constructions (definition, theorem, …) with -the same absolute name but different constructions can have the same -short name (or even same partially qualified names as soon as the full -names are different). - -Notice that the notion of absolute, partially qualified and short -names also applies to library filenames. - -**Visibility** - -|Coq| maintains a table called the name table which maps partially qualified -names of constructions to absolute names. This table is updated by the -commands :cmd:`Require`, :cmd:`Import` and :cmd:`Export` and -also each time a new declaration is added to the context. An absolute -name is called visible from a given short or partially qualified name -when this latter name is enough to denote it. This means that the -short or partially qualified name is mapped to the absolute name in -|Coq| name table. Definitions with the :attr:`local` attribute are only accessible with -their fully qualified name (see :ref:`gallina-definitions`). - -It may happen that a visible name is hidden by the short name or a -qualified name of another construction. In this case, the name that -has been hidden must be referred to using one more level of -qualification. To ensure that a construction always remains -accessible, absolute names can never be hidden. - -.. example:: - - .. coqtop:: all - - Check 0. - - Definition nat := bool. - - Check 0. - - Check Datatypes.nat. - - Locate nat. - -.. seealso:: Commands :cmd:`Locate`. - -.. _libraries-and-filesystem: - -Libraries and filesystem -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. note:: The questions described here have been subject to redesign in |Coq| 8.5. - Former versions of |Coq| use the same terminology to describe slightly different things. - -Compiled files (``.vo`` and ``.vio``) store sub-libraries. In order to refer -to them inside |Coq|, a translation from file-system names to |Coq| names -is needed. In this translation, names in the file system are called -*physical* paths while |Coq| names are contrastingly called *logical* -names. - -A logical prefix Lib can be associated with a physical path using -the command line option ``-Q`` `path` ``Lib``. All subfolders of path are -recursively associated to the logical path ``Lib`` extended with the -corresponding suffix coming from the physical path. For instance, the -folder ``path/fOO/Bar`` maps to ``Lib.fOO.Bar``. Subdirectories corresponding -to invalid |Coq| identifiers are skipped, and, by convention, -subdirectories named ``CVS`` or ``_darcs`` are skipped too. - -Thanks to this mechanism, ``.vo`` files are made available through the -logical name of the folder they are in, extended with their own -basename. For example, the name associated to the file -``path/fOO/Bar/File.vo`` is ``Lib.fOO.Bar.File``. The same caveat applies for -invalid identifiers. When compiling a source file, the ``.vo`` file stores -its logical name, so that an error is issued if it is loaded with the -wrong loadpath afterwards. - -Some folders have a special status and are automatically put in the -path. |Coq| commands associate automatically a logical path to files in -the repository trees rooted at the directory from where the command is -launched, ``coqlib/user-contrib/``, the directories listed in the -``$COQPATH``, ``${XDG_DATA_HOME}/coq/`` and ``${XDG_DATA_DIRS}/coq/`` -environment variables (see `XDG base directory specification -`_) -with the same physical-to-logical translation and with an empty logical prefix. - -The command line option ``-R`` is a variant of ``-Q`` which has the strictly -same behavior regarding loadpaths, but which also makes the -corresponding ``.vo`` files available through their short names in a way -similar to the :cmd:`Import` command. For instance, ``-R path Lib`` -associates to the file ``/path/fOO/Bar/File.vo`` the logical name -``Lib.fOO.Bar.File``, but allows this file to be accessed through the -short names ``fOO.Bar.File,Bar.File`` and ``File``. If several files with -identical base name are present in different subdirectories of a -recursive loadpath, which of these files is found first may be system- -dependent and explicit qualification is recommended. The ``From`` argument -of the ``Require`` command can be used to bypass the implicit shortening -by providing an absolute root to the required file (see :ref:`compiled-files`). - -There also exists another independent loadpath mechanism attached to -OCaml object files (``.cmo`` or ``.cmxs``) rather than |Coq| object -files as described above. The OCaml loadpath is managed using -the option ``-I`` `path` (in the OCaml world, there is neither a -notion of logical name prefix nor a way to access files in -subdirectories of path). See the command :cmd:`Declare ML Module` in -:ref:`compiled-files` to understand the need of the OCaml loadpath. - -See :ref:`command-line-options` for a more general view over the |Coq| command -line options. - -.. _Coercions: - -Coercions ---------- - -Coercions can be used to implicitly inject terms from one *class* in -which they reside into another one. A *class* is either a sort -(denoted by the keyword ``Sortclass``), a product type (denoted by the -keyword ``Funclass``), or a type constructor (denoted by its name), e.g. -an inductive type or any constant with a type of the form -:n:`forall {+ @binder }, @sort`. - -Then the user is able to apply an object that is not a function, but -can be coerced to a function, and more generally to consider that a -term of type ``A`` is of type ``B`` provided that there is a declared coercion -between ``A`` and ``B``. - -More details and examples, and a description of the commands related -to coercions are provided in :ref:`implicitcoercions`. - -.. _printing_constructions_full: - -Printing constructions in full ------------------------------- - -.. flag:: Printing All - - Coercions, implicit arguments, the type of pattern matching, but also - notations (see :ref:`syntax-extensions-and-notation-scopes`) can obfuscate the behavior of some - tactics (typically the tactics applying to occurrences of subterms are - sensitive to the implicit arguments). Turning this flag on - deactivates all high-level printing features such as coercions, - implicit arguments, returned type of pattern matching, notations and - various syntactic sugar for pattern matching or record projections. - Otherwise said, :flag:`Printing All` includes the effects of the flags - :flag:`Printing Implicit`, :flag:`Printing Coercions`, :flag:`Printing Synth`, - :flag:`Printing Projections`, and :flag:`Printing Notations`. To reactivate - the high-level printing features, use the command ``Unset Printing All``. - - .. note:: In some cases, setting :flag:`Printing All` may display terms - that are so big they become very hard to read. One technique to work around - this is use :cmd:`Undelimit Scope` and/or :cmd:`Close Scope` to turn off the - printing of notations bound to particular scope(s). This can be useful when - notations in a given scope are getting in the way of understanding - a goal, but turning off all notations with :flag:`Printing All` would make - the goal unreadable. - - .. see a contrived example here: https://github.com/coq/coq/pull/11718#discussion_r415481854 - -.. _printing-universes: - -Printing universes ------------------- - -.. flag:: Printing Universes - - Turn this flag on to activate the display of the actual level of each - occurrence of :g:`Type`. See :ref:`Sorts` for details. This wizard flag, in - combination with :flag:`Printing All` can help to diagnose failures to unify - terms apparently identical but internally different in the Calculus of Inductive - Constructions. - -.. cmd:: Print {? Sorted } Universes {? Subgraph ( {* @qualid } ) } {? @string } - :name: Print Universes - - This command can be used to print the constraints on the internal level - of the occurrences of :math:`\Type` (see :ref:`Sorts`). - - The :n:`Subgraph` clause limits the printed graph to the requested names (adjusting - constraints to preserve the implied transitive constraints between - kept universes). - - The :n:`Sorted` clause makes each universe - equivalent to a numbered label reflecting its level (with a linear - ordering) in the universe hierarchy. - - :n:`@string` is an optional output filename. - If :n:`@string` ends in ``.dot`` or ``.gv``, the constraints are printed in the DOT - language, and can be processed by Graphviz tools. The format is - unspecified if `string` doesn’t end in ``.dot`` or ``.gv``. - -.. _existential-variables: - -Existential variables ---------------------- - -.. insertprodn term_evar term_evar - -.. prodn:: - term_evar ::= _ - | ?[ @ident ] - | ?[ ?@ident ] - | ?@ident {? @%{ {+; @ident := @term } %} } - -|Coq| terms can include existential variables which represents unknown -subterms to eventually be replaced by actual subterms. - -Existential variables are generated in place of unsolvable implicit -arguments or “_” placeholders when using commands such as ``Check`` (see -Section :ref:`requests-to-the-environment`) or when using tactics such as -:tacn:`refine`, as well as in place of unsolvable instances when using -tactics such that :tacn:`eapply`. An existential -variable is defined in a context, which is the context of variables of -the placeholder which generated the existential variable, and a type, -which is the expected type of the placeholder. - -As a consequence of typing constraints, existential variables can be -duplicated in such a way that they possibly appear in different -contexts than their defining context. Thus, any occurrence of a given -existential variable comes with an instance of its original context. -In the simple case, when an existential variable denotes the -placeholder which generated it, or is used in the same context as the -one in which it was generated, the context is not displayed and the -existential variable is represented by “?” followed by an identifier. - -.. coqtop:: all - - Parameter identity : forall (X:Set), X -> X. - - Check identity _ _. - - Check identity _ (fun x => _). - -In the general case, when an existential variable :n:`?@ident` appears -outside of its context of definition, its instance, written under the -form :n:`{ {*; @ident := @term} }` is appending to its name, indicating -how the variables of its defining context are instantiated. -The variables of the context of the existential variables which are -instantiated by themselves are not written, unless the :flag:`Printing Existential Instances` flag -is on (see Section :ref:`explicit-display-existentials`), and this is why an -existential variable used in the same context as its context of definition is written with no instance. - -.. coqtop:: all - - Check (fun x y => _) 0 1. - - Set Printing Existential Instances. - - Check (fun x y => _) 0 1. - -Existential variables can be named by the user upon creation using -the syntax :n:`?[@ident]`. This is useful when the existential -variable needs to be explicitly handled later in the script (e.g. -with a named-goal selector, see :ref:`goal-selectors`). - -.. _explicit-display-existentials: - -Explicit displaying of existential instances for pretty-printing -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. flag:: Printing Existential Instances - - This flag (off by default) activates the full display of how the - context of an existential variable is instantiated at each of the - occurrences of the existential variable. - -.. _tactics-in-terms: - -Solving existential variables using tactics -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Instead of letting the unification engine try to solve an existential -variable by itself, one can also provide an explicit hole together -with a tactic to solve it. Using the syntax ``ltac:(``\ `tacexpr`\ ``)``, the user -can put a tactic anywhere a term is expected. The order of resolution -is not specified and is implementation-dependent. The inner tactic may -use any variable defined in its scope, including repeated alternations -between variables introduced by term binding as well as those -introduced by tactic binding. The expression `tacexpr` can be any tactic -expression as described in :ref:`ltac`. - -.. coqtop:: all - - Definition foo (x : nat) : nat := ltac:(exact x). - -This construction is useful when one wants to define complicated terms -using highly automated tactics without resorting to writing the proof-term -by means of the interactive proof engine. - -.. _primitive-integers: - -Primitive Integers ------------------- - -The language of terms features 63-bit machine integers as values. The type of -such a value is *axiomatized*; it is declared through the following sentence -(excerpt from the :g:`Int63` module): - -.. coqdoc:: - - Primitive int := #int63_type. - -This type is equipped with a few operators, that must be similarly declared. -For instance, equality of two primitive integers can be decided using the :g:`Int63.eqb` function, -declared and specified as follows: - -.. coqdoc:: - - Primitive eqb := #int63_eq. - Notation "m '==' n" := (eqb m n) (at level 70, no associativity) : int63_scope. - - Axiom eqb_correct : forall i j, (i == j)%int63 = true -> i = j. - -The complete set of such operators can be obtained looking at the :g:`Int63` module. - -These primitive declarations are regular axioms. As such, they must be trusted and are listed by the -:g:`Print Assumptions` command, as in the following example. - -.. coqtop:: in reset - - From Coq Require Import Int63. - Lemma one_minus_one_is_zero : (1 - 1 = 0)%int63. - Proof. apply eqb_correct; vm_compute; reflexivity. Qed. - -.. coqtop:: all - - Print Assumptions one_minus_one_is_zero. - -The reduction machines (:tacn:`vm_compute`, :tacn:`native_compute`) implement -dedicated, efficient, rules to reduce the applications of these primitive -operations. - -The extraction of these primitives can be customized similarly to the extraction -of regular axioms (see :ref:`extraction`). Nonetheless, the :g:`ExtrOCamlInt63` -module can be used when extracting to OCaml: it maps the Coq primitives to types -and functions of a :g:`Uint63` module. Said OCaml module is not produced by -extraction. Instead, it has to be provided by the user (if they want to compile -or execute the extracted code). For instance, an implementation of this module -can be taken from the kernel of Coq. - -Literal values (at type :g:`Int63.int`) are extracted to literal OCaml values -wrapped into the :g:`Uint63.of_int` (resp. :g:`Uint63.of_int64`) constructor on -64-bit (resp. 32-bit) platforms. Currently, this cannot be customized (see the -function :g:`Uint63.compile` from the kernel). - -.. _primitive-floats: - -Primitive Floats ----------------- - -The language of terms features Binary64 floating-point numbers as values. -The type of such a value is *axiomatized*; it is declared through the -following sentence (excerpt from the :g:`PrimFloat` module): - -.. coqdoc:: - - Primitive float := #float64_type. - -This type is equipped with a few operators, that must be similarly declared. -For instance, the product of two primitive floats can be computed using the -:g:`PrimFloat.mul` function, declared and specified as follows: - -.. coqdoc:: - - Primitive mul := #float64_mul. - Notation "x * y" := (mul x y) : float_scope. - - Axiom mul_spec : forall x y, Prim2SF (x * y)%float = SF64mul (Prim2SF x) (Prim2SF y). - -where :g:`Prim2SF` is defined in the :g:`FloatOps` module. - -The set of such operators is described in section :ref:`floats_library`. - -These primitive declarations are regular axioms. As such, they must be trusted, and are listed by the -:g:`Print Assumptions` command. - -The reduction machines (:tacn:`vm_compute`, :tacn:`native_compute`) implement -dedicated, efficient rules to reduce the applications of these primitive -operations, using the floating-point processor operators that are assumed -to comply with the IEEE 754 standard for floating-point arithmetic. - -The extraction of these primitives can be customized similarly to the extraction -of regular axioms (see :ref:`extraction`). Nonetheless, the :g:`ExtrOCamlFloats` -module can be used when extracting to OCaml: it maps the Coq primitives to types -and functions of a :g:`Float64` module. Said OCaml module is not produced by -extraction. Instead, it has to be provided by the user (if they want to compile -or execute the extracted code). For instance, an implementation of this module -can be taken from the kernel of Coq. - -Literal values (of type :g:`Float64.t`) are extracted to literal OCaml -values (of type :g:`float`) written in hexadecimal notation and -wrapped into the :g:`Float64.of_float` constructor, e.g.: -:g:`Float64.of_float (0x1p+0)`. -- cgit v1.2.3 From 5e03735996709ae964c981f3bf29566dabca00bb Mon Sep 17 00:00:00 2001 From: Théo Zimmermann Date: Wed, 13 May 2020 23:59:38 +0200 Subject: Add section on pattern matching from Gallina ext. --- doc/sphinx/language/extensions/match.rst | 275 +++++++++++++++++++++++++++++ doc/sphinx/language/gallina-extensions.rst | 275 ----------------------------- 2 files changed, 275 insertions(+), 275 deletions(-) create mode 100644 doc/sphinx/language/extensions/match.rst delete mode 100644 doc/sphinx/language/gallina-extensions.rst (limited to 'doc/sphinx') diff --git a/doc/sphinx/language/extensions/match.rst b/doc/sphinx/language/extensions/match.rst new file mode 100644 index 0000000000..193c799bc3 --- /dev/null +++ b/doc/sphinx/language/extensions/match.rst @@ -0,0 +1,275 @@ +Variants and extensions of :g:`match` +------------------------------------- + +.. _mult-match: + +Multiple and nested pattern matching +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The basic version of :g:`match` allows pattern matching on simple +patterns. As an extension, multiple nested patterns or disjunction of +patterns are allowed, as in ML-like languages. + +The extension just acts as a macro that is expanded during parsing +into a sequence of match on simple patterns. Especially, a +construction defined using the extended match is generally printed +under its expanded form (see :flag:`Printing Matching`). + +.. seealso:: :ref:`extendedpatternmatching`. + +.. _if-then-else: + +Pattern-matching on boolean values: the if expression +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. insertprodn term_if term_if + +.. prodn:: + term_if ::= if @term {? {? as @name } return @term100 } then @term else @term + +For inductive types with exactly two constructors and for pattern matching +expressions that do not depend on the arguments of the constructors, it is possible +to use a ``if … then … else`` notation. For instance, the definition + +.. coqtop:: all + + Definition not (b:bool) := + match b with + | true => false + | false => true + end. + +can be alternatively written + +.. coqtop:: reset all + + Definition not (b:bool) := if b then false else true. + +More generally, for an inductive type with constructors :n:`@ident__1` +and :n:`@ident__2`, the following terms are equal: + +:n:`if @term__0 {? {? as @name } return @term } then @term__1 else @term__2` + +:n:`match @term__0 {? {? as @name } return @term } with | @ident__1 {* _ } => @term__1 | @ident__2 {* _ } => @term__2 end` + +.. example:: + + .. coqtop:: all + + Check (fun x (H:{x=0}+{x<>0}) => + match H with + | left _ => true + | right _ => false + end). + +Notice that the printing uses the :g:`if` syntax because :g:`sumbool` is +declared as such (see :ref:`controlling-match-pp`). + +.. _irrefutable-patterns: + +Irrefutable patterns: the destructuring let variants +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Pattern-matching on terms inhabiting inductive type having only one +constructor can be alternatively written using :g:`let … in …` +constructions. There are two variants of them. + + +First destructuring let syntax +++++++++++++++++++++++++++++++ + +The expression :n:`let ( {*, @ident__i } ) := @term__0 in @term__1` +performs case analysis on :n:`@term__0` whose type must be an +inductive type with exactly one constructor. The number of variables +:n:`@ident__i` must correspond to the number of arguments of this +contrustor. Then, in :n:`@term__1`, these variables are bound to the +arguments of the constructor in :n:`@term__0`. For instance, the +definition + +.. coqtop:: reset all + + Definition fst (A B:Set) (H:A * B) := match H with + | pair x y => x + end. + +can be alternatively written + +.. coqtop:: reset all + + Definition fst (A B:Set) (p:A * B) := let (x, _) := p in x. + +Notice that reduction is different from regular :g:`let … in …` +construction since it happens only if :n:`@term__0` is in constructor form. +Otherwise, the reduction is blocked. + +The pretty-printing of a definition by matching on a irrefutable +pattern can either be done using :g:`match` or the :g:`let` construction +(see Section :ref:`controlling-match-pp`). + +If term inhabits an inductive type with one constructor `C`, we have an +equivalence between + +:: + + let (ident₁, …, identₙ) [dep_ret_type] := term in term' + +and + +:: + + match term [dep_ret_type] with + C ident₁ … identₙ => term' + end + + +Second destructuring let syntax ++++++++++++++++++++++++++++++++ + +Another destructuring let syntax is available for inductive types with +one constructor by giving an arbitrary pattern instead of just a tuple +for all the arguments. For example, the preceding example can be +written: + +.. coqtop:: reset all + + Definition fst (A B:Set) (p:A*B) := let 'pair x _ := p in x. + +This is useful to match deeper inside tuples and also to use notations +for the pattern, as the syntax :g:`let ’p := t in b` allows arbitrary +patterns to do the deconstruction. For example: + +.. coqtop:: all + + Definition deep_tuple (A:Set) (x:(A*A)*(A*A)) : A*A*A*A := + let '((a,b), (c, d)) := x in (a,b,c,d). + + Notation " x 'With' p " := (exist _ x p) (at level 20). + + Definition proj1_sig' (A:Set) (P:A->Prop) (t:{ x:A | P x }) : A := + let 'x With p := t in x. + +When printing definitions which are written using this construct it +takes precedence over let printing directives for the datatype under +consideration (see Section :ref:`controlling-match-pp`). + + +.. _controlling-match-pp: + +Controlling pretty-printing of match expressions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following commands give some control over the pretty-printing +of :g:`match` expressions. + +Printing nested patterns ++++++++++++++++++++++++++ + +.. flag:: Printing Matching + + The Calculus of Inductive Constructions knows pattern matching only + over simple patterns. It is however convenient to re-factorize nested + pattern matching into a single pattern matching over a nested + pattern. + + When this flag is on (default), |Coq|’s printer tries to do such + limited re-factorization. + Turning it off tells |Coq| to print only simple pattern matching problems + in the same way as the |Coq| kernel handles them. + + +Factorization of clauses with same right-hand side +++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. flag:: Printing Factorizable Match Patterns + + When several patterns share the same right-hand side, it is additionally + possible to share the clauses using disjunctive patterns. Assuming that the + printing matching mode is on, this flag (on by default) tells |Coq|'s + printer to try to do this kind of factorization. + +Use of a default clause ++++++++++++++++++++++++ + +.. flag:: Printing Allow Match Default Clause + + When several patterns share the same right-hand side which do not depend on the + arguments of the patterns, yet an extra factorization is possible: the + disjunction of patterns can be replaced with a `_` default clause. Assuming that + the printing matching mode and the factorization mode are on, this flag (on by + default) tells |Coq|'s printer to use a default clause when relevant. + +Printing of wildcard patterns +++++++++++++++++++++++++++++++ + +.. flag:: Printing Wildcard + + Some variables in a pattern may not occur in the right-hand side of + the pattern matching clause. When this flag is on (default), the + variables having no occurrences in the right-hand side of the + pattern matching clause are just printed using the wildcard symbol + “_”. + + +Printing of the elimination predicate ++++++++++++++++++++++++++++++++++++++ + +.. flag:: Printing Synth + + In most of the cases, the type of the result of a matched term is + mechanically synthesizable. Especially, if the result type does not + depend of the matched term. When this flag is on (default), + the result type is not printed when |Coq| knows that it can re- + synthesize it. + + +Printing matching on irrefutable patterns +++++++++++++++++++++++++++++++++++++++++++ + +If an inductive type has just one constructor, pattern matching can be +written using the first destructuring let syntax. + +.. table:: Printing Let @qualid + :name: Printing Let + + Specifies a set of qualids for which pattern matching is displayed using a let expression. + Note that this only applies to pattern matching instances entered with :g:`match`. + It doesn't affect pattern matching explicitly entered with a destructuring + :g:`let`. + Use the :cmd:`Add` and :cmd:`Remove` commands to update this set. + + +Printing matching on booleans ++++++++++++++++++++++++++++++ + +If an inductive type is isomorphic to the boolean type, pattern matching +can be written using ``if`` … ``then`` … ``else`` …. This table controls +which types are written this way: + +.. table:: Printing If @qualid + :name: Printing If + + Specifies a set of qualids for which pattern matching is displayed using + ``if`` … ``then`` … ``else`` …. Use the :cmd:`Add` and :cmd:`Remove` + commands to update this set. + +This example emphasizes what the printing settings offer. + +.. example:: + + .. coqtop:: all + + Definition snd (A B:Set) (H:A * B) := match H with + | pair x y => y + end. + + Test Printing Let for prod. + + Print snd. + + Remove Printing Let prod. + + Unset Printing Synth. + + Unset Printing Wildcard. + + Print snd. diff --git a/doc/sphinx/language/gallina-extensions.rst b/doc/sphinx/language/gallina-extensions.rst deleted file mode 100644 index 193c799bc3..0000000000 --- a/doc/sphinx/language/gallina-extensions.rst +++ /dev/null @@ -1,275 +0,0 @@ -Variants and extensions of :g:`match` -------------------------------------- - -.. _mult-match: - -Multiple and nested pattern matching -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The basic version of :g:`match` allows pattern matching on simple -patterns. As an extension, multiple nested patterns or disjunction of -patterns are allowed, as in ML-like languages. - -The extension just acts as a macro that is expanded during parsing -into a sequence of match on simple patterns. Especially, a -construction defined using the extended match is generally printed -under its expanded form (see :flag:`Printing Matching`). - -.. seealso:: :ref:`extendedpatternmatching`. - -.. _if-then-else: - -Pattern-matching on boolean values: the if expression -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. insertprodn term_if term_if - -.. prodn:: - term_if ::= if @term {? {? as @name } return @term100 } then @term else @term - -For inductive types with exactly two constructors and for pattern matching -expressions that do not depend on the arguments of the constructors, it is possible -to use a ``if … then … else`` notation. For instance, the definition - -.. coqtop:: all - - Definition not (b:bool) := - match b with - | true => false - | false => true - end. - -can be alternatively written - -.. coqtop:: reset all - - Definition not (b:bool) := if b then false else true. - -More generally, for an inductive type with constructors :n:`@ident__1` -and :n:`@ident__2`, the following terms are equal: - -:n:`if @term__0 {? {? as @name } return @term } then @term__1 else @term__2` - -:n:`match @term__0 {? {? as @name } return @term } with | @ident__1 {* _ } => @term__1 | @ident__2 {* _ } => @term__2 end` - -.. example:: - - .. coqtop:: all - - Check (fun x (H:{x=0}+{x<>0}) => - match H with - | left _ => true - | right _ => false - end). - -Notice that the printing uses the :g:`if` syntax because :g:`sumbool` is -declared as such (see :ref:`controlling-match-pp`). - -.. _irrefutable-patterns: - -Irrefutable patterns: the destructuring let variants -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Pattern-matching on terms inhabiting inductive type having only one -constructor can be alternatively written using :g:`let … in …` -constructions. There are two variants of them. - - -First destructuring let syntax -++++++++++++++++++++++++++++++ - -The expression :n:`let ( {*, @ident__i } ) := @term__0 in @term__1` -performs case analysis on :n:`@term__0` whose type must be an -inductive type with exactly one constructor. The number of variables -:n:`@ident__i` must correspond to the number of arguments of this -contrustor. Then, in :n:`@term__1`, these variables are bound to the -arguments of the constructor in :n:`@term__0`. For instance, the -definition - -.. coqtop:: reset all - - Definition fst (A B:Set) (H:A * B) := match H with - | pair x y => x - end. - -can be alternatively written - -.. coqtop:: reset all - - Definition fst (A B:Set) (p:A * B) := let (x, _) := p in x. - -Notice that reduction is different from regular :g:`let … in …` -construction since it happens only if :n:`@term__0` is in constructor form. -Otherwise, the reduction is blocked. - -The pretty-printing of a definition by matching on a irrefutable -pattern can either be done using :g:`match` or the :g:`let` construction -(see Section :ref:`controlling-match-pp`). - -If term inhabits an inductive type with one constructor `C`, we have an -equivalence between - -:: - - let (ident₁, …, identₙ) [dep_ret_type] := term in term' - -and - -:: - - match term [dep_ret_type] with - C ident₁ … identₙ => term' - end - - -Second destructuring let syntax -+++++++++++++++++++++++++++++++ - -Another destructuring let syntax is available for inductive types with -one constructor by giving an arbitrary pattern instead of just a tuple -for all the arguments. For example, the preceding example can be -written: - -.. coqtop:: reset all - - Definition fst (A B:Set) (p:A*B) := let 'pair x _ := p in x. - -This is useful to match deeper inside tuples and also to use notations -for the pattern, as the syntax :g:`let ’p := t in b` allows arbitrary -patterns to do the deconstruction. For example: - -.. coqtop:: all - - Definition deep_tuple (A:Set) (x:(A*A)*(A*A)) : A*A*A*A := - let '((a,b), (c, d)) := x in (a,b,c,d). - - Notation " x 'With' p " := (exist _ x p) (at level 20). - - Definition proj1_sig' (A:Set) (P:A->Prop) (t:{ x:A | P x }) : A := - let 'x With p := t in x. - -When printing definitions which are written using this construct it -takes precedence over let printing directives for the datatype under -consideration (see Section :ref:`controlling-match-pp`). - - -.. _controlling-match-pp: - -Controlling pretty-printing of match expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The following commands give some control over the pretty-printing -of :g:`match` expressions. - -Printing nested patterns -+++++++++++++++++++++++++ - -.. flag:: Printing Matching - - The Calculus of Inductive Constructions knows pattern matching only - over simple patterns. It is however convenient to re-factorize nested - pattern matching into a single pattern matching over a nested - pattern. - - When this flag is on (default), |Coq|’s printer tries to do such - limited re-factorization. - Turning it off tells |Coq| to print only simple pattern matching problems - in the same way as the |Coq| kernel handles them. - - -Factorization of clauses with same right-hand side -++++++++++++++++++++++++++++++++++++++++++++++++++ - -.. flag:: Printing Factorizable Match Patterns - - When several patterns share the same right-hand side, it is additionally - possible to share the clauses using disjunctive patterns. Assuming that the - printing matching mode is on, this flag (on by default) tells |Coq|'s - printer to try to do this kind of factorization. - -Use of a default clause -+++++++++++++++++++++++ - -.. flag:: Printing Allow Match Default Clause - - When several patterns share the same right-hand side which do not depend on the - arguments of the patterns, yet an extra factorization is possible: the - disjunction of patterns can be replaced with a `_` default clause. Assuming that - the printing matching mode and the factorization mode are on, this flag (on by - default) tells |Coq|'s printer to use a default clause when relevant. - -Printing of wildcard patterns -++++++++++++++++++++++++++++++ - -.. flag:: Printing Wildcard - - Some variables in a pattern may not occur in the right-hand side of - the pattern matching clause. When this flag is on (default), the - variables having no occurrences in the right-hand side of the - pattern matching clause are just printed using the wildcard symbol - “_”. - - -Printing of the elimination predicate -+++++++++++++++++++++++++++++++++++++ - -.. flag:: Printing Synth - - In most of the cases, the type of the result of a matched term is - mechanically synthesizable. Especially, if the result type does not - depend of the matched term. When this flag is on (default), - the result type is not printed when |Coq| knows that it can re- - synthesize it. - - -Printing matching on irrefutable patterns -++++++++++++++++++++++++++++++++++++++++++ - -If an inductive type has just one constructor, pattern matching can be -written using the first destructuring let syntax. - -.. table:: Printing Let @qualid - :name: Printing Let - - Specifies a set of qualids for which pattern matching is displayed using a let expression. - Note that this only applies to pattern matching instances entered with :g:`match`. - It doesn't affect pattern matching explicitly entered with a destructuring - :g:`let`. - Use the :cmd:`Add` and :cmd:`Remove` commands to update this set. - - -Printing matching on booleans -+++++++++++++++++++++++++++++ - -If an inductive type is isomorphic to the boolean type, pattern matching -can be written using ``if`` … ``then`` … ``else`` …. This table controls -which types are written this way: - -.. table:: Printing If @qualid - :name: Printing If - - Specifies a set of qualids for which pattern matching is displayed using - ``if`` … ``then`` … ``else`` …. Use the :cmd:`Add` and :cmd:`Remove` - commands to update this set. - -This example emphasizes what the printing settings offer. - -.. example:: - - .. coqtop:: all - - Definition snd (A B:Set) (H:A * B) := match H with - | pair x y => y - end. - - Test Printing Let for prod. - - Print snd. - - Remove Printing Let prod. - - Unset Printing Synth. - - Unset Printing Wildcard. - - Print snd. -- cgit v1.2.3 From 2eb493751f44fcb79bdd9c49eb3e3edbf71e325a Mon Sep 17 00:00:00 2001 From: Théo Zimmermann Date: Thu, 14 May 2020 00:00:28 +0200 Subject: Move extended pattern matching to new location. --- doc/sphinx/addendum/extended-pattern-matching.rst | 617 ---------------------- doc/sphinx/language/extensions/match.rst | 617 ++++++++++++++++++++++ 2 files changed, 617 insertions(+), 617 deletions(-) delete mode 100644 doc/sphinx/addendum/extended-pattern-matching.rst create mode 100644 doc/sphinx/language/extensions/match.rst (limited to 'doc/sphinx') diff --git a/doc/sphinx/addendum/extended-pattern-matching.rst b/doc/sphinx/addendum/extended-pattern-matching.rst deleted file mode 100644 index 8ec51e45ba..0000000000 --- a/doc/sphinx/addendum/extended-pattern-matching.rst +++ /dev/null @@ -1,617 +0,0 @@ -.. _extendedpatternmatching: - -Extended pattern matching -========================= - -:Authors: Cristina Cornes and Hugo Herbelin - -This section describes the full form of pattern matching in |Coq| terms. - -.. |rhs| replace:: right hand sides - -Patterns --------- - -The full syntax of :g:`match` is presented in section :ref:`term`. -Identifiers in patterns are either constructor names or variables. Any -identifier that is not the constructor of an inductive or co-inductive -type is considered to be a variable. A variable name cannot occur more -than once in a given pattern. It is recommended to start variable -names by a lowercase letter. - -If a pattern has the form ``c x`` where ``c`` is a constructor symbol and x -is a linear vector of (distinct) variables, it is called *simple*: it -is the kind of pattern recognized by the basic version of match. On -the opposite, if it is a variable ``x`` or has the form ``c p`` with ``p`` not -only made of variables, the pattern is called *nested*. - -A variable pattern matches any value, and the identifier is bound to -that value. The pattern “``_``” (called “don't care” or “wildcard” symbol) -also matches any value, but does not bind anything. It may occur an -arbitrary number of times in a pattern. Alias patterns written -:n:`(@pattern as @ident)` are also accepted. This pattern matches the -same values as :token:`pattern` does and :token:`ident` is bound to the matched -value. A pattern of the form :n:`@pattern | @pattern` is called disjunctive. A -list of patterns separated with commas is also considered as a pattern -and is called *multiple pattern*. However multiple patterns can only -occur at the root of pattern matching equations. Disjunctions of -*multiple patterns* are allowed though. - -Since extended ``match`` expressions are compiled into the primitive ones, -the expressiveness of the theory remains the same. Once parsing has finished -only simple patterns remain. The original nesting of the ``match`` expressions -is recovered at printing time. An easy way to see the result -of the expansion is to toggle off the nesting performed at printing -(use here :flag:`Printing Matching`), then by printing the term with :cmd:`Print` -if the term is a constant, or using the command :cmd:`Check`. - -The extended ``match`` still accepts an optional *elimination predicate* -given after the keyword ``return``. Given a pattern matching expression, -if all the right-hand-sides of ``=>`` have the same -type, then this type can be sometimes synthesized, and so we can omit -the return part. Otherwise the predicate after return has to be -provided, like for the basicmatch. - -Let us illustrate through examples the different aspects of extended -pattern matching. Consider for example the function that computes the -maximum of two natural numbers. We can write it in primitive syntax -by: - -.. coqtop:: in - - Fixpoint max (n m:nat) {struct m} : nat := - match n with - | O => m - | S n' => match m with - | O => S n' - | S m' => S (max n' m') - end - end. - -Multiple patterns ------------------ - -Using multiple patterns in the definition of ``max`` lets us write: - -.. coqtop:: in reset - - Fixpoint max (n m:nat) {struct m} : nat := - match n, m with - | O, _ => m - | S n', O => S n' - | S n', S m' => S (max n' m') - end. - -which will be compiled into the previous form. - -The pattern matching compilation strategy examines patterns from left -to right. A match expression is generated **only** when there is at least -one constructor in the column of patterns. E.g. the following example -does not build a match expression. - -.. coqtop:: all - - Check (fun x:nat => match x return nat with - | y => y - end). - - -Aliasing subpatterns --------------------- - -We can also use :n:`as @ident` to associate a name to a sub-pattern: - -.. coqtop:: in reset - - Fixpoint max (n m:nat) {struct n} : nat := - match n, m with - | O, _ => m - | S n' as p, O => p - | S n', S m' => S (max n' m') - end. - -Nested patterns ---------------- - -Here is now an example of nested patterns: - -.. coqtop:: in - - Fixpoint even (n:nat) : bool := - match n with - | O => true - | S O => false - | S (S n') => even n' - end. - -This is compiled into: - -.. coqtop:: all - - Unset Printing Matching. - Print even. - -.. coqtop:: none - - Set Printing Matching. - -In the previous examples patterns do not conflict with, but sometimes -it is comfortable to write patterns that admit a non trivial -superposition. Consider the boolean function :g:`lef` that given two -natural numbers yields :g:`true` if the first one is less or equal than the -second one and :g:`false` otherwise. We can write it as follows: - -.. coqtop:: in - - Fixpoint lef (n m:nat) {struct m} : bool := - match n, m with - | O, x => true - | x, O => false - | S n, S m => lef n m - end. - -Note that the first and the second multiple pattern overlap because -the couple of values ``O O`` matches both. Thus, what is the result of the -function on those values? To eliminate ambiguity we use the *textual -priority rule:* we consider patterns to be ordered from top to bottom. A -value is matched by the pattern at the ith row if and only if it is -not matched by some pattern from a previous row. Thus in the example, ``O O`` -is matched by the first pattern, and so :g:`(lef O O)` yields true. - -Another way to write this function is: - -.. coqtop:: in reset - - Fixpoint lef (n m:nat) {struct m} : bool := - match n, m with - | O, x => true - | S n, S m => lef n m - | _, _ => false - end. - -Here the last pattern superposes with the first two. Because of the -priority rule, the last pattern will be used only for values that do -not match neither the first nor the second one. - -Terms with useless patterns are not accepted by the system. Here is an -example: - -.. coqtop:: all - - Fail Check (fun x:nat => - match x with - | O => true - | S _ => false - | x => true - end). - - -Disjunctive patterns --------------------- - -Multiple patterns that share the same right-hand-side can be -factorized using the notation :n:`{+| {+, @pattern } }`. For -instance, :g:`max` can be rewritten as follows: - -.. coqtop:: in reset - - Fixpoint max (n m:nat) {struct m} : nat := - match n, m with - | S n', S m' => S (max n' m') - | 0, p | p, 0 => p - end. - -Similarly, factorization of (not necessarily multiple) patterns that -share the same variables is possible by using the notation :n:`{+| @pattern}`. -Here is an example: - -.. coqtop:: in - - Definition filter_2_4 (n:nat) : nat := - match n with - | 2 as m | 4 as m => m - | _ => 0 - end. - - -Nested disjunctive patterns are allowed, inside parentheses, with the -notation :n:`({+| @pattern})`, as in: - -.. coqtop:: in - - Definition filter_some_square_corners (p:nat*nat) : nat*nat := - match p with - | ((2 as m | 4 as m), (3 as n | 5 as n)) => (m,n) - | _ => (0,0) - end. - -About patterns of parametric types ----------------------------------- - -Parameters in patterns -~~~~~~~~~~~~~~~~~~~~~~ - -When matching objects of a parametric type, parameters do not bind in -patterns. They must be substituted by “``_``”. Consider for example the -type of polymorphic lists: - -.. coqtop:: in - - Inductive List (A:Set) : Set := - | nil : List A - | cons : A -> List A -> List A. - -We can check the function *tail*: - -.. coqtop:: all - - Check - (fun l:List nat => - match l with - | nil _ => nil nat - | cons _ _ l' => l' - end). - -When we use parameters in patterns there is an error message: - -.. coqtop:: all - - Fail Check - (fun l:List nat => - match l with - | nil A => nil nat - | cons A _ l' => l' - end). - -.. flag:: Asymmetric Patterns - - This flag (off by default) removes parameters from constructors in patterns: - -.. coqtop:: all - - Set Asymmetric Patterns. - Check (fun l:List nat => - match l with - | nil => nil _ - | cons _ l' => l' - end). - Unset Asymmetric Patterns. - -Implicit arguments in patterns ------------------------------- - -By default, implicit arguments are omitted in patterns. So we write: - -.. coqtop:: all - - Arguments nil {A}. - Arguments cons [A] _ _. - Check - (fun l:List nat => - match l with - | nil => nil - | cons _ l' => l' - end). - -But the possibility to use all the arguments is given by “``@``” implicit -explicitations (as for terms, see :ref:`explicit-applications`). - -.. coqtop:: all - - Check - (fun l:List nat => - match l with - | @nil _ => @nil nat - | @cons _ _ l' => l' - end). - - -.. _matching-dependent: - -Matching objects of dependent types ------------------------------------ - -The previous examples illustrate pattern matching on objects of non- -dependent types, but we can also use the expansion strategy to -destructure objects of dependent types. Consider the type :g:`listn` of -lists of a certain length: - -.. coqtop:: in reset - - Inductive listn : nat -> Set := - | niln : listn 0 - | consn : forall n:nat, nat -> listn n -> listn (S n). - - -Understanding dependencies in patterns --------------------------------------- - -We can define the function length over :g:`listn` by: - -.. coqdoc:: - - Definition length (n:nat) (l:listn n) := n. - -Just for illustrating pattern matching, we can define it by case -analysis: - -.. coqtop:: in - - Definition length (n:nat) (l:listn n) := - match l with - | niln => 0 - | consn n _ _ => S n - end. - -We can understand the meaning of this definition using the same -notions of usual pattern matching. - - -When the elimination predicate must be provided ------------------------------------------------ - -Dependent pattern matching -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The examples given so far do not need an explicit elimination -predicate because all the |rhs| have the same type and Coq -succeeds to synthesize it. Unfortunately when dealing with dependent -patterns it often happens that we need to write cases where the types -of the |rhs| are different instances of the elimination predicate. The -function :g:`concat` for :g:`listn` is an example where the branches have -different types and we need to provide the elimination predicate: - -.. coqtop:: in - - Fixpoint concat (n:nat) (l:listn n) (m:nat) (l':listn m) {struct l} : - listn (n + m) := - match l in listn n return listn (n + m) with - | niln => l' - | consn n' a y => consn (n' + m) a (concat n' y m l') - end. - -.. coqtop:: none - - Reset concat. - -The elimination predicate is :g:`fun (n:nat) (l:listn n) => listn (n+m)`. -In general if :g:`m` has type :g:`(I q1 … qr t1 … ts)` where :g:`q1, …, qr` -are parameters, the elimination predicate should be of the form :g:`fun y1 … ys x : (I q1 … qr y1 … ys ) => Q`. - -In the concrete syntax, it should be written : -``match m as x in (I _ … _ y1 … ys) return Q with … end``. -The variables which appear in the ``in`` and ``as`` clause are new and bounded -in the property :g:`Q` in the return clause. The parameters of the -inductive definitions should not be mentioned and are replaced by ``_``. - -Multiple dependent pattern matching -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Recall that a list of patterns is also a pattern. So, when we -destructure several terms at the same time and the branches have -different types we need to provide the elimination predicate for this -multiple pattern. It is done using the same scheme: each term may be -associated to an ``as`` clause and an ``in`` clause in order to introduce -a dependent product. - -For example, an equivalent definition for :g:`concat` (even though the -matching on the second term is trivial) would have been: - -.. coqtop:: in - - Fixpoint concat (n:nat) (l:listn n) (m:nat) (l':listn m) {struct l} : - listn (n + m) := - match l in listn n, l' return listn (n + m) with - | niln, x => x - | consn n' a y, x => consn (n' + m) a (concat n' y m x) - end. - -Even without real matching over the second term, this construction can -be used to keep types linked. If :g:`a` and :g:`b` are two :g:`listn` of the same -length, by writing - -.. coqtop:: in - - Check (fun n (a b: listn n) => - match a, b with - | niln, b0 => tt - | consn n' a y, bS => tt - end). - -we have a copy of :g:`b` in type :g:`listn 0` resp. :g:`listn (S n')`. - -.. _match-in-patterns: - -Patterns in ``in`` -~~~~~~~~~~~~~~~~~~ - -If the type of the matched term is more precise than an inductive -applied to variables, arguments of the inductive in the ``in`` branch can -be more complicated patterns than a variable. - -Moreover, constructors whose types do not follow the same pattern will -become impossible branches. In an impossible branch, you can answer -anything but False_rect unit has the advantage to be subterm of -anything. - -To be concrete: the ``tail`` function can be written: - -.. coqtop:: in - - Definition tail n (v: listn (S n)) := - match v in listn (S m) return listn m with - | niln => False_rect unit - | consn n' a y => y - end. - -and :g:`tail n v` will be subterm of :g:`v`. - -Using pattern matching to write proofs --------------------------------------- - -In all the previous examples the elimination predicate does not depend -on the object(s) matched. But it may depend and the typical case is -when we write a proof by induction or a function that yields an object -of a dependent type. An example of a proof written using ``match`` is given -in the description of the tactic :tacn:`refine`. - -For example, we can write the function :g:`buildlist` that given a natural -number :g:`n` builds a list of length :g:`n` containing zeros as follows: - -.. coqtop:: in - - Fixpoint buildlist (n:nat) : listn n := - match n return listn n with - | O => niln - | S n => consn n 0 (buildlist n) - end. - -We can also use multiple patterns. Consider the following definition -of the predicate less-equal :g:`Le`: - -.. coqtop:: in - - Inductive LE : nat -> nat -> Prop := - | LEO : forall n:nat, LE 0 n - | LES : forall n m:nat, LE n m -> LE (S n) (S m). - -We can use multiple patterns to write the proof of the lemma -:g:`forall (n m:nat), (LE n m) \/ (LE m n)`: - -.. coqtop:: in - - Fixpoint dec (n m:nat) {struct n} : LE n m \/ LE m n := - match n, m return LE n m \/ LE m n with - | O, x => or_introl (LE x 0) (LEO x) - | x, O => or_intror (LE x 0) (LEO x) - | S n as n', S m as m' => - match dec n m with - | or_introl h => or_introl (LE m' n') (LES n m h) - | or_intror h => or_intror (LE n' m') (LES m n h) - end - end. - -In the example of :g:`dec`, the first match is dependent while the second -is not. - -The user can also use match in combination with the tactic :tacn:`refine` -to build incomplete proofs beginning with a :g:`match` construction. - - -Pattern-matching on inductive objects involving local definitions ------------------------------------------------------------------ - -If local definitions occur in the type of a constructor, then there -are two ways to match on this constructor. Either the local -definitions are skipped and matching is done only on the true -arguments of the constructors, or the bindings for local definitions -can also be caught in the matching. - -.. example:: - - .. coqtop:: in reset - - Inductive list : nat -> Set := - | nil : list 0 - | cons : forall n:nat, let m := (2 * n) in list m -> list (S (S m)). - - In the next example, the local definition is not caught. - - .. coqtop:: in - - Fixpoint length n (l:list n) {struct l} : nat := - match l with - | nil => 0 - | cons n l0 => S (length (2 * n) l0) - end. - - But in this example, it is. - - .. coqtop:: in - - Fixpoint length' n (l:list n) {struct l} : nat := - match l with - | nil => 0 - | @cons _ m l0 => S (length' m l0) - end. - -.. note:: For a given matching clause, either none of the local - definitions or all of them can be caught. - -.. note:: You can only catch let bindings in mode where you bind all - variables and so you have to use ``@`` syntax. - -.. note:: this feature is incoherent with the fact that parameters - cannot be caught and consequently is somehow hidden. For example, - there is no mention of it in error messages. - -Pattern-matching and coercions ------------------------------- - -If a mismatch occurs between the expected type of a pattern and its -actual type, a coercion made from constructors is sought. If such a -coercion can be found, it is automatically inserted around the -pattern. - -.. example:: - - .. coqtop:: in - - Inductive I : Set := - | C1 : nat -> I - | C2 : I -> I. - - Coercion C1 : nat >-> I. - - .. coqtop:: all - - Check (fun x => match x with - | C2 O => 0 - | _ => 0 - end). - - -When does the expansion strategy fail? --------------------------------------- - -The strategy works very like in ML languages when treating patterns of -non-dependent types. But there are new cases of failure that are due to -the presence of dependencies. - -The error messages of the current implementation may be sometimes -confusing. When the tactic fails because patterns are somehow -incorrect then error messages refer to the initial expression. But the -strategy may succeed to build an expression whose sub-expressions are -well typed when the whole expression is not. In this situation the -message makes reference to the expanded expression. We encourage -users, when they have patterns with the same outer constructor in -different equations, to name the variable patterns in the same -positions with the same name. E.g. to write ``(cons n O x) => e1`` and -``(cons n _ x) => e2`` instead of ``(cons n O x) => e1`` and -``(cons n' _ x') => e2``. This helps to maintain certain name correspondence between the -generated expression and the original. - -Here is a summary of the error messages corresponding to each -situation: - -.. exn:: The constructor @ident expects @num arguments. - - The variable ident is bound several times in pattern termFound a constructor - of inductive type term while a constructor of term is expectedPatterns are - incorrect (because constructors are not applied to the correct number of the - arguments, because they are not linear or they are wrongly typed). - -.. exn:: Non exhaustive pattern matching. - - The pattern matching is not exhaustive. - -.. exn:: The elimination predicate term should be of arity @num (for non \ - dependent case) or @num (for dependent case). - - The elimination predicate provided to match has not the expected arity. - -.. exn:: Unable to infer a match predicate - Either there is a type incompatibility or the problem involves dependencies. - - There is a type mismatch between the different branches. The user should - provide an elimination predicate. diff --git a/doc/sphinx/language/extensions/match.rst b/doc/sphinx/language/extensions/match.rst new file mode 100644 index 0000000000..8ec51e45ba --- /dev/null +++ b/doc/sphinx/language/extensions/match.rst @@ -0,0 +1,617 @@ +.. _extendedpatternmatching: + +Extended pattern matching +========================= + +:Authors: Cristina Cornes and Hugo Herbelin + +This section describes the full form of pattern matching in |Coq| terms. + +.. |rhs| replace:: right hand sides + +Patterns +-------- + +The full syntax of :g:`match` is presented in section :ref:`term`. +Identifiers in patterns are either constructor names or variables. Any +identifier that is not the constructor of an inductive or co-inductive +type is considered to be a variable. A variable name cannot occur more +than once in a given pattern. It is recommended to start variable +names by a lowercase letter. + +If a pattern has the form ``c x`` where ``c`` is a constructor symbol and x +is a linear vector of (distinct) variables, it is called *simple*: it +is the kind of pattern recognized by the basic version of match. On +the opposite, if it is a variable ``x`` or has the form ``c p`` with ``p`` not +only made of variables, the pattern is called *nested*. + +A variable pattern matches any value, and the identifier is bound to +that value. The pattern “``_``” (called “don't care” or “wildcard” symbol) +also matches any value, but does not bind anything. It may occur an +arbitrary number of times in a pattern. Alias patterns written +:n:`(@pattern as @ident)` are also accepted. This pattern matches the +same values as :token:`pattern` does and :token:`ident` is bound to the matched +value. A pattern of the form :n:`@pattern | @pattern` is called disjunctive. A +list of patterns separated with commas is also considered as a pattern +and is called *multiple pattern*. However multiple patterns can only +occur at the root of pattern matching equations. Disjunctions of +*multiple patterns* are allowed though. + +Since extended ``match`` expressions are compiled into the primitive ones, +the expressiveness of the theory remains the same. Once parsing has finished +only simple patterns remain. The original nesting of the ``match`` expressions +is recovered at printing time. An easy way to see the result +of the expansion is to toggle off the nesting performed at printing +(use here :flag:`Printing Matching`), then by printing the term with :cmd:`Print` +if the term is a constant, or using the command :cmd:`Check`. + +The extended ``match`` still accepts an optional *elimination predicate* +given after the keyword ``return``. Given a pattern matching expression, +if all the right-hand-sides of ``=>`` have the same +type, then this type can be sometimes synthesized, and so we can omit +the return part. Otherwise the predicate after return has to be +provided, like for the basicmatch. + +Let us illustrate through examples the different aspects of extended +pattern matching. Consider for example the function that computes the +maximum of two natural numbers. We can write it in primitive syntax +by: + +.. coqtop:: in + + Fixpoint max (n m:nat) {struct m} : nat := + match n with + | O => m + | S n' => match m with + | O => S n' + | S m' => S (max n' m') + end + end. + +Multiple patterns +----------------- + +Using multiple patterns in the definition of ``max`` lets us write: + +.. coqtop:: in reset + + Fixpoint max (n m:nat) {struct m} : nat := + match n, m with + | O, _ => m + | S n', O => S n' + | S n', S m' => S (max n' m') + end. + +which will be compiled into the previous form. + +The pattern matching compilation strategy examines patterns from left +to right. A match expression is generated **only** when there is at least +one constructor in the column of patterns. E.g. the following example +does not build a match expression. + +.. coqtop:: all + + Check (fun x:nat => match x return nat with + | y => y + end). + + +Aliasing subpatterns +-------------------- + +We can also use :n:`as @ident` to associate a name to a sub-pattern: + +.. coqtop:: in reset + + Fixpoint max (n m:nat) {struct n} : nat := + match n, m with + | O, _ => m + | S n' as p, O => p + | S n', S m' => S (max n' m') + end. + +Nested patterns +--------------- + +Here is now an example of nested patterns: + +.. coqtop:: in + + Fixpoint even (n:nat) : bool := + match n with + | O => true + | S O => false + | S (S n') => even n' + end. + +This is compiled into: + +.. coqtop:: all + + Unset Printing Matching. + Print even. + +.. coqtop:: none + + Set Printing Matching. + +In the previous examples patterns do not conflict with, but sometimes +it is comfortable to write patterns that admit a non trivial +superposition. Consider the boolean function :g:`lef` that given two +natural numbers yields :g:`true` if the first one is less or equal than the +second one and :g:`false` otherwise. We can write it as follows: + +.. coqtop:: in + + Fixpoint lef (n m:nat) {struct m} : bool := + match n, m with + | O, x => true + | x, O => false + | S n, S m => lef n m + end. + +Note that the first and the second multiple pattern overlap because +the couple of values ``O O`` matches both. Thus, what is the result of the +function on those values? To eliminate ambiguity we use the *textual +priority rule:* we consider patterns to be ordered from top to bottom. A +value is matched by the pattern at the ith row if and only if it is +not matched by some pattern from a previous row. Thus in the example, ``O O`` +is matched by the first pattern, and so :g:`(lef O O)` yields true. + +Another way to write this function is: + +.. coqtop:: in reset + + Fixpoint lef (n m:nat) {struct m} : bool := + match n, m with + | O, x => true + | S n, S m => lef n m + | _, _ => false + end. + +Here the last pattern superposes with the first two. Because of the +priority rule, the last pattern will be used only for values that do +not match neither the first nor the second one. + +Terms with useless patterns are not accepted by the system. Here is an +example: + +.. coqtop:: all + + Fail Check (fun x:nat => + match x with + | O => true + | S _ => false + | x => true + end). + + +Disjunctive patterns +-------------------- + +Multiple patterns that share the same right-hand-side can be +factorized using the notation :n:`{+| {+, @pattern } }`. For +instance, :g:`max` can be rewritten as follows: + +.. coqtop:: in reset + + Fixpoint max (n m:nat) {struct m} : nat := + match n, m with + | S n', S m' => S (max n' m') + | 0, p | p, 0 => p + end. + +Similarly, factorization of (not necessarily multiple) patterns that +share the same variables is possible by using the notation :n:`{+| @pattern}`. +Here is an example: + +.. coqtop:: in + + Definition filter_2_4 (n:nat) : nat := + match n with + | 2 as m | 4 as m => m + | _ => 0 + end. + + +Nested disjunctive patterns are allowed, inside parentheses, with the +notation :n:`({+| @pattern})`, as in: + +.. coqtop:: in + + Definition filter_some_square_corners (p:nat*nat) : nat*nat := + match p with + | ((2 as m | 4 as m), (3 as n | 5 as n)) => (m,n) + | _ => (0,0) + end. + +About patterns of parametric types +---------------------------------- + +Parameters in patterns +~~~~~~~~~~~~~~~~~~~~~~ + +When matching objects of a parametric type, parameters do not bind in +patterns. They must be substituted by “``_``”. Consider for example the +type of polymorphic lists: + +.. coqtop:: in + + Inductive List (A:Set) : Set := + | nil : List A + | cons : A -> List A -> List A. + +We can check the function *tail*: + +.. coqtop:: all + + Check + (fun l:List nat => + match l with + | nil _ => nil nat + | cons _ _ l' => l' + end). + +When we use parameters in patterns there is an error message: + +.. coqtop:: all + + Fail Check + (fun l:List nat => + match l with + | nil A => nil nat + | cons A _ l' => l' + end). + +.. flag:: Asymmetric Patterns + + This flag (off by default) removes parameters from constructors in patterns: + +.. coqtop:: all + + Set Asymmetric Patterns. + Check (fun l:List nat => + match l with + | nil => nil _ + | cons _ l' => l' + end). + Unset Asymmetric Patterns. + +Implicit arguments in patterns +------------------------------ + +By default, implicit arguments are omitted in patterns. So we write: + +.. coqtop:: all + + Arguments nil {A}. + Arguments cons [A] _ _. + Check + (fun l:List nat => + match l with + | nil => nil + | cons _ l' => l' + end). + +But the possibility to use all the arguments is given by “``@``” implicit +explicitations (as for terms, see :ref:`explicit-applications`). + +.. coqtop:: all + + Check + (fun l:List nat => + match l with + | @nil _ => @nil nat + | @cons _ _ l' => l' + end). + + +.. _matching-dependent: + +Matching objects of dependent types +----------------------------------- + +The previous examples illustrate pattern matching on objects of non- +dependent types, but we can also use the expansion strategy to +destructure objects of dependent types. Consider the type :g:`listn` of +lists of a certain length: + +.. coqtop:: in reset + + Inductive listn : nat -> Set := + | niln : listn 0 + | consn : forall n:nat, nat -> listn n -> listn (S n). + + +Understanding dependencies in patterns +-------------------------------------- + +We can define the function length over :g:`listn` by: + +.. coqdoc:: + + Definition length (n:nat) (l:listn n) := n. + +Just for illustrating pattern matching, we can define it by case +analysis: + +.. coqtop:: in + + Definition length (n:nat) (l:listn n) := + match l with + | niln => 0 + | consn n _ _ => S n + end. + +We can understand the meaning of this definition using the same +notions of usual pattern matching. + + +When the elimination predicate must be provided +----------------------------------------------- + +Dependent pattern matching +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The examples given so far do not need an explicit elimination +predicate because all the |rhs| have the same type and Coq +succeeds to synthesize it. Unfortunately when dealing with dependent +patterns it often happens that we need to write cases where the types +of the |rhs| are different instances of the elimination predicate. The +function :g:`concat` for :g:`listn` is an example where the branches have +different types and we need to provide the elimination predicate: + +.. coqtop:: in + + Fixpoint concat (n:nat) (l:listn n) (m:nat) (l':listn m) {struct l} : + listn (n + m) := + match l in listn n return listn (n + m) with + | niln => l' + | consn n' a y => consn (n' + m) a (concat n' y m l') + end. + +.. coqtop:: none + + Reset concat. + +The elimination predicate is :g:`fun (n:nat) (l:listn n) => listn (n+m)`. +In general if :g:`m` has type :g:`(I q1 … qr t1 … ts)` where :g:`q1, …, qr` +are parameters, the elimination predicate should be of the form :g:`fun y1 … ys x : (I q1 … qr y1 … ys ) => Q`. + +In the concrete syntax, it should be written : +``match m as x in (I _ … _ y1 … ys) return Q with … end``. +The variables which appear in the ``in`` and ``as`` clause are new and bounded +in the property :g:`Q` in the return clause. The parameters of the +inductive definitions should not be mentioned and are replaced by ``_``. + +Multiple dependent pattern matching +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Recall that a list of patterns is also a pattern. So, when we +destructure several terms at the same time and the branches have +different types we need to provide the elimination predicate for this +multiple pattern. It is done using the same scheme: each term may be +associated to an ``as`` clause and an ``in`` clause in order to introduce +a dependent product. + +For example, an equivalent definition for :g:`concat` (even though the +matching on the second term is trivial) would have been: + +.. coqtop:: in + + Fixpoint concat (n:nat) (l:listn n) (m:nat) (l':listn m) {struct l} : + listn (n + m) := + match l in listn n, l' return listn (n + m) with + | niln, x => x + | consn n' a y, x => consn (n' + m) a (concat n' y m x) + end. + +Even without real matching over the second term, this construction can +be used to keep types linked. If :g:`a` and :g:`b` are two :g:`listn` of the same +length, by writing + +.. coqtop:: in + + Check (fun n (a b: listn n) => + match a, b with + | niln, b0 => tt + | consn n' a y, bS => tt + end). + +we have a copy of :g:`b` in type :g:`listn 0` resp. :g:`listn (S n')`. + +.. _match-in-patterns: + +Patterns in ``in`` +~~~~~~~~~~~~~~~~~~ + +If the type of the matched term is more precise than an inductive +applied to variables, arguments of the inductive in the ``in`` branch can +be more complicated patterns than a variable. + +Moreover, constructors whose types do not follow the same pattern will +become impossible branches. In an impossible branch, you can answer +anything but False_rect unit has the advantage to be subterm of +anything. + +To be concrete: the ``tail`` function can be written: + +.. coqtop:: in + + Definition tail n (v: listn (S n)) := + match v in listn (S m) return listn m with + | niln => False_rect unit + | consn n' a y => y + end. + +and :g:`tail n v` will be subterm of :g:`v`. + +Using pattern matching to write proofs +-------------------------------------- + +In all the previous examples the elimination predicate does not depend +on the object(s) matched. But it may depend and the typical case is +when we write a proof by induction or a function that yields an object +of a dependent type. An example of a proof written using ``match`` is given +in the description of the tactic :tacn:`refine`. + +For example, we can write the function :g:`buildlist` that given a natural +number :g:`n` builds a list of length :g:`n` containing zeros as follows: + +.. coqtop:: in + + Fixpoint buildlist (n:nat) : listn n := + match n return listn n with + | O => niln + | S n => consn n 0 (buildlist n) + end. + +We can also use multiple patterns. Consider the following definition +of the predicate less-equal :g:`Le`: + +.. coqtop:: in + + Inductive LE : nat -> nat -> Prop := + | LEO : forall n:nat, LE 0 n + | LES : forall n m:nat, LE n m -> LE (S n) (S m). + +We can use multiple patterns to write the proof of the lemma +:g:`forall (n m:nat), (LE n m) \/ (LE m n)`: + +.. coqtop:: in + + Fixpoint dec (n m:nat) {struct n} : LE n m \/ LE m n := + match n, m return LE n m \/ LE m n with + | O, x => or_introl (LE x 0) (LEO x) + | x, O => or_intror (LE x 0) (LEO x) + | S n as n', S m as m' => + match dec n m with + | or_introl h => or_introl (LE m' n') (LES n m h) + | or_intror h => or_intror (LE n' m') (LES m n h) + end + end. + +In the example of :g:`dec`, the first match is dependent while the second +is not. + +The user can also use match in combination with the tactic :tacn:`refine` +to build incomplete proofs beginning with a :g:`match` construction. + + +Pattern-matching on inductive objects involving local definitions +----------------------------------------------------------------- + +If local definitions occur in the type of a constructor, then there +are two ways to match on this constructor. Either the local +definitions are skipped and matching is done only on the true +arguments of the constructors, or the bindings for local definitions +can also be caught in the matching. + +.. example:: + + .. coqtop:: in reset + + Inductive list : nat -> Set := + | nil : list 0 + | cons : forall n:nat, let m := (2 * n) in list m -> list (S (S m)). + + In the next example, the local definition is not caught. + + .. coqtop:: in + + Fixpoint length n (l:list n) {struct l} : nat := + match l with + | nil => 0 + | cons n l0 => S (length (2 * n) l0) + end. + + But in this example, it is. + + .. coqtop:: in + + Fixpoint length' n (l:list n) {struct l} : nat := + match l with + | nil => 0 + | @cons _ m l0 => S (length' m l0) + end. + +.. note:: For a given matching clause, either none of the local + definitions or all of them can be caught. + +.. note:: You can only catch let bindings in mode where you bind all + variables and so you have to use ``@`` syntax. + +.. note:: this feature is incoherent with the fact that parameters + cannot be caught and consequently is somehow hidden. For example, + there is no mention of it in error messages. + +Pattern-matching and coercions +------------------------------ + +If a mismatch occurs between the expected type of a pattern and its +actual type, a coercion made from constructors is sought. If such a +coercion can be found, it is automatically inserted around the +pattern. + +.. example:: + + .. coqtop:: in + + Inductive I : Set := + | C1 : nat -> I + | C2 : I -> I. + + Coercion C1 : nat >-> I. + + .. coqtop:: all + + Check (fun x => match x with + | C2 O => 0 + | _ => 0 + end). + + +When does the expansion strategy fail? +-------------------------------------- + +The strategy works very like in ML languages when treating patterns of +non-dependent types. But there are new cases of failure that are due to +the presence of dependencies. + +The error messages of the current implementation may be sometimes +confusing. When the tactic fails because patterns are somehow +incorrect then error messages refer to the initial expression. But the +strategy may succeed to build an expression whose sub-expressions are +well typed when the whole expression is not. In this situation the +message makes reference to the expanded expression. We encourage +users, when they have patterns with the same outer constructor in +different equations, to name the variable patterns in the same +positions with the same name. E.g. to write ``(cons n O x) => e1`` and +``(cons n _ x) => e2`` instead of ``(cons n O x) => e1`` and +``(cons n' _ x') => e2``. This helps to maintain certain name correspondence between the +generated expression and the original. + +Here is a summary of the error messages corresponding to each +situation: + +.. exn:: The constructor @ident expects @num arguments. + + The variable ident is bound several times in pattern termFound a constructor + of inductive type term while a constructor of term is expectedPatterns are + incorrect (because constructors are not applied to the correct number of the + arguments, because they are not linear or they are wrongly typed). + +.. exn:: Non exhaustive pattern matching. + + The pattern matching is not exhaustive. + +.. exn:: The elimination predicate term should be of arity @num (for non \ + dependent case) or @num (for dependent case). + + The elimination predicate provided to match has not the expected arity. + +.. exn:: Unable to infer a match predicate + Either there is a type incompatibility or the problem involves dependencies. + + There is a type mismatch between the different branches. The user should + provide an elimination predicate. -- cgit v1.2.3