%% Generated by Sphinx.
\def\sphinxdocclass{report}
\documentclass[letterpaper,10pt,openany,english]{sphinxmanual}
\ifdefined\pdfpxdimen
   \let\sphinxpxdimen\pdfpxdimen\else\newdimen\sphinxpxdimen
\fi \sphinxpxdimen=.75bp\relax
%% turn off hyperref patch of \index as sphinx.xdy xindy module takes care of
%% suitable \hyperpage mark-up, working around hyperref-xindy incompatibility
\PassOptionsToPackage{hyperindex=false}{hyperref}

\PassOptionsToPackage{warn}{textcomp}




\usepackage{amsmath,amssymb,amstext}
\usepackage{polyglossia}
\setmainlanguage{english}

\usepackage[Bjarne]{fncychap}
\usepackage{sphinx}
\sphinxsetup{verbatimwithframe=false}
\fvset{fontsize=auto}
\usepackage{geometry}

% Include hyperref last.
\usepackage{hyperref}
% Fix anchor placement for figures with captions.
\usepackage{hypcap}% it must be loaded after hyperref.
% Set up styles of URL: it should be placed after hyperref.
\urlstyle{same}

\addto\captionsenglish{\renewcommand{\figurename}{Fig.}}
\addto\captionsenglish{\renewcommand{\tablename}{Table}}
\addto\captionsenglish{\renewcommand{\literalblockname}{Listing}}

\addto\captionsenglish{\renewcommand{\literalblockcontinuedname}{continued from previous page}}
\addto\captionsenglish{\renewcommand{\literalblockcontinuesname}{continues on next page}}
\addto\captionsenglish{\renewcommand{\sphinxnonalphabeticalgroupname}{Non-alphabetical}}
\addto\captionsenglish{\renewcommand{\sphinxsymbolsname}{Symbols}}
\addto\captionsenglish{\renewcommand{\sphinxnumbersname}{Numbers}}

\def\pageautorefname{page}




                 \usepackage{unicode-math}
                 \usepackage{microtype}

                 % Macro definitions
                 \usepackage{refman-preamble}

                 % Style definitions for notations
                 \usepackage{coqnotations}

                 % Style tweaks
                 \newcssclass{sigannot}{\textrm{#1:}}

                 % Silence 'LaTeX Warning: Command \nobreakspace invalid in math mode'
                 \everymath{\def\nobreakspace{\ }}
                 

\title{The Coq Reference Manual}
\date{Oct 01, 2018}
\release{8.8.2}
\author{The Coq Development Team}
\newcommand{\sphinxlogo}{\vbox{}}
\renewcommand{\releasename}{Release}
\makeindex
\begin{document}

\maketitle
\sphinxtableofcontents
\phantomsection\label{\detokenize{index::doc}}



\chapter{Introduction}
\label{\detokenize{index:introduction}}
This document is the Reference Manual of the \DUrole{smallcaps}{Coq} proof assistant.
To start using Coq, it is advised to first read a tutorial.
Links to several tutorials can be found at
\sphinxurl{https://coq.inria.fr/documentation} and
\sphinxurl{https://github.com/coq/coq/wiki\#coq-tutorials}

The \DUrole{smallcaps}{Coq} system is designed to develop mathematical proofs, and
especially to write formal specifications, programs and to verify that
programs are correct with respect to their specifications. It provides a
specification language named \DUrole{smallcaps}{Gallina}. Terms of \DUrole{smallcaps}{Gallina} can represent
programs as well as properties of these programs and proofs of these
properties. Using the so-called \sphinxstyleemphasis{Curry-Howard isomorphism}, programs,
properties and proofs are formalized in the same language called
\sphinxstyleemphasis{Calculus of Inductive Constructions}, that is a
\(\lambda\)-calculus with a rich type system. All logical judgments
in \DUrole{smallcaps}{Coq} are typing judgments. The very heart of the \DUrole{smallcaps}{Coq} system is the
type checking algorithm that checks the correctness of proofs, in other
words that checks that a program complies to its specification. \DUrole{smallcaps}{Coq} also
provides an interactive proof assistant to build proofs using specific
programs called \sphinxstyleemphasis{tactics}.

All services of the \DUrole{smallcaps}{Coq} proof assistant are accessible by interpretation
of a command language called \sphinxstyleemphasis{the vernacular}.

Coq has an interactive mode in which commands are interpreted as the
user types them in from the keyboard and a compiled mode where commands
are processed from a file.
\begin{itemize}
\item {} 
In interactive mode, users can develop their theories and proofs step by
step, and query the system for available theorems and definitions. The
interactive mode is generally run with the help of an IDE, such
as CoqIDE, documented in {\hyperref[\detokenize{practical-tools/coqide:coqintegrateddevelopmentenvironment}]{\sphinxcrossref{\DUrole{std,std-ref}{Coq Integrated Development Environment}}}},
Emacs with Proof-General \sphinxcite{zebibliography:asp00} %
\begin{footnote}[5]\sphinxAtStartFootnote
Proof-General is available at \sphinxurl{https://proofgeneral.github.io/}.
Optionally, you can enhance it with the minor mode
Company-Coq \sphinxcite{zebibliography:pit16}
(see \sphinxurl{https://github.com/cpitclaudel/company-coq}).
%
\end{footnote},
or jsCoq to run Coq in your browser (see \sphinxurl{https://github.com/ejgallego/jscoq}).
The \sphinxtitleref{coqtop} read-eval-print-loop can also be used directly, for debugging
purposes.

\item {} 
The compiled mode acts as a proof checker taking a file containing a
whole development in order to ensure its correctness. Moreover,
\DUrole{smallcaps}{Coq}’s compiler provides an output file containing a compact
representation of its input. The compiled mode is run with the \sphinxtitleref{coqc}
command.

\end{itemize}


\sphinxstrong{See also:}


{\hyperref[\detokenize{practical-tools/coq-commands:thecoqcommands}]{\sphinxcrossref{\DUrole{std,std-ref}{The Coq commands}}}}.




\section{How to read this book}
\label{\detokenize{index:how-to-read-this-book}}
This is a Reference Manual, so it is not intended for continuous reading.
We recommend using the various indexes to quickly locate the documentation
you are looking for. There is a global index, and a number of specific indexes
for tactics, vernacular commands, and error messages and warnings.
Nonetheless, the manual has some structure that is explained below.
\begin{itemize}
\item {} 
The first part describes the specification language, \DUrole{smallcaps}{Gallina}.
Chapters {\hyperref[\detokenize{language/gallina-specification-language:gallinaspecificationlanguage}]{\sphinxcrossref{\DUrole{std,std-ref}{The Gallina specification language}}}} and {\hyperref[\detokenize{language/gallina-extensions:extensionsofgallina}]{\sphinxcrossref{\DUrole{std,std-ref}{Extensions of Gallina}}}} describe the concrete
syntax as well as the meaning of programs, theorems and proofs in the
Calculus of Inductive Constructions. Chapter {\hyperref[\detokenize{language/coq-library:thecoqlibrary}]{\sphinxcrossref{\DUrole{std,std-ref}{The Coq library}}}} describes the
standard library of \DUrole{smallcaps}{Coq}. Chapter {\hyperref[\detokenize{language/cic:calculusofinductiveconstructions}]{\sphinxcrossref{\DUrole{std,std-ref}{Calculus of Inductive Constructions}}}} is a mathematical description
of the formalism. Chapter {\hyperref[\detokenize{language/module-system:themodulesystem}]{\sphinxcrossref{\DUrole{std,std-ref}{The Module System}}}} describes the module
system.

\item {} 
The second part describes the proof engine. It is divided in six
chapters. Chapter {\hyperref[\detokenize{proof-engine/vernacular-commands:vernacularcommands}]{\sphinxcrossref{\DUrole{std,std-ref}{Vernacular commands}}}} presents all commands (we
call them \sphinxstyleemphasis{vernacular commands}) that are not directly related to
interactive proving: requests to the environment, complete or partial
evaluation, loading and compiling files. How to start and stop
proofs, do multiple proofs in parallel is explained in
Chapter {\hyperref[\detokenize{proof-engine/proof-handling:proofhandling}]{\sphinxcrossref{\DUrole{std,std-ref}{Proof handling}}}}. In Chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}}, all commands that
realize one or more steps of the proof are presented: we call them
\sphinxstyleemphasis{tactics}. The language to combine these tactics into complex proof
strategies is given in Chapter {\hyperref[\detokenize{proof-engine/ltac:ltac}]{\sphinxcrossref{\DUrole{std,std-ref}{The tactic language}}}}. Examples of tactics
are described in Chapter {\hyperref[\detokenize{proof-engine/detailed-tactic-examples:detailedexamplesoftactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Detailed examples of tactics}}}}.
Finally, the \DUrole{smallcaps}{SSReflect} proof language is presented in
Chapter {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:thessreflectprooflanguage}]{\sphinxcrossref{\DUrole{std,std-ref}{The SSReflect proof language}}}}.

\item {} 
The third part describes how to extend the syntax of \DUrole{smallcaps}{Coq} in
Chapter {\hyperref[\detokenize{user-extensions/syntax-extensions:syntaxextensionsandinterpretationscopes}]{\sphinxcrossref{\DUrole{std,std-ref}{Syntax extensions and interpretation scopes}}}} and how to define
new induction principles in Chapter {\hyperref[\detokenize{user-extensions/proof-schemes:proofschemes}]{\sphinxcrossref{\DUrole{std,std-ref}{Proof schemes}}}}.

\item {} 
In the fourth part more practical tools are documented. First in
Chapter {\hyperref[\detokenize{practical-tools/coq-commands:thecoqcommands}]{\sphinxcrossref{\DUrole{std,std-ref}{The Coq commands}}}}, the usage of \sphinxtitleref{coqc} (batch mode) and
\sphinxtitleref{coqtop} (interactive mode) with their options is described. Then,
in Chapter {\hyperref[\detokenize{practical-tools/utilities:utilities}]{\sphinxcrossref{\DUrole{std,std-ref}{Utilities}}}}, various utilities that come with the
\DUrole{smallcaps}{Coq} distribution are presented. Finally, Chapter {\hyperref[\detokenize{practical-tools/coqide:coqintegrateddevelopmentenvironment}]{\sphinxcrossref{\DUrole{std,std-ref}{Coq Integrated Development Environment}}}}
describes CoqIDE.

\item {} 
The fifth part documents a number of advanced features, including coercions,
canonical structures, typeclasses, program extraction, and specialized
solvers and tactics. See the table of contents for a complete list.

\end{itemize}


\section{List of additional documentation}
\label{\detokenize{index:list-of-additional-documentation}}
This manual does not contain all the documentation the user may need
about \DUrole{smallcaps}{Coq}. Various informations can be found in the following documents:
\begin{description}
\item[{Tutorial}] \leavevmode
A companion volume to this reference manual, the \DUrole{smallcaps}{Coq} Tutorial, is
aimed at gently introducing new users to developing proofs in \DUrole{smallcaps}{Coq}
without assuming prior knowledge of type theory. In a second step,
the user can read also the tutorial on recursive types (document
\sphinxtitleref{RecTutorial.ps}).

\item[{Installation}] \leavevmode
A text file \sphinxtitleref{INSTALL} that comes with the sources explains how to
install \DUrole{smallcaps}{Coq}.

\item[{The \DUrole{smallcaps}{Coq} standard library}] \leavevmode
A commented version of sources of the \DUrole{smallcaps}{Coq} standard library
(including only the specifications, the proofs are removed) is
available at \sphinxurl{https://coq.inria.fr/stdlib/}.

\end{description}


\chapter{Credits}
\label{\detokenize{index:credits}}\phantomsection\label{\detokenize{index:id4}}
Coq is a proof assistant for higher-order logic, allowing the
development of computer programs consistent with their formal
specification. It is the result of about ten years of research of the
Coq project. We shall briefly survey here three main aspects: the
\sphinxstyleemphasis{logical language} in which we write our axiomatizations and
specifications, the \sphinxstyleemphasis{proof assistant} which allows the development of
verified mathematical proofs, and the \sphinxstyleemphasis{program extractor} which
synthesizes computer programs obeying their formal specifications,
written as logical assertions in the language.

The logical language used by \DUrole{smallcaps}{Coq} is a variety of type theory, called the
\sphinxstyleemphasis{Calculus of Inductive Constructions}. Without going back to Leibniz and
Boole, we can date the creation of what is now called mathematical logic
to the work of Frege and Peano at the turn of the century. The discovery
of antinomies in the free use of predicates or comprehension principles
prompted Russell to restrict predicate calculus with a stratification of
\sphinxstyleemphasis{types}. This effort culminated with \sphinxstyleemphasis{Principia Mathematica}, the first
systematic attempt at a formal foundation of mathematics. A
simplification of this system along the lines of simply typed
\(\lambda\)-calculus occurred with Church’s \sphinxstyleemphasis{Simple Theory of
Types}. The \(\lambda\)-calculus notation, originally used for
expressing functionality, could also be used as an encoding of natural
deduction proofs. This Curry-Howard isomorphism was used by N. de Bruijn
in the \sphinxstyleemphasis{Automath} project, the first full-scale attempt to develop and
mechanically verify mathematical proofs. This effort culminated with
Jutting’s verification of Landau’s \sphinxstyleemphasis{Grundlagen} in the 1970’s.
Exploiting this Curry-Howard isomorphism, notable achievements in proof
theory saw the emergence of two type-theoretic frameworks; the first
one, Martin-Löf’s \sphinxstyleemphasis{Intuitionistic Theory of Types}, attempts a new
foundation of mathematics on constructive principles. The second one,
Girard’s polymorphic \(\lambda\)-calculus \(F_\omega\), is a
very strong functional system in which we may represent higher-order
logic proof structures. Combining both systems in a higher-order
extension of the Automath language, T. Coquand presented in 1985 the
first version of the \sphinxstyleemphasis{Calculus of Constructions}, CoC. This strong
logical system allowed powerful axiomatizations, but direct inductive
definitions were not possible, and inductive notions had to be defined
indirectly through functional encodings, which introduced inefficiencies
and awkwardness. The formalism was extended in 1989 by T. Coquand and C.
Paulin with primitive inductive definitions, leading to the current
\sphinxstyleemphasis{Calculus of Inductive Constructions}. This extended formalism is not
rigorously defined here. Rather, numerous concrete examples are
discussed. We refer the interested reader to relevant research papers
for more information about the formalism, its meta-theoretic properties,
and semantics. However, it should not be necessary to understand this
theoretical material in order to write specifications. It is possible to
understand the Calculus of Inductive Constructions at a higher level, as
a mixture of predicate calculus, inductive predicate definitions
presented as typed PROLOG, and recursive function definitions close to
the language ML.

Automated theorem-proving was pioneered in the 1960’s by Davis and
Putnam in propositional calculus. A complete mechanization (in the sense
of a semidecision procedure) of classical first-order logic was
proposed in 1965 by J.A. Robinson, with a single uniform inference rule
called \sphinxstyleemphasis{resolution}. Resolution relies on solving equations in free
algebras (i.e. term structures), using the \sphinxstyleemphasis{unification algorithm}. Many
refinements of resolution were studied in the 1970’s, but few convincing
implementations were realized, except of course that PROLOG is in some
sense issued from this effort. A less ambitious approach to proof
development is computer-aided proof-checking. The most notable
proof-checkers developed in the 1970’s were LCF, designed by R. Milner
and his colleagues at U. Edinburgh, specialized in proving properties
about denotational semantics recursion equations, and the Boyer and
Moore theorem-prover, an automation of primitive recursion over
inductive data types. While the Boyer-Moore theorem-prover attempted to
synthesize proofs by a combination of automated methods, LCF constructed
its proofs through the programming of \sphinxstyleemphasis{tactics}, written in a high-level
functional meta-language, ML.

The salient feature which clearly distinguishes our proof assistant from
say LCF or Boyer and Moore’s, is its possibility to extract programs
from the constructive contents of proofs. This computational
interpretation of proof objects, in the tradition of Bishop’s
constructive mathematics, is based on a realizability interpretation, in
the sense of Kleene, due to C. Paulin. The user must just mark his
intention by separating in the logical statements the assertions stating
the existence of a computational object from the logical assertions
which specify its properties, but which may be considered as just
comments in the corresponding program. Given this information, the
system automatically extracts a functional term from a consistency proof
of its specifications. This functional term may be in turn compiled into
an actual computer program. This methodology of extracting programs from
proofs is a revolutionary paradigm for software engineering. Program
synthesis has long been a theme of research in artificial intelligence,
pioneered by R. Waldinger. The Tablog system of Z. Manna and R.
Waldinger allows the deductive synthesis of functional programs from
proofs in tableau form of their specifications, written in a variety of
first-order logic. Development of a systematic \sphinxstyleemphasis{programming logic},
based on extensions of Martin-Löf’s type theory, was undertaken at
Cornell U. by the Nuprl team, headed by R. Constable. The first actual
program extractor, PX, was designed and implemented around 1985 by S.
Hayashi from Kyoto University. It allows the extraction of a LISP
program from a proof in a logical system inspired by the logical
formalisms of S. Feferman. Interest in this methodology is growing in
the theoretical computer science community. We can foresee the day when
actual computer systems used in applications will contain certified
modules, automatically generated from a consistency proof of their
formal specifications. We are however still far from being able to use
this methodology in a smooth interaction with the standard tools from
software engineering, i.e. compilers, linkers, run-time systems taking
advantage of special hardware, debuggers, and the like. We hope that \DUrole{smallcaps}{Coq}
can be of use to researchers interested in experimenting with this new
methodology.

A first implementation of CoC was started in 1984 by G. Huet and T.
Coquand. Its implementation language was CAML, a functional programming
language from the ML family designed at INRIA in Rocquencourt. The core
of this system was a proof-checker for CoC seen as a typed
\(\lambda\)-calculus, called the \sphinxstyleemphasis{Constructive Engine}. This engine
was operated through a high-level notation permitting the declaration of
axioms and parameters, the definition of mathematical types and objects,
and the explicit construction of proof objects encoded as
\(\lambda\)-terms. A section mechanism, designed and implemented by
G. Dowek, allowed hierarchical developments of mathematical theories.
This high-level language was called the \sphinxstyleemphasis{Mathematical Vernacular}.
Furthermore, an interactive \sphinxstyleemphasis{Theorem Prover} permitted the incremental
construction of proof trees in a top-down manner, subgoaling recursively
and backtracking from dead-alleys. The theorem prover executed tactics
written in CAML, in the LCF fashion. A basic set of tactics was
predefined, which the user could extend by his own specific tactics.
This system (Version 4.10) was released in 1989. Then, the system was
extended to deal with the new calculus with inductive types by C.
Paulin, with corresponding new tactics for proofs by induction. A new
standard set of tactics was streamlined, and the vernacular extended for
tactics execution. A package to compile programs extracted from proofs
to actual computer programs in CAML or some other functional language
was designed and implemented by B. Werner. A new user-interface, relying
on a CAML-X interface by D. de Rauglaudre, was designed and implemented
by A. Felty. It allowed operation of the theorem-prover through the
manipulation of windows, menus, mouse-sensitive buttons, and other
widgets. This system (Version 5.6) was released in 1991.

Coq was ported to the new implementation Caml-light of X. Leroy and D.
Doligez by D. de Rauglaudre (Version 5.7) in 1992. A new version of \DUrole{smallcaps}{Coq}
was then coordinated by C. Murthy, with new tools designed by C. Parent
to prove properties of ML programs (this methodology is dual to program
extraction) and a new user-interaction loop. This system (Version 5.8)
was released in May 1993. A Centaur interface CTCoq was then developed
by Y. Bertot from the Croap project from INRIA-Sophia-Antipolis.

In parallel, G. Dowek and H. Herbelin developed a new proof engine,
allowing the general manipulation of existential variables consistently
with dependent types in an experimental version of \DUrole{smallcaps}{Coq} (V5.9).

The version V5.10 of \DUrole{smallcaps}{Coq} is based on a generic system for manipulating
terms with binding operators due to Chet Murthy. A new proof engine
allows the parallel development of partial proofs for independent
subgoals. The structure of these proof trees is a mixed representation
of derivation trees for the Calculus of Inductive Constructions with
abstract syntax trees for the tactics scripts, allowing the navigation
in a proof at various levels of details. The proof engine allows generic
environment items managed in an object-oriented way. This new
architecture, due to C. Murthy, supports several new facilities which
make the system easier to extend and to scale up:
\begin{itemize}
\item {} 
User-programmable tactics are allowed

\item {} 
It is possible to separately verify development modules, and to load
their compiled images without verifying them again - a quick
relocation process allows their fast loading

\item {} 
A generic parsing scheme allows user-definable notations, with a
symmetric table-driven pretty-printer

\item {} 
Syntactic definitions allow convenient abbreviations

\item {} 
A limited facility of meta-variables allows the automatic synthesis
of certain type expressions, allowing generic notations for e.g.
equality, pairing, and existential quantification.

\end{itemize}

In the Fall of 1994, C. Paulin-Mohring replaced the structure of
inductively defined types and families by a new structure, allowing the
mutually recursive definitions. P. Manoury implemented a translation of
recursive definitions into the primitive recursive style imposed by the
internal recursion operators, in the style of the ProPre system. C.
Muñoz implemented a decision procedure for intuitionistic propositional
logic, based on results of R. Dyckhoff. J.C. Filliâtre implemented a
decision procedure for first-order logic without contraction, based on
results of J. Ketonen and R. Weyhrauch. Finally C. Murthy implemented a
library of inversion tactics, relieving the user from tedious
definitions of “inversion predicates”.

\begin{DUlineblock}{0em}
\item[] Rocquencourt, Feb. 1st 1995
\item[] Gérard Huet
\item[] 
\end{DUlineblock}


\section{Credits: addendum for version 6.1}
\label{\detokenize{index:credits-addendum-for-version-6-1}}
The present version 6.1 of \DUrole{smallcaps}{Coq} is based on the V5.10 architecture. It
was ported to the new language Objective Caml by Bruno Barras. The
underlying framework has slightly changed and allows more conversions
between sorts.

The new version provides powerful tools for easier developments.

Cristina Cornes designed an extension of the \DUrole{smallcaps}{Coq} syntax to allow
definition of terms using a powerful pattern matching analysis in the
style of ML programs.

Amokrane Saïbi wrote a mechanism to simulate inheritance between types
families extending a proposal by Peter Aczel. He also developed a
mechanism to automatically compute which arguments of a constant may be
inferred by the system and consequently do not need to be explicitly
written.

Yann Coscoy designed a command which explains a proof term using natural
language. Pierre Crégut built a new tactic which solves problems in
quantifier-free Presburger Arithmetic. Both functionalities have been
integrated to the \DUrole{smallcaps}{Coq} system by Hugo Herbelin.

Samuel Boutin designed a tactic for simplification of commutative rings
using a canonical set of rewriting rules and equality modulo
associativity and commutativity.

Finally the organisation of the \DUrole{smallcaps}{Coq} distribution has been supervised by
Jean-Christophe Filliâtre with the help of Judicaël Courant and Bruno
Barras.

\begin{DUlineblock}{0em}
\item[] Lyon, Nov. 18th 1996
\item[] Christine Paulin
\item[] 
\end{DUlineblock}


\section{Credits: addendum for version 6.2}
\label{\detokenize{index:credits-addendum-for-version-6-2}}
In version 6.2 of \DUrole{smallcaps}{Coq}, the parsing is done using camlp4, a preprocessor
and pretty-printer for CAML designed by Daniel de Rauglaudre at INRIA.
Daniel de Rauglaudre made the first adaptation of \DUrole{smallcaps}{Coq} for camlp4, this
work was continued by Bruno Barras who also changed the structure of \DUrole{smallcaps}{Coq}
abstract syntax trees and the primitives to manipulate them. The result
of these changes is a faster parsing procedure with greatly improved
syntax-error messages. The user-interface to introduce grammar or
pretty-printing rules has also changed.

Eduardo Giménez redesigned the internal tactic libraries, giving uniform
names to Caml functions corresponding to \DUrole{smallcaps}{Coq} tactic names.

Bruno Barras wrote new, more efficient reduction functions.

Hugo Herbelin introduced more uniform notations in the \DUrole{smallcaps}{Coq} specification
language: the definitions by fixpoints and pattern matching have a more
readable syntax. Patrick Loiseleur introduced user-friendly notations
for arithmetic expressions.

New tactics were introduced: Eduardo Giménez improved the mechanism to
introduce macros for tactics, and designed special tactics for
(co)inductive definitions; Patrick Loiseleur designed a tactic to
simplify polynomial expressions in an arbitrary commutative ring which
generalizes the previous tactic implemented by Samuel Boutin.
Jean-Christophe Filliâtre introduced a tactic for refining a goal, using
a proof term with holes as a proof scheme.

David Delahaye designed the tool to search an object in the library
given its type (up to isomorphism).

Henri Laulhère produced the \DUrole{smallcaps}{Coq} distribution for the Windows
environment.

Finally, Hugo Herbelin was the main coordinator of the \DUrole{smallcaps}{Coq} documentation
with principal contributions by Bruno Barras, David Delahaye,
Jean-Christophe Filliâtre, Eduardo Giménez, Hugo Herbelin and Patrick
Loiseleur.

\begin{DUlineblock}{0em}
\item[] Orsay, May 4th 1998
\item[] Christine Paulin
\item[] 
\end{DUlineblock}


\section{Credits: addendum for version 6.3}
\label{\detokenize{index:credits-addendum-for-version-6-3}}
The main changes in version V6.3 were the introduction of a few new
tactics and the extension of the guard condition for fixpoint
definitions.

B. Barras extended the unification algorithm to complete partial terms
and fixed various tricky bugs related to universes.

D. Delahaye developed the \sphinxcode{\sphinxupquote{AutoRewrite}} tactic. He also designed the
new behavior of \sphinxcode{\sphinxupquote{Intro}} and provided the tacticals \sphinxcode{\sphinxupquote{First}} and
\sphinxcode{\sphinxupquote{Solve}}.

J.-C. Filliâtre developed the \sphinxcode{\sphinxupquote{Correctness}} tactic.

E. Giménez extended the guard condition in fixpoints.

H. Herbelin designed the new syntax for definitions and extended the
\sphinxcode{\sphinxupquote{Induction}} tactic.

P. Loiseleur developed the \sphinxcode{\sphinxupquote{Quote}} tactic and the new design of the
\sphinxcode{\sphinxupquote{Auto}} tactic, he also introduced the index of errors in the
documentation.

C. Paulin wrote the \sphinxcode{\sphinxupquote{Focus}} command and introduced the reduction
functions in definitions, this last feature was proposed by J.-F.
Monin from CNET Lannion.

\begin{DUlineblock}{0em}
\item[] Orsay, Dec. 1999
\item[] Christine Paulin
\item[] 
\end{DUlineblock}


\section{Credits: versions 7}
\label{\detokenize{index:credits-versions-7}}
The version V7 is a new implementation started in September 1999 by
Jean-Christophe Filliâtre. This is a major revision with respect to the
internal architecture of the system. The \DUrole{smallcaps}{Coq} version 7.0 was distributed
in March 2001, version 7.1 in September 2001, version 7.2 in January
2002, version 7.3 in May 2002 and version 7.4 in February 2003.

Jean-Christophe Filliâtre designed the architecture of the new system.
He introduced a new representation for environments and wrote a new
kernel for type checking terms. His approach was to use functional
data-structures in order to get more sharing, to prepare the addition of
modules and also to get closer to a certified kernel.

Hugo Herbelin introduced a new structure of terms with local
definitions. He introduced “qualified” names, wrote a new
pattern matching compilation algorithm and designed a more compact
algorithm for checking the logical consistency of universes. He
contributed to the simplification of \DUrole{smallcaps}{Coq} internal structures and the
optimisation of the system. He added basic tactics for forward reasoning
and coercions in patterns.

David Delahaye introduced a new language for tactics. General tactics
using pattern matching on goals and context can directly be written from
the \DUrole{smallcaps}{Coq} toplevel. He also provided primitives for the design of
user-defined tactics in Caml.

Micaela Mayero contributed the library on real numbers. Olivier
Desmettre extended this library with axiomatic trigonometric functions,
square, square roots, finite sums, Chasles property and basic plane
geometry.

Jean-Christophe Filliâtre and Pierre Letouzey redesigned a new
extraction procedure from \DUrole{smallcaps}{Coq} terms to Caml or Haskell programs. This
new extraction procedure, unlike the one implemented in previous version
of \DUrole{smallcaps}{Coq} is able to handle all terms in the Calculus of Inductive
Constructions, even involving universes and strong elimination. P.
Letouzey adapted user contributions to extract ML programs when it was
sensible. Jean-Christophe Filliâtre wrote \sphinxcode{\sphinxupquote{coqdoc}}, a documentation
tool for \DUrole{smallcaps}{Coq} libraries usable from version 7.2.

Bruno Barras improved the efficiency of the reduction algorithm and the
confidence level in the correctness of \DUrole{smallcaps}{Coq} critical type checking
algorithm.

Yves Bertot designed the \sphinxcode{\sphinxupquote{SearchPattern}} and \sphinxcode{\sphinxupquote{SearchRewrite}} tools
and the support for the pcoq interface
(\sphinxurl{http://www-sop.inria.fr/lemme/pcoq/}).

Micaela Mayero and David Delahaye introduced Field, a decision tactic
for commutative fields.

Christine Paulin changed the elimination rules for empty and singleton
propositional inductive types.

Loïc Pottier developed Fourier, a tactic solving linear inequalities on
real numbers.

Pierre Crégut developed a new, reflection-based version of the Omega
decision procedure.

Claudio Sacerdoti Coen designed an XML output for the \DUrole{smallcaps}{Coq} modules to be
used in the Hypertextual Electronic Library of Mathematics (HELM cf
\sphinxurl{http://www.cs.unibo.it/helm}).

A library for efficient representation of finite maps using binary trees
contributed by Jean Goubault was integrated in the basic theories.

Pierre Courtieu developed a command and a tactic to reason on the
inductive structure of recursively defined functions.

Jacek Chrząszcz designed and implemented the module system of \DUrole{smallcaps}{Coq} whose
foundations are in Judicaël Courant’s PhD thesis.

The development was coordinated by C. Paulin.

Many discussions within the Démons team and the LogiCal project
influenced significantly the design of \DUrole{smallcaps}{Coq} especially with J. Courant,
J. Duprat, J. Goubault, A. Miquel, C. Marché, B. Monate and B. Werner.

Intensive users suggested improvements of the system : Y. Bertot, L.
Pottier, L. Théry, P. Zimmerman from INRIA, C. Alvarado, P. Crégut,
J.-F. Monin from France Telecom R \& D.

\begin{DUlineblock}{0em}
\item[] Orsay, May. 2002
\item[] Hugo Herbelin \& Christine Paulin
\item[] 
\end{DUlineblock}


\section{Credits: version 8.0}
\label{\detokenize{index:credits-version-8-0}}
Coq version 8 is a major revision of the \DUrole{smallcaps}{Coq} proof assistant. First, the
underlying logic is slightly different. The so-called \sphinxstyleemphasis{impredicativity}
of the sort Set has been dropped. The main reason is that it is
inconsistent with the principle of description which is quite a useful
principle for formalizing mathematics within classical logic. Moreover,
even in an constructive setting, the impredicativity of Set does not add
so much in practice and is even subject of criticism from a large part
of the intuitionistic mathematician community. Nevertheless, the
impredicativity of Set remains optional for users interested in
investigating mathematical developments which rely on it.

Secondly, the concrete syntax of terms has been completely revised. The
main motivations were
\begin{itemize}
\item {} 
a more uniform, purified style: all constructions are now lowercase,
with a functional programming perfume (e.g. abstraction is now
written fun), and more directly accessible to the novice (e.g.
dependent product is now written forall and allows omission of
types). Also, parentheses are no longer mandatory for function
application.

\item {} 
extensibility: some standard notations (e.g. “\textless{}” and “\textgreater{}”) were
incompatible with the previous syntax. Now all standard arithmetic
notations (=, +, *, /, \textless{}, \textless{}=, ... and more) are directly part of the
syntax.

\end{itemize}

Together with the revision of the concrete syntax, a new mechanism of
\sphinxstyleemphasis{interpretation scopes} permits to reuse the same symbols (typically +,
-, *, /, \textless{}, \textless{}=) in various mathematical theories without any
ambiguities for \DUrole{smallcaps}{Coq}, leading to a largely improved readability of \DUrole{smallcaps}{Coq}
scripts. New commands to easily add new symbols are also provided.

Coming with the new syntax of terms, a slight reform of the tactic
language and of the language of commands has been carried out. The
purpose here is a better uniformity making the tactics and commands
easier to use and to remember.

Thirdly, a restructuring and uniformization of the standard library of
Coq has been performed. There is now just one Leibniz equality usable
for all the different kinds of \DUrole{smallcaps}{Coq} objects. Also, the set of real
numbers now lies at the same level as the sets of natural and integer
numbers. Finally, the names of the standard properties of numbers now
follow a standard pattern and the symbolic notations for the standard
definitions as well.

The fourth point is the release of \DUrole{smallcaps}{CoqIDE}, a new graphical gtk2-based
interface fully integrated with \DUrole{smallcaps}{Coq}. Close in style to the Proof General
Emacs interface, it is faster and its integration with \DUrole{smallcaps}{Coq} makes
interactive developments more friendly. All mathematical Unicode symbols
are usable within \DUrole{smallcaps}{CoqIDE}.

Finally, the module system of \DUrole{smallcaps}{Coq} completes the picture of \DUrole{smallcaps}{Coq} version
8.0. Though released with an experimental status in the previous version
7.4, it should be considered as a salient feature of the new version.

Besides, \DUrole{smallcaps}{Coq} comes with its load of novelties and improvements: new or
improved tactics (including a new tactic for solving first-order
statements), new management commands, extended libraries.

Bruno Barras and Hugo Herbelin have been the main contributors of the
reflection and the implementation of the new syntax. The smart automatic
translator from old to new syntax released with \DUrole{smallcaps}{Coq} is also their work
with contributions by Olivier Desmettre.

Hugo Herbelin is the main designer and implementer of the notion of
interpretation scopes and of the commands for easily adding new
notations.

Hugo Herbelin is the main implementer of the restructured standard library.

Pierre Corbineau is the main designer and implementer of the new tactic
for solving first-order statements in presence of inductive types. He is
also the maintainer of the non-domain specific automation tactics.

Benjamin Monate is the developer of the \DUrole{smallcaps}{CoqIDE} graphical interface with
contributions by Jean-Christophe Filliâtre, Pierre Letouzey, Claude
Marché and Bruno Barras.

Claude Marché coordinated the edition of the Reference Manual for \DUrole{smallcaps}{Coq}
V8.0.

Pierre Letouzey and Jacek Chrząszcz respectively maintained the
extraction tool and module system of \DUrole{smallcaps}{Coq}.

Jean-Christophe Filliâtre, Pierre Letouzey, Hugo Herbelin and other
contributors from Sophia-Antipolis and Nijmegen participated in
extending the library.

Julien Narboux built a NSIS-based automatic \DUrole{smallcaps}{Coq} installation tool for
the Windows platform.

Hugo Herbelin and Christine Paulin coordinated the development which was
under the responsibility of Christine Paulin.

\begin{DUlineblock}{0em}
\item[] Palaiseau \& Orsay, Apr. 2004
\item[] Hugo Herbelin \& Christine Paulin
\item[] (updated Apr. 2006)
\item[] 
\end{DUlineblock}


\section{Credits: version 8.1}
\label{\detokenize{index:credits-version-8-1}}
Coq version 8.1 adds various new functionalities.

Benjamin Grégoire implemented an alternative algorithm to check the
convertibility of terms in the \DUrole{smallcaps}{Coq} type checker. This alternative
algorithm works by compilation to an efficient bytecode that is
interpreted in an abstract machine similar to Xavier Leroy’s ZINC
machine. Convertibility is performed by comparing the normal forms. This
alternative algorithm is specifically interesting for proofs by
reflection. More generally, it is convenient in case of intensive
computations.

Christine Paulin implemented an extension of inductive types allowing
recursively non uniform parameters. Hugo Herbelin implemented
sort-polymorphism for inductive types (now called template polymorphism).

Claudio Sacerdoti Coen improved the tactics for rewriting on arbitrary
compatible equivalence relations. He also generalized rewriting to
arbitrary transition systems.

Claudio Sacerdoti Coen added new features to the module system.

Benjamin Grégoire, Assia Mahboubi and Bruno Barras developed a new, more
efficient and more general simplification algorithm for rings and
semirings.

Laurent Théry and Bruno Barras developed a new, significantly more
efficient simplification algorithm for fields.

Hugo Herbelin, Pierre Letouzey, Julien Forest, Julien Narboux and
Claudio Sacerdoti Coen added new tactic features.

Hugo Herbelin implemented matching on disjunctive patterns.

New mechanisms made easier the communication between \DUrole{smallcaps}{Coq} and external
provers. Nicolas Ayache and Jean-Christophe Filliâtre implemented
connections with the provers cvcl, Simplify and zenon. Hugo Herbelin
implemented an experimental protocol for calling external tools from the
tactic language.

Matthieu Sozeau developed Russell, an experimental language to specify
the behavior of programs with subtypes.

A mechanism to automatically use some specific tactic to solve
unresolved implicit has been implemented by Hugo Herbelin.

Laurent Théry’s contribution on strings and Pierre Letouzey and
Jean-Christophe Filliâtre’s contribution on finite maps have been
integrated to the \DUrole{smallcaps}{Coq} standard library. Pierre Letouzey developed a
library about finite sets “à la Objective Caml”. With Jean-Marc Notin,
he extended the library on lists. Pierre Letouzey’s contribution on
rational numbers has been integrated and extended.

Pierre Corbineau extended his tactic for solving first-order statements.
He wrote a reflection-based intuitionistic tautology solver.

Pierre Courtieu, Julien Forest and Yves Bertot added extra support to
reason on the inductive structure of recursively defined functions.

Jean-Marc Notin significantly contributed to the general maintenance of
the system. He also took care of \sphinxtitleref{coqdoc}.

Pierre Castéran contributed to the documentation of (co-)inductive types
and suggested improvements to the libraries.

Pierre Corbineau implemented a declarative mathematical proof language,
usable in combination with the tactic-based style of proof.

Finally, many users suggested improvements of the system through the
Coq-Club mailing list and bug-tracker systems, especially user groups
from INRIA Rocquencourt, Radboud University, University of Pennsylvania
and Yale University.

\begin{DUlineblock}{0em}
\item[] Palaiseau, July 2006
\item[] Hugo Herbelin
\item[] 
\end{DUlineblock}


\section{Credits: version 8.2}
\label{\detokenize{index:credits-version-8-2}}
Coq version 8.2 adds new features, new libraries and improves on many
various aspects.

Regarding the language of \DUrole{smallcaps}{Coq}, the main novelty is the introduction by
Matthieu Sozeau of a package of commands providing Haskell-style typeclasses.
Typeclasses, which come with a few convenient features such as
type-based resolution of implicit arguments, play a new landmark role
in the architecture of \DUrole{smallcaps}{Coq} with respect to automation. For
instance, thanks to typeclass support, Matthieu Sozeau could
implement a new resolution-based version of the tactics dedicated to
rewriting on arbitrary transitive relations.

Another major improvement of \DUrole{smallcaps}{Coq} 8.2 is the evolution of the arithmetic
libraries and of the tools associated to them. Benjamin Grégoire and
Laurent Théry contributed a modular library for building arbitrarily
large integers from bounded integers while Evgeny Makarov contributed a
modular library of abstract natural and integer arithmetic together
with a few convenient tactics. On his side, Pierre Letouzey made
numerous extensions to the arithmetic libraries on \(\mathbb{Z}\)
and \(\mathbb{Q}\), including extra support for automation in
presence of various number-theory concepts.

Frédéric Besson contributed a reflective tactic based on Krivine-Stengle
Positivstellensatz (the easy way) for validating provability of systems
of inequalities. The platform is flexible enough to support the
validation of any algorithm able to produce a “certificate” for the
Positivstellensatz and this covers the case of Fourier-Motzkin (for
linear systems in \(\mathbb{Q}\) and \(\mathbb{R}\)),
Fourier-Motzkin with cutting planes (for linear systems in
\(\mathbb{Z}\)) and sum-of-squares (for non-linear systems). Evgeny
Makarov made the platform generic over arbitrary ordered rings.

Arnaud Spiwack developed a library of 31-bits machine integers and,
relying on Benjamin Grégoire and Laurent Théry’s library, delivered a
library of unbounded integers in base \(2^{31}\). As importantly, he
developed a notion of “retro-knowledge” so as to safely extend the
kernel-located bytecode-based efficient evaluation algorithm of \DUrole{smallcaps}{Coq}
version 8.1 to use 31-bits machine arithmetic for efficiently computing
with the library of integers he developed.

Beside the libraries, various improvements were contributed to provide a more
comfortable end-user language and more expressive tactic language. Hugo
Herbelin and Matthieu Sozeau improved the pattern matching compilation
algorithm (detection of impossible clauses in pattern matching,
automatic inference of the return type). Hugo Herbelin, Pierre Letouzey
and Matthieu Sozeau contributed various new convenient syntactic
constructs and new tactics or tactic features: more inference of
redundant information, better unification, better support for proof or
definition by fixpoint, more expressive rewriting tactics, better
support for meta-variables, more convenient notations...

Élie Soubiran improved the module system, adding new features (such as
an “include” command) and making it more flexible and more general. He
and Pierre Letouzey improved the support for modules in the extraction
mechanism.

Matthieu Sozeau extended the Russell language, ending in an convenient
way to write programs of given specifications, Pierre Corbineau extended
the Mathematical Proof Language and the automation tools that
accompany it, Pierre Letouzey supervised and extended various parts of the
standard library, Stéphane Glondu contributed a few tactics and
improvements, Jean-Marc Notin provided help in debugging, general
maintenance and coqdoc support, Vincent Siles contributed extensions of
the Scheme command and of injection.

Bruno Barras implemented the \sphinxtitleref{coqchk} tool: this is a stand-alone
type checker that can be used to certify .vo files. Especially, as this
verifier runs in a separate process, it is granted not to be “hijacked”
by virtually malicious extensions added to \DUrole{smallcaps}{Coq}.

Yves Bertot, Jean-Christophe Filliâtre, Pierre Courtieu and Julien
Forest acted as maintainers of features they implemented in previous
versions of \DUrole{smallcaps}{Coq}.

Julien Narboux contributed to \DUrole{smallcaps}{CoqIDE}. Nicolas Tabareau made the
adaptation of the interface of the old “setoid rewrite” tactic to the
new version. Lionel Mamane worked on the interaction between \DUrole{smallcaps}{Coq} and its
external interfaces. With Samuel Mimram, he also helped making \DUrole{smallcaps}{Coq}
compatible with recent software tools. Russell O’Connor, Cezary
Kaliszyk, Milad Niqui contributed to improve the libraries of integers,
rational, and real numbers. We also thank many users and partners for
suggestions and feedback, in particular Pierre Castéran and Arthur
Charguéraud, the INRIA Marelle team, Georges Gonthier and the
INRIA-Microsoft Mathematical Components team, the Foundations group at
Radboud university in Nijmegen, reporters of bugs and participants to
the Coq-Club mailing list.

\begin{DUlineblock}{0em}
\item[] Palaiseau, June 2008
\item[] Hugo Herbelin
\item[] 
\end{DUlineblock}


\section{Credits: version 8.3}
\label{\detokenize{index:credits-version-8-3}}
Coq version 8.3 is before all a transition version with refinements or
extensions of the existing features and libraries and a new tactic nsatz
based on Hilbert’s Nullstellensatz for deciding systems of equations
over rings.

With respect to libraries, the main evolutions are due to Pierre
Letouzey with a rewriting of the library of finite sets FSets and a new
round of evolutions in the modular development of arithmetic (library
Numbers). The reason for making FSets evolve is that the computational
and logical contents were quite intertwined in the original
implementation, leading in some cases to longer computations than
expected and this problem is solved in the new MSets implementation. As
for the modular arithmetic library, it was only dealing with the basic
arithmetic operators in the former version and its current extension
adds the standard theory of the division, min and max functions, all
made available for free to any implementation of \(\mathbb{N}\),
\(\mathbb{Z}\) or \(\mathbb{Z}/n\mathbb{Z}\).

The main other evolutions of the library are due to Hugo Herbelin who
made a revision of the sorting library (including a certified
merge-sort) and to Guillaume Melquiond who slightly revised and cleaned
up the library of reals.

The module system evolved significantly. Besides the resolution of some
efficiency issues and a more flexible construction of module types, Élie
Soubiran brought a new model of name equivalence, the
\(\Delta\)-equivalence, which respects as much as possible the names
given by the users. He also designed with Pierre Letouzey a new,
convenient operator \sphinxcode{\sphinxupquote{\textless{}+}} for nesting functor application that
provides a light notation for inheriting the properties of cascading
modules.

The new tactic nsatz is due to Loïc Pottier. It works by computing
Gröbner bases. Regarding the existing tactics, various improvements have
been done by Matthieu Sozeau, Hugo Herbelin and Pierre Letouzey.

Matthieu Sozeau extended and refined the typeclasses and Program
features (the Russell language). Pierre Letouzey maintained and improved
the extraction mechanism. Bruno Barras and Élie Soubiran maintained the
Coq checker, Julien Forest maintained the Function mechanism for
reasoning over recursively defined functions. Matthieu Sozeau, Hugo
Herbelin and Jean-Marc Notin maintained coqdoc. Frédéric Besson
maintained the Micromega platform for deciding systems of inequalities.
Pierre Courtieu maintained the support for the Proof General Emacs
interface. Claude Marché maintained the plugin for calling external
provers (dp). Yves Bertot made some improvements to the libraries of
lists and integers. Matthias Puech improved the search functions.
Guillaume Melquiond usefully contributed here and there. Yann
Régis-Gianas grounded the support for Unicode on a more standard and
more robust basis.

Though invisible from outside, Arnaud Spiwack improved the general
process of management of existential variables. Pierre Letouzey and
Stéphane Glondu improved the compilation scheme of the \DUrole{smallcaps}{Coq} archive.
Vincent Gross provided support to \DUrole{smallcaps}{CoqIDE}. Jean-Marc Notin provided
support for benchmarking and archiving.

Many users helped by reporting problems, providing patches, suggesting
improvements or making useful comments, either on the bug tracker or on
the Coq-Club mailing list. This includes but not exhaustively Cédric
Auger, Arthur Charguéraud, François Garillot, Georges Gonthier, Robin
Green, Stéphane Lescuyer, Eelis van der Weegen, ...

Though not directly related to the implementation, special thanks are
going to Yves Bertot, Pierre Castéran, Adam Chlipala, and Benjamin
Pierce for the excellent teaching materials they provided.

\begin{DUlineblock}{0em}
\item[] Paris, April 2010
\item[] Hugo Herbelin
\item[] 
\end{DUlineblock}


\section{Credits: version 8.4}
\label{\detokenize{index:credits-version-8-4}}
Coq version 8.4 contains the result of three long-term projects: a new
modular library of arithmetic by Pierre Letouzey, a new proof engine by
Arnaud Spiwack and a new communication protocol for \DUrole{smallcaps}{CoqIDE} by Vincent
Gross.

The new modular library of arithmetic extends, generalizes and unifies
the existing libraries on Peano arithmetic (types nat, N and BigN),
positive arithmetic (type positive), integer arithmetic (Z and BigZ) and
machine word arithmetic (type Int31). It provides with unified notations
(e.g. systematic use of add and mul for denoting the addition and
multiplication operators), systematic and generic development of
operators and properties of these operators for all the types mentioned
above, including gcd, pcm, power, square root, base 2 logarithm,
division, modulo, bitwise operations, logical shifts, comparisons,
iterators, ...

The most visible feature of the new proof engine is the support for
structured scripts (bullets and proof brackets) but, even if yet not
user-available, the new engine also provides the basis for refining
existential variables using tactics, for applying tactics to several
goals simultaneously, for reordering goals, all features which are
planned for the next release. The new proof engine forced Pierre Letouzey
to reimplement info and Show Script differently.

Before version 8.4, \DUrole{smallcaps}{CoqIDE} was linked to \DUrole{smallcaps}{Coq} with the graphical
interface living in a separate thread. From version 8.4, \DUrole{smallcaps}{CoqIDE} is a
separate process communicating with \DUrole{smallcaps}{Coq} through a textual channel. This
allows for a more robust interfacing, the ability to interrupt \DUrole{smallcaps}{Coq}
without interrupting the interface, and the ability to manage several
sessions in parallel. Relying on the infrastructure work made by Vincent
Gross, Pierre Letouzey, Pierre Boutillier and Pierre-Marie Pédrot
contributed many various refinements of \DUrole{smallcaps}{CoqIDE}.

Coq 8.4 also comes with a bunch of various smaller-scale changes
and improvements regarding the different components of the system.

The underlying logic has been extended with \(\eta\)-conversion
thanks to Hugo Herbelin, Stéphane Glondu and Benjamin Grégoire. The
addition of \(\eta\)-conversion is justified by the confidence that
the formulation of the Calculus of Inductive Constructions based on
typed equality (such as the one considered in Lee and Werner to build a
set-theoretic model of CIC \sphinxcite{zebibliography:leewerner11}) is
applicable to the concrete implementation of \DUrole{smallcaps}{Coq}.

The underlying logic benefited also from a refinement of the guard
condition for fixpoints by Pierre Boutillier, the point being that it is
safe to propagate the information about structurally smaller arguments
through \(\beta\)-redexes that are blocked by the “match”
construction (blocked commutative cuts).

Relying on the added permissiveness of the guard condition, Hugo
Herbelin could extend the pattern matching compilation algorithm so that
matching over a sequence of terms involving dependencies of a term or of
the indices of the type of a term in the type of other terms is
systematically supported.

Regarding the high-level specification language, Pierre Boutillier
introduced the ability to give implicit arguments to anonymous
functions, Hugo Herbelin introduced the ability to define notations with
several binders (e.g. \sphinxcode{\sphinxupquote{exists x y z, P}}), Matthieu Sozeau made the
typeclass inference mechanism more robust and predictable, Enrico
Tassi introduced a command Arguments that generalizes Implicit Arguments
and Arguments Scope for assigning various properties to arguments of
constants. Various improvements in the type inference algorithm were
provided by Matthieu Sozeau and Hugo Herbelin with contributions from
Enrico Tassi.

Regarding tactics, Hugo Herbelin introduced support for referring to
expressions occurring in the goal by pattern in tactics such as set or
destruct. Hugo Herbelin also relied on ideas from Chung-Kil Hur’s Heq
plugin to introduce automatic computation of occurrences to generalize
when using destruct and induction on types with indices. Stéphane Glondu
introduced new tactics constr\_eq, is\_evar and has\_evar to be used
when writing complex tactics. Enrico Tassi added support to fine-tuning
the behavior of simpl. Enrico Tassi added the ability to specify over
which variables of a section a lemma has to be exactly generalized.
Pierre Letouzey added a tactic timeout and the interruptibility of
vm\_compute. Bug fixes and miscellaneous improvements of the tactic
language came from Hugo Herbelin, Pierre Letouzey and Matthieu Sozeau.

Regarding decision tactics, Loïc Pottier maintained nsatz, moving in
particular to a typeclass based reification of goals while Frédéric
Besson maintained Micromega, adding in particular support for division.

Regarding vernacular commands, Stéphane Glondu provided new commands to
analyze the structure of type universes.

Regarding libraries, a new library about lists of a given length (called
vectors) has been provided by Pierre Boutillier. A new instance of
finite sets based on Red-Black trees and provided by Andrew Appel has
been adapted for the standard library by Pierre Letouzey. In the library
of real analysis, Yves Bertot changed the definition of \(\pi\) and
provided a proof of the long-standing fact yet remaining unproved in
this library, namely that \(sin \frac{\pi}{2} =
1\).

Pierre Corbineau maintained the Mathematical Proof Language (C-zar).

Bruno Barras and Benjamin Grégoire maintained the call-by-value
reduction machines.

The extraction mechanism benefited from several improvements provided by
Pierre Letouzey.

Pierre Letouzey maintained the module system, with contributions from
Élie Soubiran.

Julien Forest maintained the Function command.

Matthieu Sozeau maintained the setoid rewriting mechanism.

Coq related tools have been upgraded too. In particular, coq\_makefile
has been largely revised by Pierre Boutillier. Also, patches from Adam
Chlipala for coqdoc have been integrated by Pierre Boutillier.

Bruno Barras and Pierre Letouzey maintained the \sphinxtitleref{coqchk} checker.

Pierre Courtieu and Arnaud Spiwack contributed new features for using
Coq through Proof General.

The Dp plugin has been removed. Use the plugin provided with Why 3
instead (\sphinxurl{http://why3.lri.fr}).

Under the hood, the \DUrole{smallcaps}{Coq} architecture benefited from improvements in
terms of efficiency and robustness, especially regarding universes
management and existential variables management, thanks to Pierre
Letouzey and Yann Régis-Gianas with contributions from Stéphane Glondu
and Matthias Puech. The build system is maintained by Pierre Letouzey
with contributions from Stéphane Glondu and Pierre Boutillier.

A new backtracking mechanism simplifying the task of external interfaces
has been designed by Pierre Letouzey.

The general maintenance was done by Pierre Letouzey, Hugo Herbelin,
Pierre Boutillier, Matthieu Sozeau and Stéphane Glondu with also
specific contributions from Guillaume Melquiond, Julien Narboux and
Pierre-Marie Pédrot.

Packaging tools were provided by Pierre Letouzey (Windows), Pierre
Boutillier (MacOS), Stéphane Glondu (Debian). Releasing, testing and
benchmarking support was provided by Jean-Marc Notin.

Many suggestions for improvements were motivated by feedback from users,
on either the bug tracker or the Coq-Club mailing list. Special thanks
are going to the users who contributed patches, starting with Tom
Prince. Other patch contributors include Cédric Auger, David Baelde, Dan
Grayson, Paolo Herms, Robbert Krebbers, Marc Lasson, Hendrik Tews and
Eelis van der Weegen.

\begin{DUlineblock}{0em}
\item[] Paris, December 2011
\item[] Hugo Herbelin
\item[] 
\end{DUlineblock}


\section{Credits: version 8.5}
\label{\detokenize{index:credits-version-8-5}}
Coq version 8.5 contains the result of five specific long-term projects:
\begin{itemize}
\item {} 
A new asynchronous evaluation and compilation mode by Enrico Tassi
with help from Bruno Barras and Carst Tankink.

\item {} 
Full integration of the new proof engine by Arnaud Spiwack helped by
Pierre-Marie Pédrot,

\item {} 
Addition of conversion and reduction based on native compilation by
Maxime Dénès and Benjamin Grégoire.

\item {} 
Full universe polymorphism for definitions and inductive types by
Matthieu Sozeau.

\item {} 
An implementation of primitive projections with
\(\eta\)-conversion bringing significant performance improvements
when using records by Matthieu Sozeau.

\end{itemize}

The full integration of the proof engine, by Arnaud Spiwack and
Pierre-Marie Pédrot, brings to primitive tactics and the user level Ltac
language dependent subgoals, deep backtracking and multiple goal
handling, along with miscellaneous features and an improved potential
for future modifications. Dependent subgoals allow statements in a goal
to mention the proof of another. Proofs of unsolved subgoals appear as
existential variables. Primitive backtracking makes it possible to write
a tactic with several possible outcomes which are tried successively
when subsequent tactics fail. Primitives are also available to control
the backtracking behavior of tactics. Multiple goal handling paves the
way for smarter automation tactics. It is currently used for simple goal
manipulation such as goal reordering.

The way \DUrole{smallcaps}{Coq} processes a document in batch and interactive mode has been
redesigned by Enrico Tassi with help from Bruno Barras. Opaque proofs,
the text between Proof and Qed, can be processed asynchronously,
decoupling the checking of definitions and statements from the checking
of proofs. It improves the responsiveness of interactive development,
since proofs can be processed in the background. Similarly, compilation
of a file can be split into two phases: the first one checking only
definitions and statements and the second one checking proofs. A file
resulting from the first phase \textendash{} with the .vio extension \textendash{} can be
already Required. All .vio files can be turned into complete .vo files
in parallel. The same infrastructure also allows terminating tactics to
be run in parallel on a set of goals via the \sphinxcode{\sphinxupquote{par:}} goal selector.

\DUrole{smallcaps}{CoqIDE} was modified to cope with asynchronous checking of the document.
Its source code was also made separate from that of \DUrole{smallcaps}{Coq}, so that \DUrole{smallcaps}{CoqIDE}
no longer has a special status among user interfaces, paving the way for
decoupling its release cycle from that of \DUrole{smallcaps}{Coq} in the future.

Carst Tankink developed a \DUrole{smallcaps}{Coq} back-end for user interfaces built on
Makarius Wenzel’s Prover IDE framework (PIDE), like PIDE/jEdit (with
help from Makarius Wenzel) or PIDE/Coqoon (with help from Alexander
Faithfull and Jesper Bengtson). The development of such features was
funded by the Paral-ITP French ANR project.

The full universe polymorphism extension was designed by Matthieu
Sozeau. It conservatively extends the universes system and core calculus
with definitions and inductive declarations parameterized by universes
and constraints. It is based on a modification of the kernel
architecture to handle constraint checking only, leaving the generation
of constraints to the refinement/type inference engine. Accordingly,
tactics are now fully universe aware, resulting in more localized error
messages in case of inconsistencies and allowing higher-level algorithms
like unification to be entirely type safe. The internal representation
of universes has been modified but this is invisible to the user.

The underlying logic has been extended with \(\eta\)-conversion for
records defined with primitive projections by Matthieu Sozeau. This
additional form of \(\eta\)-conversion is justified using the same
principle than the previously added \(\eta\)-conversion for function
types, based on formulations of the Calculus of Inductive Constructions
with typed equality. Primitive projections, which do not carry the
parameters of the record and are rigid names (not defined as a
pattern matching construct), make working with nested records more
manageable in terms of time and space consumption. This extension and
universe polymorphism were carried out partly while Matthieu Sozeau was
working at the IAS in Princeton.

The guard condition has been made compliant with extensional equality
principles such as propositional extensionality and univalence, thanks
to Maxime Dénès and Bruno Barras. To ensure compatibility with the
univalence axiom, a new flag “-indices-matter” has been implemented,
taking into account the universe levels of indices when computing the
levels of inductive types. This supports using \DUrole{smallcaps}{Coq} as a tool to explore
the relations between homotopy theory and type theory.

Maxime Dénès and Benjamin Grégoire developed an implementation of
conversion test and normal form computation using the OCaml native
compiler. It complements the virtual machine conversion offering much
faster computation for expensive functions.

Coq 8.5 also comes with a bunch of many various smaller-scale changes
and improvements regarding the different components of the system. We
shall only list a few of them.

Pierre Boutillier developed an improved tactic for simplification of
expressions called cbn.

Maxime Dénès maintained the bytecode-based reduction machine. Pierre
Letouzey maintained the extraction mechanism.

Pierre-Marie Pédrot has extended the syntax of terms to, experimentally,
allow holes in terms to be solved by a locally specified tactic.

Existential variables are referred to by identifiers rather than mere
numbers, thanks to Hugo Herbelin who also improved the tactic language
here and there.

Error messages for universe inconsistencies have been improved by
Matthieu Sozeau. Error messages for unification and type inference
failures have been improved by Hugo Herbelin, Pierre-Marie Pédrot and
Arnaud Spiwack.

Pierre Courtieu contributed new features for using \DUrole{smallcaps}{Coq} through Proof
General and for better interactive experience (bullets, Search, etc).

The efficiency of the whole system has been significantly improved
thanks to contributions from Pierre-Marie Pédrot.

A distribution channel for \DUrole{smallcaps}{Coq} packages using the OPAM tool has been
initiated by Thomas Braibant and developed by Guillaume Claret, with
contributions by Enrico Tassi and feedback from Hugo Herbelin.

Packaging tools were provided by Pierre Letouzey and Enrico Tassi
(Windows), Pierre Boutillier, Matthieu Sozeau and Maxime Dénès (MacOS
X). Maxime Dénès improved significantly the testing and benchmarking
support.

Many power users helped to improve the design of the new features via
the bug tracker, the coq development mailing list or the Coq-Club
mailing list. Special thanks are going to the users who contributed
patches and intensive brain-storming, starting with Jason Gross,
Jonathan Leivent, Greg Malecha, Clément Pit-Claudel, Marc Lasson, Lionel
Rieg. It would however be impossible to mention with precision all names
of people who to some extent influenced the development.

Version 8.5 is one of the most important releases of \DUrole{smallcaps}{Coq}. Its development
spanned over about 3 years and a half with about one year of
beta-testing. General maintenance during part or whole of this period
has been done by Pierre Boutillier, Pierre Courtieu, Maxime Dénès, Hugo
Herbelin, Pierre Letouzey, Guillaume Melquiond, Pierre-Marie Pédrot,
Matthieu Sozeau, Arnaud Spiwack, Enrico Tassi as well as Bruno Barras,
Yves Bertot, Frédéric Besson, Xavier Clerc, Pierre Corbineau,
Jean-Christophe Filliâtre, Julien Forest, Sébastien Hinderer, Assia
Mahboubi, Jean-Marc Notin, Yann Régis-Gianas, François Ripault, Carst
Tankink. Maxime Dénès coordinated the release process.

\begin{DUlineblock}{0em}
\item[] Paris, January 2015, revised December 2015,
\item[] Hugo Herbelin, Matthieu Sozeau and the \DUrole{smallcaps}{Coq} development team
\item[] 
\end{DUlineblock}


\section{Credits: version 8.6}
\label{\detokenize{index:credits-version-8-6}}
Coq version 8.6 contains the result of refinements, stabilization of
8.5’s features and cleanups of the internals of the system. Over the
year of (now time-based) development, about 450 bugs were resolved and
over 100 contributions integrated. The main user visible changes are:
\begin{itemize}
\item {} 
A new, faster state-of-the-art universe constraint checker, by
Jacques-Henri Jourdan.

\item {} 
In \DUrole{smallcaps}{CoqIDE} and other asynchronous interfaces, more fine-grained
asynchronous processing and error reporting by Enrico Tassi, making
\DUrole{smallcaps}{Coq} capable of recovering from errors and continue processing the
document.

\item {} 
More access to the proof engine features from Ltac: goal management
primitives, range selectors and a \sphinxcode{\sphinxupquote{typeclasses eauto}} engine handling
multiple goals and multiple successes, by Cyprien Mangin, Matthieu
Sozeau and Arnaud Spiwack.

\item {} 
Tactic behavior uniformization and specification, generalization of
intro-patterns by Hugo Herbelin and others.

\item {} 
A brand new warning system allowing to control warnings, turn them
into errors or ignore them selectively by Maxime Dénès, Guillaume
Melquiond, Pierre-Marie Pédrot and others.

\item {} 
Irrefutable patterns in abstractions, by Daniel de Rauglaudre.

\item {} 
The ssreflect subterm selection algorithm by Georges Gonthier and
Enrico Tassi is now accessible to tactic writers through the
ssrmatching plugin.

\item {} 
Integration of LtacProf, a profiler for Ltac by Jason Gross, Paul
Steckler, Enrico Tassi and Tobias Tebbi.

\end{itemize}

Coq 8.6 also comes with a bunch of smaller-scale changes and
improvements regarding the different components of the system. We shall
only list a few of them.

The iota reduction flag is now a shorthand for match, fix and cofix
flags controlling the corresponding reduction rules (by Hugo Herbelin
and Maxime Dénès).

Maxime Dénès maintained the native compilation machinery.

Pierre-Marie Pédrot separated the Ltac code from general purpose
tactics, and generalized and rationalized the handling of generic
arguments, allowing to create new versions of Ltac more easily in the
future.

In patterns and terms, @, abbreviations and notations are now
interpreted the same way, by Hugo Herbelin.

Name handling for universes has been improved by Pierre-Marie Pédrot and
Matthieu Sozeau. The minimization algorithm has been improved by
Matthieu Sozeau.

The unifier has been improved by Hugo Herbelin and Matthieu Sozeau,
fixing some incompatibilities introduced in \DUrole{smallcaps}{Coq} 8.5. Unification
constraints can now be left floating around and be seen by the user
thanks to a new option. The Keyed Unification mode has been improved by
Matthieu Sozeau.

The typeclass resolution engine and associated proof-search tactic have
been reimplemented on top of the proof-engine monad, providing better
integration in tactics, and new options have been introduced to control
it, by Matthieu Sozeau with help from Théo Zimmermann.

The efficiency of the whole system has been significantly improved
thanks to contributions from Pierre-Marie Pédrot, Maxime Dénès and
Matthieu Sozeau and performance issue tracking by Jason Gross and Paul
Steckler.

Standard library improvements by Jason Gross, Sébastien Hinderer, Pierre
Letouzey and others.

Emilio Jesús Gallego Arias contributed many cleanups and refactorings of
the pretty-printing and user interface communication components.

Frédéric Besson maintained the micromega tactic.

The OPAM repository for \DUrole{smallcaps}{Coq} packages has been maintained by Guillaume
Claret, Guillaume Melquiond, Matthieu Sozeau, Enrico Tassi and others. A
list of packages is now available at \sphinxurl{https://coq.inria.fr/opam/www/}.

Packaging tools and software development kits were prepared by Michael
Soegtrop with the help of Maxime Dénès and Enrico Tassi for Windows, and
Maxime Dénès and Matthieu Sozeau for MacOS X. Packages are now regularly
built on the continuous integration server. \DUrole{smallcaps}{Coq} now comes with a META
file usable with ocamlfind, contributed by Emilio Jesús Gallego Arias,
Gregory Malecha, and Matthieu Sozeau.

Matej Košík maintained and greatly improved the continuous integration
setup and the testing of \DUrole{smallcaps}{Coq} contributions. He also contributed many API
improvements and code cleanups throughout the system.

The contributors for this version are Bruno Barras, C.J. Bell, Yves
Bertot, Frédéric Besson, Pierre Boutillier, Tej Chajed, Guillaume
Claret, Xavier Clerc, Pierre Corbineau, Pierre Courtieu, Maxime Dénès,
Ricky Elrod, Emilio Jesús Gallego Arias, Jason Gross, Hugo Herbelin,
Sébastien Hinderer, Jacques-Henri Jourdan, Matej Košík, Xavier Leroy,
Pierre Letouzey, Gregory Malecha, Cyprien Mangin, Erik Martin-Dorel,
Guillaume Melquiond, Clément Pit\textendash{}Claudel, Pierre-Marie Pédrot, Daniel de
Rauglaudre, Lionel Rieg, Gabriel Scherer, Thomas Sibut-Pinote, Matthieu
Sozeau, Arnaud Spiwack, Paul Steckler, Enrico Tassi, Laurent Théry,
Nickolai Zeldovich and Théo Zimmermann. The development process was
coordinated by Hugo Herbelin and Matthieu Sozeau with the help of Maxime
Dénès, who was also in charge of the release process.

Many power users helped to improve the design of the new features via
the bug tracker, the pull request system, the \DUrole{smallcaps}{Coq} development mailing
list or the Coq-Club mailing list. Special thanks to the users who
contributed patches and intensive brain-storming and code reviews,
starting with Cyril Cohen, Jason Gross, Robbert Krebbers, Jonathan
Leivent, Xavier Leroy, Gregory Malecha, Clément Pit\textendash{}Claudel, Gabriel
Scherer and Beta Ziliani. It would however be impossible to mention
exhaustively the names of everybody who to some extent influenced the
development.

Version 8.6 is the first release of \DUrole{smallcaps}{Coq} developed on a time-based
development cycle. Its development spanned 10 months from the release of
Coq 8.5 and was based on a public roadmap. To date, it contains more
external contributions than any previous \DUrole{smallcaps}{Coq} system. Code reviews were
systematically done before integration of new features, with an
important focus given to compatibility and performance issues, resulting
in a hopefully more robust release than \DUrole{smallcaps}{Coq} 8.5.

Coq Enhancement Proposals (CEPs for short) were introduced by Enrico
Tassi to provide more visibility and a discussion period on new
features, they are publicly available \sphinxurl{https://github.com/coq/ceps}.

Started during this period, an effort is led by Yves Bertot and Maxime
Dénès to put together a \DUrole{smallcaps}{Coq} consortium.

\begin{DUlineblock}{0em}
\item[] Paris, November 2016,
\item[] Matthieu Sozeau and the \DUrole{smallcaps}{Coq} development team
\item[] 
\end{DUlineblock}


\section{Credits: version 8.7}
\label{\detokenize{index:credits-version-8-7}}
\DUrole{smallcaps}{Coq} version 8.7 contains the result of refinements, stabilization of features
and cleanups of the internals of the system along with a few new features. The
main user visible changes are:
\begin{itemize}
\item {} 
New tactics: variants of tactics supporting existential variables eassert,
eenough, etc... by Hugo Herbelin. Tactics extensionality in H and
inversion\_sigma by Jason Gross, specialize with ... accepting partial bindings
by Pierre Courtieu.

\item {} 
Cumulative Polymorphic Inductive Types, allowing cumulativity of universes to
go through applied inductive types, by Amin Timany and Matthieu Sozeau.

\item {} 
Integration of the SSReflect plugin and its documentation in the reference
manual, by Enrico Tassi, Assia Mahboubi and Maxime Dénès.

\item {} 
The coq\_makefile tool was completely redesigned to improve its maintainability
and the extensibility of generated Makefiles, and to make \sphinxtitleref{\_CoqProject} files
more palatable to IDEs by Enrico Tassi.

\end{itemize}

\DUrole{smallcaps}{Coq} 8.7 involved a large amount of work on cleaning and speeding up the code
base, notably the work of Pierre-Marie Pédrot on making the tactic-level system
insensitive to existential variable expansion, providing a safer API to plugin
writers and making the code more robust. The \sphinxtitleref{dev/doc/changes.txt} file
documents the numerous changes to the implementation and improvements of
interfaces. An effort to provide an official, streamlined API to plugin writers
is in progress, thanks to the work of Matej Košík.

Version 8.7 also comes with a bunch of smaller-scale changes and improvements
regarding the different components of the system. We shall only list a few of
them.

The efficiency of the whole system has been significantly improved thanks to
contributions from Pierre-Marie Pédrot, Maxime Dénès and Matthieu Sozeau and
performance issue tracking by Jason Gross and Paul Steckler.

Thomas Sibut-Pinote and Hugo Herbelin added support for side effect hooks in
cbv, cbn and simpl. The side effects are provided via a plugin available at
\sphinxurl{https://github.com/herbelin/reduction-effects/}.

The BigN, BigZ, BigQ libraries are no longer part of the \DUrole{smallcaps}{Coq} standard library,
they are now provided by a separate repository \sphinxurl{https://github.com/coq/bignums},
maintained by Pierre Letouzey.

In the Reals library, \sphinxtitleref{IZR} has been changed to produce a compact representation
of integers and real constants are now represented using \sphinxtitleref{IZR} (work by
Guillaume Melquiond).

Standard library additions and improvements by Jason Gross, Pierre Letouzey and
others, documented in the \sphinxtitleref{CHANGES} file.

The mathematical proof language/declarative mode plugin was removed from the
archive.

The OPAM repository for \DUrole{smallcaps}{Coq} packages has been maintained by Guillaume Melquiond,
Matthieu Sozeau, Enrico Tassi with contributions from many users. A list of
packages is available at \sphinxurl{https://coq.inria.fr/opam/www/}.

Packaging tools and software development kits were prepared by Michael Soegtrop
with the help of Maxime Dénès and Enrico Tassi for Windows, and Maxime Dénès for
MacOS X. Packages are regularly built on the Travis continuous integration
server.

The contributors for this version are Abhishek Anand, C.J. Bell, Yves Bertot,
Frédéric Besson, Tej Chajed, Pierre Courtieu, Maxime Dénès, Julien Forest,
Gaëtan Gilbert, Jason Gross, Hugo Herbelin, Emilio Jesús Gallego Arias, Ralf
Jung, Matej Košík, Xavier Leroy, Pierre Letouzey, Assia Mahboubi, Cyprien
Mangin, Erik Martin-Dorel, Olivier Marty, Guillaume Melquiond, Sam Pablo Kuper,
Benjamin Pierce, Pierre-Marie Pédrot, Lars Rasmusson, Lionel Rieg, Valentin
Robert, Yann Régis-Gianas, Thomas Sibut-Pinote, Michael Soegtrop, Matthieu
Sozeau, Arnaud Spiwack, Paul Steckler, George Stelle, Pierre-Yves Strub, Enrico
Tassi, Hendrik Tews, Amin Timany, Laurent Théry, Vadim Zaliva and Théo
Zimmermann.

The development process was coordinated by Matthieu Sozeau with the help of
Maxime Dénès, who was also in charge of the release process. Théo Zimmermann is
the maintainer of this release.

Many power users helped to improve the design of the new features via the bug
tracker, the pull request system, the \DUrole{smallcaps}{Coq} development mailing list or the
Coq-Club mailing list. Special thanks to the users who contributed patches and
intensive brain-storming and code reviews, starting with Jason Gross, Ralf Jung,
Robbert Krebbers, Xavier Leroy, Clément Pit\textendash{}Claudel and Gabriel Scherer. It
would however be impossible to mention exhaustively the names of everybody who
to some extent influenced the development.

Version 8.7 is the second release of \DUrole{smallcaps}{Coq} developed on a time-based development
cycle. Its development spanned 9 months from the release of \DUrole{smallcaps}{Coq} 8.6 and was
based on a public road-map. It attracted many external contributions. Code
reviews and continuous integration testing were systematically used before
integration of new features, with an important focus given to compatibility and
performance issues, resulting in a hopefully more robust release than \DUrole{smallcaps}{Coq} 8.6
while maintaining compatibility.

\DUrole{smallcaps}{Coq} Enhancement Proposals (CEPs for short) and open pull request discussions
were used to discuss publicly the new features.

The \DUrole{smallcaps}{Coq} consortium, an organization directed towards users and supporters of the
system, is now upcoming and will rely on Inria’s newly created Foundation.

\begin{DUlineblock}{0em}
\item[] Paris, August 2017,
\item[] Matthieu Sozeau and the \DUrole{smallcaps}{Coq} development team
\item[] 
\end{DUlineblock}


\section{Credits: version 8.8}
\label{\detokenize{index:credits-version-8-8}}
\DUrole{smallcaps}{Coq} version 8.8 contains the result of refinements and stabilization of
features and deprecations, cleanups of the internals of the system along
with a few new features. The main user visible changes are:
\begin{itemize}
\item {} 
Kernel: fix a subject reduction failure due to allowing fixpoints
on non-recursive values, by Matthieu Sozeau.
Handling of evars in the VM (the kernel still does not accept evars)
by Pierre-Marie Pédrot.

\item {} 
Notations: many improvements on recursive notations and support for
destructuring patterns in the syntax of notations by Hugo Herbelin.

\item {} 
Proof language: tacticals for profiling, timing and checking success
or failure of tactics by Jason Gross. The focusing bracket \sphinxcode{\sphinxupquote{\{}}
supports single-numbered goal selectors, e.g. \sphinxcode{\sphinxupquote{2:\{}}, by Théo
Zimmermann.

\item {} 
Vernacular: deprecation of commands and more uniform handling of the
\sphinxcode{\sphinxupquote{Local}} flag, by Vincent Laporte and Maxime Dénès, part of a larger
attribute system overhaul. Experimental \sphinxcode{\sphinxupquote{Show Extraction}} command by
Pierre Letouzey. Coercion now accepts \sphinxcode{\sphinxupquote{Prop}} or \sphinxcode{\sphinxupquote{Type}} as a source
by Arthur Charguéraud. \sphinxcode{\sphinxupquote{Export}} modifier for options allowing to
export the option to modules that \sphinxcode{\sphinxupquote{Import}} and not only \sphinxcode{\sphinxupquote{Require}}
a module, by Pierre-Marie Pédrot.

\item {} 
Universes: many user-level and API level enhancements: qualified
naming and printing, variance annotations for cumulative inductive
types, more general constraints and enhancements of the minimization
heuristics, interaction with modules by Gaëtan Gilbert, Pierre-Marie
Pédrot and Matthieu Sozeau.

\item {} 
Library: Decimal Numbers library by Pierre Letouzey and various small
improvements.

\item {} 
Documentation: a large community effort resulted in the migration
of the reference manual to the Sphinx documentation tool. The result
is this manual. The new documentation infrastructure (based on Sphinx)
is by Clément Pit-Claudel. The migration was coordinated by Maxime Dénès
and Paul Steckler, with some help of Théo Zimmermann during the
final integration phase. The 14 people who ported the manual are
Calvin Beck, Heiko Becker, Yves Bertot, Maxime Dénès, Richard Ford,
Pierre Letouzey, Assia Mahboubi, Clément Pit-Claudel,
Laurence Rideau, Matthieu Sozeau, Paul Steckler, Enrico Tassi,
Laurent Théry, Nikita Zyuzin.

\item {} 
Tools: experimental \sphinxcode{\sphinxupquote{-mangle-names}} option to coqtop/coqc for
linting proof scripts, by Jasper Hugunin.

\end{itemize}

On the implementation side, the \sphinxcode{\sphinxupquote{dev/doc/changes.md}} file
documents the numerous changes to the implementation and improvements of
interfaces. The file provides guidelines on porting a plugin to the new
version.

Version 8.8 also comes with a bunch of smaller-scale changes and
improvements regarding the different components of the system.
Most important ones are documented in the \sphinxcode{\sphinxupquote{CHANGES}} file.

The efficiency of the whole system has seen improvements thanks to
contributions from Gaëtan Gilbert, Pierre-Marie Pédrot, Maxime Dénès and
Matthieu Sozeau and performance issue tracking by Jason Gross and Paul
Steckler.

The official wiki and the bugtracker of \DUrole{smallcaps}{Coq} migrated to the GitHub
platform, thanks to the work of Pierre Letouzey and Théo
Zimmermann. Gaëtan Gilbert, Emilio Jesús Gallego Arias worked on
maintaining and improving the continuous integration system.

The OPAM repository for \DUrole{smallcaps}{Coq} packages has been maintained by Guillaume
Melquiond, Matthieu Sozeau, Enrico Tassi with contributions from many
users. A list of packages is available at \sphinxurl{https://coq.inria.fr/opam/www}.

The 44 contributors for this version are Yves Bertot, Joachim Breitner, Tej
Chajed, Arthur Charguéraud, Jacques-Pascal Deplaix, Maxime Dénès, Jim Fehrle,
Julien Forest, Yannick Forster, Gaëtan Gilbert, Jason Gross, Samuel Gruetter,
Thomas Hebb, Hugo Herbelin, Jasper Hugunin, Emilio Jesus Gallego Arias, Ralf
Jung, Johannes Kloos, Matej Košík, Robbert Krebbers, Tony Beta Lambda, Vincent
Laporte, Peter LeFanu Lumsdaine, Pierre Letouzey, Farzon Lotfi, Cyprien Mangin,
Guillaume Melquiond, Raphaël Monat, Carl Patenaude Poulin, Pierre-Marie Pédrot,
Clément Pit-Claudel, Matthew Ryan, Matt Quinn, Sigurd Schneider, Bernhard
Schommer, Michael Soegtrop, Matthieu Sozeau, Arnaud Spiwack, Paul Steckler,
Enrico Tassi, Anton Trunov, Martin Vassor, Vadim Zaliva and Théo Zimmermann.

Version 8.8 is the third release of \DUrole{smallcaps}{Coq} developed on a time-based
development cycle. Its development spanned 6 months from the release of
\DUrole{smallcaps}{Coq} 8.7 and was based on a public roadmap. The development process
was coordinated by Matthieu Sozeau. Maxime Dénès was in charge of the
release process. Théo Zimmermann is the maintainer of this release.

Many power users helped to improve the design of the new features via
the bug tracker, the pull request system, the \DUrole{smallcaps}{Coq} development mailing
list or the \sphinxhref{mailto:coq-club@inria.fr}{coq-club@inria.fr} mailing list. Special thanks to the users who
contributed patches and intensive brain-storming and code reviews,
starting with Jason Gross, Ralf Jung, Robbert Krebbers and Amin Timany.
It would however be impossible to mention exhaustively the names
of everybody who to some extent influenced the development.

The \DUrole{smallcaps}{Coq} consortium, an organization directed towards users and
supporters of the system, is now running and employs Maxime Dénès.
The contacts of the Coq Consortium are Yves Bertot and Maxime Dénès.

\begin{DUlineblock}{0em}
\item[] Santiago de Chile, March 2018,
\item[] Matthieu Sozeau for the \DUrole{smallcaps}{Coq} development team
\item[] 
\end{DUlineblock}


\chapter{License}
\label{\detokenize{index:license}}
This material (the Coq Reference Manual) may be distributed only subject to the
terms and conditions set forth in the Open Publication License, v1.0 or later
(the latest version is presently available at
\sphinxurl{http://www.opencontent.org/openpub}). Options A and B are not elected.


\chapter{The language}
\label{\detokenize{index:the-language}}

\section{The Gallina specification language}
\label{\detokenize{language/gallina-specification-language:the-gallina-specification-language}}\label{\detokenize{language/gallina-specification-language:gallinaspecificationlanguage}}\label{\detokenize{language/gallina-specification-language::doc}}
This chapter describes Gallina, the specification language of Coq. It allows
developing mathematical theories and to prove specifications of programs. The
theories are built from axioms, hypotheses, parameters, lemmas, theorems and
definitions of constants, functions, predicates and sets. The syntax of logical
objects involved in theories is described in Section {\hyperref[\detokenize{language/gallina-specification-language:term}]{\sphinxcrossref{\DUrole{std,std-ref}{Terms}}}}. The
language of commands, called \sphinxstyleemphasis{The Vernacular} is described in Section
{\hyperref[\detokenize{language/gallina-specification-language:vernacular}]{\sphinxcrossref{\DUrole{std,std-ref}{The Vernacular}}}}.

In Coq, logical objects are typed to ensure their logical correctness.  The
rules implemented by the typing algorithm are described in Chapter {\hyperref[\detokenize{language/cic:calculusofinductiveconstructions}]{\sphinxcrossref{\DUrole{std,std-ref}{Calculus of Inductive Constructions}}}}.


\subsection{About the grammars in the manual}
\label{\detokenize{language/gallina-specification-language:about-the-grammars-in-the-manual}}
Grammars are presented in Backus-Naur form (BNF). Terminal symbols are
set in black \sphinxcode{\sphinxupquote{typewriter font}}. In addition, there are special notations for
regular expressions.

An expression enclosed in square brackets \sphinxcode{\sphinxupquote{{[}…{]}}} means at most one
occurrence of this expression (this corresponds to an optional
component).

The notation “\sphinxcode{\sphinxupquote{entry sep … sep entry}}” stands for a non empty sequence
of expressions parsed by entry and separated by the literal “\sphinxcode{\sphinxupquote{sep}}” %
\begin{footnote}[1]\sphinxAtStartFootnote
This is similar to the expression “\sphinxstyleemphasis{entry} \(\{\) sep \sphinxstyleemphasis{entry}
\(\}\)” in standard BNF, or “\sphinxstyleemphasis{entry} \((\) sep \sphinxstyleemphasis{entry}
\()\)*” in the syntax of regular expressions.
%
\end{footnote}.

Similarly, the notation “\sphinxcode{\sphinxupquote{entry … entry}}” stands for a non empty
sequence of expressions parsed by the “\sphinxcode{\sphinxupquote{entry}}” entry, without any
separator between.

At the end, the notation “\sphinxcode{\sphinxupquote{{[}entry sep … sep entry{]}}}” stands for a
possibly empty sequence of expressions parsed by the “\sphinxcode{\sphinxupquote{entry}}” entry,
separated by the literal “\sphinxcode{\sphinxupquote{sep}}”.


\subsection{Lexical conventions}
\label{\detokenize{language/gallina-specification-language:lexical-conventions}}\label{\detokenize{language/gallina-specification-language:id2}}\begin{description}
\item[{Blanks}] \leavevmode
Space, newline and horizontal tabulation are considered as blanks.
Blanks are ignored but they separate tokens.

\item[{Comments}] \leavevmode
Comments in Coq are enclosed between \sphinxcode{\sphinxupquote{(*}} and \sphinxcode{\sphinxupquote{*)}}, and can be nested.
They can contain any character. However, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}} literals must be
correctly closed. Comments are treated as blanks.

\item[{Identifiers and access identifiers}] \leavevmode
Identifiers, written {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}, are sequences of letters, digits, \sphinxcode{\sphinxupquote{\_}} and
\sphinxcode{\sphinxupquote{'}}, that do not start with a digit or \sphinxcode{\sphinxupquote{'}}. That is, they are
recognized by the following lexical class:


\begin{productionlist}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-first_letter}}\production{first\_letter}{ a..z ∣ A..Z ∣ \_ ∣ unicode-letter}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-subsequent_letter}}\production{subsequent\_letter}{ a..z ∣ A..Z ∣ 0..9 ∣ \_ ∣ ' ∣ unicode-letter ∣ unicode-id-part}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-ident}}\production{ident}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-first-letter}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{first\_letter}}}}}{[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-subsequent-letter}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{subsequent\_letter}}}}}…{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-subsequent-letter}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{subsequent\_letter}}}}}{]}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-access_ident}}\production{access\_ident}{ .{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}}
\end{productionlist}


All characters are meaningful. In particular, identifiers are case-sensitive.
The entry \sphinxcode{\sphinxupquote{unicode-letter}} non-exhaustively includes Latin,
Greek, Gothic, Cyrillic, Arabic, Hebrew, Georgian, Hangul, Hiragana
and Katakana characters, CJK ideographs, mathematical letter-like
symbols, hyphens, non-breaking space, … The entry \sphinxcode{\sphinxupquote{unicode-id-part}}
non-exhaustively includes symbols for prime letters and subscripts.

Access identifiers, written {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-access-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{access\_ident}}}}}, are identifiers prefixed by
\sphinxtitleref{.} (dot) without blank. They are used in the syntax of qualified
identifiers.

\item[{Natural numbers and integers}] \leavevmode
Numerals are sequences of digits. Integers are numerals optionally
preceded by a minus sign.


\begin{productionlist}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-digit}}\production{digit}{ 0..9}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-num}}\production{num}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-digit}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{digit}}}}}…{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-digit}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{digit}}}}}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-integer}}\production{integer}{ {[}-{]}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}}}
\end{productionlist}


\item[{Strings}] \leavevmode
Strings are delimited by \sphinxcode{\sphinxupquote{"}} (double quote), and enclose a sequence of
any characters different from \sphinxcode{\sphinxupquote{"}} or the sequence \sphinxcode{\sphinxupquote{""}} to denote the
double quote character. In grammars, the entry for quoted strings is
\DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-string}}\sphinxcode{\sphinxupquote{string}}}.

\item[{Keywords}] \leavevmode
The following identifiers are reserved keywords, and cannot be
employed otherwise:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZus{} as at cofix else end exists exists2 fix for
forall fun if IF in let match mod Prop return
Set then Type using where with
\end{sphinxVerbatim}

\item[{Special tokens}] \leavevmode
The following sequences of characters are special tokens:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
! \PYGZpc{} \PYGZam{} \PYGZam{}\PYGZam{} ( () ) * + ++ , \PYGZhy{} \PYGZhy{}\PYGZgt{} . .( ..
/ /\PYGZbs{} : :: :\PYGZlt{} := :\PYGZgt{} ; \PYGZlt{} \PYGZlt{}\PYGZhy{} \PYGZlt{}\PYGZhy{}\PYGZgt{} \PYGZlt{}: \PYGZlt{}= \PYGZlt{}\PYGZgt{} =
=\PYGZgt{} =\PYGZus{}D \PYGZgt{} \PYGZgt{}\PYGZhy{}\PYGZgt{} \PYGZgt{}= ? ?= @ [ \PYGZbs{}/ ] \PYGZca{} \PYGZob{} \textbar{} \textbar{}\PYGZhy{}
\textbar{}\textbar{} \PYGZcb{} \PYGZti{}
\end{sphinxVerbatim}

Lexical ambiguities are resolved according to the “longest match”
rule: when a sequence of non alphanumerical characters can be
decomposed into several different ways, then the first token is the
longest possible one (among all tokens defined at this moment), and so
on.

\end{description}


\subsection{Terms}
\label{\detokenize{language/gallina-specification-language:terms}}\label{\detokenize{language/gallina-specification-language:term}}

\subsubsection{Syntax of terms}
\label{\detokenize{language/gallina-specification-language:syntax-of-terms}}
The following grammars describe the basic syntax of the terms of the
\sphinxstyleemphasis{Calculus of Inductive Constructions} (also called Cic). The formal
presentation of Cic is given in Chapter {\hyperref[\detokenize{language/cic:calculusofinductiveconstructions}]{\sphinxcrossref{\DUrole{std,std-ref}{Calculus of Inductive Constructions}}}}. Extensions of this syntax
are given in Chapter {\hyperref[\detokenize{language/gallina-extensions:extensionsofgallina}]{\sphinxcrossref{\DUrole{std,std-ref}{Extensions of Gallina}}}}. How to customize the syntax
is described in Chapter {\hyperref[\detokenize{user-extensions/syntax-extensions:syntaxextensionsandinterpretationscopes}]{\sphinxcrossref{\DUrole{std,std-ref}{Syntax extensions and interpretation scopes}}}}.


\begin{productionlist}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-term}}\production{term}{ forall {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}} , {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} fun {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}} =\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} fix {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-fix-bodies}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fix\_bodies}}}}}}
\productioncont{ \textbar{} cofix {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-cofix-bodies}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cofix\_bodies}}}}}}
\productioncont{ \textbar{} let {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}}{]} {[}: {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}{]} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} let fix {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-fix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fix\_body}}}}} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} let cofix {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-cofix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cofix\_body}}}}} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} let ( {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} , … , {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}}{]} ) {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-dep-ret-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{dep\_ret\_type}}}}}{]} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} let ' {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} {[}in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}{]} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-return-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{return\_type}}}}}{]} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} if {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-dep-ret-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{dep\_ret\_type}}}}}{]} then {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} else {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} \textless{}: {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} :\textgreater{}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} -\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-arg}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{arg}}}}} … {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-arg}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{arg}}}}}}
\productioncont{ \textbar{} @ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} … {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}{]}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} \% {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}}
\productioncont{ \textbar{} match {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-match-item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match\_item}}}}} , … , {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-match-item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match\_item}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-return-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{return\_type}}}}}{]} with}
\productioncont{   {[}{[}\textbar{}{]} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-equation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{equation}}}}} \textbar{} … \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-equation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{equation}}}}}{]} end}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-sort}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{sort}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}}}
\productioncont{ \textbar{} \_}
\productioncont{ \textbar{} ( {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} )}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-arg}}\production{arg}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} ( {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} )}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-binders}}\production{binders}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binder}}}}} … {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binder}}}}}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-binder}}\production{binder}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}}}
\productioncont{ \textbar{} ( {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} … {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} )}
\productioncont{ \textbar{} ( {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} {[}: {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}{]} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} )}
\productioncont{ \textbar{} ' {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-name}}\production{name}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} \textbar{} \_}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-qualid}}\production{qualid}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-access-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{access\_ident}}}}}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-sort}}\production{sort}{ Prop \textbar{} Set \textbar{} Type}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-fix_bodies}}\production{fix\_bodies}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-fix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fix\_body}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-fix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fix\_body}}}}} with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-fix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fix\_body}}}}} with … with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-fix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fix\_body}}}}} for {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-cofix_bodies}}\production{cofix\_bodies}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-cofix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cofix\_body}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-cofix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cofix\_body}}}}} with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-cofix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cofix\_body}}}}} with … with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-cofix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cofix\_body}}}}} for {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-fix_body}}\production{fix\_body}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-annotation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{annotation}}}}}{]} {[}: {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}{]} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-cofix_body}}\production{cofix\_body}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}}{]} {[}: {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}{]} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-annotation}}\production{annotation}{ \{ struct {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} \}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-match_item}}\production{match\_item}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} {[}as {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}}{]} {[}in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} … {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}{]}{]}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-dep_ret_type}}\production{dep\_ret\_type}{ {[}as {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}}{]} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-return-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{return\_type}}}}}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-return_type}}\production{return\_type}{ return {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-equation}}\production{equation}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-mult-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{mult\_pattern}}}}} \textbar{} … \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-mult-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{mult\_pattern}}}}} =\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-mult_pattern}}\production{mult\_pattern}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} , … , {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-pattern}}\production{pattern}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} … {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}}
\productioncont{ \textbar{} @ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} … {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} as {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} \% {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}}
\productioncont{ \textbar{} \_}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}}}
\productioncont{ \textbar{} ( {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-or-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{or\_pattern}}}}} , … , {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-or-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{or\_pattern}}}}} )}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-or_pattern}}\production{or\_pattern}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} \textbar{} … \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}}
\end{productionlist}



\subsubsection{Types}
\label{\detokenize{language/gallina-specification-language:types}}
Coq terms are typed. Coq types are recognized by the same syntactic
class as {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. We denote by \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-type}}\sphinxcode{\sphinxupquote{type}}} the semantic subclass
of types inside the syntactic class {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.


\subsubsection{Qualified identifiers and simple identifiers}
\label{\detokenize{language/gallina-specification-language:qualified-identifiers-and-simple-identifiers}}\label{\detokenize{language/gallina-specification-language:gallina-identifiers}}
\sphinxstyleemphasis{Qualified identifiers} ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}) denote \sphinxstyleemphasis{global constants}
(definitions, lemmas, theorems, remarks or facts), \sphinxstyleemphasis{global variables}
(parameters or axioms), \sphinxstyleemphasis{inductive types} or \sphinxstyleemphasis{constructors of inductive
types}. \sphinxstyleemphasis{Simple identifiers} (or shortly {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}) are a syntactic subset
of qualified identifiers. Identifiers may also denote \sphinxstyleemphasis{local variables},
while qualified identifiers do not.


\subsubsection{Numerals}
\label{\detokenize{language/gallina-specification-language:numerals}}
Numerals have no definite semantics in the calculus. They are mere
notations that can be bound to objects through the notation mechanism
(see Chapter {\hyperref[\detokenize{user-extensions/syntax-extensions:syntaxextensionsandinterpretationscopes}]{\sphinxcrossref{\DUrole{std,std-ref}{Syntax extensions and interpretation scopes}}}} for details).
Initially, numerals are bound to Peano’s representation of natural
numbers (see {\hyperref[\detokenize{language/coq-library:datatypes}]{\sphinxcrossref{\DUrole{std,std-ref}{Datatypes}}}}).

\begin{sphinxadmonition}{note}{Note:}
Negative integers are not at the same level as {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}}, for this
would make precedence unnatural.
\end{sphinxadmonition}

\index{Set (sort)}\index{Prop}\index{Type}\ignorespaces 

\subsubsection{Sorts}
\label{\detokenize{language/gallina-specification-language:sorts}}\label{\detokenize{language/gallina-specification-language:index-0}}
There are three sorts \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}}, \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}} and \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}}.
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}} is the universe of \sphinxstyleemphasis{logical propositions}. The logical propositions
themselves are typing the proofs. We denote propositions by \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-form}}\sphinxcode{\sphinxupquote{form}}}.
This constitutes a semantic subclass of the syntactic class {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}} is is the universe of \sphinxstyleemphasis{program types} or \sphinxstyleemphasis{specifications}. The
specifications themselves are typing the programs. We denote
specifications by \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-specif}}\sphinxcode{\sphinxupquote{specif}}}. This constitutes a semantic subclass of
the syntactic class {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}} is the type of \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}} and \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}}

\end{itemize}

More on sorts can be found in Section {\hyperref[\detokenize{language/cic:sorts}]{\sphinxcrossref{\DUrole{std,std-ref}{Sorts}}}}.


\subsubsection{Binders}
\label{\detokenize{language/gallina-specification-language:binders}}\label{\detokenize{language/gallina-specification-language:id3}}
Various constructions such as \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun}}}, \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall}}}, \sphinxcode{\sphinxupquote{\DUrole{keyword}{fix}}} and \sphinxcode{\sphinxupquote{\DUrole{keyword}{cofix}}}
\sphinxstyleemphasis{bind} variables. A binding is represented by an identifier. If the binding
variable is not used in the expression, the identifier can be replaced by the
symbol \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}}. When the type of a bound variable cannot be synthesized by the
system, it can be specified with the notation \sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})}}}. There is also
a notation for a sequence of binding variables sharing the same type:
\sphinxcode{\sphinxupquote{\DUrole{notation}{(\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})}}}. A
binder can also be any pattern prefixed by a quote, e.g. \sphinxcode{\sphinxupquote{\DUrole{keyword}{'}\DUrole{operator}{(}\DUrole{name}{x}\DUrole{operator}{,}\DUrole{name}{y}\DUrole{operator}{)}}}.

Some constructions allow the binding of a variable to value. This is
called a “let-binder”. The entry {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binder}}}}} of the grammar accepts
either an assumption binder as defined above or a let-binder. The notation in
the latter case is \sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}. In a let-binder, only one
variable can be introduced at the same time. It is also possible to give
the type of the variable as follows:
\sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}.

Lists of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binder}}}}} are allowed. In the case of \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun}}} and \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall}}},
it is intended that at least one binder of the list is an assumption otherwise
fun and forall gets identical. Moreover, parentheses can be omitted in
the case of a single sequence of bindings sharing the same type (e.g.:
\sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{operator}{(}\DUrole{name}{x} \DUrole{name}{y} \DUrole{name}{z} \DUrole{operator}{:} \DUrole{name}{A}\DUrole{operator}{)} \DUrole{operator}{=\textgreater{}} \DUrole{name}{t}}} can be shortened in \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{name}{x} \DUrole{name}{y} \DUrole{name}{z} \DUrole{operator}{:} \DUrole{name}{A} \DUrole{operator}{=\textgreater{}} \DUrole{name}{t}}}).

\index{fun ... =\textgreater{} ...}\ignorespaces 

\subsubsection{Abstractions}
\label{\detokenize{language/gallina-specification-language:abstractions}}\label{\detokenize{language/gallina-specification-language:index-1}}
The expression \sphinxcode{\sphinxupquote{\DUrole{notation}{fun {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}} =\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} defines the
\sphinxstyleemphasis{abstraction} of the variable {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}, of type {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}, over the term
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. It denotes a function of the variable {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} that evaluates to
the expression {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} (e.g. \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{name}{x} \DUrole{operator}{:} \DUrole{name}{A} \DUrole{operator}{=\textgreater{}} \DUrole{name}{x}}} denotes the identity
function on type \sphinxcode{\sphinxupquote{\DUrole{name}{A}}}). The keyword \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun}}} can be followed by several
binders as given in Section {\hyperref[\detokenize{language/gallina-specification-language:binders}]{\sphinxcrossref{\DUrole{std,std-ref}{Binders}}}}. Functions over
several variables are equivalent to an iteration of one-variable
functions. For instance the expression
“fun {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\(_{1}\) … {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\(_{n}\)
: {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} =\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}”
denotes the same function as “ fun {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\(_{1}\) : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} =\textgreater{} …
fun {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\(_{n}\) : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} =\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}”. If
a let-binder occurs in
the list of binders, it is expanded to a let-in definition (see
Section {\hyperref[\detokenize{language/gallina-specification-language:let-in}]{\sphinxcrossref{\DUrole{std,std-ref}{Let-in definitions}}}}).

\index{forall}\ignorespaces 

\subsubsection{Products}
\label{\detokenize{language/gallina-specification-language:products}}\label{\detokenize{language/gallina-specification-language:index-2}}
The expression \sphinxcode{\sphinxupquote{\DUrole{notation}{forall {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} denotes the
\sphinxstyleemphasis{product} of the variable {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} of type {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}, over the term {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.
As for abstractions, \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall}}} is followed by a binder list, and products
over several variables are equivalent to an iteration of one-variable
products. Note that {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} is intended to be a type.

If the variable {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} occurs in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}, the product is called
\sphinxstyleemphasis{dependent product}. The intention behind a dependent product
\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x} \DUrole{operator}{:} \DUrole{name}{A}\DUrole{operator}{,} \DUrole{name}{B}}} is twofold. It denotes either
the universal quantification of the variable \sphinxcode{\sphinxupquote{\DUrole{name}{x}}} of type \sphinxcode{\sphinxupquote{\DUrole{name}{A}}}
in the proposition \sphinxcode{\sphinxupquote{\DUrole{name}{B}}} or the functional dependent product from
\sphinxcode{\sphinxupquote{\DUrole{name}{A}}} to \sphinxcode{\sphinxupquote{\DUrole{name}{B}}} (a construction usually written
\(\Pi_{x:A}.B\) in set theory).

Non dependent product types have a special notation: \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{-\textgreater{}} \DUrole{name}{B}}} stands for
\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{operator}{\_} \DUrole{operator}{:} \DUrole{name}{A}\DUrole{operator}{,} \DUrole{name}{B}}}. The \sphinxstyleemphasis{non dependent product} is used both to denote
the propositional implication and function types.


\subsubsection{Applications}
\label{\detokenize{language/gallina-specification-language:applications}}
The expression {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_0\) {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_1\) denotes the
application of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_0\) to {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_1\).

The expression {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_0\) {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_1\) ...
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_n\) denotes the application of the term
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_0\) to the arguments {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_1\) ... then
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_n\). It is equivalent to ( … ( {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_0\)
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_1\) ) … ) {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_n\) : associativity is to the
left.

The notation \sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}} for arguments is used for making
explicit the value of implicit arguments (see
Section {\hyperref[\detokenize{language/gallina-extensions:explicit-applications}]{\sphinxcrossref{\DUrole{std,std-ref}{Explicit applications}}}}).

\index{... : ... (type cast)}\index{... \textless{}: ...}\index{... \textless{}\textless{}: ...}\ignorespaces 

\subsubsection{Type cast}
\label{\detokenize{language/gallina-specification-language:type-cast}}\label{\detokenize{language/gallina-specification-language:index-3}}
The expression \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} is a type cast expression. It enforces
the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} to be {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}.

\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \textless{}: {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} locally sets up the virtual machine for checking that
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} has type {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}.

\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \textless{}\textless{}: {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} uses native compilation for checking that {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}
has type {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}.

\index{\_}\ignorespaces 

\subsubsection{Inferable subterms}
\label{\detokenize{language/gallina-specification-language:inferable-subterms}}\label{\detokenize{language/gallina-specification-language:index-4}}
Expressions often contain redundant pieces of information. Subterms that can be
automatically inferred by Coq can be replaced by the symbol \sphinxcode{\sphinxupquote{\_}} and Coq will
guess the missing piece of information.

\index{let ... := ... (term)}\ignorespaces 

\subsubsection{Let-in definitions}
\label{\detokenize{language/gallina-specification-language:let-in-definitions}}\label{\detokenize{language/gallina-specification-language:let-in}}\label{\detokenize{language/gallina-specification-language:index-5}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{let {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}}
denotes the local binding of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} to the variable
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}’. There is a syntactic sugar for let-in
definition of functions: \sphinxcode{\sphinxupquote{\DUrole{notation}{let {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{+}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}}
stands for \sphinxcode{\sphinxupquote{\DUrole{notation}{let {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := fun \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{+}} =\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}}.

\index{match ... with ...}\ignorespaces 

\subsubsection{Definition by case analysis}
\label{\detokenize{language/gallina-specification-language:definition-by-case-analysis}}\label{\detokenize{language/gallina-specification-language:index-6}}
Objects of inductive types can be destructurated by a case-analysis
construction called \sphinxstyleemphasis{pattern matching} expression. A pattern matching
expression is used to analyze the structure of an inductive object and
to apply specific treatments accordingly.

This paragraph describes the basic form of pattern matching. See
Section {\hyperref[\detokenize{language/gallina-extensions:mult-match}]{\sphinxcrossref{\DUrole{std,std-ref}{Multiple and nested pattern matching}}}} and Chapter {\hyperref[\detokenize{addendum/extended-pattern-matching:extendedpatternmatching}]{\sphinxcrossref{\DUrole{std,std-ref}{Extended pattern matching}}}} for the description
of the general form. The basic form of pattern matching is characterized
by a single {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-match-item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match\_item}}}}} expression, a {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-mult-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{mult\_pattern}}}}} restricted to a
single {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} and {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} restricted to the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}}}}.

The expression match "{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_0\) {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-return-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{return\_type}}}}} with
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}\(_1\) =\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_1\) \(|\) … \(|\)
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}\(_n\) =\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_n\) end" denotes a
\sphinxstyleemphasis{pattern matching} over the term {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_0\) (expected to be
of an inductive type \(I\)). The terms {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_1\)…{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_n\) are the \sphinxstyleemphasis{branches} of the pattern matching
expression. Each of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}\(_i\) has a form {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} where {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} must denote a constructor. There should be
exactly one branch for every constructor of \(I\).

The {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-return-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{return\_type}}}}} expresses the type returned by the whole match
expression. There are several cases. In the \sphinxstyleemphasis{non dependent} case, all
branches have the same type, and the {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-return-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{return\_type}}}}} is the common type of
branches. In this case, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-return-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{return\_type}}}}} can usually be omitted as it can be
inferred from the type of the branches %
\begin{footnote}[2]\sphinxAtStartFootnote
Except if the inductive type is empty in which case there is no
equation that can be used to infer the return type.
%
\end{footnote}.

In the \sphinxstyleemphasis{dependent} case, there are three subcases. In the first subcase,
the type in each branch may depend on the exact value being matched in
the branch. In this case, the whole pattern matching itself depends on
the term being matched. This dependency of the term being matched in the
return type is expressed with an “as {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}” clause where {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
is dependent in the return type. For instance, in the following example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{k+kt}{bool} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=} \PYG{n+nb+bp}{true} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\textbar{}} \PYG{n+nb+bp}{false} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{eq} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{eq\PYGZus{}refl} \PYG{o}{:} \PYG{n}{eq} \PYG{n}{A} \PYG{n}{x} \PYG{n}{x}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{or} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{B}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=}
  \PYG{o}{\textbar{}} \PYG{n}{or\PYGZus{}introl} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{or} \PYG{n}{A} \PYG{n}{B}
  \PYG{o}{\textbar{}} \PYG{n}{or\PYGZus{}intror} \PYG{o}{:} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{or} \PYG{n}{A} \PYG{n}{B}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{bool\PYGZus{}case} \PYG{o}{(}\PYG{n}{b}\PYG{o}{:}\PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{:} \PYG{n}{or} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n}{b} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n}{b} \PYG{n+nb+bp}{false}\PYG{o}{)} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{b} \PYG{k}{as} \PYG{n}{x} \PYG{k}{return} \PYG{n}{or} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n}{x} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n}{x} \PYG{n+nb+bp}{false}\PYG{o}{)} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n+nb+bp}{true} \PYG{o}{=\PYGZgt{}} \PYG{n}{or\PYGZus{}introl} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n+nb+bp}{true} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n+nb+bp}{true} \PYG{n+nb+bp}{false}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq\PYGZus{}refl} \PYG{k+kt}{bool} \PYG{n+nb+bp}{true}\PYG{o}{)}
  \PYG{o}{\textbar{}} \PYG{n+nb+bp}{false} \PYG{o}{=\PYGZgt{}} \PYG{n}{or\PYGZus{}intror} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n+nb+bp}{false} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n+nb+bp}{false} \PYG{n+nb+bp}{false}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq\PYGZus{}refl} \PYG{k+kt}{bool} \PYG{n+nb+bp}{false}\PYG{o}{)}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

the branches have respective types "\sphinxcode{\sphinxupquote{\DUrole{name}{or} \DUrole{operator}{(}\DUrole{name}{eq} \DUrole{keyword,type}{bool} \DUrole{name,builtin,pseudo}{true} \DUrole{name,builtin,pseudo}{true}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{eq} \DUrole{keyword,type}{bool} \DUrole{name,builtin,pseudo}{true} \DUrole{name,builtin,pseudo}{false}\DUrole{operator}{)}}}"
and "\sphinxcode{\sphinxupquote{\DUrole{name}{or} \DUrole{operator}{(}\DUrole{name}{eq} \DUrole{keyword,type}{bool} \DUrole{name,builtin,pseudo}{false} \DUrole{name,builtin,pseudo}{true}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{eq} \DUrole{keyword,type}{bool} \DUrole{name,builtin,pseudo}{false} \DUrole{name,builtin,pseudo}{false}\DUrole{operator}{)}}}" while the whole
pattern matching expression has type "\sphinxcode{\sphinxupquote{\DUrole{name}{or} \DUrole{operator}{(}\DUrole{name}{eq} \DUrole{keyword,type}{bool} \DUrole{name}{b} \DUrole{name,builtin,pseudo}{true}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{eq} \DUrole{keyword,type}{bool} \DUrole{name}{b} \DUrole{name,builtin,pseudo}{false}\DUrole{operator}{)}}}",
the identifier \sphinxcode{\sphinxupquote{\DUrole{name}{b}}} being used to represent the dependency.

\begin{sphinxadmonition}{note}{Note:}
When the term being matched is a variable, the \sphinxcode{\sphinxupquote{as}} clause can be
omitted and the term being matched can serve itself as binding name in
the return type. For instance, the following alternative definition is
accepted and has the same meaning as the previous one.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{bool\PYGZus{}case} \PYG{o}{(}\PYG{n}{b}\PYG{o}{:}\PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{:} \PYG{n}{or} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n}{b} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n}{b} \PYG{n+nb+bp}{false}\PYG{o}{)} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{b} \PYG{k}{return} \PYG{n}{or} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n}{b} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n}{b} \PYG{n+nb+bp}{false}\PYG{o}{)} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n+nb+bp}{true} \PYG{o}{=\PYGZgt{}} \PYG{n}{or\PYGZus{}introl} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n+nb+bp}{true} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n+nb+bp}{true} \PYG{n+nb+bp}{false}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq\PYGZus{}refl} \PYG{k+kt}{bool} \PYG{n+nb+bp}{true}\PYG{o}{)}
\PYG{o}{\textbar{}} \PYG{n+nb+bp}{false} \PYG{o}{=\PYGZgt{}} \PYG{n}{or\PYGZus{}intror} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n+nb+bp}{false} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq} \PYG{k+kt}{bool} \PYG{n+nb+bp}{false} \PYG{n+nb+bp}{false}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eq\PYGZus{}refl} \PYG{k+kt}{bool} \PYG{n+nb+bp}{false}\PYG{o}{)}
\PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The second subcase is only relevant for annotated inductive types such
as the equality predicate (see Section {\hyperref[\detokenize{language/coq-library:coq-equality}]{\sphinxcrossref{\DUrole{std,std-ref}{Equality}}}}),
the order predicate on natural numbers or the type of lists of a given
length (see Section {\hyperref[\detokenize{addendum/extended-pattern-matching:matching-dependent}]{\sphinxcrossref{\DUrole{std,std-ref}{Matching objects of dependent types}}}}). In this configuration, the
type of each branch can depend on the type dependencies specific to the
branch and the whole pattern matching expression has a type determined
by the specific dependencies in the type of the term being matched. This
dependency of the return type in the annotations of the inductive type
is expressed using a “\sphinxcode{\sphinxupquote{\DUrole{keyword}{in}}} \(I\) \sphinxcode{\sphinxupquote{\DUrole{operator}{\_} \DUrole{error}{…} \DUrole{operator}{\_}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}\(_1\) …
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}\(_n\)” clause, where
\begin{itemize}
\item {} 
\(I\) is the inductive type of the term being matched;

\item {} 
the \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}} are matching the parameters of the inductive type: the
return type is not dependent on them.

\item {} 
the {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}\(_i\) are matching the annotations of the
inductive type: the return type is dependent on them

\item {} 
in the basic case which we describe below, each {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}\(_i\)
is a name {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\(_i\); see {\hyperref[\detokenize{addendum/extended-pattern-matching:match-in-patterns}]{\sphinxcrossref{\DUrole{std,std-ref}{Patterns in in}}}} for the
general case

\end{itemize}

For instance, in the following example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{eq\PYGZus{}sym} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{H}\PYG{o}{:}\PYG{n}{eq} \PYG{n}{A} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{o}{:} \PYG{n}{eq} \PYG{n}{A} \PYG{n}{y} \PYG{n}{x} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{H} \PYG{k}{in} \PYG{n}{eq} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{n}{z} \PYG{k}{return} \PYG{n}{eq} \PYG{n}{A} \PYG{n}{z} \PYG{n}{x} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n}{eq\PYGZus{}refl} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{eq\PYGZus{}refl} \PYG{n}{A} \PYG{n}{x}
\PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

the type of the branch is \sphinxcode{\sphinxupquote{\DUrole{name}{eq} \DUrole{name}{A} \DUrole{name}{x} \DUrole{name}{x}}} because the third argument of
\sphinxcode{\sphinxupquote{\DUrole{name}{eq}}} is \sphinxcode{\sphinxupquote{\DUrole{name}{x}}} in the type of the pattern \sphinxcode{\sphinxupquote{\DUrole{name}{eq\_refl}}}. On the contrary, the
type of the whole pattern matching expression has type \sphinxcode{\sphinxupquote{\DUrole{name}{eq} \DUrole{name}{A} \DUrole{name}{y} \DUrole{name}{x}}} because the
third argument of eq is y in the type of H. This dependency of the case analysis
in the third argument of \sphinxcode{\sphinxupquote{\DUrole{name}{eq}}} is expressed by the identifier \sphinxcode{\sphinxupquote{\DUrole{name}{z}}} in the
return type.

Finally, the third subcase is a combination of the first and second
subcase. In particular, it only applies to pattern matching on terms in
a type with annotations. For this third subcase, both the clauses \sphinxcode{\sphinxupquote{as}} and
\sphinxcode{\sphinxupquote{in}} are available.

There are specific notations for case analysis on types with one or two
constructors: \sphinxcode{\sphinxupquote{if … then … else …}} and \sphinxcode{\sphinxupquote{let (…,…) := … in …}} (see
Sections {\hyperref[\detokenize{language/gallina-extensions:if-then-else}]{\sphinxcrossref{\DUrole{std,std-ref}{Pattern-matching on boolean values: the if expression}}}} and {\hyperref[\detokenize{language/gallina-extensions:irrefutable-patterns}]{\sphinxcrossref{\DUrole{std,std-ref}{Irrefutable patterns: the destructuring let variants}}}}).

\index{fix}\index{cofix}\ignorespaces 

\subsubsection{Recursive functions}
\label{\detokenize{language/gallina-specification-language:recursive-functions}}\label{\detokenize{language/gallina-specification-language:index-7}}
The expression “\sphinxcode{\sphinxupquote{fix}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\(_1\) {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binder}}}}}\(_1\) \sphinxcode{\sphinxupquote{:}}
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}\(_1\) \sphinxcode{\sphinxupquote{:=}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_1\) \sphinxcode{\sphinxupquote{with … with}}
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\(_n\) {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binder}}}}}\(_n\) : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}\(_n\)
\sphinxcode{\sphinxupquote{:=}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}\(_n\) \sphinxcode{\sphinxupquote{for}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\(_i\)” denotes the
\(i\)-th component of a block of functions defined by mutual structural
recursion. It is the local counterpart of the {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} command. When
\(n=1\), the “\sphinxcode{\sphinxupquote{for}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\(_i\)” clause is omitted.

The expression “\sphinxcode{\sphinxupquote{cofix}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\(_1\) {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binder}}}}}\(_1\) \sphinxcode{\sphinxupquote{:}}
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}\(_1\) \sphinxcode{\sphinxupquote{with … with}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\(_n\) {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binder}}}}}\(_n\)
: {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}\(_n\) \sphinxcode{\sphinxupquote{for}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\(_i\)” denotes the
\(i\)-th component of a block of terms defined by a mutual guarded
co-recursion. It is the local counterpart of the {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.cofixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{CoFixpoint}}}}} command. When
\(n=1\), the “\sphinxcode{\sphinxupquote{for}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\(_i\)” clause is omitted.

The association of a single fixpoint and a local definition have a special
syntax: \sphinxcode{\sphinxupquote{\DUrole{notation}{let fix {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in}}} stands for
\sphinxcode{\sphinxupquote{\DUrole{notation}{let {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := fix {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in}}}. The same applies for co-fixpoints.


\subsection{The Vernacular}
\label{\detokenize{language/gallina-specification-language:the-vernacular}}\label{\detokenize{language/gallina-specification-language:vernacular}}

\begin{productionlist}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-sentence}}\production{sentence}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-assumption}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assumption}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{definition}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-inductive}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inductive}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fixpoint}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-assertion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assertion}}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{proof}}}}}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-assumption}}\production{assumption}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-assumption-keyword}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assumption\_keyword}}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-assums}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assums}}}}}.}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-assumption_keyword}}\production{assumption\_keyword}{ Axiom \textbar{} Conjecture}
\productioncont{ \textbar{} Parameter \textbar{} Parameters}
\productioncont{ \textbar{} Variable \textbar{} Variables}
\productioncont{ \textbar{} Hypothesis \textbar{} Hypotheses}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-assums}}\production{assums}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} … {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} ( {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} … {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} ) … ( {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} … {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} )}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-definition}}\production{definition}{ {[}Local{]} Definition {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}}{]} {[}: {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}{]} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} .}
\productioncont{ \textbar{} Let {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}}{]} {[}: {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}{]} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} .}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-inductive}}\production{inductive}{ Inductive {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ind-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ind\_body}}}}} with … with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ind-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ind\_body}}}}} .}
\productioncont{ \textbar{} CoInductive {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ind-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ind\_body}}}}} with … with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ind-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ind\_body}}}}} .}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-ind_body}}\production{ind\_body}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}}{]} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} :=}
\productioncont{ {[}{[}\textbar{}{]} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}}{]} {[}:{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}{]} \textbar{} … \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}}{]} {[}:{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}{]}{]}}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-fixpoint}}\production{fixpoint}{ Fixpoint {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-fix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fix\_body}}}}} with … with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-fix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fix\_body}}}}} .}
\productioncont{ \textbar{} CoFixpoint {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-cofix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cofix\_body}}}}} with … with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-cofix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cofix\_body}}}}} .}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-assertion}}\production{assertion}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-assertion-keyword}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assertion\_keyword}}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}}{]} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} .}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-assertion_keyword}}\production{assertion\_keyword}{ Theorem \textbar{} Lemma}
\productioncont{ \textbar{} Remark \textbar{} Fact}
\productioncont{ \textbar{} Corollary \textbar{} Proposition}
\productioncont{ \textbar{} Definition \textbar{} Example}
\phantomsection\label{\detokenize{language/gallina-specification-language:grammar-token-proof}}\production{proof}{ Proof . … Qed .}
\productioncont{ \textbar{} Proof . … Defined .}
\productioncont{ \textbar{} Proof . … Admitted .}
\end{productionlist}


This grammar describes \sphinxstyleemphasis{The Vernacular} which is the language of
commands of Gallina. A sentence of the vernacular language, like in
many natural languages, begins with a capital letter and ends with a
dot.

The different kinds of command are described hereafter. They all suppose
that the terms occurring in the sentences are well-typed.


\subsubsection{Assumptions}
\label{\detokenize{language/gallina-specification-language:assumptions}}\label{\detokenize{language/gallina-specification-language:gallina-assumptions}}
Assumptions extend the environment with axioms, parameters, hypotheses
or variables. An assumption binds an {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} to a {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}. It is accepted
by Coq if and only if this {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} is a correct type in the environment
preexisting the declaration and if {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} was not previously defined in
the same module. This {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} is considered to be the type (or
specification, or statement) assumed by {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} and we say that {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
has type {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}.

\phantomsection\label{\detokenize{language/gallina-specification-language:axiom}}\index{Parameter (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmd.parameter}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Parameter~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
This command links {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} to the name {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} as its specification in
the global context. The fact asserted by {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} is thus assumed as a
postulate.
\index{"@ident already exists. (Axiom) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:exn.ident-already-exists-axiom}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~already~exists.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Parameter~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
Adds several parameters with specification {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Parameter \DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~)}\DUrole{notation-sup}{+}}}}}}
Adds blocks of parameters with different specifications.

\end{fulllineitems}

\index{Local Parameter (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.local-parameter}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Parameter~\DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~)}\DUrole{notation-sup}{+}}}}}}
Such parameters are never made accessible through their unqualified name by
{\hyperref[\detokenize{language/gallina-extensions:coq:cmd.import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} and its variants. You have to explicitly give their fully
qualified name to refer to them.

\end{fulllineitems}

\index{Parameters (cmdv)}\index{Axiom (cmdv)}\index{Axioms (cmdv)}\index{Conjecture (cmdv)}\index{Conjectures (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.parameters}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Local}\DUrole{notation-sup}{?}}~Parameters~\DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~)}\DUrole{notation-sup}{+}}}}}}\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.axiom}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Local}\DUrole{notation-sup}{?}}~Axiom~\DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~)}\DUrole{notation-sup}{+}}}}}}\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.axioms}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Local}\DUrole{notation-sup}{?}}~Axioms~\DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~)}\DUrole{notation-sup}{+}}}}}}\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.conjecture}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Local}\DUrole{notation-sup}{?}}~Conjecture~\DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~)}\DUrole{notation-sup}{+}}}}}}\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.conjectures}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Local}\DUrole{notation-sup}{?}}~Conjectures~\DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~)}\DUrole{notation-sup}{+}}}}}}
These variants are synonyms of \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Local}\DUrole{notation-sup}{?}} Parameter \DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}} )}\DUrole{notation-sup}{+}}}}}.

\end{fulllineitems}


\end{fulllineitems}

\index{Variable (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmd.variable}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Variable~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
This command links {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} to the name {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} in the context of
the current section (see Section {\hyperref[\detokenize{language/gallina-extensions:section-mechanism}]{\sphinxcrossref{\DUrole{std,std-ref}{Section mechanism}}}} for a description of
the section mechanism). When the current section is closed, name {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
will be unknown and every object using this variable will be explicitly
parametrized (the variable is \sphinxstyleemphasis{discharged}). Using the {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.variable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variable}}}}} command out
of any section is equivalent to using {\hyperref[\detokenize{language/gallina-specification-language:coq:cmdv.local-parameter}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Local Parameter}}}}}.
\index{"@ident already exists. (Variable) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:exn.ident-already-exists-variable}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~already~exists.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Variable~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Links {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} to each {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Variable \DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~)}\DUrole{notation-sup}{+}}}}}}
Adds blocks of variables with different specifications.

\end{fulllineitems}

\index{Variables (cmdv)}\index{Hypothesis (cmdv)}\index{Hypotheses (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.variables}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Variables \DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}\DUrole{notation-sup}{+}}}}}}\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.hypothesis}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hypothesis \DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}\DUrole{notation-sup}{+}}}}}}\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.hypotheses}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hypotheses \DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}\DUrole{notation-sup}{+}}}}}}
These variants are synonyms of \sphinxcode{\sphinxupquote{\DUrole{notation}{Variable \DUrole{repeat-wrapper}{\DUrole{repeat}{( \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}\DUrole{notation-sup}{+}}}}}.

\end{fulllineitems}


\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}
It is advised to use the commands {\hyperref[\detokenize{language/gallina-specification-language:coq:cmdv.axiom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Axiom}}}}}, {\hyperref[\detokenize{language/gallina-specification-language:coq:cmdv.conjecture}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Conjecture}}}}} and
{\hyperref[\detokenize{language/gallina-specification-language:coq:cmdv.hypothesis}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hypothesis}}}}} (and their plural forms) for logical postulates (i.e. when
the assertion {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} is of sort \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}}), and to use the commands
{\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.parameter}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Parameter}}}}} and {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.variable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variable}}}}} (and their plural forms) in other cases
(corresponding to the declaration of an abstract mathematical entity).
\end{sphinxadmonition}


\subsubsection{Definitions}
\label{\detokenize{language/gallina-specification-language:definitions}}\label{\detokenize{language/gallina-specification-language:gallina-definitions}}
Definitions extend the environment with associations of names to terms.
A definition can be seen as a way to give a meaning to a name or as a
way to abbreviate a term. In any case, the name can later be replaced at
any time by its definition.

The operation of unfolding a name into its definition is called
\(\delta\)-conversion (see Section {\hyperref[\detokenize{language/cic:delta-reduction}]{\sphinxcrossref{\DUrole{std,std-ref}{\(\delta\)-reduction}}}}). A
definition is accepted by the system if and only if the defined term is
well-typed in the current context of the definition and if the name is
not already used. The name defined by the definition is called a
\sphinxstyleemphasis{constant} and the term it refers to is its \sphinxstyleemphasis{body}. A definition has a
type which is the type of its body.

A formal presentation of constants and environments is given in
Section {\hyperref[\detokenize{language/cic:typing-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{Typing rules}}}}.
\index{Definition (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmd.definition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Definition~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This command binds {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} to the name {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} in the environment,
provided that {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} is well-typed.
\index{"@ident already exists. (Definition) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:exn.ident-already-exists-definition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~already~exists.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Definition~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This variant checks that the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} is definitionally equal to
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}, and registers {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} as being of type
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}, and bound to value {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.
\index{The term ‘term’ has type ‘type’ while it is expected to have type ‘type’' (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:exn.the-term-term-has-type-type-while-it-is-expected-to-have-type-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~term~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~has~type~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~while~it~is~expected~to~have~type~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}'.}}}}
\end{fulllineitems}


\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Definition~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{Definition {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : forall {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} := fun {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}} =\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}

\index{Local Definition (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.local-definition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Definition~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Such definitions are never made accessible through their
unqualified name by {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} and its variants.
You have to explicitly give their fully qualified name to refer to them.

\end{fulllineitems}

\index{Example (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.example}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Local}\DUrole{notation-sup}{?}}~Example~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This is equivalent to {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}}.

\end{fulllineitems}


\end{fulllineitems}



\sphinxstrong{See also:}


{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}}, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Transparent}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unfold}}}}}.


\index{Let (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmd.let}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Let~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This command binds the value {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} to the name {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} in the
environment of the current section. The name {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} disappears when the
current section is eventually closed, and all persistent objects (such
as theorems) defined within the section and depending on {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} are
prefixed by the let-in definition \sphinxcode{\sphinxupquote{\DUrole{notation}{let {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in}}}.
Using the {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.let}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Let}}}}} command out of any section is equivalent to using
{\hyperref[\detokenize{language/gallina-specification-language:coq:cmdv.local-definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Local Definition}}}}}.
\index{"@ident already exists. (Let) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:exn.ident-already-exists-let}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~already~exists.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Let~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}

\index{Let Fixpoint (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.let-fixpoint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Let~Fixpoint~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-fix-body}]{\sphinxcrossref{\DUrole{hole}{fix\_body}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-fix-body}]{\sphinxcrossref{\DUrole{hole}{fix\_body}}}}}\DUrole{notation-sup}{*}}}}}}
\end{fulllineitems}

\index{Let CoFixpoint (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.let-cofixpoint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Let~CoFixpoint~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-cofix-body}]{\sphinxcrossref{\DUrole{hole}{cofix\_body}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-cofix-body}]{\sphinxcrossref{\DUrole{hole}{cofix\_body}}}}}\DUrole{notation-sup}{*}}}}}}
\end{fulllineitems}


\end{fulllineitems}



\sphinxstrong{See also:}


Section {\hyperref[\detokenize{language/gallina-extensions:section-mechanism}]{\sphinxcrossref{\DUrole{std,std-ref}{Section mechanism}}}}, commands {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}},
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Transparent}}}}}, and tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unfold}}}}}.




\subsubsection{Inductive definitions}
\label{\detokenize{language/gallina-specification-language:inductive-definitions}}\label{\detokenize{language/gallina-specification-language:gallina-inductive-definitions}}
We gradually explain simple inductive types, simple annotated inductive
types, simple parametric inductive types, mutually inductive types. We
explain also co-inductive types.


\paragraph{Simple inductive types}
\label{\detokenize{language/gallina-specification-language:simple-inductive-types}}\index{Inductive (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmd.inductive}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Inductive~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}}}\DUrole{notation-sup}{?}}~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{*}}}}}}
This command defines a simple inductive type and its constructors.
The first {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is the name of the inductively defined type
and {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-sort}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{sort}}}}} is the universe where it lives. The next {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}s
are the names of its constructors and {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} their respective types.
Depending on the universe where the inductive type {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} lives
(e.g. its type {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-sort}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{sort}}}}}), Coq provides a number of destructors.
Destructors are named {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\sphinxcode{\sphinxupquote{\_ind}}, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\sphinxcode{\sphinxupquote{\_rec}}
or {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\sphinxcode{\sphinxupquote{\_rect}} which respectively correspond to elimination
principles on \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}}, \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}} and \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}}.
The type of the destructors expresses structural induction/recursion
principles over objects of type {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.
The constant {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\sphinxcode{\sphinxupquote{\_ind}} is always provided,
whereas {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\sphinxcode{\sphinxupquote{\_rec}} and {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}\sphinxcode{\sphinxupquote{\_rect}} can be
impossible to derive (for example, when {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is a proposition).
\index{Non strictly positive occurrence of ‘ident’ in ‘type’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:exn.non-strictly-positive-occurrence-of-ident-in-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Non~strictly~positive~occurrence~of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}.}}}}
The types of the constructors have to satisfy a \sphinxstyleemphasis{positivity condition}
(see Section {\hyperref[\detokenize{language/cic:positivity}]{\sphinxcrossref{\DUrole{std,std-ref}{Positivity Condition}}}}). This condition ensures the soundness of
the inductive definition.

\end{fulllineitems}

\index{The conclusion of ‘type’ is not valid!it must be built from ‘ident’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:exn.the-conclusion-of-type-is-not-valid-it-must-be-built-from-ident}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~conclusion~of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~is~not~valid;~it~must~be~built~from~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
The conclusion of the type of the constructors must be the inductive type
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} being defined (or {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} applied to arguments in
the case of annotated inductive types — cf. next section).

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

The set of natural numbers is defined as:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{k+kt}{nat} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{:} \PYG{k+kt}{nat}
\PYG{o}{\textbar{}} \PYG{n}{S} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{k+kt}{nat} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{nat\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{nat\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{nat\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

The type nat is defined as the least \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}} containing \sphinxcode{\sphinxupquote{\DUrole{name}{O}}} and closed by
the \sphinxcode{\sphinxupquote{\DUrole{name}{S}}} constructor. The names \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{nat}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{O}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{S}}} are added to the
environment.

Now let us have a look at the elimination principles. They are three of them:
\sphinxcode{\sphinxupquote{\DUrole{name}{nat\_ind}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{nat\_rec}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{nat\_rect}}}. The type of \sphinxcode{\sphinxupquote{\DUrole{name}{nat\_ind}}} is:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{nat\PYGZus{}ind}\PYG{o}{.}
    \PYG{n}{nat\PYGZus{}ind}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{,}
           \PYG{n}{P} \PYG{n}{O} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{P} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{P} \PYG{n}{n}
\end{sphinxVerbatim}

This is the well known structural induction principle over natural
numbers, i.e. the second-order form of Peano’s induction principle. It
allows proving some universal property of natural numbers (\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall}
\DUrole{name}{n}\DUrole{operator}{:}\DUrole{keyword,type}{nat}\DUrole{operator}{,} \DUrole{name}{P} \DUrole{name}{n}}}) by induction on \sphinxcode{\sphinxupquote{\DUrole{name}{n}}}.

The types of \sphinxcode{\sphinxupquote{\DUrole{name}{nat\_rec}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{nat\_rect}}} are similar, except that they pertain
to \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{P}\DUrole{operator}{:}\DUrole{keyword,type}{nat}\DUrole{operator}{-\textgreater{}}\DUrole{keyword,namespace}{Set}\DUrole{operator}{)}}} and \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{P}\DUrole{operator}{:}\DUrole{keyword,type}{nat}\DUrole{operator}{-\textgreater{}}\DUrole{keyword,type}{Type}\DUrole{operator}{)}}} respectively. They correspond to
primitive induction principles (allowing dependent types) respectively
over sorts \sphinxcode{\sphinxupquote{Set}} and \sphinxcode{\sphinxupquote{Type}}.
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Inductive~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}}}\DUrole{notation-sup}{?}}~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\textbar{}}}}}}}
Constructors {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}s can come with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}} in which case,
the actual type of the constructor is \sphinxcode{\sphinxupquote{\DUrole{notation}{forall {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}.

In the case where inductive types have no annotations (next section
gives an example of such annotations), a constructor can be defined
by only giving the type of its arguments.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{k+kt}{nat} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{O} \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}


\end{fulllineitems}



\paragraph{Simple annotated inductive types}
\label{\detokenize{language/gallina-specification-language:simple-annotated-inductive-types}}
In an annotated inductive types, the universe where the inductive type
is defined is no longer a simple sort, but what is called an arity,
which is a type whose conclusion is a sort.

\begin{sphinxadmonition}{note}{Example}

As an example of annotated inductive types, let us define the
\sphinxcode{\sphinxupquote{\DUrole{name}{even}}} predicate:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{even} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{even\PYGZus{}0} \PYG{o}{:} \PYG{n}{even} \PYG{n}{O}
\PYG{o}{\textbar{}} \PYG{n}{even\PYGZus{}SS} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{even} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{even} \PYG{o}{(}\PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{even} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{even\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

The type \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{nat}\DUrole{operator}{-\textgreater{}}\DUrole{keyword,type}{Prop}}} means that even is a unary predicate (inductively
defined) over natural numbers. The type of its two constructors are the
defining clauses of the predicate even. The type of \sphinxcode{\sphinxupquote{\DUrole{name}{even\_ind}}} is:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{even\PYGZus{}ind}\PYG{o}{.}
    \PYG{n}{even\PYGZus{}ind}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{,}
           \PYG{n}{P} \PYG{n}{O} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{even} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{(}\PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{even} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n}
\end{sphinxVerbatim}

From a mathematical point of view it asserts that the natural numbers satisfying
the predicate even are exactly in the smallest set of naturals satisfying the
clauses \sphinxcode{\sphinxupquote{\DUrole{name}{even\_0}}} or \sphinxcode{\sphinxupquote{\DUrole{name}{even\_SS}}}. This is why, when we want to prove any
predicate \sphinxcode{\sphinxupquote{\DUrole{name}{P}}} over elements of \sphinxcode{\sphinxupquote{\DUrole{name}{even}}}, it is enough to prove it for \sphinxcode{\sphinxupquote{\DUrole{name}{O}}}
and to prove that if any natural number \sphinxcode{\sphinxupquote{\DUrole{name}{n}}} satisfies \sphinxcode{\sphinxupquote{\DUrole{name}{P}}} its double
successor \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{S} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{n}\DUrole{operator}{))}}} satisfies also \sphinxcode{\sphinxupquote{\DUrole{name}{P}}}. This is indeed analogous to the
structural induction principle we got for \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{nat}}}.
\end{sphinxadmonition}


\paragraph{Parametrized inductive types}
\label{\detokenize{language/gallina-specification-language:parametrized-inductive-types}}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Inductive~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{*}}}}}}
In the previous example, each constructor introduces a different
instance of the predicate \sphinxcode{\sphinxupquote{\DUrole{name}{even}}}. In some cases, all the constructors
introduce the same generic instance of the inductive definition, in
which case, instead of an annotation, we use a context of parameters
which are {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}} shared by all the constructors of the definition.

Parameters differ from inductive type annotations in the fact that the
conclusion of each type of constructor invoke the inductive type with
the same values of parameters as its specification.

\begin{sphinxadmonition}{note}{Example}

A typical example is the definition of polymorphic lists:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{k+kt}{list} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{.}
\end{sphinxVerbatim}

In the type of \sphinxcode{\sphinxupquote{\DUrole{name}{nil}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{cons}}}, we write \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{keyword,type}{list} \DUrole{name}{A}\DUrole{operator}{)}}} and not
just \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{list}}}. The constructors \sphinxcode{\sphinxupquote{\DUrole{name}{nil}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{cons}}} will have respectively
types:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{nil}\PYG{o}{.}
    \PYG{n}{nil}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{,} \PYG{k+kt}{list} \PYG{n}{A}

\PYG{k+kn}{Check} \PYG{n}{cons}\PYG{o}{.}
    \PYG{n}{cons}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{n}{A}
\end{sphinxVerbatim}

Types of destructors are also quantified with \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{A}\DUrole{operator}{:}\DUrole{keyword,namespace}{Set}\DUrole{operator}{)}}}.

Once again, it is possible to specify only the type of the arguments
of the constructors, and to omit the type of the conclusion:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{k+kt}{list} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{nil} \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}\begin{itemize}
\item {} 
It is possible in the type of a constructor, to
invoke recursively the inductive definition on an argument which is not
the parameter itself.

One can define :

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{list2} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{nil2} \PYG{o}{:} \PYG{n}{list2} \PYG{n}{A}
\PYG{o}{\textbar{}} \PYG{n}{cons2} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list2} \PYG{o}{(}\PYG{n}{A}\PYG{o}{*}\PYG{n}{A}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{list2} \PYG{n}{A}\PYG{o}{.}
    \PYG{n}{list2} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list2\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list2\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list2\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

that can also be written by specifying only the type of the arguments:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{list2} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{nil2} \PYG{o}{\textbar{}} \PYG{n}{cons2} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{list2} \PYG{o}{(}\PYG{n}{A}\PYG{o}{*}\PYG{n}{A}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{list2} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list2\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list2\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list2\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

But the following definition will give an error:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Inductive} \PYG{n}{listw} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{nilw} \PYG{o}{:} \PYG{n}{listw} \PYG{o}{(}\PYG{n}{A}\PYG{o}{*}\PYG{n}{A}\PYG{o}{)}
\PYG{o}{\textbar{}} \PYG{n}{consw} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{listw} \PYG{o}{(}\PYG{n}{A}\PYG{o}{*}\PYG{n}{A}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{listw} \PYG{o}{(}\PYG{n}{A}\PYG{o}{*}\PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{Last} \PYG{n}{occurrence} \PYG{k}{of} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{listw}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{must} \PYG{k}{have} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{A}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{as} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument} \PYG{k}{in}
     \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{listw (A * A)\PYGZpc{}type}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

because the conclusion of the type of constructors should be \sphinxcode{\sphinxupquote{\DUrole{name}{listw} \DUrole{name}{A}}}
in both cases.

\item {} 
A parametrized inductive definition can be defined using annotations
instead of parameters but it will sometimes give a different (bigger)
sort for the inductive definition and will produce a less convenient
rule for case elimination.

\end{itemize}
\end{sphinxadmonition}


\sphinxstrong{See also:}


Section {\hyperref[\detokenize{language/cic:inductive-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Inductive Definitions}}}} and the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}} tactic.




\paragraph{Variants}
\label{\detokenize{language/gallina-specification-language:variants}}\index{Variant (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmd.variant}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Variant~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{*}}}}}}
The {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.variant}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variant}}}}} command is identical to the {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.inductive}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Inductive}}}}} command, except
that it disallows recursive definition of types (for instance, lists cannot
be defined using {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.variant}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variant}}}}}). No induction scheme is generated for
this variant, unless option {\hyperref[\detokenize{user-extensions/proof-schemes:coq:flag.nonrecursive-elimination-schemes}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Nonrecursive Elimination Schemes}}}}} is on.
\index{The ‘num’ th argument of ‘ident’ must be ‘ident’ in ‘type’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:exn.the-num-th-argument-of-ident-must-be-ident-in-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~th~argument~of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~must~be~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}.}}}}
\end{fulllineitems}


\end{fulllineitems}



\paragraph{Mutually defined inductive types}
\label{\detokenize{language/gallina-specification-language:mutually-defined-inductive-types}}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Inductive~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\textbar{}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\textbar{}}}}\DUrole{notation-sup}{*}}}}}}
This variant allows defining a block of mutually inductive types.
It has the same semantics as the above {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.inductive}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Inductive}}}}} definition for each
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}. All {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} are simultaneously added to the environment.
Then well-typing of constructors can be checked. Each one of the {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
can be used on its own.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Inductive~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\textbar{}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\textbar{}}}}\DUrole{notation-sup}{*}}}}}}
In this variant, the inductive definitions are parametrized
with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}}. However, parameters correspond to a local context
in which the whole set of inductive declarations is done. For this
reason, the parameters must be strictly the same for each inductive types.

\end{fulllineitems}


\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

The typical example of a mutual inductive data type is the one for trees and
forests. We assume given two types \sphinxcode{\sphinxupquote{\DUrole{name}{A}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{B}}} as variables. It can
be declared the following way.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variables} \PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{tree} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{node} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{tree}

\PYG{k}{with} \PYG{n}{forest} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{leaf} \PYG{o}{:} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{tree} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest}\PYG{o}{.}
\end{sphinxVerbatim}

This declaration generates automatically six induction principles. They are
respectively called \sphinxcode{\sphinxupquote{\DUrole{name}{tree\_rec}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{tree\_ind}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{tree\_rect}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{forest\_rec}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{forest\_ind}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{forest\_rect}}}. These ones are not the most
general ones but are just the induction principles corresponding to each
inductive part seen as a single inductive definition.

To illustrate this point on our example, we give the types of \sphinxcode{\sphinxupquote{\DUrole{name}{tree\_rec}}}
and \sphinxcode{\sphinxupquote{\DUrole{name}{forest\_rec}}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{tree\PYGZus{}rec}\PYG{o}{.}
    \PYG{n}{tree\PYGZus{}rec}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{P} \PYG{o}{:} \PYG{n}{tree} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{,}
           \PYG{o}{(}\PYG{k}{forall} \PYG{o}{(}\PYG{n}{a} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f} \PYG{o}{:} \PYG{n}{forest}\PYG{o}{)}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{node} \PYG{n}{a} \PYG{n}{f}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{t} \PYG{o}{:} \PYG{n}{tree}\PYG{o}{,} \PYG{n}{P} \PYG{n}{t}

\PYG{k+kn}{Check} \PYG{n}{forest\PYGZus{}rec}\PYG{o}{.}
    \PYG{n}{forest\PYGZus{}rec}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{P} \PYG{o}{:} \PYG{n}{forest} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{,}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{b} \PYG{o}{:} \PYG{n}{B}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{leaf} \PYG{n}{b}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{o}{(}\PYG{n}{t} \PYG{o}{:} \PYG{n}{tree}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f0} \PYG{o}{:} \PYG{n}{forest}\PYG{o}{)}\PYG{o}{,} \PYG{n}{P} \PYG{n}{f0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{(}\PYG{n}{cons} \PYG{n}{t} \PYG{n}{f0}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{k}{forall} \PYG{n}{f1} \PYG{o}{:} \PYG{n}{forest}\PYG{o}{,} \PYG{n}{P} \PYG{n}{f1}
\end{sphinxVerbatim}

Assume we want to parametrize our mutual inductive definitions with the
two type variables \sphinxcode{\sphinxupquote{\DUrole{name}{A}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{B}}}, the declaration should be
done the following way:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{tree} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{node} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest} \PYG{n}{A} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{tree} \PYG{n}{A} \PYG{n}{B}

\PYG{k}{with} \PYG{n}{forest} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{leaf} \PYG{o}{:} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest} \PYG{n}{A} \PYG{n}{B}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{tree} \PYG{n}{A} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest} \PYG{n}{A} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest} \PYG{n}{A} \PYG{n}{B}\PYG{o}{.}
\end{sphinxVerbatim}

Assume we define an inductive definition inside a section
(cf. {\hyperref[\detokenize{language/gallina-extensions:section-mechanism}]{\sphinxcrossref{\DUrole{std,std-ref}{Section mechanism}}}}). When the section is closed, the variables
declared in the section and occurring free in the declaration are added as
parameters to the inductive definition.
\end{sphinxadmonition}


\sphinxstrong{See also:}


A generic command {\hyperref[\detokenize{user-extensions/proof-schemes:coq:cmd.scheme}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Scheme}}}}} is useful to build automatically various
mutual induction principles.




\paragraph{Co-inductive types}
\label{\detokenize{language/gallina-specification-language:co-inductive-types}}\label{\detokenize{language/gallina-specification-language:coinductive-types}}
The objects of an inductive type are well-founded with respect to the
constructors of the type. In other words, such objects contain only a
\sphinxstyleemphasis{finite} number of constructors. Co-inductive types arise from relaxing
this condition, and admitting types whose objects contain an infinity of
constructors. Infinite objects are introduced by a non-ending (but
effective) process of construction, defined in terms of the constructors
of the type.
\index{CoInductive (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmd.coinductive}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{CoInductive~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{*}}}}}}
This command introduces a co-inductive type.
The syntax of the command is the same as the command {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.inductive}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Inductive}}}}}.
No principle of induction is derived from the definition of a co-inductive
type, since such principles only make sense for inductive types.
For co-inductive types, the only elimination principle is case analysis.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

An example of a co-inductive type is the type of infinite sequences of
natural numbers, usually called streams.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{CoInductive} \PYG{n}{Stream} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{Seq} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Stream} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Stream}\PYG{o}{.}
\end{sphinxVerbatim}

The usual destructors on streams \sphinxcode{\sphinxupquote{\DUrole{name}{hd}\DUrole{operator}{:}\DUrole{name}{Stream}\DUrole{operator}{-\textgreater{}}\DUrole{keyword,type}{nat}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{tl}\DUrole{operator}{:}\DUrole{name}{Str}\DUrole{operator}{-\textgreater{}}\DUrole{name}{Str}}}
can be defined as follows:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{hd} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{Stream}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{let} \PYG{o}{(}\PYG{n}{a}\PYG{o}{,}\PYG{n}{s}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{x} \PYG{k}{in} \PYG{n}{a}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{tl} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{Stream}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{let} \PYG{o}{(}\PYG{n}{a}\PYG{o}{,}\PYG{n}{s}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{x} \PYG{k}{in} \PYG{n}{s}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Definition of co-inductive predicates and blocks of mutually
co-inductive definitions are also allowed.

\begin{sphinxadmonition}{note}{Example}

An example of a co-inductive predicate is the extensional equality on
streams:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{CoInductive} \PYG{n}{EqSt} \PYG{o}{:} \PYG{n}{Stream} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Stream} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
  \PYG{n}{eqst} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{s1} \PYG{n}{s2}\PYG{o}{:}\PYG{n}{Stream}\PYG{o}{,}
           \PYG{n}{hd} \PYG{n}{s1} \PYG{o}{=} \PYG{n}{hd} \PYG{n}{s2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{EqSt} \PYG{o}{(}\PYG{n}{tl} \PYG{n}{s1}\PYG{o}{)} \PYG{o}{(}\PYG{n}{tl} \PYG{n}{s2}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{EqSt} \PYG{n}{s1} \PYG{n}{s2}\PYG{o}{.}
\end{sphinxVerbatim}

In order to prove the extensional equality of two streams \sphinxcode{\sphinxupquote{\DUrole{name}{s1}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{s2}}}
we have to construct an infinite proof of equality, that is, an infinite
object of type \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{EqSt} \DUrole{name}{s1} \DUrole{name}{s2}\DUrole{operator}{)}}}. We will see how to introduce infinite
objects in Section {\hyperref[\detokenize{language/gallina-specification-language:cofixpoint}]{\sphinxcrossref{\DUrole{std,std-ref}{Definitions of recursive objects in co-inductive types}}}}.
\end{sphinxadmonition}


\subsubsection{Definition of recursive functions}
\label{\detokenize{language/gallina-specification-language:definition-of-recursive-functions}}

\paragraph{Definition of functions by recursion over inductive objects}
\label{\detokenize{language/gallina-specification-language:definition-of-functions-by-recursion-over-inductive-objects}}
This section describes the primitive form of definition by recursion over
inductive objects. See the {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}} command for more advanced
constructions.

\phantomsection\label{\detokenize{language/gallina-specification-language:fixpoint}}\index{Fixpoint (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmd.fixpoint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Fixpoint~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{curlies}{\{struct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This command allows defining functions by pattern matching over inductive
objects using a fixed point construction. The meaning of this declaration is
to define {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} a recursive function with arguments specified by
the {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}} such that {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} applied to arguments
corresponding to these {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}} has type {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}, and is
equivalent to the expression {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. The type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is
consequently \sphinxcode{\sphinxupquote{\DUrole{notation}{forall {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} and its value is equivalent
to \sphinxcode{\sphinxupquote{\DUrole{notation}{fun {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}} =\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

To be accepted, a {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} definition has to satisfy some syntactical
constraints on a special argument called the decreasing argument. They
are needed to ensure that the {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} definition always terminates.
The point of the \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{struct {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\}}}}} annotation is to let the user tell the
system which argument decreases along the recursive calls.

The \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{curlies}{\{struct {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\}}}}} annotation may be left implicit, in this case the
system tries successively arguments from left to right until it finds one
that satisfies the decreasing condition.

\begin{sphinxadmonition}{note}{Note:}\begin{itemize}
\item {} 
Some fixpoints may have several arguments that fit as decreasing
arguments, and this choice influences the reduction of the fixpoint.
Hence an explicit annotation must be used if the leftmost decreasing
argument is not the desired one. Writing explicit annotations can also
speed up type checking of large mutual fixpoints.

\item {} 
In order to keep the strong normalization property, the fixed point
reduction will only be performed when the argument in position of the
decreasing argument (which type should be in an inductive definition)
starts with a constructor.

\end{itemize}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

One can define the addition function as :

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{add} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
\PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{add} \PYG{n}{p} \PYG{n}{m}\PYG{o}{)}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{add} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{add} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}

The match operator matches a value (here \sphinxcode{\sphinxupquote{\DUrole{name}{n}}}) with the various
constructors of its (inductive) type. The remaining arguments give the
respective values to be returned, as functions of the parameters of the
corresponding constructor. Thus here when \sphinxcode{\sphinxupquote{\DUrole{name}{n}}} equals \sphinxcode{\sphinxupquote{\DUrole{name}{O}}} we return
\sphinxcode{\sphinxupquote{\DUrole{name}{m}}}, and when \sphinxcode{\sphinxupquote{\DUrole{name}{n}}} equals \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{p}\DUrole{operator}{)}}} we return \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{S} \DUrole{operator}{(}\DUrole{name}{add} \DUrole{name}{p} \DUrole{name}{m}\DUrole{operator}{))}}}.

The match operator is formally described in
Section {\hyperref[\detokenize{language/cic:match-construction}]{\sphinxcrossref{\DUrole{std,std-ref}{The match ... with ... end construction}}}}.
The system recognizes that in the inductive call \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{add} \DUrole{name}{p} \DUrole{name}{m}\DUrole{operator}{)}}} the first
argument actually decreases because it is a \sphinxstyleemphasis{pattern variable} coming
from \sphinxcode{\sphinxupquote{\DUrole{keyword}{match} \DUrole{name}{n} \DUrole{keyword}{with}}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

The following definition is not correct and generates an error message:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Fixpoint} \PYG{n}{wrongplus} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{m} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{n}
\PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{wrongplus} \PYG{n}{n} \PYG{n}{p}\PYG{o}{)}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{Recursive} \PYG{n}{definition} \PYG{k}{of} \PYG{n}{wrongplus} \PYG{k}{is} \PYG{n}{ill}\PYG{o}{\PYGZhy{}}\PYG{n}{formed}\PYG{o}{.}
    \PYG{n}{In} \PYG{n}{environment}
    \PYG{n}{wrongplus} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
    \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
    \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
    \PYG{n}{p} \PYG{o}{:} \PYG{k+kt}{nat}
    \PYG{n}{Recursive} \PYG{n}{call} \PYG{n}{to} \PYG{n}{wrongplus} \PYG{n}{has} \PYG{n}{principal} \PYG{n}{argument} \PYG{n}{equal} \PYG{n}{to} 
    \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{n}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{instead} \PYG{k}{of} \PYG{n}{a} \PYG{n}{subterm} \PYG{k}{of} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{n}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    \PYG{n}{Recursive} \PYG{n}{definition} \PYG{k}{is}\PYG{o}{:}
    \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{fun n m : nat =\PYGZgt{} match m with}
\PYG{l+s+s2}{                      \textbar{} 0 =\PYGZgt{} n}
\PYG{l+s+s2}{                      \textbar{} S p =\PYGZgt{} S (wrongplus n p)}
\PYG{l+s+s2}{                      end}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

because the declared decreasing argument \sphinxcode{\sphinxupquote{\DUrole{name}{n}}} does not actually
decrease in the recursive call. The function computing the addition over
the second argument should rather be written:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{m}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{m} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{n}
\PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{n} \PYG{n}{p}\PYG{o}{)}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{plus} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{plus} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{2}\PYG{n}{nd} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

The recursive call may not only be on direct subterms of the recursive
variable \sphinxcode{\sphinxupquote{\DUrole{name}{n}}} but also on a deeper subterm and we can directly write
the function \sphinxcode{\sphinxupquote{\DUrole{name}{mod2}}} which gives the remainder modulo 2 of a natural
number.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{mod2} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{O}
\PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{p} \PYG{k}{with}
         \PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{n}{O}
         \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{q} \PYG{o}{=\PYGZgt{}} \PYG{n}{mod2} \PYG{n}{q}
         \PYG{k}{end}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{mod2} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{mod2} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Fixpoint~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{curlies}{\{struct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}}}}}
This variant allows defining simultaneously several mutual fixpoints.
It is especially useful when defining functions over mutually defined
inductive types.

\begin{sphinxadmonition}{note}{Example}

The size of trees and forests can be defined the following way:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{tree\PYGZus{}size} \PYG{o}{(}\PYG{n}{t}\PYG{o}{:}\PYG{n}{tree}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{t} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n}{node} \PYG{n}{a} \PYG{n}{f} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{forest\PYGZus{}size} \PYG{n}{f}\PYG{o}{)}
\PYG{k}{end}
\PYG{k}{with} \PYG{n}{forest\PYGZus{}size} \PYG{o}{(}\PYG{n}{f}\PYG{o}{:}\PYG{n}{forest}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{f} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n}{leaf} \PYG{n}{b} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{1}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{n}{t} \PYG{n}{f\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{o}{(}\PYG{n}{tree\PYGZus{}size} \PYG{n}{t} \PYG{o}{+} \PYG{n}{forest\PYGZus{}size} \PYG{n}{f\PYGZsq{}}\PYG{o}{)}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{tree\PYGZus{}size} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{forest\PYGZus{}size} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}size}\PYG{o}{,} \PYG{n}{forest\PYGZus{}size} \PYG{n}{are} \PYG{n}{recursively} \PYG{n}{defined}
    \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{respectively} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st}\PYG{o}{,} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{arguments}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}


\end{fulllineitems}



\paragraph{Definitions of recursive objects in co-inductive types}
\label{\detokenize{language/gallina-specification-language:definitions-of-recursive-objects-in-co-inductive-types}}\label{\detokenize{language/gallina-specification-language:cofixpoint}}\index{CoFixpoint (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmd.cofixpoint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{CoFixpoint~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This command introduces a method for constructing an infinite object of a
coinductive type. For example, the stream containing all natural numbers can
be introduced applying the following method to the number \sphinxcode{\sphinxupquote{\DUrole{name}{O}}} (see
Section {\hyperref[\detokenize{language/gallina-specification-language:coinductive-types}]{\sphinxcrossref{\DUrole{std,std-ref}{Co-inductive types}}}} for the definition of \sphinxcode{\sphinxupquote{\DUrole{name}{Stream}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{hd}}}
and \sphinxcode{\sphinxupquote{\DUrole{name}{tl}}}):

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{CoFixpoint} \PYG{n}{from} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{Stream} \PYG{o}{:=} \PYG{n}{Seq} \PYG{n}{n} \PYG{o}{(}\PYG{n}{from} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{from} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{from} \PYG{k}{is} \PYG{n}{corecursively} \PYG{n}{defined}
\end{sphinxVerbatim}

Oppositely to recursive ones, there is no decreasing argument in a
co-recursive definition. To be admissible, a method of construction must
provide at least one extra constructor of the infinite object for each
iteration. A syntactical guard condition is imposed on co-recursive
definitions in order to ensure this: each recursive call in the
definition must be protected by at least one constructor, and only by
constructors. That is the case in the former definition, where the single
recursive call of \sphinxcode{\sphinxupquote{\DUrole{name}{from}}} is guarded by an application of \sphinxcode{\sphinxupquote{\DUrole{name}{Seq}}}.
On the contrary, the following recursive function does not satisfy the
guard condition:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{CoFixpoint} \PYG{n}{filter} \PYG{o}{(}\PYG{n}{p}\PYG{o}{:}\PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{(}\PYG{n}{s}\PYG{o}{:}\PYG{n}{Stream}\PYG{o}{)} \PYG{o}{:} \PYG{n}{Stream} \PYG{o}{:=}
  \PYG{k}{if} \PYG{n}{p} \PYG{o}{(}\PYG{n}{hd} \PYG{n}{s}\PYG{o}{)} \PYG{k}{then} \PYG{n}{Seq} \PYG{o}{(}\PYG{n}{hd} \PYG{n}{s}\PYG{o}{)} \PYG{o}{(}\PYG{n}{filter} \PYG{n}{p} \PYG{o}{(}\PYG{n}{tl} \PYG{n}{s}\PYG{o}{)}\PYG{o}{)} \PYG{k}{else} \PYG{n}{filter} \PYG{n}{p} \PYG{o}{(}\PYG{n}{tl} \PYG{n}{s}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{Recursive} \PYG{n}{definition} \PYG{k}{of} \PYG{n}{filter} \PYG{k}{is} \PYG{n}{ill}\PYG{o}{\PYGZhy{}}\PYG{n}{formed}\PYG{o}{.}
    \PYG{n}{In} \PYG{n}{environment}
    \PYG{n}{filter} \PYG{o}{:} \PYG{o}{(}\PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Stream} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Stream}
    \PYG{n}{p} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{s} \PYG{o}{:} \PYG{n}{Stream}
    \PYG{n}{Unguarded} \PYG{n}{recursive} \PYG{n}{call} \PYG{k}{in} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{filter p (tl s)}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    \PYG{n}{Recursive} \PYG{n}{definition} \PYG{k}{is}\PYG{o}{:}
    \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{fun (p : nat \PYGZhy{}\PYGZgt{} bool) (s : Stream) =\PYGZgt{}}
\PYG{l+s+s2}{     if p (hd s) then Seq (hd s) (filter p (tl s)) else filter p (tl s)}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

The elimination of co-recursive definition is done lazily, i.e. the
definition is expanded only when it occurs at the head of an application
which is the argument of a case analysis expression. In any other
context, it is considered as a canonical expression which is completely
evaluated. We can test this using the command {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.eval}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Eval}}}}}, which computes
the normal forms of a term:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{o}{(}\PYG{n}{from} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{=} \PYG{o}{(}\PYG{k}{cofix} \PYG{n}{from} \PYG{o}{(}\PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{Stream} \PYG{o}{:=} \PYG{n}{Seq} \PYG{n}{n} \PYG{o}{(}\PYG{n}{from} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{n}{Stream}

\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{o}{(}\PYG{n}{hd} \PYG{o}{(}\PYG{n}{from} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{=} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{k+kt}{nat}

\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{o}{(}\PYG{n}{tl} \PYG{o}{(}\PYG{n}{from} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{=} \PYG{o}{(}\PYG{k}{cofix} \PYG{n}{from} \PYG{o}{(}\PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{Stream} \PYG{o}{:=} \PYG{n}{Seq} \PYG{n}{n} \PYG{o}{(}\PYG{n}{from} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)} \PYG{l+m+mi}{1}
         \PYG{o}{:} \PYG{n}{Stream}
\end{sphinxVerbatim}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{CoFixpoint~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}}}}}
As in the {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} command, it is possible to introduce a block of
mutually dependent methods.

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{Assertions and proofs}
\label{\detokenize{language/gallina-specification-language:assertions-and-proofs}}\label{\detokenize{language/gallina-specification-language:assertions}}
An assertion states a proposition (or a type) of which the proof (or an
inhabitant of the type) is interactively built using tactics. The interactive
proof mode is described in Chapter {\hyperref[\detokenize{proof-engine/proof-handling:proofhandling}]{\sphinxcrossref{\DUrole{std,std-ref}{Proof handling}}}} and the tactics in
Chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}}. The basic assertion command is:
\index{Theorem (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmd.theorem}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Theorem~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
After the statement is asserted, Coq needs a proof. Once a proof of
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} under the assumptions represented by {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}} is given and
validated, the proof is generalized into a proof of \sphinxcode{\sphinxupquote{\DUrole{notation}{forall {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} and
the theorem is bound to the name {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} in the environment.
\index{The term ‘term’ has type ‘type’ which should be Set, Prop or Type (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:exn.the-term-term-has-type-type-which-should-be-set-prop-or-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~term~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~has~type~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~which~should~be~Set,~Prop~or~Type.}}}}
\end{fulllineitems}

\index{"@ident already exists. (Theorem) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:exn.ident-already-exists-theorem}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~already~exists.}}}}
The name you provided is already defined. You have then to choose
another name.

\end{fulllineitems}

\index{Lemma (cmdv)}\index{Remark (cmdv)}\index{Fact (cmdv)}\index{Corollary (cmdv)}\index{Proposition (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.lemma}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Lemma~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.remark}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Remark~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.fact}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Fact~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.corollary}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Corollary~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}\phantomsection\label{\detokenize{language/gallina-specification-language:coq:cmdv.proposition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proposition~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
These commands are all synonyms of \sphinxcode{\sphinxupquote{\DUrole{notation}{Theorem {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}} : type}}}.

\end{fulllineitems}


\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Theorem~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{*}}}}}}
This command is useful for theorems that are proved by simultaneous induction
over a mutually inductive assumption, or that assert mutually dependent
statements in some mutual co-inductive type. It is equivalent to
{\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} or {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.cofixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{CoFixpoint}}}}} but using tactics to build the proof of
the statements (or the body of the specification, depending on the point of
view). The inductive or co-inductive types on which the induction or
coinduction has to be done is assumed to be non ambiguous and is guessed by
the system.

Like in a {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} or {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.cofixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{CoFixpoint}}}}} definition, the induction hypotheses
have to be used on \sphinxstyleemphasis{structurally smaller} arguments (for a {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}}) or
be \sphinxstyleemphasis{guarded by a constructor} (for a {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.cofixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{CoFixpoint}}}}}). The verification that
recursive proof arguments are correct is done only at the time of registering
the lemma in the environment. To know if the use of induction hypotheses is
correct at some time of the interactive development of a proof, use the
command {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.guarded}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Guarded}}}}}.

The command can be used also with {\hyperref[\detokenize{language/gallina-specification-language:coq:cmdv.lemma}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Lemma}}}}}, {\hyperref[\detokenize{language/gallina-specification-language:coq:cmdv.remark}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remark}}}}}, etc. instead of
{\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.theorem}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Theorem}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Definition~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
This allows defining a term of type {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} using the proof editing
mode. It behaves as {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.theorem}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Theorem}}}}} but is intended to be used in conjunction with
{\hyperref[\detokenize{proof-engine/proof-handling:coq:cmdv.defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}} in order to define a constant of which the computational
behavior is relevant.

The command can be used also with {\hyperref[\detokenize{language/gallina-specification-language:coq:cmdv.example}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Example}}}}} instead of {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}}.


\sphinxstrong{See also:}


{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}}, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Transparent}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unfold}}}}}.



\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Let~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
Like \sphinxcode{\sphinxupquote{\DUrole{notation}{Definition {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}} except that the definition is
turned into a let-in definition generalized over the declarations depending
on it after closing the current section.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Fixpoint~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{*}}}}}}
This generalizes the syntax of {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} so that one or more bodies
can be defined interactively using the proof editing mode (when a
body is omitted, its type is mandatory in the syntax). When the block
of proofs is completed, it is intended to be ended by {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmdv.defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{CoFixpoint~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{*}}}}}}
This generalizes the syntax of {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.cofixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{CoFixpoint}}}}} so that one or more bodies
can be defined interactively using the proof editing mode.

\end{fulllineitems}


A proof starts by the keyword {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof}}}}}. Then Coq enters the proof editing mode
until the proof is completed. The proof editing mode essentially contains
tactics that are described in chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}}. Besides tactics, there
are commands to manage the proof editing mode. They are described in Chapter
{\hyperref[\detokenize{proof-engine/proof-handling:proofhandling}]{\sphinxcrossref{\DUrole{std,std-ref}{Proof handling}}}}.

When the proof is completed it should be validated and put in the environment
using the keyword {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}}.

\begin{sphinxadmonition}{note}{Note:}\begin{enumerate}
\def\theenumi{\arabic{enumi}}
\def\labelenumi{\theenumi .}
\makeatletter\def\p@enumii{\p@enumi \theenumi .}\makeatother
\item {} 
Several statements can be simultaneously asserted.

\item {} 
Not only other assertions but any vernacular command can be given
while in the process of proving a given assertion. In this case, the
command is understood as if it would have been given before the
statements still to be proved. Nonetheless, this practice is discouraged
and may stop working in future versions.

\item {} 
Proofs ended by {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} are declared opaque. Their content cannot be
unfolded (see {\hyperref[\detokenize{proof-engine/tactics:performingcomputations}]{\sphinxcrossref{\DUrole{std,std-ref}{Performing computations}}}}), thus
realizing some form of \sphinxstyleemphasis{proof-irrelevance}. To be able to unfold a
proof, the proof should be ended by {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmdv.defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}}.

\item {} 
{\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof}}}}} is recommended but can currently be omitted. On the opposite
side, {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} (or {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmdv.defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}}) is mandatory to validate a proof.

\item {} 
One can also use {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.admitted}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Admitted}}}}} in place of {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} to turn the
current asserted statement into an axiom and exit the proof editing mode.

\end{enumerate}
\end{sphinxadmonition}


\section{Extensions of Gallina}
\label{\detokenize{language/gallina-extensions:extensions-of-gallina}}\label{\detokenize{language/gallina-extensions:extensionsofgallina}}\label{\detokenize{language/gallina-extensions::doc}}
\DUrole{smallcaps}{Gallina} is the kernel language of \DUrole{smallcaps}{Coq}. We describe here extensions of
\DUrole{smallcaps}{Gallina}’s syntax.


\subsection{Record types}
\label{\detokenize{language/gallina-extensions:record-types}}\label{\detokenize{language/gallina-extensions:id1}}
The {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.record}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Record}}}}} construction is a macro allowing the definition of
records as is done in many programming languages. Its syntax is
described in the grammar below. In fact, the {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.record}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Record}}}}} macro is more general
than the usual record types, since it allows also for “manifest”
expressions. In this sense, the {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.record}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Record}}}}} construction allows defining
“signatures”.

\phantomsection\label{\detokenize{language/gallina-extensions:record-grammar}}\begin{quote}


\begin{productionlist}
\phantomsection\label{\detokenize{language/gallina-extensions:grammar-token-record}}\production{record}{ {\hyperref[\detokenize{language/gallina-extensions:grammar-token-record-keyword}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{record\_keyword}}}}} \sphinxcode{\sphinxupquote{record\_body}} with … with \sphinxcode{\sphinxupquote{record\_body}}}
\phantomsection\label{\detokenize{language/gallina-extensions:grammar-token-record_keyword}}\production{record\_keyword}{ Record \textbar{} Inductive \textbar{} CoInductive}
\phantomsection\label{\detokenize{language/gallina-extensions:grammar-token-field}}\production{field}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}} {]} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} {[} where {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{notation}}}}} {]}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}} {]} {[}: {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}} {]} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\end{productionlist}

\end{quote}

In the expression:
\index{Record (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.record}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Record~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}}}\DUrole{notation-sup}{?}}~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~\DUrole{curlies}{\{~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{;}}~\}}}}}}
\end{fulllineitems}


the first identifier {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is the name of the defined record and {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-sort}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{sort}}}}} is its
type. The optional identifier following \sphinxcode{\sphinxupquote{:=}} is the name of its constructor. If it is omitted,
the default name \sphinxcode{\sphinxupquote{Build\_}}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}, where {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is the record name, is used. If {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-sort}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{sort}}}}} is
omitted, the default sort is \sphinxtitleref{Type}. The identifiers inside the brackets are the names of
fields. For a given field {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}, its type is \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{binders}\DUrole{operator}{,} \DUrole{name}{type}}}.
Remark that the type of a particular identifier may depend on a previously-given identifier. Thus the
order of the fields is important. Finally, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binders}}}}} are parameters of the record.

More generally, a record may have explicitly defined (a.k.a. manifest)
fields. For instance, we might have:
\sphinxcode{\sphinxupquote{\DUrole{notation}{Record {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}} := \DUrole{curlies}{\{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\(\sb{\text{1}}\) : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}\(\sb{\text{1}}\) ; {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\(\sb{\text{2}}\) := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}\(\sb{\text{2}}\) ; {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\(\sb{\text{3}}\) : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}\(\sb{\text{3}}\) \}}}}}.
in which case the correctness of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}\(\sb{\text{3}}\)}}} may rely on the instance \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}\(\sb{\text{2}}\)}}} of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\(\sb{\text{2}}\)}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}\(\sb{\text{2}}\)}}} may in turn depend on \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\(\sb{\text{1}}\)}}}.

\begin{sphinxadmonition}{note}{Example}
\begin{quote}

The set of rational numbers may be defined as:
\end{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Record} \PYG{n}{Rat} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{mkRat}
\PYG{o}{\PYGZob{}}\PYG{n}{sign} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{;}
\PYG{n}{top} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{;}
\PYG{n}{bottom} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{;}
\PYG{n}{Rat\PYGZus{}bottom\PYGZus{}cond} \PYG{o}{:} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{bottom}\PYG{o}{;}
\PYG{n}{Rat\PYGZus{}irred\PYGZus{}cond} \PYG{o}{:}
\PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{o}{(}\PYG{n}{x} \PYG{o}{*} \PYG{n}{y}\PYG{o}{)} \PYG{o}{=} \PYG{n}{top} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{n}{x} \PYG{o}{*} \PYG{n}{z}\PYG{o}{)} \PYG{o}{=} \PYG{n}{bottom} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{1}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{Rat} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{sign} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{top} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{bottom} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Rat\PYGZus{}bottom\PYGZus{}cond} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Rat\PYGZus{}irred\PYGZus{}cond} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Remark here that the fields \sphinxcode{\sphinxupquote{Rat\_bottom\_cond}} depends on the field \sphinxcode{\sphinxupquote{bottom}} and \sphinxcode{\sphinxupquote{Rat\_irred\_cond}}
depends on both \sphinxcode{\sphinxupquote{top}} and \sphinxcode{\sphinxupquote{bottom}}.

Let us now see the work done by the \sphinxcode{\sphinxupquote{Record}} macro. First the macro
generates a variant type definition with just one constructor:
\sphinxcode{\sphinxupquote{\DUrole{notation}{Variant {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\(\sb{\text{0}}\) \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}}}}.

To build an object of type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, one should provide the constructor
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\(\sb{\text{0}}\)}}} with the appropriate number of terms filling the fields of the record.

\begin{sphinxadmonition}{note}{Example}

Let us define the rational \(1/2\):
\begin{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Theorem} \PYG{n}{one\PYGZus{}two\PYGZus{}irred} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{*} \PYG{n}{y} \PYG{o}{=} \PYG{l+m+mi}{1} \PYG{o}{/\PYGZbs{}} \PYG{n}{x} \PYG{o}{*} \PYG{n}{z} \PYG{o}{=} \PYG{l+m+mi}{2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{1}\PYG{o}{.}
\PYG{n}{Admitted}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{half} \PYG{o}{:=} \PYG{n}{mkRat} \PYG{n+nb+bp}{true} \PYG{l+m+mi}{1} \PYG{l+m+mi}{2} \PYG{o}{(}\PYG{n}{O\PYGZus{}S} \PYG{l+m+mi}{1}\PYG{o}{)} \PYG{n}{one\PYGZus{}two\PYGZus{}irred}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{n}{half}\PYG{o}{.}
\end{sphinxVerbatim}
\end{quote}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{language/gallina-extensions:record-named-fields-grammar}}\begin{quote}


\begin{productionlist}
\phantomsection\label{\detokenize{language/gallina-extensions:grammar-token-record_term}}\production{record\_term}{ \{\textbar{} {[}{\hyperref[\detokenize{language/gallina-extensions:grammar-token-field-def}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{field\_def}}}}} ; … ; {\hyperref[\detokenize{language/gallina-extensions:grammar-token-field-def}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{field\_def}}}}}{]} \textbar{}\}}
\phantomsection\label{\detokenize{language/gallina-extensions:grammar-token-field_def}}\production{field\_def}{ name {[}binders{]} := {\hyperref[\detokenize{language/gallina-extensions:grammar-token-record-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{record\_term}}}}}}
\end{productionlist}

\end{quote}

Alternatively, the following syntax allows creating objects by using named fields, as
shown in this grammar. The fields do not have to be in any particular order, nor do they have
to be all present if the missing ones can be inferred or prompted for
(see {\hyperref[\detokenize{addendum/program:programs}]{\sphinxcrossref{\DUrole{std,std-ref}{Program}}}}).

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{half\PYGZsq{}} \PYG{o}{:=}
  \PYG{o}{\PYGZob{}\textbar{}} \PYG{n}{sign} \PYG{o}{:=} \PYG{n+nb+bp}{true}\PYG{o}{;}
     \PYG{n}{Rat\PYGZus{}bottom\PYGZus{}cond} \PYG{o}{:=} \PYG{n}{O\PYGZus{}S} \PYG{l+m+mi}{1}\PYG{o}{;}
     \PYG{n}{Rat\PYGZus{}irred\PYGZus{}cond} \PYG{o}{:=} \PYG{n}{one\PYGZus{}two\PYGZus{}irred} \PYG{o}{\textbar{}\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{half\PYGZsq{}} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

The following settings let you control the display format for types:
\index{Printing Records (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.printing-records}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Records}}}}
If set, use the record syntax (shown above) as the default display format.

\end{fulllineitems}


You can override the display format for specified types by adding entries to these tables:
\index{Printing Record (table)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:table.printing-record}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Table}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Record~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
Specifies a set of qualids which are displayed as records.  Use the
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.add-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add @table}}}}} and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.remove-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove @table}}}}} commands to update the set of qualids.

\end{fulllineitems}

\index{Printing Constructor (table)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:table.printing-constructor}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Table}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Constructor~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
Specifies a set of qualids which are displayed as constructors.  Use the
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.add-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add @table}}}}} and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.remove-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove @table}}}}} commands to update the set of qualids.

\end{fulllineitems}


This syntax can also be used for pattern matching.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{o}{(}
  \PYG{k}{match} \PYG{n}{half} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{o}{\PYGZob{}\textbar{}} \PYG{n}{sign} \PYG{o}{:=} \PYG{n+nb+bp}{true}\PYG{o}{;} \PYG{n}{top} \PYG{o}{:=} \PYG{n}{n} \PYG{o}{\textbar{}\PYGZcb{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{n}
  \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
  \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{=} \PYG{l+m+mi}{1}
         \PYG{o}{:} \PYG{k+kt}{nat}
\end{sphinxVerbatim}

The macro generates also, when it is possible, the projection
functions for destructuring an object of type \sphinxtitleref{ident}.  These
projection functions are given the names of the corresponding
fields. If a field is named \sphinxtitleref{\_} then no projection is built
for it. In our example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{n}{top} \PYG{n}{half}\PYG{o}{.}
    \PYG{o}{=} \PYG{l+m+mi}{1}
         \PYG{o}{:} \PYG{k+kt}{nat}

\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{n}{bottom} \PYG{n}{half}\PYG{o}{.}
    \PYG{o}{=} \PYG{l+m+mi}{2}
         \PYG{o}{:} \PYG{k+kt}{nat}

\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{n}{Rat\PYGZus{}bottom\PYGZus{}cond} \PYG{n}{half}\PYG{o}{.}
    \PYG{o}{=} \PYG{n}{O\PYGZus{}S} \PYG{l+m+mi}{1}
         \PYG{o}{:} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{bottom} \PYG{n}{half}
\end{sphinxVerbatim}

An alternative syntax for projections based on a dot notation is
available:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{n}{half}\PYG{o}{.}\PYG{o}{(}\PYG{n}{top}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{=} \PYG{l+m+mi}{1}
         \PYG{o}{:} \PYG{k+kt}{nat}
\end{sphinxVerbatim}

It can be activated for printing with
\index{Printing Projections (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.printing-projections}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Projections}}}}
\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{k+kn}{Printing} \PYG{k+kn}{Projections}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{n}{top} \PYG{n}{half}\PYG{o}{.}
    \PYG{n}{half}\PYG{o}{.}\PYG{o}{(}\PYG{n}{top}\PYG{o}{)}
         \PYG{o}{:} \PYG{k+kt}{nat}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{language/gallina-extensions:record-projections-grammar}}\begin{quote}


\begin{productionlist}
\phantomsection\label{\detokenize{language/gallina-extensions:grammar-token-projection}}\production{projection}{ projection {}`.{}` ( {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} )}
\productioncont{ \textbar{} projection {}`.{}` ( {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-arg}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{arg}}}}} … {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-arg}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{arg}}}}} )}
\productioncont{ \textbar{} projection {}`.{}` ( @{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} … {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} )}
\end{productionlist}


Syntax of Record projections
\end{quote}

The corresponding grammar rules are given in the preceding grammar. When \sphinxtitleref{qualid}
denotes a projection, the syntax \sphinxtitleref{term.(qualid)} is equivalent to \sphinxtitleref{qualid term},
the syntax \sphinxtitleref{term.(qualid} \sphinxtitleref{arg}\(_{1}\) \sphinxtitleref{arg}\(_{n}\) \sphinxtitleref{)} to \sphinxtitleref{qualid} \sphinxtitleref{arg}\(_{1}\) \sphinxtitleref{…} \sphinxtitleref{arg}\(_{n}\) \sphinxtitleref{term},
and the syntax \sphinxtitleref{term.(@qualid} \sphinxtitleref{term}\(_{1}\) \sphinxtitleref{term}\(_{n}\) \sphinxtitleref{)} to \sphinxtitleref{@qualid} \sphinxtitleref{term}\(_{1}\) \sphinxtitleref{…} \sphinxtitleref{term}\(_{n}\) \sphinxtitleref{term}.
In each case, \sphinxtitleref{term} is the object projected and the
other arguments are the parameters of the inductive type.

\begin{sphinxadmonition}{note}{Note:}
Records defined with the \sphinxcode{\sphinxupquote{Record}} keyword are not allowed to be
recursive (references to the record's name in the type of its field
raises an  error). To define recursive records, one can use the \sphinxcode{\sphinxupquote{Inductive}}
and \sphinxcode{\sphinxupquote{CoInductive}} keywords, resulting in an inductive or co-inductive record.
A \sphinxstyleemphasis{caveat}, however, is that records cannot appear in mutually inductive
(or co-inductive) definitions.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
Induction schemes are automatically generated for inductive records.
Automatic generation of induction schemes for non-recursive records
defined with the \sphinxcode{\sphinxupquote{Record}} keyword can be activated with the
\sphinxcode{\sphinxupquote{Nonrecursive Elimination Schemes}} option (see {\hyperref[\detokenize{user-extensions/proof-schemes:proofschemes-induction-principles}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of induction principles with Scheme}}}}).
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxcode{\sphinxupquote{Structure}} is a synonym of the keyword \sphinxcode{\sphinxupquote{Record}}.
\end{sphinxadmonition}
\index{‘ident’ cannot be defined (warn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:warn.ident-cannot-be-defined}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~cannot~be~defined.}}}}
It can happen that the definition of a projection is impossible.
This message is followed by an explanation of this impossibility.
There may be three reasons:
\begin{enumerate}
\def\theenumi{\arabic{enumi}}
\def\labelenumi{\theenumi .}
\makeatletter\def\p@enumii{\p@enumi \theenumi .}\makeatother
\item {} 
The name \sphinxtitleref{ident} already exists in the environment (see {\hyperref[\detokenize{language/gallina-specification-language:coq:cmdv.axiom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Axiom}}}}}).

\item {} 
The body of \sphinxtitleref{ident} uses an incorrect elimination for
\sphinxtitleref{ident} (see {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}} and {\hyperref[\detokenize{language/cic:destructors}]{\sphinxcrossref{\DUrole{std,std-ref}{Destructors}}}}).

\item {} 
The type of the projections \sphinxtitleref{ident} depends on previous
projections which themselves could not be defined.

\end{enumerate}

\end{fulllineitems}

\index{Records declared with the keyword Record or Structure cannot be recursive (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:exn.records-declared-with-the-keyword-record-or-structure-cannot-be-recursive}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Records~declared~with~the~keyword~Record~or~Structure~cannot~be~recursive.}}}}
The record name \sphinxtitleref{ident} appears in the type of its fields, but uses
the keyword \sphinxcode{\sphinxupquote{Record}}. Use  the keyword \sphinxcode{\sphinxupquote{Inductive}} or \sphinxcode{\sphinxupquote{CoInductive}} instead.

\end{fulllineitems}

\index{Cannot handle mutually (co)inductive records (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:exn.cannot-handle-mutually-co-inductive-records}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~handle~mutually~(co)inductive~records.}}}}
Records  cannot  be  defined  as  part  of  mutually  inductive  (or
co-inductive) definitions,  whether with records only  or mixed with
standard definitions.

\end{fulllineitems}


During the definition of the one-constructor inductive definition, all
the errors of inductive definitions, as described in Section
{\hyperref[\detokenize{language/gallina-specification-language:gallina-inductive-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Inductive definitions}}}}, may also occur.


\sphinxstrong{See also:}


Coercions and records in section {\hyperref[\detokenize{addendum/implicit-coercions:coercions-classes-as-records}]{\sphinxcrossref{\DUrole{std,std-ref}{Classes as Records}}}} of the chapter devoted to coercions.




\subsubsection{Primitive Projections}
\label{\detokenize{language/gallina-extensions:primitive-projections}}\label{\detokenize{language/gallina-extensions:id2}}\index{Primitive Projections (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.primitive-projections}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Primitive~Projections}}}}
Turns on the use of primitive
projections when defining subsequent records (even through the \sphinxcode{\sphinxupquote{Inductive}}
and \sphinxcode{\sphinxupquote{CoInductive}} commands). Primitive projections
extended the Calculus of Inductive Constructions with a new binary
term constructor \sphinxtitleref{r.(p)} representing a primitive projection \sphinxtitleref{p} applied
to a record object \sphinxtitleref{r} (i.e., primitive projections are always applied).
Even if the record type has parameters, these do not appear at
applications of the projection, considerably reducing the sizes of
terms when manipulating parameterized records and type checking time.
On the user level, primitive projections can be used as a replacement
for the usual defined ones, although there are a few notable differences.

\end{fulllineitems}

\index{Printing Primitive Projection Parameters (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.printing-primitive-projection-parameters}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Primitive~Projection~Parameters}}}}
This compatibility option reconstructs internally omitted parameters at
printing time (even though they are absent in the actual AST manipulated
by the kernel).

\end{fulllineitems}

\index{Printing Primitive Projection Compatibility (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.printing-primitive-projection-compatibility}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Primitive~Projection~Compatibility}}}}
This compatibility option (on by default) governs the
printing of pattern matching over primitive records.

\end{fulllineitems}



\paragraph{Primitive Record Types}
\label{\detokenize{language/gallina-extensions:primitive-record-types}}
When the {\hyperref[\detokenize{language/gallina-extensions:coq:flag.primitive-projections}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Primitive Projections}}}}} option is on, definitions of
record types change meaning. When a type is declared with primitive
projections, its \sphinxcode{\sphinxupquote{\DUrole{keyword}{match}}} construct is disabled (see {\hyperref[\detokenize{language/gallina-extensions:primitive-projections}]{\sphinxcrossref{\DUrole{std,std-ref}{Primitive Projections}}}} though).
To eliminate the (co-)inductive type, one must use its defined primitive projections.

For compatibility, the parameters still appear to the user when
printing terms even though they are absent in the actual AST
manipulated by the kernel. This can be changed by unsetting the
{\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-primitive-projection-parameters}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Primitive Projection Parameters}}}}} flag. Further compatibility
printing can be deactivated thanks to the \sphinxcode{\sphinxupquote{Printing Primitive Projection
Compatibility}} option which governs the printing of pattern matching
over primitive records.

There are currently two ways to introduce primitive records types:
\begin{enumerate}
\def\theenumi{\arabic{enumi}}
\def\labelenumi{\theenumi .}
\makeatletter\def\p@enumii{\p@enumi \theenumi .}\makeatother
\item {} 
Through the \sphinxcode{\sphinxupquote{Record}} command, in which case the type has to be
non-recursive. The defined type enjoys eta-conversion definitionally,
that is the generalized form of surjective pairing for records:
\sphinxtitleref{r} \sphinxcode{\sphinxupquote{= Build\_}}\sphinxtitleref{R} \sphinxcode{\sphinxupquote{(}}\sphinxtitleref{r}\sphinxcode{\sphinxupquote{.(}}\sphinxtitleref{p}\(_{1}\)\sphinxcode{\sphinxupquote{) …}} \sphinxtitleref{r}\sphinxcode{\sphinxupquote{.(}}\sphinxtitleref{p}\(_{n}\)\sphinxcode{\sphinxupquote{))}}.
Eta-conversion allows to define dependent elimination for these types as well.

\item {} 
Through the \sphinxcode{\sphinxupquote{Inductive}} and \sphinxcode{\sphinxupquote{CoInductive}} commands, when
the body of the definition is a record declaration of the form
\sphinxcode{\sphinxupquote{Build\_}}\sphinxtitleref{R} \sphinxcode{\sphinxupquote{\{}} \sphinxtitleref{p}\(_{1}\) \sphinxcode{\sphinxupquote{:}} \sphinxtitleref{t}\(_{1}\)\sphinxcode{\sphinxupquote{; … ;}} \sphinxtitleref{p}\(_{n}\) \sphinxcode{\sphinxupquote{:}} \sphinxtitleref{t}\(_{n}\) \sphinxcode{\sphinxupquote{\}}}.
In this case the types can be recursive and eta-conversion is disallowed. These kind of record types
differ from their traditional versions in the sense that dependent
elimination is not available for them and only non-dependent case analysis
can be defined.

\end{enumerate}


\paragraph{Reduction}
\label{\detokenize{language/gallina-extensions:reduction}}
The basic reduction rule of a primitive projection is
\sphinxtitleref{p}\(_{i}\) \sphinxcode{\sphinxupquote{(Build\_}}\sphinxtitleref{R} \sphinxtitleref{t}\(_{1}\) … \sphinxtitleref{t}\(_{n}\)\sphinxcode{\sphinxupquote{)}} \({\rightarrow_{\iota}}\) \sphinxtitleref{t}\(_{i}\).
However, to take the \({\delta}\) flag into
account, projections can be in two states: folded or unfolded. An
unfolded primitive projection application obeys the rule above, while
the folded version delta-reduces to the unfolded version. This allows to
precisely mimic the usual unfolding rules of constants. Projections
obey the usual \sphinxcode{\sphinxupquote{simpl}} flags of the \sphinxcode{\sphinxupquote{Arguments}} command in particular.
There is currently no way to input unfolded primitive projections at the
user-level, and one must use the {\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-primitive-projection-compatibility}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Primitive Projection Compatibility}}}}}
to display unfolded primitive projections as matches and distinguish them from folded ones.


\paragraph{Compatibility Projections and \sphinxstyleliteralintitle{\sphinxupquote{match}}}
\label{\detokenize{language/gallina-extensions:compatibility-projections-and-match}}
To ease compatibility with ordinary record types, each primitive
projection is also defined as a ordinary constant taking parameters and
an object of the record type as arguments, and whose body is an
application of the unfolded primitive projection of the same name. These
constants are used when elaborating partial applications of the
projection. One can distinguish them from applications of the primitive
projection if the :flag{}`Printing Primitive Projection Parameters{}` option
is off: For a primitive projection application, parameters are printed
as underscores while for the compatibility projections they are printed
as usual.

Additionally, user-written \sphinxcode{\sphinxupquote{\DUrole{keyword}{match}}} constructs on primitive records
are desugared into substitution of the projections, they cannot be
printed back as \sphinxcode{\sphinxupquote{\DUrole{keyword}{match}}} constructs.


\subsection{Variants and extensions of \sphinxstyleliteralintitle{\sphinxupquote{match}}}
\label{\detokenize{language/gallina-extensions:variants-and-extensions-of-match}}

\subsubsection{Multiple and nested pattern matching}
\label{\detokenize{language/gallina-extensions:multiple-and-nested-pattern-matching}}\label{\detokenize{language/gallina-extensions:mult-match}}
The basic version of \sphinxcode{\sphinxupquote{\DUrole{keyword}{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 {\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-matching}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Matching}}}}}).


\sphinxstrong{See also:}


{\hyperref[\detokenize{addendum/extended-pattern-matching:extendedpatternmatching}]{\sphinxcrossref{\DUrole{std,std-ref}{Extended pattern matching}}}}.




\subsubsection{Pattern-matching on boolean values: the if expression}
\label{\detokenize{language/gallina-extensions:pattern-matching-on-boolean-values-the-if-expression}}\label{\detokenize{language/gallina-extensions:if-then-else}}
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 \sphinxcode{\sphinxupquote{if … then … else}} notation. For instance, the definition

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{not} \PYG{o}{(}\PYG{n}{b}\PYG{o}{:}\PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{b} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n+nb+bp}{true} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
\PYG{o}{\textbar{}} \PYG{n+nb+bp}{false} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{not} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

can be alternatively written

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{not} \PYG{o}{(}\PYG{n}{b}\PYG{o}{:}\PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{if} \PYG{n}{b} \PYG{k}{then} \PYG{n+nb+bp}{false} \PYG{k}{else} \PYG{n+nb+bp}{true}\PYG{o}{.}
    \PYG{n}{not} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

More generally, for an inductive type with constructors \sphinxtitleref{C}\(_{1}\) and \sphinxtitleref{C}\(_{2}\),
we have the following equivalence

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
if term [dep\PYGZus{}ret\PYGZus{}type] then term\(\sb{\text{1}}\) else term\(\sb{\text{2}}\) ≡
match term [dep\PYGZus{}ret\PYGZus{}type] with
\textbar{} C\(\sb{\text{1}}\) \PYGZus{} … \PYGZus{} =\PYGZgt{} term\(\sb{\text{1}}\)
\textbar{} C\(\sb{\text{2}}\) \PYGZus{} … \PYGZus{} =\PYGZgt{} term\(\sb{\text{2}}\)
end
\end{sphinxVerbatim}

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{(}\PYG{n}{H}\PYG{o}{:}\PYG{o}{\PYGZob{}}\PYG{n}{x}\PYG{o}{=}\PYG{l+m+mi}{0}\PYG{o}{\PYGZcb{}}\PYG{o}{+}\PYG{o}{\PYGZob{}}\PYG{n}{x}\PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}}\PYG{l+m+mi}{0}\PYG{o}{\PYGZcb{}}\PYG{o}{)} \PYG{o}{=\PYGZgt{}}
\PYG{k}{match} \PYG{n}{H} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{k}{left} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
\PYG{o}{\textbar{}} \PYG{k}{right} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
\PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{o}{\PYGZob{}}\PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{\PYGZcb{}} \PYG{o}{+} \PYG{o}{\PYGZob{}}\PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{\PYGZcb{}}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{k}{if} \PYG{n}{H} \PYG{k}{then} \PYG{n+nb+bp}{true} \PYG{k}{else} \PYG{n+nb+bp}{false}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{o}{\PYGZob{}}\PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{\PYGZcb{}} \PYG{o}{+} \PYG{o}{\PYGZob{}}\PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Notice that the printing uses the \sphinxcode{\sphinxupquote{\DUrole{keyword}{if}}} syntax because \sphinxtitleref{sumbool} is
declared as such (see {\hyperref[\detokenize{language/gallina-extensions:controlling-match-pp}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling pretty-printing of match expressions}}}}).


\subsubsection{Irrefutable patterns: the destructuring let variants}
\label{\detokenize{language/gallina-extensions:irrefutable-patterns-the-destructuring-let-variants}}\label{\detokenize{language/gallina-extensions:irrefutable-patterns}}
Pattern-matching on terms inhabiting inductive type having only one
constructor can be alternatively written using \sphinxcode{\sphinxupquote{\DUrole{keyword}{let} \DUrole{error}{…} \DUrole{keyword}{in} \DUrole{error}{…}}}
constructions. There are two variants of them.


\paragraph{First destructuring let syntax}
\label{\detokenize{language/gallina-extensions:first-destructuring-let-syntax}}
The expression \sphinxcode{\sphinxupquote{\DUrole{keyword}{let} \DUrole{operator}{(}}}\sphinxtitleref{ident}\(_{1}\)\sphinxcode{\sphinxupquote{\DUrole{operator}{,} \DUrole{error}{…} \DUrole{operator}{,}}} \sphinxtitleref{ident}\(_{n}\)\sphinxcode{\sphinxupquote{\DUrole{operator}{)} \DUrole{operator}{:=}}} \sphinxtitleref{term}\(_{0}\)\sphinxcode{\sphinxupquote{\DUrole{keyword}{in}}} \sphinxtitleref{term}\(_{1}\) performs
case analysis on \sphinxtitleref{term}\(_{0}\) which must be in an inductive type with one
constructor having itself \(n\) arguments. Variables \sphinxtitleref{ident}\(_{1}\) … \sphinxtitleref{ident}\(_{n}\) are
bound to the \(n\) arguments of the constructor in expression \sphinxtitleref{term}\(_{1}\). For
instance, the definition

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{fst} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{H}\PYG{o}{:}\PYG{n}{A} \PYG{o}{*} \PYG{n}{B}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{H} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n}{pair} \PYG{n}{x} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{fst} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

can be alternatively written

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{fst} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{p}\PYG{o}{:}\PYG{n}{A} \PYG{o}{*} \PYG{n}{B}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{let} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{o}{\PYGZus{}}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{p} \PYG{k}{in} \PYG{n}{x}\PYG{o}{.}
    \PYG{n}{fst} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

Notice that reduction is different from regular \sphinxcode{\sphinxupquote{\DUrole{keyword}{let} \DUrole{error}{…} \DUrole{keyword}{in} \DUrole{error}{…}}}
construction since it happens only if \sphinxtitleref{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 \sphinxcode{\sphinxupquote{\DUrole{keyword}{match}}} or the \sphinxcode{\sphinxupquote{\DUrole{keyword}{let}}} construction
(see Section {\hyperref[\detokenize{language/gallina-extensions:controlling-match-pp}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling pretty-printing of match expressions}}}}).

If term inhabits an inductive type with one constructor \sphinxtitleref{C}, we have an
equivalence between

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
let (ident\(\sb{\text{1}}\), …, identₙ) [dep\PYGZus{}ret\PYGZus{}type] := term in term\PYGZsq{}
\end{sphinxVerbatim}

and

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
match term [dep\PYGZus{}ret\PYGZus{}type] with
C ident\(\sb{\text{1}}\) … identₙ =\PYGZgt{} term\PYGZsq{}
end
\end{sphinxVerbatim}


\paragraph{Second destructuring let syntax}
\label{\detokenize{language/gallina-extensions: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:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{fst} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{p}\PYG{o}{:}\PYG{n}{A}\PYG{o}{*}\PYG{n}{B}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{let} \PYG{k}{\PYGZsq{}}\PYG{n}{pair} \PYG{n}{x} \PYG{o}{\PYGZus{}} \PYG{o}{:=} \PYG{n}{p} \PYG{k}{in} \PYG{n}{x}\PYG{o}{.}
    \PYG{n}{fst} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

This is useful to match deeper inside tuples and also to use notations
for the pattern, as the syntax \sphinxcode{\sphinxupquote{\DUrole{keyword}{let} \DUrole{error}{’}\DUrole{name}{p} \DUrole{operator}{:=} \DUrole{name}{t} \DUrole{keyword}{in} \DUrole{name}{b}}} allows arbitrary
patterns to do the deconstruction. For example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{deep\PYGZus{}tuple} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{o}{(}\PYG{n}{A}\PYG{o}{*}\PYG{n}{A}\PYG{o}{)}\PYG{o}{*}\PYG{o}{(}\PYG{n}{A}\PYG{o}{*}\PYG{n}{A}\PYG{o}{)}\PYG{o}{)} \PYG{o}{:} \PYG{n}{A}\PYG{o}{*}\PYG{n}{A}\PYG{o}{*}\PYG{n}{A}\PYG{o}{*}\PYG{n}{A} \PYG{o}{:=}
\PYG{k}{let} \PYG{k}{\PYGZsq{}}\PYG{o}{(}\PYG{o}{(}\PYG{n}{a}\PYG{o}{,}\PYG{n}{b}\PYG{o}{)}\PYG{o}{,} \PYG{o}{(}\PYG{n}{c}\PYG{o}{,} \PYG{n}{d}\PYG{o}{)}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{x} \PYG{k}{in} \PYG{o}{(}\PYG{n}{a}\PYG{o}{,}\PYG{n}{b}\PYG{o}{,}\PYG{n}{c}\PYG{o}{,}\PYG{n}{d}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{deep\PYGZus{}tuple} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{ x \PYGZsq{}With\PYGZsq{} p }\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{exist} \PYG{o}{\PYGZus{}} \PYG{n}{x} \PYG{n}{p}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{20}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Identifier} \PYG{k}{\PYGZsq{}}\PYG{n}{With\PYGZsq{}} \PYG{n}{now} \PYG{n}{a} \PYG{n}{keyword}

\PYG{k+kn}{Definition} \PYG{n}{proj1\PYGZus{}sig\PYGZsq{}} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{A}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{t}\PYG{o}{:}\PYG{o}{\PYGZob{}} \PYG{n}{x}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\textbar{}} \PYG{n}{P} \PYG{n}{x} \PYG{o}{\PYGZcb{}}\PYG{o}{)} \PYG{o}{:} \PYG{n}{A} \PYG{o}{:=}
\PYG{k}{let} \PYG{k}{\PYGZsq{}}\PYG{n}{x} \PYG{n}{With} \PYG{n}{p} \PYG{o}{:=} \PYG{n}{t} \PYG{k}{in} \PYG{n}{x}\PYG{o}{.}
    \PYG{n}{proj1\PYGZus{}sig\PYGZsq{}} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

When printing definitions which are written using this construct it
takes precedence over let printing directives for the datatype under
consideration (see Section {\hyperref[\detokenize{language/gallina-extensions:controlling-match-pp}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling pretty-printing of match expressions}}}}).


\subsubsection{Controlling pretty-printing of match expressions}
\label{\detokenize{language/gallina-extensions:controlling-pretty-printing-of-match-expressions}}\label{\detokenize{language/gallina-extensions:controlling-match-pp}}
The following commands give some control over the pretty-printing
of \sphinxcode{\sphinxupquote{\DUrole{keyword}{match}}} expressions.


\paragraph{Printing nested patterns}
\label{\detokenize{language/gallina-extensions:printing-nested-patterns}}\index{Printing Matching (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.printing-matching}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{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 option is on (default), \DUrole{smallcaps}{Coq}’s printer tries to do such
limited re-factorization.
Turning it off tells \DUrole{smallcaps}{Coq} to print only simple pattern matching problems
in the same way as the \DUrole{smallcaps}{Coq} kernel handles them.

\end{fulllineitems}



\paragraph{Factorization of clauses with same right-hand side}
\label{\detokenize{language/gallina-extensions:factorization-of-clauses-with-same-right-hand-side}}\index{Printing Factorizable Match Patterns (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.printing-factorizable-match-patterns}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{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 option (on by default) tells \DUrole{smallcaps}{Coq}'s
printer to try to do this kind of factorization.

\end{fulllineitems}



\paragraph{Use of a default clause}
\label{\detokenize{language/gallina-extensions:use-of-a-default-clause}}\index{Printing Allow Match Default Clause (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.printing-allow-match-default-clause}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{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 \sphinxtitleref{\_} default clause. Assuming that
the printing matching mode and the factorization mode are on, this option (on by
default) tells \DUrole{smallcaps}{Coq}'s printer to use a default clause when relevant.

\end{fulllineitems}



\paragraph{Printing of wildcard patterns}
\label{\detokenize{language/gallina-extensions:printing-of-wildcard-patterns}}\index{Printing Wildcard (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.printing-wildcard}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Wildcard}}}}
Some variables in a pattern may not occur in the right-hand side of
the pattern matching clause. When this option 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
“\_”.

\end{fulllineitems}



\paragraph{Printing of the elimination predicate}
\label{\detokenize{language/gallina-extensions:printing-of-the-elimination-predicate}}\index{Printing Synth (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.printing-synth}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{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 option is on (default),
the result type is not printed when \DUrole{smallcaps}{Coq} knows that it can re-
synthesize it.

\end{fulllineitems}



\paragraph{Printing matching on irrefutable patterns}
\label{\detokenize{language/gallina-extensions:printing-matching-on-irrefutable-patterns}}
If an inductive type has just one constructor, pattern matching can be
written using the first destructuring let syntax.
\index{Printing Let (table)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:table.printing-let}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Table}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Let~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
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 \sphinxcode{\sphinxupquote{\DUrole{keyword}{match}}}.
It doesn't affect pattern matching explicitly entered with a destructuring
\sphinxcode{\sphinxupquote{\DUrole{keyword}{let}}}.
Use the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.add-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add @table}}}}} and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.remove-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove @table}}}}} commands to update this set.

\end{fulllineitems}



\paragraph{Printing matching on booleans}
\label{\detokenize{language/gallina-extensions:printing-matching-on-booleans}}
If an inductive type is isomorphic to the boolean type, pattern matching
can be written using \sphinxcode{\sphinxupquote{if}} … \sphinxcode{\sphinxupquote{then}} … \sphinxcode{\sphinxupquote{else}} ….  This table controls
which types are written this way:
\index{Printing If (table)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:table.printing-if}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Table}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~If~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
Specifies a set of qualids for which pattern matching is displayed using
\sphinxcode{\sphinxupquote{if}} … \sphinxcode{\sphinxupquote{then}} … \sphinxcode{\sphinxupquote{else}} ….  Use the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.add-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add @table}}}}} and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.remove-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove @table}}}}}
commands to update this set.

\end{fulllineitems}


This example emphasizes what the printing options offer.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{snd} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{H}\PYG{o}{:}\PYG{n}{A} \PYG{o}{*} \PYG{n}{B}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{H} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n}{pair} \PYG{n}{x} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{y}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{snd} \PYG{k}{is} \PYG{n}{defined}

\PYG{n}{Test} \PYG{k+kn}{Printing} \PYG{k+kn}{Let} \PYG{k}{for} \PYG{n}{prod}\PYG{o}{.}
    \PYG{n}{Cases} \PYG{n}{on} \PYG{n}{elements} \PYG{k}{of} \PYG{n}{prod} \PYG{n}{are} \PYG{n}{printed} \PYG{k}{using} \PYG{n}{a} \PYG{o}{{}`}\PYG{k}{let}\PYG{k}{\PYGZsq{}} \PYG{n}{form}

\PYG{k+kn}{Print} \PYG{n}{snd}\PYG{o}{.}
    \PYG{n}{snd} \PYG{o}{=} 
    \PYG{k}{fun} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{n}{A} \PYG{o}{*} \PYG{n}{B}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{k}{let} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{,} \PYG{n}{y}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{H} \PYG{k}{in} \PYG{n}{y}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{,} \PYG{n}{A} \PYG{o}{*} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}
    
    \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{type\PYGZus{}scope} \PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}}\PYG{o}{]}

\PYG{n}{Remove} \PYG{k+kn}{Printing} \PYG{k+kn}{Let} \PYG{n}{prod}\PYG{o}{.}
\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Synth}\PYG{o}{.}
\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Wildcard}\PYG{o}{.}
\PYG{k+kn}{Print} \PYG{n}{snd}\PYG{o}{.}
    \PYG{n}{snd} \PYG{o}{=} 
    \PYG{k}{fun} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{n}{A} \PYG{o}{*} \PYG{n}{B}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{H} \PYG{k}{return} \PYG{n}{B} \PYG{k}{with}
                                   \PYG{o}{\textbar{}} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{y}
                                   \PYG{k}{end}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{,} \PYG{n}{A} \PYG{o}{*} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}
    
    \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{type\PYGZus{}scope} \PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}}\PYG{o}{]}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsection{Advanced recursive functions}
\label{\detokenize{language/gallina-extensions:advanced-recursive-functions}}\label{\detokenize{language/gallina-extensions:id3}}
The following experimental command is available when the \sphinxcode{\sphinxupquote{FunInd}} library has been loaded via \sphinxcode{\sphinxupquote{Require Import FunInd}}:
\index{Function (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.function}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Function~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}~\DUrole{curlies}{\{~\DUrole{hole}{decrease\_annot}~\}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


This command can be seen as a generalization of \sphinxcode{\sphinxupquote{Fixpoint}}. It is actually a wrapper
for several ways of defining a function \sphinxstyleemphasis{and other useful related
objects}, namely: an induction principle that reflects the recursive
structure of the function (see {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.function-induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{function induction}}}}}) and its fixpoint equality.
The meaning of this declaration is to define a function ident,
similarly to \sphinxcode{\sphinxupquote{Fixpoint{}`. Like in {}`{}`Fixpoint}}, the decreasing argument must
be given (unless the function is not recursive), but it might not
necessarily be \sphinxstyleemphasis{structurally} decreasing. The point of the \{\} annotation
is to name the decreasing argument \sphinxstyleemphasis{and} to describe which kind of
decreasing criteria must be used to ensure termination of recursive
calls.

The \sphinxcode{\sphinxupquote{Function}} construction also enjoys the \sphinxcode{\sphinxupquote{with}} extension to define
mutually recursive definitions. However, this feature does not work
for non structurally recursive functions.

See the documentation of functional induction ({\hyperref[\detokenize{proof-engine/tactics:coq:tacn.function-induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{function induction}}}}})
and \sphinxcode{\sphinxupquote{Functional Scheme}} ({\hyperref[\detokenize{user-extensions/proof-schemes:functional-scheme}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of induction principles with Functional Scheme}}}}) for how to use
the induction principle to easily reason about the function.

Remark: To obtain the right principle, it is better to put rigid
parameters of the function as first arguments. For example it is
better to define plus like this:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Function} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{m} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
\PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{m} \PYG{n}{p}\PYG{o}{)}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{plus} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{plus} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{2}\PYG{n}{nd} \PYG{n}{argument}\PYG{o}{)}
    \PYG{n}{plus\PYGZus{}equation} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{plus\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{plus\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{plus\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{R\PYGZus{}plus\PYGZus{}correct} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{R\PYGZus{}plus\PYGZus{}complete} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

than like this:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Function} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
\PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{p} \PYG{n}{m}\PYG{o}{)}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{plus} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{plus} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}
    \PYG{n}{plus\PYGZus{}equation} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{plus\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{plus\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{plus\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{R\PYGZus{}plus\PYGZus{}correct} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{R\PYGZus{}plus\PYGZus{}complete} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\sphinxstyleemphasis{Limitations}

\sphinxtitleref{term}\(_{0}\) must be built as a \sphinxstyleemphasis{pure pattern matching tree} (\sphinxcode{\sphinxupquote{\DUrole{keyword}{match} \DUrole{error}{…} \DUrole{keyword}{with}}})
with applications only \sphinxstyleemphasis{at the end} of each branch.

Function does not support partial application of the function being
defined. Thus, the following example cannot be accepted due to the
presence of partial application of \sphinxtitleref{wrong} in the body of
\sphinxtitleref{wrong} :

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{n}{Function} \PYG{n}{wrong} \PYG{o}{(}\PYG{n}{C}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{n}{List}\PYG{o}{.}\PYG{n}{hd} \PYG{l+m+mi}{0} \PYG{o}{(}\PYG{n}{List}\PYG{o}{.}\PYG{n}{map} \PYG{n}{wrong} \PYG{o}{(}\PYG{n}{C}\PYG{o}{::}\PYG{n}{nil}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{The} \PYG{n}{reference} \PYG{n}{List}\PYG{o}{.}\PYG{n}{hd} \PYG{n}{was} \PYG{n}{not} \PYG{n}{found} \PYG{k}{in} \PYG{n}{the} \PYG{n}{current} \PYG{n}{environment}\PYG{o}{.}
\end{sphinxVerbatim}

For now, dependent cases are not treated for non structurally
terminating functions.
\index{The recursive argument must be specified (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:exn.the-recursive-argument-must-be-specified}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~recursive~argument~must~be~specified.}}}}
\end{fulllineitems}

\index{No argument name ‘ident’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:exn.no-argument-name-ident}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~argument~name~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}

\index{Cannot use mutual definition with well-founded recursion or measure (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:exn.cannot-use-mutual-definition-with-well-founded-recursion-or-measure}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~use~mutual~definition~with~well-founded~recursion~or~measure.}}}}
\end{fulllineitems}

\index{Cannot define graph for ‘ident’ (warn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:warn.cannot-define-graph-for-ident}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~define~graph~for~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
The generation of the graph relation (\sphinxtitleref{R\_ident}) used to compute the induction scheme of ident
raised a typing error. Only \sphinxtitleref{ident} is defined; the induction scheme
will not be generated. This error happens generally when:
\begin{itemize}
\item {} 
the definition uses pattern matching on dependent types,
which \sphinxcode{\sphinxupquote{Function}} cannot deal with yet.

\item {} 
the definition is not a \sphinxstyleemphasis{pattern matching tree} as explained above.

\end{itemize}

\end{fulllineitems}

\index{Cannot define principle(s) for ‘ident’ (warn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:warn.cannot-define-principle-s-for-ident}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~define~principle(s)~for~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
The generation of the graph relation (\sphinxtitleref{R\_ident}) succeeded but the induction principle
could not be built. Only \sphinxtitleref{ident} is defined. Please report.

\end{fulllineitems}

\index{Cannot build functional inversion principle (warn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:warn.cannot-build-functional-inversion-principle}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~build~functional~inversion~principle.}}}}
\sphinxtitleref{functional inversion} will not be available for the function.

\end{fulllineitems}



\sphinxstrong{See also:}


{\hyperref[\detokenize{user-extensions/proof-schemes:functional-scheme}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of induction principles with Functional Scheme}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.function-induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{function induction}}}}}



Depending on the \sphinxcode{\sphinxupquote{\{…\}}} annotation, different definition mechanisms are
used by \sphinxcode{\sphinxupquote{Function}}. A more precise description is given below.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Function~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Defines the not recursive function \sphinxtitleref{ident} as if declared with \sphinxtitleref{Definition}. Moreover
the following are defined:
\begin{itemize}
\item {} 
\sphinxtitleref{ident\_rect}, \sphinxtitleref{ident\_rec} and \sphinxtitleref{ident\_ind}, which reflect the pattern
matching structure of \sphinxtitleref{term} (see {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.inductive}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Inductive}}}}});

\item {} 
The inductive \sphinxtitleref{R\_ident} corresponding to the graph of \sphinxtitleref{ident} (silently);

\item {} 
\sphinxtitleref{ident\_complete} and \sphinxtitleref{ident\_correct} which are inversion information
linking the function and its graph.

\end{itemize}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Function~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}~\DUrole{curlies}{\{~struct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Defines the structural recursive function \sphinxtitleref{ident} as if declared with \sphinxcode{\sphinxupquote{Fixpoint}}. Moreover the following are defined:
\begin{itemize}
\item {} 
The same objects as above;

\item {} 
The fixpoint equation of \sphinxtitleref{ident}: \sphinxtitleref{ident\_equation}.

\end{itemize}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Function~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}~\DUrole{curlies}{\{~measure~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Function~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{*}}~\DUrole{curlies}{\{~wf~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Defines a recursive function by well-founded recursion. The module \sphinxcode{\sphinxupquote{Recdef}}
of the standard library must be loaded for this feature. The \sphinxcode{\sphinxupquote{\{\}}}
annotation is mandatory and must be one of the following:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{\{measure}} \sphinxtitleref{term} \sphinxtitleref{ident} \sphinxcode{\sphinxupquote{\}}} with \sphinxtitleref{ident} being the decreasing argument
and \sphinxtitleref{term} being a function from type of \sphinxtitleref{ident} to \sphinxcode{\sphinxupquote{nat}} for which
value on the decreasing argument decreases (for the \sphinxcode{\sphinxupquote{lt}} order on \sphinxcode{\sphinxupquote{nat}})
at each recursive call of \sphinxtitleref{term}. Parameters of the function are
bound in \sphinxtitleref{term};

\item {} 
\sphinxcode{\sphinxupquote{\{wf}} \sphinxtitleref{term} \sphinxtitleref{ident} \sphinxcode{\sphinxupquote{\}}} with \sphinxtitleref{ident} being the decreasing argument and
\sphinxtitleref{term} an ordering relation on the type of \sphinxtitleref{ident} (i.e. of type
\sphinxtitleref{T}\(_{\sf ident}\) \(\rightarrow\) \sphinxtitleref{T}\(_{\sf ident}\) \(\rightarrow\) \sphinxcode{\sphinxupquote{Prop}}) for which the decreasing argument
decreases at each recursive call of \sphinxtitleref{term}. The order must be well-founded.
Parameters of the function are bound in \sphinxtitleref{term}.

\end{itemize}

Depending on the annotation, the user is left with some proof
obligations that will be used to define the function. These proofs
are: proofs that each recursive call is actually decreasing with
respect to the given criteria, and (if the criteria is \sphinxtitleref{wf}) a proof
that the ordering relation is well-founded. Once proof obligations are
discharged, the following objects are defined:
\begin{itemize}
\item {} 
The same objects as with the struct;

\item {} 
The lemma \sphinxtitleref{ident}\(_{\sf tcc}\) which collects all proof obligations in one
property;

\item {} 
The lemmas \sphinxtitleref{ident}\(_{\sf terminate}\) and \sphinxtitleref{ident}\(_{\sf F}\) which is needed to be inlined
during extraction of ident.

\end{itemize}

The way this recursive function is defined is the subject of several
papers by Yves Bertot and Antonia Balaa on the one hand, and Gilles
Barthe, Julien Forest, David Pichardie, and Vlad Rusu on the other
hand. Remark: Proof obligations are presented as several subgoals
belonging to a Lemma \sphinxtitleref{ident}\(_{\sf tcc}\).

\end{fulllineitems}



\subsection{Section mechanism}
\label{\detokenize{language/gallina-extensions:section-mechanism}}\label{\detokenize{language/gallina-extensions:id4}}
The sectioning mechanism can be used to to organize a proof in
structured sections. Then local declarations become available (see
Section {\hyperref[\detokenize{language/gallina-specification-language:gallina-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Definitions}}}}).
\index{Section (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.section}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Section~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This command is used to open a section named \sphinxtitleref{ident}.

\end{fulllineitems}

\index{End (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.end}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{End~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This command closes the section named \sphinxtitleref{ident}. After closing of the
section, the local declarations (variables and local definitions) get
\sphinxstyleemphasis{discharged}, meaning that they stop being visible and that all global
objects defined in the section are generalized with respect to the
variables and local definitions they each depended on in the section.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
 \PYG{k+kn}{Section} \PYG{n}{s1}\PYG{o}{.}
\PYG{k+kn}{Variables} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{x} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{y} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Let} \PYG{n}{y\PYGZsq{}} \PYG{o}{:=} \PYG{n}{y}\PYG{o}{.}
    \PYG{n}{y\PYGZsq{}} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{x\PYGZsq{}} \PYG{o}{:=} \PYG{n}{S} \PYG{n}{x}\PYG{o}{.}
    \PYG{n}{x\PYGZsq{}} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{x\PYGZsq{}\PYGZsq{}} \PYG{o}{:=} \PYG{n}{x\PYGZsq{}} \PYG{o}{+} \PYG{n}{y\PYGZsq{}}\PYG{o}{.}
    \PYG{n}{x\PYGZsq{}\PYGZsq{}} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Print} \PYG{n}{x\PYGZsq{}}\PYG{o}{.}
    \PYG{n}{x\PYGZsq{}} \PYG{o}{=} \PYG{n}{S} \PYG{n}{x}
         \PYG{o}{:} \PYG{k+kt}{nat}

\PYG{k+kn}{End} \PYG{n}{s1}\PYG{o}{.}
\PYG{k+kn}{Print} \PYG{n}{x\PYGZsq{}}\PYG{o}{.}
    \PYG{n}{x\PYGZsq{}} \PYG{o}{=} \PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{n}{x}
         \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
    
    \PYG{n}{Argument} \PYG{n}{scope} \PYG{k}{is} \PYG{o}{[}\PYG{n}{nat\PYGZus{}scope}\PYG{o}{]}

\PYG{k+kn}{Print} \PYG{n}{x\PYGZsq{}\PYGZsq{}}\PYG{o}{.}
    \PYG{n}{x\PYGZsq{}\PYGZsq{}} \PYG{o}{=} \PYG{k}{fun} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{k}{let} \PYG{n}{y\PYGZsq{}} \PYG{o}{:=} \PYG{n}{y} \PYG{k}{in} \PYG{n}{x\PYGZsq{}} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y\PYGZsq{}}
         \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
    
    \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{nat\PYGZus{}scope} \PYG{n}{nat\PYGZus{}scope}\PYG{o}{]}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Notice the difference between the value of \sphinxtitleref{x’} and \sphinxtitleref{x’’} inside section
\sphinxtitleref{s1} and outside.
\index{This is not the last opened section (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:exn.this-is-not-the-last-opened-section}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{This~is~not~the~last~opened~section.}}}}
\end{fulllineitems}


\end{fulllineitems}


\sphinxstylestrong{Remarks:}
\begin{enumerate}
\def\theenumi{\arabic{enumi}}
\def\labelenumi{\theenumi .}
\makeatletter\def\p@enumii{\p@enumi \theenumi .}\makeatother
\item {} 
Most commands, like \sphinxcode{\sphinxupquote{Hint}}, \sphinxcode{\sphinxupquote{Notation}}, option management, … which
appear inside a section are canceled when the section is closed.

\end{enumerate}


\subsection{Module system}
\label{\detokenize{language/gallina-extensions:module-system}}
The module system provides a way of packaging related elements
together, as well as a means of massive abstraction.
\begin{quote}


\begin{productionlist}
\phantomsection\label{\detokenize{language/gallina-extensions:grammar-token-module_type}}\production{module\_type}{ qualid}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{module\_type}}}}} with Definition qualid := term}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{module\_type}}}}} with Module qualid := qualid}
\productioncont{ \textbar{} qualid qualid … qualid}
\productioncont{ \textbar{} !qualid qualid … qualid}
\phantomsection\label{\detokenize{language/gallina-extensions:grammar-token-module_binding}}\production{module\_binding}{ ( {[}Import\textbar{}Export{]} ident … ident : module\_type )}
\phantomsection\label{\detokenize{language/gallina-extensions:grammar-token-module_bindings}}\production{module\_bindings}{ {\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-binding}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{module\_binding}}}}} … {\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-binding}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{module\_binding}}}}}}
\phantomsection\label{\detokenize{language/gallina-extensions:grammar-token-module_expression}}\production{module\_expression}{ qualid … qualid}
\productioncont{ \textbar{} !qualid … qualid}
\end{productionlist}


Syntax of modules
\end{quote}

In the syntax of module application, the ! prefix indicates that any
\sphinxtitleref{Inline} directive in the type of the functor arguments will be ignored
(see the \sphinxcode{\sphinxupquote{Module Type}} command below).
\index{Module (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.module}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This command is used to start an interactive module named \sphinxtitleref{ident}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-binding}]{\sphinxcrossref{\DUrole{hole}{module\_binding}}}}}\DUrole{notation-sup}{*}}}}}}
Starts an interactive functor with
parameters given by module\_bindings.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}}}}}}
Starts an interactive module specifying its module type.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-binding}]{\sphinxcrossref{\DUrole{hole}{module\_binding}}}}}\DUrole{notation-sup}{*}}~:~{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}}}}}}
Starts an interactive functor with parameters given by the list of \sphinxtitleref{module binding}, and output module
type \sphinxtitleref{module\_type}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\textless{}:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textless{}:}}}}}}~\begin{quote}

Starts an interactive module satisfying each \sphinxtitleref{module\_type}.
\end{quote}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-binding}]{\sphinxcrossref{\DUrole{hole}{module\_binding}}}}}\DUrole{notation-sup}{*}}~\textless{}:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textless{}:}}.}}}}
Starts an interactive functor with parameters given by the list of \sphinxtitleref{module\_binding}. The output module type
is verified against each \sphinxtitleref{module\_type}.

\end{fulllineitems}


\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~{[}~Import~\textbar{}~Export~{]}}}}}
Behaves like \sphinxcode{\sphinxupquote{Module}}, but automatically imports or exports the module.

\end{fulllineitems}



\subsubsection{Reserved commands inside an interactive module}
\label{\detokenize{language/gallina-extensions:reserved-commands-inside-an-interactive-module}}\index{Include (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.include}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Include~\DUrole{hole}{module}}}}}
Includes the content of module in the current
interactive module. Here module can be a module expression or a module
type expression. If module is a high-order module or module type
expression then the system tries to instantiate module by the current
interactive module.

\end{fulllineitems}

\index{Include (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Include~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{module}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textless{}+}}}}}}
is a shortcut for the commands \sphinxcode{\sphinxupquote{Include}} \sphinxtitleref{module} for each \sphinxtitleref{module}.

\end{fulllineitems}

\index{End (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{End~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This command closes the interactive module \sphinxtitleref{ident}. If the module type
was given the content of the module is matched against it and an error
is signaled if the matching fails. If the module is basic (is not a
functor) its components (constants, inductive types, submodules etc.)
are now available through the dot notation.
\begin{quote}
\index{No such label ‘ident’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:exn.no-such-label-ident}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~label~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}

\index{Signature components for label ‘ident’ do not match (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:exn.signature-components-for-label-ident-do-not-match}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Signature~components~for~label~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~do~not~match.}}}}
\end{fulllineitems}

\index{This is not the last opened module (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:exn.this-is-not-the-last-opened-module}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{This~is~not~the~last~opened~module.}}}}
\end{fulllineitems}

\end{quote}

\end{fulllineitems}

\index{Module (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-expression}]{\sphinxcrossref{\DUrole{hole}{module\_expression}}}}}}}}
This command defines the module identifier \sphinxtitleref{ident} to be equal
to \sphinxtitleref{module\_expression}.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-binding}]{\sphinxcrossref{\DUrole{hole}{module\_binding}}}}}\DUrole{notation-sup}{*}}~:=~{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-expression}]{\sphinxcrossref{\DUrole{hole}{module\_expression}}}}}}}}
Defines a functor with parameters given by the list of \sphinxtitleref{module\_binding} and body \sphinxtitleref{module\_expression}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-binding}]{\sphinxcrossref{\DUrole{hole}{module\_binding}}}}}\DUrole{notation-sup}{*}}~:~{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}}~:=~{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-expression}]{\sphinxcrossref{\DUrole{hole}{module\_expression}}}}}}}}
Defines a functor with parameters given by the list of \sphinxtitleref{module\_binding} (possibly none), and output module type \sphinxtitleref{module\_type},
with body \sphinxtitleref{module\_expression}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-binding}]{\sphinxcrossref{\DUrole{hole}{module\_binding}}}}}\DUrole{notation-sup}{*}}~\textless{}:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textless{}:}}~:=~{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-expression}]{\sphinxcrossref{\DUrole{hole}{module\_expression}}}}}}}}
Defines a functor with parameters given by module\_bindings (possibly none) with body \sphinxtitleref{module\_expression}.
The body is checked against each \sphinxtitleref{module\_type}\(_{i}\).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-binding}]{\sphinxcrossref{\DUrole{hole}{module\_binding}}}}}\DUrole{notation-sup}{*}}~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-expression}]{\sphinxcrossref{\DUrole{hole}{module\_expression}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textless{}+}}}}}}
is equivalent to an interactive module where each \sphinxtitleref{module\_expression} is included.

\end{fulllineitems}


\end{fulllineitems}

\index{Module Type (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.module-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~Type~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\end{fulllineitems}


This command is used to start an interactive module type \sphinxtitleref{ident}.
\begin{quote}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~Type~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-binding}]{\sphinxcrossref{\DUrole{hole}{module\_binding}}}}}\DUrole{notation-sup}{*}}}}}}
Starts an interactive functor type with parameters given by \sphinxtitleref{module\_bindings}.

\end{fulllineitems}

\end{quote}


\subsubsection{Reserved commands inside an interactive module type:}
\label{\detokenize{language/gallina-extensions:reserved-commands-inside-an-interactive-module-type}}\index{Include (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Include~\DUrole{hole}{module}}}}}
Same as \sphinxcode{\sphinxupquote{Include}} inside a module.

\end{fulllineitems}

\index{Include (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Include~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{module}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textless{}+}}}}}}
is a shortcut for the command \sphinxcode{\sphinxupquote{Include}} \sphinxtitleref{module} for each \sphinxtitleref{module}.

\end{fulllineitems}

\index{Inline (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.inline}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-assumption-keyword}]{\sphinxcrossref{\DUrole{hole}{assumption\_keyword}}}}~Inline~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-assums}]{\sphinxcrossref{\DUrole{hole}{assums}}}}}}}}
The instance of this assumption will be automatically expanded at functor application, except when
this functor application is prefixed by a \sphinxcode{\sphinxupquote{!}} annotation.

\end{fulllineitems}

\index{End (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{End~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This command closes the interactive module type \sphinxtitleref{ident}.
\index{This is not the last opened module type (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:exn.this-is-not-the-last-opened-module-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{This~is~not~the~last~opened~module~type.}}}}
\end{fulllineitems}


\end{fulllineitems}

\index{Module Type (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~Type~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}}}}}}
Defines a module type \sphinxtitleref{ident} equal to \sphinxtitleref{module\_type}.
\begin{quote}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~Type~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-binding}]{\sphinxcrossref{\DUrole{hole}{module\_binding}}}}}\DUrole{notation-sup}{*}}~:=~{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}}}}}}
Defines a functor type \sphinxtitleref{ident} specifying functors taking arguments \sphinxtitleref{module\_bindings} and
returning \sphinxtitleref{module\_type}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module~Type~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-binding}]{\sphinxcrossref{\DUrole{hole}{module\_binding}}}}}\DUrole{notation-sup}{*}}~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textless{}+}}}}}}
is equivalent to an interactive module type were each \sphinxtitleref{module\_type} is included.

\end{fulllineitems}

\end{quote}

\end{fulllineitems}

\index{Declare Module (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.declare-module}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~Module~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}}}}}}
Declares a module \sphinxtitleref{ident} of type \sphinxtitleref{module\_type}.
\begin{quote}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~Module~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-binding}]{\sphinxcrossref{\DUrole{hole}{module\_binding}}}}}\DUrole{notation-sup}{*}}~:~{\hyperref[\detokenize{language/gallina-extensions:grammar-token-module-type}]{\sphinxcrossref{\DUrole{hole}{module\_type}}}}}}}}
Declares a functor with parameters given by the list of \sphinxtitleref{module\_binding} and output module type
\sphinxtitleref{module\_type}.

\end{fulllineitems}

\end{quote}

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

Let us define a simple module.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{M}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{M} \PYG{n}{started}

\PYG{k+kn}{Definition} \PYG{n}{T} \PYG{o}{:=} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{T} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{x} \PYG{o}{:=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{x} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k+kt}{bool}

\PYG{k+kp}{exact} \PYG{n+nb+bp}{true}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Defined}\PYG{o}{.}
    \PYG{n}{y} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{End} \PYG{n}{M}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{M} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Inside a module one can define constants, prove theorems and do any
other things that can be done in the toplevel. Components of a closed
module can be accessed using the dot notation:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{n}{M}\PYG{o}{.}\PYG{n}{x}\PYG{o}{.}
    \PYG{n}{M}\PYG{o}{.}\PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{k+kt}{nat}
\end{sphinxVerbatim}

A simple module type:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{k+kt}{Type} \PYG{n}{SIG}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{k+kt}{Type} \PYG{n}{SIG} \PYG{n}{started}

\PYG{k+kn}{Parameter} \PYG{n}{T} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{.}
    \PYG{n}{T} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Parameter} \PYG{n}{x} \PYG{o}{:} \PYG{n}{T}\PYG{o}{.}
    \PYG{n}{x} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{End} \PYG{n}{SIG}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{k+kt}{Type} \PYG{n}{SIG} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

Now we can create a new module from M, giving it a less precise
specification: the y component is dropped as well as the body of x.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{N} \PYG{o}{:} \PYG{n}{SIG} \PYG{k}{with} \PYG{k+kn}{Definition} \PYG{n}{T} \PYG{o}{:=} \PYG{k+kt}{nat} \PYG{o}{:=} \PYG{n}{M}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{N} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Print} \PYG{n}{N}\PYG{o}{.}\PYG{n}{T}\PYG{o}{.}
    \PYG{n}{N}\PYG{o}{.}\PYG{n}{T} \PYG{o}{=} \PYG{k+kt}{nat}
         \PYG{o}{:} \PYG{k+kn}{Set}

\PYG{k+kn}{Print} \PYG{n}{N}\PYG{o}{.}\PYG{n}{x}\PYG{o}{.}
    \PYG{o}{*}\PYG{o}{*}\PYG{o}{*} \PYG{o}{[} \PYG{n}{N}\PYG{o}{.}\PYG{n}{x} \PYG{o}{:} \PYG{n}{N}\PYG{o}{.}\PYG{n}{T} \PYG{o}{]}

\PYG{n}{Fail} \PYG{k+kn}{Print} \PYG{n}{N}\PYG{o}{.}\PYG{n}{y}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{N}\PYG{o}{.}\PYG{n}{y} \PYG{n}{not} \PYG{n}{a} \PYG{n}{defined} \PYG{n}{object}\PYG{o}{.}
\end{sphinxVerbatim}

The definition of \sphinxcode{\sphinxupquote{N}} using the module type expression \sphinxcode{\sphinxupquote{SIG}} with
\sphinxcode{\sphinxupquote{Definition T := nat}} is equivalent to the following one:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{k+kt}{Type} \PYG{n}{SIG\PYGZsq{}}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{k+kt}{Type} \PYG{n}{SIG\PYGZsq{}} \PYG{n}{started}

\PYG{k+kn}{Definition} \PYG{n}{T} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{T} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Parameter} \PYG{n}{x} \PYG{o}{:} \PYG{n}{T}\PYG{o}{.}
    \PYG{n}{x} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{End} \PYG{n}{SIG\PYGZsq{}}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{k+kt}{Type} \PYG{n}{SIG\PYGZsq{}} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Module} \PYG{n}{N} \PYG{o}{:} \PYG{n}{SIG\PYGZsq{}} \PYG{o}{:=} \PYG{n}{M}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{N} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

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

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{P} \PYG{o}{\PYGZlt{}}\PYG{o}{:} \PYG{n}{SIG} \PYG{o}{:=} \PYG{n}{M}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{P} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Print} \PYG{n}{P}\PYG{o}{.}\PYG{n}{y}\PYG{o}{.}
    \PYG{n}{P}\PYG{o}{.}\PYG{n}{y} \PYG{o}{=} \PYG{n+nb+bp}{true}
         \PYG{o}{:} \PYG{k+kt}{bool}
\end{sphinxVerbatim}

Now let us create a functor, i.e. a parametric module

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{Two} \PYG{o}{(}\PYG{n}{X} \PYG{n}{Y}\PYG{o}{:} \PYG{n}{SIG}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{Two} \PYG{n}{started}

\PYG{k+kn}{Definition} \PYG{n}{T} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{X}\PYG{o}{.}\PYG{n}{T} \PYG{o}{*} \PYG{n}{Y}\PYG{o}{.}\PYG{n}{T}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{type}\PYG{o}{.}
    \PYG{n}{T} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{x} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{X}\PYG{o}{.}\PYG{n}{x}\PYG{o}{,} \PYG{n}{Y}\PYG{o}{.}\PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{x} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{End} \PYG{n}{Two}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{Two} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

and apply it to our modules and do some computations:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{Q} \PYG{o}{:=} \PYG{n}{Two} \PYG{n}{M} \PYG{n}{N}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{Q} \PYG{k}{is} \PYG{n}{defined}

\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{o}{(}\PYG{n}{fst} \PYG{n}{Q}\PYG{o}{.}\PYG{n}{x} \PYG{o}{+} \PYG{n}{snd} \PYG{n}{Q}\PYG{o}{.}\PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{=} \PYG{n}{N}\PYG{o}{.}\PYG{n}{x}
         \PYG{o}{:} \PYG{k+kt}{nat}
\end{sphinxVerbatim}

In the end, let us define a module type with two sub-modules, sharing
some of the fields and give one of its possible implementations:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{k+kt}{Type} \PYG{n}{SIG2}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{k+kt}{Type} \PYG{n}{SIG2} \PYG{n}{started}

\PYG{n}{Declare} \PYG{k+kn}{Module} \PYG{n}{M1} \PYG{o}{:} \PYG{n}{SIG}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{M1} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Module} \PYG{n}{M2} \PYG{o}{\PYGZlt{}}\PYG{o}{:} \PYG{n}{SIG}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{M2} \PYG{n}{started}

\PYG{k+kn}{Definition} \PYG{n}{T} \PYG{o}{:=} \PYG{n}{M1}\PYG{o}{.}\PYG{n}{T}\PYG{o}{.}
    \PYG{n}{T} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Parameter} \PYG{n}{x} \PYG{o}{:} \PYG{n}{T}\PYG{o}{.}
    \PYG{n}{x} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{End} \PYG{n}{M2}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{M2} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{End} \PYG{n}{SIG2}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{k+kt}{Type} \PYG{n}{SIG2} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Module} \PYG{n}{Mod} \PYG{o}{\PYGZlt{}}\PYG{o}{:} \PYG{n}{SIG2}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{Mod} \PYG{n}{started}

\PYG{k+kn}{Module} \PYG{n}{M1}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{M1} \PYG{n}{started}

\PYG{k+kn}{Definition} \PYG{n}{T} \PYG{o}{:=} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{T} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{x} \PYG{o}{:=} \PYG{l+m+mi}{1}\PYG{o}{.}
    \PYG{n}{x} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{End} \PYG{n}{M1}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{M1} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Module} \PYG{n}{M2} \PYG{o}{:=} \PYG{n}{M}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{M2} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{End} \PYG{n}{Mod}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{Mod} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

Notice that \sphinxcode{\sphinxupquote{M}} is a correct body for the component \sphinxcode{\sphinxupquote{M2}} since its \sphinxcode{\sphinxupquote{T}}
component is equal \sphinxcode{\sphinxupquote{nat}} and hence \sphinxcode{\sphinxupquote{M1.T}} as specified.

\begin{sphinxadmonition}{note}{Note:}\begin{enumerate}
\def\theenumi{\arabic{enumi}}
\def\labelenumi{\theenumi .}
\makeatletter\def\p@enumii{\p@enumi \theenumi .}\makeatother
\item {} 
Modules and module types can be nested components of each other.

\item {} 
One can have sections inside a module or a module type, but not a
module or a module type inside a section.

\item {} 
Commands like \sphinxcode{\sphinxupquote{Hint}} or \sphinxcode{\sphinxupquote{Notation}} can also appear inside modules and
module types. Note that in case of a module definition like:

\end{enumerate}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Module N : SIG := M.
\end{sphinxVerbatim}

or:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Module N : SIG. … End N.
\end{sphinxVerbatim}

hints and the like valid for \sphinxcode{\sphinxupquote{N}} are not those defined in \sphinxcode{\sphinxupquote{M}}
(or the module body) but the ones defined in \sphinxcode{\sphinxupquote{SIG}}.
\end{sphinxadmonition}
\phantomsection\label{\detokenize{language/gallina-extensions:import-qualid}}\index{Import (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.import}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Import~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
If \sphinxtitleref{qualid} denotes a valid basic module (i.e. its module type is a
signature), makes its components available by their short names.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{Mod}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{Mod} \PYG{n}{started}

\PYG{k+kn}{Definition} \PYG{n}{T}\PYG{o}{:=}\PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{T} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Check} \PYG{n}{T}\PYG{o}{.}
    \PYG{n}{T}
         \PYG{o}{:} \PYG{k+kn}{Set}

\PYG{k+kn}{End} \PYG{n}{Mod}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{Mod} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Check} \PYG{n}{Mod}\PYG{o}{.}\PYG{n}{T}\PYG{o}{.}
    \PYG{n}{Mod}\PYG{o}{.}\PYG{n}{T}
         \PYG{o}{:} \PYG{k+kn}{Set}

\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{n}{T}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{The} \PYG{n}{reference} \PYG{n}{T} \PYG{n}{was} \PYG{n}{not} \PYG{n}{found} \PYG{k}{in} \PYG{n}{the} \PYG{n}{current} \PYG{n}{environment}\PYG{o}{.}

\PYG{k+kn}{Import} \PYG{n}{Mod}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{n}{T}\PYG{o}{.}
    \PYG{n}{T}
         \PYG{o}{:} \PYG{k+kn}{Set}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Some features defined in modules are activated only when a module is
imported. This is for instance the case of notations (see {\hyperref[\detokenize{user-extensions/syntax-extensions:notations}]{\sphinxcrossref{\DUrole{std,std-ref}{Notations}}}}).

Declarations made with the \sphinxcode{\sphinxupquote{Local}} flag are never imported by the {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}}
command. Such declarations are only accessible through their fully
qualified name.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{A}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{A} \PYG{n}{started}

\PYG{k+kn}{Module} \PYG{n}{B}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{B} \PYG{n}{started}

\PYG{k+kn}{Local} \PYG{k+kn}{Definition} \PYG{n}{T} \PYG{o}{:=} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{T} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{End} \PYG{n}{B}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{B} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{End} \PYG{n}{A}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{A} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Import} \PYG{n}{A}\PYG{o}{.}
\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{n}{B}\PYG{o}{.}\PYG{n}{T}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{The} \PYG{n}{reference} \PYG{n}{B}\PYG{o}{.}\PYG{n}{T} \PYG{n}{was} \PYG{n}{not} \PYG{n}{found} \PYG{k}{in} \PYG{n}{the} \PYG{n}{current} \PYG{n}{environment}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{Export (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmdv.export}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Export~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
When the module containing the command Export qualid
is imported, qualid is imported as well.

\end{fulllineitems}

\index{‘qualid’ is not a module (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:exn.qualid-is-not-a-module}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~is~not~a~module.}}}}
\end{fulllineitems}

\index{Trying to mask the absolute name ‘qualid’"! (warn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:warn.trying-to-mask-the-absolute-name-qualid}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Trying~to~mask~the~absolute~name~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}!}}}}
\end{fulllineitems}


\end{fulllineitems}

\index{Print Module (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.print-module}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Module~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Prints the module type and (optionally) the body of the module \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}

\index{Print Module Type (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.print-module-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Module~Type~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Prints the module type corresponding to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}

\index{Short Module Printing (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.short-module-printing}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Short~Module~Printing}}}}
This option (off by default) disables the printing of the types of fields,
leaving only their names, for the commands {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.print-module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Module}}}}} and
{\hyperref[\detokenize{language/gallina-extensions:coq:cmd.print-module-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Module Type}}}}}.

\end{fulllineitems}



\subsection{Libraries and qualified names}
\label{\detokenize{language/gallina-extensions:libraries-and-qualified-names}}

\subsubsection{Names of libraries}
\label{\detokenize{language/gallina-extensions:names-of-libraries}}\label{\detokenize{language/gallina-extensions:id5}}
The theories developed in \DUrole{smallcaps}{Coq} are stored in \sphinxstyleemphasis{library files} which are
hierarchically classified into \sphinxstyleemphasis{libraries} and \sphinxstyleemphasis{sublibraries}. To
express this hierarchy, library names are represented by qualified
identifiers qualid, i.e. as list of identifiers separated by dots (see
{\hyperref[\detokenize{language/gallina-specification-language:gallina-identifiers}]{\sphinxcrossref{\DUrole{std,std-ref}{Qualified identifiers and simple identifiers}}}}). For instance, the library file \sphinxcode{\sphinxupquote{Mult}} of the standard
\DUrole{smallcaps}{Coq} library \sphinxcode{\sphinxupquote{Arith}} is named \sphinxcode{\sphinxupquote{Coq.Arith.Mult}}. The identifier that starts
the name of a library is called a \sphinxstyleemphasis{library root}. All library files of
the standard library of \DUrole{smallcaps}{Coq} have the reserved root \DUrole{smallcaps}{Coq} but library
filenames based on other roots can be obtained by using \DUrole{smallcaps}{Coq} commands
(coqc, coqtop, coqdep, …) options \sphinxcode{\sphinxupquote{-Q}} or \sphinxcode{\sphinxupquote{-R}} (see {\hyperref[\detokenize{practical-tools/coq-commands:command-line-options}]{\sphinxcrossref{\DUrole{std,std-ref}{By command line options}}}}).
Also, when an interactive \DUrole{smallcaps}{Coq} session starts, a library of root \sphinxcode{\sphinxupquote{Top}} is
started, unless option \sphinxcode{\sphinxupquote{-top}} or \sphinxcode{\sphinxupquote{-notop}} is set (see {\hyperref[\detokenize{practical-tools/coq-commands:command-line-options}]{\sphinxcrossref{\DUrole{std,std-ref}{By command line options}}}}).


\subsubsection{Qualified names}
\label{\detokenize{language/gallina-extensions:qualified-names}}\label{\detokenize{language/gallina-extensions:id6}}
Library files are modules which possibly contain submodules which
eventually contain constructions (axioms, parameters, definitions,
lemmas, theorems, remarks or facts). The \sphinxstyleemphasis{absolute name}, or \sphinxstyleemphasis{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 \sphinxcode{\sphinxupquote{Coq.Init.Logic.eq}} denotes Leibniz’
equality defined in the module Logic in the sublibrary \sphinxcode{\sphinxupquote{Init}} of the
standard library of \DUrole{smallcaps}{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 \sphinxcode{\sphinxupquote{Coq.Init.Logic.eq}} is \sphinxcode{\sphinxupquote{eq}}). Any partial suffix of the absolute
name is a \sphinxstyleemphasis{partially qualified name} (e.g. \sphinxcode{\sphinxupquote{Logic.eq}} is a partially
qualified name for \sphinxcode{\sphinxupquote{Coq.Init.Logic.eq}}). Especially, the short name of a
construction is its shortest partially qualified name.

\DUrole{smallcaps}{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.

\sphinxstylestrong{Visibility}

\DUrole{smallcaps}{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 {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}}, {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} and {\hyperref[\detokenize{language/gallina-extensions:coq:cmdv.export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{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
\DUrole{smallcaps}{Coq} name table. Definitions flagged as Local are only accessible with
their fully qualified name (see {\hyperref[\detokenize{language/gallina-specification-language:gallina-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{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.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{k+kt}{nat}

\PYG{k+kn}{Definition} \PYG{k+kt}{nat} \PYG{o}{:=} \PYG{k+kt}{bool}\PYG{o}{.}
    \PYG{k+kt}{nat} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Check} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{n}{Datatypes}\PYG{o}{.}\PYG{k+kt}{nat}

\PYG{k+kn}{Check} \PYG{n}{Datatypes}\PYG{o}{.}\PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{Datatypes}\PYG{o}{.}\PYG{k+kt}{nat}
         \PYG{o}{:} \PYG{k+kn}{Set}

\PYG{n}{Locate} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{Constant} \PYG{n}{Top}\PYG{o}{.}\PYG{k+kt}{nat}
    \PYG{k+kn}{Inductive} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Datatypes}\PYG{o}{.}\PYG{k+kt}{nat}
      \PYG{o}{(}\PYG{n}{shorter} \PYG{n}{name} \PYG{n}{to} \PYG{n}{refer} \PYG{n}{to} \PYG{n}{it} \PYG{k}{in} \PYG{n}{current} \PYG{n}{context} \PYG{k}{is} \PYG{n}{Datatypes}\PYG{o}{.}\PYG{k+kt}{nat}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\sphinxstrong{See also:}


Commands {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.locate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Locate}}}}} and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.locate-library}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Locate Library}}}}}.




\subsubsection{Libraries and filesystem}
\label{\detokenize{language/gallina-extensions:libraries-and-filesystem}}\label{\detokenize{language/gallina-extensions:id7}}
\begin{sphinxadmonition}{note}{Note:}
The questions described here have been subject to redesign in \DUrole{smallcaps}{Coq} 8.5.
Former versions of \DUrole{smallcaps}{Coq} use the same terminology to describe slightly different things.
\end{sphinxadmonition}

Compiled files (\sphinxcode{\sphinxupquote{.vo}} and \sphinxcode{\sphinxupquote{.vio}}) store sub-libraries. In order to refer
to them inside \DUrole{smallcaps}{Coq}, a translation from file-system names to \DUrole{smallcaps}{Coq} names
is needed. In this translation, names in the file system are called
\sphinxstyleemphasis{physical} paths while \DUrole{smallcaps}{Coq} names are contrastingly called \sphinxstyleemphasis{logical}
names.

A logical prefix Lib can be associated to a physical pathpath using
the command line option \sphinxcode{\sphinxupquote{-Q}} \sphinxtitleref{path} \sphinxcode{\sphinxupquote{Lib}}. All subfolders of path are
recursively associated to the logical path \sphinxcode{\sphinxupquote{Lib}} extended with the
corresponding suffix coming from the physical path. For instance, the
folder \sphinxcode{\sphinxupquote{path/fOO/Bar}} maps to \sphinxcode{\sphinxupquote{Lib.fOO.Bar}}. Subdirectories corresponding
to invalid \DUrole{smallcaps}{Coq} identifiers are skipped, and, by convention,
subdirectories named \sphinxcode{\sphinxupquote{CVS}} or \sphinxcode{\sphinxupquote{\_darcs}} are skipped too.

Thanks to this mechanism, \sphinxcode{\sphinxupquote{.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
\sphinxcode{\sphinxupquote{path/fOO/Bar/File.vo}} is \sphinxcode{\sphinxupquote{Lib.fOO.Bar.File}}. The same caveat applies for
invalid identifiers. When compiling a source file, the \sphinxcode{\sphinxupquote{.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. \DUrole{smallcaps}{Coq} commands associate automatically a logical path to files in
the repository trees rooted at the directory from where the command is
launched, \sphinxcode{\sphinxupquote{coqlib/user-contrib/}}, the directories listed in the
\sphinxcode{\sphinxupquote{\$COQPATH}}, \sphinxcode{\sphinxupquote{\$\{XDG\_DATA\_HOME\}/coq/}} and \sphinxcode{\sphinxupquote{\$\{XDG\_DATA\_DIRS\}/coq/}}
environment variables (see \sphinxhref{http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html}{XDG base directory specification}%
\begin{footnote}[6]\sphinxAtStartFootnote
\sphinxnolinkurl{http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html}
%
\end{footnote})
with the same physical-to-logical translation and with an empty logical prefix.

The command line option \sphinxcode{\sphinxupquote{-R}} is a variant of \sphinxcode{\sphinxupquote{-Q}} which has the strictly
same behavior regarding loadpaths, but which also makes the
corresponding \sphinxcode{\sphinxupquote{.vo}} files available through their short names in a way
not unlike the \sphinxcode{\sphinxupquote{Import}} command (see {\hyperref[\detokenize{language/gallina-extensions:import-qualid}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}). For instance, \sphinxcode{\sphinxupquote{-R}} \sphinxtitleref{path} \sphinxcode{\sphinxupquote{Lib}}
associates to the file path \sphinxtitleref{path}\sphinxcode{\sphinxupquote{/path/fOO/Bar/File.vo}} the logical name
\sphinxcode{\sphinxupquote{Lib.fOO.Bar.File}}, but allows this file to be accessed through the
short names \sphinxcode{\sphinxupquote{fOO.Bar.File,Bar.File}} and \sphinxcode{\sphinxupquote{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 \sphinxcode{\sphinxupquote{From}} argument
of the \sphinxcode{\sphinxupquote{Require}} command can be used to bypass the implicit shortening
by providing an absolute root to the required file (see {\hyperref[\detokenize{proof-engine/vernacular-commands:compiled-files}]{\sphinxcrossref{\DUrole{std,std-ref}{Compiled files}}}}).

There also exists another independent loadpath mechanism attached to
OCaml object files (\sphinxcode{\sphinxupquote{.cmo}} or \sphinxcode{\sphinxupquote{.cmxs}}) rather than \DUrole{smallcaps}{Coq} object
files as described above. The OCaml loadpath is managed using
the option \sphinxcode{\sphinxupquote{-I}} \sphinxtitleref{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 \sphinxcode{\sphinxupquote{Declare}} \sphinxcode{\sphinxupquote{ML}} \sphinxcode{\sphinxupquote{Module}} in
{\hyperref[\detokenize{proof-engine/vernacular-commands:compiled-files}]{\sphinxcrossref{\DUrole{std,std-ref}{Compiled files}}}} to understand the need of the OCaml loadpath.

See {\hyperref[\detokenize{practical-tools/coq-commands:command-line-options}]{\sphinxcrossref{\DUrole{std,std-ref}{By command line options}}}} for a more general view over the \DUrole{smallcaps}{Coq} command
line options.


\subsection{Implicit arguments}
\label{\detokenize{language/gallina-extensions:implicit-arguments}}\label{\detokenize{language/gallina-extensions:implicitarguments}}
An implicit argument of a function is an argument which can be
inferred from contextual knowledge. There are different kinds of
implicit arguments that can be considered implicit in different ways.
There are also various commands to control the setting or the
inference of implicit arguments.


\subsubsection{The different kinds of implicit arguments}
\label{\detokenize{language/gallina-extensions:the-different-kinds-of-implicit-arguments}}

\paragraph{Implicit arguments inferable from the knowledge of other arguments of a function}
\label{\detokenize{language/gallina-extensions:implicit-arguments-inferable-from-the-knowledge-of-other-arguments-of-a-function}}
The first kind of implicit arguments covers the arguments that are
inferable from the knowledge of the type of other arguments of the
function, or of the type of the surrounding context of the
application. Especially, such implicit arguments correspond to
parameters dependent in the type of the function. Typical implicit
arguments are the type arguments in polymorphic functions. There are
several kinds of such implicit arguments.

\sphinxstylestrong{Strict Implicit Arguments}

An implicit argument can be either strict or non strict. An implicit
argument is said to be \sphinxstyleemphasis{strict} if, whatever the other arguments of the
function are, it is still inferable from the type of some other
argument. Technically, an implicit argument is strict if it
corresponds to a parameter which is not applied to a variable which
itself is another parameter of the function (since this parameter may
erase its arguments), not in the body of a match, and not itself
applied or matched against patterns (since the original form of the
argument can be lost by reduction).

For instance, the first argument of

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
cons: forall A:Set, A \PYGZhy{}\PYGZgt{} list A \PYGZhy{}\PYGZgt{} list A
\end{sphinxVerbatim}

in module \sphinxcode{\sphinxupquote{List.v}} is strict because \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{list}}} is an inductive type and \sphinxcode{\sphinxupquote{\DUrole{name}{A}}}
will always be inferable from the type \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{list} \DUrole{name}{A}}} of the third argument of
\sphinxcode{\sphinxupquote{\DUrole{name}{cons}}}. Also, the first argument of \sphinxcode{\sphinxupquote{\DUrole{name}{cons}}} is strict with respect to the second one,
since the first argument is exactly the type of the second argument.
On the contrary, the second argument of a term of type

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
forall P:nat\PYGZhy{}\PYGZgt{}Prop, forall n:nat, P n \PYGZhy{}\PYGZgt{} ex nat P
\end{sphinxVerbatim}

is implicit but not strict, since it can only be inferred from the
type \sphinxcode{\sphinxupquote{\DUrole{name}{P} \DUrole{name}{n}}} of the third argument and if \sphinxcode{\sphinxupquote{\DUrole{name}{P}}} is, e.g., \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{operator}{\_} \DUrole{operator}{=\textgreater{}} \DUrole{name}{True}}}, it
reduces to an expression where \sphinxcode{\sphinxupquote{n}} does not occur any longer. The first
argument \sphinxcode{\sphinxupquote{\DUrole{name}{P}}} is implicit but not strict either because it can only be
inferred from \sphinxcode{\sphinxupquote{\DUrole{name}{P} \DUrole{name}{n}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{P}}} is not canonically inferable from an arbitrary
\sphinxcode{\sphinxupquote{\DUrole{name}{n}}} and the normal form of \sphinxcode{\sphinxupquote{\DUrole{name}{P} \DUrole{name}{n}}}. Consider, e.g., that \sphinxcode{\sphinxupquote{\DUrole{name}{n}}} is \(0\) and the third
argument has type \sphinxcode{\sphinxupquote{\DUrole{name}{True}}}, then any \sphinxcode{\sphinxupquote{\DUrole{name}{P}}} of the form

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
fun n =\PYGZgt{} match n with 0 =\PYGZgt{} True \textbar{} \PYGZus{} =\PYGZgt{} anything end
\end{sphinxVerbatim}

would be a solution of the inference problem.

\sphinxstylestrong{Contextual Implicit Arguments}

An implicit argument can be \sphinxstyleemphasis{contextual} or not. An implicit argument
is said \sphinxstyleemphasis{contextual} if it can be inferred only from the knowledge of
the type of the context of the current expression. For instance, the
only argument of:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
nil : forall A:Set, list A{}`
\end{sphinxVerbatim}

is contextual. Similarly, both arguments of a term of type:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
forall P:nat\PYGZhy{}\PYGZgt{}Prop, forall n:nat, P n \PYGZbs{}/ n = 0
\end{sphinxVerbatim}

are contextual (moreover, \sphinxcode{\sphinxupquote{\DUrole{name}{n}}} is strict and \sphinxcode{\sphinxupquote{\DUrole{name}{P}}} is not).

\sphinxstylestrong{Reversible-Pattern Implicit Arguments}

There is another class of implicit arguments that can be reinferred
unambiguously if all the types of the remaining arguments are known.
This is the class of implicit arguments occurring in the type of
another argument in position of reversible pattern, which means it is
at the head of an application but applied only to uninstantiated
distinct variables. Such an implicit argument is called \sphinxstyleemphasis{reversible-
pattern implicit argument}. A typical example is the argument \sphinxcode{\sphinxupquote{\DUrole{name}{P}}} of
nat\_rec in

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
nat\PYGZus{}rec : forall P : nat \PYGZhy{}\PYGZgt{} Set, P 0 \PYGZhy{}\PYGZgt{}
  (forall n : nat, P n \PYGZhy{}\PYGZgt{} P (S n)) \PYGZhy{}\PYGZgt{} forall x : nat, P x
\end{sphinxVerbatim}

(\sphinxcode{\sphinxupquote{\DUrole{name}{P}}} is reinferable by abstracting over \sphinxcode{\sphinxupquote{\DUrole{name}{n}}} in the type \sphinxcode{\sphinxupquote{\DUrole{name}{P} \DUrole{name}{n}}}).

See {\hyperref[\detokenize{language/gallina-extensions:controlling-rev-pattern-implicit-args}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling reversible-pattern implicit arguments}}}} for the automatic declaration of reversible-pattern
implicit arguments.


\paragraph{Implicit arguments inferable by resolution}
\label{\detokenize{language/gallina-extensions:implicit-arguments-inferable-by-resolution}}
This corresponds to a class of non-dependent implicit arguments that
are solved based on the structure of their type only.


\subsubsection{Maximal or non maximal insertion of implicit arguments}
\label{\detokenize{language/gallina-extensions:maximal-or-non-maximal-insertion-of-implicit-arguments}}
In case a function is partially applied, and the next argument to be
applied is an implicit argument, two disciplines are applicable. In
the first case, the function is considered to have no arguments
furtherly: one says that the implicit argument is not maximally
inserted. In the second case, the function is considered to be
implicitly applied to the implicit arguments it is waiting for: one
says that the implicit argument is maximally inserted.

Each implicit argument can be declared to have to be inserted maximally or non
maximally. This can be governed argument per argument by the command
{\hyperref[\detokenize{language/gallina-extensions:coq:cmd.arguments-implicits}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments (implicits)}}}}} or globally by the {\hyperref[\detokenize{language/gallina-extensions:coq:flag.maximal-implicit-insertion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Maximal Implicit Insertion}}}}} option.


\sphinxstrong{See also:}


{\hyperref[\detokenize{language/gallina-extensions:displaying-implicit-args}]{\sphinxcrossref{\DUrole{std,std-ref}{Displaying what the implicit arguments are}}}}.




\subsubsection{Casual use of implicit arguments}
\label{\detokenize{language/gallina-extensions:casual-use-of-implicit-arguments}}
In a given expression, if it is clear that some argument of a function
can be inferred from the type of the other arguments, the user can
force the given argument to be guessed by replacing it by “\_”. If
possible, the correct argument will be automatically generated.
\index{Cannot infer a term for this placeholder. (Casual use of implicit arguments) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:exn.cannot-infer-a-term-for-this-placeholder-casual-use-of-implicit-arguments}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~infer~a~term~for~this~placeholder.}}}}
\DUrole{smallcaps}{Coq} was not able to deduce an instantiation of a “\_”.

\end{fulllineitems}



\subsubsection{Declaration of implicit arguments}
\label{\detokenize{language/gallina-extensions:declaration-of-implicit-arguments}}\label{\detokenize{language/gallina-extensions:declare-implicit-args}}
In case one wants that some arguments of a given object (constant,
inductive types, constructors, assumptions, local or not) are always
inferred by \DUrole{smallcaps}{Coq}, one may declare once and for all which are the
expected implicit arguments of this object. There are two ways to do
this, \sphinxstyleemphasis{a priori} and \sphinxstyleemphasis{a posteriori}.


\paragraph{Implicit Argument Binders}
\label{\detokenize{language/gallina-extensions:implicit-argument-binders}}
In the first setting, one wants to explicitly give the implicit
arguments of a declared object as part of its definition. To do this,
one has to surround the bindings of implicit arguments by curly
braces:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{id} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{n}{A} \PYG{o}{:=} \PYG{n}{x}\PYG{o}{.}
    \PYG{n}{id} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

This automatically declares the argument A of id as a maximally
inserted implicit argument. One can then do as-if the argument was
absent in every situation but still be able to specify it if needed:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{compose} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{n}{B} \PYG{n}{C}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{g} \PYG{o}{:} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{g} \PYG{o}{(}\PYG{n}{f} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{compose} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{A}\PYG{o}{,} \PYG{n}{compose} \PYG{n}{id} \PYG{n}{id} \PYG{o}{=} \PYG{n}{id} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:=}\PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{,} \PYG{n}{compose} \PYG{n}{id} \PYG{n}{id} \PYG{o}{=} \PYG{n}{id}
\end{sphinxVerbatim}

The syntax is supported in all top-level definitions:
{\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}}, {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}}, {\hyperref[\detokenize{language/gallina-specification-language:coq:cmdv.lemma}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Lemma}}}}} and so on. For (co-)inductive datatype
declarations, the semantics are the following: an inductive parameter
declared as an implicit argument need not be repeated in the inductive
definition but will become implicit for the constructors of the
inductive only, not the inductive type itself. For example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{k+kt}{list} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{:} \PYG{k+kt}{list}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list}\PYG{o}{.}
    \PYG{k+kt}{list} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Print} \PYG{k+kt}{list}\PYG{o}{.}
    \PYG{k+kn}{Inductive} \PYG{k+kt}{list} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}  \PYG{n}{nil} \PYG{o}{:} \PYG{k+kt}{list} \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list}
    
    \PYG{n}{For} \PYG{k+kt}{list}\PYG{o}{:} \PYG{n}{Argument} \PYG{n}{A} \PYG{k}{is} \PYG{n}{implicit} \PYG{n}{and} \PYG{n}{maximally} \PYG{n}{inserted}
    \PYG{n}{For} \PYG{n}{nil}\PYG{o}{:} \PYG{n}{Argument} \PYG{n}{A} \PYG{k}{is} \PYG{n}{implicit} \PYG{n}{and} \PYG{n}{maximally} \PYG{n}{inserted}
    \PYG{n}{For} \PYG{n}{cons}\PYG{o}{:} \PYG{n}{Argument} \PYG{n}{A} \PYG{k}{is} \PYG{n}{implicit} \PYG{n}{and} \PYG{n}{maximally} \PYG{n}{inserted}
    \PYG{n}{For} \PYG{k+kt}{list}\PYG{o}{:} \PYG{n}{Argument} \PYG{n}{scope} \PYG{k}{is} \PYG{o}{[}\PYG{n}{type\PYGZus{}scope}\PYG{o}{]}
    \PYG{n}{For} \PYG{n}{nil}\PYG{o}{:} \PYG{n}{Argument} \PYG{n}{scope} \PYG{k}{is} \PYG{o}{[}\PYG{n}{type\PYGZus{}scope}\PYG{o}{]}
    \PYG{n}{For} \PYG{n}{cons}\PYG{o}{:} \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{]}
\end{sphinxVerbatim}

One can always specify the parameter if it is not uniform using the
usual implicit arguments disambiguation syntax.


\paragraph{Declaring Implicit Arguments}
\label{\detokenize{language/gallina-extensions:declaring-implicit-arguments}}
To set implicit arguments \sphinxstyleemphasis{a posteriori}, one can use the command:
\index{Arguments (implicits) (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.arguments-implicits}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Arguments~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{possibly\_bracketed\_ident}}\DUrole{notation-sup}{*}}}}}}
\end{fulllineitems}


where the list of \sphinxtitleref{possibly\_bracketed\_ident} is a prefix of the list of
arguments of \sphinxtitleref{qualid} where the ones to be declared implicit are
surrounded by square brackets and the ones to be declared as maximally
inserted implicits are surrounded by curly braces.

After the above declaration is issued, implicit arguments can just
(and have to) be skipped in any expression involving an application
of \sphinxtitleref{qualid}.

Implicit arguments can be cleared with the following syntax:
\index{Arguments (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.arguments}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Arguments~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~:~clear~implicits}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Global~Arguments~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{possibly\_bracketed\_ident}}\DUrole{notation-sup}{*}}}}}}
Says to recompute the implicit arguments of
\sphinxtitleref{qualid} after ending of the current section if any, enforcing the
implicit arguments known from inside the section to be the ones
declared by the command.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Arguments~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{possibly\_bracketed\_ident}}\DUrole{notation-sup}{*}}}}}}
When in a module, tell not to activate the
implicit arguments ofqualid declared by this command to contexts that
require the module.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Global~\textbar{}~Local}\DUrole{notation-sup}{?}}~Arguments~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{possibly\_bracketed\_ident}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}}}}}}
For names of constants, inductive types,
constructors, lemmas which can only be applied to a fixed number of
arguments (this excludes for instance constants whose type is
polymorphic), multiple implicit arguments declarations can be given.
Depending on the number of arguments qualid is applied to in practice,
the longest applicable list of implicit arguments is used to select
which implicit arguments are inserted. For printing, the omitted
arguments are the ones of the longest list of implicit arguments of
the sequence.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{k+kt}{list} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{.}
    \PYG{k+kt}{list} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{cons} \PYG{k+kt}{nat} \PYG{l+m+mi}{3} \PYG{o}{(}\PYG{n}{nil} \PYG{k+kt}{nat}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{cons} \PYG{k+kt}{nat} \PYG{l+m+mi}{3} \PYG{o}{(}\PYG{n}{nil} \PYG{k+kt}{nat}\PYG{o}{)}
         \PYG{o}{:} \PYG{k+kt}{list} \PYG{k+kt}{nat}

\PYG{k+kn}{Arguments} \PYG{n}{cons} \PYG{o}{[}\PYG{n}{A}\PYG{o}{]} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{.}
\PYG{k+kn}{Arguments} \PYG{n}{nil} \PYG{o}{[}\PYG{n}{A}\PYG{o}{]}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{cons} \PYG{l+m+mi}{3} \PYG{n}{nil}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{cons} \PYG{l+m+mi}{3} \PYG{n}{nil}
         \PYG{o}{:} \PYG{k+kt}{list} \PYG{k+kt}{nat}

\PYG{k+kn}{Fixpoint} \PYG{n}{map} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f}\PYG{o}{:}\PYG{n}{A}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{n}{B}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l}\PYG{o}{:}\PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{B} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{l} \PYG{k}{with} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil} \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{n}{a} \PYG{n}{t} \PYG{o}{=\PYGZgt{}} \PYG{n}{cons} \PYG{o}{(}\PYG{n}{f} \PYG{n}{a}\PYG{o}{)} \PYG{o}{(}\PYG{n}{map} \PYG{n}{A} \PYG{n}{B} \PYG{n}{f} \PYG{n}{t}\PYG{o}{)} \PYG{k}{end}\PYG{o}{.}
    \PYG{n}{map} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{map} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{4}\PYG{n}{th} \PYG{n}{argument}\PYG{o}{)}

\PYG{k+kn}{Fixpoint} \PYG{n}{length} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l}\PYG{o}{:}\PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{l} \PYG{k}{with} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{\PYGZus{}} \PYG{n}{m} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{length} \PYG{n}{A} \PYG{n}{m}\PYG{o}{)} \PYG{k}{end}\PYG{o}{.}
    \PYG{n}{length} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{length} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{2}\PYG{n}{nd} \PYG{n}{argument}\PYG{o}{)}

\PYG{k+kn}{Arguments} \PYG{n}{map} \PYG{o}{[}\PYG{n}{A} \PYG{n}{B}\PYG{o}{]} \PYG{n}{f} \PYG{n}{l}\PYG{o}{.}
\PYG{k+kn}{Arguments} \PYG{n}{length} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}} \PYG{n}{l}\PYG{o}{.}
\PYG{c}{(*}\PYG{c}{ A has to be maximally inserted }\PYG{c}{*)}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{l}\PYG{o}{:}\PYG{k+kt}{list} \PYG{o}{(}\PYG{k+kt}{list} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{map} \PYG{n}{length} \PYG{n}{l}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{o}{(}\PYG{k+kt}{list} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{map} \PYG{n}{length} \PYG{n}{l}
         \PYG{o}{:} \PYG{k+kt}{list} \PYG{o}{(}\PYG{k+kt}{list} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{k+kt}{nat}

\PYG{k+kn}{Arguments} \PYG{n}{map} \PYG{o}{[}\PYG{n}{A} \PYG{n}{B}\PYG{o}{]} \PYG{n}{f} \PYG{n}{l}\PYG{o}{,} \PYG{o}{[}\PYG{n}{A}\PYG{o}{]} \PYG{n}{B} \PYG{n}{f} \PYG{n}{l}\PYG{o}{,} \PYG{n}{A} \PYG{n}{B} \PYG{n}{f} \PYG{n}{l}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{l} \PYG{o}{=\PYGZgt{}} \PYG{n}{map} \PYG{n}{length} \PYG{n}{l} \PYG{o}{=} \PYG{n}{map} \PYG{o}{(}\PYG{k+kt}{list} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{k+kt}{nat} \PYG{n}{length} \PYG{n}{l}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{o}{(}\PYG{k+kt}{list} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{map} \PYG{n}{length} \PYG{n}{l} \PYG{o}{=} \PYG{n}{map} \PYG{n}{length} \PYG{n}{l}
         \PYG{o}{:} \PYG{k+kt}{list} \PYG{o}{(}\PYG{k+kt}{list} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Remark: To know which are the implicit arguments of an object, use the
command \sphinxcode{\sphinxupquote{Print Implicit}} (see {\hyperref[\detokenize{language/gallina-extensions:displaying-implicit-args}]{\sphinxcrossref{\DUrole{std,std-ref}{Displaying what the implicit arguments are}}}}).


\subsubsection{Automatic declaration of implicit arguments}
\label{\detokenize{language/gallina-extensions:automatic-declaration-of-implicit-arguments}}
\DUrole{smallcaps}{Coq} can also automatically detect what are the implicit arguments of a
defined object. The command is just
\index{Arguments (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Arguments~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~:~default~implicits}}}}
\end{fulllineitems}


The auto-detection is governed by options telling if strict,
contextual, or reversible-pattern implicit arguments must be
considered or not (see {\hyperref[\detokenize{language/gallina-extensions:controlling-strict-implicit-args}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling strict implicit arguments}}}}, {\hyperref[\detokenize{language/gallina-extensions:controlling-strict-implicit-args}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling strict implicit arguments}}}},
{\hyperref[\detokenize{language/gallina-extensions:controlling-rev-pattern-implicit-args}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling reversible-pattern implicit arguments}}}}, and also {\hyperref[\detokenize{language/gallina-extensions:controlling-insertion-implicit-args}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling the insertion of implicit arguments not followed by explicit arguments}}}}).


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Global~Arguments~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~:~default~implicits}}}}
Tell to recompute the
implicit arguments of qualid after ending of the current section if
any.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Arguments~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~:~default~implicits}}}}
When in a module, tell not to activate the implicit arguments of \sphinxtitleref{qualid} computed by this
declaration to contexts that requires the module.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{k+kt}{list} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{.}
    \PYG{k+kt}{list} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Arguments} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{default} \PYG{n}{implicits}\PYG{o}{.}
\PYG{k+kn}{Print} \PYG{k+kn}{Implicit} \PYG{n}{cons}\PYG{o}{.}
    \PYG{n}{cons} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{n}{A}
    
    \PYG{n}{Argument} \PYG{n}{A} \PYG{k}{is} \PYG{n}{implicit}

\PYG{k+kn}{Arguments} \PYG{n}{nil} \PYG{o}{:} \PYG{n}{default} \PYG{n}{implicits}\PYG{o}{.}
\PYG{k+kn}{Print} \PYG{k+kn}{Implicit} \PYG{n}{nil}\PYG{o}{.}
    \PYG{n}{nil} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{,} \PYG{k+kt}{list} \PYG{n}{A}

\PYG{k+kn}{Set} \PYG{k+kn}{Contextual} \PYG{k+kn}{Implicit}\PYG{o}{.}
\PYG{k+kn}{Arguments} \PYG{n}{nil} \PYG{o}{:} \PYG{n}{default} \PYG{n}{implicits}\PYG{o}{.}
\PYG{k+kn}{Print} \PYG{k+kn}{Implicit} \PYG{n}{nil}\PYG{o}{.}
    \PYG{n}{nil} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{,} \PYG{k+kt}{list} \PYG{n}{A}
    
    \PYG{n}{Argument} \PYG{n}{A} \PYG{k}{is} \PYG{n}{implicit} \PYG{n}{and} \PYG{n}{maximally} \PYG{n}{inserted}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The computation of implicit arguments takes account of the unfolding
of constants. For instance, the variable \sphinxcode{\sphinxupquote{p}} below has type
\sphinxcode{\sphinxupquote{(Transitivity R)}} which is reducible to
\sphinxcode{\sphinxupquote{forall x,y:U, R x y -\textgreater{} forall z:U, R y z -\textgreater{} R x z}}. As the variables \sphinxcode{\sphinxupquote{x}}, \sphinxcode{\sphinxupquote{y}} and \sphinxcode{\sphinxupquote{z}}
appear strictly in the body of the type, they are implicit.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variable} \PYG{n}{X} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{.}
    \PYG{n}{X} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Definition} \PYG{k+kn}{Relation} \PYG{o}{:=} \PYG{n}{X} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{X} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{k+kn}{Relation} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{Transitivity} \PYG{o}{(}\PYG{n}{R}\PYG{o}{:}\PYG{k+kn}{Relation}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{:}\PYG{n}{X}\PYG{o}{,} \PYG{n}{R} \PYG{n}{x} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{z}\PYG{o}{:}\PYG{n}{X}\PYG{o}{,} \PYG{n}{R} \PYG{n}{y} \PYG{n}{z} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R} \PYG{n}{x} \PYG{n}{z}\PYG{o}{.}
    \PYG{n}{Transitivity} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Variables} \PYG{o}{(}\PYG{n}{R} \PYG{o}{:} \PYG{k+kn}{Relation}\PYG{o}{)} \PYG{o}{(}\PYG{n}{p} \PYG{o}{:} \PYG{n}{Transitivity} \PYG{n}{R}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{R} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{p} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Arguments} \PYG{n}{p} \PYG{o}{:} \PYG{n}{default} \PYG{n}{implicits}\PYG{o}{.}
\PYG{k+kn}{Print} \PYG{n}{p}\PYG{o}{.}
    \PYG{o}{*}\PYG{o}{*}\PYG{o}{*} \PYG{o}{[} \PYG{n}{p} \PYG{o}{:} \PYG{n}{Transitivity} \PYG{n}{R} \PYG{o}{]}
    
    \PYG{n}{Expanded} \PYG{n}{type} \PYG{k}{for} \PYG{n}{implicit} \PYG{n}{arguments}
    \PYG{n}{p} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{X}\PYG{o}{,} \PYG{n}{R} \PYG{n}{x} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{z} \PYG{o}{:} \PYG{n}{X}\PYG{o}{,} \PYG{n}{R} \PYG{n}{y} \PYG{n}{z} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R} \PYG{n}{x} \PYG{n}{z}
    
    \PYG{k+kn}{Arguments} \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{n}{are} \PYG{n}{implicit}

\PYG{k+kn}{Print} \PYG{k+kn}{Implicit} \PYG{n}{p}\PYG{o}{.}
    \PYG{n}{p} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{X}\PYG{o}{,} \PYG{n}{R} \PYG{n}{x} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{z} \PYG{o}{:} \PYG{n}{X}\PYG{o}{,} \PYG{n}{R} \PYG{n}{y} \PYG{n}{z} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R} \PYG{n}{x} \PYG{n}{z}
    
    \PYG{k+kn}{Arguments} \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{n}{are} \PYG{n}{implicit}

\PYG{k+kn}{Variables} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{n}{c} \PYG{o}{:} \PYG{n}{X}\PYG{o}{)} \PYG{o}{(}\PYG{n}{r1} \PYG{o}{:} \PYG{n}{R} \PYG{n}{a} \PYG{n}{b}\PYG{o}{)} \PYG{o}{(}\PYG{n}{r2} \PYG{o}{:} \PYG{n}{R} \PYG{n}{b} \PYG{n}{c}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{a} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{b} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{c} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{r1} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{r2} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{p} \PYG{n}{r1} \PYG{n}{r2}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{p} \PYG{n}{r1} \PYG{n}{r2}
         \PYG{o}{:} \PYG{n}{R} \PYG{n}{a} \PYG{n}{c}
\end{sphinxVerbatim}


\subsubsection{Mode for automatic declaration of implicit arguments}
\label{\detokenize{language/gallina-extensions:mode-for-automatic-declaration-of-implicit-arguments}}\index{Implicit Arguments (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.implicit-arguments}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Implicit~Arguments}}}}
This option (off by default) allows to systematically declare implicit
the arguments detectable as such. Auto-detection of implicit arguments is
governed by options controlling whether strict and contextual implicit
arguments have to be considered or not.

\end{fulllineitems}



\subsubsection{Controlling strict implicit arguments}
\label{\detokenize{language/gallina-extensions:controlling-strict-implicit-arguments}}\label{\detokenize{language/gallina-extensions:controlling-strict-implicit-args}}\index{Strict Implicit (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.strict-implicit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Strict~Implicit}}}}
When the mode for automatic declaration of implicit arguments is on,
the default is to automatically set implicit only the strict implicit
arguments plus, for historical reasons, a small subset of the non-strict
implicit arguments. To relax this constraint and to set
implicit all non strict implicit arguments by default, you can turn this
option off.

\end{fulllineitems}

\index{Strongly Strict Implicit (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.strongly-strict-implicit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Strongly~Strict~Implicit}}}}
Use this option (off by default) to capture exactly the strict implicit
arguments and no more than the strict implicit arguments.

\end{fulllineitems}



\subsubsection{Controlling contextual implicit arguments}
\label{\detokenize{language/gallina-extensions:controlling-contextual-implicit-arguments}}\label{\detokenize{language/gallina-extensions:controlling-contextual-implicit-args}}\index{Contextual Implicit (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.contextual-implicit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Contextual~Implicit}}}}
By default, \DUrole{smallcaps}{Coq} does not automatically set implicit the contextual
implicit arguments. You can turn this option on to tell \DUrole{smallcaps}{Coq} to also
infer contextual implicit argument.

\end{fulllineitems}



\subsubsection{Controlling reversible-pattern implicit arguments}
\label{\detokenize{language/gallina-extensions:controlling-reversible-pattern-implicit-arguments}}\label{\detokenize{language/gallina-extensions:controlling-rev-pattern-implicit-args}}\index{Reversible Pattern Implicit (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.reversible-pattern-implicit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Reversible~Pattern~Implicit}}}}
By default, \DUrole{smallcaps}{Coq} does not automatically set implicit the reversible-pattern
implicit arguments. You can turn this option on to tell \DUrole{smallcaps}{Coq} to also infer
reversible-pattern implicit argument.

\end{fulllineitems}



\subsubsection{Controlling the insertion of implicit arguments not followed by explicit arguments}
\label{\detokenize{language/gallina-extensions:controlling-the-insertion-of-implicit-arguments-not-followed-by-explicit-arguments}}\label{\detokenize{language/gallina-extensions:controlling-insertion-implicit-args}}\index{Maximal Implicit Insertion (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.maximal-implicit-insertion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Maximal~Implicit~Insertion}}}}
Assuming the implicit argument mode is on, this option (off by default)
declares implicit arguments to be automatically inserted when a
function is partially applied and the next argument of the function is
an implicit one.

\end{fulllineitems}



\subsubsection{Explicit applications}
\label{\detokenize{language/gallina-extensions:explicit-applications}}\label{\detokenize{language/gallina-extensions:id8}}
In presence of non-strict or contextual argument, or in presence of
partial applications, the synthesis of implicit arguments may fail, so
one may have to give explicitly certain implicit arguments of an
application. The syntax for this is \sphinxcode{\sphinxupquote{(}} \sphinxtitleref{ident} \sphinxcode{\sphinxupquote{:=}} \sphinxtitleref{term} \sphinxcode{\sphinxupquote{)}} where \sphinxtitleref{ident} is the
name of the implicit argument and term is its corresponding explicit
term. Alternatively, one can locally deactivate the hiding of implicit
arguments of a function by using the notation \sphinxtitleref{@qualid} \sphinxtitleref{term}\(_{1}\) … \sphinxtitleref{term}\(_{n}\).
This syntax extension is given in the following grammar:

\phantomsection\label{\detokenize{language/gallina-extensions:explicit-app-grammar}}\begin{quote}


\begin{productionlist}
\phantomsection\label{\detokenize{language/gallina-extensions:grammar-token-term}}\production{term}{ @ qualid term … {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} @ qualid}
\productioncont{ \textbar{} qualid {\hyperref[\detokenize{language/gallina-extensions:grammar-token-argument}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{argument}}}}} … {\hyperref[\detokenize{language/gallina-extensions:grammar-token-argument}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{argument}}}}}}
\phantomsection\label{\detokenize{language/gallina-extensions:grammar-token-argument}}\production{argument}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} (ident := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}})}
\end{productionlist}


Syntax for explicitly giving implicit arguments
\end{quote}

\begin{sphinxadmonition}{note}{Example: (continued)}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{p} \PYG{n}{r1} \PYG{o}{(}\PYG{n}{z}\PYG{o}{:=}\PYG{n}{c}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{p} \PYG{n}{r1} \PYG{o}{(}\PYG{n}{z}\PYG{o}{:=}\PYG{n}{c}\PYG{o}{)}
         \PYG{o}{:} \PYG{n}{R} \PYG{n}{b} \PYG{n}{c} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R} \PYG{n}{a} \PYG{n}{c}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{p} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:=}\PYG{n}{a}\PYG{o}{)} \PYG{o}{(}\PYG{n}{y}\PYG{o}{:=}\PYG{n}{b}\PYG{o}{)} \PYG{n}{r1} \PYG{o}{(}\PYG{n}{z}\PYG{o}{:=}\PYG{n}{c}\PYG{o}{)} \PYG{n}{r2}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{p} \PYG{n}{r1} \PYG{n}{r2}
         \PYG{o}{:} \PYG{n}{R} \PYG{n}{a} \PYG{n}{c}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Renaming implicit arguments}
\label{\detokenize{language/gallina-extensions:renaming-implicit-arguments}}
Implicit arguments names can be redefined using the following syntax:
\index{Arguments (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Arguments~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}\DUrole{notation-sup}{*}}~:~\DUrole{hole}{rename}}}}}
\end{fulllineitems}


With the assert flag, \sphinxcode{\sphinxupquote{Arguments}} can be used to assert that a given
object has the expected number of arguments and that these arguments
are named as expected.

\begin{sphinxadmonition}{note}{Example: (continued)}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Arguments} \PYG{n}{p} \PYG{o}{[}\PYG{n}{s} \PYG{n}{t}\PYG{o}{]} \PYG{o}{\PYGZus{}} \PYG{o}{[}\PYG{n}{u}\PYG{o}{]} \PYG{o}{\PYGZus{}}\PYG{o}{:} \PYG{k}{rename}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{p} \PYG{n}{r1} \PYG{o}{(}\PYG{n}{u}\PYG{o}{:=}\PYG{n}{c}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{p} \PYG{n}{r1} \PYG{o}{(}\PYG{n}{u}\PYG{o}{:=}\PYG{n}{c}\PYG{o}{)}
         \PYG{o}{:} \PYG{n}{R} \PYG{n}{b} \PYG{n}{c} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R} \PYG{n}{a} \PYG{n}{c}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{p} \PYG{o}{(}\PYG{n}{s}\PYG{o}{:=}\PYG{n}{a}\PYG{o}{)} \PYG{o}{(}\PYG{n}{t}\PYG{o}{:=}\PYG{n}{b}\PYG{o}{)} \PYG{n}{r1} \PYG{o}{(}\PYG{n}{u}\PYG{o}{:=}\PYG{n}{c}\PYG{o}{)} \PYG{n}{r2}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{p} \PYG{n}{r1} \PYG{n}{r2}
         \PYG{o}{:} \PYG{n}{R} \PYG{n}{a} \PYG{n}{c}

\PYG{n}{Fail} \PYG{k+kn}{Arguments} \PYG{n}{p} \PYG{o}{[}\PYG{n}{s} \PYG{n}{t}\PYG{o}{]} \PYG{o}{\PYGZus{}} \PYG{o}{[}\PYG{n}{w}\PYG{o}{]} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{k}{assert}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{To} \PYG{k}{rename} \PYG{n}{arguments} \PYG{n}{the} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{rename}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{flag} \PYG{n}{must} \PYG{n}{be} \PYG{n}{specified}\PYG{o}{.}
    \PYG{n}{Argument} \PYG{n}{u} \PYG{n}{renamed} \PYG{n}{to} \PYG{n}{w}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Displaying what the implicit arguments are}
\label{\detokenize{language/gallina-extensions:displaying-what-the-implicit-arguments-are}}\label{\detokenize{language/gallina-extensions:displaying-implicit-args}}
To display the implicit arguments associated to an object, and to know
if each of them is to be used maximally or not, use the command
\index{Print Implicit (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.print-implicit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Implicit~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\end{fulllineitems}



\subsubsection{Explicit displaying of implicit arguments for pretty-printing}
\label{\detokenize{language/gallina-extensions:explicit-displaying-of-implicit-arguments-for-pretty-printing}}\index{Printing Implicit (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.printing-implicit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Implicit}}}}
By default, the basic pretty-printing rules hide the inferable implicit
arguments of an application. Turn this option on to force printing all
implicit arguments.

\end{fulllineitems}

\index{Printing Implicit Defensive (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.printing-implicit-defensive}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Implicit~Defensive}}}}
By default, the basic pretty-printing rules display the implicit
arguments that are not detected as strict implicit arguments. This
“defensive” mode can quickly make the display cumbersome so this can
be deactivated by turning this option off.

\end{fulllineitems}



\sphinxstrong{See also:}


{\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-all}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}}.




\subsubsection{Interaction with subtyping}
\label{\detokenize{language/gallina-extensions:interaction-with-subtyping}}
When an implicit argument can be inferred from the type of more than
one of the other arguments, then only the type of the first of these
arguments is taken into account, and not an upper type of all of them.
As a consequence, the inference of the implicit argument of “=” fails
in

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{k+kt}{nat} \PYG{o}{=} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Prop}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Type}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{while} \PYG{n}{it} \PYG{k}{is} \PYG{n}{expected} \PYG{n}{to} \PYG{k}{have} \PYG{n}{type} 
    \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Set}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{(}\PYG{n}{universe} \PYG{n}{inconsistency}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

but succeeds in

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{k+kt}{Prop} \PYG{o}{=} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{k+kt}{Prop} \PYG{o}{=} \PYG{k+kt}{nat}
         \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}


\subsubsection{Deactivation of implicit arguments for parsing}
\label{\detokenize{language/gallina-extensions:deactivation-of-implicit-arguments-for-parsing}}\index{Parsing Explicit (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.parsing-explicit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Parsing~Explicit}}}}
Turning this option on (it is off by default) deactivates the use of implicit arguments.

In this case, all arguments of constants, inductive types,
constructors, etc, including the arguments declared as implicit, have
to be given as if no arguments were implicit. By symmetry, this also
affects printing.

\end{fulllineitems}



\subsubsection{Canonical structures}
\label{\detokenize{language/gallina-extensions:canonical-structures}}
A canonical structure is an instance of a record/structure type that
can be used to solve unification problems involving a projection
applied to an unknown structure instance (an implicit argument) and a
value. The complete documentation of canonical structures can be found
in {\hyperref[\detokenize{addendum/canonical-structures:canonicalstructures}]{\sphinxcrossref{\DUrole{std,std-ref}{Canonical Structures}}}}; here only a simple example is given.
\index{Canonical Structure (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.canonical-structure}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Canonical~Structure~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This command declares {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} as a canonical structure.

Assume that {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} denotes an object \sphinxcode{\sphinxupquote{(Build\_struct}} \sphinxtitleref{c}\(_{1}\) … \sphinxtitleref{c}\(_{n}\) \sphinxcode{\sphinxupquote{)}} in the
structure \sphinxcode{\sphinxupquote{\DUrole{keyword}{struct}}} of which the fields are \sphinxtitleref{x}\(_{1}\), …, \sphinxtitleref{x}\(_{n}\).
Then, each time an equation of the form \sphinxcode{\sphinxupquote{(}}\sphinxtitleref{x}\(_{i}\) \sphinxcode{\sphinxupquote{\_)}} \sphinxtitleref{=}\(_{\beta\delta\iota\zeta}\) \sphinxtitleref{c}\(_{i}\) has to be
solved during the type checking process, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} is used as a solution.
Otherwise said, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} is canonically used to extend the field \sphinxtitleref{c}\(_{i}\)
into a complete structure built on \sphinxtitleref{c}\(_{i}\).

Canonical structures are particularly useful when mixed with coercions
and strict implicit arguments.

\begin{sphinxadmonition}{note}{Example}

Here is an example.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Relations}\PYG{o}{.}
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{EqNat}\PYG{o}{.}
\PYG{k+kn}{Set} \PYG{k+kn}{Implicit} \PYG{k+kn}{Arguments}\PYG{o}{.}
\PYG{k+kn}{Unset} \PYG{k+kn}{Strict} \PYG{k+kn}{Implicit}\PYG{o}{.}
\PYG{k+kn}{Structure} \PYG{n}{Setoid} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=} \PYG{o}{\PYGZob{}}\PYG{n}{Carrier} \PYG{o}{:\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{;} \PYG{n}{Equal} \PYG{o}{:} \PYG{n}{relation} \PYG{n}{Carrier}\PYG{o}{;}
                            \PYG{n}{Prf\PYGZus{}equiv} \PYG{o}{:} \PYG{n}{equivalence} \PYG{n}{Carrier} \PYG{n}{Equal}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{Setoid} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Carrier} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Equal} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Prf\PYGZus{}equiv} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{is\PYGZus{}law} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{n}{Setoid}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{Equal} \PYG{n}{x} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Equal} \PYG{o}{(}\PYG{n}{f} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{is\PYGZus{}law} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Axiom} \PYG{n}{eq\PYGZus{}nat\PYGZus{}equiv} \PYG{o}{:} \PYG{n}{equivalence} \PYG{k+kt}{nat} \PYG{n}{eq\PYGZus{}nat}\PYG{o}{.}
    \PYG{n}{eq\PYGZus{}nat\PYGZus{}equiv} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Definition} \PYG{n}{nat\PYGZus{}setoid} \PYG{o}{:} \PYG{n}{Setoid} \PYG{o}{:=} \PYG{n}{Build\PYGZus{}Setoid} \PYG{n}{eq\PYGZus{}nat\PYGZus{}equiv}\PYG{o}{.}
    \PYG{n}{nat\PYGZus{}setoid} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Canonical} \PYG{k+kn}{Structure} \PYG{n}{nat\PYGZus{}setoid}\PYG{o}{.}
\end{sphinxVerbatim}

Thanks to \sphinxcode{\sphinxupquote{\DUrole{name}{nat\_setoid}}} declared as canonical, the implicit arguments \sphinxcode{\sphinxupquote{\DUrole{name}{A}}}
and \sphinxcode{\sphinxupquote{\DUrole{name}{B}}} can be synthesized in the next statement.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{is\PYGZus{}law\PYGZus{}S} \PYG{o}{:} \PYG{n}{is\PYGZus{}law} \PYG{n}{S}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{is\PYGZus{}law} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:=}\PYG{n}{nat\PYGZus{}setoid}\PYG{o}{)} \PYG{o}{(}\PYG{n}{B}\PYG{o}{:=}\PYG{n}{nat\PYGZus{}setoid}\PYG{o}{)} \PYG{n}{S}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
If a same field occurs in several canonical structures, then
only the structure declared first as canonical is considered.
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Canonical~Structure~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This is equivalent to a regular definition of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} followed by the
declaration \sphinxcode{\sphinxupquote{\DUrole{notation}{Canonical Structure {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}


\end{fulllineitems}

\index{Print Canonical Projections (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.print-canonical-projections}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Canonical~Projections}}}}
This displays the list of global names that are components of some
canonical structure. For each of them, the canonical structure of
which it is a projection is indicated.

\begin{sphinxadmonition}{note}{Example}

For instance, the above example gives the following output:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{k+kn}{Canonical} \PYG{k+kn}{Projections}\PYG{o}{.}
    \PYG{k+kt}{nat} \PYG{o}{\PYGZlt{}\PYGZhy{}} \PYG{n}{Carrier} \PYG{o}{(} \PYG{n}{nat\PYGZus{}setoid} \PYG{o}{)}
    \PYG{n}{eq\PYGZus{}nat} \PYG{o}{\PYGZlt{}\PYGZhy{}} \PYG{n}{Equal} \PYG{o}{(} \PYG{n}{nat\PYGZus{}setoid} \PYG{o}{)}
    \PYG{n}{eq\PYGZus{}nat\PYGZus{}equiv} \PYG{o}{\PYGZlt{}\PYGZhy{}} \PYG{n}{Prf\PYGZus{}equiv} \PYG{o}{(} \PYG{n}{nat\PYGZus{}setoid} \PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}



\subsubsection{Implicit types of variables}
\label{\detokenize{language/gallina-extensions:implicit-types-of-variables}}
It is possible to bind variable names to a given type (e.g. in a
development using arithmetic, it may be convenient to bind the names \sphinxtitleref{n}
or \sphinxtitleref{m} to the type \sphinxcode{\sphinxupquote{nat}} of natural numbers). The command for that is
\index{Implicit Types (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.implicit-types}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Implicit~Types~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
\end{fulllineitems}


The effect of the command is to automatically set the type of bound
variables starting with \sphinxtitleref{ident} (either \sphinxtitleref{ident} itself or \sphinxtitleref{ident} followed by
one or more single quotes, underscore or digits) to be \sphinxtitleref{type} (unless
the bound variable is already declared with an explicit type in which
case, this latter type is considered).

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{List}\PYG{o}{.}
\PYG{k+kn}{Implicit} \PYG{n}{Types} \PYG{n}{m} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{cons\PYGZus{}inj\PYGZus{}nat} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m} \PYG{n}{n} \PYG{n}{l}\PYG{o}{,} \PYG{n}{n} \PYG{o}{::} \PYG{n}{l} \PYG{o}{=} \PYG{n}{m} \PYG{o}{::} \PYG{n}{l} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{o}{(}\PYG{n}{m} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{k+kt}{nat}\PYG{o}{)}\PYG{o}{,} \PYG{n}{n} \PYG{o}{::} \PYG{n}{l} \PYG{o}{=} \PYG{n}{m} \PYG{o}{::} \PYG{n}{l} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=} \PYG{n}{m}

\PYG{k}{intros} \PYG{n}{m} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{m}\PYG{o}{,} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{::} \PYG{n}{l} \PYG{o}{=} \PYG{n}{m} \PYG{o}{::} \PYG{n}{l} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=} \PYG{n}{m}

\PYG{k+kn}{Lemma} \PYG{n}{cons\PYGZus{}inj\PYGZus{}bool} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{m} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{bool}\PYG{o}{)} \PYG{n}{l}\PYG{o}{,} \PYG{n}{n} \PYG{o}{::} \PYG{n}{l} \PYG{o}{=} \PYG{n}{m} \PYG{o}{::} \PYG{n}{l} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{o}{(}\PYG{n}{m} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{k+kt}{bool}\PYG{o}{)}\PYG{o}{,} \PYG{n}{n} \PYG{o}{::} \PYG{n}{l} \PYG{o}{=} \PYG{n}{m} \PYG{o}{::} \PYG{n}{l} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=} \PYG{n}{m}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Implicit~Type~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
This is useful for declaring the implicit type of a single variable.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Implicit~Types~\DUrole{repeat-wrapper}{\DUrole{repeat}{(~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~)}\DUrole{notation-sup}{+}}}}}}
Adds blocks of implicit types with different specifications.

\end{fulllineitems}



\subsubsection{Implicit generalization}
\label{\detokenize{language/gallina-extensions:implicit-generalization}}\label{\detokenize{language/gallina-extensions:id9}}
\index{{}`\sphinxleftcurlybrace{} \sphinxrightcurlybrace{}}\ignorespaces 
\index{{}`( )}\ignorespaces 
Implicit generalization is an automatic elaboration of a statement
with free variables into a closed statement where these variables are
quantified explicitly. Implicit generalization is done inside binders
starting with a {}` and terms delimited by {}`\{ \} and {}`( ), always
introducing maximally inserted implicit arguments for the generalized
variables. Inside implicit generalization delimiters, free variables
in the current context are automatically quantified using a product or
a lambda abstraction to generate a closed term. In the following
statement for example, the variables n and m are automatically
generalized and become explicit arguments of the lemma as we are using
{}`( ):

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Generalizable} \PYG{k+kn}{All} \PYG{k+kn}{Variables}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{nat\PYGZus{}comm} \PYG{o}{:} \PYG{o}{{}`}\PYG{o}{(}\PYG{n}{n} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}

One can control the set of generalizable identifiers with
the \sphinxcode{\sphinxupquote{Generalizable}} vernacular command to avoid unexpected
generalizations when mistyping identifiers. There are several commands
that specify which variables should be generalizable.
\index{Generalizable All Variables (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.generalizable-all-variables}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Generalizable~All~Variables}}}}
All variables are candidate for
generalization if they appear free in the context under a
generalization delimiter. This may result in confusing errors in case
of typos. In such cases, the context will probably contain some
unexpected generalized variable.

\end{fulllineitems}

\index{Generalizable No Variables (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.generalizable-no-variables}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Generalizable~No~Variables}}}}
Disable implicit generalization  entirely. This is the default behavior.

\end{fulllineitems}

\index{Generalizable (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.generalizable}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Generalizable~(Variable~\textbar{}~Variables)~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
Allow generalization of the given identifiers only. Calling this command multiple times
adds to the allowed identifiers.

\end{fulllineitems}

\index{Global Generalizable (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.global-generalizable}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Global~Generalizable}}}}
Allows exporting the choice of generalizable variables.

\end{fulllineitems}


One can also use implicit generalization for binders, in which case
the generalized variables are added as binders and set maximally
implicit.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{id} \PYG{o}{{}`}\PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{n}{A} \PYG{o}{:=} \PYG{n}{x}\PYG{o}{.}
    \PYG{n}{id} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Print} \PYG{n}{id}\PYG{o}{.}
    \PYG{n}{id} \PYG{o}{=} \PYG{k}{fun} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}
    
    \PYG{n}{Argument} \PYG{n}{A} \PYG{k}{is} \PYG{n}{implicit} \PYG{n}{and} \PYG{n}{maximally} \PYG{n}{inserted}
    \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}}\PYG{o}{]}
\end{sphinxVerbatim}

The generalizing binders {}`\{ \} and {}`( ) work similarly to their
explicit counterparts, only binding the generalized variables
implicitly, as maximally-inserted arguments. In these binders, the
binding name for the bound object is optional, whereas the type is
mandatory, dually to regular binders.


\subsection{Coercions}
\label{\detokenize{language/gallina-extensions:coercions}}\label{\detokenize{language/gallina-extensions:id10}}
Coercions can be used to implicitly inject terms from one \sphinxstyleemphasis{class} in
which they reside into another one. A \sphinxstyleemphasis{class} is either a sort
(denoted by the keyword \sphinxcode{\sphinxupquote{Sortclass}}), a product type (denoted by the
keyword \sphinxcode{\sphinxupquote{Funclass}}), or a type constructor (denoted by its name), e.g.
an inductive type or any constant with a type of the form
\sphinxcode{\sphinxupquote{forall (}} \sphinxtitleref{x}\(_{1}\) : \sphinxtitleref{A}\(_{1}\) ) … \sphinxcode{\sphinxupquote{(}}\sphinxtitleref{x}\(_{n}\) : \sphinxtitleref{A}\(_{n}\)\sphinxcode{\sphinxupquote{)}}, \sphinxtitleref{s} where \sphinxtitleref{s} is a sort.

Then the user is able to apply an object that is not a function, but
can be coerced to a function, and more generally to consider that a
term of type \sphinxcode{\sphinxupquote{A}} is of type \sphinxcode{\sphinxupquote{B}} provided that there is a declared coercion
between \sphinxcode{\sphinxupquote{A}} and \sphinxcode{\sphinxupquote{B}}.

More details and examples, and a description of the commands related
to coercions are provided in {\hyperref[\detokenize{addendum/implicit-coercions:implicitcoercions}]{\sphinxcrossref{\DUrole{std,std-ref}{Implicit Coercions}}}}.


\subsection{Printing constructions in full}
\label{\detokenize{language/gallina-extensions:printing-constructions-in-full}}\label{\detokenize{language/gallina-extensions:printing-constructions-full}}\index{Printing All (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.printing-all}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~All}}}}
Coercions, implicit arguments, the type of pattern matching, but also
notations (see {\hyperref[\detokenize{user-extensions/syntax-extensions:syntaxextensionsandinterpretationscopes}]{\sphinxcrossref{\DUrole{std,std-ref}{Syntax extensions and interpretation scopes}}}}) can obfuscate the behavior of some
tactics (typically the tactics applying to occurrences of subterms are
sensitive to the implicit arguments). Turning this option 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, {\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-all}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}} includes the effects of the options
{\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-implicit}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Implicit}}}}}, {\hyperref[\detokenize{addendum/implicit-coercions:coq:flag.printing-coercions}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Coercions}}}}}, {\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-synth}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Synth}}}}},
{\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-projections}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Projections}}}}}, and {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:flag.printing-notations}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Notations}}}}}. To reactivate
the high-level printing features, use the command \sphinxcode{\sphinxupquote{Unset Printing All}}.

\end{fulllineitems}



\subsection{Printing universes}
\label{\detokenize{language/gallina-extensions:printing-universes}}\label{\detokenize{language/gallina-extensions:id11}}\index{Printing Universes (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.printing-universes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Universes}}}}
Turn this option on to activate the display of the actual level of each
occurrence of \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}}. See {\hyperref[\detokenize{language/cic:sorts}]{\sphinxcrossref{\DUrole{std,std-ref}{Sorts}}}} for details. This wizard option, in
combination with {\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-all}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}} can help to diagnose failures to unify
terms apparently identical but internally different in the Calculus of Inductive
Constructions.

\end{fulllineitems}


The constraints on the internal level of the occurrences of Type
(see {\hyperref[\detokenize{language/cic:sorts}]{\sphinxcrossref{\DUrole{std,std-ref}{Sorts}}}}) can be printed using the command
\index{Print Universes (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:cmd.print-universes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~\DUrole{repeat-wrapper}{\DUrole{repeat}{Sorted}\DUrole{notation-sup}{?}}~Universes}}}}
\end{fulllineitems}


If the optional \sphinxcode{\sphinxupquote{Sorted}} option is given, each universe will be made
equivalent to a numbered label reflecting its level (with a linear
ordering) in the universe hierarchy.

This command also accepts an optional output filename:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~\DUrole{repeat-wrapper}{\DUrole{repeat}{Sorted}\DUrole{notation-sup}{?}}~Universes~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
\end{fulllineitems}


If \sphinxtitleref{string} ends in \sphinxcode{\sphinxupquote{.dot}} or \sphinxcode{\sphinxupquote{.gv}}, the constraints are printed in the DOT
language, and can be processed by Graphviz tools. The format is
unspecified if \sphinxtitleref{string} doesn’t end in \sphinxcode{\sphinxupquote{.dot}} or \sphinxcode{\sphinxupquote{.gv}}.


\subsection{Existential variables}
\label{\detokenize{language/gallina-extensions:existential-variables}}\label{\detokenize{language/gallina-extensions:id12}}
\DUrole{smallcaps}{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 \sphinxcode{\sphinxupquote{Check}} (see
Section {\hyperref[\detokenize{proof-engine/vernacular-commands:requests-to-the-environment}]{\sphinxcrossref{\DUrole{std,std-ref}{Requests to the environment}}}}) or when using tactics such as
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}}, as well as in place of unsolvable instances when using
tactics such that {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{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.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{identity} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{X}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)}\PYG{o}{,} \PYG{n}{X} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{X}\PYG{o}{.}
    \PYG{n}{identity} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Check} \PYG{n}{identity} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{.}
    \PYG{n}{identity} \PYG{o}{?}\PYG{n}{y} \PYG{o}{?}\PYG{n}{x}
         \PYG{o}{:} \PYG{o}{?}\PYG{n}{X}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{x}\PYG{o}{:=}\PYG{o}{?}\PYG{n}{x}\PYG{o}{\PYGZcb{}}
    \PYG{n}{where}
    \PYG{o}{?}\PYG{n}{y} \PYG{o}{:} \PYG{o}{[} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{o}{?}\PYG{n}{P}\PYG{o}{,} \PYG{o}{?}\PYG{n}{X}\PYG{o}{]}
    \PYG{o}{?}\PYG{n}{P} \PYG{o}{:} \PYG{o}{[} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{k+kn}{Set}\PYG{o}{]}
    \PYG{o}{?}\PYG{n}{X} \PYG{o}{:} \PYG{o}{[}\PYG{n}{x} \PYG{o}{:} \PYG{o}{?}\PYG{n}{P} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{k+kn}{Set}\PYG{o}{]}
    \PYG{o}{?}\PYG{n}{x} \PYG{o}{:} \PYG{o}{[} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{P}\PYG{o}{]}

\PYG{k+kn}{Check} \PYG{n}{identity} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{identity} \PYG{o}{?}\PYG{n}{y} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{o}{?}\PYG{n}{P} \PYG{o}{=\PYGZgt{}} \PYG{o}{?}\PYG{n}{y0}\PYG{o}{)}
         \PYG{o}{:} \PYG{o}{?}\PYG{n}{X}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{x}\PYG{o}{:=}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{o}{?}\PYG{n}{P} \PYG{o}{=\PYGZgt{}} \PYG{o}{?}\PYG{n}{y0}\PYG{o}{\PYGZcb{}}
    \PYG{n}{where}
    \PYG{o}{?}\PYG{n}{y} \PYG{o}{:} \PYG{o}{[} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{o}{?}\PYG{n}{P}\PYG{o}{,} \PYG{o}{?}\PYG{n}{P0}\PYG{o}{,} \PYG{o}{?}\PYG{n}{X}\PYG{o}{]}
    \PYG{o}{?}\PYG{n}{X} \PYG{o}{:} \PYG{o}{[}\PYG{n}{x} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{o}{?}\PYG{n}{P}\PYG{o}{,} \PYG{o}{?}\PYG{n}{P0} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{k+kn}{Set}\PYG{o}{]}
    \PYG{o}{?}\PYG{n}{P} \PYG{o}{:} \PYG{o}{[} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{k+kn}{Set}\PYG{o}{]}
    \PYG{o}{?}\PYG{n}{P0} \PYG{o}{:} \PYG{o}{[}\PYG{n}{x} \PYG{o}{:} \PYG{o}{?}\PYG{n}{P} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{k+kn}{Set}\PYG{o}{]}
    \PYG{o}{?}\PYG{n}{y0} \PYG{o}{:} \PYG{o}{[}\PYG{n}{x} \PYG{o}{:} \PYG{o}{?}\PYG{n}{P} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{P0}\PYG{o}{]}
\end{sphinxVerbatim}

In the general case, when an existential variable \sphinxcode{\sphinxupquote{?}}\sphinxtitleref{ident} appears
outside of its context of definition, its instance, written under the
form

\begin{DUlineblock}{0em}
\item[] \sphinxcode{\sphinxupquote{\{}} \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}:={\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{;}}}}} \sphinxcode{\sphinxupquote{\}}}
\end{DUlineblock}

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 {\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-existential-instances}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Existential Instances}}}}}
is on (see Section {\hyperref[\detokenize{language/gallina-extensions:explicit-display-existentials}]{\sphinxcrossref{\DUrole{std,std-ref}{Explicit displaying of existential instances for pretty-printing}}}}), and this is why an
existential variable used in the same context as its context of definition is written with no instance.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{o}{\PYGZus{}}\PYG{o}{)} \PYG{l+m+mi}{0} \PYG{l+m+mi}{1}\PYG{o}{.}
    \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{o}{?}\PYG{n}{y}\PYG{o}{)} \PYG{l+m+mi}{0} \PYG{l+m+mi}{1}
         \PYG{o}{:} \PYG{o}{?}\PYG{n}{T}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{x}\PYG{o}{:=}\PYG{l+m+mi}{0}\PYG{o}{;} \PYG{n}{y}\PYG{o}{:=}\PYG{l+m+mi}{1}\PYG{o}{\PYGZcb{}}
    \PYG{n}{where}
    \PYG{o}{?}\PYG{n}{T} \PYG{o}{:} \PYG{o}{[}\PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}  \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{k+kt}{Type}\PYG{o}{]}
    \PYG{o}{?}\PYG{n}{y} \PYG{o}{:} \PYG{o}{[}\PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}  \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{T}\PYG{o}{]}

\PYG{k+kn}{Set} \PYG{k+kn}{Printing} \PYG{n}{Existential} \PYG{n}{Instances}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{o}{\PYGZus{}}\PYG{o}{)} \PYG{l+m+mi}{0} \PYG{l+m+mi}{1}\PYG{o}{.}
    \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{o}{?}\PYG{n}{y}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{x}\PYG{o}{:=}\PYG{n}{x}\PYG{o}{;} \PYG{n}{y}\PYG{o}{:=}\PYG{n}{y}\PYG{o}{\PYGZcb{}}\PYG{o}{)} \PYG{l+m+mi}{0} \PYG{l+m+mi}{1}
         \PYG{o}{:} \PYG{o}{?}\PYG{n}{T}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{x}\PYG{o}{:=}\PYG{l+m+mi}{0}\PYG{o}{;} \PYG{n}{y}\PYG{o}{:=}\PYG{l+m+mi}{1}\PYG{o}{\PYGZcb{}}
    \PYG{n}{where}
    \PYG{o}{?}\PYG{n}{T} \PYG{o}{:} \PYG{o}{[}\PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}  \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{k+kt}{Type}\PYG{o}{]}
    \PYG{o}{?}\PYG{n}{y} \PYG{o}{:} \PYG{o}{[}\PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}  \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{T}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{x}\PYG{o}{:=}\PYG{n}{x}\PYG{o}{;} \PYG{n}{y}\PYG{o}{:=}\PYG{n}{y}\PYG{o}{\PYGZcb{}}\PYG{o}{]}
\end{sphinxVerbatim}

Existential variables can be named by the user upon creation using
the syntax \sphinxcode{\sphinxupquote{\DUrole{notation}{?{[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{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 {\hyperref[\detokenize{proof-engine/ltac:goal-selectors}]{\sphinxcrossref{\DUrole{std,std-ref}{Goal selectors}}}}).


\subsubsection{Explicit displaying of existential instances for pretty-printing}
\label{\detokenize{language/gallina-extensions:explicit-displaying-of-existential-instances-for-pretty-printing}}\label{\detokenize{language/gallina-extensions:explicit-display-existentials}}\index{Printing Existential Instances (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/gallina-extensions:coq:flag.printing-existential-instances}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Existential~Instances}}}}
This option (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.

\end{fulllineitems}



\subsubsection{Solving existential variables using tactics}
\label{\detokenize{language/gallina-extensions: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 \sphinxcode{\sphinxupquote{ltac:(}}\sphinxtitleref{tacexpr}\sphinxcode{\sphinxupquote{)}}, 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 \sphinxtitleref{tacexpr} can be any tactic
expression as described in {\hyperref[\detokenize{proof-engine/ltac:ltac}]{\sphinxcrossref{\DUrole{std,std-ref}{The tactic language}}}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{foo} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=} \PYG{n}{ltac}\PYG{o}{:}\PYG{o}{(}\PYG{k+kp}{exact} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{identity} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{foo} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

This construction is useful when one wants to define complicated terms
using highly automated tactics without resorting to writing the proof-term
by means of the interactive proof engine.

This mechanism is comparable to the \sphinxcode{\sphinxupquote{Declare Implicit Tactic}} command
defined at {\hyperref[\detokenize{proof-engine/tactics:tactics-implicit-automation}]{\sphinxcrossref{\DUrole{std,std-ref}{Setting implicit automation tactics}}}}, except that the used
tactic is local to each hole instead of being declared globally.


\section{The Coq library}
\label{\detokenize{language/coq-library:the-coq-library}}\label{\detokenize{language/coq-library:thecoqlibrary}}\label{\detokenize{language/coq-library::doc}}
\index{Theories}\ignorespaces 
The \DUrole{smallcaps}{Coq} library is structured into two parts:
\begin{itemize}
\item {} 
\sphinxstylestrong{The initial library}: it contains elementary logical notions and
data-types. It constitutes the basic state of the system directly
available when running \DUrole{smallcaps}{Coq};

\item {} 
\sphinxstylestrong{The standard library}: general-purpose libraries containing various
developments of \DUrole{smallcaps}{Coq} axiomatizations about sets, lists, sorting,
arithmetic, etc. This library comes with the system and its modules
are directly accessible through the \sphinxcode{\sphinxupquote{Require}} command (see
Section {\hyperref[\detokenize{proof-engine/vernacular-commands:compiled-files}]{\sphinxcrossref{\DUrole{std,std-ref}{Compiled files}}}});

\end{itemize}

In addition, user-provided libraries or developments are provided by
\DUrole{smallcaps}{Coq} users' community. These libraries and developments are available
for download at \sphinxurl{http://coq.inria.fr} (see
Section {\hyperref[\detokenize{language/coq-library:userscontributions}]{\sphinxcrossref{\DUrole{std,std-ref}{Users’ contributions}}}}).

This chapter briefly reviews the \DUrole{smallcaps}{Coq} libraries whose contents can
also be browsed at \sphinxurl{http://coq.inria.fr/stdlib}.


\subsection{The basic library}
\label{\detokenize{language/coq-library:the-basic-library}}
This section lists the basic notions and results which are directly
available in the standard \DUrole{smallcaps}{Coq} system. Most of these constructions
are defined in the \sphinxcode{\sphinxupquote{Prelude}} module in directory \sphinxcode{\sphinxupquote{theories/Init}}
at the \DUrole{smallcaps}{Coq} root directory; this includes the modules
\sphinxcode{\sphinxupquote{Notations}},
\sphinxcode{\sphinxupquote{Logic}},
\sphinxcode{\sphinxupquote{Datatypes}},
\sphinxcode{\sphinxupquote{Specif}},
\sphinxcode{\sphinxupquote{Peano}},
\sphinxcode{\sphinxupquote{Wf}} and
\sphinxcode{\sphinxupquote{Tactics}}.
Module \sphinxcode{\sphinxupquote{Logic\_Type}} also makes it in the initial state.


\subsubsection{Notations}
\label{\detokenize{language/coq-library:notations}}\label{\detokenize{language/coq-library:init-notations}}
This module defines the parsing and pretty-printing of many symbols
(infixes, prefixes, etc.). However, it does not assign a meaning to
these notations. The purpose of this is to define and fix once for all
the precedence and associativity of very common notations. The main
notations fixed in the initial state are :


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
\hline
\sphinxstyletheadfamily 
Notation
&\sphinxstyletheadfamily 
Precedence
&\sphinxstyletheadfamily 
Associativity
\\
\hline
\sphinxcode{\sphinxupquote{\_ -\textgreater{} \_}}
&
99
&
right
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textless{}-\textgreater{} \_}}
&
95
&
no
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textbackslash{}/ \_}}
&
85
&
right
\\
\hline
\sphinxcode{\sphinxupquote{\_ /\textbackslash{} \_}}
&
80
&
right
\\
\hline
\sphinxcode{\sphinxupquote{\textasciitilde{} \_}}
&
75
&
right
\\
\hline
\sphinxcode{\sphinxupquote{\_ = \_}}
&
70
&
no
\\
\hline
\sphinxcode{\sphinxupquote{\_ = \_ = \_}}
&
70
&
no
\\
\hline
\sphinxcode{\sphinxupquote{\_ = \_ :\textgreater{} \_}}
&
70
&
no
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textless{}\textgreater{} \_}}
&
70
&
no
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textless{}\textgreater{} \_ :\textgreater{} \_}}
&
70
&
no
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textless{} \_}}
&
70
&
no
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textgreater{} \_}}
&
70
&
no
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textless{}= \_}}
&
70
&
no
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textgreater{}= \_}}
&
70
&
no
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textless{} \_ \textless{} \_}}
&
70
&
no
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textless{} \_ \textless{}= \_}}
&
70
&
no
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textless{}= \_ \textless{} \_}}
&
70
&
no
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textless{}= \_ \textless{}= \_}}
&
70
&
no
\\
\hline
\sphinxcode{\sphinxupquote{\_ + \_}}
&
50
&
left
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textbar{}\textbar{} \_}}
&
50
&
left
\\
\hline
\sphinxcode{\sphinxupquote{\_ - \_}}
&
50
&
left
\\
\hline
\sphinxcode{\sphinxupquote{\_ * \_}}
&
40
&
left
\\
\hline
\sphinxcode{\sphinxupquote{\_      \_}}
&
40
&
left
\\
\hline
\sphinxcode{\sphinxupquote{\_ / \_}}
&
40
&
left
\\
\hline
\sphinxcode{\sphinxupquote{- \_}}
&
35
&
right
\\
\hline
\sphinxcode{\sphinxupquote{/ \_}}
&
35
&
right
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textasciicircum{} \_}}
&
30
&
right
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}


\subsubsection{Logic}
\label{\detokenize{language/coq-library:logic}}\label{\detokenize{language/coq-library:coq-library-logic}}
The basic library of \DUrole{smallcaps}{Coq} comes with the definitions of standard
(intuitionistic) logical connectives (they are defined as inductive
constructions). They are equipped with an appealing syntax enriching the
subclass \sphinxtitleref{form} of the syntactic class \sphinxtitleref{term}. The syntax of \sphinxtitleref{form}
is shown below:


\begin{productionlist}
\phantomsection\label{\detokenize{language/coq-library:grammar-token-form}}\production{form}{   True                                           (True)}
\productioncont{ \textbar{} False                                          (False)}
\productioncont{ \textbar{} \textasciitilde{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}}                                         (not)}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}} /\textbackslash{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}}                                   (and)}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}} \textbackslash{}/ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}}                                   (or)}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}} -\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}}                                   (primitive implication)}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}} \textless{}-\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}}                                  (iff)}
\productioncont{ \textbar{} forall {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{type}}}}}, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}}                      (primitive for all)}
\productioncont{ \textbar{} exists {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[}: {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}}{]}, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}}                  (ex)}
\productioncont{ \textbar{} exists2 {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[}: {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}}{]}, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}} \& {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}}          (ex2)}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}                                    (eq)}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} :\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}}                          (eq)}
\end{productionlist}


\begin{sphinxadmonition}{note}{Note:}
Implication is not defined but primitive (it is a non-dependent
product of a proposition over another proposition). There is also a
primitive universal quantification (it is a dependent product over a
proposition). The primitive universal quantification allows both
first-order and higher-order quantification.
\end{sphinxadmonition}


\paragraph{Propositional Connectives}
\label{\detokenize{language/coq-library:propositional-connectives}}
\index{Connectives}\index{True (term)}\index{I (term)}\index{False (term)}\index{not (term)}\index{and (term)}\index{conj (term)}\index{proj1 (term)}\index{proj2 (term)}\index{or (term)}\index{or\_introl (term)}\index{or\_intror (term)}\index{iff (term)}\index{IF\_then\_else (term)}\ignorespaces 
First, we find propositional calculus connectives:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{True} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{I}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{False} \PYG{o}{:}  \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{not} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{and} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{conj} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Section} \PYG{k+kn}{Projections}\PYG{o}{.}
\PYG{k+kn}{Variables} \PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{proj1} \PYG{o}{:} \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{proj2} \PYG{o}{:} \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{k+kn}{Projections}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{or} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{or\PYGZus{}introl} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)}
\PYG{o}{\textbar{}} \PYG{n}{or\PYGZus{}intror} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{iff} \PYG{o}{(}\PYG{n}{P} \PYG{n}{Q}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{n}{Q} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{IF\PYGZus{}then\PYGZus{}else} \PYG{o}{(}\PYG{n}{P} \PYG{n}{Q} \PYG{n}{R}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{P} \PYG{o}{/\PYGZbs{}} \PYG{n}{Q} \PYG{o}{\PYGZbs{}/} \PYG{o}{\PYGZti{}} \PYG{n}{P} \PYG{o}{/\PYGZbs{}} \PYG{n}{R}\PYG{o}{.}
\end{sphinxVerbatim}


\paragraph{Quantifiers}
\label{\detokenize{language/coq-library:quantifiers}}
\index{Quantifiers}\index{all (term)}\index{ex (term)}\index{exists (term)}\index{ex\_intro (term)}\index{ex2 (term)}\index{exists2 (term)}\index{ex\_intro2 (term)}\ignorespaces 
Then we find first-order quantifiers:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{all} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{P} \PYG{n}{x}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{ex} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=}
 \PYG{n}{ex\PYGZus{}intro} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{P} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{ex2} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P} \PYG{n}{Q}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=}
 \PYG{n}{ex\PYGZus{}intro2} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{P} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{Q} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

The following abbreviations are allowed:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline

\sphinxcode{\sphinxupquote{exists x:A, P}}
&
\sphinxcode{\sphinxupquote{ex A (fun x:A =\textgreater{} P)}}
\\
\hline
\sphinxcode{\sphinxupquote{exists x, P}}
&
\sphinxcode{\sphinxupquote{ex \_ (fun x =\textgreater{} P)}}
\\
\hline
\sphinxcode{\sphinxupquote{exists2 x:A, P \& Q}}
&
\sphinxcode{\sphinxupquote{ex2 A (fun x:A =\textgreater{} P) (fun x:A =\textgreater{} Q)}}
\\
\hline
\sphinxcode{\sphinxupquote{exists2 x, P \& Q}}
&
\sphinxcode{\sphinxupquote{ex2 \_ (fun x =\textgreater{} P) (fun x =\textgreater{} Q)}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

The type annotation \sphinxcode{\sphinxupquote{:A}} can be omitted when \sphinxcode{\sphinxupquote{A}} can be
synthesized by the system.


\paragraph{Equality}
\label{\detokenize{language/coq-library:equality}}\label{\detokenize{language/coq-library:coq-equality}}
\index{Equality}\index{eq (term)}\index{eq\_refl (term)}\ignorespaces 
Then, we find equality, defined as an inductive relation. That is,
given a type \sphinxcode{\sphinxupquote{A}} and an \sphinxcode{\sphinxupquote{x}} of type \sphinxcode{\sphinxupquote{A}}, the
predicate \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{eq} \DUrole{name}{A} \DUrole{name}{x}\DUrole{operator}{)}}} is the smallest one which contains \sphinxcode{\sphinxupquote{x}}.
This definition, due to Christine Paulin-Mohring, is equivalent to
define \sphinxcode{\sphinxupquote{eq}} as the smallest reflexive relation, and it is also
equivalent to Leibniz' equality.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{eq} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
  \PYG{n}{eq\PYGZus{}refl} \PYG{o}{:} \PYG{n}{eq} \PYG{n}{A} \PYG{n}{x} \PYG{n}{x}\PYG{o}{.}
\end{sphinxVerbatim}


\paragraph{Lemmas}
\label{\detokenize{language/coq-library:lemmas}}
Finally, a few easy lemmas are provided.

\index{absurd (term)}\index{eq\_sym (term)}\index{eq\_trans (term)}\index{f\_equal (term)}\index{sym\_not\_eq (term)}\index{eq\_ind\_r (term)}\index{eq\_rec\_r (term)}\index{eq\_rect (term)}\index{eq\_rect\_r (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-4}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Theorem} \PYG{n}{absurd} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{C}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{.}
\PYG{k+kn}{Section} \PYG{n}{equality}\PYG{o}{.}
\PYG{k+kn}{Variables} \PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{.}
\PYG{k+kn}{Variable} \PYG{n}{f} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{.}
\PYG{k+kn}{Variables} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{A}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{eq\PYGZus{}sym} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{=} \PYG{n}{x}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{eq\PYGZus{}trans} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{=} \PYG{n}{z} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{=} \PYG{n}{z}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{f\PYGZus{}equal} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{f} \PYG{n}{x} \PYG{o}{=} \PYG{n}{f} \PYG{n}{y}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{not\PYGZus{}eq\PYGZus{}sym} \PYG{o}{:} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{x}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{equality}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{eq\PYGZus{}ind\PYGZus{}r} \PYG{o}{:}
 \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{A}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,} \PYG{n}{P} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{y} \PYG{o}{=} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{y}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{eq\PYGZus{}rec\PYGZus{}r} \PYG{o}{:}
 \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{A}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{k+kn}{Set}\PYG{o}{)}\PYG{o}{,} \PYG{n}{P} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{y} \PYG{o}{=} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{y}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{eq\PYGZus{}rect\PYGZus{}r} \PYG{o}{:}
 \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{A}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{k+kt}{Type}\PYG{o}{)}\PYG{o}{,} \PYG{n}{P} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{y} \PYG{o}{=} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{y}\PYG{o}{.}
\PYG{k+kn}{Hint} \PYG{n}{Immediate} \PYG{n}{eq\PYGZus{}sym} \PYG{n}{not\PYGZus{}eq\PYGZus{}sym} \PYG{o}{:} \PYG{n}{core}\PYG{o}{.}
\end{sphinxVerbatim}

\index{f\_equal2 ... f\_equal5 (term)}\ignorespaces 
The theorem \sphinxcode{\sphinxupquote{f\_equal}} is extended to functions with two to five
arguments. The theorem are names \sphinxcode{\sphinxupquote{f\_equal2}}, \sphinxcode{\sphinxupquote{f\_equal3}},
\sphinxcode{\sphinxupquote{f\_equal4}} and \sphinxcode{\sphinxupquote{f\_equal5}}.
For instance \sphinxcode{\sphinxupquote{f\_equal3}} is defined the following way.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Theorem} \PYG{n}{f\PYGZus{}equal3} \PYG{o}{:}
 \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A1} \PYG{n}{A2} \PYG{n}{A3} \PYG{n}{B}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f}\PYG{o}{:}\PYG{n}{A1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A3} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{)}
   \PYG{o}{(}\PYG{n}{x1} \PYG{n}{y1}\PYG{o}{:}\PYG{n}{A1}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x2} \PYG{n}{y2}\PYG{o}{:}\PYG{n}{A2}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x3} \PYG{n}{y3}\PYG{o}{:}\PYG{n}{A3}\PYG{o}{)}\PYG{o}{,}
   \PYG{n}{x1} \PYG{o}{=} \PYG{n}{y1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x2} \PYG{o}{=} \PYG{n}{y2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x3} \PYG{o}{=} \PYG{n}{y3} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{f} \PYG{n}{x1} \PYG{n}{x2} \PYG{n}{x3} \PYG{o}{=} \PYG{n}{f} \PYG{n}{y1} \PYG{n}{y2} \PYG{n}{y3}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Datatypes}
\label{\detokenize{language/coq-library:datatypes}}\label{\detokenize{language/coq-library:id1}}
\index{Datatypes}\ignorespaces 
In the basic library, we find in \sphinxcode{\sphinxupquote{Datatypes.v}} the definition
of the basic data-types of programming,
defined as inductive constructions over the sort \sphinxcode{\sphinxupquote{Set}}. Some of
them come with a special syntax shown below (this syntax table is common with
the next section {\hyperref[\detokenize{language/coq-library:specification}]{\sphinxcrossref{\DUrole{std,std-ref}{Specification}}}}):


\begin{productionlist}
\phantomsection\label{\detokenize{language/coq-library:grammar-token-specif}}\production{specif}{  {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}} * {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}}                           (prod)}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}} + {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}}                          (sum)}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}} + \{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}} \}                      (sumor)}
\productioncont{ \textbar{} \{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}} \} + \{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}} \}                  (sumbool)}
\productioncont{ \textbar{} \{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}} \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}} \}              (sig)}
\productioncont{ \textbar{} \{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}} \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}} \& {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{form}}}}} \}       (sig2)}
\productioncont{ \textbar{} \{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}} \& {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}} \}             (sigT)}
\productioncont{ \textbar{} \{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}} \& {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}} \& {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-specif}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{specif}}}}} \}    (sigT2)}
\phantomsection\label{\detokenize{language/coq-library:grammar-token-term}}\production{term}{ ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}})                               (pair)}
\end{productionlist}



\paragraph{Programming}
\label{\detokenize{language/coq-library:programming}}
\index{Programming}\index{unit (term)}\index{tt (term)}\index{bool (term)}\index{true (term)}\index{false (term)}\index{nat (term)}\index{O (term)}\index{S (term)}\index{option (term)}\index{Some (term)}\index{None (term)}\index{identity (term)}\index{refl\_identity (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-7}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{k+kt}{unit} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{tt}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{k+kt}{bool} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n+nb+bp}{true} \PYG{o}{\textbar{}} \PYG{n+nb+bp}{false}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{k+kt}{nat} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{O} \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{option} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{Some} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{\textbar{}} \PYG{n}{None}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{identity} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{a}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type} \PYG{o}{:=}
  \PYG{n}{refl\PYGZus{}identity} \PYG{o}{:} \PYG{n}{identity} \PYG{n}{A} \PYG{n}{a} \PYG{n}{a}\PYG{o}{.}
\end{sphinxVerbatim}

Note that zero is the letter \sphinxcode{\sphinxupquote{O}}, and \sphinxstyleemphasis{not} the numeral \sphinxcode{\sphinxupquote{0}}.

The predicate \sphinxcode{\sphinxupquote{identity}} is logically
equivalent to equality but it lives in sort \sphinxcode{\sphinxupquote{Type}}.
It is mainly maintained for compatibility.

We then define the disjoint sum of \sphinxcode{\sphinxupquote{A+B}} of two sets \sphinxcode{\sphinxupquote{A}} and
\sphinxcode{\sphinxupquote{B}}, and their product \sphinxcode{\sphinxupquote{A*B}}.

\index{sum (term)}\index{A+B (term)}\index{+ (term)}\index{inl (term)}\index{inr (term)}\index{prod (term)}\index{A*B (term)}\index{* (term)}\index{pair (term)}\index{fst (term)}\index{snd (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-8}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{sum} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{inl} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{\textbar{}} \PYG{n}{inr} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{prod} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{pair} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Section} \PYG{n}{projections}\PYG{o}{.}
\PYG{k+kn}{Variables} \PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{fst} \PYG{o}{(}\PYG{n}{H}\PYG{o}{:} \PYG{n}{prod} \PYG{n}{A} \PYG{n}{B}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{H} \PYG{k}{with}
                              \PYG{o}{\textbar{}} \PYG{n}{pair} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{n}{x} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}
                              \PYG{k}{end}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{snd} \PYG{o}{(}\PYG{n}{H}\PYG{o}{:} \PYG{n}{prod} \PYG{n}{A} \PYG{n}{B}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{H} \PYG{k}{with}
                              \PYG{o}{\textbar{}} \PYG{n}{pair} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{n}{x} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{y}
                              \PYG{k}{end}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{projections}\PYG{o}{.}
\end{sphinxVerbatim}

Some operations on \sphinxcode{\sphinxupquote{bool}} are also provided: \sphinxcode{\sphinxupquote{andb}} (with
infix notation \sphinxcode{\sphinxupquote{\&\&}}), \sphinxcode{\sphinxupquote{orb}} (with
infix notation \sphinxcode{\sphinxupquote{\textbar{}\textbar{}}}), \sphinxcode{\sphinxupquote{xorb}}, \sphinxcode{\sphinxupquote{implb}} and \sphinxcode{\sphinxupquote{negb}}.


\subsubsection{Specification}
\label{\detokenize{language/coq-library:specification}}\label{\detokenize{language/coq-library:id2}}
The following notions defined in module \sphinxcode{\sphinxupquote{Specif.v}} allow to build new data-types and specifications.
They are available with the syntax shown in the previous section {\hyperref[\detokenize{language/coq-library:datatypes}]{\sphinxcrossref{\DUrole{std,std-ref}{Datatypes}}}}.

For instance, given \sphinxcode{\sphinxupquote{\DUrole{name}{A}\DUrole{operator}{:}\DUrole{keyword,type}{Type}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{P}\DUrole{operator}{:}\DUrole{name}{A}\DUrole{operator}{-\textgreater{}}\DUrole{keyword,type}{Prop}}}, the construct
\sphinxcode{\sphinxupquote{\DUrole{operator}{\{}\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A} \DUrole{operator}{\textbar{}} \DUrole{name}{P} \DUrole{name}{x}\DUrole{operator}{\}}}} (in abstract syntax \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{sig} \DUrole{name}{A} \DUrole{name}{P}\DUrole{operator}{)}}}) is a
\sphinxcode{\sphinxupquote{Type}}. We may build elements of this set as \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{exist} \DUrole{name}{x} \DUrole{name}{p}\DUrole{operator}{)}}}
whenever we have a witness \sphinxcode{\sphinxupquote{\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A}}} with its justification
\sphinxcode{\sphinxupquote{\DUrole{name}{p}\DUrole{operator}{:}\DUrole{name}{P} \DUrole{name}{x}}}.

From such a \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{exist} \DUrole{name}{x} \DUrole{name}{p}\DUrole{operator}{)}}} we may in turn extract its witness
\sphinxcode{\sphinxupquote{\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A}}} (using an elimination construct such as \sphinxcode{\sphinxupquote{match}}) but
\sphinxstyleemphasis{not} its justification, which stays hidden, like in an abstract
data-type. In technical terms, one says that \sphinxcode{\sphinxupquote{sig}} is a \sphinxstyleemphasis{weak
(dependent) sum}.  A variant \sphinxcode{\sphinxupquote{sig2}} with two predicates is also
provided.

\index{\sphinxleftcurlybrace{}x:A \textbar{} P x\sphinxrightcurlybrace{} (term)}\index{sig (term)}\index{exist (term)}\index{sig2 (term)}\index{exist2 (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-9}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{sig} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{exist} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{P} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{sig2} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P} \PYG{n}{Q}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
  \PYG{n}{exist2} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{P} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{Q} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

A \sphinxstyleemphasis{strong (dependent) sum} \sphinxcode{\sphinxupquote{\DUrole{operator}{\{}\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A} \DUrole{operator}{\&} \DUrole{name}{P} \DUrole{name}{x}\DUrole{operator}{\}}}} may be also defined,
when the predicate \sphinxcode{\sphinxupquote{P}} is now defined as a
constructor of types in \sphinxcode{\sphinxupquote{Type}}.

\index{\sphinxleftcurlybrace{}x:A \& P x\sphinxrightcurlybrace{} (term)}\index{sigT (term)}\index{existT (term)}\index{sigT2 (term)}\index{existT2 (term)}\index{projT1 (term)}\index{projT2 (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-10}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{sigT} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=} \PYG{n}{existT} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{P} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Section} \PYG{n}{Projections2}\PYG{o}{.}
\PYG{k+kn}{Variable} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{.}
\PYG{k+kn}{Variable} \PYG{n}{P} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{projT1} \PYG{o}{(}\PYG{n}{H}\PYG{o}{:}\PYG{n}{sigT} \PYG{n}{A} \PYG{n}{P}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{let} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{h}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{H} \PYG{k}{in} \PYG{n}{x}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{projT2} \PYG{o}{(}\PYG{n}{H}\PYG{o}{:}\PYG{n}{sigT} \PYG{n}{A} \PYG{n}{P}\PYG{o}{)} \PYG{o}{:=}
 \PYG{k}{match} \PYG{n}{H} \PYG{k}{return} \PYG{n}{P} \PYG{o}{(}\PYG{n}{projT1} \PYG{n}{H}\PYG{o}{)} \PYG{k}{with}
  \PYG{n}{existT} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{n}{x} \PYG{n}{h} \PYG{o}{=\PYGZgt{}} \PYG{n}{h}
 \PYG{k}{end}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{Projections2}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{sigT2} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P} \PYG{n}{Q}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
  \PYG{n}{existT2} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{P} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{Q} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

A related non-dependent construct is the constructive sum
\sphinxcode{\sphinxupquote{\DUrole{operator}{\{}\DUrole{name}{A}\DUrole{operator}{\}+\{}\DUrole{name}{B}\DUrole{operator}{\}}}} of two propositions \sphinxcode{\sphinxupquote{A}} and \sphinxcode{\sphinxupquote{B}}.

\index{sumbool (term)}\index{left (term)}\index{right (term)}\index{\sphinxleftcurlybrace{}A\sphinxrightcurlybrace{}+\sphinxleftcurlybrace{}B\sphinxrightcurlybrace{} (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-11}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{sumbool} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{k}{left} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{\textbar{}} \PYG{k}{right} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

This \sphinxcode{\sphinxupquote{sumbool}} construct may be used as a kind of indexed boolean
data-type. An intermediate between \sphinxcode{\sphinxupquote{sumbool}} and \sphinxcode{\sphinxupquote{sum}} is
the mixed \sphinxcode{\sphinxupquote{sumor}} which combines \sphinxcode{\sphinxupquote{\DUrole{name}{A}\DUrole{operator}{:}\DUrole{keyword,namespace}{Set}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{B}\DUrole{operator}{:}\DUrole{keyword,type}{Prop}}}
in the construction \sphinxcode{\sphinxupquote{\DUrole{name}{A}\DUrole{operator}{+\{}\DUrole{name}{B}\DUrole{operator}{\}}}} in \sphinxcode{\sphinxupquote{Set}}.

\index{sumor (term)}\index{inleft (term)}\index{inright (term)}\index{A+\sphinxleftcurlybrace{}B\sphinxrightcurlybrace{} (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-12}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{sumor} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{B}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{inleft} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)}
\PYG{o}{\textbar{}} \PYG{n}{inright} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:}\PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

We may define variants of the axiom of choice, like in Martin-Löf's
Intuitionistic Type Theory.

\index{Choice (term)}\index{Choice2 (term)}\index{bool\_choice (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-13}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{Choice} \PYG{o}{:}
 \PYG{k}{forall} \PYG{o}{(}\PYG{n}{S} \PYG{n}{S\PYGZsq{}}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{R}\PYG{o}{:}\PYG{n}{S} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{S\PYGZsq{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,}
  \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x}\PYG{o}{:}\PYG{n}{S}\PYG{o}{,} \PYG{o}{\PYGZob{}}\PYG{n}{y} \PYG{o}{:} \PYG{n}{S\PYGZsq{}} \PYG{o}{\textbar{}} \PYG{n}{R} \PYG{n}{x} \PYG{n}{y}\PYG{o}{\PYGZcb{}}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
  \PYG{o}{\PYGZob{}}\PYG{n}{f} \PYG{o}{:} \PYG{n}{S} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{S\PYGZsq{}} \PYG{o}{\textbar{}} \PYG{k}{forall} \PYG{n}{z}\PYG{o}{:}\PYG{n}{S}\PYG{o}{,} \PYG{n}{R} \PYG{n}{z} \PYG{o}{(}\PYG{n}{f} \PYG{n}{z}\PYG{o}{)}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{Choice2} \PYG{o}{:}
 \PYG{k}{forall} \PYG{o}{(}\PYG{n}{S} \PYG{n}{S\PYGZsq{}}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{R}\PYG{o}{:}\PYG{n}{S} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{S\PYGZsq{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{)}\PYG{o}{,}
  \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x}\PYG{o}{:}\PYG{n}{S}\PYG{o}{,} \PYG{o}{\PYGZob{}}\PYG{n}{y} \PYG{o}{:} \PYG{n}{S\PYGZsq{}} \PYG{o}{\PYGZam{}}  \PYG{n}{R} \PYG{n}{x} \PYG{n}{y}\PYG{o}{\PYGZcb{}}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
   \PYG{o}{\PYGZob{}}\PYG{n}{f} \PYG{o}{:} \PYG{n}{S} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{S\PYGZsq{}} \PYG{o}{\PYGZam{}}  \PYG{k}{forall} \PYG{n}{z}\PYG{o}{:}\PYG{n}{S}\PYG{o}{,} \PYG{n}{R} \PYG{n}{z} \PYG{o}{(}\PYG{n}{f} \PYG{n}{z}\PYG{o}{)}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{bool\PYGZus{}choice} \PYG{o}{:}
 \PYG{k}{forall} \PYG{o}{(}\PYG{n}{S}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{R1} \PYG{n}{R2}\PYG{o}{:}\PYG{n}{S} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,}
  \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x}\PYG{o}{:}\PYG{n}{S}\PYG{o}{,} \PYG{o}{\PYGZob{}}\PYG{n}{R1} \PYG{n}{x}\PYG{o}{\PYGZcb{}} \PYG{o}{+} \PYG{o}{\PYGZob{}}\PYG{n}{R2} \PYG{n}{x}\PYG{o}{\PYGZcb{}}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
  \PYG{o}{\PYGZob{}}\PYG{n}{f} \PYG{o}{:} \PYG{n}{S} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool} \PYG{o}{\textbar{}}
   \PYG{k}{forall} \PYG{n}{x}\PYG{o}{:}\PYG{n}{S}\PYG{o}{,} \PYG{n}{f} \PYG{n}{x} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{/\PYGZbs{}} \PYG{n}{R1} \PYG{n}{x} \PYG{o}{\PYGZbs{}/} \PYG{n}{f} \PYG{n}{x} \PYG{o}{=} \PYG{n+nb+bp}{false} \PYG{o}{/\PYGZbs{}} \PYG{n}{R2} \PYG{n}{x}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

The next construct builds a sum between a data-type \sphinxcode{\sphinxupquote{\DUrole{name}{A}\DUrole{operator}{:}\DUrole{keyword,type}{Type}}} and
an exceptional value encoding errors:

\index{Exc (term)}\index{value (term)}\index{error (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-14}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{Exc} \PYG{o}{:=} \PYG{n}{option}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{value} \PYG{o}{:=} \PYG{n}{Some}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{error} \PYG{o}{:=} \PYG{n}{None}\PYG{o}{.}
\end{sphinxVerbatim}

This module ends with theorems, relating the sorts \sphinxcode{\sphinxupquote{Set}} or
\sphinxcode{\sphinxupquote{Type}} and \sphinxcode{\sphinxupquote{Prop}} in a way which is consistent with the
realizability interpretation.

\index{False\_rect (term)}\index{False\_rec (term)}\index{eq\_rect (term)}\index{absurd\_set (term)}\index{and\_rect (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-15}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{except} \PYG{o}{:=} \PYG{n}{False\PYGZus{}rec}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{absurd\PYGZus{}set} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{C}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{and\PYGZus{}rect2} \PYG{o}{:}
 \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)}\PYG{o}{,} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Basic Arithmetics}
\label{\detokenize{language/coq-library:basic-arithmetics}}
The basic library includes a few elementary properties of natural
numbers, together with the definitions of predecessor, addition and
multiplication, in module \sphinxcode{\sphinxupquote{Peano.v}}. It also
provides a scope \sphinxcode{\sphinxupquote{nat\_scope}} gathering standard notations for
common operations (\sphinxcode{\sphinxupquote{+}}, \sphinxcode{\sphinxupquote{*}}) and a decimal notation for
numbers, allowing for instance to write \sphinxcode{\sphinxupquote{3}} for \sphinxcode{\sphinxupquote{\DUrole{name}{S} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{O}\DUrole{operator}{)))}}}. This also works on
the left hand side of a \sphinxcode{\sphinxupquote{match}} expression (see for example
section {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}}). This scope is opened by default.

\begin{sphinxadmonition}{note}{Example}

The following example is not part of the standard library, but it
shows the usage of the notations:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{even} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{:=}
 \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
 \PYG{o}{\textbar{}} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
 \PYG{o}{\textbar{}} \PYG{l+m+mi}{1} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
 \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{even} \PYG{n}{n}
 \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\index{eq\_S (term)}\index{pred (term)}\index{pred\_Sn (term)}\index{eq\_add\_S (term)}\index{not\_eq\_S (term)}\index{IsSucc (term)}\index{O\_S (term)}\index{n\_Sn (term)}\index{plus (term)}\index{plus\_n\_O (term)}\index{plus\_n\_Sm (term)}\index{mult (term)}\index{mult\_n\_O (term)}\index{mult\_n\_Sm (term)}\ignorespaces 
Now comes the content of module \sphinxcode{\sphinxupquote{Peano}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Theorem} \PYG{n}{eq\PYGZus{}S} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{S} \PYG{n}{x} \PYG{o}{=} \PYG{n}{S} \PYG{n}{y}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{pred} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
 \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
 \PYG{o}{\textbar{}} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
 \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{u} \PYG{o}{=\PYGZgt{}} \PYG{n}{u}
 \PYG{k}{end}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{pred\PYGZus{}Sn} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{m} \PYG{o}{=} \PYG{n}{pred} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{eq\PYGZus{}add\PYGZus{}S} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{S} \PYG{n}{n} \PYG{o}{=} \PYG{n}{S} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
\PYG{k+kn}{Hint} \PYG{n}{Immediate} \PYG{n}{eq\PYGZus{}add\PYGZus{}S} \PYG{o}{:} \PYG{n}{core}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{not\PYGZus{}eq\PYGZus{}S} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{S} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{S} \PYG{n}{m}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{IsSucc} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=}
 \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
 \PYG{o}{\textbar{}} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{False}
 \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{True}
 \PYG{k}{end}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{O\PYGZus{}S} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{S} \PYG{n}{n}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{n\PYGZus{}Sn} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{S} \PYG{n}{n}\PYG{o}{.}
\PYG{k+kn}{Fixpoint} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
 \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
 \PYG{o}{\textbar{}} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
 \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{p} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)}
 \PYG{k}{end}
\PYG{n}{where} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{n + m}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{n} \PYG{n}{m}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{plus\PYGZus{}n\PYGZus{}O} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{plus\PYGZus{}n\PYGZus{}Sm} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{S} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{S} \PYG{n}{m}\PYG{o}{.}
\PYG{k+kn}{Fixpoint} \PYG{n}{mult} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
 \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
 \PYG{o}{\textbar{}} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
 \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{m} \PYG{o}{+} \PYG{n}{p} \PYG{o}{*} \PYG{n}{m}
 \PYG{k}{end}
\PYG{n}{where} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{n * m}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{mult} \PYG{n}{n} \PYG{n}{m}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{mult\PYGZus{}n\PYGZus{}O} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{n} \PYG{o}{*} \PYG{l+m+mi}{0}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{mult\PYGZus{}n\PYGZus{}Sm} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{*} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n} \PYG{o}{*} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

Finally, it gives the definition of the usual orderings \sphinxcode{\sphinxupquote{le}},
\sphinxcode{\sphinxupquote{lt}}, \sphinxcode{\sphinxupquote{ge}} and \sphinxcode{\sphinxupquote{gt}}.

\index{le (term)}\index{le\_n (term)}\index{le\_S (term)}\index{lt (term)}\index{ge (term)}\index{gt (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-17}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{le} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{le\PYGZus{}n} \PYG{o}{:} \PYG{n}{le} \PYG{n}{n} \PYG{n}{n}
\PYG{o}{\textbar{}} \PYG{n}{le\PYGZus{}S} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
\PYG{n}{where} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{n \PYGZlt{}= m}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{le} \PYG{n}{n} \PYG{n}{m}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{lt} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{S} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{ge} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{gt} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{m} \PYG{o}{\PYGZlt{}} \PYG{n}{n}\PYG{o}{.}
\end{sphinxVerbatim}

Properties of these relations are not initially known, but may be
required by the user from modules \sphinxcode{\sphinxupquote{Le}} and \sphinxcode{\sphinxupquote{Lt}}.  Finally,
\sphinxcode{\sphinxupquote{Peano}} gives some lemmas allowing pattern matching, and a double
induction principle.

\index{nat\_case (term)}\index{nat\_double\_ind (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-18}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Theorem} \PYG{n}{nat\PYGZus{}case} \PYG{o}{:}
 \PYG{k}{forall} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,}
 \PYG{n}{P} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{nat\PYGZus{}double\PYGZus{}ind} \PYG{o}{:}
 \PYG{k}{forall} \PYG{n}{R}\PYG{o}{:}\PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{,}
  \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{R} \PYG{l+m+mi}{0} \PYG{n}{n}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
  \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{R} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
  \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{R} \PYG{n}{n} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{R} \PYG{n}{n} \PYG{n}{m}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Well-founded recursion}
\label{\detokenize{language/coq-library:well-founded-recursion}}
The basic library contains the basics of well-founded recursion and
well-founded induction, in module \sphinxcode{\sphinxupquote{Wf.v}}.

\index{Well foundedness}\index{Recursion}\index{Well founded induction}\index{Acc (term)}\index{Acc\_inv (term)}\index{Acc\_rect (term)}\index{well\_founded (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-19}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Section} \PYG{n}{Well\PYGZus{}founded}\PYG{o}{.}
\PYG{k+kn}{Variable} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{.}
\PYG{k+kn}{Variable} \PYG{n}{R} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{Acc} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=}
  \PYG{n}{Acc\PYGZus{}intro} \PYG{o}{:} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{R} \PYG{n}{y} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Acc} \PYG{n}{y}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Acc} \PYG{n}{x}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{Acc\PYGZus{}inv} \PYG{n}{x} \PYG{o}{:} \PYG{n}{Acc} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{R} \PYG{n}{y} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Acc} \PYG{n}{y}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{well\PYGZus{}founded} \PYG{o}{:=} \PYG{k}{forall} \PYG{n}{a}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{Acc} \PYG{n}{a}\PYG{o}{.}
\PYG{k+kn}{Hypothesis} \PYG{n}{Rwf} \PYG{o}{:} \PYG{n}{well\PYGZus{}founded}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{well\PYGZus{}founded\PYGZus{}induction} \PYG{o}{:}
 \PYG{k}{forall} \PYG{n}{P}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{,}
  \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{R} \PYG{n}{y} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{y}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{x}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{a}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{P} \PYG{n}{a}\PYG{o}{.}
\PYG{k+kn}{Theorem} \PYG{n}{well\PYGZus{}founded\PYGZus{}ind} \PYG{o}{:}
 \PYG{k}{forall} \PYG{n}{P}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{,}
  \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{R} \PYG{n}{y} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{y}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{x}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{a}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{P} \PYG{n}{a}\PYG{o}{.}
\end{sphinxVerbatim}

The automatically generated scheme \sphinxcode{\sphinxupquote{Acc\_rect}}
can be used to define functions by fixpoints using
well-founded relations to justify termination. Assuming
extensionality of the functional used for the recursive call, the
fixpoint equation can be proved.

\index{Fix\_F (term)}\index{fix\_eq (term)}\index{Fix\_F\_inv (term)}\index{Fix\_F\_eq (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-20}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Section} \PYG{n}{FixPoint}\PYG{o}{.}
\PYG{k+kn}{Variable} \PYG{n}{P} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{.}
\PYG{k+kn}{Variable} \PYG{n}{F} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{R} \PYG{n}{y} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{y}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{x}\PYG{o}{.}
\PYG{k+kn}{Fixpoint} \PYG{n}{Fix\PYGZus{}F} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{r}\PYG{o}{:}\PYG{n}{Acc} \PYG{n}{x}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{r}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{P} \PYG{n}{x} \PYG{o}{:=}
  \PYG{n}{F} \PYG{n}{x} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{(}\PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{p}\PYG{o}{:}\PYG{n}{R} \PYG{n}{y} \PYG{n}{x}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{Fix\PYGZus{}F} \PYG{n}{y} \PYG{o}{(}\PYG{n}{Acc\PYGZus{}inv} \PYG{n}{x} \PYG{n}{r} \PYG{n}{y} \PYG{n}{p}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{Fix} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{Fix\PYGZus{}F} \PYG{n}{x} \PYG{o}{(}\PYG{n}{Rwf} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Hypothesis} \PYG{n}{F\PYGZus{}ext} \PYG{o}{:}
  \PYG{k}{forall} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f} \PYG{n}{g}\PYG{o}{:}\PYG{k}{forall} \PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{R} \PYG{n}{y} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{y}\PYG{o}{)}\PYG{o}{,}
    \PYG{o}{(}\PYG{k}{forall} \PYG{o}{(}\PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{p}\PYG{o}{:}\PYG{n}{R} \PYG{n}{y} \PYG{n}{x}\PYG{o}{)}\PYG{o}{,} \PYG{n}{f} \PYG{n}{y} \PYG{n}{p} \PYG{o}{=} \PYG{n}{g} \PYG{n}{y} \PYG{n}{p}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{F} \PYG{n}{x} \PYG{n}{f} \PYG{o}{=} \PYG{n}{F} \PYG{n}{x} \PYG{n}{g}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{Fix\PYGZus{}F\PYGZus{}eq} \PYG{o}{:}
 \PYG{k}{forall} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{r}\PYG{o}{:}\PYG{n}{Acc} \PYG{n}{x}\PYG{o}{)}\PYG{o}{,}
   \PYG{n}{F} \PYG{n}{x} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{(}\PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{p}\PYG{o}{:}\PYG{n}{R} \PYG{n}{y} \PYG{n}{x}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{Fix\PYGZus{}F} \PYG{n}{y} \PYG{o}{(}\PYG{n}{Acc\PYGZus{}inv} \PYG{n}{x} \PYG{n}{r} \PYG{n}{y} \PYG{n}{p}\PYG{o}{)}\PYG{o}{)} \PYG{o}{=} \PYG{n}{Fix\PYGZus{}F} \PYG{n}{x} \PYG{n}{r}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{Fix\PYGZus{}F\PYGZus{}inv} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{r} \PYG{n}{s}\PYG{o}{:}\PYG{n}{Acc} \PYG{n}{x}\PYG{o}{)}\PYG{o}{,} \PYG{n}{Fix\PYGZus{}F} \PYG{n}{x} \PYG{n}{r} \PYG{o}{=} \PYG{n}{Fix\PYGZus{}F} \PYG{n}{x} \PYG{n}{s}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{fix\PYGZus{}eq} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{,} \PYG{n}{Fix} \PYG{n}{x} \PYG{o}{=} \PYG{n}{F} \PYG{n}{x} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{(}\PYG{n}{y}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{p}\PYG{o}{:}\PYG{n}{R} \PYG{n}{y} \PYG{n}{x}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{Fix} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{FixPoint}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{Well\PYGZus{}founded}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Accessing the Type level}
\label{\detokenize{language/coq-library:accessing-the-type-level}}
The standard library includes \sphinxcode{\sphinxupquote{Type}} level definitions of counterparts of some
logic concepts and basic lemmas about them.

The module \sphinxcode{\sphinxupquote{Datatypes}} defines \sphinxcode{\sphinxupquote{identity}}, which is the \sphinxcode{\sphinxupquote{Type}} level counterpart
of equality:

\index{identity (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-21}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{identity} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{a}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type} \PYG{o}{:=}
  \PYG{n}{identity\PYGZus{}refl} \PYG{o}{:} \PYG{n}{identity} \PYG{n}{a} \PYG{n}{a}\PYG{o}{.}
\end{sphinxVerbatim}

Some properties of \sphinxcode{\sphinxupquote{identity}} are proved in the module \sphinxcode{\sphinxupquote{Logic\_Type}}, which also
provides the definition of \sphinxcode{\sphinxupquote{Type}} level negation:

\index{notT (term)}\ignorespaces 
\def\sphinxLiteralBlockLabel{\label{\detokenize{language/coq-library:index-22}}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{notT} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Tactics}
\label{\detokenize{language/coq-library:tactics}}
A few tactics defined at the user level are provided in the initial
state, in module \sphinxcode{\sphinxupquote{Tactics.v}}. They are listed at
\sphinxurl{http://coq.inria.fr/stdlib}, in paragraph \sphinxcode{\sphinxupquote{Init}}, link \sphinxcode{\sphinxupquote{Tactics}}.


\subsection{The standard library}
\label{\detokenize{language/coq-library:the-standard-library}}

\subsubsection{Survey}
\label{\detokenize{language/coq-library:survey}}
The rest of the standard library is structured into the following
subdirectories:
\begin{itemize}
\item {} 
\sphinxstylestrong{Logic} : Classical logic and dependent equality

\item {} 
\sphinxstylestrong{Arith} : Basic Peano arithmetic

\item {} 
\sphinxstylestrong{PArith} : Basic positive integer arithmetic

\item {} 
\sphinxstylestrong{NArith} : Basic binary natural number arithmetic

\item {} 
\sphinxstylestrong{ZArith} : Basic relative integer arithmetic

\item {} 
\sphinxstylestrong{Numbers} : Various approaches to natural, integer and cyclic numbers (currently axiomatically and on top of 2\textasciicircum{}31 binary words)

\item {} 
\sphinxstylestrong{Bool} : Booleans (basic functions and results)

\item {} 
\sphinxstylestrong{Lists} : Monomorphic and polymorphic lists (basic functions and results), Streams (infinite sequences defined with co-inductive types)

\item {} 
\sphinxstylestrong{Sets} : Sets (classical, constructive, finite, infinite, power set, etc.)

\item {} 
\sphinxstylestrong{FSets} : Specification and implementations of finite sets and finite maps (by lists and by AVL trees)

\item {} 
\sphinxstylestrong{Reals} : Axiomatization of real numbers (classical, basic functions, integer part, fractional part, limit, derivative, Cauchy series, power series and results,...)

\item {} 
\sphinxstylestrong{Relations} : Relations (definitions and basic results)

\item {} 
\sphinxstylestrong{Sorting} : Sorted list (basic definitions and heapsort correctness)

\item {} 
\sphinxstylestrong{Strings} : 8-bits characters and strings

\item {} 
\sphinxstylestrong{Wellfounded} : Well-founded relations (basic results)

\end{itemize}

These directories belong to the initial load path of the system, and
the modules they provide are compiled at installation time. So they
are directly accessible with the command \sphinxcode{\sphinxupquote{Require}} (see
Section {\hyperref[\detokenize{proof-engine/vernacular-commands:compiled-files}]{\sphinxcrossref{\DUrole{std,std-ref}{Compiled files}}}}).

The different modules of the \DUrole{smallcaps}{Coq} standard library are documented
online at \sphinxurl{http://coq.inria.fr/stdlib}.


\subsubsection{Peano’s arithmetic (nat)}
\label{\detokenize{language/coq-library:peanos-arithmetic-nat}}
\index{Peano's arithmetic}\index{nat\_scope}\ignorespaces 
While in the initial state, many operations and predicates of Peano's
arithmetic are defined, further operations and results belong to other
modules. For instance, the decidability of the basic predicates are
defined here. This is provided by requiring the module \sphinxcode{\sphinxupquote{Arith}}.

The following table describes the notations available in scope
\sphinxcode{\sphinxupquote{nat\_scope}} :


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline
\sphinxstyletheadfamily 
Notation
&\sphinxstyletheadfamily 
Interpretation
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textless{} \_}}
&
\sphinxcode{\sphinxupquote{lt}}
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textless{}= \_}}
&
\sphinxcode{\sphinxupquote{le}}
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textgreater{} \_}}
&
\sphinxcode{\sphinxupquote{gt}}
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textgreater{}= \_}}
&
\sphinxcode{\sphinxupquote{ge}}
\\
\hline
\sphinxcode{\sphinxupquote{x \textless{} y \textless{} z}}
&
\sphinxcode{\sphinxupquote{x \textless{} y /\textbackslash{} y \textless{} z}}
\\
\hline
\sphinxcode{\sphinxupquote{x \textless{} y \textless{}= z}}
&
\sphinxcode{\sphinxupquote{x \textless{} y /\textbackslash{} y \textless{}= z}}
\\
\hline
\sphinxcode{\sphinxupquote{x \textless{}= y \textless{} z}}
&
\sphinxcode{\sphinxupquote{x \textless{}= y /\textbackslash{} y \textless{} z}}
\\
\hline
\sphinxcode{\sphinxupquote{x \textless{}= y \textless{}= z}}
&
\sphinxcode{\sphinxupquote{x \textless{}= y /\textbackslash{} y \textless{}= z}}
\\
\hline
\sphinxcode{\sphinxupquote{\_ + \_}}
&
\sphinxcode{\sphinxupquote{plus}}
\\
\hline
\sphinxcode{\sphinxupquote{\_ - \_}}
&
\sphinxcode{\sphinxupquote{minus}}
\\
\hline
\sphinxcode{\sphinxupquote{\_ * \_}}
&
\sphinxcode{\sphinxupquote{mult}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}


\subsubsection{Notations for integer arithmetics}
\label{\detokenize{language/coq-library:notations-for-integer-arithmetics}}
\index{Arithmetical notations}\index{+ (term)}\index{* (term)}\index{- (term)}\index{singel: / (term)}\index{\textless{}= (term)}\index{\textgreater{}= (term)}\index{\textless{} (term)}\index{\textgreater{} (term)}\index{?= (term)}\index{mod (term)}\ignorespaces 
The following table describes the syntax of expressions
for integer arithmetics. It is provided by requiring and opening the module \sphinxcode{\sphinxupquote{ZArith}} and opening scope \sphinxcode{\sphinxupquote{Z\_scope}}.
It specifies how notations are interpreted and, when not
already reserved, the precedence and associativity.


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|T|}
\hline
\sphinxstyletheadfamily 
Notation
&\sphinxstyletheadfamily 
Interpretation
&\sphinxstyletheadfamily 
Precedence
&\sphinxstyletheadfamily 
Associativity
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textless{} \_}}
&
\sphinxcode{\sphinxupquote{Z.lt}}
&&\\
\hline
\sphinxcode{\sphinxupquote{\_ \textless{}= \_}}
&
\sphinxcode{\sphinxupquote{Z.le}}
&&\\
\hline
\sphinxcode{\sphinxupquote{\_ \textgreater{} \_}}
&
\sphinxcode{\sphinxupquote{Z.gt}}
&&\\
\hline
\sphinxcode{\sphinxupquote{\_ \textgreater{}= \_}}
&
\sphinxcode{\sphinxupquote{Z.ge}}
&&\\
\hline
\sphinxcode{\sphinxupquote{x \textless{} y \textless{} z}}
&
\sphinxcode{\sphinxupquote{x \textless{} y /\textbackslash{} y \textless{} z}}
&&\\
\hline
\sphinxcode{\sphinxupquote{x \textless{} y \textless{}= z}}
&
\sphinxcode{\sphinxupquote{x \textless{} y /\textbackslash{} y \textless{}= z}}
&&\\
\hline
\sphinxcode{\sphinxupquote{x \textless{}= y \textless{} z}}
&
\sphinxcode{\sphinxupquote{x \textless{}= y /\textbackslash{} y \textless{} z}}
&&\\
\hline
\sphinxcode{\sphinxupquote{x \textless{}= y \textless{}= z}}
&
\sphinxcode{\sphinxupquote{x \textless{}= y /\textbackslash{} y \textless{}= z}}
&&\\
\hline
\sphinxcode{\sphinxupquote{\_ ?= \_}}
&
\sphinxcode{\sphinxupquote{Z.compare}}
&
70
&
no
\\
\hline
\sphinxcode{\sphinxupquote{\_ + \_}}
&
\sphinxcode{\sphinxupquote{Z.add}}
&&\\
\hline
\sphinxcode{\sphinxupquote{\_ - \_}}
&
\sphinxcode{\sphinxupquote{Z.sub}}
&&\\
\hline
\sphinxcode{\sphinxupquote{\_ * \_}}
&
\sphinxcode{\sphinxupquote{Z.mul}}
&&\\
\hline
\sphinxcode{\sphinxupquote{\_ / \_}}
&
\sphinxcode{\sphinxupquote{Z.div}}
&&\\
\hline
\sphinxcode{\sphinxupquote{\_ mod \_}}
&
\sphinxcode{\sphinxupquote{Z.modulo}}
&
40
&
no
\\
\hline
\sphinxcode{\sphinxupquote{- \_}}
&
\sphinxcode{\sphinxupquote{Z.opp}}
&&\\
\hline
\sphinxcode{\sphinxupquote{\_ \textasciicircum{} \_}}
&
\sphinxcode{\sphinxupquote{Z.pow}}
&&\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{ZArith}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{z\PYGZus{}syntax\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{quote\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{newring\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{omega\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{l+m+mi}{2} \PYG{o}{+} \PYG{l+m+mi}{3}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z}\PYG{o}{.}
    \PYG{o}{(}\PYG{l+m+mi}{2} \PYG{o}{+} \PYG{l+m+mi}{3}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z}
         \PYG{o}{:} \PYG{n}{Z}

\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{Z\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{l+m+mi}{3}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{l+m+mi}{3}
         \PYG{o}{:} \PYG{n}{Z}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Real numbers library}
\label{\detokenize{language/coq-library:real-numbers-library}}

\paragraph{Notations for real numbers}
\label{\detokenize{language/coq-library:notations-for-real-numbers}}
This is provided by requiring and opening the module \sphinxcode{\sphinxupquote{Reals}} and
opening scope \sphinxcode{\sphinxupquote{R\_scope}}. This set of notations is very similar to
the notation for integer arithmetics. The inverse function was added.


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline
\sphinxstyletheadfamily 
Notation
&\sphinxstyletheadfamily 
Interpretation
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textless{} \_}}
&
\sphinxcode{\sphinxupquote{Rlt}}
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textless{}= \_}}
&
\sphinxcode{\sphinxupquote{Rle}}
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textgreater{} \_}}
&
\sphinxcode{\sphinxupquote{Rgt}}
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textgreater{}= \_}}
&
\sphinxcode{\sphinxupquote{Rge}}
\\
\hline
\sphinxcode{\sphinxupquote{x \textless{} y \textless{} z}}
&
\sphinxcode{\sphinxupquote{x \textless{} y /\textbackslash{} y \textless{} z}}
\\
\hline
\sphinxcode{\sphinxupquote{x \textless{} y \textless{}= z}}
&
\sphinxcode{\sphinxupquote{x \textless{} y /\textbackslash{} y \textless{}= z}}
\\
\hline
\sphinxcode{\sphinxupquote{x \textless{}= y \textless{} z}}
&
\sphinxcode{\sphinxupquote{x \textless{}= y /\textbackslash{} y \textless{} z}}
\\
\hline
\sphinxcode{\sphinxupquote{x \textless{}= y \textless{}= z}}
&
\sphinxcode{\sphinxupquote{x \textless{}= y /\textbackslash{} y \textless{}= z}}
\\
\hline
\sphinxcode{\sphinxupquote{\_ + \_}}
&
\sphinxcode{\sphinxupquote{Rplus}}
\\
\hline
\sphinxcode{\sphinxupquote{\_ - \_}}
&
\sphinxcode{\sphinxupquote{Rminus}}
\\
\hline
\sphinxcode{\sphinxupquote{\_ * \_}}
&
\sphinxcode{\sphinxupquote{Rmult}}
\\
\hline
\sphinxcode{\sphinxupquote{\_ / \_}}
&
\sphinxcode{\sphinxupquote{Rdiv}}
\\
\hline
\sphinxcode{\sphinxupquote{- \_}}
&
\sphinxcode{\sphinxupquote{Ropp}}
\\
\hline
\sphinxcode{\sphinxupquote{/ \_}}
&
\sphinxcode{\sphinxupquote{Rinv}}
\\
\hline
\sphinxcode{\sphinxupquote{\_ \textasciicircum{} \_}}
&
\sphinxcode{\sphinxupquote{pow}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Reals}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{r\PYGZus{}syntax\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{fourier\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{micromega\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}

\PYG{k+kn}{Check}  \PYG{o}{(}\PYG{l+m+mi}{2} \PYG{o}{+} \PYG{l+m+mi}{3}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{R}\PYG{o}{.}
    \PYG{o}{(}\PYG{l+m+mi}{2} \PYG{o}{+} \PYG{l+m+mi}{3}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{R}
         \PYG{o}{:} \PYG{n}{R}

\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{R\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{l+m+mi}{3}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{l+m+mi}{3}
         \PYG{o}{:} \PYG{n}{R}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Some tactics for real numbers}
\label{\detokenize{language/coq-library:some-tactics-for-real-numbers}}
In addition to the powerful \sphinxcode{\sphinxupquote{ring}}, \sphinxcode{\sphinxupquote{field}} and \sphinxcode{\sphinxupquote{fourier}}
tactics (see Chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}}), there are also:
\index{discrR (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/coq-library:coq:tacn.discrr}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{discrR}}}}
Proves that two real integer constants are different.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{DiscrR}\PYG{o}{.}
\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{R\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{l+m+mi}{5} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{5} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}

\PYG{n}{discrR}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{split\_Rabs (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/coq-library:coq:tacn.split-rabs}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{split\_Rabs}}}}
Allows unfolding the \sphinxcode{\sphinxupquote{Rabs}} constant and splits corresponding conjunctions.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Reals}\PYG{o}{.}
\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{R\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{:}\PYG{n}{R}\PYG{o}{,} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{Rabs} \PYG{n}{x}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{R}\PYG{o}{,} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{Rabs} \PYG{n}{x}

\PYG{k}{intro}\PYG{o}{;} \PYG{n}{split\PYGZus{}Rabs}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{R}
      \PYG{n}{Hlt} \PYG{o}{:} \PYG{n}{x} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{o}{\PYGZhy{}} \PYG{n}{x}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{x}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{split\_Rmult (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{language/coq-library:coq:tacn.split-rmult}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{split\_Rmult}}}}
Splits a condition that a product is non null into subgoals
corresponding to the condition on each operand of the product.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Reals}\PYG{o}{.}
\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{R\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z}\PYG{o}{:}\PYG{n}{R}\PYG{o}{,} \PYG{n}{x} \PYG{o}{*} \PYG{n}{y} \PYG{o}{*} \PYG{n}{z} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{R}\PYG{o}{,} \PYG{n}{x} \PYG{o}{*} \PYG{n}{y} \PYG{o}{*} \PYG{n}{z} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}

\PYG{k}{intros}\PYG{o}{;} \PYG{n}{split\PYGZus{}Rmult}\PYG{o}{.}
    \PYG{l+m+mi}{3} \PYG{n}{subgoals}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{n}{R}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{z} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}
\end{sphinxadmonition}

These tactics has been written with the tactic language \sphinxtitleref{L}$_{\text{tac}}$
described in Chapter {\hyperref[\detokenize{proof-engine/ltac:ltac}]{\sphinxcrossref{\DUrole{std,std-ref}{The tactic language}}}}.


\subsubsection{List library}
\label{\detokenize{language/coq-library:list-library}}
\index{Notations for lists}\index{length (term)}\index{head (term)}\index{tail (term)}\index{app (term)}\index{rev (term)}\index{nth (term)}\index{map (term)}\index{flat\_map (term)}\index{fold\_left (term)}\index{fold\_right (term)}\ignorespaces 
Some elementary operations on polymorphic lists are defined here.
They can be accessed by requiring module \sphinxcode{\sphinxupquote{List}}.

It defines the following notions:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{length}}

\item {} 
\sphinxcode{\sphinxupquote{head}} : first element (with default)

\item {} 
\sphinxcode{\sphinxupquote{tail}} : all but first element

\item {} 
\sphinxcode{\sphinxupquote{app}} : concatenation

\item {} 
\sphinxcode{\sphinxupquote{rev}} : reverse

\item {} 
\sphinxcode{\sphinxupquote{nth}} : accessing n-th element (with default)

\item {} 
\sphinxcode{\sphinxupquote{map}} : applying a function

\item {} 
\sphinxcode{\sphinxupquote{flat\_map}} : applying a function returning lists

\item {} 
\sphinxcode{\sphinxupquote{fold\_left}} : iterator (from head to tail)

\item {} 
\sphinxcode{\sphinxupquote{fold\_right}} : iterator (from tail to head)

\end{itemize}

The following table shows notations available when opening scope \sphinxcode{\sphinxupquote{list\_scope}}.


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|T|}
\hline
\sphinxstyletheadfamily 
Notation
&\sphinxstyletheadfamily 
Interpretation
&\sphinxstyletheadfamily 
Precedence
&\sphinxstyletheadfamily 
Associativity
\\
\hline
\sphinxcode{\sphinxupquote{\_ ++ \_}}
&
\sphinxcode{\sphinxupquote{app}}
&
60
&
right
\\
\hline
\sphinxcode{\sphinxupquote{\_ :: \_}}
&
\sphinxcode{\sphinxupquote{cons}}
&
60
&
right
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}


\subsection{Users’ contributions}
\label{\detokenize{language/coq-library:users-contributions}}\label{\detokenize{language/coq-library:userscontributions}}
Numerous users' contributions have been collected and are available at
URL \sphinxurl{http://coq.inria.fr/opam/www/}.  On this web page, you have a list
of all contributions with informations (author, institution, quick
description, etc.) and the possibility to download them one by one.
You will also find informations on how to submit a new
contribution.


\section{Calculus of Inductive Constructions}
\label{\detokenize{language/cic:calculus-of-inductive-constructions}}\label{\detokenize{language/cic:calculusofinductiveconstructions}}\label{\detokenize{language/cic::doc}}
The underlying formal language of \DUrole{smallcaps}{Coq} is a \sphinxstyleemphasis{Calculus of Inductive
Constructions} (\DUrole{smallcaps}{Cic}) whose inference rules are presented in this
chapter. The history of this formalism as well as pointers to related
work are provided in a separate chapter; see \sphinxstyleemphasis{Credits}.


\subsection{The terms}
\label{\detokenize{language/cic:the-terms}}\label{\detokenize{language/cic:id1}}
The expressions of the \DUrole{smallcaps}{Cic} are \sphinxstyleemphasis{terms} and all terms have a \sphinxstyleemphasis{type}.
There are types for functions (or programs), there are atomic types
(especially datatypes)... but also types for proofs and types for the
types themselves. Especially, any object handled in the formalism must
belong to a type. For instance, universal quantification is relative
to a type and takes the form "\sphinxstyleemphasis{for all x of type T, P} ". The expression
“x of type T” is written \sphinxcode{\sphinxupquote{\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{T}}}. Informally, \sphinxcode{\sphinxupquote{\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{T}}} can be thought as
“x belongs to T”.

The types of types are \sphinxstyleemphasis{sorts}. Types and sorts are themselves terms
so that terms, types and sorts are all components of a common
syntactic language of terms which is described in Section {\hyperref[\detokenize{language/cic:terms}]{\sphinxcrossref{\DUrole{std,std-ref}{Terms}}}} but,
first, we describe sorts.


\subsubsection{Sorts}
\label{\detokenize{language/cic:sorts}}\label{\detokenize{language/cic:id2}}
All sorts have a type and there is an infinite well-founded typing
hierarchy of sorts whose base sorts are \(\Prop\) and \(\Set\).

The sort \(\Prop\) intends to be the type of logical propositions. If \(M\) is a
logical proposition then it denotes the class of terms representing
proofs of \(M\). An object \(m\) belonging to \(M\) witnesses the fact that \(M\) is
provable. An object of type \(\Prop\) is called a proposition.

The sort \(\Set\) intends to be the type of small sets. This includes data
types such as booleans and naturals, but also products, subsets, and
function types over these data types.

\(\Prop\) and \(\Set\) themselves can be manipulated as ordinary terms.
Consequently they also have a type. Because assuming simply that \(\Set\)
has type \(\Set\) leads to an inconsistent theory \sphinxcite{zebibliography:coq86}, the language of
\DUrole{smallcaps}{Cic} has infinitely many sorts. There are, in addition to \(\Set\) and \(\Prop\)
a hierarchy of universes \(\Type(i)\) for any integer \(i\).

Like \(\Set\), all of the sorts \(\Type(i)\) contain small sets such as
booleans, natural numbers, as well as products, subsets and function
types over small sets. But, unlike \(\Set\), they also contain large sets,
namely the sorts \(\Set\) and \(\Type(j)\) for \(j<i\), and all products, subsets
and function types over these sorts.

Formally, we call \(\Sort\) the set of sorts which is defined by:
\begin{equation*}
\begin{split}\Sort \equiv \{\Prop,\Set,\Type(i)\;|\; i~∈ ℕ\}\end{split}
\end{equation*}
Their properties, such as: \(\Prop:\Type(1)\), \(\Set:\Type(1)\), and
\(\Type(i):\Type(i+1)\), are defined in Section {\hyperref[\detokenize{language/cic:subtyping-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{Subtyping rules}}}}.

The user does not have to mention explicitly the index \(i\) when
referring to the universe \(\Type(i)\). One only writes \(\Type\). The system
itself generates for each instance of \(\Type\) a new index for the
universe and checks that the constraints between these indexes can be
solved. From the user point of view we consequently have \(\Type:\Type\). We
shall make precise in the typing rules the constraints between the
indices.

\phantomsection\label{\detokenize{language/cic:implementation-issues}}
\sphinxstylestrong{Implementation issues} In practice, the Type hierarchy is
implemented using \sphinxstyleemphasis{algebraic
universes}. An algebraic universe \(u\) is either a variable (a qualified
identifier with a number) or a successor of an algebraic universe (an
expression \(u+1\)), or an upper bound of algebraic universes (an
expression \(\max(u 1 ,...,u n )\)), or the base universe (the expression
\(0\)) which corresponds, in the arity of template polymorphic inductive
types (see Section
{\hyperref[\detokenize{language/cic:well-formed-inductive-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Well-formed inductive definitions}}}}),
to the predicative sort \(\Set\). A graph of
constraints between the universe variables is maintained globally. To
ensure the existence of a mapping of the universes to the positive
integers, the graph of constraints must remain acyclic. Typing
expressions that violate the acyclicity of the graph of constraints
results in a Universe inconsistency error.


\sphinxstrong{See also:}


Section {\hyperref[\detokenize{language/gallina-extensions:printing-universes}]{\sphinxcrossref{\DUrole{std,std-ref}{Printing universes}}}}.




\subsubsection{Terms}
\label{\detokenize{language/cic:terms}}\label{\detokenize{language/cic:id4}}
Terms are built from sorts, variables, constants, abstractions,
applications, local definitions, and products. From a syntactic point
of view, types cannot be distinguished from terms, except that they
cannot start by an abstraction or a constructor. More precisely the
language of the \sphinxstyleemphasis{Calculus of Inductive Constructions} is built from
the following rules.
\begin{enumerate}
\def\theenumi{\arabic{enumi}}
\def\labelenumi{\theenumi .}
\makeatletter\def\p@enumii{\p@enumi \theenumi .}\makeatother
\item {} 
the sorts \(\Set\), \(\Prop\), \(\Type(i)\) are terms.

\item {} 
variables, hereafter ranged over by letters \(x\), \(y\), etc., are terms

\item {} 
constants, hereafter ranged over by letters \(c\), \(d\), etc., are terms.

\item {} 
if \(x\) is a variable and \(T\), \(U\) are terms then
\(∀ x:T,U\) (\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{T}\DUrole{operator}{,} \DUrole{name}{U}}}   in \DUrole{smallcaps}{Coq} concrete syntax) is a term.
If \(x\) occurs in \(U\), \(∀ x:T,U\) reads as
“for all \(x\) of type \(T\), \(U\)”.
As \(U\) depends on \(x\), one says that \(∀ x:T,U\) is
a \sphinxstyleemphasis{dependent product}. If \(x\) does not occur in \(U\) then
\(∀ x:T,U\) reads as
“if \(T\) then \(U\)”. A \sphinxstyleemphasis{non dependent product} can be
written: \(T \rightarrow U\).

\item {} 
if \(x\) is a variable and \(T\), \(u\) are terms then
\(λ x:T . u\) (\sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{T} \DUrole{operator}{=\textgreater{}} \DUrole{name}{u}}}
in \DUrole{smallcaps}{Coq} concrete syntax) is a term. This is a notation for the
\(\lambda\)-abstraction of \(\lambda\)-calculus \sphinxcite{zebibliography:bar81}. The term \(λ x:T . u\) is a function
which maps elements of \(T\) to the expression \(u\).

\item {} 
if \(t\) and \(u\) are terms then \((t~u)\) is a term
(\sphinxcode{\sphinxupquote{\DUrole{name}{t} \DUrole{name}{u}}} in \DUrole{smallcaps}{Coq} concrete
syntax). The term \((t~u)\) reads as “t applied to u”.

\item {} 
if \sphinxcode{\sphinxupquote{\DUrole{name}{x}}} is a variable, and \(t\), \(T\) and \(u\) are
terms then \sphinxcode{\sphinxupquote{\DUrole{keyword}{let} \DUrole{name}{x}\DUrole{operator}{:=}\DUrole{name}{t}\DUrole{operator}{:}\DUrole{name}{T} \DUrole{keyword}{in} \DUrole{name}{u}}} is
a term which denotes the term \(u\) where the variable \(x\) is locally bound
to \(t\) of type \(T\). This stands for the common “let-in” construction of
functional programs such as ML or Scheme.

\end{enumerate}
\phantomsection\label{\detokenize{language/cic:free-variables}}
\sphinxstylestrong{Free variables.}
The notion of free variables is defined as usual. In the expressions
\sphinxcode{\sphinxupquote{\DUrole{operator}{\(\lambda\)}\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{T}\DUrole{operator}{.} \DUrole{name}{U}}} and \sphinxcode{\sphinxupquote{\DUrole{error}{∀} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{T}\DUrole{operator}{,} \DUrole{name}{U}}} the occurrences of \(x\) in \(U\) are bound.

\phantomsection\label{\detokenize{language/cic:substitution}}
\sphinxstylestrong{Substitution.}
The notion of substituting a term \(t\) to free occurrences of a variable
\(x\) in a term \(u\) is defined as usual. The resulting term is written
\(\subst{u}{x}{t}\).

\phantomsection\label{\detokenize{language/cic:the-logical-vs-programming-readings}}
\sphinxstylestrong{The logical vs programming readings.}
The constructions of the \DUrole{smallcaps}{Cic} can be used to express both logical and
programming notions, accordingly to the Curry-Howard correspondence
between proofs and programs, and between propositions and types
\sphinxcite{zebibliography:cur58}\sphinxcite{zebibliography:how80}\sphinxcite{zebibliography:bru72}.

For instance, let us assume that \(\nat\) is the type of natural numbers
with zero element written \(0\) and that \sphinxcode{\sphinxupquote{\DUrole{name}{True}}} is the always true
proposition. Then \(→\) is used both to denote \(\nat→\nat\) which is the type
of functions from \(\nat\) to \(\nat\), to denote True\(\rightarrow\)True which is an
implicative proposition, to denote \(\nat →\Prop\) which is the type of
unary predicates over the natural numbers, etc.

Let us assume that \sphinxcode{\sphinxupquote{mult}} is a function of type \(\nat→\nat→\nat\) and \sphinxcode{\sphinxupquote{eqnat}} a
predicate of type nat\(\rightarrow\)nat\(\rightarrow\) Prop. The \(\lambda\)-abstraction can serve to build
“ordinary” functions as in \(λ x:\nat.(\kw{mult}~x~x)\) (i.e.
\sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{keyword,type}{nat} \DUrole{operator}{=\textgreater{}} \DUrole{name}{mult} \DUrole{name}{x} \DUrole{name}{x}}}
in \DUrole{smallcaps}{Coq} notation) but may build also predicates over the natural
numbers. For instance \(λ x:\nat.(\kw{eqnat}~x~0)\)
(i.e. \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{keyword,type}{nat} \DUrole{operator}{=\textgreater{}} \DUrole{name}{eqnat} \DUrole{name}{x} \DUrole{literal,number,integer}{0}}}
in \DUrole{smallcaps}{Coq} notation) will represent the predicate of one variable \(x\) which
asserts the equality of \(x\) with \(0\). This predicate has type
\(\nat → \Prop\)
and it can be applied to any expression of type \(\nat\), say \(t\), to give an
object \(P~t\) of type \(\Prop\), namely a proposition.

Furthermore \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{keyword,type}{nat}\DUrole{operator}{,} \DUrole{name}{P} \DUrole{name}{x}}} will represent the type of functions
which associate to each natural number \(n\) an object of type \((P~n)\) and
consequently represent the type of proofs of the formula “\(∀ x. P(x\))”.


\subsection{Typing rules}
\label{\detokenize{language/cic:typing-rules}}\label{\detokenize{language/cic:id9}}
As objects of type theory, terms are subjected to \sphinxstyleemphasis{type discipline}.
The well typing of a term depends on a global environment and a local
context.

\phantomsection\label{\detokenize{language/cic:local-context}}
\sphinxstylestrong{Local context.}
A \sphinxstyleemphasis{local context} is an ordered list of \sphinxstyleemphasis{local declarations} of names
which we call \sphinxstyleemphasis{variables}. The declaration of some variable \(x\) is
either a \sphinxstyleemphasis{local assumption}, written \(x:T\) (\(T\) is a type) or a \sphinxstyleemphasis{local
definition}, written \(x:=t:T\). We use brackets to write local contexts.
A typical example is \([x:T;y:=u:U;z:V]\). Notice that the variables
declared in a local context must be distinct. If \(Γ\) is a local context
that declares some \(x\), we
write \(x ∈ Γ\). By writing \((x:T) ∈ Γ\) we mean that either \(x:T\) is an
assumption in \(Γ\) or that there exists some \(t\) such that \(x:=t:T\) is a
definition in \(Γ\). If \(Γ\) defines some \(x:=t:T\), we also write \((x:=t:T) ∈ Γ\).
For the rest of the chapter, \(Γ::(y:T)\) denotes the local context \(Γ\)
enriched with the local assumption \(y:T\). Similarly, \(Γ::(y:=t:T)\) denotes
the local context \(Γ\) enriched with the local definition \((y:=t:T)\). The
notation \([]\) denotes the empty local context. By \(Γ_1 ; Γ_2\) we mean
concatenation of the local context \(Γ_1\) and the local context \(Γ_2\) .

\phantomsection\label{\detokenize{language/cic:global-environment}}
\sphinxstylestrong{Global environment.}
A \sphinxstyleemphasis{global environment} is an ordered list of \sphinxstyleemphasis{global declarations}.
Global declarations are either \sphinxstyleemphasis{global assumptions} or \sphinxstyleemphasis{global
definitions}, but also declarations of inductive objects. Inductive
objects themselves declare both inductive or coinductive types and
constructors (see Section {\hyperref[\detokenize{language/cic:inductive-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Inductive Definitions}}}}).

A \sphinxstyleemphasis{global assumption} will be represented in the global environment as
\((c:T)\) which assumes the name \(c\) to be of some type \(T\). A \sphinxstyleemphasis{global
definition} will be represented in the global environment as \(c:=t:T\)
which defines the name \(c\) to have value \(t\) and type \(T\). We shall call
such names \sphinxstyleemphasis{constants}. For the rest of the chapter, the \(E;c:T\) denotes
the global environment \(E\) enriched with the global assumption \(c:T\).
Similarly, \(E;c:=t:T\) denotes the global environment \(E\) enriched with the
global definition \((c:=t:T)\).

The rules for inductive definitions (see Section
{\hyperref[\detokenize{language/cic:inductive-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Inductive Definitions}}}}) have to be considered as assumption
rules to which the following definitions apply: if the name \(c\)
is declared in \(E\), we write \(c ∈ E\) and if \(c:T\) or
\(c:=t:T\) is declared in \(E\), we write \((c : T) ∈ E\).

\phantomsection\label{\detokenize{language/cic:typing-rules2}}
\sphinxstylestrong{Typing rules.}
In the following, we define simultaneously two judgments. The first
one \(\WTEG{t}{T}\) means the term \(t\) is well-typed and has type \(T\) in the
global environment \(E\) and local context \(Γ\). The second judgment \(\WFE{Γ}\)
means that the global environment \(E\) is well-formed and the local
context \(Γ\) is a valid local context in this global environment.

A term \(t\) is well typed in a global environment \(E\) iff
there exists a local context \(\Gamma\) and a term \(T\) such
that the judgment \(\WTEG{t}{T}\) can be derived from the
following rules.
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-w-empty}}\item[{W-Empty}] \leavevmode \begin{equation*}
\begin{split}\frac{%
%
}{%
\WF{[]}{}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-w-local-assum}}\item[{W-Local-Assum}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WTEG{T}{s}%
\hspace{3em}%
s \in \Sort%
\hspace{3em}%
x \not\in \Gamma % \cup E%
}{%
\WFE{\Gamma::(x:T)}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-w-local-def}}\item[{W-Local-Def}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WTEG{t}{T}%
\hspace{3em}%
x \not\in \Gamma % \cup E%
}{%
\WFE{\Gamma::(x:=t:T)}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-w-global-assum}}\item[{W-Global-Assum}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WTE{}{T}{s}%
\hspace{3em}%
s \in \Sort%
\hspace{3em}%
c \notin E%
}{%
\WF{E;c:T}{}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-w-global-def}}\item[{W-Global-Def}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WTE{}{t}{T}%
\hspace{3em}%
c \notin E%
}{%
\WF{E;c:=t:T}{}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-ax-prop}}\item[{Ax-Prop}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WFE{\Gamma}%
}{%
\WTEG{\Prop}{\Type(1)}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-ax-set}}\item[{Ax-Set}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WFE{\Gamma}%
}{%
\WTEG{\Set}{\Type(1)}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-ax-type}}\item[{Ax-Type}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WFE{\Gamma}%
}{%
\WTEG{\Type(i)}{\Type(i+1)}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-var}}\item[{Var}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WFE{\Gamma}%
\hspace{3em}%
(x:T) \in \Gamma~~\mbox{or}~~(x:=t:T) \in \Gamma~\mbox{for some $t$}%
}{%
\WTEG{x}{T}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-const}}\item[{Const}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WFE{\Gamma}%
\hspace{3em}%
(c:T) \in E~~\mbox{or}~~(c:=t:T) \in E~\mbox{for some $t$}%
}{%
\WTEG{c}{T}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-prod-prop}}\item[{Prod-Prop}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WTEG{T}{s}%
\hspace{3em}%
s \in {\Sort}%
\hspace{3em}%
\WTE{\Gamma::(x:T)}{U}{\Prop}%
}{%
\WTEG{\forall~x:T,U}{\Prop}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-prod-set}}\item[{Prod-Set}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WTEG{T}{s}%
\hspace{3em}%
s \in \{\Prop, \Set\}%
\hspace{3em}%
\WTE{\Gamma::(x:T)}{U}{\Set}%
}{%
\WTEG{\forall~x:T,U}{\Set}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-prod-type}}\item[{Prod-Type}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WTEG{T}{\Type(i)}%
\hspace{3em}%
\WTE{\Gamma::(x:T)}{U}{\Type(i)}%
}{%
\WTEG{\forall~x:T,U}{\Type(i)}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-lam}}\item[{Lam}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WTEG{\forall~x:T,U}{s}%
\hspace{3em}%
\WTE{\Gamma::(x:T)}{t}{U}%
}{%
\WTEG{\lb x:T\mto t}{\forall x:T, U}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-app}}\item[{App}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WTEG{t}{\forall~x:U,T}%
\hspace{3em}%
\WTEG{u}{U}%
}{%
\WTEG{(t\ u)}{\subst{T}{x}{u}}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-let}}\item[{Let}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WTEG{t}{T}%
\hspace{3em}%
\WTE{\Gamma::(x:=t:T)}{u}{U}%
}{%
\WTEG{\letin{x}{t:T}{u}}{\subst{U}{x}{t}}%
}\end{split}
\end{equation*}\end{description}

\begin{sphinxadmonition}{note}{Note:}
\sphinxstylestrong{Prod-Prop} and \sphinxstylestrong{Prod-Set} typing-rules make sense if we consider the
semantic difference between \(\Prop\) and \(\Set\):
\begin{itemize}
\item {} 
All values of a type that has a sort \(\Set\) are extractable.

\item {} 
No values of a type that has a sort \(\Prop\) are extractable.

\end{itemize}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
We may have \(\letin{x}{t:T}{u}\) well-typed without having
\(((λ x:T.u) t)\) well-typed (where \(T\) is a type of
\(t\)). This is because the value \(t\) associated to
\(x\) may be used in a conversion rule
(see Section {\hyperref[\detokenize{language/cic:conversion-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{Conversion rules}}}}).
\end{sphinxadmonition}


\subsection{Conversion rules}
\label{\detokenize{language/cic:conversion-rules}}\label{\detokenize{language/cic:id10}}
In \DUrole{smallcaps}{Cic}, there is an internal reduction mechanism. In particular, it
can decide if two programs are \sphinxstyleemphasis{intentionally} equal (one says
\sphinxstyleemphasis{convertible}). Convertibility is described in this section.


\subsubsection{\(\beta\)-reduction}
\label{\detokenize{language/cic:reduction}}\label{\detokenize{language/cic:beta-reduction}}
We want to be able to identify some terms as we can identify the
application of a function to a given argument with its result. For
instance the identity function over a given type T can be written
\(λx:T. x\). In any global environment \(E\) and local context
\(Γ\), we want to identify any object \(a\) (of type
\(T\)) with the application \(((λ x:T. x) a)\).  We define for
this a \sphinxstyleemphasis{reduction} (or a \sphinxstyleemphasis{conversion}) rule we call \(β\):
\begin{equation*}
\begin{split}E[Γ] ⊢ ((λx:T. t) u)~\triangleright_β~\subst{t}{x}{u}\end{split}
\end{equation*}
We say that \(\subst{t}{x}{u}\) is the \sphinxstyleemphasis{\(\beta\)-contraction} of
\(((λx:T. t) u)\) and, conversely, that \(((λ x:T. t) u)\) is the
\sphinxstyleemphasis{\(\beta\)-expansion} of \(\subst{t}{x}{u}\).

According to \(\beta\)-reduction, terms of the \sphinxstyleemphasis{Calculus of Inductive
Constructions} enjoy some fundamental properties such as confluence,
strong normalization, subject reduction. These results are
theoretically of great importance but we will not detail them here and
refer the interested reader to \sphinxcite{zebibliography:coq85}.


\subsubsection{\(\iota\)-reduction}
\label{\detokenize{language/cic:iota-reduction}}\label{\detokenize{language/cic:id12}}
A specific conversion rule is associated to the inductive objects in
the global environment. We shall give later on (see Section
{\hyperref[\detokenize{language/cic:well-formed-inductive-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Well-formed inductive definitions}}}}) the precise rules but it
just says that a destructor applied to an object built from a
constructor behaves as expected. This reduction is called \(\iota\)-reduction
and is more precisely studied in \sphinxcite{zebibliography:moh93}\sphinxcite{zebibliography:wer94}.


\subsubsection{\(\delta\)-reduction}
\label{\detokenize{language/cic:delta-reduction}}\label{\detokenize{language/cic:id15}}
We may have variables defined in local contexts or constants defined
in the global environment. It is legal to identify such a reference
with its value, that is to expand (or unfold) it into its value. This
reduction is called \(\delta\)-reduction and shows as follows.
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-delta-local}}\item[{Delta-Local}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WFE{\Gamma}%
\hspace{3em}%
(x:=t:T) ∈ Γ%
}{%
E[Γ] ⊢ x~\triangleright_Δ~t%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-delta-global}}\item[{Delta-Global}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WFE{\Gamma}%
\hspace{3em}%
(c:=t:T) ∈ E%
}{%
E[Γ] ⊢ c~\triangleright_δ~t%
}\end{split}
\end{equation*}\end{description}


\subsubsection{\(\zeta\)-reduction}
\label{\detokenize{language/cic:zeta-reduction}}\label{\detokenize{language/cic:id16}}
\DUrole{smallcaps}{Coq} allows also to remove local definitions occurring in terms by
replacing the defined variable by its value. The declaration being
destroyed, this reduction differs from \(\delta\)-reduction. It is called
\(\zeta\)-reduction and shows as follows.
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-zeta}}\item[{Zeta}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WFE{\Gamma}%
\hspace{3em}%
\WTEG{u}{U}%
\hspace{3em}%
\WTE{\Gamma::(x:=u:U)}{t}{T}%
}{%
E[Γ] ⊢ \letin{x}{u}{t}~\triangleright_ζ~\subst{t}{x}{u}%
}\end{split}
\end{equation*}\end{description}


\subsubsection{\(\eta\)-expansion}
\label{\detokenize{language/cic:expansion}}\label{\detokenize{language/cic:eta-expansion}}
Another important concept is \(\eta\)-expansion. It is legal to identify any
term \(t\) of functional type \(∀ x:T, U\) with its so-called \(\eta\)-expansion
\begin{equation*}
\begin{split}λx:T. (t~x)\end{split}
\end{equation*}
for \(x\) an arbitrary variable name fresh in \(t\).

\begin{sphinxadmonition}{note}{Note:}
We deliberately do not define \(\eta\)-reduction:
\begin{equation*}
\begin{split}λ x:T. (t~x) \not\triangleright_η t\end{split}
\end{equation*}
This is because, in general, the type of \(t\) need not to be convertible
to the type of \(λ x:T. (t~x)\). E.g., if we take \(f\) such that:
\begin{equation*}
\begin{split}f : ∀ x:\Type(2),\Type(1)\end{split}
\end{equation*}
then
\begin{equation*}
\begin{split}λ x:\Type(1),(f~x) : ∀ x:\Type(1),\Type(1)\end{split}
\end{equation*}
We could not allow
\begin{equation*}
\begin{split}λ x:Type(1),(f x) \triangleright_η f\end{split}
\end{equation*}
because the type of the reduced term \(∀ x:\Type(2),\Type(1)\) would not be
convertible to the type of the original term \(∀ x:\Type(1),\Type(1).\)
\end{sphinxadmonition}


\subsubsection{Convertibility}
\label{\detokenize{language/cic:convertibility}}\label{\detokenize{language/cic:id17}}
Let us write \(E[Γ] ⊢ t \triangleright u\) for the contextual closure of the
relation \(t\) reduces to \(u\) in the global environment
\(E\) and local context \(Γ\) with one of the previous
reductions \(\beta\), \(\iota\), \(\delta\) or \(\zeta\).

We say that two terms \(t_1\) and \(t_2\) are
\sphinxstyleemphasis{\(\beta\)\(\iota\)\(\delta\)\(\zeta\)\(\eta\)-convertible}, or simply \sphinxstyleemphasis{convertible}, or \sphinxstyleemphasis{equivalent}, in the
global environment \(E\) and local context \(Γ\) iff there
exist terms \(u_1\) and \(u_2\) such that \(E[Γ] ⊢ t_1 \triangleright
… \triangleright u_1\) and \(E[Γ] ⊢ t_2 \triangleright … \triangleright u_2\) and either \(u_1\) and
\(u_2\) are identical, or they are convertible up to \(\eta\)-expansion,
i.e. \(u_1\) is \(λ x:T. u_1'\) and \(u_2 x\) is
recursively convertible to \(u_1'\) , or, symmetrically,
\(u_2\) is \(λx:T. u_2'\)
and \(u_1 x\) is recursively convertible to u\_2′ . We then write
\(E[Γ] ⊢ t_1 =_{βδιζη} t_2\) .

Apart from this we consider two instances of polymorphic and
cumulative (see Chapter {\hyperref[\detokenize{addendum/universe-polymorphism:polymorphicuniverses}]{\sphinxcrossref{\DUrole{std,std-ref}{Polymorphic Universes}}}}) inductive types
(see below) convertible
\begin{equation*}
\begin{split}E[Γ] ⊢ t~w_1 … w_m =_{βδιζη} t~w_1' … w_m'\end{split}
\end{equation*}
if we have subtypings (see below) in both directions, i.e.,
\begin{equation*}
\begin{split}E[Γ] ⊢ t~w_1 … w_m ≤_{βδιζη} t~w_1' … w_m'\end{split}
\end{equation*}
and
\begin{equation*}
\begin{split}E[Γ] ⊢ t~w_1' … w_m' ≤_{βδιζη} t~w_1 … w_m.\end{split}
\end{equation*}
Furthermore, we consider
\begin{equation*}
\begin{split}E[Γ] ⊢ c~v_1 … v_m =_{βδιζη} c'~v_1' … v_m'\end{split}
\end{equation*}
convertible if
\begin{equation*}
\begin{split}E[Γ] ⊢ v_i =_{βδιζη} v_i'\end{split}
\end{equation*}
and we have that \(c\) and \(c'\)
are the same constructors of different instances of the same inductive
types (differing only in universe levels) such that
\begin{equation*}
\begin{split}E[Γ] ⊢ c~v_1 … v_m : t~w_1 … w_m\end{split}
\end{equation*}
and
\begin{equation*}
\begin{split}E[Γ] ⊢ c'~v_1' … v_m' : t'~ w_1' … w_m '\end{split}
\end{equation*}
and we have
\begin{equation*}
\begin{split}E[Γ] ⊢ t~w_1 … w_m =_{βδιζη} t~w_1' … w_m'.\end{split}
\end{equation*}
The convertibility relation allows introducing a new typing rule which
says that two convertible well-formed types have the same inhabitants.


\subsection{Subtyping rules}
\label{\detokenize{language/cic:subtyping-rules}}\label{\detokenize{language/cic:id18}}
At the moment, we did not take into account one rule between universes
which says that any term in a universe of index i is also a term in
the universe of index i+1 (this is the \sphinxstyleemphasis{cumulativity} rule of \DUrole{smallcaps}{Cic}).
This property extends the equivalence relation of convertibility into
a \sphinxstyleemphasis{subtyping} relation inductively defined by:
\begin{enumerate}
\def\theenumi{\arabic{enumi}}
\def\labelenumi{\theenumi .}
\makeatletter\def\p@enumii{\p@enumi \theenumi .}\makeatother
\item {} 
if \(E[Γ] ⊢ t =_{βδιζη} u\) then \(E[Γ] ⊢ t ≤_{βδιζη} u\),

\item {} 
if \(i ≤ j\) then \(E[Γ] ⊢ \Type(i) ≤_{βδιζη} \Type(j)\),

\item {} 
for any \(i\), \(E[Γ] ⊢ \Set ≤_{βδιζη} \Type(i)\),

\item {} 
\(E[Γ] ⊢ \Prop ≤_{βδιζη} \Set\), hence, by transitivity,
\(E[Γ] ⊢ \Prop ≤_{βδιζη} \Type(i)\), for any \(i\)

\item {} 
if \(E[Γ] ⊢ T =_{βδιζη} U\) and
\(E[Γ::(x:T)] ⊢ T' ≤_{βδιζη} U'\) then
\(E[Γ] ⊢ ∀x:T, T′ ≤_{βδιζη} ∀ x:U, U′\).

\item {} 
if \(\ind{p}{Γ_I}{Γ_C}\) is a universe polymorphic and cumulative
(see Chapter {\hyperref[\detokenize{addendum/universe-polymorphism:polymorphicuniverses}]{\sphinxcrossref{\DUrole{std,std-ref}{Polymorphic Universes}}}}) inductive type (see below)
and
\((t : ∀Γ_P ,∀Γ_{\mathit{Arr}(t)}, \Sort)∈Γ_I\)
and
\((t' : ∀Γ_P' ,∀Γ_{\mathit{Arr}(t)}', \Sort')∈Γ_I\)
are two different instances of \sphinxstyleemphasis{the same} inductive type (differing only in
universe levels) with constructors
\begin{equation*}
\begin{split}[c_1 : ∀Γ_P ,∀ T_{1,1} … T_{1,n_1} , t~v_{1,1} … v_{1,m} ;…;
c_k : ∀Γ_P ,∀ T_{k,1} … T_{k,n_k} ,t~v_{n,1} … v_{n,m} ]\end{split}
\end{equation*}
and
\begin{equation*}
\begin{split}[c_1 : ∀Γ_P' ,∀ T_{1,1}' … T_{1,n_1}' , t'~v_{1,1}' … v_{1,m}' ;…;
c_k : ∀Γ_P' ,∀ T_{k,1}' … T_{k,n_k}' ,t'~v_{n,1}' … v_{n,m}' ]\end{split}
\end{equation*}
respectively then
\begin{equation*}
\begin{split}E[Γ] ⊢ t~w_1 … w_m ≤_{βδιζη} t'~w_1' … w_m'\end{split}
\end{equation*}
(notice that \(t\) and \(t'\) are both
fully applied, i.e., they have a sort as a type) if
\begin{equation*}
\begin{split}E[Γ] ⊢ w_i =_{βδιζη} w_i'\end{split}
\end{equation*}
for \(1 ≤ i ≤ m\) and we have
\begin{equation*}
\begin{split}E[Γ] ⊢ T_{i,j} ≤_{βδιζη} T_{i,j}'\end{split}
\end{equation*}
and
\begin{equation*}
\begin{split}E[Γ] ⊢ A_i ≤_{βδιζη} A_i'\end{split}
\end{equation*}
where \(Γ_{\mathit{Arr}(t)} = [a_1 : A_1 ;  … ; a_l : A_l ]\) and
\(Γ_{\mathit{Arr}(t)}' = [a_1 : A_1';  … ; a_l : A_l']\).

\end{enumerate}

The conversion rule up to subtyping is now exactly:
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-conv}}\item[{Conv}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[Γ] ⊢ U : s%
\hspace{3em}%
E[Γ] ⊢ t : T%
\hspace{3em}%
E[Γ] ⊢ T ≤_{βδιζη} U%
}{%
E[Γ] ⊢ t : U%
}\end{split}
\end{equation*}\end{description}
\phantomsection\label{\detokenize{language/cic:normal-form}}
\sphinxstylestrong{Normal form}. A term which cannot be any more reduced is said to be in \sphinxstyleemphasis{normal
form}. There are several ways (or strategies) to apply the reduction
rules. Among them, we have to mention the \sphinxstyleemphasis{head reduction} which will
play an important role (see Chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}}). Any term \(t\) can be written as
\(λ x_1 :T_1 . … λ x_k :T_k . (t_0~t_1 … t_n )\) where \(t_0\) is not an
application. We say then that \(t~0\) is the \sphinxstyleemphasis{head of} \(t\). If we assume
that \(t_0\) is \(λ x:T. u_0\) then one step of \(\beta\)-head reduction of \(t\) is:
\begin{equation*}
\begin{split}λ x_1 :T_1 . … λ x_k :T_k . (λ x:T. u_0~t_1 … t_n ) \triangleright
λ (x_1 :T_1 )…(x_k :T_k ). (\subst{u_0}{x}{t_1}~t_2 … t_n )\end{split}
\end{equation*}
Iterating the process of head reduction until the head of the reduced
term is no more an abstraction leads to the \sphinxstyleemphasis{\(\beta\)-head normal form} of \(t\):
\begin{equation*}
\begin{split}t \triangleright … \triangleright λ x_1 :T_1 . …λ x_k :T_k . (v~u_1 … u_m )\end{split}
\end{equation*}
where \(v\) is not an abstraction (nor an application). Note that the head
normal form must not be confused with the normal form since some \(u_i\)
can be reducible. Similar notions of head-normal forms involving \(\delta\), \(\iota\)
and \(\zeta\) reductions or any combination of those can also be defined.


\subsection{Inductive Definitions}
\label{\detokenize{language/cic:inductive-definitions}}\label{\detokenize{language/cic:id19}}
Formally, we can represent any \sphinxstyleemphasis{inductive definition} as
\(\ind{p}{Γ_I}{Γ_C}\) where:
\begin{itemize}
\item {} 
\(Γ_I\) determines the names and types of inductive types;

\item {} 
\(Γ_C\) determines the names and types of constructors of these
inductive types;

\item {} 
\(p\) determines the number of parameters of these inductive types.

\end{itemize}

These inductive definitions, together with global assumptions and
global definitions, then form the global environment. Additionally,
for any \(p\) there always exists \(Γ_P =[a_1 :A_1 ;…;a_p :A_p ]\) such that
each \(T\) in \((t:T)∈Γ_I \cup Γ_C\) can be written as: \(∀Γ_P , T'\) where \(Γ_P\) is
called the \sphinxstyleemphasis{context of parameters}. Furthermore, we must have that
each \(T\) in \((t:T)∈Γ_I\) can be written as: \(∀Γ_P,∀Γ_{\mathit{Arr}(t)}, S\) where
\(Γ_{\mathit{Arr}(t)}\) is called the \sphinxstyleemphasis{Arity} of the inductive type t and \(S\) is called
the sort of the inductive type t (not to be confused with \(\Sort\) which is the set of sorts).

\begin{sphinxadmonition}{note}{Example}

The declaration for parameterized lists is:
\begin{equation*}
\begin{split}\ind{1}{[\List:\Set→\Set]}{\left[\begin{array}{rcl}
\Nil & : & \forall A:\Set,\List~A \\
\cons & : & \forall A:\Set, A→ \List~A→ \List~A
\end{array}
\right]}\end{split}
\end{equation*}
which corresponds to the result of the \DUrole{smallcaps}{Coq} declaration:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{k+kt}{list} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

The declaration for a mutual inductive definition of tree and forest
is:
\begin{equation*}
\begin{split}\ind{0}{\left[\begin{array}{rcl}\tree&:&\Set\\\forest&:&\Set\end{array}\right]}
 {\left[\begin{array}{rcl}
          \node &:& \forest → \tree\\
          \emptyf &:& \forest\\
          \consf &:& \tree → \forest → \forest\\
                    \end{array}\right]}\end{split}
\end{equation*}
which corresponds to the result of the \DUrole{smallcaps}{Coq} declaration:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{tree} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{node} \PYG{o}{:} \PYG{n}{forest} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{tree}
\PYG{k}{with} \PYG{n}{forest} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{emptyf} \PYG{o}{:} \PYG{n}{forest}
\PYG{o}{\textbar{}} \PYG{n}{consf} \PYG{o}{:} \PYG{n}{tree} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

The declaration for a mutual inductive definition of even and odd is:
\begin{equation*}
\begin{split}\ind{0}{\left[\begin{array}{rcl}\even&:&\nat → \Prop \\
                                \odd&:&\nat → \Prop \end{array}\right]}
 {\left[\begin{array}{rcl}
          \evenO &:& \even~0\\
          \evenS &:& \forall n, \odd~n -> \even~(\kw{S}~n)\\
          \oddS &:& \forall n, \even~n -> \odd~(\kw{S}~n)
                    \end{array}\right]}\end{split}
\end{equation*}
which corresponds to the result of the \DUrole{smallcaps}{Coq} declaration:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{even} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{even\PYGZus{}O} \PYG{o}{:} \PYG{n}{even} \PYG{l+m+mi}{0}
\PYG{o}{\textbar{}} \PYG{n}{even\PYGZus{}S} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{,} \PYG{n}{odd} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{even} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}
\PYG{k}{with} \PYG{n}{odd} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{prop} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{odd\PYGZus{}S} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{,} \PYG{n}{even} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{odd} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Types of inductive objects}
\label{\detokenize{language/cic:types-of-inductive-objects}}\label{\detokenize{language/cic:id20}}
We have to give the type of constants in a global environment E which
contains an inductive declaration.
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-ind}}\item[{Ind}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WFE{Γ}%
\hspace{3em}%
\ind{p}{Γ_I}{Γ_C} ∈ E%
\hspace{3em}%
(a:A)∈Γ_I%
}{%
E[Γ] ⊢ a : A%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-constr}}\item[{Constr}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WFE{Γ}%
\hspace{3em}%
\ind{p}{Γ_I}{Γ_C} ∈ E%
\hspace{3em}%
(c:C)∈Γ_C%
}{%
E[Γ] ⊢ c : C%
}\end{split}
\end{equation*}\end{description}

\begin{sphinxadmonition}{note}{Example}

Provided that our environment \(E\) contains inductive definitions we showed before,
these two inference rules above enable us to conclude that:
\begin{equation*}
\begin{split}\begin{array}{l}
E[Γ] ⊢ \even : \nat→\Prop\\
E[Γ] ⊢ \odd : \nat→\Prop\\
E[Γ] ⊢ \even\_O : \even~O\\
E[Γ] ⊢ \even\_S : \forall~n:\nat, \odd~n → \even~(S~n)\\
E[Γ] ⊢ \odd\_S : \forall~n:\nat, \even~n → \odd~(S~n)
\end{array}\end{split}
\end{equation*}\end{sphinxadmonition}


\subsubsection{Well-formed inductive definitions}
\label{\detokenize{language/cic:well-formed-inductive-definitions}}\label{\detokenize{language/cic:id21}}
We cannot accept any inductive declaration because some of them lead
to inconsistent systems. We restrict ourselves to definitions which
satisfy a syntactic criterion of positivity. Before giving the formal
rules, we need a few definitions:


\paragraph{Arity of a given sort}
\label{\detokenize{language/cic:arity-of-a-given-sort}}
A type \(T\) is an \sphinxstyleemphasis{arity of sort} \(s\) if it converts to the sort \(s\) or to a
product \(∀ x:T,U\) with \(U\) an arity of sort \(s\).

\begin{sphinxadmonition}{note}{Example}

\(A→\Set\) is an arity of sort \(\Set\). \(∀ A:\Prop,A→ \Prop\) is an arity of sort
\(\Prop\).
\end{sphinxadmonition}


\paragraph{Arity}
\label{\detokenize{language/cic:arity}}
A type \(T\) is an \sphinxstyleemphasis{arity} if there is a \(s∈ \Sort\) such that \(T\) is an arity of
sort \(s\).

\begin{sphinxadmonition}{note}{Example}

\(A→ Set\) and \(∀ A:\Prop,A→ \Prop\) are arities.
\end{sphinxadmonition}


\paragraph{Type constructor}
\label{\detokenize{language/cic:type-constructor}}
We say that T is a \sphinxstyleemphasis{type of constructor of I} in one of the following
two cases:
\begin{itemize}
\item {} 
\(T\) is \((I~t_1 … t_n )\)

\item {} 
\(T\) is \(∀ x:U,T'\) where \(T'\) is also a type of constructor of \(I\)

\end{itemize}

\begin{sphinxadmonition}{note}{Example}

\(\nat\) and \(\nat→\nat\) are types of constructor of \(\nat\).
\(∀ A:Type,\List~A\) and \(∀ A:Type,A→\List~A→\List~A\) are types of constructor of \(\List\).
\end{sphinxadmonition}


\paragraph{Positivity Condition}
\label{\detokenize{language/cic:positivity-condition}}\label{\detokenize{language/cic:positivity}}
The type of constructor \(T\) will be said to \sphinxstyleemphasis{satisfy the positivity
condition} for a constant \(X\) in the following cases:
\begin{itemize}
\item {} 
\(T=(X~t_1 … t_n )\) and \(X\) does not occur free in any \(t_i\)

\item {} 
\(T=∀ x:U,V\) and \(X\) occurs only strictly positively in \(U\) and the type \(V\)
satisfies the positivity condition for \(X\).

\end{itemize}


\paragraph{Strict positivity}
\label{\detokenize{language/cic:strict-positivity}}
The constant \(X\) \sphinxstyleemphasis{occurs strictly positively} in \(T\) in the following
cases:
\begin{itemize}
\item {} 
\(X\) does not occur in \(T\)

\item {} 
\(T\) converts to \((X~t_1 … t_n )\) and \(X\) does not occur in any of \(t_i\)

\item {} 
\(T\) converts to \(∀ x:U,V\) and \(X\) does not occur in type \(U\) but occurs
strictly positively in type \(V\)

\item {} 
\(T\) converts to \((I~a_1 … a_m~t_1 … t_p )\) where \(I\) is the name of an
inductive declaration of the form
\begin{equation*}
\begin{split}\ind{m}{I:A}{c_1 :∀ p_1 :P_1 ,… ∀p_m :P_m ,C_1 ;…;c_n :∀ p_1 :P_1 ,… ∀p_m :P_m ,C_n}\end{split}
\end{equation*}
(in particular, it is
not mutually defined and it has \(m\) parameters) and \(X\) does not occur in
any of the \(t_i\), and the (instantiated) types of constructor
\(\subst{C_i}{p_j}{a_j}_{j=1… m}\) of \(I\) satisfy the nested positivity condition for \(X\)

\end{itemize}


\paragraph{Nested Positivity}
\label{\detokenize{language/cic:nested-positivity}}
The type of constructor \(T\) of \(I\) \sphinxstyleemphasis{satisfies the nested positivity
condition} for a constant \(X\) in the following cases:
\begin{itemize}
\item {} 
\(T=(I~b_1 … b_m~u_1 … u_p)\), \(I\) is an inductive definition with \(m\)
parameters and \(X\) does not occur in any \(u_i\)

\item {} 
\(T=∀ x:U,V\) and \(X\) occurs only strictly positively in \(U\) and the type \(V\)
satisfies the nested positivity condition for \(X\)

\end{itemize}

\begin{sphinxadmonition}{note}{Example}

For instance, if one considers the following variant of a tree type
branching over the natural numbers:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{nattree} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{leaf} \PYG{o}{:} \PYG{n}{nattree} \PYG{n}{A}
\PYG{o}{\textbar{}} \PYG{n}{node} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nattree} \PYG{n}{A}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{nattree} \PYG{n}{A}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{TreeExample}\PYG{o}{.}
\end{sphinxVerbatim}

Then every instantiated constructor of \sphinxcode{\sphinxupquote{nattree A}} satisfies the nested positivity
condition for \sphinxcode{\sphinxupquote{nattree}}:
\begin{itemize}
\item {} 
Type \sphinxcode{\sphinxupquote{nattree A}} of constructor \sphinxcode{\sphinxupquote{leaf}} satisfies the positivity condition for
\sphinxcode{\sphinxupquote{nattree}} because \sphinxcode{\sphinxupquote{nattree}} does not appear in any (real) arguments of the
type of that constructor (primarily because \sphinxcode{\sphinxupquote{nattree}} does not have any (real)
arguments) ... (bullet 1)

\item {} 
Type \sphinxcode{\sphinxupquote{A \(\rightarrow\) (nat \(\rightarrow\) nattree A) \(\rightarrow\) nattree A}} of constructor \sphinxcode{\sphinxupquote{node}} satisfies the
positivity condition for \sphinxcode{\sphinxupquote{nattree}} because:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{nattree}} occurs only strictly positively in \sphinxcode{\sphinxupquote{A}} ... (bullet 3)

\item {} 
\sphinxcode{\sphinxupquote{nattree}} occurs only strictly positively in \sphinxcode{\sphinxupquote{nat \(\rightarrow\) nattree A}} ... (bullet 3 + 2)

\item {} 
\sphinxcode{\sphinxupquote{nattree}} satisfies the positivity condition for \sphinxcode{\sphinxupquote{nattree A}} ... (bullet 1)

\end{itemize}

\end{itemize}
\end{sphinxadmonition}


\paragraph{Correctness rules}
\label{\detokenize{language/cic:correctness-rules}}\label{\detokenize{language/cic:id22}}
We shall now describe the rules allowing the introduction of a new
inductive definition.

Let \(E\) be a global environment and \(Γ_P\), \(Γ_I\), \(Γ_C\) be contexts
such that \(Γ_I\) is \([I_1 :∀ Γ_P ,A_1 ;…;I_k :∀ Γ_P ,A_k]\), and
\(Γ_C\) is \([c_1:∀ Γ_P ,C_1 ;…;c_n :∀ Γ_P ,C_n ]\). Then
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-w-ind}}\item[{W-Ind}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WFE{Γ_P}%
\hspace{3em}%
(E[Γ_P ] ⊢ A_j : s_j )_{j=1… k}%
\hspace{3em}%
(E[Γ_I ;Γ_P ] ⊢ C_i : s_{q_i} )_{i=1… n}%
}{%
\WF{E;\ind{p}{Γ_I}{Γ_C}}{Γ}%
}\end{split}
\end{equation*}\end{description}

provided that the following side conditions hold:
\begin{itemize}
\item {} 
\(k>0\) and all of \(I_j\) and \(c_i\) are distinct names for \(j=1… k\) and \(i=1… n\),

\item {} 
\(p\) is the number of parameters of \(\ind{p}{Γ_I}{Γ_C}\) and \(Γ_P\) is the
context of parameters,

\item {} 
for \(j=1… k\) we have that \(A_j\) is an arity of sort \(s_j\) and \(I_j ∉ E\),

\item {} 
for \(i=1… n\) we have that \(C_i\) is a type of constructor of \(I_{q_i}\) which
satisfies the positivity condition for \(I_1 … I_k\) and \(c_i ∉ Γ ∪ E\).

\end{itemize}

One can remark that there is a constraint between the sort of the
arity of the inductive type and the sort of the type of its
constructors which will always be satisfied for the impredicative
sort \(\Prop\) but may fail to define inductive definition on sort \(\Set\) and
generate constraints between universes for inductive definitions in
the Type hierarchy.

\begin{sphinxadmonition}{note}{Example}

It is well known that the existential quantifier can be encoded as an
inductive definition. The following declaration introduces the second-
order existential quantifier \(∃ X.P(X)\).

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{exProp} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{exP\PYGZus{}intro} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{X}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{P} \PYG{n}{X} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{exProp} \PYG{n}{P}\PYG{o}{.}
\end{sphinxVerbatim}

The same definition on \(\Set\) is not allowed and fails:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Inductive} \PYG{n}{exSet} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{n}{exS\PYGZus{}intro} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{X}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{,} \PYG{n}{P} \PYG{n}{X} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{exSet} \PYG{n}{P}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{Large} \PYG{n}{non}\PYG{o}{\PYGZhy{}}\PYG{n}{propositional} \PYG{n}{inductive} \PYG{n}{types} \PYG{n}{must} \PYG{n}{be} \PYG{k}{in} \PYG{k+kt}{Type}\PYG{o}{.}
\end{sphinxVerbatim}

It is possible to declare the same inductive definition in the
universe \(\Type\). The \sphinxcode{\sphinxupquote{\DUrole{name}{exType}}} inductive definition has type
\((\Type(i)→\Prop)→\Type(j)\) with the constraint that the parameter \(X\) of \(\kw{exT}_{\kw{intro}}\)
has type \(\Type(k)\) with \(k<j\) and \(k≤ i\).

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{exType} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
\PYG{n}{exT\PYGZus{}intro} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{X}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{,} \PYG{n}{P} \PYG{n}{X} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{exType} \PYG{n}{P}\PYG{o}{.}
    \PYG{n}{exType} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{exType\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{exType\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{exType\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Template polymorphism}
\label{\detokenize{language/cic:template-polymorphism}}\label{\detokenize{language/cic:id23}}
Inductive types declared in \(\Type\) are polymorphic over their arguments
in \(\Type\). If \(A\) is an arity of some sort and \(s\) is a sort, we write \(A_{/s}\)
for the arity obtained from \(A\) by replacing its sort with \(s\).
Especially, if \(A\) is well-typed in some global environment and local
context, then \(A_{/s}\) is typable by typability of all products in the
Calculus of Inductive Constructions. The following typing rule is
added to the theory.

Let \(\ind{p}{Γ_I}{Γ_C}\) be an inductive definition. Let
\(Γ_P = [p_1 :P_1 ;…;p_p :P_p ]\) be its context of parameters,
\(Γ_I = [I_1:∀ Γ_P ,A_1 ;…;I_k :∀ Γ_P ,A_k ]\) its context of definitions and
\(Γ_C = [c_1 :∀ Γ_P ,C_1 ;…;c_n :∀ Γ_P ,C_n]\) its context of constructors,
with \(c_i\) a constructor of \(I_{q_i}\). Let \(m ≤ p\) be the length of the
longest prefix of parameters such that the \(m\) first arguments of all
occurrences of all \(I_j\) in all \(C_k\) (even the occurrences in the
hypotheses of \(C_k\)) are exactly applied to \(p_1 … p_m\) (\(m\) is the number
of \sphinxstyleemphasis{recursively uniform parameters} and the \(p−m\) remaining parameters
are the \sphinxstyleemphasis{recursively non-uniform parameters}). Let \(q_1 , …, q_r\) , with
\(0≤ r≤ m\), be a (possibly) partial instantiation of the recursively
uniform parameters of \(Γ_P\) . We have:
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-ind-family}}\item[{Ind-Family}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\left\{\begin{array}{l}%
\hspace{3em}%
\ind{p}{Γ_I}{Γ_C} \in E\\%
\hspace{3em}%
(E[]  ⊢ q_l : P'_l)_{l=1\ldots r}\\%
\hspace{3em}%
(E[]  ⊢ P'_l ≤_{βδιζη} \subst{P_l}{p_u}{q_u}_{u=1\ldots l-1})_{l=1\ldots r}\\%
\hspace{3em}%
1 \leq j \leq k%
\hspace{3em}%
\end{array}%
\hspace{3em}%
\right.%
}{%
E[] ⊢ I_j~q_1 … q_r :∀ [p_{r+1} :P_{r+1} ;…;p_p :P_p], (A_j)_{/s_j}%
}\end{split}
\end{equation*}\end{description}

provided that the following side conditions hold:
\begin{itemize}
\item {} 
\(Γ_{P′}\) is the context obtained from \(Γ_P\) by replacing each \(P_l\) that is
an arity with \(P_l'\) for \(1≤ l ≤ r\) (notice that \(P_l\) arity implies \(P_l'\)
arity since \((E[] ⊢ P_l' ≤_{βδιζη} \subst{P_l}{p_u}{q_u}_{u=1\ldots l-1} )\);

\item {} 
there are sorts \(s_i\) , for \(1 ≤ i ≤ k\) such that, for
\(Γ_{I'} = [I_1 :∀ Γ_{P'} ,(A_1)_{/s_1} ;…;I_k :∀ Γ_{P'} ,(A_k)_{/s_k}]\)
we have \((E[Γ_{I′} ;Γ_{P′}] ⊢ C_i : s_{q_i})_{i=1… n}\) ;

\item {} 
the sorts \(s_i\) are such that all eliminations, to
\(\Prop\), \(\Set\) and \(\Type(j)\), are allowed
(see Section {\hyperref[\detokenize{language/cic:destructors}]{\sphinxcrossref{\DUrole{std,std-ref}{Destructors}}}}).

\end{itemize}

Notice that if \(I_j~q_1 … q_r\) is typable using the rules \sphinxstylestrong{Ind-Const} and
\sphinxstylestrong{App}, then it is typable using the rule \sphinxstylestrong{Ind-Family}. Conversely, the
extended theory is not stronger than the theory without \sphinxstylestrong{Ind-Family}. We
get an equiconsistency result by mapping each \(\ind{p}{Γ_I}{Γ_C}\)
occurring into a given derivation into as many different inductive
types and constructors as the number of different (partial)
replacements of sorts, needed for this derivation, in the parameters
that are arities (this is possible because \(\ind{p}{Γ_I}{Γ_C}\) well-formed
implies that \(\ind{p}{Γ_{I'}}{Γ_{C'}}\) is well-formed and has the
same allowed eliminations, where \(Γ_{I′}\) is defined as above and
\(Γ_{C′} = [c_1 :∀ Γ_{P′} ,C_1 ;…;c_n :∀ Γ_{P′} ,C_n ]\)). That is, the changes in the
types of each partial instance \(q_1 … q_r\) can be characterized by the
ordered sets of arity sorts among the types of parameters, and to each
signature is associated a new inductive definition with fresh names.
Conversion is preserved as any (partial) instance \(I_j~q_1 … q_r\) or
\(C_i~q_1 … q_r\) is mapped to the names chosen in the specific instance of
\(\ind{p}{Γ_I}{Γ_C}\).

In practice, the rule \sphinxstylestrong{Ind-Family} is used by \DUrole{smallcaps}{Coq} only when all the
inductive types of the inductive definition are declared with an arity
whose sort is in the Type hierarchy. Then, the polymorphism is over
the parameters whose type is an arity of sort in the Type hierarchy.
The sorts \(s_j\) are chosen canonically so that each \(s_j\) is minimal with
respect to the hierarchy \(\Prop ⊂ \Set_p ⊂ \Type\) where \(\Set_p\) is predicative
\(\Set\). More precisely, an empty or small singleton inductive definition
(i.e. an inductive definition of which all inductive types are
singleton \textendash{} see Section {\hyperref[\detokenize{language/cic:destructors}]{\sphinxcrossref{\DUrole{std,std-ref}{Destructors}}}}) is set in \(\Prop\), a small non-singleton
inductive type is set in \(\Set\) (even in case \(\Set\) is impredicative \textendash{} see
Section {\hyperref[\detokenize{language/cic:the-calculus-of-inductive-construction-with-impredicative-set}]{\sphinxcrossref{The-Calculus-of-Inductive-Construction-with-impredicative-Set}}}),
and otherwise in the Type hierarchy.

Note that the side-condition about allowed elimination sorts in the
rule \sphinxstylestrong{Ind-Family} is just to avoid to recompute the allowed elimination
sorts at each instance of a pattern matching (see Section {\hyperref[\detokenize{language/cic:destructors}]{\sphinxcrossref{\DUrole{std,std-ref}{Destructors}}}}). As
an example, let us consider the following definition:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{option} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{None} \PYG{o}{:} \PYG{n}{option} \PYG{n}{A}
\PYG{o}{\textbar{}} \PYG{n}{Some} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{option} \PYG{n}{A}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

As the definition is set in the Type hierarchy, it is used
polymorphically over its parameters whose types are arities of a sort
in the Type hierarchy. Here, the parameter \(A\) has this property, hence,
if \sphinxcode{\sphinxupquote{\DUrole{name}{option}}} is applied to a type in \(\Set\), the result is in \(\Set\). Note that
if \sphinxcode{\sphinxupquote{\DUrole{name}{option}}} is applied to a type in \(\Prop\), then, the result is not set in
\(\Prop\) but in \(\Set\) still. This is because \sphinxcode{\sphinxupquote{\DUrole{name}{option}}} is not a singleton type
(see Section {\hyperref[\detokenize{language/cic:destructors}]{\sphinxcrossref{\DUrole{std,std-ref}{Destructors}}}}) and it would lose the elimination to \(\Set\) and \(\Type\)
if set in \(\Prop\).

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set} \PYG{o}{=\PYGZgt{}} \PYG{n}{option} \PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{=\PYGZgt{}} \PYG{n}{option} \PYG{n}{A}
         \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Prop} \PYG{o}{=\PYGZgt{}} \PYG{n}{option} \PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{=\PYGZgt{}} \PYG{n}{option} \PYG{n}{A}
         \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Here is another example.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{prod} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=} \PYG{n}{pair} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{prod} \PYG{n}{A} \PYG{n}{B}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

As \sphinxcode{\sphinxupquote{\DUrole{name}{prod}}} is a singleton type, it will be in \(\Prop\) if applied twice to
propositions, in \(\Set\) if applied twice to at least one type in \(\Set\) and
none in \(\Type\), and in \(\Type\) otherwise. In all cases, the three kind of
eliminations schemes are allowed.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set} \PYG{o}{=\PYGZgt{}} \PYG{n}{prod} \PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{=\PYGZgt{}} \PYG{n}{prod} \PYG{n}{A}
         \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Prop} \PYG{o}{=\PYGZgt{}} \PYG{n}{prod} \PYG{n}{A} \PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{=\PYGZgt{}} \PYG{n}{prod} \PYG{n}{A} \PYG{n}{A}
         \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{B}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{prod} \PYG{n}{A} \PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{B} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{prod} \PYG{n}{A} \PYG{n}{B}
         \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{B}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{prod} \PYG{n}{A} \PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{prod} \PYG{n}{A} \PYG{n}{B}
         \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
Template polymorphism used to be called “sort-polymorphism of
inductive types” before universe polymorphism
(see Chapter {\hyperref[\detokenize{addendum/universe-polymorphism:polymorphicuniverses}]{\sphinxcrossref{\DUrole{std,std-ref}{Polymorphic Universes}}}}) was introduced.
\end{sphinxadmonition}


\subsubsection{Destructors}
\label{\detokenize{language/cic:destructors}}\label{\detokenize{language/cic:id24}}
The specification of inductive definitions with arities and
constructors is quite natural. But we still have to say how to use an
object in an inductive type.

This problem is rather delicate. There are actually several different
ways to do that. Some of them are logically equivalent but not always
equivalent from the computational point of view or from the user point
of view.

From the computational point of view, we want to be able to define a
function whose domain is an inductively defined type by using a
combination of case analysis over the possible constructors of the
object and recursion.

Because we need to keep a consistent theory and also we prefer to keep
a strongly normalizing reduction, we cannot accept any sort of
recursion (even terminating). So the basic idea is to restrict
ourselves to primitive recursive functions and functionals.

For instance, assuming a parameter \sphinxcode{\sphinxupquote{\DUrole{name}{A}\DUrole{operator}{:}\DUrole{keyword,namespace}{Set}}} exists in the local context,
we want to build a function length of type \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{list} \DUrole{name}{A} \DUrole{operator}{-\textgreater{}} \DUrole{keyword,type}{nat}}} which computes
the length of the list, such that \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{length} \DUrole{operator}{(}\DUrole{name}{nil} \DUrole{name}{A}\DUrole{operator}{))} \DUrole{operator}{=} \DUrole{name}{O}}} and \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{length}
\DUrole{operator}{(}\DUrole{name}{cons} \DUrole{name}{A} \DUrole{name}{a} \DUrole{name}{l}\DUrole{operator}{))} \DUrole{operator}{=} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{operator}{(}\DUrole{name}{length} \DUrole{name}{l}\DUrole{operator}{))}}}. We want these equalities to be
recognized implicitly and taken into account in the conversion rule.

From the logical point of view, we have built a type family by giving
a set of constructors. We want to capture the fact that we do not have
any other way to build an object in this type. So when trying to prove
a property about an object \(m\) in an inductive definition it is enough
to enumerate all the cases where \(m\) starts with a different
constructor.

In case the inductive definition is effectively a recursive one, we
want to capture the extra property that we have built the smallest
fixed point of this recursive equation. This says that we are only
manipulating finite objects. This analysis provides induction
principles. For instance, in order to prove \sphinxcode{\sphinxupquote{\DUrole{error}{∀} \DUrole{name}{l}\DUrole{operator}{:}\DUrole{keyword,type}{list} \DUrole{name}{A}\DUrole{operator}{,(}\DUrole{name}{has\_length} \DUrole{name}{A} \DUrole{name}{l}
\DUrole{operator}{(}\DUrole{name}{length} \DUrole{name}{l}\DUrole{operator}{))}}} it is enough to prove:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{has\_length} \DUrole{name}{A} \DUrole{operator}{(}\DUrole{name}{nil} \DUrole{name}{A}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{length} \DUrole{operator}{(}\DUrole{name}{nil} \DUrole{name}{A}\DUrole{operator}{)))}}}

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{error}{∀} \DUrole{name}{a}\DUrole{operator}{:}\DUrole{name}{A}\DUrole{operator}{,} \DUrole{error}{∀} \DUrole{name}{l}\DUrole{operator}{:}\DUrole{keyword,type}{list} \DUrole{name}{A}\DUrole{operator}{,} \DUrole{operator}{(}\DUrole{name}{has\_length} \DUrole{name}{A} \DUrole{name}{l} \DUrole{operator}{(}\DUrole{name}{length} \DUrole{name}{l}\DUrole{operator}{))} \DUrole{error}{\(\rightarrow\)}}}
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{has\_length} \DUrole{name}{A} \DUrole{operator}{(}\DUrole{name}{cons} \DUrole{name}{A} \DUrole{name}{a} \DUrole{name}{l}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{length} \DUrole{operator}{(}\DUrole{name}{cons} \DUrole{name}{A} \DUrole{name}{a} \DUrole{name}{l}\DUrole{operator}{)))}}}

\end{itemize}

which given the conversion equalities satisfied by length is the same
as proving:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{has\_length} \DUrole{name}{A} \DUrole{operator}{(}\DUrole{name}{nil} \DUrole{name}{A}\DUrole{operator}{)} \DUrole{name}{O}\DUrole{operator}{)}}}

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{error}{∀} \DUrole{name}{a}\DUrole{operator}{:}\DUrole{name}{A}\DUrole{operator}{,} \DUrole{error}{∀} \DUrole{name}{l}\DUrole{operator}{:}\DUrole{keyword,type}{list} \DUrole{name}{A}\DUrole{operator}{,} \DUrole{operator}{(}\DUrole{name}{has\_length} \DUrole{name}{A} \DUrole{name}{l} \DUrole{operator}{(}\DUrole{name}{length} \DUrole{name}{l}\DUrole{operator}{))} \DUrole{error}{\(\rightarrow\)}}}
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{has\_length} \DUrole{name}{A} \DUrole{operator}{(}\DUrole{name}{cons} \DUrole{name}{A} \DUrole{name}{a} \DUrole{name}{l}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{operator}{(}\DUrole{name}{length} \DUrole{name}{l}\DUrole{operator}{)))}}}

\end{itemize}

One conceptually simple way to do that, following the basic scheme
proposed by Martin-Löf in his Intuitionistic Type Theory, is to
introduce for each inductive definition an elimination operator. At
the logical level it is a proof of the usual induction principle and
at the computational level it implements a generic operator for doing
primitive recursion over the structure.

But this operator is rather tedious to implement and use. We choose in
this version of \DUrole{smallcaps}{Coq} to factorize the operator for primitive recursion
into two more primitive operations as was first suggested by Th.
Coquand in \sphinxcite{zebibliography:coq92}. One is the definition by pattern matching. The
second one is a definition by guarded fixpoints.


\paragraph{The match ... with ... end construction}
\label{\detokenize{language/cic:the-match-with-end-construction}}\label{\detokenize{language/cic:match-construction}}
The basic idea of this operator is that we have an object \(m\) in an
inductive type \(I\) and we want to prove a property which possibly
depends on \(m\). For this, it is enough to prove the property for
\(m = (c_i~u_1 … u_{p_i} )\) for each constructor of \(I\).
The \DUrole{smallcaps}{Coq} term for this proof
will be written:
\begin{equation*}
\begin{split}\Match~m~\with~(c_1~x_{11} ... x_{1p_1} ) ⇒ f_1 | … | (c_n~x_{n1} ... x_{np_n} ) ⇒ f_n \kwend\end{split}
\end{equation*}
In this expression, if \(m\) eventually happens to evaluate to
\((c_i~u_1 … u_{p_i})\) then the expression will behave as specified in its \(i\)-th branch
and it will reduce to \(f_i\) where the \(x_{i1} …x_{ip_i}\) are replaced by the
\(u_1 … u_{p_i}\) according to the \(\iota\)-reduction.

Actually, for type checking a \(\Match…\with…\kwend\) expression we also need
to know the predicate P to be proved by case analysis. In the general
case where \(I\) is an inductively defined \(n\)-ary relation, \(P\) is a predicate
over \(n+1\) arguments: the \(n\) first ones correspond to the arguments of \(I\)
(parameters excluded), and the last one corresponds to object \(m\). \DUrole{smallcaps}{Coq}
can sometimes infer this predicate but sometimes not. The concrete
syntax for describing this predicate uses the \(\as…\In…\return\)
construction. For instance, let us assume that \(I\) is an unary predicate
with one parameter and one argument. The predicate is made explicit
using the syntax:
\begin{equation*}
\begin{split}\Match~m~\as~x~\In~I~\_~a~\return~P~\with~
(c_1~x_{11} ... x_{1p_1} ) ⇒ f_1 | …
| (c_n~x_{n1} ... x_{np_n} ) ⇒ f_n~\kwend\end{split}
\end{equation*}
The \(\as\) part can be omitted if either the result type does not depend
on \(m\) (non-dependent elimination) or \(m\) is a variable (in this case, \(m\)
can occur in \(P\) where it is considered a bound variable). The \(\In\) part
can be omitted if the result type does not depend on the arguments
of \(I\). Note that the arguments of \(I\) corresponding to parameters \sphinxstyleemphasis{must}
be \(\_\), because the result type is not generalized to all possible
values of the parameters. The other arguments of \(I\) (sometimes called
indices in the literature) have to be variables (\(a\) above) and these
variables can occur in \(P\). The expression after \(\In\) must be seen as an
\sphinxstyleemphasis{inductive type pattern}. Notice that expansion of implicit arguments
and notations apply to this pattern. For the purpose of presenting the
inference rules, we use a more compact notation:
\begin{equation*}
\begin{split}\case(m,(λ a x . P), λ x_{11} ... x_{1p_1} . f_1~| … |~λ x_{n1} ...x_{np_n} . f_n )\end{split}
\end{equation*}\phantomsection\label{\detokenize{language/cic:allowed-elimination-sorts}}
\sphinxstylestrong{Allowed elimination sorts.} An important question for building the typing rule for match is what
can be the type of \(λ a x . P\) with respect to the type of \(m\). If \(m:I\)
and \(I:A\) and \(λ a x . P : B\) then by \([I:A|B]\) we mean that one can use
\(λ a x . P\) with \(m\) in the above match-construct.

\phantomsection\label{\detokenize{language/cic:cic-notations}}
\sphinxstylestrong{Notations.} The \([I:A|B]\) is defined as the smallest relation satisfying the
following rules: We write \([I|B]\) for \([I:A|B]\) where \(A\) is the type of \(I\).

The case of inductive definitions in sorts \(\Set\) or \(\Type\) is simple.
There is no restriction on the sort of the predicate to be eliminated.
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-prod}}\item[{Prod}] \leavevmode \begin{equation*}
\begin{split}\frac{%
[(I~x):A′|B′]%
}{%
[I:∀ x:A, A′|∀ x:A, B′]%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-set-type}}\item[{Set \& Type}] \leavevmode \begin{equation*}
\begin{split}\frac{%
s_1 ∈ \{\Set,\Type(j)\}%
\hspace{3em}%
s_2 ∈ \Sort%
}{%
[I:s_1 |I→ s_2 ]%
}\end{split}
\end{equation*}\end{description}

The case of Inductive definitions of sort \(\Prop\) is a bit more
complicated, because of our interpretation of this sort. The only
harmless allowed elimination, is the one when predicate \(P\) is also of
sort \(\Prop\).
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-prop}}\item[{Prop}] \leavevmode \begin{equation*}
\begin{split}\frac{%
~%
}{%
[I:Prop|I→Prop]%
}\end{split}
\end{equation*}\end{description}

\(\Prop\) is the type of logical propositions, the proofs of properties \(P\) in
\(\Prop\) could not be used for computation and are consequently ignored by
the extraction mechanism. Assume \(A\) and \(B\) are two propositions, and the
logical disjunction \(A ∨ B\) is defined inductively by:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{or} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=}
\PYG{n}{or\PYGZus{}introl} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{or} \PYG{n}{A} \PYG{n}{B} \PYG{o}{\textbar{}} \PYG{n}{or\PYGZus{}intror} \PYG{o}{:} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{or} \PYG{n}{A} \PYG{n}{B}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The following definition which computes a boolean value by case over
the proof of \sphinxcode{\sphinxupquote{\DUrole{name}{or} \DUrole{name}{A} \DUrole{name}{B}}} is not accepted:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Definition} \PYG{n}{choice} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{or} \PYG{n}{A} \PYG{n}{B}\PYG{o}{)} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{x} \PYG{k}{with} \PYG{n}{or\PYGZus{}introl} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{n}{a} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true} \PYG{o}{\textbar{}} \PYG{n}{or\PYGZus{}intror} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{n}{b} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false} \PYG{k}{end}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{Incorrect} \PYG{n}{elimination} \PYG{k}{of} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{in} \PYG{n}{the} \PYG{n}{inductive} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{or}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{:}
    \PYG{n}{the} \PYG{k}{return} \PYG{n}{type} \PYG{n}{has} \PYG{n}{sort} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Set}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{while} \PYG{n}{it} \PYG{n}{should} \PYG{n}{be} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Prop}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    \PYG{n}{Elimination} \PYG{k}{of} \PYG{n}{an} \PYG{n}{inductive} \PYG{n}{object} \PYG{k}{of} \PYG{n}{sort} \PYG{k+kt}{Prop}
    \PYG{k}{is} \PYG{n}{not} \PYG{n}{allowed} \PYG{n}{on} \PYG{n}{a} \PYG{n}{predicate} \PYG{k}{in} \PYG{n}{sort} \PYG{k+kn}{Set}
    \PYG{n}{because} \PYG{n}{proofs} \PYG{n}{can} \PYG{n}{be} \PYG{n}{eliminated} \PYG{n}{only} \PYG{n}{to} \PYG{n}{build} \PYG{n}{proofs}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

From the computational point of view, the structure of the proof of
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{or} \DUrole{name}{A} \DUrole{name}{B}\DUrole{operator}{)}}} in this term is needed for computing the boolean value.

In general, if \(I\) has type \(\Prop\) then \(P\) cannot have type \(I→Set,\) because
it will mean to build an informative proof of type \((P~m)\) doing a case
analysis over a non-computational object that will disappear in the
extracted program. But the other way is safe with respect to our
interpretation we can have \(I\) a computational object and \(P\) a
non-computational one, it just corresponds to proving a logical property
of a computational object.

In the same spirit, elimination on \(P\) of type \(I→Type\) cannot be allowed
because it trivially implies the elimination on \(P\) of type \(I→ Set\) by
cumulativity. It also implies that there are two proofs of the same
property which are provably different, contradicting the proof-
irrelevance property which is sometimes a useful axiom:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{proof\PYGZus{}irrelevance} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{P}\PYG{o}{)}\PYG{o}{,} \PYG{n}{x}\PYG{o}{=}\PYG{n}{y}\PYG{o}{.}
    \PYG{n}{proof\PYGZus{}irrelevance} \PYG{k}{is} \PYG{n}{declared}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The elimination of an inductive definition of type \(\Prop\) on a predicate
\(P\) of type \(I→ Type\) leads to a paradox when applied to impredicative
inductive definition like the second-order existential quantifier
\sphinxcode{\sphinxupquote{\DUrole{name}{exProp}}} defined above, because it gives access to the two projections on
this type.

\phantomsection\label{\detokenize{language/cic:empty-and-singleton-elimination}}
\sphinxstylestrong{Empty and singleton elimination.} There are special inductive definitions in
\(\Prop\) for which more eliminations are allowed.
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-prop-extended}}\item[{Prop-extended}] \leavevmode \begin{equation*}
\begin{split}\frac{%
I~\kw{is an empty or singleton definition}%
\hspace{3em}%
s ∈ \Sort%
}{%
[I:Prop|I→ s]%
}\end{split}
\end{equation*}\end{description}

A \sphinxstyleemphasis{singleton definition} has only one constructor and all the
arguments of this constructor have type \(\Prop\). In that case, there is a
canonical way to interpret the informative extraction on an object in
that type, such that the elimination on any sort \(s\) is legal. Typical
examples are the conjunction of non-informative propositions and the
equality. If there is a hypothesis \(h:a=b\) in the local context, it can
be used for rewriting not only in logical propositions but also in any
type.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{n}{eq\PYGZus{}rec}\PYG{o}{.}
    \PYG{n}{eq\PYGZus{}rec} \PYG{o}{=} 
    \PYG{k}{fun} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{eq\PYGZus{}rect} \PYG{n}{x} \PYG{n}{P}
         \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{)}\PYG{o}{,}
           \PYG{n}{P} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{y}
    
    \PYG{n}{Argument} \PYG{n}{A} \PYG{k}{is} \PYG{n}{implicit}
    \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}} \PYG{n}{function\PYGZus{}scope} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{]}

\PYG{k+kn}{Require} \PYG{n}{Extraction}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{extraction\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}

\PYG{n}{Extraction} \PYG{n}{eq\PYGZus{}rec}\PYG{o}{.}
    \PYG{c}{(*}\PYG{c}{*}\PYG{c}{ val eq\PYGZus{}rec : \PYGZsq{}a1 \PYGZhy{}\PYGZgt{} \PYGZsq{}a2 \PYGZhy{}\PYGZgt{} \PYGZsq{}a1 \PYGZhy{}\PYGZgt{} \PYGZsq{}a2 }\PYG{c}{*}\PYG{c}{*)}
    
    \PYG{k}{let} \PYG{n}{eq\PYGZus{}rec} \PYG{o}{\PYGZus{}} \PYG{n}{f} \PYG{o}{\PYGZus{}} \PYG{o}{=}
      \PYG{n}{f}
\end{sphinxVerbatim}
\end{sphinxadmonition}

An empty definition has no constructors, in that case also,
elimination on any sort is allowed.

\phantomsection\label{\detokenize{language/cic:type-of-branches}}
\sphinxstylestrong{Type of branches.}
Let \(c\) be a term of type \(C\), we assume \(C\) is a type of constructor for an
inductive type \(I\). Let \(P\) be a term that represents the property to be
proved. We assume \(r\) is the number of parameters and \(p\) is the number of
arguments.

We define a new type \(\{c:C\}^P\) which represents the type of the branch
corresponding to the \(c:C\) constructor.
\begin{equation*}
\begin{split}\begin{array}{ll}
\{c:(I~p_1\ldots p_r\ t_1 \ldots t_p)\}^P &\equiv (P~t_1\ldots ~t_p~c) \\
\{c:\forall~x:T,C\}^P &\equiv \forall~x:T,\{(c~x):C\}^P
\end{array}\end{split}
\end{equation*}
We write \(\{c\}^P\) for \(\{c:C\}^P\) with \(C\) the type of \(c\).

\begin{sphinxadmonition}{note}{Example}

The following term in concrete syntax:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
match t as l return P\PYGZsq{} with
\textbar{} nil \PYGZus{} =\PYGZgt{} t1
\textbar{} cons \PYGZus{} hd tl =\PYGZgt{} t2
end
\end{sphinxVerbatim}

can be represented in abstract syntax as
\begin{equation*}
\begin{split}\case(t,P,f 1 | f 2 )\end{split}
\end{equation*}
where
\begin{eqnarray*}
  P & = & \lambda~l~.~P^\prime\\
  f_1 & = & t_1\\
  f_2 & = & \lambda~(hd:\nat)~.~\lambda~(tl:\List~\nat)~.~t_2
\end{eqnarray*}
According to the definition:
\begin{equation*}
\begin{split}\{(\kw{nil}~\nat)\}^P ≡ \{(\kw{nil}~\nat) : (\List~\nat)\}^P ≡ (P~(\kw{nil}~\nat))\end{split}
\end{equation*}\begin{equation*}
\begin{split}\begin{array}{rl}
\{(\kw{cons}~\nat)\}^P & ≡\{(\kw{cons}~\nat) : (\nat→\List~\nat→\List~\nat)\}^P \\
& ≡∀ n:\nat, \{(\kw{cons}~\nat~n) : \List~\nat→\List~\nat)\}^P \\
& ≡∀ n:\nat, ∀ l:\List~\nat, \{(\kw{cons}~\nat~n~l) : \List~\nat)\}^P \\
& ≡∀ n:\nat, ∀ l:\List~\nat,(P~(\kw{cons}~\nat~n~l)).
\end{array}\end{split}
\end{equation*}
Given some \(P\) then \(\{(\kw{nil}~\nat)\}^P\) represents the expected type of \(f_1\) ,
and \(\{(\kw{cons}~\nat)\}^P\) represents the expected type of \(f_2\).
\end{sphinxadmonition}
\phantomsection\label{\detokenize{language/cic:typing-rule}}
\sphinxstylestrong{Typing rule.}
Our very general destructor for inductive definition enjoys the
following typing rule
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-match}}\item[{match}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\begin{array}{l}%
\hspace{3em}%
E[Γ] ⊢ c : (I~q_1 … q_r~t_1 … t_s ) \\%
\hspace{3em}%
E[Γ] ⊢ P : B \\%
\hspace{3em}%
[(I~q_1 … q_r)|B] \\%
\hspace{3em}%
(E[Γ] ⊢ f_i : \{(c_{p_i}~q_1 … q_r)\}^P)_{i=1… l}%
\hspace{3em}%
\end{array}%
}{%
E[Γ] ⊢ \case(c,P,f_1  |… |f_l ) : (P~t_1 … t_s~c)%
}\end{split}
\end{equation*}\end{description}

provided \(I\) is an inductive type in a
definition \(\ind{r}{Γ_I}{Γ_C}\) with \(Γ_C = [c_1 :C_1 ;…;c_n :C_n ]\) and
\(c_{p_1} … c_{p_l}\) are the only constructors of \(I\).

\begin{sphinxadmonition}{note}{Example}

Below is a typing rule for the term shown in the previous example:
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-list-example}}\item[{list example}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\begin{array}{l}%
\hspace{3em}%
  E[Γ] ⊢ t : (\List ~\nat) \\%
\hspace{3em}%
  E[Γ] ⊢ P : B \\%
\hspace{3em}%
  [(\List ~\nat)|B] \\%
\hspace{3em}%
  E[Γ] ⊢ f_1 : {(\kw{nil} ~\nat)}^P \\%
\hspace{3em}%
  E[Γ] ⊢ f_2 : {(\kw{cons} ~\nat)}^P%
\hspace{3em}%
\end{array}%
}{%
E[Γ] ⊢ \case(t,P,f_1 |f_2 ) : (P~t)%
}\end{split}
\end{equation*}\end{description}
\end{sphinxadmonition}
\phantomsection\label{\detokenize{language/cic:definition-of-reduction}}
\sphinxstylestrong{Definition of \(\iota\)-reduction.}
We still have to define the \(\iota\)-reduction in the general case.

An \(\iota\)-redex is a term of the following form:
\begin{equation*}
\begin{split}\case((c_{p_i}~q_1 … q_r~a_1 … a_m ),P,f_1 |… |f_l )\end{split}
\end{equation*}
with \(c_{p_i}\) the \(i\)-th constructor of the inductive type \(I\) with \(r\)
parameters.

The \(\iota\)-contraction of this term is \((f_i~a_1 … a_m )\) leading to the
general reduction rule:
\begin{equation*}
\begin{split}\case((c_{p_i}~q_1 … q_r~a_1 … a_m ),P,f_1 |… |f_n ) \triangleright_ι (f_i~a_1 … a_m )\end{split}
\end{equation*}

\subsubsection{Fixpoint definitions}
\label{\detokenize{language/cic:fixpoint-definitions}}\label{\detokenize{language/cic:id26}}
The second operator for elimination is fixpoint definition. This
fixpoint may involve several mutually recursive definitions. The basic
concrete syntax for a recursive set of mutually recursive declarations
is (with \(Γ_i\) contexts):
\begin{equation*}
\begin{split}\fix~f_1 (Γ_1 ) :A_1 :=t_1 \with … \with~f_n (Γ_n ) :A_n :=t_n\end{split}
\end{equation*}
The terms are obtained by projections from this set of declarations
and are written
\begin{equation*}
\begin{split}\fix~f_1 (Γ_1 ) :A_1 :=t_1 \with … \with~f_n (Γ_n ) :A_n :=t_n \for~f_i\end{split}
\end{equation*}
In the inference rules, we represent such a term by
\begin{equation*}
\begin{split}\Fix~f_i\{f_1 :A_1':=t_1' … f_n :A_n':=t_n'\}\end{split}
\end{equation*}
with \(t_i'\) (resp. \(A_i'\)) representing the term \(t_i\) abstracted (resp.
generalized) with respect to the bindings in the context \(\Gamma\)\_i , namely
\(t_i'=λ Γ_i . t_i\) and \(A_i'=∀ Γ_i , A_i\).


\paragraph{Typing rule}
\label{\detokenize{language/cic:id27}}
The typing rule is the expected one for a fixpoint.
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-fix}}\item[{Fix}] \leavevmode \begin{equation*}
\begin{split}\frac{%
(E[Γ] ⊢ A_i : s_i )_{i=1… n}%
\hspace{3em}%
(E[Γ,f_1 :A_1 ,…,f_n :A_n ] ⊢ t_i : A_i )_{i=1… n}%
}{%
E[Γ] ⊢ \Fix~f_i\{f_1 :A_1 :=t_1 … f_n :A_n :=t_n \} : A_i%
}\end{split}
\end{equation*}\end{description}

Any fixpoint definition cannot be accepted because non-normalizing
terms allow proofs of absurdity. The basic scheme of recursion that
should be allowed is the one needed for defining primitive recursive
functionals. In that case the fixpoint enjoys a special syntactic
restriction, namely one of the arguments belongs to an inductive type,
the function starts with a case analysis and recursive calls are done
on variables coming from patterns and representing subterms. For
instance in the case of natural numbers, a proof of the induction
principle of type
\begin{equation*}
\begin{split}∀ P:\nat→\Prop, (P~O)→(∀ n:\nat, (P~n)→(P~(\kw{S}~n)))→ ∀ n:\nat, (P~n)\end{split}
\end{equation*}
can be represented by the term:
\begin{equation*}
\begin{split}\begin{array}{l}
λ P:\nat→\Prop. λ f:(P~O). λ g:(∀ n:\nat, (P~n)→(P~(S~n))).\\
\Fix~h\{h:∀ n:\nat, (P~n):=λ n:\nat. \case(n,P,f | λp:\nat. (g~p~(h~p)))\}
\end{array}\end{split}
\end{equation*}
Before accepting a fixpoint definition as being correctly typed, we
check that the definition is “guarded”. A precise analysis of this
notion can be found in \sphinxcite{zebibliography:gim94}. The first stage is to precise on which
argument the fixpoint will be decreasing. The type of this argument
should be an inductive definition. For doing this, the syntax of
fixpoints is extended and becomes
\begin{equation*}
\begin{split}\Fix~f_i\{f_1/k_1 :A_1':=t_1' … f_n/k_n :A_n':=t_n'\}\end{split}
\end{equation*}
where \(k_i\) are positive integers. Each \(k_i\) represents the index of
parameter of \(f_i\) , on which \(f_i\) is decreasing. Each \(A_i\) should be a
type (reducible to a term) starting with at least \(k_i\) products
\(∀ y_1 :B_1 ,… ∀ y_{k_i} :B_{k_i} , A_i'\) and \(B_{k_i}\) an inductive type.

Now in the definition \(t_i\), if \(f_j\) occurs then it should be applied to
at least \(k_j\) arguments and the \(k_j\)-th argument should be
syntactically recognized as structurally smaller than \(y_{k_i}\).

The definition of being structurally smaller is a bit technical. One
needs first to define the notion of \sphinxstyleemphasis{recursive arguments of a
constructor}. For an inductive definition \(\ind{r}{Γ_I}{Γ_C}\), if the
type of a constructor \(c\) has the form
\(∀ p_1 :P_1 ,… ∀ p_r :P_r, ∀ x_1:T_1, … ∀ x_r :T_r, (I_j~p_1 … p_r~t_1 … t_s )\),
then the recursive
arguments will correspond to \(T_i\) in which one of the \(I_l\) occurs.

The main rules for being structurally smaller are the following.
Given a variable \(y\) of an inductively defined type in a declaration
\(\ind{r}{Γ_I}{Γ_C}\) where \(Γ_I\) is \([I_1 :A_1 ;…;I_k :A_k]\), and \(Γ_C\) is
\([c_1 :C_1 ;…;c_n :C_n ]\), the terms structurally smaller than \(y\) are:
\begin{itemize}
\item {} 
\((t~u)\) and \(λ x:u . t\) when \(t\) is structurally smaller than \(y\).

\item {} 
\(\case(c,P,f_1 … f_n)\) when each \(f_i\) is structurally smaller than \(y\).
If \(c\) is \(y\) or is structurally smaller than \(y\), its type is an inductive
definition \(I_p\) part of the inductive declaration corresponding to \(y\).
Each \(f_i\) corresponds to a type of constructor
\(C_q ≡ ∀ p_1 :P_1 ,…,∀ p_r :P_r , ∀ y_1 :B_1 , … ∀ y_k :B_k , (I~a_1 … a_k )\)
and can consequently be written \(λ y_1 :B_1' . … λ y_k :B_k'. g_i\). (\(B_i'\) is
obtained from \(B_i\) by substituting parameters for variables) the variables
\(y_j\) occurring in \(g_i\) corresponding to recursive arguments \(B_i\) (the
ones in which one of the \(I_l\) occurs) are structurally smaller than y.

\end{itemize}

The following definitions are correct, we enter them using the {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}}
command and show the internal representation.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
\PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{p} \PYG{n}{m}\PYG{o}{)}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{plus} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{plus} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}

\PYG{k+kn}{Print} \PYG{n}{plus}\PYG{o}{.}
    \PYG{n}{plus} \PYG{o}{=} 
    \PYG{k}{fix} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
      \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
      \PYG{o}{\textbar{}} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
      \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{p} \PYG{n}{m}\PYG{o}{)}
      \PYG{k}{end}
         \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
    
    \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{nat\PYGZus{}scope} \PYG{n}{nat\PYGZus{}scope}\PYG{o}{]}

\PYG{k+kn}{Fixpoint} \PYG{n}{lgth} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l}\PYG{o}{:}\PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{l}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{O}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{\PYGZus{}} \PYG{n}{a} \PYG{n}{l\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{lgth} \PYG{n}{A} \PYG{n}{l\PYGZsq{}}\PYG{o}{)}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{lgth} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{lgth} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{2}\PYG{n}{nd} \PYG{n}{argument}\PYG{o}{)}

\PYG{k+kn}{Print} \PYG{n}{lgth}\PYG{o}{.}
    \PYG{n}{lgth} \PYG{o}{=} 
    \PYG{k}{fix} \PYG{n}{lgth} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{l}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
      \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
      \PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
      \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{n}{l\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{lgth} \PYG{n}{A} \PYG{n}{l\PYGZsq{}}\PYG{o}{)}
      \PYG{k}{end}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{,} \PYG{k+kt}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
    
    \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}}\PYG{o}{]}

\PYG{k+kn}{Fixpoint} \PYG{n}{sizet} \PYG{o}{(}\PYG{n}{t}\PYG{o}{:}\PYG{n}{tree}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=} \PYG{k}{let} \PYG{o}{(}\PYG{n}{f}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{t} \PYG{k}{in} \PYG{n}{S} \PYG{o}{(}\PYG{n}{sizef} \PYG{n}{f}\PYG{o}{)}
\PYG{k}{with} \PYG{n}{sizef} \PYG{o}{(}\PYG{n}{f}\PYG{o}{:}\PYG{n}{forest}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{f} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n}{emptyf} \PYG{o}{=\PYGZgt{}} \PYG{n}{O}
\PYG{o}{\textbar{}} \PYG{n}{consf} \PYG{n}{t} \PYG{n}{f} \PYG{o}{=\PYGZgt{}} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{sizet} \PYG{n}{t}\PYG{o}{)} \PYG{o}{(}\PYG{n}{sizef} \PYG{n}{f}\PYG{o}{)}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{sizet} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{sizef} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{sizet}\PYG{o}{,} \PYG{n}{sizef} \PYG{n}{are} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{respectively} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st}\PYG{o}{,}
    \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{arguments}\PYG{o}{)}

\PYG{k+kn}{Print} \PYG{n}{sizet}\PYG{o}{.}
    \PYG{n}{sizet} \PYG{o}{=} 
    \PYG{k}{fix} \PYG{n}{sizet} \PYG{o}{(}\PYG{n}{t} \PYG{o}{:} \PYG{n}{tree}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=} \PYG{k}{let} \PYG{o}{(}\PYG{n}{f}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{t} \PYG{k}{in} \PYG{n}{S} \PYG{o}{(}\PYG{n}{sizef} \PYG{n}{f}\PYG{o}{)}
    \PYG{k}{with} \PYG{n}{sizef} \PYG{o}{(}\PYG{n}{f} \PYG{o}{:} \PYG{n}{forest}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
      \PYG{k}{match} \PYG{n}{f} \PYG{k}{with}
      \PYG{o}{\textbar{}} \PYG{n}{emptyf} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
      \PYG{o}{\textbar{}} \PYG{n}{consf} \PYG{n}{t} \PYG{n}{f0} \PYG{o}{=\PYGZgt{}} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{sizet} \PYG{n}{t}\PYG{o}{)} \PYG{o}{(}\PYG{n}{sizef} \PYG{n}{f0}\PYG{o}{)}
      \PYG{k}{end}
    \PYG{k}{for} \PYG{n}{sizet}
         \PYG{o}{:} \PYG{n}{tree} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Reduction rule}
\label{\detokenize{language/cic:reduction-rule}}\label{\detokenize{language/cic:id29}}
Let \(F\) be the set of declarations:
\(f_1 /k_1 :A_1 :=t_1 …f_n /k_n :A_n:=t_n\).
The reduction for fixpoints is:
\begin{equation*}
\begin{split}(\Fix~f_i \{F\} a_1 …a_{k_i}) \triangleright_ι \subst{t_i}{f_k}{\Fix~f_k \{F\}}_{k=1… n} ~a_1 … a_{k_i}\end{split}
\end{equation*}
when \(a_{k_i}\) starts with a constructor. This last restriction is needed
in order to keep strong normalization and corresponds to the reduction
for primitive recursive operators. The following reductions are now
possible:
{\def\plus{\mathsf{plus}}
 \def\tri{\triangleright_\iota}
 \begin{eqnarray*}
 \plus~(\nS~(\nS~\nO))~(\nS~\nO) & \tri & \nS~(\plus~(\nS~\nO)~(\nS~\nO))\\
                                & \tri & \nS~(\nS~(\plus~\nO~(\nS~\nO)))\\
                                & \tri & \nS~(\nS~(\nS~\nO))\\
 \end{eqnarray*}}\phantomsection\label{\detokenize{language/cic:mutual-induction}}
\sphinxstylestrong{Mutual induction}

The principles of mutual induction can be automatically generated
using the Scheme command described in Section {\hyperref[\detokenize{user-extensions/proof-schemes:proofschemes-induction-principles}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of induction principles with Scheme}}}}.


\subsection{Admissible rules for global environments}
\label{\detokenize{language/cic:admissible-rules-for-global-environments}}\label{\detokenize{language/cic:id30}}
From the original rules of the type system, one can show the
admissibility of rules which change the local context of definition of
objects in the global environment. We show here the admissible rules
that are used in the discharge mechanism at the end of a section.

\phantomsection\label{\detokenize{language/cic:abstraction}}
\sphinxstylestrong{Abstraction.}
One can modify a global declaration by generalizing it over a
previously assumed constant \(c\). For doing that, we need to modify the
reference to the global declaration in the subsequent global
environment and local context by explicitly applying this constant to
the constant \(c'\).

Below, if \(Γ\) is a context of the form \([y_1 :A_1 ;…;y_n :A_n]\), we write
\(∀x:U,\subst{Γ}{c}{x}\) to mean
\([y_1 :∀ x:U,\subst{A_1}{c}{x};…;y_n :∀ x:U,\subst{A_n}{c}{x}]\)
and \(\subst{E}{|Γ|}{|Γ|c}\) to mean the parallel substitution
\(E\{y_1 /(y_1~c)\}…\{y_n/(y_n~c)\}\).

\phantomsection\label{\detokenize{language/cic:first-abstracting-property}}
\sphinxstylestrong{First abstracting property:}
\begin{equation*}
\begin{split}\frac{\WF{E;c:U;E′;c′:=t:T;E″}{Γ}}
     {\WF{E;c:U;E′;c′:=λ x:U. \subst{t}{c}{x}:∀x:U,\subst{T}{c}{x};\subst{E″}{c′}{(c′~c)}}
     {\subst{Γ}{c}{(c~c′)}}}\end{split}
\end{equation*}\begin{equation*}
\begin{split}\frac{\WF{E;c:U;E′;c′:T;E″}{Γ}}
     {\WF{E;c:U;E′;c′:∀ x:U,\subst{T}{c}{x};\subst{E″}{c′}{(c′~c)}}{Γ{c/(c~c′)}}}\end{split}
\end{equation*}\begin{equation*}
\begin{split}\frac{\WF{E;c:U;E′;\ind{p}{Γ_I}{Γ_C};E″}{Γ}}
     {\WFTWOLINES{E;c:U;E′;\ind{p+1}{∀ x:U,\subst{Γ_I}{c}{x}}{∀ x:U,\subst{Γ_C}{c}{x}};
       \subst{E″}{|Γ_I ,Γ_C |}{|Γ_I ,Γ_C | c}}
      {\subst{Γ}{|Γ_I ,Γ_C|}{|Γ_I ,Γ_C | c}}}\end{split}
\end{equation*}
One can similarly modify a global declaration by generalizing it over
a previously defined constant \(c′\). Below, if \(Γ\) is a context of the form
\([y_1 :A_1 ;…;y_n :A_n]\), we write \(\subst{Γ}{c}{u}\) to mean
\([y_1 :\subst{A_1} {c}{u};…;y_n:\subst{A_n} {c}{u}]\).

\phantomsection\label{\detokenize{language/cic:second-abstracting-property}}
\sphinxstylestrong{Second abstracting property:}
\begin{equation*}
\begin{split}\frac{\WF{E;c:=u:U;E′;c′:=t:T;E″}{Γ}}
     {\WF{E;c:=u:U;E′;c′:=(\letin{x}{u:U}{\subst{t}{c}{x}}):\subst{T}{c}{u};E″}{Γ}}\end{split}
\end{equation*}\begin{equation*}
\begin{split}\frac{\WF{E;c:=u:U;E′;c′:T;E″}{Γ}}
     {\WF{E;c:=u:U;E′;c′:\subst{T}{c}{u};E″}{Γ}}\end{split}
\end{equation*}\begin{equation*}
\begin{split}\frac{\WF{E;c:=u:U;E′;\ind{p}{Γ_I}{Γ_C};E″}{Γ}}
     {\WF{E;c:=u:U;E′;\ind{p}{\subst{Γ_I}{c}{u}}{\subst{Γ_C}{c}{u}};E″}{Γ}}\end{split}
\end{equation*}\phantomsection\label{\detokenize{language/cic:pruning-the-local-context}}
\sphinxstylestrong{Pruning the local context.}
If one abstracts or substitutes constants with the above rules then it
may happen that some declared or defined constant does not occur any
more in the subsequent global environment and in the local context.
One can consequently derive the following property.

\phantomsection\label{\detokenize{language/cic:first-pruning-property}}\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-first-pruning-property}}\item[{First pruning property:}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WF{E;c:U;E′}{Γ}%
\hspace{3em}%
c~\kw{does not occur in}~E′~\kw{and}~Γ%
}{%
\WF{E;E′}{Γ}%
}\end{split}
\end{equation*}\end{description}
\phantomsection\label{\detokenize{language/cic:second-pruning-property}}\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-second-pruning-property}}\item[{Second pruning property:}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WF{E;c:=u:U;E′}{Γ}%
\hspace{3em}%
c~\kw{does not occur in}~E′~\kw{and}~Γ%
}{%
\WF{E;E′}{Γ}%
}\end{split}
\end{equation*}\end{description}


\subsection{Co-inductive types}
\label{\detokenize{language/cic:co-inductive-types}}\label{\detokenize{language/cic:id31}}
The implementation contains also co-inductive definitions, which are
types inhabited by infinite objects. More information on co-inductive
definitions can be found in \sphinxcite{zebibliography:gimenez95b}\sphinxcite{zebibliography:gim98}\sphinxcite{zebibliography:gimcas05}.


\subsection{The Calculus of Inductive Constructions with impredicative Set}
\label{\detokenize{language/cic:the-calculus-of-inductive-constructions-with-impredicative-set}}\label{\detokenize{language/cic:the-calculus-of-inductive-construction-with-impredicative-set}}
\DUrole{smallcaps}{Coq} can be used as a type checker for the Calculus of Inductive
Constructions with an impredicative sort \(\Set\) by using the compiler
option \sphinxcode{\sphinxupquote{-impredicative-set}}. For example, using the ordinary \sphinxtitleref{coqtop}
command, the following is rejected,

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Definition} \PYG{n}{id}\PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{k}{forall} \PYG{n}{X}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{,}\PYG{n}{X}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{n}{X}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{forall X : Set, X \PYGZhy{}\PYGZgt{} X}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Type}\PYG{l+s+s2}{\PYGZdq{}}
    \PYG{n}{while} \PYG{n}{it} \PYG{k}{is} \PYG{n}{expected} \PYG{n}{to} \PYG{k}{have} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Set}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{(}\PYG{n}{universe} \PYG{n}{inconsistency}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

while it will type check, if one uses instead the \sphinxtitleref{coqtop}
\sphinxcode{\sphinxupquote{-impredicative-set}} option..

The major change in the theory concerns the rule for product formation
in the sort \(\Set\), which is extended to a domain in any sort:
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-prodimp}}\item[{ProdImp}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[Γ] ⊢ T : s%
\hspace{3em}%
s ∈ {\Sort}%
\hspace{3em}%
E[Γ::(x:T)] ⊢ U : Set%
}{%
E[Γ] ⊢ ∀ x:T,U : Set%
}\end{split}
\end{equation*}\end{description}

This extension has consequences on the inductive definitions which are
allowed. In the impredicative system, one can build so-called \sphinxstyleemphasis{large
inductive definitions} like the example of second-order existential
quantifier (\sphinxcode{\sphinxupquote{\DUrole{name}{exSet}}}).

There should be restrictions on the eliminations which can be
performed on such definitions. The elimination rules in the
impredicative system for sort \(\Set\) become:
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-set1}}\item[{Set1}] \leavevmode \begin{equation*}
\begin{split}\frac{%
s ∈ \{Prop, Set\}%
}{%
[I:Set|I→ s]%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/cic:inference-set2}}\item[{Set2}] \leavevmode \begin{equation*}
\begin{split}\frac{%
I~\kw{is a small inductive definition}%
\hspace{3em}%
s ∈ \{\Type(i)\}%
}{%
[I:Set|I→ s]%
}\end{split}
\end{equation*}\end{description}


\section{The Module System}
\label{\detokenize{language/module-system:the-module-system}}\label{\detokenize{language/module-system:themodulesystem}}\label{\detokenize{language/module-system::doc}}
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.


\subsection{Modules and module types}
\label{\detokenize{language/module-system:modules-and-module-types}}
\sphinxstylestrong{Access path.} An access path is denoted by \(p\) and can be
either a module variable \(X\) or, if \(p′\) is an access path
and \(id\) an identifier, then \(p′.id\) is an access path.

\sphinxstylestrong{Structure element.} A structure element is denoted by \(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.

\sphinxstylestrong{Structure expression.} A structure expression is denoted by \(S\) and can be:
\begin{itemize}
\item {} 
an access path \(p\)

\item {} 
a plain structure \(\Struct~e ; … ; e~\End\)

\item {} 
a functor \(\Functor(X:S)~S′\), where \(X\) is a module variable, \(S\) and \(S′\) are
structure expressions

\item {} 
an application \(S~p\), where \(S\) is a structure expression and \(p\) an
access path

\item {} 
a refined structure \(S~\with~p := p\)′ or \(S~\with~p := t:T\) where \(S\) is a
structure expression, \(p\) and \(p′\) are access paths, \(t\) is a term and \(T\) is
the type of \(t\).

\end{itemize}

\sphinxstylestrong{Module definition.} A module definition is written \(\Mod{X}{S}{S'}\)
and consists of a module variable \(X\), a module type
\(S\) which can be any structure expression and optionally a
module implementation \(S′\) which can be any structure expression
except a refined structure.

\sphinxstylestrong{Module alias.} A module alias is written \(\ModA{X}{p}\)
and consists of a module variable \(X\) and a module path
\(p\).

\sphinxstylestrong{Module type abbreviation.}
A module type abbreviation is written \(\ModType{Y}{S}\),
where \(Y\) is an identifier and \(S\) is any structure
expression .


\subsection{Typing Modules}
\label{\detokenize{language/module-system:typing-modules}}
In order to introduce the typing system we first slightly extend the syntactic
class of terms and environments given in section {\hyperref[\detokenize{language/cic:the-terms}]{\sphinxcrossref{\DUrole{std,std-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:
\begin{itemize}
\item {} 
\(\WFT{E}{S}\), denoting that a structure \(S\) is well-formed,

\item {} 
\(\WTM{E}{p}{S}\), denoting that the module pointed by \(p\) has type \(S\) in
environment \(E\).

\item {} 
\(\WEV{E}{S}{\ovl{S}}\), denoting that a structure \(S\) is evaluated to a
structure \(S\) in weak head normal form.

\item {} 
\(\WS{E}{S_1}{S_2}\) , denoting that a structure \(S_1\) is a subtype of a
structure \(S_2\).

\item {} 
\(\WS{E}{e_1}{e_2}\) , denoting that a structure element e\_1 is more
precise than a structure element e\_2.

\end{itemize}

The rules for forming structures are the following:
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-wf-str}}\item[{WF-STR}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WF{E;E′}{}%
}{%
\WFT{E}{ \Struct~E′ ~\End}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-wf-fun}}\item[{WF-FUN}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WFT{E; \ModS{X}{S}}{ \ovl{S′} }%
}{%
\WFT{E}{ \Functor(X:S)~S′}%
}\end{split}
\end{equation*}\end{description}

Evaluation of structures to weak head normal form:
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-weval-app}}\item[{WEVAL-APP}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\begin{array}{c}%
\hspace{3em}%
\WEV{E}{S}{\Functor(X:S_1 )~S_2}~~~~~\WEV{E}{S_1}{\ovl{S_1}} \\%
\hspace{3em}%
\WTM{E}{p}{S_3}~~~~~ \WS{E}{S_3}{\ovl{S_1}}%
\hspace{3em}%
\end{array}%
}{%
\WEV{E}{S~p}{S_2 \{p/X,t_1 /p_1 .c_1 ,…,t_n /p_n.c_n \}}%
}\end{split}
\end{equation*}\end{description}

In the last rule, \(\{t_1 /p_1 .c_1 ,…,t_n /p_n .c_n \}\) is the resulting
substitution from the inlining mechanism. We substitute in \(S\) the
inlined fields \(p_i .c_i\) from \(\ModS{X}{S_1 }\) by the corresponding delta-
reduced term \(t_i\) in \(p\).
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-weval-with-mod}}\item[{WEVAL-WITH-MOD}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\begin{array}{c}%
\hspace{3em}%
E[] ⊢ S \lra \Struct~e_1 ;…;e_i ; \ModS{X}{S_1 };e_{i+2} ;… ;e_n ~\End \\%
\hspace{3em}%
E;e_1 ;…;e_i [] ⊢ S_1 \lra \ovl{S_1} ~~~~~~%
\hspace{3em}%
E[] ⊢ p : S_2 \\%
\hspace{3em}%
E;e_1 ;…;e_i [] ⊢ S_2 <: \ovl{S_1}%
\hspace{3em}%
\end{array}%
}{%
\begin{array}{c}%
\hspace{3em}%
\WEV{E}{S~\with~x := p}{}\\%
\hspace{3em}%
\Struct~e_1 ;…;e_i ; \ModA{X}{p};e_{i+2} \{p/X\} ;…;e_n \{p/X\} ~\End%
\hspace{3em}%
\end{array}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-weval-with-mod-rec}}\item[{WEVAL-WITH-MOD-REC}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\begin{array}{c}%
\hspace{3em}%
\WEV{E}{S}{\Struct~e_1 ;…;e_i ; \ModS{X_1}{S_1 };e_{i+2} ;… ;e_n ~\End} \\%
\hspace{3em}%
\WEV{E;e_1 ;…;e_i }{S_1~\with~p := p_1}{\ovl{S_2}}%
\hspace{3em}%
\end{array}%
}{%
\begin{array}{c}%
\hspace{3em}%
\WEV{E}{S~\with~X_1.p := p_1}{} \\%
\hspace{3em}%
\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%
\hspace{3em}%
\end{array}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-weval-with-def}}\item[{WEVAL-WITH-DEF}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\begin{array}{c}%
\hspace{3em}%
\WEV{E}{S}{\Struct~e_1 ;…;e_i ;\Assum{}{c}{T_1};e_{i+2} ;… ;e_n ~\End} \\%
\hspace{3em}%
\WS{E;e_1 ;…;e_i }{Def()(c:=t:T)}{\Assum{}{c}{T_1}}%
\hspace{3em}%
\end{array}%
}{%
\begin{array}{c}%
\hspace{3em}%
\WEV{E}{S~\with~c := t:T}{} \\%
\hspace{3em}%
\Struct~e_1 ;…;e_i ;Def()(c:=t:T);e_{i+2} ;… ;e_n ~\End%
\hspace{3em}%
\end{array}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-weval-with-def-rec}}\item[{WEVAL-WITH-DEF-REC}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\begin{array}{c}%
\hspace{3em}%
\WEV{E}{S}{\Struct~e_1 ;…;e_i ; \ModS{X_1 }{S_1 };e_{i+2} ;… ;e_n ~\End} \\%
\hspace{3em}%
\WEV{E;e_1 ;…;e_i }{S_1~\with~p := p_1}{\ovl{S_2}}%
\hspace{3em}%
\end{array}%
}{%
\begin{array}{c}%
\hspace{3em}%
\WEV{E}{S~\with~X_1.p := t:T}{} \\%
\hspace{3em}%
\Struct~e_1 ;…;e_i ; \ModS{X}{\ovl{S_2} };e_{i+2} ;… ;e_n ~\End%
\hspace{3em}%
\end{array}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-weval-path-mod1}}\item[{WEVAL-PATH-MOD1}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\begin{array}{c}%
\hspace{3em}%
\WEV{E}{p}{\Struct~e_1 ;…;e_i ; \Mod{X}{S}{S_1};e_{i+2} ;… ;e_n End} \\%
\hspace{3em}%
\WEV{E;e_1 ;…;e_i }{S}{\ovl{S}}%
\hspace{3em}%
\end{array}%
}{%
E[] ⊢ p.X \lra \ovl{S}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-weval-path-mod2}}\item[{WEVAL-PATH-MOD2}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WF{E}{}%
\hspace{3em}%
\Mod{X}{S}{S_1}∈ E%
\hspace{3em}%
\WEV{E}{S}{\ovl{S}}%
}{%
\WEV{E}{X}{\ovl{S}}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-weval-path-alias1}}\item[{WEVAL-PATH-ALIAS1}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\begin{array}{c}%
\hspace{3em}%
\WEV{E}{p}{~\Struct~e_1 ;…;e_i ; \ModA{X}{p_1};e_{i+2}  ;… ;e_n End} \\%
\hspace{3em}%
\WEV{E;e_1 ;…;e_i }{p_1}{\ovl{S}}%
\hspace{3em}%
\end{array}%
}{%
\WEV{E}{p.X}{\ovl{S}}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-weval-path-alias2}}\item[{WEVAL-PATH-ALIAS2}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WF{E}{}%
\hspace{3em}%
\ModA{X}{p_1 }∈ E%
\hspace{3em}%
\WEV{E}{p_1}{\ovl{S}}%
}{%
\WEV{E}{X}{\ovl{S}}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-weval-path-type1}}\item[{WEVAL-PATH-TYPE1}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\begin{array}{c}%
\hspace{3em}%
\WEV{E}{p}{~\Struct~e_1 ;…;e_i ; \ModType{Y}{S};e_{i+2} ;… ;e_n End} \\%
\hspace{3em}%
\WEV{E;e_1 ;…;e_i }{S}{\ovl{S}}%
\hspace{3em}%
\end{array}%
}{%
\WEV{E}{p.Y}{\ovl{S}}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-weval-path-type2}}\item[{WEVAL-PATH-TYPE2}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WF{E}{}%
\hspace{3em}%
\ModType{Y}{S}∈ E%
\hspace{3em}%
\WEV{E}{S}{\ovl{S}}%
}{%
\WEV{E}{Y}{\ovl{S}}%
}\end{split}
\end{equation*}\end{description}

Rules for typing module:
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-mt-eval}}\item[{MT-EVAL}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WEV{E}{p}{\ovl{S}}%
}{%
E[] ⊢ p : \ovl{S}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-mt-str}}\item[{MT-STR}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[] ⊢ p : S%
}{%
E[] ⊢ p : S/p%
}\end{split}
\end{equation*}\end{description}

The last rule, called strengthening is used to make all module fields
manifestly equal to themselves. The notation \(S/p\) has the following
meaning:
\begin{itemize}
\item {} 
if \(S\lra~\Struct~e_1 ;…;e_n ~\End\) then \(S/p=~\Struct~e_1 /p;…;e_n /p ~\End\)
where \(e/p\) is defined as follows (note that opaque definitions are processed
as assumptions):
\begin{itemize}
\item {} 
\(\Def{}{c}{t}{T}/p = \Def{}{c}{t}{T}\)

\item {} 
\(\Assum{}{c}{U}/p = \Def{}{c}{p.c}{U}\)

\item {} 
\(\ModS{X}{S}/p = \ModA{X}{p.X}\)

\item {} 
\(\ModA{X}{p′}/p = \ModA{X}{p′}\)

\item {} 
\(\Ind{}{Γ_P}{Γ_C}{Γ_I}/p = \Indp{}{Γ_P}{Γ_C}{Γ_I}{p}\)

\item {} 
\(\Indpstr{}{Γ_P}{Γ_C}{Γ_I}{p'}{p} = \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'}\)

\end{itemize}

\item {} 
if \(S \lra \Functor(X:S′)~S″\) then \(S/p=S\)

\end{itemize}

The notation \(\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}\)
denotes an inductive definition that is definitionally equal to the
inductive definition in the module denoted by the path \(p\). All rules
which have \(\Ind{}{Γ_P}{Γ_C}{Γ_I}\) as premises are also valid for
\(\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}\). We give the formation rule for
\(\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}\)
below as well as the equality rules on inductive types and
constructors.

The module subtyping rules:
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-msub-str}}\item[{MSUB-STR}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\begin{array}{c}%
\hspace{3em}%
\WS{E;e_1 ;…;e_n }{e_{σ(i)}}{e'_i ~\for~ i=1..m} \\%
\hspace{3em}%
σ : \{1… m\} → \{1… n\} ~\injective%
\hspace{3em}%
\end{array}%
}{%
\WS{E}{\Struct~e_1 ;…;e_n ~\End}{~\Struct~e'_1 ;…;e'_m ~\End}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-msub-fun}}\item[{MSUB-FUN}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WS{E}{\ovl{S_1'}}{\ovl{S_1}}%
\hspace{3em}%
\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'%
}\end{split}
\end{equation*}\end{description}

Structure element subtyping rules:
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-assum-assum}}\item[{ASSUM-ASSUM}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[] ⊢ T_1 ≤_{βδιζη} T_2%
}{%
\WS{E}{\Assum{}{c}{T_1 }}{\Assum{}{c}{T_2 }}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-def-assum}}\item[{DEF-ASSUM}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[] ⊢ T_1 ≤_{βδιζη} T_2%
}{%
\WS{E}{\Def{}{c}{t}{T_1 }}{\Assum{}{c}{T_2 }}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-assum-def}}\item[{ASSUM-DEF}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[] ⊢ T_1 ≤_{βδιζη} T_2%
\hspace{3em}%
E[] ⊢ c =_{βδιζη} t_2%
}{%
\WS{E}{\Assum{}{c}{T_1 }}{\Def{}{c}{t_2 }{T_2 }}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-def-def}}\item[{DEF-DEF}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[] ⊢ T_1 ≤_{βδιζη} T_2%
\hspace{3em}%
E[] ⊢ t_1 =_{βδιζη} t_2%
}{%
\WS{E}{\Def{}{c}{t_1 }{T_1 }}{\Def{}{c}{t_2 }{T_2 }}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-ind-ind}}\item[{IND-IND}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[] ⊢ Γ_P =_{βδιζη} Γ_P'%
\hspace{3em}%
E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C'%
\hspace{3em}%
E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I'%
}{%
\WS{E}{\ind{Γ_P}{Γ_C}{Γ_I}}{\ind{Γ_P'}{Γ_C'}{Γ_I'}}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-indp-ind}}\item[{INDP-IND}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[] ⊢ Γ_P =_{βδιζη} Γ_P'%
\hspace{3em}%
E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C'%
\hspace{3em}%
E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I'%
}{%
\WS{E}{\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}}{\ind{Γ_P'}{Γ_C'}{Γ_I'}}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-indp-indp}}\item[{INDP-INDP}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\begin{array}{c}%
\hspace{3em}%
E[] ⊢ Γ_P =_{βδιζη} Γ_P'%
\hspace{3em}%
E[Γ_P ] ⊢ Γ_C =_{βδιζη} Γ_C' \\%
\hspace{3em}%
E[Γ_P ;Γ_C ] ⊢ Γ_I =_{βδιζη} Γ_I'%
\hspace{3em}%
E[] ⊢ p =_{βδιζη} p'%
\hspace{3em}%
\end{array}%
}{%
\WS{E}{\Indp{}{Γ_P}{Γ_C}{Γ_I}{p}}{\Indp{}{Γ_P'}{Γ_C'}{Γ_I'}{p'}}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-mod-mod}}\item[{MOD-MOD}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WS{E}{S_1}{S_2}%
}{%
\WS{E}{\ModS{X}{S_1 }}{\ModS{X}{S_2 }}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-alias-mod}}\item[{ALIAS-MOD}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[] ⊢ p : S_1%
\hspace{3em}%
\WS{E}{S_1}{S_2}%
}{%
\WS{E}{\ModA{X}{p}}{\ModS{X}{S_2 }}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-mod-alias}}\item[{MOD-ALIAS}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[] ⊢ p : S_2%
\hspace{3em}%
\WS{E}{S_1}{S_2}%
\hspace{3em}%
E[] ⊢ X =_{βδιζη} p%
}{%
\WS{E}{\ModS{X}{S_1 }}{\ModA{X}{p}}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-alias-alias}}\item[{ALIAS-ALIAS}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[] ⊢ p_1 =_{βδιζη} p_2%
}{%
\WS{E}{\ModA{X}{p_1 }}{\ModA{X}{p_2 }}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-modtype-modtype}}\item[{MODTYPE-MODTYPE}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WS{E}{S_1}{S_2}%
\hspace{3em}%
\WS{E}{S_2}{S_1}%
}{%
\WS{E}{\ModType{Y}{S_1 }}{\ModType{Y}{S_2 }}%
}\end{split}
\end{equation*}\end{description}

New environment formation rules
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-wf-mod1}}\item[{WF-MOD1}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WF{E}{}%
\hspace{3em}%
\WFT{E}{S}%
}{%
WF(E; \ModS{X}{S})[]%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-wf-mod2}}\item[{WF-MOD2}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WS{E}{S_2}{S_1}%
\hspace{3em}%
\WF{E}{}%
\hspace{3em}%
\WFT{E}{S_1}%
\hspace{3em}%
\WFT{E}{S_2}%
}{%
\WF{E; \Mod{X}{S_1}{S_2}}{}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-wf-alias}}\item[{WF-ALIAS}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WF{E}{}%
\hspace{3em}%
E[] ⊢ p : S%
}{%
\WF{E, \ModA{X}{p}}{}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-wf-modtype}}\item[{WF-MODTYPE}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\WF{E}{}%
\hspace{3em}%
\WFT{E}{S}%
}{%
\WF{E, \ModType{Y}{S}}{}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-wf-ind}}\item[{WF-IND}] \leavevmode \begin{equation*}
\begin{split}\frac{%
\begin{array}{c}%
\hspace{3em}%
\WF{E;\ind{Γ_P}{Γ_C}{Γ_I}}{} \\%
\hspace{3em}%
E[] ⊢ p:~\Struct~e_1 ;…;e_n ;\ind{Γ_P'}{Γ_C'}{Γ_I'};… ~\End : \\%
\hspace{3em}%
E[] ⊢ \ind{Γ_P'}{Γ_C'}{Γ_I'} <: \ind{Γ_P}{Γ_C}{Γ_I}%
\hspace{3em}%
\end{array}%
}{%
\WF{E; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p} }{}%
}\end{split}
\end{equation*}\end{description}

Component access rules
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-acc-type1}}\item[{ACC-TYPE1}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Assum{}{c}{T};… ~\End%
}{%
E[Γ] ⊢ p.c : T%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-acc-type2}}\item[{ACC-TYPE2}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Def{}{c}{t}{T};… ~\End%
}{%
E[Γ] ⊢ p.c : T%
}\end{split}
\end{equation*}\end{description}

Notice that the following rule extends the delta rule defined in section {\hyperref[\detokenize{language/cic:conversion-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{Conversion rules}}}}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-acc-delta}}\item[{ACC-DELTA}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[Γ] ⊢ p :~\Struct~e_1 ;…;e_i ;\Def{}{c}{t}{U};… ~\End%
}{%
E[Γ] ⊢ p.c \triangleright_δ t%
}\end{split}
\end{equation*}\end{description}

In the rules below we assume
\(Γ_P\) is \([p_1 :P_1 ;…;p_r :P_r ]\),
\(Γ_I\) is \([I_1 :A_1 ;…;I_k :A_k ]\),
and \(Γ_C\) is \([c_1 :C_1 ;…;c_n :C_n ]\).
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-acc-ind1}}\item[{ACC-IND1}] \leavevmode \begin{equation*}
\begin{split}\frac{%
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%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-acc-ind2}}\item[{ACC-IND2}] \leavevmode \begin{equation*}
\begin{split}\frac{%
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}%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-acc-indp1}}\item[{ACC-INDP1}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[] ⊢ p :~\Struct~e_1 ;…;e_i ; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'} ;… ~\End%
}{%
E[] ⊢ p.I_i \triangleright_δ p'.I_i%
}\end{split}
\end{equation*}\end{description}
\begin{description}
\phantomsection\label{\detokenize{language/module-system:inference-acc-indp2}}\item[{ACC-INDP2}] \leavevmode \begin{equation*}
\begin{split}\frac{%
E[] ⊢ p :~\Struct~e_1 ;…;e_i ; \Indp{}{Γ_P}{Γ_C}{Γ_I}{p'} ;… ~\End%
}{%
E[] ⊢ p.c_i \triangleright_δ p'.c_i%
}\end{split}
\end{equation*}\end{description}


\chapter{The proof engine}
\label{\detokenize{index:the-proof-engine}}

\section{Vernacular commands}
\label{\detokenize{proof-engine/vernacular-commands:vernacular-commands}}\label{\detokenize{proof-engine/vernacular-commands:vernacularcommands}}\label{\detokenize{proof-engine/vernacular-commands::doc}}

\subsection{Displaying}
\label{\detokenize{proof-engine/vernacular-commands:displaying}}\label{\detokenize{proof-engine/vernacular-commands:id1}}\phantomsection\label{\detokenize{proof-engine/vernacular-commands:print}}\index{Print (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.print}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This command displays on the screen information about the declared or
defined object referred by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.

Error messages:
\index{‘qualid’ not a defined object (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.qualid-not-a-defined-object}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~not~a~defined~object.}}}}
\end{fulllineitems}

\index{Universe instance should have length ‘num’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.universe-instance-should-have-length-num}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Universe~instance~should~have~length~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}.}}}}
\end{fulllineitems}

\index{This object does not support universe names (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.this-object-does-not-support-universe-names}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{This~object~does~not~support~universe~names.}}}}
\end{fulllineitems}

\index{Print Term (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmdv.print-term}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Term~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This is a synonym of {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.print}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}
denotes a global constant.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~\DUrole{repeat-wrapper}{\DUrole{repeat}{Term}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}@{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}}}}
This locally renames the polymorphic universes of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.
An underscore means the raw universe is printed.

\end{fulllineitems}


\end{fulllineitems}

\index{About (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.about}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{About~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This displays various information about the object
denoted by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}: its kind (module, constant, assumption, inductive,
constructor, abbreviation, …), long name, type, implicit arguments and
argument scopes. It does not print the body of definitions or proofs.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{About~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}@{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}}}}}
This locally renames the polymorphic universes of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.
An underscore means the raw universe is printed.

\end{fulllineitems}


\end{fulllineitems}

\index{Print All (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.print-all}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~All}}}}
This command displays information about the current state of the
environment, including sections and modules.
\index{Inspect (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmdv.inspect}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Inspect~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This command displays the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} last objects of the
current environment, including sections and modules.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Section~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
The name \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} should correspond to a currently open section,
this command displays the objects defined since the beginning of this
section.

\end{fulllineitems}


\end{fulllineitems}



\subsection{Flags, Options and Tables}
\label{\detokenize{proof-engine/vernacular-commands:flags-options-and-tables}}\label{\detokenize{proof-engine/vernacular-commands:flags-options-tables}}
Coq has many settings to control its behavior.  Setting types include flags, options
and tables:
\begin{itemize}
\item {} 
A \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/vernacular-commands:grammar-token-flag}}\sphinxcode{\sphinxupquote{flag}}} has a boolean value, such as {\hyperref[\detokenize{addendum/extended-pattern-matching:coq:flag.asymmetric-patterns}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Asymmetric Patterns}}}}}.

\item {} 
An \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/vernacular-commands:grammar-token-option}}\sphinxcode{\sphinxupquote{option}}} generally has a numeric or string value, such as {\hyperref[\detokenize{proof-engine/tactics:coq:opt.firstorder-depth}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Firstorder Depth}}}}}.

\item {} 
A \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{proof-engine/vernacular-commands:grammar-token-table}}\sphinxcode{\sphinxupquote{table}}} contains a set of strings or qualids.

\item {} 
In addition, some commands provide settings, such as {\hyperref[\detokenize{addendum/extraction:coq:cmd.extraction-language-ocaml}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Extraction Language OCaml}}}}}.

\end{itemize}

Flags, options and tables are identified by a series of identifiers, each with an initial
capital letter.
\index{Set (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.set}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Local~\textbar{}~Global~\textbar{}~Export}\DUrole{notation-sup}{?}}~Set~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-flag}]{\sphinxcrossref{\DUrole{hole}{flag}}}}}}}}
Sets {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-flag}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{flag}}}}} on. Scoping qualifiers are
described {\hyperref[\detokenize{proof-engine/vernacular-commands:set-unset-scope-qualifiers}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}.

\end{fulllineitems}

\index{Unset (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.unset}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Local~\textbar{}~Global~\textbar{}~Export}\DUrole{notation-sup}{?}}~Unset~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-flag}]{\sphinxcrossref{\DUrole{hole}{flag}}}}}}}}
Sets {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-flag}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{flag}}}}} off. Scoping qualifiers are
described {\hyperref[\detokenize{proof-engine/vernacular-commands:set-unset-scope-qualifiers}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}.

\end{fulllineitems}

\index{Test (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.test}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Test~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-flag}]{\sphinxcrossref{\DUrole{hole}{flag}}}}}}}}
Prints the current value of {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-flag}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{flag}}}}}.

\end{fulllineitems}

\index{Set "@option (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.set-option}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Local~\textbar{}~Global~\textbar{}~Export}\DUrole{notation-sup}{?}}~Set~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-option}]{\sphinxcrossref{\DUrole{hole}{option}}}}~(~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~\textbar{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~)}}}}
Sets {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-option}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{option}}}}} to the specified value.  Scoping qualifiers are
described {\hyperref[\detokenize{proof-engine/vernacular-commands:set-unset-scope-qualifiers}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}.

\end{fulllineitems}

\index{Unset "@option (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.unset-option}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Local~\textbar{}~Global~\textbar{}~Export}\DUrole{notation-sup}{?}}~Unset~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-option}]{\sphinxcrossref{\DUrole{hole}{option}}}}}}}}
Sets {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-option}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{option}}}}} to its default value.  Scoping qualifiers are
described {\hyperref[\detokenize{proof-engine/vernacular-commands:set-unset-scope-qualifiers}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}.

\end{fulllineitems}

\index{Test (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Test~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-option}]{\sphinxcrossref{\DUrole{hole}{option}}}}}}}}
Prints the current value of {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-option}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{option}}}}}.

\end{fulllineitems}

\index{Print Options (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.print-options}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Options}}}}
Prints the current value of all flags and options, and the names of all tables.

\end{fulllineitems}

\index{Add "@table (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.add-table}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-table}]{\sphinxcrossref{\DUrole{hole}{table}}}}~(~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~\textbar{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~)}}}}
Adds the specified value to {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{table}}}}}.

\end{fulllineitems}

\index{Remove "@table (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.remove-table}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Remove~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-table}]{\sphinxcrossref{\DUrole{hole}{table}}}}~(~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~\textbar{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~)}}}}
Removes the specified value from {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{table}}}}}.

\end{fulllineitems}

\index{Test "@table for (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.test-table-for}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Test~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-table}]{\sphinxcrossref{\DUrole{hole}{table}}}}~for~(~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~\textbar{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~)}}}}
Reports whether {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{table}}}}} contains the specified value.

\end{fulllineitems}

\index{Print Table "@table (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.print-table-table}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Table~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-table}]{\sphinxcrossref{\DUrole{hole}{table}}}}}}}}
Prints the values in {\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{table}}}}}.

\end{fulllineitems}

\index{Test (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Test~{\hyperref[\detokenize{proof-engine/vernacular-commands:grammar-token-table}]{\sphinxcrossref{\DUrole{hole}{table}}}}}}}}
A synonym for {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.print-table-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Table @table}}}}}.

\end{fulllineitems}

\index{Print Tables (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.print-tables}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Tables}}}}
A synonym for {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.print-options}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Options}}}}}.

\end{fulllineitems}



\subsubsection{Scope qualifiers for \sphinxstyleliteralintitle{\sphinxupquote{Set}} and \sphinxstyleliteralintitle{\sphinxupquote{Unset}}}
\label{\detokenize{proof-engine/vernacular-commands:scope-qualifiers-for-set-and-unset}}\label{\detokenize{proof-engine/vernacular-commands:set-unset-scope-qualifiers}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Local \textbar{} Global \textbar{} Export}\DUrole{notation-sup}{?}}}}}

Flag and option settings can be global in scope or local to nested scopes created by
{\hyperref[\detokenize{language/gallina-extensions:coq:cmd.module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Module}}}}} and {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.section}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Section}}}}} commands.  There are four alternatives:
\begin{itemize}
\item {} 
no qualifier: the original setting is \sphinxstyleemphasis{not} restored at the end of the current module or section.

\item {} 
\sphinxstylestrong{Local}: the setting is applied within the current scope.  The original value of the option
or flag is restored at the end of the current module or section.

\item {} 
\sphinxstylestrong{Global}: similar to no qualifier, the original setting is \sphinxstyleemphasis{not} restored at the end of the current
module or section.  In addition, if the value is set in a file, then {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}}-ing
the file sets the option.

\item {} 
\sphinxstylestrong{Export}: similar to \sphinxstylestrong{Local}, the original value of the option or flag is restored at the
end of the current module or section.  In addition, if the value is set in a file, then {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}}-ing
the file sets the option.

\end{itemize}

Newly opened scopes inherit the current settings.


\subsection{Requests to the environment}
\label{\detokenize{proof-engine/vernacular-commands:requests-to-the-environment}}\label{\detokenize{proof-engine/vernacular-commands:id2}}\index{Check (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.check}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Check~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This command displays the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. When called in proof mode, the
term is checked in the local context of the current subgoal.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-selector}]{\sphinxcrossref{\DUrole{hole}{selector}}}}:~Check~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This variant specifies on which subgoal to perform typing
(see Section {\hyperref[\detokenize{proof-engine/tactics:invocation-of-tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Invocation of tactics}}}}).

\end{fulllineitems}


\end{fulllineitems}

\index{Eval (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.eval}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Eval~\DUrole{hole}{convtactic}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This command performs the specified reduction on \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, and displays
the resulting term with its type. The term to be reduced may depend on
hypothesis introduced in the first subgoal (if a proof is in
progress).


\sphinxstrong{See also:}


Section {\hyperref[\detokenize{proof-engine/tactics:performingcomputations}]{\sphinxcrossref{\DUrole{std,std-ref}{Performing computations}}}}.



\end{fulllineitems}

\index{Compute (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.compute}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Compute~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This command performs a call-by-value evaluation of term by using the
bytecode-based virtual machine. It is a shortcut for \sphinxcode{\sphinxupquote{Eval vm\_compute in}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.


\sphinxstrong{See also:}


Section {\hyperref[\detokenize{proof-engine/tactics:performingcomputations}]{\sphinxcrossref{\DUrole{std,std-ref}{Performing computations}}}}.



\end{fulllineitems}

\index{Print Assumptions (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.print-assumptions}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Assumptions~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This commands display all the assumptions (axioms, parameters and
variables) a theorem or definition depends on. Especially, it informs
on the assumptions with respect to which the validity of a theorem
relies.
\index{Print Opaque Dependencies (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmdv.print-opaque-dependencies}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Opaque~Dependencies~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
Displays the set of opaque constants \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} relies on in addition to
the assumptions.

\end{fulllineitems}

\index{Print Transparent Dependencies (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmdv.print-transparent-dependencies}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Transparent~Dependencies~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
Displays the set of transparent constants \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} relies on
in addition to the assumptions.

\end{fulllineitems}

\index{Print All Dependencies (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmdv.print-all-dependencies}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~All~Dependencies~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
Displays all assumptions and constants \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} relies on.

\end{fulllineitems}


\end{fulllineitems}

\index{Search (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.search}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Search~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This command displays the name and type of all objects (hypothesis of
the current goal, theorems, axioms, etc) of the current context whose
statement contains \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}. This command is useful to remind the user
of the name of library lemmas.
\index{The reference ‘qualid’ was not found in the current environment (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.the-reference-qualid-was-not-found-in-the-current-environment}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~reference~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~was~not~found~in~the~current~environment.}}}}
There is no constant in the environment named qualid.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Search~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} is a valid identifier, this command
displays the name and type of all objects (theorems, axioms, etc) of
the current context whose name contains string. If string is a
notation’s string denoting some reference \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} (referred to by its
main symbol as in \sphinxtitleref{"+"} or by its notation’s string as in \sphinxtitleref{"\_ + \_"} or
\sphinxtitleref{"\_ 'U' \_"}, see Section {\hyperref[\detokenize{user-extensions/syntax-extensions:notations}]{\sphinxcrossref{\DUrole{std,std-ref}{Notations}}}}), the command works like \sphinxcode{\sphinxupquote{Search}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Search~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}\%{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-key}]{\sphinxcrossref{\DUrole{hole}{key}}}}}}}}
The string string must be a notation or the main
symbol of a notation which is then interpreted in the scope bound to
the delimiting key \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-key}]{\sphinxcrossref{\DUrole{hole}{key}}}}}}} (see Section {\hyperref[\detokenize{user-extensions/syntax-extensions:localinterpretationrulesfornotations}]{\sphinxcrossref{\DUrole{std,std-ref}{Local interpretation rules for notations}}}}).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Search~\DUrole{hole}{term\_pattern}}}}}
This searches for all statements or types of
definition that contains a subterm that matches the pattern
\sphinxtitleref{term\_pattern} (holes of the pattern are either denoted by \sphinxtitleref{\_} or by
\sphinxtitleref{?ident} when non linear patterns are expected).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Search~\DUrole{curlies}{\{~+~{[}-{]}\DUrole{hole}{term\_pattern\_string}~\}}}}}}
where
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{term\_pattern\_string}}}} is a term\_pattern, a string, or a string followed
by a scope delimiting key \sphinxtitleref{\%key}.  This generalization of \sphinxcode{\sphinxupquote{Search}} searches
for all objects whose statement or type contains a subterm matching
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{term\_pattern}}}} (or \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} if \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} is the notation for a reference
qualid) and whose name contains all string of the request that
correspond to valid identifiers. If a term\_pattern or a string is
prefixed by \sphinxtitleref{-}, the search excludes the objects that mention that
term\_pattern or that string.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Search~\DUrole{hole}{term\_pattern\_string}~…~\DUrole{hole}{term\_pattern\_string}~inside~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
This restricts the search to constructions defined in the modules
named by the given \sphinxcode{\sphinxupquote{\DUrole{notation}{qualid}}} sequence.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Search~\DUrole{hole}{term\_pattern\_string}~…~\DUrole{hole}{term\_pattern\_string}~outside~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
This restricts the search to constructions not defined in the modules
named by the given \sphinxcode{\sphinxupquote{\DUrole{notation}{qualid}}} sequence.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-selector}]{\sphinxcrossref{\DUrole{hole}{selector}}}}:~Search~{[}-{]}\DUrole{hole}{term\_pattern\_string}~…~{[}-{]}\DUrole{hole}{term\_pattern\_string}}}}}
This specifies the goal on which to search hypothesis (see
Section {\hyperref[\detokenize{proof-engine/tactics:invocation-of-tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Invocation of tactics}}}}).
By default the 1st goal is searched. This variant can
be combined with other variants presented here.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{ZArith}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Search} \PYG{n}{Z}\PYG{o}{.}\PYG{n}{mul} \PYG{n}{Z}\PYG{o}{.}\PYG{n}{add} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{distr}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    \PYG{n}{Z}\PYG{o}{.}\PYG{n}{mul\PYGZus{}add\PYGZus{}distr\PYGZus{}l}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{o}{:} \PYG{n}{Z}\PYG{o}{,} \PYG{o}{(}\PYG{n}{n} \PYG{o}{*} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z} \PYG{o}{=} \PYG{o}{(}\PYG{n}{n} \PYG{o}{*} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n} \PYG{o}{*} \PYG{n}{p}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z}
    \PYG{n}{Z}\PYG{o}{.}\PYG{n}{mul\PYGZus{}add\PYGZus{}distr\PYGZus{}r}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{o}{:} \PYG{n}{Z}\PYG{o}{,} \PYG{o}{(}\PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)} \PYG{o}{*} \PYG{n}{p}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z} \PYG{o}{=} \PYG{o}{(}\PYG{n}{n} \PYG{o}{*} \PYG{n}{p} \PYG{o}{+} \PYG{n}{m} \PYG{o}{*} \PYG{n}{p}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z}
    \PYG{n}{fast\PYGZus{}Zmult\PYGZus{}plus\PYGZus{}distr\PYGZus{}l}\PYG{o}{:}
      \PYG{k}{forall} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{o}{:} \PYG{n}{Z}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{n}{Z} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,}
      \PYG{n}{P} \PYG{o}{(}\PYG{n}{n} \PYG{o}{*} \PYG{n}{p} \PYG{o}{+} \PYG{n}{m} \PYG{o}{*} \PYG{n}{p}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{(}\PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)} \PYG{o}{*} \PYG{n}{p}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z}

\PYG{k+kn}{Search} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{+}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{\PYGZpc{}}\PYG{n}{Z} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{*}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{\PYGZpc{}}\PYG{n}{Z} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{distr}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{\PYGZhy{}}\PYG{n}{positive} \PYG{o}{\PYGZhy{}}\PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{Z}\PYG{o}{.}\PYG{n}{mul\PYGZus{}add\PYGZus{}distr\PYGZus{}l}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{o}{:} \PYG{n}{Z}\PYG{o}{,} \PYG{o}{(}\PYG{n}{n} \PYG{o}{*} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z} \PYG{o}{=} \PYG{o}{(}\PYG{n}{n} \PYG{o}{*} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n} \PYG{o}{*} \PYG{n}{p}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z}
    \PYG{n}{Z}\PYG{o}{.}\PYG{n}{mul\PYGZus{}add\PYGZus{}distr\PYGZus{}r}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{o}{:} \PYG{n}{Z}\PYG{o}{,} \PYG{o}{(}\PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)} \PYG{o}{*} \PYG{n}{p}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z} \PYG{o}{=} \PYG{o}{(}\PYG{n}{n} \PYG{o}{*} \PYG{n}{p} \PYG{o}{+} \PYG{n}{m} \PYG{o}{*} \PYG{n}{p}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z}

\PYG{k+kn}{Search} \PYG{o}{(}\PYG{o}{?}\PYG{n}{x} \PYG{o}{*} \PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{o}{?}\PYG{n}{x} \PYG{o}{*} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z} \PYG{k+kn}{outside} \PYG{n}{OmegaLemmas}\PYG{o}{.}
    \PYG{n}{Z}\PYG{o}{.}\PYG{n}{mul\PYGZus{}add\PYGZus{}distr\PYGZus{}l}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{o}{:} \PYG{n}{Z}\PYG{o}{,} \PYG{o}{(}\PYG{n}{n} \PYG{o}{*} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z} \PYG{o}{=} \PYG{o}{(}\PYG{n}{n} \PYG{o}{*} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n} \PYG{o}{*} \PYG{n}{p}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{Z}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}

\index{SearchAbout (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmdv.searchabout}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SearchAbout}}}}~
\DUrole{versionmodified}{Deprecated since version 8.5.}

Up to \DUrole{smallcaps}{Coq} version 8.4, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}} had the behavior of current
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.searchhead}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{SearchHead}}}}} and the behavior of current {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}} was obtained with
command {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmdv.searchabout}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{SearchAbout}}}}}. For compatibility, the deprecated name
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmdv.searchabout}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{SearchAbout}}}}} can still be used as a synonym of {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}}. For
compatibility, the list of objects to search when using {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmdv.searchabout}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{SearchAbout}}}}}
may also be enclosed by optional \sphinxcode{\sphinxupquote{{[} {]}}} delimiters.

\end{fulllineitems}


\end{fulllineitems}

\index{SearchHead (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.searchhead}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SearchHead~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This command displays the name and type of all hypothesis of the
current goal (if any) and theorems of the current context whose
statement’s conclusion has the form \sphinxtitleref{(term t1 .. tn)}. This command is
useful to remind the user of the name of library lemmas.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{SearchHead} \PYG{n}{le}\PYG{o}{.}
    \PYG{n}{le\PYGZus{}n}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}
    \PYG{n}{le\PYGZus{}0\PYGZus{}n}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}
    \PYG{n}{le\PYGZus{}S}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{S} \PYG{n}{m}
    \PYG{n}{le\PYGZus{}pred}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{pred} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{pred} \PYG{n}{m}
    \PYG{n}{le\PYGZus{}n\PYGZus{}S}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{S} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{S} \PYG{n}{m}
    \PYG{n}{le\PYGZus{}S\PYGZus{}n}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{S} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{S} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m}

\PYG{n}{SearchHead} \PYG{o}{(}\PYG{o}{@}\PYG{n}{eq} \PYG{k+kt}{bool}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{andb\PYGZus{}true\PYGZus{}intro}\PYG{o}{:}
      \PYG{k}{forall} \PYG{n}{b1} \PYG{n}{b2} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{n}{b1} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{/\PYGZbs{}} \PYG{n}{b2} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b2}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{k+kt}{bool} \PYG{o}{=} \PYG{n+nb+bp}{true}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SearchHead~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~inside~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
This restricts the search to constructions defined in the modules named
by the given \sphinxcode{\sphinxupquote{\DUrole{notation}{qualid}}} sequence.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SearchHead~term~outside~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
This restricts the search to constructions not defined in the modules
named by the given \sphinxcode{\sphinxupquote{\DUrole{notation}{qualid}}} sequence.

\end{fulllineitems}

\index{Module/section ‘qualid’ not found (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.module-section-qualid-not-found}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Module/section~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~not~found.}}}}
No module \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} has been required (see Section {\hyperref[\detokenize{proof-engine/vernacular-commands:compiled-files}]{\sphinxcrossref{\DUrole{std,std-ref}{Compiled files}}}}).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-selector}]{\sphinxcrossref{\DUrole{hole}{selector}}}}:~SearchHead~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This specifies the goal on which to
search hypothesis (see Section {\hyperref[\detokenize{proof-engine/tactics:invocation-of-tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Invocation of tactics}}}}).
By default the 1st goal is searched. This variant can be combined
with other variants presented here.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}
Up to \DUrole{smallcaps}{Coq} version 8.4, \sphinxcode{\sphinxupquote{SearchHead}} was named \sphinxcode{\sphinxupquote{Search}}.
\end{sphinxadmonition}

\end{fulllineitems}

\index{SearchPattern (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.searchpattern}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SearchPattern~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This command displays the name and type of all hypothesis of the
current goal (if any) and theorems of the current context whose
statement’s conclusion or last hypothesis and conclusion matches the
expressionterm where holes in the latter are denoted by \sphinxtitleref{\_}.
It is a variant of \sphinxcode{\sphinxupquote{\DUrole{notation}{Search \DUrole{hole}{term\_pattern}}}} that does not look for subterms
but searches for statements whose conclusion has exactly the expected
form, or whose statement finishes by the given series of
hypothesis/conclusion.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Arith}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{SearchPattern} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{o}{\PYGZus{}} \PYG{o}{=} \PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}comm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{=} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n}
    \PYG{n}{plus\PYGZus{}Snm\PYGZus{}nSm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{S} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{S} \PYG{n}{m}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}succ\PYGZus{}comm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{S} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{S} \PYG{n}{m}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}shuffle3}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)} \PYG{o}{=} \PYG{n}{m} \PYG{o}{+} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)}
    \PYG{n}{plus\PYGZus{}assoc\PYGZus{}reverse}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{+} \PYG{n}{p} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}assoc}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{+} \PYG{n}{p}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}shuffle0}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{+} \PYG{n}{p} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{p} \PYG{o}{+} \PYG{n}{m}
    \PYG{n}{f\PYGZus{}equal2\PYGZus{}plus}\PYG{o}{:}
      \PYG{k}{forall} \PYG{n}{x1} \PYG{n}{y1} \PYG{n}{x2} \PYG{n}{y2} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x1} \PYG{o}{=} \PYG{n}{y1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x2} \PYG{o}{=} \PYG{n}{y2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x1} \PYG{o}{+} \PYG{n}{x2} \PYG{o}{=} \PYG{n}{y1} \PYG{o}{+} \PYG{n}{y2}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}shuffle2}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{n}{q} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{+} \PYG{o}{(}\PYG{n}{p} \PYG{o}{+} \PYG{n}{q}\PYG{o}{)} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{q} \PYG{o}{+} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}shuffle1}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{n}{q} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{+} \PYG{o}{(}\PYG{n}{p} \PYG{o}{+} \PYG{n}{q}\PYG{o}{)} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{p} \PYG{o}{+} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{q}\PYG{o}{)}

\PYG{n}{SearchPattern} \PYG{o}{(}\PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{odd}\PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{Init}\PYG{o}{.}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{odd}\PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{even}\PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{Init}\PYG{o}{.}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{even}\PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{Init}\PYG{o}{.}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit}\PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{leb}\PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{eqb}\PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{Init}\PYG{o}{.}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{eqb}\PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{ltb}\PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit}\PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{Init}\PYG{o}{.}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{leb}\PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{Init}\PYG{o}{.}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{ltb}\PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{BinNat}\PYG{o}{.}\PYG{n}{N}\PYG{o}{.}\PYG{n}{testbit\PYGZus{}nat}\PYG{o}{:} \PYG{n}{BinNums}\PYG{o}{.}\PYG{n}{N} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{BinPosDef}\PYG{o}{.}\PYG{n}{Pos}\PYG{o}{.}\PYG{n}{testbit\PYGZus{}nat}\PYG{o}{:} \PYG{n}{BinNums}\PYG{o}{.}\PYG{n}{positive} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{BinPos}\PYG{o}{.}\PYG{n}{Pos}\PYG{o}{.}\PYG{n}{testbit\PYGZus{}nat}\PYG{o}{:} \PYG{n}{BinNums}\PYG{o}{.}\PYG{n}{positive} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    \PYG{n}{BinNatDef}\PYG{o}{.}\PYG{n}{N}\PYG{o}{.}\PYG{n}{testbit\PYGZus{}nat}\PYG{o}{:} \PYG{n}{BinNums}\PYG{o}{.}\PYG{n}{N} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}

\PYG{n}{SearchPattern} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{o}{\PYGZus{}}\PYG{o}{,} \PYG{o}{\PYGZus{}} \PYG{n}{l} \PYG{n}{l}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{List}\PYG{o}{.}\PYG{n}{incl\PYGZus{}refl}\PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{)}\PYG{o}{,} \PYG{n}{List}\PYG{o}{.}\PYG{n}{incl} \PYG{n}{l} \PYG{n}{l}
    \PYG{n}{List}\PYG{o}{.}\PYG{n}{lel\PYGZus{}refl}\PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{)}\PYG{o}{,} \PYG{n}{List}\PYG{o}{.}\PYG{n}{lel} \PYG{n}{l} \PYG{n}{l}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Patterns need not be linear: you can express that the same expression
must occur in two places by using pattern variables \sphinxtitleref{?ident}.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{SearchPattern} \PYG{o}{(}\PYG{o}{?}\PYG{n}{X1} \PYG{o}{+} \PYG{o}{\PYGZus{}} \PYG{o}{=} \PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{o}{?}\PYG{n}{X1}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}comm}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{=} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SearchPattern~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~inside~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
This restricts the search to constructions defined in the modules
named by the given \sphinxcode{\sphinxupquote{\DUrole{notation}{qualid}}} sequence.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SearchPattern~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~outside~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
This restricts the search to constructions not defined in the modules
named by the given \sphinxcode{\sphinxupquote{\DUrole{notation}{qualid}}} sequence.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-selector}]{\sphinxcrossref{\DUrole{hole}{selector}}}}:~SearchPattern~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This specifies the goal on which to
search hypothesis (see Section {\hyperref[\detokenize{proof-engine/tactics:invocation-of-tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Invocation of tactics}}}}).
By default the 1st goal is
searched. This variant can be combined with other variants presented
here.

\end{fulllineitems}


\end{fulllineitems}

\index{SearchRewrite (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.searchrewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SearchRewrite~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This command displays the name and type of all hypothesis of the
current goal (if any) and theorems of the current context whose
statement’s conclusion is an equality of which one side matches the
expression term. Holes in term are denoted by “\_”.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Arith}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{SearchRewrite} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}shuffle0}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{+} \PYG{n}{p} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{p} \PYG{o}{+} \PYG{n}{m}
    \PYG{n}{plus\PYGZus{}assoc\PYGZus{}reverse}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{+} \PYG{n}{p} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}assoc}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{+} \PYG{n}{p}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}shuffle1}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{n}{q} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{+} \PYG{o}{(}\PYG{n}{p} \PYG{o}{+} \PYG{n}{q}\PYG{o}{)} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{p} \PYG{o}{+} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{q}\PYG{o}{)}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}shuffle2}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{n}{q} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{+} \PYG{o}{(}\PYG{n}{p} \PYG{o}{+} \PYG{n}{q}\PYG{o}{)} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{q} \PYG{o}{+} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)}
    \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add\PYGZus{}carry\PYGZus{}div2}\PYG{o}{:}
      \PYG{k}{forall} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{c0} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)}\PYG{o}{,}
      \PYG{o}{(}\PYG{n}{a} \PYG{o}{+} \PYG{n}{b} \PYG{o}{+} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{b2n} \PYG{n}{c0}\PYG{o}{)} \PYG{o}{/} \PYG{l+m+mi}{2} \PYG{o}{=}
      \PYG{n}{a} \PYG{o}{/} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{n}{b} \PYG{o}{/} \PYG{l+m+mi}{2} \PYG{o}{+}
      \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{b2n}
        \PYG{o}{(}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit} \PYG{n}{a} \PYG{l+m+mi}{0} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit} \PYG{n}{b} \PYG{l+m+mi}{0}
         \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{c0} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{o}{(}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit} \PYG{n}{a} \PYG{l+m+mi}{0} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{testbit} \PYG{n}{b} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SearchRewrite~term~inside~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
This restricts the search to constructions defined in the modules
named by the given \sphinxcode{\sphinxupquote{\DUrole{notation}{qualid}}} sequence.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SearchRewrite~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~outside~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
This restricts the search to constructions not defined in the modules
named by the given \sphinxcode{\sphinxupquote{\DUrole{notation}{qualid}}} sequence.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-selector}]{\sphinxcrossref{\DUrole{hole}{selector}}}}:~SearchRewrite~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This specifies the goal on which to
search hypothesis (see Section {\hyperref[\detokenize{proof-engine/tactics:invocation-of-tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Invocation of tactics}}}}).
By default the 1st goal is
searched. This variant can be combined with other variants presented
here.

\end{fulllineitems}


\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}\index{Search Blacklist ‘string’ (table)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:table.search-blacklist-string}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Table}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Search~Blacklist~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
Specifies a set of strings used to exclude lemmas from the results of {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}},
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.searchhead}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{SearchHead}}}}}, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.searchpattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{SearchPattern}}}}} and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.searchrewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{SearchRewrite}}}}} queries.  A lemma whose
fully-qualified name contains any of the strings will be excluded from the
search results.  The default blacklisted substrings are \sphinxcode{\sphinxupquote{\_subterm}}, \sphinxcode{\sphinxupquote{\_subproof}} and
\sphinxcode{\sphinxupquote{Private\_}}.

Use the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.add-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add @table}}}}} and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.remove-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove @table}}}}} commands to update the set of
blacklisted strings.

\end{fulllineitems}

\end{sphinxadmonition}
\index{Locate (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.locate}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Locate~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This command displays the full name of objects whose name is a prefix
of the qualified identifier \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}, and consequently the \DUrole{smallcaps}{Coq} module in
which they are defined. It searches for objects from the different
qualified namespaces of \DUrole{smallcaps}{Coq}: terms, modules, Ltac, etc.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Locate} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{k+kn}{Inductive} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Datatypes}\PYG{o}{.}\PYG{k+kt}{nat}

\PYG{n}{Locate} \PYG{n}{Datatypes}\PYG{o}{.}\PYG{n}{O}\PYG{o}{.}
    \PYG{n}{Constructor} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Datatypes}\PYG{o}{.}\PYG{n}{O}
      \PYG{o}{(}\PYG{n}{shorter} \PYG{n}{name} \PYG{n}{to} \PYG{n}{refer} \PYG{n}{to} \PYG{n}{it} \PYG{k}{in} \PYG{n}{current} \PYG{n}{context} \PYG{k}{is} \PYG{n}{O}\PYG{o}{)}

\PYG{n}{Locate} \PYG{n}{Init}\PYG{o}{.}\PYG{n}{Datatypes}\PYG{o}{.}\PYG{n}{O}\PYG{o}{.}
    \PYG{n}{Constructor} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Datatypes}\PYG{o}{.}\PYG{n}{O}
      \PYG{o}{(}\PYG{n}{shorter} \PYG{n}{name} \PYG{n}{to} \PYG{n}{refer} \PYG{n}{to} \PYG{n}{it} \PYG{k}{in} \PYG{n}{current} \PYG{n}{context} \PYG{k}{is} \PYG{n}{O}\PYG{o}{)}

\PYG{n}{Locate} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Datatypes}\PYG{o}{.}\PYG{n}{O}\PYG{o}{.}
    \PYG{n}{Constructor} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Datatypes}\PYG{o}{.}\PYG{n}{O}
      \PYG{o}{(}\PYG{n}{shorter} \PYG{n}{name} \PYG{n}{to} \PYG{n}{refer} \PYG{n}{to} \PYG{n}{it} \PYG{k}{in} \PYG{n}{current} \PYG{n}{context} \PYG{k}{is} \PYG{n}{O}\PYG{o}{)}

\PYG{n}{Locate} \PYG{n}{I}\PYG{o}{.}\PYG{n}{Dont}\PYG{o}{.}\PYG{n}{Exist}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{object} \PYG{k}{of} \PYG{n}{suffix} \PYG{n}{I}\PYG{o}{.}\PYG{n}{Dont}\PYG{o}{.}\PYG{n}{Exist}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Locate~Term~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
As Locate but restricted to terms.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Locate~Module~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
As Locate but restricted to modules.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Locate~Ltac~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
As Locate but restricted to tactics.

\end{fulllineitems}


\end{fulllineitems}



\sphinxstrong{See also:}


Section {\hyperref[\detokenize{user-extensions/syntax-extensions:locating-notations}]{\sphinxcrossref{\DUrole{std,std-ref}{Locating notations}}}}




\subsection{Loading files}
\label{\detokenize{proof-engine/vernacular-commands:loading-files}}\label{\detokenize{proof-engine/vernacular-commands:id3}}
\DUrole{smallcaps}{Coq} offers the possibility of loading different parts of a whole
development stored in separate files. Their contents will be loaded as
if they were entered from the keyboard. This means that the loaded
files are ASCII files containing sequences of commands for \DUrole{smallcaps}{Coq}’s
toplevel. This kind of file is called a \sphinxstyleemphasis{script} for \DUrole{smallcaps}{Coq}. The standard
(and default) extension of \DUrole{smallcaps}{Coq}’s script files is .v.
\index{Load (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.load}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Load~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This command loads the file named \sphinxcode{\sphinxupquote{\DUrole{notation}{ident}}}.v, searching successively in
each of the directories specified in the \sphinxstyleemphasis{loadpath}. (see Section
{\hyperref[\detokenize{language/gallina-extensions:libraries-and-filesystem}]{\sphinxcrossref{\DUrole{std,std-ref}{Libraries and filesystem}}}})

Files loaded this way cannot leave proofs open, and the \sphinxcode{\sphinxupquote{Load}}
command cannot be used inside a proof either.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Load~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
Loads the file denoted by the string \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}, where
string is any complete filename. Then the \sphinxtitleref{\textasciitilde{}} and .. abbreviations are
allowed as well as shell variables. If no extension is specified, \DUrole{smallcaps}{Coq}
will use the default extension \sphinxcode{\sphinxupquote{.v}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Load~Verbose~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Load~Verbose~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
Display, while loading,
the answers of \DUrole{smallcaps}{Coq} to each command (including tactics) contained in
the loaded file.


\sphinxstrong{See also:}


Section {\hyperref[\detokenize{proof-engine/vernacular-commands:controlling-display}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling display}}}}.



\end{fulllineitems}

\index{Can’t find file ‘ident’ on loadpath (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.cant-find-file-ident-on-loadpath}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Can’t~find~file~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~on~loadpath.}}}}
\end{fulllineitems}

\index{Load is not supported inside proofs (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.load-is-not-supported-inside-proofs}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Load~is~not~supported~inside~proofs.}}}}
\end{fulllineitems}

\index{Files processed by Load cannot leave open proofs (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.files-processed-by-load-cannot-leave-open-proofs}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Files~processed~by~Load~cannot~leave~open~proofs.}}}}
\end{fulllineitems}


\end{fulllineitems}



\subsection{Compiled files}
\label{\detokenize{proof-engine/vernacular-commands:compiled-files}}\label{\detokenize{proof-engine/vernacular-commands:id4}}
This section describes the commands used to load compiled files (see
Chapter {\hyperref[\detokenize{practical-tools/coq-commands:thecoqcommands}]{\sphinxcrossref{\DUrole{std,std-ref}{The Coq commands}}}} for documentation on how to compile a file). A compiled
file is a particular case of module called \sphinxstyleemphasis{library file}.
\index{Require (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.require}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Require~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This command looks in the loadpath for a file containing module \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}
and adds the corresponding module to the environment of \DUrole{smallcaps}{Coq}. As
library files have dependencies in other library files, the command
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} recursively requires all library files the module
qualid depends on and adds the corresponding modules to the
environment of \DUrole{smallcaps}{Coq} too. \DUrole{smallcaps}{Coq} assumes that the compiled files have been
produced by a valid \DUrole{smallcaps}{Coq} compiler and their contents are then not
replayed nor rechecked.

To locate the file in the file system, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} is decomposed under the
form \sphinxtitleref{dirpath.ident} and the file \sphinxtitleref{ident.vo} is searched in the physical
directory of the file system that is mapped in \DUrole{smallcaps}{Coq} loadpath to the
logical path dirpath (see Section {\hyperref[\detokenize{language/gallina-extensions:libraries-and-filesystem}]{\sphinxcrossref{\DUrole{std,std-ref}{Libraries and filesystem}}}}). The mapping between
physical directories and logical names at the time of requiring the
file must be consistent with the mapping used to compile the file. If
several files match, one of them is picked in an unspecified fashion.
\index{Require Import (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmdv.require-import}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Require~Import~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This loads and declares the module \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}
and its dependencies then imports the contents of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} as described
{\hyperref[\detokenize{language/gallina-extensions:import-qualid}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}}. It does not import the modules on which
qualid depends unless these modules were themselves required in module
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}
using {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmdv.require-export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require Export}}}}}, as described below, or recursively required
through a sequence of {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmdv.require-export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require Export}}}}}.  If the module required has
already been loaded, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmdv.require-import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require Import}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} simply imports it, as
{\hyperref[\detokenize{language/gallina-extensions:coq:cmd.import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} would.

\end{fulllineitems}

\index{Require Export (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmdv.require-export}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Require~Export~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This command acts as {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmdv.require-import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require Import}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}},
but if a further module, say \sphinxtitleref{A}, contains a command {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmdv.require-export}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require Export}}}}} \sphinxtitleref{B},
then the command {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmdv.require-import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require Import}}}}} \sphinxtitleref{A} also imports the module \sphinxtitleref{B.}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Require~{[}Import~\textbar{}~Export{]}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
This loads the
modules named by the \sphinxcode{\sphinxupquote{\DUrole{notation}{qualid}}} sequence and their recursive
dependencies. If
\sphinxcode{\sphinxupquote{Import}} or \sphinxcode{\sphinxupquote{Export}} is given, it also imports these modules and
all the recursive dependencies that were marked or transitively marked
as \sphinxcode{\sphinxupquote{Export}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{From~\DUrole{hole}{dirpath}~Require~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This command acts as {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.require}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Require}}}}}, but picks
any library whose absolute name is of the form dirpath.dirpath’.qualid
for some \sphinxtitleref{dirpath’}. This is useful to ensure that the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} library
comes from a given package by making explicit its absolute root.

\end{fulllineitems}

\index{Cannot load qualid: no physical path bound to dirpath (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.cannot-load-qualid-no-physical-path-bound-to-dirpath}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~load~qualid:~no~physical~path~bound~to~dirpath.}}}}
\end{fulllineitems}

\index{Cannot find library foo in loadpath (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.cannot-find-library-foo-in-loadpath}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~find~library~foo~in~loadpath.}}}}
The command did not find the
file foo.vo. Either foo.v exists but is not compiled or foo.vo is in a
directory which is not in your LoadPath (see Section {\hyperref[\detokenize{language/gallina-extensions:libraries-and-filesystem}]{\sphinxcrossref{\DUrole{std,std-ref}{Libraries and filesystem}}}}).

\end{fulllineitems}

\index{Compiled library ‘ident’.vo makes inconsistent assumptions over library qualid (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.compiled-library-ident-vo-makes-inconsistent-assumptions-over-library-qualid}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Compiled~library~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.vo~makes~inconsistent~assumptions~over~library~qualid.}}}}
The command tried to load library file \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.vo that
depends on some specific version of library \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} which is not the
one already loaded in the current \DUrole{smallcaps}{Coq} session. Probably \sphinxtitleref{ident.v} was
not properly recompiled with the last version of the file containing
module \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.

\end{fulllineitems}

\index{Bad magic number (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.bad-magic-number}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Bad~magic~number.}}}}
The file \sphinxtitleref{ident.vo} was found but either it is not a
\DUrole{smallcaps}{Coq} compiled module, or it was compiled with an incompatible
version of \DUrole{smallcaps}{Coq}.

\end{fulllineitems}

\index{The file {}`ident.vo{}` contains library dirpath and not library dirpath’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.the-file-ident-vo-contains-library-dirpath-and-not-library-dirpath}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~file~{}`ident.vo{}`~contains~library~dirpath~and~not~library~dirpath’.}}}}
The library file \sphinxtitleref{dirpath’} is indirectly required by the
\sphinxcode{\sphinxupquote{Require}} command but it is bound in the current loadpath to the
file \sphinxtitleref{ident.vo} which was bound to a different library name \sphinxtitleref{dirpath} at
the time it was compiled.

\end{fulllineitems}

\index{Require is not allowed inside a module or a module type (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.require-is-not-allowed-inside-a-module-or-a-module-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Require~is~not~allowed~inside~a~module~or~a~module~type.}}}}
This command
is not allowed inside a module or a module type being defined. It is
meant to describe a dependency between compilation units. Note however
that the commands \sphinxcode{\sphinxupquote{Import}} and \sphinxcode{\sphinxupquote{Export}} alone can be used inside modules
(see Section {\hyperref[\detokenize{language/gallina-extensions:import-qualid}]{\sphinxcrossref{\DUrole{std,std-ref}{Import}}}}).


\sphinxstrong{See also:}


Chapter {\hyperref[\detokenize{practical-tools/coq-commands:thecoqcommands}]{\sphinxcrossref{\DUrole{std,std-ref}{The Coq commands}}}}



\end{fulllineitems}


\end{fulllineitems}

\index{Print Libraries (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.print-libraries}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Libraries}}}}
This command displays the list of library files loaded in the
current \DUrole{smallcaps}{Coq} session. For each of these libraries, it also tells if it
is imported.

\end{fulllineitems}

\index{Declare ML Module (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.declare-ml-module}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~ML~Module~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{+}}}}}}
This commands loads the OCaml compiled files
with names given by the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} sequence
(dynamic link). It is mainly used to load tactics dynamically. The
files are searched into the current OCaml loadpath (see the
command \sphinxcode{\sphinxupquote{Add ML Path}} in Section {\hyperref[\detokenize{language/gallina-extensions:libraries-and-filesystem}]{\sphinxcrossref{\DUrole{std,std-ref}{Libraries and filesystem}}}}).
Loading of OCaml files is only possible under the bytecode version of
\sphinxcode{\sphinxupquote{coqtop}} (i.e. \sphinxcode{\sphinxupquote{coqtop}} called with option \sphinxcode{\sphinxupquote{-byte}}, see chapter
{\hyperref[\detokenize{practical-tools/coq-commands:thecoqcommands}]{\sphinxcrossref{\DUrole{std,std-ref}{The Coq commands}}}}), or when \DUrole{smallcaps}{Coq} has been compiled with a
version of OCaml that supports native Dynlink (≥ 3.11).


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Declare~ML~Module~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{+}}}}}}
This variant is not exported to the modules that import the module
where they occur, even if outside a section.

\end{fulllineitems}

\index{File not found on loadpath: ‘string’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.file-not-found-on-loadpath-string}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{File~not~found~on~loadpath:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}.}}}}
\end{fulllineitems}

\index{Loading of ML object file forbidden in a native Coq (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.loading-of-ml-object-file-forbidden-in-a-native-coq}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Loading~of~ML~object~file~forbidden~in~a~native~Coq.}}}}
\end{fulllineitems}


\end{fulllineitems}

\index{Print ML Modules (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.print-ml-modules}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~ML~Modules}}}}
This prints the name of all OCaml modules loaded with \sphinxcode{\sphinxupquote{Declare
ML Module}}. To know from where these module were loaded, the user
should use the command \sphinxcode{\sphinxupquote{Locate File}} (see {\hyperref[\detokenize{proof-engine/vernacular-commands:locate-file}]{\sphinxcrossref{\DUrole{std,std-ref}{here}}}})

\end{fulllineitems}



\subsection{Loadpath}
\label{\detokenize{proof-engine/vernacular-commands:loadpath}}\label{\detokenize{proof-engine/vernacular-commands:id5}}
Loadpaths are preferably managed using \DUrole{smallcaps}{Coq} command line options (see
Section \sphinxtitleref{libraries-and-filesystem}) but there remain vernacular commands to manage them
for practical purposes. Such commands are only meant to be issued in
the toplevel, and using them in source files is discouraged.
\index{Pwd (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.pwd}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Pwd}}}}
This command displays the current working directory.

\end{fulllineitems}

\index{Cd (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.cd}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cd~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
This command changes the current directory according to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} which
can be any valid path.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cd}}}}
Is equivalent to Pwd.

\end{fulllineitems}


\end{fulllineitems}

\index{Add LoadPath (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.add-loadpath}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~LoadPath~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~as~\DUrole{hole}{dirpath}}}}}
This command is equivalent to the command line option
\sphinxcode{\sphinxupquote{-Q}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{dirpath}}}}. It adds the physical directory string to the current
\DUrole{smallcaps}{Coq} loadpath and maps it to the logical directory dirpath.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~LoadPath~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
Performs as Add LoadPath \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} as \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{dirpath}}}} but
for the empty directory path.

\end{fulllineitems}


\end{fulllineitems}

\index{Add Rec LoadPath (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.add-rec-loadpath}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~Rec~LoadPath~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~as~\DUrole{hole}{dirpath}}}}}
This command is equivalent to the command line option
\sphinxcode{\sphinxupquote{-R}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{dirpath}}}}. It adds the physical directory string and all its
subdirectories to the current \DUrole{smallcaps}{Coq} loadpath.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~Rec~LoadPath~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
Works as {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.add-rec-loadpath}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add Rec LoadPath}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} as \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{dirpath}}}} but for the empty
logical directory path.

\end{fulllineitems}


\end{fulllineitems}

\index{Remove LoadPath (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.remove-loadpath}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Remove~LoadPath~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
This command removes the path \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} from the current \DUrole{smallcaps}{Coq} loadpath.

\end{fulllineitems}

\index{Print LoadPath (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.print-loadpath}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~LoadPath}}}}
This command displays the current \DUrole{smallcaps}{Coq} loadpath.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~LoadPath~\DUrole{hole}{dirpath}}}}}
Works as {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.print-loadpath}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print LoadPath}}}}} but displays only
the paths that extend the \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{dirpath}}}} prefix.

\end{fulllineitems}


\end{fulllineitems}

\index{Add ML Path (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.add-ml-path}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~ML~Path~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
This command adds the path \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} to the current OCaml
loadpath (see the command \sphinxtitleref{Declare ML Module{}`} in Section {\hyperref[\detokenize{proof-engine/vernacular-commands:compiled-files}]{\sphinxcrossref{\DUrole{std,std-ref}{Compiled files}}}}).

\end{fulllineitems}

\index{Add Rec ML Path (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.add-rec-ml-path}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~Rec~ML~Path~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
This command adds the directory \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} and all its subdirectories to
the current OCaml loadpath (see the command {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.declare-ml-module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Declare ML Module}}}}}).

\end{fulllineitems}

\index{Print ML Path (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.print-ml-path}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~ML~Path~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
This command displays the current OCaml loadpath. This
command makes sense only under the bytecode version of \sphinxcode{\sphinxupquote{coqtop}}, i.e.
using option \sphinxcode{\sphinxupquote{-byte}}
(see the command Declare ML Module in Section {\hyperref[\detokenize{proof-engine/vernacular-commands:compiled-files}]{\sphinxcrossref{\DUrole{std,std-ref}{Compiled files}}}}).

\end{fulllineitems}

\phantomsection\label{\detokenize{proof-engine/vernacular-commands:locate-file}}\index{Locate File (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.locate-file}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Locate~File~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
This command displays the location of file string in the current
loadpath. Typically, string is a .cmo or .vo or .v file.

\end{fulllineitems}

\index{Locate Library (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.locate-library}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Locate~Library~\DUrole{hole}{dirpath}}}}}
This command gives the status of the \DUrole{smallcaps}{Coq} module dirpath. It tells if
the module is loaded and if not searches in the load path for a module
of logical name \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{dirpath}}}}.

\end{fulllineitems}



\subsection{Backtracking}
\label{\detokenize{proof-engine/vernacular-commands:backtracking}}\label{\detokenize{proof-engine/vernacular-commands:id6}}
The backtracking commands described in this section can only be used
interactively, they cannot be part of a vernacular file loaded via
\sphinxcode{\sphinxupquote{Load}} or compiled by \sphinxcode{\sphinxupquote{coqc}}.
\index{Reset (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.reset}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Reset~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This command removes all the objects in the environment since \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
was introduced, including \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} may be the name of a defined or
declared object as well as the name of a section. One cannot reset
over the name of a module or of an object inside a module.
\index{‘ident’: no such entry (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.ident-no-such-entry}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}:~no~such~entry.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Reset~Initial}}}}
Goes back to the initial state, just after the start
of the interactive session.

\end{fulllineitems}


\end{fulllineitems}

\index{Back (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.back}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Back}}}}
This command undoes all the effects of the last vernacular command.
Commands read from a vernacular file via a {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.load}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Load}}}}} are considered as a
single command. Proof management commands are also handled by this
command (see Chapter {\hyperref[\detokenize{proof-engine/proof-handling:proofhandling}]{\sphinxcrossref{\DUrole{std,std-ref}{Proof handling}}}}). For that, Back may have to undo more than
one command in order to reach a state where the proof management
information is available. For instance, when the last command is a
{\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}}, the management information about the closed proof has been
discarded. In this case, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.back}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Back}}}}} will then undo all the proof steps up to
the statement of this proof.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Back~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
Undo \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} vernacular commands. As for Back, some extra
commands may be undone in order to reach an adequate state. For
instance Back \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} will not re-enter a closed proof, but rather go just
before that proof.

\end{fulllineitems}

\index{Invalid backtrack (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.invalid-backtrack}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Invalid~backtrack.}}}}
The user wants to undo more commands than available in the history.

\end{fulllineitems}


\end{fulllineitems}

\index{BackTo (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.backto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{BackTo~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This command brings back the system to the state labeled \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}},
forgetting the effect of all commands executed after this state. The
state label is an integer which grows after each successful command.
It is displayed in the prompt when in -emacs mode. Just as {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.back}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Back}}}}} (see
above), the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.backto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{BackTo}}}}} command now handles proof states. For that, it may
have to undo some extra commands and end on a state \sphinxtitleref{num′ ≤ num} if
necessary.
\index{Backtrack (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmdv.backtrack}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Backtrack~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}~
\DUrole{versionmodified}{Deprecated since version 8.4.}

{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmdv.backtrack}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Backtrack}}}}} is a \sphinxstyleemphasis{deprecated} form of
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.backto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{BackTo}}}}} which allows explicitly manipulating the proof environment. The
three numbers represent the following:
\begin{itemize}
\item {} 
\sphinxstyleemphasis{first number} : State label to reach, as for {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.backto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{BackTo}}}}}.

\item {} 
\sphinxstyleemphasis{second number} : \sphinxstyleemphasis{Proof state number} to unbury once aborts have been done.
\DUrole{smallcaps}{Coq} will compute the number of {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.undo}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Undo}}}}} to perform (see Chapter {\hyperref[\detokenize{proof-engine/proof-handling:proofhandling}]{\sphinxcrossref{\DUrole{std,std-ref}{Proof handling}}}}).

\item {} 
\sphinxstyleemphasis{third number} : Number of {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.abort}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Abort}}}}} to perform, i.e. the number of currently
opened nested proofs that must be canceled (see Chapter {\hyperref[\detokenize{proof-engine/proof-handling:proofhandling}]{\sphinxcrossref{\DUrole{std,std-ref}{Proof handling}}}}).

\end{itemize}

\end{fulllineitems}

\index{Invalid backtrack (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Invalid~backtrack.}}}}
The destination state label is unknown.

\end{fulllineitems}


\end{fulllineitems}



\subsection{Quitting and debugging}
\label{\detokenize{proof-engine/vernacular-commands:quitting-and-debugging}}\label{\detokenize{proof-engine/vernacular-commands:id7}}\index{Quit (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.quit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Quit}}}}
This command permits to quit \DUrole{smallcaps}{Coq}.

\end{fulllineitems}

\index{Drop (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.drop}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Drop}}}}
This is used mostly as a debug facility by \DUrole{smallcaps}{Coq}’s implementers and does
not concern the casual user. This command permits to leave \DUrole{smallcaps}{Coq}
temporarily and enter the OCaml toplevel. The OCaml
command:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZsh{}use \PYGZdq{}include\PYGZdq{};;
\end{sphinxVerbatim}

adds the right loadpaths and loads some toplevel printers for all
abstract types of \DUrole{smallcaps}{Coq}- section\_path, identifiers, terms, judgments, ….
You can also use the file base\_include instead, that loads only the
pretty-printers for section\_paths and identifiers. You can return back
to \DUrole{smallcaps}{Coq} with the command:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
go();;
\end{sphinxVerbatim}

\begin{sphinxadmonition}{warning}{Warning:}\begin{enumerate}
\def\theenumi{\arabic{enumi}}
\def\labelenumi{\theenumi .}
\makeatletter\def\p@enumii{\p@enumi \theenumi .}\makeatother
\item {} 
It only works with the bytecode version of \DUrole{smallcaps}{Coq} (i.e. \sphinxtitleref{coqtop.byte},
see Section \sphinxtitleref{interactive-use}).

\item {} 
You must have compiled \DUrole{smallcaps}{Coq} from the source package and set the
environment variable COQTOP to the root of your copy of the sources
(see Section \sphinxtitleref{customization-by-environment-variables}).

\end{enumerate}
\end{sphinxadmonition}

\end{fulllineitems}

\index{Time (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.time}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Time~\DUrole{hole}{command}}}}}
This command executes the vernacular command \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{command}}}} and displays the
time needed to execute it.

\end{fulllineitems}

\index{Redirect (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.redirect}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Redirect~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~\DUrole{hole}{command}}}}}
This command executes the vernacular command \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{command}}}}, redirecting its
output to "\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}.out".

\end{fulllineitems}

\index{Timeout (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.timeout}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Timeout~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~\DUrole{hole}{command}}}}}
This command executes the vernacular command \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{command}}}}. If the command
has not terminated after the time specified by the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} (time
expressed in seconds), then it is interrupted and an error message is
displayed.
\index{Default Timeout (opt)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:opt.default-timeout}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Default~Timeout~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This option controls a default timeout for subsequent commands, as if they
were passed to a {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.timeout}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Timeout}}}}} command. Commands already starting by a
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.timeout}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Timeout}}}}} are unaffected.

\end{fulllineitems}


\end{fulllineitems}

\index{Fail (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.fail}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Fail~\DUrole{hole}{command}}}}}
For debugging scripts, sometimes it is desirable to know
whether a command or a tactic fails. If the given \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{command}}}}
fails, the \sphinxcode{\sphinxupquote{Fail}} statement succeeds, without changing the proof
state, and in interactive mode, the system
prints a message confirming the failure.
If the given \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{command}}}} succeeds, the statement is an error, and
it prints a message indicating that the failure did not occur.
\index{The command has not failed"! (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.the-command-has-not-failed}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~command~has~not~failed!}}}}
\end{fulllineitems}


\end{fulllineitems}



\subsection{Controlling display}
\label{\detokenize{proof-engine/vernacular-commands:controlling-display}}\label{\detokenize{proof-engine/vernacular-commands:id8}}\index{Silent (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:flag.silent}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Silent}}}}
This option controls the normal displaying.

\end{fulllineitems}

\index{Warnings (opt)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:opt.warnings}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Warnings~"\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{meta}{(}~-~\DUrole{meta}{\textbar{}}~+~\DUrole{meta}{)}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}"}}}}
This option configures the display of warnings. It is experimental, and
expects, between quotes, a comma-separated list of warning names or
categories. Adding - in front of a warning or category disables it, adding +
makes it an error. It is possible to use the special categories all and
default, the latter containing the warnings enabled by default. The flags are
interpreted from left to right, so in case of an overlap, the flags on the
right have higher priority, meaning that \sphinxtitleref{A,-A} is equivalent to \sphinxtitleref{-A}.

\end{fulllineitems}

\index{Search Output Name Only (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:flag.search-output-name-only}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Search~Output~Name~Only}}}}
This option restricts the output of search commands to identifier names;
turning it on causes invocations of {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.search}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Search}}}}}, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.searchhead}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{SearchHead}}}}},
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.searchpattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{SearchPattern}}}}}, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.searchrewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{SearchRewrite}}}}} etc. to omit types from their
output, printing only identifiers.

\end{fulllineitems}

\index{Printing Width (opt)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:opt.printing-width}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Width~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This command sets which left-aligned part of the width of the screen is used
for display. At the time of writing this documentation, the default value
is 78.

\end{fulllineitems}

\index{Printing Depth (opt)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:opt.printing-depth}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Depth~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This option controls the nesting depth of the formatter used for pretty-
printing. Beyond this depth, display of subterms is replaced by dots. At the
time of writing this documentation, the default value is 50.

\end{fulllineitems}

\index{Printing Compact Contexts (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:flag.printing-compact-contexts}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Compact~Contexts}}}}
This option controls the compact display mode for goals contexts. When on,
the printer tries to reduce the vertical size of goals contexts by putting
several variables (even if of different types) on the same line provided it
does not exceed the printing width (see {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:opt.printing-width}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Width}}}}}). At the time
of writing this documentation, it is off by default.

\end{fulllineitems}

\index{Printing Unfocused (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:flag.printing-unfocused}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Unfocused}}}}
This option controls whether unfocused goals are displayed. Such goals are
created by focusing other goals with bullets (see {\hyperref[\detokenize{proof-engine/proof-handling:bullets}]{\sphinxcrossref{\DUrole{std,std-ref}{Bullets}}}} or
{\hyperref[\detokenize{proof-engine/proof-handling:curly-braces}]{\sphinxcrossref{\DUrole{std,std-ref}{curly braces}}}}). It is off by default.

\end{fulllineitems}

\index{Printing Dependent Evars Line (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:flag.printing-dependent-evars-line}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Dependent~Evars~Line}}}}
This option controls the printing of the “(dependent evars: …)” line when
\sphinxcode{\sphinxupquote{-emacs}} is passed.

\end{fulllineitems}



\subsection{Controlling the reduction strategies and the conversion algorithm}
\label{\detokenize{proof-engine/vernacular-commands:controlling-the-reduction-strategies-and-the-conversion-algorithm}}\label{\detokenize{proof-engine/vernacular-commands:vernac-controlling-the-reduction-strategies}}
\DUrole{smallcaps}{Coq} provides reduction strategies that the tactics can invoke and two
different algorithms to check the convertibility of types. The first
conversion algorithm lazily compares applicative terms while the other
is a brute-force but efficient algorithm that first normalizes the
terms before comparing them. The second algorithm is based on a
bytecode representation of terms similar to the bytecode
representation used in the ZINC virtual machine \sphinxcite{zebibliography:leroy90}. It is
especially useful for intensive computation of algebraic values, such
as numbers, and for reflection-based tactics. The commands to fine-
tune the reduction strategies and the lazy conversion algorithm are
described first.
\index{Opaque (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.opaque}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Opaque~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
This command has an effect on unfoldable constants, i.e. on constants
defined by {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}} or {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.let}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Let}}}}} (with an explicit body), or by a command
assimilated to a definition such as {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}}, {\hyperref[\detokenize{addendum/program:coq:cmd.program-definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Program Definition}}}}}, etc,
or by a proof ended by {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmdv.defined}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Defined}}}}}. The command tells not to unfold the
constants in the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} sequence in tactics using \(\delta\)-conversion (unfolding
a constant is replacing it by its definition).

{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}} has also an effect on the conversion algorithm of \DUrole{smallcaps}{Coq}, telling
it to delay the unfolding of a constant as much as possible when \DUrole{smallcaps}{Coq}
has to check the conversion (see Section {\hyperref[\detokenize{language/cic:conversion-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{Conversion rules}}}}) of two distinct
applied constants.
\index{Global Opaque (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmdv.global-opaque}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Global~Opaque~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
The scope of {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}} is limited to the current section, or current
file, unless the variant {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmdv.global-opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Global Opaque}}}}} is used.

\end{fulllineitems}



\sphinxstrong{See also:}


Sections {\hyperref[\detokenize{proof-engine/tactics:performingcomputations}]{\sphinxcrossref{\DUrole{std,std-ref}{Performing computations}}}}, {\hyperref[\detokenize{proof-engine/tactics:tactics-automating}]{\sphinxcrossref{\DUrole{std,std-ref}{Automating}}}},
{\hyperref[\detokenize{proof-engine/proof-handling:proof-editing-mode}]{\sphinxcrossref{\DUrole{std,std-ref}{Switching on/off the proof editing mode}}}}


\index{The reference ‘qualid’ was not found in the current environment (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~reference~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~was~not~found~in~the~current~environment.}}}}
There is no constant referred by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} in the environment.
Nevertheless, if you asked {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}} \sphinxtitleref{foo} \sphinxtitleref{bar} and if \sphinxtitleref{bar} does
not exist, \sphinxtitleref{foo} is set opaque.

\end{fulllineitems}


\end{fulllineitems}

\index{Transparent (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.transparent}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Transparent~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
This command is the converse of {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}} and it applies on unfoldable
constants to restore their unfoldability after an Opaque command.

Note in particular that constants defined by a proof ended by Qed are
not unfoldable and Transparent has no effect on them. This is to keep
with the usual mathematical practice of \sphinxstyleemphasis{proof irrelevance}: what
matters in a mathematical development is the sequence of lemma
statements, not their actual proofs. This distinguishes lemmas from
the usual defined constants, whose actual values are of course
relevant in general.
\index{Global Transparent (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmdv.global-transparent}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Global~Transparent~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
The scope of Transparent is limited to the current section, or current
file, unless the variant {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmdv.global-transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Global Transparent}}}}} is
used.

\end{fulllineitems}

\index{The reference ‘qualid’ was not found in the current environment (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~reference~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~was~not~found~in~the~current~environment.}}}}
There is no constant referred by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} in the environment.


\sphinxstrong{See also:}


Sections {\hyperref[\detokenize{proof-engine/tactics:performingcomputations}]{\sphinxcrossref{\DUrole{std,std-ref}{Performing computations}}}},
{\hyperref[\detokenize{proof-engine/tactics:tactics-automating}]{\sphinxcrossref{\DUrole{std,std-ref}{Automating}}}}, {\hyperref[\detokenize{proof-engine/proof-handling:proof-editing-mode}]{\sphinxcrossref{\DUrole{std,std-ref}{Switching on/off the proof editing mode}}}}



\end{fulllineitems}


\end{fulllineitems}

\phantomsection\label{\detokenize{proof-engine/vernacular-commands:vernac-strategy}}\index{Strategy (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.strategy}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Strategy~\DUrole{hole}{level}~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}~{]}}}}}
This command generalizes the behavior of Opaque and Transparent
commands. It is used to fine-tune the strategy for unfolding
constants, both at the tactic level and at the kernel level. This
command associates a level to the qualified names in the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}
sequence. Whenever two
expressions with two distinct head constants are compared (for
instance, this comparison can be triggered by a type cast), the one
with lower level is expanded first. In case of a tie, the second one
(appearing in the cast type) is expanded.

Levels can be one of the following (higher to lower):
\begin{quote}
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{opaque}} : level of opaque constants. They cannot be expanded by
tactics (behaves like +\(\infty\), see next item).

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} : levels indexed by an integer. Level 0 corresponds to the
default behavior, which corresponds to transparent constants. This
level can also be referred to as transparent. Negative levels
correspond to constants to be expanded before normal transparent
constants, while positive levels correspond to constants to be
expanded after normal transparent constants.

\item {} 
\sphinxcode{\sphinxupquote{expand}} : level of constants that should be expanded first (behaves
like −\(\infty\))

\end{itemize}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Strategy~\DUrole{hole}{level}~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}~{]}}}}}
These directives survive section and module closure, unless the
command is prefixed by \sphinxcode{\sphinxupquote{Local}}. In the latter case, the behavior
regarding sections and modules is the same as for the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Transparent}}}}} and
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}} commands.

\end{fulllineitems}

\end{quote}

\end{fulllineitems}

\index{Print Strategy (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.print-strategy}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Strategy~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This command prints the strategy currently associated to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}. It
fails if \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} is not an unfoldable reference, that is, neither a
variable nor a constant.
\index{The reference is not unfoldable (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:exn.the-reference-is-not-unfoldable}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~reference~is~not~unfoldable.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Strategies}}}}
Print all the currently non-transparent strategies.

\end{fulllineitems}


\end{fulllineitems}

\index{Declare Reduction (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.declare-reduction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~Reduction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~\DUrole{hole}{convtactic}}}}}
This command allows giving a short name to a reduction expression, for
instance lazy beta delta {[}foo bar{]}. This short name can then be used
in \sphinxcode{\sphinxupquote{Eval}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} \sphinxcode{\sphinxupquote{in}} ... or \sphinxcode{\sphinxupquote{eval}} directives. This command
accepts the
Local modifier, for discarding this reduction name at the end of the
file or module. For the moment the name cannot be qualified. In
particular declaring the same name in several modules or in several
functor applications will be refused if these declarations are not
local. The name \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} cannot be used directly as an Ltac tactic, but
nothing prevents the user to also perform a
\sphinxcode{\sphinxupquote{Ltac}} \sphinxtitleref{ident} \sphinxcode{\sphinxupquote{:=}} \sphinxtitleref{convtactic}.


\sphinxstrong{See also:}


{\hyperref[\detokenize{proof-engine/tactics:performingcomputations}]{\sphinxcrossref{\DUrole{std,std-ref}{Performing computations}}}}



\end{fulllineitems}



\subsection{Controlling the locality of commands}
\label{\detokenize{proof-engine/vernacular-commands:controlling-the-locality-of-commands}}\label{\detokenize{proof-engine/vernacular-commands:controlling-locality-of-commands}}\index{Local (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.local}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~\DUrole{hole}{command}}}}}
\end{fulllineitems}

\index{Global (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/vernacular-commands:coq:cmd.global}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Global~\DUrole{hole}{command}}}}}
\end{fulllineitems}


Some commands support a Local or Global prefix modifier to control the
scope of their effect. There are four kinds of commands:
\begin{itemize}
\item {} 
Commands whose default is to extend their effect both outside the
section and the module or library file they occur in.  For these
commands, the Local modifier limits the effect of the command to the
current section or module it occurs in.  As an example, the {\hyperref[\detokenize{addendum/implicit-coercions:coq:cmd.coercion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Coercion}}}}}
and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.strategy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Strategy}}}}} commands belong to this category.

\item {} 
Commands whose default behavior is to stop their effect at the end
of the section they occur in but to extend their effect outside the module or
library file they occur in. For these commands, the Local modifier limits the
effect of the command to the current module if the command does not occur in a
section and the Global modifier extends the effect outside the current
sections and current module if the command occurs in a section. As an example,
the {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.ltac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac}}}}} or {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}} commands belong
to this category. Notice that a subclass of these commands do not support
extension of their scope outside sections at all and the Global modifier is not
applicable to them.

\item {} 
Commands whose default behavior is to stop their effect at the end
of the section or module they occur in.  For these commands, the \sphinxcode{\sphinxupquote{Global}}
modifier extends their effect outside the sections and modules they
occur in.  The {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Transparent}}}}} and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}}
(see Section {\hyperref[\detokenize{proof-engine/vernacular-commands:vernac-controlling-the-reduction-strategies}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling the reduction strategies and the conversion algorithm}}}}) commands
belong to this category.

\item {} 
Commands whose default behavior is to extend their effect outside
sections but not outside modules when they occur in a section and to
extend their effect outside the module or library file they occur in
when no section contains them.For these commands, the Local modifier
limits the effect to the current section or module while the Global
modifier extends the effect outside the module even when the command
occurs in a section.  The {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.set}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Set}}}}} and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.unset}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Unset}}}}} commands belong to this
category.

\end{itemize}


\section{Proof handling}
\label{\detokenize{proof-engine/proof-handling:proof-handling}}\label{\detokenize{proof-engine/proof-handling:proofhandling}}\label{\detokenize{proof-engine/proof-handling::doc}}
In \DUrole{smallcaps}{Coq}’s proof editing mode all top-level commands documented in
Chapter {\hyperref[\detokenize{proof-engine/vernacular-commands:vernacularcommands}]{\sphinxcrossref{\DUrole{std,std-ref}{Vernacular commands}}}} remain available and the user has access to specialized
commands dealing with proof development pragmas documented in this
section. They can also use some other specialized commands called
\sphinxstyleemphasis{tactics}. They are the very tools allowing the user to deal with
logical reasoning. They are documented in Chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}}.

Coq user interfaces usually have a way of marking whether the user has
switched to proof editing mode. For instance, in coqtop the prompt \sphinxcode{\sphinxupquote{Coq \textless{}}}   is changed into
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \textless{}}}}   where {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is the declared name of the theorem currently edited.

At each stage of a proof development, one has a list of goals to
prove. Initially, the list consists only in the theorem itself. After
having applied some tactics, the list of goals contains the subgoals
generated by the tactics.

To each subgoal is associated a number of hypotheses called the \sphinxstyleemphasis{local context}
of the goal. Initially, the local context contains the local variables and
hypotheses of the current section (see Section {\hyperref[\detokenize{language/gallina-specification-language:gallina-assumptions}]{\sphinxcrossref{\DUrole{std,std-ref}{Assumptions}}}}) and
the local variables and hypotheses of the theorem statement. It is enriched by
the use of certain tactics (see e.g. {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}}).

When a proof is completed, the message \sphinxcode{\sphinxupquote{Proof completed}} is displayed.
One can then register this proof as a defined constant in the
environment. Because there exists a correspondence between proofs and
terms of \(\lambda\)-calculus, known as the \sphinxstyleemphasis{Curry-Howard isomorphism}
\sphinxcite{zebibliography:how80}\sphinxcite{zebibliography:bar81}\sphinxcite{zebibliography:gir89}\sphinxcite{zebibliography:hue88}, \DUrole{smallcaps}{Coq} stores proofs as terms of \DUrole{smallcaps}{Cic}. Those
terms are called \sphinxstyleemphasis{proof terms}.
\index{No focused proof (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:exn.no-focused-proof}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~focused~proof.}}}}
Coq raises this error message when one attempts to use a proof editing command
out of the proof editing mode.

\end{fulllineitems}



\subsection{Switching on/off the proof editing mode}
\label{\detokenize{proof-engine/proof-handling:switching-on-off-the-proof-editing-mode}}\label{\detokenize{proof-engine/proof-handling:proof-editing-mode}}
The proof editing mode is entered by asserting a statement, which typically is
the assertion of a theorem using an assertion command like {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.theorem}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Theorem}}}}}. The
list of assertion commands is given in {\hyperref[\detokenize{language/gallina-specification-language:assertions}]{\sphinxcrossref{\DUrole{std,std-ref}{Assertions and proofs}}}}. The command
{\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Goal}}}}} can also be used.
\index{Goal (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.goal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Goal~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}}}}}
This is intended for quick assertion of statements, without knowing in
advance which name to give to the assertion, typically for quick
testing of the provability of a statement. If the proof of the
statement is eventually completed and validated, the statement is then
bound to the name \sphinxcode{\sphinxupquote{Unnamed\_thm}} (or a variant of this name not already
used for another statement).

\end{fulllineitems}

\index{Qed (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.qed}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Qed}}}}
This command is available in interactive editing proof mode when the
proof is completed. Then {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} extracts a proof term from the proof
script, switches back to Coq top-level and attaches the extracted
proof term to the declared name of the original goal. This name is
added to the environment as an opaque constant.
\index{Attempt to save an incomplete proof (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:exn.attempt-to-save-an-incomplete-proof}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Attempt~to~save~an~incomplete~proof.}}}}
\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}
Sometimes an error occurs when building the proof term, because
tactics do not enforce completely the term construction
constraints.

The user should also be aware of the fact that since the
proof term is completely rechecked at this point, one may have to wait
a while when the proof is large. In some exceptional cases one may
even incur a memory overflow.
\end{sphinxadmonition}
\index{Defined (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmdv.defined}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Defined}}}}
Same as {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} but the proof is then declared transparent, which means
that its content can be explicitly used for type checking and that it can be
unfolded in conversion tactics (see {\hyperref[\detokenize{proof-engine/tactics:performingcomputations}]{\sphinxcrossref{\DUrole{std,std-ref}{Performing computations}}}},
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Opaque}}}}}, {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.transparent}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Transparent}}}}}).

\end{fulllineitems}

\index{Save (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmdv.save}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Save~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Forces the name of the original goal to be {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}. This
command (and the following ones) can only be used if the original goal
has been opened using the {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Goal}}}}} command.

\end{fulllineitems}


\end{fulllineitems}

\index{Admitted (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.admitted}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Admitted}}}}
This command is available in interactive editing mode to give up
the current proof and declare the initial goal as an axiom.

\end{fulllineitems}

\index{Abort (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.abort}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Abort}}}}
This command cancels the current proof development, switching back to
the previous proof development, or to the \DUrole{smallcaps}{Coq} toplevel if no other
proof was edited.
\index{No focused proof (No proof-editing in progress) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:exn.no-focused-proof-no-proof-editing-in-progress}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~focused~proof~(No~proof-editing~in~progress).}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Abort~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Aborts the editing of the proof named {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} (in case you have
nested proofs).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Abort~All}}}}
Aborts all current goals.

\end{fulllineitems}


\end{fulllineitems}

\index{Proof {}`term{}` (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.proof-term}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This command applies in proof editing mode. It is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{exact {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}. Qed.}}}
That is, you have to give the full proof in one gulp, as a
proof term (see Section {\hyperref[\detokenize{proof-engine/tactics:applyingtheorems}]{\sphinxcrossref{\DUrole{std,std-ref}{Applying theorems}}}}).

\end{fulllineitems}

\index{Proof (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.proof}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof}}}}
Is a no-op which is useful to delimit the sequence of tactic commands
which start a proof, after a {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.theorem}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Theorem}}}}} command. It is a good practice to
use {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof}}}}} as an opening parenthesis, closed in the script with a
closing {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}}.


\sphinxstrong{See also:}


{\hyperref[\detokenize{proof-engine/tactics:coq:cmd.proof-with}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof with}}}}}



\end{fulllineitems}

\index{Proof using (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.proof-using}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~using~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This command applies in proof editing mode. It declares the set of
section variables (see {\hyperref[\detokenize{language/gallina-specification-language:gallina-assumptions}]{\sphinxcrossref{\DUrole{std,std-ref}{Assumptions}}}}) used by the proof.
At {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} time, the
system will assert that the set of section variables actually used in
the proof is a subset of the declared one.

The set of declared variables is closed under type dependency. For
example if \sphinxcode{\sphinxupquote{T}} is variable and a is a variable of type \sphinxcode{\sphinxupquote{T}}, the commands
\sphinxcode{\sphinxupquote{Proof using a}} and \sphinxcode{\sphinxupquote{Proof using T a}} are actually equivalent.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~using~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~with~\DUrole{hole}{tactic}}}}}
Combines in a single line {\hyperref[\detokenize{proof-engine/tactics:coq:cmd.proof-with}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof with}}}}} and {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.proof-using}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof using}}}}}.


\sphinxstrong{See also:}


{\hyperref[\detokenize{proof-engine/tactics:tactics-implicit-automation}]{\sphinxcrossref{\DUrole{std,std-ref}{Setting implicit automation tactics}}}}



\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~using~All}}}}
Use all section variables.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~using~\DUrole{repeat-wrapper}{\DUrole{repeat}{Type}\DUrole{notation-sup}{?}}}}}}
Use only section variables occurring in the statement.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~using~Type*}}}}
The \sphinxcode{\sphinxupquote{*}} operator computes the forward transitive closure. E.g. if the
variable \sphinxcode{\sphinxupquote{H}} has type \sphinxcode{\sphinxupquote{p \textless{} 5}} then \sphinxcode{\sphinxupquote{H}} is in \sphinxcode{\sphinxupquote{p*}} since \sphinxcode{\sphinxupquote{p}} occurs in the type
of \sphinxcode{\sphinxupquote{H}}. \sphinxcode{\sphinxupquote{Type*}} is the forward transitive closure of the entire set of
section variables occurring in the statement.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~using~-(\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}})}}}}
Use all section variables except the list of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~using~\DUrole{hole}{collection1}~+~\DUrole{hole}{collection2}}}}}
Use section variables from the union of both collections.
See {\hyperref[\detokenize{proof-engine/proof-handling:nameaset}]{\sphinxcrossref{\DUrole{std,std-ref}{Name a set of section hypotheses for Proof using}}}} to know how to form a named collection.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~using~\DUrole{hole}{collection1}~-~\DUrole{hole}{collection2}}}}}
Use section variables which are in the first collection but not in the
second one.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~using~\DUrole{hole}{collection}~-~(\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}})}}}}
Use section variables which are in the first collection but not in the
list of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~using~\DUrole{hole}{collection}~*}}}}
Use section variables in the forward transitive closure of the collection.
The \sphinxcode{\sphinxupquote{*}} operator binds stronger than \sphinxcode{\sphinxupquote{+}} and \sphinxcode{\sphinxupquote{-}}.

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{Proof using options}
\label{\detokenize{proof-engine/proof-handling:proof-using-options}}
The following options modify the behavior of \sphinxcode{\sphinxupquote{Proof using}}.
\index{Default Proof Using (opt)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:opt.default-proof-using}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Default~Proof~Using~"\DUrole{hole}{expression}"}}}}
Use \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{expression}}}} as the default \sphinxcode{\sphinxupquote{Proof using}} value. E.g. \sphinxcode{\sphinxupquote{Set Default
Proof Using "a b"}} will complete all \sphinxcode{\sphinxupquote{Proof}} commands not followed by a
\sphinxcode{\sphinxupquote{using}} part with \sphinxcode{\sphinxupquote{using a b}}.

\end{fulllineitems}

\index{Suggest Proof Using (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:flag.suggest-proof-using}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Suggest~Proof~Using}}}}
When {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.qed}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Qed}}}}} is performed, suggest a \sphinxcode{\sphinxupquote{using}} annotation if the user did not
provide one.

\end{fulllineitems}



\subsubsection{Name a set of section hypotheses for \sphinxstyleliteralintitle{\sphinxupquote{Proof using}}}
\label{\detokenize{proof-engine/proof-handling:name-a-set-of-section-hypotheses-for-proof-using}}\label{\detokenize{proof-engine/proof-handling:nameaset}}\index{Collection (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.collection}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Collection~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~\DUrole{hole}{expression}}}}}
This can be used to name a set of section
hypotheses, with the purpose of making \sphinxcode{\sphinxupquote{Proof using}} annotations more
compact.

\begin{sphinxadmonition}{note}{Example}

Define the collection named \sphinxcode{\sphinxupquote{Some}} containing \sphinxcode{\sphinxupquote{x}}, \sphinxcode{\sphinxupquote{y}} and \sphinxcode{\sphinxupquote{z}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Collection Some := x y z.
\end{sphinxVerbatim}

Define the collection named \sphinxcode{\sphinxupquote{Fewer}} containing only \sphinxcode{\sphinxupquote{x}} and \sphinxcode{\sphinxupquote{y}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Collection Fewer := Some \PYGZhy{} z
\end{sphinxVerbatim}

Define the collection named \sphinxcode{\sphinxupquote{Many}} containing the set union or set
difference of \sphinxcode{\sphinxupquote{Fewer}} and \sphinxcode{\sphinxupquote{Some}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Collection Many := Fewer + Some
Collection Many := Fewer \PYGZhy{} Some
\end{sphinxVerbatim}

Define the collection named \sphinxcode{\sphinxupquote{Many}} containing the set difference of
\sphinxcode{\sphinxupquote{Fewer}} and the unnamed collection \sphinxcode{\sphinxupquote{x y}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Collection Many := Fewer \PYGZhy{} (x y)
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}

\index{Existential (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.existential}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Existential~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This command instantiates an existential variable. {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}} is an index in
the list of uninstantiated existential variables displayed by {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmdv.show-existentials}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Show Existentials}}}}}.

This command is intended to be used to instantiate existential
variables when the proof is completed but some uninstantiated
existential variables remain. To instantiate existential variables
during proof edition, you should use the tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.instantiate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{instantiate}}}}}.

\end{fulllineitems}

\index{Grab Existential Variables (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.grab-existential-variables}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Grab~Existential~Variables}}}}
This command can be run when a proof has no more goal to be solved but
has remaining uninstantiated existential variables. It takes every
uninstantiated existential variable and turns it into a goal.

\end{fulllineitems}



\subsection{Navigation in the proof tree}
\label{\detokenize{proof-engine/proof-handling:navigation-in-the-proof-tree}}\index{Undo (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.undo}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Undo}}}}
This command cancels the effect of the last command. Thus, it
backtracks one step.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Undo~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
Repeats Undo {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}} times.

\end{fulllineitems}

\index{Restart (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmdv.restart}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Restart}}}}
This command restores the proof editing process to the original goal.
\index{No focused proof to restart (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:exn.no-focused-proof-to-restart}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~focused~proof~to~restart.}}}}
\end{fulllineitems}


\end{fulllineitems}

\index{Focus (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.focus}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Focus}}}}
This focuses the attention on the first subgoal to prove and the
printing of the other subgoals is suspended until the focused subgoal
is solved or unfocused. This is useful when there are many current
subgoals which clutter your screen.

\DUrole{versionmodified}{Deprecated since version 8.8: }Prefer the use of bullets or focusing brackets (see below).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Focus~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This focuses the attention on the {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}} th subgoal to prove.

\DUrole{versionmodified}{Deprecated since version 8.8: }Prefer the use of focusing brackets with a goal selector (see below).

\end{fulllineitems}

\index{Unfocus (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.unfocus}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unfocus}}}}
This command restores to focus the goal that were suspended by the
last {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.focus}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Focus}}}}} command.

\DUrole{versionmodified}{Deprecated since version 8.8.}

\end{fulllineitems}

\index{Unfocused (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.unfocused}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unfocused}}}}
Succeeds if the proof is fully unfocused, fails if there are some
goals out of focus.

\end{fulllineitems}

\phantomsection\label{\detokenize{proof-engine/proof-handling:curly-braces}}
\index{\sphinxleftcurlybrace{}}\index{\sphinxrightcurlybrace{}}\ignorespaces 

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\{~\DUrole{meta}{\textbar{}}~\}}}}}
The command \sphinxcode{\sphinxupquote{\{}} (without a terminating period) focuses on the first
goal, much like {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.focus}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Focus}}}}} does, however, the subproof can only be
unfocused when it has been fully solved ( \sphinxstyleemphasis{i.e.} when there is no
focused goal left). Unfocusing is then handled by \sphinxcode{\sphinxupquote{\}}} (again, without a
terminating period). See also an example in the next section.

Note that when a focused goal is proved a message is displayed
together with a suggestion about the right bullet or \sphinxcode{\sphinxupquote{\}}} to unfocus it
or focus the next one.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}:~\{}}}}
This focuses on the {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}} th subgoal to prove.

\end{fulllineitems}


Error messages:
\index{This proof is focused, but cannot be unfocused this way (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:exn.this-proof-is-focused-but-cannot-be-unfocused-this-way}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{This~proof~is~focused,~but~cannot~be~unfocused~this~way.}}}}
You are trying to use \sphinxcode{\sphinxupquote{\}}} but the current subproof has not been fully solved.

\end{fulllineitems}

\index{No such goal. (Focusing) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:exn.no-such-goal-focusing}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~goal.}}}}
\end{fulllineitems}

\index{Brackets only support the single numbered goal selector (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:exn.brackets-only-support-the-single-numbered-goal-selector}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Brackets~only~support~the~single~numbered~goal~selector.}}}}
\end{fulllineitems}



\sphinxstrong{See also:}


The error messages about bullets below.



\end{fulllineitems}



\subsubsection{Bullets}
\label{\detokenize{proof-engine/proof-handling:bullets}}\label{\detokenize{proof-engine/proof-handling:id5}}
Alternatively to \sphinxcode{\sphinxupquote{\{}} and \sphinxcode{\sphinxupquote{\}}}, proofs can be structured with bullets. The
use of a bullet \sphinxcode{\sphinxupquote{b}} for the first time focuses on the first goal \sphinxcode{\sphinxupquote{g}}, the
same bullet cannot be used again until the proof of \sphinxcode{\sphinxupquote{g}} is completed,
then it is mandatory to focus the next goal with \sphinxcode{\sphinxupquote{b}}. The consequence is
that \sphinxcode{\sphinxupquote{g}} and all goals present when \sphinxcode{\sphinxupquote{g}} was focused are focused with the
same bullet \sphinxcode{\sphinxupquote{b}}. See the example below.

Different bullets can be used to nest levels. The scope of bullet does
not go beyond enclosing \sphinxcode{\sphinxupquote{\{}} and \sphinxcode{\sphinxupquote{\}}}, so bullets can be reused as further
nesting levels provided they are delimited by these. Bullets are made of
repeated \sphinxcode{\sphinxupquote{-}}, \sphinxcode{\sphinxupquote{+}} or \sphinxcode{\sphinxupquote{*}} symbols:


\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:grammar-token-bullet}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{bullet~::=~}}\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{-}\DUrole{notation-sup}{+}}~\DUrole{meta}{\textbar{}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{+}\DUrole{notation-sup}{+}}~\DUrole{meta}{\textbar{}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{*}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}


Note again that when a focused goal is proved a message is displayed
together with a suggestion about the right bullet or \sphinxcode{\sphinxupquote{\}}} to unfocus it
or focus the next one.

\begin{sphinxadmonition}{note}{Note:}
In Proof General (\sphinxcode{\sphinxupquote{Emacs}} interface to \DUrole{smallcaps}{Coq}), you must use
bullets with the priority ordering shown above to have a correct
indentation. For example \sphinxcode{\sphinxupquote{-}} must be the outer bullet and \sphinxcode{\sphinxupquote{**}} the inner
one in the example below.
\end{sphinxadmonition}

The following example script illustrates all these features:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{o}{(}\PYG{o}{(}\PYG{o}{(}\PYG{n}{True} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{o}{(}\PYG{o}{(}\PYG{n}{True} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}

\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{split}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{o}{(}\PYG{n}{True} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}

\PYG{o}{\PYGZhy{}} \PYG{k}{split}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{o}{(}\PYG{n}{True} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}
    
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{n}{True} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}

\PYG{o}{+} \PYG{k}{split}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{n}{True} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}
    
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}

\PYG{o}{*}\PYG{o}{*} \PYG{o}{\PYGZob{}} \PYG{k}{split}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}
    
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}
    
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}

\PYG{o}{\PYGZhy{}} \PYG{k}{trivial}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
    
    \PYG{n}{This} \PYG{n}{subproof} \PYG{k}{is} \PYG{n}{complete}\PYG{o}{,} \PYG{n}{but} \PYG{n}{there} \PYG{n}{are} \PYG{n}{some} \PYG{n}{unfocused} \PYG{n}{goals}\PYG{o}{.}
    \PYG{n}{Focus} \PYG{n}{next} \PYG{n}{goal} \PYG{k}{with} \PYG{n}{bullet} \PYG{o}{\PYGZhy{}.}
    
    \PYG{l+m+mi}{4} \PYG{n}{subgoals}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{1} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{subgoal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}

\PYG{o}{\PYGZhy{}} \PYG{k}{trivial}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
    
    \PYG{n}{This} \PYG{n}{subproof} \PYG{k}{is} \PYG{n}{complete}\PYG{o}{,} \PYG{n}{but} \PYG{n}{there} \PYG{n}{are} \PYG{n}{some} \PYG{n}{unfocused} \PYG{n}{goals}\PYG{o}{.}
    \PYG{n}{Try} \PYG{n}{unfocusing} \PYG{k}{with} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZcb{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    
    \PYG{l+m+mi}{3} \PYG{n}{subgoals}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{1} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}

\PYG{o}{\PYGZcb{}}
\PYG{o}{*}\PYG{o}{*} \PYG{k}{trivial}\PYG{o}{.}
    \PYG{n}{This} \PYG{n}{subproof} \PYG{k}{is} \PYG{n}{complete}\PYG{o}{,} \PYG{n}{but} \PYG{n}{there} \PYG{n}{are} \PYG{n}{some} \PYG{n}{unfocused} \PYG{n}{goals}\PYG{o}{.}
    \PYG{n}{Focus} \PYG{n}{next} \PYG{n}{goal} \PYG{k}{with} \PYG{n}{bullet} \PYG{o}{*}\PYG{o}{*}\PYG{o}{.}
    
    \PYG{l+m+mi}{3} \PYG{n}{subgoals}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{1} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
    
    \PYG{n}{This} \PYG{n}{subproof} \PYG{k}{is} \PYG{n}{complete}\PYG{o}{,} \PYG{n}{but} \PYG{n}{there} \PYG{n}{are} \PYG{n}{some} \PYG{n}{unfocused} \PYG{n}{goals}\PYG{o}{.}
    \PYG{n}{Focus} \PYG{n}{next} \PYG{n}{goal} \PYG{k}{with} \PYG{n}{bullet} \PYG{o}{+}\PYG{o}{.}
    
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{1} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}

\PYG{o}{+} \PYG{k}{trivial}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
    
    \PYG{n}{This} \PYG{n}{subproof} \PYG{k}{is} \PYG{n}{complete}\PYG{o}{,} \PYG{n}{but} \PYG{n}{there} \PYG{n}{are} \PYG{n}{some} \PYG{n}{unfocused} \PYG{n}{goals}\PYG{o}{.}
    \PYG{n}{Focus} \PYG{n}{next} \PYG{n}{goal} \PYG{k}{with} \PYG{n}{bullet} \PYG{o}{\PYGZhy{}.}
    
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{1} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}

\PYG{o}{\PYGZhy{}} \PYG{k}{assert} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
    
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}

\PYG{o}{\PYGZob{}} \PYG{k}{trivial}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
    
    \PYG{n}{This} \PYG{n}{subproof} \PYG{k}{is} \PYG{n}{complete}\PYG{o}{,} \PYG{n}{but} \PYG{n}{there} \PYG{n}{are} \PYG{n}{some} \PYG{n}{unfocused} \PYG{n}{goals}\PYG{o}{.}
    \PYG{n}{Try} \PYG{n}{unfocusing} \PYG{k}{with} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZcb{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{1} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}

\PYG{o}{\PYGZcb{}}
\PYG{k+kp}{assumption}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{True}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
    
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{Unnamed\PYGZus{}thm} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{Wrong bullet ‘bullet’: Current bullet ‘bullet’ is not finished (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:exn.wrong-bullet-bullet-current-bullet-bullet-is-not-finished}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Wrong~bullet~{\hyperref[\detokenize{proof-engine/proof-handling:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet$_{\text{1}}$}}}}:~Current~bullet~{\hyperref[\detokenize{proof-engine/proof-handling:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet$_{\text{2}}$}}}}~is~not~finished.}}}}
Before using bullet \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/proof-handling:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet$_{\text{1}}$}}}}}}} again, you should first finish proving
the current focused goal.
Note that \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/proof-handling:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet$_{\text{1}}$}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/proof-handling:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet$_{\text{2}}$}}}}}}} may be the same.

\end{fulllineitems}

\index{Wrong bullet ‘bullet’: Bullet ‘bullet’ is mandatory here (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:exn.wrong-bullet-bullet-bullet-bullet-is-mandatory-here}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Wrong~bullet~{\hyperref[\detokenize{proof-engine/proof-handling:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet$_{\text{1}}$}}}}:~Bullet~{\hyperref[\detokenize{proof-engine/proof-handling:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet$_{\text{2}}$}}}}~is~mandatory~here.}}}}
You must put \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/proof-handling:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet$_{\text{2}}$}}}}}}} to focus on the next goal. No other bullet is
allowed here.

\end{fulllineitems}

\index{No such goal. Focus next goal with bullet ‘bullet’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:exn.no-such-goal-focus-next-goal-with-bullet-bullet}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~goal.~Focus~next~goal~with~bullet~{\hyperref[\detokenize{proof-engine/proof-handling:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet}}}}.}}}}
You tried to apply a tactic but no goals were under focus.
Using \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/proof-handling:grammar-token-bullet}]{\sphinxcrossref{\DUrole{hole}{bullet}}}}}}} is  mandatory here.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~goal.~Try~unfocusing~with~\}.}}}}
You just finished a goal focused by \sphinxcode{\sphinxupquote{\{}}, you must unfocus it with \sphinxcode{\sphinxupquote{\}}}.

\end{fulllineitems}



\subsubsection{Set Bullet Behavior}
\label{\detokenize{proof-engine/proof-handling:set-bullet-behavior}}\index{Bullet Behavior (opt)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:opt.bullet-behavior}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Bullet~Behavior~\DUrole{meta}{(}~"None"~\DUrole{meta}{\textbar{}}~"Strict~Subproofs"~\DUrole{meta}{)}}}}}
This option controls the bullet behavior and can take two possible values:
\begin{itemize}
\item {} 
"None": this makes bullets inactive.

\item {} 
"Strict Subproofs": this makes bullets active (this is the default behavior).

\end{itemize}

\end{fulllineitems}



\subsection{Requesting information}
\label{\detokenize{proof-engine/proof-handling:requesting-information}}\label{\detokenize{proof-engine/proof-handling:requestinginformation}}\index{Show (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.show}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show}}}}
This command displays the current goals.
\index{No focused proof (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~focused~proof.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
Displays only the {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}}-th subgoal.
\index{No such goal (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:exn.no-such-goal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~goal.}}}}
\end{fulllineitems}


\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Displays the named goal {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}. This is useful in
particular to display a shelved goal but only works if the
corresponding existential variable has been named by the user
(see {\hyperref[\detokenize{language/gallina-extensions:existential-variables}]{\sphinxcrossref{\DUrole{std,std-ref}{Existential variables}}}}) as in the following example.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{exists} \PYG{n}{n}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{exists} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{n}{eexists} \PYG{o}{?}\PYG{o}{[}\PYG{n}{n}\PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{focused} \PYG{n}{subgoal}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{1}\PYG{o}{)}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{?}\PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{k+kn}{Show} \PYG{n}{n}\PYG{o}{.}
    \PYG{n}{subgoal} \PYG{n}{n} \PYG{k}{is}\PYG{o}{:}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k+kt}{nat}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}

\index{Show Script (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmdv.show-script}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Script}}}}
Displays the whole list of tactics applied from the
beginning of the current proof. This tactics script may contain some
holes (subgoals not yet proved). They are printed under the form

\sphinxcode{\sphinxupquote{\textless{}Your Tactic Text here\textgreater{}}}.

\end{fulllineitems}

\index{Show Proof (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmdv.show-proof}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Proof}}}}
It displays the proof term generated by the tactics
that have been applied. If the proof is not completed, this term
contain holes, which correspond to the sub-terms which are still to be
constructed. These holes appear as a question mark indexed by an
integer, and applied to the list of variables in the context, since it
may depend on them. The types obtained by abstracting away the context
from the type of each placeholder are also printed.

\end{fulllineitems}

\index{Show Conjectures (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmdv.show-conjectures}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Conjectures}}}}
It prints the list of the names of all the
theorems that are currently being proved. As it is possible to start
proving a previous lemma during the proof of a theorem, this list may
contain several names.

\end{fulllineitems}

\index{Show Intro (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmdv.show-intro}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Intro}}}}
If the current goal begins by at least one product,
this command prints the name of the first product, as it would be
generated by an anonymous {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}}. The aim of this command is to ease
the writing of more robust scripts. For example, with an appropriate
Proof General macro, it is possible to transform any anonymous {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}}
into a qualified one such as \sphinxcode{\sphinxupquote{intro y13}}. In the case of a non-product
goal, it prints nothing.

\end{fulllineitems}

\index{Show Intros (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmdv.show-intros}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Intros}}}}
This command is similar to the previous one, it
simulates the naming process of an {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}}.

\end{fulllineitems}

\index{Show Existentials (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmdv.show-existentials}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Existentials}}}}
It displays the set of all uninstantiated
existential variables in the current proof tree, along with the type
and the context of each variable.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Match~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This variant displays a template of the Gallina
\sphinxcode{\sphinxupquote{match}} construct with a branch for each constructor of the type
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Show} \PYG{n}{Match} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{k}{match} \PYG{o}{\PYGZsh{}} \PYG{k}{with}
     \PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{=\PYGZgt{}}
     \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{x} \PYG{o}{=\PYGZgt{}}
     \PYG{k}{end}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{Unknown inductive type (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:exn.unknown-inductive-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unknown~inductive~type.}}}}
\end{fulllineitems}


\end{fulllineitems}

\index{Show Universes (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmdv.show-universes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Universes}}}}
It displays the set of all universe constraints and
its normalized form at the current stage of the proof, useful for
debugging universe inconsistencies.

\end{fulllineitems}


\end{fulllineitems}

\index{Guarded (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.guarded}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Guarded}}}}
Some tactics (e.g. {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}}) allow to build proofs using
fixpoint or co-fixpoint constructions. Due to the incremental nature
of interactive proof construction, the check of the termination (or
guardedness) of the recursive calls in the fixpoint or cofixpoint
constructions is postponed to the time of the completion of the proof.

The command {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.guarded}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Guarded}}}}} allows checking if the guard condition for
fixpoint and cofixpoint is violated at some time of the construction
of the proof without having to wait the completion of the proof.

\end{fulllineitems}



\subsection{Controlling the effect of proof editing commands}
\label{\detokenize{proof-engine/proof-handling:controlling-the-effect-of-proof-editing-commands}}\index{Hyps Limit (opt)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:opt.hyps-limit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hyps~Limit~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This option controls the maximum number of hypotheses displayed in goals
after the application of a tactic. All the hypotheses remain usable
in the proof development.
When unset, it goes back to the default mode which is to print all
available hypotheses.

\end{fulllineitems}

\index{Automatic Introduction (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:flag.automatic-introduction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Automatic~Introduction}}}}
This option controls the way binders are handled
in assertion commands such as \sphinxcode{\sphinxupquote{\DUrole{notation}{Theorem {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. When the
option is on, which is the default, binders are automatically put in
the local context of the goal to prove.

When the option is off, binders are discharged on the statement to be
proved and a tactic such as {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} (see Section {\hyperref[\detokenize{proof-engine/tactics:managingthelocalcontext}]{\sphinxcrossref{\DUrole{std,std-ref}{Managing the local context}}}})
has to be used to move the assumptions to the local context.

\end{fulllineitems}



\subsection{Controlling memory usage}
\label{\detokenize{proof-engine/proof-handling:controlling-memory-usage}}
When experiencing high memory usage the following commands can be used
to force \DUrole{smallcaps}{Coq} to optimize some of its internal data structures.
\index{Optimize Proof (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.optimize-proof}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Optimize~Proof}}}}
This command forces \DUrole{smallcaps}{Coq} to shrink the data structure used to represent
the ongoing proof.

\end{fulllineitems}

\index{Optimize Heap (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/proof-handling:coq:cmd.optimize-heap}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Optimize~Heap}}}}
This command forces the \DUrole{smallcaps}{OCaml} runtime to perform a heap compaction.
This is in general an expensive operation.
See: \sphinxhref{http://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html\#VALcompact}{OCaml Gc}%
\begin{footnote}[7]\sphinxAtStartFootnote
\sphinxnolinkurl{http://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html\#VALcompact}
%
\end{footnote}
There is also an analogous tactic {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.optimize-heap}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{optimize\_heap}}}}}.

\end{fulllineitems}



\section{Tactics}
\label{\detokenize{proof-engine/tactics:tactics}}\label{\detokenize{proof-engine/tactics:id1}}\label{\detokenize{proof-engine/tactics::doc}}
A deduction rule is a link between some (unique) formula, that we call
the \sphinxstyleemphasis{conclusion} and (several) formulas that we call the \sphinxstyleemphasis{premises}. A
deduction rule can be read in two ways. The first one says: “if I know
this and this then I can deduce this”. For instance, if I have a proof
of A and a proof of B then I have a proof of A ∧ B. This is forward
reasoning from premises to conclusion. The other way says: “to prove
this I have to prove this and this”. For instance, to prove A ∧ B, I
have to prove A and I have to prove B. This is backward reasoning from
conclusion to premises. We say that the conclusion is the \sphinxstyleemphasis{goal} to
prove and premises are the \sphinxstyleemphasis{subgoals}. The tactics implement \sphinxstyleemphasis{backward
reasoning}. When applied to a goal, a tactic replaces this goal with
the subgoals it generates. We say that a tactic reduces a goal to its
subgoal(s).

Each (sub)goal is denoted with a number. The current goal is numbered
1. By default, a tactic is applied to the current goal, but one can
address a particular goal in the list by writing n:tactic which means
“apply tactic tactic to goal number n”. We can show the list of
subgoals by typing Show (see Section {\hyperref[\detokenize{proof-engine/proof-handling:requestinginformation}]{\sphinxcrossref{\DUrole{std,std-ref}{Requesting information}}}}).

Since not every rule applies to a given statement, not every tactic can
be used to reduce a given goal. In other words, before applying a tactic
to a given goal, the system checks that some \sphinxstyleemphasis{preconditions} are
satisfied. If it is not the case, the tactic raises an error message.

Tactics are built from atomic tactics and tactic expressions (which
extends the folklore notion of tactical) to combine those atomic
tactics. This chapter is devoted to atomic tactics. The tactic
language will be described in Chapter {\hyperref[\detokenize{proof-engine/ltac:ltac}]{\sphinxcrossref{\DUrole{std,std-ref}{The tactic language}}}}.


\subsection{Invocation of tactics}
\label{\detokenize{proof-engine/tactics:invocation-of-tactics}}\label{\detokenize{proof-engine/tactics:id2}}
A tactic is applied as an ordinary command. It may be preceded by a
goal selector (see Section {\hyperref[\detokenize{proof-engine/ltac:ltac-semantics}]{\sphinxcrossref{\DUrole{std,std-ref}{Semantics}}}}). If no selector is
specified, the default selector is used.

\phantomsection\label{\detokenize{proof-engine/tactics:tactic-invocation-grammar}}\begin{quote}


\begin{productionlist}
\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-tactic_invocation}}\production{tactic\_invocation}{ toplevel\_selector : tactic.}
\productioncont{ \textbar{}tactic .}
\end{productionlist}

\end{quote}
\index{Default Goal Selector (opt)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:opt.default-goal-selector}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Default~Goal~Selector~"{\hyperref[\detokenize{proof-engine/ltac:grammar-token-toplevel-selector}]{\sphinxcrossref{\DUrole{hole}{toplevel\_selector}}}}"}}}}
This option controls the default selector \textendash{} used when no selector is
specified when applying a tactic \textendash{} is set to the chosen value. The initial
value is 1, hence the tactics are, by default, applied to the first goal.
Using value \sphinxcode{\sphinxupquote{all}} will make is so that tactics are, by default, applied to
every goal simultaneously. Then, to apply a tactic tac to the first goal
only, you can write \sphinxcode{\sphinxupquote{1:tac}}. Although more selectors are available, only
\sphinxcode{\sphinxupquote{all}} or a single natural number are valid default goal selectors.

\end{fulllineitems}



\subsubsection{Bindings list}
\label{\detokenize{proof-engine/tactics:bindings-list}}\label{\detokenize{proof-engine/tactics:bindingslist}}
Tactics that take a term as argument may also support a bindings list,
so as to instantiate some parameters of the term by name or position.
The general form of a term equipped with a bindings list is \sphinxcode{\sphinxupquote{term with
bindings\_list}} where \sphinxcode{\sphinxupquote{bindings\_list}} may be of two different forms:

\phantomsection\label{\detokenize{proof-engine/tactics:bindings-list-grammar}}\begin{quote}


\begin{productionlist}
\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-bindings_list}}\production{bindings\_list}{ (ref := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}) ... (ref := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}})}
\productioncont{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} ... {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\end{productionlist}

\end{quote}
\begin{itemize}
\item {} 
In a bindings list of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{(ref:= term)}\DUrole{notation-sup}{*}}}}}, \sphinxcode{\sphinxupquote{\DUrole{notation}{ref}}} is either an
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} or a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}. The references are determined according to the type of
\sphinxcode{\sphinxupquote{term}}. If \sphinxcode{\sphinxupquote{\DUrole{notation}{ref}}} is an identifier, this identifier has to be bound in the
type of \sphinxcode{\sphinxupquote{term}} and the binding provides the tactic with an instance for the
parameter of this name. If \sphinxcode{\sphinxupquote{\DUrole{notation}{ref}}} is some number \sphinxcode{\sphinxupquote{n}}, this number denotes
the \sphinxcode{\sphinxupquote{n}}-th non dependent premise of the \sphinxcode{\sphinxupquote{term}}, as determined by the type
of \sphinxcode{\sphinxupquote{term}}.
\index{No such binder (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.no-such-binder}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~binder.}}}}
\end{fulllineitems}


\item {} 
A bindings list can also be a simple list of terms \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{term}\DUrole{notation-sup}{*}}}}}.
In that case the references to which these terms correspond are
determined by the tactic. In case of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.elim}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{elim}}}}}
and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.case}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{case}}}}}, the terms have to
provide instances for all the dependent products in the type of term while in
the case of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}}, or of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.constructor}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{constructor}}}}} and its variants, only instances
for the dependent products that are not bound in the conclusion of the type
are required.
\index{Not the right number of missing arguments (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-the-right-number-of-missing-arguments}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~the~right~number~of~missing~arguments.}}}}
\end{fulllineitems}


\end{itemize}


\subsubsection{Occurrence sets and occurrence clauses}
\label{\detokenize{proof-engine/tactics:occurrence-sets-and-occurrence-clauses}}\label{\detokenize{proof-engine/tactics:occurencessets}}
An occurrence clause is a modifier to some tactics that obeys the
following syntax:
\begin{quote}


\begin{productionlist}
\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-occurrence_clause}}\production{occurrence\_clause}{ in {\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{goal\_occurrences}}}}}}
\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-goal_occurrences}}\production{goal\_occurrences}{ {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[}{\hyperref[\detokenize{proof-engine/tactics:grammar-token-at-occurrences}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{at\_occurrences}}}}}{]}, ... , ident {[}{\hyperref[\detokenize{proof-engine/tactics:grammar-token-at-occurrences}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{at\_occurrences}}}}}{]} {[}\textbar{}- {[}* {[}{\hyperref[\detokenize{proof-engine/tactics:grammar-token-at-occurrences}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{at\_occurrences}}}}}{]}{]}{]}{]}}
\productioncont{\textbar{} * \textbar{}- {[}* {[}{\hyperref[\detokenize{proof-engine/tactics:grammar-token-at-occurrences}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{at\_occurrences}}}}}{]}{]}}
\productioncont{\textbar{} *}
\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-at_occurrences}}\production{at\_occurrences}{ at {\hyperref[\detokenize{proof-engine/tactics:grammar-token-occurrences}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occurrences}}}}}}
\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-occurrences}}\production{occurrences}{ {[}-{]} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}} ... {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}}}
\end{productionlist}

\end{quote}

The role of an occurrence clause is to select a set of occurrences of a term
in a goal. In the first case, the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{at \DUrole{repeat-wrapper}{\DUrole{repeat}{num}\DUrole{notation-sup}{*}}}\DUrole{notation-sup}{?}}}}} parts indicate
that occurrences have to be selected in the hypotheses named {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.
If no numbers are given for hypothesis {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}, then all the
occurrences of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} in the hypothesis are selected. If numbers are
given, they refer to occurrences of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} when the term is printed
using option {\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-all}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}}, counting from left to right. In particular,
occurrences of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} in implicit arguments
(see {\hyperref[\detokenize{language/gallina-extensions:implicitarguments}]{\sphinxcrossref{\DUrole{std,std-ref}{Implicit arguments}}}}) or coercions (see {\hyperref[\detokenize{language/gallina-extensions:coercions}]{\sphinxcrossref{\DUrole{std,std-ref}{Coercions}}}}) are
counted.

If a minus sign is given between \sphinxcode{\sphinxupquote{at}} and the list of occurrences, it
negates the condition so that the clause denotes all the occurrences
except the ones explicitly mentioned after the minus sign.

As an exception to the left-to-right order, the occurrences in
the return subexpression of a match are considered \sphinxstyleemphasis{before} the
occurrences in the matched term.

In the second case, the \sphinxcode{\sphinxupquote{*}} on the left of \sphinxcode{\sphinxupquote{\textbar{}-}} means that all occurrences
of term are selected in every hypothesis.

In the first and second case, if \sphinxcode{\sphinxupquote{*}} is mentioned on the right of \sphinxcode{\sphinxupquote{\textbar{}-}}, the
occurrences of the conclusion of the goal have to be selected. If some numbers
are given, then only the occurrences denoted by these numbers are selected. If
no numbers are given, all occurrences of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} in the goal are selected.

Finally, the last notation is an abbreviation for \sphinxcode{\sphinxupquote{* \textbar{}- *}}. Note also
that \sphinxcode{\sphinxupquote{\textbar{}-}} is optional in the first case when no \sphinxcode{\sphinxupquote{*}} is given.

Here are some tactics that understand occurrence clauses: {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.set}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{set}}}}},
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.remember}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{remember}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}}.


\sphinxstrong{See also:}


{\hyperref[\detokenize{proof-engine/tactics:managingthelocalcontext}]{\sphinxcrossref{\DUrole{std,std-ref}{Managing the local context}}}}, {\hyperref[\detokenize{proof-engine/tactics:caseanalysisandinduction}]{\sphinxcrossref{\DUrole{std,std-ref}{Case analysis and induction}}}},
{\hyperref[\detokenize{language/gallina-extensions:printing-constructions-full}]{\sphinxcrossref{\DUrole{std,std-ref}{Printing constructions in full}}}}.




\subsection{Applying theorems}
\label{\detokenize{proof-engine/tactics:applying-theorems}}\label{\detokenize{proof-engine/tactics:applyingtheorems}}\index{exact (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.exact}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{exact~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic applies to any goal. It gives directly the exact proof
term of the goal. Let \sphinxcode{\sphinxupquote{T}} be our goal, let \sphinxcode{\sphinxupquote{p}} be a term of type \sphinxcode{\sphinxupquote{U}} then
\sphinxcode{\sphinxupquote{exact p}} succeeds iff \sphinxcode{\sphinxupquote{T}} and \sphinxcode{\sphinxupquote{U}} are convertible (see
{\hyperref[\detokenize{language/cic:conversion-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{Conversion rules}}}}).
\index{Not an exact proof (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-an-exact-proof}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~an~exact~proof.}}}}
\end{fulllineitems}

\index{eexact (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.eexact}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eexact~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}.}}}}
This tactic behaves like {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.exact}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exact}}}}} but is able to handle terms and
goals with existential variables.

\end{fulllineitems}


\end{fulllineitems}

\index{assumption (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.assumption}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{assumption}}}}
This tactic looks in the local context for a hypothesis whose type is
convertible to the goal. If it is the case, the subgoal is proved.
Otherwise, it fails.
\index{No such assumption (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.no-such-assumption}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~assumption.}}}}
\end{fulllineitems}

\index{eassumption (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.eassumption}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eassumption}}}}
This tactic behaves like {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.assumption}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{assumption}}}}} but is able to handle
goals with existential variables.

\end{fulllineitems}


\end{fulllineitems}

\index{refine (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.refine}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{refine~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic applies to any goal. It behaves like {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.exact}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exact}}}}} with a big
difference: the user can leave some holes (denoted by \sphinxcode{\sphinxupquote{\_}}
or \sphinxcode{\sphinxupquote{\DUrole{notation}{(\_ : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})}}}) in the term. {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} will generate as many
subgoals as there are holes in the term. The type of holes must be either
synthesized by the system or declared by an explicit cast
like \sphinxcode{\sphinxupquote{(\_ : nat -\textgreater{} Prop)}}. Any subgoal that
occurs in other subgoals is automatically shelved, as if calling
{\hyperref[\detokenize{proof-engine/tactics:coq:tacv.shelve-unifiable}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{shelve\_unifiable}}}}}. This low-level tactic can be
useful to advanced users.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{Option} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{Fail} \PYG{o}{:} \PYG{n}{Option}
\PYG{o}{\textbar{}} \PYG{n}{Ok} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Option}\PYG{o}{.}
    \PYG{n}{Option} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Option\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Option\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Option\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{get} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{:}\PYG{n}{Option}\PYG{o}{,} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{Fail} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{Option}\PYG{o}{,} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{Fail} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}

\PYG{k}{refine}
    \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x}\PYG{o}{:}\PYG{n}{Option} \PYG{o}{=\PYGZgt{}}
      \PYG{k}{match} \PYG{n}{x} \PYG{k}{return} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{Fail} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool} \PYG{k}{with}
      \PYG{o}{\textbar{}} \PYG{n}{Fail} \PYG{o}{=\PYGZgt{}} \PYG{o}{\PYGZus{}}
      \PYG{o}{\textbar{}} \PYG{n}{Ok} \PYG{n}{b} \PYG{o}{=\PYGZgt{}} \PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{b}
      \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{Option}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{Fail} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{Fail} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}

\PYG{k}{intros}\PYG{o}{;} \PYG{n}{absurd} \PYG{o}{(}\PYG{n}{Fail} \PYG{o}{=} \PYG{n}{Fail}\PYG{o}{)}\PYG{o}{;} \PYG{k}{trivial}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Defined}\PYG{o}{.}
    \PYG{n}{get} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{Invalid argument (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.invalid-argument}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Invalid~argument.}}}}
The tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} does not know what to do with the term you gave.

\end{fulllineitems}

\index{Refine passed ill-formed term (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.refine-passed-ill-formed-term}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Refine~passed~ill-formed~term.}}}}
The term you gave is not a valid proof (not easy to debug in general). This
message may also occur in higher-level tactics that call {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}}
internally.

\end{fulllineitems}

\index{Cannot infer a term for this placeholder. (refine) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.cannot-infer-a-term-for-this-placeholder-refine}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~infer~a~term~for~this~placeholder.}}}}
There is a hole in the term you gave whose type cannot be inferred. Put a
cast around it.

\end{fulllineitems}

\index{simple refine (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.simple-refine}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~refine~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic behaves like refine, but it does not shelve any subgoal. It does
not perform any beta-reduction either.

\end{fulllineitems}

\index{notypeclasses refine (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.notypeclasses-refine}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{notypeclasses~refine~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic behaves like {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} except it performs type checking without
resolution of typeclasses.

\end{fulllineitems}

\index{simple notypeclasses refine (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.simple-notypeclasses-refine}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~notypeclasses~refine~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic behaves like {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.simple-refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple refine}}}}} except it performs type checking
without resolution of typeclasses.

\end{fulllineitems}


\end{fulllineitems}

\index{apply (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.apply}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic applies to any goal. The argument term is a term well-formed in
the local context. The tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} tries to match the current goal
against the conclusion of the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. If it succeeds, then
the tactic returns as many subgoals as the number of non-dependent premises
of the type of term. If the conclusion of the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} does
not match the goal \sphinxstyleemphasis{and} the conclusion is an inductive type isomorphic to
a tuple type, then each component of the tuple is recursively matched to
the goal in the left-to-right order.

The tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} relies on first-order unification with dependent
types unless the conclusion of the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} is of the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{P (t$_{\text{1}}$ ... t$_{\text{n}}$)}}} with \sphinxcode{\sphinxupquote{P}} to be instantiated. In the latter case,
the behavior depends on the form of the goal. If the goal is of the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{(fun x =\textgreater{} Q) u$_{\text{1}}$ ... u$_{\text{n}}$}}} and the \sphinxcode{\sphinxupquote{\DUrole{notation}{t$_{\text{i}}$}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{u$_{\text{i}}$}}} unify,
then \sphinxcode{\sphinxupquote{\DUrole{name}{P}}} is taken to be \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{keyword}{fun} \DUrole{name}{x} \DUrole{operator}{=\textgreater{}} \DUrole{name}{Q}\DUrole{operator}{)}}}. Otherwise, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}}
tries to define \sphinxcode{\sphinxupquote{\DUrole{name}{P}}} by abstracting over \sphinxcode{\sphinxupquote{\DUrole{name}{t\_1} \DUrole{operator}{...} \DUrole{name}{t\_\_n}}} in the goal.
See {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} to transform the goal so that it
gets the form \sphinxcode{\sphinxupquote{\DUrole{notation}{(fun x =\textgreater{} Q) u$_{\text{1}}$ ... u$_{\text{n}}$}}}.
\index{Unable to unify ‘term’ with ‘term’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.unable-to-unify-term-with-term}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unable~to~unify~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}.}}}}
The {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} tactic failed to match the conclusion of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}
and the current goal. You can help the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} tactic by
transforming your goal with the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.change}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change}}}}} or {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}
tactics.

\end{fulllineitems}

\index{Unable to find an instance for the variables ‘ident’…‘ident’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.unable-to-find-an-instance-for-the-variables-ident-ident}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unable~to~find~an~instance~for~the~variables~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}.}}}}
This occurs when some instantiations of the premises of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} are not deducible
from the unification. This is the case, for instance, when you want to apply a
transitivity property. In this case, you have to use one of the variants below:

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}}}
Provides apply with explicit instantiations for all dependent premises of the
type of term that do not occur in the conclusion and consequently cannot be
found by unification. Notice that the collection \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}} must be given
according to the order of these dependent premises of the type of term.
\index{Not the right number of missing arguments (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~the~right~number~of~missing~arguments.}}}}
\end{fulllineitems}


\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}}
This also provides apply with values for instantiating premises. Here, variables
are referred by names and non-dependent products by increasing numbers (see
{\hyperref[\detokenize{proof-engine/tactics:bindingslist}]{\sphinxcrossref{\DUrole{std,std-ref}{bindings list}}}}).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
This is a shortcut for \sphinxcode{\sphinxupquote{\DUrole{notation}{apply {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}}; {[}.. \textbar{} ... ; {[} .. \textbar{} apply {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{n}}$}}}}{]} ... {]}}}},
i.e. for the successive applications of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}$_{\text{i+1}}$ on the last subgoal
generated by \sphinxcode{\sphinxupquote{\DUrole{notation}{apply {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{i}}$}}}}}}} , starting from the application of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term$_{\text{1}}$}}}}}}}.

\end{fulllineitems}

\index{eapply (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.eapply}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eapply~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
The tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eapply}}}}} behaves like {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} but it does not fail when no
instantiations are deducible for some variables in the premises. Rather, it
turns these variables into existential variables which are variables still to
instantiate (see {\hyperref[\detokenize{language/gallina-extensions:existential-variables}]{\sphinxcrossref{\DUrole{std,std-ref}{Existential variables}}}}). The instantiation is
intended to be found later in the proof.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~apply~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}.}}}}
This behaves like {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} but it reasons modulo conversion only on subterms
that contain no variables to instantiate. For instance, the following example
does not succeed because it would require the conversion of \sphinxcode{\sphinxupquote{id ?foo}} and
\sphinxcode{\sphinxupquote{\DUrole{name}{O}}}.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{id} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{x}\PYG{o}{.}
    \PYG{n}{id} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Parameter} \PYG{n}{H} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{y}\PYG{o}{,} \PYG{n}{id} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y}\PYG{o}{.}
    \PYG{n}{H} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Goal} \PYG{n}{O} \PYG{o}{=} \PYG{n}{O}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{n}{Fail} \PYG{n}{simple} \PYG{k}{apply} \PYG{n}{H}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{Unable} \PYG{n}{to} \PYG{n}{unify} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{id ?M160 = ?M160}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{with} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{0 = 0}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Because it reasons modulo a limited amount of conversion, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.simple-apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simple apply}}}}} fails
quicker than {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} and it is then well-suited for uses in user-defined
tactics that backtrack often. Moreover, it does not traverse tuples as {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}}
does.

\end{fulllineitems}

\index{simple apply (tacnv)}\index{simple eapply (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.simple-apply}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{simple}\DUrole{notation-sup}{?}}~apply~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.simple-eapply}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{simple}\DUrole{notation-sup}{?}}~eapply~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
This summarizes the different syntaxes for {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eapply}}}}}.

\end{fulllineitems}

\index{lapply (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.lapply}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{lapply~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic applies to any goal, say \sphinxcode{\sphinxupquote{\DUrole{name}{G}}}. The argument term has to be
well-formed in the current context, its type being reducible to a non-dependent
product \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{-\textgreater{}} \DUrole{name}{B}}} with \sphinxcode{\sphinxupquote{\DUrole{name}{B}}} possibly containing products. Then it generates
two subgoals \sphinxcode{\sphinxupquote{\DUrole{name}{B}\DUrole{operator}{-\textgreater{}}\DUrole{name}{G}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{A}}}. Applying \sphinxcode{\sphinxupquote{lapply H}} (where \sphinxcode{\sphinxupquote{\DUrole{name}{H}}} has type
\sphinxcode{\sphinxupquote{\DUrole{name}{A}\DUrole{operator}{-\textgreater{}}\DUrole{name}{B}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{B}}} does not start with a product) does the same as giving the
sequence \sphinxcode{\sphinxupquote{cut B. 2:apply H.}} where \sphinxcode{\sphinxupquote{cut}} is described below.
\index{When ‘term’ contains more than one non dependent product the tactic lapply only takes into account the first product (warn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:warn.when-term-contains-more-than-one-non-dependent-product-the-tactic-lapply-only-takes-into-account-the-first-product}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{When~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~contains~more~than~one~non~dependent~product~the~tactic~lapply~only~takes~into~account~the~first~product.}}}}
\end{fulllineitems}


\end{fulllineitems}


\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

Assume we have a transitive relation \sphinxcode{\sphinxupquote{R}} on \sphinxcode{\sphinxupquote{nat}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variable} \PYG{n}{R} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
\PYG{k+kn}{Hypothesis} \PYG{n}{Rtrans} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{R} \PYG{n}{x} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R} \PYG{n}{y} \PYG{n}{z} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R} \PYG{n}{x} \PYG{n}{z}\PYG{o}{.}
\PYG{k+kn}{Variables} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{.}
\PYG{k+kn}{Hypothesis} \PYG{n}{Rnm} \PYG{o}{:} \PYG{n}{R} \PYG{n}{n} \PYG{n}{m}\PYG{o}{.}
\PYG{k+kn}{Hypothesis} \PYG{n}{Rmp} \PYG{o}{:} \PYG{n}{R} \PYG{n}{m} \PYG{n}{p}\PYG{o}{.}
\end{sphinxVerbatim}

Consider the goal \sphinxcode{\sphinxupquote{(R n p)}} provable using the transitivity of \sphinxcode{\sphinxupquote{R}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{R} \PYG{n}{n} \PYG{n}{p}\PYG{o}{.}
\end{sphinxVerbatim}

The direct application of \sphinxcode{\sphinxupquote{Rtrans}} with \sphinxcode{\sphinxupquote{apply}} fails because no value
for \sphinxcode{\sphinxupquote{y}} in \sphinxcode{\sphinxupquote{Rtrans}} is found by \sphinxcode{\sphinxupquote{apply}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k}{apply} \PYG{n}{Rtrans}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{Unable} \PYG{n}{to} \PYG{n}{find} \PYG{n}{an} \PYG{n}{instance} \PYG{k}{for} \PYG{n}{the} \PYG{n}{variable} \PYG{n}{y}\PYG{o}{.}
\end{sphinxVerbatim}

A solution is to \sphinxcode{\sphinxupquote{apply (Rtrans n m p)}} or \sphinxcode{\sphinxupquote{(Rtrans n m)}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{apply} \PYG{o}{(}\PYG{n}{Rtrans} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{R} \PYG{n}{n} \PYG{n}{m}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{R} \PYG{n}{m} \PYG{n}{p}
\end{sphinxVerbatim}

Note that \sphinxcode{\sphinxupquote{n}} can be inferred from the goal, so the following would work
too.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{apply} \PYG{o}{(}\PYG{n}{Rtrans} \PYG{o}{\PYGZus{}} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

More elegantly, \sphinxcode{\sphinxupquote{apply Rtrans with (y:=m)}} allows only mentioning the
unknown m:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{apply} \PYG{n}{Rtrans} \PYG{k}{with} \PYG{o}{(}\PYG{n}{y} \PYG{o}{:=} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

Another solution is to mention the proof of \sphinxcode{\sphinxupquote{(R x y)}} in \sphinxcode{\sphinxupquote{Rtrans}}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{apply} \PYG{n}{Rtrans} \PYG{k}{with} \PYG{o}{(}\PYG{l+m+mi}{1} \PYG{o}{:=} \PYG{n}{Rnm}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{R} \PYG{n}{m} \PYG{n}{p}
\end{sphinxVerbatim}

... or the proof of \sphinxcode{\sphinxupquote{(R y z)}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{apply} \PYG{n}{Rtrans} \PYG{k}{with} \PYG{o}{(}\PYG{l+m+mi}{2} \PYG{o}{:=} \PYG{n}{Rmp}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{R} \PYG{n}{n} \PYG{n}{m}
\end{sphinxVerbatim}

On the opposite, one can use \sphinxcode{\sphinxupquote{eapply}} which postpones the problem of
finding \sphinxcode{\sphinxupquote{m}}. Then one can apply the hypotheses \sphinxcode{\sphinxupquote{Rnm}} and \sphinxcode{\sphinxupquote{Rmp}}. This
instantiates the existential variable and completes the proof.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{eapply} \PYG{n}{Rtrans}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{focused} \PYG{n}{subgoals}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{1}\PYG{o}{)}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{R} \PYG{n}{n} \PYG{o}{?}\PYG{n}{y}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{R} \PYG{o}{?}\PYG{n}{y} \PYG{n}{p}

\PYG{k}{apply} \PYG{n}{Rnm}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{R} \PYG{n}{m} \PYG{n}{p}

\PYG{k}{apply} \PYG{n}{Rmp}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
When the conclusion of the type of the term to \sphinxcode{\sphinxupquote{apply}} is an inductive
type isomorphic to a tuple type and \sphinxcode{\sphinxupquote{apply}} looks recursively whether a
component of the tuple matches the goal, it excludes components whose
statement would result in applying an universal lemma of the form
\sphinxcode{\sphinxupquote{forall A, ... -\textgreater{} A}}. Excluding this kind of lemma can be avoided by
setting the following option:
\end{sphinxadmonition}
\index{Universal Lemma Under Conjunction (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.universal-lemma-under-conjunction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Universal~Lemma~Under~Conjunction}}}}
This option, which preserves compatibility with versions of Coq prior to
8.4 is also available for \sphinxcode{\sphinxupquote{\DUrole{notation}{apply {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} (see {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply-in}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply ... in}}}}}).

\end{fulllineitems}

\index{apply ... in (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.apply-in}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This tactic applies to any goal. The argument {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} is a term
well-formed in the local context and the argument {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is an
hypothesis of the context.
The tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{apply {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} tries to match the conclusion of the
type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} against a non-dependent premise of the type
of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}, trying them from right to left. If it succeeds, the
statement of hypothesis {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is replaced by the conclusion of
the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. The tactic also returns as many subgoals as the
number of other non-dependent premises in the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} and of
the non-dependent premises of the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}. If the conclusion
of the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} does not match the goal \sphinxstyleemphasis{and} the conclusion
is an inductive type isomorphic to a tuple type, then
the tuple is (recursively) decomposed and the first component of the tuple
of which a non-dependent premise matches the conclusion of the type of
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}. Tuples are decomposed in a width-first left-to-right order
(for instance if the type of \sphinxcode{\sphinxupquote{\DUrole{name}{H1}}} is \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{\textless{}-\textgreater{}} \DUrole{name}{B}}} and the type of
\sphinxcode{\sphinxupquote{\DUrole{name}{H2}}} is \sphinxcode{\sphinxupquote{\DUrole{name}{A}}} then \sphinxcode{\sphinxupquote{\DUrole{keyword}{apply} \DUrole{name}{H1} \DUrole{keyword}{in} \DUrole{name}{H2}}} transforms the type of \sphinxcode{\sphinxupquote{\DUrole{name}{H2}}}
into \sphinxcode{\sphinxupquote{\DUrole{name}{B}}}). The tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} relies on first-order pattern matching
with dependent types.
\index{Statement without assumptions (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.statement-without-assumptions}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Statement~without~assumptions.}}}}
This happens if the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} has no non-dependent premise.

\end{fulllineitems}

\index{Unable to apply (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.unable-to-apply}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unable~to~apply.}}}}
This happens if the conclusion of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} does not match any of
the non-dependent premises of the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This applies each {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} in sequence in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This does the same but uses the bindings in each \sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}} to
instantiate the parameters of the corresponding type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}
(see {\hyperref[\detokenize{proof-engine/tactics:bindingslist}]{\sphinxcrossref{\DUrole{std,std-ref}{bindings list}}}}).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eapply~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This works as {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply-in}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply ... in}}}}} but turns unresolved bindings into
existential variables, if any, instead of failing.

\end{fulllineitems}

\index{apply ... in ... as (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.apply-in-as}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~\DUrole{hole}{intro\_pattern}}}}}
This works as {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply-in}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply ... in}}}}} then applies the \sphinxcode{\sphinxupquote{intro\_pattern}}
to the hypothesis {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~apply~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This behaves like {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply-in}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply ... in}}}}} but it reasons modulo conversion
only on subterms that contain no variables to instantiate. For instance,
if \sphinxcode{\sphinxupquote{\DUrole{name}{id} \DUrole{operator}{:=} \DUrole{keyword}{fun} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{keyword,type}{nat} \DUrole{operator}{=\textgreater{}} \DUrole{name}{x}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{H}\DUrole{operator}{:} \DUrole{keyword}{forall} \DUrole{name}{y}\DUrole{operator}{,} \DUrole{name}{id} \DUrole{name}{y} \DUrole{operator}{=} \DUrole{name}{y} \DUrole{operator}{-\textgreater{}} \DUrole{name}{True}}} and
\sphinxcode{\sphinxupquote{\DUrole{name}{H0} \DUrole{operator}{:} \DUrole{name}{O} \DUrole{operator}{=} \DUrole{name}{O}}} then \sphinxcode{\sphinxupquote{\DUrole{name}{simple} \DUrole{keyword}{apply} \DUrole{name}{H} \DUrole{keyword}{in} \DUrole{name}{H0}}} does not succeed because it
would require the conversion of \sphinxcode{\sphinxupquote{\DUrole{name}{id} \DUrole{operator}{?}\DUrole{name}{x}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{O}}} where \sphinxcode{\sphinxupquote{\DUrole{operator}{?}\DUrole{name}{x}}} is
an existential variable to instantiate.
Tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{simple apply {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} does not
either traverse tuples as \sphinxcode{\sphinxupquote{\DUrole{notation}{apply {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} does.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{simple}\DUrole{notation-sup}{?}}~apply~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~\DUrole{hole}{intro\_pattern}}\DUrole{notation-sup}{?}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{simple}\DUrole{notation-sup}{?}}~eapply~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~\DUrole{hole}{intro\_pattern}}\DUrole{notation-sup}{?}}}}}}
This summarizes the different syntactic variants of \sphinxcode{\sphinxupquote{\DUrole{notation}{apply {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
and \sphinxcode{\sphinxupquote{\DUrole{notation}{eapply {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}


\end{fulllineitems}

\index{constructor (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.constructor}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{constructor~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This tactic applies to a goal such that its conclusion is an inductive
type (say \sphinxcode{\sphinxupquote{\DUrole{name}{I}}}). The argument {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}} must be less or equal to the
numbers of constructor(s) of \sphinxcode{\sphinxupquote{\DUrole{name}{I}}}. Let \sphinxcode{\sphinxupquote{\DUrole{notation}{c$_{\text{i}}$}}} be the i-th
constructor of \sphinxcode{\sphinxupquote{\DUrole{name}{I}}}, then \sphinxcode{\sphinxupquote{\DUrole{keyword}{constructor} \DUrole{name}{i}}} is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{intros; apply c$_{\text{i}}$}}}.
\index{Not an inductive product (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-an-inductive-product}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~an~inductive~product.}}}}
\end{fulllineitems}

\index{Not enough constructors (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-enough-constructors}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~enough~constructors.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{constructor}}}}
This tries \sphinxcode{\sphinxupquote{\DUrole{keyword}{constructor} \DUrole{literal,number,integer}{1}}} then \sphinxcode{\sphinxupquote{\DUrole{keyword}{constructor} \DUrole{literal,number,integer}{2}}}, ..., then
\sphinxcode{\sphinxupquote{\DUrole{keyword}{constructor} \DUrole{name}{n}}} where \sphinxcode{\sphinxupquote{n}} is the number of constructors of the head
of the goal.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{constructor~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}}
Let \sphinxcode{\sphinxupquote{c}} be the i-th constructor of \sphinxcode{\sphinxupquote{\DUrole{name}{I}}}, then
\sphinxcode{\sphinxupquote{\DUrole{notation}{constructor i with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}} is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{intros; apply c with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}.

\begin{sphinxadmonition}{warning}{Warning:}
The terms in the {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bindings\_list}}}}} are checked in the context
where constructor is executed and not in the context where {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}}
is executed (the introductions are not taken into account).
\end{sphinxadmonition}

\end{fulllineitems}

\index{split (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.split}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{split~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}}}}
This applies only if \sphinxcode{\sphinxupquote{\DUrole{name}{I}}} has a single constructor. It is then
equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{constructor 1 \DUrole{repeat-wrapper}{\DUrole{repeat}{with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}}}. It is
typically used in the case of a conjunction \(A \wedge B\).
\index{exists (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.exists}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{exists~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}}
This applies only if \sphinxcode{\sphinxupquote{\DUrole{name}{I}}} has a single constructor. It is then equivalent
to \sphinxcode{\sphinxupquote{\DUrole{notation}{intros; constructor 1 with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}.}}} It is typically used in
the case of an existential quantification \(\exists x, P(x).\)

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{exists~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
This iteratively applies \sphinxcode{\sphinxupquote{\DUrole{notation}{exists {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}.

\end{fulllineitems}

\index{Not an inductive goal with 1 constructor (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-an-inductive-goal-with-1-constructor}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~an~inductive~goal~with~1~constructor.}}}}
\end{fulllineitems}


\end{fulllineitems}

\index{left (tacnv)}\index{right (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.left}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{left~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.right}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{right~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}}}}
These tactics apply only if \sphinxcode{\sphinxupquote{\DUrole{name}{I}}} has two constructors, for
instance in the case of a disjunction \(A \vee B\).
Then, they are respectively equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{constructor 1 \DUrole{repeat-wrapper}{\DUrole{repeat}{with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}}} and
\sphinxcode{\sphinxupquote{\DUrole{notation}{constructor 2 \DUrole{repeat-wrapper}{\DUrole{repeat}{with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}}}.
\index{Not an inductive goal with 2 constructors (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-an-inductive-goal-with-2-constructors}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~an~inductive~goal~with~2~constructors.}}}}
\end{fulllineitems}


\end{fulllineitems}

\index{econstructor (tacnv)}\index{eexists (tacnv)}\index{esplit (tacnv)}\index{eleft (tacnv)}\index{eright (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.econstructor}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{econstructor}}}}\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.eexists}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eexists}}}}\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.esplit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{esplit}}}}\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.eleft}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eleft}}}}\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.eright}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eright}}}}
These tactics and their variants behave like {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.constructor}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{constructor}}}}},
{\hyperref[\detokenize{proof-engine/tactics:coq:tacv.exists}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{exists}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.split}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{split}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.left}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{left}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.right}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{right}}}}} and their
variants but they introduce existential variables instead of failing
when the instantiation of a variable cannot be found
(cf. {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eapply}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}}).

\end{fulllineitems}


\end{fulllineitems}



\subsection{Managing the local context}
\label{\detokenize{proof-engine/tactics:managing-the-local-context}}\label{\detokenize{proof-engine/tactics:managingthelocalcontext}}\index{intro (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.intro}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{intro}}}}
This tactic applies to a goal that is either a product or starts with a
let-binder. If the goal is a product, the tactic implements the "Lam" rule
given in {\hyperref[\detokenize{language/cic:typing-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{Typing rules}}}} %
\begin{footnote}[1]\sphinxAtStartFootnote
Actually, only the second subgoal will be generated since the
other one can be automatically checked.
%
\end{footnote}. If the goal starts with a let-binder,
then the tactic implements a mix of the "Let" and "Conv".

If the current goal is a dependent product \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{T}\DUrole{operator}{,} \DUrole{name}{U}}}
(resp \sphinxcode{\sphinxupquote{\DUrole{keyword}{let} \DUrole{name}{x}\DUrole{operator}{:=}\DUrole{name}{t} \DUrole{keyword}{in} \DUrole{name}{U}}}) then {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} puts \sphinxcode{\sphinxupquote{\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{T}}} (resp \sphinxcode{\sphinxupquote{\DUrole{name}{x}\DUrole{operator}{:=}\DUrole{name}{t}}})
in the local context. The new subgoal is \sphinxcode{\sphinxupquote{\DUrole{name}{U}}}.

If the goal is a non-dependent product \(T \rightarrow U\), then it
puts in the local context either \sphinxcode{\sphinxupquote{\DUrole{name}{Hn}\DUrole{operator}{:}\DUrole{name}{T}}} (if \sphinxcode{\sphinxupquote{\DUrole{name}{T}}} is of type \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}}
or \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}}) or \sphinxcode{\sphinxupquote{\DUrole{name}{Xn}\DUrole{operator}{:}\DUrole{name}{T}}} (if the type of \sphinxcode{\sphinxupquote{\DUrole{name}{T}}} is \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}}).
The optional index \sphinxcode{\sphinxupquote{n}} is such that \sphinxcode{\sphinxupquote{Hn}} or \sphinxcode{\sphinxupquote{Xn}} is a fresh
identifier. In both cases, the new subgoal is \sphinxcode{\sphinxupquote{\DUrole{name}{U}}}.

If the goal is neither a product nor starting with a let definition,
the tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} applies the tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.hnf}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{hnf}}}}} until the
tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} can be applied or the goal is not head-reducible.
\index{No product even after head-reduction (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.no-product-even-after-head-reduction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~product~even~after~head-reduction.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intro~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This applies {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} but forces {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} to be the name of
the introduced hypothesis.
\index{‘ident’ is already used (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.ident-is-already-used}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~already~used.}}}}
\end{fulllineitems}


\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}
If a name used by intro hides the base name of a global constant then
the latter can still be referred to by a qualified name
(see {\hyperref[\detokenize{language/gallina-extensions:qualified-names}]{\sphinxcrossref{\DUrole{std,std-ref}{Qualified names}}}}).
\end{sphinxadmonition}
\index{intros (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.intros}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intros}}}}
This repeats {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} until it meets the head-constant. It never
reduces head-constants and it never fails.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intros~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}.}}}}
This is equivalent to the composed tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{intro {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; ... ; intro {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intros~until~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This repeats intro until it meets a premise of the goal having the
form \sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})}}} and discharges the variable
named {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} of the current goal.
\index{No such hypothesis in current goal (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.no-such-hypothesis-in-current-goal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~hypothesis~in~current~goal.}}}}
\end{fulllineitems}


\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intros~until~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This repeats {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} until the {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}}-th non-dependent
product.

\begin{sphinxadmonition}{note}{Example}

On the subgoal \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x} \DUrole{name}{y} \DUrole{operator}{:} \DUrole{keyword,type}{nat}\DUrole{operator}{,} \DUrole{name}{x} \DUrole{operator}{=} \DUrole{name}{y} \DUrole{operator}{-\textgreater{}} \DUrole{name}{y} \DUrole{operator}{=} \DUrole{name}{x}}} the
tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until 1}}} is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{intros x y H}}},
as \sphinxcode{\sphinxupquote{\DUrole{name}{x} \DUrole{operator}{=} \DUrole{name}{y} \DUrole{operator}{-\textgreater{}} \DUrole{name}{y} \DUrole{operator}{=} \DUrole{name}{x}}} is the first non-dependent product.

On the subgoal \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x} \DUrole{name}{y} \DUrole{name}{z} \DUrole{operator}{:} \DUrole{keyword,type}{nat}\DUrole{operator}{,} \DUrole{name}{x} \DUrole{operator}{=} \DUrole{name}{y} \DUrole{operator}{-\textgreater{}} \DUrole{name}{y} \DUrole{operator}{=} \DUrole{name}{x}}} the
tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until 1}}} is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{intros x y z}}}
as the product on \sphinxcode{\sphinxupquote{\DUrole{name}{z}}} can be rewritten as a non-dependent
product: \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x} \DUrole{name}{y} \DUrole{operator}{:} \DUrole{keyword,type}{nat}\DUrole{operator}{,} \DUrole{keyword,type}{nat} \DUrole{operator}{-\textgreater{}} \DUrole{name}{x} \DUrole{operator}{=} \DUrole{name}{y} \DUrole{operator}{-\textgreater{}} \DUrole{name}{y} \DUrole{operator}{=} \DUrole{name}{x}}}.
\end{sphinxadmonition}
\index{No such hypothesis in current goal (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~hypothesis~in~current~goal.}}}}
This happens when {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}} is 0 or is greater than the number of
non-dependent products of the goal.

\end{fulllineitems}


\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intro~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}\DUrole{notation-sup}{?}}~after~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intro~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}\DUrole{notation-sup}{?}}~before~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intro~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}\DUrole{notation-sup}{?}}~at~top}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intro~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}\DUrole{notation-sup}{?}}~at~bottom}}}}
These tactics apply \sphinxcode{\sphinxupquote{\DUrole{notation}{intro \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}\DUrole{notation-sup}{?}}}}} and move the freshly
introduced hypothesis respectively after the hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}},
before the hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}, at the top of the local context,
or at the bottom of the local context. All hypotheses on which the new
hypothesis depends are moved too so as to respect the order of
dependencies between hypotheses. It is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{intro \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}\DUrole{notation-sup}{?}}}}}
followed by the appropriate call to {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.move-after}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{move ... after ...}}}}},
{\hyperref[\detokenize{proof-engine/tactics:coq:tacv.move-before}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{move ... before ...}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.move-at-top}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{move ... at top}}}}},
or {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.move-at-bottom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{move ... at bottom}}}}}.

\begin{sphinxadmonition}{note}{Note:}
\sphinxcode{\sphinxupquote{\DUrole{notation}{intro at bottom}}} is a synonym for \sphinxcode{\sphinxupquote{\DUrole{notation}{intro}}} with no argument.
\end{sphinxadmonition}
\index{No such hypothesis: ‘ident’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.no-such-hypothesis-ident}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~hypothesis:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}


\end{fulllineitems}


\end{fulllineitems}

\index{intros ... (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.intros}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{intros~\DUrole{hole}{intro\_pattern\_list}}}}}
This extension of the tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{intros}}} allows to apply tactics on the fly
on the variables or hypotheses which have been introduced. An
\sphinxstyleemphasis{introduction pattern list} \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{intro\_pattern\_list}}}} is a list of
introduction patterns possibly containing the filling introduction
patterns \sphinxtitleref{*} and \sphinxtitleref{**}. An \sphinxstyleemphasis{introduction pattern} is either:
\begin{itemize}
\item {} 
a \sphinxstyleemphasis{naming introduction pattern}, i.e. either one of:
\begin{itemize}
\item {} 
the pattern \sphinxcode{\sphinxupquote{\DUrole{notation}{?}}}

\item {} 
the pattern \sphinxcode{\sphinxupquote{\DUrole{notation}{?ident}}}

\item {} 
an identifier

\end{itemize}

\item {} 
an \sphinxstyleemphasis{action introduction pattern} which itself classifies into:
\begin{itemize}
\item {} 
a \sphinxstyleemphasis{disjunctive/conjunctive introduction pattern}, i.e. either one of
\begin{itemize}
\item {} 
a disjunction of lists of patterns
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[}\DUrole{hole}{intro\_pattern\_list} \textbar{} ... \textbar{} \DUrole{hole}{intro\_pattern\_list}{]}}}}

\item {} 
a conjunction of patterns: \sphinxcode{\sphinxupquote{\DUrole{notation}{(\DUrole{repeat-wrapper}{\DUrole{repeat}{p}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}})}}}

\item {} 
a list of patterns
\sphinxcode{\sphinxupquote{\DUrole{notation}{(\DUrole{repeat-wrapper}{\DUrole{repeat}{p}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\&}})}}}
for sequence of right-associative binary constructs

\end{itemize}

\item {} 
an \sphinxstyleemphasis{equality introduction pattern}, i.e. either one of:
\begin{itemize}
\item {} 
a pattern for decomposing an equality: \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}= \DUrole{repeat-wrapper}{\DUrole{repeat}{p}\DUrole{notation-sup}{+}}{]}}}}

\item {} 
the rewriting orientations: \sphinxcode{\sphinxupquote{\DUrole{notation}{-\textgreater{}}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{\textless{}-}}}

\end{itemize}

\item {} 
the on-the-fly application of lemmas: \sphinxcode{\sphinxupquote{\DUrole{notation}{p\DUrole{repeat-wrapper}{\DUrole{repeat}{\%term}\DUrole{notation-sup}{+}}}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{p}}}
itself is not a pattern for on-the-fly application of lemmas (note:
syntax is in experimental stage)

\end{itemize}

\item {} 
the wildcard: \sphinxcode{\sphinxupquote{\DUrole{notation}{\_}}}

\end{itemize}

Assuming a goal of type \sphinxcode{\sphinxupquote{\DUrole{name}{Q} \DUrole{error}{\(\rightarrow\)} \DUrole{name}{P}}} (non-dependent product), or of type
\(\forall\)\sphinxcode{\sphinxupquote{\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{T}\DUrole{operator}{,} \DUrole{name}{P}}} (dependent product), the behavior of
\sphinxcode{\sphinxupquote{\DUrole{notation}{intros p}}} is defined inductively over the structure of the introduction
pattern \sphinxcode{\sphinxupquote{\DUrole{notation}{p}}}:

Introduction on \sphinxcode{\sphinxupquote{\DUrole{notation}{?}}} performs the introduction, and lets Coq choose a fresh
name for the variable;

Introduction on \sphinxcode{\sphinxupquote{\DUrole{notation}{?{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} performs the introduction, and lets Coq choose a
fresh name for the variable based on \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}};

Introduction on \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} behaves as described in {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}}

Introduction over a disjunction of list of patterns
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[}\DUrole{hole}{intro\_pattern\_list} \textbar{} ... \textbar{} \DUrole{hole}{intro\_pattern\_list} {]}}}} expects the product
to be over an inductive type whose number of constructors is \sphinxtitleref{n} (or more
generally over a type of conclusion an inductive type built from \sphinxtitleref{n}
constructors, e.g. \sphinxcode{\sphinxupquote{\DUrole{name}{C} \DUrole{operator}{-\textgreater{}} \DUrole{name}{A}\DUrole{operator}{\textbackslash{}/}\DUrole{name}{B}}} with \sphinxtitleref{n=2} since \sphinxcode{\sphinxupquote{\DUrole{name}{A}\DUrole{operator}{\textbackslash{}/}\DUrole{name}{B}}} has \sphinxtitleref{2}
constructors): it destructs the introduced hypothesis as \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct}}} (see
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}}) would and applies on each generated subgoal the
corresponding tactic;

The introduction patterns in \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{intro\_pattern\_list}}}} are expected to consume
no more than the number of arguments of the \sphinxtitleref{i}-th constructor. If it
consumes less, then Coq completes the pattern so that all the arguments of
the constructors of the inductive type are introduced (for instance, the
list of patterns \sphinxcode{\sphinxupquote{\DUrole{notation}{{[} \textbar{} {]} H}}} applied on goal \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{keyword,type}{nat}\DUrole{operator}{,} \DUrole{name}{x}\DUrole{operator}{=}\DUrole{literal,number,integer}{0} \DUrole{operator}{-\textgreater{}} \DUrole{literal,number,integer}{0}\DUrole{operator}{=}\DUrole{name}{x}}}
behaves the same as the list of patterns \sphinxcode{\sphinxupquote{\DUrole{notation}{{[} \textbar{} ? {]} H}}});

Introduction over a conjunction of patterns \sphinxcode{\sphinxupquote{\DUrole{notation}{(\DUrole{repeat-wrapper}{\DUrole{repeat}{p}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}})}}} expects
the goal to be a product over an inductive type \sphinxcode{\sphinxupquote{\DUrole{name}{I}}} with a single
constructor that itself has at least \sphinxtitleref{n} arguments: It performs a case
analysis over the hypothesis, as \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct}}} would, and applies the
patterns \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{p}\DUrole{notation-sup}{+}}}}} to the arguments of the constructor of \sphinxcode{\sphinxupquote{\DUrole{name}{I}}} (observe
that \sphinxcode{\sphinxupquote{\DUrole{notation}{(\DUrole{repeat-wrapper}{\DUrole{repeat}{p}\DUrole{notation-sup}{+}})}}} is an alternative notation for \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{p}\DUrole{notation-sup}{+}}{]}}}});

Introduction via \sphinxcode{\sphinxupquote{\DUrole{notation}{(\DUrole{repeat-wrapper}{\DUrole{repeat}{p}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\&}})}}} is a shortcut for introduction via
\sphinxcode{\sphinxupquote{\DUrole{notation}{(p,( ... ,( ..., p ) ... ))}}}; it expects the hypothesis to be a sequence of
right-associative binary inductive constructors such as \sphinxcode{\sphinxupquote{\DUrole{name}{conj}}} or
\sphinxcode{\sphinxupquote{\DUrole{name}{ex\_intro}}}; for instance, a hypothesis with type
\sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{/\textbackslash{}(}\DUrole{keyword}{exists} \DUrole{name}{x}\DUrole{operator}{,} \DUrole{name}{B} \DUrole{operator}{/\textbackslash{}} \DUrole{name}{C} \DUrole{operator}{/\textbackslash{}} \DUrole{name}{D}\DUrole{operator}{)}}} can be introduced via pattern
\sphinxcode{\sphinxupquote{\DUrole{notation}{(a \& x \& b \& c \& d)}}};

If the product is over an equality type, then a pattern of the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[}= \DUrole{repeat-wrapper}{\DUrole{repeat}{p}\DUrole{notation-sup}{+}}{]}}}} applies either {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} or {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.discriminate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{discriminate}}}}}
instead of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}}; if {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} is applicable, the patterns
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{p}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}} are used on the hypotheses generated by {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}}; if the
number of patterns is smaller than the number of hypotheses generated, the
pattern \sphinxcode{\sphinxupquote{\DUrole{notation}{?}}} is used to complete the list.

Introduction over \sphinxcode{\sphinxupquote{-\textgreater{}}} (respectively over \sphinxcode{\sphinxupquote{\textless{}-}})
expects the hypothesis to be an equality and the right-hand-side
(respectively the left-hand-side) is replaced by the left-hand-side
(respectively the right-hand-side) in the conclusion of the goal;
the hypothesis itself is erased; if the term to substitute is a variable, it
is substituted also in the context of goal and the variable is removed too.

Introduction over a pattern \sphinxcode{\sphinxupquote{\DUrole{notation}{p\DUrole{repeat-wrapper}{\DUrole{repeat}{\%term}\DUrole{notation-sup}{+}}}}} first applies \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{term}\DUrole{notation-sup}{+}}}}}
on the hypothesis to be introduced (as in \sphinxcode{\sphinxupquote{\DUrole{notation}{apply \DUrole{repeat-wrapper}{\DUrole{repeat}{term}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}) prior to the
application of the introduction pattern \sphinxcode{\sphinxupquote{\DUrole{notation}{p}}};

Introduction on the wildcard depends on whether the product is dependent or not:
in the non-dependent case, it erases the corresponding hypothesis (i.e. it
behaves as an {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} followed by a {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.clear}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear}}}}}) while in the
dependent case, it succeeds and erases the variable only if the wildcard is part
of a more complex list of introduction patterns that also erases the hypotheses
depending on this variable;

Introduction over \sphinxcode{\sphinxupquote{\DUrole{notation}{*}}} introduces all forthcoming quantified variables
appearing in a row; introduction over \sphinxcode{\sphinxupquote{\DUrole{notation}{**}}} introduces all forthcoming
quantified variables or hypotheses until the goal is not any more a
quantification or an implication.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{n}{B} \PYG{o}{/\PYGZbs{}} \PYG{n}{C} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{n}{B} \PYG{o}{/\PYGZbs{}} \PYG{n}{C} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}

\PYG{k}{intros} \PYG{o}{*} \PYG{o}{[}\PYG{n}{a} \PYG{o}{\textbar{}} \PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{,}\PYG{n}{c}\PYG{o}{)}\PYG{o}{]} \PYG{n}{f}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B}\PYG{o}{,} \PYG{n}{C} \PYG{o}{:} \PYG{k+kt}{Prop}
      \PYG{n}{a} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{f} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{C}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{C}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}
\sphinxcode{\sphinxupquote{\DUrole{notation}{intros \DUrole{repeat-wrapper}{\DUrole{repeat}{p}\DUrole{notation-sup}{+}}}}} is not equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{intros p; ... ; intros p}}}
for the following reason: If one of the \sphinxcode{\sphinxupquote{\DUrole{notation}{p}}} is a wildcard pattern, it
might succeed in the first case because the further hypotheses it
depends on are eventually erased too while it might fail in the second
case because of dependencies in hypotheses which are not yet
introduced (and a fortiori not yet erased).
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
In \sphinxcode{\sphinxupquote{\DUrole{notation}{intros \DUrole{hole}{intro\_pattern\_list}}}}, if the last introduction pattern
is a disjunctive or conjunctive pattern
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{intro\_pattern\_list}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textbar{}}}{]}}}}, the completion of \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{intro\_pattern\_list}}}}
so that all the arguments of the i-th constructors of the corresponding
inductive type are introduced can be controlled with the following option:
\index{Bracketing Last Introduction Pattern (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.bracketing-last-introduction-pattern}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Bracketing~Last~Introduction~Pattern}}}}
Force completion, if needed, when the last introduction pattern is a
disjunctive or conjunctive pattern (on by default).

\end{fulllineitems}

\end{sphinxadmonition}
\index{clear (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.clear}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{clear~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This tactic erases the hypothesis named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} in the local context of
the current goal. As a consequence, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is no more displayed and no
more usable in the proof development.
\index{No such hypothesis (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.no-such-hypothesis}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~hypothesis.}}}}
\end{fulllineitems}

\index{‘ident’ is used in the conclusion (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.ident-is-used-in-the-conclusion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~used~in~the~conclusion.}}}}
\end{fulllineitems}

\index{‘ident’ is used in the hypothesis ‘ident’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.ident-is-used-in-the-hypothesis-ident}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~used~in~the~hypothesis~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{clear~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{clear {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}. ... clear {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{clear~-~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This variant clears all the hypotheses except the ones depending in the
hypotheses named \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}} and in the goal.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{clear}}}}
This variants clears all the hypotheses except the ones the goal depends on.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{clear~dependent~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This clears the hypothesis {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} and all the hypotheses that
depend on it.

\end{fulllineitems}

\index{clearbody (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.clearbody}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{clearbody~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This tactic expects \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}} to be local definitions and clears
their respective bodies.
In other words, it turns the given definitions into assumptions.
\index{‘ident’ is not a local definition (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.ident-is-not-a-local-definition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~not~a~local~definition.}}}}
\end{fulllineitems}


\end{fulllineitems}


\end{fulllineitems}

\index{revert (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.revert}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{revert~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This applies to any goal with variables \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}. It moves the hypotheses
(possibly defined) to the goal, if this respects dependencies. This tactic is
the inverse of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}}.
\index{No such hypothesis (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~hypothesis.}}}}
\end{fulllineitems}

\index{‘ident’ is used in the hypothesis ‘ident’ (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~is~used~in~the~hypothesis~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}.}}}}
\end{fulllineitems}

\index{revert dependent (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.revert-dependent}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{revert~dependent~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This moves to the goal the hypothesis {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} and all the
hypotheses that depend on it.

\end{fulllineitems}


\end{fulllineitems}

\index{move ... after ... (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.move-after}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{move~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~after~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}}
This moves the hypothesis named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} in the local context after
the hypothesis named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}, where “after” is in reference to the
direction of the move. The proof term is not changed.

If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} comes before \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} in the order of dependencies,
then all the hypotheses between \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} that
(possibly indirectly) depend on \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} are moved too, and all of
them are thus moved after \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} in the order of dependencies.

If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} comes after \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} in the order of dependencies,
then all the hypotheses between \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} that
(possibly indirectly) occur in the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} are moved too,
and all of them are thus moved before \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} in the order of
dependencies.
\index{move ... before ... (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.move-before}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{move~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~before~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}}
This moves \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} towards and just before the hypothesis
named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}.  As for {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.move-after}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{move ... after ...}}}}}, dependencies
over \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} (when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} comes before \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} in
the order of dependencies) or in the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}}
(when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} comes after \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} in the order of
dependencies) are moved too.

\end{fulllineitems}

\index{move ... at top (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.move-at-top}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{move~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~at~top}}}}
This moves {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} at the top of the local context (at the beginning
of the context).

\end{fulllineitems}

\index{move ... at bottom (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.move-at-bottom}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{move~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~at~bottom}}}}
This moves {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} at the bottom of the local context (at the end of
the context).

\end{fulllineitems}

\index{No such hypothesis (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~hypothesis.}}}}
\end{fulllineitems}

\index{Cannot move ‘ident’ after ‘ident’: it occurs in the type of ‘ident’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.cannot-move-ident-after-ident-it-occurs-in-the-type-of-ident}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~move~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~after~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}:~it~occurs~in~the~type~of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}.}}}}
\end{fulllineitems}

\index{Cannot move ‘ident’ after ‘ident’: it depends on ‘ident’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.cannot-move-ident-after-ident-it-depends-on-ident}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~move~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~after~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}:~it~depends~on~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}.}}}}
\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{z} \PYG{n}{y}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{y}\PYG{o}{=}\PYG{n}{y}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{=}\PYG{n}{x}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{x}

\PYG{k}{intros} \PYG{n}{x} \PYG{n}{H} \PYG{n}{z} \PYG{n}{y} \PYG{n}{H0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{n}{z}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{x}

\PYG{k}{move} \PYG{n}{x} \PYG{k}{after} \PYG{n}{H0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{z}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y}
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{x}

\PYG{n}{Undo}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{n}{z}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{x}

\PYG{k}{move} \PYG{n}{x} \PYG{n}{before} \PYG{n}{H0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{z}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{x}

\PYG{n}{Undo}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{n}{z}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{x}

\PYG{k}{move} \PYG{n}{H0} \PYG{k}{after} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{x}

\PYG{n}{Undo}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{n}{z}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{x}

\PYG{k}{move} \PYG{n}{H0} \PYG{n}{before} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y}
      \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{x}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}

\index{rename (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.rename}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{rename~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~into~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}}}
This renames hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}}}} into \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} in the current
context. The name of the hypothesis in the proof-term, however, is left
unchanged.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rename~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}~into~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{j}}$}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
This renames the variables \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}}} into \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{j}}$}}}}}}} in parallel.
In particular, the target identifiers may contain identifiers that exist in
the source context, as long as the latter are also renamed by the same
tactic.

\end{fulllineitems}

\index{No such hypothesis (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~hypothesis.}}}}
\end{fulllineitems}

\index{‘ident’ is already used (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~already~used.}}}}
\end{fulllineitems}


\end{fulllineitems}

\index{set (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.set}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}
This replaces {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} by {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} in the conclusion of the
current goal and adds the new definition \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} to the
local context.

If {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} has holes (i.e. subexpressions of the form “\sphinxtitleref{\_}”), the
tactic first checks that all subterms matching the pattern are compatible
before doing the replacement using the leftmost subterm matching the
pattern.
\index{The variable ‘ident’ is already defined (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.the-variable-ident-is-already-defined}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~variable~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~already~defined.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})~in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}}}
This notation allows specifying which occurrences of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} have
to be substituted in the context. The \sphinxcode{\sphinxupquote{\DUrole{notation}{in {\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}} clause
is an occurrence clause whose syntax and behavior are described in
{\hyperref[\detokenize{proof-engine/tactics:occurencessets}]{\sphinxcrossref{\DUrole{std,std-ref}{goal occurences}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}\DUrole{notation-sup}{?}}}}}}
This is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{set ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := fun {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}} =\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}) \DUrole{repeat-wrapper}{\DUrole{repeat}{in {\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}\DUrole{notation-sup}{?}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}\DUrole{notation-sup}{?}}}}}}
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{set ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}) \DUrole{repeat-wrapper}{\DUrole{repeat}{in {\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}\DUrole{notation-sup}{?}}}}}
but {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is generated by Coq.

\end{fulllineitems}

\index{eset (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.eset}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eset~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}\DUrole{notation-sup}{?}}}}}}\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eset~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}\DUrole{notation-sup}{?}}}}}}
While the different variants of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.set}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{set}}}}} expect that no existential
variables are generated by the tactic, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eset}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eset}}}}} removes this
constraint. In practice, this is relevant only when {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eset}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eset}}}}} is
used as a synonym of {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.epose}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{epose}}}}}, i.e. when the {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} does
not occur in the goal.

\end{fulllineitems}


\end{fulllineitems}

\index{remember (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.remember}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{remember~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{eqn:{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}\DUrole{notation-sup}{?}}}}}}
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{set ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}) in *}}}, using a logical
(Leibniz’s) equality instead of a local definition.
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}}} is provided, it will be the name of the new equation.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{remember~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{eqn:{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}\DUrole{notation-sup}{?}}~in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}}}
This is a more general form of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.remember}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{remember}}}}} that remembers the
occurrences of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} specified by an occurrence set.

\end{fulllineitems}

\index{eremember (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.eremember}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eremember~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{eqn:{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{2}}$}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}\DUrole{notation-sup}{?}}}}}}
While the different variants of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.remember}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{remember}}}}} expect that no
existential variables are generated by the tactic, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eremember}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eremember}}}}}
removes this constraint.

\end{fulllineitems}


\end{fulllineitems}

\index{pose (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.pose}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}
This adds the local definition \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} to the current context
without performing any replacement in the goal or in the hypotheses. It is
equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{set ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}) in \textbar{}-}}}.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}
This is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{pose ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := fun {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}} =\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{pose ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}} but {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is
generated by Coq.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{epose~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}
\end{fulllineitems}

\index{epose (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.epose}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{epose~term}}}}
While the different variants of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.pose}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pose}}}}} expect that no
existential variables are generated by the tactic, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.epose}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{epose}}}}}
removes this constraint.

\end{fulllineitems}


\end{fulllineitems}

\index{decompose (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.decompose}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{decompose~{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}{]}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic recursively decomposes a complex proposition in order to
obtain atomic ones.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{n}{B} \PYG{o}{/\PYGZbs{}} \PYG{n}{C} \PYG{o}{\PYGZbs{}/} \PYG{n}{B} \PYG{o}{/\PYGZbs{}} \PYG{n}{C} \PYG{o}{\PYGZbs{}/} \PYG{n}{C} \PYG{o}{/\PYGZbs{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{n}{B} \PYG{o}{/\PYGZbs{}} \PYG{n}{C} \PYG{o}{\PYGZbs{}/} \PYG{n}{B} \PYG{o}{/\PYGZbs{}} \PYG{n}{C} \PYG{o}{\PYGZbs{}/} \PYG{n}{C} \PYG{o}{/\PYGZbs{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}

\PYG{k}{intros} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C} \PYG{n}{H}\PYG{o}{;} \PYG{n}{decompose} \PYG{o}{[}\PYG{n}{and} \PYG{n}{or}\PYG{o}{]} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{3} \PYG{n}{subgoals}
      
      \PYG{n}{A}\PYG{o}{,} \PYG{n}{B}\PYG{o}{,} \PYG{n}{C} \PYG{o}{:} \PYG{k+kt}{Prop}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{n}{B} \PYG{o}{/\PYGZbs{}} \PYG{n}{C} \PYG{o}{\PYGZbs{}/} \PYG{n}{B} \PYG{o}{/\PYGZbs{}} \PYG{n}{C} \PYG{o}{\PYGZbs{}/} \PYG{n}{C} \PYG{o}{/\PYGZbs{}} \PYG{n}{A}
      \PYG{n}{H1} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{B}
      \PYG{n}{H3} \PYG{o}{:} \PYG{n}{C}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{C}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{C}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{C}

\PYG{n}{all}\PYG{o}{:} \PYG{k+kp}{assumption}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{Unnamed\PYGZus{}thm} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.decompose}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{decompose}}}}} does not work on right-hand sides of implications or
products.
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{decompose~sum~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This decomposes sum types (like \sphinxcode{\sphinxupquote{\DUrole{name}{or}}}).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{decompose~record~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This decomposes record types (inductive types with one constructor,
like \sphinxcode{\sphinxupquote{\DUrole{name}{and}}} and \sphinxcode{\sphinxupquote{\DUrole{keyword}{exists}}} and those defined with the {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.record}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Record}}}}}
command.

\end{fulllineitems}


\end{fulllineitems}



\subsection{Controlling the proof flow}
\label{\detokenize{proof-engine/tactics:controlling-the-proof-flow}}\label{\detokenize{proof-engine/tactics:controllingtheproofflow}}\index{assert (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.assert}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~form)}}}}
This tactic applies to any goal. \sphinxcode{\sphinxupquote{\DUrole{notation}{assert (H : U)}}} adds a new hypothesis
of name \sphinxcode{\sphinxupquote{\DUrole{notation}{H}}} asserting \sphinxcode{\sphinxupquote{\DUrole{name}{U}}} to the current goal and opens a new subgoal
\sphinxcode{\sphinxupquote{\DUrole{name}{U}}} %
\begin{footnote}[2]\sphinxAtStartFootnote
This corresponds to the cut rule of sequent calculus.
%
\end{footnote}. The subgoal \sphinxcode{\sphinxupquote{\DUrole{name}{U}}} comes first in the list of subgoals remaining to
prove.

\end{fulllineitems}

\index{Not a proposition or a type (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-a-proposition-or-a-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~a~proposition~or~a~type.}}}}
Arises when the argument form is neither of type \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}}, \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}} nor
\sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert~form}}}}
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{assert ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : form)}}} but \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is generated by
Coq.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}~by~\DUrole{hole}{tactic}}}}}
This tactic behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{assert}}} but applies tactic to solve the subgoals
generated by assert.
\index{Proof is not complete. (assert) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.proof-is-not-complete-assert}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~is~not~complete.}}}}
\end{fulllineitems}


\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}~as~\DUrole{hole}{intro\_pattern}}}}}
If \sphinxcode{\sphinxupquote{\DUrole{notation}{intro\_pattern}}} is a naming introduction pattern (see {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}}),
the hypothesis is named after this introduction pattern (in particular, if
\sphinxcode{\sphinxupquote{\DUrole{notation}{intro\_pattern}}} is \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, the tactic behaves like
\sphinxcode{\sphinxupquote{\DUrole{notation}{assert ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : form)}}}). If \sphinxcode{\sphinxupquote{\DUrole{notation}{intro\_pattern}}} is an action
introduction pattern, the tactic behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{assert form}}} followed by
the action done by this introduction pattern.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}~as~\DUrole{hole}{intro\_pattern}~by~\DUrole{hole}{tactic}}}}}
This combines the two previous variants of \sphinxcode{\sphinxupquote{\DUrole{notation}{assert}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~)}}}}
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{assert ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : type) by exact {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} where \sphinxcode{\sphinxupquote{\DUrole{name}{type}}} is
the type of \sphinxcode{\sphinxupquote{\DUrole{name}{term}}}. This is deprecated in favor of \sphinxcode{\sphinxupquote{\DUrole{notation}{pose proof}}}. If the
head of term is \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, the tactic behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{specialize {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.
\index{Variable ‘ident’ is already declared (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.variable-ident-is-already-declared}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Variable~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~already~declared.}}}}
\end{fulllineitems}


\end{fulllineitems}

\index{eassert (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.eassert}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eassert~form~as~intro\_pattern~by~tactic}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}
While the different variants of \sphinxcode{\sphinxupquote{\DUrole{notation}{assert}}} expect that no existential
variables are generated by the tactic, \sphinxcode{\sphinxupquote{\DUrole{notation}{eassert}}} removes this constraint.
This allows not to specify the asserted statement completeley before starting
to prove it.

\end{fulllineitems}

\index{pose proof (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.pose-proof}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~proof~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~intro\_pattern}\DUrole{notation-sup}{?}}}}}}
This tactic behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{assert T \DUrole{repeat-wrapper}{\DUrole{repeat}{as intro\_pattern}\DUrole{notation-sup}{?}} by exact {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}
where \sphinxcode{\sphinxupquote{\DUrole{name}{T}}} is the type of \sphinxcode{\sphinxupquote{\DUrole{name}{term}}}. In particular,
\sphinxcode{\sphinxupquote{\DUrole{notation}{pose proof {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} as {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{assert ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}
and \sphinxcode{\sphinxupquote{\DUrole{notation}{pose proof {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} as intro\_pattern}}} is the same as applying the
intro\_pattern to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{epose~proof~term~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~intro\_pattern}\DUrole{notation-sup}{?}}}}}}
While \sphinxcode{\sphinxupquote{\DUrole{notation}{pose proof}}} expects that no existential variables are generated by
the tactic, \sphinxcode{\sphinxupquote{\DUrole{notation}{epose proof}}} removes this constraint.

\end{fulllineitems}

\index{enough (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.enough}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{enough~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~form)}}}}
This adds a new hypothesis of name \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} asserting \sphinxcode{\sphinxupquote{\DUrole{notation}{form}}} to the
goal the tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{enough}}} is applied to. A new subgoal stating \sphinxcode{\sphinxupquote{\DUrole{notation}{form}}} is
inserted after the initial goal rather than before it as \sphinxcode{\sphinxupquote{\DUrole{notation}{assert}}} would do.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{enough~form}}}}
This behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{enough ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} : form)}}} with the name \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} of
the hypothesis generated by Coq.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{enough~form~as~intro\_pattern}}}}
This behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{enough form}}} using \sphinxcode{\sphinxupquote{\DUrole{notation}{intro\_pattern}}} to name or
destruct the new hypothesis.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{enough~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}})~by~\DUrole{hole}{tactic}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{enough~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}~by~\DUrole{hole}{tactic}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{enough~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}~as~\DUrole{hole}{intro\_pattern}~by~\DUrole{hole}{tactic}}}}}
This behaves as above but with \sphinxcode{\sphinxupquote{\DUrole{notation}{tactic}}} expected to solve the initial goal
after the extra assumption \sphinxcode{\sphinxupquote{\DUrole{notation}{form}}} is added and possibly destructed. If the
\sphinxcode{\sphinxupquote{\DUrole{notation}{as intro\_pattern}}} clause generates more than one subgoal, \sphinxcode{\sphinxupquote{\DUrole{notation}{tactic}}} is
applied to all of them.

\end{fulllineitems}

\index{eenough (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.eenough}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eenough~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~form)~by~tactic}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eenough~form~by~tactic}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eenough~form~as~intro\_pattern~by~tactic}}}}
While the different variants of \sphinxcode{\sphinxupquote{\DUrole{notation}{enough}}} expect that no existential
variables are generated by the tactic, \sphinxcode{\sphinxupquote{\DUrole{notation}{eenough}}} removes this constraint.

\end{fulllineitems}

\index{cut (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.cut}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{cut~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}}}}}
This tactic applies to any goal. It implements the non-dependent case of
the “App” rule given in {\hyperref[\detokenize{language/cic:typing-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{Typing rules}}}}. (This is Modus Ponens inference
rule.) \sphinxcode{\sphinxupquote{\DUrole{notation}{cut U}}} transforms the current goal \sphinxcode{\sphinxupquote{\DUrole{name}{T}}} into the two following
subgoals: \sphinxcode{\sphinxupquote{\DUrole{name}{U} \DUrole{operator}{-\textgreater{}} \DUrole{name}{T}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{U}}}. The subgoal \sphinxcode{\sphinxupquote{\DUrole{name}{U} \DUrole{operator}{-\textgreater{}} \DUrole{name}{T}}} comes first in the
list of remaining subgoal to prove.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{specialize~(ident~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}})~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~intro\_pattern}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}

\index{specialize (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.specialize}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{specialize~ident~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~intro\_pattern}\DUrole{notation-sup}{?}}}}}}
The tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{specialize}}} works on local hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}. The
premises of this hypothesis (either universal quantifications or
non-dependent implications) are instantiated by concrete terms coming either
from arguments \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}}}} or from a {\hyperref[\detokenize{proof-engine/tactics:bindingslist}]{\sphinxcrossref{\DUrole{std,std-ref}{bindings list}}}}.
In the first form the application to \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}}}}  can be partial. The
first form is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{assert ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}})}}}. In the
second form, instantiation elements can also be partial. In this case the
uninstantiated arguments are inferred by unification if possible or left
quantified in the hypothesis otherwise. With the \sphinxcode{\sphinxupquote{\DUrole{notation}{as}}} clause, the local
hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is left unchanged and instead, the modified hypothesis
is introduced as specified by the \sphinxcode{\sphinxupquote{\DUrole{notation}{intro\_pattern}}}. The name \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
can also refer to a global lemma or hypothesis. In this case, for
compatibility reasons, the behavior of \sphinxcode{\sphinxupquote{\DUrole{notation}{specialize}}} is close to that of
\sphinxcode{\sphinxupquote{\DUrole{notation}{generalize}}}: the instantiated statement becomes an additional premise of
the goal. The \sphinxcode{\sphinxupquote{\DUrole{notation}{as}}} clause is especially useful in this case to immediately
introduce the instantiated statement as a local hypothesis.
\index{‘ident’ is used in hypothesis ‘ident’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.ident-is-used-in-hypothesis-ident}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~used~in~hypothesis~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}

\index{‘ident’ is used in conclusion (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.ident-is-used-in-conclusion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~used~in~conclusion.}}}}
\end{fulllineitems}


\end{fulllineitems}

\index{generalize (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.generalize}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{generalize~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic applies to any goal. It generalizes the conclusion with
respect to some term.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Show}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{y}

\PYG{k}{generalize} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}
\end{sphinxVerbatim}
\end{sphinxadmonition}

If the goal is \sphinxcode{\sphinxupquote{\DUrole{name}{G}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{t}}} is a subterm of type \sphinxcode{\sphinxupquote{\DUrole{name}{T}}} in the goal,
then \sphinxcode{\sphinxupquote{\DUrole{notation}{generalize t}}} replaces the goal by \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{T}\DUrole{operator}{),} \DUrole{name}{G}\DUrole{error}{′}}} where \sphinxcode{\sphinxupquote{\DUrole{name}{G}\DUrole{error}{′}}}
is obtained from \sphinxcode{\sphinxupquote{\DUrole{name}{G}}} by replacing all occurrences of \sphinxcode{\sphinxupquote{\DUrole{name}{t}}} by \sphinxcode{\sphinxupquote{\DUrole{name}{x}}}. The
name of the variable (here \sphinxcode{\sphinxupquote{\DUrole{name}{n}}}) is chosen based on \sphinxcode{\sphinxupquote{\DUrole{name}{T}}}.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{generalize~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}}}
This is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{generalize {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}; ... ; generalize {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.
Note that the sequence of term $_{\text{i}}$ 's are processed from n to 1.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{generalize~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~at~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}}}}}
This is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{generalize {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} but it generalizes only over the
specified occurrences of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} (counting from left to right on the
expression printed using option {\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-all}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}}).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{generalize~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{generalize {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} but it uses \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} to name
the generalized hypothesis.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{generalize~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~at~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}~as~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
This is the most general form of \sphinxcode{\sphinxupquote{\DUrole{notation}{generalize}}} that combines the previous
behaviors.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{generalize~dependent~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This generalizes term but also \sphinxstyleemphasis{all} hypotheses that depend on \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. It
clears the generalized hypotheses.

\end{fulllineitems}

\index{evar (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.evar}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{evar~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}
The \sphinxcode{\sphinxupquote{\DUrole{notation}{evar}}} tactic creates a new local definition named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} with type
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} in the context. The body of this binding is a fresh existential
variable.

\end{fulllineitems}

\index{instantiate (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.instantiate}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{instantiate~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~)}}}}
The instantiate tactic refines (see {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}}) an existential variable
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} with the term \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. It is equivalent to only {[}ident{]}:
\sphinxcode{\sphinxupquote{\DUrole{notation}{refine {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} (preferred alternative).

\begin{sphinxadmonition}{note}{Note:}
To be able to refer to an existential variable by name, the user
must have given the name explicitly (see {\hyperref[\detokenize{language/gallina-extensions:existential-variables}]{\sphinxcrossref{\DUrole{std,std-ref}{Existential variables}}}}).
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
When you are referring to hypotheses which you did not name
explicitly, be aware that Coq may make a different decision on how to
name the variable in the current goal and in the context of the
existential variable. This can lead to surprising behaviors.
\end{sphinxadmonition}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{instantiate~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}})}}}}
This variant allows to refer to an existential variable which was not named
by the user. The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} argument is the position of the existential variable
from right to left in the goal. Because this variant is not robust to slight
changes in the goal, its use is strongly discouraged.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{instantiate~(~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~)~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{instantiate~(~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~)~in~(~Value~of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~)}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{instantiate~(~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~)~in~(~Type~of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~)}}}}
These allow to refer respectively to existential variables occurring in a
hypothesis or in the body or the type of a local definition.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{instantiate}}}}
Without argument, the instantiate tactic tries to solve as many existential
variables as possible, using information gathered from other tactics in the
same tactical. This is automatically done after each complete tactic (i.e.
after a dot in proof mode), but not, for example, between each tactic when
they are sequenced by semicolons.

\end{fulllineitems}

\index{admit (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.admit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{admit}}}}
\end{fulllineitems}


The admit tactic allows temporarily skipping a subgoal so as to
progress further in the rest of the proof. A proof containing admitted
goals cannot be closed with \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Qed}}} but only with \sphinxcode{\sphinxupquote{\DUrole{name}{Admitted}}}.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{give\_up}}}}
Synonym of \sphinxcode{\sphinxupquote{\DUrole{notation}{admit}}}.

\end{fulllineitems}

\index{absurd (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.absurd}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{absurd~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic applies to any goal. The argument term is any proposition
\sphinxcode{\sphinxupquote{\DUrole{name}{P}}} of type \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}}. This tactic applies False elimination, that is it
deduces the current goal from False, and generates as subgoals \sphinxcode{\sphinxupquote{\DUrole{error}{∼}\DUrole{name}{P}}} and
\sphinxcode{\sphinxupquote{\DUrole{name}{P}}}. It is very useful in proofs by cases, where some cases are
impossible. In most cases, \sphinxcode{\sphinxupquote{\DUrole{name}{P}}} or \sphinxcode{\sphinxupquote{\DUrole{error}{∼}\DUrole{name}{P}}} is one of the hypotheses of the
local context.

\end{fulllineitems}

\index{contradiction (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.contradiction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{contradiction}}}}
This tactic applies to any goal. The contradiction tactic attempts to
find in the current context (after all intros) a hypothesis that is
equivalent to an empty inductive type (e.g. \sphinxcode{\sphinxupquote{\DUrole{name}{False}}}), to the negation of
a singleton inductive type (e.g. \sphinxcode{\sphinxupquote{\DUrole{name}{True}}} or \sphinxcode{\sphinxupquote{\DUrole{name}{x}\DUrole{operator}{=}\DUrole{name}{x}}}), or two contradictory
hypotheses.

\end{fulllineitems}

\index{No such assumption (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~assumption.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{contradiction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
The proof of False is searched in the hypothesis named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}

\index{contradict (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.contradict}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{contradict~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This tactic allows manipulating negated hypothesis and goals. The name
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} should correspond to a hypothesis. With \sphinxcode{\sphinxupquote{\DUrole{notation}{contradict H}}}, the
current goal and context is transformed in the following way:
\begin{itemize}
\item {} 
H:¬A ⊢ B becomes ⊢ A

\item {} 
H:¬A ⊢ ¬B becomes H: B ⊢ A

\item {} 
H: A ⊢ B becomes ⊢ ¬A

\item {} 
H: A ⊢ ¬B becomes H: B ⊢ ¬A

\end{itemize}

\end{fulllineitems}

\index{exfalso (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.exfalso}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{exfalso}}}}
This tactic implements the “ex falso quodlibet” logical principle: an
elimination of False is performed on the current goal, and the user is
then required to prove that False is indeed provable in the current
context. This tactic is a macro for \sphinxcode{\sphinxupquote{\DUrole{notation}{elimtype False}}}.

\end{fulllineitems}



\subsection{Case analysis and induction}
\label{\detokenize{proof-engine/tactics:case-analysis-and-induction}}\label{\detokenize{proof-engine/tactics:caseanalysisandinduction}}
The tactics presented in this section implement induction or case
analysis on inductive or co-inductive objects (see {\hyperref[\detokenize{language/cic:inductive-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Inductive Definitions}}}}).
\index{destruct (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.destruct}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic applies to any goal. The argument {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} must be of
inductive or co-inductive type and the tactic generates subgoals, one
for each possible form of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}, i.e. one for each constructor of the
inductive or co-inductive type. Unlike {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}}, no induction
hypothesis is generated by {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}}.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
If {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} denotes a quantified variable of the conclusion
of the goal, then \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} behaves
as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; destruct {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}. If {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is not
anymore dependent in the goal after application of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}}, it
is erased (to avoid erasure, use parentheses, as in \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}})}}}).

If {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is a hypothesis of the context, and {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}
is not anymore dependent in the goal after application
of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}}, it is erased (to avoid erasure, use parentheses, as
in \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}})}}}).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}~\begin{quote}

\sphinxcode{\sphinxupquote{\DUrole{notation}{destruct {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}
followed by destruct applied to the last introduced hypothesis.
\end{quote}

\begin{sphinxadmonition}{note}{Note:}
For destruction of a numeral, use syntax \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}})}}} (not
very interesting anyway).
\end{sphinxadmonition}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}}}
The argument of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}} can also be a pattern of which holes are
denoted by “\_”. In this case, the tactic checks that all subterms
matching the pattern in the conclusion and the hypotheses are compatible
and performs case analysis using this subterm.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
This is a shortcut for \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}; ...; destruct {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as~\DUrole{hole}{disj\_conj\_intro\_pattern}}}}}
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} but uses the names
in \sphinxcode{\sphinxupquote{disj\_conj\_intro\_pattern}} to name the variables introduced in the
context. The \sphinxcode{\sphinxupquote{disj\_conj\_intro\_pattern}} must have the
form \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}p11 ... p1n \textbar{} ... \textbar{} pm1 ... pmn {]}}}} with \sphinxcode{\sphinxupquote{m}} being the
number of constructors of the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. Each variable
introduced by {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}} in the context of the \sphinxcode{\sphinxupquote{i}}-th goal
gets its name from the list \sphinxcode{\sphinxupquote{\DUrole{notation}{pi1 ... pin}}} in order. If there are not
enough names, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}} invents names for the remaining variables
to introduce. More generally, the \sphinxcode{\sphinxupquote{\DUrole{notation}{pij}}} can be any introduction
pattern (see {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}}). This provides a concise notation for
chaining destruction of a hypothesis.

\end{fulllineitems}

\index{destruct ... eqn: (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.destruct-eqn}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~eqn:\DUrole{hole}{naming\_intro\_pattern}}}}}
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} but adds an equation
between {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} and the value that it takes in each of the
possible cases. The name of the equation is specified
by \sphinxcode{\sphinxupquote{naming\_intro\_pattern}} (see {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}}),
in particular \sphinxcode{\sphinxupquote{?}} can be used to let Coq generate a fresh name.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}}
This behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} providing explicit instances for
the dependent premises of the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

\end{fulllineitems}

\index{edestruct (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.edestruct}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{edestruct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{destruct {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} except that it does not
fail if the instance of a dependent premises of the type
of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} is not inferable. Instead, the unresolved instances
are left as existential variables to be inferred later, in the same way
as {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eapply}}}}} does.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}}}}
This is synonym of \sphinxcode{\sphinxupquote{\DUrole{notation}{induction {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} using {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}}}
This syntax is used for selecting which occurrences of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}
the case analysis has to be done on. The \sphinxcode{\sphinxupquote{\DUrole{notation}{in {\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}}
clause is an occurrence clause whose syntax and behavior is described
in {\hyperref[\detokenize{proof-engine/tactics:occurencessets}]{\sphinxcrossref{\DUrole{std,std-ref}{occurences sets}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{destruct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~\DUrole{hole}{disj\_conj\_intro\_pattern}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{eqn:\DUrole{hole}{naming\_intro\_pattern}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}\DUrole{notation-sup}{?}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{edestruct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~\DUrole{hole}{disj\_conj\_intro\_pattern}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{eqn:\DUrole{hole}{naming\_intro\_pattern}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}\DUrole{notation-sup}{?}}}}}}
These are the general forms of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.destruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{destruct}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.edestruct}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{edestruct}}}}}.
They combine the effects of the \sphinxcode{\sphinxupquote{with}}, \sphinxcode{\sphinxupquote{as}}, \sphinxcode{\sphinxupquote{eqn:}}, \sphinxcode{\sphinxupquote{using}},
and \sphinxcode{\sphinxupquote{in}} clauses.

\end{fulllineitems}


\end{fulllineitems}

\index{case (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.case}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{case~term}}}}
The tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{case}}} is a more basic tactic to perform case analysis without
recursion. It behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{elim {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} but using a case-analysis
elimination principle and not a recursive one.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{case~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}}
Analogous to \sphinxcode{\sphinxupquote{\DUrole{notation}{elim {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}} above.

\end{fulllineitems}

\index{ecase (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.ecase}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{ecase~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}}}}
In case the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} has dependent premises, or dependent premises
whose values are not inferable from the \sphinxcode{\sphinxupquote{\DUrole{notation}{with {\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}} clause,
\sphinxcode{\sphinxupquote{\DUrole{notation}{ecase}}} turns them into existential variables to be resolved later on.

\end{fulllineitems}

\index{simple destruct (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.simple-destruct}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~destruct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This tactic behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; case {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
is a quantified variable of the goal.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~destruct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This tactic behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}; case {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
is the name given by \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} to the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} -th
non-dependent premise of the goal.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{case\_eq~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
The tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{case\_eq}}} is a variant of the \sphinxcode{\sphinxupquote{\DUrole{notation}{case}}} tactic that allows to
perform case analysis on a term without completely forgetting its original
form. This is done by generating equalities between the original form of the
term and the outcomes of the case analysis.

\end{fulllineitems}

\index{induction (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.induction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic applies to any goal. The argument \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} must be of
inductive type and the tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{induction}}} generates subgoals, one for
each possible form of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, i.e. one for each constructor of the
inductive type.

If the argument is dependent in either the conclusion or some
hypotheses of the goal, the argument is replaced by the appropriate
constructor form in each of the resulting subgoals and induction
hypotheses are added to the local context using names whose prefix
is \sphinxstylestrong{IH}.

There are particular cases:
\begin{itemize}
\item {} 
If term is an identifier \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} denoting a quantified variable of the
conclusion of the goal, then inductionident behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; induction {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}. If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is not anymore dependent in the
goal after application of \sphinxcode{\sphinxupquote{\DUrole{notation}{induction}}}, it is erased (to avoid erasure,
use parentheses, as in \sphinxcode{\sphinxupquote{\DUrole{notation}{induction ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}})}}}).

\item {} 
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}, then \sphinxcode{\sphinxupquote{\DUrole{notation}{induction {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} behaves as
\sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} followed by \sphinxcode{\sphinxupquote{\DUrole{notation}{induction}}} applied to the last
introduced hypothesis.

\begin{sphinxadmonition}{note}{Note:}
For simple induction on a numeral, use syntax induction (num)
(not very interesting anyway).
\end{sphinxadmonition}

\item {} 
In case term is a hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} of the context, and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
is not anymore dependent in the goal after application of \sphinxcode{\sphinxupquote{\DUrole{notation}{induction}}},
it is erased (to avoid erasure, use parentheses, as in
\sphinxcode{\sphinxupquote{\DUrole{notation}{induction ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}})}}}).

\item {} 
The argument \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} can also be a pattern of which holes are denoted
by “\_”. In this case, the tactic checks that all subterms matching the
pattern in the conclusion and the hypotheses are compatible and
performs induction using this subterm.

\end{itemize}

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{induction\PYGZus{}test} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}

\PYG{k}{intros} \PYG{n}{n} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}

\PYG{k}{induction} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{S} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{S} \PYG{n}{n}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{Not an inductive product (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~an~inductive~product.}}}}
\end{fulllineitems}

\index{Unable to find an instance for the variables ‘ident’ ... ‘ident’ (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unable~to~find~an~instance~for~the~variables~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~...~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
Use in this case the variant {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.elim-with}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{elim ... with}}}}} below.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as~\DUrole{hole}{disj\_conj\_intro\_pattern}}}}}
This behaves as {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}} but uses the names in
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{disj\_conj\_intro\_pattern}}}} to name the variables introduced in the
context. The \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{disj\_conj\_intro\_pattern}}}} must typically be of the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[} p}}} $_{\text{11}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{... p}}} $_{\text{1n}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{\textbar{} ... \textbar{} p}}}$_{\text{m1}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{... p}}}$_{\text{mn}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{{]}}}}
with \sphinxcode{\sphinxupquote{\DUrole{notation}{m}}} being the number of constructors of the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. Each
variable introduced by induction in the context of the i-th goal gets its
name from the list \sphinxcode{\sphinxupquote{\DUrole{notation}{p}}}$_{\text{i1}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{... p}}}$_{\text{in}}$ in order. If there are
not enough names, induction invents names for the remaining variables to
introduce. More generally, the \sphinxcode{\sphinxupquote{\DUrole{notation}{p}}}$_{\text{ij}}$ can be any
disjunctive/conjunctive introduction pattern (see {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros ...}}}}}). For
instance, for an inductive type with  one constructor, the pattern notation
\sphinxcode{\sphinxupquote{\DUrole{notation}{(p}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{, ... , p}}}$_{\text{n}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{)}}} can be used instead of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[} p}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{... p}}}$_{\text{n}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{{]}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}}
This behaves like {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}} providing explicit instances for the
premises of the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{term}}} (see {\hyperref[\detokenize{proof-engine/tactics:bindingslist}]{\sphinxcrossref{\DUrole{std,std-ref}{bindings list}}}}).

\end{fulllineitems}

\index{einduction (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.einduction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einduction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic behaves like {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}} except that it does not fail if
some dependent premise of the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is not inferable. Instead,
the unresolved premises are posed as existential variables to be inferred
later, in the same way as {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eapply}}}}} does.

\end{fulllineitems}

\index{induction ... using ... (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.induction-using}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This behaves as {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}}  but using \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} as induction scheme.
It does not expect the conclusion of the type of the first \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} to be
inductive.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}}
This behaves as {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.induction-using}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction ... using ...}}}}} but also providing instances
for the premises of the type of the second \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This syntax is used for the case \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} denotes an induction principle
with complex predicates as the induction principles generated by
\sphinxcode{\sphinxupquote{Function}} or \sphinxcode{\sphinxupquote{Functional Scheme}} may be.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}}}
This syntax is used for selecting which occurrences of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} the
induction has to be carried on. The \sphinxcode{\sphinxupquote{\DUrole{notation}{in {\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}} clause is an
occurrence clause whose syntax and behavior is described in
{\hyperref[\detokenize{proof-engine/tactics:occurencessets}]{\sphinxcrossref{\DUrole{std,std-ref}{occurences sets}}}}. If variables or hypotheses not
mentioning \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} in their type are listed in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}},
those are generalized as well in the statement to prove.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{comm} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y} \PYG{o}{+} \PYG{n}{x}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y} \PYG{o}{+} \PYG{n}{x}

\PYG{k}{induction} \PYG{n}{y} \PYG{k}{in} \PYG{n}{x} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}}   \PYG{o}{*}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{n}{x}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{x} \PYG{o}{+} \PYG{n}{S} \PYG{n}{y} \PYG{o}{=} \PYG{n}{S} \PYG{n}{y} \PYG{o}{+} \PYG{n}{x}

\PYG{k+kn}{Show} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{IHy} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y} \PYG{o}{+} \PYG{n}{x}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{S} \PYG{n}{y} \PYG{o}{=} \PYG{n}{S} \PYG{n}{y} \PYG{o}{+} \PYG{n}{x}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{induction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}~as~\DUrole{hole}{disj\_conj\_intro\_pattern}~using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}~in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einduction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}~as~\DUrole{hole}{disj\_conj\_intro\_pattern}~using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}~in~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-goal-occurrences}]{\sphinxcrossref{\DUrole{hole}{goal\_occurrences}}}}}}}}
These are the most general forms of \sphinxcode{\sphinxupquote{induction}} and \sphinxcode{\sphinxupquote{einduction}}. It combines the
effects of the with, as, using, and in clauses.

\end{fulllineitems}

\index{elim (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.elim}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{elim~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This is a more basic induction tactic. Again, the type of the argument
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} must be an inductive type. Then, according to the type of the
goal, the tactic \sphinxcode{\sphinxupquote{elim}} chooses the appropriate destructor and applies it
as the tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} would do. For instance, if the proof context
contains \sphinxcode{\sphinxupquote{\DUrole{name}{n}\DUrole{operator}{:}\DUrole{keyword,type}{nat}}} and the current goal is \sphinxcode{\sphinxupquote{\DUrole{name}{T}}} of type \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}}, then
\sphinxcode{\sphinxupquote{\DUrole{notation}{elim n}}} is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{apply nat\_ind with (n:=n)}}}. The tactic
\sphinxcode{\sphinxupquote{elim}} does not modify the context of the goal, neither introduces the
induction loading into the context of hypotheses. More generally,
\sphinxcode{\sphinxupquote{\DUrole{notation}{elim {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} also works when the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is a statement
with premises and whose conclusion is inductive. In that case the tactic
performs induction on the conclusion of the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and leaves the
non-dependent premises of the type as subgoals. In the case of dependent
products, the tactic tries to find an instance for which the elimination
lemma applies and fails otherwise.

\end{fulllineitems}

\index{elim ... with (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.elim-with}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{elim~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}}
Allows to give explicit instances to the premises of the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}
(see {\hyperref[\detokenize{proof-engine/tactics:bindingslist}]{\sphinxcrossref{\DUrole{std,std-ref}{bindings list}}}}).

\end{fulllineitems}

\index{eelim (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.eelim}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eelim~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
In case the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} has dependent premises, this turns them into
existential variables to be resolved later on.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{elim~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{elim~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}}
Allows the user to give explicitly an induction principle \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} that
is not the standard one for the underlying inductive type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. The
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}} clause allows instantiating premises of the type of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{elim~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}~using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{eelim~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}~using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}}
These are the most general forms of \sphinxcode{\sphinxupquote{elim}} and \sphinxcode{\sphinxupquote{eelim}}. It combines the
effects of the \sphinxcode{\sphinxupquote{using}} clause and of the two uses of the \sphinxcode{\sphinxupquote{with}} clause.

\end{fulllineitems}

\index{elimtype (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.elimtype}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{elimtype~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-form}]{\sphinxcrossref{\DUrole{hole}{form}}}}}}}}
The argument \sphinxcode{\sphinxupquote{\DUrole{notation}{form}}} must be inductively defined. \sphinxcode{\sphinxupquote{\DUrole{notation}{elimtype I}}} is
equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{cut I. intro Hn; elim Hn; clear Hn.}}} Therefore the
hypothesis \sphinxcode{\sphinxupquote{\DUrole{name}{Hn}}} will not appear in the context(s) of the subgoal(s).
Conversely, if \sphinxcode{\sphinxupquote{\DUrole{name}{t}}} is a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} of (inductive) type \sphinxcode{\sphinxupquote{\DUrole{name}{I}}} that does
not occur in the goal, then \sphinxcode{\sphinxupquote{\DUrole{notation}{elim t}}} is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{elimtype I; 2:exact t.}}}

\end{fulllineitems}

\index{simple induction (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.simple-induction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~induction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This tactic behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; elim {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} when
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is a quantified variable of the goal.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~induction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This tactic behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}; elim {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
is the name given by \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} to the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}-th non-dependent
premise of the goal.

\end{fulllineitems}

\index{double induction (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.double-induction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{double~induction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This tactic is deprecated and should be replaced by
\sphinxcode{\sphinxupquote{\DUrole{notation}{induction {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; induction {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} (or
\sphinxcode{\sphinxupquote{\DUrole{notation}{induction {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} ; destruct {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} depending on the exact needs).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{double~induction~num1~num2}}}}
This tactic is deprecated and should be replaced by
\sphinxcode{\sphinxupquote{\DUrole{notation}{induction num1; induction num3}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{num3}}} is the result
of \sphinxcode{\sphinxupquote{\DUrole{notation}{num2 - num1}}}

\end{fulllineitems}

\index{dependent induction (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.dependent-induction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~induction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
The \sphinxstyleemphasis{experimental} tactic dependent induction performs induction-
inversion on an instantiated inductive predicate. One needs to first
require the Coq.Program.Equality module to use this tactic. The tactic
is based on the BasicElim tactic by Conor McBride
\sphinxcite{zebibliography:dblp-conf-types-mcbride00} and the work of Cristina Cornes around
inversion \sphinxcite{zebibliography:dblp-conf-types-cornest95}. From an instantiated
inductive predicate and a goal, it generates an equivalent goal where
the hypothesis has been generalized over its indexes which are then
constrained by equalities to be the right instances. This permits to
state lemmas without resorting to manually adding these equalities and
still get enough information in the proofs.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{le\PYGZus{}minus} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{k}{intros} \PYG{n}{n} \PYG{n}{H} \PYG{o}{;} \PYG{k}{induction} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}

Here we did not get any information on the indexes to help fulfill
this proof. The problem is that, when we use the \sphinxcode{\sphinxupquote{induction}} tactic, we
lose information on the hypothesis instance, notably that the second
argument is 1 here. Dependent induction solves this problem by adding
the corresponding equality to the context.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Program}\PYG{o}{.}\PYG{n}{Equality}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{le\PYGZus{}minus} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{k}{intros} \PYG{n}{n} \PYG{n}{H} \PYG{o}{;} \PYG{n}{dependent} \PYG{k}{induction} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}

The subgoal is cleaned up as the tactic tries to automatically
simplify the subgoals with respect to the generated equalities. In
this enriched context, it becomes possible to solve this subgoal.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{reflexivity}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{S} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{n}{IHle} \PYG{o}{:} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}

Now we are in a contradictory context and the proof can be solved.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{inversion} \PYG{n}{H}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}

This technique works with any inductive predicate. In fact, the
\sphinxcode{\sphinxupquote{dependent induction}} tactic is just a wrapper around the \sphinxcode{\sphinxupquote{induction}}
tactic. One can make its own variant by just writing a new tactic
based on the definition found in \sphinxcode{\sphinxupquote{Coq.Program.Equality}}.
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~induction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~generalizing~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This performs dependent induction on the hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} but first
generalizes the goal by the given variables so that they are universally
quantified in the goal. This is generally what one wants to do with the
variables that are inside some constructors in the induction hypothesis. The
other ones need not be further generalized.

\end{fulllineitems}

\index{dependent destruction (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.dependent-destruction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~destruction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This performs the generalization of the instance \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} but uses
\sphinxcode{\sphinxupquote{destruct}} instead of induction on the generalized hypothesis. This gives
results equivalent to \sphinxcode{\sphinxupquote{inversion}} or \sphinxcode{\sphinxupquote{dependent inversion}} if the
hypothesis is dependent.

\end{fulllineitems}


See also the larger example of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.dependent-induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{dependent induction}}}}}
and an explanation of the underlying technique.
\index{function induction (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.function-induction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{function~induction~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}})}}}}
The tactic functional induction performs case analysis and induction
following the definition of a function. It makes use of a principle
generated by \sphinxcode{\sphinxupquote{Function}} (see {\hyperref[\detokenize{language/gallina-extensions:advanced-recursive-functions}]{\sphinxcrossref{\DUrole{std,std-ref}{Advanced recursive functions}}}}) or
\sphinxcode{\sphinxupquote{Functional Scheme}} (see {\hyperref[\detokenize{user-extensions/proof-schemes:functional-scheme}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of induction principles with Functional Scheme}}}}).
Note that this tactic is only available after a \sphinxcode{\sphinxupquote{Require Import FunInd}}.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{FunInd}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{extraction\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{recdef\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}

\PYG{n}{Functional} \PYG{n}{Scheme} \PYG{n}{minus\PYGZus{}ind} \PYG{o}{:=} \PYG{n}{Induction} \PYG{k}{for} \PYG{n}{minus} \PYG{n}{Sort} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{sub\PYGZus{}equation} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{minus\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Check} \PYG{n}{minus\PYGZus{}ind}\PYG{o}{.}
    \PYG{n}{minus\PYGZus{}ind}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{,}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{l+m+mi}{0} \PYG{n}{m} \PYG{n}{n}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{k} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{n}{S} \PYG{n}{k} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{m} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{(}\PYG{n}{S} \PYG{n}{k}\PYG{o}{)} \PYG{l+m+mi}{0} \PYG{n}{n}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{k} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,}
            \PYG{n}{n} \PYG{o}{=} \PYG{n}{S} \PYG{n}{k} \PYG{o}{\PYGZhy{}\PYGZgt{}}
            \PYG{k}{forall} \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{m} \PYG{o}{=} \PYG{n}{S} \PYG{n}{l} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{k} \PYG{n}{l} \PYG{o}{(}\PYG{n}{k} \PYG{o}{\PYGZhy{}} \PYG{n}{l}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{(}\PYG{n}{S} \PYG{n}{k}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S} \PYG{n}{l}\PYG{o}{)} \PYG{o}{(}\PYG{n}{k} \PYG{o}{\PYGZhy{}} \PYG{n}{l}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{P} \PYG{n}{n} \PYG{n}{m} \PYG{o}{(}\PYG{n}{n} \PYG{o}{\PYGZhy{}} \PYG{n}{m}\PYG{o}{)}

\PYG{k+kn}{Lemma} \PYG{n}{le\PYGZus{}minus} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{n} \PYG{o}{\PYGZhy{}} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{n} \PYG{o}{\PYGZhy{}} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}

\PYG{n}{functional} \PYG{k}{induction} \PYG{o}{(}\PYG{n}{minus} \PYG{n}{n} \PYG{n}{m}\PYG{o}{)} \PYG{k}{using} \PYG{n}{minus\PYGZus{}ind}\PYG{o}{;} \PYG{k}{simpl}\PYG{o}{;} \PYG{k}{auto}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{le\PYGZus{}minus} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}})}}} must be a correct full application
of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}. In particular, the rules for implicit arguments are the
same as usual. For example use \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} if you want to write implicit
arguments explicitly.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
Parentheses around \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}} are not mandatory and can be skipped.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
\sphinxcode{\sphinxupquote{\DUrole{notation}{functional induction (f x1 x2 x3)}}} is actually a wrapper for
\sphinxcode{\sphinxupquote{\DUrole{notation}{induction x1, x2, x3, (f x1 x2 x3) using {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} followed by a cleaning
phase, where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} is the induction principle registered for \sphinxcode{\sphinxupquote{\DUrole{name}{f}}}
(by the \sphinxcode{\sphinxupquote{Function}} (see {\hyperref[\detokenize{language/gallina-extensions:advanced-recursive-functions}]{\sphinxcrossref{\DUrole{std,std-ref}{Advanced recursive functions}}}}) or
\sphinxcode{\sphinxupquote{Functional Scheme}} (see {\hyperref[\detokenize{user-extensions/proof-schemes:functional-scheme}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of induction principles with Functional Scheme}}}})
command) corresponding to the sort of the goal. Therefore
\sphinxcode{\sphinxupquote{functional induction}} may fail if the induction scheme \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} is not
defined. See also {\hyperref[\detokenize{language/gallina-extensions:advanced-recursive-functions}]{\sphinxcrossref{\DUrole{std,std-ref}{Advanced recursive functions}}}} for the function
terms accepted by \sphinxcode{\sphinxupquote{Function}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
There is a difference between obtaining an induction scheme
for a function by using \sphinxcode{\sphinxupquote{\DUrole{name}{Function}}} (see {\hyperref[\detokenize{language/gallina-extensions:advanced-recursive-functions}]{\sphinxcrossref{\DUrole{std,std-ref}{Advanced recursive functions}}}})
and by using \sphinxcode{\sphinxupquote{\DUrole{name}{Functional} \DUrole{name}{Scheme}}} after a normal definition using
\sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Fixpoint}}} or \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Definition}}}. See {\hyperref[\detokenize{language/gallina-extensions:advanced-recursive-functions}]{\sphinxcrossref{\DUrole{std,std-ref}{Advanced recursive functions}}}}
for details.
\end{sphinxadmonition}


\sphinxstrong{See also:}


{\hyperref[\detokenize{language/gallina-extensions:advanced-recursive-functions}]{\sphinxcrossref{\DUrole{std,std-ref}{Advanced recursive functions}}}}, {\hyperref[\detokenize{user-extensions/proof-schemes:functional-scheme}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of induction principles with Functional Scheme}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion}}}}}


\index{Cannot find induction information on ‘qualid’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.cannot-find-induction-information-on-qualid}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~find~induction~information~on~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}.}}}}
\end{fulllineitems}

\index{Not the right number of induction arguments (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-the-right-number-of-induction-arguments}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~the~right~number~of~induction~arguments.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{functional~induction~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}})~as~\DUrole{hole}{disj\_conj\_intro\_pattern}~using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}}
Similarly to {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.elim}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{elim}}}}}, this allows giving
explicitly the name of the introduced variables, the induction principle, and
the values of dependent premises of the elimination scheme, including
\sphinxstyleemphasis{predicates} for mutual induction when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} is part of a mutually
recursive definition.

\end{fulllineitems}

\index{discriminate (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.discriminate}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{discriminate~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic proves any goal from an assumption stating that two
structurally different \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{terms}}}} of an inductive set are equal. For
example, from \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{S} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{O}\DUrole{operator}{))=(}\DUrole{name}{S} \DUrole{name}{O}\DUrole{operator}{)}}} we can derive by absurdity any
proposition.

The argument \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is assumed to be a proof of a statement of
conclusion \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} with the two terms being elements of an
inductive set. To build the proof, the tactic traverses the normal forms
%
\begin{footnote}[3]\sphinxAtStartFootnote
Reminder: opaque constants will not be expanded by \(\delta\) reductions.
%
\end{footnote} of the terms looking for a couple of subterms \sphinxcode{\sphinxupquote{\DUrole{name}{u}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{w}}} (\sphinxcode{\sphinxupquote{\DUrole{name}{u}}}
subterm of the normal form of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{w}}} subterm of the normal
form of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}), placed at the same positions and whose head symbols are
two different constructors. If such a couple of subterms exists, then the
proof of the current goal is completed, otherwise the tactic fails.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}
The syntax \sphinxcode{\sphinxupquote{\DUrole{notation}{discriminate {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} can be used to refer to a hypothesis
quantified in the goal. In this case, the quantified hypothesis whose name is
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is first introduced in the local context using
\sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.
\end{sphinxadmonition}
\index{No primitive equality found (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.no-primitive-equality-found}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~primitive~equality~found.}}}}
\end{fulllineitems}

\index{Not a discriminable equality (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-a-discriminable-equality}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~a~discriminable~equality.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{discriminate~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This does the same thing as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} followed by
\sphinxcode{\sphinxupquote{\DUrole{notation}{discriminate {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is the identifier for the last
introduced hypothesis.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{discriminate~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}}
This does the same thing as \sphinxcode{\sphinxupquote{\DUrole{notation}{discriminate {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} but using the given
bindings to instantiate parameters or hypotheses of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{ediscriminate~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
\end{fulllineitems}

\index{ediscriminate (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.ediscriminate}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{ediscriminate~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}}}}
This works the same as \sphinxcode{\sphinxupquote{discriminate}} but if the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, or the
type of the hypothesis referred to by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}, has uninstantiated
parameters, these parameters are left as existential variables.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{discriminate}}}}
This behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{discriminate {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} if ident is the name of an
hypothesis to which \sphinxcode{\sphinxupquote{discriminate}} is applicable; if the current goal is of
the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \textless{}\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, this behaves as
\sphinxcode{\sphinxupquote{\DUrole{notation}{intro {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; discriminate {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.
\index{No discriminable equalities (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.no-discriminable-equalities}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~discriminable~equalities.}}}}
\end{fulllineitems}


\end{fulllineitems}

\index{injection (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.injection}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
The injection tactic exploits the property that constructors of
inductive types are injective, i.e. that if \sphinxcode{\sphinxupquote{\DUrole{name}{c}}} is a constructor of an
inductive type and \sphinxcode{\sphinxupquote{\DUrole{name}{c} \DUrole{name}{t}}}$_{\text{1}}$ and \sphinxcode{\sphinxupquote{\DUrole{name}{c} \DUrole{name}{t}}}$_{\text{2}}$ are equal then
\sphinxcode{\sphinxupquote{\DUrole{name}{t}}}$_{\text{1}}$ and \sphinxcode{\sphinxupquote{\DUrole{name}{t}}}$_{\text{2}}$ are equal too.

If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is a proof of a statement of conclusion \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}},
then {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} applies the injectivity of constructors as deep as
possible to derive the equality of all the subterms of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} at positions where the terms start to differ. For example, from
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{p}\DUrole{operator}{,} \DUrole{name}{S} \DUrole{name}{n}\DUrole{operator}{)} \DUrole{operator}{=} \DUrole{operator}{(}\DUrole{name}{q}\DUrole{operator}{,} \DUrole{name}{S} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{m}\DUrole{operator}{))}}} we may derive \sphinxcode{\sphinxupquote{\DUrole{name}{S} \DUrole{name}{p} \DUrole{operator}{=} \DUrole{name}{q}}} and
\sphinxcode{\sphinxupquote{\DUrole{name}{n} \DUrole{operator}{=} \DUrole{name}{S} \DUrole{name}{m}}}. For this tactic to work, the terms should be typed with an
inductive type and they should be neither convertible, nor having a different
head constructor. If these conditions are satisfied, the tactic derives the
equality of all the subterms at positions where they differ and adds them as
antecedents to the conclusion of the current goal.

\begin{sphinxadmonition}{note}{Example}

Consider the following goal:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{k+kt}{list} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{:} \PYG{k+kt}{list}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{list} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{l} \PYG{n}{n}\PYG{o}{,} \PYG{n}{P} \PYG{n}{nil} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{cons} \PYG{n}{n} \PYG{n}{l} \PYG{o}{=} \PYG{n}{cons} \PYG{l+m+mi}{0} \PYG{n}{nil} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{l}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list}
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{P} \PYG{n}{nil}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{cons} \PYG{n}{n} \PYG{n}{l} \PYG{o}{=} \PYG{n}{cons} \PYG{l+m+mi}{0} \PYG{n}{nil}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{n}{l}

\PYG{k}{injection} \PYG{n}{H0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list}
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{P} \PYG{n}{nil}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{cons} \PYG{n}{n} \PYG{n}{l} \PYG{o}{=} \PYG{n}{cons} \PYG{l+m+mi}{0} \PYG{n}{nil}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{l} \PYG{o}{=} \PYG{n}{nil} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{l}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Beware that injection yields an equality in a sigma type whenever the
injected object has a dependent type \sphinxcode{\sphinxupquote{\DUrole{name}{P}}} with its two instances in
different types \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{P} \DUrole{name}{t}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{operator}{...} \DUrole{name}{t}}}$_{\text{n}}$ \sphinxcode{\sphinxupquote{\DUrole{operator}{)}}} and
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{P} \DUrole{name}{u}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{operator}{...} \DUrole{name}{u}}}$_{\text{n}}$ $_{\text{)}}$. If \sphinxcode{\sphinxupquote{\DUrole{name}{t}}}$_{\text{1}}$ and
\sphinxcode{\sphinxupquote{\DUrole{name}{u}}}$_{\text{1}}$ are the same and have for type an inductive type for which a decidable
equality has been declared using the command {\hyperref[\detokenize{user-extensions/proof-schemes:coq:cmdv.scheme-equality}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Scheme Equality}}}}}
(see {\hyperref[\detokenize{user-extensions/proof-schemes:proofschemes-induction-principles}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of induction principles with Scheme}}}}),
the use of a sigma type is avoided.

\begin{sphinxadmonition}{note}{Note:}
If some quantified hypothesis of the goal is named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}},
then \sphinxcode{\sphinxupquote{\DUrole{notation}{injection {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} first introduces the hypothesis in the local
context using \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.
\end{sphinxadmonition}
\index{Not a projectable equality but a discriminable one (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-a-projectable-equality-but-a-discriminable-one}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~a~projectable~equality~but~a~discriminable~one.}}}}
\end{fulllineitems}

\index{Nothing to do, it is an equality between convertible ‘terms’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.nothing-to-do-it-is-an-equality-between-convertible-terms}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Nothing~to~do,~it~is~an~equality~between~convertible~\DUrole{hole}{terms}.}}}}
\end{fulllineitems}

\index{Not a primitive equality (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-a-primitive-equality}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~a~primitive~equality.}}}}
\end{fulllineitems}

\index{Nothing to inject (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.nothing-to-inject}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Nothing~to~inject.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This does the same thing as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} followed by
\sphinxcode{\sphinxupquote{\DUrole{notation}{injection {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is the identifier for the last
introduced hypothesis.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}}
This does the same as \sphinxcode{\sphinxupquote{\DUrole{notation}{injection {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} but using the given bindings to
instantiate parameters or hypotheses of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}

\index{einjection (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.einjection}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einjection~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einjection~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}}}}
This works the same as \sphinxcode{\sphinxupquote{\DUrole{notation}{injection}}} but if the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, or the
type of the hypothesis referred to by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}, has uninstantiated
parameters, these parameters are left as existential variables.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection}}}}
If the current goal is of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \textless{}\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} , this behaves as
\sphinxcode{\sphinxupquote{\DUrole{notation}{intro {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; injection {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.
\index{goal does not satisfy the expected preconditions (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.goal-does-not-satisfy-the-expected-preconditions}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{goal~does~not~satisfy~the~expected~preconditions.}}}}
\end{fulllineitems}


\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}~as~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{intro\_pattern}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~as~\DUrole{repeat-wrapper}{\DUrole{repeat}{intro\_pattern}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{injection~as~\DUrole{repeat-wrapper}{\DUrole{repeat}{intro\_pattern}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einjection~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}~as~\DUrole{repeat-wrapper}{\DUrole{repeat}{intro\_pattern}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einjection~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~as~\DUrole{repeat-wrapper}{\DUrole{repeat}{intro\_pattern}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{einjection~as~\DUrole{repeat-wrapper}{\DUrole{repeat}{intro\_pattern}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}


These variants apply \sphinxcode{\sphinxupquote{\DUrole{notation}{intros \DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{intro\_pattern}}\DUrole{notation-sup}{+}}}}} after the call to
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} or {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.einjection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{einjection}}}}} so that all equalities generated are moved in
the context of hypotheses. The number of \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{intro\_pattern}}}} must not exceed
the number of equalities newly generated. If it is smaller, fresh
names are automatically generated to adjust the list of \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{intro\_pattern}}}}
to the number of new equalities. The original equality is erased if it
corresponds to a hypothesis.
\index{Structural Injection (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.structural-injection}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Structural~Injection}}}}
This option ensure that \sphinxcode{\sphinxupquote{\DUrole{notation}{injection {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} erases the original hypothesis
and leaves the generated equalities in the context rather than putting them
as antecedents of the current goal, as if giving \sphinxcode{\sphinxupquote{\DUrole{notation}{injection {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} as}}}
(with an empty list of names). This option is off by default.

\end{fulllineitems}

\index{Keep Proof Equalities (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.keep-proof-equalities}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Keep~Proof~Equalities}}}}
By default, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} only creates new equalities between \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{terms}}}}
whose type is in sort \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}} or \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}}, thus implementing a special
behavior for objects that are proofs of a statement in \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}}. This option
controls this behavior.

\end{fulllineitems}


\end{fulllineitems}

\index{inversion (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.inversion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Let the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} in the local context be \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{I} \DUrole{name}{t}\DUrole{operator}{)}}}, where \sphinxcode{\sphinxupquote{\DUrole{name}{I}}}
is a (co)inductive predicate. Then, \sphinxcode{\sphinxupquote{inversion}} applied to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
derives for each possible constructor \sphinxcode{\sphinxupquote{\DUrole{name}{c} \DUrole{name}{i}}} of \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{I} \DUrole{name}{t}\DUrole{operator}{)}}}, all the
necessary conditions that should hold for the instance \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{I} \DUrole{name}{t}\DUrole{operator}{)}}} to be
proved by \sphinxcode{\sphinxupquote{\DUrole{name}{c} \DUrole{name}{i}}}.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} does not denote a hypothesis in the local context but
refers to a hypothesis quantified in the goal, then the latter is
first introduced in the local context using \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
As \sphinxcode{\sphinxupquote{inversion}} proofs may be large in size, we recommend the
user to stock the lemmas whenever the same instance needs to be
inverted several times. See {\hyperref[\detokenize{user-extensions/proof-schemes:derive-inversion}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of inversion principles with Derive Inversion}}}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
Part of the behavior of the \sphinxcode{\sphinxupquote{inversion}} tactic is to generate
equalities between expressions that appeared in the hypothesis that is
being processed. By default, no equalities are generated if they
relate two proofs (i.e. equalities between \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{terms}}}} whose type is in sort
\sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}}). This behavior can be turned off by using the option
:flag{}`Keep Proof Equalities{}`.
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This does the same thing as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} then \sphinxcode{\sphinxupquote{\DUrole{notation}{inversion {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is the identifier for the last introduced hypothesis.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion\_clear~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{inversion}}} and then erases \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} from the context.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~\DUrole{hole}{intro\_pattern}}}}}
This generally behaves as inversion but using names in \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{intro\_pattern}}}}
for naming hypotheses. The \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{intro\_pattern}}}} must have the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[}p}}}$_{\text{11}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{... p}}}$_{\text{1n}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{\textbar{} ... \textbar{} p}}}$_{\text{m1}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{... p}}}$_{\text{mn}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{{]}}}}
with \sphinxtitleref{m} being the number of constructors of the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}. Be
careful that the list must be of length \sphinxtitleref{m} even if \sphinxcode{\sphinxupquote{inversion}} discards
some cases (which is precisely one of its roles): for the discarded
cases, just use an empty list (i.e. \sphinxtitleref{n = 0}).The arguments of the i-th
constructor and the equalities that \sphinxcode{\sphinxupquote{inversion}} introduces in the
context of the goal corresponding to the i-th constructor, if it
exists, get their names from the list \sphinxcode{\sphinxupquote{\DUrole{notation}{p}}}$_{\text{i1}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{... p}}}$_{\text{in}}$ in
order. If there are not enough names, \sphinxcode{\sphinxupquote{inversion}} invents names for the
remaining variables to introduce. In case an equation splits into several
equations (because \sphinxcode{\sphinxupquote{inversion}} applies \sphinxcode{\sphinxupquote{injection}} on the equalities it
generates), the corresponding name \sphinxcode{\sphinxupquote{\DUrole{notation}{p}}}$_{\text{ij}}$ in the list must be
replaced by a sublist of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}p}}}$_{\text{ij1}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{... p}}}$_{\text{ijq}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{{]}}}}
(or, equivalently, \sphinxcode{\sphinxupquote{\DUrole{notation}{(p}}}$_{\text{ij1}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{, ..., p}}}$_{\text{ijq}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{)}}}) where
\sphinxtitleref{q} is the number of subequalities obtained from splitting the original
equation. Here is an example. The \sphinxcode{\sphinxupquote{inversion ... as}} variant of
\sphinxcode{\sphinxupquote{inversion}} generally behaves in a slightly more expectable way than
\sphinxcode{\sphinxupquote{inversion}} (no artificial duplication of some hypotheses referring to
other hypotheses). To take benefit of these improvements, it is enough to use
\sphinxcode{\sphinxupquote{inversion ... as {[}{]}}}, letting the names being finally chosen by Coq.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{contains0} \PYG{o}{:} \PYG{k+kt}{list} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{in\PYGZus{}hd} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{l}\PYG{o}{,} \PYG{n}{contains0} \PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{::} \PYG{n}{l}\PYG{o}{)}
\PYG{o}{\textbar{}} \PYG{n}{in\PYGZus{}tl} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{l} \PYG{n}{b}\PYG{o}{,} \PYG{n}{contains0} \PYG{n}{l} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{contains0} \PYG{o}{(}\PYG{n}{b} \PYG{o}{::} \PYG{n}{l}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{contains0} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{contains0\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{l}\PYG{o}{:}\PYG{k+kt}{list} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{contains0} \PYG{o}{(}\PYG{l+m+mi}{1} \PYG{o}{::} \PYG{n}{l}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{contains0} \PYG{n}{l}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{contains0} \PYG{o}{(}\PYG{l+m+mi}{1} \PYG{o}{::} \PYG{n}{l}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{contains0} \PYG{n}{l}

\PYG{k}{intros} \PYG{n}{l} \PYG{n}{H}\PYG{o}{;} \PYG{k}{inversion} \PYG{n}{H} \PYG{k}{as} \PYG{o}{[} \PYG{o}{\textbar{}} \PYG{n}{l\PYGZsq{}} \PYG{n}{p} \PYG{n}{Hl\PYGZsq{}} \PYG{o}{[}\PYG{n}{Heqp} \PYG{n}{Heql\PYGZsq{}}\PYG{o}{]} \PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{contains0} \PYG{o}{(}\PYG{l+m+mi}{1} \PYG{o}{::} \PYG{n}{l}\PYG{o}{)}
      \PYG{n}{l\PYGZsq{}} \PYG{o}{:} \PYG{k+kt}{list} \PYG{k+kt}{nat}
      \PYG{n}{p} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{Hl\PYGZsq{}} \PYG{o}{:} \PYG{n}{contains0} \PYG{n}{l}
      \PYG{n}{Heqp} \PYG{o}{:} \PYG{n}{p} \PYG{o}{=} \PYG{l+m+mi}{1}
      \PYG{n}{Heql\PYGZsq{}} \PYG{o}{:} \PYG{n}{l\PYGZsq{}} \PYG{o}{=} \PYG{n}{l}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{contains0} \PYG{n}{l}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~as~\DUrole{hole}{intro\_pattern}}}}}
This allows naming the hypotheses introduced by \sphinxcode{\sphinxupquote{\DUrole{notation}{inversion {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} in the
context.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion\_clear~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~\DUrole{hole}{intro\_pattern}}}}}
This allows naming the hypotheses introduced by \sphinxcode{\sphinxupquote{inversion\_clear}} in the
context. Notice that hypothesis names can be provided as if \sphinxcode{\sphinxupquote{inversion}}
were called, even though the \sphinxcode{\sphinxupquote{inversion\_clear}} will eventually erase the
hypotheses.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
Let \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}} be identifiers in the local context. This tactic behaves as
generalizing \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}, and then performing \sphinxcode{\sphinxupquote{inversion}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~\DUrole{hole}{intro\_pattern}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This allows naming the hypotheses introduced in the context by
\sphinxcode{\sphinxupquote{\DUrole{notation}{inversion {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} in \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion\_clear~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
Let \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}} be identifiers in the local context. This tactic behaves
as generalizing \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}, and then performing \sphinxcode{\sphinxupquote{inversion\_clear}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion\_clear~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~\DUrole{hole}{intro\_pattern}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This allows naming the hypotheses introduced in the context by
\sphinxcode{\sphinxupquote{\DUrole{notation}{inversion\_clear {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} in \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}.

\end{fulllineitems}

\index{dependent inversion (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.dependent-inversion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
That must be used when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} appears in the current goal. It acts like
\sphinxcode{\sphinxupquote{inversion}} and then substitutes \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} for the corresponding
\sphinxcode{\sphinxupquote{\DUrole{notation}{@{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} in the goal.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~\DUrole{hole}{intro\_pattern}}}}}
This allows naming the hypotheses introduced in the context by
\sphinxcode{\sphinxupquote{\DUrole{notation}{dependent inversion {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion\_clear~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Like \sphinxcode{\sphinxupquote{dependent inversion}}, except that \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is cleared from the
local context.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion\_clear~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~\DUrole{hole}{intro\_pattern}}}}}
This allows naming the hypotheses introduced in the context by
\sphinxcode{\sphinxupquote{\DUrole{notation}{dependent inversion\_clear {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}

\index{dependent inversion ... with ... (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.dependent-inversion-with}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This variant allows you to specify the generalization of the goal. It is
useful when the system fails to generalize the goal automatically. If
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} has type \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{I} \DUrole{name}{t}\DUrole{operator}{)}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{I}}} has type \(\forall\)
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{T}\DUrole{operator}{),} \DUrole{name}{s}}}, then \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} must be of type \sphinxcode{\sphinxupquote{\DUrole{name}{I}\DUrole{operator}{:}}}\(\forall\)
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{T}\DUrole{operator}{),} \DUrole{name}{I} \DUrole{name}{x} \DUrole{operator}{-\textgreater{}} \DUrole{name}{s'}}} where \sphinxcode{\sphinxupquote{\DUrole{name}{s'}}} is the type of the goal.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~\DUrole{hole}{intro\_pattern}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This allows naming the hypotheses introduced in the context by
\sphinxcode{\sphinxupquote{\DUrole{notation}{dependent inversion {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion\_clear~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Like {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.dependent-inversion-with}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{dependent inversion ... with ...}}}}} with but clears \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} from the
local context.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~inversion\_clear~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~\DUrole{hole}{intro\_pattern}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This allows naming the hypotheses introduced in the context by
\sphinxcode{\sphinxupquote{\DUrole{notation}{dependent inversion\_clear {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}

\index{simple inversion (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.simple-inversion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
It is a very primitive inversion tactic that derives all the necessary
equalities but it does not simplify the constraints as \sphinxcode{\sphinxupquote{inversion}} does.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simple~inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~as~\DUrole{hole}{intro\_pattern}}}}}
This allows naming the hypotheses introduced in the context by
\sphinxcode{\sphinxupquote{simple inversion}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Let \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} have type \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{I} \DUrole{name}{t}\DUrole{operator}{)}}} (\sphinxcode{\sphinxupquote{\DUrole{name}{I}}} an inductive predicate) in the
local context, and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} be a (dependent) inversion lemma. Then, this
tactic refines the current goal with the specified lemma.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This tactic behaves as generalizing \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}, then doing
\sphinxcode{\sphinxupquote{\DUrole{notation}{inversion {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} using {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{inversion\_sigma}}}}
This tactic turns equalities of dependent pairs (e.g.,
\sphinxcode{\sphinxupquote{\DUrole{name}{existT} \DUrole{name}{P} \DUrole{name}{x} \DUrole{name}{p} \DUrole{operator}{=} \DUrole{name}{existT} \DUrole{name}{P} \DUrole{name}{y} \DUrole{name}{q}}}, frequently left over by inversion on
a dependent type family) into pairs of equalities (e.g., a hypothesis
\sphinxcode{\sphinxupquote{\DUrole{name}{H} \DUrole{operator}{:} \DUrole{name}{x} \DUrole{operator}{=} \DUrole{name}{y}}} and a hypothesis of type \sphinxcode{\sphinxupquote{\DUrole{name}{rew} \DUrole{name}{H} \DUrole{keyword}{in} \DUrole{name}{p} \DUrole{operator}{=} \DUrole{name}{q}}}); these
hypotheses can subsequently be simplified using {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.subst}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{subst}}}}}, without ever
invoking any kind of axiom asserting uniqueness of identity proofs. If you
want to explicitly specify the hypothesis to be inverted, or name the
generated hypotheses, you can invoke
\sphinxcode{\sphinxupquote{\DUrole{notation}{induction H as {[}H1 H2{]} using eq\_sigT\_rect.}}} This tactic also works for
\sphinxcode{\sphinxupquote{\DUrole{name}{sig}}}, \sphinxcode{\sphinxupquote{\DUrole{name}{sigT2}}}, and \sphinxcode{\sphinxupquote{\DUrole{name}{sig2}}}, and there are similar \sphinxcode{\sphinxupquote{\DUrole{name}{eq\_sig}}}
\sphinxcode{\sphinxupquote{\DUrole{operator}{***\_}\DUrole{name}{rect}}} induction lemmas.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\sphinxstyleemphasis{Non-dependent inversion}.

Let us consider the relation Le over natural numbers and the following
variables:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{Le} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{LeO} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{l+m+mi}{0} \PYG{n}{n}
\PYG{o}{\textbar{}} \PYG{n}{LeS} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Le} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Le\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Le\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Le\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Variable} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{32}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Variable} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Warning}\PYG{o}{:} \PYG{n}{P} \PYG{k}{is} \PYG{n}{declared} \PYG{k}{as} \PYG{n}{a} \PYG{n}{local} \PYG{n}{axiom} \PYG{o}{[}\PYG{n}{local}\PYG{o}{\PYGZhy{}}\PYG{n}{declaration}\PYG{o}{,}\PYG{n}{scope}\PYG{o}{]}
    \PYG{n}{P} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Variable} \PYG{n}{Q} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{44}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Variable} \PYG{n}{Q} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Warning}\PYG{o}{:} \PYG{n}{Q} \PYG{k}{is} \PYG{n}{declared} \PYG{k}{as} \PYG{n}{a} \PYG{n}{local} \PYG{n}{axiom} \PYG{o}{[}\PYG{n}{local}\PYG{o}{\PYGZhy{}}\PYG{n}{declaration}\PYG{o}{,}\PYG{n}{scope}\PYG{o}{]}
    \PYG{n}{Q} \PYG{k}{is} \PYG{n}{declared}
\end{sphinxVerbatim}

Let us consider the following goal:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Show}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{n}{n} \PYG{n}{m}
\end{sphinxVerbatim}

To prove the goal, we may need to reason by cases on H and to derive
that m is necessarily of the form (S m 0 ) for certain m 0 and that
(Le n m 0 ). Deriving these conditions corresponds to proving that the
only possible constructor of (Le (S n) m) isLeS and that we can invert
the-\textgreater{} in the type of LeS. This inversion is possible because Le is the
smallest set closed by the constructors LeO and LeS.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{inversion\PYGZus{}clear} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m}\PYG{o}{,} \PYG{n}{m0} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{n}{n} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m0}\PYG{o}{)}
\end{sphinxVerbatim}

Note that m has been substituted in the goal for (S m0) and that the
hypothesis (Le n m0) has been added to the context.

Sometimes it is interesting to have the equality m=(S m0) in the
context to use it after. In that case we can use inversion that does
not clear the equalities:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{inversion} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m}
      \PYG{n}{n0}\PYG{o}{,} \PYG{n}{m0} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H1} \PYG{o}{:} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m0}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{n0} \PYG{o}{=} \PYG{n}{n}
      \PYG{n}{H2} \PYG{o}{:} \PYG{n}{S} \PYG{n}{m0} \PYG{o}{=} \PYG{n}{m}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{n}{n} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m0}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

\sphinxstyleemphasis{Dependent inversion.}

Let us consider the following goal:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Show}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{Q} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m} \PYG{n}{H}
\end{sphinxVerbatim}

As H occurs in the goal, we may want to reason by cases on its
structure and so, we would like inversion tactics to substitute H by
the corresponding @term in constructor form. Neither {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion}}}}} nor
\sphinxcode{\sphinxupquote{\DUrole{notation}{inversion\_clear}}} do such a substitution. To have such a behavior we
use the dependent inversion tactics:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{dependent} \PYG{n}{inversion\PYGZus{}clear} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m}\PYG{o}{,} \PYG{n}{m0} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{l} \PYG{o}{:} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{Q} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m0}\PYG{o}{)} \PYG{o}{(}\PYG{n}{LeS} \PYG{n}{n} \PYG{n}{m0} \PYG{n}{l}\PYG{o}{)}
\end{sphinxVerbatim}

Note that H has been substituted by (LeS n m0 l) andm by (S m0).
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

\sphinxstyleemphasis{Using inversion\_sigma.}

Let us consider the following inductive type of
length-indexed lists, and a lemma about inverting equality of cons:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Logic}\PYG{o}{.}\PYG{n}{Eqdep\PYGZus{}dec}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{vec} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{O}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{\PYGZob{}}\PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{xs} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{vec} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{vec\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{vec\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{vec\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Lemma} \PYG{n}{invert\PYGZus{}cons} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{n} \PYG{n}{x} \PYG{n}{xs} \PYG{n}{y} \PYG{n}{ys}\PYG{o}{,}
         \PYG{o}{@}\PYG{n}{cons} \PYG{n}{A} \PYG{n}{n} \PYG{n}{x} \PYG{n}{xs} \PYG{o}{=} \PYG{o}{@}\PYG{n}{cons} \PYG{n}{A} \PYG{n}{n} \PYG{n}{y} \PYG{n}{ys}
         \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{xs} \PYG{o}{=} \PYG{n}{ys}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{xs} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{y} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{ys} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}\PYG{o}{)}\PYG{o}{,}
      \PYG{n}{cons} \PYG{n}{A} \PYG{n}{x} \PYG{n}{xs} \PYG{o}{=} \PYG{n}{cons} \PYG{n}{A} \PYG{n}{y} \PYG{n}{ys} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{xs} \PYG{o}{=} \PYG{n}{ys}

\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{intros} \PYG{n}{A} \PYG{n}{n} \PYG{n}{x} \PYG{n}{xs} \PYG{n}{y} \PYG{n}{ys} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{xs} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}
      \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{ys} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{cons} \PYG{n}{A} \PYG{n}{x} \PYG{n}{xs} \PYG{o}{=} \PYG{n}{cons} \PYG{n}{A} \PYG{n}{y} \PYG{n}{ys}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{xs} \PYG{o}{=} \PYG{n}{ys}
\end{sphinxVerbatim}

After performing inversion, we are left with an equality of existTs:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{inversion} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{xs} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}
      \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{ys} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{cons} \PYG{n}{A} \PYG{n}{x} \PYG{n}{xs} \PYG{o}{=} \PYG{n}{cons} \PYG{n}{A} \PYG{n}{y} \PYG{n}{ys}
      \PYG{n}{H1} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}
      \PYG{n}{H2} \PYG{o}{:} \PYG{n}{existT} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}\PYG{o}{)} \PYG{n}{n} \PYG{n}{xs} \PYG{o}{=}
           \PYG{n}{existT} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}\PYG{o}{)} \PYG{n}{n} \PYG{n}{ys}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{xs} \PYG{o}{=} \PYG{n}{ys}
\end{sphinxVerbatim}

We can turn this equality into a usable form with inversion\_sigma:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{inversion\PYGZus{}sigma}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{xs} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}
      \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{ys} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{cons} \PYG{n}{A} \PYG{n}{x} \PYG{n}{xs} \PYG{o}{=} \PYG{n}{cons} \PYG{n}{A} \PYG{n}{y} \PYG{n}{ys}
      \PYG{n}{H1} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n}
      \PYG{n}{H3} \PYG{o}{:} \PYG{n}{eq\PYGZus{}rect} \PYG{n}{n} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{a} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{a}\PYG{o}{)} \PYG{n}{xs} \PYG{n}{n} \PYG{n}{H0} \PYG{o}{=} \PYG{n}{ys}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{xs} \PYG{o}{=} \PYG{n}{ys}
\end{sphinxVerbatim}

To finish cleaning up the proof, we will need to use the fact that
that all proofs of n = n for n a nat are eq\_refl:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{let} \PYG{n}{H} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{goal} \PYG{k}{with} \PYG{n}{H} \PYG{o}{:} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{H} \PYG{k}{end} \PYG{k}{in}
\PYG{k}{pose} \PYG{n}{proof} \PYG{o}{(}\PYG{n}{Eqdep\PYGZus{}dec}\PYG{o}{.}\PYG{n}{UIP\PYGZus{}refl\PYGZus{}nat} \PYG{o}{\PYGZus{}} \PYG{n}{H}\PYG{o}{)}\PYG{o}{;} \PYG{k}{subst} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{xs} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}
      \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{ys} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{cons} \PYG{n}{A} \PYG{n}{x} \PYG{n}{xs} \PYG{o}{=} \PYG{n}{cons} \PYG{n}{A} \PYG{n}{y} \PYG{n}{ys}
      \PYG{n}{H1} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}
      \PYG{n}{H3} \PYG{o}{:} \PYG{n}{eq\PYGZus{}rect} \PYG{n}{n} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{a} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{a}\PYG{o}{)} \PYG{n}{xs} \PYG{n}{n} \PYG{n}{eq\PYGZus{}refl} \PYG{o}{=} \PYG{n}{ys}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{xs} \PYG{o}{=} \PYG{n}{ys}

\PYG{k}{simpl} \PYG{k}{in} \PYG{o}{*}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{xs} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}
      \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{ys} \PYG{o}{:} \PYG{n}{vec} \PYG{n}{A} \PYG{n}{n}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{cons} \PYG{n}{A} \PYG{n}{x} \PYG{n}{xs} \PYG{o}{=} \PYG{n}{cons} \PYG{n}{A} \PYG{n}{y} \PYG{n}{ys}
      \PYG{n}{H1} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}
      \PYG{n}{H3} \PYG{o}{:} \PYG{n}{xs} \PYG{o}{=} \PYG{n}{ys}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{xs} \PYG{o}{=} \PYG{n}{ys}
\end{sphinxVerbatim}

Finally, we can finish the proof:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{assumption}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{invert\PYGZus{}cons} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{fix (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.fix}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{fix~ident~num}}}}
This tactic is a primitive tactic to start a proof by induction. In
general, it is easier to rely on higher-level induction tactics such
as the ones described in {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}}.

In the syntax of the tactic, the identifier \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is the name given to
the induction hypothesis. The natural number \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} tells on which
premise of the current goal the induction acts, starting from 1,
counting both dependent and non dependent products, but skipping local
definitions. Especially, the current lemma must be composed of at
least \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} products.

Like in a fix expression, the induction hypotheses have to be used on
structurally smaller arguments. The verification that inductive proof
arguments are correct is done only at the time of registering the
lemma in the environment. To know if the use of induction hypotheses
is correct at some time of the interactive development of a proof, use
the command \sphinxcode{\sphinxupquote{Guarded}} (see Section {\hyperref[\detokenize{proof-engine/proof-handling:requestinginformation}]{\sphinxcrossref{\DUrole{std,std-ref}{Requesting information}}}}).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{fix~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{(ident~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{+}}~{[}\DUrole{curlies}{\{struct~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}\}}{]}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})}\DUrole{notation-sup}{+}}}}}}
This starts a proof by mutual induction. The statements to be simultaneously
proved are respectively \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{binder} \DUrole{operator}{...} \DUrole{name}{binder}\DUrole{operator}{,} \DUrole{name}{type}}}.
The identifiers \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} are the names of the induction hypotheses. The identifiers
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} are the respective names of the premises on which the induction
is performed in the statements to be simultaneously proved (if not given, the
system tries to guess itself what they are).

\end{fulllineitems}

\index{cofix (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.cofix}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{cofix~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This tactic starts a proof by coinduction. The identifier \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is the
name given to the coinduction hypothesis. Like in a cofix expression,
the use of induction hypotheses have to guarded by a constructor. The
verification that the use of co-inductive hypotheses is correct is
done only at the time of registering the lemma in the environment. To
know if the use of coinduction hypotheses is correct at some time of
the interactive development of a proof, use the command \sphinxcode{\sphinxupquote{Guarded}}
(see Section {\hyperref[\detokenize{proof-engine/proof-handling:requestinginformation}]{\sphinxcrossref{\DUrole{std,std-ref}{Requesting information}}}}).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{cofix~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binder}]{\sphinxcrossref{\DUrole{hole}{binder}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}})}\DUrole{notation-sup}{+}}}}}}
This starts a proof by mutual coinduction. The statements to be
simultaneously proved are respectively \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{binder} \DUrole{operator}{...} \DUrole{name}{binder}\DUrole{operator}{,} \DUrole{name}{type}}}
The identifiers \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} are the names of the coinduction hypotheses.

\end{fulllineitems}



\subsection{Rewriting expressions}
\label{\detokenize{proof-engine/tactics:rewriting-expressions}}\label{\detokenize{proof-engine/tactics:rewritingexpressions}}
These tactics use the equality \sphinxcode{\sphinxupquote{\DUrole{name}{eq}\DUrole{operator}{:}\DUrole{keyword}{forall} \DUrole{name}{A}\DUrole{operator}{:}\DUrole{keyword,type}{Type}\DUrole{operator}{,} \DUrole{name}{A}\DUrole{operator}{-\textgreater{}}\DUrole{name}{A}\DUrole{operator}{-\textgreater{}}\DUrole{keyword,type}{Prop}}} defined in
file \sphinxcode{\sphinxupquote{Logic.v}} (see {\hyperref[\detokenize{language/coq-library:coq-library-logic}]{\sphinxcrossref{\DUrole{std,std-ref}{Logic}}}}). The notation for \sphinxcode{\sphinxupquote{\DUrole{name}{eq} \DUrole{name}{T} \DUrole{name}{t} \DUrole{name}{u}}} is
simply \sphinxcode{\sphinxupquote{\DUrole{name}{t}\DUrole{operator}{=}\DUrole{name}{u}}} dropping the implicit type of \sphinxcode{\sphinxupquote{\DUrole{name}{t}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{u}}}.
\index{rewrite (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.rewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{rewrite~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic applies to any goal. The type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} must have the form

\sphinxcode{\sphinxupquote{forall (x}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{:A}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{) ... (x}}$_{\text{n}}$ \sphinxcode{\sphinxupquote{:A}}$_{\text{n}}$ \sphinxcode{\sphinxupquote{). eq term}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{term}}$_{\text{2}}$ \sphinxcode{\sphinxupquote{.}}

where \sphinxcode{\sphinxupquote{\DUrole{name}{eq}}} is the Leibniz equality or a registered setoid equality.

Then \sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} finds the first subterm matching \sphinxtitleref{term}$_{\text{1}}$ in the goal,
resulting in instances \sphinxtitleref{term}$_{\text{1}}$' and \sphinxtitleref{term}$_{\text{2}}$' and then
replaces every occurrence of \sphinxtitleref{term}$_{\text{1}}$' by \sphinxtitleref{term}$_{\text{2}}$'.
Hence, some of the variables \sphinxcode{\sphinxupquote{\DUrole{name}{x}}}$_{\text{i}}$ are solved by unification,
and some of the types \sphinxcode{\sphinxupquote{\DUrole{name}{A}}}$_{\text{1}}$\sphinxcode{\sphinxupquote{\DUrole{operator}{,} \DUrole{operator}{...,} \DUrole{name}{A}}}$_{\text{n}}$ become new
subgoals.
\index{The ‘term’ provided does not end with an equation (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.the-term-provided-does-not-end-with-an-equation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~provided~does~not~end~with~an~equation.}}}}
\end{fulllineitems}

\index{Tactic generated a subgoal identical to the original goal. This happens if ‘term’ does not occur in the goal (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.tactic-generated-a-subgoal-identical-to-the-original-goal-this-happens-if-term-does-not-occur-in-the-goal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Tactic~generated~a~subgoal~identical~to~the~original~goal.~This~happens~if~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~does~not~occur~in~the~goal.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rewrite~-\textgreater{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rewrite~\textless{}-~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Uses the equality \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{= {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} $_{\text{2}}$ from right to left

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rewrite~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~clause}}}}
Analogous to \sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} but rewriting is done following clause
(similarly to {\hyperref[\detokenize{proof-engine/tactics:performingcomputations}]{\sphinxcrossref{\DUrole{std,std-ref}{performing computations}}}}). For instance:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite H in H}}}$_{\text{1}}$ will rewrite \sphinxtitleref{H} in the hypothesis
\sphinxtitleref{H}$_{\text{1}}$ instead of the current goal.

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite H in H}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{name}{at} \DUrole{literal,number,integer}{1}\DUrole{operator}{,} \DUrole{name}{H}}}$_{\text{2}}$ \sphinxcode{\sphinxupquote{\DUrole{name}{at} \DUrole{operator}{-} \DUrole{literal,number,integer}{2} \DUrole{operator}{\textbar{}-} \DUrole{operator}{*}}} means
\sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite H; rewrite H in H}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{name}{at} \DUrole{literal,number,integer}{1}\DUrole{operator}{;} \DUrole{keyword}{rewrite} \DUrole{name}{H} \DUrole{keyword}{in} \DUrole{name}{H}}}$_{\text{2}}$ \sphinxcode{\sphinxupquote{\DUrole{name}{at} \DUrole{operator}{-} \DUrole{literal,number,integer}{2}\DUrole{operator}{.}}}
In particular a failure will happen if any of these three simpler tactics
fails.

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite H in * \textbar{}-}}} will do \sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite H in H}}}$_{\text{i}}$ for all hypotheses
\sphinxcode{\sphinxupquote{\DUrole{name}{H}}}$_{\text{i}}$ different from \sphinxcode{\sphinxupquote{\DUrole{name}{H}}}.
A success will happen as soon as at least one of these simpler tactics succeeds.

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite H in *}}} is a combination of \sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite H}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite H in * \textbar{}-}}}
that succeeds if at least one of these two tactics succeeds.

\end{itemize}

Orientation \sphinxcode{\sphinxupquote{\DUrole{operator}{-\textgreater{}}}} or \sphinxcode{\sphinxupquote{\DUrole{operator}{\textless{}-}}} can be inserted before the {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} to rewrite.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rewrite~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~at~occurrences}}}}
Rewrite only the given occurrences of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. Occurrences are
specified from left to right as for pattern ({\hyperref[\detokenize{proof-engine/tactics:coq:tacn.pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}). The rewrite is
always performed using setoid rewriting, even for Leibniz’s equality, so one
has to \sphinxcode{\sphinxupquote{Import Setoid}} to use this variant.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rewrite~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~by~tactic}}}}
Use tactic to completely solve the side-conditions arising from the
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{rewrite~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
Is equivalent to the \sphinxtitleref{n} successive tactics \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{rewrite {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{;}}}}}, each one
working on the first subgoal generated by the previous one. Orientation
\sphinxcode{\sphinxupquote{\DUrole{operator}{-\textgreater{}}}} or \sphinxcode{\sphinxupquote{\DUrole{operator}{\textless{}-}}} can be inserted before each {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} to rewrite.  One
unique clause can be added at the end after the keyword in; it will then
affect all rewrite operations.

\end{fulllineitems}


In all forms of rewrite described above, a {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} to rewrite can be
immediately prefixed by one of the following modifiers:
\begin{itemize}
\item {} 
\sphinxtitleref{?} : the tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite ?{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} performs the rewrite of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} as many
times as possible (perhaps zero time). This form never fails.

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}?}}} : works similarly, except that it will do at most {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}} rewrites.

\item {} 
\sphinxtitleref{!} : works as \sphinxtitleref{?}, except that at least one rewrite should succeed, otherwise
the tactic fails.

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}!}}} (or simply \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}) : precisely {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}} rewrites of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} will be done,
leading to failure if these {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}} rewrites are not possible.

\end{itemize}
\index{erewrite (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.erewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{erewrite~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic works as \sphinxcode{\sphinxupquote{\DUrole{notation}{rewrite {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} but turning
unresolved bindings into existential variables, if any, instead of
failing. It has the same variants as {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} has.

\end{fulllineitems}


\end{fulllineitems}

\index{replace (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.replace}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{replace~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}}}
This tactic applies to any goal. It replaces all free occurrences of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}
in the current goal with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}} and generates an equality \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}}
as a subgoal. This equality is automatically solved if it occurs among
the assumptions, or if its symmetric form occurs. It is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{cut {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’; {[}intro H}}}$_{\text{n}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{; rewrite \textless{}- H}}}$_{\text{n}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{; clear H}}}$_{\text{n}}$\sphinxcode{\sphinxupquote{\DUrole{notation}{\textbar{}\textbar{} assumption \textbar{}\textbar{} symmetry; try assumption{]}}}}.
\index{Terms do not have convertible types (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.terms-do-not-have-convertible-types}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Terms~do~not~have~convertible~types.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{replace~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’~by~\DUrole{hole}{tactic}}}}}
This acts as \sphinxcode{\sphinxupquote{\DUrole{notation}{replace {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}} but applies \sphinxcode{\sphinxupquote{tactic}} to solve the generated
subgoal \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{replace~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Replaces \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}} using the first assumption whose type has
the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’ = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{replace~-\textgreater{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Replaces \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}} using the first assumption whose type has
the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{replace~\textless{}-~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Replaces \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}} using the first assumption whose type has
the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’ = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{replace~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}~in~clause~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~\DUrole{hole}{tactic}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{replace~-\textgreater{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~clause}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{replace~\textless{}-~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~clause}}}}
Acts as before but the replacements take place in the specified clause (see
{\hyperref[\detokenize{proof-engine/tactics:performingcomputations}]{\sphinxcrossref{\DUrole{std,std-ref}{Performing computations}}}}) and not only in the conclusion of the goal. The
clause argument must not contain any \sphinxcode{\sphinxupquote{type of}} nor \sphinxcode{\sphinxupquote{value of}}.

\end{fulllineitems}

\index{cutrewrite (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.cutrewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{cutrewrite~\textless{}-~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’)}}}}
This tactic is deprecated. It can be replaced by \sphinxcode{\sphinxupquote{\DUrole{notation}{enough ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’) as \textless{}-}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{cutrewrite~-\textgreater{}~({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’)}}}}
This tactic is deprecated. It can be replaced by \sphinxcode{\sphinxupquote{\DUrole{notation}{enough ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’) as -\textgreater{}}}}.

\end{fulllineitems}


\end{fulllineitems}

\index{subst (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.subst}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{subst~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This tactic applies to a goal that has \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} in its context and (at
least) one hypothesis, say \sphinxcode{\sphinxupquote{\DUrole{name}{H}}}, of type \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} = t}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{t = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} not occurring in \sphinxcode{\sphinxupquote{\DUrole{name}{t}}}. Then it replaces \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} by
\sphinxcode{\sphinxupquote{\DUrole{name}{t}}} everywhere in the goal (in the hypotheses and in the conclusion) and
clears \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{H}}} from the context.

If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is a local definition of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := t}}}, it is also
unfolded and cleared.

\begin{sphinxadmonition}{note}{Note:}\begin{itemize}
\item {} 
When several hypotheses have the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} = t}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{t = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, the
first one is used.

\item {} 
If \sphinxcode{\sphinxupquote{\DUrole{name}{H}}} is itself dependent in the goal, it is replaced by the proof of
reflexivity of equality.

\end{itemize}
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{subst~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{subst {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}$_{\text{1}}$\sphinxcode{\sphinxupquote{\DUrole{notation}{; ...; subst {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}$_{\text{n}}$.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{subst}}}}
This applies subst repeatedly from top to bottom to all identifiers of the
context for which an equality of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} = t}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{t = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
or \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := t}}} exists, with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} not occurring in \sphinxcode{\sphinxupquote{t}}.

\end{fulllineitems}

\index{Regular Subst Tactic (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.regular-subst-tactic}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Regular~Subst~Tactic}}}}
This option controls the behavior of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.subst}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{subst}}}}}. When it is
activated (it is by default), {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.subst}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{subst}}}}} also deals with the following corner cases:
\begin{itemize}
\item {} 
A context with ordered hypotheses \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{= {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}$_{\text{2}}$
and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{= t}}}, or \sphinxcode{\sphinxupquote{\DUrole{notation}{t′ = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}$_{\text{1{}`}}$ with \sphinxtitleref{t′} not
a variable, and no other hypotheses of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}$_{\text{2}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{= u}}}
or \sphinxcode{\sphinxupquote{\DUrole{notation}{u = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}$_{\text{2}}$; without the option, a second call to
subst would be necessary to replace \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}$_{\text{2}}$ by \sphinxtitleref{t} or
\sphinxtitleref{t′} respectively.

\item {} 
The presence of a recursive equation which without the option would
be a cause of failure of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.subst}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{subst}}}}}.

\item {} 
A context with cyclic dependencies as with hypotheses \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{= f {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}$_{\text{2}}$
and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}$_{\text{2}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{= g {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}$_{\text{1}}$ which without the
option would be a cause of failure of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.subst}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{subst}}}}}.

\end{itemize}

Additionally, it prevents a local definition such as \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := t}}} to be
unfolded which otherwise it would exceptionally unfold in configurations
containing hypotheses of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} = u}}}, or \sphinxcode{\sphinxupquote{\DUrole{notation}{u′ = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
with \sphinxtitleref{u′} not a variable. Finally, it preserves the initial order of
hypotheses, which without the option it may break.
default.

\end{fulllineitems}


\end{fulllineitems}

\index{stepl (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.stepl}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{stepl~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic is for chaining rewriting steps. It assumes a goal of the
form \sphinxcode{\sphinxupquote{\DUrole{notation}{R {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} where \sphinxcode{\sphinxupquote{R}} is a binary relation and relies on a
database of lemmas of the form \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x} \DUrole{name}{y} \DUrole{name}{z}\DUrole{operator}{,} \DUrole{name}{R} \DUrole{name}{x} \DUrole{name}{y} \DUrole{operator}{-\textgreater{}} \DUrole{name}{eq} \DUrole{name}{x} \DUrole{name}{z} \DUrole{operator}{-\textgreater{}} \DUrole{name}{R} \DUrole{name}{z} \DUrole{name}{y}}}
where \sphinxtitleref{eq} is typically a setoid equality. The application of \sphinxcode{\sphinxupquote{\DUrole{notation}{stepl {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}
then replaces the goal by \sphinxcode{\sphinxupquote{\DUrole{notation}{R {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and adds a new goal stating
\sphinxcode{\sphinxupquote{\DUrole{notation}{eq {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.
\index{Declare Left Step (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmd.declare-left-step}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~Left~Step~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Adds \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} to the database used by {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.stepl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{stepl}}}}}.

\end{fulllineitems}


This tactic is especially useful for parametric setoids which are not accepted
as regular setoids for {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} and {\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacv.setoid-replace}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_replace}}}}} (see
{\hyperref[\detokenize{addendum/generalized-rewriting:generalizedrewriting}]{\sphinxcrossref{\DUrole{std,std-ref}{Generalized rewriting}}}}).


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{stepl~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~by~\DUrole{hole}{tactic}}}}}
This applies \sphinxcode{\sphinxupquote{\DUrole{notation}{stepl {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} then applies \sphinxcode{\sphinxupquote{tactic}} to the second goal.

\end{fulllineitems}

\index{stepr (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.stepr}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{stepr~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~stepr~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~by~tactic}}}}
This behaves as {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.stepl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{stepl}}}}} but on the right-hand-side of the binary
relation. Lemmas are expected to be of the form
\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x} \DUrole{name}{y} \DUrole{name}{z}\DUrole{operator}{,} \DUrole{name}{R} \DUrole{name}{x} \DUrole{name}{y} \DUrole{operator}{-\textgreater{}} \DUrole{name}{eq} \DUrole{name}{y} \DUrole{name}{z} \DUrole{operator}{-\textgreater{}} \DUrole{name}{R} \DUrole{name}{x} \DUrole{name}{z}}}.

\end{fulllineitems}

\index{Declare Right Step (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmd.declare-right-step}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~Right~Step~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Adds \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} to the database used by {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.stepr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{stepr}}}}}.

\end{fulllineitems}


\end{fulllineitems}

\index{change (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.change}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{change~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic applies to any goal. It implements the rule \sphinxcode{\sphinxupquote{Conv}} given in
{\hyperref[\detokenize{language/cic:subtyping-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{Subtyping rules}}}}. \sphinxcode{\sphinxupquote{\DUrole{keyword}{change} \DUrole{name}{U}}} replaces the current goal \sphinxtitleref{T}
with \sphinxtitleref{U} providing that \sphinxtitleref{U} is well-formed and that \sphinxtitleref{T} and \sphinxtitleref{U} are
convertible.
\index{Not convertible (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-convertible}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~convertible.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{change~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}}}
This replaces the occurrences of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}} in the current goal.
The term \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}} must be convertible.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{change~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~at~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}}}
This replaces the occurrences numbered \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}}}} of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}}
in the current goal. The terms \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}’}}} must be convertible.
\index{Too few occurrences (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.too-few-occurrences}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Too~few~occurrences.}}}}
\end{fulllineitems}


\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{change~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{at~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This applies the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.change}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change}}}}} tactic not to the goal but to the hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}



\sphinxstrong{See also:}


{\hyperref[\detokenize{proof-engine/tactics:performingcomputations}]{\sphinxcrossref{\DUrole{std,std-ref}{Performing computations}}}}



\end{fulllineitems}



\subsection{Performing computations}
\label{\detokenize{proof-engine/tactics:performing-computations}}\label{\detokenize{proof-engine/tactics:performingcomputations}}
This set of tactics implements different specialized usages of the
tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.change}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change}}}}}.

All conversion tactics (including {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.change}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{change}}}}}) can be parameterized by the
parts of the goal where the conversion can occur. This is done using
\sphinxstyleemphasis{goal clauses} which consists in a list of hypotheses and, optionally,
of a reference to the conclusion of the goal. For defined hypothesis
it is possible to specify if the conversion should occur on the type
part, the body part or both (default).

Goal clauses are written after a conversion tactic (tactics {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.set}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{set}}}}},
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.replace}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{replace}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.autorewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{autorewrite}}}}} also use goal
clauses) and are introduced by the keyword \sphinxtitleref{in}. If no goal clause is
provided, the default is to perform the conversion only in the
conclusion.

The syntax and description of the various goal clauses is the
following:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{\DUrole{notation}{in \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}} \textbar{}-}}}  only in hypotheses \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{notation}{in \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}} \textbar{}- *}}} in hypotheses \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}} and in the
conclusion

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{notation}{in * \textbar{}-}}} in every hypothesis

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{notation}{in *}}} (equivalent to in \sphinxcode{\sphinxupquote{\DUrole{notation}{* \textbar{}- *}}}) everywhere

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{notation}{in (type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}) (value of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}) ... \textbar{}-}}} in type part of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, in the value part of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}, etc.

\end{itemize}

For backward compatibility, the notation \sphinxcode{\sphinxupquote{\DUrole{notation}{in \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}} performs
the conversion in hypotheses \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}.
\index{cbv (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.cbv}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{cbv~\DUrole{repeat-wrapper}{\DUrole{repeat}{flag}\DUrole{notation-sup}{*}}}}}}
\end{fulllineitems}

\index{lazy (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.lazy}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{lazy~\DUrole{repeat-wrapper}{\DUrole{repeat}{flag}\DUrole{notation-sup}{*}}}}}}
\end{fulllineitems}

\index{compute (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.compute}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{compute}}}}
These parameterized reduction tactics apply to any goal and perform
the normalization of the goal according to the specified flags. In
correspondence with the kinds of reduction considered in Coq namely
\(\beta\) (reduction of functional application), \(\delta\)
(unfolding of transparent constants, see {\hyperref[\detokenize{proof-engine/vernacular-commands:vernac-controlling-the-reduction-strategies}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling the reduction strategies and the conversion algorithm}}}}),
\(\iota\) (reduction of
pattern matching over a constructed term, and unfolding of \sphinxcode{\sphinxupquote{\DUrole{keyword}{fix}}} and
\sphinxcode{\sphinxupquote{\DUrole{keyword}{cofix}}} expressions) and \(\zeta\) (contraction of local definitions), the
flags are either \sphinxcode{\sphinxupquote{beta}}, \sphinxcode{\sphinxupquote{delta}}, \sphinxcode{\sphinxupquote{match}}, \sphinxcode{\sphinxupquote{fix}}, \sphinxcode{\sphinxupquote{cofix}},
\sphinxcode{\sphinxupquote{iota}} or \sphinxcode{\sphinxupquote{zeta}}. The \sphinxcode{\sphinxupquote{iota}} flag is a shorthand for \sphinxcode{\sphinxupquote{match}}, \sphinxcode{\sphinxupquote{fix}}
and \sphinxcode{\sphinxupquote{cofix}}. The \sphinxcode{\sphinxupquote{delta}} flag itself can be refined into
\sphinxcode{\sphinxupquote{\DUrole{notation}{delta \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{delta -\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}, restricting in the first
case the constants to unfold to the constants listed, and restricting in the
second case the constant to unfold to all but the ones explicitly mentioned.
Notice that the \sphinxcode{\sphinxupquote{delta}} flag does not apply to variables bound by a let-in
construction inside the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} itself (use here the \sphinxcode{\sphinxupquote{zeta}} flag). In
any cases, opaque constants are not unfolded (see {\hyperref[\detokenize{proof-engine/vernacular-commands:vernac-controlling-the-reduction-strategies}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling the reduction strategies and the conversion algorithm}}}}).

Normalization according to the flags is done by first evaluating the
head of the expression into a \sphinxstyleemphasis{weak-head} normal form, i.e. until the
evaluation is blocked by a variable (or an opaque constant, or an
axiom), as e.g. in \sphinxcode{\sphinxupquote{\DUrole{name}{x} \DUrole{name}{u1} \DUrole{operator}{...} \DUrole{name}{un}}} , or \sphinxcode{\sphinxupquote{\DUrole{keyword}{match} \DUrole{name}{x} \DUrole{keyword}{with} \DUrole{operator}{...} \DUrole{keyword}{end}}}, or
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{keyword}{fix} \DUrole{name}{f} \DUrole{name}{x} \DUrole{operator}{\{}\DUrole{keyword}{struct} \DUrole{name}{x}\DUrole{operator}{\}} \DUrole{operator}{:=} \DUrole{operator}{...)} \DUrole{name}{x}}}, or is a constructed form (a
\(\lambda\)-expression, a constructor, a cofixpoint, an inductive type, a
product type, a sort), or is a redex that the flags prevent to reduce. Once a
weak-head normal form is obtained, subterms are recursively reduced using the
same strategy.

Reduction to weak-head normal form can be done using two strategies:
\sphinxstyleemphasis{lazy} (\sphinxcode{\sphinxupquote{lazy}} tactic), or \sphinxstyleemphasis{call-by-value} (\sphinxcode{\sphinxupquote{cbv}} tactic). The lazy
strategy is a call-by-need strategy, with sharing of reductions: the
arguments of a function call are weakly evaluated only when necessary,
and if an argument is used several times then it is weakly computed
only once. This reduction is efficient for reducing expressions with
dead code. For instance, the proofs of a proposition \sphinxcode{\sphinxupquote{\DUrole{keyword}{exists} \DUrole{name}{x}\DUrole{operator}{.} \DUrole{name}{P}\DUrole{operator}{(}\DUrole{name}{x}\DUrole{operator}{)}}}
reduce to a pair of a witness \sphinxcode{\sphinxupquote{\DUrole{name}{t}}}, and a proof that \sphinxcode{\sphinxupquote{\DUrole{name}{t}}} satisfies the
predicate \sphinxcode{\sphinxupquote{\DUrole{name}{P}}}. Most of the time, \sphinxcode{\sphinxupquote{\DUrole{name}{t}}} may be computed without computing
the proof of \sphinxcode{\sphinxupquote{\DUrole{name}{P}\DUrole{operator}{(}\DUrole{name}{t}\DUrole{operator}{)}}}, thanks to the lazy strategy.

The call-by-value strategy is the one used in ML languages: the
arguments of a function call are systematically weakly evaluated
first. Despite the lazy strategy always performs fewer reductions than
the call-by-value strategy, the latter is generally more efficient for
evaluating purely computational expressions (i.e. with little dead code).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{compute}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{cbv}}}}
These are synonyms for \sphinxcode{\sphinxupquote{cbv beta delta iota zeta}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{lazy}}}}
This is a synonym for \sphinxcode{\sphinxupquote{lazy beta delta iota zeta}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{compute~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{cbv~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
These are synonyms of \sphinxcode{\sphinxupquote{\DUrole{notation}{cbv beta delta \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}} iota zeta}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{compute~-\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{cbv~-\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
These are synonyms of \sphinxcode{\sphinxupquote{\DUrole{notation}{cbv beta delta -\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}} iota zeta}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{lazy~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{lazy~-\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
These are respectively synonyms of \sphinxcode{\sphinxupquote{\DUrole{notation}{lazy beta delta \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}} iota zeta}}}
and \sphinxcode{\sphinxupquote{\DUrole{notation}{lazy beta delta -\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}} iota zeta}}}.

\end{fulllineitems}

\index{vm\_compute (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.vm-compute}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{vm\_compute}}}}
This tactic evaluates the goal using the optimized call-by-value evaluation
bytecode-based virtual machine described in \sphinxcite{zebibliography:compiledstrongreduction}.
This algorithm is dramatically more efficient than the algorithm used for the
\sphinxcode{\sphinxupquote{cbv}} tactic, but it cannot be fine-tuned. It is specially interesting for
full evaluation of algebraic objects. This includes the case of
reflection-based tactics.

\end{fulllineitems}

\index{native\_compute (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.native-compute}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{native\_compute}}}}
This tactic evaluates the goal by compilation to Objective Caml as described
in \sphinxcite{zebibliography:fullreduction}. If Coq is running in native code, it can be
typically two to five times faster than \sphinxcode{\sphinxupquote{vm\_compute}}. Note however that the
compilation cost is higher, so it is worth using only for intensive
computations.
\index{NativeCompute Profiling (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.nativecompute-profiling}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{NativeCompute~Profiling}}}}
On Linux, if you have the \sphinxcode{\sphinxupquote{perf}} profiler installed, this option makes
it possible to profile \sphinxcode{\sphinxupquote{native\_compute}} evaluations.

\end{fulllineitems}

\index{NativeCompute Profile Filename (opt)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:opt.nativecompute-profile-filename}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{NativeCompute~Profile~Filename~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
This option specifies the profile output; the default is
\sphinxcode{\sphinxupquote{native\_compute\_profile.data}}. The actual filename used
will contain extra characters to avoid overwriting an existing file; that
filename is reported to the user.
That means you can individually profile multiple uses of
\sphinxcode{\sphinxupquote{native\_compute}} in a script. From the Linux command line, run \sphinxcode{\sphinxupquote{perf report}}
on the profile file to see the results. Consult the \sphinxcode{\sphinxupquote{perf}} documentation
for more details.

\end{fulllineitems}


\end{fulllineitems}

\index{Debug Cbv (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.debug-cbv}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Debug~Cbv}}}}
This option makes {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.cbv}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbv}}}}} (and its derivative {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{compute}}}}}) print
information about the constants it encounters and the unfolding decisions it
makes.

\end{fulllineitems}

\index{red (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.red}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{red}}}}
This tactic applies to a goal that has the form:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
forall (x:T1) ... (xk:Tk), T
\end{sphinxVerbatim}

with \sphinxcode{\sphinxupquote{\DUrole{name}{T}}} \(\beta\)\(\iota\)\(\zeta\)-reducing to \sphinxcode{\sphinxupquote{\DUrole{name}{c} \DUrole{name}{t}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{operator}{...} \DUrole{name}{t}}}$_{\text{n}}$ and \sphinxcode{\sphinxupquote{\DUrole{name}{c}}} a
constant. If \sphinxcode{\sphinxupquote{\DUrole{name}{c}}} is transparent then it replaces \sphinxcode{\sphinxupquote{\DUrole{name}{c}}} with its
definition (say \sphinxcode{\sphinxupquote{\DUrole{name}{t}}}) and then reduces
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{t} \DUrole{name}{t}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{operator}{...} \DUrole{name}{t}}}$_{\text{n}}$ \sphinxcode{\sphinxupquote{\DUrole{operator}{)}}} according to \(\beta\)\(\iota\)\(\zeta\)-reduction rules.

\end{fulllineitems}

\index{Not reducible (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-reducible}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~reducible.}}}}
\end{fulllineitems}

\index{No head constant to reduce (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.no-head-constant-to-reduce}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~head~constant~to~reduce.}}}}
\end{fulllineitems}

\index{hnf (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.hnf}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{hnf}}}}
This tactic applies to any goal. It replaces the current goal with its
head normal form according to the \(\beta\)\(\delta\)\(\iota\)\(\zeta\)-reduction rules, i.e. it
reduces the head of the goal until it becomes a product or an
irreducible term. All inner \(\beta\)\(\iota\)-redexes are also reduced.

Example: The term \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{name}{n} \DUrole{operator}{:} \DUrole{keyword,type}{nat} \DUrole{operator}{=\textgreater{}} \DUrole{name}{S} \DUrole{name}{n} \DUrole{operator}{+} \DUrole{name}{S} \DUrole{name}{n}}} is not reduced by \sphinxcode{\sphinxupquote{\DUrole{notation}{hnf}}}.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}
The \(\delta\) rule only applies to transparent constants (see {\hyperref[\detokenize{proof-engine/vernacular-commands:vernac-controlling-the-reduction-strategies}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling the reduction strategies and the conversion algorithm}}}}
on transparency and opacity).
\end{sphinxadmonition}
\index{cbn (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.cbn}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{cbn}}}}
\end{fulllineitems}

\index{simpl (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.simpl}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{simpl}}}}
These tactics apply to any goal. They try to reduce a term to
something still readable instead of fully normalizing it. They perform
a sort of strong normalization with two key differences:
\begin{itemize}
\item {} 
They unfold a constant if and only if it leads to a \(\iota\)-reduction,
i.e. reducing a match or unfolding a fixpoint.

\item {} 
While reducing a constant unfolding to (co)fixpoints, the tactics
use the name of the constant the (co)fixpoint comes from instead of
the (co)fixpoint definition in recursive calls.

\end{itemize}

The \sphinxcode{\sphinxupquote{cbn}} tactic is claimed to be a more principled, faster and more
predictable replacement for \sphinxcode{\sphinxupquote{simpl}}.

The \sphinxcode{\sphinxupquote{cbn}} tactic accepts the same flags as \sphinxcode{\sphinxupquote{cbv}} and \sphinxcode{\sphinxupquote{lazy}}. The
behavior of both \sphinxcode{\sphinxupquote{simpl}} and \sphinxcode{\sphinxupquote{cbn}} can be tuned using the
Arguments vernacular command as follows:
\begin{itemize}
\item {} 
A constant can be marked to be never unfolded by \sphinxcode{\sphinxupquote{cbn}} or \sphinxcode{\sphinxupquote{simpl}}:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Arguments} \PYG{n}{minus} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k}{simpl} \PYG{n}{never}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

After that command an expression like \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{minus} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{x}\DUrole{operator}{)} \DUrole{name}{y}\DUrole{operator}{)}}} is left
untouched by the tactics \sphinxcode{\sphinxupquote{cbn}} and \sphinxcode{\sphinxupquote{simpl}}.

\item {} 
A constant can be marked to be unfolded only if applied to enough
arguments. The number of arguments required can be specified using the
\sphinxcode{\sphinxupquote{/}} symbol in the argument list of the {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}} vernacular command.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{fcomp} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C} \PYG{n}{f} \PYG{o}{(}\PYG{n}{g} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{n}{C} \PYG{o}{:=} \PYG{n}{f} \PYG{o}{(}\PYG{n}{g} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{fcomp} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Arguments} \PYG{n}{fcomp} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{n}{B} \PYG{n}{C}\PYG{o}{\PYGZcb{}} \PYG{n}{f} \PYG{n}{g} \PYG{n}{x} \PYG{o}{/.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{f \PYGZbs{}o g}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{fcomp} \PYG{n}{f} \PYG{n}{g}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{50}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

After that command the expression \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{f} \DUrole{error}{\textbackslash{}}\DUrole{name}{o} \DUrole{name}{g}\DUrole{operator}{)}}} is left untouched by
\sphinxcode{\sphinxupquote{simpl}} while \sphinxcode{\sphinxupquote{\DUrole{operator}{((}\DUrole{name}{f} \DUrole{error}{\textbackslash{}}\DUrole{name}{o} \DUrole{name}{g}\DUrole{operator}{)} \DUrole{name}{t}\DUrole{operator}{)}}} is reduced to \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{f} \DUrole{operator}{(}\DUrole{name}{g} \DUrole{name}{t}\DUrole{operator}{))}}}.
The same mechanism can be used to make a constant volatile, i.e.
always unfolded.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{volatile} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}\PYG{o}{.}
    \PYG{n}{volatile} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Arguments} \PYG{n}{volatile} \PYG{o}{/} \PYG{n}{x}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\item {} 
A constant can be marked to be unfolded only if an entire set of
arguments evaluates to a constructor. The \sphinxcode{\sphinxupquote{!}} symbol can be used to mark
such arguments.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Arguments} \PYG{n}{minus} \PYG{o}{!}\PYG{n}{n} \PYG{o}{!}\PYG{n}{m}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

After that command, the expression \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{minus} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{x}\DUrole{operator}{)} \DUrole{name}{y}\DUrole{operator}{)}}} is left untouched
by \sphinxcode{\sphinxupquote{simpl}}, while \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{minus} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{x}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{y}\DUrole{operator}{))}}} is reduced to \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{minus} \DUrole{name}{x} \DUrole{name}{y}\DUrole{operator}{)}}}.

\item {} 
A special heuristic to determine if a constant has to be unfolded
can be activated with the following command:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Arguments} \PYG{n}{minus} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k}{simpl} \PYG{n}{nomatch}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The heuristic avoids to perform a simplification step that would expose a
match construct in head position. For example the expression
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{minus} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{x}\DUrole{operator}{))} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{y}\DUrole{operator}{))}}} is simplified to \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{minus} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{x}\DUrole{operator}{)} \DUrole{name}{y}\DUrole{operator}{)}}}
even if an extra simplification is possible.

\end{itemize}

In detail, the tactic \sphinxcode{\sphinxupquote{simpl}} first applies \(\beta\)\(\iota\)-reduction. Then, it
expands transparent constants and tries to reduce further using \(\beta\)\(\iota\)-
reduction. But, when no \(\iota\) rule is applied after unfolding then
\(\delta\)-reductions are not applied. For instance trying to use \sphinxcode{\sphinxupquote{simpl}} on
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{plus} \DUrole{name}{n} \DUrole{name}{O}\DUrole{operator}{)} \DUrole{operator}{=} \DUrole{name}{n}}} changes nothing.

Notice that only transparent constants whose name can be reused in the
recursive calls are possibly unfolded by \sphinxcode{\sphinxupquote{simpl}}. For instance a
constant defined by \sphinxcode{\sphinxupquote{\DUrole{name}{plus'} \DUrole{operator}{:=} \DUrole{name}{plus}}} is possibly unfolded and reused in
the recursive calls, but a constant such as \sphinxcode{\sphinxupquote{\DUrole{name}{succ} \DUrole{operator}{:=} \DUrole{name}{plus} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{O}\DUrole{operator}{)}}} is
never unfolded. This is the main difference between \sphinxcode{\sphinxupquote{simpl}} and \sphinxcode{\sphinxupquote{cbn}}.
The tactic \sphinxcode{\sphinxupquote{cbn}} reduces whenever it will be able to reuse it or not:
\sphinxcode{\sphinxupquote{\DUrole{name}{succ} \DUrole{name}{t}}} is reduced to \sphinxcode{\sphinxupquote{\DUrole{name}{S} \DUrole{name}{t}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{cbn~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{cbn~-\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
These are respectively synonyms of \sphinxcode{\sphinxupquote{\DUrole{notation}{cbn beta delta \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}} iota zeta}}}
and \sphinxcode{\sphinxupquote{\DUrole{notation}{cbn beta delta -\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}} iota zeta}}} (see {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.cbn}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbn}}}}}).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simpl~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}}}
This applies \sphinxcode{\sphinxupquote{simpl}} only to the subterms matching \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}} in the
current goal.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simpl~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}~at~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}}}}}
This applies \sphinxcode{\sphinxupquote{simpl}} only to the \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}}}} occurrences of the subterms
matching \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}} in the current goal.
\index{Too few occurrences (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Too~few~occurrences.}}}}
\end{fulllineitems}


\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simpl~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simpl~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
This applies \sphinxcode{\sphinxupquote{simpl}} only to the applicative subterms whose head occurrence
is the unfoldable constant \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} (the constant can be referred to by
its notation using \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} if such a notation exists).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simpl~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~at~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simpl~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~at~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}}}}}
This applies \sphinxcode{\sphinxupquote{simpl}} only to the \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}}}} applicative subterms whose
head occurrence is \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} (or \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}).

\end{fulllineitems}

\index{Debug RAKAM (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.debug-rakam}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Debug~RAKAM}}}}
This option makes {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.cbn}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbn}}}}} print various debugging information.
\sphinxcode{\sphinxupquote{RAKAM}} is the Refolding Algebraic Krivine Abstract Machine.

\end{fulllineitems}

\index{unfold (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.unfold}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{unfold~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This tactic applies to any goal. The argument qualid must denote a
defined transparent constant or local definition (see
{\hyperref[\detokenize{language/gallina-specification-language:gallina-definitions}]{\sphinxcrossref{\DUrole{std,std-ref}{Definitions}}}} and {\hyperref[\detokenize{proof-engine/vernacular-commands:vernac-controlling-the-reduction-strategies}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling the reduction strategies and the conversion algorithm}}}}). The tactic
\sphinxcode{\sphinxupquote{unfold}} applies the \(\delta\) rule to each occurrence of the constant to which
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} refers in the current goal and then replaces it with its
\(\beta\)\(\iota\)-normal form.

\end{fulllineitems}

\index{‘qualid’ does not denote an evaluable constant (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.qualid-does-not-denote-an-evaluable-constant}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~does~not~denote~an~evaluable~constant.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{unfold~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Replaces \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} in hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} with its definition
and replaces the hypothesis with its \(\beta\)\(\iota\) normal form.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{unfold~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
Replaces \sphinxstyleemphasis{simultaneously} \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}} with their definitions and
replaces the current goal with its \(\beta\)\(\iota\) normal form.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{unfold~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~at~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
The lists \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}} specify the occurrences of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} to be
unfolded. Occurrences are located from left to right.
\index{Bad occurrence number of ‘qualid’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.bad-occurrence-number-of-qualid}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Bad~occurrence~number~of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}.}}}}
\end{fulllineitems}

\index{‘qualid’ does not occur (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.qualid-does-not-occur}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~does~not~occur.}}}}
\end{fulllineitems}


\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{unfold~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} denotes the discriminating symbol of a notation (e.g. "+") or
an expression defining a notation (e.g. \sphinxtitleref{"\_ + \_"}), and this notation refers to an unfoldable constant, then the
tactic unfolds it.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{unfold~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}\%key}}}}
This is variant of \sphinxcode{\sphinxupquote{\DUrole{notation}{unfold {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} gets its
interpretation from the scope bound to the delimiting key \sphinxcode{\sphinxupquote{\DUrole{notation}{key}}}
instead of its default interpretation (see {\hyperref[\detokenize{user-extensions/syntax-extensions:localinterpretationrulesfornotations}]{\sphinxcrossref{\DUrole{std,std-ref}{Local interpretation rules for notations}}}}).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{unfold~\DUrole{repeat-wrapper}{\DUrole{repeat}{qualid\_or\_string~at~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
This is the most general form, where \sphinxcode{\sphinxupquote{\DUrole{notation}{qualid\_or\_string}}} is either a
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} or a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} referring to a notation.

\end{fulllineitems}

\index{fold (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.fold}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{fold~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic applies to any goal. The term \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is reduced using the
\sphinxcode{\sphinxupquote{red}} tactic. Every occurrence of the resulting \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} in the goal is
then replaced by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{fold~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}}}
Equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{fold {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} ; ... ; fold {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}

\index{pattern (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.pattern}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{pattern~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This command applies to any goal. The argument \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} must be a free
subterm of the current goal. The command pattern performs \(\beta\)-expansion
(the inverse of \(\beta\)-reduction) of the current goal (say \sphinxcode{\sphinxupquote{\DUrole{name}{T}}}) by
\begin{itemize}
\item {} 
replacing all occurrences of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} in \sphinxcode{\sphinxupquote{\DUrole{name}{T}}} with a fresh variable

\item {} 
abstracting this variable

\item {} 
applying the abstracted goal to \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}

\end{itemize}

For instance, if the current goal \sphinxcode{\sphinxupquote{\DUrole{name}{T}}} is expressible as
\(\varphi\)\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{t}\DUrole{operator}{)}}} where the notation captures all the instances of \sphinxcode{\sphinxupquote{\DUrole{name}{t}}}
in \(\varphi\)\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{t}\DUrole{operator}{)}}}, then \sphinxcode{\sphinxupquote{\DUrole{notation}{pattern t}}} transforms it into
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{keyword}{fun} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A} \DUrole{operator}{=\textgreater{}}}} \(\varphi\)\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{x}\DUrole{operator}{))} \DUrole{name}{t}}}. This tactic can be used, for
instance, when the tactic \sphinxcode{\sphinxupquote{apply}} fails on matching.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pattern~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~at~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}}}}}
Only the occurrences \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}}}} of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} are considered for
\(\beta\)-expansion. Occurrences are located from left to right.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pattern~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~at~-~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}}}}}
All occurrences except the occurrences of indexes \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}}}}
of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} are considered for \(\beta\)-expansion. Occurrences are located from
left to right.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pattern~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
Starting from a goal \(\varphi\)\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{t}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{operator}{...} \DUrole{name}{t}}}$_{\text{m}}$\sphinxcode{\sphinxupquote{\DUrole{operator}{)}}},
the tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{pattern t}}}$_{\text{1}}$\sphinxcode{\sphinxupquote{\DUrole{notation}{, ..., t}}}$_{\text{m}}$ generates the
equivalent goal
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{keyword}{fun} \DUrole{operator}{(}\DUrole{name}{x}}}$_{\text{1}}$\sphinxcode{\sphinxupquote{\DUrole{operator}{:}\DUrole{name}{A}}}$_{\text{1}}$\sphinxcode{\sphinxupquote{\DUrole{operator}{)} \DUrole{operator}{...} \DUrole{operator}{(}\DUrole{name}{x}}}$_{\text{m}}$ \sphinxcode{\sphinxupquote{\DUrole{operator}{:}\DUrole{name}{A}}}$_{\text{m}}$ \sphinxcode{\sphinxupquote{\DUrole{operator}{)} \DUrole{operator}{=\textgreater{}}}}\(\varphi\)\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{x}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{operator}{...} \DUrole{name}{x}}}$_{\text{m}}$ \sphinxcode{\sphinxupquote{\DUrole{operator}{))} \DUrole{name}{t}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{operator}{...} \DUrole{name}{t}}}$_{\text{m}}$.
If \sphinxcode{\sphinxupquote{\DUrole{name}{t}}}$_{\text{i}}$ occurs in one of the generated types \sphinxcode{\sphinxupquote{\DUrole{name}{A}}}$_{\text{j}}$ these
occurrences will also be considered and possibly abstracted.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pattern~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~at~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
This behaves as above but processing only the occurrences \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}}}}} of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} starting from \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pattern~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{at~\DUrole{repeat-wrapper}{\DUrole{repeat}{-}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
This is the most general syntax that combines the different variants.

\end{fulllineitems}



\subsubsection{Conversion tactics applied to hypotheses}
\label{\detokenize{proof-engine/tactics:conversion-tactics-applied-to-hypotheses}}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{conv\_tactic~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
Applies the conversion tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{conv\_tactic}}} to the hypotheses
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}. The tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{conv\_tactic}}} is any of the conversion tactics
listed in this section.

If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is a local definition, then \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} can be replaced by
(type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}) to address not the body but the type of the local
definition.

Example: \sphinxcode{\sphinxupquote{\DUrole{notation}{unfold not in (type of H1) (type of H3)}}}.

\end{fulllineitems}

\index{No such hypothesis: ‘ident’ (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~hypothesis:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}



\subsection{Automation}
\label{\detokenize{proof-engine/tactics:automation}}\label{\detokenize{proof-engine/tactics:id10}}\index{auto (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.auto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{auto}}}}
\end{fulllineitems}


This tactic implements a Prolog-like resolution procedure to solve the
current goal. It first tries to solve the goal using the assumption
tactic, then it reduces the goal to an atomic one using intros and
introduces the newly generated hypotheses as hints. Then it looks at
the list of tactics associated to the head symbol of the goal and
tries to apply one of them (starting from the tactics with lower
cost). This process is recursively applied to the generated subgoals.

By default, auto only uses the hypotheses of the current goal and the
hints of the database named core.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{auto~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
Forces the search depth to be \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}. The maximal search depth
is \sphinxtitleref{5} by default.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{auto~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
Uses the hint databases \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}} in addition to the database core. See
{\hyperref[\detokenize{proof-engine/tactics:thehintsdatabasesforautoandeauto}]{\sphinxcrossref{\DUrole{std,std-ref}{The Hints Databases for auto and eauto}}}} for the list of
pre-defined databases and the way to create or extend a database.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{auto~with~*}}}}
Uses all existing hint databases. See
{\hyperref[\detokenize{proof-engine/tactics:thehintsdatabasesforautoandeauto}]{\sphinxcrossref{\DUrole{std,std-ref}{The Hints Databases for auto and eauto}}}}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{auto~using~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-lemma}]{\sphinxcrossref{\DUrole{hole}{lemma}}}}}\DUrole{notation-sup}{+}}}}}}
Uses \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-lemma}]{\sphinxcrossref{\DUrole{hole}{lemma}}}}}\DUrole{notation-sup}{+}}}}} in addition to hints (can be combined with the with
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} option).  If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-lemma}]{\sphinxcrossref{\DUrole{hole}{lemma}}}}}}} is an inductive type, it is the
collection of its constructors which is added as hints.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{info\_auto}}}}
Behaves like auto but shows the tactics it uses to solve the goal. This
variant is very useful for getting a better understanding of automation, or
to know what lemmas/assumptions were used.

\end{fulllineitems}

\index{debug auto (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.debug-auto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{debug~auto}}}}
Behaves like {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} but shows the tactics it tries to solve the goal,
including failing paths.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{info\_}\DUrole{notation-sup}{?}}auto~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-lemma}]{\sphinxcrossref{\DUrole{hole}{lemma}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
This is the most general form, combining the various options.

\end{fulllineitems}

\index{trivial (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.trivial}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{trivial}}}}
This tactic is a restriction of auto that is not recursive
and tries only hints that cost \sphinxtitleref{0}. Typically it solves trivial
equalities like \sphinxcode{\sphinxupquote{\DUrole{name}{X}\DUrole{operator}{=}\DUrole{name}{X}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{trivial~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{trivial~with~*}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{trivial~using~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-lemma}]{\sphinxcrossref{\DUrole{hole}{lemma}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}

\index{debug trivial (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.debug-trivial}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{debug~trivial}}}}
\end{fulllineitems}

\index{info\_trivial (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.info-trivial}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{info\_trivial}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{info\_}\DUrole{notation-sup}{?}}trivial~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-lemma}]{\sphinxcrossref{\DUrole{hole}{lemma}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} either solves completely the goal or else leaves it
intact. {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.trivial}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{trivial}}}}} never fail.
\end{sphinxadmonition}

The following options enable printing of informative or debug information for
the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.trivial}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{trivial}}}}} tactics:
\index{Info Auto (flag)}\index{Debug Auto (flag)}\index{Info Trivial (flag)}\index{Debug Trivial (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.info-auto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Info~Auto}}}}\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.debug-auto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Debug~Auto}}}}\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.info-trivial}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Info~Trivial}}}}\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.debug-trivial}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Debug~Trivial}}}}
\end{fulllineitems}



\sphinxstrong{See also:}


{\hyperref[\detokenize{proof-engine/tactics:thehintsdatabasesforautoandeauto}]{\sphinxcrossref{\DUrole{std,std-ref}{The Hints Databases for auto and eauto}}}}


\index{eauto (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.eauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{eauto}}}}
\end{fulllineitems}


This tactic generalizes {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}. While {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} does not try
resolution hints which would leave existential variables in the goal,
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}} does try them (informally speaking, it usessimple {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eapply}}}}}
where {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} uses simple {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}}). As a consequence, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}}
can solve such a goal:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Hint} \PYG{k+kn}{Resolve} \PYG{n}{ex\PYGZus{}intro}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{hint} \PYG{n}{ex\PYGZus{}intro} \PYG{n}{will} \PYG{n}{only} \PYG{n}{be} \PYG{n}{used} \PYG{k+kp}{by} \PYG{k}{eauto}\PYG{o}{,} \PYG{n}{because} \PYG{n}{applying} \PYG{n}{ex\PYGZus{}intro} \PYG{n}{would}
    \PYG{n}{leave} \PYG{n}{variable} \PYG{n}{x} \PYG{k}{as} \PYG{n}{unresolved} \PYG{n}{existential} \PYG{n}{variable}\PYG{o}{.}

\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{P}\PYG{o}{:}\PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{P} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{exists} \PYG{n}{n}\PYG{o}{,} \PYG{n}{P} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{P} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{exists} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{P} \PYG{n}{n}

\PYG{k}{eauto}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Note that \sphinxcode{\sphinxupquote{ex\_intro}} should be declared as a hint.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{info\_}\DUrole{notation-sup}{?}}eauto~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-lemma}]{\sphinxcrossref{\DUrole{hole}{lemma}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
The various options for eauto are the same as for auto.

\end{fulllineitems}


{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}} also obeys the following options:
\index{Info Eauto (flag)}\index{Debug Eauto (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.info-eauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Info~Eauto}}}}\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.debug-eauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Debug~Eauto}}}}
\end{fulllineitems}



\sphinxstrong{See also:}


{\hyperref[\detokenize{proof-engine/tactics:thehintsdatabasesforautoandeauto}]{\sphinxcrossref{\DUrole{std,std-ref}{The Hints Databases for auto and eauto}}}}


\index{autounfold (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.autounfold}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{autounfold~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}


This tactic unfolds constants that were declared through a \sphinxcode{\sphinxupquote{Hint Unfold}}
in the given databases.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{autounfold~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~in~clause}}}}
Performs the unfolding in the given clause.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{autounfold~with~*}}}}
Uses the unfold hints declared in all the hint databases.

\end{fulllineitems}

\index{autorewrite (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.autorewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{autorewrite~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}


This tactic %
\begin{footnote}[4]\sphinxAtStartFootnote
The behavior of this tactic has changed a lot compared to the
versions available in the previous distributions (V6). This may cause
significant changes in your theories to obtain the same result. As a
drawback of the re-engineering of the code, this tactic has also been
completely revised to get a very compact and readable version.
%
\end{footnote} carries out rewritings according to the rewriting rule
bases \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}.

Each rewriting rule from the base \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is applied to the main subgoal until
it fails. Once all the rules have been processed, if the main subgoal has
progressed (e.g., if it is distinct from the initial main goal) then the rules
of this base are processed again. If the main subgoal has not progressed then
the next base is processed. For the bases, the behavior is exactly similar to
the processing of the rewriting rules.

The rewriting rule bases are built with the \sphinxcode{\sphinxupquote{Hint Rewrite vernacular}}
command.

\begin{sphinxadmonition}{warning}{Warning:}
This tactic may loop if you build non terminating rewriting systems.
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{autorewrite~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~using~\DUrole{hole}{tactic}}}}}
Performs, in the same way, all the rewritings of the bases \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}
applying tactic to the main subgoal after each rewriting step.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{autorewrite~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
Performs all the rewritings in hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{autorewrite~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~using~\DUrole{hole}{tactic}}}}}
Performs all the rewritings in hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} applying \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic}}}}
to the main subgoal after each rewriting step.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{autorewrite~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~in~\DUrole{hole}{clause}}}}}
Performs all the rewriting in the clause \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{clause}}}}. The clause argument
must not contain any \sphinxcode{\sphinxupquote{type of}} nor \sphinxcode{\sphinxupquote{value of}}.

\end{fulllineitems}



\sphinxstrong{See also:}


{\hyperref[\detokenize{proof-engine/tactics:hintrewrite}]{\sphinxcrossref{\DUrole{std,std-ref}{Hint-Rewrite}}}} for feeding the database of lemmas used by
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.autorewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{autorewrite}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.autorewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{autorewrite}}}}} for examples showing the use of this tactic.


\index{easy (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.easy}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{easy}}}}
This tactic tries to solve the current goal by a number of standard closing steps.
In particular, it tries to close the current goal using the closing tactics
{\hyperref[\detokenize{proof-engine/tactics:coq:tacv.trivial}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{trivial}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.reflexivity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reflexivity}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.symmetry}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{symmetry}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.contradiction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{contradiction}}}}}
and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion}}}}} of hypothesis.
If this fails, it tries introducing variables and splitting and-hypotheses,
using the closing tactics afterwards, and splitting the goal using
{\hyperref[\detokenize{proof-engine/tactics:coq:tacv.split}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{split}}}}} and recursing.

This tactic solves goals that belong to many common classes; in particular, many cases of
unsatisfiable hypotheses, and simple equality goals are usually solved by this tactic.

\end{fulllineitems}

\index{now (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.now}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{now~\DUrole{hole}{tactic}}}}}
Run \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic}}}} followed by {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.easy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{easy}}}}}. This is a notation for \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic}; easy}}}.

\end{fulllineitems}



\subsection{Controlling automation}
\label{\detokenize{proof-engine/tactics:controlling-automation}}

\subsubsection{The hints databases for auto and eauto}
\label{\detokenize{proof-engine/tactics:the-hints-databases-for-auto-and-eauto}}\label{\detokenize{proof-engine/tactics:thehintsdatabasesforautoandeauto}}
The hints for {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}} are stored in databases. Each database
maps head symbols to a list of hints.
\index{Print Hint (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmd.print-hint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Hint~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Use this command
to display the hints associated to the head symbol \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}
(see {\hyperref[\detokenize{proof-engine/tactics:printhint}]{\sphinxcrossref{\DUrole{std,std-ref}{Print Hint}}}}). Each hint has a cost that is a nonnegative
integer, and an optional pattern. The hints with lower cost are tried first. A
hint is tried by {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} when the conclusion of the current goal matches its
pattern or when it has no pattern.

\end{fulllineitems}



\paragraph{Creating Hint databases}
\label{\detokenize{proof-engine/tactics:creating-hint-databases}}
One can optionally declare a hint database using the command
{\hyperref[\detokenize{proof-engine/tactics:coq:cmd.create-hintdb}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Create HintDb}}}}}. If a hint is added to an unknown database, it will be
automatically created.
\index{Create HintDb (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmd.create-hintdb}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Create~HintDb~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{discriminated}\DUrole{notation-sup}{?}}}}}}
This command creates a new database named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}. The database is
implemented by a Discrimination Tree (DT) that serves as an index of
all the lemmas. The DT can use transparency information to decide if a
constant should be indexed or not
(c.f. {\hyperref[\detokenize{proof-engine/tactics:thehintsdatabasesforautoandeauto}]{\sphinxcrossref{\DUrole{std,std-ref}{The hints databases for auto and eauto}}}}),
making the retrieval more efficient. The legacy implementation (the default one
for new databases) uses the DT only on goals without existentials (i.e., {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}
goals), for non-Immediate hints and does not make use of transparency
hints, putting more work on the unification that is run after
retrieval (it keeps a list of the lemmas in case the DT is not used).
The new implementation enabled by the discriminated option makes use
of DTs in all cases and takes transparency information into account.
However, the order in which hints are retrieved from the DT may differ
from the order in which they were inserted, making this implementation
observationally different from the legacy one.

\end{fulllineitems}


The general command to add a hint to some databases \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}} is
\index{Hint (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmd.hint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~\DUrole{hole}{hint\_definition}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}~

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~\DUrole{hole}{hint\_definition}}}}}
No database name is given: the hint is registered in the core database.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Hint~\DUrole{hole}{hint\_definition}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This is used to declare hints that must not be exported to the other modules
that require and import the current module. Inside a section, the option
Local is useless since hints do not survive anyway to the closure of
sections.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Hint~\DUrole{hole}{hint\_definition}}}}}
Idem for the core database.

\end{fulllineitems}

\index{Hint Resolve (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmdv.hint-resolve}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Resolve~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{?}}}}}}
This command adds \sphinxcode{\sphinxupquote{\DUrole{notation}{simple apply {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} to the hint list with the head
symbol of the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. The cost of that hint is the number of
subgoals generated by \sphinxcode{\sphinxupquote{\DUrole{notation}{simple apply {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} if specified. The
associated \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}} is inferred from the conclusion of the type of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} or the given \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}} if specified. In case the inferred type
of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} does not start with a product the tactic added in the hint list
is \sphinxcode{\sphinxupquote{\DUrole{notation}{exact {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}. In case this type can however be reduced to a type
starting with a product, the tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{simple apply {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is also stored in
the hints list. If the inferred type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} contains a dependent
quantification on a variable which occurs only in the premisses of the type
and not in its conclusion, no instance could be inferred for the variable by
unification with the goal. In this case, the hint is added to the hint list
of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}} instead of the hint list of auto and a warning is printed. A
typical example of a hint that is used only by {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}} is a transitivity
lemma.

\end{fulllineitems}

\index{‘term’ cannot be used as a hint (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.term-cannot-be-used-as-a-hint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~cannot~be~used~as~a~hint}}}}
The head symbol of the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is a bound variable such that
this tactic cannot be associated to a constant.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Resolve~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}}}
Adds each \sphinxcode{\sphinxupquote{\DUrole{notation}{Hint Resolve {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Resolve~-\textgreater{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Adds the left-to-right implication of an equivalence as a hint (informally
the hint will be used as \sphinxcode{\sphinxupquote{\DUrole{notation}{apply \textless{}- {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, although as mentionned
before, the tactic actually used is a restricted version of
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}}).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Resolve~\textless{}-~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Adds the right-to-left implication of an equivalence  as a hint.

\end{fulllineitems}

\index{Hint Immediate (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmdv.hint-immediate}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Immediate~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This command adds \sphinxcode{\sphinxupquote{\DUrole{notation}{simple apply {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}; trivial}}} to the hint list associated
with the head symbol of the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} in the given database. This
tactic will fail if all the subgoals generated by \sphinxcode{\sphinxupquote{\DUrole{notation}{simple apply {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} are
not solved immediately by the {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.trivial}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{trivial}}}}} tactic (which only tries tactics
with cost 0).This command is useful for theorems such as the symmetry of
equality or \sphinxcode{\sphinxupquote{\DUrole{name}{n}\DUrole{operator}{+}\DUrole{literal,number,integer}{1}\DUrole{operator}{=}\DUrole{name}{m}\DUrole{operator}{+}\DUrole{literal,number,integer}{1} \DUrole{operator}{-\textgreater{}} \DUrole{name}{n}\DUrole{operator}{=}\DUrole{name}{m}}} that we may like to introduce with a limited
use in order to avoid useless proof-search. The cost of this tactic (which
never generates subgoals) is always 1, so that it is not used by {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.trivial}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{trivial}}}}}
itself.

\end{fulllineitems}

\index{‘term’ cannot be used as a hint (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~cannot~be~used~as~a~hint}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Immediate~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}}}
Adds each \sphinxcode{\sphinxupquote{\DUrole{notation}{Hint Immediate {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}

\index{Hint Constructors (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmdv.hint-constructors}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Constructors~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is an inductive type, this command adds all its constructors as
hints of type \sphinxcode{\sphinxupquote{Resolve}}. Then, when the conclusion of current goal has the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} ...)}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} will try to apply each constructor.

\end{fulllineitems}

\index{‘ident’ is not an inductive type (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.ident-is-not-an-inductive-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~is~not~an~inductive~type}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Constructors~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
Adds each \sphinxcode{\sphinxupquote{\DUrole{notation}{Hint Constructors {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}

\index{Hint Unfold (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmdv.hint-unfold}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Unfold~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This adds the tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{unfold {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} to the hint list that will only be
used when the head constant of the goal is \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.
Its cost is 4.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Unfold~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
Adds each \sphinxcode{\sphinxupquote{\DUrole{notation}{Hint Unfold {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}

\index{Hint ( Transparent \textbar{} Opaque ) (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmdv.hint-transparent-opaque}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~\DUrole{meta}{(}~Transparent~\DUrole{meta}{\textbar{}}~Opaque~\DUrole{meta}{)}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
This adds a transparency hint to the database, making \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} a
transparent or opaque constant during resolution. This information is used
during unification of the goal with any lemma in the database and inside the
discrimination network to relax or constrain it in the case of discriminated
databases.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~\DUrole{meta}{(}~Transparent~\DUrole{meta}{\textbar{}}~Opaque~\DUrole{meta}{)}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
Declares each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} as a transparent or opaque constant.

\end{fulllineitems}

\index{Hint Extern (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmdv.hint-extern}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Extern~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}\DUrole{notation-sup}{?}}~=\textgreater{}~\DUrole{hole}{tactic}}}}}
This hint type is to extend {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} with tactics other than {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.apply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply}}}}} and
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unfold}}}}}. For that, we must specify a cost, an optional \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}} and a
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic}}}} to execute.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Hint} \PYG{n}{Extern} \PYG{l+m+mi}{4} \PYG{o}{(}\PYG{o}{\PYGZti{}}\PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{=} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{k+kp}{discriminate}\PYG{o}{.}
\end{sphinxVerbatim}

Now, when the head of the goal is a disequality, \sphinxcode{\sphinxupquote{auto}} will try
discriminate if it does not manage to solve the goal with hints with a
cost less than 4.
\end{sphinxadmonition}

One can even use some sub-patterns of the pattern in
the tactic script. A sub-pattern is a question mark followed by an
identifier, like \sphinxcode{\sphinxupquote{?X1}} or \sphinxcode{\sphinxupquote{?X2}}. Here is an example:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{List}\PYG{o}{.}
\PYG{k+kn}{Hint} \PYG{n}{Extern} \PYG{l+m+mi}{5} \PYG{o}{(}\PYG{o}{\PYGZob{}}\PYG{o}{?}\PYG{n}{X1} \PYG{o}{=} \PYG{o}{?}\PYG{n}{X2}\PYG{o}{\PYGZcb{}} \PYG{o}{+} \PYG{o}{\PYGZob{}}\PYG{o}{?}\PYG{n}{X1} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{o}{?}\PYG{n}{X2}\PYG{o}{\PYGZcb{}}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{k}{generalize}  \PYG{n}{X1}\PYG{o}{,} \PYG{n}{X2}\PYG{o}{;} \PYG{n}{decide} \PYG{n}{equality} \PYG{o}{:} \PYG{n}{eqdec}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b}\PYG{o}{:}\PYG{k+kt}{list} \PYG{o}{(}\PYG{k+kt}{nat} \PYG{o}{*} \PYG{k+kt}{nat}\PYG{o}{)}\PYG{o}{,} \PYG{o}{\PYGZob{}}\PYG{n}{a} \PYG{o}{=} \PYG{n}{b}\PYG{o}{\PYGZcb{}} \PYG{o}{+} \PYG{o}{\PYGZob{}}\PYG{n}{a} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{b}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{list} \PYG{o}{(}\PYG{k+kt}{nat} \PYG{o}{*} \PYG{k+kt}{nat}\PYG{o}{)}\PYG{o}{,} \PYG{o}{\PYGZob{}}\PYG{n}{a} \PYG{o}{=} \PYG{n}{b}\PYG{o}{\PYGZcb{}} \PYG{o}{+} \PYG{o}{\PYGZob{}}\PYG{n}{a} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{b}\PYG{o}{\PYGZcb{}}

\PYG{n}{Info} \PYG{l+m+mi}{1} \PYG{k}{auto} \PYG{k}{with} \PYG{n}{eqdec}\PYG{o}{.}
    \PYG{o}{\PYGZlt{}}\PYG{n}{ltac\PYGZus{}plugin}\PYG{o}{::}\PYG{k}{auto}\PYG{o}{@}\PYG{l+m+mi}{0}\PYG{o}{\PYGZgt{}} \PYG{n}{eqdec}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Cut~\DUrole{hole}{regexp}}}}}~
\begin{sphinxadmonition}{warning}{Warning:}
These hints currently only apply to typeclass proof search and the
{\hyperref[\detokenize{addendum/type-classes:coq:tacn.typeclasses-eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{typeclasses eauto}}}}} tactic.
\end{sphinxadmonition}

This command can be used to cut the proof-search tree according to a regular
expression matching paths to be cut. The grammar for regular expressions is
the following. Beware, there is no operator precedence during parsing, one can
check with {\hyperref[\detokenize{proof-engine/tactics:coq:cmd.print-hintdb}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print HintDb}}}}} to verify the current cut expression:


\begin{productionlist}
\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-e}}\production{e}{ ident      hint or instance identifier}
\productioncont{\textbar{} \_         any hint}
\productioncont{\textbar{} e\textbackslash{}\textbar{}e′     disjunction}
\productioncont{\textbar{} e e′      sequence}
\productioncont{\textbar{} e *       Kleene star}
\productioncont{\textbar{} emp       empty}
\productioncont{\textbar{} eps       epsilon}
\productioncont{\textbar{} ( e  )}
\end{productionlist}


The \sphinxtitleref{emp} regexp does not match any search path while \sphinxtitleref{eps}
matches the empty path. During proof search, the path of
successive successful hints on a search branch is recorded, as a
list of identifiers for the hints (note that Hint Extern’s do not have
an associated identifier).
Before applying any hint \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} the current path \sphinxtitleref{p} extended with
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is matched against the current cut expression \sphinxtitleref{c} associated to
the hint database. If matching succeeds, the hint is \sphinxstyleemphasis{not} applied. The
semantics of \sphinxcode{\sphinxupquote{Hint Cut e}} is to set the cut expression to \sphinxcode{\sphinxupquote{c \textbar{} e}}, the
initial cut expression being \sphinxtitleref{emp}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Mode~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{(+~\textbar{}~!~\textbar{}~-)}\DUrole{notation-sup}{*}}}}}}
This sets an optional mode of use of the identifier \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}. When
proof-search faces a goal that ends in an application of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} to
arguments \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} ... {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, the mode tells if the hints associated to
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} can be applied or not. A mode specification is a list of n \sphinxcode{\sphinxupquote{+}},
\sphinxcode{\sphinxupquote{!}} or \sphinxcode{\sphinxupquote{-}} items that specify if an argument of the identifier is to be
treated as an input (\sphinxcode{\sphinxupquote{+}}), if its head only is an input (\sphinxcode{\sphinxupquote{!}}) or an output
(\sphinxcode{\sphinxupquote{-}}) of the identifier. For a mode to match a list of arguments, input
terms and input heads \sphinxstyleemphasis{must not} contain existential variables or be
existential variables respectively, while outputs can be any term. Multiple
modes can be declared for a single identifier, in that case only one mode
needs to match the arguments for the hints to be applied.The head of a term
is understood here as the applicative head, or the match or projection
scrutinee’s head, recursively, casts being ignored. \sphinxcode{\sphinxupquote{Hint Mode}} is
especially useful for typeclasses, when one does not want to support default
instances and avoid ambiguity in general. Setting a parameter of a class as an
input forces proof-search to be driven by that index of the class, with \sphinxcode{\sphinxupquote{!}}
giving more flexibility by allowing existentials to still appear deeper in the
index but not at its head.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}
One can use an \sphinxcode{\sphinxupquote{Extern}} hint with no pattern to do pattern matching on
hypotheses using \sphinxcode{\sphinxupquote{match goal}} with inside the tactic.
\end{sphinxadmonition}

\end{fulllineitems}



\subsubsection{Hint databases defined in the Coq standard library}
\label{\detokenize{proof-engine/tactics:hint-databases-defined-in-the-coq-standard-library}}
Several hint databases are defined in the Coq standard library. The
actual content of a database is the collection of hints declared
to belong to this database in each of the various modules currently
loaded. Especially, requiring new modules may extend the database.
At Coq startup, only the core database is nonempty and can be used.
\begin{quote}\begin{description}
\item[{core}] \leavevmode
This special database is automatically used by \sphinxcode{\sphinxupquote{auto}}, except when
pseudo-database \sphinxcode{\sphinxupquote{nocore}} is given to \sphinxcode{\sphinxupquote{auto}}. The core database
contains only basic lemmas about negation, conjunction, and so on.
Most of the hints in this database come from the Init and Logic directories.

\item[{arith}] \leavevmode
This database contains all lemmas about Peano’s arithmetic proved in the
directories Init and Arith.

\item[{zarith}] \leavevmode
contains lemmas about binary signed integers from the directories
theories/ZArith. When required, the module Omega also extends the
database zarith with a high-cost hint that calls \sphinxcode{\sphinxupquote{omega}} on equations
and inequalities in \sphinxcode{\sphinxupquote{nat}} or \sphinxcode{\sphinxupquote{Z}}.

\item[{bool}] \leavevmode
contains lemmas about booleans, mostly from directory theories/Bool.

\item[{datatypes}] \leavevmode
is for lemmas about lists, streams and so on that are mainly proved
in the Lists subdirectory.

\item[{sets}] \leavevmode
contains lemmas about sets and relations from the directories Sets and
Relations.

\item[{typeclass\_instances}] \leavevmode
contains all the typeclass instances declared in the
environment, including those used for \sphinxcode{\sphinxupquote{setoid\_rewrite}},
from the Classes directory.

\end{description}\end{quote}

You are advised not to put your own hints in the core database, but
use one or several databases specific to your development.

\phantomsection\label{\detokenize{proof-engine/tactics:removehints}}\index{Remove Hints (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmd.remove-hints}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Remove~Hints~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}


This command removes the hints associated to terms \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}} in databases
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}.

\phantomsection\label{\detokenize{proof-engine/tactics:printhint}}\index{Print Hint (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Hint}}}}
\end{fulllineitems}


This command displays all hints that apply to the current goal. It
fails if no proof is being edited, while the two variants can be used
at every moment.

\sphinxstylestrong{Variants:}
\index{Print Hint (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Hint~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This command displays only tactics associated with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} in the hints
list. This is independent of the goal being edited, so this command will not
fail if no goal is being edited.

\end{fulllineitems}

\index{Print Hint (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Hint~*}}}}
This command displays all declared hints.

\end{fulllineitems}

\index{Print HintDb (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmd.print-hintdb}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~HintDb~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This command displays all hints from database \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}

\phantomsection\label{\detokenize{proof-engine/tactics:hintrewrite}}\index{Hint Rewrite (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmd.hint-rewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Rewrite~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This vernacular command adds the terms \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}} (their types must be
equalities) in the rewriting bases \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}} with the default orientation
(left to right). Notice that the rewriting bases are distinct from the \sphinxcode{\sphinxupquote{auto}}
hint bases and thatauto does not take them into account.

This command is synchronous with the section mechanism (see {\hyperref[\detokenize{language/gallina-extensions:section-mechanism}]{\sphinxcrossref{\DUrole{std,std-ref}{Section mechanism}}}}):
when closing a section, all aliases created by \sphinxcode{\sphinxupquote{Hint Rewrite}} in that
section are lost. Conversely, when loading a module, all \sphinxcode{\sphinxupquote{Hint Rewrite}}
declarations at the global level of that module are loaded.

\end{fulllineitems}


\sphinxstylestrong{Variants:}
\index{Hint Rewrite (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Rewrite~-\textgreater{}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This is strictly equivalent to the command above (we only make explicit the
orientation which otherwise defaults to -\textgreater{}).

\end{fulllineitems}

\index{Hint Rewrite (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Rewrite~\textless{}-~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
Adds the rewriting rules \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}} with a right-to-left orientation in
the bases \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}.

\end{fulllineitems}

\index{Hint Rewrite (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~Rewrite~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}~using~tactic~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
When the rewriting rules \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}} in \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}} will be used, the
tactic \sphinxcode{\sphinxupquote{tactic}} will be applied to the generated subgoals, the main subgoal
excluded.

\end{fulllineitems}

\index{Print Rewrite HintDb (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmd.print-rewrite-hintdb}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Rewrite~HintDb~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This command displays all rewrite hints contained in \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}



\subsubsection{Hint locality}
\label{\detokenize{proof-engine/tactics:hint-locality}}
Hints provided by the \sphinxcode{\sphinxupquote{Hint}} commands are erased when closing a section.
Conversely, all hints of a module \sphinxcode{\sphinxupquote{A}} that are not defined inside a
section (and not defined with option \sphinxcode{\sphinxupquote{Local}}) become available when the
module \sphinxcode{\sphinxupquote{A}} is imported (using e.g. \sphinxcode{\sphinxupquote{Require Import A.}}).

As of today, hints only have a binary behavior regarding locality, as
described above: either they disappear at the end of a section scope,
or they remain global forever. This causes a scalability issue,
because hints coming from an unrelated part of the code may badly
influence another development. It can be mitigated to some extent
thanks to the {\hyperref[\detokenize{proof-engine/tactics:coq:cmd.remove-hints}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove Hints}}}}} command,
but this is a mere workaround and has some limitations (for instance, external
hints cannot be removed).

A proper way to fix this issue is to bind the hints to their module scope, as
for most of the other objects Coq uses. Hints should only be made available when
the module they are defined in is imported, not just required. It is very
difficult to change the historical behavior, as it would break a lot of scripts.
We propose a smooth transitional path by providing the {\hyperref[\detokenize{proof-engine/tactics:coq:opt.loose-hint-behavior}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Loose Hint Behavior}}}}}
option which accepts three flags allowing for a fine-grained handling of
non-imported hints.
\index{Loose Hint Behavior (opt)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:opt.loose-hint-behavior}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Loose~Hint~Behavior~\DUrole{meta}{(}~"Lax"~\DUrole{meta}{\textbar{}}~"Warn"~\DUrole{meta}{\textbar{}}~"Strict"~\DUrole{meta}{)}}}}}
This option accepts three values, which control the behavior of hints w.r.t.
{\hyperref[\detokenize{language/gallina-extensions:coq:cmd.import}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Import}}}}}:
\begin{itemize}
\item {} 
"Lax": this is the default, and corresponds to the historical behavior,
that is, hints defined outside of a section have a global scope.

\item {} 
"Warn": outputs a warning when a non-imported hint is used. Note that this
is an over-approximation, because a hint may be triggered by a run that
will eventually fail and backtrack, resulting in the hint not being
actually useful for the proof.

\item {} 
"Strict": changes the behavior of an unloaded hint to a immediate fail
tactic, allowing to emulate an import-scoped hint mechanism.

\end{itemize}

\end{fulllineitems}



\subsubsection{Setting implicit automation tactics}
\label{\detokenize{proof-engine/tactics:setting-implicit-automation-tactics}}\label{\detokenize{proof-engine/tactics:tactics-implicit-automation}}\index{Proof with (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmd.proof-with}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~with~\DUrole{hole}{tactic}}}}}
This command may be used to start a proof. It defines a default tactic
to be used each time a tactic command \sphinxcode{\sphinxupquote{tactic}}$_{\text{1}}$ is ended by \sphinxcode{\sphinxupquote{...}}.
In this case the tactic command typed by the user is equivalent to
\sphinxcode{\sphinxupquote{tactic}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{;tactic}}.


\sphinxstrong{See also:}


{\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.proof}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Proof}}}}} in {\hyperref[\detokenize{proof-engine/proof-handling:proof-editing-mode}]{\sphinxcrossref{\DUrole{std,std-ref}{Switching on/off the proof editing mode}}}}.




\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~with~tactic~using~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
Combines in a single line \sphinxcode{\sphinxupquote{Proof with}} and \sphinxcode{\sphinxupquote{Proof using}}, see {\hyperref[\detokenize{proof-engine/proof-handling:proof-editing-mode}]{\sphinxcrossref{\DUrole{std,std-ref}{Switching on/off the proof editing mode}}}}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~using~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~with~\DUrole{hole}{tactic}}}}}
Combines in a single line \sphinxcode{\sphinxupquote{Proof with}} and \sphinxcode{\sphinxupquote{Proof using}}, see {\hyperref[\detokenize{proof-engine/proof-handling:proof-editing-mode}]{\sphinxcrossref{\DUrole{std,std-ref}{Switching on/off the proof editing mode}}}}

\end{fulllineitems}

\index{Declare Implicit Tactic (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmd.declare-implicit-tactic}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~Implicit~Tactic~\DUrole{hole}{tactic}}}}}
This command declares a tactic to be used to solve implicit arguments
that Coq does not know how to solve by unification. It is used every
time the term argument of a tactic has one of its holes not fully
resolved.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{quo} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n}\PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}}\PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{quo} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x // y}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{quo} \PYG{n}{x} \PYG{n}{y} \PYG{o}{\PYGZus{}}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{40}\PYG{o}{)}\PYG{o}{.}
\PYG{n}{Declare} \PYG{k+kn}{Implicit} \PYG{k+kn}{Tactic} \PYG{k+kp}{assumption}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{,} \PYG{n}{m}\PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}}\PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZob{}} \PYG{n}{q}\PYG{o}{:}\PYG{k+kt}{nat} \PYG{o}{\PYGZam{}} \PYG{o}{\PYGZob{}} \PYG{n}{r} \PYG{o}{\textbar{}} \PYG{n}{q} \PYG{o}{*} \PYG{n}{m} \PYG{o}{+} \PYG{n}{r} \PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{quo} \PYG{k}{is} \PYG{n}{declared}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZob{}}\PYG{n}{q} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZam{}} \PYG{o}{\PYGZob{}}\PYG{n}{r} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\textbar{}} \PYG{n}{q} \PYG{o}{*} \PYG{n}{m} \PYG{o}{+} \PYG{n}{r} \PYG{o}{=} \PYG{n}{n}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZcb{}}

\PYG{k}{intros}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{\PYGZob{}}\PYG{n}{q} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZam{}} \PYG{o}{\PYGZob{}}\PYG{n}{r} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\textbar{}} \PYG{n}{q} \PYG{o}{*} \PYG{n}{m} \PYG{o}{+} \PYG{n}{r} \PYG{o}{=} \PYG{n}{n}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZcb{}}

\PYG{k}{exists} \PYG{o}{(}\PYG{n}{n} \PYG{o}{//} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{\PYGZob{}}\PYG{n}{r} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\textbar{}} \PYG{n}{n} \PYG{o}{//} \PYG{n}{m} \PYG{o}{*} \PYG{n}{m} \PYG{o}{+} \PYG{n}{r} \PYG{o}{=} \PYG{n}{n}\PYG{o}{\PYGZcb{}}
\end{sphinxVerbatim}

The tactic \sphinxcode{\sphinxupquote{exists (n // m)}} did not fail. The hole was solved
by \sphinxcode{\sphinxupquote{assumption}} so that it behaved as \sphinxcode{\sphinxupquote{exists (quo n m H)}}.
\end{sphinxadmonition}

\end{fulllineitems}



\subsection{Decision procedures}
\label{\detokenize{proof-engine/tactics:decision-procedures}}\label{\detokenize{proof-engine/tactics:decisionprocedures}}\index{tauto (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.tauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{tauto}}}}
\end{fulllineitems}


This tactic implements a decision procedure for intuitionistic propositional
calculus based on the contraction-free sequent calculi LJT* of Roy Dyckhoff
\sphinxcite{zebibliography:dyc92}. Note that {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} succeeds on any instance of an
intuitionistic tautological proposition. {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} unfolds negations and
logical equivalence but does not unfold any other definition.

The following goal can be proved by {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} whereas {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} would
fail:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZbs{}/} \PYG{n}{P} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{x}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZbs{}/} \PYG{n}{P} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{x}

\PYG{k}{intros}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZbs{}/} \PYG{n}{P} \PYG{n}{x}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{n}{x}

\PYG{k}{tauto}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Moreover, if it has nothing else to do, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} performs introductions.
Therefore, the use of {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}} in the previous proof is unnecessary.
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} can for instance for:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:}\PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{o}{\PYGZti{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{x}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{o}{\PYGZti{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{x}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,}
      \PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{o}{\PYGZti{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{x}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{o}{\PYGZti{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{x}

\PYG{k}{tauto}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
In contrast, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} cannot solve the following goal
\sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Goal} \DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{A}\DUrole{operator}{:}\DUrole{keyword,type}{Prop}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{P}\DUrole{operator}{:}\DUrole{keyword,type}{nat} \DUrole{operator}{-\textgreater{}} \DUrole{keyword,type}{Prop}\DUrole{operator}{),} \DUrole{name}{A} \DUrole{operator}{\textbackslash{}/} \DUrole{operator}{(}\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{keyword,type}{nat}\DUrole{operator}{,} \DUrole{operator}{\textasciitilde{}} \DUrole{name}{A} \DUrole{operator}{-\textgreater{}} \DUrole{name}{P} \DUrole{name}{x}\DUrole{operator}{)} \DUrole{operator}{-\textgreater{}}}}
\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{keyword,type}{nat}\DUrole{operator}{,} \DUrole{operator}{\textasciitilde{}} \DUrole{operator}{\textasciitilde{}} \DUrole{operator}{(}\DUrole{name}{A} \DUrole{operator}{\textbackslash{}/} \DUrole{name}{P} \DUrole{name}{x}\DUrole{operator}{).}}}
because \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{keyword,type}{nat}\DUrole{operator}{,} \DUrole{operator}{\textasciitilde{}} \DUrole{name}{A} \DUrole{operator}{-\textgreater{}} \DUrole{name}{P} \DUrole{name}{x}\DUrole{operator}{)}}} cannot be treated as atomic and
an instantiation of \sphinxtitleref{x} is necessary.
\end{sphinxadmonition}
\index{dtauto (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.dtauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dtauto}}}}
While {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} recognizes inductively defined connectives isomorphic to
the standard connectives \sphinxcode{\sphinxupquote{and}}, \sphinxcode{\sphinxupquote{prod}}, \sphinxcode{\sphinxupquote{or}}, \sphinxcode{\sphinxupquote{sum}}, \sphinxcode{\sphinxupquote{False}},
\sphinxcode{\sphinxupquote{Empty\_set}}, \sphinxcode{\sphinxupquote{unit}}, \sphinxcode{\sphinxupquote{True}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.dtauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{dtauto}}}}} also recognizes all inductive
types with one constructor and no indices, i.e. record-style connectives.

\end{fulllineitems}

\index{intuition (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.intuition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{intuition~\DUrole{hole}{tactic}}}}}
\end{fulllineitems}


The tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intuition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intuition}}}}} takes advantage of the search-tree built by the
decision procedure involved in the tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}}. It uses this
information to generate a set of subgoals equivalent to the original one (but
simpler than it) and applies the tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic}}}} to them \sphinxcite{zebibliography:mun94}. If
this tactic fails on some goals then {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intuition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intuition}}}}} fails. In fact,
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} is simply \sphinxcode{\sphinxupquote{\DUrole{keyword}{intuition} \DUrole{name}{fail}}}.

For instance, the tactic \sphinxcode{\sphinxupquote{\DUrole{keyword}{intuition} \DUrole{keyword}{auto}}} applied to the goal

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
(forall (x:nat), P x) /\PYGZbs{} B \PYGZhy{}\PYGZgt{} (forall (y:nat), P y) /\PYGZbs{} P O \PYGZbs{}/ B /\PYGZbs{} P O
\end{sphinxVerbatim}

internally replaces it by the equivalent one:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
(forall (x:nat), P x), B \textbar{}\PYGZhy{} P O
\end{sphinxVerbatim}

and then uses {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} which completes the proof.

Originally due to César Muñoz, these tactics ({\hyperref[\detokenize{proof-engine/tactics:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} and
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intuition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intuition}}}}}) have been completely re-engineered by David Delahaye using
mainly the tactic language (see {\hyperref[\detokenize{proof-engine/ltac:ltac}]{\sphinxcrossref{\DUrole{std,std-ref}{The tactic language}}}}). The code is
now much shorter and a significant increase in performance has been noticed.
The general behavior with respect to dependent types, unfolding and
introductions has slightly changed to get clearer semantics. This may lead to
some incompatibilities.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{intuition}}}}
Is equivalent to \sphinxcode{\sphinxupquote{\DUrole{keyword}{intuition} \DUrole{keyword}{auto} \DUrole{keyword}{with} \DUrole{operator}{*}}}.

\end{fulllineitems}

\index{dintuition (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.dintuition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dintuition}}}}
While {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intuition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intuition}}}}} recognizes inductively defined connectives
isomorphic to the standard connectives \sphinxcode{\sphinxupquote{and}}, \sphinxcode{\sphinxupquote{prod}}, \sphinxcode{\sphinxupquote{or}}, \sphinxcode{\sphinxupquote{sum}}, \sphinxcode{\sphinxupquote{False}},
\sphinxcode{\sphinxupquote{Empty\_set}}, \sphinxcode{\sphinxupquote{unit}}, \sphinxcode{\sphinxupquote{True}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.dintuition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{dintuition}}}}} also recognizes all inductive
types with one constructor and no indices, i.e. record-style connectives.

\end{fulllineitems}

\index{Intuition Negation Unfolding (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.intuition-negation-unfolding}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Intuition~Negation~Unfolding}}}}
Controls whether {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intuition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intuition}}}}} unfolds inner negations which do not need
to be unfolded. This option is on by default.

\end{fulllineitems}

\index{rtauto (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.rtauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{rtauto}}}}
\end{fulllineitems}


The {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.rtauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rtauto}}}}} tactic solves propositional tautologies similarly to what
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} does. The main difference is that the proof term is built using a
reflection scheme applied to a sequent calculus proof of the goal.  The search
procedure is also implemented using a different technique.

Users should be aware that this difference may result in faster proof-search
but slower proof-checking, and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.rtauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rtauto}}}}} might not solve goals that
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} would be able to solve (e.g. goals involving universal
quantifiers).

Note that this tactic is only available after a \sphinxcode{\sphinxupquote{Require Import Rtauto}}.
\index{firstorder (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.firstorder}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{firstorder}}}}
\end{fulllineitems}


The tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.firstorder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{firstorder}}}}} is an experimental extension of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.tauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tauto}}}}} to
first- order reasoning, written by Pierre Corbineau. It is not restricted to
usual logical connectives but instead may reason about any first-order class
inductive definition.
\index{Firstorder Solver (opt)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:opt.firstorder-solver}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Firstorder~Solver~\DUrole{hole}{tactic}}}}}
The default tactic used by {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.firstorder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{firstorder}}}}} when no rule applies is
\sphinxcode{\sphinxupquote{\DUrole{keyword}{auto} \DUrole{keyword}{with} \DUrole{operator}{*}}}, it can be reset locally or globally using this option.
\index{Print Firstorder Solver (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmd.print-firstorder-solver}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Firstorder~Solver}}}}
Prints the default tactic used by {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.firstorder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{firstorder}}}}} when no rule applies.

\end{fulllineitems}


\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{firstorder~\DUrole{hole}{tactic}}}}}
Tries to solve the goal with \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic}}}} when no logical rule may apply.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{firstorder~using~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
Adds lemmas \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}} to the proof-search environment. If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}
refers to an inductive type, it is the collection of its constructors which are
added to the proof-search environment.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{firstorder~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
Adds lemmas from {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} hint bases \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}} to the proof-search
environment.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{firstorder~tactic~using~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This combines the effects of the different variants of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.firstorder}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{firstorder}}}}}.

\end{fulllineitems}

\index{Firstorder Depth (opt)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:opt.firstorder-depth}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Firstorder~Depth~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This option controls the proof-search depth bound.

\end{fulllineitems}

\index{congruence (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.congruence}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{congruence}}}}
\end{fulllineitems}


The tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.congruence}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{congruence}}}}}, by Pierre Corbineau, implements the standard
Nelson and Oppen congruence closure algorithm, which is a decision procedure
for ground equalities with uninterpreted symbols. It also includes
constructor theory (see {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.discriminate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{discriminate}}}}}). If the goal
is a non-quantified equality, congruence tries to prove it with non-quantified
equalities in the context. Otherwise it tries to infer a discriminable equality
from those in the context. Alternatively, congruence tries to prove that a
hypothesis is equal to the goal or to the negation of another hypothesis.

{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.congruence}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{congruence}}}}} is also able to take advantage of hypotheses stating
quantified equalities, but you have to provide a bound for the number of extra
equalities generated that way. Please note that one of the sides of the
equality must contain all the quantified variables in order for congruence to
match against it.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Theorem} \PYG{n}{T} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{g}\PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}\PYG{o}{)} \PYG{n}{a} \PYG{n}{b}\PYG{o}{:} \PYG{n}{a}\PYG{o}{=}\PYG{o}{(}\PYG{n}{f} \PYG{n}{a}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{g} \PYG{n}{b} \PYG{o}{(}\PYG{n}{f} \PYG{n}{a}\PYG{o}{)}\PYG{o}{)}\PYG{o}{=}\PYG{o}{(}\PYG{n}{f} \PYG{o}{(}\PYG{n}{f} \PYG{n}{a}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{g} \PYG{n}{a} \PYG{n}{b}\PYG{o}{)}\PYG{o}{=}\PYG{o}{(}\PYG{n}{f} \PYG{o}{(}\PYG{n}{g} \PYG{n}{b} \PYG{n}{a}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{g} \PYG{n}{a} \PYG{n}{b}\PYG{o}{)}\PYG{o}{=}\PYG{n}{a}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{f} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}
      \PYG{n}{g} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{A}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{a} \PYG{o}{=} \PYG{n}{f} \PYG{n}{a} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{g} \PYG{n}{b} \PYG{o}{(}\PYG{n}{f} \PYG{n}{a}\PYG{o}{)} \PYG{o}{=} \PYG{n}{f} \PYG{o}{(}\PYG{n}{f} \PYG{n}{a}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{g} \PYG{n}{a} \PYG{n}{b} \PYG{o}{=} \PYG{n}{f} \PYG{o}{(}\PYG{n}{g} \PYG{n}{b} \PYG{n}{a}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{g} \PYG{n}{a} \PYG{n}{b} \PYG{o}{=} \PYG{n}{a}

\PYG{k}{intros}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{f} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}
      \PYG{n}{g} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{f} \PYG{n}{a}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{g} \PYG{n}{b} \PYG{o}{(}\PYG{n}{f} \PYG{n}{a}\PYG{o}{)} \PYG{o}{=} \PYG{n}{f} \PYG{o}{(}\PYG{n}{f} \PYG{n}{a}\PYG{o}{)}
      \PYG{n}{H1} \PYG{o}{:} \PYG{n}{g} \PYG{n}{a} \PYG{n}{b} \PYG{o}{=} \PYG{n}{f} \PYG{o}{(}\PYG{n}{g} \PYG{n}{b} \PYG{n}{a}\PYG{o}{)}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{g} \PYG{n}{a} \PYG{n}{b} \PYG{o}{=} \PYG{n}{a}

\PYG{k+kp}{congruence}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{T} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Theorem} \PYG{n}{inj} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f}\PYG{o}{:}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{*} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{a} \PYG{n}{c} \PYG{n}{d}\PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{n}{f} \PYG{o}{=} \PYG{n}{pair} \PYG{n}{a} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Some} \PYG{o}{(}\PYG{n}{f} \PYG{n}{c}\PYG{o}{)} \PYG{o}{=} \PYG{n}{Some} \PYG{o}{(}\PYG{n}{f} \PYG{n}{d}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{c}\PYG{o}{=}\PYG{n}{d}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{f} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{*} \PYG{n}{A}
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{c}\PYG{o}{,} \PYG{n}{d} \PYG{o}{:} \PYG{n}{A}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{f} \PYG{o}{=} \PYG{n}{pair} \PYG{n}{a} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Some} \PYG{o}{(}\PYG{n}{f} \PYG{n}{c}\PYG{o}{)} \PYG{o}{=} \PYG{n}{Some} \PYG{o}{(}\PYG{n}{f} \PYG{n}{d}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{c} \PYG{o}{=} \PYG{n}{d}

\PYG{k}{intros}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{f} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{*} \PYG{n}{A}
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{c}\PYG{o}{,} \PYG{n}{d} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{f} \PYG{o}{=} \PYG{n}{pair} \PYG{n}{a}
      \PYG{n}{H0} \PYG{o}{:} \PYG{n}{Some} \PYG{o}{(}\PYG{n}{f} \PYG{n}{c}\PYG{o}{)} \PYG{o}{=} \PYG{n}{Some} \PYG{o}{(}\PYG{n}{f} \PYG{n}{d}\PYG{o}{)}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{c} \PYG{o}{=} \PYG{n}{d}

\PYG{k+kp}{congruence}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{inj} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{congruence~n}}}}
Tries to add at most \sphinxtitleref{n} instances of hypotheses stating quantified equalities
to the problem in order to solve it. A bigger value of \sphinxtitleref{n} does not make
success slower, only failure. You might consider adding some lemmas as
hypotheses using assert in order for {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.congruence}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{congruence}}}}} to use them.

\end{fulllineitems}

\index{congruence with (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.congruence-with}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{congruence~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}}}
Adds \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}} to the pool of terms used by {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.congruence}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{congruence}}}}}. This helps
in case you have partially applied constructors in your goal.

\end{fulllineitems}

\index{I don’t know how to handle dependent equality (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.i-dont-know-how-to-handle-dependent-equality}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{I~don’t~know~how~to~handle~dependent~equality.}}}}
The decision procedure managed to find a proof of the goal or of a
discriminable equality but this proof could not be built in Coq because of
dependently-typed functions.

\end{fulllineitems}

\index{Goal is solvable by congruence but some arguments are missing. Try congruence with ‘term’…‘term’, replacing metavariables by arbitrary terms (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.goal-is-solvable-by-congruence-but-some-arguments-are-missing-try-congruence-with-term-term-replacing-metavariables-by-arbitrary-terms}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Goal~is~solvable~by~congruence~but~some~arguments~are~missing.~Try~congruence~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}},~replacing~metavariables~by~arbitrary~terms.}}}}
The decision procedure could solve the goal with the provision that additional
arguments are supplied for some partially applied constructors. Any term of an
appropriate type will allow the tactic to successfully solve the goal. Those
additional arguments can be given to congruence by filling in the holes in the
terms given in the error message, using the {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.congruence-with}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{congruence with}}}}} variant described above.

\end{fulllineitems}

\index{Congruence Verbose (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:flag.congruence-verbose}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Congruence~Verbose}}}}
This option makes {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.congruence}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{congruence}}}}} print debug information.

\end{fulllineitems}



\subsection{Checking properties of terms}
\label{\detokenize{proof-engine/tactics:checking-properties-of-terms}}
Each of the following tactics acts as the identity if the check
succeeds, and results in an error otherwise.
\index{constr\_eq (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.constr-eq}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{constr\_eq~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic checks whether its arguments are equal modulo alpha
conversion and casts.

\end{fulllineitems}

\index{Not equal (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-equal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~equal.}}}}
\end{fulllineitems}

\index{unify (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.unify}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{unify~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic checks whether its arguments are unifiable, potentially
instantiating existential variables.

\end{fulllineitems}

\index{Unable to unify ‘term’ with ‘term’ (err)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unable~to~unify~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{unify~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Unification takes the transparency information defined in the hint database
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} into account (see {\hyperref[\detokenize{proof-engine/tactics:thehintsdatabasesforautoandeauto}]{\sphinxcrossref{\DUrole{std,std-ref}{the hints databases for auto and eauto}}}}).

\end{fulllineitems}

\index{is\_evar (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.is-evar}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{is\_evar~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic checks whether its argument is a current existential
variable. Existential variables are uninstantiated variables generated
by {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.eapply}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eapply}}}}} and some other tactics.

\end{fulllineitems}

\index{Not an evar (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-an-evar}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~an~evar.}}}}
\end{fulllineitems}

\index{has\_evar (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.has-evar}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{has\_evar~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic checks whether its argument has an existential variable as
a subterm. Unlike context patterns combined with \sphinxcode{\sphinxupquote{is\_evar}}, this tactic
scans all subterms, including those under binders.

\end{fulllineitems}

\index{No evars (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.no-evars}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~evars.}}}}
\end{fulllineitems}

\index{is\_var (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.is-var}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{is\_var~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic checks whether its argument is a variable or hypothesis in
the current goal context or in the opened sections.

\end{fulllineitems}

\index{Not a variable or hypothesis (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.not-a-variable-or-hypothesis}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~a~variable~or~hypothesis.}}}}
\end{fulllineitems}



\subsection{Equality}
\label{\detokenize{proof-engine/tactics:equality}}\label{\detokenize{proof-engine/tactics:id14}}\index{f\_equal (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.f-equal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{f\_equal}}}}
\end{fulllineitems}


This tactic applies to a goal of the form \sphinxcode{\sphinxupquote{\DUrole{name}{f} \DUrole{name}{a}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{operator}{...} \DUrole{name}{a}}}$_{\text{n}}$
\sphinxcode{\sphinxupquote{\DUrole{operator}{=} \DUrole{name}{f}\DUrole{error}{′}\DUrole{name}{a}\DUrole{error}{′}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{operator}{...} \DUrole{name}{a}\DUrole{error}{′}}}$_{\text{n}}$.  Using {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.f-equal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{f\_equal}}}}} on such a goal
leads to subgoals \sphinxcode{\sphinxupquote{\DUrole{name}{f}\DUrole{operator}{=}\DUrole{name}{f}\DUrole{error}{′}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{a}}}$_{\text{1}}$ = \sphinxcode{\sphinxupquote{\DUrole{name}{a}\DUrole{error}{′}}}$_{\text{1}}$ and so on up
to \sphinxcode{\sphinxupquote{\DUrole{name}{a}}}$_{\text{n}}$ \sphinxcode{\sphinxupquote{\DUrole{operator}{=} \DUrole{name}{a}\DUrole{error}{′}}}$_{\text{n}}$. Amongst these subgoals, the simple ones
(e.g. provable by {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.reflexivity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reflexivity}}}}} or {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.congruence}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{congruence}}}}}) are automatically
solved by {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.f-equal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{f\_equal}}}}}.
\index{reflexivity (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.reflexivity}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{reflexivity}}}}
\end{fulllineitems}


This tactic applies to a goal that has the form \sphinxcode{\sphinxupquote{\DUrole{name}{t}\DUrole{operator}{=}\DUrole{name}{u}}}. It checks that \sphinxtitleref{t}
and \sphinxtitleref{u} are convertible and then solves the goal. It is equivalent to
\sphinxcode{\sphinxupquote{apply refl\_equal}}.
\index{The conclusion is not a substitutive equation (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.the-conclusion-is-not-a-substitutive-equation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~conclusion~is~not~a~substitutive~equation.}}}}
\end{fulllineitems}

\index{Unable to unify ... with ... (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.unable-to-unify-with}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unable~to~unify~...~with~...}}}}
\end{fulllineitems}

\index{symmetry (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.symmetry}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{symmetry}}}}
\end{fulllineitems}


This tactic applies to a goal that has the form \sphinxcode{\sphinxupquote{\DUrole{name}{t}\DUrole{operator}{=}\DUrole{name}{u}}} and changes it into
\sphinxcode{\sphinxupquote{\DUrole{name}{u}\DUrole{operator}{=}\DUrole{name}{t}}}.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{symmetry~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
If the statement of the hypothesis ident has the form \sphinxcode{\sphinxupquote{\DUrole{name}{t}\DUrole{operator}{=}\DUrole{name}{u}}}, the tactic
changes it to \sphinxcode{\sphinxupquote{\DUrole{name}{u}\DUrole{operator}{=}\DUrole{name}{t}}}.

\end{fulllineitems}

\index{transitivity (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.transitivity}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{transitivity~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


This tactic applies to a goal that has the form \sphinxcode{\sphinxupquote{\DUrole{name}{t}\DUrole{operator}{=}\DUrole{name}{u}}} and transforms it
into the two subgoals \sphinxcode{\sphinxupquote{\DUrole{notation}{t={\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}=u}}}.


\subsection{Equality and inductive sets}
\label{\detokenize{proof-engine/tactics:equality-and-inductive-sets}}
We describe in this section some special purpose tactics dealing with
equality and inductive sets or types. These tactics use the
equality \sphinxcode{\sphinxupquote{\DUrole{name}{eq}\DUrole{operator}{:}\DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{A}\DUrole{operator}{:}\DUrole{keyword,type}{Type}\DUrole{operator}{),} \DUrole{name}{A}\DUrole{operator}{-\textgreater{}}\DUrole{name}{A}\DUrole{operator}{-\textgreater{}}\DUrole{keyword,type}{Prop}}}, simply written with the infix
symbol \sphinxcode{\sphinxupquote{\DUrole{operator}{=}}}.
\index{decide equality (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.decide-equality}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{decide~equality}}}}
This tactic solves a goal of the form \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x} \DUrole{name}{y} \DUrole{operator}{:} \DUrole{name}{R}\DUrole{operator}{,} \DUrole{operator}{\{}\DUrole{name}{x} \DUrole{operator}{=} \DUrole{name}{y}\DUrole{operator}{\}} \DUrole{operator}{+} \DUrole{operator}{\{\textasciitilde{}} \DUrole{name}{x} \DUrole{operator}{=} \DUrole{name}{y}\DUrole{operator}{\}}}},
where \sphinxcode{\sphinxupquote{\DUrole{name}{R}}} is an inductive type such that its constructors do not take
proofs or functions as arguments, nor objects in dependent types. It
solves goals of the form \sphinxcode{\sphinxupquote{\DUrole{operator}{\{}\DUrole{name}{x} \DUrole{operator}{=} \DUrole{name}{y}\DUrole{operator}{\}} \DUrole{operator}{+} \DUrole{operator}{\{\textasciitilde{}} \DUrole{name}{x} \DUrole{operator}{=} \DUrole{name}{y}\DUrole{operator}{\}}}} as well.

\end{fulllineitems}

\index{compare (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.compare}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{compare~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This tactic compares two given objects \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} of an
inductive datatype. If \sphinxcode{\sphinxupquote{\DUrole{name}{G}}} is the current goal, it leaves the sub-
goals \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} ={\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} -\textgreater{} G}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{\textasciitilde{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} -\textgreater{} G}}}. The type of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} must satisfy the same restrictions as in the
tactic \sphinxcode{\sphinxupquote{decide equality}}.

\end{fulllineitems}

\index{simplify\_eq (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.simplify-eq}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{simplify\_eq~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
Let \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} be the proof of a statement of conclusion \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} are structurally different (in the sense
described for the tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.discriminate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{discriminate}}}}}), then the tactic
\sphinxcode{\sphinxupquote{simplify\_eq}} behaves as \sphinxcode{\sphinxupquote{\DUrole{notation}{discriminate {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, otherwise it behaves as
\sphinxcode{\sphinxupquote{\DUrole{notation}{injection {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}
If some quantified hypothesis of the goal is named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}},
then \sphinxcode{\sphinxupquote{\DUrole{notation}{simplify\_eq {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} first introduces the hypothesis in the local
context using \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simplify\_eq~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This does the same thing as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} then
\sphinxcode{\sphinxupquote{\DUrole{notation}{simplify\_eq {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is the identifier for the last
introduced hypothesis.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simplify\_eq~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}}}}
This does the same as \sphinxcode{\sphinxupquote{\DUrole{notation}{simplify\_eq {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} but using the given bindings to
instantiate parameters or hypotheses of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{esimplify\_eq~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
\end{fulllineitems}

\index{esimplify\_eq (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.esimplify-eq}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{esimplify\_eq~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{proof-engine/tactics:grammar-token-bindings-list}]{\sphinxcrossref{\DUrole{hole}{bindings\_list}}}}}\DUrole{notation-sup}{?}}}}}}
This works the same as \sphinxcode{\sphinxupquote{simplify\_eq}} but if the type of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}, or the
type of the hypothesis referred to by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}, has uninstantiated
parameters, these parameters are left as existential variables.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{simplify\_eq}}}}
If the current goal has form \sphinxcode{\sphinxupquote{\DUrole{name}{t1} \DUrole{operator}{\textless{}\textgreater{}} \DUrole{name}{t2}}}, it behaves as
\sphinxcode{\sphinxupquote{\DUrole{notation}{intro {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}; simplify\_eq {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}

\index{dependent rewrite -\textgreater{} (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.dependent-rewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~rewrite~-\textgreater{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This tactic applies to any goal. If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} has type
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{existT} \DUrole{name}{B} \DUrole{name}{a} \DUrole{name}{b}\DUrole{operator}{)=(}\DUrole{name}{existT} \DUrole{name}{B} \DUrole{name}{a'} \DUrole{name}{b'}\DUrole{operator}{)}}} in the local context (i.e. each
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} of the equality has a sigma type \sphinxcode{\sphinxupquote{\DUrole{operator}{\{} \DUrole{name}{a}\DUrole{operator}{:}\DUrole{name}{A} \DUrole{operator}{\&} \DUrole{operator}{(}\DUrole{name}{B} \DUrole{name}{a}\DUrole{operator}{)\}}}}) this tactic
rewrites \sphinxcode{\sphinxupquote{\DUrole{name}{a}}} into \sphinxcode{\sphinxupquote{\DUrole{name}{a'}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{b}}} into \sphinxcode{\sphinxupquote{\DUrole{name}{b'}}} in the current goal.
This tactic works even if \sphinxcode{\sphinxupquote{\DUrole{name}{B}}} is also a sigma type. This kind of
equalities between dependent pairs may be derived by the
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.injection}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{injection}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion}}}}} tactics.

\end{fulllineitems}

\index{dependent rewrite \textless{}- (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.dependent-rewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{dependent~rewrite~\textless{}-~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Analogous to {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.dependent-rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{dependent rewrite -\textgreater{}}}}}} but uses the equality from right to
left.

\end{fulllineitems}



\subsection{Inversion}
\label{\detokenize{proof-engine/tactics:inversion}}\index{functional inversion (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.functional-inversion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{functional~inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\end{fulllineitems}


{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.functional-inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{functional inversion}}}}} is a tactic that performs inversion on hypothesis
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}
\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}} where \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} must have been defined using Function (see
{\hyperref[\detokenize{language/gallina-extensions:advanced-recursive-functions}]{\sphinxcrossref{\DUrole{std,std-ref}{Advanced recursive functions}}}}). Note that this tactic is only
available after a \sphinxcode{\sphinxupquote{Require Import FunInd}}.
\index{Hypothesis ‘ident’ must contain at least one Function (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.hypothesis-ident-must-contain-at-least-one-function}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hypothesis~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~must~contain~at~least~one~Function.}}}}
\end{fulllineitems}

\index{Cannot find inversion information for hypothesis ‘ident’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.cannot-find-inversion-information-for-hypothesis-ident}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~find~inversion~information~for~hypothesis~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
This error may be raised when some inversion lemma failed to be generated by
Function.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{functional~inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This does the same thing as \sphinxcode{\sphinxupquote{\DUrole{notation}{intros until {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} folowed by
\sphinxcode{\sphinxupquote{\DUrole{notation}{functional inversion {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} where {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is the
identifier for the last introduced hypothesis.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{functional~inversion~ident~qualid}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{functional~inversion~num~qualid}}}}
If the hypothesis \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} (or \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}) has a type of the form
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}$_{\text{1}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}$_{\text{1}}$ ... \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}$_{\text{n}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{=
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}$_{\text{2}}$ \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}$_{\text{n+1}}$ ... \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}$_{\text{n+m}}$ where
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}$_{\text{1}}$ and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}$_{\text{2}}$ are valid candidates to
functional inversion, this variant allows choosing which \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} is
inverted.

\end{fulllineitems}

\index{quote (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.quote}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{quote~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\end{fulllineitems}


This kind of inversion has nothing to do with the tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion}}}}}
above. This tactic does \sphinxcode{\sphinxupquote{\DUrole{keyword}{change} \DUrole{operator}{(@}\DUrole{name}{ident} \DUrole{name}{t}\DUrole{operator}{)}}}, where \sphinxtitleref{t} is a term built in
order to ensure the convertibility. In other words, it does inversion of the
function \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}. This function must be a fixpoint on a simple recursive
datatype: see {\hyperref[\detokenize{proof-engine/detailed-tactic-examples:quote}]{\sphinxcrossref{\DUrole{std,std-ref}{quote}}}} for the full details.
\index{quote: not a simple fixpoint (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.quote-not-a-simple-fixpoint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{quote:~not~a~simple~fixpoint.}}}}
Happens when quote is not able to perform inversion properly.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{quote~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}}}}}
All terms that are built only with \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}}}} will be considered by quote
as constants rather than variables.

\end{fulllineitems}



\subsection{Classical tactics}
\label{\detokenize{proof-engine/tactics:classical-tactics}}
In order to ease the proving process, when the Classical module is
loaded. A few more tactics are available. Make sure to load the module
using the \sphinxcode{\sphinxupquote{Require Import}} command.
\index{classical\_left (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.classical-left}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{classical\_left}}}}
\end{fulllineitems}

\index{classical\_right (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.classical-right}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{classical\_right}}}}
The tactics \sphinxcode{\sphinxupquote{classical\_left}} and \sphinxcode{\sphinxupquote{classical\_right}} are the analog of the
left and right but using classical logic. They can only be used for
disjunctions. Use \sphinxcode{\sphinxupquote{classical\_left}} to prove the left part of the
disjunction with the assumption that the negation of right part holds.
Use \sphinxcode{\sphinxupquote{classical\_right}} to prove the right part of the disjunction with
the assumption that the negation of left part holds.

\end{fulllineitems}



\subsection{Automating}
\label{\detokenize{proof-engine/tactics:automating}}\label{\detokenize{proof-engine/tactics:tactics-automating}}\index{btauto (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.btauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{btauto}}}}
\end{fulllineitems}


The tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.btauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{btauto}}}}} implements a reflexive solver for boolean
tautologies. It solves goals of the form \sphinxcode{\sphinxupquote{\DUrole{name}{t} \DUrole{operator}{=} \DUrole{name}{u}}} where \sphinxtitleref{t} and \sphinxtitleref{u} are
constructed over the following grammar:

\phantomsection\label{\detokenize{proof-engine/tactics:btauto-grammar}}\begin{quote}


\begin{productionlist}
\phantomsection\label{\detokenize{proof-engine/tactics:grammar-token-t}}\production{t}{ x}
\productioncont{∣ true}
\productioncont{∣ false}
\productioncont{∣ orb t1 t2}
\productioncont{∣ andb t1 t2}
\productioncont{∣ xorb t1 t2}
\productioncont{∣ negb t}
\productioncont{∣ if t1 then t2 else t3}
\end{productionlist}


Whenever the formula supplied is not a tautology, it also provides a
counter-example.

Internally, it uses a system very similar to the one of the ring
tactic.

Note that this tactic is only available after a \sphinxcode{\sphinxupquote{Require Import Btauto}}.
\end{quote}
\index{Cannot recognize a boolean equality (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:exn.cannot-recognize-a-boolean-equality}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~recognize~a~boolean~equality.}}}}
The goal is not of the form \sphinxcode{\sphinxupquote{\DUrole{name}{t} \DUrole{operator}{=} \DUrole{name}{u}}}. Especially note that {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.btauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{btauto}}}}}
doesn't introduce variables into the context on its own.

\end{fulllineitems}

\index{omega (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.omega}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{omega}}}}
\end{fulllineitems}


The tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}}, due to Pierre Crégut, is an automatic decision
procedure for Presburger arithmetic. It solves quantifier-free
formulas built with \sphinxtitleref{\textasciitilde{}}, \sphinxtitleref{/}, \sphinxtitleref{/{}`, {}`-\textgreater{}} on top of equalities,
inequalities and disequalities on both the type \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{nat}}} of natural numbers
and \sphinxcode{\sphinxupquote{\DUrole{name}{Z}}} of binary integers. This tactic must be loaded by the command
\sphinxcode{\sphinxupquote{Require Import Omega}}. See the additional documentation about omega
(see Chapter {\hyperref[\detokenize{addendum/omega:omega}]{\sphinxcrossref{\DUrole{std,std-ref}{Omega: a solver for quantifier-free problems in Presburger Arithmetic}}}}).
\index{ring (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.ring}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{ring}}}}
\end{fulllineitems}

\index{ring\_simplify (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.ring-simplify}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{ring\_simplify~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}


The \sphinxcode{\sphinxupquote{\DUrole{notation}{ring}}} tactic solves equations upon polynomial expressions of a ring
(or semiring) structure. It proceeds by normalizing both hand sides
of the equation (w.r.t. associativity, commutativity and
distributivity, constant propagation) and comparing syntactically the
results.

\sphinxcode{\sphinxupquote{\DUrole{notation}{ring\_simplify}}} applies the normalization procedure described above to
the given terms. The tactic then replaces all occurrences of the terms
given in the conclusion of the goal by their normal forms. If no term
is given, then the conclusion should be an equation and both hand
sides are normalized.

See {\hyperref[\detokenize{addendum/ring:theringandfieldtacticfamilies}]{\sphinxcrossref{\DUrole{std,std-ref}{The ring and field tactic families}}}} for more information on
the tactic and how to declare new ring structures. All declared field structures
can be printed with the \sphinxcode{\sphinxupquote{Print Rings}} command.
\index{field (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.field}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{field}}}}
\end{fulllineitems}

\index{field\_simplify (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.field-simplify}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{field\_simplify~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}

\index{field\_simplify\_eq (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.field-simplify-eq}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{field\_simplify\_eq}}}}
\end{fulllineitems}


The field tactic is built on the same ideas as ring: this is a
reflexive tactic that solves or simplifies equations in a field
structure. The main idea is to reduce a field expression (which is an
extension of ring expressions with the inverse and division
operations) to a fraction made of two polynomial expressions.

Tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{field}}} is used to solve subgoals, whereas \sphinxcode{\sphinxupquote{\DUrole{notation}{field\_simplify \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}}}}}
replaces the provided terms by their reduced fraction.
\sphinxcode{\sphinxupquote{\DUrole{notation}{field\_simplify\_eq}}} applies when the conclusion is an equation: it
simplifies both hand sides and multiplies so as to cancel
denominators. So it produces an equation without division nor inverse.

All of these 3 tactics may generate a subgoal in order to prove that
denominators are different from zero.

See {\hyperref[\detokenize{addendum/ring:theringandfieldtacticfamilies}]{\sphinxcrossref{\DUrole{std,std-ref}{The ring and field tactic families}}}} for more information on the tactic and how to
declare new field structures. All declared field structures can be
printed with the Print Fields command.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Reals}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{z\PYGZus{}syntax\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{r\PYGZus{}syntax\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{quote\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{newring\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{omega\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{fourier\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{micromega\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}

\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{:}\PYG{n}{R}\PYG{o}{,}
\PYG{o}{(}\PYG{n}{x} \PYG{o}{*} \PYG{n}{y} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{R} \PYG{o}{\PYGZhy{}\PYGZgt{}}
\PYG{o}{(}\PYG{n}{x} \PYG{o}{*} \PYG{o}{(}\PYG{l+m+mi}{1} \PYG{o}{/} \PYG{n}{x} \PYG{o}{+} \PYG{n}{x} \PYG{o}{/} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{R} \PYG{o}{=}
\PYG{o}{(}\PYG{o}{(}\PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1} \PYG{o}{/} \PYG{n}{y}\PYG{o}{)} \PYG{o}{*} \PYG{n}{y} \PYG{o}{*} \PYG{o}{(}\PYG{o}{\PYGZhy{}} \PYG{n}{x} \PYG{o}{*} \PYG{o}{(}\PYG{n}{x} \PYG{o}{/} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{R}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{R}\PYG{o}{,}
      \PYG{o}{(}\PYG{n}{x} \PYG{o}{*} \PYG{n}{y} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{R} \PYG{o}{\PYGZhy{}\PYGZgt{}}
      \PYG{o}{(}\PYG{n}{x} \PYG{o}{*} \PYG{o}{(}\PYG{l+m+mi}{1} \PYG{o}{/} \PYG{n}{x} \PYG{o}{+} \PYG{n}{x} \PYG{o}{/} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{R} \PYG{o}{=} \PYG{o}{(}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1} \PYG{o}{/} \PYG{n}{y} \PYG{o}{*} \PYG{n}{y} \PYG{o}{*} \PYG{o}{(}\PYG{o}{\PYGZhy{}} \PYG{n}{x} \PYG{o}{*} \PYG{o}{(}\PYG{n}{x} \PYG{o}{/} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{R}

\PYG{k}{intros}\PYG{o}{;} \PYG{k}{field}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{R}
      \PYG{n}{H} \PYG{o}{:} \PYG{o}{(}\PYG{n}{x} \PYG{o}{*} \PYG{n}{y} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{R}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{R} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{\PYGZpc{}}\PYG{n}{R} \PYG{o}{/\PYGZbs{}} \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{\PYGZpc{}}\PYG{n}{R} \PYG{o}{/\PYGZbs{}} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{\PYGZpc{}}\PYG{n}{R}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\sphinxstrong{See also:}


File plugins/setoid\_ring/RealField.v for an example of instantiation,
theory theories/Reals for many examples of use of field.


\index{fourier (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.fourier}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{fourier}}}}
\end{fulllineitems}


This tactic written by Loïc Pottier solves linear inequalities on real
numbers using Fourier’s method \sphinxcite{zebibliography:fourier}. This tactic must be loaded by
\sphinxcode{\sphinxupquote{Require Import Fourier}}.

\begin{sphinxadmonition}{note}{Example: .. coqtop:: reset all}
\begin{quote}

Require Import Reals.
Require Import Fourier.
Goal forall x y:R, (x \textless{} y)\%R -\textgreater{} (y + 1 \textgreater{}= x - 1)\%R.
intros; fourier.
\end{quote}
\end{sphinxadmonition}


\subsection{Non-logical tactics}
\label{\detokenize{proof-engine/tactics:non-logical-tactics}}\index{cycle (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.cycle}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{cycle~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This tactic puts the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} first goals at the end of the list of goals.
If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} is negative, it will put the last \(|num|\) goals at the
beginning of the list.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{P} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Goal} \PYG{n}{P} \PYG{l+m+mi}{1} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{2} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{3} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{4} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{5}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{l+m+mi}{1} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{2} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{3} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{4} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{5}

\PYG{k+kr}{repeat} \PYG{k}{split}\PYG{o}{.}
    \PYG{l+m+mi}{5} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{l+m+mi}{1}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{3}
    \PYG{n}{subgoal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
    \PYG{n}{subgoal} \PYG{l+m+mi}{5} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{5}

\PYG{n}{all}\PYG{o}{:} \PYG{n}{cycle} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{l+m+mi}{5} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{l+m+mi}{3}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{5}
    \PYG{n}{subgoal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{1}
    \PYG{n}{subgoal} \PYG{l+m+mi}{5} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}

\PYG{n}{all}\PYG{o}{:} \PYG{n}{cycle} \PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{3}\PYG{o}{.}
    \PYG{l+m+mi}{5} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{l+m+mi}{5}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{1}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}
    \PYG{n}{subgoal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{3}
    \PYG{n}{subgoal} \PYG{l+m+mi}{5} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{swap (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.swap}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{swap~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This tactic switches the position of the goals of indices \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} and
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}. If either \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} or \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} is negative then goals are
counted from the end of the focused goal list. Goals are indexed from 1,
there is no goal with position 0.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{P} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Goal} \PYG{n}{P} \PYG{l+m+mi}{1} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{2} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{3} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{4} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{5}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{l+m+mi}{1} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{2} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{3} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{4} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{5}

\PYG{k+kr}{repeat} \PYG{k}{split}\PYG{o}{.}
    \PYG{l+m+mi}{5} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{l+m+mi}{1}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{3}
    \PYG{n}{subgoal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
    \PYG{n}{subgoal} \PYG{l+m+mi}{5} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{5}

\PYG{n}{all}\PYG{o}{:} \PYG{n}{swap} \PYG{l+m+mi}{1} \PYG{l+m+mi}{3}\PYG{o}{.}
    \PYG{l+m+mi}{5} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{l+m+mi}{3}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{1}
    \PYG{n}{subgoal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
    \PYG{n}{subgoal} \PYG{l+m+mi}{5} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{5}

\PYG{n}{all}\PYG{o}{:} \PYG{n}{swap} \PYG{l+m+mi}{1} \PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{1}\PYG{o}{.}
    \PYG{l+m+mi}{5} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{l+m+mi}{5}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{1}
    \PYG{n}{subgoal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
    \PYG{n}{subgoal} \PYG{l+m+mi}{5} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{3}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{revgoals (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.revgoals}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{revgoals}}}}
\end{fulllineitems}


This tactics reverses the list of the focused goals.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{P} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Goal} \PYG{n}{P} \PYG{l+m+mi}{1} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{2} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{3} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{4} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{5}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{l+m+mi}{1} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{2} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{3} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{4} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{l+m+mi}{5}

\PYG{k+kr}{repeat} \PYG{k}{split}\PYG{o}{.}
    \PYG{l+m+mi}{5} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{l+m+mi}{1}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{3}
    \PYG{n}{subgoal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
    \PYG{n}{subgoal} \PYG{l+m+mi}{5} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{5}

\PYG{n}{all}\PYG{o}{:} \PYG{n}{revgoals}\PYG{o}{.}
    \PYG{l+m+mi}{5} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{l+m+mi}{5}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{4}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{3}
    \PYG{n}{subgoal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{2}
    \PYG{n}{subgoal} \PYG{l+m+mi}{5} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{l+m+mi}{1}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{shelve (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.shelve}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{shelve}}}}
This tactic moves all goals under focus to a shelf. While on the
shelf, goals will not be focused on. They can be solved by
unification, or they can be called back into focus with the command
{\hyperref[\detokenize{proof-engine/tactics:coq:cmd.unshelve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Unshelve}}}}}.
\index{shelve\_unifiable (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacv.shelve-unifiable}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{shelve\_unifiable}}}}
Shelves only the goals under focus that are mentioned in other goals.
Goals that appear in the type of other goals can be solved by unification.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{exists} \PYG{n}{n}\PYG{o}{,} \PYG{n}{n}\PYG{o}{=}\PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{exists} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{k}{refine} \PYG{o}{(}\PYG{n}{ex\PYGZus{}intro} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{focused} \PYG{n}{subgoal}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{1}\PYG{o}{)}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{?}\PYG{k+kn}{Goal} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{n}{all}\PYG{o}{:} \PYG{n}{shelve\PYGZus{}unifiable}\PYG{o}{.}
\PYG{k+kp}{reflexivity}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}


\end{fulllineitems}

\index{Unshelve (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:cmd.unshelve}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unshelve}}}}
This command moves all the goals on the shelf (see {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.shelve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{shelve}}}}})
from the shelf into focus, by appending them to the end of the current
list of focused goals.

\end{fulllineitems}

\index{give\_up (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/tactics:coq:tacn.give-up}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{give\_up}}}}
This tactic removes the focused goals from the proof. They are not
solved, and cannot be solved later in the proof. As the goals are not
solved, the proof cannot be closed.

The \sphinxcode{\sphinxupquote{give\_up}} tactic can be used while editing a proof, to choose to
write the proof script in a non-sequential order.

\end{fulllineitems}



\subsection{Simple tactic macros}
\label{\detokenize{proof-engine/tactics:simple-tactic-macros}}
A simple example has more value than a long explanation:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{Solve} \PYG{o}{:=} \PYG{k}{simpl}\PYG{o}{;} \PYG{k}{intros}\PYG{o}{;} \PYG{k}{auto}\PYG{o}{.}
    \PYG{n}{Solve} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Ltac} \PYG{n}{ElimBoolRewrite} \PYG{n}{b} \PYG{n}{H1} \PYG{n}{H2} \PYG{o}{:=}
\PYG{k}{elim} \PYG{n}{b}\PYG{o}{;} \PYG{o}{[} \PYG{k}{intros}\PYG{o}{;} \PYG{k}{rewrite} \PYG{n}{H1}\PYG{o}{;} \PYG{k}{eauto} \PYG{o}{\textbar{}} \PYG{k}{intros}\PYG{o}{;} \PYG{k}{rewrite} \PYG{n}{H2}\PYG{o}{;} \PYG{k}{eauto} \PYG{o}{]}\PYG{o}{.}
    \PYG{n}{ElimBoolRewrite} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The tactics macros are synchronous with the Coq section mechanism: a
tactic definition is deleted from the current environment when you
close the section (see also {\hyperref[\detokenize{language/gallina-extensions:section-mechanism}]{\sphinxcrossref{\DUrole{std,std-ref}{Section mechanism}}}}) where it was
defined. If you want that a tactic macro defined in a module is usable in the
modules that require it, you should put it outside of any section.

{\hyperref[\detokenize{proof-engine/ltac:ltac}]{\sphinxcrossref{\DUrole{std,std-ref}{The tactic language}}}} gives examples of more complex
user-defined tactics.


\section{The tactic language}
\label{\detokenize{proof-engine/ltac:the-tactic-language}}\label{\detokenize{proof-engine/ltac:ltac}}\label{\detokenize{proof-engine/ltac::doc}}
This chapter gives a compact documentation of \sphinxtitleref{L}$_{\text{tac}}$, the tactic language
available in \DUrole{smallcaps}{Coq}. We start by giving the syntax, and next, we present the
informal semantics. If you want to know more regarding this language and
especially about its foundations, you can refer to \sphinxcite{zebibliography:del00}. Chapter
{\hyperref[\detokenize{proof-engine/detailed-tactic-examples:detailedexamplesoftactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Detailed examples of tactics}}}} is devoted to giving small but nontrivial
use examples of this language.


\subsection{Syntax}
\label{\detokenize{proof-engine/ltac:syntax}}\label{\detokenize{proof-engine/ltac:ltac-syntax}}
The syntax of the tactic language is given below. See Chapter
{\hyperref[\detokenize{language/gallina-specification-language:gallinaspecificationlanguage}]{\sphinxcrossref{\DUrole{std,std-ref}{The Gallina specification language}}}} for a description of the BNF metasyntax used
in these grammar rules. Various already defined entries will be used in this
chapter: entries {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}}, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}},
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}, {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}, \sphinxcode{\sphinxupquote{cpattern}} and \sphinxcode{\sphinxupquote{atomic\_tactic}}
represent respectively the natural and integer numbers, the authorized
identificators and qualified names, Coq terms and patterns and all the atomic
tactics described in Chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}}. The syntax of \sphinxcode{\sphinxupquote{cpattern}} is
the same as that of terms, but it is extended with pattern matching
metavariables. In \sphinxcode{\sphinxupquote{cpattern}}, a pattern matching metavariable is
represented with the syntax \sphinxcode{\sphinxupquote{\DUrole{operator}{?}\DUrole{name}{id}}} where \sphinxcode{\sphinxupquote{\DUrole{name}{id}}} is an {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}. The
notation \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}} can also be used to denote metavariable whose instance is
irrelevant. In the notation \sphinxcode{\sphinxupquote{\DUrole{operator}{?}\DUrole{name}{id}}}, the identifier allows us to keep
instantiations and to make constraints whereas \sphinxcode{\sphinxupquote{\DUrole{operator}{\_}}} shows that we are not
interested in what will be matched. On the right hand side of pattern matching
clauses, the named metavariables are used without the question mark prefix. There
is also a special notation for second-order pattern matching problems: in an
applicative pattern of the form \sphinxcode{\sphinxupquote{\DUrole{operator}{@?}\DUrole{name}{id} \DUrole{name}{id1} \DUrole{error}{…} \DUrole{name}{idn}}}, the variable id matches any
complex expression with (possible) dependencies in the variables \sphinxcode{\sphinxupquote{\DUrole{name}{id1} \DUrole{error}{…} \DUrole{name}{idn}}}
and returns a functional term of the form \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{name}{id1} \DUrole{error}{…} \DUrole{name}{idn} \DUrole{operator}{=\textgreater{}} \DUrole{name}{term}}}.

The main entry of the grammar is \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}. This language is used in proof
mode but it can also be used in toplevel definitions as shown below.

\begin{sphinxadmonition}{note}{Note:}\begin{itemize}
\item {} 
The infix tacticals “… \textbar{}\textbar{} …”, “… + …”, and “… ; …” are associative.

\item {} 
In {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacarg}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacarg}}}}}, there is an overlap between qualid as a direct tactic
argument and {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} as a particular case of term. The resolution is
done by first looking for a reference of the tactic language and if
it fails, for a reference to a term. To force the resolution as a
reference of the tactic language, use the form \sphinxcode{\sphinxupquote{\DUrole{name}{ltac}\DUrole{operator}{:(@}\DUrole{name}{qualid}\DUrole{operator}{)}}}. To
force the resolution as a reference to a term, use the syntax
\sphinxcode{\sphinxupquote{\DUrole{operator}{(@}\DUrole{name}{qualid}\DUrole{operator}{)}}}.

\item {} 
As shown by the figure, tactical \sphinxcode{\sphinxupquote{\textbackslash{}\textbar{}\textbackslash{}\textbar{}}} binds more than the prefix
tacticals try, repeat, do and abstract which themselves bind more
than the postfix tactical “… ;{[} … {]}” which binds more than “… ; …”.

For instance

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kr}{try} \PYG{k+kr}{repeat} \PYG{n}{tac1} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{tac2}\PYG{o}{;} \PYG{n}{tac3}\PYG{o}{;} \PYG{o}{[}\PYG{n}{tac31} \PYG{o}{\textbar{}} \PYG{o}{..}\PYG{o}{.} \PYG{o}{\textbar{}} \PYG{n}{tac3n}\PYG{o}{]}\PYG{o}{;} \PYG{n}{tac4}\PYG{o}{.}
\end{sphinxVerbatim}

is understood as

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kr}{try} \PYG{o}{(}\PYG{k+kr}{repeat} \PYG{o}{(}\PYG{n}{tac1} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{tac2}\PYG{o}{)}\PYG{o}{)}\PYG{o}{;}
  \PYG{o}{(}\PYG{o}{(}\PYG{n}{tac3}\PYG{o}{;} \PYG{o}{[}\PYG{n}{tac31} \PYG{o}{\textbar{}} \PYG{o}{..}\PYG{o}{.} \PYG{o}{\textbar{}} \PYG{n}{tac3n}\PYG{o}{]}\PYG{o}{)}\PYG{o}{;} \PYG{n}{tac4}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\end{itemize}
\end{sphinxadmonition}


\begin{productionlist}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-expr}}\production{expr}{ {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} ; {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}}}
\productioncont{ \textbar{} {[}\textgreater{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} {]}}
\productioncont{ \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} ; {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} {]}}
\productioncont{ \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr3}}}}}}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-tacexpr3}}\production{tacexpr3}{ do ({\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}} \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}) tacexpr3}
\productioncont{ \textbar{} progress {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr3}}}}}}
\productioncont{ \textbar{} repeat {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr3}}}}}}
\productioncont{ \textbar{} try {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr3}}}}}}
\productioncont{ \textbar{} once {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr3}}}}}}
\productioncont{ \textbar{} exactly\_once {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr3}}}}}}
\productioncont{ \textbar{} timeout ({\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}} \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}) {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr3}}}}}}
\productioncont{ \textbar{} time {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}}{]} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr3}}}}}}
\productioncont{ \textbar{} only {\hyperref[\detokenize{proof-engine/ltac:grammar-token-selector}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{selector}}}}}: {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr3}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr2}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr2}}}}}}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-tacexpr2}}\production{tacexpr2}{ {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr1}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr1}}}}} \textbar{}\textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr3}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr1}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr1}}}}} + {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr3}}}}}}
\productioncont{ \textbar{} tryif {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr1}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr1}}}}} then {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr1}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr1}}}}} else {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr1}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr1}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr1}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr1}}}}}}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-tacexpr1}}\production{tacexpr1}{ fun {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} ... {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} =\textgreater{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-atom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{atom}}}}}}
\productioncont{ \textbar{} let {[}rec{]} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-let-clause}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{let\_clause}}}}} with ... with {\hyperref[\detokenize{proof-engine/ltac:grammar-token-let-clause}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{let\_clause}}}}} in {\hyperref[\detokenize{proof-engine/ltac:grammar-token-atom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{atom}}}}}}
\productioncont{ \textbar{} match goal with {\hyperref[\detokenize{proof-engine/ltac:grammar-token-context-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context\_rule}}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-context-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context\_rule}}}}} end}
\productioncont{ \textbar{} match reverse goal with {\hyperref[\detokenize{proof-engine/ltac:grammar-token-context-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context\_rule}}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-context-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context\_rule}}}}} end}
\productioncont{ \textbar{} match {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} with {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match\_rule}}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match\_rule}}}}} end}
\productioncont{ \textbar{} lazymatch goal with {\hyperref[\detokenize{proof-engine/ltac:grammar-token-context-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context\_rule}}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-context-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context\_rule}}}}} end}
\productioncont{ \textbar{} lazymatch reverse goal with {\hyperref[\detokenize{proof-engine/ltac:grammar-token-context-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context\_rule}}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-context-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context\_rule}}}}} end}
\productioncont{ \textbar{} lazymatch {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} with {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match\_rule}}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match\_rule}}}}} end}
\productioncont{ \textbar{} multimatch goal with {\hyperref[\detokenize{proof-engine/ltac:grammar-token-context-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context\_rule}}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-context-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context\_rule}}}}} end}
\productioncont{ \textbar{} multimatch reverse goal with {\hyperref[\detokenize{proof-engine/ltac:grammar-token-context-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context\_rule}}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-context-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context\_rule}}}}} end}
\productioncont{ \textbar{} multimatch {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} with {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match\_rule}}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-match-rule}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match\_rule}}}}} end}
\productioncont{ \textbar{} abstract {\hyperref[\detokenize{proof-engine/ltac:grammar-token-atom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{atom}}}}}}
\productioncont{ \textbar{} abstract {\hyperref[\detokenize{proof-engine/ltac:grammar-token-atom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{atom}}}}} using {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}}
\productioncont{ \textbar{} first {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} {]}}
\productioncont{ \textbar{} solve {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} {]}}
\productioncont{ \textbar{} idtac {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-message-token}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{message\_token}}}}} ... {\hyperref[\detokenize{proof-engine/ltac:grammar-token-message-token}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{message\_token}}}}}{]}}
\productioncont{ \textbar{} fail {[}{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}{]} {[}{\hyperref[\detokenize{proof-engine/ltac:grammar-token-message-token}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{message\_token}}}}} ... {\hyperref[\detokenize{proof-engine/ltac:grammar-token-message-token}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{message\_token}}}}}{]}}
\productioncont{ \textbar{} fresh {[} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-component}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{component}}}}} … {\hyperref[\detokenize{proof-engine/ltac:grammar-token-component}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{component}}}}} {]}}
\productioncont{ \textbar{} context {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}{]}}
\productioncont{ \textbar{} eval \sphinxcode{\sphinxupquote{redexpr}} in {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} constr : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} uconstr : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} type\_term {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} numgoals}
\productioncont{ \textbar{} guard {\hyperref[\detokenize{proof-engine/ltac:grammar-token-test}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{test}}}}}}
\productioncont{ \textbar{} assert\_fails {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr3}}}}}}
\productioncont{ \textbar{} assert\_succeeds {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacexpr3}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacexpr3}}}}}}
\productioncont{ \textbar{} \sphinxcode{\sphinxupquote{atomic\_tactic}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacarg}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacarg}}}}} ... {\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacarg}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tacarg}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-atom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{atom}}}}}}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-atom}}\production{atom}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}}
\productioncont{ \textbar{} ()}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}}}
\productioncont{ \textbar{} ( {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} )}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-component}}\production{component}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}} \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-message_token}}\production{message\_token}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}} \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}}}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-tacarg}}\production{tacarg}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}}
\productioncont{ \textbar{} ()}
\productioncont{ \textbar{} ltac : {\hyperref[\detokenize{proof-engine/ltac:grammar-token-atom}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{atom}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-let_clause}}\production{let\_clause}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} ... {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}}{]} := {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}}}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-context_rule}}\production{context\_rule}{ {\hyperref[\detokenize{proof-engine/ltac:grammar-token-context-hyp}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context\_hyp}}}}}, ..., {\hyperref[\detokenize{proof-engine/ltac:grammar-token-context-hyp}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{context\_hyp}}}}} \textbar{}- \sphinxcode{\sphinxupquote{cpattern}} =\textgreater{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}}}
\productioncont{ \textbar{} \sphinxcode{\sphinxupquote{cpattern}} =\textgreater{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}}}
\productioncont{ \textbar{} \textbar{}- \sphinxcode{\sphinxupquote{cpattern}} =\textgreater{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}}}
\productioncont{ \textbar{} \_ =\textgreater{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}}}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-context_hyp}}\production{context\_hyp}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} : \sphinxcode{\sphinxupquote{cpattern}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{name}}}}} := \sphinxcode{\sphinxupquote{cpattern}} {[}: \sphinxcode{\sphinxupquote{cpattern}}{]}}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-match_rule}}\production{match\_rule}{ \sphinxcode{\sphinxupquote{cpattern}} =\textgreater{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}}}
\productioncont{ \textbar{} context {[}ident{]} {[} \sphinxcode{\sphinxupquote{cpattern}} {]} =\textgreater{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}}}
\productioncont{ \textbar{} \_ =\textgreater{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}}}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-test}}\production{test}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}} = {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}} (\textless{} \textbar{} \textless{}= \textbar{} \textgreater{} \textbar{} \textgreater{}=) {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}}}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-selector}}\production{selector}{ {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}{]}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}}}
\productioncont{ ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}} \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}} - {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}}), ..., ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}} \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}} - {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-integer}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{integer}}}}})}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-toplevel_selector}}\production{toplevel\_selector}{ {\hyperref[\detokenize{proof-engine/ltac:grammar-token-selector}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{selector}}}}}}
\productioncont{ \textbar{} \sphinxcode{\sphinxupquote{all}}}
\productioncont{ \textbar{} \sphinxcode{\sphinxupquote{par}}}
\end{productionlist}



\begin{productionlist}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-top}}\production{top}{ {[}Local{]} Ltac {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac-def}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_def}}}}} with ... with {\hyperref[\detokenize{proof-engine/ltac:grammar-token-ltac-def}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ltac\_def}}}}}}
\phantomsection\label{\detokenize{proof-engine/ltac:grammar-token-ltac_def}}\production{ltac\_def}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} ... {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}{]} := {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} {[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} ... {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}{]} ::= {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}}}
\end{productionlist}



\subsection{Semantics}
\label{\detokenize{proof-engine/ltac:semantics}}\label{\detokenize{proof-engine/ltac:ltac-semantics}}
Tactic expressions can only be applied in the context of a proof. The
evaluation yields either a term, an integer or a tactic. Intermediate
results can be terms or integers but the final result must be a tactic
which is then applied to the focused goals.

There is a special case for \sphinxcode{\sphinxupquote{match goal}} expressions of which the clauses
evaluate to tactics. Such expressions can only be used as end result of
a tactic expression (never as argument of a non-recursive local
definition or of an application).

The rest of this section explains the semantics of every construction of
\sphinxtitleref{L}$_{\text{tac}}$.


\subsubsection{Sequence}
\label{\detokenize{proof-engine/ltac:sequence}}
A sequence is an expression of the following form:
\index{ltac-seq (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.ltac-seq}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}~;~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{2}}$}}}}}}}}
The expression \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}}}} is evaluated to \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}}, which must be
a tactic value. The tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}} is applied to the current goal,
possibly producing more goals. Then \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{2}}$}}}}}}} is evaluated to
produce \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{2}}$}}}, which must be a tactic value. The tactic
\sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{2}}$}}} is applied to all the goals produced by the prior
application. Sequence is associative.

\end{fulllineitems}



\subsubsection{Local application of tactics}
\label{\detokenize{proof-engine/ltac:local-application-of-tactics}}
Different tactics can be applied to the different goals using the
following form:
\index{{[}\textgreater{} ... \textbar{} ... \textbar{} ... {]} (dispatch) (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.dispatch}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{{[}\textgreater{}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\textbar{}}}{]}}}}}
The expressions \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{i}}$}}}}}}} are evaluated to \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{i}}$}}}, for
i = 0, ..., n and all have to be tactics. The \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{i}}$}}} is applied to the
i-th goal, for i = 1, ..., n. It fails if the number of focused goals is not
exactly n.

\begin{sphinxadmonition}{note}{Note:}
If no tactic is given for the i-th goal, it behaves as if the tactic idtac
were given. For instance, \sphinxcode{\sphinxupquote{{[}\textgreater{} \textbar{} auto{]}}} is a shortcut for \sphinxcode{\sphinxupquote{{[}\textgreater{} idtac \textbar{} auto
{]}}}.
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{[}\textgreater{}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{i}}$}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\textbar{}}}~\textbar{}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}~..~\textbar{}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{j}}$}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\textbar{}}}{]}}}}}
In this variant, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} is used for each goal coming after those
covered by the list of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{i}}$}}}}}}} but before those covered by the
list of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{j}}$}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{[}\textgreater{}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\textbar{}}}~\textbar{}~..~\textbar{}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\textbar{}}}{]}}}}}
In this variant, idtac is used for the goals not covered by the two lists of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{[}\textgreater{}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}~..~{]}}}}}
In this variant, the tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} is applied independently to each of
the goals, rather than globally. In particular, if there are no goals, the
tactic is not run at all. A tactic which expects multiple goals, such as
\sphinxcode{\sphinxupquote{swap}}, would act as if a single goal is focused.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{0}}$}}}}~;~{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{i}}$}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\textbar{}}}{]}}}}}
This variant of local tactic application is paired with a sequence. In this
variant, there must be as many \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{i}}$}}}}}}} as goals generated
by the application of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{0}}$}}}}}}} to each of the individual goals
independently. All the above variants work in this form too.
Formally, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}} ; {[} ... {]}}}} is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{{[}\textgreater{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}} ; {[}\textgreater{} ... {]} .. {]}}}}.

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{Goal selectors}
\label{\detokenize{proof-engine/ltac:goal-selectors}}\label{\detokenize{proof-engine/ltac:id2}}
We can restrict the application of a tactic to a subset of the currently
focused goals with:
\index{... : ... (goal selector) (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.goal-selector}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-toplevel-selector}]{\sphinxcrossref{\DUrole{hole}{toplevel\_selector}}}}~:~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
We can also use selectors as a tactical, which allows to use them nested
in a tactic expression, by using the keyword \sphinxcode{\sphinxupquote{only}}:
\index{only ... : ... (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacv.only}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{only~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-selector}]{\sphinxcrossref{\DUrole{hole}{selector}}}}~:~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
When selecting several goals, the tactic {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} is applied globally to all
selected goals.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{[}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}{]}~:~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
In this variant, {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} is applied locally to a goal previously named
by the user (see {\hyperref[\detokenize{language/gallina-extensions:existential-variables}]{\sphinxcrossref{\DUrole{std,std-ref}{Existential variables}}}}).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~:~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
In this variant, {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} is applied locally to the {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}}-th goal.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}-{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}~:~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
In this variant, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} is applied globally to the subset of goals
described by the given ranges. You can write a single \sphinxcode{\sphinxupquote{n}} as a shortcut
for \sphinxcode{\sphinxupquote{n-n}} when specifying multiple ranges.

\end{fulllineitems}

\index{all: ... (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacv.all}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{all:~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
In this variant, {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{expr}}}}} is applied to all focused goals. \sphinxcode{\sphinxupquote{all:}} can only
be used at the toplevel of a tactic expression.

\end{fulllineitems}

\index{par: ... (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacv.par}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{par:~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
In this variant, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} is applied to all focused goals in parallel.
The number of workers can be controlled via the command line option
\sphinxcode{\sphinxupquote{-async-proofs-tac-j}} taking as argument the desired number of workers.
Limitations: \sphinxcode{\sphinxupquote{par:}} only works on goals containing no existential
variables and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} must either solve the goal completely or do
nothing (i.e. it cannot make some progress). \sphinxcode{\sphinxupquote{par:}} can only be used at
the toplevel of a tactic expression.

\end{fulllineitems}

\index{No such goal. (Goal selector) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.no-such-goal-goal-selector}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~goal.}}}}
\end{fulllineitems}


\end{fulllineitems}



\subsubsection{For loop}
\label{\detokenize{proof-engine/ltac:for-loop}}
There is a for loop that repeats a tactic {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}} times:
\index{do (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.do}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{do~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} is evaluated to \sphinxcode{\sphinxupquote{v}} which must be a tactic value. This tactic
value \sphinxcode{\sphinxupquote{v}} is applied {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}} times. Supposing {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}} \textgreater{} 1, after the
first application of \sphinxcode{\sphinxupquote{v}}, \sphinxcode{\sphinxupquote{v}} is applied, at least once, to the generated
subgoals and so on. It fails if the application of \sphinxcode{\sphinxupquote{v}} fails before the num
applications have been completed.

\end{fulllineitems}



\subsubsection{Repeat loop}
\label{\detokenize{proof-engine/ltac:repeat-loop}}
We have a repeat loop with:
\index{repeat (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.repeat}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{repeat~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} is evaluated to \sphinxcode{\sphinxupquote{v}}. If \sphinxcode{\sphinxupquote{v}} denotes a tactic, this tactic is
applied to each focused goal independently. If the application succeeds, the
tactic is applied recursively to all the generated subgoals until it eventually
fails. The recursion stops in a subgoal when the tactic has failed \sphinxstyleemphasis{to make
progress}. The tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{repeat {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} itself never fails.

\end{fulllineitems}



\subsubsection{Error catching}
\label{\detokenize{proof-engine/ltac:error-catching}}
We can catch the tactic errors with:
\index{try (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.try}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{try~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} is evaluated to \sphinxcode{\sphinxupquote{v}} which must be a tactic value. The tactic
value \sphinxcode{\sphinxupquote{v}} is applied to each focused goal independently. If the application of
\sphinxcode{\sphinxupquote{v}} fails in a goal, it catches the error and leaves the goal unchanged. If the
level of the exception is positive, then the exception is re-raised with its
level decremented.

\end{fulllineitems}



\subsubsection{Detecting progress}
\label{\detokenize{proof-engine/ltac:detecting-progress}}
We can check if a tactic made progress with:
\index{progress (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.progress}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{progress~expr}}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} is evaluated to v which must be a tactic value. The tactic value \sphinxcode{\sphinxupquote{v}}
is applied to each focued subgoal independently. If the application of \sphinxcode{\sphinxupquote{v}}
to one of the focused subgoal produced subgoals equal to the initial
goals (up to syntactical equality), then an error of level 0 is raised.
\index{Failed to progress (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.failed-to-progress}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Failed~to~progress.}}}}
\end{fulllineitems}


\end{fulllineitems}



\subsubsection{Backtracking branching}
\label{\detokenize{proof-engine/ltac:backtracking-branching}}
We can branch with the following structure:
\index{+ (backtracking branching) (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.backtracking-branching}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}~+~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{2}}$}}}}}}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{2}}$}}}}}}} are evaluated respectively to \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}} and
\sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{2}}$}}} which must be tactic values. The tactic value \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}} is applied to
each focused goal independently and if it fails or a later tactic fails, then
the proof backtracks to the current goal and \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{2}}$}}} is applied.

Tactics can be seen as having several successes. When a tactic fails it
asks for more successes of the prior tactics.
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}} + {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{2}}$}}}}}}} has all the successes of \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}} followed by all the
successes of \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{2}}$}}}. Algebraically,
\sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}} + {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{2}}$}}}}); {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{3}}$}}}} = ({\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}; {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{3}}$}}}}) + ({\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{2}}$}}}}; {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{3}}$}}}})}}}.

Branching is left-associative.

\end{fulllineitems}



\subsubsection{First tactic to work}
\label{\detokenize{proof-engine/ltac:first-tactic-to-work}}
Backtracking branching may be too expensive. In this case we may
restrict to a local, left biased, branching and consider the first
tactic to work (i.e. which does not fail) among a panel of tactics:
\index{first (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.first}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{first~{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\textbar{}}}{]}}}}}
The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{i}}$}}}}}}} are evaluated to \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{i}}$}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{i}}$}}} must be
tactic values for i = 1, ..., n. Supposing n \textgreater{} 1,
\sphinxcode{\sphinxupquote{\DUrole{notation}{first {[}{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{n}}$}}}}{]}}}} applies \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}} in each
focused goal independently and stops if it succeeds; otherwise it
tries to apply \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{2}}$}}} and so on. It fails when there is no
applicable tactic. In other words,
\sphinxcode{\sphinxupquote{\DUrole{notation}{first {[}{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{n}}$}}}}{]}}}} behaves, in each goal, as the first
\sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{i}}$}}} to have \sphinxstyleemphasis{at least} one success.
\index{No applicable tactic (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.no-applicable-tactic}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~applicable~tactic.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{first~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
This is an \sphinxtitleref{L}$_{\text{tac}}$ alias that gives a primitive access to the first
tactical as an \sphinxtitleref{L}$_{\text{tac}}$ definition without going through a parsing rule. It
expects to be given a list of tactics through a \sphinxcode{\sphinxupquote{Tactic Notation}},
allowing to write notations of the following form:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Tactic} \PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{foo}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{tactic\PYGZus{}list}\PYG{o}{(}\PYG{n}{tacs}\PYG{o}{)} \PYG{o}{:=} \PYG{k+kr}{first} \PYG{n}{tacs}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{Left-biased branching}
\label{\detokenize{proof-engine/ltac:left-biased-branching}}
Yet another way of branching without backtracking is the following
structure:
\index{\textbar{}\textbar{} (left-biased branching) (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.left-biased-branching}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}~\textbar{}\textbar{}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{2}}$}}}}}}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{2}}$}}}}}}} are evaluated respectively to \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}} and
\sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{2}}$}}} which must be tactic values. The tactic value \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}} is
applied in each subgoal independently and if it fails \sphinxstyleemphasis{to progress} then
\sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{2}}$}}} is applied. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}} \textbar{}\textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{2}}$}}}}}}} is
equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{first {[} progress {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}} \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{2}}$}}}} {]}}}} (except that
if it fails, it fails like \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{2}}$}}}). Branching is left-associative.

\end{fulllineitems}



\subsubsection{Generalized biased branching}
\label{\detokenize{proof-engine/ltac:generalized-biased-branching}}
The tactic
\index{tryif (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.tryif}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{tryif~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}~then~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{2}}$}}}}~else~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{3}}$}}}}}}}}
is a generalization of the biased-branching tactics above. The
expression \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}}}} is evaluated to \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}}, which is then
applied to each subgoal independently. For each goal where \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}}
succeeds at least once, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{2}}$}}}}}}} is evaluated to \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{2}}$}}} which
is then applied collectively to the generated subgoals. The \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{2}}$}}}
tactic can trigger backtracking points in \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}}: where \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}}
succeeds at least once,
\sphinxcode{\sphinxupquote{\DUrole{notation}{tryif {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}} then {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{2}}$}}}} else {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{3}}$}}}}}}} is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$; v$_{\text{2}}$}}}. In each of the goals where \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}} does not succeed at least
once, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{3}}$}}}}}}} is evaluated in \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{3}}$}}} which is is then applied to the
goal.

\end{fulllineitems}



\subsubsection{Soft cut}
\label{\detokenize{proof-engine/ltac:soft-cut}}
Another way of restricting backtracking is to restrict a tactic to a
single success \sphinxstyleemphasis{a posteriori}:
\index{once (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.once}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{once~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} is evaluated to \sphinxcode{\sphinxupquote{v}} which must be a tactic value. The tactic value
\sphinxcode{\sphinxupquote{v}} is applied but only its first success is used. If \sphinxcode{\sphinxupquote{v}} fails,
\sphinxcode{\sphinxupquote{\DUrole{notation}{once {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} fails like \sphinxcode{\sphinxupquote{v}}. If \sphinxcode{\sphinxupquote{v}} has at least one success,
\sphinxcode{\sphinxupquote{\DUrole{notation}{once {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} succeeds once, but cannot produce more successes.

\end{fulllineitems}



\subsubsection{Checking the successes}
\label{\detokenize{proof-engine/ltac:checking-the-successes}}
Coq provides an experimental way to check that a tactic has \sphinxstyleemphasis{exactly
one} success:
\index{exactly\_once (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.exactly-once}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{exactly\_once~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} is evaluated to \sphinxcode{\sphinxupquote{v}} which must be a tactic value. The tactic value
\sphinxcode{\sphinxupquote{v}} is applied if it has at most one success. If \sphinxcode{\sphinxupquote{v}} fails,
\sphinxcode{\sphinxupquote{\DUrole{notation}{exactly\_once {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} fails like \sphinxcode{\sphinxupquote{v}}. If \sphinxcode{\sphinxupquote{v}} has a exactly one success,
\sphinxcode{\sphinxupquote{\DUrole{notation}{exactly\_once {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} succeeds like \sphinxcode{\sphinxupquote{v}}. If \sphinxcode{\sphinxupquote{v}} has two or more
successes, exactly\_once expr fails.

\begin{sphinxadmonition}{warning}{Warning:}
The experimental status of this tactic pertains to the fact if \sphinxcode{\sphinxupquote{v}}
performs side effects, they may occur in an unpredictable way. Indeed,
normally \sphinxcode{\sphinxupquote{v}} would only be executed up to the first success until
backtracking is needed, however exactly\_once needs to look ahead to see
whether a second success exists, and may run further effects
immediately.
\end{sphinxadmonition}
\index{This tactic has more than one success (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.this-tactic-has-more-than-one-success}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{This~tactic~has~more~than~one~success.}}}}
\end{fulllineitems}


\end{fulllineitems}



\subsubsection{Checking the failure}
\label{\detokenize{proof-engine/ltac:checking-the-failure}}
Coq provides a derived tactic to check that a tactic \sphinxstyleemphasis{fails}:
\index{assert\_fails (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.assert-fails}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert\_fails~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
This behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{tryif {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}} then fail 0 tac "succeeds" else idtac}}}.

\end{fulllineitems}



\subsubsection{Checking the success}
\label{\detokenize{proof-engine/ltac:checking-the-success}}
Coq provides a derived tactic to check that a tactic has \sphinxstyleemphasis{at least one}
success:
\index{assert\_succeeds (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.assert-succeeds}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{assert\_succeeds~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
This behaves like
\sphinxcode{\sphinxupquote{\DUrole{notation}{tryif (assert\_fails tac) then fail 0 tac "fails" else idtac}}}.

\end{fulllineitems}



\subsubsection{Solving}
\label{\detokenize{proof-engine/ltac:solving}}
We may consider the first to solve (i.e. which generates no subgoal)
among a panel of tactics:
\index{solve (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.solve}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{solve~{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\textbar{}}}{]}}}}}
The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{i}}$}}}}}}} are evaluated to \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{i}}$}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{i}}$}}} must be
tactic values, for i = 1, ..., n. Supposing n \textgreater{} 1,
\sphinxcode{\sphinxupquote{\DUrole{notation}{solve {[}{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}} \textbar{} ... \textbar{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{n}}$}}}}{]}}}} applies \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}} to
each goal independently and stops if it succeeds; otherwise it tries to
apply \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{2}}$}}} and so on. It fails if there is no solving tactic.
\index{Cannot solve the goal (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.cannot-solve-the-goal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~solve~the~goal.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{solve~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
This is an \sphinxtitleref{L}$_{\text{tac}}$ alias that gives a primitive access to the \sphinxcode{\sphinxupquote{\DUrole{notation}{solve:}}}
tactical. See the \sphinxcode{\sphinxupquote{\DUrole{notation}{first}}} tactical for more information.

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{Identity}
\label{\detokenize{proof-engine/ltac:identity}}
The constant \sphinxcode{\sphinxupquote{\DUrole{notation}{idtac}}} is the identity tactic: it leaves any goal unchanged but
it appears in the proof script.
\index{idtac (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.idtac}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{idtac~\DUrole{repeat-wrapper}{\DUrole{repeat}{message\_token}\DUrole{notation-sup}{*}}}}}}
This prints the given tokens. Strings and integers are printed
literally. If a (term) variable is given, its contents are printed.

\end{fulllineitems}



\subsubsection{Failing}
\label{\detokenize{proof-engine/ltac:failing}}\index{fail (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.fail}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{fail}}}}
This is the always-failing tactic: it does not solve any
goal. It is useful for defining other tacticals since it can be caught by
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.try}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{try}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.repeat}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{repeat}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match-goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match goal}}}}}, or the branching tacticals.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{fail~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
The number is the failure level. If no level is specified, it defaults to 0.
The level is used by {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.try}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{try}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.repeat}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{repeat}}}}}, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match-goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match goal}}}}} and the branching
tacticals. If 0, it makes {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match-goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match goal}}}}} consider the next clause
(backtracking). If nonzero, the current {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.match-goal}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{match goal}}}}} block, {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.try}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{try}}}}},
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.repeat}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{repeat}}}}}, or branching command is aborted and the level is decremented. In
the case of \sphinxcode{\sphinxupquote{\DUrole{notation}{+}}}, a nonzero level skips the first backtrack point, even if
the call to \sphinxcode{\sphinxupquote{\DUrole{notation}{fail {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} is not enclosed in a \sphinxcode{\sphinxupquote{\DUrole{notation}{+}}} command,
respecting the algebraic identity.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{fail~\DUrole{repeat-wrapper}{\DUrole{repeat}{message\_token}\DUrole{notation-sup}{*}}}}}}
The given tokens are used for printing the failure message.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{fail~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{message\_token}\DUrole{notation-sup}{*}}}}}}
This is a combination of the previous variants.

\end{fulllineitems}

\index{gfail (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacv.gfail}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{gfail}}}}
This variant fails even when used after \sphinxcode{\sphinxupquote{\DUrole{notation}{;}}} and there are no goals left.
Similarly, \sphinxcode{\sphinxupquote{gfail}} fails even when used after \sphinxcode{\sphinxupquote{all:}} and there are no
goals left. See the example for clarification.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{gfail~\DUrole{repeat-wrapper}{\DUrole{repeat}{message\_token}\DUrole{notation-sup}{*}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{gfail~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{message\_token}\DUrole{notation-sup}{*}}}}}}
These variants fail with an error message or an error level even if
there are no goals left. Be careful however if Coq terms have to be
printed as part of the failure: term construction always forces the
tactic into the goals, meaning that if there are no goals when it is
evaluated, a tactic call like \sphinxcode{\sphinxupquote{\DUrole{notation}{let x := H in fail 0 x}}} will succeed.

\end{fulllineitems}

\index{Tactic Failure message (level ‘num’) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.tactic-failure-message-level-num}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Tactic~Failure~message~(level~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}).}}}}
\end{fulllineitems}

\index{No such goal. (fail) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.no-such-goal-fail}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~such~goal.}}}}
\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{n}{fail}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{5}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{n}{fail}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:} \PYG{k+kn}{Tactic} \PYG{n}{failure}\PYG{o}{.}

\PYG{n}{Abort}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{trivial}\PYG{o}{;} \PYG{n}{fail}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{Unnamed\PYGZus{}thm} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{trivial}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{n}{fail}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{5}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{n}{fail}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:} \PYG{n}{No} \PYG{n}{such} \PYG{n}{goal}\PYG{o}{.}

\PYG{n}{Abort}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{trivial}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{n}{all}\PYG{o}{:} \PYG{n}{fail}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{Unnamed\PYGZus{}thm0} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{n}{gfail}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{6}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{n}{gfail}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:} \PYG{k+kn}{Tactic} \PYG{n}{failure}\PYG{o}{.}

\PYG{n}{Abort}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{trivial}\PYG{o}{;} \PYG{n}{gfail}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{15}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k}{trivial}\PYG{o}{;} \PYG{n}{gfail}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:} \PYG{k+kn}{Tactic} \PYG{n}{failure}\PYG{o}{.}

\PYG{n}{Abort}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{trivial}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{n}{gfail}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{6}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{n}{gfail}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:} \PYG{n}{No} \PYG{n}{such} \PYG{n}{goal}\PYG{o}{.}

\PYG{n}{Abort}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{trivial}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{n}{all}\PYG{o}{:} \PYG{n}{gfail}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{11}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{n}{all}\PYG{o}{:} \PYG{n}{gfail}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:} \PYG{k+kn}{Tactic} \PYG{n}{failure}\PYG{o}{.}

\PYG{n}{Abort}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}



\subsubsection{Timeout}
\label{\detokenize{proof-engine/ltac:timeout}}
We can force a tactic to stop if it has not finished after a certain
amount of time:
\index{timeout (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.timeout}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{timeout~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} is evaluated to \sphinxcode{\sphinxupquote{v}} which must be a tactic value. The tactic value
\sphinxcode{\sphinxupquote{v}} is applied normally, except that it is interrupted after \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} seconds
if it is still running. In this case the outcome is a failure.

\begin{sphinxadmonition}{warning}{Warning:}
For the moment, timeout is based on elapsed time in seconds,
which is very machine-dependent: a script that works on a quick machine
may fail on a slow one. The converse is even possible if you combine a
timeout with some other tacticals. This tactical is hence proposed only
for convenience during debugging or other development phases, we strongly
advise you to not leave any timeout in final scripts. Note also that
this tactical isn’t available on the native Windows port of Coq.
\end{sphinxadmonition}

\end{fulllineitems}



\subsubsection{Timing a tactic}
\label{\detokenize{proof-engine/ltac:timing-a-tactic}}
A tactic execution can be timed:
\index{time (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.time}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{time~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
evaluates \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} and displays the running time of the tactic expression, whether it
fails or succeeds. In case of several successes, the time for each successive
run is displayed. Time is in seconds and is machine-dependent. The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}
argument is optional. When provided, it is used to identify this particular
occurrence of time.

\end{fulllineitems}



\subsubsection{Timing a tactic that evaluates to a term}
\label{\detokenize{proof-engine/ltac:timing-a-tactic-that-evaluates-to-a-term}}
Tactic expressions that produce terms can be timed with the experimental
tactic
\index{time\_constr (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.time-constr}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{time\_constr~expr}}}}
which evaluates \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}} ()}}} and displays the time the tactic expression
evaluated, assuming successful evaluation. Time is in seconds and is
machine-dependent.

This tactic currently does not support nesting, and will report times
based on the innermost execution. This is due to the fact that it is
implemented using the tactics
\index{restart\_timer (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.restart-timer}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{restart\_timer~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
\end{fulllineitems}


and
\index{finish\_timing (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.finish-timing}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{finish\_timing~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
\end{fulllineitems}


which (re)set and display an optionally named timer, respectively. The
parenthesized string argument to \sphinxcode{\sphinxupquote{\DUrole{notation}{finish\_timing}}} is also optional, and
determines the label associated with the timer for printing.

By copying the definition of \sphinxcode{\sphinxupquote{\DUrole{notation}{time\_constr}}} from the standard library,
users can achive support for a fixed pattern of nesting by passing
different \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}} parameters to \sphinxcode{\sphinxupquote{\DUrole{notation}{restart\_timer}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{finish\_timing}}}
at each level of nesting.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{time\PYGZus{}constr1} \PYG{n}{tac} \PYG{o}{:=}
  \PYG{k}{let} \PYG{n}{eval\PYGZus{}early} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{goal} \PYG{k}{with} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{restart\PYGZus{}timer} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{(depth 1)}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{end} \PYG{k}{in}
  \PYG{k}{let} \PYG{n}{ret} \PYG{o}{:=} \PYG{n}{tac} \PYG{n+nb+bp}{()} \PYG{k}{in}
  \PYG{k}{let} \PYG{n}{eval\PYGZus{}early} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{goal} \PYG{k}{with} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{finish\PYGZus{}timing} \PYG{o}{(} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Tactic evaluation}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{)} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{(depth 1)}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{end} \PYG{k}{in}
  \PYG{n}{ret}\PYG{o}{.}
    \PYG{n}{time\PYGZus{}constr1} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k}{let} \PYG{n}{v} \PYG{o}{:=} \PYG{n}{time\PYGZus{}constr}
       \PYG{n}{ltac}\PYG{o}{:}\PYG{o}{(}\PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}}
               \PYG{k}{let} \PYG{n}{x} \PYG{o}{:=} \PYG{n}{time\PYGZus{}constr1} \PYG{n}{ltac}\PYG{o}{:}\PYG{o}{(}\PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{constr}\PYG{o}{:}\PYG{o}{(}\PYG{l+m+mi}{10} \PYG{o}{*} \PYG{l+m+mi}{10}\PYG{o}{)}\PYG{o}{)} \PYG{k}{in}
               \PYG{k}{let} \PYG{n}{y} \PYG{o}{:=} \PYG{n}{time\PYGZus{}constr1} \PYG{n}{ltac}\PYG{o}{:}\PYG{o}{(}\PYG{k}{fun} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{eval} \PYG{k}{compute} \PYG{k}{in} \PYG{n}{x}\PYG{o}{)} \PYG{k}{in}
               \PYG{n}{y}\PYG{o}{)} \PYG{k}{in}
  \PYG{k}{pose} \PYG{n}{v}\PYG{o}{.}
    \PYG{k+kn}{Tactic} \PYG{n}{evaluation} \PYG{o}{(}\PYG{n}{depth} \PYG{l+m+mi}{1}\PYG{o}{)} \PYG{n}{ran} \PYG{k}{for} \PYG{l+m+mi}{0}\PYG{o}{.} \PYG{n}{secs} \PYG{o}{(}\PYG{l+m+mi}{0}\PYG{o}{.}\PYG{n}{u}\PYG{o}{,}\PYG{l+m+mi}{0}\PYG{o}{.}\PYG{n}{s}\PYG{o}{)}
    \PYG{k+kn}{Tactic} \PYG{n}{evaluation} \PYG{o}{(}\PYG{n}{depth} \PYG{l+m+mi}{1}\PYG{o}{)} \PYG{n}{ran} \PYG{k}{for} \PYG{l+m+mi}{0}\PYG{o}{.} \PYG{n}{secs} \PYG{o}{(}\PYG{l+m+mi}{0}\PYG{o}{.}\PYG{n}{u}\PYG{o}{,}\PYG{l+m+mi}{0}\PYG{o}{.}\PYG{n}{s}\PYG{o}{)}
    \PYG{k+kn}{Tactic} \PYG{n}{evaluation} \PYG{n}{ran} \PYG{k}{for} \PYG{l+m+mi}{0}\PYG{o}{.} \PYG{n}{secs} \PYG{o}{(}\PYG{l+m+mi}{0}\PYG{o}{.}\PYG{n}{u}\PYG{o}{,}\PYG{l+m+mi}{0}\PYG{o}{.}\PYG{n}{s}\PYG{o}{)}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n} \PYG{o}{:=} \PYG{l+m+mi}{100} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{n}{Abort}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}



\subsubsection{Local definitions}
\label{\detokenize{proof-engine/ltac:local-definitions}}
Local definitions can be done as follows:
\index{let ... := ... (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.let}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{let~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{1}}$}}}}~:=~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}~:=~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{i}}$}}}}}\DUrole{notation-sup}{*}}~in~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{i}}$}}}}}}} is evaluated to \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{i}}$}}}, then, \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} is evaluated
by substituting \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{i}}$}}} to each occurrence of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}}}, for
i = 1, ..., n. There are no dependencies between the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{i}}$}}}}}}} and the
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident$_{\text{i}}$}}}}}}}.

Local definitions can be made recursive by using \sphinxcode{\sphinxupquote{\DUrole{notation}{let rec}}} instead of \sphinxcode{\sphinxupquote{\DUrole{notation}{let}}}.
In this latter case, the definitions are evaluated lazily so that the rec
keyword can be used also in non-recursive cases so as to avoid the eager
evaluation of local definitions.

\end{fulllineitems}



\subsubsection{Application}
\label{\detokenize{proof-engine/ltac:application}}
An application is an expression of the following form:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-tacarg}]{\sphinxcrossref{\DUrole{hole}{tacarg}}}}}\DUrole{notation-sup}{+}}}}}}
The reference \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} must be bound to some defined tactic definition
expecting at least as many arguments as the provided \sphinxcode{\sphinxupquote{\DUrole{notation}{tacarg}}}. The
expressions \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{i}}$}}}}}}} are evaluated to \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{i}}$}}}, for i = 1, ..., n.

\end{fulllineitems}



\subsubsection{Function construction}
\label{\detokenize{proof-engine/ltac:function-construction}}
A parameterized tactic can be built anonymously (without resorting to
local definitions) with:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{fun~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~=\textgreater{}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
Indeed, local definitions of functions are a syntactic sugar for binding
a \sphinxcode{\sphinxupquote{\DUrole{notation}{fun}}} tactic to an identifier.

\end{fulllineitems}



\subsubsection{Pattern matching on terms}
\label{\detokenize{proof-engine/ltac:pattern-matching-on-terms}}
We can carry out pattern matching on terms with:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{match~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{cpattern$_{\text{i}}$}~=\textgreater{}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{i}}$}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textbar{}}}~end}}}}
The expression \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} is evaluated and should yield a term which is
matched against \sphinxcode{\sphinxupquote{\DUrole{notation}{cpattern$_{\text{1}}$}}}. The matching is non-linear: if a
metavariable occurs more than once, it should match the same expression
every time. It is first-order except on the variables of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{@?id}}}
that occur in head position of an application. For these variables, the
matching is second-order and returns a functional term.

Alternatively, when a metavariable of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{?id}}} occurs under binders,
say \sphinxcode{\sphinxupquote{\DUrole{notation}{x$_{\text{1}}$, …, x$_{\text{n}}$}}} and the expression matches, the
metavariable is instantiated by a term which can then be used in any
context which also binds the variables \sphinxcode{\sphinxupquote{\DUrole{notation}{x$_{\text{1}}$, …, x$_{\text{n}}$}}} with
same types. This provides with a primitive form of matching under
context which does not require manipulating a functional term.

If the matching with \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{cpattern$_{\text{1}}$}}}} succeeds, then \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}}}} is
evaluated into some value by substituting the pattern matching
instantiations to the metavariables. If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}}}} evaluates to a
tactic and the match expression is in position to be applied to a goal
(e.g. it is not bound to a variable by a \sphinxcode{\sphinxupquote{\DUrole{notation}{let in}}}), then this tactic is
applied. If the tactic succeeds, the list of resulting subgoals is the
result of the match expression. If \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}}}} does not evaluate to a
tactic or if the match expression is not in position to be applied to a
goal, then the result of the evaluation of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}}}} is the result
of the match expression.

If the matching with \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{cpattern$_{\text{1}}$}}}} fails, or if it succeeds but the
evaluation of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}}}} fails, or if the evaluation of
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}}}} succeeds but returns a tactic in execution position whose
execution fails, then \sphinxcode{\sphinxupquote{\DUrole{notation}{cpattern$_{\text{2}}$}}} is used and so on. The pattern
\sphinxcode{\sphinxupquote{\DUrole{notation}{\_}}} matches any term and shadows all remaining patterns if any. If all
clauses fail (in particular, there is no pattern \sphinxcode{\sphinxupquote{\DUrole{notation}{\_}}}) then a
no-matching-clause error is raised.

Failures in subsequent tactics do not cause backtracking to select new
branches or inside the right-hand side of the selected branch even if it
has backtracking points.
\index{No matching clauses for match (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.no-matching-clauses-for-match}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~matching~clauses~for~match.}}}}
No pattern can be used and, in particular, there is no \sphinxcode{\sphinxupquote{\DUrole{notation}{\_}}} pattern.

\end{fulllineitems}

\index{Argument of match does not evaluate to a term (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.argument-of-match-does-not-evaluate-to-a-term}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Argument~of~match~does~not~evaluate~to~a~term.}}}}
This happens when \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} does not denote a term.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{multimatch~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{cpattern$_{\text{i}}$}~=\textgreater{}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{i}}$}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textbar{}}}~end}}}}
Using multimatch instead of match will allow subsequent tactics to
backtrack into a right-hand side tactic which has backtracking points
left and trigger the selection of a new matching branch when all the
backtracking points of the right-hand side have been consumed.

The syntax \sphinxcode{\sphinxupquote{\DUrole{notation}{match …}}} is, in fact, a shorthand for \sphinxcode{\sphinxupquote{\DUrole{notation}{once multimatch …}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{lazymatch~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{cpattern$_{\text{i}}$}~=\textgreater{}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{i}}$}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textbar{}}}~end}}}}
Using lazymatch instead of match will perform the same pattern
matching procedure but will commit to the first matching branch
rather than trying a new matching if the right-hand side fails. If
the right-hand side of the selected branch is a tactic with
backtracking points, then subsequent failures cause this tactic to
backtrack.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{context~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{[}\DUrole{hole}{cpattern}{]}}}}}
This special form of patterns matches any term with a subterm matching
cpattern. If there is a match, the optional \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is assigned the "matched
context", i.e. the initial term where the matched subterm is replaced by a
hole. The example below will show how to use such term contexts.

If the evaluation of the right-hand-side of a valid match fails, the next
matching subterm is tried. If no further subterm matches, the next clause
is tried. Matching subterms are considered top-bottom and from left to
right (with respect to the raw printing obtained by setting option
{\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-all}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}}).

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{f} \PYG{n}{x} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{x} \PYG{k}{with}
    \PYG{n}{context} \PYG{n}{f} \PYG{o}{[}\PYG{n}{S} \PYG{o}{?}\PYG{n}{X}\PYG{o}{]} \PYG{o}{=\PYGZgt{}}
    \PYG{k+kr}{idtac} \PYG{n}{X}\PYG{o}{;}                    \PYG{c}{(*}\PYG{c}{ To display the evaluation order }\PYG{c}{*)}
    \PYG{k}{assert} \PYG{o}{(}\PYG{n}{p} \PYG{o}{:=} \PYG{n}{eq\PYGZus{}refl} \PYG{l+m+mi}{1} \PYG{o}{:} \PYG{n}{X}\PYG{o}{=}\PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{;}    \PYG{c}{(*}\PYG{c}{ To filter the case X=1 }\PYG{c}{*)}
    \PYG{k}{let} \PYG{n}{x}\PYG{o}{:=} \PYG{n}{context} \PYG{n}{f}\PYG{o}{[}\PYG{n}{O}\PYG{o}{]} \PYG{k}{in} \PYG{k}{assert} \PYG{o}{(}\PYG{n}{x}\PYG{o}{=}\PYG{n}{O}\PYG{o}{)} \PYG{c}{(*}\PYG{c}{ To observe the context }\PYG{c}{*)}
  \PYG{k}{end}\PYG{o}{.}
    \PYG{n}{f} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Goal} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{n}{f} \PYG{o}{(}\PYG{l+m+mi}{3}\PYG{o}{+}\PYG{l+m+mi}{4}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{2}
    \PYG{l+m+mi}{1}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{p} \PYG{o}{:} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{l+m+mi}{1}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{1} \PYG{o}{+} \PYG{l+m+mi}{4} \PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}



\subsubsection{Pattern matching on goals}
\label{\detokenize{proof-engine/ltac:pattern-matching-on-goals}}\label{\detokenize{proof-engine/ltac:ltac-match-goal}}
We can perform pattern matching on goals using the following expression:
\index{match goal (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.match-goal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{match~goal~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{hyp}\DUrole{notation-sup}{+}}~\textbar{}-~\DUrole{hole}{cpattern}~=\textgreater{}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textbar{}}}~\textbar{}~\_~=\textgreater{}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}~end}}}}
If each hypothesis pattern \sphinxcode{\sphinxupquote{\DUrole{notation}{hyp}}}$_{\text{1,i}}$, with i = 1, ..., m$_{\text{1}}$ is
matched (non-linear first-order unification) by a hypothesis of the
goal and if \sphinxcode{\sphinxupquote{\DUrole{notation}{cpattern\_1}}} is matched by the conclusion of the goal,
then \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr$_{\text{1}}$}}}}}}} is evaluated to \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}} by substituting the
pattern matching to the metavariables and the real hypothesis names
bound to the possible hypothesis names occurring in the hypothesis
patterns. If \sphinxcode{\sphinxupquote{\DUrole{notation}{v$_{\text{1}}$}}} is a tactic value, then it is applied to the
goal. If this application fails, then another combination of hypotheses
is tried with the same proof context pattern. If there is no other
combination of hypotheses then the second proof context pattern is tried
and so on. If the next to last proof context pattern fails then
the last \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} is evaluated to \sphinxcode{\sphinxupquote{\DUrole{notation}{v}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{v}}} is
applied. Note also that matching against subterms (using the \sphinxcode{\sphinxupquote{\DUrole{notation}{context
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} {[} \DUrole{hole}{cpattern} {]}}}}) is available and is also subject to yielding several
matchings.

Failures in subsequent tactics do not cause backtracking to select new
branches or combinations of hypotheses, or inside the right-hand side of
the selected branch even if it has backtracking points.
\index{No matching clauses for match goal (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.no-matching-clauses-for-match-goal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~matching~clauses~for~match~goal.}}}}
No clause succeeds, i.e. all matching patterns, if any, fail at the
application of the right-hand-side.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}
It is important to know that each hypothesis of the goal can be matched
by at most one hypothesis pattern. The order of matching is the
following: hypothesis patterns are examined from right to left
(i.e. hyp$_{\text{i,m}}$$_{\text{i{}`}}$ before hyp$_{\text{i,1}}$). For each
hypothesis pattern, the goal hypotheses are matched in order (newest
first), but it possible to reverse this order (oldest first)
with the \sphinxcode{\sphinxupquote{\DUrole{notation}{match reverse goal with}}} variant.
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{multimatch~goal~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{hyp}\DUrole{notation-sup}{+}}~\textbar{}-~\DUrole{hole}{cpattern}~=\textgreater{}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textbar{}}}~\textbar{}~\_~=\textgreater{}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}~end}}}}
Using \sphinxcode{\sphinxupquote{\DUrole{notation}{multimatch}}} instead of \sphinxcode{\sphinxupquote{\DUrole{notation}{match}}} will allow subsequent tactics
to backtrack into a right-hand side tactic which has backtracking points
left and trigger the selection of a new matching branch or combination of
hypotheses when all the backtracking points of the right-hand side have
been consumed.

The syntax \sphinxcode{\sphinxupquote{\DUrole{notation}{match {[}reverse{]} goal …}}} is, in fact, a shorthand for
\sphinxcode{\sphinxupquote{\DUrole{notation}{once multimatch {[}reverse{]} goal …}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{lazymatch~goal~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{hyp}\DUrole{notation-sup}{+}}~\textbar{}-~\DUrole{hole}{cpattern}~=\textgreater{}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textbar{}}}~\textbar{}~\_~=\textgreater{}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}~end}}}}
Using lazymatch instead of match will perform the same pattern matching
procedure but will commit to the first matching branch with the first
matching combination of hypotheses rather than trying a new matching if
the right-hand side fails. If the right-hand side of the selected branch
is a tactic with backtracking points, then subsequent failures cause
this tactic to backtrack.

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{Filling a term context}
\label{\detokenize{proof-engine/ltac:filling-a-term-context}}
The following expression is not a tactic in the sense that it does not
produce subgoals but generates a term to be used in tactic expressions:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{context~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{[}{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}{]}}}}}
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} must denote a context variable bound by a context pattern of a
match expression. This expression evaluates replaces the hole of the
value of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} by the value of \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}.
\index{Not a context variable (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.not-a-context-variable}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~a~context~variable.}}}}
\end{fulllineitems}

\index{Unbound context identifier ‘ident’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.unbound-context-identifier-ident}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unbound~context~identifier~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}


\end{fulllineitems}



\subsubsection{Generating fresh hypothesis names}
\label{\detokenize{proof-engine/ltac:generating-fresh-hypothesis-names}}
Tactics sometimes have to generate new names for hypothesis. Letting the
system decide a name with the intro tactic is not so good since it is
very awkward to retrieve the name the system gave. The following
expression returns an identifier:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{fresh~\DUrole{repeat-wrapper}{\DUrole{repeat}{component}\DUrole{notation-sup}{*}}}}}}
It evaluates to an identifier unbound in the goal. This fresh identifier
is obtained by concatenating the value of the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ltac:grammar-token-component}]{\sphinxcrossref{\DUrole{hole}{component}}}}}}}s (each of them
is, either a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}} which has to refer to a (unqualified) name, or
directly a name denoted by a \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}).

If the resulting name is already used, it is padded with a number so that it
becomes fresh. If no component is given, the name is a fresh derivative of
the name \sphinxcode{\sphinxupquote{H}}.

\end{fulllineitems}



\subsubsection{Computing in a constr}
\label{\detokenize{proof-engine/ltac:computing-in-a-constr}}
Evaluation of a term can be performed with:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{eval~\DUrole{hole}{redexpr}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
where \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{redexpr}}}} is a reduction tactic among {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.red}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{red}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.hnf}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{hnf}}}}},
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.compute}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{compute}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.simpl}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{simpl}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.cbv}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cbv}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.lazy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lazy}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unfold}}}}},
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.fold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fold}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}}.

\end{fulllineitems}



\subsubsection{Recovering the type of a term}
\label{\detokenize{proof-engine/ltac:recovering-the-type-of-a-term}}
The following returns the type of term:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{type~of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}



\subsubsection{Manipulating untyped terms}
\label{\detokenize{proof-engine/ltac:manipulating-untyped-terms}}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{uconstr~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
The terms built in \sphinxtitleref{L}$_{\text{tac}}$ are well-typed by default. It may not be
appropriate for building large terms using a recursive \sphinxtitleref{L}$_{\text{tac}}$ function: the
term has to be entirely type checked at each step, resulting in potentially
very slow behavior. It is possible to build untyped terms using \sphinxtitleref{L}$_{\text{tac}}$ with
the \sphinxcode{\sphinxupquote{\DUrole{notation}{uconstr : {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} syntax.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{type\_term~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
An untyped term, in \sphinxtitleref{L}$_{\text{tac}}$, can contain references to hypotheses or to
\sphinxtitleref{L}$_{\text{tac}}$ variables containing typed or untyped terms. An untyped term can be
type checked using the function type\_term whose argument is parsed as an
untyped term and returns a well-typed term which can be used in tactics.

\end{fulllineitems}


Untyped terms built using \sphinxcode{\sphinxupquote{\DUrole{notation}{uconstr :}}} can also be used as arguments to the
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} tactic. In that case the untyped term is type
checked against the conclusion of the goal, and the holes which are not solved
by the typing procedure are turned into new subgoals.


\subsubsection{Counting the goals}
\label{\detokenize{proof-engine/ltac:counting-the-goals}}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{numgoals}}}}
The number of goals under focus can be recovered using the \sphinxcode{\sphinxupquote{\DUrole{notation}{numgoals}}}
function. Combined with the guard command below, it can be used to
branch over the number of goals produced by previous tactics.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{pr\PYGZus{}numgoals} \PYG{o}{:=} \PYG{k}{let} \PYG{n}{n} \PYG{o}{:=} \PYG{n}{numgoals} \PYG{k}{in} \PYG{k+kr}{idtac} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{There are}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{n} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{goals}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{n}{True} \PYG{o}{/\PYGZbs{}} \PYG{n}{True} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{.}
\PYG{k}{split}\PYG{o}{;}\PYG{o}{[\textbar{}}\PYG{k}{split}\PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{all}\PYG{o}{:}\PYG{n}{pr\PYGZus{}numgoals}\PYG{o}{.}
    \PYG{n}{There} \PYG{n}{are} \PYG{l+m+mi}{3} \PYG{n}{goals}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{fulllineitems}



\subsubsection{Testing boolean expressions}
\label{\detokenize{proof-engine/ltac:testing-boolean-expressions}}\index{guard (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.guard}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{guard~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-test}]{\sphinxcrossref{\DUrole{hole}{test}}}}}}}}
The {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.guard}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{guard}}}}} tactic tests a boolean expression, and fails if the expression
evaluates to false. If the expression evaluates to true, it succeeds
without affecting the proof.

The accepted tests are simple integer comparisons.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{True} \PYG{o}{/\PYGZbs{}} \PYG{n}{True} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}\PYG{o}{.}
\PYG{k}{split}\PYG{o}{;}\PYG{o}{[\textbar{}}\PYG{k}{split}\PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{all}\PYG{o}{:}\PYG{k}{let} \PYG{n}{n}\PYG{o}{:=} \PYG{n}{numgoals} \PYG{k}{in} \PYG{n}{guard} \PYG{n}{n}\PYG{o}{\PYGZlt{}}\PYG{l+m+mi}{4}\PYG{o}{.}
\PYG{n}{Fail} \PYG{n}{all}\PYG{o}{:}\PYG{k}{let} \PYG{n}{n}\PYG{o}{:=} \PYG{n}{numgoals} \PYG{k}{in} \PYG{n}{guard} \PYG{n}{n}\PYG{o}{=}\PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{k+kn}{Ltac} \PYG{n}{call} \PYG{n}{to} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{guard (test)}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{failed}\PYG{o}{.}
    \PYG{n}{Condition} \PYG{n}{not} \PYG{n}{satisfied}\PYG{o}{:} \PYG{l+m+mi}{3}\PYG{o}{=}\PYG{l+m+mi}{2}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\index{Condition not satisfied (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.condition-not-satisfied}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Condition~not~satisfied.}}}}
\end{fulllineitems}


\end{fulllineitems}



\subsubsection{Proving a subgoal as a separate lemma}
\label{\detokenize{proof-engine/ltac:proving-a-subgoal-as-a-separate-lemma}}\index{abstract (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.abstract}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{abstract~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
From the outside, \sphinxcode{\sphinxupquote{\DUrole{notation}{abstract {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}} is the same as \sphinxcode{\sphinxupquote{\DUrole{notation}{solve {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}.
Internally it saves an auxiliary lemma called \sphinxcode{\sphinxupquote{ident\_subproofn}} where
\sphinxcode{\sphinxupquote{ident}} is the name of the current goal and \sphinxcode{\sphinxupquote{n}} is chosen so that this is
a fresh name. Such an auxiliary lemma is inlined in the final proof term.

This tactical is useful with tactics such as {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}} or
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.discriminate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{discriminate}}}}} that generate huge proof terms. With that tool the user
can avoid the explosion at time of the Save command without having to cut
manually the proof in smaller lemmas.

It may be useful to generate lemmas minimal w.r.t. the assumptions they
depend on. This can be obtained thanks to the option below.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{abstract~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}~using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Give explicitly the name of the auxiliary lemma.

\begin{sphinxadmonition}{warning}{Warning:}
Use this feature at your own risk; explicitly named and reused subterms
don’t play well with asynchronous proofs.
\end{sphinxadmonition}

\end{fulllineitems}

\index{transparent\_abstract (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacv.transparent-abstract}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{transparent\_abstract~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
Save the subproof in a transparent lemma rather than an opaque one.

\begin{sphinxadmonition}{warning}{Warning:}
Use this feature at your own risk; building computationally relevant
terms with tactics is fragile.
\end{sphinxadmonition}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{transparent\_abstract~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}~using~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Give explicitly the name of the auxiliary transparent lemma.

\begin{sphinxadmonition}{warning}{Warning:}
Use this feature at your own risk; building computationally relevant terms
with tactics is fragile, and explicitly named and reused subterms
don’t play well with asynchronous proofs.
\end{sphinxadmonition}

\end{fulllineitems}

\index{Proof is not complete. (abstract) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.proof-is-not-complete-abstract}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Proof~is~not~complete.}}}}
\end{fulllineitems}


\end{fulllineitems}



\subsection{Tactic toplevel definitions}
\label{\detokenize{proof-engine/ltac:tactic-toplevel-definitions}}

\subsubsection{Defining \sphinxtitleref{L}$_{\text{tac}}$ functions}
\label{\detokenize{proof-engine/ltac:defining-ltac-functions}}
Basically, \sphinxtitleref{L}$_{\text{tac}}$ toplevel definitions are made as follows:
\index{Ltac (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:cmd.ltac}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}~:=~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
This defines a new \sphinxtitleref{L}$_{\text{tac}}$ function that can be used in any tactic
script or new \sphinxtitleref{L}$_{\text{tac}}$ toplevel definition.

\begin{sphinxadmonition}{note}{Note:}
The preceding definition can equivalently be written:

\sphinxcode{\sphinxupquote{\DUrole{notation}{Ltac {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := fun \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}} =\textgreater{} {\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}
\end{sphinxadmonition}

Recursive and mutual recursive function definitions are also possible
with the syntax:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}}\DUrole{notation-sup}{*}}~:=~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
It is also possible to \sphinxstyleemphasis{redefine} an existing user-defined tactic using the syntax:

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}~::=~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
A previous definition of qualid must exist in the environment. The new
definition will always be used instead of the old one and it goes across
module boundaries.

\end{fulllineitems}


If preceded by the keyword Local the tactic definition will not be
exported outside the current module.

\end{fulllineitems}



\subsubsection{Printing \sphinxtitleref{L}$_{\text{tac}}$ tactics}
\label{\detokenize{proof-engine/ltac:printing-ltac-tactics}}\index{Print Ltac (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:cmd.print-ltac}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Ltac~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
Defined \sphinxtitleref{L}$_{\text{tac}}$ functions can be displayed using this command.

\end{fulllineitems}

\index{Print Ltac Signatures (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:cmd.print-ltac-signatures}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Ltac~Signatures}}}}
This command displays a list of all user-defined tactics, with their arguments.

\end{fulllineitems}



\subsection{Debugging \sphinxtitleref{L}$_{\text{tac}}$ tactics}
\label{\detokenize{proof-engine/ltac:debugging-ltac-tactics}}

\subsubsection{Info trace}
\label{\detokenize{proof-engine/ltac:info-trace}}\index{Info (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:cmd.info}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Info~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~{\hyperref[\detokenize{proof-engine/ltac:grammar-token-expr}]{\sphinxcrossref{\DUrole{hole}{expr}}}}}}}}
This command can be used to print the trace of the path eventually taken by an
\sphinxtitleref{L}$_{\text{tac}}$ script. That is, the list of executed tactics, discarding
all the branches which have failed. To that end the {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.info}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Info}}}}} command can be
used with the following syntax.

The number \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} is the unfolding level of tactics in the trace. At level
0, the trace contains a sequence of tactics in the actual script, at level 1,
the trace will be the concatenation of the traces of these tactics, etc…

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{t} \PYG{n}{x} \PYG{o}{:=} \PYG{k}{exists} \PYG{n}{x}\PYG{o}{;} \PYG{k+kp}{reflexivity}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{exists} \PYG{n}{n}\PYG{o}{,} \PYG{n}{n}\PYG{o}{=}\PYG{l+m+mi}{0}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Info} \PYG{l+m+mi}{0} \PYG{n}{t} \PYG{l+m+mi}{1}\PYG{o}{\textbar{}}\PYG{o}{\textbar{}}\PYG{n}{t} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{t} \PYG{o}{\PYGZlt{}}\PYG{n}{constr}\PYG{o}{:}\PYG{o}{(}\PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{\PYGZgt{}}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Undo}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Info} \PYG{l+m+mi}{1} \PYG{n}{t} \PYG{l+m+mi}{1}\PYG{o}{\textbar{}}\PYG{o}{\textbar{}}\PYG{n}{t} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{k}{exists}  \PYG{k}{with} \PYG{l+m+mi}{0}\PYG{o}{;}\PYG{k+kp}{reflexivity} 
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The trace produced by {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.info}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Info}}}}} tries its best to be a reparsable
\sphinxtitleref{L}$_{\text{tac}}$ script, but this goal is not achievable in all generality.
So some of the output traces will contain oddities.

As an additional help for debugging, the trace produced by {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.info}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Info}}}}} contains
(in comments) the messages produced by the {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.idtac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{idtac}}}}} tactical at the right
position in the script. In particular, the calls to idtac in branches which failed are
not printed.
\index{Info Level (opt)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:opt.info-level}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Info~Level~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
This option is an alternative to the {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.info}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Info}}}}} command.

This will automatically print the same trace as \sphinxcode{\sphinxupquote{\DUrole{notation}{Info {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}} at each
tactic call. The unfolding level can be overridden by a call to the
{\hyperref[\detokenize{proof-engine/ltac:coq:cmd.info}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Info}}}}} command.

\end{fulllineitems}


\end{fulllineitems}



\subsubsection{Interactive debugger}
\label{\detokenize{proof-engine/ltac:interactive-debugger}}\index{Ltac Debug (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:flag.ltac-debug}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac~Debug}}}}
This option governs the step-by-step debugger that comes with the \sphinxtitleref{L}$_{\text{tac}}$ interpreter

\end{fulllineitems}


When the debugger is activated, it stops at every step of the evaluation of
the current \sphinxtitleref{L}$_{\text{tac}}$ expression and prints information on what it is doing.
The debugger stops, prompting for a command which can be one of the
following:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline

simple newline:
&
go to the next step
\\
\hline
h:
&
get help
\\
\hline
x:
&
exit current evaluation
\\
\hline
s:
&
continue current evaluation without stopping
\\
\hline
r n:
&
advance n steps further
\\
\hline
r string:
&
advance up to the next call to “idtac string”
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}
\index{Debug mode not available in the IDE (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:exn.debug-mode-not-available-in-the-ide}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Debug~mode~not~available~in~the~IDE}}}}
\end{fulllineitems}


A non-interactive mode for the debugger is available via the option:
\index{Ltac Batch Debug (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:flag.ltac-batch-debug}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac~Batch~Debug}}}}
This option has the effect of presenting a newline at every prompt, when
the debugger is on. The debug log thus created, which does not require
user input to generate when this option is set, can then be run through
external tools such as diff.

\end{fulllineitems}



\subsubsection{Profiling \sphinxtitleref{L}$_{\text{tac}}$ tactics}
\label{\detokenize{proof-engine/ltac:profiling-ltac-tactics}}
It is possible to measure the time spent in invocations of primitive
tactics as well as tactics defined in \sphinxtitleref{L}$_{\text{tac}}$ and their inner
invocations. The primary use is the development of complex tactics,
which can sometimes be so slow as to impede interactive usage. The
reasons for the performence degradation can be intricate, like a slowly
performing \sphinxtitleref{L}$_{\text{tac}}$ match or a sub-tactic whose performance only
degrades in certain situations. The profiler generates a call tree and
indicates the time spent in a tactic depending on its calling context. Thus
it allows to locate the part of a tactic definition that contains the
performance issue.
\index{Ltac Profiling (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:flag.ltac-profiling}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ltac~Profiling}}}}
This option enables and disables the profiler.

\end{fulllineitems}

\index{Show Ltac Profile (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:cmd.show-ltac-profile}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Ltac~Profile}}}}
Prints the profile


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Ltac~Profile~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
Prints a profile for all tactics that start with \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}. Append a period
(.) to the string if you only want exactly that name.

\end{fulllineitems}


\end{fulllineitems}

\index{Reset Ltac Profile (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:cmd.reset-ltac-profile}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Reset~Ltac~Profile}}}}
Resets the profile, that is, deletes all accumulated information.

\begin{sphinxadmonition}{warning}{Warning:}
Backtracking across a {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.reset-ltac-profile}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Reset Ltac Profile}}}}} will not restore the information.
\end{sphinxadmonition}

\end{fulllineitems}


\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Coq}\PYG{o}{.}\PYG{k+kp}{omega}\PYG{o}{.}\PYG{n}{Omega}\PYG{o}{.}
\PYG{k+kn}{Ltac} \PYG{n}{mytauto} \PYG{o}{:=} \PYG{k}{tauto}\PYG{o}{.}
\PYG{k+kn}{Ltac} \PYG{n}{tac} \PYG{o}{:=} \PYG{k}{intros}\PYG{o}{;} \PYG{k+kr}{repeat} \PYG{k}{split}\PYG{o}{;} \PYG{k+kp}{omega} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{mytauto}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{n}{max} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{o}{(}\PYG{n}{y} \PYG{o}{\PYGZhy{}} \PYG{n}{x}\PYG{o}{)}\PYG{o}{)} \PYG{o}{(}\PYG{n}{only} \PYG{n}{parsing}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C} \PYG{n}{D} \PYG{n}{E} \PYG{n}{F} \PYG{n}{G} \PYG{n}{H} \PYG{n}{I} \PYG{n}{J} \PYG{n}{K} \PYG{n}{L} \PYG{n}{M} \PYG{n}{N} \PYG{n}{O} \PYG{n}{P} \PYG{n}{Q} \PYG{n}{R} \PYG{n}{S} \PYG{n}{T} \PYG{n}{U} \PYG{n}{V} \PYG{n}{W} \PYG{n}{X} \PYG{n}{Y} \PYG{n}{Z}\PYG{o}{,}
    \PYG{n}{max} \PYG{n}{x} \PYG{o}{(}\PYG{n}{max} \PYG{n}{y} \PYG{n}{z}\PYG{o}{)} \PYG{o}{=} \PYG{n}{max} \PYG{o}{(}\PYG{n}{max} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{n}{z} \PYG{o}{/\PYGZbs{}} \PYG{n}{max} \PYG{n}{x} \PYG{o}{(}\PYG{n}{max} \PYG{n}{y} \PYG{n}{z}\PYG{o}{)} \PYG{o}{=} \PYG{n}{max} \PYG{o}{(}\PYG{n}{max} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{n}{z}
    \PYG{o}{/\PYGZbs{}}
    \PYG{o}{(}\PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{n}{B} \PYG{o}{/\PYGZbs{}} \PYG{n}{C} \PYG{o}{/\PYGZbs{}} \PYG{n}{D} \PYG{o}{/\PYGZbs{}} \PYG{n}{E} \PYG{o}{/\PYGZbs{}} \PYG{n}{F} \PYG{o}{/\PYGZbs{}} \PYG{n}{G} \PYG{o}{/\PYGZbs{}} \PYG{n}{H} \PYG{o}{/\PYGZbs{}} \PYG{n}{I} \PYG{o}{/\PYGZbs{}} \PYG{n}{J} \PYG{o}{/\PYGZbs{}} \PYG{n}{K} \PYG{o}{/\PYGZbs{}} \PYG{n}{L} \PYG{o}{/\PYGZbs{}} \PYG{n}{M} \PYG{o}{/\PYGZbs{}}
     \PYG{n}{N} \PYG{o}{/\PYGZbs{}} \PYG{n}{O} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{o}{/\PYGZbs{}} \PYG{n}{Q} \PYG{o}{/\PYGZbs{}} \PYG{n}{R} \PYG{o}{/\PYGZbs{}} \PYG{n}{S} \PYG{o}{/\PYGZbs{}} \PYG{n}{T} \PYG{o}{/\PYGZbs{}} \PYG{n}{U} \PYG{o}{/\PYGZbs{}} \PYG{n}{V} \PYG{o}{/\PYGZbs{}} \PYG{n}{W} \PYG{o}{/\PYGZbs{}} \PYG{n}{X} \PYG{o}{/\PYGZbs{}} \PYG{n}{Y} \PYG{o}{/\PYGZbs{}} \PYG{n}{Z}
     \PYG{o}{\PYGZhy{}\PYGZgt{}}
     \PYG{n}{Z} \PYG{o}{/\PYGZbs{}} \PYG{n}{Y} \PYG{o}{/\PYGZbs{}} \PYG{n}{X} \PYG{o}{/\PYGZbs{}} \PYG{n}{W} \PYG{o}{/\PYGZbs{}} \PYG{n}{V} \PYG{o}{/\PYGZbs{}} \PYG{n}{U} \PYG{o}{/\PYGZbs{}} \PYG{n}{T} \PYG{o}{/\PYGZbs{}} \PYG{n}{S} \PYG{o}{/\PYGZbs{}} \PYG{n}{R} \PYG{o}{/\PYGZbs{}} \PYG{n}{Q} \PYG{o}{/\PYGZbs{}} \PYG{n}{P} \PYG{o}{/\PYGZbs{}} \PYG{n}{O} \PYG{o}{/\PYGZbs{}} \PYG{n}{N} \PYG{o}{/\PYGZbs{}}
     \PYG{n}{M} \PYG{o}{/\PYGZbs{}} \PYG{n}{L} \PYG{o}{/\PYGZbs{}} \PYG{n}{K} \PYG{o}{/\PYGZbs{}} \PYG{n}{J} \PYG{o}{/\PYGZbs{}} \PYG{n}{I} \PYG{o}{/\PYGZbs{}} \PYG{n}{H} \PYG{o}{/\PYGZbs{}} \PYG{n}{G} \PYG{o}{/\PYGZbs{}} \PYG{n}{F} \PYG{o}{/\PYGZbs{}} \PYG{n}{E} \PYG{o}{/\PYGZbs{}} \PYG{n}{D} \PYG{o}{/\PYGZbs{}} \PYG{n}{C} \PYG{o}{/\PYGZbs{}} \PYG{n}{B} \PYG{o}{/\PYGZbs{}} \PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Set Ltac Profiling.
tac.
    No more subgoals.

Show Ltac Profile.
    total time:      1.563s
    
     tactic                                   local  total   calls       max 
    ────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
    ─tac \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}   0.1\PYGZpc{} 100.0\PYGZpc{}       1    1.563s
    ─\PYGZlt{}Coq.Init.Tauto.with\PYGZus{}uniform\PYGZus{}flags\PYGZgt{} \PYGZhy{}\PYGZhy{}\PYGZhy{}   0.0\PYGZpc{}  72.8\PYGZpc{}      26    0.057s
    ─\PYGZlt{}Coq.Init.Tauto.tauto\PYGZus{}gen\PYGZgt{} \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}   0.0\PYGZpc{}  72.7\PYGZpc{}      26    0.057s
    ─\PYGZlt{}Coq.Init.Tauto.tauto\PYGZus{}intuitionistic\PYGZgt{} \PYGZhy{}   0.0\PYGZpc{}  72.7\PYGZpc{}      26    0.057s
    ─t\PYGZus{}tauto\PYGZus{}intuit \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}   0.1\PYGZpc{}  72.6\PYGZpc{}      26    0.057s
    ─\PYGZlt{}Coq.Init.Tauto.simplif\PYGZgt{} \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}  49.1\PYGZpc{}  70.1\PYGZpc{}      26    0.055s
    ─omega \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}  26.7\PYGZpc{}  26.7\PYGZpc{}      28    0.189s
    ─\PYGZlt{}Coq.Init.Tauto.is\PYGZus{}conj\PYGZgt{} \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}  13.0\PYGZpc{}  13.0\PYGZpc{}   28756    0.017s
    ─elim id \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}   4.1\PYGZpc{}   4.1\PYGZpc{}     650    0.007s
    ─\PYGZlt{}Coq.Init.Tauto.axioms\PYGZgt{} \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}   1.8\PYGZpc{}   2.4\PYGZpc{}       0    0.002s
    
     tactic                                   local  total   calls       max 
    ────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
    ─tac \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}   0.1\PYGZpc{} 100.0\PYGZpc{}       1    1.563s
     ├─\PYGZlt{}Coq.Init.Tauto.with\PYGZus{}uniform\PYGZus{}flags\PYGZgt{} \PYGZhy{}   0.0\PYGZpc{}  72.8\PYGZpc{}      26    0.057s
     │└\PYGZlt{}Coq.Init.Tauto.tauto\PYGZus{}gen\PYGZgt{} \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}   0.0\PYGZpc{}  72.7\PYGZpc{}      26    0.057s
     │└\PYGZlt{}Coq.Init.Tauto.tauto\PYGZus{}intuitionistic\PYGZgt{}   0.0\PYGZpc{}  72.7\PYGZpc{}      26    0.057s
     │└t\PYGZus{}tauto\PYGZus{}intuit \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}   0.1\PYGZpc{}  72.6\PYGZpc{}      26    0.057s
     │ ├─\PYGZlt{}Coq.Init.Tauto.simplif\PYGZgt{} \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}  49.1\PYGZpc{}  70.1\PYGZpc{}      26    0.055s
     │ │ ├─\PYGZlt{}Coq.Init.Tauto.is\PYGZus{}conj\PYGZgt{} \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}  13.0\PYGZpc{}  13.0\PYGZpc{}   28756    0.017s
     │ │ └─elim id \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}   4.1\PYGZpc{}   4.1\PYGZpc{}     650    0.007s
     │ └─\PYGZlt{}Coq.Init.Tauto.axioms\PYGZgt{} \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}   1.8\PYGZpc{}   2.4\PYGZpc{}       0    0.002s
     └─omega \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}  26.7\PYGZpc{}  26.7\PYGZpc{}      28    0.189s

Show Ltac Profile \PYGZdq{}omega\PYGZdq{}.
    total time:      1.563s
    
     tactic                                   local  total   calls       max 
    ────────────────────────────────────────┴──────┴──────┴───────┴─────────┘
    ─omega \PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}  26.7\PYGZpc{}  26.7\PYGZpc{}      28    0.189s
    
     tactic                                   local  total   calls       max
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Abort}\PYG{o}{.}
\PYG{k+kn}{Unset} \PYG{k+kn}{Ltac} \PYG{n}{Profiling}\PYG{o}{.}
\end{sphinxVerbatim}
\index{start ltac profiling (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.start-ltac-profiling}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{start~ltac~profiling}}}}
This tactic behaves like {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.idtac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{idtac}}}}} but enables the profiler.

\end{fulllineitems}

\index{stop ltac profiling (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.stop-ltac-profiling}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{stop~ltac~profiling}}}}
Similarly to {\hyperref[\detokenize{proof-engine/ltac:coq:tacn.start-ltac-profiling}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{start ltac profiling}}}}}, this tactic behaves like
{\hyperref[\detokenize{proof-engine/ltac:coq:tacn.idtac}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{idtac}}}}}. Together, they allow you to exclude parts of a proof script
from profiling.

\end{fulllineitems}

\index{reset ltac profile (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.reset-ltac-profile}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{reset~ltac~profile}}}}
This tactic behaves like the corresponding vernacular command
and allow displaying and resetting the profile from tactic scripts for
benchmarking purposes.

\end{fulllineitems}

\index{show ltac profile (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.show-ltac-profile}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{show~ltac~profile}}}}
This tactic behaves like the corresponding vernacular command
and allow displaying and resetting the profile from tactic scripts for
benchmarking purposes.

\end{fulllineitems}

\index{show ltac profile (tacn)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{show~ltac~profile~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
This tactic behaves like the corresponding vernacular command
and allow displaying and resetting the profile from tactic scripts for
benchmarking purposes.

\end{fulllineitems}


You can also pass the \sphinxcode{\sphinxupquote{-profile-ltac}} command line option to \sphinxcode{\sphinxupquote{coqc}}, which
turns the {\hyperref[\detokenize{proof-engine/ltac:coq:flag.ltac-profiling}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Ltac Profiling}}}}} option on at the beginning of each document,
and performs a {\hyperref[\detokenize{proof-engine/ltac:coq:cmd.show-ltac-profile}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Show Ltac Profile}}}}} at the end.

\begin{sphinxadmonition}{warning}{Warning:}
Note that the profiler currently does not handle backtracking into
multi-success tactics, and issues a warning to this effect in many cases
when such backtracking occurs.
\end{sphinxadmonition}


\subsubsection{Run-time optimization tactic}
\label{\detokenize{proof-engine/ltac:run-time-optimization-tactic}}\index{optimize\_heap (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ltac:coq:tacn.optimize-heap}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{optimize\_heap}}}}
\end{fulllineitems}


This tactic behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{idtac}}}, except that running it compacts the
heap in the OCaml run-time system. It is analogous to the Vernacular
command {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmd.optimize-heap}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Optimize Heap}}}}}.


\section{Detailed examples of tactics}
\label{\detokenize{proof-engine/detailed-tactic-examples:detailed-examples-of-tactics}}\label{\detokenize{proof-engine/detailed-tactic-examples:detailedexamplesoftactics}}\label{\detokenize{proof-engine/detailed-tactic-examples::doc}}
This chapter presents detailed examples of certain tactics, to
illustrate their behavior.


\subsection{dependent induction}
\label{\detokenize{proof-engine/detailed-tactic-examples:dependent-induction}}\label{\detokenize{proof-engine/detailed-tactic-examples:id1}}
The tactics \sphinxcode{\sphinxupquote{dependent induction}} and \sphinxcode{\sphinxupquote{dependent destruction}} are another
solution for inverting inductive predicate instances and potentially
doing induction at the same time. It is based on the \sphinxcode{\sphinxupquote{BasicElim}} tactic
of Conor McBride which works by abstracting each argument of an
inductive instance by a variable and constraining it by equalities
afterwards. This way, the usual induction and destruct tactics can be
applied to the abstracted instance and after simplification of the
equalities we get the expected goals.

The abstracting tactic is called generalize\_eqs and it takes as
argument a hypothesis to generalize. It uses the JMeq datatype
defined in Coq.Logic.JMeq, hence we need to require it before. For
example, revisiting the first example of the inversion documentation:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Logic}\PYG{o}{.}\PYG{n}{JMeq}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{Le} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set} \PYG{o}{:=}
     \PYG{o}{\textbar{}} \PYG{n}{LeO} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{l+m+mi}{0} \PYG{n}{n}
     \PYG{o}{\textbar{}} \PYG{n}{LeS} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Variable} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n} \PYG{n}{m}\PYG{o}{.}
\PYG{k}{intros} \PYG{n}{n} \PYG{n}{m} \PYG{n}{H}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{generalize\PYGZus{}eqs} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m}\PYG{o}{,} \PYG{n}{gen\PYGZus{}x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{Le} \PYG{n}{gen\PYGZus{}x} \PYG{n}{m}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{gen\PYGZus{}x} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n} \PYG{n}{m}
\end{sphinxVerbatim}

The index \sphinxcode{\sphinxupquote{S n}} gets abstracted by a variable here, but a corresponding
equality is added under the abstract instance so that no information
is actually lost. The goal is now almost amenable to do induction or
case analysis. One should indeed first move \sphinxcode{\sphinxupquote{n}} into the goal to
strengthen it before doing induction, or \sphinxcode{\sphinxupquote{n}} will be fixed in the
inductive hypotheses (this does not matter for case analysis). As a
rule of thumb, all the variables that appear inside constructors in
the indices of the hypothesis should be generalized. This is exactly
what the \sphinxcode{\sphinxupquote{generalize\_eqs\_vars}} variant does:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{generalize\PYGZus{}eqs\PYGZus{}vars} \PYG{n}{H}\PYG{o}{.}
\PYG{k}{induction} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{n0} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n} \PYG{n}{n0}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{S} \PYG{n}{n0} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)}
\end{sphinxVerbatim}

As the hypothesis itself did not appear in the goal, we did not need
to use an heterogeneous equality to relate the new hypothesis to the
old one (which just disappeared here). However, the tactic works just
as well in this case, e.g.:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variable} \PYG{n}{Q} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)}\PYG{o}{,} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{(}\PYG{n}{p} \PYG{o}{:} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m}\PYG{o}{)}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m} \PYG{n}{p}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{p} \PYG{o}{:} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{Q} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m} \PYG{n}{p}

\PYG{n}{generalize\PYGZus{}eqs\PYGZus{}vars} \PYG{n}{p}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{m}\PYG{o}{,} \PYG{n}{gen\PYGZus{}x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{p} \PYG{o}{:} \PYG{n}{Le} \PYG{n}{gen\PYGZus{}x} \PYG{n}{m}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{o}{(}\PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{p0} \PYG{o}{:} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m}\PYG{o}{)}\PYG{o}{,}
      \PYG{n}{gen\PYGZus{}x} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{JMeq} \PYG{n}{p} \PYG{n}{p0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m} \PYG{n}{p0}
\end{sphinxVerbatim}

One drawback of this approach is that in the branches one will have to
substitute the equalities back into the instance to get the right
assumptions. Sometimes injection of constructors will also be needed
to recover the needed equalities. Also, some subgoals should be
directly solved because of inconsistent contexts arising from the
constraints on indexes. The nice thing is that we can make a tactic
based on discriminate, injection and variants of substitution to
automatically do such simplifications (which may involve the axiom K).
This is what the \sphinxcode{\sphinxupquote{simplify\_dep\_elim}} tactic from \sphinxcode{\sphinxupquote{Coq.Program.Equality}}
does. For example, we might simplify the previous goals considerably:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Program}\PYG{o}{.}\PYG{n}{Equality}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{induction} \PYG{n}{p} \PYG{o}{;} \PYG{n}{simplify\PYGZus{}dep\PYGZus{}elim}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{p} \PYG{o}{:} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m}
      \PYG{n}{IHp} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{n0} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{p0} \PYG{o}{:} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n0}\PYG{o}{)} \PYG{n}{m}\PYG{o}{)}\PYG{o}{,}
            \PYG{n}{n} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{p} \PYG{o}{\PYGZti{}}\PYG{o}{=} \PYG{n}{p0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n0}\PYG{o}{)} \PYG{n}{m} \PYG{n}{p0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{Q} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)} \PYG{o}{(}\PYG{n}{LeS} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p}\PYG{o}{)}
\end{sphinxVerbatim}

The higher-order tactic \sphinxcode{\sphinxupquote{do\_depind}} defined in \sphinxcode{\sphinxupquote{Coq.Program.Equality}}
takes a tactic and combines the building blocks we have seen with it:
generalizing by equalities calling the given tactic with the
generalized induction hypothesis as argument and cleaning the subgoals
with respect to equalities. Its most important instantiations
are \sphinxcode{\sphinxupquote{dependent induction}} and \sphinxcode{\sphinxupquote{dependent destruction}} that do induction or
simply case analysis on the generalized hypothesis. For example we can
redo what we’ve done manually with dependent destruction:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{ex} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n} \PYG{n}{m}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros} \PYG{n}{n} \PYG{n}{m} \PYG{n}{H}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{dependent} \PYG{n}{destruction} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{n}{n} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)}
\end{sphinxVerbatim}

This gives essentially the same result as inversion. Now if the
destructed hypothesis actually appeared in the goal, the tactic would
still be able to invert it, contrary to dependent inversion. Consider
the following example on vectors:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{k+kn}{Implicit} \PYG{k+kn}{Arguments}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variable} \PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{vector} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type} \PYG{o}{:=}
         \PYG{o}{\textbar{}} \PYG{n}{vnil} \PYG{o}{:} \PYG{n}{vector} \PYG{l+m+mi}{0}
         \PYG{o}{\textbar{}} \PYG{n}{vcons} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{,} \PYG{n}{vector} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{vector} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{,} \PYG{k}{forall} \PYG{n}{v} \PYG{o}{:} \PYG{n}{vector} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{,}
         \PYG{k}{exists} \PYG{n}{v\PYGZsq{}} \PYG{o}{:} \PYG{n}{vector} \PYG{n}{n}\PYG{o}{,} \PYG{k}{exists} \PYG{n}{a} \PYG{o}{:} \PYG{n}{A}\PYG{o}{,} \PYG{n}{v} \PYG{o}{=} \PYG{n}{vcons} \PYG{n}{a} \PYG{n}{v\PYGZsq{}}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros} \PYG{n}{n} \PYG{n}{v}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{dependent} \PYG{n}{destruction} \PYG{n}{v}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{a} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{v} \PYG{o}{:} \PYG{n}{vector} \PYG{n}{n}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{exists} \PYG{o}{(}\PYG{n}{v\PYGZsq{}} \PYG{o}{:} \PYG{n}{vector} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{a0} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)}\PYG{o}{,} \PYG{n}{vcons} \PYG{n}{a} \PYG{n}{v} \PYG{o}{=} \PYG{n}{vcons} \PYG{n}{a0} \PYG{n}{v\PYGZsq{}}
\end{sphinxVerbatim}

In this case, the \sphinxcode{\sphinxupquote{v}} variable can be replaced in the goal by the
generalized hypothesis only when it has a type of the form \sphinxcode{\sphinxupquote{vector (S n)}},
that is only in the second case of the destruct. The first one is
dismissed because \sphinxcode{\sphinxupquote{S n \textless{}\textgreater{} 0}}.


\subsubsection{A larger example}
\label{\detokenize{proof-engine/detailed-tactic-examples:a-larger-example}}
Let’s see how the technique works with induction on inductive
predicates on a real example. We will develop an example application
to the theory of simply-typed lambda-calculus formalized in a
dependently-typed style:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{type} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
         \PYG{o}{\textbar{}} \PYG{n}{base} \PYG{o}{:} \PYG{n}{type}
         \PYG{o}{\textbar{}} \PYG{n}{arrow} \PYG{o}{:} \PYG{n}{type} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{type} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{type}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{ t \PYGZhy{}\PYGZhy{}\PYGZgt{} t\PYGZsq{} }\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{arrow} \PYG{n}{t} \PYG{n}{t\PYGZsq{}}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{20}\PYG{o}{,} \PYG{n}{t\PYGZsq{}} \PYG{n}{at} \PYG{n}{next} \PYG{n}{level}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{ctx} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
         \PYG{o}{\textbar{}} \PYG{n}{empty} \PYG{o}{:} \PYG{n}{ctx}
         \PYG{o}{\textbar{}} \PYG{n}{snoc} \PYG{o}{:} \PYG{n}{ctx} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{type} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{ctx}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{ G , tau }\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{snoc} \PYG{n}{G} \PYG{n}{tau}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{20}\PYG{o}{,} \PYG{n}{tau} \PYG{n}{at} \PYG{n}{next} \PYG{n}{level}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{conc} \PYG{o}{(}\PYG{n}{G} \PYG{n}{D} \PYG{o}{:} \PYG{n}{ctx}\PYG{o}{)} \PYG{o}{:} \PYG{n}{ctx} \PYG{o}{:=}
         \PYG{k}{match} \PYG{n}{D} \PYG{k}{with}
         \PYG{o}{\textbar{}} \PYG{n}{empty} \PYG{o}{=\PYGZgt{}} \PYG{n}{G}
         \PYG{o}{\textbar{}} \PYG{n}{snoc} \PYG{n}{D\PYGZsq{}} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{snoc} \PYG{o}{(}\PYG{n}{conc} \PYG{n}{G} \PYG{n}{D\PYGZsq{}}\PYG{o}{)} \PYG{n}{x}
         \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{ G ; D }\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{conc} \PYG{n}{G} \PYG{n}{D}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{20}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{term} \PYG{o}{:} \PYG{n}{ctx} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{type} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type} \PYG{o}{:=}
         \PYG{o}{\textbar{}} \PYG{n}{ax} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{G} \PYG{n}{tau}\PYG{o}{,} \PYG{n}{term} \PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau}\PYG{o}{)} \PYG{n}{tau}
         \PYG{o}{\textbar{}} \PYG{n}{weak} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{G} \PYG{n}{tau}\PYG{o}{,}
                    \PYG{n}{term} \PYG{n}{G} \PYG{n}{tau} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{tau\PYGZsq{}}\PYG{o}{,} \PYG{n}{term} \PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}}\PYG{o}{)} \PYG{n}{tau}
         \PYG{o}{\textbar{}} \PYG{n}{abs} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{G} \PYG{n}{tau} \PYG{n}{tau\PYGZsq{}}\PYG{o}{,}
                   \PYG{n}{term} \PYG{o}{(}\PYG{n}{G} \PYG{o}{,} \PYG{n}{tau}\PYG{o}{)} \PYG{n}{tau\PYGZsq{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{term} \PYG{n}{G} \PYG{o}{(}\PYG{n}{tau} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{tau\PYGZsq{}}\PYG{o}{)}
         \PYG{o}{\textbar{}} \PYG{n}{app} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{G} \PYG{n}{tau} \PYG{n}{tau\PYGZsq{}}\PYG{o}{,}
                   \PYG{n}{term} \PYG{n}{G} \PYG{o}{(}\PYG{n}{tau} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{tau\PYGZsq{}}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{term} \PYG{n}{G} \PYG{n}{tau} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{term} \PYG{n}{G} \PYG{n}{tau\PYGZsq{}}\PYG{o}{.}
\end{sphinxVerbatim}

We have defined types and contexts which are snoc-lists of types. We
also have a \sphinxcode{\sphinxupquote{conc}} operation that concatenates two contexts. The \sphinxcode{\sphinxupquote{term}}
datatype represents in fact the possible typing derivations of the
calculus, which are isomorphic to the well-typed terms, hence the
name. A term is either an application of:
\begin{itemize}
\item {} 
the axiom rule to type a reference to the first variable in a
context

\item {} 
the weakening rule to type an object in a larger context

\item {} 
the abstraction or lambda rule to type a function

\item {} 
the application to type an application of a function to an argument

\end{itemize}

Once we have this datatype we want to do proofs on it, like weakening:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{weakening} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{G} \PYG{n}{D} \PYG{n}{tau}\PYG{o}{,} \PYG{n}{term} \PYG{o}{(}\PYG{n}{G} \PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{n}{tau} \PYG{o}{\PYGZhy{}\PYGZgt{}}
                  \PYG{k}{forall} \PYG{n}{tau\PYGZsq{}}\PYG{o}{,} \PYG{n}{term} \PYG{o}{(}\PYG{n}{G} \PYG{o}{,} \PYG{n}{tau\PYGZsq{}} \PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{n}{tau}\PYG{o}{.}
\end{sphinxVerbatim}

The problem here is that we can’t just use induction on the typing
derivation because it will forget about the \sphinxcode{\sphinxupquote{G ; D}} constraint appearing
in the instance. A solution would be to rewrite the goal as:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{weakening\PYGZsq{}} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{G\PYGZsq{}} \PYG{n}{tau}\PYG{o}{,} \PYG{n}{term} \PYG{n}{G\PYGZsq{}} \PYG{n}{tau} \PYG{o}{\PYGZhy{}\PYGZgt{}}
                   \PYG{k}{forall} \PYG{n}{G} \PYG{n}{D}\PYG{o}{,} \PYG{o}{(}\PYG{n}{G} \PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{o}{=} \PYG{n}{G\PYGZsq{}} \PYG{o}{\PYGZhy{}\PYGZgt{}}
                   \PYG{k}{forall} \PYG{n}{tau\PYGZsq{}}\PYG{o}{,} \PYG{n}{term} \PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}} \PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{n}{tau}\PYG{o}{.}
\end{sphinxVerbatim}

With this proper separation of the index from the instance and the
right induction loading (putting \sphinxcode{\sphinxupquote{G}} and \sphinxcode{\sphinxupquote{D}} after the inducted-on
hypothesis), the proof will go through, but it is a very tedious
process. One is also forced to make a wrapper lemma to get back the
more natural statement. The \sphinxcode{\sphinxupquote{dependent induction}} tactic alleviates this
trouble by doing all of this plumbing of generalizing and substituting
back automatically. Indeed we can simply write:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Program}\PYG{o}{.}\PYG{n}{Tactics}\PYG{o}{.}
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Program}\PYG{o}{.}\PYG{n}{Equality}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{weakening} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{G} \PYG{n}{D} \PYG{n}{tau}\PYG{o}{,} \PYG{n}{term} \PYG{o}{(}\PYG{n}{G} \PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{n}{tau} \PYG{o}{\PYGZhy{}\PYGZgt{}}
                  \PYG{k}{forall} \PYG{n}{tau\PYGZsq{}}\PYG{o}{,} \PYG{n}{term} \PYG{o}{(}\PYG{n}{G} \PYG{o}{,} \PYG{n}{tau\PYGZsq{}} \PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{n}{tau}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Proof} \PYG{k}{with} \PYG{k}{simpl} \PYG{k}{in} \PYG{o}{*} \PYG{o}{;} \PYG{n}{simpl\PYGZus{}depind} \PYG{o}{;} \PYG{k}{auto}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intros} \PYG{n}{G} \PYG{n}{D} \PYG{n}{tau} \PYG{n}{H}\PYG{o}{.}
\PYG{n}{dependent} \PYG{k}{induction} \PYG{n}{H} \PYG{n}{generalizing} \PYG{n}{G} \PYG{n}{D} \PYG{o}{;} \PYG{k}{intros}\PYG{o}{.}
\end{sphinxVerbatim}

This call to dependent induction has an additional arguments which is
a list of variables appearing in the instance that should be
generalized in the goal, so that they can vary in the induction
hypotheses. By default, all variables appearing inside constructors
(except in a parameter position) of the instantiated hypothesis will
be generalized automatically but one can always give the list
explicitly.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Show}\PYG{o}{.}
    \PYG{l+m+mi}{4} \PYG{n}{subgoals}
      
      \PYG{n}{G0} \PYG{o}{:} \PYG{n}{ctx}
      \PYG{n}{tau} \PYG{o}{:} \PYG{n}{type}
      \PYG{n}{G}\PYG{o}{,} \PYG{n}{D} \PYG{o}{:} \PYG{n}{ctx}
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{G0}\PYG{o}{,} \PYG{n}{tau} \PYG{o}{=} \PYG{n}{G}\PYG{o}{;} \PYG{n}{D}
      \PYG{n}{tau\PYGZsq{}} \PYG{o}{:} \PYG{n}{type}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}}\PYG{o}{)}\PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{n}{tau}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}0}\PYG{o}{)}\PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{n}{tau}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}0}\PYG{o}{)}\PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{o}{(}\PYG{n}{tau} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{tau\PYGZsq{}}\PYG{o}{)}
    \PYG{n}{subgoal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}0}\PYG{o}{)}\PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{n}{tau\PYGZsq{}}
\end{sphinxVerbatim}

The \sphinxcode{\sphinxupquote{simpl\_depind}} tactic includes an automatic tactic that tries to
simplify equalities appearing at the beginning of induction
hypotheses, generally using trivial applications of \sphinxcode{\sphinxupquote{reflexivity}}. In
cases where the equality is not between constructor forms though, one
must help the automation by giving some arguments, using the
\sphinxcode{\sphinxupquote{specialize}} tactic for example.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{destruct} \PYG{n}{D}\PYG{o}{..}\PYG{o}{.} \PYG{k}{apply} \PYG{n}{weak}\PYG{o}{;} \PYG{k}{apply} \PYG{n}{ax}\PYG{o}{.}
\PYG{k}{apply} \PYG{n}{ax}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{destruct} \PYG{n}{D}\PYG{o}{..}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Show}\PYG{o}{.}
    \PYG{l+m+mi}{4} \PYG{n}{subgoals}
      
      \PYG{n}{G0} \PYG{o}{:} \PYG{n}{ctx}
      \PYG{n}{tau} \PYG{o}{:} \PYG{n}{type}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{term} \PYG{n}{G0} \PYG{n}{tau}
      \PYG{n}{tau\PYGZsq{}} \PYG{o}{:} \PYG{n}{type}
      \PYG{n}{IHterm} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{G} \PYG{n}{D} \PYG{o}{:} \PYG{n}{ctx}\PYG{o}{,}
               \PYG{n}{G0} \PYG{o}{=} \PYG{n}{G}\PYG{o}{;} \PYG{n}{D} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{tau\PYGZsq{}} \PYG{o}{:} \PYG{n}{type}\PYG{o}{,} \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}}\PYG{o}{)}\PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{n}{tau}
      \PYG{n}{tau\PYGZsq{}0} \PYG{o}{:} \PYG{n}{type}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{n}{G0}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}}\PYG{o}{)}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}0}\PYG{o}{)} \PYG{n}{tau}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}0}\PYG{o}{)}\PYG{o}{;} \PYG{n}{D}\PYG{o}{)}\PYG{o}{,} \PYG{n}{t}\PYG{o}{)} \PYG{n}{tau}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}0}\PYG{o}{)}\PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{o}{(}\PYG{n}{tau} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{tau\PYGZsq{}}\PYG{o}{)}
    \PYG{n}{subgoal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}0}\PYG{o}{)}\PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{n}{tau\PYGZsq{}}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{specialize} \PYG{o}{(}\PYG{n}{IHterm} \PYG{n}{G0} \PYG{n}{empty} \PYG{n}{eq\PYGZus{}refl}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{4} \PYG{n}{subgoals}
      
      \PYG{n}{G0} \PYG{o}{:} \PYG{n}{ctx}
      \PYG{n}{tau} \PYG{o}{:} \PYG{n}{type}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{term} \PYG{n}{G0} \PYG{n}{tau}
      \PYG{n}{tau\PYGZsq{}} \PYG{o}{:} \PYG{n}{type}
      \PYG{n}{IHterm} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{tau\PYGZsq{}} \PYG{o}{:} \PYG{n}{type}\PYG{o}{,} \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{n}{G0}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}}\PYG{o}{)}\PYG{o}{;} \PYG{n}{empty}\PYG{o}{)} \PYG{n}{tau}
      \PYG{n}{tau\PYGZsq{}0} \PYG{o}{:} \PYG{n}{type}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{n}{G0}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}}\PYG{o}{)}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}0}\PYG{o}{)} \PYG{n}{tau}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}0}\PYG{o}{)}\PYG{o}{;} \PYG{n}{D}\PYG{o}{)}\PYG{o}{,} \PYG{n}{t}\PYG{o}{)} \PYG{n}{tau}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}0}\PYG{o}{)}\PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{o}{(}\PYG{n}{tau} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{tau\PYGZsq{}}\PYG{o}{)}
    \PYG{n}{subgoal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}0}\PYG{o}{)}\PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{n}{tau\PYGZsq{}}
\end{sphinxVerbatim}

Once the induction hypothesis has been narrowed to the right equality,
it can be used directly.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{apply} \PYG{n}{weak}\PYG{o}{,} \PYG{n}{IHterm}\PYG{o}{.}
    \PYG{l+m+mi}{3} \PYG{n}{subgoals}
      
      \PYG{n}{tau} \PYG{o}{:} \PYG{n}{type}
      \PYG{n}{G}\PYG{o}{,} \PYG{n}{D} \PYG{o}{:} \PYG{n}{ctx}
      \PYG{n}{IHterm} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{G0} \PYG{n}{D0} \PYG{o}{:} \PYG{n}{ctx}\PYG{o}{,}
               \PYG{n}{G}\PYG{o}{;} \PYG{n}{D} \PYG{o}{=} \PYG{n}{G0}\PYG{o}{;} \PYG{n}{D0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{tau\PYGZsq{}} \PYG{o}{:} \PYG{n}{type}\PYG{o}{,} \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{n}{G0}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}}\PYG{o}{)}\PYG{o}{;} \PYG{n}{D0}\PYG{o}{)} \PYG{n}{tau}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{term} \PYG{o}{(}\PYG{n}{G}\PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{n}{tau}
      \PYG{n}{t}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}0} \PYG{o}{:} \PYG{n}{type}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}0}\PYG{o}{)}\PYG{o}{;} \PYG{n}{D}\PYG{o}{)}\PYG{o}{,} \PYG{n}{t}\PYG{o}{)} \PYG{n}{tau}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}0}\PYG{o}{)}\PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{o}{(}\PYG{n}{tau} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{tau\PYGZsq{}}\PYG{o}{)}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{term} \PYG{o}{(}\PYG{o}{(}\PYG{n}{G}\PYG{o}{,} \PYG{n}{tau\PYGZsq{}0}\PYG{o}{)}\PYG{o}{;} \PYG{n}{D}\PYG{o}{)} \PYG{n}{tau\PYGZsq{}}
\end{sphinxVerbatim}

Now concluding this subgoal is easy.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{constructor}\PYG{o}{;} \PYG{k}{apply} \PYG{n}{IHterm}\PYG{o}{;} \PYG{k+kp}{reflexivity}\PYG{o}{.}
\end{sphinxVerbatim}


\sphinxstrong{See also:}


The {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{induction}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.case}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{case}}}}}, and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.inversion}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{inversion}}}}} tactics.




\subsection{autorewrite}
\label{\detokenize{proof-engine/detailed-tactic-examples:autorewrite}}
Here are two examples of \sphinxcode{\sphinxupquote{autorewrite}} use. The first one ( \sphinxstyleemphasis{Ackermann
function}) shows actually a quite basic use where there is no
conditional rewriting. The second one ( \sphinxstyleemphasis{Mac Carthy function})
involves conditional rewritings and shows how to deal with them using
the optional tactic of the \sphinxcode{\sphinxupquote{Hint Rewrite}} command.

\begin{sphinxadmonition}{note}{Example: Ackermann function}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Arith}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variable} \PYG{n}{Ack} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{Ack0} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Ack} \PYG{l+m+mi}{0} \PYG{n}{m} \PYG{o}{=} \PYG{n}{S} \PYG{n}{m}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{Ack1} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Ack} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{Ack} \PYG{n}{n} \PYG{l+m+mi}{1}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{Ack2} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Ack} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)} \PYG{o}{=} \PYG{n}{Ack} \PYG{n}{n} \PYG{o}{(}\PYG{n}{Ack} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Hint} \PYG{k+kn}{Rewrite} \PYG{n}{Ack0} \PYG{n}{Ack1} \PYG{n}{Ack2} \PYG{o}{:} \PYG{n}{base0}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{ResAck0} \PYG{o}{:} \PYG{n}{Ack} \PYG{l+m+mi}{3} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{l+m+mi}{29}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{Ack} \PYG{l+m+mi}{3} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{l+m+mi}{29}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{autorewrite} \PYG{k}{with} \PYG{n}{base0} \PYG{k}{using} \PYG{k+kr}{try} \PYG{k+kp}{reflexivity}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example: MacCarthy function}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Omega}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variable} \PYG{n}{g} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{g0} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{g} \PYG{l+m+mi}{0} \PYG{n}{m} \PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{g1} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{o}{(}\PYG{n}{n} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{m} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{100}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{g} \PYG{n}{n} \PYG{n}{m} \PYG{o}{=} \PYG{n}{g} \PYG{o}{(}\PYG{n}{pred} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{10}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{g2} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{o}{(}\PYG{n}{n} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{100}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{g} \PYG{n}{n} \PYG{n}{m} \PYG{o}{=} \PYG{n}{g} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{11}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Hint} \PYG{k+kn}{Rewrite} \PYG{n}{g0} \PYG{n}{g1} \PYG{n}{g2} \PYG{k}{using} \PYG{k+kp}{omega} \PYG{o}{:} \PYG{n}{base1}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{Resg0} \PYG{o}{:} \PYG{n}{g} \PYG{l+m+mi}{1} \PYG{l+m+mi}{110} \PYG{o}{=} \PYG{l+m+mi}{100}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{g} \PYG{l+m+mi}{1} \PYG{l+m+mi}{110} \PYG{o}{=} \PYG{l+m+mi}{100}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{autorewrite} \PYG{k}{with} \PYG{n}{base1} \PYG{k}{using} \PYG{k+kp}{reflexivity} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{k}{simpl}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{Resg1} \PYG{o}{:} \PYG{n}{g} \PYG{l+m+mi}{1} \PYG{l+m+mi}{95} \PYG{o}{=} \PYG{l+m+mi}{91}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{g} \PYG{l+m+mi}{1} \PYG{l+m+mi}{95} \PYG{o}{=} \PYG{l+m+mi}{91}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{autorewrite} \PYG{k}{with} \PYG{n}{base1} \PYG{k}{using} \PYG{k+kp}{reflexivity} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{k}{simpl}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsection{quote}
\label{\detokenize{proof-engine/detailed-tactic-examples:quote}}\label{\detokenize{proof-engine/detailed-tactic-examples:id2}}
The tactic \sphinxcode{\sphinxupquote{quote}} allows using Barendregt’s so-called 2-level approach
without writing any ML code. Suppose you have a language \sphinxcode{\sphinxupquote{L}} of
'abstract terms' and a type \sphinxcode{\sphinxupquote{A}} of 'concrete terms' and a function \sphinxcode{\sphinxupquote{f : L -\textgreater{} A}}.
If \sphinxcode{\sphinxupquote{L}} is a simple inductive datatype and \sphinxcode{\sphinxupquote{f}} a simple fixpoint,
\sphinxcode{\sphinxupquote{quote f}} will replace the head of current goal by a convertible term of
the form \sphinxcode{\sphinxupquote{(f t)}}. \sphinxcode{\sphinxupquote{L}} must have a constructor of type: \sphinxcode{\sphinxupquote{A -\textgreater{} L}}.

Here is an example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Quote}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameters} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{A} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{B} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{C} \PYG{k}{is} \PYG{n}{declared}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{formula} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}and} \PYG{o}{:} \PYG{n}{formula} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula} \PYG{c}{(*}\PYG{c}{ binary constructor }\PYG{c}{*)}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}or} \PYG{o}{:} \PYG{n}{formula} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}not} \PYG{o}{:} \PYG{n}{formula} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula} \PYG{c}{(*}\PYG{c}{ unary constructor }\PYG{c}{*)}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}true} \PYG{o}{:} \PYG{n}{formula} \PYG{c}{(*}\PYG{c}{ 0\PYGZhy{}ary constructor }\PYG{c}{*)}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}const} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula} \PYG{c}{(*}\PYG{c}{ constructor for constants }\PYG{c}{*)}\PYG{o}{.}
    \PYG{n}{formula} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{formula\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{formula\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{formula\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{interp\PYGZus{}f} \PYG{o}{(}\PYG{n}{f}\PYG{o}{:}\PYG{n}{formula}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=}
         \PYG{k}{match} \PYG{n}{f} \PYG{k}{with}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}and} \PYG{n}{f1} \PYG{n}{f2} \PYG{o}{=\PYGZgt{}} \PYG{n}{interp\PYGZus{}f} \PYG{n}{f1} \PYG{o}{/\PYGZbs{}} \PYG{n}{interp\PYGZus{}f} \PYG{n}{f2}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}or} \PYG{n}{f1} \PYG{n}{f2} \PYG{o}{=\PYGZgt{}} \PYG{n}{interp\PYGZus{}f} \PYG{n}{f1} \PYG{o}{\PYGZbs{}/} \PYG{n}{interp\PYGZus{}f} \PYG{n}{f2}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}not} \PYG{n}{f1} \PYG{o}{=\PYGZgt{}} \PYG{o}{\PYGZti{}} \PYG{n}{interp\PYGZus{}f} \PYG{n}{f1}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}true} \PYG{o}{=\PYGZgt{}} \PYG{n}{True}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}const} \PYG{n}{c} \PYG{o}{=\PYGZgt{}} \PYG{n}{c}
         \PYG{k}{end}\PYG{o}{.}
    \PYG{n}{interp\PYGZus{}f} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{interp\PYGZus{}f} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{o}{\PYGZti{}} \PYG{n}{B} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{o}{\PYGZti{}} \PYG{n}{B} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{A}\PYG{o}{)}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{quote} \PYG{n}{interp\PYGZus{}f}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{interp\PYGZus{}f}
        \PYG{o}{(}\PYG{n}{f\PYGZus{}and} \PYG{o}{(}\PYG{n}{f\PYGZus{}const} \PYG{n}{A}\PYG{o}{)}
           \PYG{o}{(}\PYG{n}{f\PYGZus{}and} \PYG{o}{(}\PYG{n}{f\PYGZus{}or} \PYG{o}{(}\PYG{n}{f\PYGZus{}const} \PYG{n}{A}\PYG{o}{)} \PYG{n}{f\PYGZus{}true}\PYG{o}{)}
              \PYG{o}{(}\PYG{n}{f\PYGZus{}and} \PYG{o}{(}\PYG{n}{f\PYGZus{}not} \PYG{o}{(}\PYG{n}{f\PYGZus{}const} \PYG{n}{B}\PYG{o}{)}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f\PYGZus{}const} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{A}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}
\end{sphinxVerbatim}

The algorithm to perform this inversion is: try to match the term with
right-hand sides expression of \sphinxcode{\sphinxupquote{f}}. If there is a match, apply the
corresponding left-hand side and call yourself recursively on sub-
terms. If there is no match, we are at a leaf: return the
corresponding constructor (here \sphinxcode{\sphinxupquote{f\_const}}) applied to the term.

When \sphinxcode{\sphinxupquote{quote}} is not able to perform inversion properly, it will error out with
{\hyperref[\detokenize{proof-engine/tactics:coq:exn.quote-not-a-simple-fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{quote: not a simple fixpoint}}}}}.


\subsubsection{Introducing variables map}
\label{\detokenize{proof-engine/detailed-tactic-examples:introducing-variables-map}}
The normal use of quote is to make proofs by reflection: one defines a
function \sphinxcode{\sphinxupquote{simplify : formula -\textgreater{} formula}} and proves a theorem
\sphinxcode{\sphinxupquote{simplify\_ok: (f:formula)(interp\_f (simplify f)) -\textgreater{} (interp\_f f)}}. Then,
one can simplify formulas by doing:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{quote} \PYG{n}{interp\PYGZus{}f}\PYG{o}{.}
\PYG{k}{apply} \PYG{n}{simplify\PYGZus{}ok}\PYG{o}{.}
\PYG{k}{compute}\PYG{o}{.}
\end{sphinxVerbatim}

But there is a problem with leafs: in the example above one cannot
write a function that implements, for example, the logical
simplifications \(A \wedge A \rightarrow A\) or \(A \wedge
\lnot A \rightarrow \mathrm{False}\). This is because \sphinxcode{\sphinxupquote{Prop}} is
impredicative.

It is better to use that type of formulas:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Quote}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameters} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{formula} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}and} \PYG{o}{:} \PYG{n}{formula} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}or} \PYG{o}{:} \PYG{n}{formula} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}not} \PYG{o}{:} \PYG{n}{formula} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}true} \PYG{o}{:} \PYG{n}{formula}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}atom} \PYG{o}{:} \PYG{n}{index} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula}\PYG{o}{.}
    \PYG{n}{formula} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{formula\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{formula\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{formula\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\sphinxcode{\sphinxupquote{index}} is defined in module \sphinxcode{\sphinxupquote{Quote}}. Equality on that type is
decidable so we are able to simplify \(A \wedge A\) into \(A\)
at the abstract level.

When there are variables, there are bindings, and \sphinxcode{\sphinxupquote{quote}} also
provides a type \sphinxcode{\sphinxupquote{(varmap A)}} of bindings from index to any set
\sphinxcode{\sphinxupquote{A}}, and a function \sphinxcode{\sphinxupquote{varmap\_find}} to search in such maps. The
interpretation function also has another argument, a variables map:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{interp\PYGZus{}f} \PYG{o}{(}\PYG{n}{vm}\PYG{o}{:}\PYG{n}{varmap} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f}\PYG{o}{:}\PYG{n}{formula}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{f}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=}
         \PYG{k}{match} \PYG{n}{f} \PYG{k}{with}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}and} \PYG{n}{f1} \PYG{n}{f2} \PYG{o}{=\PYGZgt{}} \PYG{n}{interp\PYGZus{}f} \PYG{n}{vm} \PYG{n}{f1} \PYG{o}{/\PYGZbs{}} \PYG{n}{interp\PYGZus{}f} \PYG{n}{vm} \PYG{n}{f2}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}or} \PYG{n}{f1} \PYG{n}{f2} \PYG{o}{=\PYGZgt{}} \PYG{n}{interp\PYGZus{}f} \PYG{n}{vm} \PYG{n}{f1} \PYG{o}{\PYGZbs{}/} \PYG{n}{interp\PYGZus{}f} \PYG{n}{vm} \PYG{n}{f2}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}not} \PYG{n}{f1} \PYG{o}{=\PYGZgt{}} \PYG{o}{\PYGZti{}} \PYG{n}{interp\PYGZus{}f} \PYG{n}{vm} \PYG{n}{f1}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}true} \PYG{o}{=\PYGZgt{}} \PYG{n}{True}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}atom} \PYG{n}{i} \PYG{o}{=\PYGZgt{}} \PYG{n}{varmap\PYGZus{}find} \PYG{n}{True} \PYG{n}{i} \PYG{n}{vm}
         \PYG{k}{end}\PYG{o}{.}
    \PYG{n}{interp\PYGZus{}f} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{interp\PYGZus{}f} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{2}\PYG{n}{nd} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}

\sphinxcode{\sphinxupquote{quote}} handles this second case properly:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{n}{B} \PYG{o}{\PYGZbs{}/} \PYG{n}{A}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{o}{\PYGZti{}} \PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{n}{B} \PYG{o}{\PYGZbs{}/} \PYG{n}{A}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{o}{\PYGZti{}} \PYG{n}{B}\PYG{o}{)}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{quote} \PYG{n}{interp\PYGZus{}f}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{interp\PYGZus{}f}
        \PYG{o}{(}\PYG{n}{Node\PYGZus{}vm} \PYG{n}{B} \PYG{o}{(}\PYG{n}{Node\PYGZus{}vm} \PYG{n}{A} \PYG{o}{(}\PYG{n}{Empty\PYGZus{}vm} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Empty\PYGZus{}vm} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Empty\PYGZus{}vm} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{)}
        \PYG{o}{(}\PYG{n}{f\PYGZus{}and} \PYG{o}{(}\PYG{n}{f\PYGZus{}atom} \PYG{o}{(}\PYG{n}{Left\PYGZus{}idx} \PYG{n}{End\PYGZus{}idx}\PYG{o}{)}\PYG{o}{)}
           \PYG{o}{(}\PYG{n}{f\PYGZus{}and} \PYG{o}{(}\PYG{n}{f\PYGZus{}or} \PYG{o}{(}\PYG{n}{f\PYGZus{}atom} \PYG{n}{End\PYGZus{}idx}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f\PYGZus{}atom} \PYG{o}{(}\PYG{n}{Left\PYGZus{}idx} \PYG{n}{End\PYGZus{}idx}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}
              \PYG{o}{(}\PYG{n}{f\PYGZus{}or} \PYG{o}{(}\PYG{n}{f\PYGZus{}atom} \PYG{o}{(}\PYG{n}{Left\PYGZus{}idx} \PYG{n}{End\PYGZus{}idx}\PYG{o}{)}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f\PYGZus{}not} \PYG{o}{(}\PYG{n}{f\PYGZus{}atom} \PYG{n}{End\PYGZus{}idx}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}
\end{sphinxVerbatim}

It builds \sphinxcode{\sphinxupquote{vm}} and \sphinxcode{\sphinxupquote{t}} such that \sphinxcode{\sphinxupquote{(f vm t)}} is convertible with the
conclusion of current goal.


\subsubsection{Combining variables and constants}
\label{\detokenize{proof-engine/detailed-tactic-examples:combining-variables-and-constants}}
One can have both variables and constants in abstracts terms; for
example, this is the case for the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.ring}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ring}}}}} tactic. Then one must provide to
\sphinxcode{\sphinxupquote{quote}} a list of \sphinxstyleemphasis{constructors of constants}. For example, if the list
is \sphinxcode{\sphinxupquote{{[}O S{]}}} then closed natural numbers will be considered as constants
and other terms as variables.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Quote}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameters} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{formula} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}and} \PYG{o}{:} \PYG{n}{formula} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}or} \PYG{o}{:} \PYG{n}{formula} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}not} \PYG{o}{:} \PYG{n}{formula} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}true} \PYG{o}{:} \PYG{n}{formula}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}const} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula} \PYG{c}{(*}\PYG{c}{ constructor for constants }\PYG{c}{*)}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}atom} \PYG{o}{:} \PYG{n}{index} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{formula}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{interp\PYGZus{}f} \PYG{o}{(}\PYG{n}{vm}\PYG{o}{:}\PYG{n}{varmap} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f}\PYG{o}{:}\PYG{n}{formula}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{f}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=}
         \PYG{k}{match} \PYG{n}{f} \PYG{k}{with}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}and} \PYG{n}{f1} \PYG{n}{f2} \PYG{o}{=\PYGZgt{}} \PYG{n}{interp\PYGZus{}f} \PYG{n}{vm} \PYG{n}{f1} \PYG{o}{/\PYGZbs{}} \PYG{n}{interp\PYGZus{}f} \PYG{n}{vm} \PYG{n}{f2}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}or} \PYG{n}{f1} \PYG{n}{f2} \PYG{o}{=\PYGZgt{}} \PYG{n}{interp\PYGZus{}f} \PYG{n}{vm} \PYG{n}{f1} \PYG{o}{\PYGZbs{}/} \PYG{n}{interp\PYGZus{}f} \PYG{n}{vm} \PYG{n}{f2}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}not} \PYG{n}{f1} \PYG{o}{=\PYGZgt{}} \PYG{o}{\PYGZti{}} \PYG{n}{interp\PYGZus{}f} \PYG{n}{vm} \PYG{n}{f1}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}true} \PYG{o}{=\PYGZgt{}} \PYG{n}{True}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}const} \PYG{n}{c} \PYG{o}{=\PYGZgt{}} \PYG{n}{c}
         \PYG{o}{\textbar{}} \PYG{n}{f\PYGZus{}atom} \PYG{n}{i} \PYG{o}{=\PYGZgt{}} \PYG{n}{varmap\PYGZus{}find} \PYG{n}{True} \PYG{n}{i} \PYG{n}{vm}
         \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{o}{\PYGZti{}} \PYG{n}{B} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{n}{C} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{quote} \PYG{n}{interp\PYGZus{}f} \PYG{o}{[} \PYG{n}{A} \PYG{n}{B} \PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{interp\PYGZus{}f} \PYG{o}{(}\PYG{n}{Node\PYGZus{}vm} \PYG{o}{(}\PYG{n}{C} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Empty\PYGZus{}vm} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Empty\PYGZus{}vm} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{)}
        \PYG{o}{(}\PYG{n}{f\PYGZus{}and} \PYG{o}{(}\PYG{n}{f\PYGZus{}const} \PYG{n}{A}\PYG{o}{)}
           \PYG{o}{(}\PYG{n}{f\PYGZus{}and} \PYG{o}{(}\PYG{n}{f\PYGZus{}or} \PYG{o}{(}\PYG{n}{f\PYGZus{}const} \PYG{n}{A}\PYG{o}{)} \PYG{n}{f\PYGZus{}true}\PYG{o}{)}
              \PYG{o}{(}\PYG{n}{f\PYGZus{}and} \PYG{o}{(}\PYG{n}{f\PYGZus{}not} \PYG{o}{(}\PYG{n}{f\PYGZus{}const} \PYG{n}{B}\PYG{o}{)}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f\PYGZus{}atom} \PYG{n}{End\PYGZus{}idx}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Undo}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{n}{True}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{o}{\PYGZti{}} \PYG{n}{B} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{n}{C} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{)}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{quote} \PYG{n}{interp\PYGZus{}f} \PYG{o}{[} \PYG{n}{B} \PYG{n}{C} \PYG{n}{iff} \PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{interp\PYGZus{}f} \PYG{o}{(}\PYG{n}{Node\PYGZus{}vm} \PYG{n}{A} \PYG{o}{(}\PYG{n}{Empty\PYGZus{}vm} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Empty\PYGZus{}vm} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{)}
        \PYG{o}{(}\PYG{n}{f\PYGZus{}and} \PYG{o}{(}\PYG{n}{f\PYGZus{}atom} \PYG{n}{End\PYGZus{}idx}\PYG{o}{)}
           \PYG{o}{(}\PYG{n}{f\PYGZus{}and} \PYG{o}{(}\PYG{n}{f\PYGZus{}or} \PYG{o}{(}\PYG{n}{f\PYGZus{}atom} \PYG{n}{End\PYGZus{}idx}\PYG{o}{)} \PYG{n}{f\PYGZus{}true}\PYG{o}{)}
              \PYG{o}{(}\PYG{n}{f\PYGZus{}and} \PYG{o}{(}\PYG{n}{f\PYGZus{}not} \PYG{o}{(}\PYG{n}{f\PYGZus{}const} \PYG{n}{B}\PYG{o}{)}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f\PYGZus{}const} \PYG{o}{(}\PYG{n}{C} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{warning}{Warning:}
Since functional inversion is undecidable in the general case,
don’t expect miracles from it!
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{quote~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~using~\DUrole{hole}{tactic}}}}}
\sphinxcode{\sphinxupquote{tactic}} must be a functional tactic (starting with \sphinxcode{\sphinxupquote{fun x =\textgreater{}}}) and
will be called with the quoted version of term according to \sphinxcode{\sphinxupquote{ident}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{quote~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}{]}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~using~\DUrole{hole}{tactic}}}}}
Same as above, but will use the additional \sphinxcode{\sphinxupquote{ident}} list to chose
which subterms are constants (see above).

\end{fulllineitems}



\sphinxstrong{See also:}


Comments from the source file \sphinxcode{\sphinxupquote{plugins/quote/quote.ml}}




\sphinxstrong{See also:}


The {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.ring}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ring}}}}} tactic.




\subsection{Using the tactic language}
\label{\detokenize{proof-engine/detailed-tactic-examples:using-the-tactic-language}}

\subsubsection{About the cardinality of the set of natural numbers}
\label{\detokenize{proof-engine/detailed-tactic-examples:about-the-cardinality-of-the-set-of-natural-numbers}}
The first example which shows how to use pattern matching over the
proof context is a proof of the fact that natural numbers have more
than two elements. This can be done as follows:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{card\PYGZus{}nat} \PYG{o}{:}
  \PYG{o}{\PYGZti{}} \PYG{k}{exists} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{k}{exists} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{k}{forall} \PYG{n}{z}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=} \PYG{n}{z} \PYG{o}{\PYGZbs{}/} \PYG{n}{y} \PYG{o}{=} \PYG{n}{z}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{red}\PYG{o}{;} \PYG{k}{intros} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{o}{(}\PYG{n}{y}\PYG{o}{,} \PYG{n}{Hy}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{elim} \PYG{o}{(}\PYG{n}{Hy} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{;} \PYG{k}{elim} \PYG{o}{(}\PYG{n}{Hy} \PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{;} \PYG{k}{elim} \PYG{o}{(}\PYG{n}{Hy} \PYG{l+m+mi}{2}\PYG{o}{)}\PYG{o}{;} \PYG{k}{intros}\PYG{o}{;}

\PYG{k}{match} \PYG{n}{goal} \PYG{k}{with}
    \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{o}{?}\PYG{n}{a} \PYG{o}{=} \PYG{o}{?}\PYG{n}{b}\PYG{o}{,} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{o}{?}\PYG{n}{a} \PYG{o}{=} \PYG{o}{?}\PYG{n}{c} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}}
        \PYG{k}{cut} \PYG{o}{(}\PYG{n}{b} \PYG{o}{=} \PYG{n}{c}\PYG{o}{)}\PYG{o}{;} \PYG{o}{[} \PYG{k+kp}{discriminate} \PYG{o}{\textbar{}} \PYG{k}{transitivity} \PYG{n}{a}\PYG{o}{;} \PYG{k}{auto} \PYG{o}{]}
\PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}

We can notice that all the (very similar) cases coming from the three
eliminations (with three distinct natural numbers) are successfully
solved by a match goal structure and, in particular, with only one
pattern (use of non-linear matching).


\subsubsection{Permutations of lists}
\label{\detokenize{proof-engine/detailed-tactic-examples:permutations-of-lists}}
A more complex example is the problem of permutations of
lists. The aim is to show that a list is a permutation of
another list.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Section} \PYG{n}{Sort}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variable} \PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{perm} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
    \PYG{o}{\textbar{}} \PYG{n}{perm\PYGZus{}refl} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{l}\PYG{o}{,} \PYG{n}{perm} \PYG{n}{l} \PYG{n}{l}
    \PYG{o}{\textbar{}} \PYG{n}{perm\PYGZus{}cons} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{l0} \PYG{n}{l1}\PYG{o}{,} \PYG{n}{perm} \PYG{n}{l0} \PYG{n}{l1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{perm} \PYG{o}{(}\PYG{n}{a} \PYG{o}{::} \PYG{n}{l0}\PYG{o}{)} \PYG{o}{(}\PYG{n}{a} \PYG{o}{::} \PYG{n}{l1}\PYG{o}{)}
    \PYG{o}{\textbar{}} \PYG{n}{perm\PYGZus{}append} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{l}\PYG{o}{,} \PYG{n}{perm} \PYG{o}{(}\PYG{n}{a} \PYG{o}{::} \PYG{n}{l}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l} \PYG{o}{+}\PYG{o}{+} \PYG{n}{a} \PYG{o}{::} \PYG{n}{nil}\PYG{o}{)}
    \PYG{o}{\textbar{}} \PYG{n}{perm\PYGZus{}trans} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{l0} \PYG{n}{l1} \PYG{n}{l2}\PYG{o}{,} \PYG{n}{perm} \PYG{n}{l0} \PYG{n}{l1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{perm} \PYG{n}{l1} \PYG{n}{l2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{perm} \PYG{n}{l0} \PYG{n}{l2}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{End} \PYG{n}{Sort}\PYG{o}{.}
\end{sphinxVerbatim}

First, we define the permutation predicate as shown above.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{perm\PYGZus{}aux} \PYG{n}{n} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{goal} \PYG{k}{with}
    \PYG{o}{\textbar{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{(}\PYG{n}{perm} \PYG{o}{\PYGZus{}} \PYG{o}{?}\PYG{n}{l} \PYG{o}{?}\PYG{n}{l}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{k}{apply} \PYG{n}{perm\PYGZus{}refl}
    \PYG{o}{\textbar{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{(}\PYG{n}{perm} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{o}{?}\PYG{n}{a} \PYG{o}{::} \PYG{o}{?}\PYG{n}{l1}\PYG{o}{)} \PYG{o}{(}\PYG{o}{?}\PYG{n}{a} \PYG{o}{::} \PYG{o}{?}\PYG{n}{l2}\PYG{o}{)}\PYG{o}{)} \PYG{o}{=\PYGZgt{}}
        \PYG{k}{let} \PYG{n}{newn} \PYG{o}{:=} \PYG{n}{eval} \PYG{k}{compute} \PYG{k}{in} \PYG{o}{(}\PYG{n}{length} \PYG{n}{l1}\PYG{o}{)} \PYG{k}{in}
            \PYG{o}{(}\PYG{k}{apply} \PYG{n}{perm\PYGZus{}cons}\PYG{o}{;} \PYG{n}{perm\PYGZus{}aux} \PYG{n}{newn}\PYG{o}{)}
    \PYG{o}{\textbar{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{(}\PYG{n}{perm} \PYG{o}{?}\PYG{n}{A} \PYG{o}{(}\PYG{o}{?}\PYG{n}{a} \PYG{o}{::} \PYG{o}{?}\PYG{n}{l1}\PYG{o}{)} \PYG{o}{?}\PYG{n}{l2}\PYG{o}{)} \PYG{o}{=\PYGZgt{}}
        \PYG{k}{match} \PYG{n}{eval} \PYG{k}{compute} \PYG{k}{in} \PYG{n}{n} \PYG{k}{with}
            \PYG{o}{\textbar{}} \PYG{l+m+mi}{1} \PYG{o}{=\PYGZgt{}} \PYG{n}{fail}
            \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}}
                \PYG{k}{let} \PYG{n}{l1\PYGZsq{}} \PYG{o}{:=} \PYG{n}{constr}\PYG{o}{:}\PYG{o}{(}\PYG{n}{l1} \PYG{o}{+}\PYG{o}{+} \PYG{n}{a} \PYG{o}{::} \PYG{n}{nil}\PYG{o}{)} \PYG{k}{in}
                    \PYG{o}{(}\PYG{k}{apply} \PYG{o}{(}\PYG{n}{perm\PYGZus{}trans} \PYG{n}{A} \PYG{o}{(}\PYG{n}{a} \PYG{o}{::} \PYG{n}{l1}\PYG{o}{)} \PYG{n}{l1\PYGZsq{}} \PYG{n}{l2}\PYG{o}{)}\PYG{o}{;}
                    \PYG{o}{[} \PYG{k}{apply} \PYG{n}{perm\PYGZus{}append} \PYG{o}{\textbar{}} \PYG{k}{compute}\PYG{o}{;} \PYG{n}{perm\PYGZus{}aux} \PYG{o}{(}\PYG{n}{pred} \PYG{n}{n}\PYG{o}{)} \PYG{o}{]}\PYG{o}{)}
        \PYG{k}{end}
\PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

Next we define an auxiliary tactic \sphinxcode{\sphinxupquote{perm\_aux}} which takes an argument
used to control the recursion depth. This tactic behaves as follows. If
the lists are identical (i.e. convertible), it concludes. Otherwise, if
the lists have identical heads, it proceeds to look at their tails.
Finally, if the lists have different heads, it rotates the first list by
putting its head at the end if the new head hasn't been the head previously. To check this, we keep track of the
number of performed rotations using the argument \sphinxcode{\sphinxupquote{n}}. We do this by
decrementing \sphinxcode{\sphinxupquote{n}} each time we perform a rotation. It works because
for a list of length \sphinxcode{\sphinxupquote{n}} we can make exactly \sphinxcode{\sphinxupquote{n - 1}} rotations
to generate at most \sphinxcode{\sphinxupquote{n}} distinct lists. Notice that we use the natural
numbers of Coq for the rotation counter. From {\hyperref[\detokenize{proof-engine/ltac:ltac-syntax}]{\sphinxcrossref{\DUrole{std,std-ref}{Syntax}}}} we know
that it is possible to use the usual natural numbers, but they are only
used as arguments for primitive tactics and they cannot be handled, so,
in particular, we cannot make computations with them. Thus the natural
choice is to use Coq data structures so that Coq makes the computations
(reductions) by \sphinxcode{\sphinxupquote{eval compute in}} and we can get the terms back by match.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{solve\PYGZus{}perm} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{goal} \PYG{k}{with}
    \PYG{o}{\textbar{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{(}\PYG{n}{perm} \PYG{o}{\PYGZus{}} \PYG{o}{?}\PYG{n}{l1} \PYG{o}{?}\PYG{n}{l2}\PYG{o}{)} \PYG{o}{=\PYGZgt{}}
        \PYG{k}{match} \PYG{n}{eval} \PYG{k}{compute} \PYG{k}{in} \PYG{o}{(}\PYG{n}{length} \PYG{n}{l1} \PYG{o}{=} \PYG{n}{length} \PYG{n}{l2}\PYG{o}{)} \PYG{k}{with}
            \PYG{o}{\textbar{}} \PYG{o}{(}\PYG{o}{?}\PYG{n}{n} \PYG{o}{=} \PYG{o}{?}\PYG{n}{n}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{perm\PYGZus{}aux} \PYG{n}{n}
        \PYG{k}{end}
\PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

The main tactic is \sphinxcode{\sphinxupquote{solve\_perm}}. It computes the lengths of the two lists
and uses them as arguments to call \sphinxcode{\sphinxupquote{perm\_aux}} if the lengths are equal (if they
aren't, the lists cannot be permutations of each other). Using this tactic we
can now prove lemmas as follows:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{solve\PYGZus{}perm\PYGZus{}ex1} \PYG{o}{:}
  \PYG{n}{perm} \PYG{k+kt}{nat} \PYG{o}{(}\PYG{l+m+mi}{1} \PYG{o}{::} \PYG{l+m+mi}{2} \PYG{o}{::} \PYG{l+m+mi}{3} \PYG{o}{::} \PYG{n}{nil}\PYG{o}{)} \PYG{o}{(}\PYG{l+m+mi}{3} \PYG{o}{::} \PYG{l+m+mi}{2} \PYG{o}{::} \PYG{l+m+mi}{1} \PYG{o}{::} \PYG{n}{nil}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{n}{solve\PYGZus{}perm}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{solve\PYGZus{}perm\PYGZus{}ex2} \PYG{o}{:}
  \PYG{n}{perm} \PYG{k+kt}{nat}
    \PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{::} \PYG{l+m+mi}{1} \PYG{o}{::} \PYG{l+m+mi}{2} \PYG{o}{::} \PYG{l+m+mi}{3} \PYG{o}{::} \PYG{l+m+mi}{4} \PYG{o}{::} \PYG{l+m+mi}{5} \PYG{o}{::} \PYG{l+m+mi}{6} \PYG{o}{::} \PYG{l+m+mi}{7} \PYG{o}{::} \PYG{l+m+mi}{8} \PYG{o}{::} \PYG{l+m+mi}{9} \PYG{o}{::} \PYG{n}{nil}\PYG{o}{)}
      \PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{::} \PYG{l+m+mi}{2} \PYG{o}{::} \PYG{l+m+mi}{4} \PYG{o}{::} \PYG{l+m+mi}{6} \PYG{o}{::} \PYG{l+m+mi}{8} \PYG{o}{::} \PYG{l+m+mi}{9} \PYG{o}{::} \PYG{l+m+mi}{7} \PYG{o}{::} \PYG{l+m+mi}{5} \PYG{o}{::} \PYG{l+m+mi}{3} \PYG{o}{::} \PYG{l+m+mi}{1} \PYG{o}{::} \PYG{n}{nil}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{n}{solve\PYGZus{}perm}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Deciding intuitionistic propositional logic}
\label{\detokenize{proof-engine/detailed-tactic-examples:deciding-intuitionistic-propositional-logic}}
Pattern matching on goals allows a powerful backtracking when returning tactic
values. An interesting application is the problem of deciding intuitionistic
propositional logic. Considering the contraction-free sequent calculi LJT* of
Roy Dyckhoff \sphinxcite{zebibliography:dyc92}, it is quite natural to code such a tactic using the
tactic language as shown below.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{basic} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{goal} \PYG{k}{with}
    \PYG{o}{\textbar{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{n}{True} \PYG{o}{=\PYGZgt{}} \PYG{k}{trivial}
    \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{False} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k+kp}{contradiction}
    \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{o}{?}\PYG{n}{A} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{=\PYGZgt{}} \PYG{k+kp}{assumption}
\PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{simplify} \PYG{o}{:=}
\PYG{k+kr}{repeat} \PYG{o}{(}\PYG{k}{intros}\PYG{o}{;}
    \PYG{k}{match} \PYG{n}{goal} \PYG{k}{with}
        \PYG{o}{\textbar{}} \PYG{n}{H} \PYG{o}{:} \PYG{o}{\PYGZti{}} \PYG{o}{\PYGZus{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k}{red} \PYG{k}{in} \PYG{n}{H}
        \PYG{o}{\textbar{}} \PYG{n}{H} \PYG{o}{:} \PYG{o}{\PYGZus{}} \PYG{o}{/\PYGZbs{}} \PYG{o}{\PYGZus{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}}
            \PYG{k}{elim} \PYG{n}{H}\PYG{o}{;} \PYG{k+kr}{do} \PYG{l+m+mi}{2} \PYG{k}{intro}\PYG{o}{;} \PYG{k}{clear} \PYG{n}{H}
        \PYG{o}{\textbar{}} \PYG{n}{H} \PYG{o}{:} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZbs{}/} \PYG{o}{\PYGZus{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}}
            \PYG{k}{elim} \PYG{n}{H}\PYG{o}{;} \PYG{k}{intro}\PYG{o}{;} \PYG{k}{clear} \PYG{n}{H}
        \PYG{o}{\textbar{}} \PYG{n}{H} \PYG{o}{:} \PYG{o}{?}\PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{o}{?}\PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{?}\PYG{n}{C} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}}
            \PYG{k}{cut} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{)}\PYG{o}{;}
                \PYG{o}{[} \PYG{k}{intro} \PYG{o}{\textbar{}} \PYG{k}{intros}\PYG{o}{;} \PYG{k}{apply} \PYG{n}{H}\PYG{o}{;} \PYG{k}{split}\PYG{o}{;} \PYG{k+kp}{assumption} \PYG{o}{]}
        \PYG{o}{\textbar{}} \PYG{n}{H}\PYG{o}{:} \PYG{o}{?}\PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{o}{?}\PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{?}\PYG{n}{C} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}}
            \PYG{k}{cut} \PYG{o}{(}\PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{)}\PYG{o}{;}
                \PYG{o}{[} \PYG{k}{cut} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{)}\PYG{o}{;}
                    \PYG{o}{[} \PYG{k}{intros}\PYG{o}{;} \PYG{k}{clear} \PYG{n}{H}
                    \PYG{o}{\textbar{}} \PYG{k}{intro}\PYG{o}{;} \PYG{k}{apply} \PYG{n}{H}\PYG{o}{;} \PYG{k}{left}\PYG{o}{;} \PYG{k+kp}{assumption} \PYG{o}{]}
                \PYG{o}{\textbar{}} \PYG{k}{intro}\PYG{o}{;} \PYG{k}{apply} \PYG{n}{H}\PYG{o}{;} \PYG{k}{right}\PYG{o}{;} \PYG{k+kp}{assumption} \PYG{o}{]}
        \PYG{o}{\textbar{}} \PYG{n}{H0} \PYG{o}{:} \PYG{o}{?}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{?}\PYG{n}{B}\PYG{o}{,} \PYG{n}{H1} \PYG{o}{:} \PYG{o}{?}\PYG{n}{A} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}}
            \PYG{k}{cut} \PYG{n}{B}\PYG{o}{;} \PYG{o}{[} \PYG{k}{intro}\PYG{o}{;} \PYG{k}{clear} \PYG{n}{H0} \PYG{o}{\textbar{}} \PYG{k}{apply} \PYG{n}{H0}\PYG{o}{;} \PYG{k+kp}{assumption} \PYG{o}{]}
        \PYG{o}{\textbar{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{/\PYGZbs{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k}{split}
        \PYG{o}{\textbar{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZti{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k}{red}
    \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{my\PYGZus{}tauto} \PYG{o}{:=}
  \PYG{n}{simplify}\PYG{o}{;} \PYG{n}{basic} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}}
  \PYG{k}{match} \PYG{n}{goal} \PYG{k}{with}
      \PYG{o}{\textbar{}} \PYG{n}{H} \PYG{o}{:} \PYG{o}{(}\PYG{o}{?}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{?}\PYG{n}{B}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{?}\PYG{n}{C} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}}
          \PYG{k}{cut} \PYG{o}{(}\PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{)}\PYG{o}{;}
              \PYG{o}{[} \PYG{k}{intro}\PYG{o}{;} \PYG{k}{cut} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{)}\PYG{o}{;}
                  \PYG{o}{[} \PYG{k}{intro}\PYG{o}{;} \PYG{k}{cut} \PYG{n}{C}\PYG{o}{;}
                      \PYG{o}{[} \PYG{k}{intro}\PYG{o}{;} \PYG{k}{clear} \PYG{n}{H} \PYG{o}{\textbar{}} \PYG{k}{apply} \PYG{n}{H}\PYG{o}{;} \PYG{k+kp}{assumption} \PYG{o}{]}
                  \PYG{o}{\textbar{}} \PYG{k}{clear} \PYG{n}{H} \PYG{o}{]}
              \PYG{o}{\textbar{}} \PYG{k}{intro}\PYG{o}{;} \PYG{k}{apply} \PYG{n}{H}\PYG{o}{;} \PYG{k}{intro}\PYG{o}{;} \PYG{k+kp}{assumption} \PYG{o}{]}\PYG{o}{;} \PYG{n}{my\PYGZus{}tauto}
      \PYG{o}{\textbar{}} \PYG{n}{H} \PYG{o}{:} \PYG{o}{\PYGZti{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{?}\PYG{n}{B} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}}
          \PYG{k}{cut} \PYG{o}{(}\PYG{n}{False} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{)}\PYG{o}{;}
              \PYG{o}{[} \PYG{k}{intro}\PYG{o}{;} \PYG{k}{cut} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}\PYG{o}{)}\PYG{o}{;}
                  \PYG{o}{[} \PYG{k}{intro}\PYG{o}{;} \PYG{k}{cut} \PYG{n}{B}\PYG{o}{;}
                      \PYG{o}{[} \PYG{k}{intro}\PYG{o}{;} \PYG{k}{clear} \PYG{n}{H} \PYG{o}{\textbar{}} \PYG{k}{apply} \PYG{n}{H}\PYG{o}{;} \PYG{k+kp}{assumption} \PYG{o}{]}
                  \PYG{o}{\textbar{}} \PYG{k}{clear} \PYG{n}{H} \PYG{o}{]}
              \PYG{o}{\textbar{}} \PYG{k}{intro}\PYG{o}{;} \PYG{k}{apply} \PYG{n}{H}\PYG{o}{;} \PYG{k}{red}\PYG{o}{;} \PYG{k}{intro}\PYG{o}{;} \PYG{k+kp}{assumption} \PYG{o}{]}\PYG{o}{;} \PYG{n}{my\PYGZus{}tauto}
      \PYG{o}{\textbar{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZbs{}/} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{o}{(}\PYG{k}{left}\PYG{o}{;} \PYG{n}{my\PYGZus{}tauto}\PYG{o}{)} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{o}{(}\PYG{k}{right}\PYG{o}{;} \PYG{n}{my\PYGZus{}tauto}\PYG{o}{)}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

The tactic \sphinxcode{\sphinxupquote{basic}} tries to reason using simple rules involving truth, falsity
and available assumptions. The tactic \sphinxcode{\sphinxupquote{simplify}} applies all the reversible
rules of Dyckhoff’s system. Finally, the tactic \sphinxcode{\sphinxupquote{my\_tauto}} (the main
tactic to be called) simplifies with \sphinxcode{\sphinxupquote{simplify}}, tries to conclude with
\sphinxcode{\sphinxupquote{basic}} and tries several paths using the backtracking rules (one of the
four Dyckhoff’s rules for the left implication to get rid of the contraction
and the right \sphinxcode{\sphinxupquote{or}}).

Having defined \sphinxcode{\sphinxupquote{my\_tauto}}, we can prove tautologies like these:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{my\PYGZus{}tauto\PYGZus{}ex1} \PYG{o}{:}
  \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{/\PYGZbs{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZbs{}/} \PYG{n}{B}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{n}{my\PYGZus{}tauto}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{my\PYGZus{}tauto\PYGZus{}ex2} \PYG{o}{:}
  \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{,} \PYG{o}{(}\PYG{o}{\PYGZti{}} \PYG{o}{\PYGZti{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}} \PYG{o}{\PYGZti{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{n}{my\PYGZus{}tauto}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Deciding type isomorphisms}
\label{\detokenize{proof-engine/detailed-tactic-examples:deciding-type-isomorphisms}}
A more tricky problem is to decide equalities between types modulo
isomorphisms. Here, we choose to use the isomorphisms of the simply
typed \(\lambda\)-calculus with Cartesian product and unit type (see, for
example, \sphinxcite{zebibliography:rc95}). The axioms of this \(\lambda\)-calculus are given below.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{type\PYGZus{}scope}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Section} \PYG{n}{Iso\PYGZus{}axioms}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variables} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{Com} \PYG{o}{:} \PYG{n}{A} \PYG{o}{*} \PYG{n}{B} \PYG{o}{=} \PYG{n}{B} \PYG{o}{*} \PYG{n}{A}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{Ass} \PYG{o}{:} \PYG{n}{A} \PYG{o}{*} \PYG{o}{(}\PYG{n}{B} \PYG{o}{*} \PYG{n}{C}\PYG{o}{)} \PYG{o}{=} \PYG{n}{A} \PYG{o}{*} \PYG{n}{B} \PYG{o}{*} \PYG{n}{C}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{Cur} \PYG{o}{:} \PYG{o}{(}\PYG{n}{A} \PYG{o}{*} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{Dis} \PYG{o}{:} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{*} \PYG{n}{C}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{)} \PYG{o}{*} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{P\PYGZus{}unit} \PYG{o}{:} \PYG{n}{A} \PYG{o}{*} \PYG{k+kt}{unit} \PYG{o}{=} \PYG{n}{A}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{AR\PYGZus{}unit} \PYG{o}{:} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{unit}\PYG{o}{)} \PYG{o}{=} \PYG{k+kt}{unit}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{AL\PYGZus{}unit} \PYG{o}{:} \PYG{o}{(}\PYG{k+kt}{unit} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}\PYG{o}{)} \PYG{o}{=} \PYG{n}{A}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{Cons} \PYG{o}{:} \PYG{n}{B} \PYG{o}{=} \PYG{n}{C} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{*} \PYG{n}{B} \PYG{o}{=} \PYG{n}{A} \PYG{o}{*} \PYG{n}{C}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{intro} \PYG{n}{Heq}\PYG{o}{;} \PYG{k}{rewrite} \PYG{n}{Heq}\PYG{o}{;} \PYG{k+kp}{reflexivity}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{End} \PYG{n}{Iso\PYGZus{}axioms}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{simplify\PYGZus{}type} \PYG{n}{ty} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{ty} \PYG{k}{with}
    \PYG{o}{\textbar{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{*} \PYG{o}{?}\PYG{n}{B} \PYG{o}{*} \PYG{o}{?}\PYG{n}{C} \PYG{o}{=\PYGZgt{}}
        \PYG{k}{rewrite} \PYG{o}{\PYGZlt{}\PYGZhy{}} \PYG{o}{(}\PYG{n}{Ass} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C}\PYG{o}{)}\PYG{o}{;} \PYG{k+kr}{try} \PYG{n}{simplify\PYGZus{}type\PYGZus{}eq}
    \PYG{o}{\textbar{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{*} \PYG{o}{?}\PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{?}\PYG{n}{C} \PYG{o}{=\PYGZgt{}}
        \PYG{k}{rewrite} \PYG{o}{(}\PYG{n}{Cur} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C}\PYG{o}{)}\PYG{o}{;} \PYG{k+kr}{try} \PYG{n}{simplify\PYGZus{}type\PYGZus{}eq}
    \PYG{o}{\textbar{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{?}\PYG{n}{B} \PYG{o}{*} \PYG{o}{?}\PYG{n}{C} \PYG{o}{=\PYGZgt{}}
        \PYG{k}{rewrite} \PYG{o}{(}\PYG{n}{Dis} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C}\PYG{o}{)}\PYG{o}{;} \PYG{k+kr}{try} \PYG{n}{simplify\PYGZus{}type\PYGZus{}eq}
    \PYG{o}{\textbar{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{*} \PYG{k+kt}{unit} \PYG{o}{=\PYGZgt{}}
        \PYG{k}{rewrite} \PYG{o}{(}\PYG{n}{P\PYGZus{}unit} \PYG{n}{A}\PYG{o}{)}\PYG{o}{;} \PYG{k+kr}{try} \PYG{n}{simplify\PYGZus{}type\PYGZus{}eq}
    \PYG{o}{\textbar{}} \PYG{k+kt}{unit} \PYG{o}{*} \PYG{o}{?}\PYG{n}{B} \PYG{o}{=\PYGZgt{}}
        \PYG{k}{rewrite} \PYG{o}{(}\PYG{n}{Com} \PYG{k+kt}{unit} \PYG{n}{B}\PYG{o}{)}\PYG{o}{;} \PYG{k+kr}{try} \PYG{n}{simplify\PYGZus{}type\PYGZus{}eq}
    \PYG{o}{\textbar{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{unit} \PYG{o}{=\PYGZgt{}}
        \PYG{k}{rewrite} \PYG{o}{(}\PYG{n}{AR\PYGZus{}unit} \PYG{n}{A}\PYG{o}{)}\PYG{o}{;} \PYG{k+kr}{try} \PYG{n}{simplify\PYGZus{}type\PYGZus{}eq}
    \PYG{o}{\textbar{}} \PYG{k+kt}{unit} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{?}\PYG{n}{B} \PYG{o}{=\PYGZgt{}}
        \PYG{k}{rewrite} \PYG{o}{(}\PYG{n}{AL\PYGZus{}unit} \PYG{n}{B}\PYG{o}{)}\PYG{o}{;} \PYG{k+kr}{try} \PYG{n}{simplify\PYGZus{}type\PYGZus{}eq}
    \PYG{o}{\textbar{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{*} \PYG{o}{?}\PYG{n}{B} \PYG{o}{=\PYGZgt{}}
        \PYG{o}{(}\PYG{n}{simplify\PYGZus{}type} \PYG{n}{A}\PYG{o}{;} \PYG{k+kr}{try} \PYG{n}{simplify\PYGZus{}type\PYGZus{}eq}\PYG{o}{)} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}}
        \PYG{o}{(}\PYG{n}{simplify\PYGZus{}type} \PYG{n}{B}\PYG{o}{;} \PYG{k+kr}{try} \PYG{n}{simplify\PYGZus{}type\PYGZus{}eq}\PYG{o}{)}
    \PYG{o}{\textbar{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{?}\PYG{n}{B} \PYG{o}{=\PYGZgt{}}
        \PYG{o}{(}\PYG{n}{simplify\PYGZus{}type} \PYG{n}{A}\PYG{o}{;} \PYG{k+kr}{try} \PYG{n}{simplify\PYGZus{}type\PYGZus{}eq}\PYG{o}{)} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}}
        \PYG{o}{(}\PYG{n}{simplify\PYGZus{}type} \PYG{n}{B}\PYG{o}{;} \PYG{k+kr}{try} \PYG{n}{simplify\PYGZus{}type\PYGZus{}eq}\PYG{o}{)}
\PYG{k}{end}
\PYG{k}{with} \PYG{n}{simplify\PYGZus{}type\PYGZus{}eq} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{goal} \PYG{k}{with}
    \PYG{o}{\textbar{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{=} \PYG{o}{?}\PYG{n}{B} \PYG{o}{=\PYGZgt{}} \PYG{k+kr}{try} \PYG{n}{simplify\PYGZus{}type} \PYG{n}{A}\PYG{o}{;} \PYG{k+kr}{try} \PYG{n}{simplify\PYGZus{}type} \PYG{n}{B}
\PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{len} \PYG{n}{trm} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{trm} \PYG{k}{with}
    \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}} \PYG{o}{*} \PYG{o}{?}\PYG{n}{B} \PYG{o}{=\PYGZgt{}} \PYG{k}{let} \PYG{n}{succ} \PYG{o}{:=} \PYG{n}{len} \PYG{n}{B} \PYG{k}{in} \PYG{n}{constr}\PYG{o}{:}\PYG{o}{(}\PYG{n}{S} \PYG{n}{succ}\PYG{o}{)}
    \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{constr}\PYG{o}{:}\PYG{o}{(}\PYG{l+m+mi}{1}\PYG{o}{)}
\PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{assoc} \PYG{o}{:=} \PYG{k+kr}{repeat} \PYG{k}{rewrite} \PYG{o}{\PYGZlt{}\PYGZhy{}} \PYG{n}{Ass}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{solve\PYGZus{}type\PYGZus{}eq} \PYG{n}{n} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{goal} \PYG{k}{with}
    \PYG{o}{\textbar{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{=} \PYG{o}{?}\PYG{n}{A} \PYG{o}{=\PYGZgt{}} \PYG{k+kp}{reflexivity}
    \PYG{o}{\textbar{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{*} \PYG{o}{?}\PYG{n}{B} \PYG{o}{=} \PYG{o}{?}\PYG{n}{A} \PYG{o}{*} \PYG{o}{?}\PYG{n}{C} \PYG{o}{=\PYGZgt{}}
        \PYG{k}{apply} \PYG{n}{Cons}\PYG{o}{;} \PYG{k}{let} \PYG{n}{newn} \PYG{o}{:=} \PYG{n}{len} \PYG{n}{B} \PYG{k}{in} \PYG{n}{solve\PYGZus{}type\PYGZus{}eq} \PYG{n}{newn}
    \PYG{o}{\textbar{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{*} \PYG{o}{?}\PYG{n}{B} \PYG{o}{=} \PYG{o}{?}\PYG{n}{C} \PYG{o}{=\PYGZgt{}}
        \PYG{k}{match} \PYG{n}{eval} \PYG{k}{compute} \PYG{k}{in} \PYG{n}{n} \PYG{k}{with}
            \PYG{o}{\textbar{}} \PYG{l+m+mi}{1} \PYG{o}{=\PYGZgt{}} \PYG{n}{fail}
            \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}}
                \PYG{k}{pattern} \PYG{o}{(}\PYG{n}{A} \PYG{o}{*} \PYG{n}{B}\PYG{o}{)} \PYG{n}{at} \PYG{l+m+mi}{1}\PYG{o}{;} \PYG{k}{rewrite} \PYG{n}{Com}\PYG{o}{;} \PYG{n}{assoc}\PYG{o}{;} \PYG{n}{solve\PYGZus{}type\PYGZus{}eq} \PYG{o}{(}\PYG{n}{pred} \PYG{n}{n}\PYG{o}{)}
        \PYG{k}{end}
\PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{compare\PYGZus{}structure} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{goal} \PYG{k}{with}
    \PYG{o}{\textbar{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{?}\PYG{n}{A} \PYG{o}{=} \PYG{o}{?}\PYG{n}{B} \PYG{o}{=\PYGZgt{}}
        \PYG{k}{let} \PYG{n}{l1} \PYG{o}{:=} \PYG{n}{len} \PYG{n}{A}
        \PYG{k}{with} \PYG{n}{l2} \PYG{o}{:=} \PYG{n}{len} \PYG{n}{B} \PYG{k}{in}
            \PYG{k}{match} \PYG{n}{eval} \PYG{k}{compute} \PYG{k}{in} \PYG{o}{(}\PYG{n}{l1} \PYG{o}{=} \PYG{n}{l2}\PYG{o}{)} \PYG{k}{with}
                \PYG{o}{\textbar{}} \PYG{o}{?}\PYG{n}{n} \PYG{o}{=} \PYG{o}{?}\PYG{n}{n} \PYG{o}{=\PYGZgt{}} \PYG{n}{solve\PYGZus{}type\PYGZus{}eq} \PYG{n}{n}
            \PYG{k}{end}
\PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{solve\PYGZus{}iso} \PYG{o}{:=} \PYG{n}{simplify\PYGZus{}type\PYGZus{}eq}\PYG{o}{;} \PYG{n}{compare\PYGZus{}structure}\PYG{o}{.}
\end{sphinxVerbatim}

The tactic to judge equalities modulo this axiomatization is shown above.
The algorithm is quite simple. First types are simplified using axioms that
can be oriented (this is done by \sphinxcode{\sphinxupquote{simplify\_type}} and \sphinxcode{\sphinxupquote{simplify\_type\_eq}}).
The normal forms are sequences of Cartesian products without Cartesian product
in the left component. These normal forms are then compared modulo permutation
of the components by the tactic \sphinxcode{\sphinxupquote{compare\_structure}}. If they have the same
lengths, the tactic \sphinxcode{\sphinxupquote{solve\_type\_eq}} attempts to prove that the types are equal.
The main tactic that puts all these components together is called \sphinxcode{\sphinxupquote{solve\_iso}}.

Here are examples of what can be solved by \sphinxcode{\sphinxupquote{solve\_iso}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{solve\PYGZus{}iso\PYGZus{}ex1} \PYG{o}{:}
  \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{,} \PYG{n}{A} \PYG{o}{*} \PYG{k+kt}{unit} \PYG{o}{*} \PYG{n}{B} \PYG{o}{=} \PYG{n}{B} \PYG{o}{*} \PYG{o}{(}\PYG{k+kt}{unit} \PYG{o}{*} \PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{intros}\PYG{o}{;} \PYG{n}{solve\PYGZus{}iso}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{solve\PYGZus{}iso\PYGZus{}ex2} \PYG{o}{:}
  \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{,}
    \PYG{o}{(}\PYG{n}{A} \PYG{o}{*} \PYG{k+kt}{unit} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{*} \PYG{o}{(}\PYG{n}{C} \PYG{o}{*} \PYG{k+kt}{unit}\PYG{o}{)}\PYG{o}{)} \PYG{o}{=}
    \PYG{o}{(}\PYG{n}{A} \PYG{o}{*} \PYG{k+kt}{unit} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{C} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{unit}\PYG{o}{)} \PYG{o}{*} \PYG{n}{C}\PYG{o}{)} \PYG{o}{*} \PYG{o}{(}\PYG{k+kt}{unit} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{intros}\PYG{o}{;} \PYG{n}{solve\PYGZus{}iso}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}


\section{The SSReflect proof language}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-ssr-proof-language}}\label{\detokenize{proof-engine/ssreflect-proof-language:thessreflectprooflanguage}}\label{\detokenize{proof-engine/ssreflect-proof-language::doc}}\begin{quote}\begin{description}
\item[{Authors}] \leavevmode
Georges Gonthier, Assia Mahboubi, Enrico Tassi

\end{description}\end{quote}


\subsection{Introduction}
\label{\detokenize{proof-engine/ssreflect-proof-language:introduction}}
This chapter describes a set of tactics known as \DUrole{smallcaps}{SSReflect} originally
designed to provide support for the so-called \sphinxstyleemphasis{small scale reflection}
proof methodology. Despite the original purpose this set of tactic is
of general interest and is available in \DUrole{smallcaps}{Coq} starting from version 8.7.

\DUrole{smallcaps}{SSReflect} was developed independently of the tactics described in
Chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}}. Indeed the scope of the tactics part of \DUrole{smallcaps}{SSReflect} largely
overlaps with the standard set of tactics. Eventually the overlap will
be reduced in future releases of \DUrole{smallcaps}{Coq}.

Proofs written in \DUrole{smallcaps}{SSReflect} typically look quite different from the
ones written using only tactics as per Chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}}. We try to
summarise here the most “visible” ones in order to help the reader
already accustomed to the tactics described in Chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}} to read
this chapter.

The first difference between the tactics described in this chapter and the
tactics described in Chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}} is the way hypotheses are managed
(we call this \sphinxstyleemphasis{bookkeeping}). In Chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}} the most common
approach is to avoid moving explicitly hypotheses back and forth between the
context and the conclusion of the goal. On the contrary in \DUrole{smallcaps}{SSReflect} all
bookkeeping is performed on the conclusion of the goal, using for that
purpose a couple of syntactic constructions behaving similar to tacticals
(and often named as such in this chapter). The \sphinxcode{\sphinxupquote{:}} tactical moves hypotheses
from the context to the conclusion, while \sphinxcode{\sphinxupquote{=\textgreater{}}} moves hypotheses from the
conclusion to the context, and \sphinxcode{\sphinxupquote{in}} moves back and forth a hypothesis from the
context to the conclusion for the time of applying an action to it.

While naming hypotheses is commonly done by means of an \sphinxcode{\sphinxupquote{as}} clause in the
basic model of Chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}}, it is here to \sphinxcode{\sphinxupquote{=\textgreater{}}} that this task is
devoted. Tactics frequently leave new assumptions in the conclusion, and are
often followed by \sphinxcode{\sphinxupquote{=\textgreater{}}} to explicitly name them. While generalizing the
goal is normally not explicitly needed in Chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}}, it is an
explicit operation performed by \sphinxcode{\sphinxupquote{:}}.


\sphinxstrong{See also:}


{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:bookkeeping-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Bookkeeping}}}}



Beside the difference of bookkeeping model, this chapter includes
specific tactics which have no explicit counterpart in Chapter {\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}}
such as tactics to mix forward steps and generalizations as
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacv.generally-have}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{generally have}}}}} or {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacv.without-loss}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{without loss}}}}}.

\DUrole{smallcaps}{SSReflect} adopts the point of view that rewriting, definition
expansion and partial evaluation participate all to a same concept of
rewriting a goal in a larger sense. As such, all these functionalities
are provided by the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.rewrite-ssreflect}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} tactic.

\DUrole{smallcaps}{SSReflect} includes a little language of patterns to select subterms in
tactics or tacticals where it matters. Its most notable application is
in the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.rewrite-ssreflect}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} tactic, where patterns are
used to specify where the rewriting step has to take place.

Finally, \DUrole{smallcaps}{SSReflect} supports so-called reflection steps, typically
allowing to switch back and forth between the computational view and
logical view of a concept.

To conclude it is worth mentioning that \DUrole{smallcaps}{SSReflect} tactics can be mixed
with non \DUrole{smallcaps}{SSReflect} tactics in the same proof, or in the same Ltac
expression. The few exceptions to this statement are described in
section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:compatibility-issues-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Compatibility issues}}}}.


\subsubsection{Acknowledgments}
\label{\detokenize{proof-engine/ssreflect-proof-language:acknowledgments}}
The authors would like to thank Frédéric Blanqui, François Pottier and
Laurence Rideau for their comments and suggestions.


\subsection{Usage}
\label{\detokenize{proof-engine/ssreflect-proof-language:usage}}

\subsubsection{Getting started}
\label{\detokenize{proof-engine/ssreflect-proof-language:getting-started}}
To be available, the tactics presented in this manual need the
following minimal set of libraries to be loaded: \sphinxcode{\sphinxupquote{ssreflect.v}},
\sphinxcode{\sphinxupquote{ssrfun.v}} and \sphinxcode{\sphinxupquote{ssrbool.v}}.
Moreover, these tactics come with a methodology
specific to the authors of \DUrole{smallcaps}{SSReflect} and which requires a few options
to be set in a different way than in their default way. All in all,
this corresponds to working in the following context:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{From} \PYG{n}{Coq} \PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{ssreflect} \PYG{n}{ssrfun} \PYG{n}{ssrbool}\PYG{o}{.}
\PYG{k+kn}{Set} \PYG{k+kn}{Implicit} \PYG{k+kn}{Arguments}\PYG{o}{.}
\PYG{k+kn}{Unset} \PYG{k+kn}{Strict} \PYG{k+kn}{Implicit}\PYG{o}{.}
\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{k+kn}{Implicit} \PYG{n}{Defensive}\PYG{o}{.}
\end{sphinxVerbatim}


\sphinxstrong{See also:}


{\hyperref[\detokenize{language/gallina-extensions:coq:flag.implicit-arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Implicit Arguments}}}}}, {\hyperref[\detokenize{language/gallina-extensions:coq:flag.strict-implicit}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Strict Implicit}}}}},
{\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-implicit-defensive}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Implicit Defensive}}}}}




\subsubsection{Compatibility issues}
\label{\detokenize{proof-engine/ssreflect-proof-language:compatibility-issues}}\label{\detokenize{proof-engine/ssreflect-proof-language:compatibility-issues-ssr}}
Requiring the above modules creates an environment which is mostly
compatible with the rest of \DUrole{smallcaps}{Coq}, up to a few discrepancies:
\begin{itemize}
\item {} 
New keywords (\sphinxcode{\sphinxupquote{is}}) might clash with variable, constant, tactic or
tactical names, or with quasi-keywords in tactic or vernacular
notations.

\item {} 
New tactic(al)s names ({\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.last}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{last}}}}}, {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.done}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{done}}}}}, {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.have}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{have}}}}}, {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacv.suffices}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{suffices}}}}},
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.suff}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{suff}}}}}, {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacv.without-loss}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{without loss}}}}}, {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.wlog}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{wlog}}}}}, {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.congr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{congr}}}}}, {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.unlock}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unlock}}}}})
might clash with user tactic names.

\item {} 
Identifiers with both leading and trailing \sphinxcode{\sphinxupquote{\_}}, such as \sphinxcode{\sphinxupquote{\_x\_}}, are
reserved by \DUrole{smallcaps}{SSReflect} and cannot appear in scripts.

\item {} 
The extensions to the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} tactic are partly incompatible with those
available in current versions of \DUrole{smallcaps}{Coq}; in particular: \sphinxcode{\sphinxupquote{rewrite .. in
(type of k)}} or \sphinxcode{\sphinxupquote{rewrite .. in *}} or any other variant of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}}
will not work, and the \DUrole{smallcaps}{SSReflect} syntax and semantics for occurrence selection
and rule chaining is different. Use an explicit rewrite direction
(\sphinxcode{\sphinxupquote{rewrite \textless{}- …}} or \sphinxcode{\sphinxupquote{rewrite -\textgreater{} …}}) to access the \DUrole{smallcaps}{Coq} rewrite tactic.

\item {} 
New symbols (\sphinxcode{\sphinxupquote{//}}, \sphinxcode{\sphinxupquote{/=}}, \sphinxcode{\sphinxupquote{//=}}) might clash with adjacent
existing symbols.
This can be avoided by inserting white spaces.

\item {} 
New constant and theorem names might clash with the user theory.
This can be avoided by not importing all of \DUrole{smallcaps}{SSReflect}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{From} \PYG{n}{Coq} \PYG{k+kn}{Require} \PYG{n}{ssreflect}\PYG{o}{.}
\PYG{k+kn}{Import} \PYG{n}{ssreflect}\PYG{o}{.}\PYG{n}{SsrSyntax}\PYG{o}{.}
\end{sphinxVerbatim}

Note that the full
syntax of \DUrole{smallcaps}{SSReflect}’s rewrite and reserved identifiers are enabled
only if the ssreflect module has been required and if \sphinxcode{\sphinxupquote{SsrSyntax}} has
been imported. Thus a file that requires (without importing) \sphinxcode{\sphinxupquote{ssreflect}}
and imports \sphinxcode{\sphinxupquote{SsrSyntax}}, can be required and imported without
automatically enabling \DUrole{smallcaps}{SSReflect}’s extended rewrite syntax and
reserved identifiers.

\item {} 
Some user notations (in particular, defining an infix \sphinxcode{\sphinxupquote{;}}) might
interfere with the "open term", parenthesis free, syntax of tactics
such as have, set and pose.

\item {} 
The generalization of if statements to non-Boolean conditions is turned off
by \DUrole{smallcaps}{SSReflect}, because it is mostly subsumed by Coercion to \sphinxcode{\sphinxupquote{bool}} of the
\sphinxcode{\sphinxupquote{sumXXX}} types (declared in \sphinxcode{\sphinxupquote{ssrfun.v}}) and the
\sphinxcode{\sphinxupquote{\DUrole{notation}{if {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} is {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} then {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} else {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} construct
(see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:pattern-conditional-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Pattern conditional}}}}).  To use the
generalized form, turn off the \DUrole{smallcaps}{SSReflect} Boolean \sphinxcode{\sphinxupquote{if}} notation using the command:
\sphinxcode{\sphinxupquote{Close Scope boolean\_if\_scope}}.

\item {} 
The following two options can be unset to disable the incompatible
rewrite syntax and allow reserved identifiers to appear in scripts.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Unset} \PYG{n}{SsrRewrite}\PYG{o}{.}
\PYG{k+kn}{Unset} \PYG{n}{SsrIdents}\PYG{o}{.}
\end{sphinxVerbatim}

\end{itemize}


\subsection{Gallina extensions}
\label{\detokenize{proof-engine/ssreflect-proof-language:gallina-extensions}}
Small-scale reflection makes an extensive use of the programming
subset of \DUrole{smallcaps}{Gallina}, \DUrole{smallcaps}{Coq}’s logical specification language. This subset
is quite suited to the description of functions on representations,
because it closely follows the well-established design of the ML
programming language. The \DUrole{smallcaps}{SSReflect} extension provides three additions
to \DUrole{smallcaps}{Gallina}, for pattern assignment, pattern testing, and polymorphism;
these mitigate minor but annoying discrepancies between \DUrole{smallcaps}{Gallina} and
ML.


\subsubsection{Pattern assignment}
\label{\detokenize{proof-engine/ssreflect-proof-language:pattern-assignment}}
The \DUrole{smallcaps}{SSReflect} extension provides the following construct for
irrefutable pattern matching, that is, destructuring assignment:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{term~+=~}}\DUrole{notation}{let:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


Note the colon \sphinxcode{\sphinxupquote{:}} after the \sphinxcode{\sphinxupquote{let}} keyword, which avoids any ambiguity
with a function definition or \DUrole{smallcaps}{Coq}’s basic destructuring let. The let:
construct differs from the latter in that
\begin{itemize}
\item {} 
The pattern can be nested (deep pattern matching), in particular,
this allows expression of the form:

\end{itemize}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
let: exist (x, y) p\PYGZus{}xy := Hp in … .
\end{sphinxVerbatim}
\begin{itemize}
\item {} 
The destructured constructor is explicitly given in the pattern, and
is used for type inference.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{f} \PYG{n}{u} \PYG{o}{:=} \PYG{k}{let}\PYG{o}{:} \PYG{o}{(}\PYG{n}{m}\PYG{o}{,} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{u} \PYG{k}{in} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n}\PYG{o}{.}
    \PYG{n}{f} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Check} \PYG{n}{f}\PYG{o}{.}
    \PYG{n}{f}
         \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{*} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
\end{sphinxVerbatim}

Using \sphinxcode{\sphinxupquote{\DUrole{keyword}{let}\DUrole{operator}{:}}} Coq infers a type for \sphinxcode{\sphinxupquote{\DUrole{name}{f}}},
whereas with a usual \sphinxcode{\sphinxupquote{let}} the same term requires an extra type
annotation in order to type check.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{f} \PYG{n}{u} \PYG{o}{:=} \PYG{k}{let} \PYG{o}{(}\PYG{n}{m}\PYG{o}{,} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{u} \PYG{k}{in} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{32}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{33}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Definition} \PYG{n}{f} \PYG{n}{u} \PYG{o}{:=} \PYG{k}{let} \PYG{o}{(}\PYG{n}{m}\PYG{o}{,} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{u} \PYG{k}{in} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}}                                 \PYG{o}{\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:} \PYG{n}{Cannot} \PYG{n}{infer} \PYG{n}{a} \PYG{n}{type} \PYG{k}{for} \PYG{n}{this} \PYG{n}{expression}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{itemize}

The \sphinxcode{\sphinxupquote{let:}} construct is just (more legible) notation for the primitive
\DUrole{smallcaps}{Gallina} expression \sphinxcode{\sphinxupquote{\DUrole{notation}{match {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} =\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} end}}}.

The \DUrole{smallcaps}{SSReflect} destructuring assignment supports all the dependent
match annotations; the full syntax is


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{term~+=~}}\DUrole{notation}{let:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{as~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{return~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


where the second {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} and the second {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} are \sphinxstyleemphasis{types}.

When the \sphinxcode{\sphinxupquote{as}} and \sphinxcode{\sphinxupquote{return}} keywords are both present, then {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is bound
in both the second {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} and the second {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}; variables
in the optional type {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} are bound only in the second term, and
other variables in the first  {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} are bound only in the third
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}, however.


\subsubsection{Pattern conditional}
\label{\detokenize{proof-engine/ssreflect-proof-language:pattern-conditional}}\label{\detokenize{proof-engine/ssreflect-proof-language:pattern-conditional-ssr}}
The following construct can be used for a refutable pattern matching,
that is, pattern testing:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{term~+=~}}\DUrole{notation}{if~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~is~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}~then~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~else~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


Although this construct is not strictly ML (it does exist in variants
such as the pattern calculus or the \(\rho\)-calculus), it turns out to be
very convenient for writing functions on representations, because most
such functions manipulate simple data types such as Peano integers,
options, lists, or binary trees, and the pattern conditional above is
almost always the right construct for analyzing such simple types. For
example, the null and all list function(al)s can be defined as follows:

\begin{sphinxadmonition}{note}{Example}
\begin{quote}
\end{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variable} \PYG{n}{d}\PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{.}
    \PYG{n}{d} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Fixpoint} \PYG{n}{null} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{d}\PYG{o}{)} \PYG{o}{:=}
  \PYG{k}{if} \PYG{n}{s} \PYG{k}{is} \PYG{n}{nil} \PYG{k}{then} \PYG{n+nb+bp}{true} \PYG{k}{else} \PYG{n+nb+bp}{false}\PYG{o}{.}
    \PYG{n}{null} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{null} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}

\PYG{k+kn}{Variable} \PYG{n}{a} \PYG{o}{:} \PYG{n}{d} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}\PYG{o}{.}
    \PYG{n}{a} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Fixpoint} \PYG{n}{all} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{d}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{:=}
  \PYG{k}{if} \PYG{n}{s} \PYG{k}{is} \PYG{n}{cons} \PYG{n}{x} \PYG{n}{s\PYGZsq{}} \PYG{k}{then} \PYG{n}{a} \PYG{n}{x} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{all} \PYG{n}{s\PYGZsq{}} \PYG{k}{else} \PYG{n+nb+bp}{true}\PYG{o}{.}
    \PYG{n}{all} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{all} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The pattern conditional also provides a notation for destructuring
assignment with a refutable pattern, adapted to the pure functional
setting of \DUrole{smallcaps}{Gallina}, which lacks a \sphinxcode{\sphinxupquote{Match\_Failure}} exception.

Like \sphinxcode{\sphinxupquote{let:}} above, the \sphinxcode{\sphinxupquote{if…is}} construct is just (more legible) notation
for the primitive \DUrole{smallcaps}{Gallina} expression
\sphinxcode{\sphinxupquote{\DUrole{notation}{match {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} =\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} \textbar{} \_ =\textgreater{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} end}}}.

Similarly, it will always be displayed as the expansion of this form
in terms of primitive match expressions (where the default expression
may be replicated).

Explicit pattern testing also largely subsumes the generalization of
the \sphinxcode{\sphinxupquote{if}} construct to all binary data types; compare
\sphinxcode{\sphinxupquote{\DUrole{notation}{if {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} is inl \_ then {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} else {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} and
\sphinxcode{\sphinxupquote{\DUrole{notation}{if {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} then {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} else {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}.

The latter appears to be marginally shorter, but it is quite
ambiguous, and indeed often requires an explicit annotation
\sphinxcode{\sphinxupquote{(term : \{\_\} + \{\_\})}} to type check, which evens the character count.

Therefore, \DUrole{smallcaps}{SSReflect} restricts by default the condition of a plain if
construct to the standard \sphinxcode{\sphinxupquote{bool}} type; this avoids spurious type
annotations.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{orb} \PYG{n}{b1} \PYG{n}{b2} \PYG{o}{:=} \PYG{k}{if} \PYG{n}{b1} \PYG{k}{then} \PYG{n+nb+bp}{true} \PYG{k}{else} \PYG{n}{b2}\PYG{o}{.}
    \PYG{n}{orb} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}

As pointed out in section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:compatibility-issues-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Compatibility issues}}}},
this restriction can be removed with
the command:

\sphinxcode{\sphinxupquote{Close Scope boolean\_if\_scope.}}

Like \sphinxcode{\sphinxupquote{let:}} above, the \sphinxcode{\sphinxupquote{if-is-then-else}}
construct supports
the dependent match annotations:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{term~+=~}}\DUrole{notation}{if~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~is~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}~as~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}~return~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~then~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~else~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


As in \sphinxcode{\sphinxupquote{let:}} the variable {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} (and those in the type pattern)
are bound in the second {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}; {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is also bound in the
third {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} (but not in the fourth {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}), while the
variables in the first {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} are bound only in the third
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

Another variant allows to treat the \sphinxcode{\sphinxupquote{else}} case first:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{term~+=~}}\DUrole{notation}{if~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~isn't~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}~then~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~else~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


Note that {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} eventually binds variables in the third
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} and not in the second {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.


\subsubsection{Parametric polymorphism}
\label{\detokenize{proof-engine/ssreflect-proof-language:parametric-polymorphism}}\label{\detokenize{proof-engine/ssreflect-proof-language:parametric-polymorphism-ssr}}
Unlike ML, polymorphism in core \DUrole{smallcaps}{Gallina} is explicit: the type
parameters of polymorphic functions must be declared explicitly, and
supplied at each point of use. However, \DUrole{smallcaps}{Coq} provides two features to
suppress redundant parameters:
\begin{itemize}
\item {} 
Sections are used to provide (possibly implicit) parameters for a
set of definitions.

\item {} 
Implicit arguments declarations are used to tell \DUrole{smallcaps}{Coq} to use type
inference to deduce some parameters from the context at each point of
call.

\end{itemize}

The combination of these features provides a fairly good emulation of
ML-style polymorphism, but unfortunately this emulation breaks down
for higher-order programming. Implicit arguments are indeed not
inferred at all points of use, but only at points of call, leading to
expressions such as

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{all\PYGZus{}null} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{T}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{all} \PYG{o}{(}\PYG{o}{@}\PYG{n}{null} \PYG{n}{T}\PYG{o}{)} \PYG{n}{s}\PYG{o}{.}
    \PYG{n}{all\PYGZus{}null} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Unfortunately, such higher-order expressions are quite frequent in
representation functions, especially those which use \DUrole{smallcaps}{Coq}'s
\sphinxcode{\sphinxupquote{Structures}} to emulate Haskell typeclasses.

Therefore, \DUrole{smallcaps}{SSReflect} provides a variant of \DUrole{smallcaps}{Coq}’s implicit argument
declaration, which causes \DUrole{smallcaps}{Coq} to fill in some implicit parameters at
each point of use, e.g., the above definition can be written:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Prenex} \PYG{k+kn}{Implicits} \PYG{n}{null}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{all\PYGZus{}null} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{T}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{all} \PYG{n}{null} \PYG{n}{s}\PYG{o}{.}
    \PYG{n}{all\PYGZus{}null} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Better yet, it can be omitted entirely, since \sphinxcode{\sphinxupquote{all\_null s}} isn’t much of
an improvement over \sphinxcode{\sphinxupquote{all null s}}.

The syntax of the new declaration is
\index{Prenex Implicits (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:cmd.prenex-implicits}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Prenex~Implicits~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}


Let us denote \(c_1\) … \(c_n\) the list of identifiers given to a
\sphinxcode{\sphinxupquote{Prenex Implicits}} command.  The command checks that each ci is the name of
a functional constant, whose implicit arguments are prenex, i.e., the first
\(n_i > 0\) arguments of \(c_i\) are implicit; then it assigns
\sphinxcode{\sphinxupquote{Maximal Implicit}} status to these arguments.

As these prenex implicit arguments are ubiquitous and have often large
display strings, it is strongly recommended to change the default
display settings of \DUrole{smallcaps}{Coq} so that they are not printed (except after
a \sphinxcode{\sphinxupquote{Set Printing All}} command). All \DUrole{smallcaps}{SSReflect} library files thus start
with the incantation

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{k+kn}{Implicit} \PYG{k+kn}{Arguments}\PYG{o}{.}
\PYG{k+kn}{Unset} \PYG{k+kn}{Strict} \PYG{k+kn}{Implicit}\PYG{o}{.}
\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{k+kn}{Implicit} \PYG{n}{Defensive}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Anonymous arguments}
\label{\detokenize{proof-engine/ssreflect-proof-language:anonymous-arguments}}
When in a definition, the type of a certain argument is mandatory, but
not its name, one usually uses “arrow” abstractions for prenex
arguments, or the \sphinxcode{\sphinxupquote{(\_ : term)}} syntax for inner arguments. In \DUrole{smallcaps}{SSReflect},
the latter can be replaced by the open syntax \sphinxcode{\sphinxupquote{of term}} or
(equivalently) \sphinxcode{\sphinxupquote{\& term}}, which are both syntactically equivalent to a
\sphinxcode{\sphinxupquote{(\_ : term)}} expression. This feature almost behaves as the
following extension of the binder syntax:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{binder~+=~}}\DUrole{notation}{\&~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\textbar{}~of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


Caveat: \sphinxcode{\sphinxupquote{\& T}} and \sphinxcode{\sphinxupquote{of T}} abbreviations have to appear at the end
of a binder list. For instance, the usual two-constructor polymorphic
type list, i.e. the one of the standard \sphinxcode{\sphinxupquote{List}} library, can be
defined by the following declaration:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{k+kt}{list} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=} \PYG{n}{nil} \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{k}{of} \PYG{n}{A} \PYG{o}{\PYGZam{}} \PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{.}
    \PYG{k+kt}{list} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{list\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Wildcards}
\label{\detokenize{proof-engine/ssreflect-proof-language:wildcards}}
The terms passed as arguments to \DUrole{smallcaps}{SSReflect} tactics can contain
\sphinxstyleemphasis{holes}, materialized by wildcards \sphinxcode{\sphinxupquote{\_}}. Since \DUrole{smallcaps}{SSReflect} allows a more
powerful form of type inference for these arguments, it enhances the
possibilities of using such wildcards. These holes are in particular
used as a convenient shorthand for abstractions, especially in local
definitions or type expressions.

Wildcards may be interpreted as abstractions (see for example sections
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:definitions-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Definitions}}}} and ref:\sphinxtitleref{structure\_ssr}), or their content can be
inferred from the whole context of the goal (see for example section
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:abbreviations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations}}}}).


\subsubsection{Definitions}
\label{\detokenize{proof-engine/ssreflect-proof-language:definitions}}\label{\detokenize{proof-engine/ssreflect-proof-language:definitions-ssr}}\index{pose (ssreflect) (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.pose-ssreflect}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose}}}}
This tactic allows to add a defined constant to a proof context.
\DUrole{smallcaps}{SSReflect} generalizes this tactic in several ways. In particular, the
\DUrole{smallcaps}{SSReflect} pose tactic supports \sphinxstyleemphasis{open syntax}: the body of the
definition does not need surrounding parentheses. For instance:

\end{fulllineitems}


\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{pose} \PYG{n}{t} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{.}
\end{sphinxVerbatim}

is a valid tactic expression.

The pose tactic is also improved for the local definition of higher
order terms. Local definitions of functions can use the same syntax as
global ones.
For example, the tactic {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.pose-ssreflect}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pose}}}}} supoprts parameters:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k}{pose} \PYG{n}{f} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{f} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The \DUrole{smallcaps}{SSReflect} pose tactic also supports (co)fixpoints, by providing
the local counterpart of the \sphinxcode{\sphinxupquote{Fixpoint f := …}} and \sphinxcode{\sphinxupquote{CoFixpoint f := …}}
constructs. For instance, the following tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{pose} \PYG{k}{fix} \PYG{n}{f} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{x}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
  \PYG{k}{if} \PYG{n}{x} \PYG{k}{is} \PYG{n}{S} \PYG{n}{p} \PYG{k}{then} \PYG{n}{S} \PYG{o}{(}\PYG{n}{f} \PYG{n}{p} \PYG{n}{y}\PYG{o}{)} \PYG{k}{else} \PYG{l+m+mi}{0}\PYG{o}{.}
\end{sphinxVerbatim}

defines a local fixpoint \sphinxcode{\sphinxupquote{f}}, which mimics the standard plus operation
on natural numbers.

Similarly, local cofixpoints can be defined by a tactic of the form:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
pose cofix f (arg : T) := … .
\end{sphinxVerbatim}

The possibility to include wildcards in the body of the definitions
offers a smooth way of defining local abstractions. The type of
“holes” is guessed by type inference, and the holes are abstracted.
For instance the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{pose} \PYG{n}{f} \PYG{o}{:=} \PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{.}
\end{sphinxVerbatim}

is shorthand for:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{pose} \PYG{n}{f} \PYG{n}{n} \PYG{o}{:=} \PYG{n}{n} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{.}
\end{sphinxVerbatim}

When the local definition of a function involves both arguments and
holes, hole abstractions appear first. For instance, the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{pose} \PYG{n}{f} \PYG{n}{x} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{.}
\end{sphinxVerbatim}

is shorthand for:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{pose} \PYG{n}{f} \PYG{n}{n} \PYG{n}{x} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{n}\PYG{o}{.}
\end{sphinxVerbatim}

The interaction of the pose tactic with the interpretation of implicit
arguments results in a powerful and concise syntax for local
definitions involving dependent types. For instance, the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{pose} \PYG{n}{f} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

adds to the context the local definition:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{pose} \PYG{n}{f} \PYG{o}{(}\PYG{n}{Tx} \PYG{n}{Ty} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{Tx}\PYG{o}{)} \PYG{o}{(}\PYG{n}{y} \PYG{o}{:} \PYG{n}{Ty}\PYG{o}{)} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

The generalization of wildcards makes the use of the pose tactic
resemble ML-like definitions of polymorphic functions.


\subsubsection{Abbreviations}
\label{\detokenize{proof-engine/ssreflect-proof-language:abbreviations}}\label{\detokenize{proof-engine/ssreflect-proof-language:abbreviations-ssr}}
The \DUrole{smallcaps}{SSReflect} set tactic performs abbreviations: it introduces a
defined constant for a subterm appearing in the goal and/or in the
context.

\DUrole{smallcaps}{SSReflect} extends the set tactic by supplying:
\begin{itemize}
\item {} 
an open syntax, similarly to the pose tactic;

\item {} 
a more aggressive matching algorithm;

\item {} 
an improved interpretation of wildcards, taking advantage of the
matching algorithm;

\item {} 
an improved occurrence selection mechanism allowing to abstract only
selected occurrences of a term.

\end{itemize}

The general syntax of this tactic is
\index{set (ssreflect) (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.set-ssreflect}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{occ\_switch~::=~}}\DUrole{notation}{\DUrole{curlies}{\{~\DUrole{repeat-wrapper}{\DUrole{repeat}{+~\DUrole{meta}{\textbar{}}~-}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{*}}~\}}}}}}
\end{fulllineitems}


where:
\begin{itemize}
\item {} 
{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is a fresh identifier chosen by the user.

\item {} 
term 1 is an optional type annotation. The type annotation term 1
can be given in open syntax (no surrounding parentheses). If no
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}} (described hereafter) is present,
it is also the case for the second {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.
On the other hand, in presence of {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}}, parentheses
surrounding the second {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} are mandatory.

\item {} 
In the occurrence switch {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}}, if the first element of the
list is a natural, this element should be a number, and not an Ltac
variable. The empty list \sphinxcode{\sphinxupquote{\{\}}} is not interpreted as a valid occurrence
switch.

\end{itemize}

The tactic:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{o}{:}  \PYG{n}{f} \PYG{n}{x} \PYG{o}{+} \PYG{n}{f} \PYG{n}{x} \PYG{o}{=} \PYG{n}{f} \PYG{n}{x}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{f} \PYG{n}{x} \PYG{o}{+} \PYG{n}{f} \PYG{n}{x} \PYG{o}{=} \PYG{n}{f} \PYG{n}{x}

\PYG{k}{set} \PYG{n}{t} \PYG{o}{:=} \PYG{n}{f} \PYG{o}{\PYGZus{}}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{t} \PYG{o}{:=} \PYG{n}{f} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{t} \PYG{o}{+} \PYG{n}{t} \PYG{o}{=} \PYG{n}{t}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{set} \PYG{n}{t} \PYG{o}{:=} \PYG{o}{\PYGZob{}}\PYG{l+m+mi}{2}\PYG{o}{\PYGZcb{}}\PYG{o}{(}\PYG{n}{f} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{t} \PYG{o}{:=} \PYG{n}{f} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{f} \PYG{n}{x} \PYG{o}{+} \PYG{n}{t} \PYG{o}{=} \PYG{n}{f} \PYG{n}{x}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The type annotation may contain wildcards, which will be filled
with the appropriate value by the matching process.

The tactic first tries to find a subterm of the goal matching
the second {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}
(and its type), and stops at the first subterm it finds. Then
the occurrences of this subterm selected by the optional {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}}
are replaced by {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} and a definition \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}
is added to the
context. If no {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}} is present, then all the occurrences are
abstracted.


\paragraph{Matching}
\label{\detokenize{proof-engine/ssreflect-proof-language:matching}}
The matching algorithm compares a pattern {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} with a subterm of the
goal by comparing their heads and then pairwise unifying their
arguments (modulo conversion). Head symbols match under the following
conditions:
\begin{itemize}
\item {} 
If the head of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} is a constant, then it should be syntactically
equal to the head symbol of the subterm.

\item {} 
If this head is a projection of a canonical structure, then
canonical structure equations are used for the matching.

\item {} 
If the head of term is \sphinxstyleemphasis{not} a constant, the subterm should have the
same structure (\(\lambda\) abstraction,let…in structure …).

\item {} 
If the head of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} is a hole, the subterm should have at least as
many arguments as {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

\end{itemize}

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:}  \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{z}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{z}

\PYG{k}{set} \PYG{n}{t} \PYG{o}{:=} \PYG{o}{\PYGZus{}} \PYG{n}{x}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{t} \PYG{o}{:=} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{t} \PYG{n}{y} \PYG{o}{=} \PYG{n}{z}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\begin{itemize}
\item {} 
In the special case where \sphinxcode{\sphinxupquote{term}} is of the form
\sphinxcode{\sphinxupquote{(let f := t0 in f) t1 … tn}} , then the pattern \sphinxcode{\sphinxupquote{term}} is treated
as \sphinxcode{\sphinxupquote{(\_ t1 … tn)}}. For each
subterm in the goal having the form \sphinxcode{\sphinxupquote{(A u1 … um)}} with m ≥ n, the
matching algorithm successively tries to find the largest partial
application \sphinxcode{\sphinxupquote{(A u1 … uj)}} convertible to the head \sphinxcode{\sphinxupquote{t0}} of \sphinxcode{\sphinxupquote{term}}.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{o}{(}\PYG{k}{let} \PYG{n}{f} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{z} \PYG{k}{in} \PYG{n}{f} \PYG{l+m+mi}{1}\PYG{o}{)} \PYG{l+m+mi}{2} \PYG{l+m+mi}{3} \PYG{o}{=} \PYG{l+m+mi}{6}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{k}{let} \PYG{n}{f} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{z} \PYG{k}{in} \PYG{n}{f} \PYG{l+m+mi}{1}\PYG{o}{)} \PYG{l+m+mi}{2} \PYG{l+m+mi}{3} \PYG{o}{=} \PYG{l+m+mi}{6}

\PYG{k}{set} \PYG{n}{t} \PYG{o}{:=} \PYG{o}{(}\PYG{k}{let} \PYG{n}{g} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:=} \PYG{n}{S} \PYG{n}{y} \PYG{o}{+} \PYG{n}{z} \PYG{k}{in} \PYG{n}{g}\PYG{o}{)} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{t} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{unkeyed} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{n}{y} \PYG{o}{+} \PYG{n}{z}\PYG{o}{)}\PYG{o}{)} \PYG{l+m+mi}{2} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{t} \PYG{l+m+mi}{3} \PYG{o}{=} \PYG{l+m+mi}{6}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The notation \sphinxcode{\sphinxupquote{unkeyed}} defined in \sphinxcode{\sphinxupquote{ssreflect.v}} is a shorthand for
the degenerate term \sphinxcode{\sphinxupquote{let x := … in x}}.

\end{itemize}

Moreover:
\begin{itemize}
\item {} 
Multiple holes in \sphinxcode{\sphinxupquote{term}} are treated as independent placeholders.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{z}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{z}

\PYG{k}{set} \PYG{n}{t} \PYG{o}{:=} \PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{t} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{t} \PYG{o}{=} \PYG{n}{z}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\item {} 
The type of the subterm matched should fit the type (possibly casted
by some type annotations) of the pattern \sphinxcode{\sphinxupquote{term}}.

\item {} 
The replacement of the subterm found by the instantiated pattern
should not capture variables. In the example above \sphinxcode{\sphinxupquote{x}} is bound
and should not be captured.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{k}{set} \PYG{n}{t} \PYG{o}{:=} \PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{14}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k}{set} \PYG{n}{t} \PYG{o}{:=} \PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:}
    \PYG{k+kn}{Ltac} \PYG{n}{call} \PYG{n}{to} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{set (ssrfwdid) (ssrsetfwd) (ssrclauses)}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{failed}\PYG{o}{.}
    \PYG{n}{The} \PYG{k}{pattern} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{)} \PYG{n}{did} \PYG{n}{not} \PYG{k}{match} \PYG{n}{and} \PYG{n}{has} \PYG{n}{holes}\PYG{o}{.} \PYG{n}{Did} \PYG{n}{you} \PYG{n}{mean} \PYG{k}{pose}\PYG{o}{?}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\item {} 
Typeclass inference should fill in any residual hole, but matching
should never assign a value to a global existential variable.

\end{itemize}


\paragraph{Occurrence selection}
\label{\detokenize{proof-engine/ssreflect-proof-language:occurrence-selection}}\label{\detokenize{proof-engine/ssreflect-proof-language:occurrence-selection-ssr}}
\DUrole{smallcaps}{SSReflect} provides a generic syntax for the selection of occurrences
by their position indexes. These \sphinxstyleemphasis{occurrence switches} are shared by
all \DUrole{smallcaps}{SSReflect} tactics which require control on subterm selection like
rewriting, generalization, …

An \sphinxstyleemphasis{occurrence switch} can be:
\begin{itemize}
\item {} 
A list natural numbers \sphinxcode{\sphinxupquote{\{+ n1 … nm\}}}
of occurrences affected by the tactic.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{f} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{n}{f} \PYG{l+m+mi}{8} \PYG{o}{=} \PYG{n}{f} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{n}{f} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{f} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{n}{f} \PYG{l+m+mi}{8} \PYG{o}{=} \PYG{n}{f} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{n}{f} \PYG{l+m+mi}{2}

\PYG{k}{set} \PYG{n}{x} \PYG{o}{:=} \PYG{o}{\PYGZob{}}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{l+m+mi}{3}\PYG{o}{\PYGZcb{}}\PYG{o}{(}\PYG{n}{f} \PYG{l+m+mi}{2}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:=} \PYG{n}{f} \PYG{l+m+mi}{2} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{f} \PYG{l+m+mi}{8} \PYG{o}{=} \PYG{n}{f} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{n}{x}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Notice that some occurrences of a given term may be
hidden to the user, for example because of a notation. The vernacular
\sphinxcode{\sphinxupquote{Set Printing All}} command displays all these hidden occurrences and
should be used to find the correct coding of the occurrences to be
selected %
\begin{footnote}[8]\sphinxAtStartFootnote
Unfortunately, even after a call to the Set Printing All command,
some occurrences are still not displayed to the user, essentially the
ones possibly hidden in the predicate of a dependent match structure.
%
\end{footnote}.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{a \PYGZlt{} b}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{:=} \PYG{o}{(}\PYG{n}{le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{a}\PYG{o}{)} \PYG{n}{b}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{x} \PYG{o}{\PYGZlt{}} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{S} \PYG{n}{x} \PYG{o}{\PYGZlt{}} \PYG{n}{S} \PYG{n}{y}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{\PYGZlt{}} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{S} \PYG{n}{x} \PYG{o}{\PYGZlt{}} \PYG{n}{S} \PYG{n}{y}

\PYG{k}{set} \PYG{n}{t} \PYG{o}{:=} \PYG{n}{S} \PYG{n}{x}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{t} \PYG{o}{:=} \PYG{n}{S} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{t} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{t} \PYG{o}{\PYGZlt{}} \PYG{n}{S} \PYG{n}{y}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\item {} 
A list of natural numbers between \sphinxcode{\sphinxupquote{\{n1 … nm\}}}.
This is equivalent to the previous \sphinxcode{\sphinxupquote{\{+ n1 … nm\}}} but the list
should start with a number, and not with an Ltac variable.

\item {} 
A list \sphinxcode{\sphinxupquote{\{- n1 … nm\}}} of occurrences \sphinxstyleemphasis{not} to be affected by the
tactic.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{f} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{n}{f} \PYG{l+m+mi}{8} \PYG{o}{=} \PYG{n}{f} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{n}{f} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{f} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{n}{f} \PYG{l+m+mi}{8} \PYG{o}{=} \PYG{n}{f} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{n}{f} \PYG{l+m+mi}{2}

\PYG{k}{set} \PYG{n}{x} \PYG{o}{:=} \PYG{o}{\PYGZob{}}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{2}\PYG{o}{\PYGZcb{}}\PYG{o}{(}\PYG{n}{f} \PYG{l+m+mi}{2}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:=} \PYG{n}{f} \PYG{l+m+mi}{2} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{f} \PYG{l+m+mi}{8} \PYG{o}{=} \PYG{n}{f} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{n}{x}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Note that, in this goal, it behaves like \sphinxcode{\sphinxupquote{set x := \{1 3\}(f 2).}}

\item {} 
In particular, the switch \sphinxcode{\sphinxupquote{\{+\}}} selects \sphinxstyleemphasis{all} the occurrences. This
switch is useful to turn off the default behavior of a tactic which
automatically clears some assumptions (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Discharge}}}} for
instance).

\item {} 
The switch \sphinxcode{\sphinxupquote{\{-\}}} imposes that \sphinxstyleemphasis{no} occurrences of the term should be
affected by the tactic. The tactic: \sphinxcode{\sphinxupquote{set x := \{-\}(f 2).}} leaves the goal
unchanged and adds the definition \sphinxcode{\sphinxupquote{x := f 2}} to the context. This kind
of tactic may be used to take advantage of the power of the matching
algorithm in a local definition, instead of copying large terms by
hand.

\end{itemize}

It is important to remember that matching \sphinxstyleemphasis{preceeds} occurrence
selection.
\begin{quote}

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{z}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{z}

\PYG{k}{set} \PYG{n}{a} \PYG{o}{:=} \PYG{o}{\PYGZob{}}\PYG{l+m+mi}{2}\PYG{o}{\PYGZcb{}}\PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{a} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{a} \PYG{o}{+} \PYG{n}{z}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}

Hence, in the following goal, the same tactic fails since there is
only one occurrence of the selected term.
\begin{quote}

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)} \PYG{o}{+} \PYG{o}{(}\PYG{n}{z} \PYG{o}{+} \PYG{n}{z}\PYG{o}{)} \PYG{o}{=} \PYG{n}{z} \PYG{o}{+} \PYG{n}{z}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{o}{(}\PYG{n}{z} \PYG{o}{+} \PYG{n}{z}\PYG{o}{)} \PYG{o}{=} \PYG{n}{z} \PYG{o}{+} \PYG{n}{z}

\PYG{k}{set} \PYG{n}{a} \PYG{o}{:=} \PYG{o}{\PYGZob{}}\PYG{l+m+mi}{2}\PYG{o}{\PYGZcb{}}\PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{19}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k}{set} \PYG{n}{a} \PYG{o}{:=} \PYG{o}{\PYGZob{}}\PYG{l+m+mi}{2}\PYG{o}{\PYGZcb{}}\PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:}
    \PYG{k+kn}{Ltac} \PYG{n}{call} \PYG{n}{to} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{set (ssrfwdid) (ssrsetfwd) (ssrclauses)}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{failed}\PYG{o}{.}
    \PYG{n}{Only} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2} \PYG{n}{occurence} \PYG{k}{of} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{o}{(}\PYG{n}{z} \PYG{o}{+} \PYG{n}{z}\PYG{o}{)}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}


\subsubsection{Basic localization}
\label{\detokenize{proof-engine/ssreflect-proof-language:basic-localization}}\label{\detokenize{proof-engine/ssreflect-proof-language:basic-localization-ssr}}
It is possible to define an abbreviation for a term appearing in the
context of a goal thanks to the in tactical.

A tactic of the form:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}


introduces a defined constant called \sphinxcode{\sphinxupquote{x}} in the context, and folds it in
the context entries mentioned on the right hand side of \sphinxcode{\sphinxupquote{in}}.
The body of \sphinxcode{\sphinxupquote{x}} is the first subterm matching these context entries
(taken in the given order).

A tactic of the form:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~*}}}}
\end{fulllineitems}


matches term and then folds \sphinxcode{\sphinxupquote{x}} similarly in all the given context entries
but also folds \sphinxcode{\sphinxupquote{x}} in the goal.
\begin{quote}

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{t} \PYG{o}{(}\PYG{n}{Hx} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{3}\PYG{o}{)} \PYG{o}{:} \PYG{n}{x} \PYG{o}{+} \PYG{n}{t} \PYG{o}{=} \PYG{l+m+mi}{4}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{t} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{Hx} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{3}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{t} \PYG{o}{=} \PYG{l+m+mi}{4}

\PYG{k}{set} \PYG{n}{z} \PYG{o}{:=} \PYG{l+m+mi}{3} \PYG{k}{in} \PYG{n}{Hx}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{t} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{z} \PYG{o}{:=} \PYG{l+m+mi}{3} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{Hx} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{z}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{t} \PYG{o}{=} \PYG{l+m+mi}{4}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}

If the localization also mentions the goal, then the result is the following one:
\begin{quote}

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{t} \PYG{o}{(}\PYG{n}{Hx} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{3}\PYG{o}{)} \PYG{o}{:} \PYG{n}{x} \PYG{o}{+} \PYG{n}{t} \PYG{o}{=} \PYG{l+m+mi}{4}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{t} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{Hx} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{3}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{t} \PYG{o}{=} \PYG{l+m+mi}{4}

\PYG{k}{set} \PYG{n}{z} \PYG{o}{:=} \PYG{l+m+mi}{3} \PYG{k}{in} \PYG{n}{Hx} \PYG{o}{*} \PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{t} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{z} \PYG{o}{:=} \PYG{l+m+mi}{3} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{Hx} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{z}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{t} \PYG{o}{=} \PYG{n}{S} \PYG{n}{z}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}

Indeed, remember that 4 is just a notation for (S 3).

The use of the \sphinxcode{\sphinxupquote{in}} tactical is not limited to the localization of
abbreviations: for a complete description of the in tactical, see
section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:bookkeeping-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Bookkeeping}}}} and {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:localization-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Localization}}}}.


\subsection{Basic tactics}
\label{\detokenize{proof-engine/ssreflect-proof-language:basic-tactics}}\label{\detokenize{proof-engine/ssreflect-proof-language:basic-tactics-ssr}}
A sizable fraction of proof scripts consists of steps that do not
"prove" anything new, but instead perform menial bookkeeping tasks
such as selecting the names of constants and assumptions or splitting
conjuncts. Although they are logically trivial, bookkeeping steps are
extremely important because they define the structure of the data-flow
of a proof script. This is especially true for reflection-based
proofs, which often involve large numbers of constants and
assumptions. Good bookkeeping consists in always explicitly declaring
(i.e., naming) all new constants and assumptions in the script, and
systematically pruning irrelevant constants and assumptions in the
context. This is essential in the context of an interactive
development environment (IDE), because it facilitates navigating the
proof, allowing to instantly "jump back" to the point at which a
questionable assumption was added, and to find relevant assumptions by
browsing the pruned context. While novice or casual \DUrole{smallcaps}{Coq} users may find
the automatic name selection feature convenient, the usage of such a
feature severely undermines the readability and maintainability of
proof scripts, much like automatic variable declaration in programming
languages. The \DUrole{smallcaps}{SSReflect} tactics are therefore designed to support
precise bookkeeping and to eliminate name generation heuristics. The
bookkeeping features of \DUrole{smallcaps}{SSReflect} are implemented as tacticals (or
pseudo-tacticals), shared across most \DUrole{smallcaps}{SSReflect} tactics, and thus form
the foundation of the \DUrole{smallcaps}{SSReflect} proof language.


\subsubsection{Bookkeeping}
\label{\detokenize{proof-engine/ssreflect-proof-language:bookkeeping}}\label{\detokenize{proof-engine/ssreflect-proof-language:bookkeeping-ssr}}
During the course of a proof \DUrole{smallcaps}{Coq} always present the user with a
\sphinxstyleemphasis{sequent} whose general form is:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
ci : Ti
…
dj := ej : Tj
…
Fk : Pk
…
=================
forall (xl : Tl ) …,
let ym := bm in … in
Pn \PYGZhy{}\PYGZgt{} … \PYGZhy{}\PYGZgt{} C
\end{sphinxVerbatim}

The \sphinxstyleemphasis{goal} to be proved appears below the double line; above the line
is the \sphinxstyleemphasis{context} of the sequent, a set of declarations of \sphinxstyleemphasis{constants}
\sphinxcode{\sphinxupquote{ci}} , \sphinxstyleemphasis{defined constants} d i , and \sphinxstyleemphasis{facts} \sphinxcode{\sphinxupquote{Fk}} that can be used to
prove the goal (usually, \sphinxcode{\sphinxupquote{Ti}} , \sphinxcode{\sphinxupquote{Tj : Type}} and \sphinxcode{\sphinxupquote{Pk : Prop}}).
The various
kinds of declarations can come in any order. The top part of the
context consists of declarations produced by the Section
commands \sphinxcode{\sphinxupquote{Variable}}, \sphinxcode{\sphinxupquote{Let}}, and \sphinxcode{\sphinxupquote{Hypothesis}}.
This \sphinxstyleemphasis{section context} is never
affected by the \DUrole{smallcaps}{SSReflect} tactics: they only operate on the lower part
— the \sphinxstyleemphasis{proof context}. As in the figure above, the goal often
decomposes into a series of (universally) quantified \sphinxstyleemphasis{variables}
\sphinxcode{\sphinxupquote{(xl : Tl)}}, local \sphinxstyleemphasis{definitions}
\sphinxcode{\sphinxupquote{let ym := bm in}}, and \sphinxstyleemphasis{assumptions}
\sphinxcode{\sphinxupquote{P n -\textgreater{}}},
and a \sphinxstyleemphasis{conclusion} \sphinxcode{\sphinxupquote{C}} (as in the context, variables, definitions, and
assumptions can appear in any order). The conclusion is what actually
needs to be proved — the rest of the goal can be seen as a part of the
proof context that happens to be “below the line”.

However, although they are logically equivalent, there are fundamental
differences between constants and facts on the one hand, and variables
and assumptions on the others. Constants and facts are \sphinxstyleemphasis{unordered},
but \sphinxstyleemphasis{named} explicitly in the proof text; variables and assumptions
are \sphinxstyleemphasis{ordered}, but \sphinxstyleemphasis{unnamed}: the display names of variables may
change at any time because of \(\alpha\)-conversion.

Similarly, basic deductive steps such as apply can only operate on the
goal because the \DUrole{smallcaps}{Gallina} terms that control their action (e.g., the
type of the lemma used by \sphinxcode{\sphinxupquote{apply}}) only provide unnamed bound variables.
%
\begin{footnote}[9]\sphinxAtStartFootnote
Thus scripts that depend on bound variable names, e.g., via intros
or with, are inherently fragile.
%
\end{footnote} Since the proof script can only refer directly to the context, it
must constantly shift declarations from the goal to the context and
conversely in between deductive steps.

In \DUrole{smallcaps}{SSReflect} these moves are performed by two \sphinxstyleemphasis{tacticals} \sphinxcode{\sphinxupquote{=\textgreater{}}} and
\sphinxcode{\sphinxupquote{:}}, so that the bookkeeping required by a deductive step can be
directly associated to that step, and that tactics in an \DUrole{smallcaps}{SSReflect}
script correspond to actual logical steps in the proof rather than
merely shuffle facts. Still, some isolated bookkeeping is unavoidable,
such as naming variables and assumptions at the beginning of a
proof. \DUrole{smallcaps}{SSReflect} provides a specific \sphinxcode{\sphinxupquote{move}} tactic for this purpose.

Now \sphinxcode{\sphinxupquote{move}} does essentially nothing: it is mostly a placeholder for
\sphinxcode{\sphinxupquote{=\textgreater{}}} and \sphinxcode{\sphinxupquote{:}}. The \sphinxcode{\sphinxupquote{=\textgreater{}}} tactical moves variables, local definitions,
and assumptions to the context, while the \sphinxcode{\sphinxupquote{:}} tactical moves facts and
constants to the goal.

\begin{sphinxadmonition}{note}{Example}

For example, the proof of %
\begin{footnote}[10]\sphinxAtStartFootnote
The name \sphinxcode{\sphinxupquote{subnK}} reads as “right cancellation rule for nat
subtraction”.
%
\end{footnote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{subnK} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m} \PYG{n}{n}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{n}{n} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{m} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{n}{n} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{m}
\end{sphinxVerbatim}

might start with

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{n}{m} \PYG{n}{n} \PYG{n}{le\PYGZus{}n\PYGZus{}m}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{m}\PYG{o}{,} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{le\PYGZus{}n\PYGZus{}m} \PYG{o}{:} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{n}{n} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{m}
\end{sphinxVerbatim}

where move does nothing, but \sphinxcode{\sphinxupquote{=\textgreater{} m n le\_m\_n}} changes
the variables and assumption of the goal in the constants
\sphinxcode{\sphinxupquote{m n : nat}} and the fact \sphinxcode{\sphinxupquote{le\_n\_m : n \textless{}=  m}}, thus exposing the
conclusion \sphinxcode{\sphinxupquote{m - n + n = m}}.

The \sphinxcode{\sphinxupquote{:}} tactical is the converse of \sphinxcode{\sphinxupquote{=\textgreater{}}}, indeed it removes facts and
constants from the context by turning them into variables and
assumptions.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{move}\PYG{o}{:} \PYG{n}{m} \PYG{n}{le\PYGZus{}n\PYGZus{}m}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{n}{n} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{m}
\end{sphinxVerbatim}

turns back \sphinxcode{\sphinxupquote{m}} and \sphinxcode{\sphinxupquote{le\_m\_n}} into a variable and an assumption,
removing them from the proof context, and changing the goal to
\sphinxcode{\sphinxupquote{forall m, n \textless{}= m -\textgreater{} m - n + n = m}}
which can be proved by induction on \sphinxcode{\sphinxupquote{n}} using \sphinxcode{\sphinxupquote{elim: n}}.
\end{sphinxadmonition}

Because they are tacticals, \sphinxcode{\sphinxupquote{:}} and \sphinxcode{\sphinxupquote{=\textgreater{}}} can be combined, as in

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{move}\PYG{o}{:} \PYG{n}{m} \PYG{n}{le\PYGZus{}n\PYGZus{}m} \PYG{o}{=\PYGZgt{}} \PYG{n}{p} \PYG{n}{le\PYGZus{}n\PYGZus{}p}\PYG{o}{.}
\end{sphinxVerbatim}

simultaneously renames \sphinxcode{\sphinxupquote{m}} and \sphinxcode{\sphinxupquote{le\_m\_n}} into \sphinxcode{\sphinxupquote{p}} and \sphinxcode{\sphinxupquote{le\_n\_p}},
respectively, by first turning them into unnamed variables, then
turning these variables back into constants and facts.

Furthermore, \DUrole{smallcaps}{SSReflect} redefines the basic \DUrole{smallcaps}{Coq} tactics \sphinxcode{\sphinxupquote{case}}, \sphinxcode{\sphinxupquote{elim}},
and \sphinxcode{\sphinxupquote{apply}} so that they can take better advantage of
\sphinxcode{\sphinxupquote{:}} and \sphinxcode{\sphinxupquote{=\textgreater{}}}. In there
\DUrole{smallcaps}{SSReflect} variants, these tactic operate on the first variable or
constant of the goal and they do not use or change the proof context.
The \sphinxcode{\sphinxupquote{:}} tactical is used to operate on an element in the context.

\begin{sphinxadmonition}{note}{Example}
\begin{quote}

For instance the proof of \sphinxcode{\sphinxupquote{subnK}} could continue with \sphinxcode{\sphinxupquote{elim: n}}.
Instead of \sphinxcode{\sphinxupquote{elim n}} (note, no colon), this has the advantage of
removing n from the context. Better yet, this \sphinxcode{\sphinxupquote{elim}} can be combined
with previous move and with the branching version of the \sphinxcode{\sphinxupquote{=\textgreater{}}} tactical
(described in {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}),
to encapsulate the inductive step in a single
command:
\end{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{subnK} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m} \PYG{n}{n}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{n}{n} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{m} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{n}{n} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{m}

\PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{n}{m} \PYG{n}{n} \PYG{n}{le\PYGZus{}n\PYGZus{}m}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{m}\PYG{o}{,} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{le\PYGZus{}n\PYGZus{}m} \PYG{o}{:} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{n}{n} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{m}

\PYG{k}{elim}\PYG{o}{:} \PYG{n}{n} \PYG{n}{m} \PYG{n}{le\PYGZus{}n\PYGZus{}m} \PYG{o}{=\PYGZgt{}} \PYG{o}{[\textbar{}}\PYG{n}{n} \PYG{n}{IHn}\PYG{o}{]} \PYG{n}{m} \PYG{o}{=\PYGZgt{}} \PYG{o}{[}\PYG{o}{\PYGZus{}} \PYG{o}{\textbar{}} \PYG{n}{lt\PYGZus{}n\PYGZus{}m}\PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{m}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{m} \PYG{o}{\PYGZhy{}} \PYG{n}{S} \PYG{n}{n} \PYG{o}{+} \PYG{n}{S} \PYG{n}{n} \PYG{o}{=} \PYG{n}{m}
\end{sphinxVerbatim}

which breaks down the proof into two subgoals, the second one
having in its context
\sphinxcode{\sphinxupquote{lt\_n\_m : S n \textless{}= m}} and
\sphinxcode{\sphinxupquote{IHn : forall m, n \textless{}= m -\textgreater{} m - n + n = m}}.
\end{sphinxadmonition}

The \sphinxcode{\sphinxupquote{:}} and \sphinxcode{\sphinxupquote{=\textgreater{}}} tacticals can be explained very simply if one views
the goal as a stack of variables and assumptions piled on a conclusion:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{tactic : a b c}} pushes the context constants \sphinxcode{\sphinxupquote{a}}, \sphinxcode{\sphinxupquote{b}}, \sphinxcode{\sphinxupquote{c}} as goal
variables \sphinxstyleemphasis{before} performing tactic.

\item {} 
\sphinxcode{\sphinxupquote{tactic =\textgreater{} a b c}} pops the top three goal variables as context
constants \sphinxcode{\sphinxupquote{a}}, \sphinxcode{\sphinxupquote{b}}, \sphinxcode{\sphinxupquote{c}}, \sphinxstyleemphasis{after} tactic has been performed.

\end{itemize}

These pushes and pops do not need to balance out as in the examples
above, so \sphinxcode{\sphinxupquote{move: m le\_n\_m =\textgreater{} p}}
would rename \sphinxcode{\sphinxupquote{m}} into \sphinxcode{\sphinxupquote{p}}, but leave an extra assumption \sphinxcode{\sphinxupquote{n \textless{}= p}}
in the goal.

Basic tactics like apply and elim can also be used without the ’:’
tactical: for example we can directly start a proof of \sphinxcode{\sphinxupquote{subnK}} by
induction on the top variable \sphinxcode{\sphinxupquote{m}} with

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{elim}\PYG{o}{=\PYGZgt{}} \PYG{o}{[\textbar{}}\PYG{n}{m} \PYG{n}{IHm}\PYG{o}{]} \PYG{n}{n} \PYG{n}{le\PYGZus{}n}\PYG{o}{.}
\end{sphinxVerbatim}

The general form of the localization tactical in is also best
explained in terms of the goal stack:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
tactic in a H1 H2 *.
\end{sphinxVerbatim}

is basically equivalent to

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{move}\PYG{o}{:} \PYG{n}{a} \PYG{n}{H1} \PYG{n}{H2}\PYG{o}{;} \PYG{n}{tactic} \PYG{o}{=\PYGZgt{}} \PYG{n}{a} \PYG{n}{H1} \PYG{n}{H2}\PYG{o}{.}
\end{sphinxVerbatim}

with two differences: the in tactical will preserve the body of a ifa
is a defined constant, and if the \sphinxcode{\sphinxupquote{*}} is omitted it will use a
temporary abbreviation to hide the statement of the goal from
\sphinxcode{\sphinxupquote{tactic}}.

The general form of the in tactical can be used directly with the
\sphinxcode{\sphinxupquote{move}}, \sphinxcode{\sphinxupquote{case}} and \sphinxcode{\sphinxupquote{elim}} tactics, so that one can write

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{elim}\PYG{o}{:} \PYG{n}{n} \PYG{o}{=\PYGZgt{}} \PYG{o}{[\textbar{}}\PYG{n}{n} \PYG{n}{IHn}\PYG{o}{]} \PYG{k}{in} \PYG{n}{m} \PYG{n}{le\PYGZus{}n\PYGZus{}m} \PYG{o}{*}\PYG{o}{.}
\end{sphinxVerbatim}

instead of

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{elim}\PYG{o}{:} \PYG{n}{n} \PYG{n}{m} \PYG{n}{le\PYGZus{}n\PYGZus{}m} \PYG{o}{=\PYGZgt{}} \PYG{o}{[\textbar{}}\PYG{n}{n} \PYG{n}{IHn}\PYG{o}{]} \PYG{n}{m} \PYG{n}{le\PYGZus{}n\PYGZus{}m}\PYG{o}{.}
\end{sphinxVerbatim}

This is quite useful for inductive proofs that involve many facts.

See section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:localization-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Localization}}}} for
the general syntax and presentation of the in
tactical.


\subsubsection{The defective tactics}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-defective-tactics}}\label{\detokenize{proof-engine/ssreflect-proof-language:the-defective-tactics-ssr}}
In this section we briefly present the three basic tactics performing
context manipulations and the main backward chaining tool.


\paragraph{The move tactic.}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-move-tactic}}
The move tactic, in its defective form, behaves like the primitive \sphinxcode{\sphinxupquote{hnf}}
\DUrole{smallcaps}{Coq} tactic. For example, such a defective:
\index{move (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.move}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{move}}}}
\end{fulllineitems}


exposes the first assumption in the goal, i.e. its changes the
goal \sphinxcode{\sphinxupquote{not False}} into \sphinxcode{\sphinxupquote{False -\textgreater{} False}}.

More precisely, the \sphinxcode{\sphinxupquote{move}} tactic inspects the goal and does nothing
(\sphinxcode{\sphinxupquote{idtac}}) if an introduction step is possible, i.e. if the goal is a
product or a \sphinxcode{\sphinxupquote{let…in}}, and performs \sphinxcode{\sphinxupquote{hnf}} otherwise.

Of course this tactic is most often used in combination with the
bookkeeping tacticals (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}} and {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Discharge}}}}). These
combinations mostly subsume the {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.generalize}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{generalize}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.revert}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{revert}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.rename}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rename}}}}},
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.clear}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{pattern}}}}} tactics.


\paragraph{The case tactic}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-case-tactic}}
The \sphinxcode{\sphinxupquote{case}} tactic performs \sphinxstyleemphasis{primitive case analysis} on (co)inductive
types; specifically, it destructs the top variable or assumption of
the goal, exposing its constructor(s) and its arguments, as well as
setting the value of its type family indices if it belongs to a type
family (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:type-families-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Type families}}}}).

The \DUrole{smallcaps}{SSReflect} case tactic has a special behavior on equalities. If the
top assumption of the goal is an equality, the case tactic “destructs”
it as a set of equalities between the constructor arguments of its
left and right hand sides, as per the tactic injection. For example,
\sphinxcode{\sphinxupquote{case}} changes the goal:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
(x, y) = (1, 2) \PYGZhy{}\PYGZgt{} G.
\end{sphinxVerbatim}

into:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
x = 1 \PYGZhy{}\PYGZgt{} y = 2 \PYGZhy{}\PYGZgt{} G.
\end{sphinxVerbatim}

Note also that the case of \DUrole{smallcaps}{SSReflect} performs \sphinxcode{\sphinxupquote{False}} elimination, even
if no branch is generated by this case operation. Hence the command:
\sphinxcode{\sphinxupquote{case.}} on a goal of the form \sphinxcode{\sphinxupquote{False -\textgreater{} G}} will succeed and
prove the goal.


\paragraph{The elim tactic}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-elim-tactic}}
The \sphinxcode{\sphinxupquote{elim}} tactic performs inductive elimination on inductive types. The
defective:
\index{elim (ssreflect) (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.elim-ssreflect}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{elim}}}}
\end{fulllineitems}


tactic performs inductive elimination on a goal whose top assumption
has an inductive type.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{m} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}

\PYG{k}{elim}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{S} \PYG{n}{n}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{The apply tactic}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-apply-tactic}}\label{\detokenize{proof-engine/ssreflect-proof-language:apply-ssr}}
The \sphinxcode{\sphinxupquote{apply}} tactic is the main backward chaining tactic of the proof
system. It takes as argument any {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} and applies it to the goal.
Assumptions in the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} that don’t directly match the goal
may generate one or more subgoals.

In fact the \DUrole{smallcaps}{SSReflect} tactic:
\index{apply (ssreflect) (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.apply-ssreflect}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply}}}}
\end{fulllineitems}


is a synonym for:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
intro top; first [refine top \textbar{} refine (top \PYGZus{}) \textbar{} refine (top \PYGZus{} \PYGZus{}) \textbar{} …]; clear top.
\end{sphinxVerbatim}

where \sphinxcode{\sphinxupquote{top}} is a fresh name, and the sequence of refine tactics tries to
catch the appropriate number of wildcards to be inserted. Note that
this use of the refine tactic implies that the tactic tries to match
the goal up to expansion of constants and evaluation of subterms.

\DUrole{smallcaps}{SSReflect}’s apply has a special behavior on goals containing
existential metavariables of sort Prop.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{y}\PYG{o}{,} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{exists} \PYG{n}{x} \PYG{o}{:} \PYG{o}{\PYGZob{}} \PYG{n}{n} \PYG{o}{\textbar{}} \PYG{n}{n} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{3} \PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}} \PYG{n}{proj1\PYGZus{}sig} \PYG{n}{x}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,}
      \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{exists} \PYG{n}{x} \PYG{o}{:} \PYG{o}{\PYGZob{}}\PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\textbar{}} \PYG{n}{n} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{3}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}} \PYG{n}{proj1\PYGZus{}sig} \PYG{n}{x}

\PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{n}{y} \PYG{n}{y\PYGZus{}gt1} \PYG{n}{y\PYGZus{}lt2}\PYG{o}{;} \PYG{k}{apply}\PYG{o}{:} \PYG{o}{(}\PYG{n}{ex\PYGZus{}intro} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{n}{exist} \PYG{o}{\PYGZus{}} \PYG{n}{y} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{focused} \PYG{n}{subgoals}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{2}\PYG{o}{)}
      
      \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{y\PYGZus{}gt1} \PYG{o}{:} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{y}
      \PYG{n}{y\PYGZus{}lt2} \PYG{o}{:} \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{3}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{k}{forall} \PYG{n}{Hyp0} \PYG{o}{:} \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{3}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}} \PYG{n}{proj1\PYGZus{}sig} \PYG{o}{(}\PYG{n}{exist} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{n} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{3}\PYG{o}{)} \PYG{n}{y} \PYG{n}{Hyp0}\PYG{o}{)}

\PYG{k+kp}{by} \PYG{k}{apply}\PYG{o}{:} \PYG{n}{lt\PYGZus{}trans} \PYG{n}{y\PYGZus{}lt2} \PYG{o}{\PYGZus{}}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{focused} \PYG{n}{subgoal}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{1}\PYG{o}{)}
      
      \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{y\PYGZus{}gt1} \PYG{o}{:} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{y}
      \PYG{n}{y\PYGZus{}lt2} \PYG{o}{:} \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{Hyp0} \PYG{o}{:} \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{3}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}} \PYG{n}{proj1\PYGZus{}sig} \PYG{o}{(}\PYG{n}{exist} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{n} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{3}\PYG{o}{)} \PYG{n}{y} \PYG{n}{Hyp0}\PYG{o}{)}

\PYG{k+kp}{by} \PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{n}{y\PYGZus{}lt3}\PYG{o}{;} \PYG{k}{apply}\PYG{o}{:} \PYG{n}{lt\PYGZus{}trans} \PYG{n}{y\PYGZus{}gt1}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}

Note that the last \sphinxcode{\sphinxupquote{\_}} of the tactic
\sphinxcode{\sphinxupquote{apply: (ex\_intro \_ (exist \_ y \_))}}
represents a proof that \sphinxcode{\sphinxupquote{y \textless{} 3}}. Instead of generating the goal:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
0 \PYGZlt{} proj1\PYGZus{}sig (exist (fun n : nat =\PYGZgt{} n \PYGZlt{} 3) y ?Goal).
\end{sphinxVerbatim}

the system tries to prove \sphinxcode{\sphinxupquote{y \textless{} 3}} calling the trivial tactic.
If it succeeds, let’s say because the context contains
\sphinxcode{\sphinxupquote{H : y \textless{} 3}}, then the
system generates the following goal:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
0 \PYGZlt{} proj1\PYGZus{}sig (exist (fun n =\PYGZgt{} n \PYGZlt{} 3) y H).
\end{sphinxVerbatim}

Otherwise the missing proof is considered to be irrelevant, and is
thus discharged generating the two goals shown above.

Last, the user can replace the trivial tactic by defining an Ltac
expression named \sphinxcode{\sphinxupquote{ssrautoprop}}.
\end{sphinxadmonition}


\subsubsection{Discharge}
\label{\detokenize{proof-engine/ssreflect-proof-language:discharge}}\label{\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}}
The general syntax of the discharging tactical \sphinxcode{\sphinxupquote{:}} is:
\index{... : ... (ssreflect) (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.ssreflect}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\DUrole{hole}{d\_item}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{d\_item~::=~}}\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{clear\_switch~::=~}}\DUrole{notation}{\DUrole{curlies}{\{~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~\}}}}}}
\end{fulllineitems}


with the following requirements:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{tactic}} must be one of the four basic tactics described in {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:the-defective-tactics-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{The defective tactics}}}},
i.e., \sphinxcode{\sphinxupquote{move}}, \sphinxcode{\sphinxupquote{case}}, \sphinxcode{\sphinxupquote{elim}} or \sphinxcode{\sphinxupquote{apply}}, the \sphinxcode{\sphinxupquote{exact}}
tactic (section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:terminators-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Terminators}}}}),
the \sphinxcode{\sphinxupquote{congr}} tactic (section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:congruence-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Congruence}}}}),
or the application of the \sphinxstyleemphasis{view}
tactical ‘/’ (section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:interpreting-assumptions-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Interpreting assumptions}}}}) to one of move, case, or elim.

\item {} 
The optional {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} specifies \sphinxstyleemphasis{equation generation} (section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:generation-of-equations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of equations}}}}),
and is only allowed if tactic is \sphinxcode{\sphinxupquote{move}}, \sphinxcode{\sphinxupquote{case}} or \sphinxcode{\sphinxupquote{elim}}, or the
application of the view tactical ‘/’ (section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:interpreting-assumptions-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Interpreting assumptions}}}}) to \sphinxcode{\sphinxupquote{case}} or \sphinxcode{\sphinxupquote{elim}}.

\item {} 
An {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}} selects occurrences of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}, as in {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:abbreviations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations}}}}; {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}}
is not allowed if \sphinxcode{\sphinxupquote{tactic}} is \sphinxcode{\sphinxupquote{apply}} or \sphinxcode{\sphinxupquote{exact}}.

\item {} 
A clear item {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}} specifies facts and constants to be
deleted from the proof context (as per the clear tactic).

\end{itemize}

The \sphinxcode{\sphinxupquote{:}} tactical first \sphinxstyleemphasis{discharges} all the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}}, right to left,
and then performs tactic, i.e., for each {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}}, starting with the last one :
\begin{enumerate}
\def\theenumi{\arabic{enumi}}
\def\labelenumi{\theenumi .}
\makeatletter\def\p@enumii{\p@enumi \theenumi .}\makeatother
\item {} 
The \DUrole{smallcaps}{SSReflect} matching algorithm described in section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:abbreviations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations}}}} is
used to find occurrences of term in the goal, after filling any holes
‘\_’ in term; however if tactic is apply or exact a different matching
algorithm, described below, is used %
\begin{footnote}[11]\sphinxAtStartFootnote
Also, a slightly different variant may be used for the first {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}}
of case and elim; see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:type-families-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Type families}}}}.
%
\end{footnote}.

\item {} 
These occurrences are replaced by a new variable; in particular, if
term is a fact, this adds an assumption to the goal.

\item {} 
If term is \sphinxstyleemphasis{exactly} the name of a constant or fact in the proof
context, it is deleted from the context, unless there is an
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}}.

\end{enumerate}

Finally, tactic is performed just after the first {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}}
has been generalized
— that is, between steps 2 and 3. The names listed in
the final {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}} (if it is present) are cleared first, before
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}} n is discharged.

Switches affect the discharging of a {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}} as follows:
\begin{itemize}
\item {} 
An {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}} restricts generalization (step 2) to a specific subset
of the occurrences of term, as per section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:abbreviations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations}}}}, and prevents clearing (step
3).

\item {} 
All the names specified by a {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}} are deleted from the
context in step 3, possibly in addition to term.

\end{itemize}

For example, the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{move}\PYG{o}{:} \PYG{n}{n} \PYG{o}{\PYGZob{}}\PYG{l+m+mi}{2}\PYG{o}{\PYGZcb{}}\PYG{n}{n} \PYG{o}{(}\PYG{n}{refl\PYGZus{}equal} \PYG{n}{n}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}
\begin{itemize}
\item {} 
first generalizes \sphinxcode{\sphinxupquote{(refl\_equal n : n = n)}};

\item {} 
then generalizes the second occurrence of \sphinxcode{\sphinxupquote{n}}.

\item {} 
finally generalizes all the other occurrences of \sphinxcode{\sphinxupquote{n}}, and clears \sphinxcode{\sphinxupquote{n}}
from the proof context (assuming n is a proof constant).

\end{itemize}

Therefore this tactic changes any goal \sphinxcode{\sphinxupquote{G}} into

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{forall} \PYG{n}{n} \PYG{n}{n0} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{G}\PYG{o}{.}
\end{sphinxVerbatim}

where the name \sphinxcode{\sphinxupquote{n0}} is picked by the \DUrole{smallcaps}{Coq} display function, and assuming
\sphinxcode{\sphinxupquote{n}} appeared only in \sphinxcode{\sphinxupquote{G}}.

Finally, note that a discharge operation generalizes defined constants
as variables, and not as local definitions. To override this behavior,
prefix the name of the local definition with a \sphinxcode{\sphinxupquote{@}}, like in \sphinxcode{\sphinxupquote{move: @n}}.

This is in contrast with the behavior of the in tactical (see
section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:localization-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Localization}}}}), which preserves local
definitions by default.


\paragraph{Clear rules}
\label{\detokenize{proof-engine/ssreflect-proof-language:clear-rules}}
The clear step will fail if term is a proof constant that appears in
other facts; in that case either the facts should be cleared
explicitly with a {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}}, or the clear step should be disabled.
The latter can be done by adding an {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}} or simply by putting
parentheses around term: both
\sphinxcode{\sphinxupquote{move: (n).}}
and
\sphinxcode{\sphinxupquote{move: \{+\}n.}}
generalize \sphinxcode{\sphinxupquote{n}} without clearing \sphinxcode{\sphinxupquote{n}} from the proof context.

The clear step will also fail if the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}} contains a {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} that
is not in the \sphinxstyleemphasis{proof} context. Note that \DUrole{smallcaps}{SSReflect} never clears a
section constant.

If tactic is \sphinxcode{\sphinxupquote{move}} or \sphinxcode{\sphinxupquote{case}} and an equation {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is given, then clear
(step 3) for {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}} is suppressed (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:generation-of-equations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of equations}}}}).


\paragraph{Matching for apply and exact}
\label{\detokenize{proof-engine/ssreflect-proof-language:matching-for-apply-and-exact}}
The matching algorithm for {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}} of the \DUrole{smallcaps}{SSReflect}
\sphinxcode{\sphinxupquote{apply}} and \sphinxcode{\sphinxupquote{exact}}
tactics exploits the type of the first {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}} to interpret
wildcards in the
other {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}} and to determine which occurrences of these should be
generalized. Therefore, occur switches are not needed for apply and
exact.

Indeed, the \DUrole{smallcaps}{SSReflect} tactic \sphinxcode{\sphinxupquote{apply: H x}} is equivalent to
\sphinxcode{\sphinxupquote{refine (@H \_ … \_ x); clear H x}}
with an appropriate number of wildcards between \sphinxcode{\sphinxupquote{H}} and \sphinxcode{\sphinxupquote{x}}.

Note that this means that matching for \sphinxcode{\sphinxupquote{apply}} and \sphinxcode{\sphinxupquote{exact}} has much more
context to interpret wildcards; in particular it can accommodate the
\sphinxcode{\sphinxupquote{\_}} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}}, which would always be rejected after \sphinxcode{\sphinxupquote{move:}}.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{Hfg} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{n}{f} \PYG{n}{x} \PYG{o}{=} \PYG{n}{g} \PYG{n}{x}\PYG{o}{)} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{f} \PYG{n}{a} \PYG{o}{=} \PYG{n}{g} \PYG{n}{b}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{Hfg} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{f} \PYG{n}{x} \PYG{o}{=} \PYG{n}{g} \PYG{n}{x}
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{f} \PYG{n}{a} \PYG{o}{=} \PYG{n}{g} \PYG{n}{b}

\PYG{k}{apply}\PYG{o}{:} \PYG{n}{trans\PYGZus{}equal} \PYG{o}{(}\PYG{n}{Hfg} \PYG{o}{\PYGZus{}}\PYG{o}{)} \PYG{o}{\PYGZus{}}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{focused} \PYG{n}{subgoal}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{1}\PYG{o}{)}
      
      \PYG{n}{Hfg} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{f} \PYG{n}{x} \PYG{o}{=} \PYG{n}{g} \PYG{n}{x}
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{g} \PYG{n}{a} \PYG{o}{=} \PYG{n}{g} \PYG{n}{b}
\end{sphinxVerbatim}
\end{sphinxadmonition}

This tactic is equivalent (see section
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:bookkeeping-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Bookkeeping}}}}) to:
\sphinxcode{\sphinxupquote{refine (trans\_equal (Hfg \_) \_).}}
and this is a common idiom for applying transitivity on the left hand
side of an equation.


\paragraph{The abstract tactic}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-abstract-tactic}}\label{\detokenize{proof-engine/ssreflect-proof-language:abstract-ssr}}\index{abstract (ssreflect) (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.abstract-ssreflect}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{abstract:~\DUrole{repeat-wrapper}{\DUrole{repeat}{d\_item}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}


This tactic assigns an abstract constant previously introduced with the \sphinxcode{\sphinxupquote{{[}:
name {]}}} intro pattern (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}).

In a goal like the following:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
m : nat
abs : \PYGZlt{}hidden\PYGZgt{}
n : nat
=============
m \PYGZlt{} 5 + n
\end{sphinxVerbatim}

The tactic \sphinxcode{\sphinxupquote{abstract: abs n}} first generalizes the goal with respect ton
(that is not visible to the abstract constant abs) and then assigns
abs. The resulting goal is:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
m : nat
n : nat
=============
m \PYGZlt{} 5 + n
\end{sphinxVerbatim}

Once this subgoal is closed, all other goals having abs in their
context see the type assigned to \sphinxcode{\sphinxupquote{abs}}. In this case:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
m : nat
abs : forall n, m \PYGZlt{} 5 + n
=============
…
\end{sphinxVerbatim}

For a more detailed example the reader should refer to
section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:structure-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Structure}}}}.


\subsubsection{Introduction in the context}
\label{\detokenize{proof-engine/ssreflect-proof-language:introduction-in-the-context}}\label{\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}}
The application of a tactic to a given goal can generate (quantified)
variables, assumptions, or definitions, which the user may want to
\sphinxstyleemphasis{introduce} as new facts, constants or defined constants,
respectively. If the tactic splits the goal into several subgoals,
each of them may require the introduction of different constants and
facts. Furthermore it is very common to immediately decompose or
rewrite with an assumption instead of adding it to the context, as the
goal can often be simplified and even proved after this.

All these operations are performed by the introduction tactical \sphinxcode{\sphinxupquote{=\textgreater{}}},
whose general syntax is
\index{=\textgreater{} (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic}~=\textgreater{}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{i\_item~::=~}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}~\DUrole{meta}{\textbar{}}~/{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{s\_item~::=~}}\DUrole{notation}{/=~\DUrole{meta}{\textbar{}}~//~\DUrole{meta}{\textbar{}}~//=}}}}
\end{fulllineitems}



\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{i\_pattern~::=~}}\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{meta}{\textbar{}}~\_~\DUrole{meta}{\textbar{}}~?~\DUrole{meta}{\textbar{}}~*~\DUrole{meta}{\textbar{}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}}\DUrole{notation-sup}{?}}~-\textgreater{}~\DUrole{meta}{\textbar{}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}}\DUrole{notation-sup}{?}}\textless{}-~\DUrole{meta}{\textbar{}}~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}\DUrole{notation-sup}{?}\DUrole{notation-sub}{\textbar{}}}~{]}~\DUrole{meta}{\textbar{}}~-~\DUrole{meta}{\textbar{}}~{[}:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~{]}}}}}
\end{fulllineitems}


The \sphinxcode{\sphinxupquote{=\textgreater{}}} tactical first executes tactic, then the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} s,
left to right. An {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{s\_item}}}}} specifies a
simplification operation; a {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}}
h specifies context pruning as in {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Discharge}}}}.
The {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}} s can be seen as a variant of \sphinxstyleemphasis{intro patterns}
{\hyperref[\detokenize{proof-engine/tactics:tactics}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics}}}}: each performs an introduction operation, i.e., pops some
variables or assumptions from the goal.

An {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{s\_item}}}}} can simplify the set of subgoals or the subgoals themselves:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{//}} removes all the “trivial” subgoals that can be resolved by the
\DUrole{smallcaps}{SSReflect} tactic {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.done}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{done}}}}} described in {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:terminators-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Terminators}}}}, i.e.,
it executes \sphinxcode{\sphinxupquote{try done}}.

\item {} 
\sphinxcode{\sphinxupquote{/=}} simplifies the goal by performing partial evaluation, as per the
tactic \sphinxcode{\sphinxupquote{simpl}} %
\begin{footnote}[12]\sphinxAtStartFootnote
Except /= does not expand the local definitions created by the
\DUrole{smallcaps}{SSReflect} in tactical.
%
\end{footnote}.

\item {} 
\sphinxcode{\sphinxupquote{//=}} combines both kinds of simplification; it is equivalent to
\sphinxcode{\sphinxupquote{/= //}}, i.e., \sphinxcode{\sphinxupquote{simpl; try done}}.

\end{itemize}

When an {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{s\_item}}}}} bears a {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}}, then the
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}} is executed
\sphinxstyleemphasis{after} the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{s\_item}}}}}, e.g., \sphinxcode{\sphinxupquote{\{IHn\}//}} will solve some subgoals,
possibly using the fact \sphinxcode{\sphinxupquote{IHn}}, and will erase \sphinxcode{\sphinxupquote{IHn}} from the context
of the remaining subgoals.

The last entry in the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} grammar rule, \sphinxcode{\sphinxupquote{/}}{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}},
represents a view (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:views-and-reflection-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Views and reflection}}}}).
If the next {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} is a view, then the view is
applied to the assumption in top position once all the
previous {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} have been performed.

The view is applied to the top assumption.

\DUrole{smallcaps}{SSReflect} supports the following {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}} s:
\begin{description}
\item[{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}}] \leavevmode
pops the top variable, assumption, or local definition into
a new constant, fact, or defined constant {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}, respectively.
Note that defined constants cannot be introduced when \(\delta\)-expansion is
required to expose the top variable or assumption.

\item[{\sphinxcode{\sphinxupquote{?}}}] \leavevmode
pops the top variable into an anonymous constant or fact, whose name
is picked by the tactic interpreter. \DUrole{smallcaps}{SSReflect} only generates names that cannot
appear later in the user script %
\begin{footnote}[13]\sphinxAtStartFootnote
\DUrole{smallcaps}{SSReflect} reserves all identifiers of the form “\_x\_”, which is
used for such generated names.
%
\end{footnote}.

\item[{\sphinxcode{\sphinxupquote{\_}}}] \leavevmode
pops the top variable into an anonymous constant that will be deleted
from the proof context of all the subgoals produced by the \sphinxcode{\sphinxupquote{=\textgreater{}}} tactical.
They should thus never be displayed, except in an error message if the
constant is still actually used in the goal or context after the last
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} has been executed ({\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{s\_item}}}}} can erase goals or
terms where the constant appears).

\item[{\sphinxcode{\sphinxupquote{*}}}] \leavevmode
pops all the remaining apparent variables/assumptions as anonymous
constants/facts. Unlike \sphinxcode{\sphinxupquote{?}} and \sphinxcode{\sphinxupquote{move}} the \sphinxcode{\sphinxupquote{*}}
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} does not
expand definitions in the goal to expose quantifiers, so it may be useful
to repeat a \sphinxcode{\sphinxupquote{move=\textgreater{} *}} tactic, e.g., on the goal:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
forall a b : bool, a \PYGZlt{}\PYGZgt{} b
\end{sphinxVerbatim}

a first \sphinxcode{\sphinxupquote{move=\textgreater{} *}} adds only \sphinxcode{\sphinxupquote{\_a\_ : bool}} and \sphinxcode{\sphinxupquote{\_b\_ : bool}}
to the context; it takes a second \sphinxcode{\sphinxupquote{move=\textgreater{} *}} to add \sphinxcode{\sphinxupquote{\_Hyp\_ : \_a\_ = \_b\_}}.

\item[{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}} \sphinxcode{\sphinxupquote{-\textgreater{}}}}] \leavevmode
(resp. {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}} \sphinxcode{\sphinxupquote{\textless{}-}})
pops the top assumption (which should be a rewritable proposition) into an
anonymous fact, rewrites (resp. rewrites right to left) the goal with this
fact (using the \DUrole{smallcaps}{SSReflect} \sphinxcode{\sphinxupquote{rewrite}} tactic described in section
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:rewriting-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Rewriting}}}}, and honoring the optional occurrence selector), and
finally deletes the anonymous fact from the context.

\item[{\sphinxcode{\sphinxupquote{{[}}} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} * \sphinxcode{\sphinxupquote{\textbar{} … \textbar{}}} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} * \sphinxcode{\sphinxupquote{{]}}}}] \leavevmode
when it is the
very \sphinxstyleemphasis{first} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}} after tactic \sphinxcode{\sphinxupquote{=\textgreater{}}} tactical \sphinxstyleemphasis{and} tactic
is not a move, is a \sphinxstyleemphasis{branching}{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}}. It executes the sequence
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}}\(_i\) on the i-th   subgoal produced by tactic. The
execution of tactic should thus generate exactly m subgoals, unless the
\sphinxcode{\sphinxupquote{{[}…{]}}} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}} comes after an initial \sphinxcode{\sphinxupquote{//}} or \sphinxcode{\sphinxupquote{//=}}
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{s\_item}}}}} that closes some of the goals produced by \sphinxcode{\sphinxupquote{tactic}}, in
which case exactly m subgoals should remain after thes- item, or we have
the trivial branching {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}} {[}{]}, which always does nothing,
regardless of the number of remaining subgoals.

\item[{\sphinxcode{\sphinxupquote{{[}}} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} * \sphinxcode{\sphinxupquote{\textbar{} … \textbar{}}} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} * \sphinxcode{\sphinxupquote{{]}}}}] \leavevmode
when it is \sphinxstyleemphasis{not}
the first {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}} or when tactic is a \sphinxcode{\sphinxupquote{move}}, is a
\sphinxstyleemphasis{destructing} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}}. It starts by destructing the top
variable, using the \DUrole{smallcaps}{SSReflect} \sphinxcode{\sphinxupquote{case}} tactic described in
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:the-defective-tactics-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{The defective tactics}}}}. It then behaves as the corresponding
branching {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}}, executing the
sequence:token:\sphinxtitleref{i\_item}\(_i\)  in the i-th subgoal generated by the
case analysis; unless we have the trivial destructing {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}}
\sphinxcode{\sphinxupquote{{[}{]}}}, the latter should generate exactly m subgoals, i.e., the top
variable should have an inductive type with exactly m constructors %
\begin{footnote}[14]\sphinxAtStartFootnote
More precisely, it should have a quantified inductive type with a
assumptions and m − a constructors.
%
\end{footnote}.
While it is good style to use the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} i * to pop the variables
and assumptions corresponding to each constructor, this is not enforced by
\DUrole{smallcaps}{SSReflect}.

\item[{\sphinxcode{\sphinxupquote{-}}}] \leavevmode
does nothing, but counts as an intro pattern. It can also be used to
force the interpretation of \sphinxcode{\sphinxupquote{{[}}} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} * \sphinxcode{\sphinxupquote{\textbar{} … \textbar{}}}
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} * \sphinxcode{\sphinxupquote{{]}}} as a case analysis like in \sphinxcode{\sphinxupquote{move=\textgreater{} -{[}H1 H2{]}}}. It
can also be used to indicate explicitly the link between a view and a name
like in \sphinxcode{\sphinxupquote{move=\textgreater{} /eqP-H1}}.  Last, it can serve as a separator between
views.  Section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:views-and-reflection-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Views and reflection}}}} %
\begin{footnote}[16]\sphinxAtStartFootnote
The current state of the proof shall be displayed by the Show
Proof command of \DUrole{smallcaps}{Coq} proof mode.
%
\end{footnote} explains in which
respect the tactic \sphinxcode{\sphinxupquote{move=\textgreater{} /v1/v2}} differs from the tactic \sphinxcode{\sphinxupquote{move=\textgreater{}
/v1-/v2}}.

\item[{\sphinxcode{\sphinxupquote{{[}:}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} \sphinxcode{\sphinxupquote{…{]}}}}] \leavevmode
introduces in the context an abstract constant
for each {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}.  Its type has to be fixed later on by using the
\sphinxcode{\sphinxupquote{abstract}} tactic.  Before then the type displayed is \sphinxcode{\sphinxupquote{\textless{}hidden\textgreater{}}}.

\end{description}

Note that \DUrole{smallcaps}{SSReflect} does not support the syntax \sphinxcode{\sphinxupquote{(ipat, …, ipat)}} for
destructing intro-patterns.

Clears are deferred until the end of the intro pattern.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{leb} \PYG{l+m+mi}{0} \PYG{n}{x} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{leb} \PYG{l+m+mi}{0} \PYG{n}{x}\PYG{o}{)} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{o}{(}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{leb} \PYG{n}{y} \PYG{l+m+mi}{2}\PYG{o}{)} \PYG{o}{=} \PYG{n+nb+bp}{true}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{leb} \PYG{l+m+mi}{0} \PYG{n}{x} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{leb} \PYG{l+m+mi}{0} \PYG{n}{x} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{leb} \PYG{n}{y} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n+nb+bp}{true}

\PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{o}{\PYGZob{}}\PYG{n}{x}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n+nb+bp}{true} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{leb} \PYG{n}{y} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n+nb+bp}{true}
\end{sphinxVerbatim}
\end{sphinxadmonition}

If the cleared names are reused in the same intro pattern, a renaming
is performed behind the scenes.

Facts mentioned in a clear switch must be valid names in the proof
context (excluding the section context).

The rules for interpreting branching and destructing {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}} are
motivated by the fact that it would be pointless to have a branching
pattern if tactic is a \sphinxcode{\sphinxupquote{move}}, and in most of the remaining cases
tactic is \sphinxcode{\sphinxupquote{case}} or \sphinxcode{\sphinxupquote{elim}}, which implies destruction.
The rules above imply that:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{move=\textgreater{} {[}a b{]}.}}

\item {} 
\sphinxcode{\sphinxupquote{case=\textgreater{} {[}a b{]}.}}

\item {} 
\sphinxcode{\sphinxupquote{case=\textgreater{} a b.}}

\end{itemize}

are all equivalent, so which one to use is a matter of style; \sphinxcode{\sphinxupquote{move}} should
be used for casual decomposition, such as splitting a pair, and \sphinxcode{\sphinxupquote{case}}
should be used for actual decompositions, in particular for type families
(see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:type-families-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Type families}}}}) and proof by contradiction.

The trivial branching {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}} can be used to force the branching
interpretation, e.g.:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{case=\textgreater{} {[}{]} {[}a b{]} c.}}

\item {} 
\sphinxcode{\sphinxupquote{move=\textgreater{} {[}{[}a b{]} c{]}.}}

\item {} 
\sphinxcode{\sphinxupquote{case; case=\textgreater{} a b c.}}

\end{itemize}

are all equivalent.


\subsubsection{Generation of equations}
\label{\detokenize{proof-engine/ssreflect-proof-language:generation-of-equations}}\label{\detokenize{proof-engine/ssreflect-proof-language:generation-of-equations-ssr}}
The generation of named equations option stores the definition of a
new constant as an equation. The tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{move} \PYG{n}{En}\PYG{o}{:} \PYG{o}{(}\PYG{n}{size} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{n}\PYG{o}{.}
\end{sphinxVerbatim}

where \sphinxcode{\sphinxupquote{l}} is a list, replaces \sphinxcode{\sphinxupquote{size l}} by \sphinxcode{\sphinxupquote{n}} in the goal and
adds the fact \sphinxcode{\sphinxupquote{En : size l = n}} to the context.
This is quite different from:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{pose} \PYG{n}{n} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{size} \PYG{n}{l}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

which generates a definition \sphinxcode{\sphinxupquote{n := (size l)}}. It is not possible to
generalize or rewrite such a definition; on the other hand, it is
automatically expanded during computation, whereas expanding the
equation \sphinxcode{\sphinxupquote{En}} requires explicit rewriting.

The use of this equation name generation option with a \sphinxcode{\sphinxupquote{case}} or an
\sphinxcode{\sphinxupquote{elim}} tactic changes the status of the first {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}}, in order to
deal with the possible parameters of the constants introduced.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{a} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{b}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{a} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{b}

\PYG{k}{case} \PYG{n}{E} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=\PYGZgt{}} \PYG{o}{[\textbar{}}\PYG{n}{n}\PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{E} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{b}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{S} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{b}
\end{sphinxVerbatim}
\end{sphinxadmonition}

If the user does not provide a branching {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} as first
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}}, or if the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} does not provide enough names for
the arguments of a constructor, then the constants generated are introduced
under fresh \DUrole{smallcaps}{SSReflect} names.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{a} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{b}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{a} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{b}

\PYG{k}{case} \PYG{n}{E} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=\PYGZgt{}} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{E} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{n}{H} \PYG{o}{:} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{b}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{False}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{False}

\PYG{k+kn}{Show} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{,} \PYG{o}{\PYGZus{}}\PYG{n}{n\PYGZus{}} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{E} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{S} \PYG{o}{\PYGZus{}}\PYG{n}{n\PYGZus{}}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{S} \PYG{o}{\PYGZus{}}\PYG{n}{n\PYGZus{}} \PYG{o}{=} \PYG{n}{b}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{False}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Combining the generation of named equations mechanism with thecase
tactic strengthens the power of a case analysis. On the other hand,
when combined with the elim tactic, this feature is mostly useful for
debug purposes, to trace the values of decomposed parameters and
pinpoint failing branches.


\subsubsection{Type families}
\label{\detokenize{proof-engine/ssreflect-proof-language:type-families}}\label{\detokenize{proof-engine/ssreflect-proof-language:type-families-ssr}}
When the top assumption of a goal has an inductive type, two specific
operations are possible: the case analysis performed by the \sphinxcode{\sphinxupquote{case}}
tactic, and the application of an induction principle, performed by
the \sphinxcode{\sphinxupquote{elim}} tactic. When this top assumption has an inductive type, which
is moreover an instance of a type family, \DUrole{smallcaps}{Coq} may need help from the
user to specify which occurrences of the parameters of the type should
be substituted.

A specific \sphinxcode{\sphinxupquote{/}} switch indicates the type family parameters of the type
of a {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}} immediately following this \sphinxcode{\sphinxupquote{/}} switch,
using the syntax:
\index{case (ssreflect) (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacv.case-ssreflect}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{case:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\DUrole{hole}{d\_item}}}}}\DUrole{notation-sup}{+}}~/~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\DUrole{hole}{d\_item}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{elim:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\DUrole{hole}{d\_item}}}}}\DUrole{notation-sup}{+}}~/~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\DUrole{hole}{d\_item}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}


The {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}} on the right side of the \sphinxcode{\sphinxupquote{/}} switch are discharged as
described in section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Discharge}}}}. The case analysis or elimination
will be done on the type of the top assumption after these discharge
operations.

Every {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}} preceding the \sphinxcode{\sphinxupquote{/}} is interpreted as arguments of this
type, which should be an instance of an inductive type family. These terms
are not actually generalized, but rather selected for substitution.
Occurrence switches can be used to restrict the substitution. If a term is
left completely implicit (e.g. writing just \sphinxcode{\sphinxupquote{\_}}), then a pattern is
inferred looking at the type of the top assumption. This allows for the
compact syntax:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{case}\PYG{o}{:} \PYG{o}{\PYGZob{}}\PYG{l+m+mi}{2}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZus{}} \PYG{o}{/} \PYG{n}{eqP}\PYG{o}{.}
\end{sphinxVerbatim}

where \sphinxcode{\sphinxupquote{\_}} is interpreted as \sphinxcode{\sphinxupquote{(\_ == \_)}} since
\sphinxcode{\sphinxupquote{eqP T a b : reflect (a = b) (a == b)}} and reflect is a type family with
one index.

Moreover if the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}} list is too short, it is padded with an
initial sequence of \sphinxcode{\sphinxupquote{\_}} of the right length.

\begin{sphinxadmonition}{note}{Example}

Here is a small example on lists. We define first a function which
adds an element at the end of a given list.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{List}\PYG{o}{.}
\PYG{k+kn}{Section} \PYG{n}{LastCases}\PYG{o}{.}
\PYG{k+kn}{Variable} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{.}
    \PYG{n}{A} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Implicit} \PYG{k+kt}{Type} \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{.}
\PYG{k+kn}{Fixpoint} \PYG{n}{add\PYGZus{}last} \PYG{n}{a} \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{n}{a} \PYG{o}{::} \PYG{n}{nil}
  \PYG{o}{\textbar{}} \PYG{n}{hd} \PYG{o}{::} \PYG{n}{tl} \PYG{o}{=\PYGZgt{}} \PYG{n}{hd} \PYG{o}{::} \PYG{o}{(}\PYG{n}{add\PYGZus{}last} \PYG{n}{a} \PYG{n}{tl}\PYG{o}{)} \PYG{k}{end}\PYG{o}{.}
    \PYG{n}{add\PYGZus{}last} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{add\PYGZus{}last} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{2}\PYG{n}{nd} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}

Then we define an inductive predicate for case analysis on lists
according to their last element:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{last\PYGZus{}spec} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{LastSeq0} \PYG{o}{:} \PYG{n}{last\PYGZus{}spec} \PYG{n}{nil}
\PYG{o}{\textbar{}} \PYG{n}{LastAdd} \PYG{n}{s} \PYG{n}{x} \PYG{o}{:} \PYG{n}{last\PYGZus{}spec} \PYG{o}{(}\PYG{n}{add\PYGZus{}last} \PYG{n}{x} \PYG{n}{s}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{last\PYGZus{}spec} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{last\PYGZus{}spec\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{last\PYGZus{}spec\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{last\PYGZus{}spec\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Theorem} \PYG{n}{lastP} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{,} \PYG{n}{last\PYGZus{}spec} \PYG{n}{l}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{,} \PYG{n}{last\PYGZus{}spec} \PYG{n}{l}

\PYG{n}{Admitted}\PYG{o}{.}
    \PYG{n}{lastP} \PYG{k}{is} \PYG{n}{declared}
\end{sphinxVerbatim}

We are now ready to use \sphinxcode{\sphinxupquote{lastP}} in conjunction with \sphinxcode{\sphinxupquote{case}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{l} \PYG{o}{:} \PYG{o}{(}\PYG{n}{length} \PYG{n}{l}\PYG{o}{)} \PYG{o}{*} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{length} \PYG{o}{(}\PYG{n}{l} \PYG{o}{+}\PYG{o}{+} \PYG{n}{l}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{length} \PYG{n}{l} \PYG{o}{*} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{length} \PYG{o}{(}\PYG{n}{l} \PYG{o}{+}\PYG{o}{+} \PYG{n}{l}\PYG{o}{)}

\PYG{k}{case}\PYG{o}{:} \PYG{o}{(}\PYG{n}{lastP} \PYG{n}{l}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{length} \PYG{n}{nil} \PYG{o}{*} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{length} \PYG{o}{(}\PYG{n}{nil} \PYG{o}{+}\PYG{o}{+} \PYG{n}{nil}\PYG{o}{)}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{k}{forall} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)}\PYG{o}{,}
     \PYG{n}{length} \PYG{o}{(}\PYG{n}{add\PYGZus{}last} \PYG{n}{x} \PYG{n}{s}\PYG{o}{)} \PYG{o}{*} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{length} \PYG{o}{(}\PYG{n}{add\PYGZus{}last} \PYG{n}{x} \PYG{n}{s} \PYG{o}{+}\PYG{o}{+} \PYG{n}{add\PYGZus{}last} \PYG{n}{x} \PYG{n}{s}\PYG{o}{)}
\end{sphinxVerbatim}

Applied to the same goal, the command:
\sphinxcode{\sphinxupquote{case: l / (lastP l).}}
generates the same subgoals but \sphinxcode{\sphinxupquote{l}} has been cleared from both contexts.

Again applied to the same goal, the command.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{l} \PYG{o}{:} \PYG{o}{(}\PYG{n}{length} \PYG{n}{l}\PYG{o}{)} \PYG{o}{*} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{length} \PYG{o}{(}\PYG{n}{l} \PYG{o}{+}\PYG{o}{+} \PYG{n}{l}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{length} \PYG{n}{l} \PYG{o}{*} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{length} \PYG{o}{(}\PYG{n}{l} \PYG{o}{+}\PYG{o}{+} \PYG{n}{l}\PYG{o}{)}

\PYG{k}{case}\PYG{o}{:} \PYG{o}{\PYGZob{}}\PYG{l+m+mi}{1} \PYG{l+m+mi}{3}\PYG{o}{\PYGZcb{}}\PYG{n}{l} \PYG{o}{/} \PYG{o}{(}\PYG{n}{lastP} \PYG{n}{l}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{length} \PYG{n}{nil} \PYG{o}{*} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{length} \PYG{o}{(}\PYG{n}{l} \PYG{o}{+}\PYG{o}{+} \PYG{n}{nil}\PYG{o}{)}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{k}{forall} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)}\PYG{o}{,}
     \PYG{n}{length} \PYG{o}{(}\PYG{n}{add\PYGZus{}last} \PYG{n}{x} \PYG{n}{s}\PYG{o}{)} \PYG{o}{*} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{length} \PYG{o}{(}\PYG{n}{l} \PYG{o}{+}\PYG{o}{+} \PYG{n}{add\PYGZus{}last} \PYG{n}{x} \PYG{n}{s}\PYG{o}{)}
\end{sphinxVerbatim}

Note that selected occurrences on the left of the \sphinxcode{\sphinxupquote{/}}
switch have been substituted with l instead of being affected by
the case analysis.
\end{sphinxadmonition}

The equation name generation feature combined with a type family /
switch generates an equation for the \sphinxstyleemphasis{first} dependent {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}}
specified by the user. Again starting with the above goal, the
command:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{l} \PYG{o}{:} \PYG{o}{(}\PYG{n}{length} \PYG{n}{l}\PYG{o}{)} \PYG{o}{*} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{length} \PYG{o}{(}\PYG{n}{l} \PYG{o}{+}\PYG{o}{+} \PYG{n}{l}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{length} \PYG{n}{l} \PYG{o}{*} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{length} \PYG{o}{(}\PYG{n}{l} \PYG{o}{+}\PYG{o}{+} \PYG{n}{l}\PYG{o}{)}

\PYG{k}{case} \PYG{n}{E}\PYG{o}{:} \PYG{o}{\PYGZob{}}\PYG{l+m+mi}{1} \PYG{l+m+mi}{3}\PYG{o}{\PYGZcb{}}\PYG{n}{l} \PYG{o}{/} \PYG{o}{(}\PYG{n}{lastP} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{o}{[\textbar{}}\PYG{n}{s} \PYG{n}{x}\PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}
      \PYG{n}{E} \PYG{o}{:} \PYG{n}{l} \PYG{o}{=} \PYG{n}{nil}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{length} \PYG{n}{nil} \PYG{o}{*} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{length} \PYG{o}{(}\PYG{n}{l} \PYG{o}{+}\PYG{o}{+} \PYG{n}{nil}\PYG{o}{)}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{length} \PYG{o}{(}\PYG{n}{add\PYGZus{}last} \PYG{n}{x} \PYG{n}{s}\PYG{o}{)} \PYG{o}{*} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{length} \PYG{o}{(}\PYG{n}{l} \PYG{o}{+}\PYG{o}{+} \PYG{n}{add\PYGZus{}last} \PYG{n}{x} \PYG{n}{s}\PYG{o}{)}

\PYG{k+kn}{Show} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{l}\PYG{o}{,} \PYG{n}{s} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{E} \PYG{o}{:} \PYG{n}{l} \PYG{o}{=} \PYG{n}{add\PYGZus{}last} \PYG{n}{x} \PYG{n}{s}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{length} \PYG{o}{(}\PYG{n}{add\PYGZus{}last} \PYG{n}{x} \PYG{n}{s}\PYG{o}{)} \PYG{o}{*} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{length} \PYG{o}{(}\PYG{n}{l} \PYG{o}{+}\PYG{o}{+} \PYG{n}{add\PYGZus{}last} \PYG{n}{x} \PYG{n}{s}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

There must be at least one {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}} to the left of the / switch; this
prevents any confusion with the view feature. However, the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}}
to the right of the \sphinxcode{\sphinxupquote{/}} are optional, and if they are omitted the first
assumption provides the instance of the type family.

The equation always refers to the first {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{d\_item}}}}} in the actual tactic
call, before any padding with initial \sphinxcode{\sphinxupquote{\_}}. Thus, if an inductive type
has two family parameters, it is possible to have\textbar{}SSR\textbar{} generate an
equation for the second one by omitting the pattern for the first;
note however that this will fail if the type of the second parameter
depends on the value of the first parameter.


\subsection{Control flow}
\label{\detokenize{proof-engine/ssreflect-proof-language:control-flow}}

\subsubsection{Indentation and bullets}
\label{\detokenize{proof-engine/ssreflect-proof-language:indentation-and-bullets}}\label{\detokenize{proof-engine/ssreflect-proof-language:indentation-ssr}}
A linear development of \DUrole{smallcaps}{Coq} scripts gives little information on the
structure of the proof. In addition, replaying a proof after some
changes in the statement to be proved will usually not display
information to distinguish between the various branches of case
analysis for instance.

To help the user in this organization of the proof script at development
time, \DUrole{smallcaps}{SSReflect} provides some bullets to highlight the structure of branching
proofs. The available bullets are \sphinxcode{\sphinxupquote{-}}, \sphinxcode{\sphinxupquote{+}} and \sphinxcode{\sphinxupquote{*}}.  Combined with
tabulation, this lets us highlight four nested levels of branching; the most
we have ever needed is three. Indeed, the use of “simpl and closing”
switches, of terminators (see above section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:terminators-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Terminators}}}}) and
selectors (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:selectors-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Selectors}}}}) is powerful enough to avoid most
of the time more than two levels of indentation.

Here is a fragment of such a structured script:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
case E1: (abezoutn \PYGZus{} \PYGZus{}) =\PYGZgt{} [[\textbar{} k1] [\textbar{} k2]].
\PYGZhy{} rewrite !muln0 !gexpn0 mulg1 =\PYGZgt{} H1.
  move/eqP: (sym\PYGZus{}equal F0); rewrite \PYGZhy{}H1 orderg1 eqn\PYGZus{}mul1.
  by case/andP; move/eqP.
\PYGZhy{} rewrite muln0 gexpn0 mulg1 =\PYGZgt{} H1.
  have F1: t \PYGZpc{}\textbar{} t * S k2.+1 \PYGZhy{} 1.
    apply: (@dvdn\PYGZus{}trans (orderg x)); first by rewrite F0; exact: dvdn\PYGZus{}mull.
    rewrite orderg\PYGZus{}dvd; apply/eqP; apply: (mulgI x).
    rewrite \PYGZhy{}\PYGZob{}1\PYGZcb{}(gexpn1 x) mulg1 gexpn\PYGZus{}add leq\PYGZus{}add\PYGZus{}sub //.
    by move: P1; case t.
  rewrite dvdn\PYGZus{}subr in F1; last by exact: dvdn\PYGZus{}mulr.
  + rewrite H1 F0 \PYGZhy{}\PYGZob{}2\PYGZcb{}(muln1 (p \PYGZca{} l)); congr (\PYGZus{} * \PYGZus{}).
    by apply/eqP; rewrite \PYGZhy{}dvdn1.
  + by move: P1; case: (t) =\PYGZgt{} [\textbar{} [\textbar{} s1]].
\PYGZhy{} rewrite muln0 gexpn0 mul1g =\PYGZgt{} H1.
...
\end{sphinxVerbatim}


\subsubsection{Terminators}
\label{\detokenize{proof-engine/ssreflect-proof-language:terminators}}\label{\detokenize{proof-engine/ssreflect-proof-language:terminators-ssr}}
To further structure scripts, \DUrole{smallcaps}{SSReflect} supplies \sphinxstyleemphasis{terminating}
tacticals to explicitly close off tactics. When replaying scripts, we
then have the nice property that an error immediately occurs when a
closed tactic fails to prove its subgoal.

It is hence recommended practice that the proof of any subgoal should
end with a tactic which \sphinxstyleemphasis{fails if it does not solve the current goal},
like discriminate, contradiction or assumption.

In fact, \DUrole{smallcaps}{SSReflect} provides a generic tactical which turns any tactic
into a closing one (similar to now). Its general syntax is:
\index{by (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.by}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{by~\DUrole{hole}{tactic}}}}}
\end{fulllineitems}


The Ltac expression \sphinxcode{\sphinxupquote{\DUrole{notation}{by {[}\DUrole{hole}{tactic} \textbar{} {[}\DUrole{hole}{tactic} \textbar{} …{]}}}} is equivalent to
\sphinxcode{\sphinxupquote{\DUrole{notation}{{[}by \DUrole{hole}{tactic} \textbar{} by \DUrole{hole}{tactic} \textbar{} ...{]}}}} and this form should be preferred
to the former.

In the script provided as example in section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:indentation-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Indentation and bullets}}}}, the
paragraph corresponding to each sub-case ends with a tactic line prefixed
with a \sphinxcode{\sphinxupquote{by}}, like in:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{by} \PYG{k}{apply}\PYG{o}{/}\PYG{n}{eqP}\PYG{o}{;} \PYG{k}{rewrite} \PYG{o}{\PYGZhy{}}\PYG{n}{dvdn1}\PYG{o}{.}
\end{sphinxVerbatim}
\index{done (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.done}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{done}}}}
\end{fulllineitems}


The {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.by}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{by}}}}} tactical is implemented using the user-defined, and extensible
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.done}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{done}}}}} tactic. This {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.done}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{done}}}}} tactic tries to solve the current goal by some
trivial means and fails if it doesn’t succeed. Indeed, the tactic
expression \sphinxcode{\sphinxupquote{\DUrole{notation}{by \DUrole{hole}{tactic}}}} is equivalent to \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic}; done}}}.

Conversely, the tactic

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{by} \PYG{o}{[} \PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

is equivalent to:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{done}\PYG{o}{.}
\end{sphinxVerbatim}

The default implementation of the done tactic, in the \sphinxcode{\sphinxupquote{ssreflect.v}}
file, is:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{k+kp}{done} \PYG{o}{:=}
  \PYG{k}{trivial}\PYG{o}{;} \PYG{k}{hnf}\PYG{o}{;} \PYG{k}{intros}\PYG{o}{;} \PYG{k+kp}{solve}
   \PYG{o}{[} \PYG{k+kr}{do} \PYG{o}{!}\PYG{o}{[}\PYG{k+kp}{solve} \PYG{o}{[}\PYG{k}{trivial} \PYG{o}{\textbar{}} \PYG{k}{apply}\PYG{o}{:} \PYG{n}{sym\PYGZus{}equal}\PYG{o}{;} \PYG{k}{trivial}\PYG{o}{]}
         \PYG{o}{\textbar{}} \PYG{k+kp}{discriminate} \PYG{o}{\textbar{}} \PYG{k+kp}{contradiction} \PYG{o}{\textbar{}} \PYG{k}{split}\PYG{o}{]}
   \PYG{o}{\textbar{}} \PYG{k}{case} \PYG{n}{not\PYGZus{}locked\PYGZus{}false\PYGZus{}eq\PYGZus{}true}\PYG{o}{;} \PYG{k+kp}{assumption}
   \PYG{o}{\textbar{}} \PYG{k}{match} \PYG{n}{goal} \PYG{k}{with} \PYG{n}{H} \PYG{o}{:} \PYG{o}{\PYGZti{}} \PYG{o}{\PYGZus{}} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{k+kp}{solve} \PYG{o}{[}\PYG{k}{case} \PYG{n}{H}\PYG{o}{;} \PYG{k}{trivial}\PYG{o}{]} \PYG{k}{end} \PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

The lemma \sphinxcode{\sphinxupquote{not\_locked\_false\_eq\_true}} is needed to discriminate
\sphinxstyleemphasis{locked} boolean predicates (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:locking-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Locking, unlocking}}}}). The iterator
tactical do is presented in section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:iteration-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Iteration}}}}. This tactic can be
customized by the user, for instance to include an \sphinxcode{\sphinxupquote{auto}} tactic.

A natural and common way of closing a goal is to apply a lemma which
is the exact one needed for the goal to be solved. The defective form
of the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{exact}\PYG{o}{.}
\end{sphinxVerbatim}

is equivalent to:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kr}{do} \PYG{o}{[}\PYG{k+kp}{done} \PYG{o}{\textbar{}} \PYG{k+kp}{by} \PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{n}{top}\PYG{o}{;} \PYG{k}{apply} \PYG{n}{top}\PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

where \sphinxcode{\sphinxupquote{top}} is a fresh name assigned to the top assumption of the goal.
This applied form is supported by the : discharge tactical, and the
tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{exact}\PYG{o}{:} \PYG{n}{MyLemma}\PYG{o}{.}
\end{sphinxVerbatim}

is equivalent to:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{by} \PYG{k}{apply}\PYG{o}{:} \PYG{n}{MyLemma}\PYG{o}{.}
\end{sphinxVerbatim}

(see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Discharge}}}} for the documentation of the apply: combination).

\begin{sphinxadmonition}{warning}{Warning:}
The list of tactics (possibly chained by semicolons) that
follows the \sphinxcode{\sphinxupquote{by}} keyword is considered to be a parenthesized block applied to
the current goal. Hence for example if the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{by} \PYG{k}{rewrite} \PYG{n}{my\PYGZus{}lemma1}\PYG{o}{.}
\end{sphinxVerbatim}

succeeds, then the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{by} \PYG{k}{rewrite} \PYG{n}{my\PYGZus{}lemma1}\PYG{o}{;} \PYG{k}{apply} \PYG{n}{my\PYGZus{}lemma2}\PYG{o}{.}
\end{sphinxVerbatim}

usually fails since it is equivalent to:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kp}{by} \PYG{o}{(}\PYG{k}{rewrite} \PYG{n}{my\PYGZus{}lemma1}\PYG{o}{;} \PYG{k}{apply} \PYG{n}{my\PYGZus{}lemma2}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Selectors}
\label{\detokenize{proof-engine/ssreflect-proof-language:selectors}}\label{\detokenize{proof-engine/ssreflect-proof-language:selectors-ssr}}
When composing tactics, the two tacticals \sphinxcode{\sphinxupquote{first}} and \sphinxcode{\sphinxupquote{last}} let the user
restrict the application of a tactic to only one of the subgoals
generated by the previous tactic. This covers the frequent cases where
a tactic generates two subgoals one of which can be easily disposed
of.

This is another powerful way of linearization of scripts, since it
happens very often that a trivial subgoal can be solved in a less than
one line tactic. For instance, the tactic:
\index{last (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.last}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic}~;~last~by~\DUrole{hole}{tactic}}}}}
\end{fulllineitems}


tries to solve the last subgoal generated by the first
tactic using the given second tactic, and fails if it does not succeed.
Its analogue
\index{first (ssreflect) (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.first-ssreflect}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic}~;~first~by~\DUrole{hole}{tactic}}}}}
\end{fulllineitems}


tries to solve the first subgoal generated by the first tactic using the
second given tactic, and fails if it does not succeed.

\DUrole{smallcaps}{SSReflect} also offers an extension of this facility, by supplying
tactics to \sphinxstyleemphasis{permute} the subgoals generated by a tactic. The tactic:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic};~last~first}}}}
\end{fulllineitems}


inverts the order of the subgoals generated by tactic. It is
equivalent to:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic};~first~last}}}}
\end{fulllineitems}


More generally, the tactic:
\index{last first (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.last-first}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic};~last~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~first}}}}
\end{fulllineitems}


where {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}} is a \DUrole{smallcaps}{Coq} numeral, or an Ltac variable
denoting a \DUrole{smallcaps}{Coq}
numeral, having the value k. It rotates the n subgoals G1 , …, Gn
generated by tactic. The first subgoal becomes Gn + 1 − k and the
circular order of subgoals remains unchanged.

Conversely, the tactic:
\index{first last (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.first-last}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic};~first~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~last}}}}
\end{fulllineitems}


rotates the n subgoals G1 , …, Gn generated by tactic in order that
the first subgoal becomes Gk .

Finally, the tactics \sphinxcode{\sphinxupquote{last}} and \sphinxcode{\sphinxupquote{first}} combine with the branching syntax
of Ltac: if the tactic generates n subgoals on a given goal,
then the tactic

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
tactic ; last k [ tactic1 \textbar{}…\textbar{} tacticm ] \textbar{}\textbar{} tacticn.
\end{sphinxVerbatim}

where natural denotes the integer k as above, applies tactic1 to the n
−k + 1-th goal, … tacticm to the n −k + 2 − m-th goal and tactic n
to the others.

\begin{sphinxadmonition}{note}{Example}

Here is a small example on lists. We define first a function which
adds an element at the end of a given list.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{test} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{C1} \PYG{n}{n} \PYG{k}{of} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{1} \PYG{o}{:} \PYG{n}{test} \PYG{n}{n}
\PYG{o}{\textbar{}} \PYG{n}{C2} \PYG{n}{n} \PYG{k}{of} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{2} \PYG{o}{:} \PYG{n}{test} \PYG{n}{n}
\PYG{o}{\textbar{}} \PYG{n}{C3} \PYG{n}{n} \PYG{k}{of} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{3} \PYG{o}{:} \PYG{n}{test} \PYG{n}{n}
\PYG{o}{\textbar{}} \PYG{n}{C4} \PYG{n}{n} \PYG{k}{of} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{4} \PYG{o}{:} \PYG{n}{test} \PYG{n}{n}\PYG{o}{.}
    \PYG{n}{test} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{test\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Lemma} \PYG{n}{example} \PYG{n}{n} \PYG{o}{(}\PYG{n}{t} \PYG{o}{:} \PYG{n}{test} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{t} \PYG{o}{:} \PYG{n}{test} \PYG{n}{n}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k}{case}\PYG{o}{:} \PYG{n}{t}\PYG{o}{;} \PYG{k+kr}{last} \PYG{l+m+mi}{2} \PYG{o}{[}\PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{n}{k}\PYG{o}{\textbar{}} \PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{n}{l}\PYG{o}{]}\PYG{o}{;} \PYG{k+kr}{idtac}\PYG{o}{.}
    \PYG{l+m+mi}{4} \PYG{n}{subgoals}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{n0} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n0} \PYG{o}{=} \PYG{l+m+mi}{1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{k} \PYG{o}{=} \PYG{l+m+mi}{2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{l} \PYG{o}{=} \PYG{l+m+mi}{3} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
    \PYG{n}{subgoal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{k}{forall} \PYG{n}{n0} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n0} \PYG{o}{=} \PYG{l+m+mi}{4} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Iteration}
\label{\detokenize{proof-engine/ssreflect-proof-language:iteration}}\label{\detokenize{proof-engine/ssreflect-proof-language:iteration-ssr}}
\DUrole{smallcaps}{SSReflect} offers an accurate control on the repetition of tactics,
thanks to the do tactical, whose general syntax is:
\index{do (ssreflect) (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.do-ssreflect}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{do~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult}]{\sphinxcrossref{\DUrole{hole}{mult}}}}}\DUrole{notation-sup}{?}}~(~\DUrole{hole}{tactic}~\textbar{}~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{tactic}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textbar{}}}~{]}~)}}}}
\end{fulllineitems}


where {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{mult}}}}} is a \sphinxstyleemphasis{multiplier}.

Brackets can only be omitted if a single tactic is given \sphinxstyleemphasis{and} a
multiplier is present.

A tactic of the form:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
do [ tactic 1 \textbar{} … \textbar{} tactic n ].
\end{sphinxVerbatim}

is equivalent to the standard Ltac expression:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
first [ tactic 1 \textbar{} … \textbar{} tactic n ].
\end{sphinxVerbatim}

The optional multiplier {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{mult}}}}} specifies how many times the action of
tactic should be repeated on the current subgoal.

There are four kinds of multipliers:


\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{mult~::=~}}\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~!~\DUrole{meta}{\textbar{}}~!~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~?~\DUrole{meta}{\textbar{}}~?}}}}
\end{fulllineitems}


Their meaning is:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{n!}} the step tactic is repeated exactly n times (where n is a
positive integer argument).

\item {} 
\sphinxcode{\sphinxupquote{!}} the step tactic is repeated as many times as possible, and done
at least once.

\item {} 
\sphinxcode{\sphinxupquote{?}} the step tactic is repeated as many times as possible,
optionally.

\item {} 
\sphinxcode{\sphinxupquote{n?}} the step tactic is repeated up to n times, optionally.

\end{itemize}

For instance, the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{tactic}\PYG{o}{;} \PYG{k+kr}{do} \PYG{l+m+mi}{1}\PYG{o}{?} \PYG{k}{rewrite} \PYG{n}{mult\PYGZus{}comm}\PYG{o}{.}
\end{sphinxVerbatim}

rewrites at most one time the lemma \sphinxcode{\sphinxupquote{mult\_comm}} in all the subgoals
generated by tactic , whereas the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{tactic}\PYG{o}{;} \PYG{k+kr}{do} \PYG{l+m+mi}{2}\PYG{o}{!} \PYG{k}{rewrite} \PYG{n}{mult\PYGZus{}comm}\PYG{o}{.}
\end{sphinxVerbatim}

rewrites exactly two times the lemma \sphinxcode{\sphinxupquote{mult\_comm}} in all the subgoals
generated by tactic, and fails if this rewrite is not possible in some
subgoal.

Note that the combination of multipliers and rewrite is so often used
that multipliers are in fact integrated to the syntax of the
\DUrole{smallcaps}{SSReflect} rewrite tactic, see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:rewriting-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Rewriting}}}}.


\subsubsection{Localization}
\label{\detokenize{proof-engine/ssreflect-proof-language:localization}}\label{\detokenize{proof-engine/ssreflect-proof-language:localization-ssr}}
In sections {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:basic-localization-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Basic localization}}}} and {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:bookkeeping-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Bookkeeping}}}}, we have
already presented the \sphinxstyleemphasis{localization} tactical in, whose general syntax is:
\index{in (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.in}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{*}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


where {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is a name in the
context. On the left side of \sphinxcode{\sphinxupquote{in}},
\sphinxcode{\sphinxupquote{tactic}} can be \sphinxcode{\sphinxupquote{move}}, \sphinxcode{\sphinxupquote{case}}, \sphinxcode{\sphinxupquote{elim}}, \sphinxcode{\sphinxupquote{rewrite}}, \sphinxcode{\sphinxupquote{set}},
or any tactic formed with the general iteration tactical \sphinxcode{\sphinxupquote{do}} (see section
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:iteration-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Iteration}}}}).

The operation described by tactic is performed in the facts listed after
\sphinxcode{\sphinxupquote{in}} and in the goal if a \sphinxcode{\sphinxupquote{*}} ends the list of names.

The \sphinxcode{\sphinxupquote{in}} tactical successively:
\begin{itemize}
\item {} 
generalizes the selected hypotheses, possibly “protecting” the goal
if \sphinxcode{\sphinxupquote{*}} is not present,

\item {} 
performs \sphinxcode{\sphinxupquote{tactic}}, on the obtained goal,

\item {} 
reintroduces the generalized facts, under the same names.

\end{itemize}

This defective form of the \sphinxcode{\sphinxupquote{do}} tactical is useful to avoid clashes
between standard Ltac in and the \DUrole{smallcaps}{SSReflect} tactical in.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Ltac} \PYG{n}{mytac} \PYG{n}{H} \PYG{o}{:=} \PYG{k}{rewrite} \PYG{n}{H}\PYG{o}{.}
    \PYG{n}{mytac} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{y} \PYG{o}{(}\PYG{n}{H1} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{n}{H2} \PYG{o}{:} \PYG{n}{y} \PYG{o}{=} \PYG{l+m+mi}{3}\PYG{o}{)} \PYG{o}{:} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{l+m+mi}{6}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H1} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}
      \PYG{n}{H2} \PYG{o}{:} \PYG{n}{y} \PYG{o}{=} \PYG{l+m+mi}{3}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{l+m+mi}{6}

\PYG{k+kr}{do} \PYG{o}{[}\PYG{n}{mytac} \PYG{n}{H2}\PYG{o}{]} \PYG{k}{in} \PYG{n}{H1} \PYG{o}{*}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H2} \PYG{o}{:} \PYG{n}{y} \PYG{o}{=} \PYG{l+m+mi}{3}
      \PYG{n}{H1} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{3}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{3} \PYG{o}{=} \PYG{l+m+mi}{6}
\end{sphinxVerbatim}

the last tactic rewrites the hypothesis \sphinxcode{\sphinxupquote{H2 : y = 3}} both in
\sphinxcode{\sphinxupquote{H1 : x = y}} and in the goal \sphinxcode{\sphinxupquote{x + y = 6}}.
\end{sphinxadmonition}

By default \sphinxcode{\sphinxupquote{in}} keeps the body of local definitions. To erase the body
of a local definition during the generalization phase, the name of the
local definition must be written between parentheses, like in
\sphinxcode{\sphinxupquote{rewrite H in H1 (def\_n) H2.}}

From \DUrole{smallcaps}{SSReflect} 1.5 the grammar for the in tactical has been extended
to the following one:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{tactic}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}~\textbar{}~\DUrole{repeat-wrapper}{\DUrole{repeat}{@}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\textbar{}~(~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~)~\textbar{}~(~\DUrole{repeat-wrapper}{\DUrole{repeat}{@}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\DUrole{hole}{c\_pattern}}}}~)}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{*}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


In its simplest form the last option lets one rename hypotheses that
can’t be cleared (like section variables). For example, \sphinxcode{\sphinxupquote{(y := x)}}
generalizes over \sphinxcode{\sphinxupquote{x}} and reintroduces the generalized variable under the
name \sphinxcode{\sphinxupquote{y}} (and does not clear \sphinxcode{\sphinxupquote{x}}).
For a more precise description of this form of localization refer
to {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:advanced-generalization-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Advanced generalization}}}}.


\subsubsection{Structure}
\label{\detokenize{proof-engine/ssreflect-proof-language:structure}}\label{\detokenize{proof-engine/ssreflect-proof-language:structure-ssr}}
Forward reasoning structures the script by explicitly specifying some
assumptions to be added to the proof context. It is closely associated
with the declarative style of proof, since an extensive use of these
highlighted statements make the script closer to a (very detailed)
textbook proof.

Forward chaining tactics allow to state an intermediate lemma and start a
piece of script dedicated to the proof of this statement. The use of closing
tactics (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:terminators-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Terminators}}}}) and of indentation makes
syntactically explicit the portion of the script building the proof of the
intermediate statement.


\paragraph{The have tactic.}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-have-tactic}}
The main \DUrole{smallcaps}{SSReflect} forward reasoning tactic is the \sphinxcode{\sphinxupquote{have}} tactic. It can
be use in two modes: one starts a new (sub)proof for an intermediate
result in the main proof, and the other provides explicitly a proof
term for this intermediate step.

In the first mode, the syntax of have in its defective form is:
\index{have (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.have}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{have~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


This tactic supports open syntax for {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. Applied to a goal \sphinxcode{\sphinxupquote{G}}, it
generates a first subgoal requiring a proof of \sphinxcode{\sphinxupquote{term}} in the context of
\sphinxcode{\sphinxupquote{G}}. The second generated subgoal is of the form \sphinxcode{\sphinxupquote{term -\textgreater{} G}}, where term
becomes the new top assumption, instead of being introduced with a
fresh name. At the proof-term level, the have tactic creates a \(\beta\)
redex, and introduces the lemma under a fresh name, automatically
chosen.

Like in the case of the \sphinxcode{\sphinxupquote{pose}} tactic (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:definitions-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Definitions}}}}), the types of
the holes are abstracted in term.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k}{have}\PYG{o}{:} \PYG{o}{\PYGZus{}} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
\end{sphinxVerbatim}

The invokation of \sphinxcode{\sphinxupquote{have}} is equivalent to:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{have}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The have tactic also enjoys the same abstraction mechanism as the \sphinxcode{\sphinxupquote{pose}}
tactic for the non-inferred implicit arguments. For instance, the
tactic:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{have}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{o}{(}\PYG{n}{T} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{T}\PYG{o}{)} \PYG{o}{(}\PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)}\PYG{o}{,} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{o}{(}\PYG{k}{forall} \PYG{o}{(}\PYG{n}{T} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{T}\PYG{o}{)} \PYG{o}{(}\PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)}\PYG{o}{,} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
\end{sphinxVerbatim}

opens a new subgoal where the type of \sphinxcode{\sphinxupquote{x}} is quantified.
\end{sphinxadmonition}

The behavior of the defective have tactic makes it possible to
generalize it in the following general construction:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{have~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}\DUrole{notation-sup}{*}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}~\textbar{}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-ssr_binder}]{\sphinxcrossref{\DUrole{hole}{ssr\_binder}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\textbar{}~by~\DUrole{hole}{tactic}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


Open syntax is supported for both {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}. For the description
of {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} and {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{s\_item}}}}} see section
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}. The first mode of the
have tactic, which opens a sub-proof for an intermediate result, uses
tactics of the form:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{have~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~by~\DUrole{hole}{tactic}}}}}
\end{fulllineitems}


which behave like:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{have}\PYG{o}{:} \PYG{n}{term} \PYG{o}{;} \PYG{k+kr}{first} \PYG{k+kp}{by} \PYG{n}{tactic}\PYG{o}{.}
\PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{n}{clear\PYGZus{}switch} \PYG{n}{i\PYGZus{}item}\PYG{o}{.}
\end{sphinxVerbatim}

Note that the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{clear\_switch}}}}} \sphinxstyleemphasis{precedes} the:token:\sphinxtitleref{i\_item}, which
allows to reuse
a name of the context, possibly used by the proof of the assumption,
to introduce the new assumption itself.

The{}`{}`by{}`{}` feature is especially convenient when the proof script of the
statement is very short, basically when it fits in one line like in:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{have} \PYG{n}{H23} \PYG{o}{:} \PYG{l+m+mi}{3} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{l+m+mi}{3} \PYG{k+kp}{by} \PYG{k}{rewrite} \PYG{n}{addnC}\PYG{o}{.}
\end{sphinxVerbatim}

The possibility of using {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} supplies a very concise syntax for
the further use of the intermediate step. For instance,

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{a} \PYG{o}{:} \PYG{l+m+mi}{3} \PYG{o}{*} \PYG{n}{a} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{n}{a}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{3} \PYG{o}{*} \PYG{n}{a} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{n}{a}

\PYG{k}{have} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{n}{x} \PYG{o}{*} \PYG{n}{a} \PYG{o}{=} \PYG{n}{a}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{a} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{*} \PYG{n}{a} \PYG{o}{=} \PYG{n}{a}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{a} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{n}{a}
\end{sphinxVerbatim}

Note how the second goal was rewritten using the stated equality.
Also note that in this last subgoal, the intermediate result does not
appear in the context.
\end{sphinxadmonition}

Thanks to the deferred execution of clears, the following idiom is
also supported (assuming x occurs in the goal only):

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{have} \PYG{o}{\PYGZob{}}\PYG{n}{x}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}\PYG{o}{.}
\end{sphinxVerbatim}

Another frequent use of the intro patterns combined with \sphinxcode{\sphinxupquote{have}} is the
destruction of existential assumptions like in the tactic:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k}{have} \PYG{o}{[}\PYG{n}{x} \PYG{n}{Px}\PYG{o}{]}\PYG{o}{:} \PYG{k}{exists} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{exists} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}

\PYG{n}{Focus} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{7}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{n}{Focus} \PYG{l+m+mi}{2}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Warning}\PYG{o}{:} \PYG{n}{The} \PYG{n}{Focus} \PYG{n}{command} \PYG{k}{is} \PYG{n}{deprecated}\PYG{o}{;} \PYG{n}{use} \PYG{k}{\PYGZsq{}}\PYG{l+m+mi}{2}\PYG{o}{:} \PYG{o}{\PYGZob{}}\PYG{k}{\PYGZsq{}} \PYG{n}{instead}
    \PYG{o}{[}\PYG{n}{deprecated}\PYG{o}{\PYGZhy{}}\PYG{n}{focus}\PYG{o}{,}\PYG{n}{deprecated}\PYG{o}{]}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{Px} \PYG{o}{:} \PYG{n}{x} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
\end{sphinxVerbatim}
\end{sphinxadmonition}

An alternative use of the \sphinxcode{\sphinxupquote{have}} tactic is to provide the explicit proof
term for the intermediate lemma, using tactics of the form:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{have~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~:=~term}}}}
\end{fulllineitems}


This tactic creates a new assumption of type the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.
If the
optional {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is present, this assumption is introduced under the
name {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}}. Note that the body of the constant is lost for the user.

Again, non inferred implicit arguments and explicit holes are
abstracted.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k}{have} \PYG{n}{H} \PYG{o}{:=} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{x}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
\end{sphinxVerbatim}

adds to the context \sphinxcode{\sphinxupquote{H : Type -\textgreater{} Prop.}} This is a schematic example but
the feature is specially useful when the proof term to give involves
for instance a lemma with some hidden implicit arguments.
\end{sphinxadmonition}

After the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}}, a list of binders is allowed.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k}{have} \PYG{n}{H} \PYG{n}{x} \PYG{o}{(}\PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{k+kp}{by} \PYG{k+kp}{omega}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
\end{sphinxVerbatim}
\end{sphinxadmonition}

A proof term provided after \sphinxcode{\sphinxupquote{:=}} can mention these bound variables
(that are automatically introduced with the given names).
Since the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}} can be omitted, to avoid ambiguity,
bound variables can be surrounded
with parentheses even if no type is specified:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{have} \PYG{o}{(}\PYG{n}{x}\PYG{o}{)} \PYG{o}{:} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{x} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{x} \PYG{k+kp}{by} \PYG{k+kp}{omega}\PYG{o}{.}
\end{sphinxVerbatim}

The {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_item}}}}} and {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{s\_item}}}}} can be used to interpret the asserted
hypothesis with views (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:views-and-reflection-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Views and reflection}}}}) or simplify the resulting
goals.

The \sphinxcode{\sphinxupquote{have}} tactic also supports a \sphinxcode{\sphinxupquote{suff}} modifier which allows for
asserting that a given statement implies the current goal without
copying the goal itself.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k}{have} \PYG{k}{suff} \PYG{n}{H} \PYG{o}{:} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{l+m+mi}{3}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{l+m+mi}{3} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}

\PYG{n}{Focus} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{7}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{n}{Focus} \PYG{l+m+mi}{2}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Warning}\PYG{o}{:} \PYG{n}{The} \PYG{n}{Focus} \PYG{n}{command} \PYG{k}{is} \PYG{n}{deprecated}\PYG{o}{;} \PYG{n}{use} \PYG{k}{\PYGZsq{}}\PYG{l+m+mi}{2}\PYG{o}{:} \PYG{o}{\PYGZob{}}\PYG{k}{\PYGZsq{}} \PYG{n}{instead}
    \PYG{o}{[}\PYG{n}{deprecated}\PYG{o}{\PYGZhy{}}\PYG{n}{focus}\PYG{o}{,}\PYG{n}{deprecated}\PYG{o}{]}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{l+m+mi}{3} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
\end{sphinxVerbatim}

Note that H is introduced in the second goal.
\end{sphinxadmonition}

The \sphinxcode{\sphinxupquote{suff}} modifier is not
compatible with the presence of a list of binders.


\paragraph{Generating let in context entries with have}
\label{\detokenize{proof-engine/ssreflect-proof-language:generating-let-in-context-entries-with-have}}\label{\detokenize{proof-engine/ssreflect-proof-language:generating-let-ssr}}
Since \DUrole{smallcaps}{SSReflect} 1.5 the \sphinxcode{\sphinxupquote{have}} tactic supports a “transparent” modifier
to generate let in context entries: the \sphinxcode{\sphinxupquote{@}} symbol in front of the
context entry name.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{Ord} \PYG{n}{n} \PYG{o}{:=} \PYG{n}{Sub} \PYG{n}{x} \PYG{k}{of} \PYG{n}{x} \PYG{o}{\PYGZlt{}} \PYG{n}{n}\PYG{o}{.}
    \PYG{n}{Ord} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Ord\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Ord\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Ord\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}I\PYGZus{} n}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{Ord} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{8}\PYG{o}{,} \PYG{n}{n} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{2}\PYG{o}{,} \PYG{n}{format} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}\PYGZsq{}I\PYGZus{}\PYGZsq{} n}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Arguments} \PYG{n}{Sub} \PYG{o}{\PYGZob{}}\PYG{o}{\PYGZus{}}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{n} \PYG{n}{m} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{n}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k}{have} \PYG{o}{@}\PYG{n}{i} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}n} \PYG{k+kp}{by} \PYG{k}{apply}\PYG{o}{:} \PYG{o}{(}\PYG{n}{Sub} \PYG{n}{m}\PYG{o}{)}\PYG{o}{;} \PYG{k+kp}{omega}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{n}
      \PYG{n}{i} \PYG{o}{:=} \PYG{n}{Sub} \PYG{n}{m}
             \PYG{o}{(}\PYG{n}{Decidable}\PYG{o}{.}\PYG{n}{dec\PYGZus{}not\PYGZus{}not} \PYG{o}{(}\PYG{n}{m} \PYG{o}{\PYGZlt{}} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{dec\PYGZus{}lt} \PYG{n}{m} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{k}{fun} \PYG{o}{..}\PYG{o}{.} \PYG{o}{=\PYGZgt{}} \PYG{o}{..}\PYG{o}{.} \PYG{o}{..}\PYG{o}{.}\PYG{o}{)}\PYG{o}{)}
       \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}n}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Note that the sub-term produced by \sphinxcode{\sphinxupquote{omega}} is in general huge and
uninteresting, and hence one may want to hide it.
For this purpose the \sphinxcode{\sphinxupquote{{[}: name {]}}} intro pattern and the tactic
\sphinxcode{\sphinxupquote{abstract}} (see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:abstract-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{The abstract tactic}}}}) are provided.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{n} \PYG{n}{m} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{n}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k}{have} \PYG{o}{[}\PYG{o}{:}\PYG{n}{pm}\PYG{o}{]} \PYG{o}{@}\PYG{n}{i} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}n} \PYG{k+kp}{by} \PYG{k}{apply}\PYG{o}{:} \PYG{o}{(}\PYG{n}{Sub} \PYG{n}{m}\PYG{o}{)}\PYG{o}{;} \PYG{n}{abstract}\PYG{o}{:} \PYG{n}{pm}\PYG{o}{;} \PYG{k+kp}{omega}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{n}
      \PYG{n}{pm} \PYG{o}{:} \PYG{n}{m} \PYG{o}{\PYGZlt{}} \PYG{n}{n} \PYG{c}{(*}\PYG{c}{1}\PYG{c}{*)}
      \PYG{n}{i} \PYG{o}{:=} \PYG{n}{Sub} \PYG{n}{m} \PYG{n}{pm} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}n}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
\end{sphinxVerbatim}

The type of \sphinxcode{\sphinxupquote{pm}} can be cleaned up by its annotation \sphinxcode{\sphinxupquote{(*1*)}} by just
simplifying it. The annotations are there for technical reasons only.
\end{sphinxadmonition}

When intro patterns for abstract constants are used in conjunction
with have and an explicit term, they must be used as follows:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{n} \PYG{n}{m} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{n}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k}{have} \PYG{o}{[}\PYG{o}{:}\PYG{n}{pm}\PYG{o}{]} \PYG{o}{@}\PYG{n}{i} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}n} \PYG{o}{:=} \PYG{n}{Sub} \PYG{n}{m} \PYG{n}{pm}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{n}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{S} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}

\PYG{k+kp}{by} \PYG{k+kp}{omega}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{n}
      \PYG{n}{pm} \PYG{o}{:} \PYG{n}{S} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n} \PYG{c}{(*}\PYG{c}{1}\PYG{c}{*)}
      \PYG{n}{i} \PYG{o}{:=} \PYG{n}{Sub} \PYG{n}{m} \PYG{n}{pm} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}n} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}n}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
\end{sphinxVerbatim}
\end{sphinxadmonition}

In this case the abstract constant \sphinxcode{\sphinxupquote{pm}} is assigned by using it in
the term that follows \sphinxcode{\sphinxupquote{:=}} and its corresponding goal is left to be
solved. Goals corresponding to intro patterns for abstract constants
are opened in the order in which the abstract constants are declared
(not in the “order” in which they are used in the term).

Note that abstract constants do respect scopes. Hence, if a variable
is declared after their introduction, it has to be properly
generalized (i.e. explicitly passed to the abstract constant when one
makes use of it).

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{n} \PYG{n}{m} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{n}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k}{have} \PYG{o}{[}\PYG{o}{:}\PYG{n}{pm}\PYG{o}{]} \PYG{o}{@}\PYG{n}{i} \PYG{n}{k} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}}\PYG{o}{(}\PYG{n}{n}\PYG{o}{+}\PYG{n}{k}\PYG{o}{)} \PYG{k+kp}{by} \PYG{k}{apply}\PYG{o}{:} \PYG{o}{(}\PYG{n}{Sub} \PYG{n}{m}\PYG{o}{)}\PYG{o}{;} \PYG{n}{abstract}\PYG{o}{:} \PYG{n}{pm} \PYG{n}{k}\PYG{o}{;} \PYG{k+kp}{omega}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZlt{}} \PYG{n}{n}
      \PYG{n}{pm} \PYG{o}{:} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{k} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{m} \PYG{o}{\PYGZlt{}} \PYG{n}{n} \PYG{o}{+} \PYG{n}{k}\PYG{o}{)} \PYG{c}{(*}\PYG{c}{1}\PYG{c}{*)}
      \PYG{n}{i} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{k} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{Sub} \PYG{n}{m} \PYG{o}{(}\PYG{n}{pm} \PYG{n}{k}\PYG{o}{)} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{k} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}}\PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{k}\PYG{o}{)}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Last, notice that the use of intro patterns for abstract constants is
orthogonal to the transparent flag \sphinxcode{\sphinxupquote{@}} for have.


\paragraph{The have tactic and typeclass resolution}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-have-tactic-and-typeclass-resolution}}
Since \DUrole{smallcaps}{SSReflect} 1.5 the \sphinxcode{\sphinxupquote{have}} tactic behaves as follows with respect to
typeclass inference.
\begin{quote}
\end{quote}
\begin{itemize}
\item {} 
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{have} \PYG{n}{foo} \PYG{o}{:} \PYG{n}{ty}\PYG{o}{.}
\end{sphinxVerbatim}

Full inference for \sphinxcode{\sphinxupquote{ty}}. The first subgoal demands a
proof of such instantiated statement.

\item {} 
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{have} \PYG{n}{foo} \PYG{o}{:} \PYG{n}{ty} \PYG{o}{:=} \PYG{o}{.}
\end{sphinxVerbatim}

No inference for \sphinxcode{\sphinxupquote{ty}}. Unresolved instances are
quantified in \sphinxcode{\sphinxupquote{ty}}. The first subgoal demands a proof of such quantified
statement. Note that no proof term follows \sphinxcode{\sphinxupquote{:=}}, hence two subgoals are
generated.

\item {} 
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{have} \PYG{n}{foo} \PYG{o}{:} \PYG{n}{ty} \PYG{o}{:=} \PYG{n}{t}\PYG{o}{.}
\end{sphinxVerbatim}

No inference for \sphinxcode{\sphinxupquote{ty}} and \sphinxcode{\sphinxupquote{t}}.

\item {} 
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{have} \PYG{n}{foo} \PYG{o}{:=} \PYG{n}{t}\PYG{o}{.}
\end{sphinxVerbatim}

No inference for \sphinxcode{\sphinxupquote{t}}. Unresolved instances are
quantified in the (inferred) type of \sphinxcode{\sphinxupquote{t}} and abstracted in \sphinxcode{\sphinxupquote{t}}.

\end{itemize}
\index{SsrHave NoTCResolution (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:flag.ssrhave-notcresolution}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SsrHave~NoTCResolution}}}}
This option restores the behavior of \DUrole{smallcaps}{SSReflect} 1.4 and below (never resolve typeclasses).

\end{fulllineitems}



\paragraph{Variants: the suff and wlog tactics}
\label{\detokenize{proof-engine/ssreflect-proof-language:variants-the-suff-and-wlog-tactics}}
As it is often the case in mathematical textbooks, forward reasoning
may be used in slightly different variants. One of these variants is
to show that the intermediate step L easily implies the initial goal
G. By easily we mean here that the proof of L ⇒ G is shorter than the
one of L itself. This kind of reasoning step usually starts with: “It
suffices to show that …”.

This is such a frequent way of reasoning that \DUrole{smallcaps}{SSReflect} has a variant
of the \sphinxcode{\sphinxupquote{have}} tactic called \sphinxcode{\sphinxupquote{suffices}} (whose abridged name is \sphinxcode{\sphinxupquote{suff}}).
The
\sphinxcode{\sphinxupquote{have}} and \sphinxcode{\sphinxupquote{suff}} tactics are equivalent and have the same syntax but:
\begin{itemize}
\item {} 
the order of the generated subgoals is inversed

\item {} 
but the optional clear item is still performed in the \sphinxstyleemphasis{second}
branch. This means that the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{suff} \PYG{o}{\PYGZob{}}\PYG{n}{H}\PYG{o}{\PYGZcb{}} \PYG{n}{H} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
\end{sphinxVerbatim}

fails if the context of the current goal indeed contains an
assumption named \sphinxcode{\sphinxupquote{H}}.

\end{itemize}

The rationale of this clearing policy is to make possible “trivial”
refinements of an assumption, without changing its name in the main
branch of the reasoning.

The \sphinxcode{\sphinxupquote{have}} modifier can follow the \sphinxcode{\sphinxupquote{suff}} tactic.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{G}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{G}

\PYG{k}{suff} \PYG{k}{have} \PYG{n}{H} \PYG{o}{:} \PYG{n}{P}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{P}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{G}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{o}{(}\PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{G}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{G}
\end{sphinxVerbatim}

Note that, in contrast with \sphinxcode{\sphinxupquote{have suff}}, the name H has been introduced
in the first goal.
\end{sphinxadmonition}

Another useful construct is reduction, showing that a particular case
is in fact general enough to prove a general property. This kind of
reasoning step usually starts with: “Without loss of generality, we
can suppose that …”. Formally, this corresponds to the proof of a goal
\sphinxcode{\sphinxupquote{G}} by introducing a cut \sphinxcode{\sphinxupquote{wlog\_statement -\textgreater{} G}}. Hence the user shall
provide a proof for both \sphinxcode{\sphinxupquote{(wlog\_statement -\textgreater{} G) -\textgreater{} G}} and
\sphinxcode{\sphinxupquote{wlog\_statement -\textgreater{} G}}. However, such cuts are usually rather
painful to perform by
hand, because the statement \sphinxcode{\sphinxupquote{wlog\_statement}} is tedious to write by hand,
and sometimes even to read.

\DUrole{smallcaps}{SSReflect} implements this kind of reasoning step through the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacv.without-loss}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{without loss}}}}}
tactic, whose short name is {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.wlog}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{wlog}}}}}. It offers support to describe
the shape of the cut statements, by providing the simplifying
hypothesis and by pointing at the elements of the initial goals which
should be generalized. The general syntax of without loss is:
\index{wlog (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.wlog}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{wlog~\DUrole{repeat-wrapper}{\DUrole{repeat}{suff}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}\DUrole{notation-sup}{?}}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}~/~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}

\index{without loss (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacv.without-loss}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{without~loss~\DUrole{repeat-wrapper}{\DUrole{repeat}{suff}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}\DUrole{notation-sup}{?}}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}~/~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


where each {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is a constant in the context
of the goal. Open syntax is supported for {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}.

In its defective form:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{wlog:~/~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{without~loss:~/~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


on a goal G, it creates two subgoals: a first one to prove the
formula (term -\textgreater{} G) -\textgreater{} G and a second one to prove the formula
term -\textgreater{} G.

If the optional list of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is present
on the left side of \sphinxcode{\sphinxupquote{/}}, these constants are generalized in the
premise (term -\textgreater{} G) of the first subgoal. By default bodies of local
definitions are erased. This behavior can be inhibited by prefixing the
name of the local definition with the \sphinxcode{\sphinxupquote{@}} character.

In the second subgoal, the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{n}{clear\PYGZus{}switch} \PYG{n}{i\PYGZus{}item}\PYG{o}{.}
\end{sphinxVerbatim}

is performed if at least one of these optional switches is present in
the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.wlog}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{wlog}}}}} tactic.

The {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.wlog}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{wlog}}}}} tactic is specially useful when a symmetry argument
simplifies a proof. Here is an example showing the beginning of the
proof that quotient and reminder of natural number euclidean division
are unique.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{quo\PYGZus{}rem\PYGZus{}unicity} \PYG{n}{d} \PYG{n}{q1} \PYG{n}{q2} \PYG{n}{r1} \PYG{n}{r2} \PYG{o}{:}
  \PYG{n}{q1}\PYG{o}{*}\PYG{n}{d} \PYG{o}{+} \PYG{n}{r1} \PYG{o}{=} \PYG{n}{q2}\PYG{o}{*}\PYG{n}{d} \PYG{o}{+} \PYG{n}{r2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{r1} \PYG{o}{\PYGZlt{}} \PYG{n}{d} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{r2} \PYG{o}{\PYGZlt{}} \PYG{n}{d} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{q1}\PYG{o}{,} \PYG{n}{r1}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{n}{q2}\PYG{o}{,} \PYG{n}{r2}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{d}\PYG{o}{,} \PYG{n}{q1}\PYG{o}{,} \PYG{n}{q2}\PYG{o}{,} \PYG{n}{r1}\PYG{o}{,} \PYG{n}{r2} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{q1} \PYG{o}{*} \PYG{n}{d} \PYG{o}{+} \PYG{n}{r1} \PYG{o}{=} \PYG{n}{q2} \PYG{o}{*} \PYG{n}{d} \PYG{o}{+} \PYG{n}{r2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{r1} \PYG{o}{\PYGZlt{}} \PYG{n}{d} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{r2} \PYG{o}{\PYGZlt{}} \PYG{n}{d} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{q1}\PYG{o}{,} \PYG{n}{r1}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{n}{q2}\PYG{o}{,} \PYG{n}{r2}\PYG{o}{)}

\PYG{k}{wlog}\PYG{o}{:} \PYG{n}{q1} \PYG{n}{q2} \PYG{n}{r1} \PYG{n}{r2} \PYG{o}{/} \PYG{n}{q1} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{q2}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{d}\PYG{o}{,} \PYG{n}{q1}\PYG{o}{,} \PYG{n}{q2}\PYG{o}{,} \PYG{n}{r1}\PYG{o}{,} \PYG{n}{r2} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{k}{forall} \PYG{n}{q3} \PYG{n}{q4} \PYG{n}{r3} \PYG{n}{r4} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,}
       \PYG{n}{q3} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{q4} \PYG{o}{\PYGZhy{}\PYGZgt{}}
       \PYG{n}{q3} \PYG{o}{*} \PYG{n}{d} \PYG{o}{+} \PYG{n}{r3} \PYG{o}{=} \PYG{n}{q4} \PYG{o}{*} \PYG{n}{d} \PYG{o}{+} \PYG{n}{r4} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{r3} \PYG{o}{\PYGZlt{}} \PYG{n}{d} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{r4} \PYG{o}{\PYGZlt{}} \PYG{n}{d} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{q3}\PYG{o}{,} \PYG{n}{r3}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{n}{q4}\PYG{o}{,} \PYG{n}{r4}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
      \PYG{n}{q1} \PYG{o}{*} \PYG{n}{d} \PYG{o}{+} \PYG{n}{r1} \PYG{o}{=} \PYG{n}{q2} \PYG{o}{*} \PYG{n}{d} \PYG{o}{+} \PYG{n}{r2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{r1} \PYG{o}{\PYGZlt{}} \PYG{n}{d} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{r2} \PYG{o}{\PYGZlt{}} \PYG{n}{d} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{q1}\PYG{o}{,} \PYG{n}{r1}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{n}{q2}\PYG{o}{,} \PYG{n}{r2}\PYG{o}{)}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{q1} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{q2} \PYG{o}{\PYGZhy{}\PYGZgt{}}
     \PYG{n}{q1} \PYG{o}{*} \PYG{n}{d} \PYG{o}{+} \PYG{n}{r1} \PYG{o}{=} \PYG{n}{q2} \PYG{o}{*} \PYG{n}{d} \PYG{o}{+} \PYG{n}{r2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{r1} \PYG{o}{\PYGZlt{}} \PYG{n}{d} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{r2} \PYG{o}{\PYGZlt{}} \PYG{n}{d} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{q1}\PYG{o}{,} \PYG{n}{r1}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{n}{q2}\PYG{o}{,} \PYG{n}{r2}\PYG{o}{)}

\PYG{k+kp}{by} \PYG{k}{case} \PYG{o}{(}\PYG{n}{le\PYGZus{}gt\PYGZus{}dec} \PYG{n}{q1} \PYG{n}{q2}\PYG{o}{)}\PYG{o}{=\PYGZgt{}} \PYG{n}{H}\PYG{o}{;} \PYG{k+kr}{last} \PYG{k}{symmetry}\PYG{o}{;} \PYG{k}{eauto} \PYG{k}{with} \PYG{n}{arith}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{d}\PYG{o}{,} \PYG{n}{q1}\PYG{o}{,} \PYG{n}{q2}\PYG{o}{,} \PYG{n}{r1}\PYG{o}{,} \PYG{n}{r2} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{q1} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{q2} \PYG{o}{\PYGZhy{}\PYGZgt{}}
      \PYG{n}{q1} \PYG{o}{*} \PYG{n}{d} \PYG{o}{+} \PYG{n}{r1} \PYG{o}{=} \PYG{n}{q2} \PYG{o}{*} \PYG{n}{d} \PYG{o}{+} \PYG{n}{r2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{r1} \PYG{o}{\PYGZlt{}} \PYG{n}{d} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{r2} \PYG{o}{\PYGZlt{}} \PYG{n}{d} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{q1}\PYG{o}{,} \PYG{n}{r1}\PYG{o}{)} \PYG{o}{=} \PYG{o}{(}\PYG{n}{q2}\PYG{o}{,} \PYG{n}{r2}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The \sphinxcode{\sphinxupquote{wlog suff}} variant is simpler, since it cuts \sphinxcode{\sphinxupquote{wlog\_statement}} instead
of \sphinxcode{\sphinxupquote{wlog\_statement -\textgreater{} G}}. It thus opens the goals
\sphinxcode{\sphinxupquote{wlog\_statement -\textgreater{} G}}
and \sphinxcode{\sphinxupquote{wlog\_statement}}.

In its simplest form the \sphinxcode{\sphinxupquote{generally have : …}} tactic is equivalent to
\sphinxcode{\sphinxupquote{wlog suff : …}} followed by last first. When the \sphinxcode{\sphinxupquote{have}} tactic is used
with the \sphinxcode{\sphinxupquote{generally}} (or \sphinxcode{\sphinxupquote{gen}}) modifier it accepts an extra identifier
followed by a comma before the usual intro pattern. The identifier
will name the new hypothesis in its more general form, while the intro
pattern will be used to process its instance.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{simple} \PYG{n}{n} \PYG{o}{(}\PYG{n}{ngt0} \PYG{o}{:} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}} \PYG{n}{n} \PYG{o}{)} \PYG{o}{:} \PYG{n}{P} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{ngt0} \PYG{o}{:} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}} \PYG{n}{n}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{n}{n}

\PYG{n}{gen} \PYG{k}{have} \PYG{n}{ltnV}\PYG{o}{,} \PYG{o}{/}\PYG{n}{andP}\PYG{o}{[}\PYG{n}{nge0} \PYG{n}{neq0}\PYG{o}{]} \PYG{o}{:} \PYG{n}{n} \PYG{n}{ngt0} \PYG{o}{/} \PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}\PYG{o}{)} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{o}{(}\PYG{n}{n} \PYG{o}{!=} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{ngt0} \PYG{o}{:} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}} \PYG{n}{n}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}\PYG{o}{)} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{o}{(}\PYG{n}{n} \PYG{o}{!=} \PYG{l+m+mi}{0}\PYG{o}{)}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{P} \PYG{n}{n}

\PYG{n}{Focus} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{7}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{n}{Focus} \PYG{l+m+mi}{2}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Warning}\PYG{o}{:} \PYG{n}{The} \PYG{n}{Focus} \PYG{n}{command} \PYG{k}{is} \PYG{n}{deprecated}\PYG{o}{;} \PYG{n}{use} \PYG{k}{\PYGZsq{}}\PYG{l+m+mi}{2}\PYG{o}{:} \PYG{o}{\PYGZob{}}\PYG{k}{\PYGZsq{}} \PYG{n}{instead}
    \PYG{o}{[}\PYG{n}{deprecated}\PYG{o}{\PYGZhy{}}\PYG{n}{focus}\PYG{o}{,}\PYG{n}{deprecated}\PYG{o}{]}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{ngt0} \PYG{o}{:} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}} \PYG{n}{n}
      \PYG{n}{ltnV} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}\PYG{o}{)} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{o}{(}\PYG{n}{n} \PYG{o}{!=} \PYG{l+m+mi}{0}\PYG{o}{)}
      \PYG{n}{nge0} \PYG{o}{:} \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}
      \PYG{n}{neq0} \PYG{o}{:} \PYG{n}{n} \PYG{o}{!=} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{n}{n}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subparagraph{Advanced generalization}
\label{\detokenize{proof-engine/ssreflect-proof-language:advanced-generalization}}\label{\detokenize{proof-engine/ssreflect-proof-language:advanced-generalization-ssr}}
The complete syntax for the items on the left hand side of the \sphinxcode{\sphinxupquote{/}}
separator is the following one:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{wlog~…~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}~\textbar{}~\DUrole{repeat-wrapper}{\DUrole{repeat}{@}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\textbar{}~(~\DUrole{repeat-wrapper}{\DUrole{repeat}{@}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\DUrole{hole}{c\_pattern}}}})}\DUrole{notation-sup}{?}}~/~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


Clear operations are intertwined with generalization operations. This
helps in particular avoiding dependency issues while generalizing some
facts.

If an {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is prefixed with the \sphinxcode{\sphinxupquote{@}} mark, then a let-in redex is
created, which keeps track if its body (if any). The syntax
\sphinxcode{\sphinxupquote{( ident := c\_pattern)}} allows to generalize an arbitrary term using a
given name. Note that its simplest form \sphinxcode{\sphinxupquote{(x := y)}} is just a renaming of
\sphinxcode{\sphinxupquote{y}} into \sphinxcode{\sphinxupquote{x}}. In particular, this can be useful in order to simulate the
generalization of a section variable, otherwise not allowed. Indeed
renaming does not require the original variable to be cleared.

The syntax \sphinxcode{\sphinxupquote{(@x := y)}} generates a let-in abstraction but with the
following caveat: \sphinxcode{\sphinxupquote{x}} will not bind \sphinxcode{\sphinxupquote{y}}, but its body, whenever \sphinxcode{\sphinxupquote{y}} can be
unfolded. This covers the case of both local and global definitions, as
illustrated in the following example.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Section} \PYG{n}{Test}\PYG{o}{.}
\PYG{k+kn}{Variable} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{x} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Definition} \PYG{n}{addx} \PYG{n}{z} \PYG{o}{:=} \PYG{n}{z} \PYG{o}{+} \PYG{n}{x}\PYG{o}{.}
    \PYG{n}{addx} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{addx} \PYG{n}{x}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{addx} \PYG{n}{x}

\PYG{k}{wlog} \PYG{n}{H} \PYG{o}{:} \PYG{o}{(}\PYG{n}{y} \PYG{o}{:=} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{o}{@}\PYG{n}{twoy} \PYG{o}{:=} \PYG{n}{addx} \PYG{n}{x}\PYG{o}{)} \PYG{o}{/} \PYG{n}{twoy} \PYG{o}{=} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{y}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{k}{forall} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{k}{let} \PYG{n}{twoy} \PYG{o}{:=} \PYG{n}{y} \PYG{o}{+} \PYG{n}{y} \PYG{k}{in} \PYG{n}{twoy} \PYG{o}{=} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{twoy}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
      \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{addx} \PYG{n}{x}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{twoy}
\end{sphinxVerbatim}

To avoid unfolding the term captured by the pattern add x one can use
the pattern \sphinxcode{\sphinxupquote{id (addx x)}}, that would produce the following first
subgoal

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{wlog} \PYG{n}{H} \PYG{o}{:} \PYG{o}{(}\PYG{n}{y} \PYG{o}{:=} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{o}{@}\PYG{n}{twoy} \PYG{o}{:=} \PYG{n}{id} \PYG{o}{(}\PYG{n}{addx} \PYG{n}{x}\PYG{o}{)}\PYG{o}{)} \PYG{o}{/} \PYG{n}{twoy} \PYG{o}{=} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{y}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{k}{forall} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{k}{let} \PYG{n}{twoy} \PYG{o}{:=} \PYG{n}{addx} \PYG{n}{y} \PYG{k}{in} \PYG{n}{twoy} \PYG{o}{=} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{addx} \PYG{n}{y}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
      \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{addx} \PYG{n}{x}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{addx} \PYG{n}{y}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsection{Rewriting}
\label{\detokenize{proof-engine/ssreflect-proof-language:rewriting}}\label{\detokenize{proof-engine/ssreflect-proof-language:rewriting-ssr}}
The generalized use of reflection implies that most of the
intermediate results handled are properties of effectively computable
functions. The most efficient mean of establishing such results are
computation and simplification of expressions involving such
functions, i.e., rewriting. \DUrole{smallcaps}{SSReflect} therefore includes an
extended \sphinxcode{\sphinxupquote{rewrite}} tactic, that unifies and combines most of the
rewriting functionalities.


\subsubsection{An extended rewrite tactic}
\label{\detokenize{proof-engine/ssreflect-proof-language:an-extended-rewrite-tactic}}
The main features of the rewrite tactic are:
\begin{itemize}
\item {} 
It can perform an entire series of such operations in any subset of
the goal and/or context;

\item {} 
It allows to perform rewriting, simplifications, folding/unfolding
of definitions, closing of goals;

\item {} 
Several rewriting operations can be chained in a single tactic;

\item {} 
Control over the occurrence at which rewriting is to be performed is
significantly enhanced.

\end{itemize}

The general form of an \DUrole{smallcaps}{SSReflect} rewrite tactic is:
\index{rewrite (ssreflect) (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.rewrite-ssreflect}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{rewrite~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-rstep}]{\sphinxcrossref{\DUrole{hole}{rstep}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}


The combination of a rewrite tactic with the in tactical (see section
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:localization-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Localization}}}}) performs rewriting in both the context and the goal.

A rewrite step {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-rstep}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rstep}}}}} has the general form:


\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-rstep}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{rstep~::=~}}\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_prefix}]{\sphinxcrossref{\DUrole{hole}{r\_prefix}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\DUrole{hole}{r\_item}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_prefix}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{r\_prefix~::=~}}\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{-}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult}]{\sphinxcrossref{\DUrole{hole}{mult}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{[}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_pattern}]{\sphinxcrossref{\DUrole{hole}{r\_pattern}}}}~{]}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_pattern}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{r\_pattern~::=~}}\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{meta}{\textbar{}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{meta}{\textbar{}}~\DUrole{meta}{(}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as~\DUrole{meta}{)}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{r\_item~::=~}}\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{/}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}}}}}
\end{fulllineitems}


An {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_prefix}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_prefix}}}}} contains annotations to qualify where and how the rewrite
operation should be performed:
\begin{itemize}
\item {} 
The optional initial \sphinxcode{\sphinxupquote{-}} indicates the direction of the rewriting of
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_item}}}}}:
if present the direction is right-to-left and it is left-to-right otherwise.

\item {} 
The multiplier {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{mult}}}}} (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:iteration-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Iteration}}}})
specifies if and how the
rewrite operation should be repeated.

\item {} 
A rewrite operation matches the occurrences of a \sphinxstyleemphasis{rewrite pattern},
and replaces these occurrences by another term, according to the
given {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_item}}}}}. The optional \sphinxstyleemphasis{redex switch} \sphinxcode{\sphinxupquote{{[}r\_pattern{]}}},
which should
always be surrounded by brackets, gives explicitly this rewrite
pattern. In its simplest form, it is a regular term. If no explicit
redex switch is present the rewrite pattern to be matched is inferred
from the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_item}}}}}.

\item {} 
This optional term, or the {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_item}}}}}, may be preceded by an occurrence
switch (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:selectors-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Selectors}}}}) or a clear item
(see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Discharge}}}}),
these two possibilities being exclusive. An occurrence switch selects
the occurrences of the rewrite pattern which should be affected by the
rewrite operation.

\end{itemize}

An {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_item}}}}} can be:
\begin{itemize}
\item {} 
A \sphinxstyleemphasis{simplification} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_item}}}}},
represented by a {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{s\_item}}}}} (see section
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}). Simplification operations are intertwined with the possible
other rewrite operations specified by the list of {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_item}}}}}.

\item {} 
A \sphinxstyleemphasis{folding/unfolding} {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_item}}}}}. The tactic:
\sphinxcode{\sphinxupquote{rewrite /term}} unfolds the
head constant of term in every occurrence of the first matching of
term in the goal. In particular, if \sphinxcode{\sphinxupquote{my\_def}} is a (local or global)
defined constant, the tactic: \sphinxcode{\sphinxupquote{rewrite /my\_def.}} is analogous to:
\sphinxcode{\sphinxupquote{unfold my\_def}}.
Conversely: \sphinxcode{\sphinxupquote{rewrite -/my\_def.}} is equivalent to: \sphinxcode{\sphinxupquote{fold my\_def}}.
When an unfold {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_item}}}}} is combined with a
redex pattern, a conversion
operation is performed. A tactic of the form:
\sphinxcode{\sphinxupquote{rewrite -{[}term1{]}/term2.}}
is equivalent to: \sphinxcode{\sphinxupquote{change term1 with term2.}} If \sphinxcode{\sphinxupquote{term2}} is a
single constant and \sphinxcode{\sphinxupquote{term1}} head symbol is not \sphinxcode{\sphinxupquote{term2}}, then the head
symbol of \sphinxcode{\sphinxupquote{term1}} is repeatedly unfolded until \sphinxcode{\sphinxupquote{term2}} appears.

\item {} \begin{description}
\item[{A {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}, which can be:}] \leavevmode\begin{itemize}
\item {} 
A term whose type has the form:
\sphinxcode{\sphinxupquote{forall (x1 : A1 )…(xn : An ), eq term1 term2}} where
\sphinxcode{\sphinxupquote{eq}} is the Leibniz equality or a registered setoid
equality.

\item {} 
A list of terms \sphinxcode{\sphinxupquote{(t1 ,…,tn)}}, each \sphinxcode{\sphinxupquote{ti}} having a type above.
The tactic: \sphinxcode{\sphinxupquote{rewrite r\_prefix (t1 ,…,tn ).}}
is equivalent to: \sphinxcode{\sphinxupquote{do {[}rewrite r\_prefix t1 \textbar{} … \textbar{} rewrite r\_prefix tn {]}.}}

\item {} 
An anonymous rewrite lemma \sphinxcode{\sphinxupquote{(\_ : term)}}, where term has a type as above.  tactic: \sphinxcode{\sphinxupquote{rewrite (\_ : term)}} is in fact synonym of: \sphinxcode{\sphinxupquote{cutrewrite (term).}}.

\end{itemize}

\end{description}

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{double} \PYG{n}{x} \PYG{o}{:=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{x}\PYG{o}{.}
    \PYG{n}{double} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{ddouble} \PYG{n}{x} \PYG{o}{:=} \PYG{n}{double} \PYG{o}{(}\PYG{n}{double} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{ddouble} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{o}{:} \PYG{n}{ddouble} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{4} \PYG{o}{*} \PYG{n}{x}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{ddouble} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{4} \PYG{o}{*} \PYG{n}{x}

\PYG{k}{rewrite} \PYG{o}{[}\PYG{n}{ddouble} \PYG{o}{\PYGZus{}}\PYG{o}{]}\PYG{o}{/}\PYG{n}{double}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{double} \PYG{n}{x} \PYG{o}{+} \PYG{n}{double} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{4} \PYG{o}{*} \PYG{n}{x}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{warning}{Warning:}
The \DUrole{smallcaps}{SSReflect} terms containing holes are \sphinxstyleemphasis{not} typed as
abstractions in this context. Hence the following script fails.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{f} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{x} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{.}
    \PYG{n}{f} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{f} \PYG{n}{y} \PYG{n}{x}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{f} \PYG{n}{y} \PYG{n}{x}

\PYG{k}{rewrite} \PYG{o}{\PYGZhy{}}\PYG{o}{[}\PYG{n}{f} \PYG{n}{y}\PYG{o}{]}\PYG{o}{/}\PYG{o}{(}\PYG{n}{y} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{22}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k}{rewrite} \PYG{o}{\PYGZhy{}}\PYG{o}{[}\PYG{n}{f} \PYG{n}{y}\PYG{o}{]}\PYG{o}{/}\PYG{o}{(}\PYG{n}{y} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:}
    \PYG{k+kn}{Ltac} \PYG{n}{call} \PYG{n}{to} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{rewrite (ssrrwargs) (ssrclauses)}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{failed}\PYG{o}{.}
    \PYG{k}{fold} \PYG{k}{pattern} \PYG{o}{(}\PYG{n}{y} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{)} \PYG{n}{does} \PYG{n}{not} \PYG{k}{match} \PYG{n}{redex} \PYG{o}{(}\PYG{n}{f} \PYG{n}{y}\PYG{o}{)}
\end{sphinxVerbatim}

but the following script succeeds

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{o}{\PYGZhy{}}\PYG{o}{[}\PYG{n}{f} \PYG{n}{y} \PYG{n}{x}\PYG{o}{]}\PYG{o}{/}\PYG{o}{(}\PYG{n}{y} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y} \PYG{o}{+} \PYG{n}{x}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{itemize}


\subsubsection{Remarks and examples}
\label{\detokenize{proof-engine/ssreflect-proof-language:remarks-and-examples}}

\paragraph{Rewrite redex selection}
\label{\detokenize{proof-engine/ssreflect-proof-language:rewrite-redex-selection}}
The general strategy of \DUrole{smallcaps}{SSReflect} is to grasp as many redexes as
possible and to let the user select the ones to be rewritten thanks to
the improved syntax for the control of rewriting.

This may be a source of incompatibilities between the two rewrite
tactics.

In a rewrite tactic of the form:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{n}{occ\PYGZus{}switch} \PYG{o}{[}\PYG{n}{term1}\PYG{o}{]}\PYG{n}{term2}\PYG{o}{.}
\end{sphinxVerbatim}

\sphinxcode{\sphinxupquote{term1}} is the explicit rewrite redex and \sphinxcode{\sphinxupquote{term2}} is the rewrite rule.
This execution of this tactic unfolds as follows:
\begin{itemize}
\item {} 
First \sphinxcode{\sphinxupquote{term1}} and \sphinxcode{\sphinxupquote{term2}} are \(\beta\)\(\iota\) normalized. Then \sphinxcode{\sphinxupquote{term2}}
is put in head
normal form if the Leibniz equality constructor \sphinxcode{\sphinxupquote{eq}} is not the head
symbol. This may involve \(\zeta\) reductions.

\item {} 
Then, the matching algorithm (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:abbreviations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations}}}})
determines the
first subterm of the goal matching the rewrite pattern. The rewrite
pattern is given by \sphinxcode{\sphinxupquote{term1}}, if an explicit redex pattern switch is
provided, or by the type of \sphinxcode{\sphinxupquote{term2}} otherwise. However, matching skips
over matches that would lead to trivial rewrites. All the occurrences
of this subterm in the goal are candidates for rewriting.

\item {} 
Then only the occurrences coded by {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}} (see again section
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:abbreviations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations}}}}) are finally selected for rewriting.

\item {} 
The left hand side of \sphinxcode{\sphinxupquote{term2}} is unified with the subterm found by
the matching algorithm, and if this succeeds, all the selected
occurrences in the goal are replaced by the right hand side of \sphinxcode{\sphinxupquote{term2}}.

\item {} 
Finally the goal is \(\beta\)\(\iota\) normalized.

\end{itemize}

In the case \sphinxcode{\sphinxupquote{term2}} is a list of terms, the first top-down (in the
goal) left-to-right (in the list) matching rule gets selected.


\paragraph{Chained rewrite steps}
\label{\detokenize{proof-engine/ssreflect-proof-language:chained-rewrite-steps}}
The possibility to chain rewrite operations in a single tactic makes
scripts more compact and gathers in a single command line a bunch of
surgical operations which would be described by a one sentence in a
pen and paper proof.

Performing rewrite and simplification operations in a single tactic
enhances significantly the concision of scripts. For instance the
tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{o}{/}\PYG{n}{my\PYGZus{}def} \PYG{o}{\PYGZob{}}\PYG{l+m+mi}{2}\PYG{o}{\PYGZcb{}}\PYG{o}{[}\PYG{n}{f} \PYG{o}{\PYGZus{}}\PYG{o}{]}\PYG{o}{/=} \PYG{n}{my\PYGZus{}eq} \PYG{o}{//}\PYG{o}{=}\PYG{o}{.}
\end{sphinxVerbatim}

unfolds \sphinxcode{\sphinxupquote{my\_def}} in the goal, simplifies the second occurrence of the
first subterm matching pattern \sphinxcode{\sphinxupquote{{[}f \_{]}}}, rewrites \sphinxcode{\sphinxupquote{my\_eq}}, simplifies the
goals and closes trivial goals.

Here are some concrete examples of chained rewrite operations, in the
proof of basic results on natural numbers arithmetic.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{addn0} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m}\PYG{o}{,} \PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
    \PYG{n}{addn0} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Axiom} \PYG{n}{addnS} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m} \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{+} \PYG{n}{S} \PYG{n}{n} \PYG{o}{=} \PYG{n}{S} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{n}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{addnS} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Axiom} \PYG{n}{addSnnS} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m} \PYG{n}{n}\PYG{o}{,} \PYG{n}{S} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{m} \PYG{o}{+} \PYG{n}{S} \PYG{n}{n}\PYG{o}{.}
    \PYG{n}{addSnnS} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Lemma} \PYG{n}{addnCA} \PYG{n}{m} \PYG{n}{n} \PYG{n}{p} \PYG{o}{:} \PYG{n}{m} \PYG{o}{+} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{m}\PYG{o}{,} \PYG{n}{n}\PYG{o}{,} \PYG{n}{p} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{m} \PYG{o}{+} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)}

\PYG{k+kp}{by} \PYG{k}{elim}\PYG{o}{:} \PYG{n}{m} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{o}{[} \PYG{o}{\textbar{}} \PYG{n}{m} \PYG{n}{Hrec}\PYG{o}{]} \PYG{n}{p}\PYG{o}{;} \PYG{k}{rewrite} \PYG{o}{?}\PYG{n}{addSnnS} \PYG{o}{\PYGZhy{}}\PYG{o}{?}\PYG{n}{addnS}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{addnCA} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Lemma} \PYG{n}{addnC} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{m} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m}

\PYG{k+kp}{by} \PYG{k}{rewrite} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZob{}}\PYG{l+m+mi}{1}\PYG{o}{\PYGZcb{}}\PYG{o}{[}\PYG{n}{n}\PYG{o}{]}\PYG{n}{addn0} \PYG{n}{addnCA} \PYG{n}{addn0}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{addnC} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Note the use of the \sphinxcode{\sphinxupquote{?}} switch for parallel rewrite operations in the
proof of \sphinxcode{\sphinxupquote{addnCA}}.


\paragraph{Explicit redex switches are matched first}
\label{\detokenize{proof-engine/ssreflect-proof-language:explicit-redex-switches-are-matched-first}}
If an {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_prefix}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_prefix}}}}} involves a \sphinxstyleemphasis{redex switch}, the first step is to find a
subterm matching this redex pattern, independently from the left hand
side of the equality the user wants to rewrite.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{t} \PYG{n}{u}\PYG{o}{,} \PYG{n}{t} \PYG{o}{+} \PYG{n}{u} \PYG{o}{=} \PYG{n}{u} \PYG{o}{+} \PYG{n}{t}\PYG{o}{)} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y} \PYG{o}{+} \PYG{n}{x}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{t} \PYG{n}{u} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{t} \PYG{o}{+} \PYG{n}{u} \PYG{o}{=} \PYG{n}{u} \PYG{o}{+} \PYG{n}{t}
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{y} \PYG{o}{+} \PYG{n}{x}

\PYG{k}{rewrite} \PYG{o}{[}\PYG{n}{y} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{]}\PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{t} \PYG{n}{u} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{t} \PYG{o}{+} \PYG{n}{u} \PYG{o}{=} \PYG{n}{u} \PYG{o}{+} \PYG{n}{t}
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Note that if this first pattern matching is not compatible with the
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_item}}}}}, the rewrite fails, even if the goal contains a
correct redex matching both the redex switch and the left hand side of
the equality.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{t} \PYG{n}{u}\PYG{o}{,} \PYG{n}{t} \PYG{o}{+} \PYG{n}{u} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{t}\PYG{o}{)} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{*} \PYG{l+m+mi}{4} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{H} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{t} \PYG{n}{u} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{t} \PYG{o}{+} \PYG{n}{u} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{t}
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{*} \PYG{l+m+mi}{4} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{l+m+mi}{0}

\PYG{k}{rewrite} \PYG{o}{[}\PYG{n}{x} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{]}\PYG{n}{H}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{16}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k}{rewrite} \PYG{o}{[}\PYG{n}{x} \PYG{o}{+} \PYG{o}{\PYGZus{}}\PYG{o}{]}\PYG{n}{H}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:}
    \PYG{k+kn}{Ltac} \PYG{n}{call} \PYG{n}{to} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{rewrite (ssrrwargs) (ssrclauses)}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{failed}\PYG{o}{.}
    \PYG{k}{pattern} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{*} \PYG{l+m+mi}{4}\PYG{o}{)} \PYG{n}{does} \PYG{n}{not} \PYG{k}{match} \PYG{n}{LHS} \PYG{k}{of} \PYG{n}{H}
\end{sphinxVerbatim}

Indeed the left hand side of \sphinxcode{\sphinxupquote{H}} does not match
the redex identified by the pattern \sphinxcode{\sphinxupquote{x + y * 4}}.
\end{sphinxadmonition}


\paragraph{Occurrence switches and redex switches}
\label{\detokenize{proof-engine/ssreflect-proof-language:occurrence-switches-and-redex-switches}}
\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)}

\PYG{k}{rewrite} \PYG{o}{\PYGZob{}}\PYG{l+m+mi}{2}\PYG{o}{\PYGZcb{}}\PYG{o}{[}\PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{]}\PYG{o}{(}\PYG{o}{\PYGZus{}}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{z}\PYG{o}{,} \PYG{n}{z} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{z}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{z} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{z}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The second subgoal is generated by the use of an anonymous lemma in
the rewrite tactic. The effect of the tactic on the initial goal is to
rewrite this lemma at the second occurrence of the first matching
\sphinxcode{\sphinxupquote{x + y + 0}} of the explicit rewrite redex \sphinxcode{\sphinxupquote{\_ + y + 0}}.


\paragraph{Occurrence selection and repetition}
\label{\detokenize{proof-engine/ssreflect-proof-language:occurrence-selection-and-repetition}}
Occurrence selection has priority over repetition switches. This means
the repetition of a rewrite tactic specified by a multiplier will
perform matching each time an elementary rewrite operation is
performed. Repeated rewrite tactics apply to every subgoal generated
by the previous tactic, including the previous instances of the
repetition.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{y} \PYG{o}{(}\PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{1}

\PYG{k}{rewrite} \PYG{l+m+mi}{2}\PYG{o}{!}\PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{n}{z}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{4} \PYG{n}{subgoals}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{n}{z}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{z} \PYG{o}{=} \PYG{n}{z}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{n}{z}
    \PYG{n}{subgoal} \PYG{l+m+mi}{4} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{z} \PYG{o}{=} \PYG{n}{z}
\end{sphinxVerbatim}
\end{sphinxadmonition}

This last tactic generates \sphinxstyleemphasis{three} subgoals because
the second rewrite operation specified with the \sphinxcode{\sphinxupquote{2!}} multiplier
applies to the two subgoals generated by the first rewrite.


\paragraph{Multi-rule rewriting}
\label{\detokenize{proof-engine/ssreflect-proof-language:multi-rule-rewriting}}
The rewrite tactic can be provided a \sphinxstyleemphasis{tuple} of rewrite rules, or more
generally a tree of such rules, since this tuple can feature arbitrary
inner parentheses. We call \sphinxstyleemphasis{multirule} such a generalized rewrite
rule. This feature is of special interest when it is combined with
multiplier switches, which makes the rewrite tactic iterate the
rewrite operations prescribed by the rules on the current goal.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variables} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{n}{c} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{a} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{b} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{c} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Hypothesis} \PYG{n}{eqab} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{b}\PYG{o}{.}
    \PYG{n}{eqab} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Hypothesis} \PYG{n}{eqac} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{c}\PYG{o}{.}
    \PYG{n}{eqac} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{a}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{,} \PYG{n}{c} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{eqab} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{b}
      \PYG{n}{eqac} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{c}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{a} \PYG{o}{=} \PYG{n}{a}

\PYG{k}{rewrite} \PYG{o}{(}\PYG{n}{eqab}\PYG{o}{,} \PYG{n}{eqac}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{,} \PYG{n}{c} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{eqab} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{b}
      \PYG{n}{eqac} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{c}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{b} \PYG{o}{=} \PYG{n}{b}
\end{sphinxVerbatim}

Indeed rule \sphinxcode{\sphinxupquote{eqab}} is the first to apply among the ones
gathered in the tuple passed to the rewrite tactic. This multirule
\sphinxcode{\sphinxupquote{(eqab, eqac)}} is actually a \DUrole{smallcaps}{Coq} term and we can name it with a
definition:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{multi1} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{eqab}\PYG{o}{,} \PYG{n}{eqac}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{multi1} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

In this case, the tactic \sphinxcode{\sphinxupquote{rewrite multi1}} is a synonym for
\sphinxcode{\sphinxupquote{rewrite (eqab, eqac)}}.
\end{sphinxadmonition}

More precisely, a multirule rewrites the first subterm to which one of
the rules applies in a left-to-right traversal of the goal, with the
first rule from the multirule tree in left-to-right order. Matching is
performed according to the algorithm described in
Section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:abbreviations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations}}}}, but
literal matches have priority.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{d} \PYG{o}{:=} \PYG{n}{a}\PYG{o}{.}
    \PYG{n}{d} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Hypotheses} \PYG{n}{eqd0} \PYG{o}{:} \PYG{n}{d} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{eqd0} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Definition} \PYG{n}{multi2} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{eqab}\PYG{o}{,} \PYG{n}{eqd0}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{multi2} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{d} \PYG{o}{=} \PYG{n}{b}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{,} \PYG{n}{c} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{eqab} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{b}
      \PYG{n}{eqac} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{c}
      \PYG{n}{eqd0} \PYG{o}{:} \PYG{n}{d} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{d} \PYG{o}{=} \PYG{n}{b}

\PYG{k}{rewrite} \PYG{n}{multi2}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{,} \PYG{n}{c} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{eqab} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{b}
      \PYG{n}{eqac} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{c}
      \PYG{n}{eqd0} \PYG{o}{:} \PYG{n}{d} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{b}
\end{sphinxVerbatim}

Indeed rule \sphinxcode{\sphinxupquote{eqd0}} applies without unfolding the
definition of \sphinxcode{\sphinxupquote{d}}.
\end{sphinxadmonition}

For repeated rewrites the selection process is
repeated anew.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Hypothesis} \PYG{n}{eq\PYGZus{}adda\PYGZus{}b} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{n}{a} \PYG{o}{=} \PYG{n}{b}\PYG{o}{.}
    \PYG{n}{eq\PYGZus{}adda\PYGZus{}b} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Hypothesis} \PYG{n}{eq\PYGZus{}adda\PYGZus{}c} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{n}{a} \PYG{o}{=} \PYG{n}{c}\PYG{o}{.}
    \PYG{n}{eq\PYGZus{}adda\PYGZus{}c} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Hypothesis} \PYG{n}{eqb0} \PYG{o}{:} \PYG{n}{b} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{eqb0} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Definition} \PYG{n}{multi3} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{eq\PYGZus{}adda\PYGZus{}b}\PYG{o}{,} \PYG{n}{eq\PYGZus{}adda\PYGZus{}c}\PYG{o}{,} \PYG{n}{eqb0}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{multi3} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{a} \PYG{o}{=} \PYG{l+m+mi}{12} \PYG{o}{+} \PYG{n}{a}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{,} \PYG{n}{c} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{eqab} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{b}
      \PYG{n}{eqac} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{c}
      \PYG{n}{eqd0} \PYG{o}{:} \PYG{n}{d} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{n}{eq\PYGZus{}adda\PYGZus{}b} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{n}{a} \PYG{o}{=} \PYG{n}{b}
      \PYG{n}{eq\PYGZus{}adda\PYGZus{}c} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{n}{a} \PYG{o}{=} \PYG{n}{c}
      \PYG{n}{eqb0} \PYG{o}{:} \PYG{n}{b} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{a} \PYG{o}{=} \PYG{l+m+mi}{12} \PYG{o}{+} \PYG{n}{a}

\PYG{k}{rewrite} \PYG{l+m+mi}{2}\PYG{o}{!}\PYG{n}{multi3}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{,} \PYG{n}{c} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{eqab} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{b}
      \PYG{n}{eqac} \PYG{o}{:} \PYG{n}{a} \PYG{o}{=} \PYG{n}{c}
      \PYG{n}{eqd0} \PYG{o}{:} \PYG{n}{d} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{n}{eq\PYGZus{}adda\PYGZus{}b} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{n}{a} \PYG{o}{=} \PYG{n}{b}
      \PYG{n}{eq\PYGZus{}adda\PYGZus{}c} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{n}{a} \PYG{o}{=} \PYG{n}{c}
      \PYG{n}{eqb0} \PYG{o}{:} \PYG{n}{b} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{12} \PYG{o}{+} \PYG{n}{a}
\end{sphinxVerbatim}

It uses \sphinxcode{\sphinxupquote{eq\_adda\_b}} then \sphinxcode{\sphinxupquote{eqb0}} on the left-hand
side only. Without the bound \sphinxcode{\sphinxupquote{2}} one would obtain \sphinxcode{\sphinxupquote{0 = 0}}.
\end{sphinxadmonition}

The grouping of rules inside a multirule does not affect the selection
strategy but can make it easier to include one rule set in another or
to (universally) quantify over the parameters of a subset of rules (as
there is special code that will omit unnecessary quantifiers for rules
that can be syntactically extracted). It is also possible to reverse
the direction of a rule subset, using a special dedicated syntax: the
tactic rewrite \sphinxcode{\sphinxupquote{(=\textasciitilde{} multi1)}} is equivalent to \sphinxcode{\sphinxupquote{rewrite multi1\_rev}}.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Hypothesis} \PYG{n}{eqba} \PYG{o}{:} \PYG{n}{b} \PYG{o}{=} \PYG{n}{a}\PYG{o}{.}
    \PYG{n}{eqba} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Hypothesis} \PYG{n}{eqca} \PYG{o}{:} \PYG{n}{c} \PYG{o}{=} \PYG{n}{a}\PYG{o}{.}
    \PYG{n}{eqca} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Definition} \PYG{n}{multi1\PYGZus{}rev} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{eqba}\PYG{o}{,} \PYG{n}{eqca}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{multi1\PYGZus{}rev} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}

except that the constants \sphinxcode{\sphinxupquote{eqba}}, \sphinxcode{\sphinxupquote{eqab}}, \sphinxcode{\sphinxupquote{mult1\_rev}}
have not been created.

Rewriting with multirules is useful to implement simplification or
transformation procedures, to be applied on terms of small to medium
size. For instance the library \sphinxtitleref{ssrnat} (Mathematical Components library)
provides two implementations
for arithmetic operations on natural numbers: an elementary one and a
tail recursive version, less inefficient but also less convenient for
reasoning purposes. The library also provides one lemma per such
operation, stating that both versions return the same values when
applied to the same arguments:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{addE} \PYG{o}{:} \PYG{n}{add} \PYG{o}{=}\PYG{l+m+mi}{2} \PYG{n}{addn}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{doubleE} \PYG{o}{:} \PYG{n}{double} \PYG{o}{=}\PYG{l+m+mi}{1} \PYG{n}{doublen}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{add\PYGZus{}mulE} \PYG{n}{n} \PYG{n}{m} \PYG{n}{s} \PYG{o}{:} \PYG{n}{add\PYGZus{}mul} \PYG{n}{n} \PYG{n}{m} \PYG{n}{s} \PYG{o}{=} \PYG{n}{addn} \PYG{o}{(}\PYG{n}{muln} \PYG{n}{n} \PYG{n}{m}\PYG{o}{)} \PYG{n}{s}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{mulE} \PYG{o}{:} \PYG{n}{mul} \PYG{o}{=}\PYG{l+m+mi}{2} \PYG{n}{muln}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{mul\PYGZus{}expE} \PYG{n}{m} \PYG{n}{n} \PYG{n}{p} \PYG{o}{:} \PYG{n}{mul\PYGZus{}exp} \PYG{n}{m} \PYG{n}{n} \PYG{n}{p} \PYG{o}{=} \PYG{n}{muln} \PYG{o}{(}\PYG{n}{expn} \PYG{n}{m} \PYG{n}{n}\PYG{o}{)} \PYG{n}{p}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{expE} \PYG{o}{:} \PYG{n}{exp} \PYG{o}{=}\PYG{l+m+mi}{2} \PYG{n}{expn}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{oddE} \PYG{o}{:} \PYG{n}{odd} \PYG{o}{=}\PYG{l+m+mi}{1} \PYG{n}{oddn}\PYG{o}{.}
\end{sphinxVerbatim}

The operation on the left hand side of each lemma is the efficient
version, and the corresponding naive implementation is on the right
hand side. In order to reason conveniently on expressions involving
the efficient operations, we gather all these rules in the definition
\sphinxcode{\sphinxupquote{trecE}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{trecE} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{addE}\PYG{o}{,} \PYG{o}{(}\PYG{n}{doubleE}\PYG{o}{,} \PYG{n}{oddE}\PYG{o}{)}\PYG{o}{,} \PYG{o}{(}\PYG{n}{mulE}\PYG{o}{,} \PYG{n}{add\PYGZus{}mulE}\PYG{o}{,} \PYG{o}{(}\PYG{n}{expE}\PYG{o}{,} \PYG{n}{mul\PYGZus{}expE}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

The tactic: \sphinxcode{\sphinxupquote{rewrite !trecE.}}
restores the naive versions of each operation in a goal involving the
efficient ones, e.g. for the purpose of a correctness proof.


\paragraph{Wildcards vs abstractions}
\label{\detokenize{proof-engine/ssreflect-proof-language:wildcards-vs-abstractions}}
The rewrite tactic supports \sphinxcode{\sphinxupquote{r\_items}} containing holes. For example, in
the tactic \sphinxcode{\sphinxupquote{rewrite (\_ : \_ * 0 = 0).}}
the term \sphinxcode{\sphinxupquote{\_ * 0 = 0}} is interpreted as \sphinxcode{\sphinxupquote{forall n : nat, n * 0 = 0.}}
Anyway this tactic is \sphinxstyleemphasis{not} equivalent to
\sphinxcode{\sphinxupquote{rewrite (\_ : forall x, x * 0 = 0).}}.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{y} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{n}{y} \PYG{o}{*} \PYG{o}{(}\PYG{n}{z} \PYG{o}{*} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{y} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{n}{y} \PYG{o}{*} \PYG{o}{(}\PYG{n}{z} \PYG{o}{*} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{k}{rewrite} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{o}{\PYGZus{}} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{y} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{n}{y} \PYG{o}{*} \PYG{o}{(}\PYG{n}{z} \PYG{o}{*} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}

while the other tactic results in

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{n}{x} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{*} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{n}{y} \PYG{o}{*} \PYG{o}{(}\PYG{n}{z} \PYG{o}{*} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}

The first tactic requires you to prove the instance of the (missing)
lemma that was used, while the latter requires you prove the quantified
form.
\end{sphinxadmonition}


\paragraph{When SSReflect rewrite fails on standard Coq licit rewrite}
\label{\detokenize{proof-engine/ssreflect-proof-language:when-ssr-rewrite-fails-on-standard-coq-licit-rewrite}}
In a few cases, the \DUrole{smallcaps}{SSReflect} rewrite tactic fails rewriting some
redexes which standard \DUrole{smallcaps}{Coq} successfully rewrites. There are two main
cases:
\begin{itemize}
\item {} 
\DUrole{smallcaps}{SSReflect} never accepts to rewrite indeterminate patterns like:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{foo} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{unit}\PYG{o}{)} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{tt}\PYG{o}{.}
\end{sphinxVerbatim}

\DUrole{smallcaps}{SSReflect} will however accept the
\(\eta\)\(\zeta\) expansion of this rule:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{fubar} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{unit}\PYG{o}{)} \PYG{o}{:} \PYG{o}{(}\PYG{k}{let} \PYG{n}{u} \PYG{o}{:=} \PYG{n}{x} \PYG{k}{in} \PYG{n}{u}\PYG{o}{)} \PYG{o}{=} \PYG{n}{tt}\PYG{o}{.}
\end{sphinxVerbatim}

\item {} 
The standard rewrite tactic provided by \DUrole{smallcaps}{Coq} uses a different algorithm
to find instances of the rewrite rule.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variable} \PYG{n}{g} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{g} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Definition} \PYG{n}{f} \PYG{o}{:=} \PYG{n}{g}\PYG{o}{.}
    \PYG{n}{f} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Axiom} \PYG{n}{H} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{n}{g} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{H} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{f} \PYG{l+m+mi}{3} \PYG{o}{+} \PYG{n}{f} \PYG{l+m+mi}{3} \PYG{o}{=} \PYG{n}{f} \PYG{l+m+mi}{6}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{g} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{f} \PYG{l+m+mi}{3} \PYG{o}{+} \PYG{n}{f} \PYG{l+m+mi}{3} \PYG{o}{=} \PYG{n}{f} \PYG{l+m+mi}{6}

\PYG{c}{(*}\PYG{c}{ we call the standard rewrite tactic here }\PYG{c}{*)}
\PYG{k}{rewrite} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{g} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{f} \PYG{l+m+mi}{6}
\end{sphinxVerbatim}

This rewriting is not possible in \DUrole{smallcaps}{SSReflect} because
there is no occurrence of the head symbol \sphinxcode{\sphinxupquote{f}} of the rewrite rule in the
goal.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{n}{H}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{9}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k}{rewrite} \PYG{n}{H}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:}
    \PYG{k+kn}{Ltac} \PYG{n}{call} \PYG{n}{to} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{rewrite (ssrrwargs) (ssrclauses)}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{failed}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{LHS} \PYG{k}{of} \PYG{n}{H}
        \PYG{o}{(}\PYG{n}{g} \PYG{o}{\PYGZus{}}\PYG{o}{)}
    \PYG{n}{does} \PYG{n}{not} \PYG{k}{match} \PYG{n}{any} \PYG{n}{subterm} \PYG{k}{of} \PYG{n}{the} \PYG{n}{goal}
\end{sphinxVerbatim}

Rewriting with \sphinxcode{\sphinxupquote{H}} first requires unfolding the occurrences of
\sphinxcode{\sphinxupquote{f}}
where the substitution is to be performed (here there is a single such
occurrence), using tactic \sphinxcode{\sphinxupquote{rewrite /f}} (for a global replacement of
f by g) or \sphinxcode{\sphinxupquote{rewrite pattern/f}}, for a finer selection.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{o}{/}\PYG{n}{f} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{g} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{g} \PYG{l+m+mi}{6}
\end{sphinxVerbatim}

alternatively one can override the pattern inferred from \sphinxcode{\sphinxupquote{H}}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{o}{[}\PYG{n}{f} \PYG{o}{\PYGZus{}}\PYG{o}{]}\PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{g} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{f} \PYG{l+m+mi}{6}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{itemize}


\paragraph{Existential metavariables and rewriting}
\label{\detokenize{proof-engine/ssreflect-proof-language:existential-metavariables-and-rewriting}}
The rewrite tactic will not instantiate existing existential
metavariables when matching a redex pattern.

If a rewrite rule generates a goal with new existential metavariables
in the \sphinxcode{\sphinxupquote{Prop}} sort, these will be generalized as for \sphinxcode{\sphinxupquote{apply}}
(see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:apply-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{The apply tactic}}}}) and
corresponding new goals will be generated.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{leq} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}\PYG{o}{.}
    \PYG{n}{leq} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{m \PYGZlt{}= n}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{leq} \PYG{n}{m} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat\PYGZus{}scope}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{43}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{m \PYGZlt{}= n}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{leq} \PYG{n}{m} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat\PYGZus{}scope}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Warning}\PYG{o}{:} \PYG{k+kn}{Notation} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{o}{\PYGZus{}} \PYG{n}{was} \PYG{n}{already} \PYG{n}{used} \PYG{k}{in} \PYG{n}{scope} \PYG{n}{nat\PYGZus{}scope}\PYG{o}{.}

\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{m \PYGZlt{} n}\PYG{l+s+s2}{\PYGZdq{}}  \PYG{o}{:=} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat\PYGZus{}scope}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{44}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{m \PYGZlt{} n}\PYG{l+s+s2}{\PYGZdq{}}  \PYG{o}{:=} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat\PYGZus{}scope}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Warning}\PYG{o}{:} \PYG{k+kn}{Notation} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZlt{}} \PYG{o}{\PYGZus{}} \PYG{n}{was} \PYG{n}{already} \PYG{n}{used} \PYG{k}{in} \PYG{n}{scope} \PYG{n}{nat\PYGZus{}scope}\PYG{o}{.}

\PYG{k+kn}{Inductive} \PYG{n}{Ord} \PYG{n}{n} \PYG{o}{:=} \PYG{n}{Sub} \PYG{n}{x} \PYG{k}{of} \PYG{n}{x} \PYG{o}{\PYGZlt{}} \PYG{n}{n}\PYG{o}{.}
    \PYG{n}{Ord} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Ord\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Ord\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Ord\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}I\PYGZus{} n}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{Ord} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{8}\PYG{o}{,} \PYG{n}{n} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{2}\PYG{o}{,} \PYG{n}{format} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}\PYGZsq{}I\PYGZus{}\PYGZsq{} n}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Arguments} \PYG{n}{Sub} \PYG{o}{\PYGZob{}}\PYG{o}{\PYGZus{}}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{val} \PYG{n}{n} \PYG{o}{(}\PYG{n}{i} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}n}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{let}\PYG{o}{:} \PYG{n}{Sub} \PYG{n}{a} \PYG{o}{\PYGZus{}} \PYG{o}{:=} \PYG{n}{i} \PYG{k}{in} \PYG{n}{a}\PYG{o}{.}
    \PYG{n}{val} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{insub} \PYG{n}{n} \PYG{n}{x} \PYG{o}{:=}
  \PYG{k}{if} \PYG{o}{@}\PYG{n}{idP} \PYG{o}{(}\PYG{n}{x} \PYG{o}{\PYGZlt{}} \PYG{n}{n}\PYG{o}{)} \PYG{k}{is} \PYG{n}{ReflectT} \PYG{o}{\PYGZus{}} \PYG{n}{Px} \PYG{k}{then} \PYG{n}{Some} \PYG{o}{(}\PYG{n}{Sub} \PYG{n}{x} \PYG{n}{Px}\PYG{o}{)} \PYG{k}{else} \PYG{n}{None}\PYG{o}{.}
    \PYG{n}{insub} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Axiom} \PYG{n}{insubT} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{x} \PYG{n}{Px}\PYG{o}{,} \PYG{n}{insub} \PYG{n}{n} \PYG{n}{x} \PYG{o}{=} \PYG{n}{Some} \PYG{o}{(}\PYG{n}{Sub} \PYG{n}{x} \PYG{n}{Px}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{insubT} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}2}\PYG{o}{)} \PYG{n}{y} \PYG{o}{:} \PYG{n}{Some} \PYG{n}{x} \PYG{o}{=} \PYG{n}{insub} \PYG{l+m+mi}{2} \PYG{n}{y}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}2}
      \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{Some} \PYG{n}{x} \PYG{o}{=} \PYG{n}{insub} \PYG{l+m+mi}{2} \PYG{n}{y}

\PYG{k}{rewrite} \PYG{n}{insubT}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}2}
      \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{Hyp0} \PYG{o}{:} \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2}\PYG{o}{,} \PYG{n}{Some} \PYG{n}{x} \PYG{o}{=} \PYG{n}{Some} \PYG{o}{(}\PYG{n}{Sub} \PYG{n}{y} \PYG{n}{Hyp0}\PYG{o}{)}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2}
\end{sphinxVerbatim}

Since the argument corresponding to Px is not supplied by the user, the
resulting goal should be \sphinxcode{\sphinxupquote{Some x = Some (Sub y ?Goal).}}
Instead, \DUrole{smallcaps}{SSReflect} \sphinxcode{\sphinxupquote{rewrite}} tactic hides the existential variable.

As in {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:apply-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{The apply tactic}}}}, the \sphinxcode{\sphinxupquote{ssrautoprop}} tactic is used to try to
solve the existential variable.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}2}\PYG{o}{)} \PYG{n}{y} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2}\PYG{o}{)} \PYG{o}{:} \PYG{n}{Some} \PYG{n}{x} \PYG{o}{=} \PYG{n}{insub} \PYG{l+m+mi}{2} \PYG{n}{y}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}2}
      \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{Some} \PYG{n}{x} \PYG{o}{=} \PYG{n}{insub} \PYG{l+m+mi}{2} \PYG{n}{y}

\PYG{k}{rewrite} \PYG{n}{insubT}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{k}{\PYGZsq{}}\PYG{n}{I\PYGZus{}2}
      \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{l+m+mi}{2}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{Some} \PYG{n}{x} \PYG{o}{=} \PYG{n}{Some} \PYG{o}{(}\PYG{n}{Sub} \PYG{n}{y} \PYG{n}{H}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

As a temporary limitation, this behavior is available only if the
rewriting rule is stated using Leibniz equality (as opposed to setoid
relations). It will be extended to other rewriting relations in the
future.


\subsubsection{Locking, unlocking}
\label{\detokenize{proof-engine/ssreflect-proof-language:locking-unlocking}}\label{\detokenize{proof-engine/ssreflect-proof-language:locking-ssr}}
As program proofs tend to generate large goals, it is important to be
able to control the partial evaluation performed by the simplification
operations that are performed by the tactics. These evaluations can
for example come from a \sphinxcode{\sphinxupquote{/=}} simplification switch, or from rewrite
steps which may expand large terms while performing conversion. We
definitely want to avoid repeating large subterms of the goal in the
proof script. We do this by “clamping down” selected function symbols
in the goal, which prevents them from being considered in
simplification or rewriting steps. This clamping is accomplished by
using the occurrence switches (see section:ref:\sphinxtitleref{abbreviations\_ssr})
together with “term tagging” operations.

\DUrole{smallcaps}{SSReflect} provides two levels of tagging.

The first one uses auxiliary definitions to introduce a provably equal
copy of any term t. However this copy is (on purpose) \sphinxstyleemphasis{not
convertible} to t in the \DUrole{smallcaps}{Coq} system %
\begin{footnote}[15]\sphinxAtStartFootnote
This is an implementation feature: there is no such obstruction
in the metatheory
%
\end{footnote}. The job is done by the
following construction:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{master\PYGZus{}key} \PYG{o}{:} \PYG{k+kt}{unit}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k+kp}{exact} \PYG{n}{tt}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{locked} \PYG{n}{A} \PYG{o}{:=} \PYG{k}{let}\PYG{o}{:} \PYG{n}{tt} \PYG{o}{:=} \PYG{n}{master\PYGZus{}key} \PYG{k}{in} \PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{A} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{lock} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{x}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=} \PYG{n}{locked} \PYG{n}{x} \PYG{o}{:\PYGZgt{}} \PYG{n}{A}\PYG{o}{.}
\end{sphinxVerbatim}

Note that the definition of \sphinxstyleemphasis{master\_key} is explicitly opaque. The
equation \sphinxcode{\sphinxupquote{t = locked t}} given by the \sphinxcode{\sphinxupquote{lock}} lemma can be used for
selective rewriting, blocking on the fly the reduction in the term \sphinxcode{\sphinxupquote{t}}.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variable} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{.}
    \PYG{n}{A} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Fixpoint} \PYG{n}{has} \PYG{o}{(}\PYG{n}{p} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{:=}
  \PYG{k}{if} \PYG{n}{l} \PYG{k}{is} \PYG{n}{cons} \PYG{n}{x} \PYG{n}{l} \PYG{k}{then} \PYG{n}{p} \PYG{n}{x} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{o}{(}\PYG{n}{has} \PYG{n}{p} \PYG{n}{l}\PYG{o}{)} \PYG{k}{else} \PYG{n+nb+bp}{false}\PYG{o}{.}
    \PYG{n}{has} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{has} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{2}\PYG{n}{nd} \PYG{n}{argument}\PYG{o}{)}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{p} \PYG{n}{x} \PYG{n}{y} \PYG{n}{l} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{n}{p} \PYG{n}{x} \PYG{o}{=} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{:} \PYG{n}{has} \PYG{n}{p} \PYG{o}{(} \PYG{n}{x} \PYG{o}{::} \PYG{n}{y} \PYG{o}{::} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=} \PYG{n+nb+bp}{true}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{p} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{p} \PYG{n}{x} \PYG{o}{=} \PYG{n+nb+bp}{true}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{has} \PYG{n}{p} \PYG{o}{(}\PYG{n}{x} \PYG{o}{::} \PYG{n}{y} \PYG{o}{::} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=} \PYG{n+nb+bp}{true}

\PYG{k}{rewrite} \PYG{o}{\PYGZob{}}\PYG{l+m+mi}{2}\PYG{o}{\PYGZcb{}}\PYG{o}{[}\PYG{n}{cons}\PYG{o}{]}\PYG{n}{lock} \PYG{o}{/=} \PYG{o}{\PYGZhy{}}\PYG{n}{lock}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{p} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}
      \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{p} \PYG{n}{x} \PYG{o}{=} \PYG{n+nb+bp}{true}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{p} \PYG{n}{x} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{has} \PYG{n}{p} \PYG{o}{(}\PYG{n}{y} \PYG{o}{::} \PYG{n}{l}\PYG{o}{)} \PYG{o}{=} \PYG{n+nb+bp}{true}
\end{sphinxVerbatim}
\end{sphinxadmonition}

It is sometimes desirable to globally prevent a definition from being
expanded by simplification; this is done by adding locked in the
definition.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{lid} \PYG{o}{:=} \PYG{n}{locked} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{lid} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{n}{lid} \PYG{l+m+mi}{3} \PYG{o}{=} \PYG{l+m+mi}{3}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{lid} \PYG{l+m+mi}{3} \PYG{o}{=} \PYG{l+m+mi}{3}

\PYG{k}{rewrite} \PYG{o}{/=}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{lid} \PYG{l+m+mi}{3} \PYG{o}{=} \PYG{l+m+mi}{3}

\PYG{k}{unlock} \PYG{n}{lid}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{3} \PYG{o}{=} \PYG{l+m+mi}{3}
\end{sphinxVerbatim}
\end{sphinxadmonition}

We provide a special tactic unlock for unfolding such definitions
while removing “locks”, e.g., the tactic:
\index{unlock (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.unlock}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{unlock~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\end{fulllineitems}


replaces the occurrence(s) of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} coded by the
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}} with the corresponding body.

We found that it was usually preferable to prevent the expansion of
some functions by the partial evaluation switch \sphinxcode{\sphinxupquote{/=}}, unless this
allowed the evaluation of a condition. This is possible thanks to another
mechanism of term tagging, resting on the following \sphinxstyleemphasis{Notation}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}nosimpl\PYGZsq{} t}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{k}{let}\PYG{o}{:} \PYG{n}{tt} \PYG{o}{:=} \PYG{n}{tt} \PYG{k}{in} \PYG{n}{t}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

The term \sphinxcode{\sphinxupquote{(nosimpl t)}} simplifies to \sphinxcode{\sphinxupquote{t}} \sphinxstyleemphasis{except} in a definition.
More precisely, given:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{foo} \PYG{o}{:=} \PYG{o}{(}\PYG{k}{nosimpl} \PYG{n}{bar}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

the term \sphinxcode{\sphinxupquote{foo}} (or \sphinxcode{\sphinxupquote{(foo t’)}}) will \sphinxstyleemphasis{not} be expanded by the \sphinxstyleemphasis{simpl}
tactic unless it is in a forcing context (e.g., in \sphinxcode{\sphinxupquote{match foo t’ with …
end}}, \sphinxcode{\sphinxupquote{foo t’}} will be reduced if this allows \sphinxcode{\sphinxupquote{match}} to be reduced).
Note that \sphinxcode{\sphinxupquote{nosimpl bar}} is simply notation for a term that reduces to
\sphinxcode{\sphinxupquote{bar}}; hence \sphinxcode{\sphinxupquote{unfold foo}} will replace \sphinxcode{\sphinxupquote{foo}} by \sphinxcode{\sphinxupquote{bar}}, and
\sphinxcode{\sphinxupquote{fold foo}} will replace \sphinxcode{\sphinxupquote{bar}} by \sphinxcode{\sphinxupquote{foo}}.

\begin{sphinxadmonition}{warning}{Warning:}
The \sphinxcode{\sphinxupquote{nosimpl}} trick only works if no reduction is apparent in
\sphinxcode{\sphinxupquote{t}}; in particular, the declaration:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{foo} \PYG{n}{x} \PYG{o}{:=} \PYG{k}{nosimpl} \PYG{o}{(}\PYG{n}{bar} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

will usually not work. Anyway, the common practice is to tag only the
function, and to use the following definition, which blocks the
reduction as expected:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{foo} \PYG{n}{x} \PYG{o}{:=} \PYG{k}{nosimpl} \PYG{n}{bar} \PYG{n}{x}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

A standard example making this technique shine is the case of
arithmetic operations. We define for instance:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{addn} \PYG{o}{:=} \PYG{k}{nosimpl} \PYG{n}{plus}\PYG{o}{.}
\end{sphinxVerbatim}

The operation \sphinxcode{\sphinxupquote{addn}} behaves exactly like \sphinxcode{\sphinxupquote{plus}}, except that
\sphinxcode{\sphinxupquote{(addn (S n) m)}} will not simplify spontaneously to
\sphinxcode{\sphinxupquote{(S (addn n m))}} (the two terms, however, are convertible).
In addition, the unfolding step: \sphinxcode{\sphinxupquote{rewrite /addn}}
will replace \sphinxcode{\sphinxupquote{addn}} directly with \sphinxcode{\sphinxupquote{plus}}, so the \sphinxcode{\sphinxupquote{nosimpl}} form is
essentially invisible.


\subsubsection{Congruence}
\label{\detokenize{proof-engine/ssreflect-proof-language:congruence}}\label{\detokenize{proof-engine/ssreflect-proof-language:congruence-ssr}}
Because of the way matching interferes with parameters of type families,
the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{apply}\PYG{o}{:} \PYG{n}{my\PYGZus{}congr\PYGZus{}property}\PYG{o}{.}
\end{sphinxVerbatim}

will generally fail to perform congruence simplification, even on
rather simple cases. We therefore provide a more robust alternative in
which the function is supplied:
\index{congr (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.congr}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{congr~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


This tactic:
+ checks that the goal is a Leibniz equality
+ matches both sides of this equality with “term applied to some arguments”, inferring the right number of arguments from the goal and the type of term. This may expand some definitions or fixpoints.
+ generates the subgoals corresponding to pairwise equalities of the arguments present in the goal.

The goal can be a non dependent product \sphinxcode{\sphinxupquote{P -\textgreater{} Q}}. In that case, the
system asserts the equation \sphinxcode{\sphinxupquote{P = Q}}, uses it to solve the goal, and
calls the \sphinxcode{\sphinxupquote{congr}} tactic on the remaining goal \sphinxcode{\sphinxupquote{P = Q}}. This can be useful
for instance to perform a transitivity step, like in the following
situation.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}\PYG{o}{)} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{z}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{=} \PYG{n}{z}

\PYG{k}{congr} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{=} \PYG{o}{\PYGZus{}}\PYG{o}{)} \PYG{o}{:} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{focused} \PYG{n}{subgoal}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{1}\PYG{o}{)}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{y} \PYG{o}{=} \PYG{n}{z}

\PYG{n}{Abort}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{=} \PYG{n}{z}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{=} \PYG{n}{z}

\PYG{k}{congr} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{=} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{focused} \PYG{n}{subgoal}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{1}\PYG{o}{)}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{y} \PYG{o}{=} \PYG{n}{z}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The optional {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{num}}}}} forces the number of arguments for which the
tactic should generate equality proof obligations.

This tactic supports equalities between applications with dependent
arguments. Yet dependent arguments should have exactly the same
parameters on both sides, and these parameters should appear as first
arguments.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{f} \PYG{n}{n} \PYG{o}{:=}
  \PYG{k}{if} \PYG{n}{n} \PYG{k}{is} \PYG{l+m+mi}{0} \PYG{k}{then} \PYG{n}{plus} \PYG{k}{else} \PYG{n}{mult}\PYG{o}{.}
    \PYG{n}{f} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{g} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{plus}\PYG{o}{.}
    \PYG{n}{g} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{f} \PYG{l+m+mi}{0} \PYG{n}{x} \PYG{n}{y} \PYG{o}{=} \PYG{n}{g} \PYG{l+m+mi}{1} \PYG{l+m+mi}{1} \PYG{n}{x} \PYG{n}{y}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{f} \PYG{l+m+mi}{0} \PYG{n}{x} \PYG{n}{y} \PYG{o}{=} \PYG{n}{g} \PYG{l+m+mi}{1} \PYG{l+m+mi}{1} \PYG{n}{x} \PYG{n}{y}

\PYG{k}{congr} \PYG{n}{plus}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}

This script shows that the \sphinxcode{\sphinxupquote{congr}} tactic matches \sphinxcode{\sphinxupquote{plus}}
with \sphinxcode{\sphinxupquote{f 0}} on the left hand side and \sphinxcode{\sphinxupquote{g 1 1}} on the right hand
side, and solves the goal.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{n} \PYG{n}{m} \PYG{o}{(}\PYG{n}{Hnm} \PYG{o}{:} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:} \PYG{n}{S} \PYG{n}{m} \PYG{o}{+} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n} \PYG{o}{\PYGZhy{}} \PYG{n}{S} \PYG{n}{m}\PYG{o}{)} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{Hnm} \PYG{o}{:} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{S} \PYG{n}{m} \PYG{o}{+} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n} \PYG{o}{\PYGZhy{}} \PYG{n}{S} \PYG{n}{m}\PYG{o}{)} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n}

\PYG{k}{congr} \PYG{n}{S}\PYG{o}{;} \PYG{k}{rewrite} \PYG{o}{\PYGZhy{}}\PYG{o}{/}\PYG{n}{plus}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{Hnm} \PYG{o}{:} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{m} \PYG{o}{+} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n} \PYG{o}{\PYGZhy{}} \PYG{n}{S} \PYG{n}{m}\PYG{o}{)} \PYG{o}{=} \PYG{n}{n}
\end{sphinxVerbatim}

The tactic \sphinxcode{\sphinxupquote{rewrite -/plus}} folds back the expansion of plus
which was necessary for matching both sides of the equality with
an application of \sphinxcode{\sphinxupquote{S}}.
\end{sphinxadmonition}

Like most \DUrole{smallcaps}{SSReflect} arguments, term can contain wildcards.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{x} \PYG{o}{+} \PYG{o}{(}\PYG{n}{y} \PYG{o}{*} \PYG{o}{(}\PYG{n}{y} \PYG{o}{+} \PYG{n}{x} \PYG{o}{\PYGZhy{}} \PYG{n}{x}\PYG{o}{)}\PYG{o}{)} \PYG{o}{=} \PYG{n}{x} \PYG{o}{*} \PYG{l+m+mi}{1} \PYG{o}{+} \PYG{o}{(}\PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{*} \PYG{n}{y}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{*} \PYG{o}{(}\PYG{n}{y} \PYG{o}{+} \PYG{n}{x} \PYG{o}{\PYGZhy{}} \PYG{n}{x}\PYG{o}{)} \PYG{o}{=} \PYG{n}{x} \PYG{o}{*} \PYG{l+m+mi}{1} \PYG{o}{+} \PYG{o}{(}\PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{*} \PYG{n}{y}

\PYG{k}{congr} \PYG{o}{(} \PYG{o}{\PYGZus{}} \PYG{o}{+} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{*} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{3} \PYG{n}{focused} \PYG{n}{subgoals}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{3}\PYG{o}{)}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{=} \PYG{n}{x} \PYG{o}{*} \PYG{l+m+mi}{1}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{y} \PYG{o}{=} \PYG{n}{y} \PYG{o}{+} \PYG{l+m+mi}{0}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{y} \PYG{o}{+} \PYG{n}{x} \PYG{o}{\PYGZhy{}} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsection{Contextual patterns}
\label{\detokenize{proof-engine/ssreflect-proof-language:contextual-patterns}}\label{\detokenize{proof-engine/ssreflect-proof-language:contextual-patterns-ssr}}
The simple form of patterns used so far, terms possibly containing
wild cards, often require an additional {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{occ\_switch}}}}} to be specified.
While this may work pretty fine for small goals, the use of
polymorphic functions and dependent types may lead to an invisible
duplication of function arguments. These copies usually end up in
types hidden by the implicit arguments machinery or by user-defined
notations. In these situations computing the right occurrence numbers
is very tedious because they must be counted on the goal as printed
after setting the {\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-all}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}} flag. Moreover the resulting script is
not really informative for the reader, since it refers to occurrence
numbers he cannot easily see.

Contextual patterns mitigate these issues allowing to specify
occurrences according to the context they occur in.


\subsubsection{Syntax}
\label{\detokenize{proof-engine/ssreflect-proof-language:syntax}}
The following table summarizes the full syntax of {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{c\_pattern}}}}} and the
corresponding subterm(s) identified by the pattern. In the third
column we use s.m.r. for “the subterms matching the redex” specified
in the second column.


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
\hline
\sphinxstyletheadfamily 
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{c\_pattern}}}}}
&\sphinxstyletheadfamily 
redex
&\sphinxstyletheadfamily 
subterms affected
\\
\hline
\sphinxcode{\sphinxupquote{term}}
&
\sphinxcode{\sphinxupquote{term}}
&
all occurrences of \sphinxcode{\sphinxupquote{term}}
\\
\hline
\sphinxcode{\sphinxupquote{ident in term}}
&
subterm of \sphinxcode{\sphinxupquote{term}} selected by \sphinxcode{\sphinxupquote{ident}}
&
all the subterms identified by \sphinxcode{\sphinxupquote{ident}} in all the
occurrences of \sphinxcode{\sphinxupquote{term}}
\\
\hline
\sphinxcode{\sphinxupquote{term1 in ident in term2}}
&
\sphinxcode{\sphinxupquote{term1}} in all s.m.r.
&
in all the subterms identified by
\sphinxcode{\sphinxupquote{ident}} in all the occurrences of \sphinxcode{\sphinxupquote{term2}}
\\
\hline
\sphinxcode{\sphinxupquote{term1 as ident in term2}}
&
\sphinxcode{\sphinxupquote{term 1}}
&
in all the subterms identified by \sphinxcode{\sphinxupquote{ident{}`
in all the occurrences of {}`{}`term2{[}term 1 /ident{]}}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

The rewrite tactic supports two more patterns obtained prefixing the
first two with in. The intended meaning is that the pattern identifies
all subterms of the specified context. The \sphinxcode{\sphinxupquote{rewrite}} tactic will infer a
pattern for the redex looking at the rule used for rewriting.


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
\hline
\sphinxstyletheadfamily 
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_pattern}}}}}
&\sphinxstyletheadfamily 
redex
&\sphinxstyletheadfamily 
subterms affected
\\
\hline
\sphinxcode{\sphinxupquote{in term}}
&
inferred from rule
&
in all s.m.r. in all occurrences of \sphinxcode{\sphinxupquote{term}}
\\
\hline
\sphinxcode{\sphinxupquote{in ident in term}}
&
inferred from rule
&
in all s.m.r. in all the subterms identified by \sphinxcode{\sphinxupquote{ident}}
in all the occurrences of \sphinxcode{\sphinxupquote{term}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

The first {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{c\_pattern}}}}} is the simplest form matching any context but
selecting a specific redex and has been described in the previous
sections. We have seen so far that the possibility of selecting a
redex using a term with holes is already a powerful means of redex
selection. Similarly, any terms provided by the user in the more
complex forms of \sphinxcode{\sphinxupquote{c\_patterns}}
presented in the tables above can contain
holes.

For a quick glance at what can be expressed with the last
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_pattern}}}}}
consider the goal \sphinxcode{\sphinxupquote{a = b}} and the tactic

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{o}{[}\PYG{k}{in} \PYG{n}{X} \PYG{k}{in} \PYG{o}{\PYGZus{}} \PYG{o}{=} \PYG{n}{X}\PYG{o}{]}\PYG{n}{rule}\PYG{o}{.}
\end{sphinxVerbatim}

It rewrites all occurrences of the left hand side of \sphinxcode{\sphinxupquote{rule}}
inside \sphinxcode{\sphinxupquote{b}}  only (\sphinxcode{\sphinxupquote{a}}, and the hidden type of the equality, are ignored). Note that the
variant \sphinxcode{\sphinxupquote{rewrite {[}X in \_ = X{]}rule}} would have rewritten \sphinxcode{\sphinxupquote{b}}
exactly (i.e., it would only work if \sphinxcode{\sphinxupquote{b}} and the left hand side
of rule can be unified).


\subsubsection{Matching contextual patterns}
\label{\detokenize{proof-engine/ssreflect-proof-language:matching-contextual-patterns}}
The {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{c\_pattern}}}}} and {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_pattern}}}}} involving terms
with holes are matched
against the goal in order to find a closed instantiation. This
matching proceeds as follows:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline
\sphinxstyletheadfamily 
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{c\_pattern}}}}}
&\sphinxstyletheadfamily 
instantiation order and place for \sphinxcode{\sphinxupquote{term\_i}} and redex
\\
\hline
\sphinxcode{\sphinxupquote{term}}
&
\sphinxcode{\sphinxupquote{term}} is matched against the goal, redex is unified with
the instantiation of \sphinxcode{\sphinxupquote{term}}
\\
\hline
\sphinxcode{\sphinxupquote{ident in term}}
&
\sphinxcode{\sphinxupquote{term}} is matched against the goal, redex is unified with the
subterm of the instantiation of \sphinxcode{\sphinxupquote{term}} identified by
\sphinxcode{\sphinxupquote{ident}}
\\
\hline
\sphinxcode{\sphinxupquote{term1 in ident in term2}}
&
\sphinxcode{\sphinxupquote{term2}} is matched against the goal, \sphinxcode{\sphinxupquote{term1}}
is matched against the subterm of the instantiation of
\sphinxcode{\sphinxupquote{term1}} identified by \sphinxcode{\sphinxupquote{ident}}, redex is unified with
the instantiation of \sphinxcode{\sphinxupquote{term1}}
\\
\hline
\sphinxcode{\sphinxupquote{term1 as ident in term2}}
&
\sphinxcode{\sphinxupquote{term2{[}term1/ident{]}}} is matched against
the goal, redex is unified with the instantiation of \sphinxcode{\sphinxupquote{term1}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

In the following patterns, the redex is intended to be inferred from
the rewrite rule.


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|}
\hline
\sphinxstyletheadfamily 
{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{r\_pattern}}}}}
&\sphinxstyletheadfamily 
instantiation order and place for \sphinxcode{\sphinxupquote{term\_i}} and redex
\\
\hline
\sphinxcode{\sphinxupquote{in ident in term}}
&
\sphinxcode{\sphinxupquote{term}} is matched against the goal, the redex is matched against
the subterm of the instantiation of \sphinxcode{\sphinxupquote{term}} identified by
\sphinxcode{\sphinxupquote{ident}}
\\
\hline
\sphinxcode{\sphinxupquote{in term}}
&
\sphinxcode{\sphinxupquote{term}} is matched against the goal, redex is matched against the
instantiation of \sphinxcode{\sphinxupquote{term}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}


\subsubsection{Examples}
\label{\detokenize{proof-engine/ssreflect-proof-language:examples}}

\paragraph{Contextual pattern in set and the : tactical}
\label{\detokenize{proof-engine/ssreflect-proof-language:contextual-pattern-in-set-and-the-tactical}}
As already mentioned in section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:abbreviations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations}}}} the \sphinxcode{\sphinxupquote{set}}
tactic takes as an
argument a term in open syntax. This term is interpreted as the
simplest form of {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{c\_pattern}}}}}. To avoid confusion in the grammar, open
syntax is supported only for the simplest form of patterns, while
parentheses are required around more complex patterns.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{a} \PYG{o}{+} \PYG{n}{b} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{n}{b} \PYG{o}{+} \PYG{o}{(}\PYG{n}{a} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{a} \PYG{o}{+} \PYG{n}{b} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{n}{b} \PYG{o}{+} \PYG{o}{(}\PYG{n}{a} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{)}

\PYG{k}{set} \PYG{n}{t} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{X} \PYG{k}{in} \PYG{o}{\PYGZus{}} \PYG{o}{=} \PYG{n}{X}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{t} \PYG{o}{:=} \PYG{n}{b} \PYG{o}{+} \PYG{o}{(}\PYG{n}{a} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{a} \PYG{o}{+} \PYG{n}{b} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{n}{t}

\PYG{k}{rewrite} \PYG{o}{\PYGZob{}}\PYG{o}{\PYGZcb{}}\PYG{o}{/}\PYG{n}{t}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{a} \PYG{o}{+} \PYG{n}{b} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{n}{b} \PYG{o}{+} \PYG{o}{(}\PYG{n}{a} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{)}

\PYG{k}{set} \PYG{n}{t} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{a} \PYG{o}{+} \PYG{o}{\PYGZus{}} \PYG{k}{in} \PYG{n}{X} \PYG{k}{in} \PYG{o}{\PYGZus{}} \PYG{o}{=} \PYG{n}{X}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{t} \PYG{o}{:=} \PYG{n}{a} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{a} \PYG{o}{+} \PYG{n}{b} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{n}{b} \PYG{o}{+} \PYG{n}{t}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Since the user may define an infix notation for \sphinxcode{\sphinxupquote{in}} the result of the former
tactic may be ambiguous. The disambiguation rule implemented is to prefer
patterns over simple terms, but to interpret a pattern with double
parentheses as a simple term. For example, the following tactic would
capture any occurrence of the term \sphinxcode{\sphinxupquote{a in A}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{set} \PYG{n}{t} \PYG{o}{:=} \PYG{o}{(}\PYG{o}{(}\PYG{n}{a} \PYG{k}{in} \PYG{n}{A}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

Contextual patterns can also be used as arguments of the \sphinxcode{\sphinxupquote{:}} tactical.
For example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{elim}\PYG{o}{:} \PYG{n}{n} \PYG{o}{(}\PYG{n}{n} \PYG{k}{in} \PYG{o}{\PYGZus{}} \PYG{o}{=} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{refl\PYGZus{}equal} \PYG{n}{n}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}


\paragraph{Contextual patterns in rewrite}
\label{\detokenize{proof-engine/ssreflect-proof-language:contextual-patterns-in-rewrite}}
\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{n .+1}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{Datatypes}\PYG{o}{.}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{2}\PYG{o}{,} \PYG{k}{left} \PYG{n}{associativity}\PYG{o}{,}
                     \PYG{n}{format} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{n .+1}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)} \PYG{o}{:} \PYG{n}{nat\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{addSn} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m} \PYG{n}{n}\PYG{o}{,} \PYG{n}{m}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{n}\PYG{o}{)}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1}\PYG{o}{.}
    \PYG{n}{addSn} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Axiom} \PYG{n}{addn0} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m}\PYG{o}{,} \PYG{n}{m} \PYG{o}{+} \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
    \PYG{n}{addn0} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Axiom} \PYG{n}{addnC} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{m} \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{.}
    \PYG{n}{addnC} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{n}{f} \PYG{o}{:} \PYG{o}{(}\PYG{n}{x}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)} \PYG{o}{+} \PYG{n}{f} \PYG{o}{(}\PYG{n}{x}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{n}{z} \PYG{o}{+} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{f} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{f} \PYG{o}{(}\PYG{n}{x}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{n}{z} \PYG{o}{+} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{k}{rewrite} \PYG{o}{[}\PYG{k}{in} \PYG{n}{f} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{]}\PYG{n}{addSn}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{f} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{f} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{(}\PYG{n}{z} \PYG{o}{+} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}

Note: the simplification rule \sphinxcode{\sphinxupquote{addSn}} is applied only under the \sphinxcode{\sphinxupquote{f}}
symbol.
Then we simplify also the first addition and expand 0 into 0+0.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{n}{addSn} \PYG{o}{\PYGZhy{}}\PYG{o}{[}\PYG{n}{X} \PYG{k}{in} \PYG{o}{\PYGZus{}} \PYG{o}{=} \PYG{n}{X}\PYG{o}{]}\PYG{n}{addn0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{f} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{f} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{(}\PYG{n}{z} \PYG{o}{+} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}

Note that the right hand side of \sphinxcode{\sphinxupquote{addn0}} is undetermined, but the
rewrite pattern specifies the redex explicitly. The right hand side
of \sphinxcode{\sphinxupquote{addn0}} is unified with the term identified by \sphinxcode{\sphinxupquote{X}}, here \sphinxcode{\sphinxupquote{0}}.

The following pattern does not specify a redex, since it identifies an
entire region, hence the rewrite rule has to be instantiated
explicitly. Thus the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{o}{\PYGZhy{}}\PYG{o}{\PYGZob{}}\PYG{l+m+mi}{2}\PYG{o}{\PYGZcb{}}\PYG{o}{[}\PYG{k}{in} \PYG{n}{X} \PYG{k}{in} \PYG{o}{\PYGZus{}} \PYG{o}{=} \PYG{n}{X}\PYG{o}{]}\PYG{o}{(}\PYG{n}{addn0} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{f} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{f} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{(}\PYG{n}{z} \PYG{o}{+} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)}
\end{sphinxVerbatim}

The following tactic is quite tricky:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{o}{[}\PYG{o}{\PYGZus{}}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{k}{in} \PYG{n}{X} \PYG{k}{in} \PYG{n}{f} \PYG{o}{\PYGZus{}} \PYG{n}{X}\PYG{o}{]}\PYG{o}{(}\PYG{n}{addnC} \PYG{n}{x}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{f} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{f} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{(}\PYG{n}{z} \PYG{o}{+} \PYG{o}{(}\PYG{n}{y} \PYG{o}{+} \PYG{n}{x}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)}
\end{sphinxVerbatim}

The explicit redex \sphinxcode{\sphinxupquote{\_.+1}} is important since its head constant \sphinxcode{\sphinxupquote{S}}
differs from the head constant inferred from
\sphinxcode{\sphinxupquote{(addnC x.+1)}} (that is \sphinxcode{\sphinxupquote{+}}).
Moreover, the pattern \sphinxcode{\sphinxupquote{f \_ X}} is important to rule out
the first occurrence of \sphinxcode{\sphinxupquote{(x + y).+1}}.
Last, only the subterms of \sphinxcode{\sphinxupquote{f \_ X}}
identified by \sphinxcode{\sphinxupquote{X}} are rewritten, thus the first argument of
\sphinxcode{\sphinxupquote{f}} is skipped too.
Also note the pattern \sphinxcode{\sphinxupquote{\_.+1}} is interpreted in the context
identified by \sphinxcode{\sphinxupquote{X}}, thus it gets instantiated to
\sphinxcode{\sphinxupquote{(y + x).+1}} and not \sphinxcode{\sphinxupquote{(x + y).+1}}.

The last rewrite pattern allows to specify exactly the shape of the
term identified by X, that is thus unified with the left hand side of
the rewrite rule.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{rewrite} \PYG{o}{[}\PYG{n}{x}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{y} \PYG{k}{as} \PYG{n}{X} \PYG{k}{in} \PYG{n}{f} \PYG{n}{X} \PYG{o}{\PYGZus{}}\PYG{o}{]}\PYG{n}{addnC}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{f} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1} \PYG{o}{+} \PYG{n}{f} \PYG{o}{(}\PYG{n}{y} \PYG{o}{+} \PYG{n}{x}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1}\PYG{o}{)} \PYG{o}{(}\PYG{n}{z} \PYG{o}{+} \PYG{o}{(}\PYG{n}{y} \PYG{o}{+} \PYG{n}{x}\PYG{o}{.}\PYG{o}{+}\PYG{l+m+mi}{1}\PYG{o}{)}\PYG{o}{)} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Patterns for recurrent contexts}
\label{\detokenize{proof-engine/ssreflect-proof-language:patterns-for-recurrent-contexts}}
The user can define shortcuts for recurrent contexts corresponding to
the \sphinxcode{\sphinxupquote{ident in term}} part. The notation scope identified with
\sphinxcode{\sphinxupquote{\%pattern}}
provides a special notation \sphinxcode{\sphinxupquote{(X in t)}} the user must adopt
in order to define
context shortcuts.

The following example is taken from \sphinxcode{\sphinxupquote{ssreflect.v}} where the
\sphinxcode{\sphinxupquote{LHS}} and \sphinxcode{\sphinxupquote{RHS}} shortcuts are defined.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{n}{RHS} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{X} \PYG{k}{in} \PYG{o}{\PYGZus{}} \PYG{o}{=} \PYG{n}{X}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{k}{pattern}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{n}{LHS} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{X} \PYG{k}{in} \PYG{n}{X} \PYG{o}{=} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{k}{pattern}\PYG{o}{.}
\end{sphinxVerbatim}

Shortcuts defined this way can be freely used in place of the trailing
\sphinxcode{\sphinxupquote{ident in term}} part of any contextual pattern. Some examples follow:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{set} \PYG{n}{rhs} \PYG{o}{:=} \PYG{n}{RHS}\PYG{o}{.}
\PYG{k}{rewrite} \PYG{o}{[}\PYG{k}{in} \PYG{n}{RHS}\PYG{o}{]}\PYG{n}{rule}\PYG{o}{.}
\PYG{k}{case}\PYG{o}{:} \PYG{o}{(}\PYG{n}{a} \PYG{o}{+} \PYG{o}{\PYGZus{}} \PYG{k}{in} \PYG{n}{RHS}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}


\subsection{Views and reflection}
\label{\detokenize{proof-engine/ssreflect-proof-language:views-and-reflection}}\label{\detokenize{proof-engine/ssreflect-proof-language:views-and-reflection-ssr}}
The bookkeeping facilities presented in section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:basic-tactics-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Basic tactics}}}} are
crafted to ease simultaneous introductions and generalizations of facts and
operations of casing, naming etc. It also a common practice to make a stack
operation immediately followed by an \sphinxstyleemphasis{interpretation} of the fact
being pushed, that is, to apply a lemma to this fact before passing it
to a tactic for decomposition, application and so on.

\DUrole{smallcaps}{SSReflect} provides a convenient, unified syntax to combine these
interpretation operations with the proof stack operations. This \sphinxstyleemphasis{view
mechanism} relies on the combination of the \sphinxcode{\sphinxupquote{/}} view switch with
bookkeeping tactics and tacticals.


\subsubsection{Interpreting eliminations}
\label{\detokenize{proof-engine/ssreflect-proof-language:interpreting-eliminations}}
The view syntax combined with the \sphinxcode{\sphinxupquote{elim}} tactic specifies an elimination
scheme to be used instead of the default, generated, one. Hence the
\DUrole{smallcaps}{SSReflect} tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{elim}\PYG{o}{/}\PYG{n}{V}\PYG{o}{.}
\end{sphinxVerbatim}

is a synonym for:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{intro} \PYG{n}{top}\PYG{o}{;} \PYG{k}{elim} \PYG{n}{top} \PYG{k}{using} \PYG{n}{V}\PYG{o}{;} \PYG{k}{clear} \PYG{n}{top}\PYG{o}{.}
\end{sphinxVerbatim}

where top is a fresh name and V any second-order lemma.

Since an elimination view supports the two bookkeeping tacticals of
discharge and introduction (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:basic-tactics-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Basic tactics}}}}),
the \DUrole{smallcaps}{SSReflect} tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{elim}\PYG{o}{/}\PYG{n}{V}\PYG{o}{:} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{y}\PYG{o}{.}
\end{sphinxVerbatim}

is a synonym for:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{elim} \PYG{n}{x} \PYG{k}{using} \PYG{n}{V}\PYG{o}{;} \PYG{k}{clear} \PYG{n}{x}\PYG{o}{;} \PYG{k}{intro} \PYG{n}{y}\PYG{o}{.}
\end{sphinxVerbatim}

where \sphinxcode{\sphinxupquote{x}} is a variable in the context, \sphinxcode{\sphinxupquote{y}} a fresh name and \sphinxcode{\sphinxupquote{V}}
any second order lemma; \DUrole{smallcaps}{SSReflect} relaxes the syntactic restrictions of the \DUrole{smallcaps}{Coq}
\sphinxcode{\sphinxupquote{elim}}. The first pattern following \sphinxcode{\sphinxupquote{:}} can be a \sphinxcode{\sphinxupquote{\_}} wildcard if the
conclusion of the view \sphinxcode{\sphinxupquote{V}} specifies a pattern for its last argument
(e.g., if \sphinxcode{\sphinxupquote{V}} is a functional induction lemma generated by the
\sphinxcode{\sphinxupquote{Function}} command).

The elimination view mechanism is compatible with the equation name
generation (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:generation-of-equations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of equations}}}}).

\begin{sphinxadmonition}{note}{Example}
\begin{quote}

The following script illustrates a toy example of this feature. Let us
define a function adding an element at the end of a list:
\end{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variable} \PYG{n}{d} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{.}
    \PYG{n}{d} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Fixpoint} \PYG{n}{add\PYGZus{}last} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{d}\PYG{o}{)} \PYG{o}{(}\PYG{n}{z} \PYG{o}{:} \PYG{n}{d}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{s}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{d} \PYG{o}{:=}
  \PYG{k}{if} \PYG{n}{s} \PYG{k}{is} \PYG{n}{cons} \PYG{n}{x} \PYG{n}{s\PYGZsq{}} \PYG{k}{then} \PYG{n}{cons} \PYG{n}{x} \PYG{o}{(}\PYG{n}{add\PYGZus{}last} \PYG{n}{s\PYGZsq{}} \PYG{n}{z}\PYG{o}{)} \PYG{k}{else} \PYG{n}{z} \PYG{o}{::} \PYG{n}{nil}\PYG{o}{.}
    \PYG{n}{add\PYGZus{}last} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{add\PYGZus{}last} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}

One can define an alternative, reversed, induction principle on
inductively defined lists, by proving the following lemma:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{last\PYGZus{}ind\PYGZus{}list} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{d} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{,}
  \PYG{n}{P} \PYG{n}{nil} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{s} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{d}\PYG{o}{)}\PYG{o}{,} \PYG{n}{P} \PYG{n}{s} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{(}\PYG{n}{add\PYGZus{}last} \PYG{n}{s} \PYG{n}{x}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
    \PYG{k}{forall} \PYG{n}{s} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{d}\PYG{o}{,} \PYG{n}{P} \PYG{n}{s}\PYG{o}{.}
    \PYG{n}{last\PYGZus{}ind\PYGZus{}list} \PYG{k}{is} \PYG{n}{declared}
\end{sphinxVerbatim}

Then the combination of elimination views with equation names result
in a concise syntax for reasoning inductively using the user-defined
elimination scheme.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{d}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{d}\PYG{o}{)}\PYG{o}{:} \PYG{n}{l} \PYG{o}{=} \PYG{n}{l}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{d} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{d}
      \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{d}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{l} \PYG{o}{=} \PYG{n}{l}

\PYG{k}{elim}\PYG{o}{/}\PYG{n}{last\PYGZus{}ind\PYGZus{}list} \PYG{n}{E} \PYG{o}{:} \PYG{n}{l}\PYG{o}{=\PYGZgt{}} \PYG{o}{[\textbar{}} \PYG{n}{u} \PYG{n}{v}\PYG{o}{]}\PYG{o}{;} \PYG{k+kr}{last} \PYG{k+kr}{first}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{d} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{d}
      \PYG{n}{u} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{d}
      \PYG{n}{v} \PYG{o}{:} \PYG{n}{d}
      \PYG{n}{l} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{d}
      \PYG{n}{E} \PYG{o}{:} \PYG{n}{l} \PYG{o}{=} \PYG{n}{add\PYGZus{}last} \PYG{n}{u} \PYG{n}{v}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{u} \PYG{o}{=} \PYG{n}{u} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{add\PYGZus{}last} \PYG{n}{u} \PYG{n}{v} \PYG{o}{=} \PYG{n}{add\PYGZus{}last} \PYG{n}{u} \PYG{n}{v}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{nil} \PYG{o}{=} \PYG{n}{nil}
\end{sphinxVerbatim}
\end{sphinxadmonition}

User-provided eliminators (potentially generated with \DUrole{smallcaps}{Coq}’s \sphinxcode{\sphinxupquote{Function}}
command) can be combined with the type family switches described
in section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:type-families-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Type families}}}}.
Consider an eliminator \sphinxcode{\sphinxupquote{foo\_ind}} of type:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
foo\PYGZus{}ind : forall …, forall x : T, P p1 … pm.
\end{sphinxVerbatim}

and consider the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
elim/foo\PYGZus{}ind: e1 … / en.
\end{sphinxVerbatim}

The \sphinxcode{\sphinxupquote{elim/}} tactic distinguishes two cases:
\begin{quote}\begin{description}
\item[{truncated eliminator}] \leavevmode
when \sphinxcode{\sphinxupquote{x}} does not occur in \sphinxcode{\sphinxupquote{P p1 … pm}} and the
type of \sphinxcode{\sphinxupquote{en}} unifies with \sphinxcode{\sphinxupquote{T}} and \sphinxcode{\sphinxupquote{en}} is not \sphinxcode{\sphinxupquote{\_}}.
In that case, \sphinxcode{\sphinxupquote{en}} is
passed to the eliminator as the last argument (\sphinxcode{\sphinxupquote{x}} in \sphinxcode{\sphinxupquote{foo\_ind}}) and
\sphinxcode{\sphinxupquote{en−1 … e1}} are used as patterns to select in the goal the occurrences that
will be bound by the predicate \sphinxcode{\sphinxupquote{P}}, thus it must be possible to unify
the sub-term of the goal matched by \sphinxcode{\sphinxupquote{en−1}} with \sphinxcode{\sphinxupquote{pm}} , the one matched
by \sphinxcode{\sphinxupquote{en−2}} with \sphinxcode{\sphinxupquote{pm−1}} and so on.

\item[{regular eliminator}] \leavevmode
in all the other cases. Here it must be possible
to unify the term matched by \sphinxcode{\sphinxupquote{en}} with \sphinxcode{\sphinxupquote{pm}} , the one matched by
\sphinxcode{\sphinxupquote{en−1}}
with \sphinxcode{\sphinxupquote{pm−1}} and so on. Note that standard eliminators have the shape
\sphinxcode{\sphinxupquote{…forall x, P … x}}, thus \sphinxcode{\sphinxupquote{en}} is the pattern identifying the
eliminated term, as expected.

\end{description}\end{quote}

As explained in section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:type-families-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Type families}}}}, the initial prefix of
\sphinxcode{\sphinxupquote{ei}} can be omitted.

Here is an example of a regular, but nontrivial, eliminator.

\begin{sphinxadmonition}{note}{Example}

Here is a toy example illustrating this feature.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Function} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{m} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
  \PYG{k}{if} \PYG{n}{n} \PYG{k}{is} \PYG{n}{S} \PYG{n}{p} \PYG{k}{then} \PYG{n}{S} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{m} \PYG{n}{p}\PYG{o}{)} \PYG{k}{else} \PYG{n}{m}\PYG{o}{.}
    \PYG{n}{plus} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{plus} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{2}\PYG{n}{nd} \PYG{n}{argument}\PYG{o}{)}
    \PYG{n}{plus\PYGZus{}equation} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{plus\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{plus\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{plus\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{R\PYGZus{}plus\PYGZus{}correct} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{R\PYGZus{}plus\PYGZus{}complete} \PYG{k}{is} \PYG{n}{defined}

\PYG{n}{About} \PYG{n}{plus\PYGZus{}ind}\PYG{o}{.}
    \PYG{n}{plus\PYGZus{}ind} \PYG{o}{:}
    \PYG{k}{forall} \PYG{o}{(}\PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,}
    \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{n}{p} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{n}{S} \PYG{n}{p} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{p} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{m} \PYG{n}{p}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{(}\PYG{n}{S} \PYG{n}{p}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{m} \PYG{n}{p}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
    \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{\PYGZus{}}\PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,}
     \PYG{n}{n} \PYG{o}{=} \PYG{o}{\PYGZus{}}\PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{match} \PYG{o}{\PYGZus{}}\PYG{n}{x} \PYG{k}{with}
               \PYG{o}{\textbar{}} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{True}
               \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{False}
               \PYG{k}{end} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{\PYGZus{}}\PYG{n}{x} \PYG{n}{m}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{P} \PYG{n}{n} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{m} \PYG{n}{n}\PYG{o}{)}
    
    \PYG{k+kn}{Arguments} \PYG{n}{m}\PYG{o}{,} \PYG{n}{P} \PYG{n}{are} \PYG{n}{implicit}
    \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{nat\PYGZus{}scope} \PYG{n}{function\PYGZus{}scope} \PYG{n}{function\PYGZus{}scope} \PYG{n}{function\PYGZus{}scope}
      \PYG{n}{nat\PYGZus{}scope}\PYG{o}{]}
    \PYG{n}{plus\PYGZus{}ind} \PYG{k}{is} \PYG{n}{transparent}
    \PYG{n}{Expands} \PYG{n}{to}\PYG{o}{:} \PYG{n}{Constant} \PYG{n}{Top}\PYG{o}{.}\PYG{n}{Test}\PYG{o}{.}\PYG{n}{plus\PYGZus{}ind}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{n}{z} \PYG{o}{=} \PYG{n}{plus} \PYG{n}{x} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{y} \PYG{n}{z}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{,} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{plus} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{n}{z} \PYG{o}{=} \PYG{n}{plus} \PYG{n}{x} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{y} \PYG{n}{z}\PYG{o}{)}
\end{sphinxVerbatim}

The following tactics are all valid and perform the same elimination
on this goal.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{elim}\PYG{o}{/}\PYG{n}{plus\PYGZus{}ind}\PYG{o}{:} \PYG{n}{z} \PYG{o}{/} \PYG{o}{(}\PYG{n}{plus} \PYG{o}{\PYGZus{}} \PYG{n}{z}\PYG{o}{)}\PYG{o}{.}
\PYG{k}{elim}\PYG{o}{/}\PYG{n}{plus\PYGZus{}ind}\PYG{o}{:} \PYG{o}{\PYGZob{}}\PYG{n}{z}\PYG{o}{\PYGZcb{}}\PYG{o}{(}\PYG{n}{plus} \PYG{o}{\PYGZus{}} \PYG{n}{z}\PYG{o}{)}\PYG{o}{.}
\PYG{k}{elim}\PYG{o}{/}\PYG{n}{plus\PYGZus{}ind}\PYG{o}{:} \PYG{o}{\PYGZob{}}\PYG{n}{z}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZus{}}\PYG{o}{.}
\PYG{k}{elim}\PYG{o}{/}\PYG{n}{plus\PYGZus{}ind}\PYG{o}{:} \PYG{n}{z} \PYG{o}{/} \PYG{o}{\PYGZus{}}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{elim}\PYG{o}{/}\PYG{n}{plus\PYGZus{}ind}\PYG{o}{:} \PYG{n}{z} \PYG{o}{/} \PYG{o}{\PYGZus{}}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{n} \PYG{n}{p} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,}
      \PYG{n}{n} \PYG{o}{=} \PYG{n}{S} \PYG{n}{p} \PYG{o}{\PYGZhy{}\PYGZgt{}}
      \PYG{n}{plus} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{n}{p} \PYG{o}{=} \PYG{n}{plus} \PYG{n}{x} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{y} \PYG{n}{p}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
      \PYG{n}{S} \PYG{o}{(}\PYG{n}{plus} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{n}{p}\PYG{o}{)} \PYG{o}{=} \PYG{n}{plus} \PYG{n}{x} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{y} \PYG{o}{(}\PYG{n}{S} \PYG{n}{p}\PYG{o}{)}\PYG{o}{)}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{k}{forall} \PYG{n}{n} \PYG{o}{\PYGZus{}}\PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,}
     \PYG{n}{n} \PYG{o}{=} \PYG{o}{\PYGZus{}}\PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}}
     \PYG{k}{match} \PYG{o}{\PYGZus{}}\PYG{n}{x} \PYG{k}{with}
     \PYG{o}{\textbar{}} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{True}
     \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{False}
     \PYG{k}{end} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{plus} \PYG{n}{x} \PYG{n}{y} \PYG{o}{=} \PYG{n}{plus} \PYG{n}{x} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{y} \PYG{o}{\PYGZus{}}\PYG{n}{x}\PYG{o}{)}
\end{sphinxVerbatim}

The two latter examples feature a wildcard pattern: in this case,
the resulting pattern is inferred from the type of the eliminator.
In both these examples, it is \sphinxcode{\sphinxupquote{(plus \_ \_)}}, which matches the subterm
\sphinxcode{\sphinxupquote{plus (plus x y) z}} thus instantiating the last \sphinxcode{\sphinxupquote{\_}} with \sphinxcode{\sphinxupquote{z}}.
Note that the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{elim}\PYG{o}{/}\PYG{n}{plus\PYGZus{}ind}\PYG{o}{:} \PYG{n}{y} \PYG{o}{/} \PYG{o}{\PYGZus{}}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{20}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k}{elim}\PYG{o}{/}\PYG{n}{plus\PYGZus{}ind}\PYG{o}{:} \PYG{n}{y} \PYG{o}{/} \PYG{o}{\PYGZus{}}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:}
    \PYG{k+kn}{Ltac} \PYG{n}{call} \PYG{n}{to} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{elim (ssrarg) (ssrclauses)}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{failed}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{given} \PYG{k}{pattern} \PYG{n}{matches} \PYG{n}{the} \PYG{n}{term} \PYG{n}{y} \PYG{n}{while} \PYG{n}{the} \PYG{n}{inferred} \PYG{k}{pattern} \PYG{n}{z} \PYG{n}{doesn\PYGZsq{}t}
\end{sphinxVerbatim}

triggers an error: in the conclusion
of the \sphinxcode{\sphinxupquote{plus\_ind}} eliminator, the first argument of the predicate
\sphinxcode{\sphinxupquote{P}} should be the same as the second argument of \sphinxcode{\sphinxupquote{plus}}, in the
second argument of \sphinxcode{\sphinxupquote{P}}, but \sphinxcode{\sphinxupquote{y}} and \sphinxcode{\sphinxupquote{z}} do no unify.
\end{sphinxadmonition}

Here is an example of a truncated eliminator:

\begin{sphinxadmonition}{note}{Example}

Consider the goal:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Lemma test p n (n\PYGZus{}gt0 : 0 \PYGZlt{} n) (pr\PYGZus{}p : prime p) :
  p \PYGZpc{}\textbar{} \PYGZbs{}prod\PYGZus{}(i \PYGZlt{}\PYGZhy{} prime\PYGZus{}decomp n \textbar{} i \PYGZbs{}in prime\PYGZus{}decomp n) i.1 \PYGZca{} i.2 \PYGZhy{}\PYGZgt{}
    exists2 x : nat * nat, x \PYGZbs{}in prime\PYGZus{}decomp n \PYGZam{} p = x.1.
Proof.
elim/big\PYGZus{}prop: \PYGZus{} =\PYGZgt{} [\textbar{} u v IHu IHv \textbar{} [q e] /=].
\end{sphinxVerbatim}

where the type of the \sphinxcode{\sphinxupquote{big\_prop}} eliminator is

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
big\PYGZus{}prop: forall (R : Type) (Pb : R \PYGZhy{}\PYGZgt{} Type)
  (idx : R) (op1 : R \PYGZhy{}\PYGZgt{} R \PYGZhy{}\PYGZgt{} R), Pb idx \PYGZhy{}\PYGZgt{}
  (forall x y : R, Pb x \PYGZhy{}\PYGZgt{} Pb y \PYGZhy{}\PYGZgt{} Pb (op1 x y)) \PYGZhy{}\PYGZgt{}
  forall (I : Type) (r : seq I) (P : pred I) (F : I \PYGZhy{}\PYGZgt{} R),
  (forall i : I, P i \PYGZhy{}\PYGZgt{} Pb (F i)) \PYGZhy{}\PYGZgt{}
    Pb (\PYGZbs{}big[op1/idx]\PYGZus{}(i \PYGZlt{}\PYGZhy{} r \textbar{} P i) F i).
\end{sphinxVerbatim}

Since the pattern for the argument of Pb is not specified, the
inferred one is used instead: \sphinxcode{\sphinxupquote{big{[}\_/\_{]}\_(i \textless{}- \_ \textbar{} \_ i) \_ i}},
and after the introductions, the following goals are generated:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
subgoal 1 is:
  p \PYGZpc{}\textbar{} 1 \PYGZhy{}\PYGZgt{} exists2 x : nat * nat, x \PYGZbs{}in prime\PYGZus{}decomp n \PYGZam{} p = x.1
subgoal 2 is:
  p \PYGZpc{}\textbar{} u * v \PYGZhy{}\PYGZgt{} exists2 x : nat * nat, x \PYGZbs{}in prime\PYGZus{}decomp n \PYGZam{} p = x.1
subgoal 3 is:
  (q, e) \PYGZbs{}in prime\PYGZus{}decomp n \PYGZhy{}\PYGZgt{} p \PYGZpc{}\textbar{} q \PYGZca{} e \PYGZhy{}\PYGZgt{}
    exists2 x : nat * nat, x \PYGZbs{}in prime\PYGZus{}decomp n \PYGZam{} p = x.1.
\end{sphinxVerbatim}

Note that the pattern matching algorithm instantiated all the
variables occurring in the pattern.
\end{sphinxadmonition}


\subsubsection{Interpreting assumptions}
\label{\detokenize{proof-engine/ssreflect-proof-language:interpreting-assumptions}}\label{\detokenize{proof-engine/ssreflect-proof-language:interpreting-assumptions-ssr}}
Interpreting an assumption in the context of a proof consists in
applying to it a lemma before generalizing, and/or decomposing this
assumption. For instance, with the extensive use of boolean reflection
(see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:views-and-reflection-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Views and reflection}}}}.4), it is quite frequent
to need to decompose the logical interpretation of (the boolean
expression of) a fact, rather than the fact itself. This can be
achieved by a combination of \sphinxcode{\sphinxupquote{move : \_ =\textgreater{} \_}} switches, like in the
following example, where \sphinxcode{\sphinxupquote{\textbar{}\textbar{}}} is a notation for the boolean
disjunction.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variables} \PYG{n}{P} \PYG{n}{Q} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{P} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{Q} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Hypothesis} \PYG{n}{P2Q} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}\PYG{o}{.}
    \PYG{n}{P2Q} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{a} \PYG{o}{:} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{a}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{P2Q} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}
      \PYG{n}{a} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{a}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}

\PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{n}{HPa}\PYG{o}{;} \PYG{k}{move}\PYG{o}{:} \PYG{o}{\PYGZob{}}\PYG{n}{HPa}\PYG{o}{\PYGZcb{}}\PYG{o}{(}\PYG{n}{P2Q} \PYG{n}{HPa}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{HQa}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{P2Q} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}
      \PYG{n}{a} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{n}{HQa} \PYG{o}{:} \PYG{n}{Q} \PYG{n}{a}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
\end{sphinxVerbatim}

which transforms the hypothesis \sphinxcode{\sphinxupquote{HPa : P a}} which has been introduced
from the initial statement into \sphinxcode{\sphinxupquote{HQa : Q a}}.
This operation is so common that the tactic shell has specific
syntax for it. The following scripts:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{n}{HPa}\PYG{o}{;} \PYG{k}{move}\PYG{o}{/}\PYG{n}{P2Q}\PYG{o}{:} \PYG{n}{HPa} \PYG{o}{=\PYGZgt{}} \PYG{n}{HQa}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{P2Q} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}
      \PYG{n}{a} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{n}{HQa} \PYG{o}{:} \PYG{n}{Q} \PYG{n}{a}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
\end{sphinxVerbatim}

or more directly:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{move}\PYG{o}{/}\PYG{n}{P2Q}\PYG{o}{=\PYGZgt{}} \PYG{n}{HQa}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{P2Q} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}
      \PYG{n}{a} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{n}{HQa} \PYG{o}{:} \PYG{n}{Q} \PYG{n}{a}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
\end{sphinxVerbatim}

are equivalent to the former one. The former script shows how to
interpret a fact (already in the context), thanks to the discharge
tactical (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Discharge}}}}) and the latter, how to interpret the top
assumption of a goal. Note that the number of wildcards to be inserted
to find the correct application of the view lemma to the hypothesis
has been automatically inferred.
\end{sphinxadmonition}

The view mechanism is compatible with the \sphinxcode{\sphinxupquote{case}} tactic and with the
equation name generation mechanism (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:generation-of-equations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Generation of equations}}}}):

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variables} \PYG{n}{P} \PYG{n}{Q}\PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{P} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{Q} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Hypothesis} \PYG{n}{Q2P} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{a} \PYG{o}{\PYGZbs{}/} \PYG{n}{P} \PYG{n}{b}\PYG{o}{.}
    \PYG{n}{Q2P} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{Q} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{Q2P} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{a} \PYG{o}{\PYGZbs{}/} \PYG{n}{P} \PYG{n}{b}
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{Q} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}

\PYG{k}{case}\PYG{o}{/}\PYG{n}{Q2P}\PYG{o}{=\PYGZgt{}} \PYG{o}{[}\PYG{n}{HPa} \PYG{o}{\textbar{}} \PYG{n}{HPb}\PYG{o}{]}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{Q2P} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{a} \PYG{o}{\PYGZbs{}/} \PYG{n}{P} \PYG{n}{b}
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{n}{HPa} \PYG{o}{:} \PYG{n}{P} \PYG{n}{a}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{True}
\end{sphinxVerbatim}

This view tactic performs:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{n}{HQ}\PYG{o}{;} \PYG{k}{case}\PYG{o}{:} \PYG{o}{\PYGZob{}}\PYG{n}{HQ}\PYG{o}{\PYGZcb{}}\PYG{o}{(}\PYG{n}{Q2P} \PYG{n}{HQ}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{o}{[}\PYG{n}{HPa} \PYG{o}{\textbar{}} \PYG{n}{HPb}\PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The term on the right of the \sphinxcode{\sphinxupquote{/}} view switch is called a \sphinxstyleemphasis{view lemma}.
Any \DUrole{smallcaps}{SSReflect} term coercing to a product type can be used as a view
lemma.

The examples we have given so far explicitly provide the direction of
the translation to be performed. In fact, view lemmas need not to be
oriented. The view mechanism is able to detect which application is
relevant for the current goal.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variables} \PYG{n}{P} \PYG{n}{Q}\PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{P} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{Q} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Hypothesis} \PYG{n}{PQequiv} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}\PYG{o}{.}
    \PYG{n}{PQequiv} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{PQequiv} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}

\PYG{k}{move}\PYG{o}{/}\PYG{n}{PQequiv}\PYG{o}{=\PYGZgt{}} \PYG{n}{HQab}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{PQequiv} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{n}{HQab} \PYG{o}{:} \PYG{n}{Q} \PYG{n}{a}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
\end{sphinxVerbatim}

has the same behavior as the first example above.

The view mechanism can insert automatically a \sphinxstyleemphasis{view hint} to transform
the double implication into the expected simple implication. The last
script is in fact equivalent to:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{True}\PYG{o}{.}
\PYG{k}{move}\PYG{o}{/}\PYG{o}{(}\PYG{n}{iffLR} \PYG{o}{(}\PYG{n}{PQequiv} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

where:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{iffLR} \PYG{n}{P} \PYG{n}{Q} \PYG{o}{:} \PYG{o}{(}\PYG{n}{P} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{Q}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Specializing assumptions}
\label{\detokenize{proof-engine/ssreflect-proof-language:specializing-assumptions}}
The special case when the \sphinxstyleemphasis{head symbol} of the view lemma is a
wildcard is used to interpret an assumption by \sphinxstyleemphasis{specializing} it. The
view mechanism hence offers the possibility to apply a higher-order
assumption to some given arguments.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{z} \PYG{o}{:} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{z} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{z} \PYG{o}{=} \PYG{n}{x}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{z} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{n}{z} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{z} \PYG{o}{=} \PYG{n}{x}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{z} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{k}{move}\PYG{o}{/}\PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{l+m+mi}{0} \PYG{n}{z}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{+} \PYG{n}{z} \PYG{o}{=} \PYG{n}{z} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{z} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{z} \PYG{o}{=} \PYG{l+m+mi}{0}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Interpreting goals}
\label{\detokenize{proof-engine/ssreflect-proof-language:interpreting-goals}}
In a similar way, it is also often convenient to
changing a goal by turning it into an equivalent proposition. The view
mechanism of \DUrole{smallcaps}{SSReflect} has a special syntax \sphinxcode{\sphinxupquote{apply/}} for combining  in a
single tactic simultaneous goal interpretation operations and
bookkeeping steps.

\begin{sphinxadmonition}{note}{Example}
\begin{quote}

The following example use the \sphinxcode{\sphinxupquote{\textasciitilde{}\textasciitilde{}}} prenex notation for boolean negation:
\end{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variables} \PYG{n}{P} \PYG{n}{Q}\PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{P} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{Q} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Hypothesis} \PYG{n}{PQequiv} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}\PYG{o}{.}
    \PYG{n}{PQequiv} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{a} \PYG{o}{:} \PYG{n}{P} \PYG{o}{(}\PYG{o}{(}\PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{a}\PYG{o}{)} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{a}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{PQequiv} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}
      \PYG{n}{a} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{o}{(}\PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{a}\PYG{o}{)}

\PYG{k}{apply}\PYG{o}{/}\PYG{n}{PQequiv}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{focused} \PYG{n}{subgoal}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{1}\PYG{o}{)}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}
      \PYG{n}{PQequiv} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{n}{P} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{n}{a}
      \PYG{n}{a} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{Q} \PYG{o}{(}\PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{a}\PYG{o}{)}
\end{sphinxVerbatim}

thus in this case, the tactic \sphinxcode{\sphinxupquote{apply/PQequiv}} is equivalent to
\sphinxcode{\sphinxupquote{apply: (iffRL (PQequiv \_ \_))}}, where \sphinxcode{\sphinxupquote{iffRL}} is tha analogue of
\sphinxcode{\sphinxupquote{iffRL}} for the converse implication.
\end{sphinxadmonition}

Any \DUrole{smallcaps}{SSReflect} term whose type coerces to a double implication can be
used as a view for goal interpretation.

Note that the goal interpretation view mechanism supports both \sphinxcode{\sphinxupquote{apply}}
and \sphinxcode{\sphinxupquote{exact}} tactics. As expected, a goal interpretation view command
exact/term should solve the current goal or it will fail.

\begin{sphinxadmonition}{warning}{Warning:}
Goal interpretation view tactics are \sphinxstyleemphasis{not} compatible with
the bookkeeping tactical \sphinxcode{\sphinxupquote{=\textgreater{}}} since this would be redundant with the
\sphinxcode{\sphinxupquote{apply: term =\textgreater{} \_}} construction.
\end{sphinxadmonition}


\subsubsection{Boolean reflection}
\label{\detokenize{proof-engine/ssreflect-proof-language:boolean-reflection}}
In the Calculus of Inductive Constructions, there is an obvious
distinction between logical propositions and boolean values. On the
one hand, logical propositions are objects of \sphinxstyleemphasis{sort} \sphinxcode{\sphinxupquote{Prop}} which is
the carrier of intuitionistic reasoning. Logical connectives in
\sphinxcode{\sphinxupquote{Prop}} are \sphinxstyleemphasis{types}, which give precise information on the structure
of their proofs; this information is automatically exploited by \DUrole{smallcaps}{Coq}
tactics.  For example, \DUrole{smallcaps}{Coq} knows that a proof of \sphinxcode{\sphinxupquote{A \textbackslash{}/ B}} is
either a proof of \sphinxcode{\sphinxupquote{A}} or a proof of \sphinxcode{\sphinxupquote{B}}.  The tactics \sphinxcode{\sphinxupquote{left}} and
\sphinxcode{\sphinxupquote{right}} change the goal \sphinxcode{\sphinxupquote{A \textbackslash{}/ B}} to \sphinxcode{\sphinxupquote{A}} and \sphinxcode{\sphinxupquote{B}}, respectively;
dually, the tactic \sphinxcode{\sphinxupquote{case}} reduces the goal \sphinxcode{\sphinxupquote{A \textbackslash{}/ B =\textgreater{} G}} to two
subgoals \sphinxcode{\sphinxupquote{A =\textgreater{} G}} and \sphinxcode{\sphinxupquote{B =\textgreater{} G}}.

On the other hand, bool is an inductive \sphinxstyleemphasis{datatype} with two
constructors true and false. Logical connectives on bool are
\sphinxstyleemphasis{computable functions}, defined by their truth tables, using case
analysis:

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{orb} \PYG{o}{(}\PYG{n}{b1} \PYG{n}{b2} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{if} \PYG{n}{b1} \PYG{k}{then} \PYG{n+nb+bp}{true} \PYG{k}{else} \PYG{n}{b2}\PYG{o}{.}
    \PYG{n}{orb} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Properties of such connectives are also established using case
analysis

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{n}{b} \PYG{o}{:} \PYG{n}{b} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b} \PYG{o}{=} \PYG{n+nb+bp}{true}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{b} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b} \PYG{o}{=} \PYG{n+nb+bp}{true}

\PYG{k+kp}{by} \PYG{k}{case}\PYG{o}{:} \PYG{n}{b}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}

Once \sphinxcode{\sphinxupquote{b}} is replaced by \sphinxcode{\sphinxupquote{true}} in the first goal and by \sphinxcode{\sphinxupquote{false}} in the
second one, the goals reduce by computations to the trivial \sphinxcode{\sphinxupquote{true = true}}.
\end{sphinxadmonition}

Thus, \sphinxcode{\sphinxupquote{Prop}} and \sphinxcode{\sphinxupquote{bool}} are truly complementary: the former supports
robust natural deduction, the latter allows brute-force
evaluation. \DUrole{smallcaps}{SSReflect} supplies a generic mechanism to have the best of
the two worlds and move freely from a propositional version of a
decidable predicate to its boolean version.

First, booleans are injected into propositions using the coercion
mechanism:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Coercion} \PYG{n}{is\PYGZus{}true} \PYG{o}{(}\PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{b} \PYG{o}{=} \PYG{n+nb+bp}{true}\PYG{o}{.}
\end{sphinxVerbatim}

This allows any boolean formula \sphinxcode{\sphinxupquote{b}} to be used in a context where \DUrole{smallcaps}{Coq}
would expect a proposition, e.g., after \sphinxcode{\sphinxupquote{Lemma … : {}`{}`. It is then
interpreted as {}`{}`(is\_true b)}}, i.e., the proposition \sphinxcode{\sphinxupquote{b = true}}. Coercions
are elided by the pretty-printer, so they are essentially transparent
to the user.


\subsubsection{The reflect predicate}
\label{\detokenize{proof-engine/ssreflect-proof-language:the-reflect-predicate}}
To get all the benefits of the boolean reflection, it is in fact
convenient to introduce the following inductive predicate \sphinxcode{\sphinxupquote{reflect}} to
relate propositions and booleans:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{reflect} \PYG{o}{(}\PYG{n}{P}\PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{Reflect\PYGZus{}true} \PYG{o}{:} \PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{reflect} \PYG{n}{P} \PYG{n+nb+bp}{true}
\PYG{o}{\textbar{}} \PYG{n}{Reflect\PYGZus{}false} \PYG{o}{:} \PYG{o}{\PYGZti{}}\PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{reflect} \PYG{n}{P} \PYG{n+nb+bp}{false}\PYG{o}{.}
\end{sphinxVerbatim}

The statement \sphinxcode{\sphinxupquote{(reflect P b)}} asserts that \sphinxcode{\sphinxupquote{(is\_true b)}} and \sphinxcode{\sphinxupquote{P}} are
logically equivalent propositions.

For instance, the following lemma:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{andP}\PYG{o}{:} \PYG{k}{forall} \PYG{n}{b1} \PYG{n}{b2}\PYG{o}{,} \PYG{n}{reflect} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{/\PYGZbs{}} \PYG{n}{b2}\PYG{o}{)} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b2}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

relates the boolean conjunction to the logical one \sphinxcode{\sphinxupquote{/\textbackslash{}}}. Note that in
\sphinxcode{\sphinxupquote{andP}}, \sphinxcode{\sphinxupquote{b1}} and \sphinxcode{\sphinxupquote{b2}} are two boolean variables and the
proposition \sphinxcode{\sphinxupquote{b1 /\textbackslash{} b2}} hides two coercions. The conjunction of
\sphinxcode{\sphinxupquote{b1}} and \sphinxcode{\sphinxupquote{b2}} can then be viewed as \sphinxcode{\sphinxupquote{b1 /\textbackslash{} b2}} or as \sphinxcode{\sphinxupquote{b1 \&\& b2}}.

Expressing logical equivalences through this family of inductive types
makes possible to take benefit from \sphinxstyleemphasis{rewritable equations} associated
to the case analysis of \DUrole{smallcaps}{Coq}’s inductive types.

Since the equivalence predicate is defined in \DUrole{smallcaps}{Coq} as:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{iff} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

where \sphinxcode{\sphinxupquote{/\textbackslash{}}} is a notation for \sphinxcode{\sphinxupquote{and}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{and} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{conj} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{and} \PYG{n}{A} \PYG{n}{B}\PYG{o}{.}
\end{sphinxVerbatim}

This make case analysis very different according to the way an
equivalence property has been defined.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{andE} \PYG{o}{(}\PYG{n}{b1} \PYG{n}{b2} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{:} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{/\PYGZbs{}} \PYG{n}{b2}\PYG{o}{)} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b2}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

Let us compare the respective behaviors of \sphinxcode{\sphinxupquote{andE}} and \sphinxcode{\sphinxupquote{andP}}.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{b1} \PYG{n}{b2} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{:} \PYG{k}{if} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b2}\PYG{o}{)} \PYG{k}{then} \PYG{n}{b1} \PYG{k}{else} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}}\PYG{o}{(}\PYG{n}{b1}\PYG{o}{\textbar{}}\PYG{o}{\textbar{}}\PYG{n}{b2}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{b1}\PYG{o}{,} \PYG{n}{b2} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{if} \PYG{n}{b1} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b2} \PYG{k}{then} \PYG{n}{b1} \PYG{k}{else} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b2}\PYG{o}{)}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{case}\PYG{o}{:} \PYG{o}{(}\PYG{o}{@}\PYG{n}{andE} \PYG{n}{b1} \PYG{n}{b2}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{b1}\PYG{o}{,} \PYG{n}{b2} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{n}{b1} \PYG{o}{/\PYGZbs{}} \PYG{n}{b2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{b1} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b2}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
      \PYG{o}{(}\PYG{n}{b1} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{b1} \PYG{o}{/\PYGZbs{}} \PYG{n}{b2}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{if} \PYG{n}{b1} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b2} \PYG{k}{then} \PYG{n}{b1} \PYG{k}{else} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b2}\PYG{o}{)}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{case}\PYG{o}{:} \PYG{o}{(}\PYG{o}{@}\PYG{n}{andP} \PYG{n}{b1} \PYG{n}{b2}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{b1}\PYG{o}{,} \PYG{n}{b2} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{b1} \PYG{o}{/\PYGZbs{}} \PYG{n}{b2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{b1}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{o}{\PYGZti{}} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{/\PYGZbs{}} \PYG{n}{b2}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b2}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Expressing reflection relation through the \sphinxcode{\sphinxupquote{reflect}} predicate is hence
a very convenient way to deal with classical reasoning, by case
analysis. Using the \sphinxcode{\sphinxupquote{reflect}} predicate allows moreover to program rich
specifications inside its two constructors, which will be
automatically taken into account during destruction. This
formalisation style gives far more efficient specifications than
quantified (double) implications.

A naming convention in \DUrole{smallcaps}{SSReflect} is to postfix the name of view lemmas
with \sphinxcode{\sphinxupquote{P}}. For example, \sphinxcode{\sphinxupquote{orP}} relates \sphinxcode{\sphinxupquote{\textbar{}\textbar{}}} and \sphinxcode{\sphinxupquote{\textbackslash{}/}},
\sphinxcode{\sphinxupquote{negP}} relates \sphinxcode{\sphinxupquote{\textasciitilde{}\textasciitilde{}}} and \sphinxcode{\sphinxupquote{\textasciitilde{}}}.

The view mechanism is compatible with reflect predicates.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Ha} \PYG{o}{:} \PYG{n}{a}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Hb} \PYG{o}{:} \PYG{n}{b}\PYG{o}{)} \PYG{o}{:} \PYG{n}{a} \PYG{o}{/\PYGZbs{}} \PYG{n}{b}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{n}{Ha} \PYG{o}{:} \PYG{n}{a}
      \PYG{n}{Hb} \PYG{o}{:} \PYG{n}{b}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{a} \PYG{o}{/\PYGZbs{}} \PYG{n}{b}

\PYG{k}{apply}\PYG{o}{/}\PYG{n}{andP}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{focused} \PYG{n}{subgoal}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{1}\PYG{o}{)}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{n}{Ha} \PYG{o}{:} \PYG{n}{a}
      \PYG{n}{Hb} \PYG{o}{:} \PYG{n}{b}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{a} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b}
\end{sphinxVerbatim}

Conversely

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{:} \PYG{n}{a} \PYG{o}{/\PYGZbs{}} \PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{a}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{a} \PYG{o}{/\PYGZbs{}} \PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{a}

\PYG{k}{move}\PYG{o}{/}\PYG{n}{andP}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{a} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{a}
\end{sphinxVerbatim}
\end{sphinxadmonition}

The same tactics can also be used to perform the converse operation,
changing a boolean conjunction into a logical one. The view mechanism
guesses the direction of the transformation to be used i.e., the
constructor of the reflect predicate which should be chosen.


\subsubsection{General mechanism for interpreting goals and assumptions}
\label{\detokenize{proof-engine/ssreflect-proof-language:general-mechanism-for-interpreting-goals-and-assumptions}}

\paragraph{Specializing assumptions}
\label{\detokenize{proof-engine/ssreflect-proof-language:id10}}
The \DUrole{smallcaps}{SSReflect} tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
move/(\PYGZus{} term1 … termn).
\end{sphinxVerbatim}

is equivalent to the tactic:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
intro top; generalize (top term1 … termn); clear top.
\end{sphinxVerbatim}

where \sphinxcode{\sphinxupquote{top}} is a fresh name for introducing the top assumption of the
current goal.


\paragraph{Interpreting assumptions}
\label{\detokenize{proof-engine/ssreflect-proof-language:id11}}
The general form of an assumption view tactic is:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{[}move~\textbar{}~case{]}~/~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


The term , called the \sphinxstyleemphasis{view lemma} can be:
\begin{itemize}
\item {} 
a (term coercible to a) function;

\item {} 
a (possibly quantified) implication;

\item {} 
a (possibly quantified) double implication;

\item {} 
a (possibly quantified) instance of the reflect predicate (see
section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:views-and-reflection-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Views and reflection}}}}).

\end{itemize}

Let \sphinxcode{\sphinxupquote{top}} be the top assumption in the goal.

There are three steps in the behavior of an assumption view tactic:
\begin{itemize}
\item {} 
It first introduces \sphinxcode{\sphinxupquote{top}}.

\item {} 
If the type of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} is neither a double implication nor an
instance of the reflect predicate, then the tactic automatically
generalises a term of the form: \sphinxcode{\sphinxupquote{term term1 … termn}} where the
terms \sphinxcode{\sphinxupquote{term1 … termn}} instantiate the possible quantified variables of
\sphinxcode{\sphinxupquote{term}} , in order for \sphinxcode{\sphinxupquote{(term term1 … termn top)}} to be well typed.

\item {} 
If the type of \sphinxcode{\sphinxupquote{term}} is an equivalence, or an instance of the
reflect predicate, it generalises a term of the form:
\sphinxcode{\sphinxupquote{(termvh (term term1 … termn ))}} where the term \sphinxcode{\sphinxupquote{termvh}}
inserted is called an
\sphinxstyleemphasis{assumption interpretation view hint}.

\item {} 
It finally clears top.

\end{itemize}

For a \sphinxcode{\sphinxupquote{case/term}} tactic, the generalisation step is replaced by a
case analysis step.

\sphinxstyleemphasis{View hints} are declared by the user (see section:ref:\sphinxtitleref{views\_and\_reflection\_ssr}.8) and are
stored in the Hint View database. The proof engine automatically
detects from the shape of the top assumption \sphinxcode{\sphinxupquote{top}} and of the view lemma
\sphinxcode{\sphinxupquote{term}} provided to the tactic the appropriate view hint in the
database to be inserted.

If \sphinxcode{\sphinxupquote{term}} is a double implication, then the view hint will be one of
the defined view hints for implication. These hints are by default the
ones present in the file \sphinxcode{\sphinxupquote{ssreflect.v}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{iffLR} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{P} \PYG{n}{Q}\PYG{o}{,} \PYG{o}{(}\PYG{n}{P} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{Q}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q}\PYG{o}{.}
\end{sphinxVerbatim}

which transforms a double implication into the left-to-right one, or:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{iffRL} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{P} \PYG{n}{Q}\PYG{o}{,} \PYG{o}{(}\PYG{n}{P} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{Q}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P}\PYG{o}{.}
\end{sphinxVerbatim}

which produces the converse implication. In both cases, the two
first Prop arguments are implicit.

If \sphinxcode{\sphinxupquote{term}} is an instance of the \sphinxcode{\sphinxupquote{reflect}} predicate, then \sphinxcode{\sphinxupquote{A}} will be one
of the defined view hints for the \sphinxcode{\sphinxupquote{reflec{}`{}`t predicate, which are by
default the ones present in the file {}`{}`ssrbool.v}}. These hints are not
only used for choosing the appropriate direction of the translation,
but they also allow complex transformation, involving negations.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{introN} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)}\PYG{o}{,} \PYG{n}{reflect} \PYG{n}{P} \PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}} \PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}}\PYG{n}{b}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Ha} \PYG{o}{:} \PYG{n}{a}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Hb} \PYG{o}{:} \PYG{n}{b}\PYG{o}{)} \PYG{o}{:} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{n}{Ha} \PYG{o}{:} \PYG{n}{a}
      \PYG{n}{Hb} \PYG{o}{:} \PYG{n}{b}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b}\PYG{o}{)}

\PYG{k}{apply}\PYG{o}{/}\PYG{n}{andP}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{focused} \PYG{n}{subgoal}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{1}\PYG{o}{)}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{n}{Ha} \PYG{o}{:} \PYG{n}{a}
      \PYG{n}{Hb} \PYG{o}{:} \PYG{n}{b}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{\PYGZti{}} \PYG{o}{(}\PYG{n}{a} \PYG{o}{/\PYGZbs{}} \PYG{n}{b}\PYG{o}{)}
\end{sphinxVerbatim}

In fact this last script does not
exactly use the hint \sphinxcode{\sphinxupquote{introN}}, but the more general hint:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{introNTF} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{b} \PYG{n}{c} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)}\PYG{o}{,}
  \PYG{n}{reflect} \PYG{n}{P} \PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{k}{if} \PYG{n}{c} \PYG{k}{then} \PYG{o}{\PYGZti{}} \PYG{n}{P} \PYG{k}{else} \PYG{n}{P}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b} \PYG{o}{=} \PYG{n}{c}\PYG{o}{.}
\end{sphinxVerbatim}

The lemma {}` \sphinxtitleref{introN{}`} is an instantiation of introNF using c := true.
\end{sphinxadmonition}

Note that views, being part of {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{i\_pattern}}}}}, can be used to interpret
assertions too. For example the following script asserts \sphinxcode{\sphinxupquote{a \&\& b}} but
actually uses its propositional interpretation.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{(}\PYG{n}{pab} \PYG{o}{:} \PYG{n}{b} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{a}\PYG{o}{)} \PYG{o}{:} \PYG{n}{b}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{n}{pab} \PYG{o}{:} \PYG{n}{b} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{a}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{b}

\PYG{k}{have} \PYG{o}{/}\PYG{n}{andP} \PYG{o}{[}\PYG{n}{pa} \PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{o}{]} \PYG{o}{:} \PYG{o}{(}\PYG{n}{a} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{b}\PYG{o}{)} \PYG{k+kp}{by} \PYG{k}{rewrite} \PYG{n}{andbC}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{n}{pab} \PYG{o}{:} \PYG{n}{b} \PYG{o}{\PYGZam{}\PYGZam{}} \PYG{n}{a}
      \PYG{n}{pa} \PYG{o}{:} \PYG{n}{a}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n+nb+bp}{true}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Interpreting goals

A goal interpretation view tactic of the form:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply/{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


applied to a goal \sphinxcode{\sphinxupquote{top}} is interpreted in the following way:
\begin{itemize}
\item {} 
If the type of \sphinxcode{\sphinxupquote{term}} is not an instance of the \sphinxcode{\sphinxupquote{reflect}} predicate,
nor an equivalence, then the term \sphinxcode{\sphinxupquote{term}} is applied to the current
goal \sphinxcode{\sphinxupquote{top}}, possibly inserting implicit arguments.

\item {} 
If the type of \sphinxcode{\sphinxupquote{term}} is an instance of the reflect predicate or an
equivalence, then a \sphinxstyleemphasis{goal interpretation view hint} can possibly be
inserted, which corresponds to the application of a term
\sphinxcode{\sphinxupquote{(termvh (term \_ … \_))}} to the current goal, possibly inserting implicit arguments.

\end{itemize}

Like assumption interpretation view hints, goal interpretation ones
are user-defined lemmas stored (see section {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:views-and-reflection-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Views and reflection}}}}) in the \sphinxcode{\sphinxupquote{Hint View}}
database bridging the possible gap between the type of \sphinxcode{\sphinxupquote{term}} and the
type of the goal.


\subsubsection{Interpreting equivalences}
\label{\detokenize{proof-engine/ssreflect-proof-language:interpreting-equivalences}}
Equivalent boolean propositions are simply \sphinxstyleemphasis{equal} boolean terms. A
special construction helps the user to prove boolean equalities by
considering them as logical double implications (between their coerced
versions), while performing at the same time logical operations on
both sides.

The syntax of double views is:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply/{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}/{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


The first term is the view lemma applied to the left hand side of the
equality, while the second term is the one applied to the right hand side.

In this context, the identity view can be used when no view has to be applied:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{idP} \PYG{o}{:} \PYG{n}{reflect} \PYG{n}{b1} \PYG{n}{b1}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{b1} \PYG{n}{b2} \PYG{n}{b3} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{:} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b2}\PYG{o}{)} \PYG{o}{=} \PYG{n}{b3}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{b1}\PYG{o}{,} \PYG{n}{b2}\PYG{o}{,} \PYG{n}{b3} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b2}\PYG{o}{)} \PYG{o}{=} \PYG{n}{b3}

\PYG{k}{apply}\PYG{o}{/}\PYG{n}{idP}\PYG{o}{/}\PYG{n}{idP}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{focused} \PYG{n}{subgoals}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{2}\PYG{o}{)}
      
      \PYG{n}{b1}\PYG{o}{,} \PYG{n}{b2}\PYG{o}{,} \PYG{n}{b3} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b2}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{b3}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{b3} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b2}\PYG{o}{)}
\end{sphinxVerbatim}

The same goal can be decomposed in several ways, and the user may
choose the most convenient interpretation.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{b1} \PYG{n}{b2} \PYG{n}{b3} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{:} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b2}\PYG{o}{)} \PYG{o}{=} \PYG{n}{b3}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{b1}\PYG{o}{,} \PYG{n}{b2}\PYG{o}{,} \PYG{n}{b3} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{o}{(}\PYG{n}{b1} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{n}{b2}\PYG{o}{)} \PYG{o}{=} \PYG{n}{b3}

\PYG{k}{apply}\PYG{o}{/}\PYG{n}{norP}\PYG{o}{/}\PYG{n}{idP}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{focused} \PYG{n}{subgoals}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{2}\PYG{o}{)}
      
      \PYG{n}{b1}\PYG{o}{,} \PYG{n}{b2}\PYG{o}{,} \PYG{n}{b3} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b1} \PYG{o}{/\PYGZbs{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{b3}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{b3} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b1} \PYG{o}{/\PYGZbs{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b2}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Declaring new Hint Views}
\label{\detokenize{proof-engine/ssreflect-proof-language:declaring-new-hint-views}}\label{\detokenize{proof-engine/ssreflect-proof-language:declaring-new-hints-ssr}}
The database of hints for the view mechanism is extensible via a
dedicated vernacular command. As library \sphinxcode{\sphinxupquote{ssrbool.v}} already declares a
corpus of hints, this feature is probably useful only for users who
define their own logical connectives. Users can declare their own
hints following the syntax used in \sphinxcode{\sphinxupquote{ssrbool.v}}:
\index{Hint View for move (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:cmd.hint-view-for-move}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~View~for~move~/~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}

\index{Hint View for apply (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:cmd.hint-view-for-apply}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~View~for~apply~/~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


The {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is the name of the lemma to be
declared as a hint. If \sphinxtitleref{move} is used as
tactic, the hint is declared for assumption interpretation tactics,
\sphinxtitleref{apply} declares hints for goal interpretations. Goal interpretation
view hints are declared for both simple views and left hand side
views. The optional natural number is the number of implicit
arguments to be considered for the declared hint view lemma.

The command:
\index{Hint View for apply (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~View~for~apply//{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


with a double slash \sphinxcode{\sphinxupquote{//}}, declares hint views for right hand sides of
double views.

See the files \sphinxcode{\sphinxupquote{ssreflect.v}} and \sphinxcode{\sphinxupquote{ssrbool.v}} for examples.


\subsubsection{Multiple views}
\label{\detokenize{proof-engine/ssreflect-proof-language:multiple-views}}
The hypotheses and the goal can be interpreted by applying multiple views
in sequence. Both move and apply can be followed by an arbitrary
number of \sphinxcode{\sphinxupquote{/term}}. The main difference between the following two
tactics

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{apply}\PYG{o}{/}\PYG{n}{v1}\PYG{o}{/}\PYG{n}{v2}\PYG{o}{/}\PYG{n}{v3}\PYG{o}{.}
\PYG{k}{apply}\PYG{o}{/}\PYG{n}{v1}\PYG{o}{;} \PYG{k}{apply}\PYG{o}{/}\PYG{n}{v2}\PYG{o}{;} \PYG{k}{apply}\PYG{o}{/}\PYG{n}{v3}\PYG{o}{.}
\end{sphinxVerbatim}

is that the former applies all the views to the principal goal.
Applying a view with hypotheses generates new goals, and the second
line would apply the view \sphinxcode{\sphinxupquote{v2}} to all the goals generated by \sphinxcode{\sphinxupquote{apply/v1}}.

Note that the NO-OP intro pattern \sphinxcode{\sphinxupquote{-}} can be used to separate two views,
making the two following examples equivalent:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{o}{/}\PYG{n}{v1}\PYG{o}{;} \PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{o}{/}\PYG{n}{v2}\PYG{o}{.}
\PYG{k}{move}\PYG{o}{=\PYGZgt{}} \PYG{o}{/}\PYG{n}{v1} \PYG{o}{\PYGZhy{}} \PYG{o}{/}\PYG{n}{v2}\PYG{o}{.}
\end{sphinxVerbatim}

The tactic \sphinxcode{\sphinxupquote{move}} can be used together with the \sphinxcode{\sphinxupquote{in}} tactical to
pass a given hypothesis to a lemma.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Variable} \PYG{n}{P2Q} \PYG{o}{:} \PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q}\PYG{o}{.}
    \PYG{n}{P2Q} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Variable} \PYG{n}{Q2R} \PYG{o}{:} \PYG{n}{Q} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R}\PYG{o}{.}
    \PYG{n}{Q2R} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{(}\PYG{n}{p} \PYG{o}{:} \PYG{n}{P}\PYG{o}{)} \PYG{o}{:} \PYG{n}{True}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q}\PYG{o}{,} \PYG{n}{R} \PYG{o}{:} \PYG{k+kt}{Prop}
      \PYG{n}{P2Q} \PYG{o}{:} \PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q}
      \PYG{n}{Q2R} \PYG{o}{:} \PYG{n}{Q} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R}
      \PYG{n}{p} \PYG{o}{:} \PYG{n}{P}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}

\PYG{k}{move}\PYG{o}{/}\PYG{n}{P2Q}\PYG{o}{/}\PYG{n}{Q2R} \PYG{k}{in} \PYG{n}{p}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{P}\PYG{o}{,} \PYG{n}{Q}\PYG{o}{,} \PYG{n}{R} \PYG{o}{:} \PYG{k+kt}{Prop}
      \PYG{n}{P2Q} \PYG{o}{:} \PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Q}
      \PYG{n}{Q2R} \PYG{o}{:} \PYG{n}{Q} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R}
      \PYG{n}{p} \PYG{o}{:} \PYG{n}{R}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{True}
\end{sphinxVerbatim}
\end{sphinxadmonition}

If the list of views is of length two, \sphinxcode{\sphinxupquote{Hint Views}} for interpreting
equivalences are indeed taken into account, otherwise only single
\sphinxcode{\sphinxupquote{Hint Views}} are used.


\subsection{SSReflect searching tool}
\label{\detokenize{proof-engine/ssreflect-proof-language:ssr-searching-tool}}
\DUrole{smallcaps}{SSReflect} proposes an extension of the Search command. Its syntax is:
\index{Search (ssreflect) (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:cmd.search-ssreflect}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Search~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{-}\DUrole{notation-sup}{?}}~\DUrole{meta}{(}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}~\DUrole{meta}{)}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\%~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}\DUrole{notation-sup}{*}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{-}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


where {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} is the name of an open module. This command returns
the list of lemmas:
\begin{itemize}
\item {} 
whose \sphinxstyleemphasis{conclusion} contains a subterm matching the optional first
pattern. A - reverses the test, producing the list of lemmas whose
conclusion does not contain any subterm matching the pattern;

\item {} 
whose name contains the given string. A \sphinxcode{\sphinxupquote{-}} prefix reverses the test,
producing the list of lemmas whose name does not contain the string. A
string that contains symbols or is followed by a scope key, is
interpreted as the constant whose notation involves that string (e.g.,
\sphinxtitleref{+} for \sphinxtitleref{addn}), if this is unambiguous; otherwise the diagnostic
includes the output of the \sphinxcode{\sphinxupquote{Locate}} vernacular command.

\item {} 
whose statement, including assumptions and types, contains a subterm
matching the next patterns. If a pattern is prefixed by \sphinxcode{\sphinxupquote{-}}, the test is
reversed;

\item {} 
contained in the given list of modules, except the ones in the
modules prefixed by a \sphinxcode{\sphinxupquote{-}}.

\end{itemize}

Note that:
\begin{itemize}
\item {} 
As for regular terms, patterns can feature scope indications. For
instance, the command: \sphinxcode{\sphinxupquote{Search \_ (\_ + \_)\%N.}} lists all the lemmas whose
statement (conclusion or hypotheses) involves an application of the
binary operation denoted by the infix \sphinxcode{\sphinxupquote{+}} symbol in the \sphinxcode{\sphinxupquote{N}} scope (which is
\DUrole{smallcaps}{SSReflect} scope for natural numbers).

\item {} 
Patterns with holes should be surrounded by parentheses.

\item {} 
Search always volunteers the expansion of the notation, avoiding the
need to execute Locate independently. Moreover, a string fragment
looks for any notation that contains fragment as a substring. If the
\sphinxcode{\sphinxupquote{ssrbool.v}} library is imported, the command: \sphinxcode{\sphinxupquote{Search "\textasciitilde{}\textasciitilde{}".}} answers :

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Search} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZti{}\PYGZti{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZti{}\PYGZti{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{is} \PYG{n}{part} \PYG{k}{of} \PYG{n}{notation} \PYG{o}{(}\PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{o}{\PYGZus{}}\PYG{o}{)}
    \PYG{n}{In} \PYG{n}{bool\PYGZus{}scope}\PYG{o}{,} \PYG{o}{(}\PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b}\PYG{o}{)} \PYG{n}{denotes} \PYG{n}{negb} \PYG{n}{b}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{12}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Search} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZti{}\PYGZti{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Warning}\PYG{o}{:} \PYG{n}{Listing} \PYG{n}{only} \PYG{n}{lemmas} \PYG{k}{with} \PYG{n}{conclusion} \PYG{n}{matching} \PYG{o}{(}\PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{o}{?}\PYG{n}{b}\PYG{o}{)}
    \PYG{n}{negbT}  \PYG{k}{forall} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{n}{b} \PYG{o}{=} \PYG{n+nb+bp}{false} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b}
    
    \PYG{n}{contra}  \PYG{k}{forall} \PYG{n}{c} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{o}{(}\PYG{n}{c} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{c}
    
    \PYG{n}{contraNN}  \PYG{k}{forall} \PYG{n}{c} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{o}{(}\PYG{n}{c} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{c}
    
    \PYG{n}{contraL}  \PYG{k}{forall} \PYG{n}{c} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{o}{(}\PYG{n}{c} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{c}
    
    \PYG{n}{contraTN}  \PYG{k}{forall} \PYG{n}{c} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{o}{(}\PYG{n}{c} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{c}
    
    \PYG{n}{contraFN}  \PYG{k}{forall} \PYG{n}{c} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{o}{(}\PYG{n}{c} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{b} \PYG{o}{=} \PYG{n+nb+bp}{false} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{c}
    
    \PYG{n}{introN}  \PYG{k}{forall} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)}\PYG{o}{,} \PYG{n}{reflect} \PYG{n}{P} \PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}} \PYG{n}{P} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{\PYGZti{}}\PYG{o}{\PYGZti{}} \PYG{n}{b}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\item {} 
A diagnostic is issued if there are different matching notations; it
is an error if all matches are partial.

\item {} 
Similarly, a diagnostic warns about multiple interpretations, and
signals an error if there is no default one.

\item {} 
The command \sphinxcode{\sphinxupquote{Search in M.}} is a way of obtaining the complete
signature of the module \sphinxcode{\sphinxupquote{M}}.

\item {} 
Strings and pattern indications can be interleaved, but the first
indication has a special status if it is a pattern, and only filters
the conclusion of lemmas:
\begin{itemize}
\item {} 
The command : \sphinxcode{\sphinxupquote{Search (\_ =1 \_) "bij".}} lists all the lemmas whose
conclusion features a \sphinxcode{\sphinxupquote{=1}} and whose name contains the string \sphinxcode{\sphinxupquote{bij}}.

\item {} 
The command : \sphinxcode{\sphinxupquote{Search "bij" (\_ =1 \_).}} lists all the lemmas whose
statement, including hypotheses, features a \sphinxcode{\sphinxupquote{=1}} and whose name
contains the string \sphinxcode{\sphinxupquote{bij}}.

\end{itemize}

\end{itemize}


\subsection{Synopsis and Index}
\label{\detokenize{proof-engine/ssreflect-proof-language:synopsis-and-index}}

\subsubsection{Parameters}
\label{\detokenize{proof-engine/ssreflect-proof-language:parameters}}
\DUrole{smallcaps}{SSReflect} tactics


\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_tactic}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{d\_tactic~::=~}}\DUrole{notation}{elim~\DUrole{meta}{\textbar{}}~case~\DUrole{meta}{\textbar{}}~congr~\DUrole{meta}{\textbar{}}~apply~\DUrole{meta}{\textbar{}}~exact~\DUrole{meta}{\textbar{}}~move}}}}
\end{fulllineitems}


Notation scope


\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-key}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{key~::=~}}\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\end{fulllineitems}


Module name


\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-modname}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{modname~::=~}}\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
\end{fulllineitems}


Natural number


\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-natural}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{natural~::=~}}\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\end{fulllineitems}


where {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} is an Ltac variable denoting a standard \DUrole{smallcaps}{Coq} numeral
(should not be the name of a tactic which can be followed by a
bracket \sphinxcode{\sphinxupquote{{[}}}, like \sphinxcode{\sphinxupquote{do}}, \sphinxcode{\sphinxupquote{have}},…)


\subsubsection{Items and switches}
\label{\detokenize{proof-engine/ssreflect-proof-language:items-and-switches}}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-ssr_binder}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{ssr\_binder~::=~}}\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{meta}{\textbar{}}~(~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}~)}}}}
\end{fulllineitems}


binder see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:abbreviations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations}}}}.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{clear\_switch~::=~}}\DUrole{notation}{\DUrole{curlies}{\{~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~\}}}}}}
\end{fulllineitems}


clear switch see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Discharge}}}}


\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{c\_pattern~::=~}}\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~in~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~as}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


context pattern see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:contextual-patterns-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Contextual patterns}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{d\_item~::=~}}\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{meta}{\textbar{}}~(~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\DUrole{hole}{c\_pattern}}}}~)}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


discharge item see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Discharge}}}}


\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-gen_item}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{gen\_item~::=~}}\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{@}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{meta}{\textbar{}}~(~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~)~\DUrole{meta}{\textbar{}}~(~\DUrole{repeat-wrapper}{\DUrole{repeat}{@}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\DUrole{hole}{c\_pattern}}}}~)}}}}
\end{fulllineitems}


generalization item see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:structure-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Structure}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{i\_pattern~::=~}}\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{meta}{\textbar{}}~\_~\DUrole{meta}{\textbar{}}~?~\DUrole{meta}{\textbar{}}~*~\DUrole{meta}{\textbar{}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}}\DUrole{notation-sup}{?}}~-\textgreater{}~\DUrole{meta}{\textbar{}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}}\DUrole{notation-sup}{?}}~\textless{}-~\DUrole{meta}{\textbar{}}~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}\DUrole{notation-sup}{*}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\textbar{}}}~\DUrole{meta}{\textbar{}}~-~\DUrole{meta}{\textbar{}}~{[}:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~{]}}}}}
\end{fulllineitems}


intro pattern {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{i\_item~::=~}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}~\DUrole{meta}{\textbar{}}~/~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


intro item  see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}


\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-int_mult}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{int\_mult~::=~}}\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult_mark}]{\sphinxcrossref{\DUrole{hole}{mult\_mark}}}}}}}}
\end{fulllineitems}


multiplier  see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:iteration-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Iteration}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{occ\_switch~::=~}}\DUrole{notation}{\DUrole{curlies}{\{~\DUrole{repeat-wrapper}{\DUrole{repeat}{+~\DUrole{meta}{\textbar{}}~-}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{*}}~\}}}}}}
\end{fulllineitems}


occur. switch see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:occurrence-selection-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Occurrence selection}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{mult~::=~}}\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult_mark}]{\sphinxcrossref{\DUrole{hole}{mult\_mark}}}}}}}}
\end{fulllineitems}


multiplier see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:iteration-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Iteration}}}}


\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult_mark}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{mult\_mark~::=~}}\DUrole{notation}{?~\DUrole{meta}{\textbar{}}~!}}}}
\end{fulllineitems}


multiplier mark see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:iteration-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Iteration}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{r\_item~::=~}}\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{/}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}}}}}
\end{fulllineitems}


rewrite item see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:rewriting-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Rewriting}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{r\_prefix~::=~}}\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{-}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-int_mult}]{\sphinxcrossref{\DUrole{hole}{int\_mult}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{[}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_pattern}]{\sphinxcrossref{\DUrole{hole}{r\_pattern}}}}~{]}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


rewrite prefix see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:rewriting-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Rewriting}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{r\_pattern~::=~}}\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\DUrole{hole}{c\_pattern}}}}~\DUrole{meta}{\textbar{}}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~in}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


rewrite pattern see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:rewriting-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Rewriting}}}}


\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_step}}\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{r\_step~::=~}}\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_prefix}]{\sphinxcrossref{\DUrole{hole}{r\_prefix}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_item}]{\sphinxcrossref{\DUrole{hole}{r\_item}}}}}}}}
\end{fulllineitems}


rewrite step see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:rewriting-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Rewriting}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{s\_item~::=~}}\DUrole{notation}{/=~\DUrole{meta}{\textbar{}}~//~\DUrole{meta}{\textbar{}}~//=}}}}
\end{fulllineitems}


simplify switch see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}


\subsubsection{Tactics}
\label{\detokenize{proof-engine/ssreflect-proof-language:tactics}}
\sphinxstyleemphasis{Note}: \sphinxcode{\sphinxupquote{without loss}} and \sphinxcode{\sphinxupquote{suffices}} are synonyms for \sphinxcode{\sphinxupquote{wlog}} and \sphinxcode{\sphinxupquote{suff}}
respectively.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{move}}}}
\end{fulllineitems}


idtac or hnf see  {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:bookkeeping-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Bookkeeping}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{apply}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{exact}}}}
\end{fulllineitems}


application see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:the-defective-tactics-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{The defective tactics}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{abstract}}}}
see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:abstract-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{The abstract tactic}}}} and {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:generating-let-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Generating let in context entries with have}}}}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{elim}}}}
\end{fulllineitems}


induction see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:the-defective-tactics-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{The defective tactics}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{case}}}}
\end{fulllineitems}


case analysis see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:the-defective-tactics-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{The defective tactics}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{rewrite~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_step}]{\sphinxcrossref{\DUrole{hole}{r\_step}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}


rewrite  see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:rewriting-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Rewriting}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{have~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}\DUrole{notation-sup}{*}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}~\DUrole{meta}{\textbar{}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-ssr_binder}]{\sphinxcrossref{\DUrole{hole}{ssr\_binder}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{have~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}\DUrole{notation-sup}{*}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-s_item}]{\sphinxcrossref{\DUrole{hole}{s\_item}}}}~\DUrole{meta}{\textbar{}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-ssr_binder}]{\sphinxcrossref{\DUrole{hole}{ssr\_binder}}}}}\DUrole{notation-sup}{+}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~\DUrole{hole}{tactic}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{have~suff~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{have~suff~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~\DUrole{hole}{tactic}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{gen~have~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~,}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}}\DUrole{notation-sup}{?}}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-gen_item}]{\sphinxcrossref{\DUrole{hole}{gen\_item}}}}}\DUrole{notation-sup}{+}}~/~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~\DUrole{hole}{tactic}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}

\index{generally have (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacv.generally-have}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{generally~have~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~,}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}}\DUrole{notation-sup}{?}}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-gen_item}]{\sphinxcrossref{\DUrole{hole}{gen\_item}}}}}\DUrole{notation-sup}{+}}~/~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~\DUrole{hole}{tactic}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


forward  chaining see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:structure-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Structure}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{wlog~\DUrole{repeat-wrapper}{\DUrole{repeat}{suff}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}\DUrole{notation-sup}{?}}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-gen_item}]{\sphinxcrossref{\DUrole{hole}{gen\_item}}}}~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{notation-sup}{*}}~/~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


specializing see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:structure-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Structure}}}}
\index{suff (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacn.suff}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{suff~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}\DUrole{notation-sup}{*}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-ssr_binder}]{\sphinxcrossref{\DUrole{hole}{ssr\_binder}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~\DUrole{hole}{tactic}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}

\index{suffices (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:tacv.suffices}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{suffices~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}\DUrole{notation-sup}{*}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-ssr_binder}]{\sphinxcrossref{\DUrole{hole}{ssr\_binder}}}}}\DUrole{notation-sup}{+}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~\DUrole{hole}{tactic}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{suff~\DUrole{repeat-wrapper}{\DUrole{repeat}{have}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~\DUrole{hole}{tactic}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{suffices~\DUrole{repeat-wrapper}{\DUrole{repeat}{have}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_pattern}]{\sphinxcrossref{\DUrole{hole}{i\_pattern}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~\DUrole{hole}{tactic}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


backchaining see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:structure-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Structure}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


local definition {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:definitions-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Definitions}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-ssr_binder}]{\sphinxcrossref{\DUrole{hole}{ssr\_binder}}}}}\DUrole{notation-sup}{+}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


local function definition


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~fix~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-fix-body}]{\sphinxcrossref{\DUrole{hole}{fix\_body}}}}}}}}
\end{fulllineitems}


local fix definition


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{pose~cofix~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-fix-body}]{\sphinxcrossref{\DUrole{hole}{fix\_body}}}}}}}}
\end{fulllineitems}


local cofix definition


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{set~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-occ_switch}]{\sphinxcrossref{\DUrole{hole}{occ\_switch}}}}}\DUrole{notation-sup}{?}}~\DUrole{meta}{(}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{meta}{\textbar{}}~(~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-c_pattern}]{\sphinxcrossref{\DUrole{hole}{c\_pattern}}}})~\DUrole{meta}{)}}}}}
\end{fulllineitems}


abbreviation see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:abbreviations-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{unlock~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-r_prefix}]{\sphinxcrossref{\DUrole{hole}{r\_prefix}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}}}}}}
\end{fulllineitems}


unlock see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:locking-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Locking, unlocking}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{congr~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


congruence {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:congruence-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Congruence}}}}


\subsubsection{Tacticals}
\label{\detokenize{proof-engine/ssreflect-proof-language:tacticals}}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{tactic~+=~}}\DUrole{notation}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_tactic}]{\sphinxcrossref{\DUrole{hole}{d\_tactic}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-d_item}]{\sphinxcrossref{\DUrole{hole}{d\_item}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


discharge {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:discharge-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Discharge}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{tactic~+=~}}\DUrole{notation}{\DUrole{hole}{tactic}~=\textgreater{}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-i_item}]{\sphinxcrossref{\DUrole{hole}{i\_item}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}


introduction see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:introduction-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Introduction in the context}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{tactic~+=~}}\DUrole{notation}{\DUrole{hole}{tactic}~in~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-gen_item}]{\sphinxcrossref{\DUrole{hole}{gen\_item}}}}~\DUrole{meta}{\textbar{}}~{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-clear_switch}]{\sphinxcrossref{\DUrole{hole}{clear\_switch}}}}}\DUrole{notation-sup}{+}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{*}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


localization see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:localization-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Localization}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{tactic~+=~}}\DUrole{notation}{do~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-mult}]{\sphinxcrossref{\DUrole{hole}{mult}}}}}\DUrole{notation-sup}{?}}~\DUrole{meta}{(}~\DUrole{hole}{tactic}~\DUrole{meta}{\textbar{}}~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{tactic}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textbar{}}}~{]}~\DUrole{meta}{)}}}}}
\end{fulllineitems}


iteration  see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:iteration-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Iteration}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{tactic~+=~}}\DUrole{notation}{\DUrole{hole}{tactic}~;~\DUrole{meta}{(}~first~\DUrole{meta}{\textbar{}}~last~\DUrole{meta}{)}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{?}}~\DUrole{meta}{(}~\DUrole{hole}{tactic}~\DUrole{meta}{\textbar{}}~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{tactic}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textbar{}}}~{]}~\DUrole{meta}{)}}}}}
\end{fulllineitems}


selector  see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:selectors-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Selectors}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{tactic~+=~}}\DUrole{notation}{\DUrole{hole}{tactic}~;~\DUrole{meta}{(}~first~\DUrole{meta}{\textbar{}}~last~\DUrole{meta}{)}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


rotation see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:selectors-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Selectors}}}}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\sphinxcode{\sphinxupquote{tactic~+=~}}\DUrole{notation}{by~\DUrole{meta}{(}~\DUrole{hole}{tactic}~\DUrole{meta}{\textbar{}}~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{tactic}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{\textbar{}}}~{]}~\DUrole{meta}{)}}}}}
\end{fulllineitems}


closing see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:terminators-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Terminators}}}}


\subsubsection{Commands}
\label{\detokenize{proof-engine/ssreflect-proof-language:commands}}\index{Hint View for (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{proof-engine/ssreflect-proof-language:coq:cmd.hint-view-for}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~View~for~\DUrole{meta}{(}~move~\DUrole{meta}{\textbar{}}~apply~\DUrole{meta}{)}~/~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textbar{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


view hint declaration see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:declaring-new-hints-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Declaring new Hint Views}}}}
\index{Hint View for apply (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hint~View~for~apply~//~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


right hand side double , view hint declaration see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:declaring-new-hints-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Declaring new Hint Views}}}}
\index{Prenex Implicits (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Prenex~Implicits~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
\end{fulllineitems}


prenex implicits declaration see {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:parametric-polymorphism-ssr}]{\sphinxcrossref{\DUrole{std,std-ref}{Parametric polymorphism}}}}


\chapter{User extensions}
\label{\detokenize{index:user-extensions}}

\section{Syntax extensions and interpretation scopes}
\label{\detokenize{user-extensions/syntax-extensions:syntax-extensions-and-interpretation-scopes}}\label{\detokenize{user-extensions/syntax-extensions:syntaxextensionsandinterpretationscopes}}\label{\detokenize{user-extensions/syntax-extensions::doc}}
In this chapter, we introduce advanced commands to modify the way Coq
parses and prints objects, i.e. the translations between the concrete
and internal representations of terms and commands.

The main commands to provide custom symbolic notations for terms are
{\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}} and {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.infix}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Infix}}}}}; they will be described in the
{\hyperref[\detokenize{user-extensions/syntax-extensions:notations}]{\sphinxcrossref{\DUrole{std,std-ref}{next section}}}}. There is also a
variant of {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}} which does not modify the parser; this provides a
form of {\hyperref[\detokenize{user-extensions/syntax-extensions:abbreviations}]{\sphinxcrossref{\DUrole{std,std-ref}{abbreviation}}}}. It is
sometimes expected that the same symbolic notation has different meanings in
different contexts; to achieve this form of overloading, \DUrole{smallcaps}{Coq} offers a notion
of {\hyperref[\detokenize{user-extensions/syntax-extensions:scopes}]{\sphinxcrossref{\DUrole{std,std-ref}{interpretation scopes}}}}.
The main command to provide custom notations for tactics is {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.tactic-notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Tactic Notation}}}}}.


\subsection{Notations}
\label{\detokenize{user-extensions/syntax-extensions:notations}}\label{\detokenize{user-extensions/syntax-extensions:id1}}

\subsubsection{Basic notations}
\label{\detokenize{user-extensions/syntax-extensions:basic-notations}}\index{Notation (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.notation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Notation}}}}
\end{fulllineitems}


A \sphinxstyleemphasis{notation} is a symbolic expression denoting some term or term
pattern.

A typical notation is the use of the infix symbol \sphinxcode{\sphinxupquote{/\textbackslash{}}} to denote the
logical conjunction (and). Such a notation is declared by

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{A /\PYGZbs{} B}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{and} \PYG{n}{A} \PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

The expression \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{and} \DUrole{name}{A} \DUrole{name}{B}\DUrole{operator}{)}}} is the abbreviated term and the string \sphinxcode{\sphinxupquote{\DUrole{literal,string,double}{"A /\textbackslash{} B"}}}
(called a \sphinxstyleemphasis{notation}) tells how it is symbolically written.

A notation is always surrounded by double quotes (except when the
abbreviation has the form of an ordinary applicative expression;
see {\hyperref[\detokenize{user-extensions/syntax-extensions:abbreviations}]{\sphinxcrossref{\DUrole{std,std-ref}{Abbreviations}}}}). The notation is composed of \sphinxstyleemphasis{tokens} separated by
spaces. Identifiers in the string (such as \sphinxcode{\sphinxupquote{A}} and \sphinxcode{\sphinxupquote{B}}) are the \sphinxstyleemphasis{parameters}
of the notation. Each of them must occur at least once in the denoted term. The
other elements of the string (such as \sphinxcode{\sphinxupquote{/\textbackslash{}}}) are the \sphinxstyleemphasis{symbols}.

An identifier can be used as a symbol but it must be surrounded by
single quotes to avoid the confusion with a parameter. Similarly,
every symbol of at least 3 characters and starting with a simple quote
must be quoted (then it starts by two single quotes). Here is an
example.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}IF\PYGZsq{} c1 \PYGZsq{}then\PYGZsq{} c2 \PYGZsq{}else\PYGZsq{} c3}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{IF\PYGZus{}then\PYGZus{}else} \PYG{n}{c1} \PYG{n}{c2} \PYG{n}{c3}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

A notation binds a syntactic expression to a term. Unless the parser
and pretty-printer of Coq already know how to deal with the syntactic
expression (see {\hyperref[\detokenize{user-extensions/syntax-extensions:reservingnotations}]{\sphinxcrossref{\DUrole{std,std-ref}{Reserving notations}}}}), explicit precedences and
associativity rules have to be given.

\begin{sphinxadmonition}{note}{Note:}
The right-hand side of a notation is interpreted at the time the notation is
given. In particular, disambiguation of constants, {\hyperref[\detokenize{language/gallina-extensions:implicitarguments}]{\sphinxcrossref{\DUrole{std,std-ref}{implicit arguments}}}}, {\hyperref[\detokenize{language/gallina-extensions:coercions}]{\sphinxcrossref{\DUrole{std,std-ref}{coercions}}}}, etc. are resolved at the
time of the declaration of the notation.
\end{sphinxadmonition}


\subsubsection{Precedences and associativity}
\label{\detokenize{user-extensions/syntax-extensions:precedences-and-associativity}}
Mixing different symbolic notations in the same text may cause serious
parsing ambiguity. To deal with the ambiguity of notations, Coq uses
precedence levels ranging from 0 to 100 (plus one extra level numbered
200) and associativity rules.

Consider for example the new notation

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{A \PYGZbs{}/ B}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{or} \PYG{n}{A} \PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

Clearly, an expression such as \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{A}\DUrole{operator}{:}\DUrole{keyword,type}{Prop}\DUrole{operator}{,} \DUrole{name}{True} \DUrole{operator}{/\textbackslash{}} \DUrole{name}{A} \DUrole{operator}{\textbackslash{}/} \DUrole{name}{A} \DUrole{operator}{\textbackslash{}/} \DUrole{name}{False}}}
is ambiguous. To tell the Coq parser how to interpret the
expression, a priority between the symbols \sphinxcode{\sphinxupquote{/\textbackslash{}}} and \sphinxcode{\sphinxupquote{\textbackslash{}/}} has to be
given. Assume for instance that we want conjunction to bind more than
disjunction. This is expressed by assigning a precedence level to each
notation, knowing that a lower level binds more than a higher level.
Hence the level for disjunction must be higher than the level for
conjunction.

Since connectives are not tight articulation points of a text, it
is reasonable to choose levels not so far from the highest level which
is 100, for example 85 for disjunction and 80 for conjunction %
\begin{footnote}[17]\sphinxAtStartFootnote
which are the levels effectively chosen in the current
implementation of Coq
%
\end{footnote}.

Similarly, an associativity is needed to decide whether \sphinxcode{\sphinxupquote{\DUrole{name}{True} \DUrole{operator}{/\textbackslash{}} \DUrole{name}{False} \DUrole{operator}{/\textbackslash{}} \DUrole{name}{False}}}
defaults to \sphinxcode{\sphinxupquote{\DUrole{name}{True} \DUrole{operator}{/\textbackslash{}} \DUrole{operator}{(}\DUrole{name}{False} \DUrole{operator}{/\textbackslash{}} \DUrole{name}{False}\DUrole{operator}{)}}} (right associativity) or to
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{True} \DUrole{operator}{/\textbackslash{}} \DUrole{name}{False}\DUrole{operator}{)} \DUrole{operator}{/\textbackslash{}} \DUrole{name}{False}}} (left associativity). We may even consider that the
expression is not well-formed and that parentheses are mandatory (this is a “no
associativity”) %
\begin{footnote}[18]\sphinxAtStartFootnote
Coq accepts notations declared as nonassociative but the parser on
which Coq is built, namely Camlp5, currently does not implement \sphinxcode{\sphinxupquote{no associativity}} and
replaces it with \sphinxcode{\sphinxupquote{left associativity}}; hence it is the same for Coq: \sphinxcode{\sphinxupquote{no associativity}}
is in fact \sphinxcode{\sphinxupquote{left associativity}} for the purposes of parsing
%
\end{footnote}. We do not know of a special convention of
the associativity of disjunction and conjunction, so let us apply for instance a
right associativity (which is the choice of Coq).

Precedence levels and associativity rules of notations have to be
given between parentheses in a list of modifiers that the {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}}
command understands. Here is how the previous examples refine.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{A /\PYGZbs{} B}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{and} \PYG{n}{A} \PYG{n}{B}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{80}\PYG{o}{,} \PYG{k}{right} \PYG{n}{associativity}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{A \PYGZbs{}/ B}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{or} \PYG{n}{A} \PYG{n}{B}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{85}\PYG{o}{,} \PYG{k}{right} \PYG{n}{associativity}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

By default, a notation is considered nonassociative, but the
precedence level is mandatory (except for special cases whose level is
canonical). The level is either a number or the phrase \sphinxcode{\sphinxupquote{next level}}
whose meaning is obvious.
Some {\hyperref[\detokenize{language/coq-library:init-notations}]{\sphinxcrossref{\DUrole{std,std-ref}{associativities are predefined}}}} in the
\sphinxcode{\sphinxupquote{Notations}} module.


\subsubsection{Complex notations}
\label{\detokenize{user-extensions/syntax-extensions:complex-notations}}
Notations can be made from arbitrarily complex symbols. One can for
instance define prefix notations.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZti{} x}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{not} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{75}\PYG{o}{,} \PYG{k}{right} \PYG{n}{associativity}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

One can also define notations for incomplete terms, with the hole
expected to be inferred during type checking.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x = y}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{o}{@}\PYG{n}{eq} \PYG{o}{\PYGZus{}} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{70}\PYG{o}{,} \PYG{n}{no} \PYG{n}{associativity}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

One can define \sphinxstyleemphasis{closed} notations whose both sides are symbols. In this case,
the default precedence level for the inner subexpression is 200, and the default
level for the notation itself is 0.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{( x , y )}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{o}{@}\PYG{n}{pair} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

One can also define notations for binders.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZob{} x : A \textbar{} P \PYGZcb{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{sig} \PYG{n}{A} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{P}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

In the last case though, there is a conflict with the notation for
type casts. The notation for types casts, as shown by the command {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.print-grammar-constr}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print
Grammar constr}}}}} is at level 100. To avoid \sphinxcode{\sphinxupquote{x : A}} being parsed as a type cast,
it is necessary to put \sphinxcode{\sphinxupquote{x}} at a level below 100, typically 99. Hence, a correct
definition is the following:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZob{} x : A \textbar{} P \PYGZcb{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{sig} \PYG{n}{A} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{P}\PYG{o}{)}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{99}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Setting} \PYG{n}{notation} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{0}\PYG{o}{.}
\end{sphinxVerbatim}

More generally, it is required that notations are explicitly factorized on the
left. See the next section for more about factorization.


\subsubsection{Simple factorization rules}
\label{\detokenize{user-extensions/syntax-extensions:simple-factorization-rules}}
Coq extensible parsing is performed by \sphinxstyleemphasis{Camlp5} which is essentially a LL1
parser: it decides which notation to parse by looking at tokens from left to right.
Hence, some care has to be taken not to hide already existing rules by new
rules. Some simple left factorization work has to be done. Here is an example.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x \PYGZlt{} y}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{lt} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{70}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x \PYGZlt{} y \PYGZlt{} z}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{x} \PYG{o}{\PYGZlt{}} \PYG{n}{y} \PYG{o}{/\PYGZbs{}} \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{n}{z}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{70}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{55}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x \PYGZlt{} y \PYGZlt{} z}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{x} \PYG{o}{\PYGZlt{}} \PYG{n}{y} \PYG{o}{/\PYGZbs{}} \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{n}{z}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{70}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:}
    \PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZus{} \PYGZlt{} \PYGZus{} \PYGZlt{} \PYGZus{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{is} \PYG{n}{already} \PYG{n}{defined} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{70} \PYG{k}{with} \PYG{n}{arguments} \PYG{n}{constr}
    \PYG{n}{at} \PYG{n}{next} \PYG{n}{level}\PYG{o}{,} \PYG{n}{constr} \PYG{n}{at} \PYG{n}{next} \PYG{n}{level}\PYG{o}{,} \PYG{n}{constr} \PYG{n}{at} \PYG{n}{next} \PYG{n}{level}
    \PYG{n}{while} \PYG{n}{it} \PYG{k}{is} \PYG{n}{now} \PYG{n}{required} \PYG{n}{to} \PYG{n}{be} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{70} \PYG{k}{with} \PYG{n}{arguments} \PYG{n}{constr}
    \PYG{n}{at} \PYG{n}{next} \PYG{n}{level}\PYG{o}{,} \PYG{n}{constr} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{200}\PYG{o}{,} \PYG{n}{constr} \PYG{n}{at} \PYG{n}{next} \PYG{n}{level}\PYG{o}{.}
\end{sphinxVerbatim}

In order to factorize the left part of the rules, the subexpression
referred to by \sphinxcode{\sphinxupquote{y}} has to be at the same level in both rules. However the
default behavior puts \sphinxcode{\sphinxupquote{y}} at the next level below 70 in the first rule
(\sphinxcode{\sphinxupquote{no associativity}} is the default), and at level 200 in the second
rule (\sphinxcode{\sphinxupquote{level 200}} is the default for inner expressions). To fix this, we
need to force the parsing level of \sphinxcode{\sphinxupquote{y}}, as follows.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x \PYGZlt{} y}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{lt} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{70}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x \PYGZlt{} y \PYGZlt{} z}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{x} \PYG{o}{\PYGZlt{}} \PYG{n}{y} \PYG{o}{/\PYGZbs{}} \PYG{n}{y} \PYG{o}{\PYGZlt{}} \PYG{n}{z}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{70}\PYG{o}{,} \PYG{n}{y} \PYG{n}{at} \PYG{n}{next} \PYG{n}{level}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

For the sake of factorization with Coq predefined rules, simple rules
have to be observed for notations starting with a symbol, e.g., rules
starting with “\sphinxcode{\sphinxupquote{\{}}” or “\sphinxcode{\sphinxupquote{(}}” should be put at level 0. The list
of Coq predefined notations can be found in the chapter on {\hyperref[\detokenize{language/coq-library:thecoqlibrary}]{\sphinxcrossref{\DUrole{std,std-ref}{The Coq library}}}}.
\index{Print Grammar constr (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.print-grammar-constr}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Grammar~constr.}}}}
This command displays the current state of the Coq term parser.

\end{fulllineitems}

\index{Print Grammar pattern (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.print-grammar-pattern}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Grammar~pattern.}}}}
This displays the state of the subparser of patterns (the parser used in the
grammar of the match with constructions).

\end{fulllineitems}



\subsubsection{Displaying symbolic notations}
\label{\detokenize{user-extensions/syntax-extensions:displaying-symbolic-notations}}
The command {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}} has an effect both on the Coq parser and on the
Coq printer. For example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{and} \PYG{n}{True} \PYG{n}{True}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{True} \PYG{o}{/\PYGZbs{}} \PYG{n}{True}
         \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}

However, printing, especially pretty-printing, also requires some
care. We may want specific indentations, line breaks, alignment if on
several lines, etc. For pretty-printing, \DUrole{smallcaps}{Coq} relies on \DUrole{smallcaps}{OCaml}
formatting library, which provides indentation and automatic line
breaks depending on page width by means of \sphinxstyleemphasis{formatting boxes}.

The default printing of notations is rudimentary. For printing a
notation, a formatting box is opened in such a way that if the
notation and its arguments cannot fit on a single line, a line break
is inserted before the symbols of the notation and the arguments on
the next lines are aligned with the argument on the first line.

A first, simple control that a user can have on the printing of a
notation is the insertion of spaces at some places of the notation.
This is performed by adding extra spaces between the symbols and
parameters: each extra space (other than the single space needed to
separate the components) is interpreted as a space to be inserted by
the printer. Here is an example showing how to add spaces around the
bar of the notation.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZob{}\PYGZob{} x : A \textbar{} P \PYGZcb{}\PYGZcb{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{sig} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{A} \PYG{o}{=\PYGZgt{}} \PYG{n}{P}\PYG{o}{)}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{0}\PYG{o}{,} \PYG{n}{x} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{99}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{sig} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}\PYG{o}{=}\PYG{n}{x}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{\PYGZob{}}\PYG{o}{\PYGZob{}}\PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\textbar{}} \PYG{n}{x} \PYG{o}{=} \PYG{n}{x}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{k+kn}{Set}
\end{sphinxVerbatim}

The second, more powerful control on printing is by using the format
modifier. Here is an example

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}If\PYGZsq{} c1 \PYGZsq{}then\PYGZsq{} c2 \PYGZsq{}else\PYGZsq{} c3}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{IF\PYGZus{}then\PYGZus{}else} \PYG{n}{c1} \PYG{n}{c2} \PYG{n}{c3}\PYG{o}{)}
\PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{200}\PYG{o}{,} \PYG{k}{right} \PYG{n}{associativity}\PYG{o}{,} \PYG{n}{format}
\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}[v   \PYGZsq{} \PYGZsq{}If\PYGZsq{}  c1 \PYGZsq{}/\PYGZsq{} \PYGZsq{}[\PYGZsq{} \PYGZsq{}then\PYGZsq{}  c2  \PYGZsq{}]\PYGZsq{} \PYGZsq{}/\PYGZsq{} \PYGZsq{}[\PYGZsq{} \PYGZsq{}else\PYGZsq{}  c3 \PYGZsq{}]\PYGZsq{} \PYGZsq{}]\PYGZsq{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Identifier} \PYG{k}{\PYGZsq{}}\PYG{n}{If\PYGZsq{}} \PYG{n}{now} \PYG{n}{a} \PYG{n}{keyword}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check}
  \PYG{o}{(}\PYG{n}{IF\PYGZus{}then\PYGZus{}else} \PYG{o}{(}\PYG{n}{IF\PYGZus{}then\PYGZus{}else} \PYG{n}{True} \PYG{n}{False} \PYG{n}{True}\PYG{o}{)}
    \PYG{o}{(}\PYG{n}{IF\PYGZus{}then\PYGZus{}else} \PYG{n}{True} \PYG{n}{False} \PYG{n}{True}\PYG{o}{)}
    \PYG{o}{(}\PYG{n}{IF\PYGZus{}then\PYGZus{}else} \PYG{n}{True} \PYG{n}{False} \PYG{n}{True}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{If} \PYG{n}{If} \PYG{n}{True}
          \PYG{k}{then} \PYG{n}{False} 
          \PYG{k}{else} \PYG{n}{True}
       \PYG{k}{then} \PYG{n}{If} \PYG{n}{True}
               \PYG{k}{then} \PYG{n}{False} 
               \PYG{k}{else} \PYG{n}{True} 
       \PYG{k}{else} \PYG{n}{If} \PYG{n}{True}
               \PYG{k}{then} \PYG{n}{False} 
               \PYG{k}{else} \PYG{n}{True}
         \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}

A \sphinxstyleemphasis{format} is an extension of the string denoting the notation with
the possible following elements delimited by single quotes:
\begin{itemize}
\item {} 
extra spaces are translated into simple spaces

\item {} 
tokens of the form \sphinxcode{\sphinxupquote{'/ '}} are translated into breaking point, in
case a line break occurs, an indentation of the number of spaces after
the “ \sphinxcode{\sphinxupquote{/}}” is applied (2 spaces in the given example)

\item {} 
token of the form \sphinxcode{\sphinxupquote{'//'}} force writing on a new line

\item {} 
well-bracketed pairs of tokens of the form \sphinxcode{\sphinxupquote{'{[} '}} and \sphinxcode{\sphinxupquote{'{]}'}} are
translated into printing boxes; in case a line break occurs, an extra
indentation of the number of spaces given after the “ \sphinxcode{\sphinxupquote{{[}}}” is applied
(4 spaces in the example)

\item {} 
well-bracketed pairs of tokens of the form \sphinxcode{\sphinxupquote{'{[}hv '}} and \sphinxcode{\sphinxupquote{'{]}'}} are
translated into horizontal-or-else-vertical printing boxes; if the
content of the box does not fit on a single line, then every breaking
point forces a newline and an extra indentation of the number of
spaces given after the “ \sphinxcode{\sphinxupquote{{[}}}” is applied at the beginning of each
newline (3 spaces in the example)

\item {} 
well-bracketed pairs of tokens of the form \sphinxcode{\sphinxupquote{'{[}v '}} and \sphinxcode{\sphinxupquote{'{]}'}} are
translated into vertical printing boxes; every breaking point forces a
newline, even if the line is large enough to display the whole content
of the box, and an extra indentation of the number of spaces given
after the “\sphinxcode{\sphinxupquote{{[}}}” is applied at the beginning of each newline

\end{itemize}

Notations disappear when a section is closed. No typing of the denoted
expression is performed at definition time. Type checking is done only
at the time of use of the notation.

\begin{sphinxadmonition}{note}{Note:}
Sometimes, a notation is expected only for the parser. To do
so, the option \sphinxcode{\sphinxupquote{only parsing}} is allowed in the list of modifiers
of {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}}. Conversely, the \sphinxcode{\sphinxupquote{only printing}} modifier can be
used to declare that a notation should only be used for printing and
should not declare a parsing rule. In particular, such notations do
not modify the parser.
\end{sphinxadmonition}


\subsubsection{The Infix command}
\label{\detokenize{user-extensions/syntax-extensions:the-infix-command}}
The {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.infix}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Infix}}}}} command is a shortening for declaring notations of infix
symbols.
\index{Infix (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.infix}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Infix~"\DUrole{hole}{symbol}"~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~(\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{modifier}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}).}}}}
This command is equivalent to
\begin{quote}

\sphinxcode{\sphinxupquote{\DUrole{notation}{Notation "x \DUrole{hole}{symbol} y" := ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}} x y) (\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{modifier}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}).}}}
\end{quote}

where \sphinxcode{\sphinxupquote{x}} and \sphinxcode{\sphinxupquote{y}} are fresh names. Here is an example.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Infix} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{/\PYGZbs{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{and} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{80}\PYG{o}{,} \PYG{k}{right} \PYG{n}{associativity}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\end{fulllineitems}



\subsubsection{Reserving notations}
\label{\detokenize{user-extensions/syntax-extensions:reserving-notations}}\label{\detokenize{user-extensions/syntax-extensions:reservingnotations}}
A given notation may be used in different contexts. Coq expects all
uses of the notation to be defined at the same precedence and with the
same associativity. To avoid giving the precedence and associativity
every time, it is possible to declare a parsing rule in advance
without giving its interpretation. Here is an example from the initial
state of Coq.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Reserved} \PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x = y}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{70}\PYG{o}{,} \PYG{n}{no} \PYG{n}{associativity}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

Reserving a notation is also useful for simultaneously defining an
inductive type or a recursive constant and a notation for it.

\begin{sphinxadmonition}{note}{Note:}
The notations mentioned in the module {\hyperref[\detokenize{language/coq-library:init-notations}]{\sphinxcrossref{\DUrole{std,std-ref}{Notations}}}} are reserved. Hence
their precedence and associativity cannot be changed.
\end{sphinxadmonition}


\subsubsection{Simultaneous definition of terms and notations}
\label{\detokenize{user-extensions/syntax-extensions:simultaneous-definition-of-terms-and-notations}}
Thanks to reserved notations, the inductive, co-inductive, record, recursive and
corecursive definitions can benefit from customized notations. To do this, insert
a \sphinxcode{\sphinxupquote{where}} notation clause after the definition of the (co)inductive type or
(co)recursive term (or after the definition of each of them in case of mutual
definitions). The exact syntax is given by {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl-notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{decl\_notation}}}}} for inductive,
co-inductive, recursive and corecursive definitions and in {\hyperref[\detokenize{language/gallina-extensions:record-types}]{\sphinxcrossref{\DUrole{std,std-ref}{Record types}}}}
for records. Here are examples:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Reserved} \PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{A \PYGZam{} B}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{80}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{and\PYGZsq{}} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{conj\PYGZsq{}} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZam{}} \PYG{n}{B}
\PYG{n}{where} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{A \PYGZam{} B}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{and\PYGZsq{}} \PYG{n}{A} \PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{plus} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
    \PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
    \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{p}\PYG{o}{+}\PYG{n}{m}\PYG{o}{)}
\PYG{k}{end}
\PYG{n}{where} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{n + m}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{plus} \PYG{n}{n} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Displaying information about notations}
\label{\detokenize{user-extensions/syntax-extensions:displaying-information-about-notations}}\index{Printing Notations (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:flag.printing-notations}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Notations}}}}
Controls whether to use notations for printing terms wherever possible.
Default is on.

\end{fulllineitems}



\sphinxstrong{See also:}

\begin{description}
\item[{{\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-all}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing All}}}}}}] \leavevmode
To disable other elements in addition to notations.

\end{description}




\subsubsection{Locating notations}
\label{\detokenize{user-extensions/syntax-extensions:locating-notations}}\label{\detokenize{user-extensions/syntax-extensions:id4}}
To know to which notations a given symbol belongs to, use the {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.locate}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Locate}}}}}
command. You can call it on any (composite) symbol surrounded by double quotes.
To locate a particular notation, use a string where the variables of the
notation are replaced by “\sphinxcode{\sphinxupquote{\_}}” and where possible single quotes inserted around
identifiers or tokens starting with a single quote are dropped.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Locate} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{exists}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    \PYG{k+kn}{Notation}
    \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}exists\PYGZsq{} x .. y , p}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{ex} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{o}{..} \PYG{o}{(}\PYG{n}{ex} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{p}\PYG{o}{)}\PYG{o}{)} \PYG{o}{..}\PYG{o}{)} \PYG{o}{:} \PYG{n}{type\PYGZus{}scope}
    \PYG{o}{(}\PYG{n}{default} \PYG{n}{interpretation}\PYG{o}{)}
    \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}exists\PYGZsq{} ! x .. y , p}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{ex}
                                 \PYG{o}{(}\PYG{n}{unique}
                                    \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{o}{..} \PYG{o}{(}\PYG{n}{ex} \PYG{o}{(}\PYG{n}{unique} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{p}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)} \PYG{o}{..}\PYG{o}{)}\PYG{o}{)}
    \PYG{o}{:} \PYG{n}{type\PYGZus{}scope} \PYG{o}{(}\PYG{n}{default} \PYG{n}{interpretation}\PYG{o}{)}

\PYG{n}{Locate} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{exists \PYGZus{} .. \PYGZus{} , \PYGZus{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
    \PYG{k+kn}{Notation}
    \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}exists\PYGZsq{} x .. y , p}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{ex} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{o}{..} \PYG{o}{(}\PYG{n}{ex} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{p}\PYG{o}{)}\PYG{o}{)} \PYG{o}{..}\PYG{o}{)} \PYG{o}{:} \PYG{n}{type\PYGZus{}scope}
    \PYG{o}{(}\PYG{n}{default} \PYG{n}{interpretation}\PYG{o}{)}
\end{sphinxVerbatim}


\subsubsection{Notations and binders}
\label{\detokenize{user-extensions/syntax-extensions:notations-and-binders}}
Notations can include binders. This section lists
different ways to deal with binders. For further examples, see also
{\hyperref[\detokenize{user-extensions/syntax-extensions:recursivenotationswithbinders}]{\sphinxcrossref{\DUrole{std,std-ref}{Notations with recursive patterns involving binders}}}}.


\paragraph{Binders bound in the notation and parsed as identifiers}
\label{\detokenize{user-extensions/syntax-extensions:binders-bound-in-the-notation-and-parsed-as-identifiers}}
Here is the basic example of a notation using a binder:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}sigma\PYGZsq{} x : A , B}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{sigT} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{A} \PYG{o}{=\PYGZgt{}} \PYG{n}{B}\PYG{o}{)}\PYG{o}{)}
  \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{200}\PYG{o}{,} \PYG{n}{x} \PYG{n}{ident}\PYG{o}{,} \PYG{n}{A} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{200}\PYG{o}{,} \PYG{k}{right} \PYG{n}{associativity}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

The binding variables in the right-hand side that occur as a parameter
of the notation (here \sphinxcode{\sphinxupquote{\DUrole{name}{x}}}) dynamically bind all the occurrences
in their respective binding scope after instantiation of the
parameters of the notation. This means that the term bound to \sphinxcode{\sphinxupquote{\DUrole{name}{B}}} can
refer to the variable name bound to \sphinxcode{\sphinxupquote{\DUrole{name}{x}}} as shown in the following
application of the notation:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{sigma} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{z} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{sigma} \PYG{n}{z} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{z} \PYG{o}{=} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{k+kn}{Set}
\end{sphinxVerbatim}

Notice the modifier \sphinxcode{\sphinxupquote{x ident}} in the declaration of the
notation. It tells to parse \sphinxcode{\sphinxupquote{\DUrole{name}{x}}} as a single identifier.


\paragraph{Binders bound in the notation and parsed as patterns}
\label{\detokenize{user-extensions/syntax-extensions:binders-bound-in-the-notation-and-parsed-as-patterns}}
In the same way as patterns can be used as binders, as in
\sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{keyword}{'}\DUrole{operator}{(}\DUrole{name}{x}\DUrole{operator}{,}\DUrole{name}{y}\DUrole{operator}{)} \DUrole{operator}{=\textgreater{}} \DUrole{name}{x}\DUrole{operator}{+}\DUrole{name}{y}}} or \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{keyword}{'}\DUrole{operator}{(}\DUrole{name}{existT} \DUrole{operator}{\_} \DUrole{name}{x} \DUrole{operator}{\_)} \DUrole{operator}{=\textgreater{}} \DUrole{name}{x}}}, notations can be
defined so that any \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}}} can be used in place of the
binder. Here is an example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}subset\PYGZsq{} \PYGZsq{} p , P }\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{sig} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{P}\PYG{o}{)}\PYG{o}{)}
  \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{200}\PYG{o}{,} \PYG{n}{p} \PYG{k}{pattern}\PYG{o}{,} \PYG{n}{format} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}subset\PYGZsq{}  \PYGZsq{} p ,  P}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{subset} \PYG{k}{\PYGZsq{}}\PYG{o}{(}\PYG{n}{x}\PYG{o}{,}\PYG{n}{y}\PYG{o}{)}\PYG{o}{,} \PYG{n}{x}\PYG{o}{+}\PYG{n}{y}\PYG{o}{=}\PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{subset} \PYG{k}{\PYGZsq{}}\PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{)}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{k+kn}{Set}
\end{sphinxVerbatim}

The modifier \sphinxcode{\sphinxupquote{p pattern}} in the declaration of the notation tells to parse
\sphinxcode{\sphinxupquote{\DUrole{name}{p}}} as a pattern. Note that a single variable is both an identifier and a
pattern, so, e.g., the following also works:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{subset} \PYG{k}{\PYGZsq{}}\PYG{n}{x}\PYG{o}{,} \PYG{n}{x}\PYG{o}{=}\PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{subset} \PYG{k}{\PYGZsq{}}\PYG{n}{x}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{k+kn}{Set}
\end{sphinxVerbatim}

If one wants to prevent such a notation to be used for printing when the
pattern is reduced to a single identifier, one has to use instead
the modifier \sphinxcode{\sphinxupquote{p strict pattern}}. For parsing, however, a
\sphinxcode{\sphinxupquote{strict pattern}} will continue to include the case of a
variable. Here is an example showing the difference:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}subset\PYGZus{}bis\PYGZsq{} \PYGZsq{} p , P}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{sig} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{P}\PYG{o}{)}\PYG{o}{)}
  \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{200}\PYG{o}{,} \PYG{n}{p} \PYG{n}{strict} \PYG{k}{pattern}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}subset\PYGZus{}bis\PYGZsq{} p , P }\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{sig} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{P}\PYG{o}{)}\PYG{o}{)}
  \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{200}\PYG{o}{,} \PYG{n}{p} \PYG{n}{ident}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{subset\PYGZus{}bis} \PYG{k}{\PYGZsq{}}\PYG{n}{x}\PYG{o}{,} \PYG{n}{x}\PYG{o}{=}\PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{subset\PYGZus{}bis} \PYG{n}{x}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{k+kn}{Set}
\end{sphinxVerbatim}

The default level for a \sphinxcode{\sphinxupquote{pattern}} is 0. One can use a different level by
using \sphinxcode{\sphinxupquote{pattern at level}} \(n\) where the scale is the same as the one for
terms (see {\hyperref[\detokenize{language/coq-library:init-notations}]{\sphinxcrossref{\DUrole{std,std-ref}{Notations}}}}).


\paragraph{Binders bound in the notation and parsed as terms}
\label{\detokenize{user-extensions/syntax-extensions:binders-bound-in-the-notation-and-parsed-as-terms}}
Sometimes, for the sake of factorization of rules, a binder has to be
parsed as a term. This is typically the case for a notation such as
the following:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZob{} x : A \textbar{} P \PYGZcb{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{sig} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{A} \PYG{o}{=\PYGZgt{}} \PYG{n}{P}\PYG{o}{)}\PYG{o}{)}
    \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{0}\PYG{o}{,} \PYG{n}{x} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{99} \PYG{k}{as} \PYG{n}{ident}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

This is so because the grammar also contains rules starting with \sphinxcode{\sphinxupquote{\DUrole{operator}{\{\}}}} and
followed by a term, such as the rule for the notation \sphinxcode{\sphinxupquote{\DUrole{operator}{\{} \DUrole{name}{A} \DUrole{operator}{\}} \DUrole{operator}{+} \DUrole{operator}{\{} \DUrole{name}{B} \DUrole{operator}{\}}}} for the
constant \sphinxcode{\sphinxupquote{\DUrole{name}{sumbool}}} (see {\hyperref[\detokenize{language/coq-library:specification}]{\sphinxcrossref{\DUrole{std,std-ref}{Specification}}}}).

Then, in the rule, \sphinxcode{\sphinxupquote{x ident}} is replaced by \sphinxcode{\sphinxupquote{x at level 99 as ident}} meaning
that \sphinxcode{\sphinxupquote{x}} is parsed as a term at level 99 (as done in the notation for
\sphinxcode{\sphinxupquote{\DUrole{name}{sumbool}}}), but that this term has actually to be an identifier.

The notation \sphinxcode{\sphinxupquote{\DUrole{operator}{\{} \DUrole{name}{x} \DUrole{operator}{\textbar{}} \DUrole{name}{P} \DUrole{operator}{\}}}} is already defined in the standard
library with the \sphinxcode{\sphinxupquote{as ident}} modifier. We cannot redefine it but
one can define an alternative notation, say \sphinxcode{\sphinxupquote{\DUrole{operator}{\{} \DUrole{name}{p} \DUrole{name}{such} \DUrole{name}{that} \DUrole{name}{P} \DUrole{operator}{\}}}},
using instead \sphinxcode{\sphinxupquote{as pattern}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZob{} p \PYGZsq{}such\PYGZsq{} \PYGZsq{}that\PYGZsq{} P \PYGZcb{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{sig} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{p} \PYG{o}{=\PYGZgt{}} \PYG{n}{P}\PYG{o}{)}\PYG{o}{)}
  \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{0}\PYG{o}{,} \PYG{n}{p} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{99} \PYG{k}{as} \PYG{k}{pattern}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

Then, the following works:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{\PYGZob{}}\PYG{o}{(}\PYG{n}{x}\PYG{o}{,}\PYG{n}{y}\PYG{o}{)} \PYG{n}{such} \PYG{n}{that} \PYG{n}{x}\PYG{o}{+}\PYG{n}{y}\PYG{o}{=}\PYG{l+m+mi}{0}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{o}{\PYGZob{}}\PYG{o}{(}\PYG{n}{x}\PYG{o}{,} \PYG{n}{y}\PYG{o}{)} \PYG{n}{such} \PYG{n}{that} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{k+kn}{Set}
\end{sphinxVerbatim}

To enforce that the pattern should not be used for printing when it
is just an identifier, one could have said
\sphinxcode{\sphinxupquote{p at level 99 as strict pattern}}.

Note also that in the absence of a \sphinxcode{\sphinxupquote{as ident}}, \sphinxcode{\sphinxupquote{as strict pattern}} or
\sphinxcode{\sphinxupquote{as pattern}} modifiers, the default is to consider subexpressions occurring
in binding position and parsed as terms to be \sphinxcode{\sphinxupquote{as ident}}.


\paragraph{Binders not bound in the notation}
\label{\detokenize{user-extensions/syntax-extensions:binders-not-bound-in-the-notation}}\label{\detokenize{user-extensions/syntax-extensions:notationswithbinders}}
We can also have binders in the right-hand side of a notation which
are not themselves bound in the notation. In this case, the binders
are considered up to renaming of the internal binder. E.g., for the
notation

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}exists\PYGZus{}different\PYGZsq{} n}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{k}{exists} \PYG{n}{p}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{p}\PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}}\PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{200}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

the next command fails because p does not bind in the instance of n.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{exists\PYGZus{}different} \PYG{n}{p}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{The} \PYG{n}{reference} \PYG{n}{p} \PYG{n}{was} \PYG{n}{not} \PYG{n}{found} \PYG{k}{in} \PYG{n}{the} \PYG{n}{current} \PYG{n}{environment}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{[\PYGZgt{} a , .. , b \PYGZlt{}]}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=}
  \PYG{o}{(}\PYG{n}{cons} \PYG{n}{a} \PYG{o}{..} \PYG{o}{(}\PYG{n}{cons} \PYG{n}{b} \PYG{n}{nil}\PYG{o}{)} \PYG{o}{..}\PYG{o}{,} \PYG{n}{cons} \PYG{n}{b} \PYG{o}{..} \PYG{o}{(}\PYG{n}{cons} \PYG{n}{a} \PYG{n}{nil}\PYG{o}{)} \PYG{o}{..}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Notations with recursive patterns}
\label{\detokenize{user-extensions/syntax-extensions:notations-with-recursive-patterns}}\label{\detokenize{user-extensions/syntax-extensions:recursivenotations}}
A mechanism is provided for declaring elementary notations with
recursive patterns. The basic example is:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{[ x ; .. ; y ]}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{cons} \PYG{n}{x} \PYG{o}{..} \PYG{o}{(}\PYG{n}{cons} \PYG{n}{y} \PYG{n}{nil}\PYG{o}{)} \PYG{o}{..}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Setting} \PYG{n}{notation} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{0}\PYG{o}{.}
\end{sphinxVerbatim}

On the right-hand side, an extra construction of the form \sphinxcode{\sphinxupquote{.. t ..}} can
be used. Notice that \sphinxcode{\sphinxupquote{..}} is part of the Coq syntax and it must not be
confused with the three-dots notation “\sphinxcode{\sphinxupquote{…}}” used in this manual to denote
a sequence of arbitrary size.

On the left-hand side, the part “\sphinxcode{\sphinxupquote{x s .. s y}}” of the notation parses
any number of times (but at least once) a sequence of expressions
separated by the sequence of tokens \sphinxcode{\sphinxupquote{s}} (in the example, \sphinxcode{\sphinxupquote{s}} is just “\sphinxcode{\sphinxupquote{;}}”).

The right-hand side must contain a subterm of the form either
\sphinxcode{\sphinxupquote{\(\phi\)(x, .. \(\phi\)(y,t) ..)}} or \sphinxcode{\sphinxupquote{\(\phi\)(y, .. \(\phi\)(x,t) ..)}} where \(φ([~]_E , [~]_I)\),
called the \sphinxstyleemphasis{iterator} of the recursive notation is an arbitrary expression with
distinguished placeholders and where \(t\) is called the \sphinxstyleemphasis{terminating
expression} of the recursive notation. In the example, we choose the names
\(x\) and \(y\) but in practice they can of course be chosen
arbitrarily. Note that the placeholder \([~]_I\) has to occur only once but
\([~]_E\) can occur several times.

Parsing the notation produces a list of expressions which are used to
fill the first placeholder of the iterating pattern which itself is
repeatedly nested as many times as the length of the list, the second
placeholder being the nesting point. In the innermost occurrence of the
nested iterating pattern, the second placeholder is finally filled with the
terminating expression.

In the example above, the iterator \(φ([~]_E , [~]_I)\) is \(cons [~]_E [~]_I\)
and the terminating expression is \sphinxcode{\sphinxupquote{nil}}. Here are other examples:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{( x , y , .. , z )}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{pair} \PYG{o}{..} \PYG{o}{(}\PYG{n}{pair} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{o}{..} \PYG{n}{z}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{[\textbar{} t * ( x , y , .. , z ) ; ( a , b , .. , c )  * u \textbar{}]}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=}
  \PYG{o}{(}\PYG{n}{pair} \PYG{o}{(}\PYG{n}{pair} \PYG{o}{..} \PYG{o}{(}\PYG{n}{pair} \PYG{o}{(}\PYG{n}{pair} \PYG{n}{t} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{n}{pair} \PYG{n}{t} \PYG{n}{y}\PYG{o}{)}\PYG{o}{)} \PYG{o}{..} \PYG{o}{(}\PYG{n}{pair} \PYG{n}{t} \PYG{n}{z}\PYG{o}{)}\PYG{o}{)}
        \PYG{o}{(}\PYG{n}{pair} \PYG{o}{..} \PYG{o}{(}\PYG{n}{pair} \PYG{o}{(}\PYG{n}{pair} \PYG{n}{a} \PYG{n}{u}\PYG{o}{)} \PYG{o}{(}\PYG{n}{pair} \PYG{n}{b} \PYG{n}{u}\PYG{o}{)}\PYG{o}{)} \PYG{o}{..} \PYG{o}{(}\PYG{n}{pair} \PYG{n}{c} \PYG{n}{u}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}
  \PYG{o}{(}\PYG{n}{t} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{39}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

Notations with recursive patterns can be reserved like standard
notations, they can also be declared within
{\hyperref[\detokenize{user-extensions/syntax-extensions:scopes}]{\sphinxcrossref{\DUrole{std,std-ref}{interpretation scopes}}}}.


\subsubsection{Notations with recursive patterns involving binders}
\label{\detokenize{user-extensions/syntax-extensions:notations-with-recursive-patterns-involving-binders}}\label{\detokenize{user-extensions/syntax-extensions:recursivenotationswithbinders}}
Recursive notations can also be used with binders. The basic example
is:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}exists\PYGZsq{} x .. y , p}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=}
  \PYG{o}{(}\PYG{n}{ex} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{o}{..} \PYG{o}{(}\PYG{n}{ex} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{p}\PYG{o}{)}\PYG{o}{)} \PYG{o}{..}\PYG{o}{)}\PYG{o}{)}
  \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{200}\PYG{o}{,} \PYG{n}{x} \PYG{n}{binder}\PYG{o}{,} \PYG{n}{y} \PYG{n}{binder}\PYG{o}{,} \PYG{k}{right} \PYG{n}{associativity}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

The principle is the same as in {\hyperref[\detokenize{user-extensions/syntax-extensions:recursivenotations}]{\sphinxcrossref{\DUrole{std,std-ref}{Notations with recursive patterns}}}}
except that in the iterator
\(φ([~]_E , [~]_I)\), the placeholder \([~]_E\) can also occur in
position of the binding variable of a \sphinxcode{\sphinxupquote{fun}} or a \sphinxcode{\sphinxupquote{forall}}.

To specify that the part “\sphinxcode{\sphinxupquote{x .. y}}” of the notation parses a sequence of
binders, \sphinxcode{\sphinxupquote{x}} and \sphinxcode{\sphinxupquote{y}} must be marked as \sphinxcode{\sphinxupquote{binder}} in the list of modifiers
of the notation. The binders of the parsed sequence are used to fill the
occurrences of the first placeholder of the iterating pattern which is
repeatedly nested as many times as the number of binders generated. If ever the
generalization operator \sphinxcode{\sphinxupquote{'}} (see {\hyperref[\detokenize{language/gallina-extensions:implicit-generalization}]{\sphinxcrossref{\DUrole{std,std-ref}{Implicit generalization}}}}) is
used in the binding list, the added binders are taken into account too.

There are two flavors of binder parsing. If \sphinxcode{\sphinxupquote{x}} and \sphinxcode{\sphinxupquote{y}} are marked as binder,
then a sequence such as \sphinxcode{\sphinxupquote{\DUrole{name}{a} \DUrole{name}{b} \DUrole{name}{c} \DUrole{operator}{:} \DUrole{name}{T}}} will be accepted and interpreted as
the sequence of binders \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{a}\DUrole{operator}{:}\DUrole{name}{T}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{b}\DUrole{operator}{:}\DUrole{name}{T}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{c}\DUrole{operator}{:}\DUrole{name}{T}\DUrole{operator}{)}}}. For instance, in the
notation above, the syntax \sphinxcode{\sphinxupquote{\DUrole{keyword}{exists} \DUrole{name}{a} \DUrole{name}{b} \DUrole{operator}{:} \DUrole{keyword,type}{nat}\DUrole{operator}{,} \DUrole{name}{a} \DUrole{operator}{=} \DUrole{name}{b}}} is valid.

The variables \sphinxcode{\sphinxupquote{x}} and \sphinxcode{\sphinxupquote{y}} can also be marked as closed binder in which
case only well-bracketed binders of the form \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{a} \DUrole{name}{b} \DUrole{name}{c}\DUrole{operator}{:}\DUrole{name}{T}\DUrole{operator}{)}}} or \sphinxcode{\sphinxupquote{\DUrole{operator}{\{}\DUrole{name}{a} \DUrole{name}{b} \DUrole{name}{c}\DUrole{operator}{:}\DUrole{name}{T}\DUrole{operator}{\}}}}
etc. are accepted.

With closed binders, the recursive sequence in the left-hand side can
be of the more general form \sphinxcode{\sphinxupquote{x s .. s y}} where \sphinxcode{\sphinxupquote{s}} is an arbitrary sequence of
tokens. With open binders though, \sphinxcode{\sphinxupquote{s}} has to be empty. Here is an
example of recursive notation with closed binders:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}mylet\PYGZsq{} f x .. y :=  t \PYGZsq{}in\PYGZsq{} u}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{:=}
  \PYG{o}{(}\PYG{k}{let} \PYG{n}{f} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{o}{..} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{t}\PYG{o}{)} \PYG{o}{..} \PYG{k}{in} \PYG{n}{u}\PYG{o}{)}
  \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{200}\PYG{o}{,} \PYG{n}{x} \PYG{n}{closed} \PYG{n}{binder}\PYG{o}{,} \PYG{n}{y} \PYG{n}{closed} \PYG{n}{binder}\PYG{o}{,} \PYG{k}{right} \PYG{n}{associativity}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

A recursive pattern for binders can be used in position of a recursive
pattern for terms. Here is an example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}FUNAPP\PYGZsq{} x .. y , f}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=}
  \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{o}{..} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{o}{(}\PYG{o}{..} \PYG{o}{(}\PYG{n}{f} \PYG{n}{x}\PYG{o}{)} \PYG{o}{..}\PYG{o}{)} \PYG{n}{y} \PYG{o}{)} \PYG{o}{..}\PYG{o}{)}
  \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{200}\PYG{o}{,} \PYG{n}{x} \PYG{n}{binder}\PYG{o}{,} \PYG{n}{y} \PYG{n}{binder}\PYG{o}{,} \PYG{k}{right} \PYG{n}{associativity}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

If an occurrence of the \([~]_E\) is not in position of a binding
variable but of a term, it is the name used in the binding which is
used. Here is an example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}exists\PYGZus{}non\PYGZus{}null\PYGZsq{} x .. y  , P}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=}
  \PYG{o}{(}\PYG{n}{ex} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{/\PYGZbs{}} \PYG{o}{..} \PYG{o}{(}\PYG{n}{ex} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{/\PYGZbs{}} \PYG{n}{P}\PYG{o}{)}\PYG{o}{)} \PYG{o}{..}\PYG{o}{)}\PYG{o}{)}
  \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{200}\PYG{o}{,} \PYG{n}{x} \PYG{n}{binder}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Predefined entries}
\label{\detokenize{user-extensions/syntax-extensions:predefined-entries}}
By default, sub-expressions are parsed as terms and the corresponding
grammar entry is called \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{constr}}}}. However, one may sometimes want
to restrict the syntax of terms in a notation. For instance, the
following notation will accept to parse only global reference in
position of \sphinxcode{\sphinxupquote{\DUrole{name}{x}}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}apply\PYGZsq{} f a1 .. an}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{o}{..} \PYG{o}{(}\PYG{n}{f} \PYG{n}{a1}\PYG{o}{)} \PYG{o}{..} \PYG{n}{an}\PYG{o}{)}
  \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{10}\PYG{o}{,} \PYG{n}{f} \PYG{n}{global}\PYG{o}{,} \PYG{n}{a1}\PYG{o}{,} \PYG{n}{an} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{9}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

In addition to \sphinxcode{\sphinxupquote{global}}, one can restrict the syntax of a
sub-expression by using the entry names \sphinxcode{\sphinxupquote{ident}} or \sphinxcode{\sphinxupquote{pattern}}
already seen in {\hyperref[\detokenize{user-extensions/syntax-extensions:notationswithbinders}]{\sphinxcrossref{\DUrole{std,std-ref}{Binders not bound in the notation}}}}, even when the
corresponding expression is not used as a binder in the right-hand
side. E.g.:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}apply\PYGZus{}id\PYGZsq{} f a1 .. an}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{o}{..} \PYG{o}{(}\PYG{n}{f} \PYG{n}{a1}\PYG{o}{)} \PYG{o}{..} \PYG{n}{an}\PYG{o}{)}
  \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{10}\PYG{o}{,} \PYG{n}{f} \PYG{n}{ident}\PYG{o}{,} \PYG{n}{a1}\PYG{o}{,} \PYG{n}{an} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{9}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Summary}
\label{\detokenize{user-extensions/syntax-extensions:summary}}

\paragraph{Syntax of notations}
\label{\detokenize{user-extensions/syntax-extensions:syntax-of-notations}}\label{\detokenize{user-extensions/syntax-extensions:notationsyntax}}
The different syntactic variants of the command Notation are given on the
following figure. The optional \DUrole{inline-grammar-production}{\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-scope}}\sphinxcode{\sphinxupquote{scope}}} is described in
{\hyperref[\detokenize{user-extensions/syntax-extensions:scopes}]{\sphinxcrossref{\DUrole{std,std-ref}{Interpretation scopes}}}}.


\begin{productionlist}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-notation}}\production{notation}{ {[}Local{]} Notation {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} {[}{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-modifiers}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{modifiers}}}}}{]} {[}: {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope}}}}}{]}.}
\productioncont{ \textbar{} {[}Local{]} Infix {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} {[}{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-modifiers}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{modifiers}}}}}{]} {[}: {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope}}}}}{]}.}
\productioncont{ \textbar{} {[}Local{]} Reserved Notation {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}} {[}{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-modifiers}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{modifiers}}}}}{]} .}
\productioncont{ \textbar{} Inductive {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ind-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ind\_body}}}}} {[}{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl-notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{decl\_notation}}}}}{]} with … with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ind-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ind\_body}}}}} {[}{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl-notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{decl\_notation}}}}}{]}.}
\productioncont{ \textbar{} CoInductive {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ind-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ind\_body}}}}} {[}{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl-notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{decl\_notation}}}}}{]} with … with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ind-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ind\_body}}}}} {[}{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl-notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{decl\_notation}}}}}{]}.}
\productioncont{ \textbar{} Fixpoint {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-fix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fix\_body}}}}} {[}{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl-notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{decl\_notation}}}}}{]} with … with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-fix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fix\_body}}}}} {[}{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl-notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{decl\_notation}}}}}{]}.}
\productioncont{ \textbar{} CoFixpoint {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-cofix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cofix\_body}}}}} {[}{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl-notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{decl\_notation}}}}}{]} with … with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-cofix-body}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{cofix\_body}}}}} {[}{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-decl-notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{decl\_notation}}}}}{]}.}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-decl_notation}}\production{decl\_notation}{ {[}where {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} {[}: {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope}}}}}{]} and … and {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}} := {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} {[}: {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope}}}}}{]}{]}.}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-modifiers}}\production{modifiers}{ at level {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} , … , {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} at level {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}} {[}{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-binderinterp}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binderinterp}}}}}{]}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} , … , {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} at next level {[}{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-binderinterp}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{binderinterp}}}}}{]}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} ident}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} global}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} bigint}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} {[}strict{]} pattern {[}at level {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}}{]}}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} binder}
\productioncont{ \textbar{} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} closed binder}
\productioncont{ \textbar{} left associativity}
\productioncont{ \textbar{} right associativity}
\productioncont{ \textbar{} no associativity}
\productioncont{ \textbar{} only parsing}
\productioncont{ \textbar{} only printing}
\productioncont{ \textbar{} format {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}}}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-binderinterp}}\production{binderinterp}{ as ident}
\productioncont{ \textbar{} as pattern}
\productioncont{ \textbar{} as strict pattern}
\end{productionlist}


\begin{sphinxadmonition}{note}{Note:}
No typing of the denoted expression is performed at definition
time. Type checking is done only at the time of use of the notation.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
Many examples of Notation may be found in the files composing
the initial state of Coq (see directory \sphinxcode{\sphinxupquote{\$COQLIB/theories/Init}}).
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
The notation \sphinxcode{\sphinxupquote{"\{ x \}"}} has a special status in such a way that
complex notations of the form \sphinxcode{\sphinxupquote{"x + \{ y \}"}} or \sphinxcode{\sphinxupquote{"x * \{ y \}"}} can be
nested with correct precedences. Especially, every notation involving
a pattern of the form \sphinxcode{\sphinxupquote{"\{ x \}"}} is parsed as a notation where the
pattern \sphinxcode{\sphinxupquote{"\{ x \}"}} has been simply replaced by \sphinxcode{\sphinxupquote{"x"}} and the curly
brackets are parsed separately. E.g. \sphinxcode{\sphinxupquote{"y + \{ z \}"}} is not parsed as a
term of the given form but as a term of the form \sphinxcode{\sphinxupquote{"y + z"}} where \sphinxcode{\sphinxupquote{z}}
has been parsed using the rule parsing \sphinxcode{\sphinxupquote{"\{ x \}"}}. Especially, level
and precedences for a rule including patterns of the form \sphinxcode{\sphinxupquote{"\{ x \}"}}
are relative not to the textual notation but to the notation where the
curly brackets have been removed (e.g. the level and the associativity
given to some notation, say \sphinxcode{\sphinxupquote{"\{ y \} \& \{ z \}"}} in fact applies to the
underlying \sphinxcode{\sphinxupquote{"\{ x \}"}}-free rule which is \sphinxcode{\sphinxupquote{"y \& z"}}).
\end{sphinxadmonition}


\paragraph{Persistence of notations}
\label{\detokenize{user-extensions/syntax-extensions:persistence-of-notations}}
Notations disappear when a section is closed.
\index{Local Notation (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.local-notation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Notation~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-notation}]{\sphinxcrossref{\DUrole{hole}{notation}}}}}}}}
Notations survive modules unless the command \sphinxcode{\sphinxupquote{Local Notation}} is used instead
of {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Notation}}}}}.

\end{fulllineitems}



\subsection{Interpretation scopes}
\label{\detokenize{user-extensions/syntax-extensions:interpretation-scopes}}\label{\detokenize{user-extensions/syntax-extensions:scopes}}
An \sphinxstyleemphasis{interpretation scope} is a set of notations for terms with their
interpretations. Interpretation scopes provide a weak, purely
syntactical form of notation overloading: the same notation, for
instance the infix symbol \sphinxcode{\sphinxupquote{+}}, can be used to denote distinct
definitions of the additive operator. Depending on which interpretation
scopes are currently open, the interpretation is different.
Interpretation scopes can include an interpretation for numerals and
strings. However, this is only made possible at the Objective Caml
level.

See {\hyperref[\detokenize{user-extensions/syntax-extensions:notationsyntax}]{\sphinxcrossref{\DUrole{std,std-ref}{above}}}} for the syntax of notations including the
possibility to declare them in a given scope. Here is a typical example which
declares the notation for conjunction in the scope \sphinxcode{\sphinxupquote{type\_scope}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{A /\PYGZbs{} B}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{and} \PYG{n}{A} \PYG{n}{B}\PYG{o}{)} \PYG{o}{:} \PYG{n}{type\PYGZus{}scope}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{note}{Note:}
A notation not defined in a scope is called a \sphinxstyleemphasis{lonely}
notation.
\end{sphinxadmonition}


\subsubsection{Global interpretation rules for notations}
\label{\detokenize{user-extensions/syntax-extensions:global-interpretation-rules-for-notations}}
At any time, the interpretation of a notation for a term is done within
a \sphinxstyleemphasis{stack} of interpretation scopes and lonely notations. In case a
notation has several interpretations, the actual interpretation is the
one defined by (or in) the more recently declared (or opened) lonely
notation (or interpretation scope) which defines this notation.
Typically if a given notation is defined in some scope \sphinxcode{\sphinxupquote{scope}} but has
also an interpretation not assigned to a scope, then, if \sphinxcode{\sphinxupquote{scope}} is open
before the lonely interpretation is declared, then the lonely
interpretation is used (and this is the case even if the
interpretation of the notation in scope is given after the lonely
interpretation: otherwise said, only the order of lonely
interpretations and opening of scopes matters, and not the declaration
of interpretations within a scope).

The initial state of Coq declares three interpretation scopes and no
lonely notations. These scopes, in opening order, are \sphinxcode{\sphinxupquote{core\_scope}},
\sphinxcode{\sphinxupquote{type\_scope}} and \sphinxcode{\sphinxupquote{nat\_scope}}.
\index{Open Scope (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.open-scope}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Open~Scope~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}}}}
The command to add a scope to the interpretation scope stack is
\sphinxcode{\sphinxupquote{\DUrole{notation}{Open Scope {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}}}.

\end{fulllineitems}

\index{Close Scope (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.close-scope}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Close~Scope~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}}}}
It is also possible to remove a scope from the interpretation scope
stack by using the command \sphinxcode{\sphinxupquote{\DUrole{notation}{Close Scope {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}}}.

Notice that this command does not only cancel the last \sphinxcode{\sphinxupquote{\DUrole{notation}{Open Scope {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}}}
but all its invocations.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}
\sphinxcode{\sphinxupquote{Open Scope}} and \sphinxcode{\sphinxupquote{Close Scope}} do not survive the end of sections
where they occur. When defined outside of a section, they are exported
to the modules that import the module where they occur.
\end{sphinxadmonition}
\index{Local Open Scope (cmd)}\index{Local Close Scope (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.local-open-scope}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Open~Scope~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}.}}}}\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.local-close-scope}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Close~Scope~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}.}}}}
These variants are not exported to the modules that import the module where
they occur, even if outside a section.

\end{fulllineitems}

\index{Global Open Scope (cmd)}\index{Global Close Scope (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.global-open-scope}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Global~Open~Scope~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}.}}}}\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.global-close-scope}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Global~Close~Scope~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}.}}}}
These variants survive sections. They behave as if Global were absent when
not inside a section.

\end{fulllineitems}



\subsubsection{Local interpretation rules for notations}
\label{\detokenize{user-extensions/syntax-extensions:local-interpretation-rules-for-notations}}\label{\detokenize{user-extensions/syntax-extensions:localinterpretationrulesfornotations}}
In addition to the global rules of interpretation of notations, some
ways to change the interpretation of subterms are available.


\paragraph{Local opening of an interpretation scope}
\label{\detokenize{user-extensions/syntax-extensions:local-opening-of-an-interpretation-scope}}
It is possible to locally extend the interpretation scope stack using the syntax
\sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{term}\DUrole{operator}{)\%}\DUrole{name}{key}}} (or simply \sphinxcode{\sphinxupquote{\DUrole{name}{term}\DUrole{operator}{\%}\DUrole{name}{key}}} for atomic terms), where key is a
special identifier called \sphinxstyleemphasis{delimiting key} and bound to a given scope.

In such a situation, the term term, and all its subterms, are
interpreted in the scope stack extended with the scope bound tokey.
\index{Delimit Scope (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.delimit-scope}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Delimit~Scope~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
To bind a delimiting key to a scope, use the command
\sphinxcode{\sphinxupquote{\DUrole{notation}{Delimit Scope {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}} with {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}

\end{fulllineitems}

\index{Undelimit Scope (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.undelimit-scope}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Undelimit~Scope~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}}}}
To remove a delimiting key of a scope, use the command
\sphinxcode{\sphinxupquote{\DUrole{notation}{Undelimit Scope {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}}}

\end{fulllineitems}



\paragraph{Binding arguments of a constant to an interpretation scope}
\label{\detokenize{user-extensions/syntax-extensions:binding-arguments-of-a-constant-to-an-interpretation-scope}}\index{Arguments (scopes) (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.arguments-scopes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Arguments~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}\DUrole{notation-sup}{+}}}}}}
It is possible to set in advance that some arguments of a given constant have
to be interpreted in a given scope. The command is
\sphinxcode{\sphinxupquote{\DUrole{notation}{Arguments {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}\DUrole{notation-sup}{+}}}}} where the list is a prefix of the
arguments of \sphinxcode{\sphinxupquote{qualid}} eventually annotated with their \sphinxcode{\sphinxupquote{scope}}. Grouping
round parentheses can be used to decorate multiple arguments with the same
scope. \sphinxcode{\sphinxupquote{scope}} can be either a scope name or its delimiting key. For
example the following command puts the first two arguments of \sphinxcode{\sphinxupquote{\DUrole{name}{plus\_fct}}}
in the scope delimited by the key \sphinxcode{\sphinxupquote{F}} (\sphinxcode{\sphinxupquote{Rfun\_scope}}) and the last
argument in the scope delimited by the key \sphinxcode{\sphinxupquote{R}} (\sphinxcode{\sphinxupquote{R\_scope}}).

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Arguments} \PYG{n}{plus\PYGZus{}fct} \PYG{o}{(}\PYG{n}{f1} \PYG{n}{f2}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{F} \PYG{n}{x}\PYG{o}{\PYGZpc{}}\PYG{n}{R}\PYG{o}{.}
\end{sphinxVerbatim}

The \sphinxcode{\sphinxupquote{Arguments}} command accepts scopes decoration to all grouping
parentheses. In the following example arguments A and B are marked as
maximally inserted implicit arguments and are put into the type\_scope scope.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Arguments} \PYG{n}{respectful} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{n}{B}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZpc{}}\PYG{n}{type} \PYG{o}{(}\PYG{n}{R} \PYG{n}{R\PYGZsq{}}\PYG{o}{)}\PYG{o}{\PYGZpc{}}\PYG{n}{signature} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{.}
\end{sphinxVerbatim}

When interpreting a term, if some of the arguments of qualid are built
from a notation, then this notation is interpreted in the scope stack
extended by the scope bound (if any) to this argument. The effect of
the scope is limited to the argument itself. It does not propagate to
subterms but the subterms that, after interpretation of the notation,
turn to be themselves arguments of a reference are interpreted
accordingly to the argument scopes bound to this reference.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Arguments~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~:~clear~scopes}}}}
This command can be used to clear argument scopes of {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Arguments~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}\%scope}\DUrole{notation-sup}{+}}~:~extra~scopes}}}}
Defines extra argument scopes, to be used in case of coercion to \sphinxcode{\sphinxupquote{Funclass}}
(see the {\hyperref[\detokenize{addendum/implicit-coercions:implicitcoercions}]{\sphinxcrossref{\DUrole{std,std-ref}{Implicit Coercions}}}} chapter) or with a computed type.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Global~Arguments~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}\DUrole{notation-sup}{+}}}}}}
This behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{Arguments qualid \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}\DUrole{notation-sup}{+}}}}} but survives when a
section is closed instead of stopping working at section closing. Without the
\sphinxcode{\sphinxupquote{Global}} modifier, the effect of the command stops when the section it belongs
to ends.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Arguments~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}\DUrole{notation-sup}{+}}}}}}
This behaves like \sphinxcode{\sphinxupquote{\DUrole{notation}{Arguments {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}} \DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-name}]{\sphinxcrossref{\DUrole{hole}{name}}}}\%{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}\DUrole{notation-sup}{+}}}}} but does not
survive modules and files. Without the \sphinxcode{\sphinxupquote{Local}} modifier, the effect of the
command is visible from within other modules or files.

\end{fulllineitems}


\end{fulllineitems}



\sphinxstrong{See also:}


The command {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.about}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{About}}}}} can be used to show the scopes bound to the
arguments of a function.



\begin{sphinxadmonition}{note}{Note:}
In notations, the subterms matching the identifiers of the
notations are interpreted in the scope in which the identifiers
occurred at the time of the declaration of the notation. Here is an
example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{g} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}\PYG{o}{.}
    \PYG{n}{g} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{@@}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n+nb+bp}{true} \PYG{o}{(}\PYG{n}{only} \PYG{n}{parsing}\PYG{o}{)} \PYG{o}{:} \PYG{n}{bool\PYGZus{}scope}\PYG{o}{.}
    \PYG{n}{Setting} \PYG{n}{notation} \PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{0}\PYG{o}{.}

\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{@@}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n+nb+bp}{false} \PYG{o}{(}\PYG{n}{only} \PYG{n}{parsing}\PYG{o}{)}\PYG{o}{:} \PYG{n}{mybool\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Bind} \PYG{k+kn}{Scope} \PYG{n}{bool\PYGZus{}scope} \PYG{k}{with} \PYG{k+kt}{bool}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsh{} x \PYGZsh{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{g} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{40}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{\PYGZsh{}} \PYG{o}{@@} \PYG{o}{\PYGZsh{}}\PYG{o}{.}
    \PYG{o}{\PYGZsh{}} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZsh{}}
         \PYG{o}{:} \PYG{k+kt}{bool}

\PYG{k+kn}{Arguments} \PYG{n}{g} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZpc{}}\PYG{n}{mybool\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{\PYGZsh{}} \PYG{o}{@@} \PYG{o}{\PYGZsh{}}\PYG{o}{.}
    \PYG{o}{\PYGZsh{}} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZsh{}}
         \PYG{o}{:} \PYG{k+kt}{bool}

\PYG{k+kn}{Delimit} \PYG{k+kn}{Scope} \PYG{n}{mybool\PYGZus{}scope} \PYG{k}{with} \PYG{n}{mybool}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{\PYGZsh{}} \PYG{o}{@@}\PYG{o}{\PYGZpc{}}\PYG{n}{mybool} \PYG{o}{\PYGZsh{}}\PYG{o}{.}
    \PYG{o}{\PYGZsh{}} \PYG{n+nb+bp}{false} \PYG{o}{\PYGZsh{}}
         \PYG{o}{:} \PYG{k+kt}{bool}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Binding types of arguments to an interpretation scope}
\label{\detokenize{user-extensions/syntax-extensions:binding-types-of-arguments-to-an-interpretation-scope}}\index{Bind Scope (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.bind-scope}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Bind~Scope~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
When an interpretation scope is naturally associated to a type (e.g.  the
scope of operations on the natural numbers), it may be convenient to bind it
to this type. When a scope \sphinxcode{\sphinxupquote{scope}} is bound to a type \sphinxcode{\sphinxupquote{type}}, any new function
defined later on gets its arguments of type \sphinxcode{\sphinxupquote{type}} interpreted by default in
scope scope (this default behavior can however be overwritten by explicitly
using the command {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.arguments}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Arguments}}}}}).

Whether the argument of a function has some type \sphinxcode{\sphinxupquote{type}} is determined
statically. For instance, if \sphinxcode{\sphinxupquote{f}} is a polymorphic function of type
\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{X}\DUrole{operator}{:}\DUrole{keyword,type}{Type}\DUrole{operator}{,} \DUrole{name}{X} \DUrole{operator}{-\textgreater{}} \DUrole{name}{X}}} and type \sphinxcode{\sphinxupquote{\DUrole{name}{t}}} is bound to a scope \sphinxcode{\sphinxupquote{scope}},
then \sphinxcode{\sphinxupquote{\DUrole{name}{a}}} of type \sphinxcode{\sphinxupquote{\DUrole{name}{t}}} in \sphinxcode{\sphinxupquote{\DUrole{name}{f} \DUrole{name}{t} \DUrole{name}{a}}} is not recognized as an argument to
be interpreted in scope \sphinxcode{\sphinxupquote{scope}}.

More generally, any coercion \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}}}} (see the {\hyperref[\detokenize{addendum/implicit-coercions:implicitcoercions}]{\sphinxcrossref{\DUrole{std,std-ref}{Implicit Coercions}}}} chapter)
can be bound to an interpretation scope. The command to do it is
\sphinxcode{\sphinxupquote{\DUrole{notation}{Bind Scope {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}} with {\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}}}}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{U} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{.}
\PYG{k+kn}{Bind} \PYG{k+kn}{Scope} \PYG{n}{U\PYGZus{}scope} \PYG{k}{with} \PYG{n}{U}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{n}{Uplus} \PYG{o}{:} \PYG{n}{U} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{U} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{U}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{n}{P} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{T}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{,} \PYG{n}{T} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{U} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{n}{f} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{T}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{,} \PYG{n}{T} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{U}\PYG{o}{.}
\PYG{n}{Infix} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{+}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{n}{Uplus} \PYG{o}{:} \PYG{n}{U\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Notations}\PYG{o}{.}
\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{nat\PYGZus{}scope}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{n}{y1} \PYG{n}{y2} \PYG{n}{z} \PYG{n}{t} \PYG{o}{=\PYGZgt{}} \PYG{n}{P} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{t}\PYG{o}{)} \PYG{o}{(}\PYG{o}{(}\PYG{n}{f} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{n}{y1} \PYG{o}{+} \PYG{n}{y2}\PYG{o}{)} \PYG{o}{+} \PYG{n}{z}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y1} \PYG{n}{y2} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{z} \PYG{o}{:} \PYG{n}{U}\PYG{o}{)} \PYG{o}{(}\PYG{n}{t} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{=\PYGZgt{}}
    \PYG{n}{P} \PYG{k+kt}{nat} \PYG{o}{(}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add} \PYG{n}{x} \PYG{n}{t}\PYG{o}{)} \PYG{o}{(}\PYG{n}{Uplus} \PYG{o}{(}\PYG{n}{f} \PYG{k+kt}{nat} \PYG{o}{(}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{add} \PYG{n}{y1} \PYG{n}{y2}\PYG{o}{)}\PYG{o}{)} \PYG{n}{z}\PYG{o}{)}
         \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{U}\PYG{o}{)} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)}\PYG{o}{,} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{note}{Note:}
The scopes \sphinxcode{\sphinxupquote{type\_scope}} and \sphinxcode{\sphinxupquote{function\_scope}} also have a local
effect on interpretation. See the next section.
\end{sphinxadmonition}

\end{fulllineitems}



\subsubsection{The \sphinxstyleliteralintitle{\sphinxupquote{type\_scope}} interpretation scope}
\label{\detokenize{user-extensions/syntax-extensions:the-type-scope-interpretation-scope}}
\index{type\_scope}\ignorespaces 
The scope \sphinxcode{\sphinxupquote{type\_scope}} has a special status. It is a primitive interpretation
scope which is temporarily activated each time a subterm of an expression is
expected to be a type. It is delimited by the key \sphinxcode{\sphinxupquote{type}}, and bound to the
coercion class \sphinxcode{\sphinxupquote{Sortclass}}. It is also used in certain situations where an
expression is statically known to be a type, including the conclusion and the
type of hypotheses within an Ltac goal match (see
{\hyperref[\detokenize{proof-engine/ltac:ltac-match-goal}]{\sphinxcrossref{\DUrole{std,std-ref}{Pattern matching on goals}}}}), the statement of a theorem, the type of a definition,
the type of a binder, the domain and codomain of implication, the codomain of
products, and more generally any type argument of a declared or defined
constant.


\subsubsection{The \sphinxstyleliteralintitle{\sphinxupquote{function\_scope}} interpretation scope}
\label{\detokenize{user-extensions/syntax-extensions:the-function-scope-interpretation-scope}}
\index{function\_scope}\ignorespaces 
The scope \sphinxcode{\sphinxupquote{function\_scope}} also has a special status.
It is temporarily activated each time the argument of a global reference is
recognized to be a \sphinxcode{\sphinxupquote{Funclass}} istance, i.e., of type \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A}\DUrole{operator}{,} \DUrole{name}{B}}} or
\sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{-\textgreater{}} \DUrole{name}{B}}}.


\subsubsection{Interpretation scopes used in the standard library of Coq}
\label{\detokenize{user-extensions/syntax-extensions:interpretation-scopes-used-in-the-standard-library-of-coq}}
We give an overview of the scopes used in the standard library of Coq.
For a complete list of notations in each scope, use the commands {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.print-scopes}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print
Scopes}}}}} or {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmdv.print-scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Scope}}}}}.
\begin{description}
\item[{\sphinxcode{\sphinxupquote{type\_scope}}}] \leavevmode
This scope includes infix * for product types and infix + for sum types. It
is delimited by the key \sphinxcode{\sphinxupquote{type}}, and bound to the coercion class
\sphinxcode{\sphinxupquote{Sortclass}}, as described above.

\item[{\sphinxcode{\sphinxupquote{function\_scope}}}] \leavevmode
This scope is delimited by the key \sphinxcode{\sphinxupquote{function}}, and bound to the coercion class
\sphinxcode{\sphinxupquote{Funclass}}, as described above.

\item[{\sphinxcode{\sphinxupquote{nat\_scope}}}] \leavevmode
This scope includes the standard arithmetical operators and relations on type
nat. Positive numerals in this scope are mapped to their canonical
representent built from \sphinxcode{\sphinxupquote{\DUrole{name}{O}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{S}}}. The scope is delimited by the key
\sphinxcode{\sphinxupquote{nat}}, and bound to the type \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{nat}}} (see above).

\item[{\sphinxcode{\sphinxupquote{N\_scope}}}] \leavevmode
This scope includes the standard arithmetical operators and relations on
type \sphinxcode{\sphinxupquote{\DUrole{name}{N}}} (binary natural numbers). It is delimited by the key \sphinxcode{\sphinxupquote{N}} and comes
with an interpretation for numerals as closed terms of type \sphinxcode{\sphinxupquote{\DUrole{name}{N}}}.

\item[{\sphinxcode{\sphinxupquote{Z\_scope}}}] \leavevmode
This scope includes the standard arithmetical operators and relations on
type \sphinxcode{\sphinxupquote{\DUrole{name}{Z}}} (binary integer numbers). It is delimited by the key \sphinxcode{\sphinxupquote{Z}} and comes
with an interpretation for numerals as closed terms of type \sphinxcode{\sphinxupquote{\DUrole{name}{Z}}}.

\item[{\sphinxcode{\sphinxupquote{positive\_scope}}}] \leavevmode
This scope includes the standard arithmetical operators and relations on
type \sphinxcode{\sphinxupquote{\DUrole{name}{positive}}} (binary strictly positive numbers). It is delimited by
key \sphinxcode{\sphinxupquote{positive}} and comes with an interpretation for numerals as closed
terms of type \sphinxcode{\sphinxupquote{\DUrole{name}{positive}}}.

\item[{\sphinxcode{\sphinxupquote{Q\_scope}}}] \leavevmode
This scope includes the standard arithmetical operators and relations on
type \sphinxcode{\sphinxupquote{\DUrole{name}{Q}}} (rational numbers defined as fractions of an integer and a
strictly positive integer modulo the equality of the numerator-
denominator cross-product). As for numerals, only 0 and 1 have an
interpretation in scope \sphinxcode{\sphinxupquote{Q\_scope}} (their interpretations are 0/1 and 1/1
respectively).

\item[{\sphinxcode{\sphinxupquote{Qc\_scope}}}] \leavevmode
This scope includes the standard arithmetical operators and relations on the
type \sphinxcode{\sphinxupquote{\DUrole{name}{Qc}}} of rational numbers defined as the type of irreducible
fractions of an integer and a strictly positive integer.

\item[{\sphinxcode{\sphinxupquote{real\_scope}}}] \leavevmode
This scope includes the standard arithmetical operators and relations on
type \sphinxcode{\sphinxupquote{\DUrole{name}{R}}} (axiomatic real numbers). It is delimited by the key \sphinxcode{\sphinxupquote{R}} and comes
with an interpretation for numerals using the \sphinxcode{\sphinxupquote{\DUrole{name}{IZR}}} morphism from binary
integer numbers to \sphinxcode{\sphinxupquote{\DUrole{name}{R}}}.

\item[{\sphinxcode{\sphinxupquote{bool\_scope}}}] \leavevmode
This scope includes notations for the boolean operators. It is delimited by the
key \sphinxcode{\sphinxupquote{bool}}, and bound to the type \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{bool}}} (see above).

\item[{\sphinxcode{\sphinxupquote{list\_scope}}}] \leavevmode
This scope includes notations for the list operators. It is delimited by the key
\sphinxcode{\sphinxupquote{list}}, and bound to the type \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{list}}} (see above).

\item[{\sphinxcode{\sphinxupquote{core\_scope}}}] \leavevmode
This scope includes the notation for pairs. It is delimited by the key \sphinxcode{\sphinxupquote{core}}.

\item[{\sphinxcode{\sphinxupquote{string\_scope}}}] \leavevmode
This scope includes notation for strings as elements of the type string.
Special characters and escaping follow Coq conventions on strings (see
{\hyperref[\detokenize{language/gallina-specification-language:lexical-conventions}]{\sphinxcrossref{\DUrole{std,std-ref}{Lexical conventions}}}}). Especially, there is no convention to visualize non
printable characters of a string. The file \sphinxcode{\sphinxupquote{String.v}} shows an example
that contains quotes, a newline and a beep (i.e. the ASCII character
of code 7).

\item[{\sphinxcode{\sphinxupquote{char\_scope}}}] \leavevmode
This scope includes interpretation for all strings of the form \sphinxcode{\sphinxupquote{"c"}}
where \sphinxcode{\sphinxupquote{\DUrole{name}{c}}} is an ASCII character, or of the form \sphinxcode{\sphinxupquote{"nnn"}} where nnn is
a three-digits number (possibly with leading 0's), or of the form
\sphinxcode{\sphinxupquote{""""}}. Their respective denotations are the ASCII code of \sphinxcode{\sphinxupquote{\DUrole{name}{c}}}, the
decimal ASCII code \sphinxcode{\sphinxupquote{nnn}}, or the ascii code of the character \sphinxcode{\sphinxupquote{"}} (i.e.
the ASCII code 34), all of them being represented in the type \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{ascii}}}.

\end{description}


\subsubsection{Displaying information about scopes}
\label{\detokenize{user-extensions/syntax-extensions:displaying-information-about-scopes}}\index{Print Visibility (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.print-visibility}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Visibility}}}}
This displays the current stack of notations in scopes and lonely
notations that is used to interpret a notation. The top of the stack
is displayed last. Notations in scopes whose interpretation is hidden
by the same notation in a more recently opened scope are not displayed.
Hence each notation is displayed only once.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Visibility~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}}}}
This displays the current stack of notations in scopes and lonely
notations assuming that {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope}}}}} is pushed on top of the stack. This is
useful to know how a subterm locally occurring in the scope {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope}}}}} is
interpreted.

\end{fulllineitems}


\end{fulllineitems}

\index{Print Scopes (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.print-scopes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Scopes}}}}
This displays all the notations, delimiting keys and corresponding
classes of all the existing interpretation scopes. It also displays the
lonely notations.
\index{Print Scope (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmdv.print-scope}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Scope~{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\DUrole{hole}{scope}}}}}}}}
This displays all the notations defined in the interpretation scope {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-scope}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{scope}}}}}.
It also displays the delimiting key if any and the class to which the
scope is bound, if any.

\end{fulllineitems}


\end{fulllineitems}



\subsection{Abbreviations}
\label{\detokenize{user-extensions/syntax-extensions:abbreviations}}\label{\detokenize{user-extensions/syntax-extensions:id5}}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Local}\DUrole{notation-sup}{?}}~Notation~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{(only~parsing)}\DUrole{notation-sup}{?}}.}}}}
An \sphinxstyleemphasis{abbreviation} is a name, possibly applied to arguments, that
denotes a (presumably) more complex expression. Here are examples:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{n}{Nlist} \PYG{o}{:=} \PYG{o}{(}\PYG{k+kt}{list} \PYG{k+kt}{nat}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{l+m+mi}{1} \PYG{o}{::} \PYG{l+m+mi}{2} \PYG{o}{::} \PYG{l+m+mi}{3} \PYG{o}{::} \PYG{n}{nil}\PYG{o}{.}
    \PYG{o}{[}\PYG{l+m+mi}{1}\PYG{o}{;} \PYG{l+m+mi}{2}\PYG{o}{;} \PYG{l+m+mi}{3}\PYG{o}{]}
         \PYG{o}{:} \PYG{n}{Nlist}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{n}{reflexive} \PYG{n}{R} \PYG{o}{:=} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{n}{R} \PYG{n}{x} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{k}{forall} \PYG{n}{A}\PYG{o}{:}\PYG{k+kt}{Prop}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{A}\PYG{o}{.}
    \PYG{n}{reflexive} \PYG{n}{iff}
         \PYG{o}{:} \PYG{k+kt}{Prop}

\PYG{k+kn}{Check} \PYG{n}{reflexive} \PYG{n}{iff}\PYG{o}{.}
    \PYG{n}{reflexive} \PYG{n}{iff}
         \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}

An abbreviation expects no precedence nor associativity, since it
is parsed as an usual application. Abbreviations are used as
much as possible by the Coq printers unless the modifier \sphinxcode{\sphinxupquote{(only
parsing)}} is given.

An abbreviation is bound to an absolute name as an ordinary definition is
and it also can be referred to by a qualified name.

Abbreviations are syntactic in the sense that they are bound to
expressions which are not typed at the time of the definition of the
abbreviation but at the time they are used. Especially, abbreviations
can be bound to terms with holes (i.e. with “\sphinxcode{\sphinxupquote{\_}}”). For example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{explicit\PYGZus{}id} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{a}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{a}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{n}{id} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{explicit\PYGZus{}id} \PYG{o}{\PYGZus{}}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{id} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{id} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{k+kt}{nat}
\end{sphinxVerbatim}

Abbreviations disappear when a section is closed. No typing of the
denoted expression is performed at definition time. Type checking is
done only at the time of use of the abbreviation.

\end{fulllineitems}



\subsection{Tactic Notations}
\label{\detokenize{user-extensions/syntax-extensions:tactic-notations}}\label{\detokenize{user-extensions/syntax-extensions:tacticnotation}}
Tactic notations allow to customize the syntax of tactics. They have the following syntax:


\begin{productionlist}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-tacn}}\production{tacn}{ Tactic Notation {[}{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-tactic-level}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tactic\_level}}}}}{]} {[}{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-prod-item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{prod\_item}}}}} … {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-prod-item}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{prod\_item}}}}}{]} := \sphinxcode{\sphinxupquote{tactic}}.}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-prod_item}}\production{prod\_item}{ {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{string}}}}} \textbar{} {\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-tactic-argument-type}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{tactic\_argument\_type}}}}}({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}})}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-tactic_level}}\production{tactic\_level}{ (at level {\hyperref[\detokenize{proof-engine/ssreflect-proof-language:grammar-token-natural}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{natural}}}}})}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:grammar-token-tactic_argument_type}}\production{tactic\_argument\_type}{ ident \textbar{} simple\_intropattern \textbar{} reference}
\productioncont{ \textbar{} hyp \textbar{} hyp\_list \textbar{} ne\_hyp\_list}
\productioncont{ \textbar{} constr \textbar{} uconstr \textbar{} constr\_list \textbar{} ne\_constr\_list}
\productioncont{ \textbar{} integer \textbar{} integer\_list \textbar{} ne\_integer\_list}
\productioncont{ \textbar{} int\_or\_var \textbar{} int\_or\_var\_list \textbar{} ne\_int\_or\_var\_list}
\productioncont{ \textbar{} tactic \textbar{} tactic0 \textbar{} tactic1 \textbar{} tactic2 \textbar{} tactic3}
\productioncont{ \textbar{} tactic4 \textbar{} tactic5}
\end{productionlist}

\index{Tactic Notation (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.tactic-notation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Tactic~Notation~\DUrole{repeat-wrapper}{\DUrole{repeat}{(at~level~\DUrole{hole}{level})}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{user-extensions/syntax-extensions:grammar-token-prod-item}]{\sphinxcrossref{\DUrole{hole}{prod\_item}}}}}\DUrole{notation-sup}{+}}~:=~\DUrole{hole}{tactic}.}}}}
A tactic notation extends the parser and pretty-printer of tactics with a new
rule made of the list of production items. It then evaluates into the
tactic expression \sphinxcode{\sphinxupquote{tactic}}. For simple tactics, it is recommended to use
a terminal symbol, i.e. a string, for the first production item. The
tactic level indicates the parsing precedence of the tactic notation.
This information is particularly relevant for notations of tacticals.
Levels 0 to 5 are available (default is 5).
\index{Print Grammar tactic (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/syntax-extensions:coq:cmd.print-grammar-tactic}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Grammar~tactic}}}}
To know the parsing precedences of the existing tacticals, use the command
\sphinxcode{\sphinxupquote{Print Grammar tactic}}.

\end{fulllineitems}


Each type of tactic argument has a specific semantic regarding how it
is parsed and how it is interpreted. The semantic is described in the
following table. The last command gives examples of tactics which use
the corresponding kind of argument.


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|T|}
\hline
\sphinxstyletheadfamily 
Tactic argument type
&\sphinxstyletheadfamily 
parsed as
&\sphinxstyletheadfamily 
interpreted as
&\sphinxstyletheadfamily 
as in tactic
\\
\hline
\sphinxcode{\sphinxupquote{ident}}
&
identifier
&
a user-given name
&
intro
\\
\hline
\sphinxcode{\sphinxupquote{simple\_intropattern}}
&
intro\_pattern
&
an intro pattern
&
intros
\\
\hline
\sphinxcode{\sphinxupquote{hyp}}
&
identifier
&
a hypothesis defined in context
&
clear
\\
\hline
\sphinxcode{\sphinxupquote{reference}}
&
qualified identifier
&
a global reference of term
&
unfold
\\
\hline
\sphinxcode{\sphinxupquote{constr}}
&
term
&
a term
&
exact
\\
\hline
\sphinxcode{\sphinxupquote{uconstr}}
&
term
&
an untyped term
&
refine
\\
\hline
\sphinxcode{\sphinxupquote{integer}}
&
integer
&
an integer
&\\
\hline
\sphinxcode{\sphinxupquote{int\_or\_var}}
&
identifier or integer
&
an integer
&
do
\\
\hline
\sphinxcode{\sphinxupquote{tactic}}
&
tactic at level 5
&
a tactic
&\\
\hline
\sphinxcode{\sphinxupquote{tacticn}}
&
tactic at level n
&
a tactic
&\\
\hline
\sphinxstyleemphasis{entry}\sphinxcode{\sphinxupquote{\_list}}
&
list of \sphinxstyleemphasis{entry}
&
a list of how \sphinxstyleemphasis{entry} is interpreted
&\\
\hline
\sphinxcode{\sphinxupquote{ne\_}}\sphinxstyleemphasis{entry}\sphinxcode{\sphinxupquote{\_list}}
&
non-empty list of \sphinxstyleemphasis{entry}
&
a list of how \sphinxstyleemphasis{entry} is interpreted
&\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

\begin{sphinxadmonition}{note}{Note:}
In order to be bound in tactic definitions, each syntactic
entry for argument type must include the case of a simple \sphinxtitleref{L}$_{\text{tac}}$
identifier as part of what it parses. This is naturally the case for
\sphinxcode{\sphinxupquote{ident}}, \sphinxcode{\sphinxupquote{simple\_intropattern}}, \sphinxcode{\sphinxupquote{reference}}, \sphinxcode{\sphinxupquote{constr}}, ... but not for \sphinxcode{\sphinxupquote{integer}}.
This is the reason for introducing a special entry \sphinxcode{\sphinxupquote{int\_or\_var}} which
evaluates to integers only but which syntactically includes
identifiers in order to be usable in tactic definitions.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
The \sphinxstyleemphasis{entry}\sphinxcode{\sphinxupquote{\_list}} and \sphinxcode{\sphinxupquote{ne\_}}\sphinxstyleemphasis{entry}\sphinxcode{\sphinxupquote{\_list}} entries can be used in
primitive tactics or in other notations at places where a list of the
underlying entry can be used: entry is either \sphinxcode{\sphinxupquote{constr}}, \sphinxcode{\sphinxupquote{hyp}}, \sphinxcode{\sphinxupquote{integer}}
or \sphinxcode{\sphinxupquote{int\_or\_var}}.
\end{sphinxadmonition}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Tactic~Notation}}}}
Tactic notations disappear when a section is closed. They survive when
a module is closed unless the command \sphinxcode{\sphinxupquote{Local Tactic Notation}} is used instead
of {\hyperref[\detokenize{user-extensions/syntax-extensions:coq:cmd.tactic-notation}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Tactic Notation}}}}}.

\end{fulllineitems}



\section{Proof schemes}
\label{\detokenize{user-extensions/proof-schemes:proof-schemes}}\label{\detokenize{user-extensions/proof-schemes:proofschemes}}\label{\detokenize{user-extensions/proof-schemes::doc}}

\subsection{Generation of induction principles with \sphinxstyleliteralintitle{\sphinxupquote{Scheme}}}
\label{\detokenize{user-extensions/proof-schemes:generation-of-induction-principles-with-scheme}}\label{\detokenize{user-extensions/proof-schemes:proofschemes-induction-principles}}
The \sphinxcode{\sphinxupquote{Scheme}} command is a high-level tool for generating automatically
(possibly mutual) induction principles for given types and sorts. Its
syntax follows the schema:
\index{Scheme (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/proof-schemes:coq:cmd.scheme}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Scheme~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~Induction~for~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~Sort~sort~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~Induction~for~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~Sort~sort}\DUrole{notation-sup}{*}}}}}}
\end{fulllineitems}


where each \sphinxtitleref{ident'ᵢ} is a different inductive type identifier
belonging to the same package of mutual inductive definitions. This
command generates the \sphinxtitleref{identᵢ{}`s to be mutually recursive
definitions. Each term {}`identᵢ} proves a general principle of mutual
induction for objects in type \sphinxtitleref{identᵢ}.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Scheme~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~Minimality~for~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~Sort~sort~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~Minimality~for~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}'~Sort~sort}\DUrole{notation-sup}{*}}}}}}
Same as before but defines a non-dependent elimination principle more
natural in case of inductively defined relations.

\end{fulllineitems}

\index{Scheme Equality (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/proof-schemes:coq:cmdv.scheme-equality}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Scheme~Equality~for~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Tries to generate a Boolean equality and a proof of the decidability of the usual equality. If \sphinxtitleref{ident}
involves some other inductive types, their equality has to be defined first.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Scheme~Induction~for~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~Sort~sort~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~Induction~for~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~Sort~sort}\DUrole{notation-sup}{*}}}}}}
If you do not provide the name of the schemes, they will be automatically computed from the
sorts involved (works also with Minimality).

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}
\begin{quote}

Induction scheme for tree and forest.

A mutual induction principle for tree and forest in sort \sphinxcode{\sphinxupquote{Set}} can be defined using the command
\begin{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{tree} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=} \PYG{n}{node} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{tree}
\PYG{k}{with} \PYG{n}{forest} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
    \PYG{n}{leaf} \PYG{o}{:} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest}
  \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{tree} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest}\PYG{o}{.}
    \PYG{n}{tree}\PYG{o}{,} \PYG{n}{forest} \PYG{n}{are} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{forest\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{forest\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{forest\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}

\PYG{n}{Scheme} \PYG{n}{tree\PYGZus{}forest\PYGZus{}rec} \PYG{o}{:=} \PYG{n}{Induction} \PYG{k}{for} \PYG{n}{tree} \PYG{n}{Sort} \PYG{k+kn}{Set}
  \PYG{k}{with} \PYG{n}{forest\PYGZus{}tree\PYGZus{}rec} \PYG{o}{:=} \PYG{n}{Induction} \PYG{k}{for} \PYG{n}{forest} \PYG{n}{Sort} \PYG{k+kn}{Set}\PYG{o}{.}
    \PYG{n}{forest\PYGZus{}tree\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}forest\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}forest\PYGZus{}rec}\PYG{o}{,} \PYG{n}{forest\PYGZus{}tree\PYGZus{}rec} \PYG{n}{are} \PYG{n}{recursively} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{quote}
\end{quote}

You may now look at the type of tree\_forest\_rec:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{tree\PYGZus{}forest\PYGZus{}rec}\PYG{o}{.}
    \PYG{n}{tree\PYGZus{}forest\PYGZus{}rec}
         \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{n}{tree} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P0} \PYG{o}{:} \PYG{n}{forest} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{)}\PYG{o}{,}
           \PYG{o}{(}\PYG{k}{forall} \PYG{o}{(}\PYG{n}{a} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f} \PYG{o}{:} \PYG{n}{forest}\PYG{o}{)}\PYG{o}{,} \PYG{n}{P0} \PYG{n}{f} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{(}\PYG{n}{node} \PYG{n}{a} \PYG{n}{f}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{b} \PYG{o}{:} \PYG{n}{B}\PYG{o}{,} \PYG{n}{P0} \PYG{o}{(}\PYG{n}{leaf} \PYG{n}{b}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{t} \PYG{o}{:} \PYG{n}{tree}\PYG{o}{,} \PYG{n}{P} \PYG{n}{t} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{f1} \PYG{o}{:} \PYG{n}{forest}\PYG{o}{,} \PYG{n}{P0} \PYG{n}{f1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P0} \PYG{o}{(}\PYG{n}{cons} \PYG{n}{t} \PYG{n}{f1}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{k}{forall} \PYG{n}{t} \PYG{o}{:} \PYG{n}{tree}\PYG{o}{,} \PYG{n}{P} \PYG{n}{t}
\end{sphinxVerbatim}

This principle involves two different predicates for trees andforests;
it also has three premises each one corresponding to a constructor of
one of the inductive definitions.

The principle \sphinxtitleref{forest\_tree\_rec} shares exactly the same premises, only
the conclusion now refers to the property of forests.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

Predicates odd and even on naturals.

Let odd and even be inductively defined as:
\begin{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{odd} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{oddS} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{even} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{odd} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}
\PYG{k}{with} \PYG{n}{even} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
  \PYG{o}{\textbar{}} \PYG{n}{evenO} \PYG{o}{:} \PYG{n}{even} \PYG{l+m+mi}{0}
  \PYG{o}{\textbar{}} \PYG{n}{evenS} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{odd} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{even} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{odd}\PYG{o}{,} \PYG{n}{even} \PYG{n}{are} \PYG{n}{defined}
    \PYG{n}{odd\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{even\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{quote}

The following command generates a powerful elimination principle:
\begin{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Scheme} \PYG{n}{odd\PYGZus{}even} \PYG{o}{:=} \PYG{n}{Minimality} \PYG{k}{for} \PYG{n}{odd} \PYG{n}{Sort} \PYG{k+kt}{Prop}
\PYG{k}{with} \PYG{n}{even\PYGZus{}odd} \PYG{o}{:=} \PYG{n}{Minimality} \PYG{k}{for} \PYG{n}{even} \PYG{n}{Sort} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{even\PYGZus{}odd} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{odd\PYGZus{}even} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{odd\PYGZus{}even}\PYG{o}{,} \PYG{n}{even\PYGZus{}odd} \PYG{n}{are} \PYG{n}{recursively} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{quote}

The type of odd\_even for instance will be:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{odd\PYGZus{}even}\PYG{o}{.}
    \PYG{n}{odd\PYGZus{}even}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{P} \PYG{n}{P0} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{,}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{even} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P0} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{n}{P0} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{odd} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P0} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{odd} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n}
\end{sphinxVerbatim}

The type of \sphinxtitleref{even\_odd} shares the same premises but the conclusion is
\sphinxtitleref{(n:nat)(even n)-\textgreater{}(P0 n)}.
\end{sphinxadmonition}


\subsubsection{Automatic declaration of schemes}
\label{\detokenize{user-extensions/proof-schemes:automatic-declaration-of-schemes}}\index{Elimination Schemes (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/proof-schemes:coq:flag.elimination-schemes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Elimination~Schemes}}}}
Enables automatic declaration of induction principles when defining a new
inductive type.  Defaults to on.

\end{fulllineitems}

\index{Nonrecursive Elimination Schemes (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/proof-schemes:coq:flag.nonrecursive-elimination-schemes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Nonrecursive~Elimination~Schemes}}}}
Enables automatic declaration of induction principles for types declared with the {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.variant}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variant}}}}} and
{\hyperref[\detokenize{language/gallina-extensions:coq:cmd.record}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Record}}}}} commands.  Defaults to off.

\end{fulllineitems}

\index{Case Analysis Schemes (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/proof-schemes:coq:flag.case-analysis-schemes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Case~Analysis~Schemes}}}}
This flag governs the generation of case analysis lemmas for inductive types,
i.e. corresponding to the pattern matching term alone and without fixpoint.

\end{fulllineitems}

\index{Boolean Equality Schemes (flag)}\index{Decidable Equality Schemes (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/proof-schemes:coq:flag.boolean-equality-schemes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Boolean~Equality~Schemes}}}}\phantomsection\label{\detokenize{user-extensions/proof-schemes:coq:flag.decidable-equality-schemes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Decidable~Equality~Schemes}}}}
These flags control the automatic declaration of those Boolean equalities (see
the second variant of \sphinxcode{\sphinxupquote{Scheme}}).

\end{fulllineitems}


\begin{sphinxadmonition}{warning}{Warning:}
You have to be careful with this option since Coq may now reject well-defined
inductive types because it cannot compute a Boolean equality for them.
\end{sphinxadmonition}
\index{Rewriting Schemes (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/proof-schemes:coq:flag.rewriting-schemes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Rewriting~Schemes}}}}
This flag governs generation of equality-related schemes such as congruence.

\end{fulllineitems}



\subsubsection{Combined Scheme}
\label{\detokenize{user-extensions/proof-schemes:combined-scheme}}
The \sphinxcode{\sphinxupquote{Combined Scheme}} command is a tool for combining induction
principles generated by the \sphinxcode{\sphinxupquote{Scheme command}}. Its syntax follows the
schema :
\index{Combined Scheme (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/proof-schemes:coq:cmd.combined-scheme}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Combined~Scheme~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~from~\DUrole{repeat-wrapper}{\DUrole{repeat}{ident}\DUrole{notation-sup}{+}\DUrole{notation-sub}{,}}}}}}
\end{fulllineitems}


where each identᵢ after the \sphinxcode{\sphinxupquote{from}} is a different inductive principle that must
belong to the same package of mutual inductive principle definitions.
This command generates the leftmost \sphinxtitleref{ident} to be the conjunction of the
principles: it is built from the common premises of the principles and
concluded by the conjunction of their conclusions.

\begin{sphinxadmonition}{note}{Example}

We can define the induction principles for trees and forests using:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Scheme} \PYG{n}{tree\PYGZus{}forest\PYGZus{}ind} \PYG{o}{:=} \PYG{n}{Induction} \PYG{k}{for} \PYG{n}{tree} \PYG{n}{Sort} \PYG{k+kt}{Prop}
\PYG{k}{with} \PYG{n}{forest\PYGZus{}tree\PYGZus{}ind} \PYG{o}{:=} \PYG{n}{Induction} \PYG{k}{for} \PYG{n}{forest} \PYG{n}{Sort} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{forest\PYGZus{}tree\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}forest\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}forest\PYGZus{}ind}\PYG{o}{,} \PYG{n}{forest\PYGZus{}tree\PYGZus{}ind} \PYG{n}{are} \PYG{n}{recursively} \PYG{n}{defined}
\end{sphinxVerbatim}

Then we can build the combined induction principle which gives the
conjunction of the conclusions of each individual principle:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Combined} \PYG{n}{Scheme} \PYG{n}{tree\PYGZus{}forest\PYGZus{}mutind} \PYG{n}{from} \PYG{n}{tree\PYGZus{}forest\PYGZus{}ind}\PYG{o}{,}\PYG{n}{forest\PYGZus{}tree\PYGZus{}ind}\PYG{o}{.}
    \PYG{n}{tree\PYGZus{}forest\PYGZus{}mutind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}forest\PYGZus{}mutind} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined}
\end{sphinxVerbatim}

The type of tree\_forest\_mutrec will be:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{tree\PYGZus{}forest\PYGZus{}mutind}\PYG{o}{.}
    \PYG{n}{tree\PYGZus{}forest\PYGZus{}mutind}
         \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{n}{tree} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P0} \PYG{o}{:} \PYG{n}{forest} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,}
           \PYG{o}{(}\PYG{k}{forall} \PYG{o}{(}\PYG{n}{a} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f} \PYG{o}{:} \PYG{n}{forest}\PYG{o}{)}\PYG{o}{,} \PYG{n}{P0} \PYG{n}{f} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{(}\PYG{n}{node} \PYG{n}{a} \PYG{n}{f}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{b} \PYG{o}{:} \PYG{n}{B}\PYG{o}{,} \PYG{n}{P0} \PYG{o}{(}\PYG{n}{leaf} \PYG{n}{b}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{t} \PYG{o}{:} \PYG{n}{tree}\PYG{o}{,} \PYG{n}{P} \PYG{n}{t} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{forall} \PYG{n}{f1} \PYG{o}{:} \PYG{n}{forest}\PYG{o}{,} \PYG{n}{P0} \PYG{n}{f1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P0} \PYG{o}{(}\PYG{n}{cons} \PYG{n}{t} \PYG{n}{f1}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{t} \PYG{o}{:} \PYG{n}{tree}\PYG{o}{,} \PYG{n}{P} \PYG{n}{t}\PYG{o}{)} \PYG{o}{/\PYGZbs{}} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{f2} \PYG{o}{:} \PYG{n}{forest}\PYG{o}{,} \PYG{n}{P0} \PYG{n}{f2}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsection{Generation of induction principles with \sphinxstyleliteralintitle{\sphinxupquote{Functional}} \sphinxstyleliteralintitle{\sphinxupquote{Scheme}}}
\label{\detokenize{user-extensions/proof-schemes:generation-of-induction-principles-with-functional-scheme}}\label{\detokenize{user-extensions/proof-schemes:functional-scheme}}
The \sphinxcode{\sphinxupquote{Functional Scheme}} command is a high-level experimental tool for
generating automatically induction principles corresponding to
(possibly mutually recursive) functions. First, it must be made
available via \sphinxcode{\sphinxupquote{Require Import FunInd}}. Its syntax then follows the
schema:
\index{Functional Scheme (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/proof-schemes:coq:cmd.functional-scheme}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Functional~Scheme~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~Induction~for~ident'~Sort~sort~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~Induction~for~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~Sort~sort}\DUrole{notation-sup}{*}}}}}}
\end{fulllineitems}


where each \sphinxtitleref{ident'ᵢ} is a different mutually defined function
name (the names must be in the same order as when they were defined). This
command generates the induction principle for each \sphinxtitleref{identᵢ}, following
the recursive structure and case analyses of the corresponding function
identᵢ’.

\begin{sphinxadmonition}{warning}{Warning:}
There is a difference between induction schemes generated by the command
{\hyperref[\detokenize{user-extensions/proof-schemes:coq:cmd.functional-scheme}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Functional Scheme}}}}} and these generated by the {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}}. Indeed,
{\hyperref[\detokenize{language/gallina-extensions:coq:cmd.function}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Function}}}}} generally produces smaller principles that are closer to how
a user would implement them. See {\hyperref[\detokenize{language/gallina-extensions:advanced-recursive-functions}]{\sphinxcrossref{\DUrole{std,std-ref}{Advanced recursive functions}}}} for details.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

Induction scheme for div2.

We define the function div2 as follows:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{FunInd}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{extraction\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{recdef\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}

\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Arith}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{z\PYGZus{}syntax\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{quote\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{newring\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}

\PYG{k+kn}{Fixpoint} \PYG{n}{div2} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
\PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
\PYG{o}{\textbar{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n\PYGZsq{}}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{n\PYGZsq{}}\PYG{o}{)}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{div2} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{div2} \PYG{k}{is} \PYG{n}{recursively} \PYG{n}{defined} \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{argument}\PYG{o}{)}
\end{sphinxVerbatim}

The definition of a principle of induction corresponding to the
recursive structure of \sphinxtitleref{div2} is defined by the command:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Functional} \PYG{n}{Scheme} \PYG{n}{div2\PYGZus{}ind} \PYG{o}{:=} \PYG{n}{Induction} \PYG{k}{for} \PYG{n}{div2} \PYG{n}{Sort} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{div2\PYGZus{}equation} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{div2\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

You may now look at the type of div2\_ind:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{div2\PYGZus{}ind}\PYG{o}{.}
    \PYG{n}{div2\PYGZus{}ind}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{,}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{l+m+mi}{0} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{n}{n0} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{n} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n0} \PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{l+m+mi}{1} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{n}{n0} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,}
            \PYG{n}{n} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n0} \PYG{o}{\PYGZhy{}\PYGZgt{}}
            \PYG{k}{forall} \PYG{n}{n\PYGZsq{}} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,}
            \PYG{n}{n0} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n\PYGZsq{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n\PYGZsq{}} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{n\PYGZsq{}}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{(}\PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n\PYGZsq{}}\PYG{o}{)}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{n\PYGZsq{}}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{P} \PYG{n}{n} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{n}\PYG{o}{)}
\end{sphinxVerbatim}

We can now prove the following lemma using this principle:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{div2\PYGZus{}le\PYGZsq{}} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{div2} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{div2} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}

\PYG{k}{intro} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{div2} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}

\PYG{k}{pattern} \PYG{n}{n}\PYG{o}{,} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{n}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{k}{fun} \PYG{n}{n0} \PYG{n}{n1} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{n1} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n0}\PYG{o}{)} \PYG{n}{n} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{n}\PYG{o}{)}

\PYG{k}{apply} \PYG{n}{div2\PYGZus{}ind}\PYG{o}{;} \PYG{k}{intros}\PYG{o}{.}
    \PYG{l+m+mi}{3} \PYG{n}{subgoals}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{n0} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{e} \PYG{o}{:} \PYG{n}{n0} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{1}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{S} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{n\PYGZsq{}}\PYG{o}{)} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n\PYGZsq{}}\PYG{o}{)}

\PYG{k}{auto} \PYG{k}{with} \PYG{n}{arith}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{n0}\PYG{o}{,} \PYG{n}{n1} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{e} \PYG{o}{:} \PYG{n}{n0} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n1}
      \PYG{n}{e0} \PYG{o}{:} \PYG{n}{n1} \PYG{o}{=} \PYG{l+m+mi}{0}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{1}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{S} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{n\PYGZsq{}}\PYG{o}{)} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n\PYGZsq{}}\PYG{o}{)}

\PYG{k}{auto} \PYG{k}{with} \PYG{n}{arith}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{n0}\PYG{o}{,} \PYG{n}{n1} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{e} \PYG{o}{:} \PYG{n}{n0} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n1}
      \PYG{n}{n\PYGZsq{}} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{e0} \PYG{o}{:} \PYG{n}{n1} \PYG{o}{=} \PYG{n}{S} \PYG{n}{n\PYGZsq{}}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{div2} \PYG{n}{n\PYGZsq{}} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n\PYGZsq{}}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{S} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{n\PYGZsq{}}\PYG{o}{)} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n\PYGZsq{}}\PYG{o}{)}

\PYG{k}{simpl}\PYG{o}{;} \PYG{k}{auto} \PYG{k}{with} \PYG{n}{arith}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{div2\PYGZus{}le\PYGZsq{}} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

We can use directly the functional induction ({\hyperref[\detokenize{proof-engine/tactics:coq:tacn.function-induction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{function induction}}}}}) tactic instead
of the pattern/apply trick:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Reset} \PYG{n}{div2\PYGZus{}le\PYGZsq{}}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{div2\PYGZus{}le} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{div2} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{div2} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}

\PYG{k}{intro} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{div2} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n}

\PYG{n}{functional} \PYG{k}{induction} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{n}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{3} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{0}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{1}
    \PYG{n}{subgoal} \PYG{l+m+mi}{3} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{S} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{n\PYGZsq{}}\PYG{o}{)} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n\PYGZsq{}}\PYG{o}{)}

\PYG{k}{auto} \PYG{k}{with} \PYG{n}{arith}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{subgoals}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{l+m+mi}{0} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{1}
    
    \PYG{n}{subgoal} \PYG{l+m+mi}{2} \PYG{k}{is}\PYG{o}{:}
     \PYG{n}{S} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{n\PYGZsq{}}\PYG{o}{)} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n\PYGZsq{}}\PYG{o}{)}

\PYG{k}{auto} \PYG{k}{with} \PYG{n}{arith}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n\PYGZsq{}} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{IHn0} \PYG{o}{:} \PYG{n}{div2} \PYG{n}{n\PYGZsq{}} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n\PYGZsq{}}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{S} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{n\PYGZsq{}}\PYG{o}{)} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n\PYGZsq{}}\PYG{o}{)}

\PYG{k}{auto} \PYG{k}{with} \PYG{n}{arith}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{div2\PYGZus{}le} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

Induction scheme for tree\_size.

We define trees by the following mutual inductive type:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{A} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{.}
    \PYG{n}{A} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Inductive} \PYG{n}{tree} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{n}{node} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{tree}
\PYG{k}{with} \PYG{n}{forest} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{empty} \PYG{o}{:} \PYG{n}{forest}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{tree} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{forest}\PYG{o}{.}
    \PYG{n}{tree}\PYG{o}{,} \PYG{n}{forest} \PYG{n}{are} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{forest\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{forest\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{forest\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

We define the function tree\_size that computes the size of a tree or a
forest. Note that we use \sphinxcode{\sphinxupquote{Function}} which generally produces better
principles.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{FunInd}\PYG{o}{.}
\PYG{n}{Function} \PYG{n}{tree\PYGZus{}size} \PYG{o}{(}\PYG{n}{t}\PYG{o}{:}\PYG{n}{tree}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{t} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n}{node} \PYG{n}{A} \PYG{n}{f} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{forest\PYGZus{}size} \PYG{n}{f}\PYG{o}{)}
\PYG{k}{end}
\PYG{k}{with} \PYG{n}{forest\PYGZus{}size} \PYG{o}{(}\PYG{n}{f}\PYG{o}{:}\PYG{n}{forest}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
\PYG{k}{match} \PYG{n}{f} \PYG{k}{with}
\PYG{o}{\textbar{}} \PYG{n}{empty} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{n}{t} \PYG{n}{f\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{o}{(}\PYG{n}{tree\PYGZus{}size} \PYG{n}{t} \PYG{o}{+} \PYG{n}{forest\PYGZus{}size} \PYG{n}{f\PYGZsq{}}\PYG{o}{)}
\PYG{k}{end}\PYG{o}{.}
    \PYG{n}{tree\PYGZus{}size} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{forest\PYGZus{}size} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}size}\PYG{o}{,} \PYG{n}{forest\PYGZus{}size} \PYG{n}{are} \PYG{n}{recursively} \PYG{n}{defined}
    \PYG{o}{(}\PYG{n}{decreasing} \PYG{n}{respectively} \PYG{n}{on} \PYG{l+m+mi}{1}\PYG{n}{st}\PYG{o}{,} \PYG{l+m+mi}{1}\PYG{n}{st} \PYG{n}{arguments}\PYG{o}{)}
    \PYG{n}{tree\PYGZus{}size\PYGZus{}equation} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}size\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}size\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{tree\PYGZus{}size\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{forest\PYGZus{}size\PYGZus{}equation} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{forest\PYGZus{}size\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{forest\PYGZus{}size\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{forest\PYGZus{}size\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{R\PYGZus{}tree\PYGZus{}size\PYGZus{}correct} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{R\PYGZus{}forest\PYGZus{}size\PYGZus{}correct} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{R\PYGZus{}tree\PYGZus{}size\PYGZus{}complete} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{R\PYGZus{}forest\PYGZus{}size\PYGZus{}complete} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

Notice that the induction principles \sphinxcode{\sphinxupquote{tree\_size\_ind}} and \sphinxcode{\sphinxupquote{forest\_size\_ind}}
generated by \sphinxcode{\sphinxupquote{Function}} are not mutual.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{tree\PYGZus{}size\PYGZus{}ind}\PYG{o}{.}
    \PYG{n}{tree\PYGZus{}size\PYGZus{}ind}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{P} \PYG{o}{:} \PYG{n}{tree} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{,}
           \PYG{o}{(}\PYG{k}{forall} \PYG{o}{(}\PYG{n}{t} \PYG{o}{:} \PYG{n}{tree}\PYG{o}{)} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f} \PYG{o}{:} \PYG{n}{forest}\PYG{o}{)}\PYG{o}{,}
            \PYG{n}{t} \PYG{o}{=} \PYG{n}{node} \PYG{n}{A} \PYG{n}{f} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{(}\PYG{n}{node} \PYG{n}{A} \PYG{n}{f}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S} \PYG{o}{(}\PYG{n}{forest\PYGZus{}size} \PYG{n}{f}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{k}{forall} \PYG{n}{t} \PYG{o}{:} \PYG{n}{tree}\PYG{o}{,} \PYG{n}{P} \PYG{n}{t} \PYG{o}{(}\PYG{n}{tree\PYGZus{}size} \PYG{n}{t}\PYG{o}{)}
\end{sphinxVerbatim}

Mutual induction principles following the recursive structure of \sphinxcode{\sphinxupquote{tree\_size}}
and \sphinxcode{\sphinxupquote{forest\_size}} can be generated by the following command:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Functional} \PYG{n}{Scheme} \PYG{n}{tree\PYGZus{}size\PYGZus{}ind2} \PYG{o}{:=} \PYG{n}{Induction} \PYG{k}{for} \PYG{n}{tree\PYGZus{}size} \PYG{n}{Sort} \PYG{k+kt}{Prop}
\PYG{k}{with} \PYG{n}{forest\PYGZus{}size\PYGZus{}ind2} \PYG{o}{:=} \PYG{n}{Induction} \PYG{k}{for} \PYG{n}{forest\PYGZus{}size} \PYG{n}{Sort} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{tree\PYGZus{}size\PYGZus{}ind2} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{forest\PYGZus{}size\PYGZus{}ind2} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

You may now look at the type of \sphinxtitleref{tree\_size\_ind2}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{n}{tree\PYGZus{}size\PYGZus{}ind2}\PYG{o}{.}
    \PYG{n}{tree\PYGZus{}size\PYGZus{}ind2}
         \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{n}{tree} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P0} \PYG{o}{:} \PYG{n}{forest} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,}
           \PYG{o}{(}\PYG{k}{forall} \PYG{o}{(}\PYG{n}{t} \PYG{o}{:} \PYG{n}{tree}\PYG{o}{)} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f} \PYG{o}{:} \PYG{n}{forest}\PYG{o}{)}\PYG{o}{,}
            \PYG{n}{t} \PYG{o}{=} \PYG{n}{node} \PYG{n}{A} \PYG{n}{f} \PYG{o}{\PYGZhy{}\PYGZgt{}}
            \PYG{n}{P0} \PYG{n}{f} \PYG{o}{(}\PYG{n}{forest\PYGZus{}size} \PYG{n}{f}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{o}{(}\PYG{n}{node} \PYG{n}{A} \PYG{n}{f}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S} \PYG{o}{(}\PYG{n}{forest\PYGZus{}size} \PYG{n}{f}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{f0} \PYG{o}{:} \PYG{n}{forest}\PYG{o}{,} \PYG{n}{f0} \PYG{o}{=} \PYG{n}{empty} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P0} \PYG{n}{empty} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{o}{(}\PYG{k}{forall} \PYG{o}{(}\PYG{n}{f1} \PYG{o}{:} \PYG{n}{forest}\PYG{o}{)} \PYG{o}{(}\PYG{n}{t} \PYG{o}{:} \PYG{n}{tree}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f\PYGZsq{}} \PYG{o}{:} \PYG{n}{forest}\PYG{o}{)}\PYG{o}{,}
            \PYG{n}{f1} \PYG{o}{=} \PYG{n}{cons} \PYG{n}{t} \PYG{n}{f\PYGZsq{}} \PYG{o}{\PYGZhy{}\PYGZgt{}}
            \PYG{n}{P} \PYG{n}{t} \PYG{o}{(}\PYG{n}{tree\PYGZus{}size} \PYG{n}{t}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
            \PYG{n}{P0} \PYG{n}{f\PYGZsq{}} \PYG{o}{(}\PYG{n}{forest\PYGZus{}size} \PYG{n}{f\PYGZsq{}}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
            \PYG{n}{P0} \PYG{o}{(}\PYG{n}{cons} \PYG{n}{t} \PYG{n}{f\PYGZsq{}}\PYG{o}{)} \PYG{o}{(}\PYG{n}{tree\PYGZus{}size} \PYG{n}{t} \PYG{o}{+} \PYG{n}{forest\PYGZus{}size} \PYG{n}{f\PYGZsq{}}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}}
           \PYG{k}{forall} \PYG{n}{t} \PYG{o}{:} \PYG{n}{tree}\PYG{o}{,} \PYG{n}{P} \PYG{n}{t} \PYG{o}{(}\PYG{n}{tree\PYGZus{}size} \PYG{n}{t}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsection{Generation of inversion principles with \sphinxstyleliteralintitle{\sphinxupquote{Derive}} \sphinxstyleliteralintitle{\sphinxupquote{Inversion}}}
\label{\detokenize{user-extensions/proof-schemes:generation-of-inversion-principles-with-derive-inversion}}\label{\detokenize{user-extensions/proof-schemes:derive-inversion}}
The syntax of \sphinxcode{\sphinxupquote{Derive}} \sphinxcode{\sphinxupquote{Inversion}} follows the schema:
\index{Derive Inversion (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{user-extensions/proof-schemes:coq:cmd.derive-inversion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Derive~Inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~with~forall~(x~:~T),~I~t~Sort~sort}}}}
\end{fulllineitems}


This command generates an inversion principle for the \sphinxtitleref{inversion … using}
tactic. Let \sphinxtitleref{I} be an inductive predicate and \sphinxtitleref{x} the variables occurring
in t. This command generates and stocks the inversion lemma for the
sort \sphinxtitleref{sort} corresponding to the instance \sphinxtitleref{∀ (x:T), I t} with the name
\sphinxtitleref{ident} in the global environment. When applied, it is equivalent to
having inverted the instance with the tactic \sphinxtitleref{inversion}.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Derive~Inversion\_clear~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~with~forall~(x:T),~I~t~Sort~sort}}}}
When applied, it is equivalent to having inverted the instance with the
tactic inversion replaced by the tactic \sphinxtitleref{inversion\_clear}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Derive~Dependent~Inversion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~with~forall~(x:T),~I~t~Sort~sort}}}}
When applied, it is equivalent to having inverted the instance with
the tactic \sphinxtitleref{dependent inversion}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Derive~Dependent~Inversion\_clear~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~with~forall(x:T),~I~t~Sort~sort}}}}
When applied, it is equivalent to having inverted the instance
with the tactic \sphinxtitleref{dependent inversion\_clear}.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

Consider the relation \sphinxtitleref{Le} over natural numbers and the following
parameter \sphinxcode{\sphinxupquote{P}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{Le} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{LeO} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{l+m+mi}{0} \PYG{n}{n}
\PYG{o}{\textbar{}} \PYG{n}{LeS} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Le} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Le\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Le\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Le\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Parameter} \PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
    \PYG{n}{P} \PYG{k}{is} \PYG{n}{declared}
\end{sphinxVerbatim}

To generate the inversion lemma for the instance \sphinxtitleref{(Le (S n) m)} and the
sort \sphinxtitleref{Prop}, we do:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Derive} \PYG{n}{Inversion\PYGZus{}clear} \PYG{n}{leminv} \PYG{k}{with} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m}\PYG{o}{)} \PYG{n}{Sort} \PYG{k+kt}{Prop}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{n}{leminv}\PYG{o}{.}
    \PYG{n}{leminv}
         \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{P} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)}\PYG{o}{,}
           \PYG{o}{(}\PYG{k}{forall} \PYG{n}{m0} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m0}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n} \PYG{n}{m}
\end{sphinxVerbatim}

Then we can use the proven inversion lemma:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Show}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{P} \PYG{n}{n} \PYG{n}{m}

\PYG{k}{inversion} \PYG{n}{H} \PYG{k}{using} \PYG{n}{leminv}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{Le} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n}{m}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{m0} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{Le} \PYG{n}{n} \PYG{n}{m0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{P} \PYG{n}{n} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m0}\PYG{o}{)}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\chapter{Practical tools}
\label{\detokenize{index:practical-tools}}

\section{The Coq commands}
\label{\detokenize{practical-tools/coq-commands:the-coq-commands}}\label{\detokenize{practical-tools/coq-commands:thecoqcommands}}\label{\detokenize{practical-tools/coq-commands::doc}}
There are three \DUrole{smallcaps}{Coq} commands:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{coqtop}}: the \DUrole{smallcaps}{Coq} toplevel (interactive mode);

\item {} 
\sphinxcode{\sphinxupquote{coqc}}: the \DUrole{smallcaps}{Coq} compiler (batch compilation);

\item {} 
\sphinxcode{\sphinxupquote{coqchk}}: the \DUrole{smallcaps}{Coq} checker (validation of compiled libraries).

\end{itemize}

The options are (basically) the same for the first two commands, and
roughly described below. You can also look at the \sphinxcode{\sphinxupquote{man}} pages of
\sphinxcode{\sphinxupquote{coqtop}} and \sphinxcode{\sphinxupquote{coqc}} for more details.


\subsection{Interactive use (coqtop)}
\label{\detokenize{practical-tools/coq-commands:interactive-use-coqtop}}\label{\detokenize{practical-tools/coq-commands:interactive-use}}
In the interactive mode, also known as the \DUrole{smallcaps}{Coq} toplevel, the user can
develop his theories and proofs step by step. The \DUrole{smallcaps}{Coq} toplevel is run
by the command \sphinxcode{\sphinxupquote{coqtop}}.

There are two different binary images of \DUrole{smallcaps}{Coq}: the byte-code one and the
native-code one (if OCaml provides a native-code compiler for
your platform, which is supposed in the following). By default,
\sphinxcode{\sphinxupquote{coqtop}} executes the native-code version; run \sphinxcode{\sphinxupquote{coqtop.byte}} to get
the byte-code version.

The byte-code toplevel is based on an OCaml toplevel (to
allow dynamic linking of tactics). You can switch to the OCaml toplevel
with the command \sphinxcode{\sphinxupquote{Drop.}}, and come back to the \DUrole{smallcaps}{Coq}
toplevel with the command \sphinxcode{\sphinxupquote{Coqloop.loop();;}}.


\subsection{Batch compilation (coqc)}
\label{\detokenize{practical-tools/coq-commands:batch-compilation-coqc}}
The \sphinxcode{\sphinxupquote{coqc}} command takes a name \sphinxstyleemphasis{file} as argument. Then it looks for a
vernacular file named \sphinxstyleemphasis{file}.v, and tries to compile it into a
\sphinxstyleemphasis{file}.vo file (See {\hyperref[\detokenize{proof-engine/vernacular-commands:compiled-files}]{\sphinxcrossref{\DUrole{std,std-ref}{Compiled files}}}}).

\begin{sphinxadmonition}{caution}{Caution:}
The name \sphinxstyleemphasis{file} should be a regular \DUrole{smallcaps}{Coq} identifier as defined in Section {\hyperref[\detokenize{language/gallina-specification-language:lexical-conventions}]{\sphinxcrossref{\DUrole{std,std-ref}{Lexical conventions}}}}.
It should contain only letters, digits or underscores (\_). For example \sphinxcode{\sphinxupquote{/bar/foo/toto.v}} is valid,
but \sphinxcode{\sphinxupquote{/bar/foo/to-to.v}} is not.
\end{sphinxadmonition}


\subsection{Customization at launch time}
\label{\detokenize{practical-tools/coq-commands:customization-at-launch-time}}

\subsubsection{By resource file}
\label{\detokenize{practical-tools/coq-commands:by-resource-file}}
When \DUrole{smallcaps}{Coq} is launched, with either \sphinxcode{\sphinxupquote{coqtop}} or \sphinxcode{\sphinxupquote{coqc}}, the
resource file \sphinxcode{\sphinxupquote{\$XDG\_CONFIG\_HOME/coq/coqrc.xxx}}, if it exists, will
be implicitly prepended to any document read by Coq, whether it is an
interactive session or a file to compile. Here, \sphinxcode{\sphinxupquote{\$XDG\_CONFIG\_HOME}}
is the configuration directory of the user (by default it's \sphinxcode{\sphinxupquote{\textasciitilde{}/.config}})
and \sphinxcode{\sphinxupquote{xxx}} is the version number (e.g. 8.8). If
this file is not found, then the file \sphinxcode{\sphinxupquote{\$XDG\_CONFIG\_HOME/coqrc}} is
searched. If not found, it is the file \sphinxcode{\sphinxupquote{\textasciitilde{}/.coqrc.xxx}} which is searched,
and, if still not found, the file \sphinxcode{\sphinxupquote{\textasciitilde{}/.coqrc}}. If the latter is also
absent, no resource file is loaded.
You can also specify an arbitrary name for the resource file
(see option \sphinxcode{\sphinxupquote{-init-file}} below).

The resource file may contain, for instance, \sphinxcode{\sphinxupquote{Add LoadPath}} commands to add
directories to the load path of \DUrole{smallcaps}{Coq}. It is possible to skip the
loading of the resource file with the option \sphinxcode{\sphinxupquote{-q}}.


\subsubsection{By environment variables}
\label{\detokenize{practical-tools/coq-commands:by-environment-variables}}\label{\detokenize{practical-tools/coq-commands:customization-by-environment-variables}}
Load path can be specified to the \DUrole{smallcaps}{Coq} system by setting up \sphinxcode{\sphinxupquote{\$COQPATH}}
environment variable. It is a list of directories separated by
\sphinxcode{\sphinxupquote{:}} (\sphinxcode{\sphinxupquote{;}} on Windows). \DUrole{smallcaps}{Coq} will also honor \sphinxcode{\sphinxupquote{\$XDG\_DATA\_HOME}} and
\sphinxcode{\sphinxupquote{\$XDG\_DATA\_DIRS}} (see Section {\hyperref[\detokenize{language/gallina-extensions:libraries-and-filesystem}]{\sphinxcrossref{\DUrole{std,std-ref}{Libraries and filesystem}}}}).

Some \DUrole{smallcaps}{Coq} commands call other \DUrole{smallcaps}{Coq} commands. In this case, they look for
the commands in directory specified by \sphinxcode{\sphinxupquote{\$COQBIN}}. If this variable is
not set, they look for the commands in the executable path.

The \sphinxcode{\sphinxupquote{\$COQ\_COLORS}} environment variable can be used to specify the set
of colors used by \sphinxcode{\sphinxupquote{coqtop}} to highlight its output. It uses the same
syntax as the \sphinxcode{\sphinxupquote{\$LS\_COLORS}} variable from GNU’s ls, that is, a colon-separated
list of assignments of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{name=\DUrole{repeat-wrapper}{\DUrole{repeat}{attr}\DUrole{notation-sup}{*}\DUrole{notation-sub}{;}}}}} where
\sphinxcode{\sphinxupquote{name}} is the name of the corresponding highlight tag and each \sphinxcode{\sphinxupquote{attr}} is an
ANSI escape code. The list of highlight tags can be retrieved with the
\sphinxcode{\sphinxupquote{-list-tags}} command-line option of \sphinxcode{\sphinxupquote{coqtop}}.


\subsubsection{By command line options}
\label{\detokenize{practical-tools/coq-commands:by-command-line-options}}\label{\detokenize{practical-tools/coq-commands:command-line-options}}
The following command-line options are recognized by the commands \sphinxcode{\sphinxupquote{coqc}}
and \sphinxcode{\sphinxupquote{coqtop}}, unless stated otherwise:
\begin{quote}\begin{description}
\item[{-I \sphinxstyleemphasis{directory}, -include \sphinxstyleemphasis{directory}}] \leavevmode
Add physical path \sphinxstyleemphasis{directory}
to the OCaml loadpath.


\sphinxstrong{See also:}


{\hyperref[\detokenize{language/gallina-extensions:names-of-libraries}]{\sphinxcrossref{\DUrole{std,std-ref}{Names of libraries}}}} and the
command Declare ML Module Section {\hyperref[\detokenize{proof-engine/vernacular-commands:compiled-files}]{\sphinxcrossref{\DUrole{std,std-ref}{Compiled files}}}}.



\item[{-Q \sphinxstyleemphasis{directory} dirpath}] \leavevmode
Add physical path \sphinxstyleemphasis{directory} to the list of
directories where \DUrole{smallcaps}{Coq} looks for a file and bind it to the logical
directory \sphinxstyleemphasis{dirpath}. The subdirectory structure of \sphinxstyleemphasis{directory} is
recursively available from \DUrole{smallcaps}{Coq} using absolute names (extending the
dirpath prefix) (see Section {\hyperref[\detokenize{language/gallina-extensions:qualified-names}]{\sphinxcrossref{\DUrole{std,std-ref}{Qualified names}}}}).Note that only those
subdirectories and files which obey the lexical conventions of what is
an \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} are taken into account. Conversely, the
underlying file systems or operating systems may be more restrictive
than \DUrole{smallcaps}{Coq}. While Linux’s ext4 file system supports any \DUrole{smallcaps}{Coq} recursive
layout (within the limit of 255 bytes per filename), the default on
NTFS (Windows) or HFS+ (MacOS X) file systems is on the contrary to
disallow two files differing only in the case in the same directory.


\sphinxstrong{See also:}


Section {\hyperref[\detokenize{language/gallina-extensions:names-of-libraries}]{\sphinxcrossref{\DUrole{std,std-ref}{Names of libraries}}}}.



\item[{-R \sphinxstyleemphasis{directory} dirpath}] \leavevmode
Do as -Q \sphinxstyleemphasis{directory} dirpath but make the
subdirectory structure of \sphinxstyleemphasis{directory} recursively visible so that the
recursive contents of physical \sphinxstyleemphasis{directory} is available from \DUrole{smallcaps}{Coq} using
short or partially qualified names.


\sphinxstrong{See also:}


Section {\hyperref[\detokenize{language/gallina-extensions:names-of-libraries}]{\sphinxcrossref{\DUrole{std,std-ref}{Names of libraries}}}}.



\item[{-top dirpath}] \leavevmode
Set the toplevel module name to dirpath instead of Top.
Not valid for \sphinxtitleref{coqc} as the toplevel module name is inferred from the
name of the output file.

\item[{-exclude-dir \sphinxstyleemphasis{directory}}] \leavevmode
Exclude any subdirectory named \sphinxstyleemphasis{directory}
while processing options such as -R and -Q. By default, only the
conventional version control management directories named CVS
and\_darcs are excluded.

\item[{-nois}] \leavevmode
Start from an empty state instead of loading the Init.Prelude
module.

\item[{-init-file \sphinxstyleemphasis{file}}] \leavevmode
Load \sphinxstyleemphasis{file} as the resource file instead of
loading the default resource file from the standard configuration
directories.

\item[{-q}] \leavevmode
Do not to load the default resource file.

\item[{-load-ml-source \sphinxstyleemphasis{file}}] \leavevmode
Load the OCaml source file \sphinxstyleemphasis{file}.

\item[{-load-ml-object \sphinxstyleemphasis{file}}] \leavevmode
Load the OCaml object file \sphinxstyleemphasis{file}.

\item[{-l \sphinxstyleemphasis{file}, -load-vernac-source \sphinxstyleemphasis{file}}] \leavevmode
Load and execute the \DUrole{smallcaps}{Coq}
script from \sphinxstyleemphasis{file.v}.

\item[{-lv \sphinxstyleemphasis{file}, -load-vernac-source-verbose \sphinxstyleemphasis{file}}] \leavevmode
Load and execute the
\DUrole{smallcaps}{Coq} script from \sphinxstyleemphasis{file.v}. Write its contents to the standard output as
it is executed.

\item[{-load-vernac-object dirpath}] \leavevmode
Load \DUrole{smallcaps}{Coq} compiled library dirpath. This
is equivalent to runningRequire dirpath.

\item[{-require dirpath}] \leavevmode
Load \DUrole{smallcaps}{Coq} compiled library dirpath and import it.
This is equivalent to running Require Import dirpath.

\item[{-batch}] \leavevmode
Exit just after argument parsing. Available for \sphinxtitleref{coqtop} only.

\item[{-compile \sphinxstyleemphasis{file.v}}] \leavevmode
Compile file \sphinxstyleemphasis{file.v} into \sphinxstyleemphasis{file.vo}. This option
implies -batch (exit just after argument parsing). It is available only
for \sphinxtitleref{coqtop}, as this behavior is the purpose of \sphinxtitleref{coqc}.

\item[{-compile-verbose \sphinxstyleemphasis{file.v}}] \leavevmode
Same as -compile but also output the
content of \sphinxstyleemphasis{file.v} as it is compiled.

\item[{-verbose}] \leavevmode
Output the content of the input file as it is compiled.
This option is available for \sphinxtitleref{coqc} only; it is the counterpart of
-compile-verbose.

\item[{-w (all\textbar{}none\textbar{}w\(\sb{\text{1}}\),…,wₙ)}] \leavevmode
Configure the display of warnings. This
option expects all, none or a comma-separated list of warning names or
categories (see Section {\hyperref[\detokenize{proof-engine/vernacular-commands:controlling-display}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling display}}}}).

\item[{-color (on\textbar{}off\textbar{}auto)}] \leavevmode
Enable or not the coloring of output of \sphinxtitleref{coqtop}.
Default is auto, meaning that \sphinxtitleref{coqtop} dynamically decides, depending on
whether the output channel supports ANSI escape sequences.

\item[{-beautify}] \leavevmode
Pretty-print each command to \sphinxstyleemphasis{file.beautified} when
compiling \sphinxstyleemphasis{file.v}, in order to get old-fashioned
syntax/definitions/notations.

\item[{-emacs, -ide-slave}] \leavevmode
Start a special toplevel to communicate with a
specific IDE.

\item[{-impredicative-set}] \leavevmode
Change the logical theory of \DUrole{smallcaps}{Coq} by declaring the
sort Set impredicative.

\begin{sphinxadmonition}{warning}{Warning:}
This is known to be inconsistent with some
standard axioms of classical mathematics such as the functional
axiom of choice or the principle of description.
\end{sphinxadmonition}

\item[{-type-in-type}] \leavevmode
Collapse the universe hierarchy of \DUrole{smallcaps}{Coq}.

\begin{sphinxadmonition}{warning}{Warning:}
This makes the logic inconsistent.
\end{sphinxadmonition}

\item[{-mangle-names \sphinxstyleemphasis{ident}}] \leavevmode
Experimental: Do not depend on this option. Replace
Coq's auto-generated name scheme with names of the form \sphinxstyleemphasis{ident0}, \sphinxstyleemphasis{ident1},
etc. The command \sphinxcode{\sphinxupquote{Set Mangle Names}} turns the behavior on in a document,
and \sphinxcode{\sphinxupquote{Set Mangle Names Prefix "ident"}} changes the used prefix. This feature
is intended to be used as a linter for developments that want to be robust to
changes in the auto-generated name scheme. The options are provided to
facilitate tracking down problems.

\item[{-compat \sphinxstyleemphasis{version}}] \leavevmode
Attempt to maintain some backward-compatibility
with a previous version.

\item[{-dump-glob \sphinxstyleemphasis{file}}] \leavevmode
Dump references for global names in file \sphinxstyleemphasis{file}
(to be used by coqdoc, see {\hyperref[\detokenize{practical-tools/utilities:coqdoc}]{\sphinxcrossref{\DUrole{std,std-ref}{Documenting Coq files with coqdoc}}}}). By default, if \sphinxstyleemphasis{file.v} is being
compiled, \sphinxstyleemphasis{file.glob} is used.

\item[{-no-glob}] \leavevmode
Disable the dumping of references for global names.

\item[{-image \sphinxstyleemphasis{file}}] \leavevmode
Set the binary image to be used by \sphinxtitleref{coqc} to be \sphinxstyleemphasis{file}
instead of the standard one. Not of general use.

\item[{-bindir \sphinxstyleemphasis{directory}}] \leavevmode
Set the directory containing \DUrole{smallcaps}{Coq} binaries to be
used by \sphinxtitleref{coqc}. It is equivalent to doing export COQBIN= \sphinxstyleemphasis{directory}
before launching \sphinxtitleref{coqc}.

\item[{-where}] \leavevmode
Print the location of \DUrole{smallcaps}{Coq}’s standard library and exit.

\item[{-config}] \leavevmode
Print the locations of \DUrole{smallcaps}{Coq}’s binaries, dependencies, and
libraries, then exit.

\item[{-filteropts}] \leavevmode
Print the list of command line arguments that \sphinxtitleref{coqtop} has
recognized as options and exit.

\item[{-v}] \leavevmode
Print \DUrole{smallcaps}{Coq}’s version and exit.

\item[{-list-tags}] \leavevmode
Print the highlight tags known by \DUrole{smallcaps}{Coq} as well as their
currently associated color and exit.

\item[{-h, --help}] \leavevmode
Print a short usage and exit.

\end{description}\end{quote}


\subsection{Compiled libraries checker (coqchk)}
\label{\detokenize{practical-tools/coq-commands:compiled-libraries-checker-coqchk}}
The \sphinxcode{\sphinxupquote{coqchk}} command takes a list of library paths as argument, described either
by their logical name or by their physical filename, hich must end in \sphinxcode{\sphinxupquote{.vo}}. The
corresponding compiled libraries (\sphinxcode{\sphinxupquote{.vo}} files) are searched in the path,
recursively processing the libraries they depend on. The content of all these
libraries is then type checked. The effect of \sphinxcode{\sphinxupquote{coqchk}} is only to return with
normal exit code in case of success, and with positive exit code if an error has
been found. Error messages are not deemed to help the user understand what is
wrong. In the current version, it does not modify the compiled libraries to mark
them as successfully checked.

Note that non-logical information is not checked. By logical
information, we mean the type and optional body associated to names.
It excludes for instance anything related to the concrete syntax of
objects (customized syntax rules, association between short and long
names), implicit arguments, etc.

This tool can be used for several purposes. One is to check that a
compiled library provided by a third-party has not been forged and
that loading it cannot introduce inconsistencies %
\begin{footnote}[19]\sphinxAtStartFootnote
Ill-formed non-logical information might for instance bind
Coq.Init.Logic.True to short name False, so apparently False is
inhabited, but using fully qualified names, Coq.Init.Logic.False will
always refer to the absurd proposition, what we guarantee is that
there is no proof of this latter constant.
%
\end{footnote}. Another point is
to get an even higher level of security. Since \sphinxcode{\sphinxupquote{coqtop}} can be extended
with custom tactics, possibly ill-typed code, it cannot be guaranteed
that the produced compiled libraries are correct. \sphinxcode{\sphinxupquote{coqchk}} is a
standalone verifier, and thus it cannot be tainted by such malicious
code.

Command-line options \sphinxcode{\sphinxupquote{-Q}}, \sphinxcode{\sphinxupquote{-R}}, \sphinxcode{\sphinxupquote{-where}} and \sphinxcode{\sphinxupquote{-impredicative-set}} are supported
by \sphinxcode{\sphinxupquote{coqchk}} and have the same meaning as for \sphinxcode{\sphinxupquote{coqtop}}. As there is no notion of
relative paths in object files \sphinxcode{\sphinxupquote{-Q}} and \sphinxcode{\sphinxupquote{-R}} have exactly the same meaning.
\begin{quote}\begin{description}
\item[{-norec \sphinxstyleemphasis{module}}] \leavevmode
Check \sphinxstyleemphasis{module} but do not check its dependencies.

\item[{-admit \sphinxstyleemphasis{module}}] \leavevmode
Do not check \sphinxstyleemphasis{module} and any of its dependencies,
unless explicitly required.

\item[{-o}] \leavevmode
At exit, print a summary about the context. List the names of all
assumptions and variables (constants without body).

\item[{-silent}] \leavevmode
Do not write progress information to the standard output.

\end{description}\end{quote}

Environment variable \sphinxcode{\sphinxupquote{\$COQLIB}} can be set to override the location of
the standard library.

The algorithm for deciding which modules are checked or admitted is
the following: assuming that \sphinxcode{\sphinxupquote{coqchk}} is called with argument \sphinxcode{\sphinxupquote{M}}, option
\sphinxcode{\sphinxupquote{-norec N}}, and \sphinxcode{\sphinxupquote{-admit A}}. Let us write \(\overline{S}\) for the
set of reflexive transitive dependencies of set \(S\). Then:
\begin{itemize}
\item {} 
Modules \(C = \overline{M} \backslash \overline{A} \cup M \cup N\) are loaded and type checked before being added
to the context.

\item {} 
And \(M \cup N \backslash C\) is the set of modules that are loaded and added to the
context without type checking. Basic integrity checks (checksums) are
nonetheless performed.

\end{itemize}

As a rule of thumb, -admit can be used to tell Coq that some libraries
have already been checked. So \sphinxcode{\sphinxupquote{coqchk A B}} can be split in \sphinxcode{\sphinxupquote{coqchk A}} \&\&
\sphinxcode{\sphinxupquote{coqchk B -admit A}} without type checking any definition twice. Of
course, the latter is slightly slower since it makes more disk access.
It is also less secure since an attacker might have replaced the
compiled library \sphinxcode{\sphinxupquote{A}} after it has been read by the first command, but
before it has been read by the second command.


\section{Utilities}
\label{\detokenize{practical-tools/utilities:utilities}}\label{\detokenize{practical-tools/utilities:id1}}\label{\detokenize{practical-tools/utilities::doc}}
The distribution provides utilities to simplify some tedious works
beside proof development, tactics writing or documentation.


\subsection{Using Coq as a library}
\label{\detokenize{practical-tools/utilities:using-coq-as-a-library}}
In previous versions, \sphinxcode{\sphinxupquote{coqmktop}} was used to build custom
toplevels - for example for better debugging or custom static
linking. Nowadays, the preferred method is to use \sphinxcode{\sphinxupquote{ocamlfind}}.

The most basic custom toplevel is built using:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZpc{} ocamlfind ocamlopt \PYGZhy{}thread \PYGZhy{}rectypes \PYGZhy{}linkall \PYGZhy{}linkpkg \PYGZbs{}
              \PYGZhy{}package coq.toplevel \PYGZbs{}
               toplevel/coqtop\PYGZbs{}\PYGZus{}bin.ml \PYGZhy{}o my\PYGZbs{}\PYGZus{}toplevel.native
\end{sphinxVerbatim}

For example, to statically link \sphinxtitleref{L}$_{\text{tac}}$, you can just do:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZpc{} ocamlfind ocamlopt \PYGZhy{}thread \PYGZhy{}rectypes \PYGZhy{}linkall \PYGZhy{}linkpkg \PYGZbs{}
              \PYGZhy{}package coq.toplevel \PYGZhy{}package coq.ltac \PYGZbs{}
              toplevel/coqtop\PYGZbs{}\PYGZus{}bin.ml \PYGZhy{}o my\PYGZbs{}\PYGZus{}toplevel.native
\end{sphinxVerbatim}

and similarly for other plugins.


\subsection{Building a Coq project with coq\_makefile}
\label{\detokenize{practical-tools/utilities:building-a-coq-project-with-coq-makefile}}
The majority of \DUrole{smallcaps}{Coq} projects are very similar: a collection of \sphinxcode{\sphinxupquote{.v}}
files and eventually some \sphinxcode{\sphinxupquote{.ml}} ones (a \DUrole{smallcaps}{Coq} plugin). The main piece of
metadata needed in order to build the project are the command line
options to \sphinxcode{\sphinxupquote{coqc}} (e.g. \sphinxcode{\sphinxupquote{-R}}, \sphinxcode{\sphinxupquote{-I}}, see also: section
{\hyperref[\detokenize{practical-tools/coq-commands:command-line-options}]{\sphinxcrossref{\DUrole{std,std-ref}{By command line options}}}}). Collecting the list of files and options is the job
of the \sphinxcode{\sphinxupquote{\_CoqProject}} file.

A simple example of a \sphinxcode{\sphinxupquote{\_CoqProject}} file follows:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZhy{}R theories/ MyCode
theories/foo.v
theories/bar.v
\PYGZhy{}I src/
src/baz.ml4
src/bazaux.ml
src/qux\PYGZus{}plugin.mlpack
\end{sphinxVerbatim}

Currently, both \DUrole{smallcaps}{CoqIDE} and Proof-General (version ≥ \sphinxcode{\sphinxupquote{4.3pre}})
understand \sphinxcode{\sphinxupquote{\_CoqProject}} files and invoke \DUrole{smallcaps}{Coq} with the desired options.

The \sphinxcode{\sphinxupquote{coq\_makefile}} utility can be used to set up a build infrastructure
for the \DUrole{smallcaps}{Coq} project based on makefiles. The recommended way of
invoking \sphinxcode{\sphinxupquote{coq\_makefile}} is the following one:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
coq\PYGZus{}makefile \PYGZhy{}f \PYGZus{}CoqProject \PYGZhy{}o CoqMakefile
\end{sphinxVerbatim}

Such command generates the following files:
\begin{description}
\item[{CoqMakefile}] \leavevmode
is a generic makefile for \sphinxcode{\sphinxupquote{GNU Make}} that provides
targets to build the project (both \sphinxcode{\sphinxupquote{.v}} and \sphinxcode{\sphinxupquote{.ml*}} files), to install it
system-wide in the \sphinxcode{\sphinxupquote{coq-contrib}} directory (i.e. where \DUrole{smallcaps}{Coq} is installed)
as well as to invoke coqdoc to generate HTML documentation.

\item[{CoqMakefile.conf}] \leavevmode
contains make variables assignments that reflect
the contents of the \sphinxcode{\sphinxupquote{\_CoqProject}} file as well as the path relevant to
\DUrole{smallcaps}{Coq}.

\end{description}

An optional file \sphinxcode{\sphinxupquote{CoqMakefile.local}} can be provided by the user in order to
extend \sphinxcode{\sphinxupquote{CoqMakefile}}. In particular one can declare custom actions to be
performed before or after the build process. Similarly one can customize the
install target or even provide new targets. Extension points are documented in
paragraph {\hyperref[\detokenize{practical-tools/utilities:coqmakefilelocal}]{\sphinxcrossref{\DUrole{std,std-ref}{CoqMakefile.local}}}}.

The extensions of the files listed in \sphinxcode{\sphinxupquote{\_CoqProject}} is used in order to
decide how to build them. In particular:
\begin{itemize}
\item {} 
\DUrole{smallcaps}{Coq} files must use the \sphinxcode{\sphinxupquote{.v}} extension

\item {} 
\DUrole{smallcaps}{OCaml} files must use the \sphinxcode{\sphinxupquote{.ml}} or \sphinxcode{\sphinxupquote{.mli}} extension

\item {} 
\DUrole{smallcaps}{OCaml} files that require pre processing for syntax
extensions (like \sphinxcode{\sphinxupquote{VERNAC EXTEND}}) must use the \sphinxcode{\sphinxupquote{.ml4}} extension

\item {} 
In order to generate a plugin one has to list all \DUrole{smallcaps}{OCaml}
modules (i.e. \sphinxcode{\sphinxupquote{Baz}} for \sphinxcode{\sphinxupquote{baz.ml}}) in a \sphinxcode{\sphinxupquote{.mlpack}} file (or \sphinxcode{\sphinxupquote{.mllib}}
file).

\end{itemize}

The use of \sphinxcode{\sphinxupquote{.mlpack}} files has to be preferred over \sphinxcode{\sphinxupquote{.mllib}} files,
since it results in a “packed” plugin: All auxiliary modules (as
\sphinxcode{\sphinxupquote{Baz}} and \sphinxcode{\sphinxupquote{Bazaux}}) are hidden inside the plugin’s "namespace"
(\sphinxcode{\sphinxupquote{Qux\_plugin}}). This reduces the chances of begin unable to load two
distinct plugins because of a clash in their auxiliary module names.


\subsubsection{CoqMakefile.local}
\label{\detokenize{practical-tools/utilities:coqmakefile-local}}\label{\detokenize{practical-tools/utilities:coqmakefilelocal}}
The optional file \sphinxcode{\sphinxupquote{CoqMakefile.local}} is included by the generated
file \sphinxcode{\sphinxupquote{CoqMakefile}}. It can contain two kinds of directives.

\sphinxstylestrong{Variable assignment}

The variable must belong to the variables listed in the \sphinxcode{\sphinxupquote{Parameters}}
section of the generated makefile.
Here we describe only few of them.
\begin{quote}\begin{description}
\item[{CAMLPKGS}] \leavevmode
can be used to specify third party findlib packages, and is
passed to the OCaml compiler on building or linking of modules. Eg:
\sphinxcode{\sphinxupquote{-package yojson}}.

\item[{CAMLFLAGS}] \leavevmode
can be used to specify additional flags to the \DUrole{smallcaps}{OCaml}
compiler, like \sphinxcode{\sphinxupquote{-bin-annot}} or \sphinxcode{\sphinxupquote{-w}}....

\item[{COQC, COQDEP, COQDOC}] \leavevmode
can be set in order to use alternative binaries
(e.g. wrappers)

\item[{COQ\_SRC\_SUBDIRS}] \leavevmode
can be extended by including other paths in which \sphinxcode{\sphinxupquote{*.cm*}} files
are searched. For example \sphinxcode{\sphinxupquote{COQ\_SRC\_SUBDIRS+=user-contrib/Unicoq}}
lets you build a plugin containing OCaml code that depends on the
OCaml code of \sphinxcode{\sphinxupquote{Unicoq}}.

\end{description}\end{quote}

\sphinxstylestrong{Rule extension}

The following makefile rules can be extended.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
pre\PYGZhy{}all::
        echo \PYGZdq{}This line is print before making the all target\PYGZdq{}
install\PYGZhy{}extra::
        cp ThisExtraFile /there/it/goes
\end{sphinxVerbatim}
\end{sphinxadmonition}
\begin{description}
\item[{\sphinxcode{\sphinxupquote{pre-all::}}}] \leavevmode
run before the \sphinxcode{\sphinxupquote{all}} target. One can use this to configure
the project, or initialize sub modules or check dependencies are met.

\item[{\sphinxcode{\sphinxupquote{post-all::}}}] \leavevmode
run after the \sphinxcode{\sphinxupquote{all}} target. One can use this to run a test
suite, or compile extracted code.

\item[{\sphinxcode{\sphinxupquote{install-extra::}}}] \leavevmode
run after \sphinxcode{\sphinxupquote{install}}. One can use this to install extra files.

\item[{\sphinxcode{\sphinxupquote{install-doc::}}}] \leavevmode
One can use this to install extra doc.

\item[{\sphinxcode{\sphinxupquote{uninstall::}}}] \leavevmode


\item[{\sphinxcode{\sphinxupquote{uninstall-doc::}}}] \leavevmode


\item[{\sphinxcode{\sphinxupquote{clean::}}}] \leavevmode


\item[{\sphinxcode{\sphinxupquote{cleanall::}}}] \leavevmode


\item[{\sphinxcode{\sphinxupquote{archclean::}}}] \leavevmode


\item[{\sphinxcode{\sphinxupquote{merlin-hook::}}}] \leavevmode
One can append lines to the generated \sphinxcode{\sphinxupquote{.merlin}} file extending this
target.

\end{description}


\subsubsection{Timing targets and performance testing}
\label{\detokenize{practical-tools/utilities:timing-targets-and-performance-testing}}
The generated \sphinxcode{\sphinxupquote{Makefile}} supports the generation of two kinds of timing
data: per-file build-times, and per-line times for an individual file.

The following targets and Makefile variables allow collection of per-
file timing data:
\begin{itemize}
\item {} \begin{description}
\item[{\sphinxcode{\sphinxupquote{TIMED=1}}}] \leavevmode
passing this variable will cause \sphinxcode{\sphinxupquote{make}} to emit a line
describing the user-space build-time and peak memory usage for each
file built.

\begin{sphinxadmonition}{note}{Note:}
On \sphinxcode{\sphinxupquote{Mac OS}}, this works best if you’ve installed \sphinxcode{\sphinxupquote{gnu-time}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

For example, the output of \sphinxcode{\sphinxupquote{make TIMED=1}} may look like
this:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
COQDEP Fast.v
COQDEP Slow.v
COQC Slow.v
Slow (user: 0.34 mem: 395448 ko)
COQC Fast.v
Fast (user: 0.01 mem: 45184 ko)
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{description}

\item {} \begin{description}
\item[{\sphinxcode{\sphinxupquote{pretty-timed}}}] \leavevmode
this target stores the output of \sphinxcode{\sphinxupquote{make TIMED=1}} into
\sphinxcode{\sphinxupquote{time-of-build.log}}, and displays a table of the times, sorted from
slowest to fastest, which is also stored in \sphinxcode{\sphinxupquote{time-of-build-pretty.log}}.
If you want to construct the \sphinxcode{\sphinxupquote{log}} for targets other than the default
one, you can pass them via the variable \sphinxcode{\sphinxupquote{TGTS}}, e.g., \sphinxcode{\sphinxupquote{make pretty-timed
TGTS="a.vo b.vo"}}.

\begin{sphinxadmonition}{note}{Note:}
This target will \sphinxstyleemphasis{append} to the timing log; if you want a
fresh start, you must remove the \sphinxcode{\sphinxupquote{filetime-of-build.log}} or
\sphinxcode{\sphinxupquote{run make cleanall}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

For example, the output of \sphinxcode{\sphinxupquote{make pretty-timed}} may look like this:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
COQDEP Fast.v
COQDEP Slow.v
COQC Slow.v
Slow (user: 0.36 mem: 393912 ko)
COQC Fast.v
Fast (user: 0.05 mem: 45992 ko)
Time     \textbar{} File Name
\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}
0m00.41s \textbar{} Total
\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}
0m00.36s \textbar{} Slow
0m00.05s \textbar{} Fast
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{description}

\item {} \begin{description}
\item[{\sphinxcode{\sphinxupquote{print-pretty-timed-diff}}}] \leavevmode
this target builds a table of timing changes between two compilations; run
\sphinxcode{\sphinxupquote{make make-pretty-timed-before}} to build the log of the “before” times,
and run \sphinxcode{\sphinxupquote{make make-pretty-timed-after}} to build the log of the “after”
times. The table is printed on the command line, and stored in
\sphinxcode{\sphinxupquote{time-of-build-both.log}}. This target is most useful for profiling the
difference between two commits in a repository.

\begin{sphinxadmonition}{note}{Note:}
This target requires \sphinxcode{\sphinxupquote{python}} to build the table.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
The \sphinxcode{\sphinxupquote{make-pretty-timed-before}} and \sphinxcode{\sphinxupquote{make-pretty-timed-after}} targets will
\sphinxstyleemphasis{append} to the timing log; if you want a fresh start, you must remove
the files \sphinxcode{\sphinxupquote{time-of-build-before.log}} and \sphinxcode{\sphinxupquote{time-of-build-after.log}} or run
\sphinxcode{\sphinxupquote{make cleanall}} \sphinxstyleemphasis{before} building either the “before” or “after”
targets.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
The table will be sorted first by absolute time
differences rounded towards zero to a whole-number of seconds, then by
times in the “after” column, and finally lexicographically by file
name. This will put the biggest changes in either direction first, and
will prefer sorting by build-time over subsecond changes in build time
(which are frequently noise); lexicographic sorting forces an order on
files which take effectively no time to compile.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

For example, the output table from
\sphinxcode{\sphinxupquote{make print-pretty-timed-diff}} may look like this:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
After    \textbar{} File Name \textbar{} Before   \textbar{}\textbar{} Change    \textbar{} \PYGZpc{} Change
\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}
0m00.39s \textbar{} Total     \textbar{} 0m00.35s \textbar{}\textbar{} +0m00.03s \textbar{} +11.42\PYGZpc{}
\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}
0m00.37s \textbar{} Slow      \textbar{} 0m00.01s \textbar{}\textbar{} +0m00.36s \textbar{} +3600.00\PYGZpc{}
0m00.02s \textbar{} Fast      \textbar{} 0m00.34s \textbar{}\textbar{} \PYGZhy{}0m00.32s \textbar{} \PYGZhy{}94.11\PYGZpc{}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{description}

\end{itemize}

The following targets and \sphinxcode{\sphinxupquote{Makefile}} variables allow collection of per-
line timing data:
\begin{itemize}
\item {} \begin{description}
\item[{\sphinxcode{\sphinxupquote{TIMING=1}}}] \leavevmode
passing this variable will cause \sphinxcode{\sphinxupquote{make}} to use \sphinxcode{\sphinxupquote{coqc -time}} to
write to a \sphinxcode{\sphinxupquote{.v.timing}} file for each \sphinxcode{\sphinxupquote{.v}} file compiled, which contains
line-by-line timing information.

\begin{sphinxadmonition}{note}{Example}

For example, running \sphinxcode{\sphinxupquote{make all TIMING=1}} may result in a file like this:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Chars 0 \PYGZhy{} 26 [Require\PYGZti{}Coq.ZArith.BinInt.] 0.157 secs (0.128u,0.028s)
Chars 27 \PYGZhy{} 68 [Declare\PYGZti{}Reduction\PYGZti{}comp\PYGZti{}:=\PYGZti{}vm\PYGZus{}c...] 0. secs (0.u,0.s)
Chars 69 \PYGZhy{} 162 [Definition\PYGZti{}foo0\PYGZti{}:=\PYGZti{}Eval\PYGZti{}comp\PYGZti{}i...] 0.153 secs (0.136u,0.019s)
Chars 163 \PYGZhy{} 208 [Definition\PYGZti{}foo1\PYGZti{}:=\PYGZti{}Eval\PYGZti{}comp\PYGZti{}i...] 0.239 secs (0.236u,0.s)
\end{sphinxVerbatim}
\end{sphinxadmonition}

\end{description}

\item {} 
\sphinxcode{\sphinxupquote{print-pretty-single-time-diff}}
\begin{quote}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
print\PYGZhy{}pretty\PYGZhy{}single\PYGZhy{}time\PYGZhy{}diff BEFORE=path/to/file.v.before\PYGZhy{}timing AFTER=path/to/file.v.after\PYGZhy{}timing
\end{sphinxVerbatim}

this target will make a sorted table of the per-line timing differences
between the timing logs in the \sphinxcode{\sphinxupquote{BEFORE}} and \sphinxcode{\sphinxupquote{AFTER}} files, display it, and
save it to the file specified by the \sphinxcode{\sphinxupquote{TIME\_OF\_PRETTY\_BUILD\_FILE}} variable,
which defaults to \sphinxcode{\sphinxupquote{time-of-build-pretty.log}}.
To generate the \sphinxcode{\sphinxupquote{.v.before-timing}} or \sphinxcode{\sphinxupquote{.v.after-timing}} files, you should
pass  \sphinxcode{\sphinxupquote{TIMING=before}} or \sphinxcode{\sphinxupquote{TIMING=after}} rather than \sphinxcode{\sphinxupquote{TIMING=1}}.

\begin{sphinxadmonition}{note}{Note:}
The sorting used here is the same as in the \sphinxcode{\sphinxupquote{print-pretty-timed -diff}} target.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
This target requires python to build the table.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

For example, running  \sphinxcode{\sphinxupquote{print-pretty-single-time-diff}} might give a table like this:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
After     \textbar{} Code                                                \textbar{} Before    \textbar{}\textbar{} Change    \textbar{} \PYGZpc{} Change
\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}
0m00.50s  \textbar{} Total                                               \textbar{} 0m04.17s  \textbar{}\textbar{} \PYGZhy{}0m03.66s \textbar{} \PYGZhy{}87.96\PYGZpc{}
\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}\PYGZhy{}
0m00.145s \textbar{} Chars 069 \PYGZhy{} 162 [Definition\PYGZti{}foo0\PYGZti{}:=\PYGZti{}Eval\PYGZti{}comp\PYGZti{}i...] \textbar{} 0m00.192s \textbar{}\textbar{} \PYGZhy{}0m00.04s \textbar{} \PYGZhy{}24.47\PYGZpc{}
0m00.126s \textbar{} Chars 000 \PYGZhy{} 026 [Require\PYGZti{}Coq.ZArith.BinInt.]        \textbar{} 0m00.143s \textbar{}\textbar{} \PYGZhy{}0m00.01s \textbar{} \PYGZhy{}11.88\PYGZpc{}
   N/A    \textbar{} Chars 027 \PYGZhy{} 068 [Declare\PYGZti{}Reduction\PYGZti{}comp\PYGZti{}:=\PYGZti{}nati...] \textbar{} 0m00.s    \textbar{}\textbar{} +0m00.00s \textbar{} N/A
0m00.s    \textbar{} Chars 027 \PYGZhy{} 068 [Declare\PYGZti{}Reduction\PYGZti{}comp\PYGZti{}:=\PYGZti{}vm\PYGZus{}c...] \textbar{}    N/A    \textbar{}\textbar{} +0m00.00s \textbar{} N/A
0m00.231s \textbar{} Chars 163 \PYGZhy{} 208 [Definition\PYGZti{}foo1\PYGZti{}:=\PYGZti{}Eval\PYGZti{}comp\PYGZti{}i...] \textbar{} 0m03.836s \textbar{}\textbar{} \PYGZhy{}0m03.60s \textbar{} \PYGZhy{}93.97\PYGZpc{}
\end{sphinxVerbatim}
\end{sphinxadmonition}
\end{quote}

\item {} \begin{description}
\item[{\sphinxcode{\sphinxupquote{all.timing.diff}}, \sphinxcode{\sphinxupquote{path/to/file.v.timing.diff}}}] \leavevmode
The \sphinxcode{\sphinxupquote{path/to/file.v.timing.diff}} target will make a \sphinxcode{\sphinxupquote{.v.timing.diff}} file for
the corresponding \sphinxcode{\sphinxupquote{.v}} file, with a table as would be generated by
the \sphinxcode{\sphinxupquote{print-pretty-single-time-diff}} target; it depends on having already
made the corresponding \sphinxcode{\sphinxupquote{.v.before-timing}} and \sphinxcode{\sphinxupquote{.v.after-timing}} files,
which can be made by passing \sphinxcode{\sphinxupquote{TIMING=before}} and \sphinxcode{\sphinxupquote{TIMING=after}}.
The  \sphinxcode{\sphinxupquote{all.timing.diff}} target will make such timing difference files for
all of the \sphinxcode{\sphinxupquote{.v}} files that the \sphinxcode{\sphinxupquote{Makefile}} knows about. It will fail if
some \sphinxcode{\sphinxupquote{.v.before-timing}} or \sphinxcode{\sphinxupquote{.v.after-timing}} files don’t exist.

\begin{sphinxadmonition}{note}{Note:}
This target requires python to build the table.
\end{sphinxadmonition}

\end{description}

\end{itemize}


\subsubsection{Reusing/extending the generated Makefile}
\label{\detokenize{practical-tools/utilities:reusing-extending-the-generated-makefile}}
Including the generated makefile with an include directive is
discouraged. The contents of this file, including variable names and
status of rules shall change in the future. Users are advised to
include \sphinxcode{\sphinxupquote{Makefile.conf}} or call a target of the generated Makefile as in
\sphinxcode{\sphinxupquote{make -f Makefile target}} from another Makefile.

One way to get access to all targets of the generated \sphinxcode{\sphinxupquote{CoqMakefile}} is to
have a generic target for invoking unknown targets.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZsh{} KNOWNTARGETS will not be passed along to CoqMakefile
KNOWNTARGETS := CoqMakefile extra\PYGZhy{}stuff extra\PYGZhy{}stuff2
\PYGZsh{} KNOWNFILES will not get implicit targets from the final rule, and so
\PYGZsh{} depending on them won\PYGZsq{}t invoke the submake
\PYGZsh{} Warning: These files get declared as PHONY, so any targets depending
\PYGZsh{} on them always get rebuilt
KNOWNFILES   := Makefile \PYGZus{}CoqProject

.DEFAULT\PYGZus{}GOAL := invoke\PYGZhy{}coqmakefile

CoqMakefile: Makefile \PYGZus{}CoqProject
        \PYGZdl{}(COQBIN)coq\PYGZus{}makefile \PYGZhy{}f \PYGZus{}CoqProject \PYGZhy{}o CoqMakefile

invoke\PYGZhy{}coqmakefile: CoqMakefile
        \PYGZdl{}(MAKE) \PYGZhy{}\PYGZhy{}no\PYGZhy{}print\PYGZhy{}directory \PYGZhy{}f CoqMakefile \PYGZdl{}(filter\PYGZhy{}out \PYGZdl{}(KNOWNTARGETS),\PYGZdl{}(MAKECMDGOALS))

.PHONY: invoke\PYGZhy{}coqmakefile \PYGZdl{}(KNOWNFILES)

\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}
\PYGZsh{}\PYGZsh{}                      Your targets here                         \PYGZsh{}\PYGZsh{}
\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}\PYGZsh{}

\PYGZsh{} This should be the last rule, to handle any targets not declared above
\PYGZpc{}: invoke\PYGZhy{}coqmakefile
        @true
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Building a subset of the targets with \sphinxstyleliteralintitle{\sphinxupquote{-j}}}
\label{\detokenize{practical-tools/utilities:building-a-subset-of-the-targets-with-j}}
To build, say, two targets foo.vo and bar.vo in parallel one can use
\sphinxcode{\sphinxupquote{make only TGTS="foo.vo bar.vo" -j}}.

\begin{sphinxadmonition}{note}{Note:}
\sphinxcode{\sphinxupquote{make foo.vo bar.vo -j}} has a different meaning for the make
utility, in particular it may build a shared prerequisite twice.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
For users of coq\_makefile with version \textless{} 8.7
\begin{itemize}
\item {} 
Support for "subdirectory" is deprecated. To perform actions before
or after the build (like invoking \sphinxcode{\sphinxupquote{make}} on a subdirectory) one can hook
in pre-all and post-all extension points.

\item {} 
\sphinxcode{\sphinxupquote{-extra-phony}} and \sphinxcode{\sphinxupquote{-extra}} are deprecated. To provide additional target
(\sphinxcode{\sphinxupquote{.PHONY}} or not) please use \sphinxcode{\sphinxupquote{CoqMakefile.local}}.

\end{itemize}
\end{sphinxadmonition}


\subsection{Module dependencies}
\label{\detokenize{practical-tools/utilities:module-dependencies}}
In order to compute module dependencies (so to use \sphinxcode{\sphinxupquote{make}}), \DUrole{smallcaps}{Coq} comes
with an appropriate tool, \sphinxcode{\sphinxupquote{coqdep}}.

\sphinxcode{\sphinxupquote{coqdep}} computes inter-module dependencies for \DUrole{smallcaps}{Coq} and \DUrole{smallcaps}{OCaml}
programs, and prints the dependencies on the standard output in a
format readable by make. When a directory is given as argument, it is
recursively looked at.

Dependencies of \DUrole{smallcaps}{Coq} modules are computed by looking at \sphinxcode{\sphinxupquote{Require}}
commands (\sphinxcode{\sphinxupquote{Require}}, \sphinxcode{\sphinxupquote{Require Export}}, \sphinxcode{\sphinxupquote{Require Import}}), but also at the
command \sphinxcode{\sphinxupquote{Declare ML Module}}.

Dependencies of \DUrole{smallcaps}{OCaml} modules are computed by looking at
\sphinxtitleref{open} commands and the dot notation \sphinxstyleemphasis{module.value}. However, this is
done approximately and you are advised to use \sphinxcode{\sphinxupquote{ocamldep}} instead for the
\DUrole{smallcaps}{OCaml} module dependencies.

See the man page of \sphinxcode{\sphinxupquote{coqdep}} for more details and options.

The build infrastructure generated by \sphinxcode{\sphinxupquote{coq\_makefile}} uses \sphinxcode{\sphinxupquote{coqdep}} to
automatically compute the dependencies among the files part of the
project.


\subsection{Documenting Coq files with coqdoc}
\label{\detokenize{practical-tools/utilities:documenting-coq-files-with-coqdoc}}\label{\detokenize{practical-tools/utilities:coqdoc}}
coqdoc is a documentation tool for the proof assistant \DUrole{smallcaps}{Coq}, similar to
\sphinxcode{\sphinxupquote{javadoc}} or \sphinxcode{\sphinxupquote{ocamldoc}}. The task of coqdoc is
\begin{enumerate}
\def\theenumi{\arabic{enumi}}
\def\labelenumi{\theenumi .}
\makeatletter\def\p@enumii{\p@enumi \theenumi .}\makeatother
\item {} 
to produce a nice \DUrole{smallcaps}{LaTeX} and/or HTML document from \DUrole{smallcaps}{Coq} source files,
readable for a human and not only for the proof assistant;

\item {} 
to help the user navigate his own (or third-party) sources.

\end{enumerate}


\subsubsection{Principles}
\label{\detokenize{practical-tools/utilities:principles}}
Documentation is inserted into \DUrole{smallcaps}{Coq} files as \sphinxstyleemphasis{special comments}. Thus
your files will compile as usual, whether you use coqdoc or not. coqdoc
presupposes that the given \DUrole{smallcaps}{Coq} files are well-formed (at least
lexically). Documentation starts with \sphinxcode{\sphinxupquote{(**}}, followed by a space, and
ends with \sphinxcode{\sphinxupquote{*)}}. The documentation format is inspired by Todd
A. Coram’s \sphinxstyleemphasis{Almost Free Text (AFT)} tool: it is mainly \sphinxcode{\sphinxupquote{ASCII}} text with
some syntax-light controls, described below. coqdoc is robust: it
shouldn’t fail, whatever the input is. But remember: “garbage in,
garbage out”.


\paragraph{Coq material inside documentation.}
\label{\detokenize{practical-tools/utilities:coq-material-inside-documentation}}
\DUrole{smallcaps}{Coq} material is quoted between the delimiters \sphinxcode{\sphinxupquote{{[}}} and \sphinxcode{\sphinxupquote{{]}}}. Square brackets
may be nested, the inner ones being understood as being part of the
quoted code (thus you can quote a term like \sphinxcode{\sphinxupquote{fun x =\textgreater{} u}} by writing  \sphinxcode{\sphinxupquote{{[}fun
x =\textgreater{} u{]}}}). Inside quotations, the code is pretty-printed in the same
way as it is in code parts.

Preformatted vernacular is enclosed by \sphinxcode{\sphinxupquote{{[}{[}}} and \sphinxcode{\sphinxupquote{{]}{]}}}. The former must be
followed by a newline and the latter must follow a newline.


\paragraph{Pretty-printing.}
\label{\detokenize{practical-tools/utilities:pretty-printing}}
coqdoc uses different faces for identifiers and keywords. The pretty-
printing of \DUrole{smallcaps}{Coq} tokens (identifiers or symbols) can be controlled
using one of the following commands:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
(** printing  *token* \PYGZpc{}...LATEX...\PYGZpc{} \PYGZsh{}...html...\PYGZsh{} *)
\end{sphinxVerbatim}

or

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
(** printing  *token* \PYGZdl{}...LATEX math...\PYGZdl{} \PYGZsh{}...html...\PYGZsh{} *)
\end{sphinxVerbatim}

It gives the \DUrole{smallcaps}{LaTeX} and HTML texts to be produced for the given \DUrole{smallcaps}{Coq}
token. Either the \DUrole{smallcaps}{LaTeX} or the HTML rule may be omitted, causing the
default pretty-printing to be used for this token.

The printing for one token can be removed with

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
(** remove printing  *token* *)
\end{sphinxVerbatim}

Initially, the pretty-printing table contains the following mapping:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|T|T|T|T|T|}
\hline

\sphinxtitleref{-\textgreater{}}
&
\(\rightarrow\)
&&
\sphinxtitleref{\textless{}-}
&
←
&&
\sphinxtitleref{*}
&
×
\\
\hline
\sphinxtitleref{\textless{}=}
&
≤
&&
\sphinxtitleref{\textgreater{}=}
&
≥
&&
\sphinxtitleref{=\textgreater{}}
&
⇒
\\
\hline
\sphinxtitleref{\textless{}\textgreater{}}
&
≠
&&
\sphinxtitleref{\textless{}-\textgreater{}}
&
↔
&&
\sphinxtitleref{\textbar{}-}
&
⊢
\\
\hline
\sphinxtitleref{\textbackslash{}/}
&
∨
&&
\sphinxtitleref{/\textbackslash{}}
&
∧
&&
\sphinxtitleref{\textasciitilde{}}
&
¬
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

Any of these can be overwritten or suppressed using the printing
commands.

\begin{sphinxadmonition}{note}{Note:}
The recognition of tokens is done by a (\sphinxcode{\sphinxupquote{ocaml}}) lex
automaton and thus applies the longest-match rule. For instance, \sphinxtitleref{-\textgreater{}\textasciitilde{}}
is recognized as a single token, where \DUrole{smallcaps}{Coq} sees two tokens. It is the
responsibility of the user to insert space between tokens \sphinxstyleemphasis{or} to give
pretty-printing rules for the possible combinations, e.g.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
(** printing \PYGZhy{}\PYGZgt{}\PYGZti{} \PYGZpc{}\PYGZbs{}ensuremath\PYGZob{}\PYGZbs{}rightarrow\PYGZbs{}lnot\PYGZcb{}\PYGZpc{} *)
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Sections}
\label{\detokenize{practical-tools/utilities:sections}}
Sections are introduced by 1 to 4 asterisks at the beginning of a line
followed by a space and the title of the section. One asterisk is a section,
two a subsection, etc.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
(** * Well\PYGZhy{}founded relations

    In this section, we introduce...  *)
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Lists.}
\label{\detokenize{practical-tools/utilities:lists}}
List items are introduced by a leading dash. coqdoc uses whitespace to
determine the depth of a new list item and which text belongs in which
list items. A list ends when a line of text starts at or before the
level of indenting of the list’s dash. A list item’s dash must always
be the first non-space character on its line (so, in particular, a
list can not begin on the first line of a comment - start it on the
second line instead).

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
We go by induction on [n]:
\PYGZhy{} If [n] is 0...
\PYGZhy{} If [n] is [S n\PYGZsq{}] we require...

  two paragraphs of reasoning, and two subcases:

  \PYGZhy{} In the first case...
  \PYGZhy{} In the second case...

So the theorem holds.
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Rules.}
\label{\detokenize{practical-tools/utilities:rules}}
More than 4 leading dashes produce a horizontal rule.


\paragraph{Emphasis.}
\label{\detokenize{practical-tools/utilities:emphasis}}
Text can be italicized by enclosing it in underscores. A non-identifier
character must precede the leading underscore and follow the trailing
underscore, so that uses of underscores in names aren’t mistaken for
emphasis. Usually, these are spaces or punctuation.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
This sentence contains some \PYGZus{}emphasized text\PYGZus{}.
\end{sphinxVerbatim}


\paragraph{Escaping to LaTeX and HTML.}
\label{\detokenize{practical-tools/utilities:escaping-to-latex-and-html}}
Pure \DUrole{smallcaps}{LaTeX} or HTML material can be inserted using the following
escape sequences:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{\$...LATEX stuff...\$}} inserts some \DUrole{smallcaps}{LaTeX} material in math mode.
Simply discarded in HTML output.

\item {} 
\sphinxcode{\sphinxupquote{\%...LATEX stuff...\%}} inserts some \DUrole{smallcaps}{LaTeX} material. Simply
discarded in HTML output.

\item {} 
\sphinxcode{\sphinxupquote{\#...HTML stuff...\#}} inserts some HTML material. Simply discarded in
\DUrole{smallcaps}{LaTeX} output.

\end{itemize}

\begin{sphinxadmonition}{note}{Note:}
to simply output the characters \sphinxcode{\sphinxupquote{\$}}, \sphinxcode{\sphinxupquote{\%}} and \sphinxcode{\sphinxupquote{\#}} and escaping
their escaping role, these characters must be doubled.
\end{sphinxadmonition}


\paragraph{Verbatim}
\label{\detokenize{practical-tools/utilities:verbatim}}
Verbatim material is introduced by a leading \sphinxcode{\sphinxupquote{\textless{}\textless{}}} and closed by \sphinxcode{\sphinxupquote{\textgreater{}\textgreater{}}}
at the beginning of a line.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Here is the corresponding caml code:
\PYGZlt{}\PYGZlt{}
  let rec fact n =
    if n \PYGZlt{}= 1 then 1 else n * fact (n\PYGZhy{}1)
\PYGZgt{}\PYGZgt{}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\paragraph{Hyperlinks}
\label{\detokenize{practical-tools/utilities:hyperlinks}}
Hyperlinks can be inserted into the HTML output, so that any
identifier is linked to the place of its definition.

\sphinxcode{\sphinxupquote{coqc file.v}} automatically dumps localization information in
\sphinxcode{\sphinxupquote{file.glob}} or appends it to a file specified using the option \sphinxcode{\sphinxupquote{-{-}dump-glob
file}}. Take care of erasing this global file, if any, when starting
the whole compilation process.

Then invoke coqdoc or \sphinxcode{\sphinxupquote{coqdoc -{-}glob-from file}} to tell coqdoc to look
for name resolutions in the file \sphinxcode{\sphinxupquote{file}} (it will look in \sphinxcode{\sphinxupquote{file.glob}}
by default).

Identifiers from the \DUrole{smallcaps}{Coq} standard library are linked to the Coq website
\sphinxurl{http://coq.inria.fr/library/}. This behavior can be changed
using command line options \sphinxcode{\sphinxupquote{-{-}no-externals}} and \sphinxcode{\sphinxupquote{-{-}coqlib}}; see below.


\paragraph{Hiding / Showing parts of the source.}
\label{\detokenize{practical-tools/utilities:hiding-showing-parts-of-the-source}}
Some parts of the source can be hidden using command line options \sphinxcode{\sphinxupquote{-g}}
and \sphinxcode{\sphinxupquote{-l}} (see below), or using such comments:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
(* begin hide *)
 *some Coq material*
(* end hide *)
\end{sphinxVerbatim}

Conversely, some parts of the source which would be hidden can be
shown using such comments:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
(* begin show *)
 *some Coq material*
(* end show *)
\end{sphinxVerbatim}

The latter cannot be used around some inner parts of a proof, but can
be used around a whole proof.


\subsubsection{Usage}
\label{\detokenize{practical-tools/utilities:usage}}
coqdoc is invoked on a shell command line as follows:
\sphinxcode{\sphinxupquote{coqdoc \textless{}options and files\textgreater{}}}.
Any command line argument which is not an option is considered to be a
file (even if it starts with a \sphinxcode{\sphinxupquote{-}}). \DUrole{smallcaps}{Coq} files are identified by the
suffixes \sphinxcode{\sphinxupquote{.v}} and \sphinxcode{\sphinxupquote{.g}} and \DUrole{smallcaps}{LaTeX} files by the suffix \sphinxcode{\sphinxupquote{.tex}}.
\begin{quote}\begin{description}
\item[{HTML output}] \leavevmode
This is the default output format. One HTML file is created for
each \DUrole{smallcaps}{Coq} file given on the command line, together with a file
\sphinxcode{\sphinxupquote{index.html}} (unless \sphinxcode{\sphinxupquote{option-no-index is passed}}). The HTML pages use a
style sheet named \sphinxcode{\sphinxupquote{style.css}}. Such a file is distributed with coqdoc.

\item[{\DUrole{smallcaps}{LaTeX} output}] \leavevmode
A single \DUrole{smallcaps}{LaTeX} file is created, on standard
output. It can be redirected to a file using the option \sphinxcode{\sphinxupquote{-o}}. The order of
files on the command line is kept in the final document. \DUrole{smallcaps}{LaTeX}
files given on the command line are copied ‘as is’ in the final
document . DVI and PostScript can be produced directly with the
options \sphinxcode{\sphinxupquote{-dvi}} and \sphinxcode{\sphinxupquote{-ps}} respectively.

\item[{TEXmacs output}] \leavevmode
To translate the input files to TEXmacs format,
to be used by the TEXmacs \DUrole{smallcaps}{Coq} interface.

\end{description}\end{quote}


\paragraph{Command line options}
\label{\detokenize{practical-tools/utilities:command-line-options}}
\sphinxstylestrong{Overall options}
\begin{quote}
\begin{quote}\begin{description}
\item[{--HTML}] \leavevmode
Select a HTML output.

\item[{--\DUrole{smallcaps}{LaTeX}}] \leavevmode
Select a \DUrole{smallcaps}{LaTeX} output.

\item[{--dvi}] \leavevmode
Select a DVI output.

\item[{--ps}] \leavevmode
Select a PostScript output.

\item[{--texmacs}] \leavevmode
Select a TEXmacs output.

\item[{--stdout}] \leavevmode
Write output to stdout.

\item[{-o file, --output file}] \leavevmode
Redirect the output into the file ‘file’
(meaningless with \sphinxcode{\sphinxupquote{-html}}).

\item[{-d dir, --directory dir}] \leavevmode
Output files into directory ‘dir’ instead of
the current directory (option \sphinxcode{\sphinxupquote{-d}} does not change the filename specified
with the option \sphinxcode{\sphinxupquote{-o}}, if any).

\item[{--body-only}] \leavevmode
Suppress the header and trailer of the final document.
Thus, you can insert the resulting document into a larger one.

\item[{-p string, --preamble string}] \leavevmode
Insert some material in the \DUrole{smallcaps}{LaTeX}
preamble, right before \sphinxcode{\sphinxupquote{\textbackslash{}begin\{document\}}} (meaningless with \sphinxcode{\sphinxupquote{-html}}).

\item[{--vernac-file file,--tex-file file}] \leavevmode
Considers the file ‘file’
respectively as a \sphinxcode{\sphinxupquote{.v}} (or \sphinxcode{\sphinxupquote{.g}}) file or a \sphinxcode{\sphinxupquote{.tex}} file.

\item[{--files-from file}] \leavevmode
Read filenames to be processed from the file ‘file’ as if
they were given on the command line. Useful for program sources split
up into several directories.

\item[{-q, --quiet}] \leavevmode
Be quiet. Do not print anything except errors.

\item[{-h, --help}] \leavevmode
Give a short summary of the options and exit.

\item[{-v, --version}] \leavevmode
Print the version and exit.

\end{description}\end{quote}
\end{quote}

\sphinxstylestrong{Index options}
\begin{quote}

The default behavior is to build an index, for the HTML output only,
into \sphinxcode{\sphinxupquote{index.html}}.
\begin{quote}\begin{description}
\item[{--no-index}] \leavevmode
Do not output the index.

\item[{--multi-index}] \leavevmode
Generate one page for each category and each letter in
the index, together with a top page \sphinxcode{\sphinxupquote{index.html}}.

\item[{--index string}] \leavevmode
Make the filename of the index string instead of
“index”. Useful since “index.html” is special.

\end{description}\end{quote}
\end{quote}

\sphinxstylestrong{Table of contents option}
\begin{quote}
\begin{quote}\begin{description}
\item[{-toc, --table-of-contents}] \leavevmode
Insert a table of contents. For a \DUrole{smallcaps}{LaTeX}
output, it inserts a \sphinxcode{\sphinxupquote{\textbackslash{}tableofcontents}} at the beginning of the
document. For a HTML output, it builds a table of contents into
\sphinxcode{\sphinxupquote{toc.html}}.

\item[{--toc-depth int}] \leavevmode
Only include headers up to depth \sphinxcode{\sphinxupquote{int}} in the table of
contents.

\end{description}\end{quote}
\end{quote}

\sphinxstylestrong{Hyperlink options}
\begin{quote}
\begin{quote}\begin{description}
\item[{--glob-from file}] \leavevmode
Make references using \DUrole{smallcaps}{Coq} globalizations from file
file. (Such globalizations are obtained with Coq option \sphinxcode{\sphinxupquote{-dump-glob}}).

\item[{--no-externals}] \leavevmode
Do not insert links to the \DUrole{smallcaps}{Coq} standard library.

\item[{--external url coqdir}] \leavevmode
Use given URL for linking references whose
name starts with prefix \sphinxcode{\sphinxupquote{coqdir}}.

\item[{--coqlib url}] \leavevmode
Set base URL for the Coq standard library (default is
\sphinxurl{http://coq.inria.fr/library/}). This is equivalent to \sphinxcode{\sphinxupquote{-{-}external url
Coq}}.

\item[{-R dir coqdir}] \leavevmode
Map physical directory dir to \DUrole{smallcaps}{Coq} logical
directory  \sphinxcode{\sphinxupquote{coqdir}} (similarly to \DUrole{smallcaps}{Coq} option \sphinxcode{\sphinxupquote{-R}}).

\begin{sphinxadmonition}{note}{Note:}
option \sphinxcode{\sphinxupquote{-R}} only has
effect on the files \sphinxstyleemphasis{following} it on the command line, so you will
probably need to put this option first.
\end{sphinxadmonition}

\end{description}\end{quote}
\end{quote}

\sphinxstylestrong{Title options}
\begin{quote}
\begin{quote}\begin{description}
\item[{-s , --short}] \leavevmode
Do not insert titles for the files. The default
behavior is to insert a title like “Library Foo” for each file.

\item[{--lib-name string}] \leavevmode
Print “string Foo” instead of “Library Foo” in
titles. For example “Chapter” and “Module” are reasonable choices.

\item[{--no-lib-name}] \leavevmode
Print just “Foo” instead of “Library Foo” in titles.

\item[{--lib-subtitles}] \leavevmode
Look for library subtitles. When enabled, the
beginning of each file is checked for a comment of the form:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
(** * ModuleName : text *)
\end{sphinxVerbatim}

where \sphinxcode{\sphinxupquote{ModuleName}} must be the name of the file. If it is present, the
text is used as a subtitle for the module in appropriate places.

\item[{-t string, --title string}] \leavevmode
Set the document title.

\end{description}\end{quote}
\end{quote}

\sphinxstylestrong{Contents options}
\begin{quote}
\begin{quote}\begin{description}
\item[{-g, --gallina}] \leavevmode
Do not print proofs.

\item[{-l, --light}] \leavevmode
Light mode. Suppress proofs (as with \sphinxcode{\sphinxupquote{-g}}) and the following commands:
\begin{itemize}
\item {} 
{[}Recursive{]} Tactic Definition

\item {} 
Hint / Hints

\item {} 
Require

\item {} 
Transparent / Opaque

\item {} 
Implicit Argument / Implicits

\item {} 
Section / Variable / Hypothesis / End

\end{itemize}

The behavior of options \sphinxcode{\sphinxupquote{-g}} and \sphinxcode{\sphinxupquote{-l}} can be locally overridden using the
\sphinxcode{\sphinxupquote{(* begin show *) … (* end show *)}} environment (see above).

There are a few options that control the parsing of comments:

\item[{--parse-comments}] \leavevmode
Parse regular comments delimited by \sphinxcode{\sphinxupquote{(*}} and \sphinxcode{\sphinxupquote{*)}} as
well. They are typeset inline.

\item[{--plain-comments}] \leavevmode
Do not interpret comments, simply copy them as
plain-text.

\item[{--interpolate}] \leavevmode
Use the globalization information to typeset
identifiers appearing in \DUrole{smallcaps}{Coq} escapings inside comments.

\end{description}\end{quote}
\end{quote}

\sphinxstylestrong{Language options}
\begin{quote}

The default behavior is to assume ASCII 7 bit input files.
\begin{quote}\begin{description}
\item[{-latin1, --latin1}] \leavevmode
Select ISO-8859-1 input files. It is equivalent to
--inputenc latin1 --charset iso-8859-1.

\item[{-utf8, --utf8}] \leavevmode
Set --inputenc utf8x for \DUrole{smallcaps}{LaTeX} output and--charset
utf-8 for HTML output. Also use Unicode replacements for a couple of
standard plain ASCII notations such as \(\rightarrow\) for \sphinxcode{\sphinxupquote{-\textgreater{}}} and ∀ for \sphinxcode{\sphinxupquote{forall}}. \DUrole{smallcaps}{LaTeX}
UTF-8 support can be found
at \sphinxurl{http://www.ctan.org/pkg/unicode}. For the interpretation of Unicode
characters by \DUrole{smallcaps}{LaTeX}, extra packages which coqdoc does not provide
by default might be required, such as textgreek for some Greek letters
or \sphinxcode{\sphinxupquote{stmaryrd}} for some mathematical symbols. If a Unicode character is
missing an interpretation in the utf8x input encoding, add
\sphinxcode{\sphinxupquote{\textbackslash{}DeclareUnicodeCharacter\{code\}\{LATEX-interpretation\}}}. Packages
and declarations can be added with option \sphinxcode{\sphinxupquote{-p}}.

\item[{--inputenc string}] \leavevmode
Give a \DUrole{smallcaps}{LaTeX} input encoding, as an option to \DUrole{smallcaps}{LaTeX}
package \sphinxcode{\sphinxupquote{inputenc}}.

\item[{--charset string}] \leavevmode
Specify the HTML character set, to be inserted in
the HTML header.

\end{description}\end{quote}
\end{quote}


\subsubsection{The coqdoc LaTeX style file}
\label{\detokenize{practical-tools/utilities:the-coqdoc-latex-style-file}}
In case you choose to produce a document without the default \DUrole{smallcaps}{LaTeX}
preamble (by using option \sphinxcode{\sphinxupquote{-{-}no-preamble}}), then you must insert into
your own preamble the command

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZbs{}usepackage\PYGZob{}coqdoc\PYGZcb{}
\end{sphinxVerbatim}

The package optionally takes the argument \sphinxcode{\sphinxupquote{{[}color{]}}} to typeset
identifiers with colors (this requires the \sphinxcode{\sphinxupquote{xcolor}} package).

Then you may alter the rendering of the document by redefining some
macros:
\begin{quote}\begin{description}
\item[{coqdockw, coqdocid, …}] \leavevmode
The one-argument macros for typesetting
keywords and identifiers. Defaults are sans-serif for keywords and
italic for identifiers.For example, if you would like a slanted font
for keywords, you may insert

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZbs{}renewcommand\PYGZob{}\PYGZbs{}coqdockw\PYGZcb{}[1]\PYGZob{}\PYGZbs{}textsl\PYGZob{}\PYGZsh{}1\PYGZcb{}\PYGZcb{}
\end{sphinxVerbatim}

anywhere between \sphinxcode{\sphinxupquote{\textbackslash{}usepackage\{coqdoc\}}} and \sphinxcode{\sphinxupquote{\textbackslash{}begin\{document\}}}.

\item[{coqdocmodule}] \leavevmode
One-argument macro for typesetting the title of a \sphinxcode{\sphinxupquote{.v}}
file. Default is

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZbs{}newcommand\PYGZob{}\PYGZbs{}coqdocmodule\PYGZcb{}[1]\PYGZob{}\PYGZbs{}section*\PYGZob{}Module \PYGZsh{}1\PYGZcb{}\PYGZcb{}
\end{sphinxVerbatim}

and you may redefine it using \sphinxcode{\sphinxupquote{\textbackslash{}renewcommand}}.

\end{description}\end{quote}


\subsection{Embedded Coq phrases inside LaTeX documents}
\label{\detokenize{practical-tools/utilities:embedded-coq-phrases-inside-latex-documents}}
When writing documentation about a proof development, one may want
to insert \DUrole{smallcaps}{Coq} phrases inside a \DUrole{smallcaps}{LaTeX} document, possibly together
with the corresponding answers of the system. We provide a mechanical
way to process such \DUrole{smallcaps}{Coq} phrases embedded in \DUrole{smallcaps}{LaTeX} files: the \sphinxcode{\sphinxupquote{coq-tex}}
filter. This filter extracts \DUrole{smallcaps}{Coq} phrases embedded in \DUrole{smallcaps}{LaTeX} files,
evaluates them, and insert the outcome of the evaluation after each
phrase.

Starting with a file \sphinxcode{\sphinxupquote{file.tex}} containing \DUrole{smallcaps}{Coq} phrases, the \sphinxcode{\sphinxupquote{coq-tex}}
filter produces a file named \sphinxcode{\sphinxupquote{file.v.tex}} with the Coq outcome.

There are options to produce the \DUrole{smallcaps}{Coq} parts in smaller font, italic,
between horizontal rules, etc. See the man page of \sphinxcode{\sphinxupquote{coq-tex}} for more
details.


\subsection{Coq and GNU Emacs}
\label{\detokenize{practical-tools/utilities:coq-and-gnu-emacs}}

\subsubsection{The Coq Emacs mode}
\label{\detokenize{practical-tools/utilities:the-coq-emacs-mode}}
\DUrole{smallcaps}{Coq} comes with a Major mode for GNU Emacs, \sphinxcode{\sphinxupquote{gallina.el}}. This mode
provides syntax highlighting and also a rudimentary indentation
facility in the style of the \sphinxcode{\sphinxupquote{Caml}} GNU Emacs mode.

Add the following lines to your \sphinxcode{\sphinxupquote{.emacs}} file:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
(setq auto\PYGZhy{}mode\PYGZhy{}alist (cons \PYGZsq{}(\PYGZdq{}\PYGZbs{}\PYGZbs{}.v\PYGZdl{}\PYGZdq{} . coq\PYGZhy{}mode) auto\PYGZhy{}mode\PYGZhy{}alist))
(autoload \PYGZsq{}coq\PYGZhy{}mode \PYGZdq{}gallina\PYGZdq{} \PYGZdq{}Major mode for editing Coq vernacular.\PYGZdq{} t)
\end{sphinxVerbatim}

The \DUrole{smallcaps}{Coq} major mode is triggered by visiting a file with extension \sphinxcode{\sphinxupquote{.v}},
or manually with the command \sphinxcode{\sphinxupquote{M-x coq-mode}}. It gives you the correct
syntax table for the \DUrole{smallcaps}{Coq} language, and also a rudimentary indentation
facility:
\begin{itemize}
\item {} 
pressing \sphinxcode{\sphinxupquote{Tab}} at the beginning of a line indents the line like the
line above;

\item {} 
extra tabulations increase the indentation level (by 2 spaces by default);

\item {} 
\sphinxcode{\sphinxupquote{M-Tab}} decreases the indentation level.

\end{itemize}

An inferior mode to run \DUrole{smallcaps}{Coq} under Emacs, by Marco Maggesi, is also
included in the distribution, in file \sphinxcode{\sphinxupquote{inferior-coq.el}}. Instructions to
use it are contained in this file.


\subsubsection{Proof-General}
\label{\detokenize{practical-tools/utilities:proof-general}}
Proof-General is a generic interface for proof assistants based on
Emacs. The main idea is that the \DUrole{smallcaps}{Coq} commands you are editing are sent
to a \DUrole{smallcaps}{Coq} toplevel running behind Emacs and the answers of the system
automatically inserted into other Emacs buffers. Thus you don’t need
to copy-paste the \DUrole{smallcaps}{Coq} material from your files to the \DUrole{smallcaps}{Coq} toplevel or
conversely from the \DUrole{smallcaps}{Coq} toplevel to some files.

Proof-General is developed and distributed independently of the system
\DUrole{smallcaps}{Coq}. It is freely available at \sphinxurl{https://proofgeneral.github.io/}.


\subsection{Module specification}
\label{\detokenize{practical-tools/utilities:module-specification}}
Given a \DUrole{smallcaps}{Coq} vernacular file, the gallina filter extracts its
specification (inductive types declarations, definitions, type of
lemmas and theorems), removing the proofs parts of the file. The \DUrole{smallcaps}{Coq}
file \sphinxcode{\sphinxupquote{file.v}} gives birth to the specification file \sphinxcode{\sphinxupquote{file.g}} (where
the suffix \sphinxcode{\sphinxupquote{.g}} stands for \DUrole{smallcaps}{Gallina}).

See the man page of \sphinxcode{\sphinxupquote{gallina}} for more details and options.


\subsection{Man pages}
\label{\detokenize{practical-tools/utilities:man-pages}}
There are man pages for the commands \sphinxcode{\sphinxupquote{coqdep}}, \sphinxcode{\sphinxupquote{gallina}} and \sphinxcode{\sphinxupquote{coq-tex}}. Man
pages are installed at installation time (see installation
instructions in file \sphinxcode{\sphinxupquote{INSTALL}}, step 6).


\section{Coq Integrated Development Environment}
\label{\detokenize{practical-tools/coqide:coq-integrated-development-environment}}\label{\detokenize{practical-tools/coqide:coqintegrateddevelopmentenvironment}}\label{\detokenize{practical-tools/coqide::doc}}
The Coq Integrated Development Environment is a graphical tool, to be
used as a user-friendly replacement to \sphinxtitleref{coqtop}. Its main purpose is to
allow the user to navigate forward and backward into a Coq vernacular
file, executing corresponding commands or undoing them respectively.

\DUrole{smallcaps}{CoqIDE} is run by typing the command \sphinxtitleref{coqide} on the command line.
Without argument, the main screen is displayed with an “unnamed
buffer”, and with a filename as argument, another buffer displaying
the contents of that file. Additionally, \sphinxtitleref{coqide} accepts the same
options as \sphinxtitleref{coqtop}, given in {\hyperref[\detokenize{practical-tools/coq-commands:thecoqcommands}]{\sphinxcrossref{\DUrole{std,std-ref}{The Coq commands}}}}, the ones having obviously
no meaning for \DUrole{smallcaps}{CoqIDE} being ignored.

\phantomsection\label{\detokenize{practical-tools/coqide:coqide-mainscreen}}\begin{quote}

\noindent\sphinxincludegraphics{{coqide}.png}
\end{quote}

A sample \DUrole{smallcaps}{CoqIDE} main screen, while navigating into a file \sphinxtitleref{Fermat.v},
is shown in the figure {\hyperref[\detokenize{practical-tools/coqide:coqide-mainscreen}]{\sphinxcrossref{\DUrole{std,std-ref}{CoqIDE main screen}}}}.
At the top is a menu bar, and a tool bar
below it. The large window on the left is displaying the various
\sphinxstyleemphasis{script buffers}. The upper right window is the \sphinxstyleemphasis{goal window}, where
goals to be proven are displayed. The lower right window is the \sphinxstyleemphasis{message
window}, where various messages resulting from commands are displayed.
At the bottom is the status bar.


\subsection{Managing files and buffers, basic editing}
\label{\detokenize{practical-tools/coqide:managing-files-and-buffers-basic-editing}}
In the script window, you may open arbitrarily many buffers to edit.
The \sphinxstyleemphasis{File} menu allows you to open files or create some, save them,
print or export them into various formats. Among all these buffers,
there is always one which is the current \sphinxstyleemphasis{running buffer}, whose name
is displayed on a background in the \sphinxstyleemphasis{processed} color (green by default), which
is the one where Coq commands are currently executed.

Buffers may be edited as in any text editor, and classical basic
editing commands (Copy/Paste, …) are available in the \sphinxstyleemphasis{Edit} menu.
\DUrole{smallcaps}{CoqIDE} offers only basic editing commands, so if you need more complex
editing commands, you may launch your favorite text editor on the
current buffer, using the \sphinxstyleemphasis{Edit/External Editor} menu.


\subsection{Interactive navigation into Coq scripts}
\label{\detokenize{practical-tools/coqide:interactive-navigation-into-coq-scripts}}
The running buffer is the one where navigation takes place. The toolbar offers
five basic commands for this. The first one, represented by a down arrow icon,
is for going forward executing one command. If that command is successful, the
part of the script that has been executed is displayed on a background with the
processed color. If that command fails, the error message is displayed in the
message window, and the location of the error is emphasized by an underline in
the error foreground color (red by default).

In the figure {\hyperref[\detokenize{practical-tools/coqide:coqide-mainscreen}]{\sphinxcrossref{\DUrole{std,std-ref}{CoqIDE main screen}}}},
the running buffer is \sphinxtitleref{Fermat.v}, all commands until
the \sphinxcode{\sphinxupquote{Theorem}} have been already executed, and the user tried to go
forward executing \sphinxcode{\sphinxupquote{Induction n}}. That command failed because no such
tactic exists (names of standard tactics are written in lowercase),
and the failing command is underlined.

Notice that the processed part of the running buffer is not editable. If
you ever want to modify something you have to go backward using the up
arrow tool, or even better, put the cursor where you want to go back
and use the goto button. Unlike with \sphinxtitleref{coqtop}, you should never use
\sphinxcode{\sphinxupquote{Undo}} to go backward.

There are two additional buttons for navigation within the running buffer. The
"down" button with a line goes directly to the end; the "up" button with a line
goes back to the beginning. The handling of errors when using the go-to-the-end
button depends on whether \DUrole{smallcaps}{Coq} is running in asynchronous mode or not (see
Chapter {\hyperref[\detokenize{addendum/parallel-proof-processing:asynchronousandparallelproofprocessing}]{\sphinxcrossref{\DUrole{std,std-ref}{Asynchronous and Parallel Proof Processing}}}}). If it is not running in that mode, execution
stops as soon as an error is found. Otherwise, execution continues, and the
error is marked with an underline in the error foreground color, with a
background in the error background color (pink by default). The same
characterization of error-handling applies when running several commands using
the "goto" button.

If you ever try to execute a command that runs for a long time
and would like to abort it before it terminates, you may
use the interrupt button (the white cross on a red circle).

There are other buttons on the \DUrole{smallcaps}{CoqIDE} toolbar: a button to save the running
buffer; a button to close the current buffer (an "X"); buttons to switch among
buffers (left and right arrows); an "information" button; and a "gears" button.

The "information" button is described in Section {\hyperref[\detokenize{practical-tools/coqide:try-tactics-automatically}]{\sphinxcrossref{\DUrole{std,std-ref}{Trying tactics automatically}}}}.

The "gears" button submits proof terms to the \DUrole{smallcaps}{Coq} kernel for type checking.
When \DUrole{smallcaps}{Coq} uses asynchronous processing (see Chapter {\hyperref[\detokenize{addendum/parallel-proof-processing:asynchronousandparallelproofprocessing}]{\sphinxcrossref{\DUrole{std,std-ref}{Asynchronous and Parallel Proof Processing}}}}),
proofs may have been completed without kernel-checking of generated proof terms.
The presence of unchecked proof terms is indicated by \sphinxcode{\sphinxupquote{Qed}} statements that
have a subdued \sphinxstyleemphasis{being-processed} color (light blue by default), rather than the
processed color, though their preceding proofs have the processed color.

Notice that for all these buttons, except for the "gears" button, their operations
are also available in the menu, where their keyboard shortcuts are given.


\subsection{Trying tactics automatically}
\label{\detokenize{practical-tools/coqide:trying-tactics-automatically}}\label{\detokenize{practical-tools/coqide:try-tactics-automatically}}
The menu Try Tactics provides some features for automatically trying
to solve the current goal using simple tactics. If such a tactic
succeeds in solving the goal, then its text is automatically inserted
into the script. There is finally a combination of these tactics,
called the \sphinxstyleemphasis{proof wizard} which will try each of them in turn. This
wizard is also available as a tool button (the "information" button). The set of
tactics tried by the wizard is customizable in the preferences.

These tactics are general ones, in particular they do not refer to
particular hypotheses. You may also try specific tactics related to
the goal or one of the hypotheses, by clicking with the right mouse
button on the goal or the considered hypothesis. This is the
“contextual menu on goals” feature, that may be disabled in the
preferences if undesirable.


\subsection{Proof folding}
\label{\detokenize{practical-tools/coqide:proof-folding}}
As your script grows bigger and bigger, it might be useful to hide the
proofs of your theorems and lemmas.

This feature is toggled via the Hide entry of the Navigation menu. The
proof shall be enclosed between \sphinxcode{\sphinxupquote{Proof.}} and \sphinxcode{\sphinxupquote{Qed.}}, both with their final
dots. The proof that shall be hidden or revealed is the first one
whose beginning statement (such as \sphinxcode{\sphinxupquote{Theorem}}) precedes the insertion
cursor.


\subsection{Vernacular commands, templates}
\label{\detokenize{practical-tools/coqide:vernacular-commands-templates}}
The Templates menu allows using shortcuts to insert vernacular
commands. This is a nice way to proceed if you are not sure of the
syntax of the command you want.

Moreover, from this menu you can automatically insert templates of complex
commands like \sphinxcode{\sphinxupquote{Fixpoint}} that you can conveniently fill afterwards.


\subsection{Queries}
\label{\detokenize{practical-tools/coqide:queries}}
\noindent\sphinxincludegraphics{{coqide-queries}.png}

We call \sphinxstyleemphasis{query} any vernacular command that does not change the current state,
such as \sphinxcode{\sphinxupquote{Check}}, \sphinxcode{\sphinxupquote{Search}}, etc. To run such commands interactively, without
writing them in scripts, \DUrole{smallcaps}{CoqIDE} offers a \sphinxstyleemphasis{query pane}. The query pane can be
displayed on demand by using the \sphinxcode{\sphinxupquote{View}} menu, or using the shortcut \sphinxcode{\sphinxupquote{F1}}.
Queries can also be performed by selecting a particular phrase, then choosing an
item from the \sphinxcode{\sphinxupquote{Queries}} menu. The response then appears in the message window.
The image above shows the result after selecting of the phrase
\sphinxcode{\sphinxupquote{Nat.mul}} in the script window, and choosing \sphinxcode{\sphinxupquote{Print}} from the \sphinxcode{\sphinxupquote{Queries}}
menu.


\subsection{Compilation}
\label{\detokenize{practical-tools/coqide:compilation}}
The \sphinxtitleref{Compile} menu offers direct commands to:
\begin{itemize}
\item {} 
compile the current buffer

\item {} 
run a compilation using \sphinxtitleref{make}

\item {} 
go to the last compilation error

\item {} 
create a \sphinxtitleref{Makefile} using \sphinxtitleref{coq\_makefile}.

\end{itemize}


\subsection{Customizations}
\label{\detokenize{practical-tools/coqide:customizations}}
You may customize your environment using the menu Edit/Preferences. A new
window will be displayed, with several customization sections
presented as a notebook.

The first section is for selecting the text font used for scripts,
goal and message windows.

The second section is devoted to file management: you may configure
automatic saving of files, by periodically saving the contents into
files named \sphinxtitleref{\#f\#} for each opened file \sphinxtitleref{f}. You may also activate the
\sphinxstyleemphasis{revert} feature: in case a opened file is modified on the disk by a
third party, \DUrole{smallcaps}{CoqIDE} may read it again for you. Note that in the case
you edited that same file, you will be prompted to choose to either
discard your changes or not. The File charset encoding choice is
described below in {\hyperref[\detokenize{practical-tools/coqide:character-encoding-saved-files}]{\sphinxcrossref{\DUrole{std,std-ref}{Character encoding for saved files}}}}.

The \sphinxtitleref{Externals} section allows customizing the external commands for
compilation, printing, web browsing. In the browser command, you may
use \sphinxtitleref{\%s} to denote the URL to open, for example:
\sphinxtitleref{firefox -remote "OpenURL(\%s)"}.

The \sphinxtitleref{Tactics Wizard} section allows defining the set of tactics that
should be tried, in sequence, to solve the current goal.

The last section is for miscellaneous boolean settings, such as the
“contextual menu on goals” feature presented in the section
{\hyperref[\detokenize{practical-tools/coqide:try-tactics-automatically}]{\sphinxcrossref{\DUrole{std,std-ref}{Try tactics automatically}}}}.

Notice that these settings are saved in the file \sphinxtitleref{.coqiderc} of your
home directory.

A Gtk2 accelerator keymap is saved under the name \sphinxtitleref{.coqide.keys}. It
is not recommended to edit this file manually: to modify a given menu
shortcut, go to the corresponding menu item without releasing the
mouse button, press the key you want for the new shortcut, and release
the mouse button afterwards. If your system does not allow it, you may
still edit this configuration file by hand, but this is more involved.


\subsection{Using Unicode symbols}
\label{\detokenize{practical-tools/coqide:using-unicode-symbols}}
\DUrole{smallcaps}{CoqIDE} is based on GTK+ and inherits from it support for Unicode in
its text windows. Consequently a large set of symbols is available for
notations.


\subsubsection{Displaying Unicode symbols}
\label{\detokenize{practical-tools/coqide:displaying-unicode-symbols}}
You just need to define suitable notations as described in the chapter
{\hyperref[\detokenize{user-extensions/syntax-extensions:syntaxextensionsandinterpretationscopes}]{\sphinxcrossref{\DUrole{std,std-ref}{Syntax extensions and interpretation scopes}}}}. For example, to use the
mathematical symbols ∀ and ∃, you may define:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{∀ x : T, P}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=}
\PYG{o}{(}\PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{T}\PYG{o}{,} \PYG{n}{P}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{200}\PYG{o}{,} \PYG{n}{x} \PYG{n}{ident}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{∃ x : T, P}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=}
\PYG{o}{(}\PYG{k}{exists} \PYG{n}{x} \PYG{o}{:} \PYG{n}{T}\PYG{o}{,} \PYG{n}{P}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{200}\PYG{o}{,} \PYG{n}{x} \PYG{n}{ident}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

There exists a small set of such notations already defined, in the
file \sphinxtitleref{utf8.v} of Coq library, so you may enable them just by
\sphinxcode{\sphinxupquote{Require Import Unicode.Utf8}} inside \DUrole{smallcaps}{CoqIDE}, or equivalently,
by starting \DUrole{smallcaps}{CoqIDE} with \sphinxcode{\sphinxupquote{coqide -l utf8}}.

However, there are some issues when using such Unicode symbols: you of
course need to use a character font which supports them. In the Fonts
section of the preferences, the Preview line displays some Unicode
symbols, so you could figure out if the selected font is OK. Related
to this, one thing you may need to do is choosing whether GTK+ should
use antialiased fonts or not, by setting the environment variable
\sphinxtitleref{GDK\_USE\_XFT} to 1 or 0 respectively.


\subsubsection{Defining an input method for non-ASCII symbols}
\label{\detokenize{practical-tools/coqide:defining-an-input-method-for-non-ascii-symbols}}
To input a Unicode symbol, a general method provided by GTK+ is to
simultaneously press the Control, Shift and “u” keys, release, then
type the hexadecimal code of the symbol required, for example \sphinxtitleref{2200}
for the ∀ symbol. A list of symbol codes is available at
\sphinxtitleref{http://www.unicode.org}.

An alternative method which does not require to know the hexadecimal
code of the character is to use an Input Method Editor. On POSIX
systems (Linux distributions, BSD variants and MacOS X), you can
use \sphinxtitleref{uim} version 1.6 or later which provides a LaTeX-style input
method.

To configure uim, execute uim-pref-gtk as your regular user. In the
"Global Settings" group set the default Input Method to "ELatin"
(don’t forget to tick the checkbox "Specify default IM"). In the
"ELatin" group set the layout to "TeX", and remember the content of
the "{[}ELatin{]} on" field (by default Control-\textbackslash{}). You can now execute
\DUrole{smallcaps}{CoqIDE} with the following commands (assuming you use a Bourne-style
shell):

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZdl{} export GTK\PYGZus{}IM\PYGZus{}MODULE=uim
\PYGZdl{} coqide
\end{sphinxVerbatim}

Activate the ELatin Input Method with Control-\textbackslash{}, then type the
sequence \sphinxtitleref{\textbackslash{}Gamma}. You will see the sequence being replaced by \(\Gamma\) as
soon as you type the second "a".


\subsubsection{Character encoding for saved files}
\label{\detokenize{practical-tools/coqide:character-encoding-for-saved-files}}\label{\detokenize{practical-tools/coqide:character-encoding-saved-files}}
In the Files section of the preferences, the encoding option is
related to the way files are saved.

If you have no need to exchange files with non UTF-8 aware
applications, it is better to choose the UTF-8 encoding, since it
guarantees that your files will be read again without problems. (This
is because when \DUrole{smallcaps}{CoqIDE} reads a file, it tries to automatically detect
its character encoding.)

If you choose something else than UTF-8, then missing characters will
be written encoded by \sphinxtitleref{x\{....\}} or \sphinxtitleref{x\{........\}} where each dot is
an hexadecimal digit: the number between braces is the hexadecimal
Unicode index for the missing character.


\chapter{Addendum}
\label{\detokenize{index:addendum}}

\section{Extended pattern matching}
\label{\detokenize{addendum/extended-pattern-matching:extended-pattern-matching}}\label{\detokenize{addendum/extended-pattern-matching:extendedpatternmatching}}\label{\detokenize{addendum/extended-pattern-matching::doc}}\begin{quote}\begin{description}
\item[{Authors}] \leavevmode
Cristina Cornes and Hugo Herbelin

\end{description}\end{quote}

This section describes the full form of pattern matching in \DUrole{smallcaps}{Coq} terms.


\subsection{Patterns}
\label{\detokenize{addendum/extended-pattern-matching:patterns}}
The full syntax of match is presented in Figures 1.1 and 1.2.
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 \sphinxcode{\sphinxupquote{(c x)}} where \sphinxcode{\sphinxupquote{c}} is a constructor symbol and x
is a linear vector of (distinct) variables, it is called \sphinxstyleemphasis{simple}: it
is the kind of pattern recognized by the basic version of match. On
the opposite, if it is a variable \sphinxcode{\sphinxupquote{x}} or has the form \sphinxcode{\sphinxupquote{(c p)}} with \sphinxcode{\sphinxupquote{p}} not
only made of variables, the pattern is called \sphinxstyleemphasis{nested}.

A variable pattern matches any value, and the identifier is bound to
that value. The pattern “\sphinxcode{\sphinxupquote{\_}}” (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
\sphinxcode{\sphinxupquote{\DUrole{notation}{({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}} as \DUrole{hole}{identifier})}}} are also accepted. This pattern matches the
same values as \sphinxcode{\sphinxupquote{pattern}} does and \sphinxcode{\sphinxupquote{identifier}} is bound to the matched
value. A pattern of the form \sphinxcode{\sphinxupquote{\DUrole{notation}{pattern \textbar{} pattern}}} is called disjunctive. A
list of patterns separated with commas is also considered as a pattern
and is called \sphinxstyleemphasis{multiple pattern}. However multiple patterns can only
occur at the root of pattern matching equations. Disjunctions of
\sphinxstyleemphasis{multiple patterns} are allowed though.

Since extended \sphinxcode{\sphinxupquote{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 \sphinxcode{\sphinxupquote{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 {\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-matching}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Matching}}}}}), then by printing the term with {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.print}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print}}}}}
if the term is a constant, or using the command {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.check}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Check}}}}}.

The extended \sphinxcode{\sphinxupquote{match}} still accepts an optional \sphinxstyleemphasis{elimination predicate}
given after the keyword \sphinxcode{\sphinxupquote{return}}. Given a pattern matching expression,
if all the right-hand-sides of \sphinxcode{\sphinxupquote{=\textgreater{}}} 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:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{max} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{m}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
  \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{n\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{m} \PYG{k}{with}
            \PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{n}{n\PYGZsq{}}
            \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{m\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{max} \PYG{n}{n\PYGZsq{}} \PYG{n}{m\PYGZsq{}}\PYG{o}{)}
            \PYG{k}{end}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}


\subsection{Multiple patterns}
\label{\detokenize{addendum/extended-pattern-matching:multiple-patterns}}
Using multiple patterns in the definition of \sphinxcode{\sphinxupquote{max}} lets us write:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{max} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{m}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
    \PYG{k}{match} \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{k}{with}
    \PYG{o}{\textbar{}} \PYG{n}{O}\PYG{o}{,} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
    \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{n\PYGZsq{}}\PYG{o}{,} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{n}{n\PYGZsq{}}
    \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{n\PYGZsq{}}\PYG{o}{,} \PYG{n}{S} \PYG{n}{m\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{max} \PYG{n}{n\PYGZsq{}} \PYG{n}{m\PYGZsq{}}\PYG{o}{)}
    \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

which will be compiled into the previous form.

The pattern matching compilation strategy examines patterns from left
to right. A match expression is generated \sphinxstylestrong{only} when there is at least
one constructor in the column of patterns. E.g. the following example
does not build a match expression.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x}\PYG{o}{:}\PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{x} \PYG{k}{return} \PYG{k+kt}{nat} \PYG{k}{with}
                    \PYG{o}{\textbar{}} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{y}
                    \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}
         \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
\end{sphinxVerbatim}


\subsection{Aliasing subpatterns}
\label{\detokenize{addendum/extended-pattern-matching:aliasing-subpatterns}}
We can also use \sphinxcode{\sphinxupquote{\DUrole{notation}{as {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} to associate a name to a sub-pattern:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{max} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{O}\PYG{o}{,} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
  \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{n\PYGZsq{}} \PYG{k}{as} \PYG{n}{p}\PYG{o}{,} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{p}
  \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{n\PYGZsq{}}\PYG{o}{,} \PYG{n}{S} \PYG{n}{m\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{max} \PYG{n}{n\PYGZsq{}} \PYG{n}{m\PYGZsq{}}\PYG{o}{)}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}


\subsection{Nested patterns}
\label{\detokenize{addendum/extended-pattern-matching:nested-patterns}}
Here is now an example of nested patterns:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{even} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
  \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
  \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n\PYGZsq{}}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{even} \PYG{n}{n\PYGZsq{}}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

This is compiled into:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Matching}\PYG{o}{.}
\PYG{k+kn}{Print} \PYG{n}{even}\PYG{o}{.}
    \PYG{n}{even} \PYG{o}{=} 
    \PYG{k}{fix} \PYG{n}{even} \PYG{o}{(}\PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{:=}
      \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
      \PYG{o}{\textbar{}} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
      \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{n0} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{n0} \PYG{k}{with}
                \PYG{o}{\textbar{}} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
                \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{n\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{even} \PYG{n}{n\PYGZsq{}}
                \PYG{k}{end}
      \PYG{k}{end}
         \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool}
    
    \PYG{n}{Argument} \PYG{n}{scope} \PYG{k}{is} \PYG{o}{[}\PYG{n}{nat\PYGZus{}scope}\PYG{o}{]}
\end{sphinxVerbatim}

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 \sphinxcode{\sphinxupquote{\DUrole{name}{lef}}} that given two
natural numbers yields \sphinxcode{\sphinxupquote{\DUrole{name,builtin,pseudo}{true}}} if the first one is less or equal than the
second one and \sphinxcode{\sphinxupquote{\DUrole{name,builtin,pseudo}{false}}} otherwise. We can write it as follows:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{lef} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{m}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{O}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
  \PYG{o}{\textbar{}} \PYG{n}{x}\PYG{o}{,} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
  \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{n}\PYG{o}{,} \PYG{n}{S} \PYG{n}{m} \PYG{o}{=\PYGZgt{}} \PYG{n}{lef} \PYG{n}{n} \PYG{n}{m}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

Note that the first and the second multiple pattern overlap because
the couple of values \sphinxcode{\sphinxupquote{O O}} matches both. Thus, what is the result of the
function on those values? To eliminate ambiguity we use the \sphinxstyleemphasis{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, \sphinxcode{\sphinxupquote{O O}}
is matched by the first pattern, and so \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{lef} \DUrole{name}{O} \DUrole{name}{O}\DUrole{operator}{)}}} yields true.

Another way to write this function is:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{lef} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{m}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{O}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
  \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{n}\PYG{o}{,} \PYG{n}{S} \PYG{n}{m} \PYG{o}{=\PYGZgt{}} \PYG{n}{lef} \PYG{n}{n} \PYG{n}{m}
  \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}}\PYG{o}{,} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

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:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x}\PYG{o}{:}\PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}}
              \PYG{k}{match} \PYG{n}{x} \PYG{k}{with}
              \PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
              \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
              \PYG{o}{\textbar{}} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
              \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{This} \PYG{n}{clause} \PYG{k}{is} \PYG{n}{redundant}\PYG{o}{.}
\end{sphinxVerbatim}


\subsection{Disjunctive patterns}
\label{\detokenize{addendum/extended-pattern-matching:disjunctive-patterns}}
Multiple patterns that share the same right-hand-side can be
factorized using the notation \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-mult-pattern}]{\sphinxcrossref{\DUrole{hole}{mult\_pattern}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textbar{}}}}}}. For
instance, \sphinxcode{\sphinxupquote{\DUrole{name}{max}}} can be rewritten as follows:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{max} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{m}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{n\PYGZsq{}}\PYG{o}{,} \PYG{n}{S} \PYG{n}{m\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{max} \PYG{n}{n\PYGZsq{}} \PYG{n}{m\PYGZsq{}}\PYG{o}{)}
  \PYG{o}{\textbar{}} \PYG{l+m+mi}{0}\PYG{o}{,} \PYG{n}{p} \PYG{o}{\textbar{}} \PYG{n}{p}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{p}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

Similarly, factorization of (not necessarily multiple) patterns that
share the same variables is possible by using the notation \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-pattern}]{\sphinxcrossref{\DUrole{hole}{pattern}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{\textbar{}}}}}}.
Here is an example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{filter\PYGZus{}2\PYGZus{}4} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{l+m+mi}{2} \PYG{k}{as} \PYG{n}{m} \PYG{o}{\textbar{}} \PYG{l+m+mi}{4} \PYG{k}{as} \PYG{n}{m} \PYG{o}{=\PYGZgt{}} \PYG{n}{m}
  \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

Here is another example using disjunctive subpatterns.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{filter\PYGZus{}some\PYGZus{}square\PYGZus{}corners} \PYG{o}{(}\PYG{n}{p}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{*}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{*}\PYG{k+kt}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{p} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{o}{(}\PYG{o}{(}\PYG{l+m+mi}{2} \PYG{k}{as} \PYG{n}{m} \PYG{o}{\textbar{}} \PYG{l+m+mi}{4} \PYG{k}{as} \PYG{n}{m}\PYG{o}{)}\PYG{o}{,} \PYG{o}{(}\PYG{l+m+mi}{3} \PYG{k}{as} \PYG{n}{n} \PYG{o}{\textbar{}} \PYG{l+m+mi}{5} \PYG{k}{as} \PYG{n}{n}\PYG{o}{)}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{o}{(}\PYG{n}{m}\PYG{o}{,}\PYG{n}{n}\PYG{o}{)}
  \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{o}{(}\PYG{l+m+mi}{0}\PYG{o}{,}\PYG{l+m+mi}{0}\PYG{o}{)}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}


\subsection{About patterns of parametric types}
\label{\detokenize{addendum/extended-pattern-matching:about-patterns-of-parametric-types}}

\subsubsection{Parameters in patterns}
\label{\detokenize{addendum/extended-pattern-matching:parameters-in-patterns}}
When matching objects of a parametric type, parameters do not bind in
patterns. They must be substituted by “\sphinxcode{\sphinxupquote{\_}}”. Consider for example the
type of polymorphic lists:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{List} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{:} \PYG{n}{List} \PYG{n}{A}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{List} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{List} \PYG{n}{A}\PYG{o}{.}
\end{sphinxVerbatim}

We can check the function \sphinxstyleemphasis{tail}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check}
  \PYG{o}{(}\PYG{k}{fun} \PYG{n}{l}\PYG{o}{:}\PYG{n}{List} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}}
     \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
     \PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil} \PYG{k+kt}{nat}
     \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{n}{l\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{l\PYGZsq{}}
     \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{l} \PYG{o}{:} \PYG{n}{List} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
                        \PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil} \PYG{k+kt}{nat}
                        \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{n}{l\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{l\PYGZsq{}}
                        \PYG{k}{end}
         \PYG{o}{:} \PYG{n}{List} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{List} \PYG{k+kt}{nat}
\end{sphinxVerbatim}

When we use parameters in patterns there is an error message:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Check}
  \PYG{o}{(}\PYG{k}{fun} \PYG{n}{l}\PYG{o}{:}\PYG{n}{List} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}}
     \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
     \PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{n}{A} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil} \PYG{k+kt}{nat}
     \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{n}{A} \PYG{o}{\PYGZus{}} \PYG{n}{l\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{l\PYGZsq{}}
     \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{The} \PYG{n}{parameters} \PYG{k+kr}{do} \PYG{n}{not} \PYG{n}{bind} \PYG{k}{in} \PYG{n}{patterns}\PYG{o}{;} \PYG{n}{they} \PYG{n}{must} \PYG{n}{be} \PYG{n}{replaced} \PYG{k+kp}{by} \PYG{l+s+sc}{\PYGZsq{}\PYGZus{}\PYGZsq{}}\PYG{o}{.}
\end{sphinxVerbatim}
\index{Asymmetric Patterns (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extended-pattern-matching:coq:flag.asymmetric-patterns}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Asymmetric~Patterns}}}}
This flag (off by default) removes parameters from constructors in patterns:

\end{fulllineitems}


\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{n}{Asymmetric} \PYG{n}{Patterns}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{l}\PYG{o}{:}\PYG{n}{List} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}}
  \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil}
  \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{\PYGZus{}} \PYG{n}{l\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{l\PYGZsq{}}
  \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{72}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{74}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{l}\PYG{o}{:}\PYG{n}{List} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}}   \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}   \PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil}   \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{\PYGZus{}} \PYG{n}{l\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{l\PYGZsq{}}   \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}}                                                                         \PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:}
    \PYG{n}{In} \PYG{n}{environment}
    \PYG{n}{l} \PYG{o}{:} \PYG{n}{List} \PYG{k+kt}{nat}
    \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}
    \PYG{n}{l\PYGZsq{}} \PYG{o}{:} \PYG{n}{List} \PYG{k+kt}{nat}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{l\PYGZsq{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{List nat}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{while} \PYG{n}{it} \PYG{k}{is} \PYG{n}{expected} \PYG{n}{to} \PYG{k}{have} \PYG{n}{type}
     \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{forall A : Set, List A}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}

\PYG{k+kn}{Unset} \PYG{n}{Asymmetric} \PYG{n}{Patterns}\PYG{o}{.}
\end{sphinxVerbatim}


\subsection{Implicit arguments in patterns}
\label{\detokenize{addendum/extended-pattern-matching:implicit-arguments-in-patterns}}
By default, implicit arguments are omitted in patterns. So we write:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Arguments} \PYG{n}{nil} \PYG{o}{[}\PYG{n}{A}\PYG{o}{]}\PYG{o}{.}
\PYG{k+kn}{Arguments} \PYG{n}{cons} \PYG{o}{[}\PYG{n}{A}\PYG{o}{]} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{.}
\PYG{k+kn}{Check}
  \PYG{o}{(}\PYG{k}{fun} \PYG{n}{l}\PYG{o}{:}\PYG{n}{List} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}}
     \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
     \PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil}
     \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{\PYGZus{}} \PYG{n}{l\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{l\PYGZsq{}}
     \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{l} \PYG{o}{:} \PYG{n}{List} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
                        \PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil}
                        \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{\PYGZus{}} \PYG{n}{l\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{l\PYGZsq{}}
                        \PYG{k}{end}
         \PYG{o}{:} \PYG{n}{List} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{List} \PYG{k+kt}{nat}
\end{sphinxVerbatim}

But the possibility to use all the arguments is given by “\sphinxcode{\sphinxupquote{@}}” implicit
explicitations (as for terms 2.7.11).

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check}
  \PYG{o}{(}\PYG{k}{fun} \PYG{n}{l}\PYG{o}{:}\PYG{n}{List} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}}
     \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
     \PYG{o}{\textbar{}} \PYG{o}{@}\PYG{n}{nil} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{o}{@}\PYG{n}{nil} \PYG{k+kt}{nat}
     \PYG{o}{\textbar{}} \PYG{o}{@}\PYG{n}{cons} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{n}{l\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{l\PYGZsq{}}
     \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{l} \PYG{o}{:} \PYG{n}{List} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
                        \PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{n}{nil}
                        \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{\PYGZus{}} \PYG{n}{l\PYGZsq{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{l\PYGZsq{}}
                        \PYG{k}{end}
         \PYG{o}{:} \PYG{n}{List} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{List} \PYG{k+kt}{nat}
\end{sphinxVerbatim}


\subsection{Matching objects of dependent types}
\label{\detokenize{addendum/extended-pattern-matching:matching-objects-of-dependent-types}}\label{\detokenize{addendum/extended-pattern-matching:matching-dependent}}
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 \sphinxcode{\sphinxupquote{\DUrole{name}{listn}}} of
lists of a certain length:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{listn} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{niln} \PYG{o}{:} \PYG{n}{listn} \PYG{l+m+mi}{0}
\PYG{o}{\textbar{}} \PYG{n}{consn} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{listn} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{listn} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}


\subsection{Understanding dependencies in patterns}
\label{\detokenize{addendum/extended-pattern-matching:understanding-dependencies-in-patterns}}
We can define the function length over \sphinxcode{\sphinxupquote{\DUrole{name}{listn}}} by:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{length} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l}\PYG{o}{:}\PYG{n}{listn} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{n}\PYG{o}{.}
\end{sphinxVerbatim}

Just for illustrating pattern matching, we can define it by case
analysis:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{length} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l}\PYG{o}{:}\PYG{n}{listn} \PYG{n}{n}\PYG{o}{)} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{niln} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
  \PYG{o}{\textbar{}} \PYG{n}{consn} \PYG{n}{n} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{n}{n}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

We can understand the meaning of this definition using the same
notions of usual pattern matching.


\subsection{When the elimination predicate must be provided}
\label{\detokenize{addendum/extended-pattern-matching:when-the-elimination-predicate-must-be-provided}}

\subsubsection{Dependent pattern matching}
\label{\detokenize{addendum/extended-pattern-matching:dependent-pattern-matching}}
The examples given so far do not need an explicit elimination
predicate because all the right hand sides 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 right hand sides are different instances of the elimination predicate. The
function \sphinxcode{\sphinxupquote{\DUrole{name}{concat}}} for \sphinxcode{\sphinxupquote{\DUrole{name}{listn}}} is an example where the branches have
different types and we need to provide the elimination predicate:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{concat} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l}\PYG{o}{:}\PYG{n}{listn} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l\PYGZsq{}}\PYG{o}{:}\PYG{n}{listn} \PYG{n}{m}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{l}\PYG{o}{\PYGZcb{}} \PYG{o}{:}
 \PYG{n}{listn} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{l} \PYG{k}{in} \PYG{n}{listn} \PYG{n}{n} \PYG{k}{return} \PYG{n}{listn} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{niln} \PYG{o}{=\PYGZgt{}} \PYG{n}{l\PYGZsq{}}
  \PYG{o}{\textbar{}} \PYG{n}{consn} \PYG{n}{n\PYGZsq{}} \PYG{n}{a} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{consn} \PYG{o}{(}\PYG{n}{n\PYGZsq{}} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)} \PYG{n}{a} \PYG{o}{(}\PYG{n}{concat} \PYG{n}{n\PYGZsq{}} \PYG{n}{y} \PYG{n}{m} \PYG{n}{l\PYGZsq{}}\PYG{o}{)}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

The elimination predicate is \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{operator}{(}\DUrole{name}{n}\DUrole{operator}{:}\DUrole{keyword,type}{nat}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{l}\DUrole{operator}{:}\DUrole{name}{listn} \DUrole{name}{n}\DUrole{operator}{)} \DUrole{operator}{=\textgreater{}} \DUrole{name}{listn} \DUrole{operator}{(}\DUrole{name}{n}\DUrole{operator}{+}\DUrole{name}{m}\DUrole{operator}{)}}}.
In general if \sphinxcode{\sphinxupquote{\DUrole{name}{m}}} has type \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{I} \DUrole{name}{q1} \DUrole{error}{…} \DUrole{name}{qr} \DUrole{name}{t1} \DUrole{error}{…} \DUrole{name}{ts}\DUrole{operator}{)}}} where \sphinxcode{\sphinxupquote{\DUrole{name}{q1}\DUrole{operator}{,} \DUrole{error}{…}\DUrole{operator}{,} \DUrole{name}{qr}}}
are parameters, the elimination predicate should be of the form \sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{name}{y1} \DUrole{error}{…} \DUrole{name}{ys} \DUrole{name}{x} \DUrole{operator}{:} \DUrole{operator}{(}\DUrole{name}{I} \DUrole{name}{q1} \DUrole{error}{…} \DUrole{name}{qr} \DUrole{name}{y1} \DUrole{error}{…} \DUrole{name}{ys} \DUrole{operator}{)} \DUrole{operator}{=\textgreater{}} \DUrole{name}{Q}}}.

In the concrete syntax, it should be written :
\sphinxcode{\sphinxupquote{match m as x in (I \_ … \_ y1 … ys) return Q with … end}}.
The variables which appear in the \sphinxcode{\sphinxupquote{in}} and \sphinxcode{\sphinxupquote{as}} clause are new and bounded
in the property \sphinxcode{\sphinxupquote{\DUrole{name}{Q}}} in the return clause. The parameters of the
inductive definitions should not be mentioned and are replaced by \sphinxcode{\sphinxupquote{\_}}.


\subsubsection{Multiple dependent pattern matching}
\label{\detokenize{addendum/extended-pattern-matching: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 \sphinxcode{\sphinxupquote{as}} clause and an \sphinxcode{\sphinxupquote{in}} clause in order to introduce
a dependent product.

For example, an equivalent definition for \sphinxcode{\sphinxupquote{\DUrole{name}{concat}}} (even though the
matching on the second term is trivial) would have been:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{concat} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l}\PYG{o}{:}\PYG{n}{listn} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{l\PYGZsq{}}\PYG{o}{:}\PYG{n}{listn} \PYG{n}{m}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{l}\PYG{o}{\PYGZcb{}} \PYG{o}{:}
 \PYG{n}{listn} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{l} \PYG{k}{in} \PYG{n}{listn} \PYG{n}{n}\PYG{o}{,} \PYG{n}{l\PYGZsq{}} \PYG{k}{return} \PYG{n}{listn} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{niln}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}
  \PYG{o}{\textbar{}} \PYG{n}{consn} \PYG{n}{n\PYGZsq{}} \PYG{n}{a} \PYG{n}{y}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{consn} \PYG{o}{(}\PYG{n}{n\PYGZsq{}} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)} \PYG{n}{a} \PYG{o}{(}\PYG{n}{concat} \PYG{n}{n\PYGZsq{}} \PYG{n}{y} \PYG{n}{m} \PYG{n}{x}\PYG{o}{)}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

Even without real matching over the second term, this construction can
be used to keep types linked. If \sphinxcode{\sphinxupquote{\DUrole{name}{a}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{b}}} are two \sphinxcode{\sphinxupquote{\DUrole{name}{listn}}} of the same
length, by writing

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{n} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b}\PYG{o}{:} \PYG{n}{listn} \PYG{n}{n}\PYG{o}{)} \PYG{o}{=\PYGZgt{}}
 \PYG{k}{match} \PYG{n}{a}\PYG{o}{,} \PYG{n}{b} \PYG{k}{with}
 \PYG{o}{\textbar{}} \PYG{n}{niln}\PYG{o}{,} \PYG{n}{b0} \PYG{o}{=\PYGZgt{}} \PYG{n}{tt}
 \PYG{o}{\textbar{}} \PYG{n}{consn} \PYG{n}{n\PYGZsq{}} \PYG{n}{a} \PYG{n}{y}\PYG{o}{,} \PYG{n}{bS} \PYG{o}{=\PYGZgt{}} \PYG{n}{tt}
 \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

we have a copy of \sphinxcode{\sphinxupquote{\DUrole{name}{b}}} in type \sphinxcode{\sphinxupquote{\DUrole{name}{listn} \DUrole{literal,number,integer}{0}}} resp. \sphinxcode{\sphinxupquote{\DUrole{name}{listn} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{n'}\DUrole{operator}{)}}}.


\subsubsection{Patterns in \sphinxstyleliteralintitle{\sphinxupquote{in}}}
\label{\detokenize{addendum/extended-pattern-matching:patterns-in-in}}\label{\detokenize{addendum/extended-pattern-matching:match-in-patterns}}
If the type of the matched term is more precise than an inductive
applied to variables, arguments of the inductive in the \sphinxcode{\sphinxupquote{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 \sphinxcode{\sphinxupquote{tail}} function can be written:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{tail} \PYG{n}{n} \PYG{o}{(}\PYG{n}{v}\PYG{o}{:} \PYG{n}{listn} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)}\PYG{o}{)} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{v} \PYG{k}{in} \PYG{n}{listn} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)} \PYG{k}{return} \PYG{n}{listn} \PYG{n}{m} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{niln} \PYG{o}{=\PYGZgt{}} \PYG{n}{False\PYGZus{}rect} \PYG{k+kt}{unit}
  \PYG{o}{\textbar{}} \PYG{n}{consn} \PYG{n}{n\PYGZsq{}} \PYG{n}{a} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{y}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

and \sphinxcode{\sphinxupquote{\DUrole{name}{tail} \DUrole{name}{n} \DUrole{name}{v}}} will be subterm of \sphinxcode{\sphinxupquote{\DUrole{name}{v}}}.


\subsection{Using pattern matching to write proofs}
\label{\detokenize{addendum/extended-pattern-matching: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 \sphinxcode{\sphinxupquote{match}} is given
in the description of the tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}}.

For example, we can write the function \sphinxcode{\sphinxupquote{\DUrole{name}{buildlist}}} that given a natural
number \sphinxcode{\sphinxupquote{\DUrole{name}{n}}} builds a list of length \sphinxcode{\sphinxupquote{\DUrole{name}{n}}} containing zeros as follows:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{buildlist} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{listn} \PYG{n}{n} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n} \PYG{k}{return} \PYG{n}{listn} \PYG{n}{n} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{niln}
  \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{n} \PYG{o}{=\PYGZgt{}} \PYG{n}{consn} \PYG{n}{n} \PYG{l+m+mi}{0} \PYG{o}{(}\PYG{n}{buildlist} \PYG{n}{n}\PYG{o}{)}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

We can also use multiple patterns. Consider the following definition
of the predicate less-equal \sphinxcode{\sphinxupquote{\DUrole{name}{Le}}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{LE} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
  \PYG{o}{\textbar{}} \PYG{n}{LEO} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{LE} \PYG{l+m+mi}{0} \PYG{n}{n}
  \PYG{o}{\textbar{}} \PYG{n}{LES} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{LE} \PYG{n}{n} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{LE} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

We can use multiple patterns to write the proof of the lemma
\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{n} \DUrole{name}{m}\DUrole{operator}{:}\DUrole{keyword,type}{nat}\DUrole{operator}{),} \DUrole{operator}{(}\DUrole{name}{LE} \DUrole{name}{n} \DUrole{name}{m}\DUrole{operator}{)} \DUrole{operator}{\textbackslash{}/} \DUrole{operator}{(}\DUrole{name}{LE} \DUrole{name}{m} \DUrole{name}{n}\DUrole{operator}{)}}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{dec} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{n}{LE} \PYG{n}{n} \PYG{n}{m} \PYG{o}{\PYGZbs{}/} \PYG{n}{LE} \PYG{n}{m} \PYG{n}{n} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{k}{return} \PYG{n}{LE} \PYG{n}{n} \PYG{n}{m} \PYG{o}{\PYGZbs{}/} \PYG{n}{LE} \PYG{n}{m} \PYG{n}{n} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{O}\PYG{o}{,} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{or\PYGZus{}introl} \PYG{o}{(}\PYG{n}{LE} \PYG{n}{x} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{(}\PYG{n}{LEO} \PYG{n}{x}\PYG{o}{)}
  \PYG{o}{\textbar{}} \PYG{n}{x}\PYG{o}{,} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{n}{or\PYGZus{}intror} \PYG{o}{(}\PYG{n}{LE} \PYG{n}{x} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{(}\PYG{n}{LEO} \PYG{n}{x}\PYG{o}{)}
  \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{n} \PYG{k}{as} \PYG{n}{n\PYGZsq{}}\PYG{o}{,} \PYG{n}{S} \PYG{n}{m} \PYG{k}{as} \PYG{n}{m\PYGZsq{}} \PYG{o}{=\PYGZgt{}}
      \PYG{k}{match} \PYG{n}{dec} \PYG{n}{n} \PYG{n}{m} \PYG{k}{with}
      \PYG{o}{\textbar{}} \PYG{n}{or\PYGZus{}introl} \PYG{n}{h} \PYG{o}{=\PYGZgt{}} \PYG{n}{or\PYGZus{}introl} \PYG{o}{(}\PYG{n}{LE} \PYG{n}{m\PYGZsq{}} \PYG{n}{n\PYGZsq{}}\PYG{o}{)} \PYG{o}{(}\PYG{n}{LES} \PYG{n}{n} \PYG{n}{m} \PYG{n}{h}\PYG{o}{)}
      \PYG{o}{\textbar{}} \PYG{n}{or\PYGZus{}intror} \PYG{n}{h} \PYG{o}{=\PYGZgt{}} \PYG{n}{or\PYGZus{}intror} \PYG{o}{(}\PYG{n}{LE} \PYG{n}{n\PYGZsq{}} \PYG{n}{m\PYGZsq{}}\PYG{o}{)} \PYG{o}{(}\PYG{n}{LES} \PYG{n}{m} \PYG{n}{n} \PYG{n}{h}\PYG{o}{)}
      \PYG{k}{end}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

In the example of \sphinxcode{\sphinxupquote{\DUrole{name}{dec}}}, the first match is dependent while the second
is not.

The user can also use match in combination with the tactic {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.refine}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{refine}}}}} (see
Section 8.2.3) to build incomplete proofs beginning with a match
construction.


\subsection{Pattern-matching on inductive objects involving local definitions}
\label{\detokenize{addendum/extended-pattern-matching: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.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{k+kt}{list} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{:} \PYG{k+kt}{list} \PYG{l+m+mi}{0}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{k}{let} \PYG{n}{m} \PYG{o}{:=} \PYG{o}{(}\PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{n}\PYG{o}{)} \PYG{k}{in} \PYG{k+kt}{list} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{o}{(}\PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{m}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

In the next example, the local definition is not caught.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{length} \PYG{n}{n} \PYG{o}{(}\PYG{n}{l}\PYG{o}{:}\PYG{k+kt}{list} \PYG{n}{n}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{l}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
  \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{n}{n} \PYG{n}{l0} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{length} \PYG{o}{(}\PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{n}\PYG{o}{)} \PYG{n}{l0}\PYG{o}{)}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

But in this example, it is.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Fixpoint} \PYG{n}{length\PYGZsq{}} \PYG{n}{n} \PYG{o}{(}\PYG{n}{l}\PYG{o}{:}\PYG{k+kt}{list} \PYG{n}{n}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{k}{struct} \PYG{n}{l}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{l} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
  \PYG{o}{\textbar{}} \PYG{o}{@}\PYG{n}{cons} \PYG{o}{\PYGZus{}} \PYG{n}{m} \PYG{n}{l0} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{length\PYGZsq{}} \PYG{n}{m} \PYG{n}{l0}\PYG{o}{)}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
For a given matching clause, either none of the local
definitions or all of them can be caught.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Note:}
You can only catch let bindings in mode where you bind all
variables and so you have to use \sphinxcode{\sphinxupquote{@}} syntax.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{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.
\end{sphinxadmonition}


\subsection{Pattern-matching and coercions}
\label{\detokenize{addendum/extended-pattern-matching: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.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{I} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{:=}
  \PYG{o}{\textbar{}} \PYG{n}{C1} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{I}
  \PYG{o}{\textbar{}} \PYG{n}{C2} \PYG{o}{:} \PYG{n}{I} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{I}\PYG{o}{.}
\PYG{k+kn}{Coercion} \PYG{n}{C1} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{I}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{x} \PYG{k}{with}
                \PYG{o}{\textbar{}} \PYG{n}{C2} \PYG{n}{O} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
                \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
                \PYG{k}{end}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{I} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{x} \PYG{k}{with}
                 \PYG{o}{\textbar{}} \PYG{n}{C1} \PYG{o}{\PYGZus{}} \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{l+m+mi}{0}
                 \PYG{k}{end}
         \PYG{o}{:} \PYG{n}{I} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsection{When does the expansion strategy fail?}
\label{\detokenize{addendum/extended-pattern-matching: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 \sphinxcode{\sphinxupquote{(cons n O x) =\textgreater{} e1}} and
\sphinxcode{\sphinxupquote{(cons n \_ x) =\textgreater{} e2}} instead of \sphinxcode{\sphinxupquote{(cons n O x) =\textgreater{} e1}} and
\sphinxcode{\sphinxupquote{(cons n' \_ x') =\textgreater{} 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:
\index{The constructor ‘ident’ expects ‘num’ arguments (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extended-pattern-matching:coq:exn.the-constructor-ident-expects-num-arguments}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~constructor~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~expects~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{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).

\end{fulllineitems}

\index{Non exhaustive pattern matching (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extended-pattern-matching:coq:exn.non-exhaustive-pattern-matching}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Non~exhaustive~pattern~matching.}}}}
The pattern matching is not exhaustive.

\end{fulllineitems}

\index{The elimination predicate term should be of arity ‘num’ (for non dependent case) or ‘num’ (for dependent case) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extended-pattern-matching:coq:exn.the-elimination-predicate-term-should-be-of-arity-num-for-non-dependent-case-or-num-for-dependent-case}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{The~elimination~predicate~term~should~be~of~arity~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~(for~non~dependent~case)~or~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}~(for~dependent~case).}}}}
The elimination predicate provided to match has not the expected arity.

\end{fulllineitems}

\index{Unable to infer a match predicate (err)}\index{Either there is a type incompatibility or the problem involves dependencies (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extended-pattern-matching:coq:exn.unable-to-infer-a-match-predicate}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unable~to~infer~a~match~predicate}}}}\phantomsection\label{\detokenize{addendum/extended-pattern-matching:coq:exn.either-there-is-a-type-incompatibility-or-the-problem-involves-dependencies}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{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.

\end{fulllineitems}



\section{Implicit Coercions}
\label{\detokenize{addendum/implicit-coercions:implicit-coercions}}\label{\detokenize{addendum/implicit-coercions:implicitcoercions}}\label{\detokenize{addendum/implicit-coercions::doc}}\begin{quote}\begin{description}
\item[{Author}] \leavevmode
Amokrane Saïbi

\end{description}\end{quote}


\subsection{General Presentation}
\label{\detokenize{addendum/implicit-coercions:general-presentation}}
This section describes the inheritance mechanism of \DUrole{smallcaps}{Coq}. In \DUrole{smallcaps}{Coq} with
inheritance, we are not interested in adding any expressive power to
our theory, but only convenience. Given a term, possibly not typable,
we are interested in the problem of determining if it can be well
typed modulo insertion of appropriate coercions. We allow to write:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{\DUrole{name}{f} \DUrole{name}{a}}} where \sphinxcode{\sphinxupquote{\DUrole{name}{f}\DUrole{operator}{:(}\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A}\DUrole{operator}{,}\DUrole{name}{B}\DUrole{operator}{)}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{a}\DUrole{operator}{:}\DUrole{name}{A'}}} when \sphinxcode{\sphinxupquote{A'}} can
be seen in some sense as a subtype of \sphinxcode{\sphinxupquote{A}}.

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A}}} when \sphinxcode{\sphinxupquote{A}} is not a type, but can be seen in
a certain sense as a type: set, group, category etc.

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{name}{f} \DUrole{name}{a}}} when \sphinxcode{\sphinxupquote{f}} is not a function, but can be seen in a certain sense
as a function: bijection, functor, any structure morphism etc.

\end{itemize}


\subsection{Classes}
\label{\detokenize{addendum/implicit-coercions:classes}}
A class with \sphinxtitleref{n} parameters is any defined name with a type
\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{:}\DUrole{name}{A\(\sb{\text{1}}\)}\DUrole{operator}{)..(}\DUrole{name}{xₙ}\DUrole{operator}{:}\DUrole{name}{Aₙ}\DUrole{operator}{),}\DUrole{name}{s}}} where \sphinxcode{\sphinxupquote{s}} is a sort.  Thus a class with
parameters is considered as a single class and not as a family of
classes.  An object of a class \sphinxcode{\sphinxupquote{C}} is any term of type \sphinxcode{\sphinxupquote{\DUrole{name}{C} \DUrole{name}{t\(\sb{\text{1}}\)} \DUrole{operator}{..} \DUrole{name}{tₙ}}}.
In addition to these user-defined classes, we have two built-in classes:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{Sortclass}}, the class of sorts; its objects are the terms whose type is a
sort (e.g. \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Prop}}} or \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}}).

\item {} 
\sphinxcode{\sphinxupquote{Funclass}}, the class of functions; its objects are all the terms with a functional
type, i.e. of form \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A}\DUrole{operator}{,}\DUrole{name}{B}}}.

\end{itemize}

Formally, the syntax of a classes is defined as:


\begin{productionlist}
\phantomsection\label{\detokenize{addendum/implicit-coercions:grammar-token-class}}\production{class}{ qualid}
\productioncont{ \textbar{} \sphinxcode{\sphinxupquote{Sortclass}}}
\productioncont{ \textbar{} \sphinxcode{\sphinxupquote{Funclass}}}
\end{productionlist}



\subsection{Coercions}
\label{\detokenize{addendum/implicit-coercions:coercions}}
A name \sphinxcode{\sphinxupquote{f}} can be declared as a coercion between a source user-defined class
\sphinxcode{\sphinxupquote{C}} with \sphinxtitleref{n} parameters and a target class \sphinxcode{\sphinxupquote{D}} if one of these
conditions holds:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{D}} is a user-defined class, then the type of \sphinxcode{\sphinxupquote{f}} must have the form
\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{:}\DUrole{name}{A\(\sb{\text{1}}\)}\DUrole{operator}{)..(}\DUrole{name}{xₙ}\DUrole{operator}{:}\DUrole{name}{Aₙ}\DUrole{operator}{)(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C} \DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{xₙ}\DUrole{operator}{),} \DUrole{name}{D} \DUrole{name}{u\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{uₘ}}} where \sphinxtitleref{m}
is the number of parameters of \sphinxcode{\sphinxupquote{D}}.

\item {} 
\sphinxcode{\sphinxupquote{D}} is \sphinxcode{\sphinxupquote{Funclass}}, then the type of \sphinxcode{\sphinxupquote{f}} must have the form
\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{:}\DUrole{name}{A\(\sb{\text{1}}\)}\DUrole{operator}{)..(}\DUrole{name}{xₙ}\DUrole{operator}{:}\DUrole{name}{Aₙ}\DUrole{operator}{)(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C} \DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{xₙ}\DUrole{operator}{)(}\DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A}\DUrole{operator}{),} \DUrole{name}{B}}}.

\item {} 
\sphinxcode{\sphinxupquote{D}} is \sphinxcode{\sphinxupquote{Sortclass}}, then the type of \sphinxcode{\sphinxupquote{f}} must have the form
\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{:}\DUrole{name}{A\(\sb{\text{1}}\)}\DUrole{operator}{)..(}\DUrole{name}{xₙ}\DUrole{operator}{:}\DUrole{name}{Aₙ}\DUrole{operator}{)(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C} \DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{xₙ}\DUrole{operator}{),} \DUrole{name}{s}}} with \sphinxcode{\sphinxupquote{s}} a sort.

\end{itemize}

We then write \sphinxcode{\sphinxupquote{\DUrole{name}{f} \DUrole{operator}{:} \DUrole{name}{C} \DUrole{operator}{\textgreater{}-\textgreater{}} \DUrole{name}{D}}}. The restriction on the type
of coercions is called \sphinxstyleemphasis{the uniform inheritance condition}.

\begin{sphinxadmonition}{note}{Note:}
The built-in class \sphinxcode{\sphinxupquote{Sortclass}} can be used as a source class, but
the built-in class \sphinxcode{\sphinxupquote{Funclass}} cannot.
\end{sphinxadmonition}

To coerce an object \sphinxcode{\sphinxupquote{\DUrole{name}{t}\DUrole{operator}{:}\DUrole{name}{C} \DUrole{name}{t\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{tₙ}}} of \sphinxcode{\sphinxupquote{C}} towards \sphinxcode{\sphinxupquote{D}}, we have to
apply the coercion \sphinxcode{\sphinxupquote{f}} to it; the obtained term \sphinxcode{\sphinxupquote{\DUrole{name}{f} \DUrole{name}{t\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{tₙ} \DUrole{name}{t}}} is
then an object of \sphinxcode{\sphinxupquote{D}}.


\subsection{Identity Coercions}
\label{\detokenize{addendum/implicit-coercions:identity-coercions}}
Identity coercions are special cases of coercions used to go around
the uniform inheritance condition. Let \sphinxcode{\sphinxupquote{C}} and \sphinxcode{\sphinxupquote{D}} be two classes
with respectively \sphinxtitleref{n} and \sphinxtitleref{m} parameters and
\sphinxcode{\sphinxupquote{\DUrole{name}{f}\DUrole{operator}{:}\DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{:}\DUrole{name}{T\(\sb{\text{1}}\)}\DUrole{operator}{)..(}\DUrole{name}{xₖ}\DUrole{operator}{:}\DUrole{name}{Tₖ}\DUrole{operator}{)(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C} \DUrole{name}{u\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{uₙ}\DUrole{operator}{),} \DUrole{name}{D} \DUrole{name}{v\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{vₘ}}} a function which
does not verify the uniform inheritance condition. To declare \sphinxcode{\sphinxupquote{f}} as
coercion, one has first to declare a subclass \sphinxcode{\sphinxupquote{C'}} of \sphinxcode{\sphinxupquote{C}}:
\begin{quote}

\sphinxcode{\sphinxupquote{\DUrole{name}{C'} \DUrole{operator}{:=} \DUrole{keyword}{fun} \DUrole{operator}{(}\DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{:}\DUrole{name}{T\(\sb{\text{1}}\)}\DUrole{operator}{)..(}\DUrole{name}{xₖ}\DUrole{operator}{:}\DUrole{name}{Tₖ}\DUrole{operator}{)} \DUrole{operator}{=\textgreater{}} \DUrole{name}{C} \DUrole{name}{u\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{uₙ}}}
\end{quote}

We then define an \sphinxstyleemphasis{identity coercion} between \sphinxcode{\sphinxupquote{C'}} and \sphinxcode{\sphinxupquote{C}}:
\begin{quote}

\sphinxcode{\sphinxupquote{\DUrole{name}{Id\_C'\_C}  \DUrole{operator}{:=} \DUrole{keyword}{fun} \DUrole{operator}{(}\DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{:}\DUrole{name}{T\(\sb{\text{1}}\)}\DUrole{operator}{)..(}\DUrole{name}{xₖ}\DUrole{operator}{:}\DUrole{name}{Tₖ}\DUrole{operator}{)(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C'} \DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{xₖ}\DUrole{operator}{)} \DUrole{operator}{=\textgreater{}} \DUrole{operator}{(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C} \DUrole{name}{u\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{uₙ}\DUrole{operator}{)}}}
\end{quote}

We can now declare \sphinxcode{\sphinxupquote{f}} as coercion from \sphinxcode{\sphinxupquote{C'}} to \sphinxcode{\sphinxupquote{D}}, since we can
"cast" its type as
\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{:}\DUrole{name}{T\(\sb{\text{1}}\)}\DUrole{operator}{)..(}\DUrole{name}{xₖ}\DUrole{operator}{:}\DUrole{name}{Tₖ}\DUrole{operator}{)(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C'} \DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{xₖ}\DUrole{operator}{),}\DUrole{name}{D} \DUrole{name}{v\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{vₘ}}}.

The identity coercions have a special status: to coerce an object
\sphinxcode{\sphinxupquote{\DUrole{name}{t}\DUrole{operator}{:}\DUrole{name}{C'} \DUrole{name}{t\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{tₖ}}}
of \sphinxcode{\sphinxupquote{C'}} towards \sphinxcode{\sphinxupquote{C}}, we do not have to insert explicitly \sphinxcode{\sphinxupquote{Id\_C'\_C}}
since \sphinxcode{\sphinxupquote{\DUrole{name}{Id\_C'\_C} \DUrole{name}{t\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{tₖ} \DUrole{name}{t}}} is convertible with \sphinxcode{\sphinxupquote{t}}.  However we
"rewrite" the type of \sphinxcode{\sphinxupquote{t}} to become an object of \sphinxcode{\sphinxupquote{C}}; in this case,
it becomes \sphinxcode{\sphinxupquote{\DUrole{name}{C} \DUrole{name}{uₙ'}\DUrole{operator}{..}\DUrole{name}{uₖ'}}} where each \sphinxcode{\sphinxupquote{uᵢ'}} is the result of the
substitution in \sphinxcode{\sphinxupquote{uᵢ}} of the variables \sphinxcode{\sphinxupquote{xⱼ}} by \sphinxcode{\sphinxupquote{tⱼ}}.


\subsection{Inheritance Graph}
\label{\detokenize{addendum/implicit-coercions:inheritance-graph}}
Coercions form an inheritance graph with classes as nodes.  We call
\sphinxstyleemphasis{coercion path} an ordered list of coercions between two nodes of
the graph.  A class \sphinxcode{\sphinxupquote{C}} is said to be a subclass of \sphinxcode{\sphinxupquote{D}} if there is a
coercion path in the graph from \sphinxcode{\sphinxupquote{C}} to \sphinxcode{\sphinxupquote{D}}; we also say that \sphinxcode{\sphinxupquote{C}}
inherits from \sphinxcode{\sphinxupquote{D}}. Our mechanism supports multiple inheritance since a
class may inherit from several classes, contrary to simple inheritance
where a class inherits from at most one class.  However there must be
at most one path between two classes. If this is not the case, only
the \sphinxstyleemphasis{oldest} one is valid and the others are ignored. So the order
of declaration of coercions is important.

We extend notations for coercions to coercion paths. For instance
\sphinxcode{\sphinxupquote{\DUrole{operator}{{[}}\DUrole{name}{f\(\sb{\text{1}}\)}\DUrole{operator}{;..;}\DUrole{name}{fₖ}\DUrole{operator}{{]}} \DUrole{operator}{:} \DUrole{name}{C} \DUrole{operator}{\textgreater{}-\textgreater{}} \DUrole{name}{D}}} is the coercion path composed
by the coercions \sphinxcode{\sphinxupquote{f\(\sb{\text{1}}\)..fₖ}}.  The application of a coercion path to a
term consists of the successive application of its coercions.


\subsection{Declaring Coercions}
\label{\detokenize{addendum/implicit-coercions:declaring-coercions}}\index{Coercion (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:cmd.coercion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Coercion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~:~{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}~\textgreater{}-\textgreater{}~{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}}}}}
Declares the construction denoted by \sphinxtitleref{qualid} as a coercion between
the two given classes.
\index{‘qualid’ not declared (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:exn.qualid-not-declared}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~not~declared.}}}}
\end{fulllineitems}

\index{‘qualid’ is already a coercion (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:exn.qualid-is-already-a-coercion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~is~already~a~coercion.}}}}
\end{fulllineitems}

\index{Funclass cannot be a source class (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:exn.funclass-cannot-be-a-source-class}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Funclass~cannot~be~a~source~class.}}}}
\end{fulllineitems}

\index{‘qualid’ is not a function (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:exn.qualid-is-not-a-function}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~is~not~a~function.}}}}
\end{fulllineitems}

\index{Cannot find the source class of ‘qualid’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:exn.cannot-find-the-source-class-of-qualid}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~find~the~source~class~of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}.}}}}
\end{fulllineitems}

\index{Cannot recognize ‘class’ as a source class of ‘qualid’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:exn.cannot-recognize-class-as-a-source-class-of-qualid}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~recognize~{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}~as~a~source~class~of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}.}}}}
\end{fulllineitems}

\index{‘qualid’ does not respect the uniform inheritance condition (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:exn.qualid-does-not-respect-the-uniform-inheritance-condition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~does~not~respect~the~uniform~inheritance~condition.}}}}
\end{fulllineitems}

\index{Found target class ... instead of ... (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:exn.found-target-class-instead-of}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Found~target~class~...~instead~of~...}}}}
\end{fulllineitems}

\index{Ambiguous path (warn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:warn.ambiguous-path}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Warning}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ambiguous~path.}}}}
When the coercion {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{qualid}}}}} is added to the inheritance graph,
invalid coercion paths are ignored; they are signaled by a warning
displaying these paths of the form \sphinxcode{\sphinxupquote{\DUrole{operator}{{[}}\DUrole{name}{f\(\sb{\text{1}}\)}\DUrole{operator}{;..;}\DUrole{name}{fₙ}\DUrole{operator}{{]}} \DUrole{operator}{:} \DUrole{name}{C} \DUrole{operator}{\textgreater{}-\textgreater{}} \DUrole{name}{D}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Coercion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~:~{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}~\textgreater{}-\textgreater{}~{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}}}}}
Declares the construction denoted by \sphinxtitleref{qualid} as a coercion local to
the current section.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Coercion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This defines \sphinxtitleref{ident} just like \sphinxcode{\sphinxupquote{Definition}} \sphinxtitleref{ident} \sphinxcode{\sphinxupquote{:=}} \sphinxtitleref{term},
and then declares \sphinxtitleref{ident} as a coercion between it source and its target.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Coercion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
This defines \sphinxtitleref{ident} just like \sphinxcode{\sphinxupquote{Definition}} \sphinxtitleref{ident} : \sphinxtitleref{type} \sphinxcode{\sphinxupquote{:=}} \sphinxtitleref{term},
and then declares \sphinxtitleref{ident} as a coercion between it source and its target.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Coercion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This defines \sphinxtitleref{ident} just like \sphinxcode{\sphinxupquote{Let}} \sphinxtitleref{ident} \sphinxcode{\sphinxupquote{:=}} \sphinxtitleref{term},
and then declares \sphinxtitleref{ident} as a coercion between it source and its target.

\end{fulllineitems}


\end{fulllineitems}


Assumptions can be declared as coercions at declaration time.
This extends the grammar of assumptions from
Figure {\hyperref[\detokenize{language/gallina-specification-language:vernacular}]{\sphinxcrossref{\DUrole{std,std-ref}{The Vernacular}}}} as follows:


\begin{productionlist}
\phantomsection\label{\detokenize{addendum/implicit-coercions:grammar-token-assumption}}\production{assumption}{ assumption\_keyword assums .}
\phantomsection\label{\detokenize{addendum/implicit-coercions:grammar-token-assums}}\production{assums}{ simple\_assums}
\productioncont{ \textbar{} (simple\_assums) ... (simple\_assums)}
\phantomsection\label{\detokenize{addendum/implicit-coercions:grammar-token-simple_assums}}\production{simple\_assums}{ ident ... ident :{[}\textgreater{}{]} term}
\end{productionlist}


If the extra \sphinxcode{\sphinxupquote{\textgreater{}}} is present before the type of some assumptions, these
assumptions are declared as coercions.

Similarly, constructors of inductive types can be declared as coercions at
definition time of the inductive type. This extends and modifies the
grammar of inductive types from Figure {\hyperref[\detokenize{language/gallina-specification-language:vernacular}]{\sphinxcrossref{\DUrole{std,std-ref}{The Vernacular}}}} as follows:


\begin{productionlist}
\phantomsection\label{\detokenize{addendum/implicit-coercions:grammar-token-inductive}}\production{inductive}{ \sphinxcode{\sphinxupquote{Inductive}} ind\_body \sphinxcode{\sphinxupquote{with}} ... \sphinxcode{\sphinxupquote{with}} ind\_body}
\productioncont{ \textbar{} \sphinxcode{\sphinxupquote{CoInductive}} ind\_body \sphinxcode{\sphinxupquote{with}} ... \sphinxcode{\sphinxupquote{with}} ind\_body}
\phantomsection\label{\detokenize{addendum/implicit-coercions:grammar-token-ind_body}}\production{ind\_body}{ ident {[}binders{]} : term := {[}{[}\textbar{}{]} constructor \textbar{} ... \textbar{} constructor{]}}
\phantomsection\label{\detokenize{addendum/implicit-coercions:grammar-token-constructor}}\production{constructor}{ ident {[}binders{]} {[}:{[}\textgreater{}{]} term{]}}
\end{productionlist}


Especially, if the extra \sphinxcode{\sphinxupquote{\textgreater{}}} is present in a constructor
declaration, this constructor is declared as a coercion.
\index{Identity Coercion (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:cmd.identity-coercion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Identity~Coercion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}~\textgreater{}-\textgreater{}~{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}}}}}
If \sphinxcode{\sphinxupquote{C}} is the source \sphinxtitleref{class} and \sphinxcode{\sphinxupquote{D}} the destination, we check
that \sphinxcode{\sphinxupquote{C}} is a constant with a body of the form
\sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{operator}{(}\DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{:}\DUrole{name}{T\(\sb{\text{1}}\)}\DUrole{operator}{)..(}\DUrole{name}{xₙ}\DUrole{operator}{:}\DUrole{name}{Tₙ}\DUrole{operator}{)} \DUrole{operator}{=\textgreater{}} \DUrole{name}{D} \DUrole{name}{t\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{tₘ}}} where \sphinxtitleref{m} is the
number of parameters of \sphinxcode{\sphinxupquote{D}}.  Then we define an identity
function with type \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{:}\DUrole{name}{T\(\sb{\text{1}}\)}\DUrole{operator}{)..(}\DUrole{name}{xₙ}\DUrole{operator}{:}\DUrole{name}{Tₙ}\DUrole{operator}{)(}\DUrole{name}{y}\DUrole{operator}{:}\DUrole{name}{C} \DUrole{name}{x\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{xₙ}\DUrole{operator}{),}\DUrole{name}{D} \DUrole{name}{t\(\sb{\text{1}}\)}\DUrole{operator}{..}\DUrole{name}{tₘ}}},
and we declare it as an identity coercion between \sphinxcode{\sphinxupquote{C}} and \sphinxcode{\sphinxupquote{D}}.
\index{‘class’ must be a transparent constant (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:exn.class-must-be-a-transparent-constant}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}~must~be~a~transparent~constant.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~Identity~Coercion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\textgreater{}-\textgreater{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Same as \sphinxcode{\sphinxupquote{Identity Coercion}} but locally to the current section.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{SubClass~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{:name:~SubClass}}}}
If \sphinxtitleref{type} is a class \sphinxtitleref{ident'} applied to some arguments then
\sphinxtitleref{ident} is defined and an identity coercion of name
\sphinxtitleref{Id\_ident\_ident'} is
declared. Otherwise said, this is an abbreviation for
\begin{quote}

\sphinxcode{\sphinxupquote{Definition}} \sphinxtitleref{ident} \sphinxcode{\sphinxupquote{:=}} \sphinxtitleref{type}.

\sphinxcode{\sphinxupquote{Identity Coercion}} \sphinxtitleref{Id\_ident\_ident'} : \sphinxtitleref{ident} \sphinxcode{\sphinxupquote{\textgreater{}-\textgreater{}}} \sphinxtitleref{ident'}.
\end{quote}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Local~SubClass~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
Same as before but locally to the current section.

\end{fulllineitems}


\end{fulllineitems}



\subsection{Displaying Available Coercions}
\label{\detokenize{addendum/implicit-coercions:displaying-available-coercions}}\index{Print Classes (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:cmd.print-classes}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Classes}}}}
Print the list of declared classes in the current context.

\end{fulllineitems}

\index{Print Coercions (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:cmd.print-coercions}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Coercions}}}}
Print the list of declared coercions in the current context.

\end{fulllineitems}

\index{Print Graph (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:cmd.print-graph}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Graph}}}}
Print the list of valid coercion paths in the current context.

\end{fulllineitems}

\index{Print Coercion Paths (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:cmd.print-coercion-paths}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Coercion~Paths~{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}~{\hyperref[\detokenize{addendum/implicit-coercions:grammar-token-class}]{\sphinxcrossref{\DUrole{hole}{class}}}}}}}}
Print the list of valid coercion paths between the two given classes.

\end{fulllineitems}



\subsection{Activating the Printing of Coercions}
\label{\detokenize{addendum/implicit-coercions:activating-the-printing-of-coercions}}\index{Printing Coercions (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:flag.printing-coercions}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Coercions}}}}
When on, this option forces all the coercions to be printed.
By default, coercions are not printed.

\end{fulllineitems}

\index{Printing Coercion (table)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:table.printing-coercion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Table}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Printing~Coercion~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
Specifies a set of qualids for which coercions are always displayed.  Use the
{\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.add-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add @table}}}}} and {\hyperref[\detokenize{proof-engine/vernacular-commands:coq:cmd.remove-table}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Remove @table}}}}} commands to update the set of qualids.

\end{fulllineitems}



\subsection{Classes as Records}
\label{\detokenize{addendum/implicit-coercions:classes-as-records}}\label{\detokenize{addendum/implicit-coercions:coercions-classes-as-records}}
We allow the definition of \sphinxstyleemphasis{Structures with Inheritance} (or classes as records)
by extending the existing {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.record}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Record}}}}} macro. Its new syntax is:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Record~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textgreater{}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}}~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~\DUrole{curlies}{\{~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:\DUrole{repeat-wrapper}{\DUrole{repeat}{\textgreater{}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{;}}~\}}}}}}
The first identifier \sphinxtitleref{ident} is the name of the defined record and
\sphinxtitleref{sort} is its type. The optional identifier after \sphinxcode{\sphinxupquote{:=}} is the name
of the constuctor (it will be \sphinxcode{\sphinxupquote{Build\_}}\sphinxtitleref{ident} if not given).
The other identifiers are the names of the fields, and the \sphinxtitleref{term}
are their respective types. If \sphinxcode{\sphinxupquote{:\textgreater{}}} is used instead of \sphinxcode{\sphinxupquote{:}} in
the declaration of a field, then the name of this field is automatically
declared as a coercion from the record name to the class of this
field type. Remark that the fields always verify the uniform
inheritance condition. If the optional \sphinxcode{\sphinxupquote{\textgreater{}}} is given before the
record name, then the constructor name is automatically declared as
a coercion from the class of the last field type to the record name
(this may fail if the uniform inheritance condition is not
satisfied).

\end{fulllineitems}

\index{Structure (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:cmdv.structure}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Structure~\DUrole{repeat-wrapper}{\DUrole{repeat}{\textgreater{}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}}~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~\DUrole{curlies}{\{~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:\DUrole{repeat-wrapper}{\DUrole{repeat}{\textgreater{}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{;}}~\}}}}}}
This is a synonym of {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.record}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Record}}}}}.

\end{fulllineitems}



\subsection{Coercions and Sections}
\label{\detokenize{addendum/implicit-coercions:coercions-and-sections}}
The inheritance mechanism is compatible with the section
mechanism. The global classes and coercions defined inside a section
are redefined after its closing, using their new value and new
type. The classes and coercions which are local to the section are
simply forgotten.
Coercions with a local source class or a local target class, and
coercions which do not verify the uniform inheritance condition any longer
are also forgotten.


\subsection{Coercions and Modules}
\label{\detokenize{addendum/implicit-coercions:coercions-and-modules}}\index{Automatic Coercions Import (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/implicit-coercions:coq:flag.automatic-coercions-import}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Automatic~Coercions~Import}}}}
Since \DUrole{smallcaps}{Coq} version 8.3, the coercions present in a module are activated
only when the module is explicitly imported. Formerly, the coercions
were activated as soon as the module was required, whether it was
imported or not.

This option makes it possible to recover the behavior of the versions of
\DUrole{smallcaps}{Coq} prior to 8.3.

\end{fulllineitems}



\subsection{Examples}
\label{\detokenize{addendum/implicit-coercions:examples}}
There are three situations:


\subsubsection{Coercion at function application}
\label{\detokenize{addendum/implicit-coercions:coercion-at-function-application}}
\sphinxcode{\sphinxupquote{\DUrole{name}{f} \DUrole{name}{a}}} is ill-typed where \sphinxcode{\sphinxupquote{\DUrole{name}{f}\DUrole{operator}{:}\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A}\DUrole{operator}{,}\DUrole{name}{B}}} and \sphinxcode{\sphinxupquote{\DUrole{name}{a}\DUrole{operator}{:}\DUrole{name}{A'}}}. If there is a
coercion path between \sphinxcode{\sphinxupquote{A'}} and \sphinxcode{\sphinxupquote{A}}, then \sphinxcode{\sphinxupquote{\DUrole{name}{f} \DUrole{name}{a}}} is transformed into
\sphinxcode{\sphinxupquote{\DUrole{name}{f} \DUrole{name}{a'}}} where \sphinxcode{\sphinxupquote{a'}} is the result of the application of this
coercion path to \sphinxcode{\sphinxupquote{a}}.

We first give an example of coercion between atomic inductive types

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{bool\PYGZus{}in\PYGZus{}nat} \PYG{o}{(}\PYG{n}{b}\PYG{o}{:}\PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{:=} \PYG{k}{if} \PYG{n}{b} \PYG{k}{then} \PYG{l+m+mi}{0} \PYG{k}{else} \PYG{l+m+mi}{1}\PYG{o}{.}
    \PYG{n}{bool\PYGZus{}in\PYGZus{}nat} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Coercion} \PYG{n}{bool\PYGZus{}in\PYGZus{}nat} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{bool\PYGZus{}in\PYGZus{}nat} \PYG{k}{is} \PYG{n}{now} \PYG{n}{a} \PYG{n}{coercion}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n+nb+bp}{true}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n+nb+bp}{true}
         \PYG{o}{:} \PYG{k+kt}{Prop}

\PYG{k+kn}{Set} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n+nb+bp}{true}\PYG{o}{)}\PYG{o}{.}
    \PYG{l+m+mi}{0} \PYG{o}{=} \PYG{n}{bool\PYGZus{}in\PYGZus{}nat} \PYG{n+nb+bp}{true}
         \PYG{o}{:} \PYG{k+kt}{Prop}

\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{warning}{Warning:}
Note that \sphinxcode{\sphinxupquote{Check true=O}} would fail. This is "normal" behavior of
coercions. To validate \sphinxcode{\sphinxupquote{true=O}}, the coercion is searched from
\sphinxcode{\sphinxupquote{nat}} to \sphinxcode{\sphinxupquote{bool}}. There is none.
\end{sphinxadmonition}

We give an example of coercion between classes with parameters.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameters} \PYG{o}{(}\PYG{n}{C} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{D} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{E} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{C} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{D} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{E} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Parameter} \PYG{n}{f} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{C} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{D} \PYG{o}{(}\PYG{n}{S} \PYG{n}{n}\PYG{o}{)} \PYG{n+nb+bp}{true}\PYG{o}{.}
    \PYG{n}{f} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Coercion} \PYG{n}{f} \PYG{o}{:} \PYG{n}{C} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{D}\PYG{o}{.}
    \PYG{n}{f} \PYG{k}{is} \PYG{n}{now} \PYG{n}{a} \PYG{n}{coercion}

\PYG{k+kn}{Parameter} \PYG{n}{g} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{n}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{(}\PYG{n}{b}\PYG{o}{:}\PYG{k+kt}{bool}\PYG{o}{)}\PYG{o}{,} \PYG{n}{D} \PYG{n}{n} \PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{E} \PYG{n}{b}\PYG{o}{.}
    \PYG{n}{g} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Coercion} \PYG{n}{g} \PYG{o}{:} \PYG{n}{D} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{E}\PYG{o}{.}
    \PYG{n}{g} \PYG{k}{is} \PYG{n}{now} \PYG{n}{a} \PYG{n}{coercion}

\PYG{k+kn}{Parameter} \PYG{n}{c} \PYG{o}{:} \PYG{n}{C} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{c} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Parameter} \PYG{n}{T} \PYG{o}{:} \PYG{n}{E} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{T} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{T} \PYG{n}{c}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{T} \PYG{n}{c}
         \PYG{o}{:} \PYG{k+kt}{nat}

\PYG{k+kn}{Set} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{T} \PYG{n}{c}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{T} \PYG{o}{(}\PYG{n}{g} \PYG{l+m+mi}{1} \PYG{n+nb+bp}{true} \PYG{o}{(}\PYG{n}{f} \PYG{l+m+mi}{0} \PYG{n}{c}\PYG{o}{)}\PYG{o}{)}
         \PYG{o}{:} \PYG{k+kt}{nat}

\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\end{sphinxVerbatim}

We give now an example using identity coercions.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{D\PYGZsq{}} \PYG{o}{(}\PYG{n}{b}\PYG{o}{:}\PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{D} \PYG{l+m+mi}{1} \PYG{n}{b}\PYG{o}{.}
    \PYG{n}{D\PYGZsq{}} \PYG{k}{is} \PYG{n}{defined}

\PYG{n}{Identity} \PYG{k+kn}{Coercion} \PYG{n}{IdD\PYGZsq{}D} \PYG{o}{:} \PYG{n}{D\PYGZsq{}} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{D}\PYG{o}{.}
\PYG{k+kn}{Print} \PYG{n}{IdD\PYGZsq{}D}\PYG{o}{.}
    \PYG{n}{IdD\PYGZsq{}D} \PYG{o}{=} 
    \PYG{o}{(}\PYG{k}{fun} \PYG{o}{(}\PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{D\PYGZsq{}} \PYG{n}{b}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}\PYG{o}{)} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{n}{D\PYGZsq{}} \PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{D} \PYG{l+m+mi}{1} \PYG{n}{b}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{b} \PYG{o}{:} \PYG{k+kt}{bool}\PYG{o}{,} \PYG{n}{D\PYGZsq{}} \PYG{n}{b} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{D} \PYG{l+m+mi}{1} \PYG{n}{b}
    
    \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{bool\PYGZus{}scope} \PYG{o}{\PYGZus{}}\PYG{o}{]}
    \PYG{n}{IdD\PYGZsq{}D} \PYG{k}{is} \PYG{n}{a} \PYG{n}{coercion}

\PYG{k+kn}{Parameter} \PYG{n}{d\PYGZsq{}} \PYG{o}{:} \PYG{n}{D\PYGZsq{}} \PYG{n+nb+bp}{true}\PYG{o}{.}
    \PYG{n}{d\PYGZsq{}} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{T} \PYG{n}{d\PYGZsq{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{T} \PYG{n}{d\PYGZsq{}}
         \PYG{o}{:} \PYG{k+kt}{nat}

\PYG{k+kn}{Set} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{T} \PYG{n}{d\PYGZsq{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{T} \PYG{o}{(}\PYG{n}{g} \PYG{l+m+mi}{1} \PYG{n+nb+bp}{true} \PYG{n}{d\PYGZsq{}}\PYG{o}{)}
         \PYG{o}{:} \PYG{k+kt}{nat}

\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\end{sphinxVerbatim}

In the case of functional arguments, we use the monotonic rule of
sub-typing. To coerce \sphinxcode{\sphinxupquote{\DUrole{name}{t} \DUrole{operator}{:} \DUrole{keyword}{forall} \DUrole{name}{x} \DUrole{operator}{:} \DUrole{name}{A}\DUrole{operator}{,} \DUrole{name}{B}}} towards
\sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x} \DUrole{operator}{:} \DUrole{name}{A'}\DUrole{operator}{,} \DUrole{name}{B'}}}, we have to coerce \sphinxcode{\sphinxupquote{A'}} towards \sphinxcode{\sphinxupquote{A}} and \sphinxcode{\sphinxupquote{B}}
towards \sphinxcode{\sphinxupquote{B'}}. An example is given below:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameters} \PYG{o}{(}\PYG{n}{A} \PYG{n}{B} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{)} \PYG{o}{(}\PYG{n}{h} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{A} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{B} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{h} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Coercion} \PYG{n}{h} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{.}
    \PYG{n}{h} \PYG{k}{is} \PYG{n}{now} \PYG{n}{a} \PYG{n}{coercion}

\PYG{k+kn}{Parameter} \PYG{n}{U} \PYG{o}{:} \PYG{o}{(}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{E} \PYG{n+nb+bp}{true}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{U} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Parameter} \PYG{n}{t} \PYG{o}{:} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{C} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{n}{t} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{U} \PYG{n}{t}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{U} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{A} \PYG{o}{=\PYGZgt{}} \PYG{n}{t} \PYG{n}{x}\PYG{o}{)}
         \PYG{o}{:} \PYG{k+kt}{nat}

\PYG{k+kn}{Set} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{U} \PYG{n}{t}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{U} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{A} \PYG{o}{=\PYGZgt{}} \PYG{n}{g} \PYG{l+m+mi}{1} \PYG{n+nb+bp}{true} \PYG{o}{(}\PYG{n}{f} \PYG{l+m+mi}{0} \PYG{o}{(}\PYG{n}{t} \PYG{o}{(}\PYG{n}{h} \PYG{n}{x}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}
         \PYG{o}{:} \PYG{k+kt}{nat}

\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\end{sphinxVerbatim}

Remark the changes in the result following the modification of the
previous example.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{U\PYGZsq{}} \PYG{o}{:} \PYG{o}{(}\PYG{n}{C} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{)} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{U\PYGZsq{}} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Parameter} \PYG{n}{t\PYGZsq{}} \PYG{o}{:} \PYG{n}{E} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}\PYG{o}{.}
    \PYG{n}{t\PYGZsq{}} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{U\PYGZsq{}} \PYG{n}{t\PYGZsq{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{U\PYGZsq{}} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{C} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{t\PYGZsq{}} \PYG{n}{x}\PYG{o}{)}
         \PYG{o}{:} \PYG{k+kt}{nat}

\PYG{k+kn}{Set} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{U\PYGZsq{}} \PYG{n}{t\PYGZsq{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{U\PYGZsq{}} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{n}{C} \PYG{l+m+mi}{0} \PYG{o}{=\PYGZgt{}} \PYG{n}{h} \PYG{o}{(}\PYG{n}{t\PYGZsq{}} \PYG{o}{(}\PYG{n}{g} \PYG{l+m+mi}{1} \PYG{n+nb+bp}{true} \PYG{o}{(}\PYG{n}{f} \PYG{l+m+mi}{0} \PYG{n}{x}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}
         \PYG{o}{:} \PYG{k+kt}{nat}

\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Coercion to a type}
\label{\detokenize{addendum/implicit-coercions:coercion-to-a-type}}
An assumption \sphinxcode{\sphinxupquote{x:A}} when \sphinxcode{\sphinxupquote{A}} is not a type, is ill-typed.  It is
replaced by \sphinxcode{\sphinxupquote{x:A'}} where \sphinxcode{\sphinxupquote{A'}} is the result of the application to
\sphinxcode{\sphinxupquote{A}} of the coercion path between the class of \sphinxcode{\sphinxupquote{A}} and
\sphinxcode{\sphinxupquote{Sortclass}} if it exists.  This case occurs in the abstraction
\sphinxcode{\sphinxupquote{\DUrole{keyword}{fun} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A} \DUrole{operator}{=\textgreater{}} \DUrole{name}{t}}}, universal quantification \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A}\DUrole{operator}{,}\DUrole{name}{B}}}, global
variables and parameters of (co-)inductive definitions and
functions. In \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{name}{x}\DUrole{operator}{:}\DUrole{name}{A}\DUrole{operator}{,}\DUrole{name}{B}}}, such a coercion path may also be applied
to \sphinxcode{\sphinxupquote{B}} if necessary.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{k+kn}{Graph} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{.}
    \PYG{k+kn}{Graph} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Parameter} \PYG{n}{Node} \PYG{o}{:} \PYG{k+kn}{Graph} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{.}
    \PYG{n}{Node} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Coercion} \PYG{n}{Node} \PYG{o}{:} \PYG{k+kn}{Graph} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Sortclass}\PYG{o}{.}
    \PYG{n}{Node} \PYG{k}{is} \PYG{n}{now} \PYG{n}{a} \PYG{n}{coercion}

\PYG{k+kn}{Parameter} \PYG{n}{G} \PYG{o}{:} \PYG{k+kn}{Graph}\PYG{o}{.}
    \PYG{n}{G} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Parameter} \PYG{n}{Arrows} \PYG{o}{:} \PYG{n}{G} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{G} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{.}
    \PYG{n}{Arrows} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Check} \PYG{n}{Arrows}\PYG{o}{.}
    \PYG{n}{Arrows}
         \PYG{o}{:} \PYG{n}{G} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{G} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}

\PYG{k+kn}{Parameter} \PYG{n}{fg} \PYG{o}{:} \PYG{n}{G} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{G}\PYG{o}{.}
    \PYG{n}{fg} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Check} \PYG{n}{fg}\PYG{o}{.}
    \PYG{n}{fg}
         \PYG{o}{:} \PYG{n}{G} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{G}

\PYG{k+kn}{Set} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{n}{fg}\PYG{o}{.}
    \PYG{n}{fg}
         \PYG{o}{:} \PYG{n}{Node} \PYG{n}{G} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Node} \PYG{n}{G}

\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Coercion to a function}
\label{\detokenize{addendum/implicit-coercions:coercion-to-a-function}}
\sphinxcode{\sphinxupquote{f a}} is ill-typed because \sphinxcode{\sphinxupquote{f:A}} is not a function. The term
\sphinxcode{\sphinxupquote{f}} is replaced by the term obtained by applying to \sphinxcode{\sphinxupquote{f}} the
coercion path between \sphinxcode{\sphinxupquote{A}} and \sphinxcode{\sphinxupquote{Funclass}} if it exists.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Parameter} \PYG{n}{bij} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{.}
    \PYG{n}{bij} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Parameter} \PYG{n}{ap} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{,} \PYG{n}{bij} \PYG{n}{A} \PYG{n}{B} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}\PYG{o}{.}
    \PYG{n}{ap} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Coercion} \PYG{n}{ap} \PYG{o}{:} \PYG{n}{bij} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Funclass}\PYG{o}{.}
    \PYG{n}{ap} \PYG{k}{is} \PYG{n}{now} \PYG{n}{a} \PYG{n}{coercion}

\PYG{k+kn}{Parameter} \PYG{n}{b} \PYG{o}{:} \PYG{n}{bij} \PYG{k+kt}{nat} \PYG{k+kt}{nat}\PYG{o}{.}
    \PYG{n}{b} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{b} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{b} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{k+kt}{nat}

\PYG{k+kn}{Set} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{b} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{ap} \PYG{k+kt}{nat} \PYG{k+kt}{nat} \PYG{n}{b} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{k+kt}{nat}

\PYG{k+kn}{Unset} \PYG{k+kn}{Printing} \PYG{n}{Coercions}\PYG{o}{.}
\end{sphinxVerbatim}

Let us see the resulting graph after all these examples.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{k+kn}{Graph}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{bool\PYGZus{}in\PYGZus{}nat}\PYG{o}{]} \PYG{o}{:} \PYG{k+kt}{bool} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
    \PYG{o}{[}\PYG{n}{f}\PYG{o}{]} \PYG{o}{:} \PYG{n}{C} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{D}
    \PYG{o}{[}\PYG{n}{f}\PYG{o}{;} \PYG{n}{g}\PYG{o}{]} \PYG{o}{:} \PYG{n}{C} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{E}
    \PYG{o}{[}\PYG{n}{g}\PYG{o}{]} \PYG{o}{:} \PYG{n}{D} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{E}
    \PYG{o}{[}\PYG{n}{IdD\PYGZsq{}D}\PYG{o}{]} \PYG{o}{:} \PYG{n}{D\PYGZsq{}} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{D}
    \PYG{o}{[}\PYG{n}{IdD\PYGZsq{}D}\PYG{o}{;} \PYG{n}{g}\PYG{o}{]} \PYG{o}{:} \PYG{n}{D\PYGZsq{}} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{E}
    \PYG{o}{[}\PYG{n}{h}\PYG{o}{]} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{B}
    \PYG{o}{[}\PYG{n}{Node}\PYG{o}{]} \PYG{o}{:} \PYG{k+kn}{Graph} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Sortclass}
    \PYG{o}{[}\PYG{n}{ap}\PYG{o}{]} \PYG{o}{:} \PYG{n}{bij} \PYG{o}{\PYGZgt{}}\PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Funclass}
\end{sphinxVerbatim}


\section{Canonical Structures}
\label{\detokenize{addendum/canonical-structures:canonical-structures}}\label{\detokenize{addendum/canonical-structures:canonicalstructures}}\label{\detokenize{addendum/canonical-structures::doc}}\begin{quote}\begin{description}
\item[{Authors}] \leavevmode
Assia Mahboubi and Enrico Tassi

\end{description}\end{quote}

This chapter explains the basics of canonical structures and how they can be used
to overload notations and build a hierarchy of algebraic structures. The
examples are taken from \sphinxcite{zebibliography:cswcu}. We invite the interested reader to refer
to this paper for all the details that are omitted here for brevity. The
interested reader shall also find in \sphinxcite{zebibliography:cslessadhoc} a detailed description
of another, complementary, use of canonical structures: advanced proof search.
This latter papers also presents many techniques one can employ to tune the
inference of canonical structures.


\subsection{Notation overloading}
\label{\detokenize{addendum/canonical-structures:notation-overloading}}
We build an infix notation == for a comparison predicate. Such
notation will be overloaded, and its meaning will depend on the types
of the terms that are compared.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{EQ}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{EQ} \PYG{n}{started}

\PYG{k+kn}{Record} \PYG{n}{class} \PYG{o}{(}\PYG{n}{T} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:=} \PYG{k+kn}{Class} \PYG{o}{\PYGZob{}} \PYG{n}{cmp} \PYG{o}{:} \PYG{n}{T} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{T} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{class} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{cmp} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Structure} \PYG{n}{type} \PYG{o}{:=} \PYG{n}{Pack} \PYG{o}{\PYGZob{}} \PYG{n}{obj} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{;} \PYG{n}{class\PYGZus{}of} \PYG{o}{:} \PYG{n}{class} \PYG{n}{obj} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{type} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{obj} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{class\PYGZus{}of} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{op} \PYG{o}{(}\PYG{n}{e} \PYG{o}{:} \PYG{n}{type}\PYG{o}{)} \PYG{o}{:} \PYG{n}{obj} \PYG{n}{e} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{obj} \PYG{n}{e} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
    \PYG{k}{let} \PYG{k}{\PYGZsq{}}\PYG{n}{Pack} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{k+kn}{Class} \PYG{o}{\PYGZus{}} \PYG{n}{the\PYGZus{}cmp}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{e} \PYG{k}{in} \PYG{n}{the\PYGZus{}cmp}\PYG{o}{.}
    \PYG{n}{op} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Check} \PYG{n}{op}\PYG{o}{.}
    \PYG{n}{op}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{e} \PYG{o}{:} \PYG{n}{type}\PYG{o}{,} \PYG{n}{obj} \PYG{n}{e} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{obj} \PYG{n}{e} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}

\PYG{k+kn}{Arguments} \PYG{n}{op} \PYG{o}{\PYGZob{}}\PYG{n}{e}\PYG{o}{\PYGZcb{}} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{k}{simpl} \PYG{n}{never}\PYG{o}{.}
\PYG{k+kn}{Arguments} \PYG{k+kn}{Class} \PYG{o}{\PYGZob{}}\PYG{n}{T}\PYG{o}{\PYGZcb{}} \PYG{n}{cmp}\PYG{o}{.}
\PYG{k+kn}{Module} \PYG{n}{theory}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{theory} \PYG{n}{started}

\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x == y}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{op} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{70}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{theory}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{theory} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{End} \PYG{n}{EQ}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{EQ} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

We use Coq modules as namespaces. This allows us to follow the same
pattern and naming convention for the rest of the chapter. The base
namespace contains the definitions of the algebraic structure. To
keep the example small, the algebraic structure \sphinxcode{\sphinxupquote{EQ.type}} we are
defining is very simplistic, and characterizes terms on which a binary
relation is defined, without requiring such relation to validate any
property. The inner theory module contains the overloaded notation \sphinxcode{\sphinxupquote{==}}
and will eventually contain lemmas holding all the instances of the
algebraic structure (in this case there are no lemmas).

Note that in practice the user may want to declare \sphinxcode{\sphinxupquote{EQ.obj}} as a
coercion, but we will not do that here.

The following line tests that, when we assume a type \sphinxcode{\sphinxupquote{e}} that is in
theEQ class, we can relate two of its objects with \sphinxcode{\sphinxupquote{==}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Import} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{theory}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{e} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e}\PYG{o}{)}\PYG{o}{,} \PYG{n}{a} \PYG{o}{=}\PYG{o}{=} \PYG{n}{b}\PYG{o}{.}
    \PYG{k}{forall} \PYG{o}{(}\PYG{n}{e} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e}\PYG{o}{)}\PYG{o}{,} \PYG{n}{a} \PYG{o}{=}\PYG{o}{=} \PYG{n}{b}
         \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}

Still, no concrete type is in the \sphinxcode{\sphinxupquote{EQ}} class.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{l+m+mi}{3} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{3}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{3}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{nat}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{while} \PYG{n}{it} \PYG{k}{is} \PYG{n}{expected} \PYG{n}{to} \PYG{k}{have} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{EQ.obj ?e}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

We amend that by equipping \sphinxcode{\sphinxupquote{nat}} with a comparison relation.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{nat\PYGZus{}eq} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{compare} \PYG{n}{x} \PYG{n}{y} \PYG{o}{=} \PYG{n}{Eq}\PYG{o}{.}
    \PYG{n}{nat\PYGZus{}eq} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{nat\PYGZus{}EQcl} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{class} \PYG{k+kt}{nat} \PYG{o}{:=} \PYG{n}{EQ}\PYG{o}{.}\PYG{k+kn}{Class} \PYG{n}{nat\PYGZus{}eq}\PYG{o}{.}
    \PYG{n}{nat\PYGZus{}EQcl} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Canonical} \PYG{k+kn}{Structure} \PYG{n}{nat\PYGZus{}EQty} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{type} \PYG{o}{:=} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{Pack} \PYG{k+kt}{nat} \PYG{n}{nat\PYGZus{}EQcl}\PYG{o}{.}
    \PYG{n}{nat\PYGZus{}EQty} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Check} \PYG{l+m+mi}{3} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{3}\PYG{o}{.}
    \PYG{l+m+mi}{3} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{3}
         \PYG{o}{:} \PYG{k+kt}{Prop}

\PYG{n}{Eval} \PYG{k}{compute} \PYG{k}{in} \PYG{l+m+mi}{3} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{4}\PYG{o}{.}
    \PYG{o}{=} \PYG{n}{Lt} \PYG{o}{=} \PYG{n}{Eq}
         \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}

This last test shows that \DUrole{smallcaps}{Coq} is now not only able to type check \sphinxcode{\sphinxupquote{3 == 3}},
but also that the infix relation was bound to the \sphinxcode{\sphinxupquote{nat\_eq}} relation.
This relation is selected whenever \sphinxcode{\sphinxupquote{==}} is used on terms of type nat.
This can be read in the line declaring the canonical structure
\sphinxcode{\sphinxupquote{nat\_EQty}}, where the first argument to \sphinxcode{\sphinxupquote{Pack}} is the key and its second
argument a group of canonical values associated to the key. In this
case we associate to nat only one canonical value (since its class,
\sphinxcode{\sphinxupquote{nat\_EQcl}} has just one member). The use of the projection \sphinxcode{\sphinxupquote{op}} requires
its argument to be in the class \sphinxcode{\sphinxupquote{EQ}}, and uses such a member (function)
to actually compare its arguments.

Similarly, we could equip any other type with a comparison relation,
and use the \sphinxcode{\sphinxupquote{==}} notation on terms of this type.


\subsubsection{Derived Canonical Structures}
\label{\detokenize{addendum/canonical-structures:derived-canonical-structures}}
We know how to use \sphinxcode{\sphinxupquote{== {}`{}` on base types, like {}`{}`nat}}, \sphinxcode{\sphinxupquote{bool}}, \sphinxcode{\sphinxupquote{Z}}. Here we show
how to deal with type constructors, i.e. how to make the following
example work:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{e} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e}\PYG{o}{)}\PYG{o}{,} \PYG{o}{(}\PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{)} \PYG{o}{=}\PYG{o}{=} \PYG{o}{(}\PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{In} \PYG{n}{environment}
    \PYG{n}{e} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{type}
    \PYG{n}{a} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e}
    \PYG{n}{b} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{(a, b)}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{(EQ.obj e * EQ.obj e)\PYGZpc{}type}\PYG{l+s+s2}{\PYGZdq{}}
    \PYG{n}{while} \PYG{n}{it} \PYG{k}{is} \PYG{n}{expected} \PYG{n}{to} \PYG{k}{have} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{EQ.obj ?e}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

The error message is telling that \DUrole{smallcaps}{Coq} has no idea on how to compare
pairs of objects. The following construction is telling Coq exactly
how to do that.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{pair\PYGZus{}eq} \PYG{o}{(}\PYG{n}{e1} \PYG{n}{e2} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e1} \PYG{o}{*} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e2}\PYG{o}{)} \PYG{o}{:=}
  \PYG{n}{fst} \PYG{n}{x} \PYG{o}{=}\PYG{o}{=} \PYG{n}{fst} \PYG{n}{y} \PYG{o}{/\PYGZbs{}} \PYG{n}{snd} \PYG{n}{x} \PYG{o}{=}\PYG{o}{=} \PYG{n}{snd} \PYG{n}{y}\PYG{o}{.}
    \PYG{n}{pair\PYGZus{}eq} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{pair\PYGZus{}EQcl} \PYG{n}{e1} \PYG{n}{e2} \PYG{o}{:=} \PYG{n}{EQ}\PYG{o}{.}\PYG{k+kn}{Class} \PYG{o}{(}\PYG{n}{pair\PYGZus{}eq} \PYG{n}{e1} \PYG{n}{e2}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{pair\PYGZus{}EQcl} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Canonical} \PYG{k+kn}{Structure} \PYG{n}{pair\PYGZus{}EQty} \PYG{o}{(}\PYG{n}{e1} \PYG{n}{e2} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{type} \PYG{o}{:=}
    \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{Pack} \PYG{o}{(}\PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e1} \PYG{o}{*} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e2}\PYG{o}{)} \PYG{o}{(}\PYG{n}{pair\PYGZus{}EQcl} \PYG{n}{e1} \PYG{n}{e2}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{pair\PYGZus{}EQty} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Check} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{e} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e}\PYG{o}{)}\PYG{o}{,} \PYG{o}{(}\PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{)} \PYG{o}{=}\PYG{o}{=} \PYG{o}{(}\PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{forall} \PYG{o}{(}\PYG{n}{e} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e}\PYG{o}{)}\PYG{o}{,} \PYG{o}{(}\PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{)} \PYG{o}{=}\PYG{o}{=} \PYG{o}{(}\PYG{n}{a}\PYG{o}{,} \PYG{n}{b}\PYG{o}{)}
         \PYG{o}{:} \PYG{k+kt}{Prop}

\PYG{k+kn}{Check} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{o}{(}\PYG{l+m+mi}{3}\PYG{o}{,} \PYG{l+m+mi}{4}\PYG{o}{)} \PYG{o}{=}\PYG{o}{=} \PYG{o}{(}\PYG{n}{n}\PYG{o}{,} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
    \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{o}{(}\PYG{l+m+mi}{3}\PYG{o}{,} \PYG{l+m+mi}{4}\PYG{o}{)} \PYG{o}{=}\PYG{o}{=} \PYG{o}{(}\PYG{n}{n}\PYG{o}{,} \PYG{n}{m}\PYG{o}{)}
         \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}

Thanks to the \sphinxcode{\sphinxupquote{pair\_EQty}} declaration, \DUrole{smallcaps}{Coq} is able to build a comparison
relation for pairs whenever it is able to build a comparison relation
for each component of the pair. The declaration associates to the key \sphinxcode{\sphinxupquote{*}}
(the type constructor of pairs) the canonical comparison
relation \sphinxcode{\sphinxupquote{pair\_eq}} whenever the type constructor \sphinxcode{\sphinxupquote{*}} is applied to two
types being themselves in the \sphinxcode{\sphinxupquote{EQ}} class.


\subsection{Hierarchy of structures}
\label{\detokenize{addendum/canonical-structures:hierarchy-of-structures}}
To get to an interesting example we need another base class to be
available. We choose the class of types that are equipped with an
order relation, to which we associate the infix \sphinxcode{\sphinxupquote{\textless{}=}} notation.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{LE}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{LE} \PYG{n}{started}

\PYG{k+kn}{Record} \PYG{n}{class} \PYG{n}{T} \PYG{o}{:=} \PYG{k+kn}{Class} \PYG{o}{\PYGZob{}} \PYG{n}{cmp} \PYG{o}{:} \PYG{n}{T} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{T} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{class} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{cmp} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Structure} \PYG{n}{type} \PYG{o}{:=} \PYG{n}{Pack} \PYG{o}{\PYGZob{}} \PYG{n}{obj} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{;} \PYG{n}{class\PYGZus{}of} \PYG{o}{:} \PYG{n}{class} \PYG{n}{obj} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{type} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{obj} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{class\PYGZus{}of} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{op} \PYG{o}{(}\PYG{n}{e} \PYG{o}{:} \PYG{n}{type}\PYG{o}{)} \PYG{o}{:} \PYG{n}{obj} \PYG{n}{e} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{obj} \PYG{n}{e} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop} \PYG{o}{:=}
    \PYG{k}{let} \PYG{k}{\PYGZsq{}}\PYG{n}{Pack} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{k+kn}{Class} \PYG{o}{\PYGZus{}} \PYG{n}{f}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{e} \PYG{k}{in} \PYG{n}{f}\PYG{o}{.}
    \PYG{n}{op} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Arguments} \PYG{n}{op} \PYG{o}{\PYGZob{}}\PYG{o}{\PYGZus{}}\PYG{o}{\PYGZcb{}} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{k}{simpl} \PYG{n}{never}\PYG{o}{.}
\PYG{k+kn}{Arguments} \PYG{k+kn}{Class} \PYG{o}{\PYGZob{}}\PYG{n}{T}\PYG{o}{\PYGZcb{}} \PYG{n}{cmp}\PYG{o}{.}
\PYG{k+kn}{Module} \PYG{n}{theory}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{theory} \PYG{n}{started}

\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x \PYGZlt{}= y}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{op} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{70}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{theory}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{theory} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{End} \PYG{n}{LE}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{LE} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

As before we register a canonical \sphinxcode{\sphinxupquote{LE}} class for \sphinxcode{\sphinxupquote{nat}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Import} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{theory}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{nat\PYGZus{}le} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:=} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{compare} \PYG{n}{x} \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{n}{Gt}\PYG{o}{.}
    \PYG{n}{nat\PYGZus{}le} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{nat\PYGZus{}LEcl} \PYG{o}{:} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{class} \PYG{k+kt}{nat} \PYG{o}{:=} \PYG{n}{LE}\PYG{o}{.}\PYG{k+kn}{Class} \PYG{n}{nat\PYGZus{}le}\PYG{o}{.}
    \PYG{n}{nat\PYGZus{}LEcl} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Canonical} \PYG{k+kn}{Structure} \PYG{n}{nat\PYGZus{}LEty} \PYG{o}{:} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{type} \PYG{o}{:=} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{Pack} \PYG{k+kt}{nat} \PYG{n}{nat\PYGZus{}LEcl}\PYG{o}{.}
    \PYG{n}{nat\PYGZus{}LEty} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

And we enable \DUrole{smallcaps}{Coq} to relate pair of terms with \sphinxcode{\sphinxupquote{\textless{}=}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{pair\PYGZus{}le} \PYG{n}{e1} \PYG{n}{e2} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e1} \PYG{o}{*} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e2}\PYG{o}{)} \PYG{o}{:=}
   \PYG{n}{fst} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{fst} \PYG{n}{y} \PYG{o}{/\PYGZbs{}} \PYG{n}{snd} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{snd} \PYG{n}{y}\PYG{o}{.}
    \PYG{n}{pair\PYGZus{}le} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{pair\PYGZus{}LEcl} \PYG{n}{e1} \PYG{n}{e2} \PYG{o}{:=} \PYG{n}{LE}\PYG{o}{.}\PYG{k+kn}{Class} \PYG{o}{(}\PYG{n}{pair\PYGZus{}le} \PYG{n}{e1} \PYG{n}{e2}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{pair\PYGZus{}LEcl} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Canonical} \PYG{k+kn}{Structure} \PYG{n}{pair\PYGZus{}LEty} \PYG{o}{(}\PYG{n}{e1} \PYG{n}{e2} \PYG{o}{:} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{:} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{type} \PYG{o}{:=}
   \PYG{n}{LE}\PYG{o}{.}\PYG{n}{Pack} \PYG{o}{(}\PYG{n}{LE}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e1} \PYG{o}{*} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e2}\PYG{o}{)} \PYG{o}{(}\PYG{n}{pair\PYGZus{}LEcl} \PYG{n}{e1} \PYG{n}{e2}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{pair\PYGZus{}LEty} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{l+m+mi}{3}\PYG{o}{,}\PYG{l+m+mi}{4}\PYG{o}{,}\PYG{l+m+mi}{5}\PYG{o}{)} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{o}{(}\PYG{l+m+mi}{3}\PYG{o}{,}\PYG{l+m+mi}{4}\PYG{o}{,}\PYG{l+m+mi}{5}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{(}\PYG{l+m+mi}{3}\PYG{o}{,} \PYG{l+m+mi}{4}\PYG{o}{,} \PYG{l+m+mi}{5}\PYG{o}{)} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{o}{(}\PYG{l+m+mi}{3}\PYG{o}{,} \PYG{l+m+mi}{4}\PYG{o}{,} \PYG{l+m+mi}{5}\PYG{o}{)}
         \PYG{o}{:} \PYG{k+kt}{Prop}
\end{sphinxVerbatim}

At the current stage we can use \sphinxcode{\sphinxupquote{==}} and \sphinxcode{\sphinxupquote{\textless{}=}} on concrete types, like
tuples of natural numbers, but we can’t develop an algebraic theory
over the types that are equipped with both relations.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{l+m+mi}{2} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{3} \PYG{o}{/\PYGZbs{}} \PYG{l+m+mi}{2} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{3} \PYG{o}{/\PYGZbs{}} \PYG{l+m+mi}{2} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{2}
         \PYG{o}{:} \PYG{k+kt}{Prop}

\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{e} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e}\PYG{o}{)}\PYG{o}{,} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{=}\PYG{o}{=} \PYG{n}{y}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{In} \PYG{n}{environment}
    \PYG{n}{e} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{type}
    \PYG{n}{x} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e}
    \PYG{n}{y} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{EQ.obj e}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{while} \PYG{n}{it} \PYG{k}{is} \PYG{n}{expected} \PYG{n}{to} \PYG{k}{have} \PYG{n}{type}
     \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{LE.obj ?e}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}

\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{e} \PYG{o}{:} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e}\PYG{o}{)}\PYG{o}{,} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{=}\PYG{o}{=} \PYG{n}{y}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{In} \PYG{n}{environment}
    \PYG{n}{e} \PYG{o}{:} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{type}
    \PYG{n}{x} \PYG{o}{:} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e}
    \PYG{n}{y} \PYG{o}{:} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{x}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{LE.obj e}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{while} \PYG{n}{it} \PYG{k}{is} \PYG{n}{expected} \PYG{n}{to} \PYG{k}{have} \PYG{n}{type}
     \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{EQ.obj ?e}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

We need to define a new class that inherits from both \sphinxcode{\sphinxupquote{EQ}} and \sphinxcode{\sphinxupquote{LE}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{LEQ}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{LEQ} \PYG{n}{started}

\PYG{k+kn}{Record} \PYG{n}{mixin} \PYG{o}{(}\PYG{n}{e} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{le} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:=}
    \PYG{n}{Mixin} \PYG{o}{\PYGZob{}} \PYG{n}{compat} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e}\PYG{o}{,} \PYG{n}{le} \PYG{n}{x} \PYG{n}{y} \PYG{o}{/\PYGZbs{}} \PYG{n}{le} \PYG{n}{y} \PYG{n}{x} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{=}\PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{mixin} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{compat} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Record} \PYG{n}{class} \PYG{n}{T} \PYG{o}{:=} \PYG{k+kn}{Class} \PYG{o}{\PYGZob{}}
                      \PYG{n}{EQ\PYGZus{}class} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{class} \PYG{n}{T}\PYG{o}{;}
                      \PYG{n}{LE\PYGZus{}class} \PYG{o}{:} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{class} \PYG{n}{T}\PYG{o}{;}
                      \PYG{n}{extra} \PYG{o}{:} \PYG{n}{mixin} \PYG{o}{(}\PYG{n}{EQ}\PYG{o}{.}\PYG{n}{Pack} \PYG{n}{T} \PYG{n}{EQ\PYGZus{}class}\PYG{o}{)} \PYG{o}{(}\PYG{n}{LE}\PYG{o}{.}\PYG{n}{cmp} \PYG{n}{T} \PYG{n}{LE\PYGZus{}class}\PYG{o}{)} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{class} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{EQ\PYGZus{}class} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{LE\PYGZus{}class} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{extra} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Structure} \PYG{n}{type} \PYG{o}{:=} \PYG{o}{\PYGZus{}}\PYG{n}{Pack} \PYG{o}{\PYGZob{}} \PYG{n}{obj} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{;} \PYG{n}{class\PYGZus{}of} \PYG{o}{:} \PYG{n}{class} \PYG{n}{obj} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{type} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{obj} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{class\PYGZus{}of} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Arguments} \PYG{n}{Mixin} \PYG{o}{\PYGZob{}}\PYG{n}{e} \PYG{n}{le}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZus{}}\PYG{o}{.}
\PYG{k+kn}{Arguments} \PYG{k+kn}{Class} \PYG{o}{\PYGZob{}}\PYG{n}{T}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{.}
\end{sphinxVerbatim}

The mixin component of the \sphinxcode{\sphinxupquote{LEQ}} class contains all the extra content we
are adding to \sphinxcode{\sphinxupquote{EQ}} and \sphinxcode{\sphinxupquote{LE}}. In particular it contains the requirement
that the two relations we are combining are compatible.

Unfortunately there is still an obstacle to developing the algebraic
theory of this new class.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{theory}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{theory} \PYG{n}{started}

\PYG{n}{Fail} \PYG{k+kn}{Check} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{le} \PYG{o}{:} \PYG{n}{type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{obj} \PYG{n}{le}\PYG{o}{)}\PYG{o}{,} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{In} \PYG{n}{environment}
    \PYG{n}{le} \PYG{o}{:} \PYG{n}{type}
    \PYG{n}{n} \PYG{o}{:} \PYG{n}{obj} \PYG{n}{le}
    \PYG{n}{m} \PYG{o}{:} \PYG{n}{obj} \PYG{n}{le}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{n}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{obj le}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{while} \PYG{n}{it} \PYG{k}{is} \PYG{n}{expected} \PYG{n}{to} \PYG{k}{have} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{LE.obj ?e}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

The problem is that the two classes \sphinxcode{\sphinxupquote{LE}} and \sphinxcode{\sphinxupquote{LEQ}} are not yet related by
a subclass relation. In other words \DUrole{smallcaps}{Coq} does not see that an object of
the \sphinxcode{\sphinxupquote{LEQ}} class is also an object of the \sphinxcode{\sphinxupquote{LE}} class.

The following two constructions tell \DUrole{smallcaps}{Coq} how to canonically build the
\sphinxcode{\sphinxupquote{LE.type}} and \sphinxcode{\sphinxupquote{EQ.type}} structure given an \sphinxcode{\sphinxupquote{LEQ.type}} structure on the same
type.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{to\PYGZus{}EQ} \PYG{o}{(}\PYG{n}{e} \PYG{o}{:} \PYG{n}{type}\PYG{o}{)} \PYG{o}{:} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{type} \PYG{o}{:=}
   \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{Pack} \PYG{o}{(}\PYG{n}{obj} \PYG{n}{e}\PYG{o}{)} \PYG{o}{(}\PYG{n}{EQ\PYGZus{}class} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{n}{class\PYGZus{}of} \PYG{n}{e}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{to\PYGZus{}EQ} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Canonical} \PYG{k+kn}{Structure} \PYG{n}{to\PYGZus{}EQ}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{to\PYGZus{}LE} \PYG{o}{(}\PYG{n}{e} \PYG{o}{:} \PYG{n}{type}\PYG{o}{)} \PYG{o}{:} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{type} \PYG{o}{:=}
   \PYG{n}{LE}\PYG{o}{.}\PYG{n}{Pack} \PYG{o}{(}\PYG{n}{obj} \PYG{n}{e}\PYG{o}{)} \PYG{o}{(}\PYG{n}{LE\PYGZus{}class} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{n}{class\PYGZus{}of} \PYG{n}{e}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{to\PYGZus{}LE} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Canonical} \PYG{k+kn}{Structure} \PYG{n}{to\PYGZus{}LE}\PYG{o}{.}
\end{sphinxVerbatim}

We can now formulate out first theorem on the objects of the \sphinxcode{\sphinxupquote{LEQ}}
structure.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
   \PYG{k+kn}{Lemma} \PYG{n}{lele\PYGZus{}eq} \PYG{o}{(}\PYG{n}{e} \PYG{o}{:} \PYG{n}{type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{obj} \PYG{n}{e}\PYG{o}{)} \PYG{o}{:} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{=}\PYG{o}{=} \PYG{n}{y}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{e} \PYG{o}{:} \PYG{n}{type}
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{obj} \PYG{n}{e}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{=}\PYG{o}{=} \PYG{n}{y}

\PYG{n}{now} \PYG{k}{intros}\PYG{o}{;} \PYG{k}{apply} \PYG{o}{(}\PYG{n}{compat} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{n}{extra} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{n}{class\PYGZus{}of} \PYG{n}{e}\PYG{o}{)}\PYG{o}{)} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)}\PYG{o}{;} \PYG{k}{split}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{lele\PYGZus{}eq} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Arguments} \PYG{n}{lele\PYGZus{}eq} \PYG{o}{\PYGZob{}}\PYG{n}{e}\PYG{o}{\PYGZcb{}} \PYG{n}{x} \PYG{n}{y} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{theory}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{theory} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{End} \PYG{n}{LEQ}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{LEQ} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Import} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{theory}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{n}{lele\PYGZus{}eq}\PYG{o}{.}
    \PYG{n}{lele\PYGZus{}eq}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{o}{?}\PYG{n}{e}\PYG{o}{,} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{=}\PYG{o}{=} \PYG{n}{y}
    \PYG{n}{where}
    \PYG{o}{?}\PYG{n}{e} \PYG{o}{:} \PYG{o}{[} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{]}
\end{sphinxVerbatim}

Of course one would like to apply results proved in the algebraic
setting to any concrete instate of the algebraic structure.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Example} \PYG{n}{test\PYGZus{}algebraic} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{n}{m}

\PYG{n}{Fail} \PYG{k}{apply} \PYG{o}{(}\PYG{n}{lele\PYGZus{}eq} \PYG{n}{n} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{In} \PYG{n}{environment}
    \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{n}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{nat}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{while} \PYG{n}{it} \PYG{k}{is} \PYG{n}{expected} \PYG{n}{to} \PYG{k}{have} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{LEQ.obj ?e}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}

\PYG{n}{Abort}\PYG{o}{.}
\PYG{k+kn}{Example} \PYG{n}{test\PYGZus{}algebraic2} \PYG{o}{(}\PYG{n}{l1} \PYG{n}{l2} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l1} \PYG{o}{*} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l2}\PYG{o}{)} \PYG{o}{:}
     \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{l1}\PYG{o}{,} \PYG{n}{l2} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{type}
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l1} \PYG{o}{*} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l2}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{n}{m}

\PYG{n}{Fail} \PYG{k}{apply} \PYG{o}{(}\PYG{n}{lele\PYGZus{}eq} \PYG{n}{n} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{In} \PYG{n}{environment}
    \PYG{n}{l1}\PYG{o}{,} \PYG{n}{l2} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{type}
    \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l1} \PYG{o}{*} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l2}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{n}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{(LEQ.obj l1 * LEQ.obj l2)\PYGZpc{}type}\PYG{l+s+s2}{\PYGZdq{}}
    \PYG{n}{while} \PYG{n}{it} \PYG{k}{is} \PYG{n}{expected} \PYG{n}{to} \PYG{k}{have} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{LEQ.obj ?e}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}

\PYG{n}{Abort}\PYG{o}{.}
\end{sphinxVerbatim}

Again one has to tell \DUrole{smallcaps}{Coq} that the type \sphinxcode{\sphinxupquote{nat}} is in the \sphinxcode{\sphinxupquote{LEQ}} class, and
how the type constructor \sphinxcode{\sphinxupquote{*}} interacts with the \sphinxcode{\sphinxupquote{LEQ}} class. In the
following proofs are omitted for brevity.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Lemma} \PYG{n}{nat\PYGZus{}LEQ\PYGZus{}compat} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{/\PYGZbs{}} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{/\PYGZbs{}} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{n}{m}

\PYG{n}{Admitted}\PYG{o}{.}
    \PYG{n}{nat\PYGZus{}LEQ\PYGZus{}compat} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Definition} \PYG{n}{nat\PYGZus{}LEQmx} \PYG{o}{:=} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{Mixin} \PYG{n}{nat\PYGZus{}LEQ\PYGZus{}compat}\PYG{o}{.}
    \PYG{n}{nat\PYGZus{}LEQmx} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Lemma} \PYG{n}{pair\PYGZus{}LEQ\PYGZus{}compat} \PYG{o}{(}\PYG{n}{l1} \PYG{n}{l2} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l1} \PYG{o}{*} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l2}\PYG{o}{)} \PYG{o}{:}
   \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{/\PYGZbs{}} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{l1}\PYG{o}{,} \PYG{n}{l2} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{type}
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l1} \PYG{o}{*} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l2}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{/\PYGZbs{}} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZlt{}\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{n}{m}

\PYG{n}{Admitted}\PYG{o}{.}
    \PYG{n}{pair\PYGZus{}LEQ\PYGZus{}compat} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Definition} \PYG{n}{pair\PYGZus{}LEQmx} \PYG{n}{l1} \PYG{n}{l2} \PYG{o}{:=} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{Mixin} \PYG{o}{(}\PYG{n}{pair\PYGZus{}LEQ\PYGZus{}compat} \PYG{n}{l1} \PYG{n}{l2}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{pair\PYGZus{}LEQmx} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

The following script registers an \sphinxcode{\sphinxupquote{LEQ}} class for \sphinxcode{\sphinxupquote{nat}} and for the type
constructor \sphinxcode{\sphinxupquote{*}}. It also tests that they work as expected.

Unfortunately, these declarations are very verbose. In the following
subsection we show how to make them more compact.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Module} \PYG{n}{Add\PYGZus{}instance\PYGZus{}attempt}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{Add\PYGZus{}instance\PYGZus{}attempt} \PYG{n}{started}

\PYG{k+kn}{Canonical} \PYG{k+kn}{Structure} \PYG{n}{nat\PYGZus{}LEQty} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{type} \PYG{o}{:=}
    \PYG{n}{LEQ}\PYG{o}{.}\PYG{o}{\PYGZus{}}\PYG{n}{Pack} \PYG{k+kt}{nat} \PYG{o}{(}\PYG{n}{LEQ}\PYG{o}{.}\PYG{k+kn}{Class} \PYG{n}{nat\PYGZus{}EQcl} \PYG{n}{nat\PYGZus{}LEcl} \PYG{n}{nat\PYGZus{}LEQmx}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{nat\PYGZus{}LEQty} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Canonical} \PYG{k+kn}{Structure} \PYG{n}{pair\PYGZus{}LEQty} \PYG{o}{(}\PYG{n}{l1} \PYG{n}{l2} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{type} \PYG{o}{:=}
    \PYG{n}{LEQ}\PYG{o}{.}\PYG{o}{\PYGZus{}}\PYG{n}{Pack} \PYG{o}{(}\PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l1} \PYG{o}{*} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l2}\PYG{o}{)}
      \PYG{o}{(}\PYG{n}{LEQ}\PYG{o}{.}\PYG{k+kn}{Class}
         \PYG{o}{(}\PYG{n}{EQ}\PYG{o}{.}\PYG{n}{class\PYGZus{}of} \PYG{o}{(}\PYG{n}{pair\PYGZus{}EQty} \PYG{o}{(}\PYG{n}{to\PYGZus{}EQ} \PYG{n}{l1}\PYG{o}{)} \PYG{o}{(}\PYG{n}{to\PYGZus{}EQ} \PYG{n}{l2}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}
         \PYG{o}{(}\PYG{n}{LE}\PYG{o}{.}\PYG{n}{class\PYGZus{}of} \PYG{o}{(}\PYG{n}{pair\PYGZus{}LEty} \PYG{o}{(}\PYG{n}{to\PYGZus{}LE} \PYG{n}{l1}\PYG{o}{)} \PYG{o}{(}\PYG{n}{to\PYGZus{}LE} \PYG{n}{l2}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}
         \PYG{o}{(}\PYG{n}{pair\PYGZus{}LEQmx} \PYG{n}{l1} \PYG{n}{l2}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{pair\PYGZus{}LEQty} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{264}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Canonical} \PYG{k+kn}{Structure} \PYG{n}{pair\PYGZus{}LEQty} \PYG{o}{(}\PYG{n}{l1} \PYG{n}{l2} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{type} \PYG{o}{:=}     \PYG{n}{LEQ}\PYG{o}{.}\PYG{o}{\PYGZus{}}\PYG{n}{Pack} \PYG{o}{(}\PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l1} \PYG{o}{*} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l2}\PYG{o}{)}       \PYG{o}{(}\PYG{n}{LEQ}\PYG{o}{.}\PYG{k+kn}{Class}          \PYG{o}{(}\PYG{n}{EQ}\PYG{o}{.}\PYG{n}{class\PYGZus{}of} \PYG{o}{(}\PYG{n}{pair\PYGZus{}EQty} \PYG{o}{(}\PYG{n}{to\PYGZus{}EQ} \PYG{n}{l1}\PYG{o}{)} \PYG{o}{(}\PYG{n}{to\PYGZus{}EQ} \PYG{n}{l2}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}          \PYG{o}{(}\PYG{n}{LE}\PYG{o}{.}\PYG{n}{class\PYGZus{}of} \PYG{o}{(}\PYG{n}{pair\PYGZus{}LEty} \PYG{o}{(}\PYG{n}{to\PYGZus{}LE} \PYG{n}{l1}\PYG{o}{)} \PYG{o}{(}\PYG{n}{to\PYGZus{}LE} \PYG{n}{l2}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}          \PYG{o}{(}\PYG{n}{pair\PYGZus{}LEQmx} \PYG{n}{l1} \PYG{n}{l2}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Warning}\PYG{o}{:} \PYG{n}{Ignoring} \PYG{n}{canonical} \PYG{n}{projection} \PYG{n}{to} \PYG{n}{LEQ}\PYG{o}{.}\PYG{k+kn}{Class} \PYG{k+kp}{by} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{class\PYGZus{}of} \PYG{k}{in}
    \PYG{n}{pair\PYGZus{}LEQty}\PYG{o}{:} \PYG{n}{redundant} \PYG{k}{with} \PYG{n}{nat\PYGZus{}LEQty}

\PYG{k+kn}{Example} \PYG{n}{test\PYGZus{}algebraic} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{n}{m}

\PYG{n}{now} \PYG{k}{apply} \PYG{o}{(}\PYG{n}{lele\PYGZus{}eq} \PYG{n}{n} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{test\PYGZus{}algebraic} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Example} \PYG{n}{test\PYGZus{}algebraic2} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{*} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{n}{m}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{*} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{m} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{n}{m}

\PYG{n}{now} \PYG{k}{apply} \PYG{o}{(}\PYG{n}{lele\PYGZus{}eq} \PYG{n}{n} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
    \PYG{n}{test\PYGZus{}algebraic2} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{End} \PYG{n}{Add\PYGZus{}instance\PYGZus{}attempt}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{Add\PYGZus{}instance\PYGZus{}attempt} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

Note that no direct proof of \sphinxcode{\sphinxupquote{n \textless{}= m -\textgreater{} m \textless{}= n -\textgreater{} n == m}} is provided by
the user for \sphinxcode{\sphinxupquote{n}} and m of type \sphinxcode{\sphinxupquote{nat * nat}}. What the user provides is a
proof of this statement for \sphinxcode{\sphinxupquote{n}} and \sphinxcode{\sphinxupquote{m}} of type \sphinxcode{\sphinxupquote{nat}} and a proof that the
pair constructor preserves this property. The combination of these two
facts is a simple form of proof search that \DUrole{smallcaps}{Coq} performs automatically
while inferring canonical structures.


\subsubsection{Compact declaration of Canonical Structures}
\label{\detokenize{addendum/canonical-structures:compact-declaration-of-canonical-structures}}
We need some infrastructure for that.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Strings}\PYG{o}{.}\PYG{n}{String}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{z\PYGZus{}syntax\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{quote\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{newring\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{ascii\PYGZus{}syntax\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{string\PYGZus{}syntax\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}

\PYG{k+kn}{Module} \PYG{n}{infrastructure}\PYG{o}{.}
    \PYG{n}{Interactive} \PYG{k+kn}{Module} \PYG{n}{infrastructure} \PYG{n}{started}

\PYG{k+kn}{Inductive} \PYG{n}{phantom} \PYG{o}{\PYGZob{}}\PYG{n}{T} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{t} \PYG{o}{:} \PYG{n}{T}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=} \PYG{n}{Phantom}\PYG{o}{.}
    \PYG{n}{phantom} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{phantom\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{phantom\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{phantom\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{unify} \PYG{o}{\PYGZob{}}\PYG{n}{T1} \PYG{n}{T2}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{t1} \PYG{o}{:} \PYG{n}{T1}\PYG{o}{)} \PYG{o}{(}\PYG{n}{t2} \PYG{o}{:} \PYG{n}{T2}\PYG{o}{)} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{n}{option} \PYG{k+kt}{string}\PYG{o}{)} \PYG{o}{:=}
    \PYG{n}{phantom} \PYG{n}{t1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{phantom} \PYG{n}{t2}\PYG{o}{.}
    \PYG{n}{unify} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Definition} \PYG{n}{id} \PYG{o}{\PYGZob{}}\PYG{n}{T}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZob{}}\PYG{n}{t} \PYG{o}{:} \PYG{n}{T}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{phantom} \PYG{n}{t}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{x}\PYG{o}{.}
    \PYG{n}{id} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{[find v \textbar{} t1 \PYGZti{} t2 ] p}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{v} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{unify} \PYG{n}{t1} \PYG{n}{t2} \PYG{n}{None}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{p}\PYG{o}{)}
    \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{50}\PYG{o}{,} \PYG{n}{v} \PYG{n}{ident}\PYG{o}{,} \PYG{n}{only} \PYG{n}{parsing}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{[find v \textbar{} t1 \PYGZti{} t2 \textbar{} s ] p}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{v} \PYG{o}{(}\PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{unify} \PYG{n}{t1} \PYG{n}{t2} \PYG{o}{(}\PYG{n}{Some} \PYG{n}{s}\PYG{o}{)}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{p}\PYG{o}{)}
    \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{50}\PYG{o}{,} \PYG{n}{v} \PYG{n}{ident}\PYG{o}{,} \PYG{n}{only} \PYG{n}{parsing}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}Error : t : s}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{unify} \PYG{o}{\PYGZus{}} \PYG{n}{t} \PYG{o}{(}\PYG{n}{Some} \PYG{n}{s}\PYG{o}{)}\PYG{o}{)}
    \PYG{o}{(}\PYG{n}{at} \PYG{n}{level} \PYG{l+m+mi}{50}\PYG{o}{,} \PYG{n}{format} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}\PYGZsq{}Error\PYGZsq{} : t : s}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{string\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{infrastructure}\PYG{o}{.}
    \PYG{k+kn}{Module} \PYG{n}{infrastructure} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

To explain the notation \sphinxcode{\sphinxupquote{{[}find v \textbar{} t1 \textasciitilde{} t2{]}}} let us pick one of its
instances: \sphinxcode{\sphinxupquote{{[}find e \textbar{} EQ.obj e \textasciitilde{} T \textbar{} "is not an EQ.type" {]}}}. It should be
read as: “find a class e such that its objects have type T or fail
with message "T is not an EQ.type"”.

The other utilities are used to ask \DUrole{smallcaps}{Coq} to solve a specific unification
problem, that will in turn require the inference of some canonical structures.
They are explained in more details in \sphinxcite{zebibliography:cswcu}.

We now have all we need to create a compact “packager” to declare
instances of the \sphinxcode{\sphinxupquote{LEQ}} class.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Import} \PYG{n}{infrastructure}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{packager} \PYG{n}{T} \PYG{n}{e0} \PYG{n}{le0} \PYG{o}{(}\PYG{n}{m0} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{mixin} \PYG{n}{e0} \PYG{n}{le0}\PYG{o}{)} \PYG{o}{:=}
  \PYG{o}{[}\PYG{n}{find} \PYG{n}{e} \PYG{o}{\textbar{}} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{e} \PYG{o}{\PYGZti{}} \PYG{n}{T} \PYG{o}{\textbar{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{is not an EQ.type}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{]}
  \PYG{o}{[}\PYG{n}{find} \PYG{n}{o} \PYG{o}{\textbar{}} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{o} \PYG{o}{\PYGZti{}} \PYG{n}{T} \PYG{o}{\textbar{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{is not an LE.type}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{]}
  \PYG{o}{[}\PYG{n}{find} \PYG{n}{ce} \PYG{o}{\textbar{}} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{class\PYGZus{}of} \PYG{n}{e} \PYG{o}{\PYGZti{}} \PYG{n}{ce} \PYG{o}{]}
  \PYG{o}{[}\PYG{n}{find} \PYG{n}{co} \PYG{o}{\textbar{}} \PYG{n}{LE}\PYG{o}{.}\PYG{n}{class\PYGZus{}of} \PYG{n}{o} \PYG{o}{\PYGZti{}} \PYG{n}{co} \PYG{o}{]}
  \PYG{o}{[}\PYG{n}{find} \PYG{n}{m} \PYG{o}{\textbar{}} \PYG{n}{m} \PYG{o}{\PYGZti{}} \PYG{n}{m0} \PYG{o}{\textbar{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{is not the right mixin}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{]}
  \PYG{n}{LEQ}\PYG{o}{.}\PYG{o}{\PYGZus{}}\PYG{n}{Pack} \PYG{n}{T} \PYG{o}{(}\PYG{n}{LEQ}\PYG{o}{.}\PYG{k+kn}{Class} \PYG{n}{ce} \PYG{n}{co} \PYG{n}{m}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{packager} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Notation} \PYG{n}{Pack} \PYG{n}{T} \PYG{n}{m} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{packager} \PYG{n}{T} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{n}{m} \PYG{o}{\PYGZus{}} \PYG{n}{id} \PYG{o}{\PYGZus{}} \PYG{n}{id} \PYG{o}{\PYGZus{}} \PYG{n}{id} \PYG{o}{\PYGZus{}} \PYG{n}{id} \PYG{o}{\PYGZus{}} \PYG{n}{id}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

The object \sphinxcode{\sphinxupquote{Pack}} takes a type \sphinxcode{\sphinxupquote{T}} (the key) and a mixin \sphinxcode{\sphinxupquote{m}}. It infers all
the other pieces of the class \sphinxcode{\sphinxupquote{LEQ}} and declares them as canonical
values associated to the \sphinxcode{\sphinxupquote{T}} key. All in all, the only new piece of
information we add in the \sphinxcode{\sphinxupquote{LEQ}} class is the mixin, all the rest is
already canonical for \sphinxcode{\sphinxupquote{T}} and hence can be inferred by \DUrole{smallcaps}{Coq}.

\sphinxcode{\sphinxupquote{Pack}} is a notation, hence it is not type checked at the time of its
declaration. It will be type checked when it is used, an in that case \sphinxcode{\sphinxupquote{T}} is
going to be a concrete type. The odd arguments \sphinxcode{\sphinxupquote{\_}} and \sphinxcode{\sphinxupquote{id}} we pass to the
packager represent respectively the classes to be inferred (like \sphinxcode{\sphinxupquote{e}}, \sphinxcode{\sphinxupquote{o}},
etc) and a token (\sphinxcode{\sphinxupquote{id}}) to force their inference. Again, for all the details
the reader can refer to \sphinxcite{zebibliography:cswcu}.

The declaration of canonical instances can now be way more compact:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Canonical} \PYG{k+kn}{Structure} \PYG{n}{nat\PYGZus{}LEQty} \PYG{o}{:=} \PYG{n}{Eval} \PYG{k}{hnf} \PYG{k}{in} \PYG{n}{Pack} \PYG{k+kt}{nat} \PYG{n}{nat\PYGZus{}LEQmx}\PYG{o}{.}
    \PYG{n}{nat\PYGZus{}LEQty} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Canonical} \PYG{k+kn}{Structure} \PYG{n}{pair\PYGZus{}LEQty} \PYG{o}{(}\PYG{n}{l1} \PYG{n}{l2} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{:=}
   \PYG{n}{Eval} \PYG{k}{hnf} \PYG{k}{in} \PYG{n}{Pack} \PYG{o}{(}\PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l1} \PYG{o}{*} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l2}\PYG{o}{)} \PYG{o}{(}\PYG{n}{pair\PYGZus{}LEQmx} \PYG{n}{l1} \PYG{n}{l2}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{pair\PYGZus{}LEQty} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{118}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Canonical} \PYG{k+kn}{Structure} \PYG{n}{pair\PYGZus{}LEQty} \PYG{o}{(}\PYG{n}{l1} \PYG{n}{l2} \PYG{o}{:} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{type}\PYG{o}{)} \PYG{o}{:=}    \PYG{n}{Eval} \PYG{k}{hnf} \PYG{k}{in} \PYG{n}{Pack} \PYG{o}{(}\PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l1} \PYG{o}{*} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{obj} \PYG{n}{l2}\PYG{o}{)} \PYG{o}{(}\PYG{n}{pair\PYGZus{}LEQmx} \PYG{n}{l1} \PYG{n}{l2}\PYG{o}{)}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Warning}\PYG{o}{:} \PYG{n}{Ignoring} \PYG{n}{canonical} \PYG{n}{projection} \PYG{n}{to} \PYG{n}{LEQ}\PYG{o}{.}\PYG{k+kn}{Class} \PYG{k+kp}{by} \PYG{n}{LEQ}\PYG{o}{.}\PYG{n}{class\PYGZus{}of} \PYG{k}{in}
    \PYG{n}{pair\PYGZus{}LEQty}\PYG{o}{:} \PYG{n}{redundant} \PYG{k}{with} \PYG{n}{nat\PYGZus{}LEQty}
\end{sphinxVerbatim}

Error messages are also quite intelligible (if one skips to the end of
the message).

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Canonical} \PYG{k+kn}{Structure} \PYG{n}{err} \PYG{o}{:=} \PYG{n}{Eval} \PYG{k}{hnf} \PYG{k}{in} \PYG{n}{Pack} \PYG{k+kt}{bool} \PYG{n}{nat\PYGZus{}LEQmx}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{id}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{phantom (EQ.obj ?e) \PYGZhy{}\PYGZgt{} phantom (EQ.obj ?e)}\PYG{l+s+s2}{\PYGZdq{}}
    \PYG{n}{while} \PYG{n}{it} \PYG{k}{is} \PYG{n}{expected} \PYG{n}{to} \PYG{k}{have} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}Error:bool:}\PYG{l+s+s2}{\PYGZdq{}}\PYG{k}{is} \PYG{n}{not} \PYG{n}{an} \PYG{n}{EQ}\PYG{o}{.}\PYG{n}{type}\PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}


\section{Type Classes}
\label{\detokenize{addendum/type-classes:type-classes}}\label{\detokenize{addendum/type-classes:typeclasses}}\label{\detokenize{addendum/type-classes::doc}}
This chapter presents a quick reference of the commands related to type
classes. For an actual introduction to typeclasses, there is a
description of the system \sphinxcite{zebibliography:sozeau08} and the literature on type
classes in Haskell which also applies.


\subsection{Class and Instance declarations}
\label{\detokenize{addendum/type-classes:class-and-instance-declarations}}
The syntax for class and instance declarations is the same as the record
syntax of Coq:

\sphinxcode{\sphinxupquote{Class Id (}} \sphinxtitleref{p}\(_{1}\) \sphinxcode{\sphinxupquote{:}} \sphinxtitleref{t}\(_{1}\) \sphinxcode{\sphinxupquote{) ⋯ (}} \sphinxtitleref{p}\(_{n}\) \sphinxcode{\sphinxupquote{:}} \sphinxtitleref{t}\(_{n}\) \sphinxcode{\sphinxupquote{) {[}:
sort{]} := \{}} \sphinxtitleref{f}\(_{1}\) \sphinxcode{\sphinxupquote{:}} \sphinxtitleref{u}\(_{1}\) \sphinxcode{\sphinxupquote{; ⋮}} \sphinxtitleref{f}\(_{m}\) \sphinxcode{\sphinxupquote{:}} \sphinxtitleref{u}\(_{m}\) \sphinxcode{\sphinxupquote{\}.}}

\sphinxcode{\sphinxupquote{Instance ident : Id}} \sphinxtitleref{p}\(_{1}\) \sphinxcode{\sphinxupquote{⋯}} \sphinxtitleref{p}\(_{n}\) \sphinxcode{\sphinxupquote{:= \{}} \sphinxtitleref{f}\(_{1}\) \sphinxcode{\sphinxupquote{:=}} \sphinxtitleref{t}\(_{1}\) \sphinxcode{\sphinxupquote{; ⋮}} \sphinxtitleref{f}\(_{m}\) \sphinxcode{\sphinxupquote{:=}} \sphinxtitleref{t}\(_{m}\) \sphinxcode{\sphinxupquote{\}.}}

The \sphinxtitleref{p}\(_{i}\) \sphinxcode{\sphinxupquote{:}} \sphinxtitleref{t}\(_{i}\) variables are called the \sphinxstyleemphasis{parameters} of the class and
the \sphinxtitleref{f}\(_{i}\) \sphinxcode{\sphinxupquote{:}} \sphinxtitleref{t}\(_{i}\) are called the \sphinxstyleemphasis{methods}. Each class definition gives
rise to a corresponding record declaration and each instance is a
regular definition whose name is given by ident and type is an
instantiation of the record type.

We’ll use the following example class in the rest of the chapter:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Class} \PYG{n}{EqDec} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:=} \PYG{o}{\PYGZob{}}
  \PYG{n}{eqb} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool} \PYG{o}{;}
  \PYG{n}{eqb\PYGZus{}leibniz} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{n}{eqb} \PYG{n}{x} \PYG{n}{y} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

This class implements a boolean equality test which is compatible with
Leibniz equality on some type. An example implementation is:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Instance} \PYG{n}{unit\PYGZus{}EqDec} \PYG{o}{:} \PYG{n}{EqDec} \PYG{k+kt}{unit} \PYG{o}{:=}
 \PYG{o}{\PYGZob{}} \PYG{n}{eqb} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:=} \PYG{n+nb+bp}{true} \PYG{o}{;}
   \PYG{n}{eqb\PYGZus{}leibniz} \PYG{n}{x} \PYG{n}{y} \PYG{n}{H} \PYG{o}{:=}
         \PYG{k}{match} \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{k}{return} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y} \PYG{k}{with} \PYG{n}{tt}\PYG{o}{,} \PYG{n}{tt} \PYG{o}{=\PYGZgt{}} \PYG{n}{eq\PYGZus{}refl} \PYG{n}{tt} \PYG{k}{end} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

If one does not give all the members in the Instance declaration, Coq
enters the proof-mode and the user is asked to build inhabitants of
the remaining fields, e.g.:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Instance} \PYG{n}{eq\PYGZus{}bool} \PYG{o}{:} \PYG{n}{EqDec} \PYG{k+kt}{bool} \PYG{o}{:=}
\PYG{o}{\PYGZob{}} \PYG{n}{eqb} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:=} \PYG{k}{if} \PYG{n}{x} \PYG{k}{then} \PYG{n}{y} \PYG{k}{else} \PYG{n}{negb} \PYG{n}{y} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{intros} \PYG{n}{x} \PYG{n}{y} \PYG{n}{H}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{k+kt}{bool}
      \PYG{n}{H} \PYG{o}{:} \PYG{o}{(}\PYG{k}{if} \PYG{n}{x} \PYG{k}{then} \PYG{n}{y} \PYG{k}{else} \PYG{n}{negb} \PYG{n}{y}\PYG{o}{)} \PYG{o}{=} \PYG{n+nb+bp}{true}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{destruct} \PYG{n}{x} \PYG{o}{;} \PYG{k}{destruct} \PYG{n}{y} \PYG{o}{;} \PYG{o}{(}\PYG{k+kp}{discriminate} \PYG{o}{\textbar{}}\PYG{o}{\textbar{}} \PYG{k+kp}{reflexivity}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Defined}\PYG{o}{.}
    \PYG{n}{eq\PYGZus{}bool} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

One has to take care that the transparency of every field is
determined by the transparency of the {\hyperref[\detokenize{addendum/type-classes:coq:cmd.instance}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Instance}}}}} proof. One can use
alternatively the {\hyperref[\detokenize{addendum/type-classes:coq:cmdv.program-instance}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Program Instance}}}}} variant which has richer facilities
for dealing with obligations.


\subsection{Binding classes}
\label{\detokenize{addendum/type-classes:binding-classes}}
Once a typeclass is declared, one can use it in class binders:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{neqb} \PYG{o}{\PYGZob{}}\PYG{n}{A}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZob{}}\PYG{n}{eqa} \PYG{o}{:} \PYG{n}{EqDec} \PYG{n}{A}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{negb} \PYG{o}{(}\PYG{n}{eqb} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{neqb} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

When one calls a class method, a constraint is generated that is
satisfied only in contexts where the appropriate instances can be
found. In the example above, a constraint \sphinxcode{\sphinxupquote{EqDec A}} is generated and
satisfied by \sphinxcode{\sphinxupquote{eqa : EqDec A}}. In case no satisfying constraint can be
found, an error is raised:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Definition} \PYG{n}{neqb\PYGZsq{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{negb} \PYG{o}{(}\PYG{n}{eqb} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{Unable} \PYG{n}{to} \PYG{n}{satisfy} \PYG{n}{the} \PYG{n}{following} \PYG{n}{constraints}\PYG{o}{:}
    \PYG{n}{In} \PYG{n}{environment}\PYG{o}{:}
    \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
    \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}
    
    \PYG{o}{?}\PYG{n}{EqDec} \PYG{o}{:} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{EqDec A}\PYG{l+s+s2}{\PYGZdq{}}
\end{sphinxVerbatim}

The algorithm used to solve constraints is a variant of the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}}
tactic that does proof search with a set of lemmas (the instances). It
will use local hypotheses as well as declared lemmas in
the \sphinxcode{\sphinxupquote{typeclass\_instances}} database. Hence the example can also be
written:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{neqb\PYGZsq{}} \PYG{n}{A} \PYG{o}{(}\PYG{n}{eqa} \PYG{o}{:} \PYG{n}{EqDec} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{negb} \PYG{o}{(}\PYG{n}{eqb} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{neqb\PYGZsq{}} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

However, the generalizing binders should be used instead as they have
particular support for typeclasses:
\begin{itemize}
\item {} 
They automatically set the maximally implicit status for typeclass
arguments, making derived functions as easy to use as class methods.
In the example above, \sphinxcode{\sphinxupquote{A}} and \sphinxcode{\sphinxupquote{eqa}} should be set maximally implicit.

\item {} 
They support implicit quantification on partially applied type
classes ({\hyperref[\detokenize{language/gallina-extensions:implicit-generalization}]{\sphinxcrossref{\DUrole{std,std-ref}{Implicit generalization}}}}). Any argument not given as part of a typeclass
binder will be automatically generalized.

\item {} 
They also support implicit quantification on {\hyperref[\detokenize{addendum/type-classes:superclasses}]{\sphinxcrossref{\DUrole{std,std-ref}{Superclasses}}}}.

\end{itemize}

Following the previous example, one can write:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Generalizable} \PYG{k+kn}{Variables} \PYG{n}{A} \PYG{n}{B} \PYG{n}{C}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{neqb\PYGZus{}implicit} \PYG{o}{{}`}\PYG{o}{\PYGZob{}}\PYG{n}{eqa} \PYG{o}{:} \PYG{n}{EqDec} \PYG{n}{A}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{negb} \PYG{o}{(}\PYG{n}{eqb} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{neqb\PYGZus{}implicit} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

Here \sphinxcode{\sphinxupquote{A}} is implicitly generalized, and the resulting function is
equivalent to the one above.


\subsection{Parameterized Instances}
\label{\detokenize{addendum/type-classes:parameterized-instances}}
One can declare parameterized instances as in Haskell simply by giving
the constraints as a binding context before the instance, e.g.:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Instance} \PYG{n}{prod\PYGZus{}eqb} \PYG{o}{{}`}\PYG{o}{(}\PYG{n}{EA} \PYG{o}{:} \PYG{n}{EqDec} \PYG{n}{A}\PYG{o}{,} \PYG{n}{EB} \PYG{o}{:} \PYG{n}{EqDec} \PYG{n}{B}\PYG{o}{)} \PYG{o}{:} \PYG{n}{EqDec} \PYG{o}{(}\PYG{n}{A} \PYG{o}{*} \PYG{n}{B}\PYG{o}{)} \PYG{o}{:=}
\PYG{o}{\PYGZob{}} \PYG{n}{eqb} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{k}{with}
             \PYG{o}{\textbar{}} \PYG{o}{(}\PYG{n}{la}\PYG{o}{,} \PYG{n}{ra}\PYG{o}{)}\PYG{o}{,} \PYG{o}{(}\PYG{n}{lb}\PYG{o}{,} \PYG{n}{rb}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{andb} \PYG{o}{(}\PYG{n}{eqb} \PYG{n}{la} \PYG{n}{lb}\PYG{o}{)} \PYG{o}{(}\PYG{n}{eqb} \PYG{n}{ra} \PYG{n}{rb}\PYG{o}{)}
             \PYG{k}{end} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

These instances are used just as well as lemmas in the instance hint
database.


\subsection{Sections and contexts}
\label{\detokenize{addendum/type-classes:sections-and-contexts}}
To ease the parametrization of developments by typeclasses, we provide a new
way to introduce variables into section contexts, compatible with the implicit
argument mechanism. The new command works similarly to the {\hyperref[\detokenize{language/gallina-specification-language:coq:cmdv.variables}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Variables}}}}}
vernacular, except it accepts any binding context as argument. For example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Section} \PYG{n}{EqDec\PYGZus{}defs}\PYG{o}{.}
\PYG{k+kn}{Context} \PYG{o}{{}`}\PYG{o}{\PYGZob{}}\PYG{n}{EA} \PYG{o}{:} \PYG{n}{EqDec} \PYG{n}{A}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{A} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{EA} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{Global} \PYG{k+kn}{Instance} \PYG{n}{option\PYGZus{}eqb} \PYG{o}{:} \PYG{n}{EqDec} \PYG{o}{(}\PYG{n}{option} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:=}
  \PYG{o}{\PYGZob{}} \PYG{n}{eqb} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:=} \PYG{k}{match} \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{k}{with}
         \PYG{o}{\textbar{}} \PYG{n}{Some} \PYG{n}{x}\PYG{o}{,} \PYG{n}{Some} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{eqb} \PYG{n}{x} \PYG{n}{y}
         \PYG{o}{\textbar{}} \PYG{n}{None}\PYG{o}{,} \PYG{n}{None} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
         \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}}\PYG{o}{,} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
         \PYG{k}{end} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}
      \PYG{n}{EA} \PYG{o}{:} \PYG{n}{EqDec} \PYG{n}{A}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{option} \PYG{n}{A}\PYG{o}{,}
      \PYG{k}{match} \PYG{n}{x} \PYG{k}{with}
      \PYG{o}{\textbar{}} \PYG{n}{Some} \PYG{n}{x0} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{y} \PYG{k}{with}
                   \PYG{o}{\textbar{}} \PYG{n}{Some} \PYG{n}{y0} \PYG{o}{=\PYGZgt{}} \PYG{n}{eqb} \PYG{n}{x0} \PYG{n}{y0}
                   \PYG{o}{\textbar{}} \PYG{n}{None} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
                   \PYG{k}{end}
      \PYG{o}{\textbar{}} \PYG{n}{None} \PYG{o}{=\PYGZgt{}} \PYG{k}{match} \PYG{n}{y} \PYG{k}{with}
                \PYG{o}{\textbar{}} \PYG{n}{Some} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{false}
                \PYG{o}{\textbar{}} \PYG{n}{None} \PYG{o}{=\PYGZgt{}} \PYG{n+nb+bp}{true}
                \PYG{k}{end}
      \PYG{k}{end} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{=} \PYG{n}{y}

\PYG{n}{Admitted}\PYG{o}{.}
    \PYG{n}{option\PYGZus{}eqb} \PYG{k}{is} \PYG{n}{declared}

\PYG{k+kn}{End} \PYG{n}{EqDec\PYGZus{}defs}\PYG{o}{.}
\PYG{n}{About} \PYG{n}{option\PYGZus{}eqb}\PYG{o}{.}
    \PYG{n}{option\PYGZus{}eqb} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{,} \PYG{n}{EqDec} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{EqDec} \PYG{o}{(}\PYG{n}{option} \PYG{n}{A}\PYG{o}{)}
    
    \PYG{k+kn}{Arguments} \PYG{n}{A}\PYG{o}{,} \PYG{n}{EA} \PYG{n}{are} \PYG{n}{implicit} \PYG{n}{and} \PYG{n}{maximally} \PYG{n}{inserted}
    \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}}\PYG{o}{]}
    \PYG{n}{Expands} \PYG{n}{to}\PYG{o}{:} \PYG{n}{Constant} \PYG{n}{Top}\PYG{o}{.}\PYG{n}{option\PYGZus{}eqb}
\end{sphinxVerbatim}

Here the Global modifier redeclares the instance at the end of the
section, once it has been generalized by the context variables it
uses.


\subsection{Building hierarchies}
\label{\detokenize{addendum/type-classes:building-hierarchies}}

\subsubsection{Superclasses}
\label{\detokenize{addendum/type-classes:superclasses}}\label{\detokenize{addendum/type-classes:id2}}
One can also parameterize classes by other classes, generating a
hierarchy of classes and superclasses. In the same way, we give the
superclasses as a binding context:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Class} \PYG{n}{Ord} \PYG{o}{{}`}\PYG{o}{(}\PYG{n}{E} \PYG{o}{:} \PYG{n}{EqDec} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:=} \PYG{o}{\PYGZob{}} \PYG{n}{le} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{bool} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{Ord} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{le} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

Contrary to Haskell, we have no special syntax for superclasses, but
this declaration is equivalent to:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Class {}`(E : EqDec A) =\PYGZgt{} Ord A :=
  \PYGZob{} le : A \PYGZhy{}\PYGZgt{} A \PYGZhy{}\PYGZgt{} bool \PYGZcb{}.
\end{sphinxVerbatim}

This declaration means that any instance of the \sphinxcode{\sphinxupquote{Ord}} class must have
an instance of \sphinxcode{\sphinxupquote{EqDec}}. The parameters of the subclass contain at
least all the parameters of its superclasses in their order of
appearance (here A is the only one). As we have seen, \sphinxcode{\sphinxupquote{Ord}} is encoded
as a record type with two parameters: a type \sphinxcode{\sphinxupquote{A}} and an \sphinxcode{\sphinxupquote{E}} of type
\sphinxcode{\sphinxupquote{EqDec A}}. However, one can still use it as if it had a single
parameter inside generalizing binders: the generalization of
superclasses will be done automatically.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{le\PYGZus{}eqb} \PYG{o}{{}`}\PYG{o}{\PYGZob{}}\PYG{n}{Ord} \PYG{n}{A}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{andb} \PYG{o}{(}\PYG{n}{le} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{n}{le} \PYG{n}{y} \PYG{n}{x}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{le\PYGZus{}eqb} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

In some cases, to be able to specify sharing of structures, one may
want to give explicitly the superclasses. It is is possible to do it
directly in regular binders, and using the \sphinxcode{\sphinxupquote{!}} modifier in class
binders. For example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{lt} \PYG{o}{{}`}\PYG{o}{\PYGZob{}}\PYG{n}{eqa} \PYG{o}{:} \PYG{n}{EqDec} \PYG{n}{A}\PYG{o}{,} \PYG{o}{!} \PYG{n}{Ord} \PYG{n}{eqa}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{andb} \PYG{o}{(}\PYG{n}{le} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{n}{neqb} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{lt} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

The \sphinxcode{\sphinxupquote{!}} modifier switches the way a binder is parsed back to the regular
interpretation of Coq. In particular, it uses the implicit arguments
mechanism if available, as shown in the example.


\subsubsection{Substructures}
\label{\detokenize{addendum/type-classes:substructures}}
Substructures are components of a class which are instances of a class
themselves. They often arise when using classes for logical
properties, e.g.:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Class} \PYG{n}{Reflexive} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{R} \PYG{o}{:} \PYG{n}{relation} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:=}
  \PYG{k+kp}{reflexivity} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{n}{R} \PYG{n}{x} \PYG{n}{x}\PYG{o}{.}
\PYG{k+kn}{Class} \PYG{n}{Transitive} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{R} \PYG{o}{:} \PYG{n}{relation} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:=}
  \PYG{k}{transitivity} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z}\PYG{o}{,} \PYG{n}{R} \PYG{n}{x} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R} \PYG{n}{y} \PYG{n}{z} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R} \PYG{n}{x} \PYG{n}{z}\PYG{o}{.}
\end{sphinxVerbatim}

This declares singleton classes for reflexive and transitive relations,
(see the {\hyperref[\detokenize{addendum/type-classes:singleton-class}]{\sphinxcrossref{\DUrole{std,std-ref}{singleton class}}}} variant for an
explanation). These may be used as parts of other classes:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Class} \PYG{n}{PreOrder} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{R} \PYG{o}{:} \PYG{n}{relation} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:=}
\PYG{o}{\PYGZob{}} \PYG{n}{PreOrder\PYGZus{}Reflexive} \PYG{o}{:\PYGZgt{}} \PYG{n}{Reflexive} \PYG{n}{A} \PYG{n}{R} \PYG{o}{;}
  \PYG{n}{PreOrder\PYGZus{}Transitive} \PYG{o}{:\PYGZgt{}} \PYG{n}{Transitive} \PYG{n}{A} \PYG{n}{R} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{PreOrder} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{PreOrder\PYGZus{}Reflexive} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{PreOrder\PYGZus{}Transitive} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

The syntax \sphinxcode{\sphinxupquote{:\textgreater{}}} indicates that each \sphinxcode{\sphinxupquote{PreOrder}} can be seen as a
\sphinxcode{\sphinxupquote{Reflexive}} relation. So each time a reflexive relation is needed, a
preorder can be used instead. This is very similar to the coercion
mechanism of \sphinxcode{\sphinxupquote{Structure}} declarations. The implementation simply
declares each projection as an instance.

One can also declare existing objects or structure projections using
the Existing Instance command to achieve the same effect.


\subsection{Summary of the commands}
\label{\detokenize{addendum/type-classes:summary-of-the-commands}}\index{Class (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:cmd.class}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Class~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}}}\DUrole{notation-sup}{?}}~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~\DUrole{curlies}{\{~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:\DUrole{repeat-wrapper}{\DUrole{repeat}{\textgreater{}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{+}\DUrole{notation-sub}{;}}~\}}}}}}
The {\hyperref[\detokenize{addendum/type-classes:coq:cmd.class}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Class}}}}} command is used to declare a typeclass with parameters
\sphinxcode{\sphinxupquote{binders}} and fields the declared record fields.

\end{fulllineitems}


Variants:

\phantomsection\label{\detokenize{addendum/type-classes:singleton-class}}\index{Class (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Class~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-sort}]{\sphinxcrossref{\DUrole{hole}{sort}}}}}\DUrole{notation-sup}{?}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This variant declares a \sphinxstyleemphasis{singleton} class with a single method.  This
singleton class is a so-called definitional class, represented simply
as a definition \sphinxcode{\sphinxupquote{ident binders := term}} and whose instances are
themselves objects of this type. Definitional classes are not wrapped
inside records, and the trivial projection of an instance of such a
class is convertible to the instance itself. This can be useful to
make instances of existing objects easily and to reduce proof size by
not inserting useless projections. The class constant itself is
declared rigid during resolution so that the class abstraction is
maintained.

\end{fulllineitems}

\index{Existing Class (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:cmd.existing-class}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Existing~Class~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This variant declares a class a posteriori from a constant or
inductive definition. No methods or instances are defined.

\end{fulllineitems}

\index{Instance (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:cmd.instance}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Instance~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~Class~t1~…~tn~{[}\textbar{}~priority{]}~:=~\DUrole{curlies}{\{~field1~:=~b1~;~…;~fieldi~:=~bi~\}}}}}}
\end{fulllineitems}


The {\hyperref[\detokenize{addendum/type-classes:coq:cmd.instance}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Instance}}}}} command is used to declare a typeclass instance named
\sphinxcode{\sphinxupquote{ident}} of the class {\hyperref[\detokenize{addendum/type-classes:coq:cmd.class}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Class}}}}} with parameters \sphinxcode{\sphinxupquote{t1}} to \sphinxcode{\sphinxupquote{tn}} and
fields \sphinxcode{\sphinxupquote{b1}} to \sphinxcode{\sphinxupquote{bi}}, where each field must be a declared field of
the class.  Missing fields must be filled in interactive proof mode.

An arbitrary context of \sphinxcode{\sphinxupquote{binders}} can be put after the name of the
instance and before the colon to declare a parameterized instance. An
optional priority can be declared, 0 being the highest priority as for
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}} hints. If the priority is not specified, it defaults to the number
of non-dependent binders of the instance.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Instance~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}}~:~forall~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}\DUrole{notation-sup}{?}},~Class~t1~…~tn~{[}\textbar{}~priority{]}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This syntax is used for declaration of singleton class instances or
for directly giving an explicit term of type \sphinxcode{\sphinxupquote{forall binders, Class
t1 … tn}}.  One need not even mention the unique field name for
singleton classes.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Global~Instance}}}}
One can use the \sphinxcode{\sphinxupquote{Global}} modifier on instances declared in a
section so that their generalization is automatically redeclared
after the section is closed.

\end{fulllineitems}

\index{Program Instance (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:cmdv.program-instance}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Program~Instance}}}}
Switches the type checking to Program (chapter {\hyperref[\detokenize{addendum/program:programs}]{\sphinxcrossref{\DUrole{std,std-ref}{Program}}}}) and
uses the obligation mechanism to manage missing fields.

\end{fulllineitems}

\index{Declare Instance (cmdv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:cmdv.declare-instance}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Declare~Instance}}}}
In a Module Type, this command states that a corresponding concrete
instance should exist in any implementation of this Module Type. This
is similar to the distinction between {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.parameter}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Parameter}}}}} vs. {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}}, or
between {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.declare-module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Declare Module}}}}} and {\hyperref[\detokenize{language/gallina-extensions:coq:cmd.module}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Module}}}}}.

\end{fulllineitems}


Besides the {\hyperref[\detokenize{addendum/type-classes:coq:cmd.class}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Class}}}}} and {\hyperref[\detokenize{addendum/type-classes:coq:cmd.instance}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Instance}}}}} vernacular commands, there are a
few other commands related to typeclasses.
\index{Existing Instance (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:cmd.existing-instance}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Existing~Instance~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~{[}\textbar{}~priority{]}}}}}
This command adds an arbitrary list of constants whose type ends with
an applied typeclass to the instance database with an optional
priority.  It can be used for redeclaring instances at the end of
sections, or declaring structure projections as instances. This is
equivalent to \sphinxcode{\sphinxupquote{Hint Resolve ident : typeclass\_instances}}, except it
registers instances for {\hyperref[\detokenize{addendum/generalized-rewriting:coq:cmd.print-instances}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Instances}}}}}.

\end{fulllineitems}

\index{Context (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:cmd.context}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Context~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}}}}}
Declares variables according to the given binding context, which might
use {\hyperref[\detokenize{language/gallina-extensions:implicit-generalization}]{\sphinxcrossref{\DUrole{std,std-ref}{Implicit generalization}}}}.

\end{fulllineitems}

\index{typeclasses eauto (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:tacn.typeclasses-eauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{typeclasses~eauto}}}}
This tactic uses a different resolution engine than {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}} and
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}. The main differences are the following:
\begin{itemize}
\item {} 
Contrary to {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.eauto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{eauto}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}, the resolution is done entirely in
the new proof engine (as of Coq 8.6), meaning that backtracking is
available among dependent subgoals, and shelving goals is supported.
\sphinxcode{\sphinxupquote{typeclasses eauto}} is a multi-goal tactic. It analyses the dependencies
between subgoals to avoid backtracking on subgoals that are entirely
independent.

\item {} 
When called with no arguments, \sphinxcode{\sphinxupquote{typeclasses eauto}} uses
the \sphinxcode{\sphinxupquote{typeclass\_instances}} database by default (instead of core).
Dependent subgoals are automatically shelved, and shelved goals can
remain after resolution ends (following the behavior of Coq 8.5).

\begin{sphinxadmonition}{note}{Note:}
As of Coq 8.6, \sphinxcode{\sphinxupquote{all:once (typeclasses eauto)}} faithfully
mimicks what happens during typeclass resolution when it is called
during refinement/type inference, except that \sphinxstyleemphasis{only} declared class
subgoals are considered at the start of resolution during type
inference, while \sphinxcode{\sphinxupquote{all}} can select non-class subgoals as well. It might
move to \sphinxcode{\sphinxupquote{all:typeclasses eauto}} in future versions when the
refinement engine will be able to backtrack.
\end{sphinxadmonition}

\item {} 
When called with specific databases (e.g. with), \sphinxcode{\sphinxupquote{typeclasses eauto}}
allows shelved goals to remain at any point during search and treat
typeclass goals like any other.

\item {} 
The transparency information of databases is used consistently for
all hints declared in them. It is always used when calling the
unifier. When considering local hypotheses, we use the transparent
state of the first hint database given. Using an empty database
(created with {\hyperref[\detokenize{proof-engine/tactics:coq:cmd.create-hintdb}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Create HintDb}}}}} for example) with unfoldable variables and
constants as the first argument of \sphinxcode{\sphinxupquote{typeclasses eauto}} hence makes
resolution with the local hypotheses use full conversion during
unification.

\end{itemize}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{typeclasses~eauto~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}~
\begin{sphinxadmonition}{warning}{Warning:}
The semantics for the limit \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}
is different than for auto. By default, if no limit is given, the
search is unbounded. Contrary to {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}, introduction steps are
counted, which might result in larger limits being necessary when
searching with \sphinxcode{\sphinxupquote{typeclasses eauto}} than with {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.auto}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{auto}}}}}.
\end{sphinxadmonition}

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{typeclasses~eauto~with~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This variant runs resolution with the given hint databases. It treats
typeclass subgoals the same as other subgoals (no shelving of
non-typeclass goals in particular).

\end{fulllineitems}


\end{fulllineitems}

\index{autoapply (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:tacn.autoapply}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{autoapply~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
The tactic \sphinxcode{\sphinxupquote{autoapply}} applies a term using the transparency information
of the hint database ident, and does \sphinxstyleemphasis{no} typeclass resolution. This can
be used in {\hyperref[\detokenize{proof-engine/tactics:coq:cmdv.hint-extern}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Extern}}}}}’s for typeclass instances (in the hint
database \sphinxcode{\sphinxupquote{typeclass\_instances}}) to allow backtracking on the typeclass
subgoals created by the lemma application, rather than doing typeclass
resolution locally at the hint application time.

\end{fulllineitems}



\subsubsection{Typeclasses Transparent, Typclasses Opaque}
\label{\detokenize{addendum/type-classes:typeclasses-transparent-typclasses-opaque}}\label{\detokenize{addendum/type-classes:typeclassestransparent}}\index{Typeclasses Transparent (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:cmd.typeclasses-transparent}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Typeclasses~Transparent~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
This command makes the identifiers transparent during typeclass
resolution.

\end{fulllineitems}

\index{Typeclasses Opaque (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:cmd.typeclasses-opaque}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Typeclasses~Opaque~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
Make the identifiers opaque for typeclass search. It is useful when some
constants prevent some unifications and make resolution fail. It is also
useful to declare constants which should never be unfolded during
proof-search, like fixpoints or anything which does not look like an
abbreviation. This can additionally speed up proof search as the typeclass
map can be indexed by such rigid constants (see
{\hyperref[\detokenize{proof-engine/tactics:thehintsdatabasesforautoandeauto}]{\sphinxcrossref{\DUrole{std,std-ref}{The hints databases for auto and eauto}}}}).

\end{fulllineitems}


By default, all constants and local variables are considered transparent. One
should take care not to make opaque any constant that is used to abbreviate a
type, like:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
relation A := A \PYGZhy{}\PYGZgt{} A \PYGZhy{}\PYGZgt{} Prop.
\end{sphinxVerbatim}

This is equivalent to \sphinxcode{\sphinxupquote{Hint Transparent, Opaque ident : typeclass\_instances}}.


\subsubsection{Options}
\label{\detokenize{addendum/type-classes:options}}\index{Typeclasses Dependency Order (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:flag.typeclasses-dependency-order}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Typeclasses~Dependency~Order}}}}
This option (on by default since 8.6) respects the dependency order
between subgoals, meaning that subgoals on which other subgoals depend
come first, while the non-dependent subgoals were put before
the dependent ones previously (Coq 8.5 and below). This can result in
quite different performance behaviors of proof search.

\end{fulllineitems}

\index{Typeclasses Filtered Unification (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:flag.typeclasses-filtered-unification}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Typeclasses~Filtered~Unification}}}}
This option, available since Coq 8.6 and off by default, switches the
hint application procedure to a filter-then-unify strategy. To apply a
hint, we first check that the goal \sphinxstyleemphasis{matches} syntactically the
inferred or specified pattern of the hint, and only then try to
\sphinxstyleemphasis{unify} the goal with the conclusion of the hint. This can drastically
improve performance by calling unification less often, matching
syntactic patterns being very quick. This also provides more control
on the triggering of instances. For example, forcing a constant to
explicitely appear in the pattern will make it never apply on a goal
where there is a hole in that place.

\end{fulllineitems}

\index{Typeclasses Limit Intros (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:flag.typeclasses-limit-intros}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Typeclasses~Limit~Intros}}}}
This option (on by default) controls the ability to apply hints while
avoiding (functional) eta-expansions in the generated proof term. It
does so by allowing hints that conclude in a product to apply to a
goal with a matching product directly, avoiding an introduction.

\begin{sphinxadmonition}{warning}{Warning:}
This can be expensive as it requires rebuilding hint
clauses dynamically, and does not benefit from the invertibility
status of the product introduction rule, resulting in potentially more
expensive proof-search (i.e. more useless backtracking).
\end{sphinxadmonition}

\end{fulllineitems}

\index{Typeclass Resolution For Conversion (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:flag.typeclass-resolution-for-conversion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Typeclass~Resolution~For~Conversion}}}}
This option (on by default) controls the use of typeclass resolution
when a unification problem cannot be solved during elaboration/type
inference. With this option on, when a unification fails, typeclass
resolution is tried before launching unification once again.

\end{fulllineitems}

\index{Typeclasses Strict Resolution (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:flag.typeclasses-strict-resolution}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Typeclasses~Strict~Resolution}}}}
Typeclass declarations introduced when this option is set have a
stricter resolution behavior (the option is off by default). When
looking for unifications of a goal with an instance of this class, we
“freeze” all the existentials appearing in the goals, meaning that
they are considered rigid during unification and cannot be
instantiated.

\end{fulllineitems}

\index{Typeclasses Unique Solutions (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:flag.typeclasses-unique-solutions}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Typeclasses~Unique~Solutions}}}}
When a typeclass resolution is launched we ensure that it has a single
solution or fail. This ensures that the resolution is canonical, but
can make proof search much more expensive.

\end{fulllineitems}

\index{Typeclasses Unique Instances (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:flag.typeclasses-unique-instances}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Typeclasses~Unique~Instances}}}}
Typeclass declarations introduced when this option is set have a more
efficient resolution behavior (the option is off by default). When a
solution to the typeclass goal of this class is found, we never
backtrack on it, assuming that it is canonical.

\end{fulllineitems}

\index{Typeclasses Debug (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:flag.typeclasses-debug}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Typeclasses~Debug}}}}
Controls whether typeclass resolution steps are shown during search.  Setting this flag
also sets {\hyperref[\detokenize{addendum/type-classes:coq:opt.typeclasses-debug-verbosity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Typeclasses Debug Verbosity}}}}} to 1.

\end{fulllineitems}

\index{Typeclasses Debug Verbosity (opt)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:opt.typeclasses-debug-verbosity}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Option}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Typeclasses~Debug~Verbosity~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}}}}}
Determines how much information is shown for typeclass resolution steps during search.
1 is the default level.  2 shows additional information such as tried tactics and shelving
of goals.  Setting this option also sets {\hyperref[\detokenize{addendum/type-classes:coq:flag.typeclasses-debug}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Typeclasses Debug}}}}}.

\end{fulllineitems}

\index{Refine Instance Mode (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:flag.refine-instance-mode}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Refine~Instance~Mode}}}}
This option allows to switch the behavior of instance declarations made through
the Instance command.
\begin{itemize}
\item {} 
When it is on (the default), instances that have unsolved holes in
their proof-term silently open the proof mode with the remaining
obligations to prove.

\item {} 
When it is off, they fail with an error instead.

\end{itemize}

\end{fulllineitems}



\subsubsection{Typeclasses eauto \sphinxtitleref{:=}}
\label{\detokenize{addendum/type-classes:typeclasses-eauto}}\index{Typeclasses eauto (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/type-classes:coq:cmd.typeclasses-eauto}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Typeclasses~eauto~:=~\DUrole{repeat-wrapper}{\DUrole{repeat}{debug}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{curlies}{\{dfs~\textbar{}~bfs\}}}\DUrole{notation-sup}{?}}~depth}}}}
This command allows more global customization of the typeclass
resolution tactic. The semantics of the options are:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{debug}} In debug mode, the trace of successfully applied tactics is
printed.

\item {} 
\sphinxcode{\sphinxupquote{dfs, bfs}} This sets the search strategy to depth-first search (the
default) or breadth-first search.

\item {} 
\sphinxcode{\sphinxupquote{depth}} This sets the depth limit of the search.

\end{itemize}

\end{fulllineitems}



\section{Omega: a solver for quantifier-free problems in Presburger Arithmetic}
\label{\detokenize{addendum/omega:omega-a-solver-for-quantifier-free-problems-in-presburger-arithmetic}}\label{\detokenize{addendum/omega:omega}}\label{\detokenize{addendum/omega::doc}}\begin{quote}\begin{description}
\item[{Author}] \leavevmode
Pierre Crégut

\end{description}\end{quote}


\subsection{Description of \sphinxstyleliteralintitle{\sphinxupquote{omega}}}
\label{\detokenize{addendum/omega:description-of-omega}}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{omega}}}}
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}} is a tactic for solving goals in Presburger arithmetic,
i.e. for proving formulas made of equations and inequalities over the
type \sphinxcode{\sphinxupquote{nat}} of natural numbers or the type \sphinxcode{\sphinxupquote{Z}} of binary-encoded integers.
Formulas on \sphinxcode{\sphinxupquote{nat}} are automatically injected into \sphinxcode{\sphinxupquote{Z}}. The procedure
may use any hypothesis of the current proof session to solve the goal.

Multiplication is handled by {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}} but only goals where at
least one of the two multiplicands of products is a constant are
solvable. This is the restriction meant by "Presburger arithmetic".

If the tactic cannot solve the goal, it fails with an error message.
In any case, the computation eventually stops.

\end{fulllineitems}

\index{romega (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/omega:coq:tacv.romega}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{romega}}}}
To be documented.

\end{fulllineitems}



\subsection{Arithmetical goals recognized by \sphinxstyleliteralintitle{\sphinxupquote{omega}}}
\label{\detokenize{addendum/omega:arithmetical-goals-recognized-by-omega}}
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}} applies only to quantifier-free formulas built from the connectives:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
/\PYGZbs{}  \PYGZbs{}/  \PYGZti{}  \PYGZhy{}\PYGZgt{}
\end{sphinxVerbatim}

on atomic formulas. Atomic formulas are built from the predicates:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
=  \PYGZlt{}  \PYGZlt{}=  \PYGZgt{}  \PYGZgt{}=
\end{sphinxVerbatim}

on \sphinxcode{\sphinxupquote{nat}} or \sphinxcode{\sphinxupquote{Z}}. In expressions of type \sphinxcode{\sphinxupquote{nat}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}} recognizes:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
+  \PYGZhy{}  *  S  O  pred
\end{sphinxVerbatim}

and in expressions of type \sphinxcode{\sphinxupquote{Z}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}} recognizes numeral constants and:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
+  \PYGZhy{}  *  Z.succ Z.pred
\end{sphinxVerbatim}

All expressions of type \sphinxcode{\sphinxupquote{nat}} or \sphinxcode{\sphinxupquote{Z}} not built on these
operators are considered abstractly as if they
were arbitrary variables of type \sphinxcode{\sphinxupquote{nat}} or \sphinxcode{\sphinxupquote{Z}}.


\subsection{Messages from \sphinxstyleliteralintitle{\sphinxupquote{omega}}}
\label{\detokenize{addendum/omega:messages-from-omega}}
When {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}} does not solve the goal, one of the following errors
is generated:
\index{omega can't solve this system (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/omega:coq:exn.omega-can-t-solve-this-system}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{omega~can't~solve~this~system.}}}}
This may happen if your goal is not quantifier-free (if it is
universally quantified, try {\hyperref[\detokenize{proof-engine/tactics:coq:tacv.intros}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intros}}}}} first; if it contains
existentials quantifiers too, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}} is not strong enough to solve your
goal). This may happen also if your goal contains arithmetical
operators not recognized by {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}}. Finally, your goal may be simply
not true!

\end{fulllineitems}

\index{omega: Not a quantifier-free goal (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/omega:coq:exn.omega-not-a-quantifier-free-goal}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{omega:~Not~a~quantifier-free~goal.}}}}
If your goal is universally quantified, you should first apply
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.intro}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{intro}}}}} as many times as needed.

\end{fulllineitems}

\index{omega: Unrecognized predicate or connective: ‘ident’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/omega:coq:exn.omega-unrecognized-predicate-or-connective-ident}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{omega:~Unrecognized~predicate~or~connective:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}

\index{omega: Unrecognized atomic proposition: ... (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/omega:coq:exn.omega-unrecognized-atomic-proposition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{omega:~Unrecognized~atomic~proposition:~...}}}}
\end{fulllineitems}

\index{omega: Can't solve a goal with proposition variables (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/omega:coq:exn.omega-can-t-solve-a-goal-with-proposition-variables}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{omega:~Can't~solve~a~goal~with~proposition~variables.}}}}
\end{fulllineitems}

\index{omega: Unrecognized proposition (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/omega:coq:exn.omega-unrecognized-proposition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{omega:~Unrecognized~proposition.}}}}
\end{fulllineitems}

\index{omega: Can't solve a goal with non-linear products (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/omega:coq:exn.omega-can-t-solve-a-goal-with-non-linear-products}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{omega:~Can't~solve~a~goal~with~non-linear~products.}}}}
\end{fulllineitems}

\index{omega: Can't solve a goal with equality on type ... (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/omega:coq:exn.omega-can-t-solve-a-goal-with-equality-on-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{omega:~Can't~solve~a~goal~with~equality~on~type~...}}}}
\end{fulllineitems}



\subsection{Using \sphinxstyleliteralintitle{\sphinxupquote{omega}}}
\label{\detokenize{addendum/omega:using-omega}}
The \sphinxcode{\sphinxupquote{omega}} tactic does not belong to the core system. It should be
loaded by

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Omega}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Omega}\PYG{o}{.}
\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{Z\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{m} \PYG{n}{n}\PYG{o}{:}\PYG{n}{Z}\PYG{o}{,} \PYG{l+m+mi}{1} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{n}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{m} \PYG{n}{n} \PYG{o}{:} \PYG{n}{Z}\PYG{o}{,} \PYG{l+m+mi}{1} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{m} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{n}

\PYG{k}{intros}\PYG{o}{;} \PYG{k+kp}{omega}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{n}{Abort}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{z}\PYG{o}{:}\PYG{n}{Z}\PYG{o}{,} \PYG{n}{z} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{z} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZgt{}} \PYG{n}{z}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{z} \PYG{o}{:} \PYG{n}{Z}\PYG{o}{,} \PYG{n}{z} \PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{z} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZgt{}} \PYG{n}{z}

\PYG{k}{intro}\PYG{o}{;} \PYG{k+kp}{omega}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{n}{Abort}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsection{Options}
\label{\detokenize{addendum/omega:options}}\index{Stable Omega (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/omega:coq:flag.stable-omega}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Stable~Omega}}}}~
\DUrole{versionmodified}{Deprecated since version 8.5.}

This deprecated option (on by default) is for compatibility with Coq pre 8.5. It
resets internal name counters to make executions of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}} independent.

\end{fulllineitems}

\index{Omega UseLocalDefs (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/omega:coq:flag.omega-uselocaldefs}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Omega~UseLocalDefs}}}}
This option (on by default) allows {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}} to use the bodies of local
variables.

\end{fulllineitems}

\index{Omega System (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/omega:coq:flag.omega-system}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Omega~System}}}}
This option (off by default) activate the printing of debug information

\end{fulllineitems}

\index{Omega Action (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/omega:coq:flag.omega-action}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Omega~Action}}}}
This option (off by default) activate the printing of debug information

\end{fulllineitems}



\subsection{Technical data}
\label{\detokenize{addendum/omega:technical-data}}

\subsubsection{Overview of the tactic}
\label{\detokenize{addendum/omega:overview-of-the-tactic}}\begin{itemize}
\item {} 
The goal is negated twice and the first negation is introduced as a hypothesis.

\item {} 
Hypotheses are decomposed in simple equations or inequalities. Multiple
goals may result from this phase.

\item {} 
Equations and inequalities over \sphinxcode{\sphinxupquote{nat}} are translated over
\sphinxcode{\sphinxupquote{Z}}, multiple goals may result from the translation of subtraction.

\item {} 
Equations and inequalities are normalized.

\item {} 
Goals are solved by the OMEGA decision procedure.

\item {} 
The script of the solution is replayed.

\end{itemize}


\subsubsection{Overview of the OMEGA decision procedure}
\label{\detokenize{addendum/omega:overview-of-the-omega-decision-procedure}}
The OMEGA decision procedure involved in the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}} tactic uses
a small subset of the decision procedure presented in \sphinxcite{zebibliography:theomegapaper}
Here is an overview, refer to the original paper for more information.
\begin{itemize}
\item {} 
Equations and inequalities are normalized by division by the GCD of their
coefficients.

\item {} 
Equations are eliminated, using the Banerjee test to get a coefficient
equal to one.

\item {} 
Note that each inequality cuts the Euclidean space in half.

\item {} 
Inequalities are solved by projecting on the hyperspace
defined by cancelling one of the variables. They are partitioned
according to the sign of the coefficient of the eliminated
variable. Pairs of inequalities from different classes define a
new edge in the projection.

\item {} 
Redundant inequalities are eliminated or merged in new
equations that can be eliminated by the Banerjee test.

\item {} 
The last two steps are iterated until a contradiction is reached
(success) or there is no more variable to eliminate (failure).

\end{itemize}

It may happen that there is a real solution and no integer one. The last
steps of the Omega procedure are not implemented, so the
decision procedure is only partial.


\subsection{Bugs}
\label{\detokenize{addendum/omega:bugs}}\begin{itemize}
\item {} 
The simplification procedure is very dumb and this results in
many redundant cases to explore.

\item {} 
Much too slow.

\item {} 
Certainly other bugs! You can report them to \sphinxurl{https://coq.inria.fr/bugs/}.

\end{itemize}


\section{Micromega: tactics for solving arithmetic goals over ordered rings}
\label{\detokenize{addendum/micromega:micromega-tactics-for-solving-arithmetic-goals-over-ordered-rings}}\label{\detokenize{addendum/micromega::doc}}\begin{quote}\begin{description}
\item[{Authors}] \leavevmode
Frédéric Besson and Evgeny Makarov

\end{description}\end{quote}


\subsection{Short description of the tactics}
\label{\detokenize{addendum/micromega:short-description-of-the-tactics}}
The Psatz module (\sphinxcode{\sphinxupquote{Require Import Psatz.}}) gives access to several
tactics for solving arithmetic goals over \(\mathbb{Z}\), \(\mathbb{Q}\), and \(\mathbb{R}\) %
\begin{footnote}[20]\sphinxAtStartFootnote
Support for \sphinxtitleref{nat} and \(\mathbb{N}\) is obtained by pre-processing the goal with
the \sphinxtitleref{zify} tactic.
%
\end{footnote}.
It also possible to get the tactics for integers by a \sphinxcode{\sphinxupquote{Require Import Lia}},
rationals \sphinxcode{\sphinxupquote{Require Import Lqa}} and reals \sphinxcode{\sphinxupquote{Require Import Lra}}.
\begin{itemize}
\item {} 
{\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} is a decision procedure for linear integer arithmetic;

\item {} 
{\hyperref[\detokenize{addendum/micromega:coq:tacn.nia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nia}}}}} is an incomplete proof procedure for integer non-linear
arithmetic;

\item {} 
{\hyperref[\detokenize{addendum/micromega:coq:tacn.lra}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lra}}}}} is a decision procedure for linear (real or rational) arithmetic;

\item {} 
{\hyperref[\detokenize{addendum/micromega:coq:tacn.nra}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{nra}}}}} is an incomplete proof procedure for non-linear (real or
rational) arithmetic;

\item {} 
{\hyperref[\detokenize{addendum/micromega:coq:tacn.psatz}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{psatz}}}}} \sphinxcode{\sphinxupquote{D n}} where \sphinxcode{\sphinxupquote{D}} is \(\mathbb{Z}\) or \(\mathbb{Q}\) or \(\mathbb{R}\), and
\sphinxcode{\sphinxupquote{n}} is an optional integer limiting the proof search depth,
is an incomplete proof procedure for non-linear arithmetic.
It is based on John Harrison’s HOL Light
driver to the external prover \sphinxtitleref{csdp} %
\begin{footnote}[21]\sphinxAtStartFootnote
Sources and binaries can be found at \sphinxurl{https://projects.coin-or.org/Csdp}
%
\end{footnote}. Note that the \sphinxtitleref{csdp} driver is
generating a \sphinxstyleemphasis{proof cache} which makes it possible to rerun scripts
even without \sphinxtitleref{csdp}.

\end{itemize}

The tactics solve propositional formulas parameterized by atomic
arithmetic expressions interpreted over a domain \(D\) ∈ \{ℤ, ℚ, ℝ\}.
The syntax of the formulas is the following:
\begin{quote}


\begin{productionlist}
\phantomsection\label{\detokenize{addendum/micromega:grammar-token-F}}\production{F}{ A ∣ P ∣ True ∣ False ∣ F ∧ F ∣ F ∨ F ∣ F ↔ F ∣ F \(\rightarrow\) F ∣ ¬ F}
\phantomsection\label{\detokenize{addendum/micromega:grammar-token-A}}\production{A}{ p = p ∣ p \textgreater{} p ∣ p \textless{} p ∣ p ≥ p ∣ p ≤ p}
\phantomsection\label{\detokenize{addendum/micromega:grammar-token-p}}\production{p}{ c ∣ x ∣ −p ∣ p − p ∣ p + p ∣ p × p ∣ p \textasciicircum{} n}
\end{productionlist}

\end{quote}

where \(c\) is a numeric constant, \(x \in D\) is a numeric variable, the
operators \(−, +, ×\) are respectively subtraction, addition, and product;
\(p ^ n\) is exponentiation by a constant \(n\), \(P\) is an arbitrary proposition.
For \(\mathbb{Q}\), equality is not Leibniz equality = but the equality of
rationals ==.

For \(\mathbb{Z}\) (resp. \(\mathbb{Q}\)), \(c\) ranges over integer constants (resp. rational
constants). For \(\mathbb{R}\), the tactic recognizes as real constants the
following expressions:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
c ::= R0 \textbar{} R1 \textbar{} Rmul(c,c) \textbar{} Rplus(c,c) \textbar{} Rminus(c,c) \textbar{} IZR z \textbar{} IQR q \textbar{} Rdiv(c,c) \textbar{} Rinv c
\end{sphinxVerbatim}

where \(z\) is a constant in \(\mathbb{Z}\) and \(q\) is a constant in \(\mathbb{Q}\).
This includes integer constants written using the decimal notation, \sphinxstyleemphasis{i.e.}, c\%R.


\subsection{\sphinxstyleemphasis{Positivstellensatz} refutations}
\label{\detokenize{addendum/micromega:positivstellensatz-refutations}}
The name \sphinxtitleref{psatz} is an abbreviation for \sphinxstyleemphasis{positivstellensatz} \textendash{} literally
"positivity theorem" \textendash{} which generalizes Hilbert’s \sphinxstyleemphasis{nullstellensatz}. It
relies on the notion of Cone. Given a (finite) set of polynomials \(S\),
\(\mathit{Cone}(S)\) is inductively defined as the smallest set of polynomials
closed under the following rules:

\(\begin{array}{l}
\dfrac{p \in S}{p \in \mathit{Cone}(S)} \quad
\dfrac{}{p^2 \in \mathit{Cone}(S)} \quad
\dfrac{p_1 \in \mathit{Cone}(S) \quad p_2 \in \mathit{Cone}(S) \quad
\Join \in \{+,*\}} {p_1 \Join p_2 \in \mathit{Cone}(S)}\\
\end{array}\)

The following theorem provides a proof principle for checking that a
set of polynomial inequalities does not have solutions %
\begin{footnote}[22]\sphinxAtStartFootnote
Variants deal with equalities and strict inequalities.
%
\end{footnote}.

\phantomsection\label{\detokenize{addendum/micromega:psatz-thm}}
\sphinxstylestrong{Theorem (Psatz)}. Let \(S\) be a set of polynomials.
If \(-1\) belongs to \(\mathit{Cone}(S)\), then the conjunction
\(\bigwedge_{p \in S} p\ge 0\)  is unsatisfiable.
A proof based on this theorem is called a \sphinxstyleemphasis{positivstellensatz}
refutation. The tactics work as follows. Formulas are normalized into
conjunctive normal form \(\bigwedge_i C_i\) where \(C_i\) has the
general form \((\bigwedge_{j\in S_i} p_j \Join 0) \to \mathit{False}\) and
\(\Join \in \{>,\ge,=\}\) for \(D\in \{\mathbb{Q},\mathbb{R}\}\) and
\(\Join \in \{\ge, =\}\) for \(\mathbb{Z}\).

For each conjunct \(C_i\), the tactic calls an oracle which searches for
\(-1\) within the cone. Upon success, the oracle returns a \sphinxstyleemphasis{cone
expression} that is normalized by the ring tactic (see {\hyperref[\detokenize{addendum/ring:theringandfieldtacticfamilies}]{\sphinxcrossref{\DUrole{std,std-ref}{The ring and field tactic families}}}})
and checked to be \(-1\).


\subsection{\sphinxtitleref{lra}: a decision procedure for linear real and rational arithmetic}
\label{\detokenize{addendum/micromega:lra-a-decision-procedure-for-linear-real-and-rational-arithmetic}}\index{lra (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:tacn.lra}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{lra}}}}
\end{fulllineitems}


This tactic is searching for \sphinxstyleemphasis{linear} refutations using Fourier
elimination %
\begin{footnote}[23]\sphinxAtStartFootnote
More efficient linear programming techniques could equally be employed.
%
\end{footnote}. As a result, this tactic explores a subset of the \sphinxstyleemphasis{Cone}
defined as
\begin{quote}

\(\mathit{LinCone}(S) =\left\{ \left. \sum_{p \in S} \alpha_p \times p~\right|~\alpha_p \mbox{ are positive constants} \right\}\)
\end{quote}

The deductive power of \sphinxtitleref{lra} is the combined deductive power of
\sphinxtitleref{ring\_simplify} and \sphinxtitleref{fourier}. There is also an overlap with the field
tactic \sphinxstyleemphasis{e.g.}, \(x = 10 * x / 10\) is solved by \sphinxtitleref{lra}.


\subsection{\sphinxtitleref{lia}: a tactic for linear integer arithmetic}
\label{\detokenize{addendum/micromega:lia-a-tactic-for-linear-integer-arithmetic}}\index{lia (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:tacn.lia}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{lia}}}}
\end{fulllineitems}


This tactic offers an alternative to the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}} and {\hyperref[\detokenize{addendum/omega:coq:tacv.romega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{romega}}}}}
tactics. Roughly speaking, the deductive power of lia is the combined deductive
power of {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.ring-simplify}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ring\_simplify}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}}. However, it solves linear
goals that {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}} and {\hyperref[\detokenize{addendum/omega:coq:tacv.romega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{romega}}}}} do not solve, such as the following
so-called \sphinxstyleemphasis{omega nightmare} \sphinxcite{zebibliography:theomegapaper}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,}
  \PYG{l+m+mi}{27} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{11} \PYG{o}{*} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{13} \PYG{o}{*} \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{45} \PYG{o}{\PYGZhy{}\PYGZgt{}}
  \PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{10} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{7} \PYG{o}{*} \PYG{n}{x} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{9} \PYG{o}{*} \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{=} \PYG{l+m+mi}{4} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}\PYG{o}{.}
\end{sphinxVerbatim}

The estimation of the relative efficiency of {\hyperref[\detokenize{addendum/micromega:coq:tacn.lia}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lia}}}}} \sphinxstyleemphasis{vs} {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.omega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{omega}}}}} and
{\hyperref[\detokenize{addendum/omega:coq:tacv.romega}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{romega}}}}} is under evaluation.


\subsubsection{High level view of \sphinxtitleref{lia}}
\label{\detokenize{addendum/micromega:high-level-view-of-lia}}
Over \(\mathbb{R}\), \sphinxstyleemphasis{positivstellensatz} refutations are a complete proof
principle %
\begin{footnote}[24]\sphinxAtStartFootnote
In practice, the oracle might fail to produce such a refutation.
%
\end{footnote}. However, this is not the case over \(\mathbb{Z}\). Actually,
\sphinxstyleemphasis{positivstellensatz} refutations are not even sufficient to decide
linear \sphinxstyleemphasis{integer} arithmetic. The canonical example is \(2 * x = 1 -> \mathtt{False}\)
which is a theorem of \(\mathbb{Z}\) but not a theorem of \({\mathbb{R}}\). To remedy this
weakness, the \sphinxtitleref{lia} tactic is using recursively a combination of:
\begin{itemize}
\item {} 
linear \sphinxstyleemphasis{positivstellensatz} refutations;

\item {} 
cutting plane proofs;

\item {} 
case split.

\end{itemize}


\subsubsection{Cutting plane proofs}
\label{\detokenize{addendum/micromega:cutting-plane-proofs}}
are a way to take into account the discreteness of \(\mathbb{Z}\) by rounding up
(rational) constants up-to the closest integer.

\phantomsection\label{\detokenize{addendum/micromega:ceil-thm}}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Theorem}}} \sphinxbfcode{\sphinxupquote{Bound~on~the~ceiling~function}}}
Let \(p\) be an integer and \(c\) a rational constant. Then
\(p \ge c \rightarrow p \ge \lceil{c}\rceil\).

\end{fulllineitems}


For instance, from 2 x = 1 we can deduce
\begin{itemize}
\item {} 
\(x \ge 1/2\) whose cut plane is \(x \ge \lceil{1/2}\rceil = 1\);

\item {} 
\(x \le 1/2\) whose cut plane is \(x \le \lfloor{1/2}\rfloor = 0\).

\end{itemize}

By combining these two facts (in normal form) \(x − 1 \ge 0\) and
\(-x \ge 0\), we conclude by exhibiting a \sphinxstyleemphasis{positivstellensatz} refutation:
\(−1 \equiv x−1 + −x \in \mathit{Cone}({x−1,x})\).

Cutting plane proofs and linear \sphinxstyleemphasis{positivstellensatz} refutations are a
complete proof principle for integer linear arithmetic.


\subsubsection{Case split}
\label{\detokenize{addendum/micromega:case-split}}
enumerates over the possible values of an expression.

\phantomsection\label{\detokenize{addendum/micromega:casesplit-thm}}
\sphinxstylestrong{Theorem}. Let \(p\) be an integer and \(c_1\) and \(c_2\)
integer constants. Then:
\begin{quote}

\(c_1 \le p \le c_2 \Rightarrow \bigvee_{x \in [c_1,c_2]} p = x\)
\end{quote}

Our current oracle tries to find an expression \(e\) with a small range
\([c_1,c_2]\). We generate \(c_2 − c_1\) subgoals which contexts are enriched
with an equation \(e = i\) for \(i \in [c_1,c_2]\) and recursively search for
a proof.


\subsection{\sphinxtitleref{nra}: a proof procedure for non-linear arithmetic}
\label{\detokenize{addendum/micromega:nra-a-proof-procedure-for-non-linear-arithmetic}}\index{nra (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:tacn.nra}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{nra}}}}
\end{fulllineitems}


This tactic is an \sphinxstyleemphasis{experimental} proof procedure for non-linear
arithmetic. The tactic performs a limited amount of non-linear
reasoning before running the linear prover of \sphinxtitleref{lra}. This pre-processing
does the following:
\begin{itemize}
\item {} 
If the context contains an arithmetic expression of the form
\(e[x^2]\) where \(x\) is a monomial, the context is enriched with
\(x^2 \ge 0\);

\item {} 
For all pairs of hypotheses \(e_1 \ge 0\), \(e_2 \ge 0\), the context is
enriched with \(e_1 \times e_2 \ge 0\).

\end{itemize}

After this pre-processing, the linear prover of \sphinxtitleref{lra} searches for a
proof by abstracting monomials by variables.


\subsection{\sphinxtitleref{nia}: a proof procedure for non-linear integer arithmetic}
\label{\detokenize{addendum/micromega:nia-a-proof-procedure-for-non-linear-integer-arithmetic}}\index{nia (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:tacn.nia}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{nia}}}}
\end{fulllineitems}


This tactic is a proof procedure for non-linear integer arithmetic.
It performs a pre-processing similar to \sphinxtitleref{nra}. The obtained goal is
solved using the linear integer prover \sphinxtitleref{lia}.


\subsection{\sphinxtitleref{psatz}: a proof procedure for non-linear arithmetic}
\label{\detokenize{addendum/micromega:psatz-a-proof-procedure-for-non-linear-arithmetic}}\index{psatz (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/micromega:coq:tacn.psatz}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{psatz}}}}
\end{fulllineitems}


This tactic explores the \(\mathit{Cone}\) by increasing degrees \textendash{} hence the
depth parameter \(n\). In theory, such a proof search is complete \textendash{} if the
goal is provable the search eventually stops. Unfortunately, the
external oracle is using numeric (approximate) optimization techniques
that might miss a refutation.

To illustrate the working of the tactic, consider we wish to prove the
following Coq goal:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{ZArith} \PYG{n}{Psatz}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{z\PYGZus{}syntax\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{quote\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{newring\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{omega\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{r\PYGZus{}syntax\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{micromega\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}

\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{Z\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{o}{\PYGZhy{}}\PYG{n}{x}\PYG{o}{\PYGZca{}}\PYG{l+m+mi}{2} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{Z}\PYG{o}{,} \PYG{o}{\PYGZhy{}} \PYG{n}{x} \PYG{o}{\PYGZca{}} \PYG{l+m+mi}{2} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}

\PYG{k}{intro} \PYG{n}{x}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{x} \PYG{o}{:} \PYG{n}{Z}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{\PYGZhy{}} \PYG{n}{x} \PYG{o}{\PYGZca{}} \PYG{l+m+mi}{2} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1} \PYG{o}{\PYGZgt{}}\PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{False}

\PYG{n}{psatz} \PYG{n}{Z} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{9}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{n}{psatz} \PYG{n}{Z} \PYG{l+m+mi}{2}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:}
    \PYG{n}{In} \PYG{n}{nested} \PYG{k+kn}{Ltac} \PYG{n}{calls} \PYG{n}{to} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{psatz (constr) (int\PYGZus{}or\PYGZus{}var)}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{,} 
    \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{xpsatz}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{and} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{psatz\PYGZus{}Z (int\PYGZus{}or\PYGZus{}var) (tactic)}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{,} \PYG{k+kr}{last} \PYG{n}{call} \PYG{n}{failed}\PYG{o}{.}
    \PYG{k+kn}{Tactic} \PYG{n}{failure}\PYG{o}{:}  \PYG{n}{Skipping} \PYG{n}{what} \PYG{n}{remains} \PYG{k}{of} \PYG{n}{this} \PYG{n}{tactic}\PYG{o}{:} \PYG{n}{the} \PYG{n}{complexity} \PYG{k}{of} \PYG{n}{the} \PYG{n}{goal} \PYG{n}{requires} \PYG{n}{the} \PYG{n}{use} \PYG{k}{of} \PYG{n}{a} \PYG{n}{specialized} \PYG{n}{external} \PYG{n}{tool} \PYG{n}{called} \PYG{n}{csdp}\PYG{o}{.} 
    
    \PYG{n}{Unfortunately} \PYG{n}{Coq} \PYG{n}{isn\PYGZsq{}t} \PYG{n}{aware} \PYG{k}{of} \PYG{n}{the} \PYG{n}{presence} \PYG{k}{of} \PYG{n}{any} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{csdp}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{executable} \PYG{k}{in} \PYG{n}{the} \PYG{n}{path}\PYG{o}{.} 
    
    \PYG{n}{Csdp} \PYG{n}{packages} \PYG{n}{are} \PYG{n}{provided} \PYG{k+kp}{by} \PYG{n}{some} \PYG{n}{OS} \PYG{n}{distributions}\PYG{o}{;} \PYG{n}{binaries} \PYG{n}{and} \PYG{n}{source} \PYG{n}{code} \PYG{n}{can} \PYG{n}{be} \PYG{n}{downloaded} \PYG{n}{from} \PYG{n}{https}\PYG{o}{:}\PYG{o}{//}\PYG{n}{projects}\PYG{o}{.}\PYG{n}{coin}\PYG{o}{\PYGZhy{}}\PYG{n}{or}\PYG{o}{.}\PYG{n}{org}\PYG{o}{/}\PYG{n}{Csdp}\PYG{o}{.}
\end{sphinxVerbatim}

As shown, such a goal is solved by \sphinxcode{\sphinxupquote{intro x. psatz Z 2.}}. The oracle returns the
cone expression \(2 \times (x-1) + (\mathbf{x-1}) \times (\mathbf{x−1}) + -x^2\)
(polynomial hypotheses are printed in bold). By construction, this expression
belongs to \(\mathit{Cone}({−x^2,x -1})\). Moreover, by running \sphinxtitleref{ring} we
obtain \(-1\). By Theorem {\hyperref[\detokenize{addendum/micromega:psatz-thm}]{\sphinxcrossref{\DUrole{std,std-ref}{Psatz}}}}, the goal is valid.


\section{Extraction of programs in OCaml and Haskell}
\label{\detokenize{addendum/extraction:extraction-of-programs-in-ocaml-and-haskell}}\label{\detokenize{addendum/extraction:extraction}}\label{\detokenize{addendum/extraction::doc}}\begin{quote}\begin{description}
\item[{Authors}] \leavevmode
Jean-Christophe Filliâtre and Pierre Letouzey

\end{description}\end{quote}

We present here the \DUrole{smallcaps}{Coq} extraction commands, used to build certified
and relatively efficient functional programs, extracting them from
either \DUrole{smallcaps}{Coq} functions or \DUrole{smallcaps}{Coq} proofs of specifications. The
functional languages available as output are currently \DUrole{smallcaps}{OCaml}, Haskell
and Scheme. In the following, "ML" will be used (abusively) to refer
to any of the three.

Before using any of the commands or options described in this chapter,
the extraction framework should first be loaded explicitly
via \sphinxcode{\sphinxupquote{Require Extraction}}, or via the more robust
\sphinxcode{\sphinxupquote{From Coq Require Extraction}}.
Note that in earlier versions of Coq, these commands and options were
directly available without any preliminary \sphinxcode{\sphinxupquote{Require}}.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{n}{Extraction}\PYG{o}{.}
\end{sphinxVerbatim}


\subsection{Generating ML Code}
\label{\detokenize{addendum/extraction:generating-ml-code}}
\begin{sphinxadmonition}{note}{Note:}
In the following, a qualified identifier \sphinxtitleref{qualid}
can be used to refer to any kind of \DUrole{smallcaps}{Coq} global "object" : constant,
inductive type, inductive constructor or module name.
\end{sphinxadmonition}

The next two commands are meant to be used for rapid preview of
extraction. They both display extracted term(s) inside \DUrole{smallcaps}{Coq}.
\index{Extraction (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.extraction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}}}}
Extraction of the mentioned object in the \DUrole{smallcaps}{Coq} toplevel.

\end{fulllineitems}

\index{Recursive Extraction (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.recursive-extraction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Recursive~Extraction~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
Recursive extraction of all the mentioned objects and
all their dependencies in the \DUrole{smallcaps}{Coq} toplevel.

\end{fulllineitems}


All the following commands produce real ML files. User can choose to
produce one monolithic file or one file per \DUrole{smallcaps}{Coq} library.
\index{Extraction (cmd)}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~"\DUrole{hole}{file}"~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
Recursive extraction of all the mentioned objects and all
their dependencies in one monolithic \sphinxtitleref{file}.
Global and local identifiers are renamed according to the chosen ML
language to fulfill its syntactic conventions, keeping original
names as much as possible.

\end{fulllineitems}

\index{Extraction Library (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.extraction-library}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~Library~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Extraction of the whole \DUrole{smallcaps}{Coq} library \sphinxcode{\sphinxupquote{ident.v}} to an ML module
\sphinxcode{\sphinxupquote{ident.ml}}. In case of name clash, identifiers are here renamed
using prefixes \sphinxcode{\sphinxupquote{coq\_}}  or \sphinxcode{\sphinxupquote{Coq\_}} to ensure a session-independent
renaming.

\end{fulllineitems}

\index{Recursive Extraction Library (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.recursive-extraction-library}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Recursive~Extraction~Library~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
Extraction of the \DUrole{smallcaps}{Coq} library \sphinxcode{\sphinxupquote{ident.v}} and all other modules
\sphinxcode{\sphinxupquote{ident.v}} depends on.

\end{fulllineitems}

\index{Separate Extraction (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.separate-extraction}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Separate~Extraction~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
Recursive extraction of all the mentioned objects and all
their dependencies, just as \sphinxcode{\sphinxupquote{Extraction "file"}},
but instead of producing one monolithic file, this command splits
the produced code in separate ML files, one per corresponding Coq
\sphinxcode{\sphinxupquote{.v}} file. This command is hence quite similar to
{\hyperref[\detokenize{addendum/extraction:coq:cmd.recursive-extraction-library}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Recursive Extraction Library}}}}}, except that only the needed
parts of Coq libraries are extracted instead of the whole.
The naming convention in case of name clash is the same one as
{\hyperref[\detokenize{addendum/extraction:coq:cmd.extraction-library}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Extraction Library}}}}}: identifiers are here renamed using prefixes
\sphinxcode{\sphinxupquote{coq\_}}  or \sphinxcode{\sphinxupquote{Coq\_}}.

\end{fulllineitems}


The following command is meant to help automatic testing of
the extraction, see for instance the \sphinxcode{\sphinxupquote{test-suite}} directory
in the \DUrole{smallcaps}{Coq} sources.
\index{Extraction TestCompile (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.extraction-testcompile}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~TestCompile~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
All the mentioned objects and all their dependencies are extracted
to a temporary \DUrole{smallcaps}{OCaml} file, just as in \sphinxcode{\sphinxupquote{Extraction "file"}}. Then
this temporary file and its signature are compiled with the same
\DUrole{smallcaps}{OCaml} compiler used to built \DUrole{smallcaps}{Coq}. This command succeeds only
if the extraction and the \DUrole{smallcaps}{OCaml} compilation succeed. It fails
if the current target language of the extraction is not \DUrole{smallcaps}{OCaml}.

\end{fulllineitems}



\subsection{Extraction Options}
\label{\detokenize{addendum/extraction:extraction-options}}

\subsubsection{Setting the target language}
\label{\detokenize{addendum/extraction:setting-the-target-language}}
The ability to fix target language is the first and more important
of the extraction options. Default is \sphinxcode{\sphinxupquote{OCaml}}.
\index{Extraction Language OCaml (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.extraction-language-ocaml}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~Language~OCaml}}}}
\end{fulllineitems}

\index{Extraction Language Haskell (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.extraction-language-haskell}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~Language~Haskell}}}}
\end{fulllineitems}

\index{Extraction Language Scheme (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.extraction-language-scheme}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~Language~Scheme}}}}
\end{fulllineitems}



\subsubsection{Inlining and optimizations}
\label{\detokenize{addendum/extraction:inlining-and-optimizations}}
Since \DUrole{smallcaps}{OCaml} is a strict language, the extracted code has to
be optimized in order to be efficient (for instance, when using
induction principles we do not want to compute all the recursive calls
but only the needed ones). So the extraction mechanism provides an
automatic optimization routine that will be called each time the user
wants to generate an \DUrole{smallcaps}{OCaml} program. The optimizations can be split in two
groups: the type-preserving ones (essentially constant inlining and
reductions) and the non type-preserving ones (some function
abstractions of dummy types are removed when it is deemed safe in order
to have more elegant types). Therefore some constants may not appear in the
resulting monolithic \DUrole{smallcaps}{OCaml} program. In the case of modular extraction,
even if some inlining is done, the inlined constants are nevertheless
printed, to ensure session-independent programs.

Concerning Haskell, type-preserving optimizations are less useful
because of laziness. We still make some optimizations, for example in
order to produce more readable code.

The type-preserving optimizations are controlled by the following \DUrole{smallcaps}{Coq} options:
\index{Extraction Optimize (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:flag.extraction-optimize}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~Optimize}}}}
Default is on. This controls all type-preserving optimizations made on
the ML terms (mostly reduction of dummy beta/iota redexes, but also
simplifications on Cases, etc). Turn this option off if you want a
ML term as close as possible to the Coq term.

\end{fulllineitems}

\index{Extraction Conservative Types (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:flag.extraction-conservative-types}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~Conservative~Types}}}}
Default is off. This controls the non type-preserving optimizations
made on ML terms (which try to avoid function abstraction of dummy
types). Turn this option on to make sure that \sphinxcode{\sphinxupquote{e:t}}
implies that \sphinxcode{\sphinxupquote{e':t'}} where \sphinxcode{\sphinxupquote{e'}} and \sphinxcode{\sphinxupquote{t'}} are the extracted
code of \sphinxcode{\sphinxupquote{e}} and \sphinxcode{\sphinxupquote{t}} respectively.

\end{fulllineitems}

\index{Extraction KeepSingleton (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:flag.extraction-keepsingleton}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~KeepSingleton}}}}
Default is off. Normally, when the extraction of an inductive type
produces a singleton type (i.e. a type with only one constructor, and
only one argument to this constructor), the inductive structure is
removed and this type is seen as an alias to the inner type.
The typical example is \sphinxcode{\sphinxupquote{sig}}. This option allows disabling this
optimization when one wishes to preserve the inductive structure of types.

\end{fulllineitems}

\index{Extraction AutoInline (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:flag.extraction-autoinline}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~AutoInline}}}}
Default is on. The extraction mechanism inlines the bodies of
some defined constants, according to some heuristics
like size of bodies, uselessness of some arguments, etc.
Those heuristics are not always perfect; if you want to disable
this feature, turn this option off.

\end{fulllineitems}

\index{Extraction Inline (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.extraction-inline}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~Inline~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
In addition to the automatic inline feature, the constants
mentionned by this command will always be inlined during extraction.

\end{fulllineitems}

\index{Extraction NoInline (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.extraction-noinline}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~NoInline~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}}\DUrole{notation-sup}{+}}}}}}
Conversely, the constants mentionned by this command will
never be inlined during extraction.

\end{fulllineitems}

\index{Print Extraction Inline (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.print-extraction-inline}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Extraction~Inline}}}}
Prints the current state of the table recording the custom inlinings
declared by the two previous commands.

\end{fulllineitems}

\index{Reset Extraction Inline (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.reset-extraction-inline}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Reset~Extraction~Inline}}}}
Empties the table recording the custom inlinings (see the
previous commands).

\end{fulllineitems}


\sphinxstylestrong{Inlining and printing of a constant declaration:}

The user can explicitly ask for a constant to be extracted by two means:
\begin{itemize}
\item {} 
by mentioning it on the extraction command line

\item {} 
by extracting the whole \DUrole{smallcaps}{Coq} module of this constant.

\end{itemize}

In both cases, the declaration of this constant will be present in the
produced file. But this same constant may or may not be inlined in
the following terms, depending on the automatic/custom inlining mechanism.

For the constants non-explicitly required but needed for dependency
reasons, there are two cases:
\begin{itemize}
\item {} 
If an inlining decision is taken, whether automatically or not,
all occurrences of this constant are replaced by its extracted body,
and this constant is not declared in the generated file.

\item {} 
If no inlining decision is taken, the constant is normally
declared in the produced file.

\end{itemize}


\subsubsection{Extra elimination of useless arguments}
\label{\detokenize{addendum/extraction:extra-elimination-of-useless-arguments}}
The following command provides some extra manual control on the
code elimination performed during extraction, in a way which
is independent but complementary to the main elimination
principles of extraction (logical parts and types).
\index{Extraction Implicit (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.extraction-implicit}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~Implicit~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}~{]}}}}}
This experimental command allows declaring some arguments of
\sphinxtitleref{qualid} as implicit, i.e. useless in extracted code and hence to
be removed by extraction. Here \sphinxtitleref{qualid} can be any function or
inductive constructor, and the given \sphinxtitleref{ident} are the names of
the concerned arguments. In fact, an argument can also be referred
by a number indicating its position, starting from 1.

\end{fulllineitems}


When an actual extraction takes place, an error is normally raised if the
{\hyperref[\detokenize{addendum/extraction:coq:cmd.extraction-implicit}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Extraction Implicit}}}}} declarations cannot be honored, that is
if any of the implicit arguments still occurs in the final code.
This behavior can be relaxed via the following option:
\index{Extraction SafeImplicits (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:flag.extraction-safeimplicits}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~SafeImplicits}}}}
Default is on. When this option is off, a warning is emitted
instead of an error if some implicit arguments still occur in the
final code of an extraction. This way, the extracted code may be
obtained nonetheless and reviewed manually to locate the source of the issue
(in the code, some comments mark the location of these remaining implicit arguments).
Note that this extracted code might not compile or run properly,
depending of the use of these remaining implicit arguments.

\end{fulllineitems}



\subsubsection{Realizing axioms}
\label{\detokenize{addendum/extraction:realizing-axioms}}
Extraction will fail if it encounters an informative axiom not realized.
A warning will be issued if it encounters a logical axiom, to remind the
user that inconsistent logical axioms may lead to incorrect or
non-terminating extracted terms.

It is possible to assume some axioms while developing a proof. Since
these axioms can be any kind of proposition or object or type, they may
perfectly well have some computational content. But a program must be
a closed term, and of course the system cannot guess the program which
realizes an axiom.  Therefore, it is possible to tell the system
what ML term corresponds to a given axiom.
\index{Extract Constant (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.extract-constant}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extract~Constant~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~=\textgreater{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
Give an ML extraction for the given constant.
The \sphinxtitleref{string} may be an identifier or a quoted string.

\end{fulllineitems}

\index{Extract Inlined Constant (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.extract-inlined-constant}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extract~Inlined~Constant~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~=\textgreater{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
Same as the previous one, except that the given ML terms will
be inlined everywhere instead of being declared via a \sphinxcode{\sphinxupquote{let}}.

\begin{sphinxadmonition}{note}{Note:}
This command is sugar for an {\hyperref[\detokenize{addendum/extraction:coq:cmd.extract-constant}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Extract Constant}}}}} followed
by a {\hyperref[\detokenize{addendum/extraction:coq:cmd.extraction-inline}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Extraction Inline}}}}}. Hence a {\hyperref[\detokenize{addendum/extraction:coq:cmd.reset-extraction-inline}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Reset Extraction Inline}}}}}
will have an effect on the realized and inlined axiom.
\end{sphinxadmonition}

\end{fulllineitems}


\begin{sphinxadmonition}{caution}{Caution:}
It is the responsibility of the user to ensure that the ML
terms given to realize the axioms do have the expected types. In
fact, the strings containing realizing code are just copied to the
extracted files. The extraction recognizes whether the realized axiom
should become a ML type constant or a ML object declaration. For example:
\end{sphinxadmonition}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{X}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{x}\PYG{o}{:}\PYG{n}{X}\PYG{o}{.}
\PYG{n}{Extract} \PYG{n}{Constant} \PYG{n}{X} \PYG{o}{=\PYGZgt{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{int}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\PYG{n}{Extract} \PYG{n}{Constant} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{0}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

Notice that in the case of type scheme axiom (i.e. whose type is an
arity, that is a sequence of product finished by a sort), then some type
variables have to be given (as quoted strings). The syntax is then:


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extract~Constant~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~...~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~=\textgreater{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
\end{fulllineitems}


The number of type variables is checked by the system. For example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Axiom} \PYG{n}{Y} \PYG{o}{:} \PYG{k+kn}{Set} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kn}{Set}\PYG{o}{.}
\PYG{n}{Extract} \PYG{n}{Constant} \PYG{n}{Y} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}a}\PYG{l+s+s2}{\PYGZdq{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{\PYGZsq{}b}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{=\PYGZgt{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{ \PYGZsq{}a * \PYGZsq{}b }\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}

Realizing an axiom via {\hyperref[\detokenize{addendum/extraction:coq:cmd.extract-constant}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Extract Constant}}}}} is only useful in the
case of an informative axiom (of sort \sphinxcode{\sphinxupquote{Type}} or \sphinxcode{\sphinxupquote{Set}}). A logical axiom
has no computational content and hence will not appear in extracted
terms. But a warning is nonetheless issued if extraction encounters a
logical axiom. This warning reminds user that inconsistent logical
axioms may lead to incorrect or non-terminating extracted terms.

If an informative axiom has not been realized before an extraction, a
warning is also issued and the definition of the axiom is filled with
an exception labeled \sphinxcode{\sphinxupquote{AXIOM TO BE REALIZED}}. The user must then
search these exceptions inside the extracted file and replace them by
real code.


\subsubsection{Realizing inductive types}
\label{\detokenize{addendum/extraction:realizing-inductive-types}}
The system also provides a mechanism to specify ML terms for inductive
types and constructors. For instance, the user may want to use the ML
native boolean type instead of the \DUrole{smallcaps}{Coq} one. The syntax is the following:
\index{Extract Inductive (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.extract-inductive}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extract~Inductive~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~=\textgreater{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{+}}~{]}}}}}
Give an ML extraction for the given inductive type. You must specify
extractions for the type itself (first \sphinxtitleref{string}) and all its
constructors (all the \sphinxtitleref{string} between square brackets). In this form,
the ML extraction must be an ML inductive datatype, and the native
pattern matching of the language will be used.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extract~Inductive~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-qualid}]{\sphinxcrossref{\DUrole{hole}{qualid}}}}~=\textgreater{}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}\DUrole{notation-sup}{+}}~{]}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-string}]{\sphinxcrossref{\DUrole{hole}{string}}}}}}}}
Same as before, with a final extra \sphinxtitleref{string} that indicates how to
perform pattern matching over this inductive type. In this form,
the ML extraction could be an arbitrary type.
For an inductive type with \sphinxtitleref{k} constructors, the function used to
emulate the pattern matching should expect \sphinxtitleref{(k+1)} arguments, first the \sphinxtitleref{k}
branches in functional form, and then the inductive element to
destruct. For instance, the match branch \sphinxcode{\sphinxupquote{\textbar{} S n =\textgreater{} foo}} gives the
functional form \sphinxcode{\sphinxupquote{(fun n -\textgreater{} foo)}}. Note that a constructor with no
arguments is considered to have one unit argument, in order to block
early evaluation of the branch: \sphinxcode{\sphinxupquote{\textbar{} O =\textgreater{} bar}} leads to the functional
form \sphinxcode{\sphinxupquote{(fun () -\textgreater{} bar)}}. For instance, when extracting \sphinxcode{\sphinxupquote{nat}}
into \DUrole{smallcaps}{OCaml} \sphinxcode{\sphinxupquote{int}}, the code to be provided has type:
\sphinxcode{\sphinxupquote{(unit-\textgreater{}'a)-\textgreater{}(int-\textgreater{}'a)-\textgreater{}int-\textgreater{}'a}}.

\end{fulllineitems}


\begin{sphinxadmonition}{caution}{Caution:}
As for {\hyperref[\detokenize{addendum/extraction:coq:cmd.extract-constant}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Extract Constant}}}}}, this command should be used with care:
\begin{itemize}
\item {} 
The ML code provided by the user is currently \sphinxstylestrong{not} checked at all by
extraction, even for syntax errors.

\item {} 
Extracting an inductive type to a pre-existing ML inductive type
is quite sound. But extracting to a general type (by providing an
ad-hoc pattern matching) will often \sphinxstylestrong{not} be fully rigorously
correct. For instance, when extracting \sphinxcode{\sphinxupquote{nat}} to \DUrole{smallcaps}{OCaml} \sphinxcode{\sphinxupquote{int}},
it is theoretically possible to build \sphinxcode{\sphinxupquote{nat}} values that are
larger than \DUrole{smallcaps}{OCaml} \sphinxcode{\sphinxupquote{max\_int}}. It is the user's responsibility to
be sure that no overflow or other bad events occur in practice.

\item {} 
Translating an inductive type to an arbitrary ML type does \sphinxstylestrong{not}
magically improve the asymptotic complexity of functions, even if the
ML type is an efficient representation. For instance, when extracting
\sphinxcode{\sphinxupquote{nat}} to \DUrole{smallcaps}{OCaml} \sphinxcode{\sphinxupquote{int}}, the function \sphinxcode{\sphinxupquote{Nat.mul}} stays quadratic.
It might be interesting to associate this translation with
some specific {\hyperref[\detokenize{addendum/extraction:coq:cmd.extract-constant}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Extract Constant}}}}} when primitive counterparts exist.

\end{itemize}
\end{sphinxadmonition}

Typical examples are the following:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Extract} \PYG{k+kn}{Inductive} \PYG{k+kt}{unit} \PYG{o}{=\PYGZgt{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{unit}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{[} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{()}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{]}\PYG{o}{.}
\PYG{n}{Extract} \PYG{k+kn}{Inductive} \PYG{k+kt}{bool} \PYG{o}{=\PYGZgt{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{bool}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{[} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{true}\PYG{l+s+s2}{\PYGZdq{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{false}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{]}\PYG{o}{.}
\PYG{n}{Extract} \PYG{k+kn}{Inductive} \PYG{n}{sumbool} \PYG{o}{=\PYGZgt{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{bool}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{[} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{true}\PYG{l+s+s2}{\PYGZdq{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{false}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{note}{Note:}
When extracting to \DUrole{smallcaps}{OCaml}, if an inductive constructor or type has arity 2 and
the corresponding string is enclosed by parentheses, and the string meets
\DUrole{smallcaps}{OCaml}'s lexical criteria for an infix symbol, then the rest of the string is
used as an infix constructor or type.
\end{sphinxadmonition}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Extract} \PYG{k+kn}{Inductive} \PYG{k+kt}{list} \PYG{o}{=\PYGZgt{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{list}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{[} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{[]}\PYG{l+s+s2}{\PYGZdq{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{(::)}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{]}\PYG{o}{.}
\PYG{n}{Extract} \PYG{k+kn}{Inductive} \PYG{n}{prod} \PYG{o}{=\PYGZgt{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{(*)}\PYG{l+s+s2}{\PYGZdq{}}  \PYG{o}{[} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{(,)}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

As an example of translation to a non-inductive datatype, let's turn
\sphinxcode{\sphinxupquote{nat}} into \DUrole{smallcaps}{OCaml} \sphinxcode{\sphinxupquote{int}} (see caveat above):

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Extract} \PYG{k+kn}{Inductive} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{int} \PYG{o}{[} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{0}\PYG{l+s+s2}{\PYGZdq{}} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{succ}\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{]} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{(fun fO fS n \PYGZhy{}\PYGZgt{} if n=0 then fO () else fS (n\PYGZhy{}1))}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{.}
\end{sphinxVerbatim}


\subsubsection{Avoiding conflicts with existing filenames}
\label{\detokenize{addendum/extraction:avoiding-conflicts-with-existing-filenames}}
When using {\hyperref[\detokenize{addendum/extraction:coq:cmd.extraction-library}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Extraction Library}}}}}, the names of the extracted files
directly depend on the names of the \DUrole{smallcaps}{Coq} files. It may happen that
these filenames are in conflict with already existing files,
either in the standard library of the target language or in other
code that is meant to be linked with the extracted code.
For instance the module \sphinxcode{\sphinxupquote{List}} exists both in \DUrole{smallcaps}{Coq} and in \DUrole{smallcaps}{OCaml}.
It is possible to instruct the extraction not to use particular filenames.
\index{Extraction Blacklist (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.extraction-blacklist}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Extraction~Blacklist~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{+}}}}}}
Instruct the extraction to avoid using these names as filenames
for extracted code.

\end{fulllineitems}

\index{Print Extraction Blacklist (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.print-extraction-blacklist}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Extraction~Blacklist}}}}
Show the current list of filenames the extraction should avoid.

\end{fulllineitems}

\index{Reset Extraction Blacklist (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/extraction:coq:cmd.reset-extraction-blacklist}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Reset~Extraction~Blacklist}}}}
Allow the extraction to use any filename.

\end{fulllineitems}


For \DUrole{smallcaps}{OCaml}, a typical use of these commands is
\sphinxcode{\sphinxupquote{Extraction Blacklist String List}}.


\subsection{Differences between Coq and ML type systems}
\label{\detokenize{addendum/extraction:differences-between-coq-and-ml-type-systems}}
Due to differences between \DUrole{smallcaps}{Coq} and ML type systems,
some extracted programs are not directly typable in ML.
We now solve this problem (at least in \DUrole{smallcaps}{OCaml}) by adding
when needed some unsafe casting \sphinxcode{\sphinxupquote{Obj.magic}}, which give
a generic type \sphinxcode{\sphinxupquote{'a}} to any term.

First, if some part of the program is \sphinxstyleemphasis{very} polymorphic, there
may be no ML type for it. In that case the extraction to ML works
alright but the generated code may be refused by the ML
type checker. A very well known example is the \sphinxcode{\sphinxupquote{distr-pair}}
function:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{dp} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{n}{B}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}}\PYG{o}{(}\PYG{n}{x}\PYG{o}{:}\PYG{n}{A}\PYG{o}{)}\PYG{o}{(}\PYG{n}{y}\PYG{o}{:}\PYG{n}{B}\PYG{o}{)}\PYG{o}{(}\PYG{n}{f}\PYG{o}{:}\PYG{k}{forall} \PYG{n}{C}\PYG{o}{:}\PYG{k+kt}{Type}\PYG{o}{,} \PYG{n}{C}\PYG{o}{\PYGZhy{}\PYGZgt{}}\PYG{n}{C}\PYG{o}{)} \PYG{o}{:=} \PYG{o}{(}\PYG{n}{f} \PYG{n}{A} \PYG{n}{x}\PYG{o}{,} \PYG{n}{f} \PYG{n}{B} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

In \DUrole{smallcaps}{OCaml}, for instance, the direct extracted term would be:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
let dp x y f = Pair((f () x),(f () y))
\end{sphinxVerbatim}

and would have type:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
dp : \PYGZsq{}a \PYGZhy{}\PYGZgt{} \PYGZsq{}a \PYGZhy{}\PYGZgt{} (unit \PYGZhy{}\PYGZgt{} \PYGZsq{}a \PYGZhy{}\PYGZgt{} \PYGZsq{}b) \PYGZhy{}\PYGZgt{} (\PYGZsq{}b,\PYGZsq{}b) prod
\end{sphinxVerbatim}

which is not its original type, but a restriction.

We now produce the following correct version:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
let dp x y f = Pair ((Obj.magic f () x), (Obj.magic f () y))
\end{sphinxVerbatim}

Secondly, some \DUrole{smallcaps}{Coq} definitions may have no counterpart in ML. This
happens when there is a quantification over types inside the type
of a constructor; for example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{anything} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=} \PYG{n}{dummy} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A}\PYG{o}{:}\PYG{k+kn}{Set}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{anything}\PYG{o}{.}
\end{sphinxVerbatim}

which corresponds to the definition of an ML dynamic type.
In \DUrole{smallcaps}{OCaml}, we must cast any argument of the constructor dummy
(no GADT are produced yet by the extraction).

Even with those unsafe castings, you should never get error like
\sphinxcode{\sphinxupquote{segmentation fault}}. In fact even if your program may seem
ill-typed to the \DUrole{smallcaps}{OCaml} type checker, it can't go wrong : it comes
from a Coq well-typed terms, so for example inductive types will always
have the correct number of arguments, etc. Of course, when launching
manually some extracted function, you should apply it to arguments
of the right shape (from the \DUrole{smallcaps}{Coq} point-of-view).

More details about the correctness of the extracted programs can be
found in \sphinxcite{zebibliography:let02}.

We have to say, though, that in most "realistic" programs, these problems do not
occur. For example all the programs of Coq library are accepted by the \DUrole{smallcaps}{OCaml}
type checker without any \sphinxcode{\sphinxupquote{Obj.magic}} (see examples below).


\subsection{Some examples}
\label{\detokenize{addendum/extraction:some-examples}}
We present here two examples of extraction, taken from the
\DUrole{smallcaps}{Coq} Standard Library. We choose \DUrole{smallcaps}{OCaml} as the target language,
but everything, with slight modifications, can also be done in the
other languages supported by extraction.
We then indicate where to find other examples and tests of extraction.


\subsubsection{A detailed example: Euclidean division}
\label{\detokenize{addendum/extraction:a-detailed-example-euclidean-division}}
The file \sphinxcode{\sphinxupquote{Euclid}} contains the proof of Euclidean division.
The natural numbers used here are unary, represented by the type{}`{}`nat{}`{}`,
which is defined by two constructors \sphinxcode{\sphinxupquote{O}} and \sphinxcode{\sphinxupquote{S}}.
This module contains a theorem \sphinxcode{\sphinxupquote{eucl\_dev}}, whose type is:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
forall b:nat, b \PYGZgt{} 0 \PYGZhy{}\PYGZgt{} forall a:nat, diveucl a b
\end{sphinxVerbatim}

where \sphinxcode{\sphinxupquote{diveucl}} is a type for the pair of the quotient and the
modulo, plus some logical assertions that disappear during extraction.
We can now extract this program to \DUrole{smallcaps}{OCaml}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{n}{Extraction}\PYG{o}{.}
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Euclid} \PYG{n}{Wf\PYGZus{}nat}\PYG{o}{.}
\PYG{n}{Extraction} \PYG{n}{Inline} \PYG{n}{gt\PYGZus{}wf\PYGZus{}rec} \PYG{n}{lt\PYGZus{}wf\PYGZus{}rec} \PYG{n}{induction\PYGZus{}ltof2}\PYG{o}{.}
\PYG{n}{Recursive} \PYG{n}{Extraction} \PYG{n}{eucl\PYGZus{}dev}\PYG{o}{.}
    \PYG{n}{type} \PYG{k+kt}{nat} \PYG{o}{=}
    \PYG{o}{\textbar{}} \PYG{n}{O}
    \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{k}{of} \PYG{k+kt}{nat}
    
    \PYG{n}{type} \PYG{n}{sumbool} \PYG{o}{=}
    \PYG{o}{\textbar{}} \PYG{n}{Left}
    \PYG{o}{\textbar{}} \PYG{n}{Right}
    
    \PYG{c}{(*}\PYG{c}{*}\PYG{c}{ val sub : nat \PYGZhy{}\PYGZgt{} nat \PYGZhy{}\PYGZgt{} nat }\PYG{c}{*}\PYG{c}{*)}
    
    \PYG{k}{let} \PYG{n}{rec} \PYG{n}{sub} \PYG{n}{n} \PYG{n}{m} \PYG{o}{=}
      \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
      \PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n}
      \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{k} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{k}{match} \PYG{n}{m} \PYG{k}{with}
                \PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{n}
                \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{l} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{sub} \PYG{n}{k} \PYG{n}{l}\PYG{o}{)}
    
    \PYG{c}{(*}\PYG{c}{*}\PYG{c}{ val le\PYGZus{}lt\PYGZus{}dec : nat \PYGZhy{}\PYGZgt{} nat \PYGZhy{}\PYGZgt{} sumbool }\PYG{c}{*}\PYG{c}{*)}
    
    \PYG{k}{let} \PYG{n}{rec} \PYG{n}{le\PYGZus{}lt\PYGZus{}dec} \PYG{n}{n} \PYG{n}{m} \PYG{o}{=}
      \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
      \PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Left}
      \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{n0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{k}{match} \PYG{n}{m} \PYG{k}{with}
                 \PYG{o}{\textbar{}} \PYG{n}{O} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Right}
                 \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{n}{m0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{le\PYGZus{}lt\PYGZus{}dec} \PYG{n}{n0} \PYG{n}{m0}\PYG{o}{)}
    
    \PYG{c}{(*}\PYG{c}{*}\PYG{c}{ val le\PYGZus{}gt\PYGZus{}dec : nat \PYGZhy{}\PYGZgt{} nat \PYGZhy{}\PYGZgt{} sumbool }\PYG{c}{*}\PYG{c}{*)}
    
    \PYG{k}{let} \PYG{n}{le\PYGZus{}gt\PYGZus{}dec} \PYG{o}{=}
      \PYG{n}{le\PYGZus{}lt\PYGZus{}dec}
    
    \PYG{n}{type} \PYG{n}{diveucl} \PYG{o}{=}
    \PYG{o}{\textbar{}} \PYG{n}{Divex} \PYG{k}{of} \PYG{k+kt}{nat} \PYG{o}{*} \PYG{k+kt}{nat}
    
    \PYG{c}{(*}\PYG{c}{*}\PYG{c}{ val eucl\PYGZus{}dev : nat \PYGZhy{}\PYGZgt{} nat \PYGZhy{}\PYGZgt{} diveucl }\PYG{c}{*}\PYG{c}{*)}
    
    \PYG{k}{let} \PYG{n}{rec} \PYG{n}{eucl\PYGZus{}dev} \PYG{n}{n} \PYG{n}{m} \PYG{o}{=}
      \PYG{k}{let} \PYG{n}{s} \PYG{o}{=} \PYG{n}{le\PYGZus{}gt\PYGZus{}dec} \PYG{n}{n} \PYG{n}{m} \PYG{k}{in}
      \PYG{o}{(}\PYG{k}{match} \PYG{n}{s} \PYG{k}{with}
       \PYG{o}{\textbar{}} \PYG{n}{Left} \PYG{o}{\PYGZhy{}\PYGZgt{}}
         \PYG{k}{let} \PYG{n}{d} \PYG{o}{=} \PYG{k}{let} \PYG{n}{y} \PYG{o}{=} \PYG{n}{sub} \PYG{n}{m} \PYG{n}{n} \PYG{k}{in} \PYG{n}{eucl\PYGZus{}dev} \PYG{n}{n} \PYG{n}{y} \PYG{k}{in}
         \PYG{k}{let} \PYG{n}{Divex} \PYG{o}{(}\PYG{n}{q}\PYG{o}{,} \PYG{n}{r}\PYG{o}{)} \PYG{o}{=} \PYG{n}{d} \PYG{k}{in} \PYG{n}{Divex} \PYG{o}{(}\PYG{o}{(}\PYG{n}{S} \PYG{n}{q}\PYG{o}{)}\PYG{o}{,} \PYG{n}{r}\PYG{o}{)}
       \PYG{o}{\textbar{}} \PYG{n}{Right} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Divex} \PYG{o}{(}\PYG{n}{O}\PYG{o}{,} \PYG{n}{m}\PYG{o}{)}\PYG{o}{)}
\end{sphinxVerbatim}

The inlining of \sphinxcode{\sphinxupquote{gt\_wf\_rec}} and others is not
mandatory. It only enhances readability of extracted code.
You can then copy-paste the output to a file \sphinxcode{\sphinxupquote{euclid.ml}} or let
\DUrole{smallcaps}{Coq} do it for you with the following command:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Extraction \PYGZdq{}euclid\PYGZdq{} eucl\PYGZus{}dev.
\end{sphinxVerbatim}

Let us play the resulting program (in an \DUrole{smallcaps}{OCaml} toplevel):

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZsh{}use \PYGZdq{}euclid.ml\PYGZdq{};;
type nat = O \textbar{} S of nat
type sumbool = Left \textbar{} Right
val sub : nat \PYGZhy{}\PYGZgt{} nat \PYGZhy{}\PYGZgt{} nat = \PYGZlt{}fun\PYGZgt{}
val le\PYGZus{}lt\PYGZus{}dec : nat \PYGZhy{}\PYGZgt{} nat \PYGZhy{}\PYGZgt{} sumbool = \PYGZlt{}fun\PYGZgt{}
val le\PYGZus{}gt\PYGZus{}dec : nat \PYGZhy{}\PYGZgt{} nat \PYGZhy{}\PYGZgt{} sumbool = \PYGZlt{}fun\PYGZgt{}
type diveucl = Divex of nat * nat
val eucl\PYGZus{}dev : nat \PYGZhy{}\PYGZgt{} nat \PYGZhy{}\PYGZgt{} diveucl = \PYGZlt{}fun\PYGZgt{}

\PYGZsh{} eucl\PYGZus{}dev (S (S O)) (S (S (S (S (S O)))));;
\PYGZhy{} : diveucl = Divex (S (S O), S O)
\end{sphinxVerbatim}

It is easier to test on \DUrole{smallcaps}{OCaml} integers:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYGZsh{} let rec nat\PYGZus{}of\PYGZus{}int = function 0 \PYGZhy{}\PYGZgt{} O \textbar{} n \PYGZhy{}\PYGZgt{} S (nat\PYGZus{}of\PYGZus{}int (n\PYGZhy{}1));;
val nat\PYGZus{}of\PYGZus{}int : int \PYGZhy{}\PYGZgt{} nat = \PYGZlt{}fun\PYGZgt{}

\PYGZsh{} let rec int\PYGZus{}of\PYGZus{}nat = function O \PYGZhy{}\PYGZgt{} 0 \textbar{} S p \PYGZhy{}\PYGZgt{} 1+(int\PYGZus{}of\PYGZus{}nat p);;
val int\PYGZus{}of\PYGZus{}nat : nat \PYGZhy{}\PYGZgt{} int = \PYGZlt{}fun\PYGZgt{}

\PYGZsh{} let div a b =
  let Divex (q,r) = eucl\PYGZus{}dev (nat\PYGZus{}of\PYGZus{}int b) (nat\PYGZus{}of\PYGZus{}int a)
  in (int\PYGZus{}of\PYGZus{}nat q, int\PYGZus{}of\PYGZus{}nat r);;
val div : int \PYGZhy{}\PYGZgt{} int \PYGZhy{}\PYGZgt{} int * int = \PYGZlt{}fun\PYGZgt{}

\PYGZsh{} div 173 15;;
\PYGZhy{} : int * int = (11, 8)
\end{sphinxVerbatim}

Note that these \sphinxcode{\sphinxupquote{nat\_of\_int}} and \sphinxcode{\sphinxupquote{int\_of\_nat}} are now
available via a mere \sphinxcode{\sphinxupquote{Require Import ExtrOcamlIntConv}} and then
adding these functions to the list of functions to extract. This file
\sphinxcode{\sphinxupquote{ExtrOcamlIntConv.v}} and some others in \sphinxcode{\sphinxupquote{plugins/extraction/}}
are meant to help building concrete program via extraction.


\subsubsection{Extraction's horror museum}
\label{\detokenize{addendum/extraction:extraction-s-horror-museum}}
Some pathological examples of extraction are grouped in the file
\sphinxcode{\sphinxupquote{test-suite/success/extraction.v}} of the sources of \DUrole{smallcaps}{Coq}.


\subsubsection{Users' Contributions}
\label{\detokenize{addendum/extraction:users-contributions}}
Several of the \DUrole{smallcaps}{Coq} Users' Contributions use extraction to produce
certified programs. In particular the following ones have an automatic
extraction test:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{additions}} : \sphinxurl{https://github.com/coq-contribs/additions}

\item {} 
\sphinxcode{\sphinxupquote{bdds}} : \sphinxurl{https://github.com/coq-contribs/bdds}

\item {} 
\sphinxcode{\sphinxupquote{canon-bdds}} : \sphinxurl{https://github.com/coq-contribs/canon-bdds}

\item {} 
\sphinxcode{\sphinxupquote{chinese}} : \sphinxurl{https://github.com/coq-contribs/chinese}

\item {} 
\sphinxcode{\sphinxupquote{continuations}} : \sphinxurl{https://github.com/coq-contribs/continuations}

\item {} 
\sphinxcode{\sphinxupquote{coq-in-coq}} : \sphinxurl{https://github.com/coq-contribs/coq-in-coq}

\item {} 
\sphinxcode{\sphinxupquote{exceptions}} : \sphinxurl{https://github.com/coq-contribs/exceptions}

\item {} 
\sphinxcode{\sphinxupquote{firing-squad}} : \sphinxurl{https://github.com/coq-contribs/firing-squad}

\item {} 
\sphinxcode{\sphinxupquote{founify}} : \sphinxurl{https://github.com/coq-contribs/founify}

\item {} 
\sphinxcode{\sphinxupquote{graphs}} : \sphinxurl{https://github.com/coq-contribs/graphs}

\item {} 
\sphinxcode{\sphinxupquote{higman-cf}} : \sphinxurl{https://github.com/coq-contribs/higman-cf}

\item {} 
\sphinxcode{\sphinxupquote{higman-nw}} : \sphinxurl{https://github.com/coq-contribs/higman-nw}

\item {} 
\sphinxcode{\sphinxupquote{hardware}} : \sphinxurl{https://github.com/coq-contribs/hardware}

\item {} 
\sphinxcode{\sphinxupquote{multiplier}} : \sphinxurl{https://github.com/coq-contribs/multiplier}

\item {} 
\sphinxcode{\sphinxupquote{search-trees}} : \sphinxurl{https://github.com/coq-contribs/search-trees}

\item {} 
\sphinxcode{\sphinxupquote{stalmarck}} : \sphinxurl{https://github.com/coq-contribs/stalmarck}

\end{itemize}

Note that \sphinxcode{\sphinxupquote{continuations}} and \sphinxcode{\sphinxupquote{multiplier}} are a bit particular. They are
examples of developments where \sphinxcode{\sphinxupquote{Obj.magic}} is needed. This is
probably due to a heavy use of impredicativity. After compilation, those
two examples run nonetheless, thanks to the correction of the
extraction \sphinxcite{zebibliography:let02}.


\section{Program}
\label{\detokenize{addendum/program:program}}\label{\detokenize{addendum/program:programs}}\label{\detokenize{addendum/program::doc}}\begin{quote}\begin{description}
\item[{Author}] \leavevmode
Matthieu Sozeau

\end{description}\end{quote}

We present here the \sphinxstylestrong{Program} tactic commands, used to build
certified \DUrole{smallcaps}{Coq} programs, elaborating them from their algorithmic
skeleton and a rich specification \sphinxcite{zebibliography:sozeau06}. It can be thought of as a
dual of {\hyperref[\detokenize{addendum/extraction:extraction}]{\sphinxcrossref{\DUrole{std,std-ref}{Extraction}}}}. The goal of \sphinxstylestrong{Program} is to
program as in a regular functional programming language whilst using
as rich a specification as desired and proving that the code meets the
specification using the whole \DUrole{smallcaps}{Coq} proof apparatus. This is done using
a technique originating from the “Predicate subtyping” mechanism of
PVS \sphinxcite{zebibliography:rushby98}, which generates type checking conditions while typing a
term constrained to a particular type. Here we insert existential
variables in the term, which must be filled with proofs to get a
complete \DUrole{smallcaps}{Coq} term. \sphinxstylestrong{Program} replaces the \sphinxstylestrong{Program} tactic by Catherine
Parent \sphinxcite{zebibliography:parent95b} which had a similar goal but is no longer maintained.

The languages available as input are currently restricted to \DUrole{smallcaps}{Coq}’s
term language, but may be extended to OCaml, Haskell and
others in the future. We use the same syntax as \DUrole{smallcaps}{Coq} and permit to use
implicit arguments and the existing coercion mechanism. Input terms
and types are typed in an extended system (Russell) and interpreted
into \DUrole{smallcaps}{Coq} terms. The interpretation process may produce some proof
obligations which need to be resolved to create the final term.


\subsection{Elaborating programs}
\label{\detokenize{addendum/program:elaborating-programs}}\label{\detokenize{addendum/program:id4}}
The main difference from \DUrole{smallcaps}{Coq} is that an object in a type \sphinxcode{\sphinxupquote{\DUrole{name}{T} \DUrole{operator}{:} \DUrole{keyword,namespace}{Set}}} can
be considered as an object of type \sphinxcode{\sphinxupquote{\DUrole{operator}{\{}\DUrole{name}{x} \DUrole{operator}{:} \DUrole{name}{T} \DUrole{operator}{\textbar{}} \DUrole{name}{P}\DUrole{operator}{\}}}} for any well-formed
\sphinxcode{\sphinxupquote{\DUrole{name}{P} \DUrole{operator}{:} \DUrole{keyword,type}{Prop}}}. If we go from \sphinxcode{\sphinxupquote{\DUrole{name}{T}}} to the subset of \sphinxcode{\sphinxupquote{\DUrole{name}{T}}} verifying property
\sphinxcode{\sphinxupquote{\DUrole{name}{P}}}, we must prove that the object under consideration verifies it. Russell
will generate an obligation for every such coercion. In the other direction,
Russell will automatically insert a projection.

Another distinction is the treatment of pattern matching. Apart from
the following differences, it is equivalent to the standard match
operation (see {\hyperref[\detokenize{addendum/extended-pattern-matching:extendedpatternmatching}]{\sphinxcrossref{\DUrole{std,std-ref}{Extended pattern matching}}}}).
\begin{itemize}
\item {} 
Generation of equalities. A match expression is always generalized
by the corresponding equality. As an example, the expression:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
match x with
\textbar{} 0 =\PYGZgt{} t
\textbar{} S n =\PYGZgt{} u
end.
\end{sphinxVerbatim}

will be first rewritten to:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
(match x as y return (x = y \PYGZhy{}\PYGZgt{} \PYGZus{}) with
\textbar{} 0 =\PYGZgt{} fun H : x = 0 \PYGZhy{}\PYGZgt{} t
\textbar{} S n =\PYGZgt{} fun H : x = S n \PYGZhy{}\PYGZgt{} u
end) (eq\PYGZus{}refl x).
\end{sphinxVerbatim}

This permits to get the proper equalities in the context of proof
obligations inside clauses, without which reasoning is very limited.

\item {} 
Generation of disequalities. If a pattern intersects with a previous
one, a disequality is added in the context of the second branch. See
for example the definition of div2 below, where the second branch is
typed in a context where \sphinxcode{\sphinxupquote{\DUrole{error}{∀} \DUrole{name}{p}\DUrole{operator}{,} \DUrole{operator}{\_} \DUrole{operator}{\textless{}\textgreater{}} \DUrole{name}{S} \DUrole{operator}{(}\DUrole{name}{S} \DUrole{name}{p}\DUrole{operator}{)}}}.

\item {} 
Coercion. If the object being matched is coercible to an inductive
type, the corresponding coercion will be automatically inserted. This
also works with the previous mechanism.

\end{itemize}

There are options to control the generation of equalities and
coercions.
\index{Program Cases (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:flag.program-cases}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Program~Cases}}}}
This controls the special treatment of pattern matching generating equalities
and disequalities when using \sphinxstylestrong{Program} (it is on by default). All
pattern-matches and let-patterns are handled using the standard algorithm
of \DUrole{smallcaps}{Coq} (see {\hyperref[\detokenize{addendum/extended-pattern-matching:extendedpatternmatching}]{\sphinxcrossref{\DUrole{std,std-ref}{Extended pattern matching}}}}) when this option is
deactivated.

\end{fulllineitems}

\index{Program Generalized Coercion (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:flag.program-generalized-coercion}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Program~Generalized~Coercion}}}}
This controls the coercion of general inductive types when using \sphinxstylestrong{Program}
(the option is on by default). Coercion of subset types and pairs is still
active in this case.

\end{fulllineitems}



\subsubsection{Syntactic control over equalities}
\label{\detokenize{addendum/program:syntactic-control-over-equalities}}\label{\detokenize{addendum/program:syntactic-control}}
To give more control over the generation of equalities, the
type checker will fall back directly to \DUrole{smallcaps}{Coq}’s usual typing of dependent
pattern matching if a return or in clause is specified. Likewise, the
if construct is not treated specially by \sphinxstylestrong{Program} so boolean tests in
the code are not automatically reflected in the obligations. One can
use the \sphinxcode{\sphinxupquote{\DUrole{name}{dec}}} combinator to get the correct hypotheses as in:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Program} \PYG{n}{Arith}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Program} \PYG{k+kn}{Definition} \PYG{n}{id} \PYG{o}{(}\PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{o}{\PYGZob{}} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\textbar{}} \PYG{n}{x} \PYG{o}{=} \PYG{n}{n} \PYG{o}{\PYGZcb{}} \PYG{o}{:=}
  \PYG{k}{if} \PYG{n}{dec} \PYG{o}{(}\PYG{n}{leb} \PYG{n}{n} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{k}{then} \PYG{l+m+mi}{0}
  \PYG{k}{else} \PYG{n}{S} \PYG{o}{(}\PYG{n}{pred} \PYG{n}{n}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{id} \PYG{n}{has} \PYG{n}{type}\PYG{o}{\PYGZhy{}}\PYG{n}{checked}\PYG{o}{,} \PYG{n}{generating} \PYG{l+m+mi}{2} \PYG{n}{obligations}
    \PYG{n}{Solving} \PYG{n}{obligations} \PYG{n}{automatically}\PYG{o}{..}\PYG{o}{.}
    \PYG{l+m+mi}{2} \PYG{n}{obligations} \PYG{n}{remaining}
    \PYG{n}{Obligation} \PYG{l+m+mi}{1} \PYG{k}{of} \PYG{n}{id}\PYG{o}{:}
    \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{o}{(}\PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=}\PYG{o}{?} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{x} \PYG{o}{=} \PYG{n}{n}\PYG{o}{)} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{.}
     
    \PYG{n}{Obligation} \PYG{l+m+mi}{2} \PYG{k}{of} \PYG{n}{id}\PYG{o}{:}
    \PYG{o}{(}\PYG{k}{forall} \PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,}
     \PYG{o}{(}\PYG{n}{n} \PYG{o}{\PYGZlt{}}\PYG{o}{=}\PYG{o}{?} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{=} \PYG{n+nb+bp}{false} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{x} \PYG{o}{=} \PYG{n}{n}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S} \PYG{o}{(}\PYG{n}{Init}\PYG{o}{.}\PYG{n}{Nat}\PYG{o}{.}\PYG{n}{pred} \PYG{n}{n}\PYG{o}{)}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

The \sphinxcode{\sphinxupquote{\DUrole{keyword}{let}}} tupling construct \sphinxcode{\sphinxupquote{\DUrole{keyword}{let} \DUrole{operator}{(}\DUrole{name}{x1}\DUrole{operator}{,} \DUrole{operator}{...,} \DUrole{name}{xn}\DUrole{operator}{)} \DUrole{operator}{:=} \DUrole{name}{t} \DUrole{keyword}{in} \DUrole{name}{b}}} does not
produce an equality, contrary to the let pattern construct \sphinxcode{\sphinxupquote{\DUrole{keyword}{let} \DUrole{error}{’}\DUrole{operator}{(}\DUrole{name}{x1}\DUrole{operator}{,}
\DUrole{operator}{...,} \DUrole{name}{xn}\DUrole{operator}{)} \DUrole{operator}{:=} \DUrole{name}{t} \DUrole{keyword}{in} \DUrole{name}{b}}}. Also, \sphinxcode{\sphinxupquote{\DUrole{name}{term} \DUrole{operator}{:\textgreater{}}}} explicitly asks the system to
coerce term to its support type. It can be useful in notations, for
example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Notation} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{ x {}`= y }\PYG{l+s+s2}{\PYGZdq{}} \PYG{o}{:=} \PYG{o}{(}\PYG{o}{@}\PYG{n}{eq} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:\PYGZgt{}}\PYG{o}{)} \PYG{o}{(}\PYG{n}{y} \PYG{o}{:\PYGZgt{}}\PYG{o}{)}\PYG{o}{)} \PYG{o}{(}\PYG{n}{only} \PYG{n}{parsing}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

This notation denotes equality on subset types using equality on their
support types, avoiding uses of proof-irrelevance that would come up
when reasoning with equality on the subset types themselves.

The next two commands are similar to their standard counterparts
{\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.definition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Definition}}}}} and {\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}}
in that they define constants. However, they may require the user to
prove some goals to construct the final definitions.


\subsubsection{Program Definition}
\label{\detokenize{addendum/program:program-definition}}\label{\detokenize{addendum/program:id5}}\index{Program Definition (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:cmd.program-definition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Program~Definition~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This command types the value term in Russell and generates proof
obligations. Once solved using the commands shown below, it binds the
final \DUrole{smallcaps}{Coq} term to the name \sphinxcode{\sphinxupquote{ident}} in the environment.
\index{"@ident already exists. (Program Definition) (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:exn.ident-already-exists-program-definition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~already~exists.}}}}
\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Program~Definition~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
It interprets the type \sphinxcode{\sphinxupquote{type}}, potentially generating proof
obligations to be resolved. Once done with them, we have a \DUrole{smallcaps}{Coq}
type \sphinxtitleref{type}\(_{0}\). It then elaborates the preterm \sphinxcode{\sphinxupquote{term}} into a \DUrole{smallcaps}{Coq}
term \sphinxtitleref{term}\(_{0}\), checking that the type of \sphinxtitleref{term}\(_{0}\) is coercible to
\sphinxtitleref{type}\(_{0}\), and registers \sphinxcode{\sphinxupquote{ident}} as being of type \sphinxtitleref{type}\(_{0}\) once the
set of obligations generated during the interpretation of \sphinxtitleref{term}\(_{0}\)
and the aforementioned coercion derivation are solved.
\index{In environment … the term: ‘term’ does not have type ‘type’. Actually, it has type ... (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:exn.in-environment-the-term-term-does-not-have-type-type-actually-it-has-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{In~environment~…~the~term:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~does~not~have~type~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}.~Actually,~it~has~type~...}}}}
\end{fulllineitems}


\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Program~Definition~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-binders}]{\sphinxcrossref{\DUrole{hole}{binders}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
This is equivalent to:

\sphinxcode{\sphinxupquote{\DUrole{name}{Program} \DUrole{keyword,namespace}{Definition} \DUrole{name}{ident} \DUrole{operator}{:} \DUrole{keyword}{forall} \DUrole{name}{binders}\DUrole{operator}{,} \DUrole{name}{type} \DUrole{operator}{:=} \DUrole{keyword}{fun} \DUrole{name}{binders} \DUrole{operator}{=\textgreater{}} \DUrole{name}{term}}}.

\end{fulllineitems}


\end{fulllineitems}



\sphinxstrong{See also:}


Sections {\hyperref[\detokenize{proof-engine/vernacular-commands:vernac-controlling-the-reduction-strategies}]{\sphinxcrossref{\DUrole{std,std-ref}{Controlling the reduction strategies and the conversion algorithm}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.unfold}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{unfold}}}}}




\subsubsection{Program Fixpoint}
\label{\detokenize{addendum/program:program-fixpoint}}\label{\detokenize{addendum/program:id6}}\index{Program Fixpoint (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:cmd.program-fixpoint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Program~Fixpoint~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{hole}{params}~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{curlies}{\{{\hyperref[\detokenize{addendum/program:grammar-token-order}]{\sphinxcrossref{\DUrole{hole}{order}}}}\}}}\DUrole{notation-sup}{?}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}~:=~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}
\end{fulllineitems}


The optional order annotation follows the grammar:


\begin{productionlist}
\phantomsection\label{\detokenize{addendum/program:grammar-token-order}}\production{order}{ measure {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} ({\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}})? \textbar{} wf {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\end{productionlist}

\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{\DUrole{name}{measure} \DUrole{name}{f} \DUrole{operator}{(} \DUrole{name}{R} \DUrole{operator}{)}}} where \sphinxcode{\sphinxupquote{\DUrole{name}{f}}} is a value of type \sphinxcode{\sphinxupquote{\DUrole{name}{X}}} computed on
any subset of the arguments and the optional (parenthesised) term
\sphinxcode{\sphinxupquote{(R)}} is a relation on \sphinxcode{\sphinxupquote{X}}. By default \sphinxcode{\sphinxupquote{X}} defaults to \sphinxcode{\sphinxupquote{nat}} and \sphinxcode{\sphinxupquote{R}}
to \sphinxcode{\sphinxupquote{lt}}.

\item {} 
\sphinxcode{\sphinxupquote{\DUrole{name}{wf} \DUrole{name}{R} \DUrole{name}{x}}} which is equivalent to \sphinxcode{\sphinxupquote{\DUrole{name}{measure} \DUrole{name}{x} \DUrole{operator}{(}\DUrole{name}{R}\DUrole{operator}{)}}}.

\end{itemize}

The structural fixpoint operator behaves just like the one of \DUrole{smallcaps}{Coq} (see
{\hyperref[\detokenize{language/gallina-specification-language:coq:cmd.fixpoint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Fixpoint}}}}}), except it may also generate obligations. It works
with mutually recursive definitions too.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Program} \PYG{n}{Arith}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Program} \PYG{k+kn}{Fixpoint} \PYG{n}{div2} \PYG{o}{(}\PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{:} \PYG{o}{\PYGZob{}} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\textbar{}} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{x} \PYG{o}{\PYGZbs{}/} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZcb{}} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{p}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{p}\PYG{o}{)}
  \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{O}
  \PYG{k}{end}\PYG{o}{.}
    \PYG{n}{Solving} \PYG{n}{obligations} \PYG{n}{automatically}\PYG{o}{..}\PYG{o}{.}
    \PYG{l+m+mi}{4} \PYG{n}{obligations} \PYG{n}{remaining}
\end{sphinxVerbatim}

Here we have one obligation for each branch (branches for \sphinxcode{\sphinxupquote{\DUrole{literal,number,integer}{0}}} and
\sphinxcode{\sphinxupquote{(S 0)}} are automatically generated by the pattern matching
compilation algorithm).

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Obligation} \PYG{l+m+mi}{1}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{p}\PYG{o}{,} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{o} \PYG{o}{:} \PYG{n}{p} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{\PYGZbs{}/} \PYG{n}{p} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{+} \PYG{l+m+mi}{1}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{p}\PYG{o}{)} \PYG{o}{=} \PYG{n}{S} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{S} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)}\PYG{o}{)} \PYG{o}{\PYGZbs{}/} \PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{p}\PYG{o}{)} \PYG{o}{=} \PYG{n}{S} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{S} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{0}\PYG{o}{)} \PYG{o}{+} \PYG{l+m+mi}{1}\PYG{o}{)}
\end{sphinxVerbatim}

One can use a well-founded order or a measure as termination orders
using the syntax:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Program} \PYG{k+kn}{Fixpoint} \PYG{n}{div2} \PYG{o}{(}\PYG{n}{n} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{)} \PYG{o}{\PYGZob{}}\PYG{n}{measure} \PYG{n}{n}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{o}{\PYGZob{}} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\textbar{}} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{x} \PYG{o}{\PYGZbs{}/} \PYG{n}{n} \PYG{o}{=} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{\PYGZcb{}} \PYG{o}{:=}
  \PYG{k}{match} \PYG{n}{n} \PYG{k}{with}
  \PYG{o}{\textbar{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{S} \PYG{n}{p}\PYG{o}{)} \PYG{o}{=\PYGZgt{}} \PYG{n}{S} \PYG{o}{(}\PYG{n}{div2} \PYG{n}{p}\PYG{o}{)}
  \PYG{o}{\textbar{}} \PYG{o}{\PYGZus{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{O}
  \PYG{k}{end}\PYG{o}{.}
\end{sphinxVerbatim}

\begin{sphinxadmonition}{caution}{Caution:}
When defining structurally recursive functions, the generated
obligations should have the prototype of the currently defined
functional in their context. In this case, the obligations should be
transparent (e.g. defined using \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Defined}}}) so that the guardedness
condition on recursive calls can be checked by the kernel’s type-
checker. There is an optimization in the generation of obligations
which gets rid of the hypothesis corresponding to the functional when
it is not necessary, so that the obligation can be declared opaque
(e.g. using \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Qed}}}). However, as soon as it appears in the context, the
proof of the obligation is \sphinxstyleemphasis{required} to be declared transparent.

No such problems arise when using measures or well-founded recursion.
\end{sphinxadmonition}


\subsubsection{Program Lemma}
\label{\detokenize{addendum/program:program-lemma}}\label{\detokenize{addendum/program:id7}}\index{Program Lemma (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:cmd.program-lemma}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Program~Lemma~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-type}]{\sphinxcrossref{\DUrole{hole}{type}}}}}}}}
The Russell language can also be used to type statements of logical
properties. It will generate obligations, try to solve them
automatically and fail if some unsolved obligations remain. In this
case, one can first define the lemma’s statement using \sphinxcode{\sphinxupquote{\DUrole{name}{Program}
\DUrole{keyword,namespace}{Definition}}} and use it as the goal afterwards. Otherwise the proof
will be started with the elaborated version as a goal. The
\sphinxcode{\sphinxupquote{\DUrole{name}{Program}}} prefix can similarly be used as a prefix for
\sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Variable}}}, \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Hypothesis}}}, \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Axiom}}} etc.

\end{fulllineitems}



\subsection{Solving obligations}
\label{\detokenize{addendum/program:solving-obligations}}\label{\detokenize{addendum/program:id8}}
The following commands are available to manipulate obligations. The
optional identifier is used when multiple functions have unsolved
obligations (e.g. when defining mutually recursive blocks). The
optional tactic is replaced by the default one if not specified.
\index{Obligation Tactic (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:cmd.obligation-tactic}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{Local\textbar{}Global}\DUrole{notation-sup}{?}}~Obligation~Tactic~:=~\DUrole{hole}{tactic}}}}}
Sets the default obligation solving tactic applied to all obligations
automatically, whether to solve them or when starting to prove one,
e.g. using \sphinxcode{\sphinxupquote{\DUrole{name}{Next}}}. \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Local}}} makes the setting last only for the current
module. Inside sections, local is the default.

\end{fulllineitems}

\index{Show Obligation Tactic (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:cmd.show-obligation-tactic}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Show~Obligation~Tactic}}}}
Displays the current default tactic.

\end{fulllineitems}

\index{Obligations (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:cmd.obligations}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Obligations~\DUrole{repeat-wrapper}{\DUrole{repeat}{of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
Displays all remaining obligations.

\end{fulllineitems}

\index{Obligation num (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:cmd.obligation-num}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Obligation~num~\DUrole{repeat-wrapper}{\DUrole{repeat}{of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
Start the proof of obligation num.

\end{fulllineitems}

\index{Next Obligation (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:cmd.next-obligation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Next~Obligation~\DUrole{repeat-wrapper}{\DUrole{repeat}{of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
Start the proof of the next unsolved obligation.

\end{fulllineitems}

\index{Solve Obligations (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:cmd.solve-obligations}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Solve~Obligations~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{repeat-wrapper}{\DUrole{repeat}{of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~with~\DUrole{hole}{tactic}}\DUrole{notation-sup}{?}}}}}}
Tries to solve each obligation of \sphinxcode{\sphinxupquote{ident}} using the given \sphinxcode{\sphinxupquote{tactic}} or the default one.

\end{fulllineitems}

\index{Solve All Obligations (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:cmd.solve-all-obligations}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Solve~All~Obligations~\DUrole{repeat-wrapper}{\DUrole{repeat}{with~\DUrole{hole}{tactic}}\DUrole{notation-sup}{?}}}}}}
Tries to solve each obligation of every program using the given
tactic or the default one (useful for mutually recursive definitions).

\end{fulllineitems}

\index{Admit Obligations (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:cmd.admit-obligations}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Admit~Obligations~\DUrole{repeat-wrapper}{\DUrole{repeat}{of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
Admits all obligations (of \sphinxcode{\sphinxupquote{ident}}).

\begin{sphinxadmonition}{note}{Note:}
Does not work with structurally recursive programs.
\end{sphinxadmonition}

\end{fulllineitems}

\index{Preterm (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:cmd.preterm}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Preterm~\DUrole{repeat-wrapper}{\DUrole{repeat}{of~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
Shows the term that will be fed to the kernel once the obligations
are solved. Useful for debugging.

\end{fulllineitems}

\index{Transparent Obligations (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:flag.transparent-obligations}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Transparent~Obligations}}}}
Controls whether all obligations should be declared as transparent
(the default), or if the system should infer which obligations can be
declared opaque.

\end{fulllineitems}

\index{Hide Obligations (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:flag.hide-obligations}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Hide~Obligations}}}}
Controls whether obligations appearing in the
term should be hidden as implicit arguments of the special
constantProgram.Tactics.obligation.

\end{fulllineitems}

\index{Shrink Obligations (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:flag.shrink-obligations}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Shrink~Obligations}}}}
\sphinxstyleemphasis{Deprecated since 8.7}

This option (on by default) controls whether obligations should have
their context minimized to the set of variables used in the proof of
the obligation, to avoid unnecessary dependencies.

\end{fulllineitems}


The module \sphinxcode{\sphinxupquote{\DUrole{name}{Coq}\DUrole{operator}{.}\DUrole{name}{Program}\DUrole{operator}{.}\DUrole{name}{Tactics}}} defines the default tactic for solving
obligations called \sphinxcode{\sphinxupquote{\DUrole{name}{program\_simpl}}}. Importing \sphinxcode{\sphinxupquote{\DUrole{name}{Coq}\DUrole{operator}{.}\DUrole{name}{Program}\DUrole{operator}{.}\DUrole{name}{Program}}} also
adds some useful notations, as documented in the file itself.


\subsection{Frequently Asked Questions}
\label{\detokenize{addendum/program:frequently-asked-questions}}\label{\detokenize{addendum/program:program-faq}}\index{Ill-formed recursive definition (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/program:coq:exn.ill-formed-recursive-definition}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ill-formed~recursive~definition.}}}}
This error can happen when one tries to define a function by structural
recursion on a subset object, which means the \DUrole{smallcaps}{Coq} function looks like:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Program Fixpoint f (x : A \textbar{} P) := match x with A b =\PYGZgt{} f b end.
\end{sphinxVerbatim}

Supposing \sphinxcode{\sphinxupquote{b : A}}, the argument at the recursive call to \sphinxcode{\sphinxupquote{f}} is not a
direct subterm of \sphinxcode{\sphinxupquote{x}} as \sphinxcode{\sphinxupquote{b}} is wrapped inside an \sphinxcode{\sphinxupquote{exist}} constructor to
build an object of type \sphinxcode{\sphinxupquote{\{x : A \textbar{} P\}}}.  Hence the definition is
rejected by the guardedness condition checker.  However one can use
wellfounded recursion on subset objects like this:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Program Fixpoint f (x : A \textbar{} P) \PYGZob{} measure (size x) \PYGZcb{} :=
  match x with A b =\PYGZgt{} f b end.
\end{sphinxVerbatim}

One will then just have to prove that the measure decreases at each
recursive call. There are three drawbacks though:
\begin{enumerate}
\def\theenumi{\arabic{enumi}}
\def\labelenumi{\theenumi .}
\makeatletter\def\p@enumii{\p@enumi \theenumi .}\makeatother
\item {} 
A measure function has to be defined;

\item {} 
The reduction is a little more involved, although it works well
using lazy evaluation;

\item {} 
Mutual recursion on the underlying inductive type isn’t possible
anymore, but nested mutual recursion is always possible.

\end{enumerate}

\end{fulllineitems}



\section{The ring and field tactic families}
\label{\detokenize{addendum/ring:the-ring-and-field-tactic-families}}\label{\detokenize{addendum/ring:theringandfieldtacticfamilies}}\label{\detokenize{addendum/ring::doc}}\begin{quote}\begin{description}
\item[{Author}] \leavevmode
Bruno Barras, Benjamin Grégoire, Assia Mahboubi, Laurent Théry %
\begin{footnote}[25]\sphinxAtStartFootnote
based on previous work from Patrick Loiseleur and Samuel Boutin
%
\end{footnote}

\end{description}\end{quote}

This chapter presents the tactics dedicated to dealing with ring and
field equations.


\subsection{What does this tactic do?}
\label{\detokenize{addendum/ring:what-does-this-tactic-do}}
\sphinxcode{\sphinxupquote{ring}} does associative-commutative rewriting in ring and semiring
structures. Assume you have two binary functions \(\oplus\) and
\(\otimes\) that are associative and commutative, with \(\oplus\)
distributive on \(\otimes\), and two constants 0 and 1 that are unities for
\(\oplus\) and \(\otimes\). A polynomial is an expression built on
variables \(V_0\), \(V_1\), \(\dots\) and constants by application
of \(\oplus\) and \(\otimes\).

Let an ordered product be a product of variables \(V_{i_1} \otimes \dots
\otimes V_{i_n}\) verifying \(i_1 ≤ i_2 ≤ \dots ≤ i_n\) . Let a monomial be
the product of a constant and an ordered product. We can order the monomials by
the lexicographic order on products of variables. Let a canonical sum be an
ordered sum of monomials that are all different, i.e. each monomial in the sum
is strictly less than the following monomial according to the lexicographic
order. It is an easy theorem to show that every polynomial is equivalent (modulo
the ring properties) to exactly one canonical sum. This canonical sum is called
the normal form of the polynomial. In fact, the actual representation shares
monomials with same prefixes. So what does the \sphinxcode{\sphinxupquote{ring}} tactic do? It normalizes polynomials over
any ring or semiring structure. The basic use of \sphinxcode{\sphinxupquote{ring}} is to simplify ring
expressions, so that the user does not have to deal manually with the theorems
of associativity and commutativity.

\begin{sphinxadmonition}{note}{Example}
\begin{description}
\item[{In the ring of integers, the normal form of}] \leavevmode
\(x (3 + yx + 25(1 − z)) + zx\)

\item[{is}] \leavevmode
\(28x + (−24)xz + xxy\).

\end{description}
\end{sphinxadmonition}

\sphinxcode{\sphinxupquote{ring}} is also able to compute a normal form modulo monomial equalities.
For example, under the hypothesis that \(2x^2 = yz+1\), the normal form of
\(2(x + 1)x − x − zy\) is \(x+1\).


\subsection{The variables map}
\label{\detokenize{addendum/ring:the-variables-map}}
It is frequent to have an expression built with \(+\) and \(\times\),
but rarely on variables only. Let us associate a number to each subterm of a
ring expression in the Gallina language. For example, consider this expression
in the semiring \sphinxcode{\sphinxupquote{nat}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
(plus (mult (plus (f (5)) x) x)
      (mult (if b then (4) else (f (3))) (2)))
\end{sphinxVerbatim}

As a ring expression, it has 3 subterms. Give each subterm a number in
an arbitrary order:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
\hline

0
&
\(\mapsto\)
&
if b then (4) else (f (3))
\\
\hline
1
&
\(\mapsto\)
&
(f (5))
\\
\hline
2
&
\(\mapsto\)
&
x
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

Then normalize the “abstract” polynomial
\(((V_1 \otimes V_2 ) \oplus V_2) \oplus (V_0 \otimes 2)\)
In our example the normal form is:
\((2 \otimes V_0 ) \oplus (V_1 \otimes V_2) \oplus (V_2 \otimes V_2 )\).
Then substitute the variables by their values in the variables map to
get the concrete normal polynomial:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
(plus (mult (2) (if b then (4) else (f (3))))
      (plus (mult (f (5)) x) (mult x x)))
\end{sphinxVerbatim}


\subsection{Is it automatic?}
\label{\detokenize{addendum/ring:is-it-automatic}}
Yes, building the variables map and doing the substitution after
normalizing is automatically done by the tactic. So you can just
forget this paragraph and use the tactic according to your intuition.


\subsection{Concrete usage in Coq}
\label{\detokenize{addendum/ring:concrete-usage-in-coq}}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{ring}}}}
\end{fulllineitems}


The \sphinxcode{\sphinxupquote{ring}} tactic solves equations upon polynomial expressions of a ring
(or semiring) structure. It proceeds by normalizing both sides
of the equation (w.r.t. associativity, commutativity and
distributivity, constant propagation, rewriting of monomials) and
comparing syntactically the results.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{ring\_simplify}}}}
\end{fulllineitems}


\sphinxcode{\sphinxupquote{ring\_simplify}} applies the normalization procedure described above to
the given terms. The tactic then replaces all occurrences of the terms
given in the conclusion of the goal by their normal forms. If no term
is given, then the conclusion should be an equation and both
sides are normalized. The tactic can also be applied in a hypothesis.

The tactic must be loaded by \sphinxcode{\sphinxupquote{Require Import Ring}}. The ring structures
must be declared with the \sphinxcode{\sphinxupquote{Add Ring}} command (see below). The ring of
booleans is predefined; if one wants to use the tactic on \sphinxcode{\sphinxupquote{nat}} one must
first require the module \sphinxcode{\sphinxupquote{ArithRing}} exported by \sphinxcode{\sphinxupquote{Arith}}); for \sphinxcode{\sphinxupquote{Z}}, do
\sphinxcode{\sphinxupquote{Require Import ZArithRing}} or simply \sphinxcode{\sphinxupquote{Require Import ZArith}}; for \sphinxcode{\sphinxupquote{N}}, do
\sphinxcode{\sphinxupquote{Require Import NArithRing}} or \sphinxcode{\sphinxupquote{Require Import NArith}}.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{ZArith}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{z\PYGZus{}syntax\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{quote\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{newring\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{omega\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}

\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{Z\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{n}{c}\PYG{o}{:}\PYG{n}{Z}\PYG{o}{,}
    \PYG{o}{(}\PYG{n}{a} \PYG{o}{+} \PYG{n}{b} \PYG{o}{+} \PYG{n}{c}\PYG{o}{)} \PYG{o}{\PYGZca{}} \PYG{l+m+mi}{2} \PYG{o}{=}
     \PYG{n}{a} \PYG{o}{*} \PYG{n}{a} \PYG{o}{+} \PYG{n}{b} \PYG{o}{\PYGZca{}} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{n}{c} \PYG{o}{*} \PYG{n}{c} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{a} \PYG{o}{*} \PYG{n}{b} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{a} \PYG{o}{*} \PYG{n}{c} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{b} \PYG{o}{*} \PYG{n}{c}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{n}{c} \PYG{o}{:} \PYG{n}{Z}\PYG{o}{,}
      \PYG{o}{(}\PYG{n}{a} \PYG{o}{+} \PYG{n}{b} \PYG{o}{+} \PYG{n}{c}\PYG{o}{)} \PYG{o}{\PYGZca{}} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{a} \PYG{o}{*} \PYG{n}{a} \PYG{o}{+} \PYG{n}{b} \PYG{o}{\PYGZca{}} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{n}{c} \PYG{o}{*} \PYG{n}{c} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{a} \PYG{o}{*} \PYG{n}{b} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{a} \PYG{o}{*} \PYG{n}{c} \PYG{o}{+} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{b} \PYG{o}{*} \PYG{n}{c}

\PYG{k}{intros}\PYG{o}{;} \PYG{k}{ring}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{n}{Abort}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b}\PYG{o}{:}\PYG{n}{Z}\PYG{o}{,}
     \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{a} \PYG{o}{*} \PYG{n}{b} \PYG{o}{=} \PYG{l+m+mi}{30} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{a} \PYG{o}{+} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZca{}} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{a} \PYG{o}{\PYGZca{}} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{n}{b} \PYG{o}{\PYGZca{}} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{l+m+mi}{30}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{a} \PYG{n}{b} \PYG{o}{:} \PYG{n}{Z}\PYG{o}{,} \PYG{l+m+mi}{2} \PYG{o}{*} \PYG{n}{a} \PYG{o}{*} \PYG{n}{b} \PYG{o}{=} \PYG{l+m+mi}{30} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{n}{a} \PYG{o}{+} \PYG{n}{b}\PYG{o}{)} \PYG{o}{\PYGZca{}} \PYG{l+m+mi}{2} \PYG{o}{=} \PYG{n}{a} \PYG{o}{\PYGZca{}} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{n}{b} \PYG{o}{\PYGZca{}} \PYG{l+m+mi}{2} \PYG{o}{+} \PYG{l+m+mi}{30}

\PYG{k}{intros} \PYG{n}{a} \PYG{n}{b} \PYG{n}{H}\PYG{o}{;} \PYG{k}{ring} \PYG{o}{[}\PYG{n}{H}\PYG{o}{]}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{n}{Abort}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{ring~{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}{]}}}}}
\end{fulllineitems}


decides the equality of two terms modulo ring operations and
the equalities defined by the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}s.
Each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} has to be a proof of some equality \sphinxtitleref{m = p}, where \sphinxtitleref{m} is a monomial (after “abstraction”), \sphinxtitleref{p} a polynomial and \sphinxtitleref{=} the corresponding equality of the ring structure.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{ring\_simplify~{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}{]}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\end{fulllineitems}


performs the simplification in the hypothesis named \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\begin{sphinxadmonition}{note}{Note:}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{ring\_simplify~\DUrole{hole}{term1};~ring\_simplify~\DUrole{hole}{term2}}}}}
\end{fulllineitems}


is not equivalent to


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{ring\_simplify~\DUrole{hole}{term1}~\DUrole{hole}{term2}}}}}
\end{fulllineitems}


In the latter case the variables map
is shared between the two terms, and common subterm \sphinxtitleref{t} of \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{term1}}}} and \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{term2}}}}
will have the same associated variable number. So the first
alternative should be avoided for terms belonging to the same ring
theory.
\end{sphinxadmonition}

Error messages:
\index{Not a valid ring equation (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:exn.not-a-valid-ring-equation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Not~a~valid~ring~equation.}}}}
The conclusion of the goal is not provable in the corresponding ring theory.

\end{fulllineitems}

\index{Arguments of ring\_simplify do not have all the same type (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:exn.arguments-of-ring-simplify-do-not-have-all-the-same-type}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Arguments~of~ring\_simplify~do~not~have~all~the~same~type.}}}}
\sphinxcode{\sphinxupquote{ring\_simplify}} cannot simplify terms of several rings at the same
time. Invoke the tactic once per ring structure.

\end{fulllineitems}

\index{Cannot find a declared ring structure over ‘term’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:exn.cannot-find-a-declared-ring-structure-over-term}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~find~a~declared~ring~structure~over~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}.}}}}
No ring has been declared for the type of the terms to be simplified.
Use \sphinxcode{\sphinxupquote{Add Ring}} first.

\end{fulllineitems}

\index{Cannot find a declared ring structure for equality ‘term’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:exn.cannot-find-a-declared-ring-structure-for-equality-term}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cannot~find~a~declared~ring~structure~for~equality~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}.}}}}
Same as above in the case of the \sphinxcode{\sphinxupquote{ring}} tactic.

\end{fulllineitems}



\subsection{Adding a ring structure}
\label{\detokenize{addendum/ring:adding-a-ring-structure}}
Declaring a new ring consists in proving that a ring signature (a
carrier set, an equality, and ring operations: \sphinxcode{\sphinxupquote{Ring\_theory.ring\_theory}}
and \sphinxcode{\sphinxupquote{Ring\_theory.semi\_ring\_theory}}) satisfies the ring axioms. Semi-
rings (rings without + inverse) are also supported. The equality can
be either Leibniz equality, or any relation declared as a setoid (see
{\hyperref[\detokenize{addendum/generalized-rewriting:tactics-enabled-on-user-provided-relations}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics enabled on user provided relations}}}}).
The definitions of ring and semiring (see module \sphinxcode{\sphinxupquote{Ring\_theory}}) are:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Record} \PYG{n}{ring\PYGZus{}theory} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{mk\PYGZus{}rt} \PYG{o}{\PYGZob{}}
  \PYG{n}{Radd\PYGZus{}0\PYGZus{}l}    \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{n}{x} \PYG{o}{=}\PYG{o}{=} \PYG{n}{x}\PYG{o}{;}
  \PYG{n}{Radd\PYGZus{}sym}    \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{n}{y} \PYG{o}{=}\PYG{o}{=} \PYG{n}{y} \PYG{o}{+} \PYG{n}{x}\PYG{o}{;}
  \PYG{n}{Radd\PYGZus{}assoc}  \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{o}{(}\PYG{n}{y} \PYG{o}{+} \PYG{n}{z}\PYG{o}{)} \PYG{o}{=}\PYG{o}{=} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)} \PYG{o}{+} \PYG{n}{z}\PYG{o}{;}
  \PYG{n}{Rmul\PYGZus{}1\PYGZus{}l}    \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{l+m+mi}{1} \PYG{o}{*} \PYG{n}{x} \PYG{o}{=}\PYG{o}{=} \PYG{n}{x}\PYG{o}{;}
  \PYG{n}{Rmul\PYGZus{}sym}    \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{n}{x} \PYG{o}{*} \PYG{n}{y} \PYG{o}{=}\PYG{o}{=} \PYG{n}{y} \PYG{o}{*} \PYG{n}{x}\PYG{o}{;}
  \PYG{n}{Rmul\PYGZus{}assoc}  \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z}\PYG{o}{,} \PYG{n}{x} \PYG{o}{*} \PYG{o}{(}\PYG{n}{y} \PYG{o}{*} \PYG{n}{z}\PYG{o}{)} \PYG{o}{=}\PYG{o}{=} \PYG{o}{(}\PYG{n}{x} \PYG{o}{*} \PYG{n}{y}\PYG{o}{)} \PYG{o}{*} \PYG{n}{z}\PYG{o}{;}
  \PYG{n}{Rdistr\PYGZus{}l}    \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z}\PYG{o}{,} \PYG{o}{(}\PYG{n}{x} \PYG{o}{+} \PYG{n}{y}\PYG{o}{)} \PYG{o}{*} \PYG{n}{z} \PYG{o}{=}\PYG{o}{=} \PYG{o}{(}\PYG{n}{x} \PYG{o}{*} \PYG{n}{z}\PYG{o}{)} \PYG{o}{+} \PYG{o}{(}\PYG{n}{y} \PYG{o}{*} \PYG{n}{z}\PYG{o}{)}\PYG{o}{;}
  \PYG{n}{Rsub\PYGZus{}def}    \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{n}{x} \PYG{o}{\PYGZhy{}} \PYG{n}{y} \PYG{o}{=}\PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{o}{\PYGZhy{}}\PYG{n}{y}\PYG{o}{;}
  \PYG{n}{Ropp\PYGZus{}def}    \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{o}{(}\PYG{o}{\PYGZhy{}} \PYG{n}{x}\PYG{o}{)} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{0}
\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\PYG{k+kn}{Record} \PYG{n}{semi\PYGZus{}ring\PYGZus{}theory} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{mk\PYGZus{}srt} \PYG{o}{\PYGZob{}}
  \PYG{n}{SRadd\PYGZus{}0\PYGZus{}l}   \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{,} \PYG{l+m+mi}{0} \PYG{o}{+} \PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{n}{n}\PYG{o}{;}
  \PYG{n}{SRadd\PYGZus{}sym}   \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{n}{m} \PYG{o}{=}\PYG{o}{=} \PYG{n}{m} \PYG{o}{+} \PYG{n}{n} \PYG{o}{;}
  \PYG{n}{SRadd\PYGZus{}assoc} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p}\PYG{o}{,} \PYG{n}{n} \PYG{o}{+} \PYG{o}{(}\PYG{n}{m} \PYG{o}{+} \PYG{n}{p}\PYG{o}{)} \PYG{o}{=}\PYG{o}{=} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)} \PYG{o}{+} \PYG{n}{p}\PYG{o}{;}
  \PYG{n}{SRmul\PYGZus{}1\PYGZus{}l}   \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{,} \PYG{l+m+mi}{1}\PYG{o}{*}\PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{n}{n}\PYG{o}{;}
  \PYG{n}{SRmul\PYGZus{}0\PYGZus{}l}   \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n}\PYG{o}{,} \PYG{l+m+mi}{0}\PYG{o}{*}\PYG{n}{n} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{;}
  \PYG{n}{SRmul\PYGZus{}sym}   \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m}\PYG{o}{,} \PYG{n}{n}\PYG{o}{*}\PYG{n}{m} \PYG{o}{=}\PYG{o}{=} \PYG{n}{m}\PYG{o}{*}\PYG{n}{n}\PYG{o}{;}
  \PYG{n}{SRmul\PYGZus{}assoc} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p}\PYG{o}{,} \PYG{n}{n}\PYG{o}{*}\PYG{o}{(}\PYG{n}{m}\PYG{o}{*}\PYG{n}{p}\PYG{o}{)} \PYG{o}{=}\PYG{o}{=} \PYG{o}{(}\PYG{n}{n}\PYG{o}{*}\PYG{n}{m}\PYG{o}{)}\PYG{o}{*}\PYG{n}{p}\PYG{o}{;}
  \PYG{n}{SRdistr\PYGZus{}l}   \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{p}\PYG{o}{,} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)}\PYG{o}{*}\PYG{n}{p} \PYG{o}{=}\PYG{o}{=} \PYG{n}{n}\PYG{o}{*}\PYG{n}{p} \PYG{o}{+} \PYG{n}{m}\PYG{o}{*}\PYG{n}{p}
\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

This implementation of \sphinxcode{\sphinxupquote{ring}} also features a notion of constant that
can be parameterized. This can be used to improve the handling of
closed expressions when operations are effective. It consists in
introducing a type of \sphinxstyleemphasis{coefficients} and an implementation of the ring
operations, and a morphism from the coefficient type to the ring
carrier type. The morphism needs not be injective, nor surjective.

As an example, one can consider the real numbers. The set of
coefficients could be the rational numbers, upon which the ring
operations can be implemented. The fact that there exists a morphism
is defined by the following properties:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Record} \PYG{n}{ring\PYGZus{}morph} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{mkmorph} \PYG{o}{\PYGZob{}}
  \PYG{n}{morph0}    \PYG{o}{:} \PYG{o}{[}\PYG{n}{cO}\PYG{o}{]} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{;}
  \PYG{n}{morph1}    \PYG{o}{:} \PYG{o}{[}\PYG{n}{cI}\PYG{o}{]} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{1}\PYG{o}{;}
  \PYG{n}{morph\PYGZus{}add} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{o}{[}\PYG{n}{x} \PYG{o}{+}\PYG{o}{!} \PYG{n}{y}\PYG{o}{]} \PYG{o}{=}\PYG{o}{=} \PYG{o}{[}\PYG{n}{x}\PYG{o}{]}\PYG{o}{+}\PYG{o}{[}\PYG{n}{y}\PYG{o}{]}\PYG{o}{;}
  \PYG{n}{morph\PYGZus{}sub} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{o}{[}\PYG{n}{x} \PYG{o}{\PYGZhy{}}\PYG{o}{!} \PYG{n}{y}\PYG{o}{]} \PYG{o}{=}\PYG{o}{=} \PYG{o}{[}\PYG{n}{x}\PYG{o}{]}\PYG{o}{\PYGZhy{}}\PYG{o}{[}\PYG{n}{y}\PYG{o}{]}\PYG{o}{;}
  \PYG{n}{morph\PYGZus{}mul} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{o}{[}\PYG{n}{x} \PYG{o}{*}\PYG{o}{!} \PYG{n}{y}\PYG{o}{]} \PYG{o}{=}\PYG{o}{=} \PYG{o}{[}\PYG{n}{x}\PYG{o}{]}\PYG{o}{*}\PYG{o}{[}\PYG{n}{y}\PYG{o}{]}\PYG{o}{;}
  \PYG{n}{morph\PYGZus{}opp} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{o}{[}\PYG{o}{\PYGZhy{}}\PYG{o}{!}\PYG{n}{x}\PYG{o}{]} \PYG{o}{=}\PYG{o}{=} \PYG{o}{\PYGZhy{}}\PYG{o}{[}\PYG{n}{x}\PYG{o}{]}\PYG{o}{;}
  \PYG{n}{morph\PYGZus{}eq}  \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{n}{x}\PYG{o}{?}\PYG{o}{=}\PYG{o}{!}\PYG{n}{y} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{[}\PYG{n}{x}\PYG{o}{]} \PYG{o}{=}\PYG{o}{=} \PYG{o}{[}\PYG{n}{y}\PYG{o}{]}
\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\PYG{k+kn}{Record} \PYG{n}{semi\PYGZus{}morph} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{mkRmorph} \PYG{o}{\PYGZob{}}
  \PYG{n}{Smorph0} \PYG{o}{:} \PYG{o}{[}\PYG{n}{cO}\PYG{o}{]} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{;}
  \PYG{n}{Smorph1} \PYG{o}{:} \PYG{o}{[}\PYG{n}{cI}\PYG{o}{]} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{1}\PYG{o}{;}
  \PYG{n}{Smorph\PYGZus{}add} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{o}{[}\PYG{n}{x} \PYG{o}{+}\PYG{o}{!} \PYG{n}{y}\PYG{o}{]} \PYG{o}{=}\PYG{o}{=} \PYG{o}{[}\PYG{n}{x}\PYG{o}{]}\PYG{o}{+}\PYG{o}{[}\PYG{n}{y}\PYG{o}{]}\PYG{o}{;}
  \PYG{n}{Smorph\PYGZus{}mul} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{o}{[}\PYG{n}{x} \PYG{o}{*}\PYG{o}{!} \PYG{n}{y}\PYG{o}{]} \PYG{o}{=}\PYG{o}{=} \PYG{o}{[}\PYG{n}{x}\PYG{o}{]}\PYG{o}{*}\PYG{o}{[}\PYG{n}{y}\PYG{o}{]}\PYG{o}{;}
  \PYG{n}{Smorph\PYGZus{}eq}  \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,} \PYG{n}{x}\PYG{o}{?}\PYG{o}{=}\PYG{o}{!}\PYG{n}{y} \PYG{o}{=} \PYG{n+nb+bp}{true} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{[}\PYG{n}{x}\PYG{o}{]} \PYG{o}{=}\PYG{o}{=} \PYG{o}{[}\PYG{n}{y}\PYG{o}{]}
\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

where \sphinxcode{\sphinxupquote{c0}} and \sphinxcode{\sphinxupquote{cI}} denote the 0 and 1 of the coefficient set, \sphinxcode{\sphinxupquote{+!}}, \sphinxcode{\sphinxupquote{*!}}, \sphinxcode{\sphinxupquote{-!}}
are the implementations of the ring operations, \sphinxcode{\sphinxupquote{==}} is the equality of
the coefficients, \sphinxcode{\sphinxupquote{?+!}} is an implementation of this equality, and \sphinxcode{\sphinxupquote{{[}x{]}}}
is a notation for the image of \sphinxcode{\sphinxupquote{x}} by the ring morphism.

Since \sphinxcode{\sphinxupquote{Z}} is an initial ring (and \sphinxcode{\sphinxupquote{N}} is an initial semiring), it can
always be considered as a set of coefficients. There are basically
three kinds of (semi-)rings:
\begin{description}
\item[{abstract rings}] \leavevmode
to be used when operations are not effective. The set
of coefficients is \sphinxcode{\sphinxupquote{Z}} (or \sphinxcode{\sphinxupquote{N}} for semirings).

\item[{computational rings}] \leavevmode
to be used when operations are effective. The
set of coefficients is the ring itself. The user only has to provide
an implementation for the equality.

\item[{customized ring}] \leavevmode
for other cases. The user has to provide the
coefficient set and the morphism.

\end{description}

This implementation of ring can also recognize simple power
expressions as ring expressions. A power function is specified by the
following property:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Section} \PYG{n}{POWER}\PYG{o}{.}
\PYG{k+kn}{Variable} \PYG{n}{Cpow} \PYG{o}{:} \PYG{k+kn}{Set}\PYG{o}{.}
\PYG{k+kn}{Variable} \PYG{n}{Cp\PYGZus{}phi} \PYG{o}{:} \PYG{n}{N} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Cpow}\PYG{o}{.}
\PYG{k+kn}{Variable} \PYG{n}{rpow} \PYG{o}{:} \PYG{n}{R} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Cpow} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R}\PYG{o}{.}
\PYG{k+kn}{Record} \PYG{n}{power\PYGZus{}theory} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{mkpow\PYGZus{}th} \PYG{o}{\PYGZob{}}
    \PYG{n}{rpow\PYGZus{}pow\PYGZus{}N} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{r} \PYG{n}{n}\PYG{o}{,} \PYG{n}{req} \PYG{o}{(}\PYG{n}{rpow} \PYG{n}{r} \PYG{o}{(}\PYG{n}{Cp\PYGZus{}phi} \PYG{n}{n}\PYG{o}{)}\PYG{o}{)} \PYG{o}{(}\PYG{n}{pow\PYGZus{}N} \PYG{n}{rI} \PYG{n}{rmul} \PYG{n}{r} \PYG{n}{n}\PYG{o}{)}
  \PYG{o}{\PYGZcb{}}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{POWER}\PYG{o}{.}
\end{sphinxVerbatim}

The syntax for adding a new ring is
\index{Add Ring (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:cmd.add-ring}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~Ring~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{(~{\hyperref[\detokenize{addendum/ring:grammar-token-ring-mod}]{\sphinxcrossref{\DUrole{hole}{ring\_mod}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{,~{\hyperref[\detokenize{addendum/ring:grammar-token-ring-mod}]{\sphinxcrossref{\DUrole{hole}{ring\_mod}}}}}\DUrole{notation-sup}{*}}~)}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is not relevant. It is used just for error messages. The
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is a proof that the ring signature satisfies the (semi-)ring
axioms. The optional list of modifiers is used to tailor the behavior
of the tactic. The following list describes their syntax and effects:


\begin{productionlist}
\phantomsection\label{\detokenize{addendum/ring:grammar-token-ring_mod}}\production{ring\_mod}{ abstract \textbar{} decidable {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} \textbar{} morphism {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} setoid {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} constants {[}\sphinxcode{\sphinxupquote{ltac}}{]}}
\productioncont{ \textbar{} preprocess {[}\sphinxcode{\sphinxupquote{ltac}}{]}}
\productioncont{ \textbar{} postprocess {[}\sphinxcode{\sphinxupquote{ltac}}{]}}
\productioncont{ \textbar{} power\_tac {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}} {[}\sphinxcode{\sphinxupquote{ltac}}{]}}
\productioncont{ \textbar{} sign {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\productioncont{ \textbar{} div {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\end{productionlist}

\begin{description}
\item[{abstract}] \leavevmode
declares the ring as abstract. This is the default.

\item[{decidable \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}] \leavevmode
declares the ring as computational. The expression
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is the correctness proof of an equality test \sphinxcode{\sphinxupquote{?=!}}
(which  hould be evaluable). Its type should be of the form
\sphinxcode{\sphinxupquote{forall x y, x ?=! y = true \(\rightarrow\) x == y}}.

\item[{morphism \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}] \leavevmode
declares the ring as a customized one. The expression
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is a proof that there exists a morphism between a set of
coefficient and the ring carrier (see \sphinxcode{\sphinxupquote{Ring\_theory.ring\_morph}} and
\sphinxcode{\sphinxupquote{Ring\_theory.semi\_morph}}).

\item[{setoid \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}] \leavevmode
forces the use of given setoid. The first
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is a proof that the equality is indeed a setoid (see
\sphinxcode{\sphinxupquote{Setoid.Setoid\_Theory}}), and the second \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} a proof that the
ring operations are morphisms (see \sphinxcode{\sphinxupquote{Ring\_theory.ring\_eq\_ext}} and
\sphinxcode{\sphinxupquote{Ring\_theory.sring\_eq\_ext}}).
This modifier needs not be used if the setoid and morphisms have been
declared.

\item[{constants {[}\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{ltac}}}}{]}}] \leavevmode
specifies a tactic expression \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{ltac}}}} that, given a
term, returns either an object of the coefficient set that is mapped
to the expression via the morphism, or returns
\sphinxcode{\sphinxupquote{InitialRing.NotConstant}}. The default behavior is to map only 0 and 1
to their counterpart in the coefficient set. This is generally not
desirable for non trivial computational rings.

\item[{preprocess {[}\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{ltac}}}}{]}}] \leavevmode
specifies a tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{ltac}}}} that is applied as a
preliminary step for \sphinxcode{\sphinxupquote{ring}} and \sphinxcode{\sphinxupquote{ring\_simplify}}. It can be used to
transform a goal so that it is better recognized. For instance, \sphinxcode{\sphinxupquote{S n}}
can be changed to \sphinxcode{\sphinxupquote{plus 1 n}}.

\item[{postprocess {[}\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{ltac}}}}{]}}] \leavevmode
specifies a tactic \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{ltac}}}} that is applied as a final
step for \sphinxcode{\sphinxupquote{ring\_simplify}}. For instance, it can be used to undo
modifications of the preprocessor.

\item[{power\_tac \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} {[}\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{ltac}}}}{]}}] \leavevmode
allows \sphinxcode{\sphinxupquote{ring}} and \sphinxcode{\sphinxupquote{ring\_simplify}} to recognize
power expressions with a constant positive integer exponent (example:
:\(x^2\) ). The term \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is a proof that a given power function satisfies
the specification of a power function (term has to be a proof of
\sphinxcode{\sphinxupquote{Ring\_theory.power\_theory}}) and \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{ltac}}}} specifies a tactic expression
that, given a term, “abstracts” it into an object of type \sphinxcode{\sphinxupquote{N}} whose
interpretation via \sphinxcode{\sphinxupquote{Cp\_phi}} (the evaluation function of power
coefficient) is the original term, or returns \sphinxcode{\sphinxupquote{InitialRing.NotConstant}}
if not a constant coefficient (i.e. \sphinxtitleref{L}$_{\text{tac}}$ is the inverse function of
\sphinxcode{\sphinxupquote{Cp\_phi}}). See files \sphinxcode{\sphinxupquote{plugins/setoid\_ring/ZArithRing.v}}
and \sphinxcode{\sphinxupquote{plugins/setoid\_ring/RealField.v}} for examples. By default the tactic
does not recognize power expressions as ring expressions.

\item[{sign \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}] \leavevmode
allows \sphinxcode{\sphinxupquote{ring\_simplify}} to use a minus operation when
outputting its normal form, i.e writing \sphinxcode{\sphinxupquote{x − y}} instead of \sphinxcode{\sphinxupquote{x + (− y)}}. The
term \sphinxtitleref{:n:{}`@term} is a proof that a given sign function indicates expressions
that are signed (\sphinxtitleref{term} has to be a proof of \sphinxcode{\sphinxupquote{Ring\_theory.get\_sign}}). See
\sphinxcode{\sphinxupquote{plugins/setoid\_ring/InitialRing.v}} for examples of sign function.

\item[{div \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}] \leavevmode
allows \sphinxcode{\sphinxupquote{ring}} and \sphinxcode{\sphinxupquote{ring\_simplify}} to use monomials with
coefficients other than 1 in the rewriting. The term \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is a proof
that a given division function satisfies the specification of an
euclidean division function (\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} has to be a proof of
\sphinxcode{\sphinxupquote{Ring\_theory.div\_theory}}). For example, this function is called when
trying to rewrite \(7x\) by \(2x = z\) to tell that \(7 = 3 \times 2 + 1\). See
\sphinxcode{\sphinxupquote{plugins/setoid\_ring/InitialRing.v}} for examples of div function.

\end{description}

Error messages:
\index{Bad ring structure (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:exn.bad-ring-structure}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Bad~ring~structure.}}}}
The proof of the ring structure provided is not
of the expected type.

\end{fulllineitems}

\index{Bad lemma for decidability of equality (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:exn.bad-lemma-for-decidability-of-equality}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Bad~lemma~for~decidability~of~equality.}}}}
The equality function
provided in the case of a computational ring has not the expected
type.

\end{fulllineitems}

\index{Ring operation should be declared as a morphism (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:exn.ring-operation-should-be-declared-as-a-morphism}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Ring~operation~should~be~declared~as~a~morphism.}}}}
A setoid associated to the carrier of the ring structure has been found,
but the ring operation should be declared as morphism. See {\hyperref[\detokenize{addendum/generalized-rewriting:tactics-enabled-on-user-provided-relations}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics enabled on user provided relations}}}}.

\end{fulllineitems}



\subsection{How does it work?}
\label{\detokenize{addendum/ring:how-does-it-work}}
The code of \sphinxcode{\sphinxupquote{ring}} is a good example of a tactic written using \sphinxstyleemphasis{reflection}.
What is reflection? Basically, using it means that a part of a tactic is written
in Gallina, Coq's language of terms, rather than \sphinxtitleref{L}$_{\text{tac}}$ or \DUrole{smallcaps}{OCaml}. From the
philosophical point of view, reflection is using the ability of the Calculus of
Constructions to speak and reason about itself. For the \sphinxcode{\sphinxupquote{ring}} tactic we used
Coq as a programming language and also as a proof environment to build a tactic
and to prove its correctness.

The interested reader is strongly advised to have a look at the
file \sphinxcode{\sphinxupquote{Ring\_polynom.v}}. Here a type for polynomials is defined:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{PExpr} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
  \PYG{o}{\textbar{}} \PYG{n}{PEc} \PYG{o}{:} \PYG{n}{C} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr}
  \PYG{o}{\textbar{}} \PYG{n}{PEX} \PYG{o}{:} \PYG{n}{positive} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr}
  \PYG{o}{\textbar{}} \PYG{n}{PEadd} \PYG{o}{:} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr}
  \PYG{o}{\textbar{}} \PYG{n}{PEsub} \PYG{o}{:} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr}
  \PYG{o}{\textbar{}} \PYG{n}{PEmul} \PYG{o}{:} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr}
  \PYG{o}{\textbar{}} \PYG{n}{PEopp} \PYG{o}{:} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr}
  \PYG{o}{\textbar{}} \PYG{n}{PEpow} \PYG{o}{:} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{N} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr}\PYG{o}{.}
\end{sphinxVerbatim}

Polynomials in normal form are defined as:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Inductive} \PYG{n}{Pol} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
  \PYG{o}{\textbar{}} \PYG{n}{Pc} \PYG{o}{:} \PYG{n}{C} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Pol}
  \PYG{o}{\textbar{}} \PYG{n}{Pinj} \PYG{o}{:} \PYG{n}{positive} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Pol} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Pol}
  \PYG{o}{\textbar{}} \PYG{n}{PX} \PYG{o}{:} \PYG{n}{Pol} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{positive} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Pol} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Pol}\PYG{o}{.}
\end{sphinxVerbatim}

where \sphinxcode{\sphinxupquote{Pinj n P}} denotes \sphinxcode{\sphinxupquote{P}} in which \(V_i\) is replaced by \(V_{i+n}\) ,
and \sphinxcode{\sphinxupquote{PX P n Q}} denotes \(P \otimes V_1^n \oplus Q'\), \sphinxtitleref{Q'} being \sphinxtitleref{Q} where \(V_i\) is replaced by \(V_{i+1}\).

Variable maps are represented by lists of ring elements, and two
interpretation functions, one that maps a variables map and a
polynomial to an element of the concrete ring, and the second one that
does the same for normal forms:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{PEeval} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{R} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R} \PYG{o}{:=} \PYG{o}{[}\PYG{o}{..}\PYG{o}{.}\PYG{o}{]}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{Pphi\PYGZus{}dev} \PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{R} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Pol} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{R} \PYG{o}{:=} \PYG{o}{[}\PYG{o}{..}\PYG{o}{.}\PYG{o}{]}\PYG{o}{.}
\end{sphinxVerbatim}

A function to normalize polynomials is defined, and the big theorem is
its correctness w.r.t interpretation, that is:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{norm} \PYG{o}{:} \PYG{n}{PExpr} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{Pol} \PYG{o}{:=} \PYG{o}{[}\PYG{o}{..}\PYG{o}{.}\PYG{o}{]}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{Pphi\PYGZus{}dev\PYGZus{}ok} \PYG{o}{:}
   \PYG{k}{forall} \PYG{n}{l} \PYG{n}{pe} \PYG{n}{npe}\PYG{o}{,} \PYG{n}{norm} \PYG{n}{pe} \PYG{o}{=} \PYG{n}{npe} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{PEeval} \PYG{n}{l} \PYG{n}{pe} \PYG{o}{=}\PYG{o}{=} \PYG{n}{Pphi\PYGZus{}dev} \PYG{n}{l} \PYG{n}{npe}\PYG{o}{.}
\end{sphinxVerbatim}

So now, what is the scheme for a normalization proof? Let p be the
polynomial expression that the user wants to normalize. First a little
piece of \DUrole{smallcaps}{ML} code guesses the type of \sphinxtitleref{p}, the ring theory \sphinxtitleref{T} to use, an
abstract polynomial \sphinxtitleref{ap} and a variables map \sphinxtitleref{v} such that \sphinxtitleref{p} is \(\beta\delta\iota\)-
equivalent to \sphinxcode{\sphinxupquote{(PEeval}} \sphinxtitleref{v} \sphinxtitleref{ap}\sphinxcode{\sphinxupquote{)}}. Then we replace it by \sphinxcode{\sphinxupquote{(Pphi\_dev}} \sphinxtitleref{v}
\sphinxcode{\sphinxupquote{(norm}} \sphinxtitleref{ap}\sphinxcode{\sphinxupquote{))}}, using the main correctness theorem and we reduce it to a
concrete expression \sphinxtitleref{p’}, which is the concrete normal form of \sphinxtitleref{p}. This is summarized in this diagram:


\begin{savenotes}\sphinxattablestart
\centering
\begin{tabulary}{\linewidth}[t]{|T|T|T|}
\hline

\sphinxtitleref{p}
&
\(\rightarrow_{\beta\delta\iota}\)
&
\sphinxcode{\sphinxupquote{(PEeval}} \sphinxtitleref{v} \sphinxtitleref{ap}\sphinxcode{\sphinxupquote{)}}
\\
\hline

&
\sphinxtitleref{=}$_{\text{(by the main correctness theorem)}}$
&

\\
\hline
\sphinxtitleref{p’}
&
\(\leftarrow_{\beta\delta\iota}\)
&
\sphinxcode{\sphinxupquote{(Pphi\_dev}} \sphinxtitleref{v} \sphinxcode{\sphinxupquote{(norm}} \sphinxtitleref{ap}\sphinxcode{\sphinxupquote{))}}
\\
\hline
\end{tabulary}
\par
\sphinxattableend\end{savenotes}

The user does not see the right part of the diagram. From outside, the
tactic behaves like a \(\beta\delta\iota\) simplification extended with rewriting rules
for associativity and commutativity. Basically, the proof is only the
application of the main correctness theorem to well-chosen arguments.


\subsection{Dealing with fields}
\label{\detokenize{addendum/ring:dealing-with-fields}}

\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{field}}}}
\end{fulllineitems}


The \sphinxcode{\sphinxupquote{field}} tactic is an extension of the \sphinxcode{\sphinxupquote{ring}} tactic that deals with rational
expressions. Given a rational expression \(F = 0\). It first reduces the
expression \sphinxtitleref{F} to a common denominator \(N/D = 0\) where \sphinxtitleref{N} and \sphinxtitleref{D}
are two ring expressions. For example, if we take \(F = (1 − 1/x) x − x + 1\), this
gives \(N = (x − 1) x − x^2 + x\) and \(D = x\). It then calls ring to solve
\(N = 0\).
Note that \sphinxcode{\sphinxupquote{field}} also generates nonzero conditions for all the
denominators it encounters in the reduction. In our example, it
generates the condition \(x \neq 0\). These conditions appear as one subgoal
which is a conjunction if there are several denominators. Nonzero
conditions are always polynomial expressions. For example when
reducing the expression \(1/(1 + 1/x)\), two side conditions are
generated: \(x \neq 0\) and \(x + 1 \neq 0\). Factorized expressions are broken since
a field is an integral domain, and when the equality test on
coefficients is complete w.r.t. the equality of the target field,
constants can be proven different from zero automatically.

The tactic must be loaded by \sphinxcode{\sphinxupquote{Require Import Field}}. New field
structures can be declared to the system with the \sphinxcode{\sphinxupquote{Add Field}} command
(see below). The field of real numbers is defined in module \sphinxcode{\sphinxupquote{RealField}}
(in \sphinxcode{\sphinxupquote{plugins/setoid\_ring}}). It is exported by module \sphinxcode{\sphinxupquote{Rbase}}, so
that requiring \sphinxcode{\sphinxupquote{Rbase}} or \sphinxcode{\sphinxupquote{Reals}} is enough to use the field tactics on
real numbers. Rational numbers in canonical form are also declared as
a field in the module \sphinxcode{\sphinxupquote{Qcanon}}.

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Reals}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{r\PYGZus{}syntax\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{fourier\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{micromega\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}

\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{R\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{x}\PYG{o}{,}
       \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{l+m+mi}{1} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1} \PYG{o}{/} \PYG{n}{x}\PYG{o}{)} \PYG{o}{*} \PYG{n}{x} \PYG{o}{\PYGZhy{}} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{x} \PYG{o}{:} \PYG{n}{R}\PYG{o}{,} \PYG{n}{x} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{(}\PYG{l+m+mi}{1} \PYG{o}{\PYGZhy{}} \PYG{l+m+mi}{1} \PYG{o}{/} \PYG{n}{x}\PYG{o}{)} \PYG{o}{*} \PYG{n}{x} \PYG{o}{\PYGZhy{}} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{1} \PYG{o}{=} \PYG{l+m+mi}{0}

\PYG{k}{intros}\PYG{o}{;} \PYG{k}{field}\PYG{o}{;} \PYG{k}{auto}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{n}{Abort}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y}\PYG{o}{,}
       \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{=} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{/} \PYG{n}{y} \PYG{o}{=} \PYG{l+m+mi}{1}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{R}\PYG{o}{,} \PYG{n}{y} \PYG{o}{\PYGZlt{}}\PYG{o}{\PYGZgt{}} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{y} \PYG{o}{=} \PYG{n}{x} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{x} \PYG{o}{/} \PYG{n}{y} \PYG{o}{=} \PYG{l+m+mi}{1}

\PYG{k}{intros} \PYG{n}{x} \PYG{n}{y} \PYG{n}{H} \PYG{n}{H1}\PYG{o}{;} \PYG{k}{field} \PYG{o}{[}\PYG{n}{H1}\PYG{o}{]}\PYG{o}{;} \PYG{k}{auto}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{n}{Abort}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{field~{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}{]}}}}}
decides the equality of two terms modulo
field operations and the equalities defined
by the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}s. Each \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} has to be a proof of some equality
\sphinxtitleref{m} \sphinxcode{\sphinxupquote{=}} \sphinxtitleref{p}, where \sphinxtitleref{m} is a monomial (after “abstraction”), \sphinxtitleref{p} a polynomial
and \sphinxcode{\sphinxupquote{=}} the corresponding equality of the field structure.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Note:}
rewriting works with the equality  \sphinxtitleref{m} \sphinxcode{\sphinxupquote{=}} \sphinxtitleref{p} only if \sphinxtitleref{p} is a polynomial since
rewriting is handled by the underlying ring tactic.
\end{sphinxadmonition}


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{field\_simplify}}}}
performs the simplification in the conclusion of the
goal, \(F_1 = F_2\) becomes \(N_1 / D_1 = N_2 / D_2\). A normalization step
(the same as the one for rings) is then applied to \(N_1\), \(D_1\),
\(N_2\) and \(D_2\). This way, polynomials remain in factorized form during
fraction simplification. This yields smaller expressions when
reducing to the same denominator since common factors can be canceled.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{field\_simplify~{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}{]}}}}}
performs the simplification in the conclusion of the goal using the equalities
defined by the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}s.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{field\_simplify~{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}{]}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}}}}}
performs the simplification in the terms \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{terms}}}}  of the conclusion of the goal
using the equalities defined by \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}s inside the brackets.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{field\_simplify~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
performs the simplification in the assumption \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{field\_simplify~{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}{]}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
performs the simplification
in the assumption \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} using the equalities defined by the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}s.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{field\_simplify~{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}{]}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
performs the simplification in the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}s of the assumption \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} using the
equalities defined by  the \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}s inside the brackets.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{field\_simplify\_eq}}}}
performs the simplification in the conclusion of
the goal removing the denominator. \(F_1 = F_2\) becomes \(N_1 D_2 = N_2 D_1\).

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{field\_simplify\_eq~{[}~\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}{]}}}}}
performs the simplification in
the conclusion of the goal using the equalities defined by
\sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}s.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{field\_simplify\_eq~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
performs the simplification in the assumption \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}.

\end{fulllineitems}



\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{field\_simplify\_eq~{[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{*}}{]}~in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
performs the simplification in the assumption \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} using the equalities defined by
\sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{terms}}}}s and removing the denominator.

\end{fulllineitems}



\subsection{Adding a new field structure}
\label{\detokenize{addendum/ring:adding-a-new-field-structure}}
Declaring a new field consists in proving that a field signature (a
carrier set, an equality, and field operations:
\sphinxcode{\sphinxupquote{Field\_theory.field\_theory}} and \sphinxcode{\sphinxupquote{Field\_theory.semi\_field\_theory}})
satisfies the field axioms. Semi-fields (fields without + inverse) are
also supported. The equality can be either Leibniz equality, or any
relation declared as a setoid (see {\hyperref[\detokenize{addendum/generalized-rewriting:tactics-enabled-on-user-provided-relations}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics enabled on user provided relations}}}}). The definition of
fields and semifields is:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Record} \PYG{n}{field\PYGZus{}theory} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{mk\PYGZus{}field} \PYG{o}{\PYGZob{}}
  \PYG{n}{F\PYGZus{}R} \PYG{o}{:} \PYG{n}{ring\PYGZus{}theory} \PYG{n}{rO} \PYG{n}{rI} \PYG{n}{radd} \PYG{n}{rmul} \PYG{n}{rsub} \PYG{n}{ropp} \PYG{n}{req}\PYG{o}{;}
  \PYG{n}{F\PYGZus{}1\PYGZus{}neq\PYGZus{}0} \PYG{o}{:} \PYG{o}{\PYGZti{}} \PYG{l+m+mi}{1} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{;}
  \PYG{n}{Fdiv\PYGZus{}def} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{p} \PYG{n}{q}\PYG{o}{,} \PYG{n}{p} \PYG{o}{/} \PYG{n}{q} \PYG{o}{=}\PYG{o}{=} \PYG{n}{p} \PYG{o}{*} \PYG{o}{/} \PYG{n}{q}\PYG{o}{;}
  \PYG{n}{Finv\PYGZus{}l} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{p}\PYG{o}{,} \PYG{o}{\PYGZti{}} \PYG{n}{p} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}}  \PYG{o}{/} \PYG{n}{p} \PYG{o}{*} \PYG{n}{p} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{1}
\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\PYG{k+kn}{Record} \PYG{n}{semi\PYGZus{}field\PYGZus{}theory} \PYG{o}{:} \PYG{k+kt}{Prop} \PYG{o}{:=} \PYG{n}{mk\PYGZus{}sfield} \PYG{o}{\PYGZob{}}
  \PYG{n}{SF\PYGZus{}SR} \PYG{o}{:} \PYG{n}{semi\PYGZus{}ring\PYGZus{}theory} \PYG{n}{rO} \PYG{n}{rI} \PYG{n}{radd} \PYG{n}{rmul} \PYG{n}{req}\PYG{o}{;}
  \PYG{n}{SF\PYGZus{}1\PYGZus{}neq\PYGZus{}0} \PYG{o}{:} \PYG{o}{\PYGZti{}} \PYG{l+m+mi}{1} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{0}\PYG{o}{;}
  \PYG{n}{SFdiv\PYGZus{}def} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{p} \PYG{n}{q}\PYG{o}{,} \PYG{n}{p} \PYG{o}{/} \PYG{n}{q} \PYG{o}{=}\PYG{o}{=} \PYG{n}{p} \PYG{o}{*} \PYG{o}{/} \PYG{n}{q}\PYG{o}{;}
  \PYG{n}{SFinv\PYGZus{}l} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{p}\PYG{o}{,} \PYG{o}{\PYGZti{}} \PYG{n}{p} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{0} \PYG{o}{\PYGZhy{}\PYGZgt{}}  \PYG{o}{/} \PYG{n}{p} \PYG{o}{*} \PYG{n}{p} \PYG{o}{=}\PYG{o}{=} \PYG{l+m+mi}{1}
\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

The result of the normalization process is a fraction represented by
the following type:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Record} \PYG{n}{linear} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=} \PYG{n}{mk\PYGZus{}linear} \PYG{o}{\PYGZob{}}
  \PYG{n}{num} \PYG{o}{:} \PYG{n}{PExpr} \PYG{n}{C}\PYG{o}{;}
  \PYG{n}{denum} \PYG{o}{:} \PYG{n}{PExpr} \PYG{n}{C}\PYG{o}{;}
  \PYG{n}{condition} \PYG{o}{:} \PYG{k+kt}{list} \PYG{o}{(}\PYG{n}{PExpr} \PYG{n}{C}\PYG{o}{)}
\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

where \sphinxcode{\sphinxupquote{num}} and \sphinxcode{\sphinxupquote{denum}} are the numerator and denominator; \sphinxcode{\sphinxupquote{condition}} is a
list of expressions that have appeared as a denominator during the
normalization process. These expressions must be proven different from
zero for the correctness of the algorithm.

The syntax for adding a new field is
\index{Add Field (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/ring:coq:cmd.add-field}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~Field~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{(~{\hyperref[\detokenize{addendum/ring:grammar-token-field-mod}]{\sphinxcrossref{\DUrole{hole}{field\_mod}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{,~{\hyperref[\detokenize{addendum/ring:grammar-token-field-mod}]{\sphinxcrossref{\DUrole{hole}{field\_mod}}}}}\DUrole{notation-sup}{*}}~)}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}


The \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}} is not relevant. It is used just for error
messages. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is a proof that the field signature satisfies the
(semi-)field axioms. The optional list of modifiers is used to tailor
the behavior of the tactic.


\begin{productionlist}
\phantomsection\label{\detokenize{addendum/ring:grammar-token-field_mod}}\production{field\_mod}{ {\hyperref[\detokenize{addendum/ring:grammar-token-ring-mod}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ring\_mod}}}}} \textbar{} completeness {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{term}}}}}}
\end{productionlist}


Since field tactics are built upon \sphinxcode{\sphinxupquote{ring}}
tactics, all modifiers of the \sphinxcode{\sphinxupquote{Add Ring}} apply. There is only one
specific modifier:
\begin{description}
\item[{completeness \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}}}] \leavevmode
allows the field tactic to prove automatically
that the image of nonzero coefficients are mapped to nonzero
elements of the field. \sphinxcode{\sphinxupquote{\DUrole{notation}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}}} is a proof of

\sphinxcode{\sphinxupquote{forall x y, {[}x{]} == {[}y{]} -\textgreater{}  x ?=! y = true}},

which is the completeness of equality on coefficients
w.r.t. the field equality.

\end{description}


\subsection{History of ring}
\label{\detokenize{addendum/ring:history-of-ring}}
First Samuel Boutin designed the tactic \sphinxcode{\sphinxupquote{ACDSimpl}}. This tactic did lot
of rewriting. But the proofs terms generated by rewriting were too big
for \DUrole{smallcaps}{Coq}’s type checker. Let us see why:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{ZArith}\PYG{o}{.}
\PYG{k+kn}{Open} \PYG{k+kn}{Scope} \PYG{n}{Z\PYGZus{}scope}\PYG{o}{.}
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{Z}\PYG{o}{,}
       \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{3} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{y} \PYG{o}{*} \PYG{n}{z} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{3} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{z} \PYG{o}{*} \PYG{n}{y}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{Z}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{3} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{y} \PYG{o}{*} \PYG{n}{z} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{3} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{z} \PYG{o}{*} \PYG{n}{y}

\PYG{k}{intros}\PYG{o}{;} \PYG{k}{rewrite} \PYG{o}{(}\PYG{n}{Zmult\PYGZus{}comm} \PYG{n}{y} \PYG{n}{z}\PYG{o}{)}\PYG{o}{;} \PYG{k+kp}{reflexivity}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Save} \PYG{n}{foo}\PYG{o}{.}
    \PYG{n}{foo} \PYG{k}{is} \PYG{n}{defined}

\PYG{k+kn}{Print}  \PYG{n}{foo}\PYG{o}{.}
    \PYG{n}{foo} \PYG{o}{=} 
    \PYG{k}{fun} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{Z} \PYG{o}{=\PYGZgt{}}
    \PYG{n}{eq\PYGZus{}ind\PYGZus{}r} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{z0} \PYG{o}{:} \PYG{n}{Z} \PYG{o}{=\PYGZgt{}} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{3} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{z0} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{3} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{z} \PYG{o}{*} \PYG{n}{y}\PYG{o}{)} \PYG{n}{eq\PYGZus{}refl}
      \PYG{o}{(}\PYG{n}{Z}\PYG{o}{.}\PYG{n}{mul\PYGZus{}comm} \PYG{n}{y} \PYG{n}{z}\PYG{o}{)}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{x} \PYG{n}{y} \PYG{n}{z} \PYG{o}{:} \PYG{n}{Z}\PYG{o}{,} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{3} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{y} \PYG{o}{*} \PYG{n}{z} \PYG{o}{=} \PYG{n}{x} \PYG{o}{+} \PYG{l+m+mi}{3} \PYG{o}{+} \PYG{n}{y} \PYG{o}{+} \PYG{n}{z} \PYG{o}{*} \PYG{n}{y}
    
    \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{Z\PYGZus{}scope} \PYG{n}{Z\PYGZus{}scope} \PYG{n}{Z\PYGZus{}scope}\PYG{o}{]}
\end{sphinxVerbatim}

At each step of rewriting, the whole context is duplicated in the
proof term. Then, a tactic that does hundreds of rewriting generates
huge proof terms. Since \sphinxcode{\sphinxupquote{ACDSimpl}} was too slow, Samuel Boutin rewrote
it using reflection (see \sphinxcite{zebibliography:bou97}). Later, it
was rewritten by Patrick Loiseleur: the new tactic does not any
more require \sphinxcode{\sphinxupquote{ACDSimpl}} to compile and it makes use of \(\beta\delta\iota\)-reduction not
only to replace the rewriting steps, but also to achieve the
interleaving of computation and reasoning (see {\hyperref[\detokenize{addendum/ring:discussion-reflection}]{\sphinxcrossref{\DUrole{std,std-ref}{Discussion}}}}). He also wrote
some \DUrole{smallcaps}{ML} code for the \sphinxcode{\sphinxupquote{Add Ring}} command that allows registering new rings dynamically.

Proofs terms generated by ring are quite small, they are linear in the
number of \(\oplus\) and \(\otimes\) operations in the normalized terms. Type checking
those terms requires some time because it makes a large use of the
conversion rule, but memory requirements are much smaller.


\subsection{Discussion}
\label{\detokenize{addendum/ring:discussion}}\label{\detokenize{addendum/ring:discussion-reflection}}
Efficiency is not the only motivation to use reflection here. \sphinxcode{\sphinxupquote{ring}}
also deals with constants, it rewrites for example the expression
\sphinxcode{\sphinxupquote{34 + 2 * x − x + 12}} to the expected result \sphinxcode{\sphinxupquote{x + 46}}.
For the tactic \sphinxcode{\sphinxupquote{ACDSimpl}}, the only constants were 0 and 1.
So the expression \sphinxcode{\sphinxupquote{34 + 2 * (x − 1) + 12}}
is interpreted as \(V_0 \oplus V_1 \otimes (V_2 \ominus 1) \oplus V_3\),
with the variables mapping
\(\{V_0 \mapsto 34; V_1 \mapsto 2; V_2 \mapsto x; V_3 \mapsto 12\}\).
Then it is rewritten to \sphinxcode{\sphinxupquote{34 − x + 2 * x + 12}}, very far from the expected result.
Here rewriting is not sufficient: you have to do some kind of reduction
(some kind of computation) to achieve the normalization.

The tactic \sphinxcode{\sphinxupquote{ring}} is not only faster than the old one: by using
reflection, we get for free the integration of computation and reasoning
that would be very difficult to implement without it.

Is it the ultimate way to write tactics? The answer is: yes and no.
The \sphinxcode{\sphinxupquote{ring}} tactic intensively uses the conversion rules of the Calculus of
Inductive Constructions, i.e. it replaces proofs by computations as much as possible.
It can be useful in all situations where a classical tactic generates huge proof
terms, like symbolic processing and tautologies. But there
are also tactics like \sphinxcode{\sphinxupquote{auto}} or \sphinxcode{\sphinxupquote{linear}} that do many complex computations,
using side-effects and backtracking, and generate a small proof term.
Clearly, it would be significantly less efficient to replace them by
tactics using reflection.

Another idea suggested by Benjamin Werner: reflection could be used to
couple an external tool (a rewriting program or a model checker)
with \DUrole{smallcaps}{Coq}. We define (in \DUrole{smallcaps}{Coq}) a type of terms, a type of \sphinxstyleemphasis{traces}, and
prove a correctness theorem that states that \sphinxstyleemphasis{replaying traces} is safe
with respect to some interpretation. Then we let the external tool do every
computation (using side-effects, backtracking, exception, or others
features that are not available in pure lambda calculus) to produce
the trace. Now we can check in \DUrole{smallcaps}{Coq} that the trace has the expected
semantics by applying the correctness theorem.


\section{Nsatz: tactics for proving equalities in integral domains}
\label{\detokenize{addendum/nsatz:nsatz-tactics-for-proving-equalities-in-integral-domains}}\label{\detokenize{addendum/nsatz:nsatz-chapter}}\label{\detokenize{addendum/nsatz::doc}}\begin{quote}\begin{description}
\item[{Author}] \leavevmode
Loïc Pottier

\end{description}\end{quote}
\index{nsatz (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/nsatz:coq:tacn.nsatz}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{nsatz}}}}
This tactic is for solving goals of the form

\(\begin{array}{l}
\forall X_1, \ldots, X_n \in A, \\
P_1(X_1, \ldots, X_n) = Q_1(X_1, \ldots, X_n), \ldots, P_s(X_1, \ldots, X_n) = Q_s(X_1, \ldots, X_n) \\
\vdash P(X_1, \ldots, X_n) = Q(X_1, \ldots, X_n) \\
\end{array}\)

where \(P, Q, P_1, Q_1, \ldots, P_s, Q_s\) are polynomials and \(A\) is an integral
domain, i.e. a commutative ring with no zero divisors. For example, \(A\)
can be \(\mathbb{R}\), \(\mathbb{Z}\), or \(\mathbb{Q}\).
Note that the equality \(=\) used in these goals can be
any setoid equality (see {\hyperref[\detokenize{addendum/generalized-rewriting:tactics-enabled-on-user-provided-relations}]{\sphinxcrossref{\DUrole{std,std-ref}{Tactics enabled on user provided relations}}}}) , not only Leibniz equality.

It also proves formulas

\(\begin{array}{l}
\forall X_1, \ldots, X_n \in A, \\
P_1(X_1, \ldots, X_n) = Q_1(X_1, \ldots, X_n) \wedge \ldots \wedge P_s(X_1, \ldots, X_n) = Q_s(X_1, \ldots, X_n) \\
\rightarrow P(X_1, \ldots, X_n) = Q(X_1, \ldots, X_n) \\
\end{array}\)

doing automatic introductions.

You can load the \sphinxcode{\sphinxupquote{Nsatz}} module with the command \sphinxcode{\sphinxupquote{Require Import Nsatz}}.

\end{fulllineitems}



\subsection{More about \sphinxtitleref{nsatz}}
\label{\detokenize{addendum/nsatz:more-about-nsatz}}
Hilbert’s Nullstellensatz theorem shows how to reduce proofs of
equalities on polynomials on a commutative ring \(A\) with no zero divisors
to algebraic computations: it is easy to see that if a polynomial \(P\) in
\(A[X_1,\ldots,X_n]\) verifies \(c P^r = \sum_{i=1}^{s} S_i P_i\), with
\(c \in A\), \(c \not = 0\),
\(r\) a positive integer, and the \(S_i\) s in \(A[X_1,\ldots,X_n ]\),
then \(P\) is zero whenever polynomials \(P_1,\ldots,P_s\) are zero
(the converse is also true when \(A\) is an algebraically closed field: the method is
complete).

So, solving our initial problem reduces to finding \(S_1, \ldots, S_s\),
\(c\) and \(r\) such that \(c (P-Q)^r = \sum_{i} S_i (P_i-Q_i)\),
which will be proved by the tactic ring.

This is achieved by the computation of a Gröbner basis of the ideal
generated by \(P_1-Q_1,...,P_s-Q_s\), with an adapted version of the
Buchberger algorithm.

This computation is done after a step of \sphinxstyleemphasis{reification}, which is
performed using {\hyperref[\detokenize{addendum/type-classes:typeclasses}]{\sphinxcrossref{\DUrole{std,std-ref}{Type Classes}}}}.


\begin{fulllineitems}
\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{nsatz~with~radicalmax:={\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}\%N~strategy:={\hyperref[\detokenize{language/gallina-specification-language:grammar-token-num}]{\sphinxcrossref{\DUrole{hole}{num}}}}\%Z~parameters:={[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}}{]}~variables:={[}\DUrole{repeat-wrapper}{\DUrole{repeat}{{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}}{]}}}}}
Most complete syntax for \sphinxtitleref{nsatz}.
\begin{itemize}
\item {} 
\sphinxtitleref{radicalmax} is a bound when searching for r such that
\(c (P−Q) r = \sum_{i=1..s} S_i (P i − Q i)\)

\item {} 
\sphinxtitleref{strategy} gives the order on variables \(X_1,\ldots,X_n\) and the strategy
used in Buchberger algorithm (see \sphinxcite{zebibliography:sugar} for details):
\begin{itemize}
\item {} 
strategy = 0: reverse lexicographic order and newest s-polynomial.

\item {} 
strategy = 1: reverse lexicographic order and sugar strategy.

\item {} 
strategy = 2: pure lexicographic order and newest s-polynomial.

\item {} 
strategy = 3: pure lexicographic order and sugar strategy.

\end{itemize}

\item {} 
\sphinxtitleref{parameters} is the list of variables \(X_{i_1},\ldots,X_{i_k}\) among
\(X_1,\ldots,X_n\) which are considered as parameters: computation will be performed with
rational fractions in these variables, i.e. polynomials are considered
with coefficients in \(R(X_{i_1},\ldots,X_{i_k})\). In this case, the coefficient
\(c\) can be a non constant polynomial in \(X_{i_1},\ldots,X_{i_k}\), and the tactic
produces a goal which states that \(c\) is not zero.

\item {} 
\sphinxtitleref{variables} is the list of the variables in the decreasing order in
which they will be used in the Buchberger algorithm. If \sphinxtitleref{variables} = \sphinxtitleref{(@nil R)},
then \sphinxtitleref{lvar} is replaced by all the variables which are not in
\sphinxtitleref{parameters}.

\end{itemize}

\end{fulllineitems}


See the file \sphinxtitleref{Nsatz.v} for many examples, especially in geometry.


\section{Generalized rewriting}
\label{\detokenize{addendum/generalized-rewriting:generalized-rewriting}}\label{\detokenize{addendum/generalized-rewriting:generalizedrewriting}}\label{\detokenize{addendum/generalized-rewriting::doc}}\begin{quote}\begin{description}
\item[{Author}] \leavevmode
Matthieu Sozeau

\end{description}\end{quote}

This chapter presents the extension of several equality related
tactics to work over user-defined structures (called setoids) that are
equipped with ad-hoc equivalence relations meant to behave as
equalities. Actually, the tactics have also been generalized to
relations weaker then equivalences (e.g. rewriting systems). The
toolbox also extends the automatic rewriting capabilities of the
system, allowing the specification of custom strategies for rewriting.

This documentation is adapted from the previous setoid documentation
by Claudio Sacerdoti Coen (based on previous work by Clément Renard).
The new implementation is a drop-in replacement for the old one
%
\begin{footnote}[26]\sphinxAtStartFootnote
Nicolas Tabareau helped with the gluing.
%
\end{footnote}, hence most of the documentation still applies.

The work is a complete rewrite of the previous implementation, based
on the typeclass infrastructure. It also improves on and generalizes
the previous implementation in several ways:
\begin{itemize}
\item {} 
User-extensible algorithm. The algorithm is separated into two parts:
generation of the rewriting constraints (written in ML) and solving
these constraints using typeclass resolution. As typeclass
resolution is extensible using tactics, this allows users to define
general ways to solve morphism constraints.

\item {} 
Subrelations. An example extension to the base algorithm is the
ability to define one relation as a subrelation of another so that
morphism declarations on one relation can be used automatically for
the other. This is done purely using tactics and typeclass search.

\item {} 
Rewriting under binders. It is possible to rewrite under binders in
the new implementation, if one provides the proper morphisms. Again,
most of the work is handled in the tactics.

\item {} 
First-class morphisms and signatures. Signatures and morphisms are
ordinary Coq terms, hence they can be manipulated inside Coq, put
inside structures and lemmas about them can be proved inside the
system. Higher-order morphisms are also allowed.

\item {} 
Performance. The implementation is based on a depth-first search for
the first solution to a set of constraints which can be as fast as
linear in the size of the term, and the size of the proof term is
linear in the size of the original term. Besides, the extensibility
allows the user to customize the proof search if necessary.

\end{itemize}


\subsection{Introduction to generalized rewriting}
\label{\detokenize{addendum/generalized-rewriting:introduction-to-generalized-rewriting}}

\subsubsection{Relations and morphisms}
\label{\detokenize{addendum/generalized-rewriting:relations-and-morphisms}}
A parametric \sphinxstyleemphasis{relation} \sphinxcode{\sphinxupquote{R}} is any term of type
\sphinxcode{\sphinxupquote{forall (x1 : T1) ... (xn : Tn), relation A}}.
The expression \sphinxcode{\sphinxupquote{A}}, which depends on \sphinxcode{\sphinxupquote{x1 ... xn}} , is called the \sphinxstyleemphasis{carrier}
of the relation and \sphinxcode{\sphinxupquote{R}} is said to be a relation over \sphinxcode{\sphinxupquote{A}}; the list
\sphinxcode{\sphinxupquote{x1,...,xn}} is the (possibly empty) list of parameters of the relation.

\begin{sphinxadmonition}{note}{Example: Parametric relation}

It is possible to implement finite sets of elements of type \sphinxcode{\sphinxupquote{A}} as
unordered lists of elements of type \sphinxcode{\sphinxupquote{A}}.
The function \sphinxcode{\sphinxupquote{set\_eq: forall (A : Type), relation (list A)}}
satisfied by two lists with the same elements is a parametric relation
over \sphinxcode{\sphinxupquote{(list A)}} with one parameter \sphinxcode{\sphinxupquote{A}}. The type of \sphinxcode{\sphinxupquote{set\_eq}}
is convertible with \sphinxcode{\sphinxupquote{forall (A : Type), list A -\textgreater{} list A -\textgreater{} Prop.}}
\end{sphinxadmonition}

An \sphinxstyleemphasis{instance} of a parametric relation \sphinxcode{\sphinxupquote{R}} with n parameters is any term
\sphinxcode{\sphinxupquote{(R t1 ... tn)}}.

Let \sphinxcode{\sphinxupquote{R}} be a relation over \sphinxcode{\sphinxupquote{A}} with \sphinxcode{\sphinxupquote{n}} parameters. A term is a parametric
proof of reflexivity for \sphinxcode{\sphinxupquote{R}} if it has type
\sphinxcode{\sphinxupquote{forall (x1 : T1) ... (xn : Tn), reflexive (R x1 ... xn)}}.
Similar definitions are given for parametric proofs of symmetry and transitivity.

\begin{sphinxadmonition}{note}{Example: Parametric relation (continued)}

The \sphinxcode{\sphinxupquote{set\_eq}} relation of the previous example can be proved to be
reflexive, symmetric and transitive. A parametric unary function \sphinxcode{\sphinxupquote{f}} of type
\sphinxcode{\sphinxupquote{forall (x1 : T1) ... (xn : Tn), A1 -\textgreater{} A2}} covariantly respects two parametric relation instances
\sphinxcode{\sphinxupquote{R1}} and \sphinxcode{\sphinxupquote{R2}} if, whenever \sphinxcode{\sphinxupquote{x}}, \sphinxcode{\sphinxupquote{y}} satisfy \sphinxcode{\sphinxupquote{R1 x y}}, their images (\sphinxcode{\sphinxupquote{f x}}) and (\sphinxcode{\sphinxupquote{f y}})
satisfy \sphinxcode{\sphinxupquote{R2 (f x) (f y)}}. An \sphinxcode{\sphinxupquote{f}} that respects its input and output
relations will be called a unary covariant \sphinxstyleemphasis{morphism}. We can also say
that \sphinxcode{\sphinxupquote{f}} is a monotone function with respect to \sphinxcode{\sphinxupquote{R1}} and \sphinxcode{\sphinxupquote{R2}} . The
sequence \sphinxcode{\sphinxupquote{x1 ... xn}} represents the parameters of the morphism.
\end{sphinxadmonition}

Let \sphinxcode{\sphinxupquote{R1}} and \sphinxcode{\sphinxupquote{R2}} be two parametric relations. The \sphinxstyleemphasis{signature} of a
parametric morphism of type \sphinxcode{\sphinxupquote{forall (x1 : T1) ... (xn : Tn), A1 -\textgreater{} A2}}
that covariantly respects two instances \(I_{R_1}\) and \(I_{R_2}\) of \sphinxcode{\sphinxupquote{R1}} and \sphinxcode{\sphinxupquote{R2}}
is written \(I_{R_1} ++> I_{R_2}\). Notice that the special arrow ++\textgreater{}, which
reminds the reader of covariance, is placed between the two relation
instances, not between the two carriers. The signature relation
instances and morphism will be typed in a context introducing
variables for the parameters.

The previous definitions are extended straightforwardly to n-ary
morphisms, that are required to be simultaneously monotone on every
argument.

Morphisms can also be contravariant in one or more of their arguments.
A morphism is contravariant on an argument associated to the relation
instance \(R\) if it is covariant on the same argument when the inverse
relation \(R^{−1}\) (\sphinxcode{\sphinxupquote{inverse R}} in Coq) is considered. The special arrow \sphinxcode{\sphinxupquote{-{-}\textgreater{}}}
is used in signatures for contravariant morphisms.

Functions having arguments related by symmetric relations instances
are both covariant and contravariant in those arguments. The special
arrow \sphinxcode{\sphinxupquote{==\textgreater{}}} is used in signatures for morphisms that are both
covariant and contravariant.

An instance of a parametric morphism \(f\) with \(n\)
parameters is any term \(f \, t_1 \ldots t_n\).

\begin{sphinxadmonition}{note}{Example: Morphisms}

Continuing the previous example, let \sphinxcode{\sphinxupquote{union: forall (A : Type), list A -\textgreater{} list A -\textgreater{} list A}}
perform the union of two sets by appending one list to the other. \sphinxcode{\sphinxupquote{union{}` is a binary
morphism parametric over {}`{}`A}} that respects the relation instance
\sphinxcode{\sphinxupquote{(set\_eq A)}}. The latter condition is proved by showing:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k}{forall} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{(}\PYG{n}{S1} \PYG{n}{S1\PYGZsq{}} \PYG{n}{S2} \PYG{n}{S2\PYGZsq{}}\PYG{o}{:} \PYG{k+kt}{list} \PYG{n}{A}\PYG{o}{)}\PYG{o}{,}
  \PYG{n}{set\PYGZus{}eq} \PYG{n}{A} \PYG{n}{S1} \PYG{n}{S1\PYGZsq{}} \PYG{o}{\PYGZhy{}\PYGZgt{}}
  \PYG{n}{set\PYGZus{}eq} \PYG{n}{A} \PYG{n}{S2} \PYG{n}{S2\PYGZsq{}} \PYG{o}{\PYGZhy{}\PYGZgt{}}
  \PYG{n}{set\PYGZus{}eq} \PYG{n}{A} \PYG{o}{(}\PYG{n}{union} \PYG{n}{A} \PYG{n}{S1} \PYG{n}{S2}\PYG{o}{)} \PYG{o}{(}\PYG{n}{union} \PYG{n}{A} \PYG{n}{S1\PYGZsq{}} \PYG{n}{S2\PYGZsq{}}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

The signature of the function \sphinxcode{\sphinxupquote{union A}} is \sphinxcode{\sphinxupquote{set\_eq A ==\textgreater{} set\_eq A ==\textgreater{} set\_eq A}}
for all \sphinxcode{\sphinxupquote{A}}.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example: Contravariant morphisms}

The division function \sphinxcode{\sphinxupquote{Rdiv : R -\textgreater{} R -\textgreater{} R}} is a morphism of signature
\sphinxcode{\sphinxupquote{le ++\textgreater{} le -{-}\textgreater{} le}} where \sphinxcode{\sphinxupquote{le}} is the usual order relation over
real numbers. Notice that division is covariant in its first argument
and contravariant in its second argument.
\end{sphinxadmonition}

Leibniz equality is a relation and every function is a morphism that
respects Leibniz equality. Unfortunately, Leibniz equality is not
always the intended equality for a given structure.

In the next section we will describe the commands to register terms as
parametric relations and morphisms. Several tactics that deal with
equality in Coq can also work with the registered relations. The exact
list of tactics will be given {\hyperref[\detokenize{addendum/generalized-rewriting:tactics-enabled-on-user-provided-relations}]{\sphinxcrossref{\DUrole{std,std-ref}{in this section}}}}.
For instance, the tactic reflexivity can be used to solve a goal \sphinxcode{\sphinxupquote{R n n}} whenever \sphinxcode{\sphinxupquote{R}}
is an instance of a registered reflexive relation. However, the
tactics that replace in a context \sphinxcode{\sphinxupquote{C{[}{]}}} one term with another one
related by \sphinxcode{\sphinxupquote{R}} must verify that \sphinxcode{\sphinxupquote{C{[}{]}}} is a morphism that respects the
intended relation. Currently the verification consists of checking
whether \sphinxcode{\sphinxupquote{C{[}{]}}} is a syntactic composition of morphism instances that respects some obvious
compatibility constraints.

\begin{sphinxadmonition}{note}{Example: Rewriting}

Continuing the previous examples, suppose that the user must prove
\sphinxcode{\sphinxupquote{set\_eq int (union int (union int S1 S2) S2) (f S1 S2)}} under the
hypothesis \sphinxcode{\sphinxupquote{H : set\_eq int S2 (@nil int)}}. It
is possible to use the \sphinxcode{\sphinxupquote{rewrite}} tactic to replace the first two
occurrences of \sphinxcode{\sphinxupquote{S2}} with \sphinxcode{\sphinxupquote{@nil int}} in the goal since the
context \sphinxcode{\sphinxupquote{set\_eq int (union int (union int S1 nil) nil) (f S1 S2)}},
being a composition of morphisms instances, is a morphism. However the
tactic will fail replacing the third occurrence of \sphinxcode{\sphinxupquote{S2}}  unless \sphinxcode{\sphinxupquote{f}}
has also been declared as a morphism.
\end{sphinxadmonition}


\subsubsection{Adding new relations and morphisms}
\label{\detokenize{addendum/generalized-rewriting:adding-new-relations-and-morphisms}}\index{Add Parametric Relation (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:cmd.add-parametric-relation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~Parametric~Relation~(x1~:~T1)~...~(xn~:~Tk)~:~(A~t1~...~tn)~(Aeq~t′1~...~t′m)~\DUrole{repeat-wrapper}{\DUrole{repeat}{reflexivity~proved~by~refl}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{symmetry~proved~by~sym}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{transitivity~proved~by~trans}\DUrole{notation-sup}{?}}~as~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This command declares a parametric relation \sphinxcode{\sphinxupquote{\DUrole{name}{Aeq}\DUrole{operator}{:} \DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{y1} \DUrole{operator}{:} \DUrole{name}{\(\beta\)1} \DUrole{operator}{...} \DUrole{name}{ym} \DUrole{operator}{:} \DUrole{name}{\(\beta\)m}\DUrole{operator}{)}}},
\sphinxcode{\sphinxupquote{\DUrole{name}{relation} \DUrole{operator}{(}\DUrole{name}{A} \DUrole{name}{t1} \DUrole{operator}{...} \DUrole{name}{tn}\DUrole{operator}{)}}} over \sphinxcode{\sphinxupquote{\DUrole{operator}{(}\DUrole{name}{A} \DUrole{operator}{:} \DUrole{name}{\(\alpha\)i} \DUrole{operator}{-\textgreater{}} \DUrole{operator}{...} \DUrole{name}{\(\alpha\)n} \DUrole{operator}{-\textgreater{}} \DUrole{keyword,type}{Type}\DUrole{operator}{)}}}.

The {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} gives a unique name to the morphism and it is used
by the command to generate fresh names for automatically provided
lemmas used internally.

Notice that the carrier and relation parameters may refer to the
context of variables introduced at the beginning of the declaration,
but the instances need not be made only of variables. Also notice that
\sphinxcode{\sphinxupquote{A}} is \sphinxstyleemphasis{not} required to be a term having the same parameters as \sphinxcode{\sphinxupquote{Aeq}},
although that is often the case in practice (this departs from the
previous implementation).

To use this command, you need to first import the module \sphinxcode{\sphinxupquote{Setoid}} using
the command \sphinxcode{\sphinxupquote{Require Import Setoid}}.

\end{fulllineitems}

\index{Add Relation (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:cmd.add-relation}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~Relation}}}}
In case the carrier and relations are not parametric, one can use this command
instead, whose syntax is the same except there is no local context.

The proofs of reflexivity, symmetry and transitivity can be omitted if
the relation is not an equivalence relation. The proofs must be
instances of the corresponding relation definitions: e.g. the proof of
reflexivity must have a type convertible to
\sphinxcode{\sphinxupquote{\DUrole{name}{reflexive} \DUrole{operator}{(}\DUrole{name}{A} \DUrole{name}{t1} \DUrole{operator}{...} \DUrole{name}{tn}\DUrole{operator}{)} \DUrole{operator}{(}\DUrole{name}{Aeq} \DUrole{name}{t}\DUrole{error}{′} \DUrole{literal,number,integer}{1} \DUrole{error}{…}\DUrole{name}{t}\DUrole{error}{′} \DUrole{name}{n}\DUrole{operator}{)}}}.
Each proof may refer to the introduced variables as well.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example: Parametric relation}

For Leibniz equality, we may declare:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Add} \PYG{n}{Parametric} \PYG{k+kn}{Relation} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:} \PYG{n}{A} \PYG{o}{(}\PYG{o}{@}\PYG{n}{eq} \PYG{n}{A}\PYG{o}{)}
  \PYG{o}{[}\PYG{k+kp}{reflexivity} \PYG{n}{proved} \PYG{k+kp}{by} \PYG{o}{@}\PYG{n}{refl\PYGZus{}equal} \PYG{n}{A}\PYG{o}{]}
\PYG{o}{..}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Some tactics ({\hyperref[\detokenize{proof-engine/tactics:coq:tacn.reflexivity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reflexivity}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.symmetry}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{symmetry}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.transitivity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{transitivity}}}}}) work only on
relations that respect the expected properties. The remaining tactics
({\hyperref[\detokenize{proof-engine/tactics:coq:tacn.replace}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{replace}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} and derived tactics such as {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.autorewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{autorewrite}}}}}) do not
require any properties over the relation. However, they are able to
replace terms with related ones only in contexts that are syntactic
compositions of parametric morphism instances declared with the
following command.
\index{Add Parametric Morphism (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:cmd.add-parametric-morphism}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~Parametric~Morphism~(x1~:~T1)~...~(xk~:~Tk)~:~(f~t1~...~tn)~with~signature~sig~as~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This command declares \sphinxcode{\sphinxupquote{f}} as a parametric morphism of signature \sphinxcode{\sphinxupquote{sig}}. The
identifier {\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{ident}}}}} gives a unique name to the morphism and it is used as
the base name of the typeclass instance definition and as the name of
the lemma that proves the well-definedness of the morphism. The
parameters of the morphism as well as the signature may refer to the
context of variables. The command asks the user to prove interactively
that \sphinxcode{\sphinxupquote{f}} respects the relations identified from the signature.

\end{fulllineitems}


\begin{sphinxadmonition}{note}{Example}

We start the example by assuming a small theory over
homogeneous sets and we declare set equality as a parametric
equivalence relation and union of two sets as a parametric morphism.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Export} \PYG{n}{Setoid}\PYG{o}{.}
\PYG{k+kn}{Require} \PYG{k+kn}{Export} \PYG{n}{Relation\PYGZus{}Definitions}\PYG{o}{.}
\PYG{k+kn}{Set} \PYG{k+kn}{Implicit} \PYG{k+kn}{Arguments}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{k}{set} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{n}{empty} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A}\PYG{o}{,} \PYG{k}{set} \PYG{n}{A}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{n}{eq\PYGZus{}set} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A}\PYG{o}{,} \PYG{k}{set} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{set} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{.}
\PYG{k+kn}{Parameter} \PYG{n}{union} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A}\PYG{o}{,} \PYG{k}{set} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{set} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k}{set} \PYG{n}{A}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{eq\PYGZus{}set\PYGZus{}refl} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A}\PYG{o}{,} \PYG{n}{reflexive} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{n}{eq\PYGZus{}set} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:=}\PYG{n}{A}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{eq\PYGZus{}set\PYGZus{}sym} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A}\PYG{o}{,} \PYG{n}{symmetric} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{n}{eq\PYGZus{}set} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:=}\PYG{n}{A}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{eq\PYGZus{}set\PYGZus{}trans} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A}\PYG{o}{,} \PYG{n}{transitive} \PYG{o}{\PYGZus{}} \PYG{o}{(}\PYG{n}{eq\PYGZus{}set} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:=}\PYG{n}{A}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{empty\PYGZus{}neutral} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{o}{(}\PYG{n}{S} \PYG{o}{:} \PYG{k}{set} \PYG{n}{A}\PYG{o}{)}\PYG{o}{,} \PYG{n}{eq\PYGZus{}set} \PYG{o}{(}\PYG{n}{union} \PYG{n}{S} \PYG{o}{(}\PYG{n}{empty} \PYG{n}{A}\PYG{o}{)}\PYG{o}{)} \PYG{n}{S}\PYG{o}{.}
\PYG{k+kn}{Axiom} \PYG{n}{union\PYGZus{}compat} \PYG{o}{:}
  \PYG{k}{forall} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)}\PYG{o}{,}
    \PYG{k}{forall} \PYG{n}{x} \PYG{n}{x\PYGZsq{}} \PYG{o}{:} \PYG{k}{set} \PYG{n}{A}\PYG{o}{,} \PYG{n}{eq\PYGZus{}set} \PYG{n}{x} \PYG{n}{x\PYGZsq{}} \PYG{o}{\PYGZhy{}\PYGZgt{}}
    \PYG{k}{forall} \PYG{n}{y} \PYG{n}{y\PYGZsq{}} \PYG{o}{:} \PYG{k}{set} \PYG{n}{A}\PYG{o}{,} \PYG{n}{eq\PYGZus{}set} \PYG{n}{y} \PYG{n}{y\PYGZsq{}} \PYG{o}{\PYGZhy{}\PYGZgt{}}
      \PYG{n}{eq\PYGZus{}set} \PYG{o}{(}\PYG{n}{union} \PYG{n}{x} \PYG{n}{y}\PYG{o}{)} \PYG{o}{(}\PYG{n}{union} \PYG{n}{x\PYGZsq{}} \PYG{n}{y\PYGZsq{}}\PYG{o}{)}\PYG{o}{.}
\PYG{n}{Add} \PYG{n}{Parametric} \PYG{k+kn}{Relation} \PYG{n}{A} \PYG{o}{:} \PYG{o}{(}\PYG{k}{set} \PYG{n}{A}\PYG{o}{)} \PYG{o}{(}\PYG{o}{@}\PYG{n}{eq\PYGZus{}set} \PYG{n}{A}\PYG{o}{)}
  \PYG{k+kp}{reflexivity} \PYG{n}{proved} \PYG{k+kp}{by} \PYG{o}{(}\PYG{n}{eq\PYGZus{}set\PYGZus{}refl} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:=}\PYG{n}{A}\PYG{o}{)}\PYG{o}{)}
  \PYG{k}{symmetry} \PYG{n}{proved} \PYG{k+kp}{by} \PYG{o}{(}\PYG{n}{eq\PYGZus{}set\PYGZus{}sym} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:=}\PYG{n}{A}\PYG{o}{)}\PYG{o}{)}
  \PYG{k}{transitivity} \PYG{n}{proved} \PYG{k+kp}{by} \PYG{o}{(}\PYG{n}{eq\PYGZus{}set\PYGZus{}trans} \PYG{o}{(}\PYG{n}{A}\PYG{o}{:=}\PYG{n}{A}\PYG{o}{)}\PYG{o}{)}
  \PYG{k}{as} \PYG{n}{eq\PYGZus{}set\PYGZus{}rel}\PYG{o}{.}
\PYG{n}{Add} \PYG{n}{Parametric} \PYG{k+kn}{Morphism} \PYG{n}{A} \PYG{o}{:} \PYG{o}{(}\PYG{o}{@}\PYG{n}{union} \PYG{n}{A}\PYG{o}{)}
  \PYG{k}{with} \PYG{n}{signature} \PYG{o}{(}\PYG{o}{@}\PYG{n}{eq\PYGZus{}set} \PYG{n}{A}\PYG{o}{)} \PYG{o}{=}\PYG{o}{=\PYGZgt{}} \PYG{o}{(}\PYG{o}{@}\PYG{n}{eq\PYGZus{}set} \PYG{n}{A}\PYG{o}{)} \PYG{o}{=}\PYG{o}{=\PYGZgt{}} \PYG{o}{(}\PYG{o}{@}\PYG{n}{eq\PYGZus{}set} \PYG{n}{A}\PYG{o}{)} \PYG{k}{as} \PYG{n}{union\PYGZus{}mor}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k+kp}{exact} \PYG{o}{(}\PYG{o}{@}\PYG{n}{union\PYGZus{}compat} \PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}

It is possible to reduce the burden of specifying parameters using
(maximally inserted) implicit arguments. If \sphinxcode{\sphinxupquote{A}} is always set as
maximally implicit in the previous example, one can write:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Add} \PYG{n}{Parametric} \PYG{k+kn}{Relation} \PYG{n}{A} \PYG{o}{:} \PYG{o}{(}\PYG{k}{set} \PYG{n}{A}\PYG{o}{)} \PYG{n}{eq\PYGZus{}set}
  \PYG{k+kp}{reflexivity} \PYG{n}{proved} \PYG{k+kp}{by} \PYG{n}{eq\PYGZus{}set\PYGZus{}refl}
  \PYG{k}{symmetry} \PYG{n}{proved} \PYG{k+kp}{by} \PYG{n}{eq\PYGZus{}set\PYGZus{}sym}
  \PYG{k}{transitivity} \PYG{n}{proved} \PYG{k+kp}{by} \PYG{n}{eq\PYGZus{}set\PYGZus{}trans}
  \PYG{k}{as} \PYG{n}{eq\PYGZus{}set\PYGZus{}rel}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Add} \PYG{n}{Parametric} \PYG{k+kn}{Morphism} \PYG{n}{A} \PYG{o}{:} \PYG{o}{(}\PYG{o}{@}\PYG{n}{union} \PYG{n}{A}\PYG{o}{)} \PYG{k}{with}
  \PYG{n}{signature} \PYG{n}{eq\PYGZus{}set} \PYG{o}{=}\PYG{o}{=\PYGZgt{}} \PYG{n}{eq\PYGZus{}set} \PYG{o}{=}\PYG{o}{=\PYGZgt{}} \PYG{n}{eq\PYGZus{}set} \PYG{k}{as} \PYG{n}{union\PYGZus{}mor}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k+kp}{exact} \PYG{o}{(}\PYG{o}{@}\PYG{n}{union\PYGZus{}compat} \PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}

We proceed now by proving a simple lemma performing a rewrite step and
then applying reflexivity, as we would do working with Leibniz
equality. Both tactic applications are accepted since the required
properties over \sphinxcode{\sphinxupquote{eq\_set}} and \sphinxcode{\sphinxupquote{union}} can be established from the two
declarations above.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Goal} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{S} \PYG{o}{:} \PYG{k}{set} \PYG{k+kt}{nat}\PYG{o}{)}\PYG{o}{,}
  \PYG{n}{eq\PYGZus{}set} \PYG{o}{(}\PYG{n}{union} \PYG{o}{(}\PYG{n}{union} \PYG{n}{S} \PYG{n}{empty}\PYG{o}{)} \PYG{n}{S}\PYG{o}{)} \PYG{o}{(}\PYG{n}{union} \PYG{n}{S} \PYG{n}{S}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{intros}\PYG{o}{.}
\PYG{k}{rewrite} \PYG{n}{empty\PYGZus{}neutral}\PYG{o}{.}
\PYG{k+kp}{reflexivity}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}

The tables of relations and morphisms are managed by the typeclass
instance mechanism. The behavior on section close is to generalize the
instances by the variables of the section (and possibly hypotheses
used in the proofs of instance declarations) but not to export them in
the rest of the development for proof search. One can use the
cmd:\sphinxtitleref{Existing Instance} command to do so outside the section, using the name of the
declared morphism suffixed by \sphinxcode{\sphinxupquote{\_Morphism}}, or use the \sphinxcode{\sphinxupquote{Global}} modifier
for the corresponding class instance declaration
(see {\hyperref[\detokenize{addendum/generalized-rewriting:first-class-setoids-and-morphisms}]{\sphinxcrossref{\DUrole{std,std-ref}{First Class Setoids and Morphisms}}}}) at
definition time. When loading a compiled file or importing a module,
all the declarations of this module will be loaded.
\end{sphinxadmonition}


\subsubsection{Rewriting and non reflexive relations}
\label{\detokenize{addendum/generalized-rewriting:rewriting-and-non-reflexive-relations}}
To replace only one argument of an n-ary morphism it is necessary to
prove that all the other arguments are related to themselves by the
respective relation instances.

\begin{sphinxadmonition}{note}{Example}

To replace \sphinxcode{\sphinxupquote{(union S empty)}} with \sphinxcode{\sphinxupquote{S}} in \sphinxcode{\sphinxupquote{(union (union S empty) S) (union S S)}}
the rewrite tactic must exploit the monotony of \sphinxcode{\sphinxupquote{union}} (axiom \sphinxcode{\sphinxupquote{union\_compat}}
in the previous example). Applying \sphinxcode{\sphinxupquote{union\_compat}} by hand we are left with the
goal \sphinxcode{\sphinxupquote{eq\_set (union S S) (union S S)}}.
\end{sphinxadmonition}

When the relations associated to some arguments are not reflexive, the
tactic cannot automatically prove the reflexivity goals, that are left
to the user.

Setoids whose relations are partial equivalence relations (PER) are
useful for dealing with partial functions. Let \sphinxcode{\sphinxupquote{R}} be a PER. We say that an
element \sphinxcode{\sphinxupquote{x}} is defined if \sphinxcode{\sphinxupquote{R x x}}. A partial function whose domain
comprises all the defined elements is declared as a morphism that
respects \sphinxcode{\sphinxupquote{R}}. Every time a rewriting step is performed the user must
prove that the argument of the morphism is defined.

\begin{sphinxadmonition}{note}{Example}

Let \sphinxcode{\sphinxupquote{eqO}} be \sphinxcode{\sphinxupquote{fun x y =\textgreater{} x = y /\textbackslash{} x \textless{}\textgreater{} 0}} (the
smallest PER over nonzero elements). Division can be declared as a
morphism of signature \sphinxcode{\sphinxupquote{eq ==\textgreater{} eq0 ==\textgreater{} eq}}. Replacing \sphinxcode{\sphinxupquote{x}} with
\sphinxcode{\sphinxupquote{y}} in \sphinxcode{\sphinxupquote{div x n = div y n}} opens an additional goal \sphinxcode{\sphinxupquote{eq0 n n}}
which is equivalent to \sphinxcode{\sphinxupquote{n = n /\textbackslash{} n \textless{}\textgreater{} 0}}.
\end{sphinxadmonition}


\subsubsection{Rewriting and non symmetric relations}
\label{\detokenize{addendum/generalized-rewriting:rewriting-and-non-symmetric-relations}}
When the user works up to relations that are not symmetric, it is no
longer the case that any covariant morphism argument is also
contravariant. As a result it is no longer possible to replace a term
with a related one in every context, since the obtained goal implies
the previous one if and only if the replacement has been performed in
a contravariant position. In a similar way, replacement in an
hypothesis can be performed only if the replaced term occurs in a
covariant position.

\begin{sphinxadmonition}{note}{Example: Covariance and contravariance}

Suppose that division over real numbers has been defined as a morphism of signature
\sphinxcode{\sphinxupquote{Z.div : Z.lt ++\textgreater{} Z.lt -{-}\textgreater{} Z.lt}} (i.e. \sphinxcode{\sphinxupquote{Z.div}} is increasing in
its first argument, but decreasing on the second one). Let \sphinxcode{\sphinxupquote{\textless{}}}
denote \sphinxcode{\sphinxupquote{Z.lt}}. Under the hypothesis \sphinxcode{\sphinxupquote{H : x \textless{} y}} we have
\sphinxcode{\sphinxupquote{k \textless{} x / y -\textgreater{} k \textless{} x / x}}, but not \sphinxcode{\sphinxupquote{k \textless{} y / x -\textgreater{} k \textless{} x / x}}. Dually,
under the same hypothesis \sphinxcode{\sphinxupquote{k \textless{} x / y -\textgreater{} k \textless{} y / y}} holds, but
\sphinxcode{\sphinxupquote{k \textless{} y / x -\textgreater{} k \textless{} y / y}} does not. Thus, if the current goal is
\sphinxcode{\sphinxupquote{k \textless{} x / x}}, it is possible to replace only the second occurrence of
\sphinxcode{\sphinxupquote{x}} (in contravariant position) with \sphinxcode{\sphinxupquote{y}} since the obtained goal
must imply the current one. On the contrary, if \sphinxcode{\sphinxupquote{k \textless{} x / x}} is an
hypothesis, it is possible to replace only the first occurrence of
\sphinxcode{\sphinxupquote{x}} (in covariant position) with \sphinxcode{\sphinxupquote{y}} since the current
hypothesis must imply the obtained one.

Contrary to the previous implementation, no specific error message
will be raised when trying to replace a term that occurs in the wrong
position. It will only fail because the rewriting constraints are not
satisfiable. However it is possible to use the at modifier to specify
which occurrences should be rewritten.

As expected, composing morphisms together propagates the variance
annotations by switching the variance every time a contravariant
position is traversed.
\end{sphinxadmonition}

\begin{sphinxadmonition}{note}{Example}

Let us continue the previous example and let us consider
the goal \sphinxcode{\sphinxupquote{x / (x / x) \textless{} k}}. The first and third occurrences of
\sphinxcode{\sphinxupquote{x}} are in a contravariant position, while the second one is in
covariant position. More in detail, the second occurrence of \sphinxcode{\sphinxupquote{x}}
occurs covariantly in \sphinxcode{\sphinxupquote{(x / x)}} (since division is covariant in
its first argument), and thus contravariantly in \sphinxcode{\sphinxupquote{x / (x / x)}}
(since division is contravariant in its second argument), and finally
covariantly in \sphinxcode{\sphinxupquote{x / (x / x) \textless{} k}} (since \sphinxcode{\sphinxupquote{\textless{}}}, as every
transitive relation, is contravariant in its first argument with
respect to the relation itself).
\end{sphinxadmonition}


\subsubsection{Rewriting in ambiguous setoid contexts}
\label{\detokenize{addendum/generalized-rewriting:rewriting-in-ambiguous-setoid-contexts}}
One function can respect several different relations and thus it can
be declared as a morphism having multiple signatures.

\begin{sphinxadmonition}{note}{Example}

Union over homogeneous lists can be given all the
following signatures: \sphinxcode{\sphinxupquote{eq ==\textgreater{} eq ==\textgreater{} eq}} (\sphinxcode{\sphinxupquote{eq}} being the
equality over ordered lists) \sphinxcode{\sphinxupquote{set\_eq ==\textgreater{} set\_eq ==\textgreater{} set\_eq}}
(\sphinxcode{\sphinxupquote{set\_eq}} being the equality over unordered lists up to duplicates),
\sphinxcode{\sphinxupquote{multiset\_eq ==\textgreater{} multiset\_eq ==\textgreater{} multiset\_eq}} (\sphinxcode{\sphinxupquote{multiset\_eq}}
being the equality over unordered lists).
\end{sphinxadmonition}

To declare multiple signatures for a morphism, repeat the {\hyperref[\detokenize{addendum/generalized-rewriting:coq:cmd.add-morphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Add Morphism}}}}}
command.

When morphisms have multiple signatures it can be the case that a
rewrite request is ambiguous, since it is unclear what relations
should be used to perform the rewriting. Contrary to the previous
implementation, the tactic will always choose the first possible
solution to the set of constraints generated by a rewrite and will not
try to find \sphinxstyleemphasis{all} the possible solutions to warn the user about them.


\subsection{Commands and tactics}
\label{\detokenize{addendum/generalized-rewriting:commands-and-tactics}}

\subsubsection{First class setoids and morphisms}
\label{\detokenize{addendum/generalized-rewriting:first-class-setoids-and-morphisms}}\label{\detokenize{addendum/generalized-rewriting:id2}}
The implementation is based on a first-class representation of
properties of relations and morphisms as typeclasses. That is, the
various combinations of properties on relations and morphisms are
represented as records and instances of theses classes are put in a
hint database. For example, the declaration:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Add Parametric Relation (x1 : T1) ... (xn : Tn) : (A t1 ... tn) (Aeq t′1 ... t′m)
  [reflexivity proved by refl]
  [symmetry proved by sym]
  [transitivity proved by trans]
  as id.
\end{sphinxVerbatim}

is equivalent to an instance declaration:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
Instance (x1 : T1) ... (xn : Tn) =\PYGZgt{} id : @Equivalence (A t1 ... tn) (Aeq t′1 ... t′m) :=
  [Equivalence\PYGZus{}Reflexive := refl]
  [Equivalence\PYGZus{}Symmetric := sym]
  [Equivalence\PYGZus{}Transitive := trans].
\end{sphinxVerbatim}

The declaration itself amounts to the definition of an object of the
record type \sphinxcode{\sphinxupquote{Coq.Classes.RelationClasses.Equivalence}} and a hint added
to the \sphinxcode{\sphinxupquote{typeclass\_instances}} hint database. Morphism declarations are
also instances of a typeclass defined in \sphinxcode{\sphinxupquote{Classes.Morphisms}}. See the
documentation on {\hyperref[\detokenize{addendum/type-classes:typeclasses}]{\sphinxcrossref{\DUrole{std,std-ref}{Type Classes}}}} and the theories files in Classes
for further explanations.

One can inform the rewrite tactic about morphisms and relations just
by using the typeclass mechanism to declare them using Instance and
Context vernacular commands. Any object of type Proper (the type of
morphism declarations) in the local context will also be automatically
used by the rewriting tactic to solve constraints.

Other representations of first class setoids and morphisms can also be
handled by encoding them as records. In the following example, the
projections of the setoid relation and of the morphism function can be
registered as parametric relations and morphisms.

\begin{sphinxadmonition}{note}{Example: First class setoids}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Relation\PYGZus{}Definitions} \PYG{n}{Setoid}\PYG{o}{.}
\PYG{k+kn}{Record} \PYG{n}{Setoid} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
\PYG{o}{\PYGZob{}} \PYG{n}{car}\PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{;}
  \PYG{n}{eq}\PYG{o}{:} \PYG{n}{car} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{car} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{;}
  \PYG{n}{refl}\PYG{o}{:} \PYG{n}{reflexive} \PYG{o}{\PYGZus{}} \PYG{n}{eq}\PYG{o}{;}
  \PYG{n}{sym}\PYG{o}{:} \PYG{n}{symmetric} \PYG{o}{\PYGZus{}} \PYG{n}{eq}\PYG{o}{;}
  \PYG{n}{trans}\PYG{o}{:} \PYG{n}{transitive} \PYG{o}{\PYGZus{}} \PYG{n}{eq}
\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\PYG{n}{Add} \PYG{n}{Parametric} \PYG{k+kn}{Relation} \PYG{o}{(}\PYG{n}{s} \PYG{o}{:} \PYG{n}{Setoid}\PYG{o}{)} \PYG{o}{:} \PYG{o}{(}\PYG{o}{@}\PYG{n}{car} \PYG{n}{s}\PYG{o}{)} \PYG{o}{(}\PYG{o}{@}\PYG{n}{eq} \PYG{n}{s}\PYG{o}{)}
  \PYG{k+kp}{reflexivity} \PYG{n}{proved} \PYG{k+kp}{by} \PYG{o}{(}\PYG{n}{refl} \PYG{n}{s}\PYG{o}{)}
  \PYG{k}{symmetry} \PYG{n}{proved} \PYG{k+kp}{by} \PYG{o}{(}\PYG{n}{sym} \PYG{n}{s}\PYG{o}{)}
  \PYG{k}{transitivity} \PYG{n}{proved} \PYG{k+kp}{by} \PYG{o}{(}\PYG{n}{trans} \PYG{n}{s}\PYG{o}{)} \PYG{k}{as} \PYG{n}{eq\PYGZus{}rel}\PYG{o}{.}
\PYG{k+kn}{Record} \PYG{k+kn}{Morphism} \PYG{o}{(}\PYG{n}{S1} \PYG{n}{S2} \PYG{o}{:} \PYG{n}{Setoid}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{:=}
\PYG{o}{\PYGZob{}} \PYG{n}{f}\PYG{o}{:} \PYG{n}{car} \PYG{n}{S1} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{car} \PYG{n}{S2}\PYG{o}{;}
  \PYG{n}{compat}\PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{x1} \PYG{n}{x2} \PYG{o}{:} \PYG{n}{car} \PYG{n}{S1}\PYG{o}{)}\PYG{o}{,} \PYG{n}{eq} \PYG{n}{S1} \PYG{n}{x1} \PYG{n}{x2} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{eq} \PYG{n}{S2} \PYG{o}{(}\PYG{n}{f} \PYG{n}{x1}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f} \PYG{n}{x2}\PYG{o}{)}
\PYG{o}{\PYGZcb{}}\PYG{o}{.}
\PYG{n}{Add} \PYG{n}{Parametric} \PYG{k+kn}{Morphism} \PYG{o}{(}\PYG{n}{S1} \PYG{n}{S2} \PYG{o}{:} \PYG{n}{Setoid}\PYG{o}{)} \PYG{o}{(}\PYG{n}{M} \PYG{o}{:} \PYG{k+kn}{Morphism} \PYG{n}{S1} \PYG{n}{S2}\PYG{o}{)} \PYG{o}{:}
  \PYG{o}{(}\PYG{o}{@}\PYG{n}{f} \PYG{n}{S1} \PYG{n}{S2} \PYG{n}{M}\PYG{o}{)} \PYG{k}{with} \PYG{n}{signature} \PYG{o}{(}\PYG{o}{@}\PYG{n}{eq} \PYG{n}{S1} \PYG{o}{=}\PYG{o}{=\PYGZgt{}} \PYG{o}{@}\PYG{n}{eq} \PYG{n}{S2}\PYG{o}{)} \PYG{k}{as} \PYG{n}{apply\PYGZus{}mor}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{apply} \PYG{o}{(}\PYG{n}{compat} \PYG{n}{S1} \PYG{n}{S2} \PYG{n}{M}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{test} \PYG{o}{:} \PYG{k}{forall} \PYG{o}{(}\PYG{n}{S1} \PYG{n}{S2} \PYG{o}{:} \PYG{n}{Setoid}\PYG{o}{)} \PYG{o}{(}\PYG{n}{m} \PYG{o}{:} \PYG{k+kn}{Morphism} \PYG{n}{S1} \PYG{n}{S2}\PYG{o}{)}
  \PYG{o}{(}\PYG{n}{x} \PYG{n}{y} \PYG{o}{:} \PYG{n}{car} \PYG{n}{S1}\PYG{o}{)}\PYG{o}{,} \PYG{n}{eq} \PYG{n}{S1} \PYG{n}{x} \PYG{n}{y} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{eq} \PYG{n}{S2} \PYG{o}{(}\PYG{n}{f} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{n}{m} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}} \PYG{n}{m} \PYG{n}{y}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{intros}\PYG{o}{.}
\PYG{k}{rewrite} \PYG{n}{H}\PYG{o}{.}
\PYG{k+kp}{reflexivity}\PYG{o}{.}
\PYG{k+kn}{Qed}\PYG{o}{.}
\end{sphinxVerbatim}
\end{sphinxadmonition}


\subsubsection{Tactics enabled on user provided relations}
\label{\detokenize{addendum/generalized-rewriting:tactics-enabled-on-user-provided-relations}}\label{\detokenize{addendum/generalized-rewriting:id3}}
The following tactics, all prefixed by \sphinxcode{\sphinxupquote{setoid\_}}, deal with arbitrary
registered relations and morphisms. Moreover, all the corresponding
unprefixed tactics (i.e. {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.reflexivity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reflexivity}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.symmetry}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{symmetry}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.transitivity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{transitivity}}}}},
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.replace}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{replace}}}}}, {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}}) have been extended to fall back to their prefixed
counterparts when the relation involved is not Leibniz equality.
Notice, however, that using the prefixed tactics it is possible to
pass additional arguments such as \sphinxcode{\sphinxupquote{using relation}}.
\index{setoid\_reflexivity (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:tacv.setoid-reflexivity}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{setoid\_reflexivity}}}}
\end{fulllineitems}

\index{setoid\_symmetry (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:tacv.setoid-symmetry}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{setoid\_symmetry~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}

\index{setoid\_transitivity (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:tacv.setoid-transitivity}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{setoid\_transitivity}}}}
\end{fulllineitems}

\index{setoid\_rewrite (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:tacv.setoid-rewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{setoid\_rewrite~\DUrole{repeat-wrapper}{\DUrole{repeat}{\DUrole{hole}{orientation}}\DUrole{notation-sup}{?}}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{at~\DUrole{hole}{occs}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}}}}}
\end{fulllineitems}

\index{setoid\_replace (tacnv)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:tacv.setoid-replace}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Variant}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{setoid\_replace~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~with~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{using~relation~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}\DUrole{notation-sup}{?}}~\DUrole{repeat-wrapper}{\DUrole{repeat}{by~\DUrole{hole}{tactic}}\DUrole{notation-sup}{?}}}}}}
The \sphinxcode{\sphinxupquote{using relation}} arguments cannot be passed to the unprefixed form.
The latter argument tells the tactic what parametric relation should
be used to replace the first tactic argument with the second one. If
omitted, it defaults to the \sphinxcode{\sphinxupquote{DefaultRelation}} instance on the type of
the objects. By default, it means the most recent \sphinxcode{\sphinxupquote{Equivalence}} instance
in the environment, but it can be customized by declaring
new \sphinxcode{\sphinxupquote{DefaultRelation}} instances. As Leibniz equality is a declared
equivalence, it will fall back to it if no other relation is declared
on a given type.

\end{fulllineitems}


Every derived tactic that is based on the unprefixed forms of the
tactics considered above will also work up to user defined relations.
For instance, it is possible to register hints for {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.autorewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{autorewrite}}}}} that
are not proofs of Leibniz equalities. In particular it is possible to
exploit {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.autorewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{autorewrite}}}}} to simulate normalization in a term rewriting
system up to user defined equalities.


\subsubsection{Printing relations and morphisms}
\label{\detokenize{addendum/generalized-rewriting:printing-relations-and-morphisms}}\index{Print Instances (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:cmd.print-instances}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Print~Instances}}}}
This command can be used to show the list of currently
registered \sphinxcode{\sphinxupquote{Reflexive}} (using \sphinxcode{\sphinxupquote{Print Instances Reflexive}}), \sphinxcode{\sphinxupquote{Symmetric}}
or \sphinxcode{\sphinxupquote{Transitive}} relations, Equivalences, PreOrders, PERs, and Morphisms
(implemented as \sphinxcode{\sphinxupquote{Proper}} instances). When the rewriting tactics refuse
to replace a term in a context because the latter is not a composition
of morphisms, the {\hyperref[\detokenize{addendum/generalized-rewriting:coq:cmd.print-instances}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Print Instances}}}}} command can be useful to understand
what additional morphisms should be registered.

\end{fulllineitems}



\subsubsection{Deprecated syntax and backward incompatibilities}
\label{\detokenize{addendum/generalized-rewriting:deprecated-syntax-and-backward-incompatibilities}}\index{Add Setoid (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:cmd.add-setoid}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~Setoid~{\hyperref[\detokenize{addendum/micromega:grammar-token-a}]{\sphinxcrossref{\DUrole{hole}{A}}}}~\DUrole{hole}{Aeq}~\DUrole{hole}{ST}~as~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This command for declaring setoids and morphisms is also accepted due
to backward compatibility reasons.

Here \sphinxcode{\sphinxupquote{Aeq}} is a congruence relation without parameters, \sphinxcode{\sphinxupquote{A}} is its carrier
and \sphinxcode{\sphinxupquote{ST}} is an object of type (\sphinxcode{\sphinxupquote{Setoid\_Theory A Aeq}}) (i.e. a record
packing together the reflexivity, symmetry and transitivity lemmas).
Notice that the syntax is not completely backward compatible since the
identifier was not required.

\end{fulllineitems}

\index{Add Morphism (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:cmd.add-morphism}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Add~Morphism~f~:~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This command is restricted to the declaration of morphisms
without parameters. It is not fully backward compatible since the
property the user is asked to prove is slightly different: for n-ary
morphisms the hypotheses of the property are permuted; moreover, when
the morphism returns a proposition, the property is now stated using a
bi-implication in place of a simple implication. In practice, porting
an old development to the new semantics is usually quite simple.

\end{fulllineitems}


Notice that several limitations of the old implementation have been
lifted. In particular, it is now possible to declare several relations
with the same carrier and several signatures for the same morphism.
Moreover, it is now also possible to declare several morphisms having
the same signature. Finally, the {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.replace}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{replace}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}} tactics can be
used to replace terms in contexts that were refused by the old
implementation. As discussed in the next section, the semantics of the
new {\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacv.setoid-rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_rewrite}}}}} tactic differs slightly from the old one and
{\hyperref[\detokenize{proof-engine/tactics:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}}.


\subsection{Extensions}
\label{\detokenize{addendum/generalized-rewriting:extensions}}

\subsubsection{Rewriting under binders}
\label{\detokenize{addendum/generalized-rewriting:rewriting-under-binders}}
\begin{sphinxadmonition}{warning}{Warning:}
Due to compatibility issues, this feature is enabled only
when calling the {\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacv.setoid-rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_rewrite}}}}} tactic directly and not {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite}}}}}.
\end{sphinxadmonition}

To be able to rewrite under binding constructs, one must declare
morphisms with respect to pointwise (setoid) equivalence of functions.
Example of such morphisms are the standard \sphinxcode{\sphinxupquote{all}} and \sphinxcode{\sphinxupquote{ex}} combinators for
universal and existential quantification respectively. They are
declared as morphisms in the \sphinxcode{\sphinxupquote{Classes.Morphisms\_Prop}} module. For
example, to declare that universal quantification is a morphism for
logical equivalence:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Instance} \PYG{n}{all\PYGZus{}iff\PYGZus{}morphism} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{)} \PYG{o}{:}
         \PYG{n}{Proper} \PYG{o}{(}\PYG{n}{pointwise\PYGZus{}relation} \PYG{n}{A} \PYG{n}{iff} \PYG{o}{=}\PYG{o}{=\PYGZgt{}} \PYG{n}{iff}\PYG{o}{)} \PYG{o}{(}\PYG{o}{@}\PYG{n}{all} \PYG{n}{A}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{n}{simpl\PYGZus{}relation}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{subgoal}
      
      \PYG{n}{S1}\PYG{o}{,} \PYG{n}{S2} \PYG{o}{:} \PYG{n}{Setoid}
      \PYG{n}{M} \PYG{o}{:} \PYG{k+kn}{Morphism} \PYG{n}{S1} \PYG{n}{S2}
      \PYG{n}{x}\PYG{o}{,} \PYG{n}{y} \PYG{o}{:} \PYG{n}{car} \PYG{n}{S1}
      \PYG{n}{H} \PYG{o}{:} \PYG{n}{eq} \PYG{n}{S1} \PYG{n}{x} \PYG{n}{y}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{o}{(}\PYG{k}{let} \PYG{o}{(}\PYG{n}{car0}\PYG{o}{,} \PYG{n}{eq0}\PYG{o}{,} \PYG{o}{\PYGZus{}}\PYG{o}{,} \PYG{o}{\PYGZus{}}\PYG{o}{,} \PYG{o}{\PYGZus{}}\PYG{o}{)} \PYG{k}{as} \PYG{n}{s} \PYG{k}{return} \PYG{o}{(}\PYG{n}{car} \PYG{n}{s} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{car} \PYG{n}{s} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Prop}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{S2} \PYG{k}{in} \PYG{n}{eq0}\PYG{o}{)}
        \PYG{o}{(}\PYG{n}{f} \PYG{n}{M} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{n}{f} \PYG{n}{M} \PYG{n}{y}\PYG{o}{)}
\end{sphinxVerbatim}

One then has to show that if two predicates are equivalent at every
point, their universal quantifications are equivalent. Once we have
declared such a morphism, it will be used by the setoid rewriting
tactic each time we try to rewrite under an \sphinxcode{\sphinxupquote{all}} application (products
in \sphinxcode{\sphinxupquote{Prop}} are implicitly translated to such applications).

Indeed, when rewriting under a lambda, binding variable \sphinxcode{\sphinxupquote{x}}, say from \sphinxcode{\sphinxupquote{P x}}
to \sphinxcode{\sphinxupquote{Q x}} using the relation iff, the tactic will generate a proof of
\sphinxcode{\sphinxupquote{pointwise\_relation A iff (fun x =\textgreater{} P x) (fun x =\textgreater{} Q x)}} from the proof
of \sphinxcode{\sphinxupquote{iff (P x) (Q x)}} and a constraint of the form \sphinxcode{\sphinxupquote{Proper (pointwise\_relation A iff ==\textgreater{} ?) m}}
will be generated for the surrounding morphism \sphinxcode{\sphinxupquote{m}}.

Hence, one can add higher-order combinators as morphisms by providing
signatures using pointwise extension for the relations on the
functional arguments (or whatever subrelation of the pointwise
extension). For example, one could declare the \sphinxcode{\sphinxupquote{map}} combinator on lists
as a morphism:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Instance} \PYG{n}{map\PYGZus{}morphism} \PYG{o}{{}`}\PYG{o}{\PYGZob{}}\PYG{n}{Equivalence} \PYG{n}{A} \PYG{n}{eqA}\PYG{o}{,} \PYG{n}{Equivalence} \PYG{n}{B} \PYG{n}{eqB}\PYG{o}{\PYGZcb{}} \PYG{o}{:}
         \PYG{n}{Proper} \PYG{o}{(}\PYG{o}{(}\PYG{n}{eqA} \PYG{o}{=}\PYG{o}{=\PYGZgt{}} \PYG{n}{eqB}\PYG{o}{)} \PYG{o}{=}\PYG{o}{=\PYGZgt{}} \PYG{n}{list\PYGZus{}equiv} \PYG{n}{eqA} \PYG{o}{=}\PYG{o}{=\PYGZgt{}} \PYG{n}{list\PYGZus{}equiv} \PYG{n}{eqB}\PYG{o}{)} \PYG{o}{(}\PYG{o}{@}\PYG{n}{map} \PYG{n}{A} \PYG{n}{B}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

where \sphinxcode{\sphinxupquote{list\_equiv}} implements an equivalence on lists parameterized by
an equivalence on the elements.

Note that when one does rewriting with a lemma under a binder using
{\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacv.setoid-rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_rewrite}}}}}, the application of the lemma may capture the bound
variable, as the semantics are different from rewrite where the lemma
is first matched on the whole term. With the new {\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacv.setoid-rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_rewrite}}}}},
matching is done on each subterm separately and in its local
environment, and all matches are rewritten \sphinxstyleemphasis{simultaneously} by
default. The semantics of the previous {\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacv.setoid-rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{setoid\_rewrite}}}}} implementation
can almost be recovered using the \sphinxcode{\sphinxupquote{at 1}} modifier.


\subsubsection{Subrelations}
\label{\detokenize{addendum/generalized-rewriting:subrelations}}
Subrelations can be used to specify that one relation is included in
another, so that morphism signatures for one can be used for the
other. If a signature mentions a relation \sphinxcode{\sphinxupquote{R}} on the left of an
arrow \sphinxcode{\sphinxupquote{==\textgreater{}}}, then the signature also applies for any relation \sphinxcode{\sphinxupquote{S}} that is
smaller than \sphinxcode{\sphinxupquote{R}}, and the inverse applies on the right of an arrow. One
can then declare only a few morphisms instances that generate the
complete set of signatures for a particular constant. By default, the
only declared subrelation is \sphinxcode{\sphinxupquote{iff}}, which is a subrelation of \sphinxcode{\sphinxupquote{impl}} and
\sphinxcode{\sphinxupquote{inverse impl}} (the dual of implication). That’s why we can declare only
two morphisms for conjunction: \sphinxcode{\sphinxupquote{Proper (impl ==\textgreater{} impl ==\textgreater{} impl) and}} and
\sphinxcode{\sphinxupquote{Proper (iff ==\textgreater{} iff ==\textgreater{} iff) and}}. This is sufficient to satisfy any
rewriting constraints arising from a rewrite using \sphinxcode{\sphinxupquote{iff}}, \sphinxcode{\sphinxupquote{impl}} or
\sphinxcode{\sphinxupquote{inverse impl}} through \sphinxcode{\sphinxupquote{and}}.

Subrelations are implemented in \sphinxcode{\sphinxupquote{Classes.Morphisms}} and are a prime
example of a mostly user-space extension of the algorithm.


\subsubsection{Constant unfolding}
\label{\detokenize{addendum/generalized-rewriting:constant-unfolding}}
The resolution tactic is based on typeclasses and hence regards user-
defined constants as transparent by default. This may slow down the
resolution due to a lot of unifications (all the declared \sphinxcode{\sphinxupquote{Proper}}
instances are tried at each node of the search tree). To speed it up,
declare your constant as rigid for proof search using the command
{\hyperref[\detokenize{addendum/type-classes:coq:cmd.typeclasses-opaque}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Typeclasses Opaque}}}}}.


\subsection{Strategies for rewriting}
\label{\detokenize{addendum/generalized-rewriting:strategies-for-rewriting}}

\subsubsection{Definitions}
\label{\detokenize{addendum/generalized-rewriting:definitions}}
The generalized rewriting tactic is based on a set of strategies that can be
combined to obtain custom rewriting procedures. Its set of strategies is based
on Elan’s rewriting strategies \sphinxcite{zebibliography:luttik97specificationof}. Rewriting
strategies are applied using the tactic \sphinxcode{\sphinxupquote{rewrite\_strat s}} where \sphinxcode{\sphinxupquote{s}} is a
strategy expression. Strategies are defined inductively as described by the
following grammar:


\begin{productionlist}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-s, t, u}}\production{s, t, u}{ {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-strategy}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{strategy}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-lemma}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lemma}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-lemma-right-to-left}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{lemma\_right\_to\_left}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-failure}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{failure}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-identity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{identity}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-reflexivity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{reflexivity}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-progress}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{progress}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-failure-catch}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{failure\_catch}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-composition}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{composition}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-left-biased-choice}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{left\_biased\_choice}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-iteration-one-or-more}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{iteration\_one\_or\_more}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-iteration-zero-or-more}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{iteration\_zero\_or\_more}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-one-subterm}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{one\_subterm}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-all-subterms}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{all\_subterms}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-innermost-first}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{innermost\_first}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-outermost-first}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{outermost\_first}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-bottom-up}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{bottom\_up}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-top-down}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{top\_down}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-apply-hint}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply\_hint}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-any-of-the-terms}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{any\_of\_the\_terms}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-apply-reduction}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{apply\_reduction}}}}}}
\productioncont{ \textbar{} {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-fold-expression}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{fold\_expression}}}}}}
\end{productionlist}



\begin{productionlist}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-strategy}}\production{strategy}{ "(" \sphinxcode{\sphinxupquote{s}} ")"}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-lemma}}\production{lemma}{ \sphinxcode{\sphinxupquote{c}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-lemma_right_to_left}}\production{lemma\_right\_to\_left}{ "\textless{}-" \sphinxcode{\sphinxupquote{c}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-failure}}\production{failure}{ \sphinxcode{\sphinxupquote{fail}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-identity}}\production{identity}{ \sphinxcode{\sphinxupquote{id}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-reflexivity}}\production{reflexivity}{ \sphinxcode{\sphinxupquote{refl}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-progress}}\production{progress}{ {\hyperref[\detokenize{addendum/generalized-rewriting:grammar-token-progress}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{progress}}}}} \sphinxcode{\sphinxupquote{s}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-failure_catch}}\production{failure\_catch}{ \sphinxcode{\sphinxupquote{try}} \sphinxcode{\sphinxupquote{s}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-composition}}\production{composition}{ \sphinxcode{\sphinxupquote{s}} ";" \sphinxcode{\sphinxupquote{u}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-left_biased_choice}}\production{left\_biased\_choice}{ choice \sphinxcode{\sphinxupquote{s}} {\hyperref[\detokenize{proof-engine/tactics:grammar-token-t}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{t}}}}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-iteration_one_or_more}}\production{iteration\_one\_or\_more}{ \sphinxcode{\sphinxupquote{repeat}} \sphinxcode{\sphinxupquote{s}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-iteration_zero_or_more}}\production{iteration\_zero\_or\_more}{ \sphinxcode{\sphinxupquote{any}} \sphinxcode{\sphinxupquote{s}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-one_subterm}}\production{one\_subterm}{ subterm \sphinxcode{\sphinxupquote{s}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-all_subterms}}\production{all\_subterms}{ subterms \sphinxcode{\sphinxupquote{s}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-innermost_first}}\production{innermost\_first}{ \sphinxcode{\sphinxupquote{innermost}} \sphinxcode{\sphinxupquote{s}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-outermost_first}}\production{outermost\_first}{ \sphinxcode{\sphinxupquote{outermost}} \sphinxcode{\sphinxupquote{s}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-bottom_up}}\production{bottom\_up}{ \sphinxcode{\sphinxupquote{bottomup}} \sphinxcode{\sphinxupquote{s}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-top_down}}\production{top\_down}{ \sphinxcode{\sphinxupquote{topdown}} \sphinxcode{\sphinxupquote{s}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-apply_hint}}\production{apply\_hint}{ hints \sphinxcode{\sphinxupquote{hintdb}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-any_of_the_terms}}\production{any\_of\_the\_terms}{ terms (\sphinxcode{\sphinxupquote{c}})+}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-apply_reduction}}\production{apply\_reduction}{ eval \sphinxcode{\sphinxupquote{redexpr}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-fold_expression}}\production{fold\_expression}{ fold \sphinxcode{\sphinxupquote{c}}}
\end{productionlist}


Actually a few of these are defined in term of the others using a
primitive fixpoint operator:


\begin{productionlist}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-try _s_}}\production{try {}`s{}`}{ choice \sphinxcode{\sphinxupquote{s}} \sphinxcode{\sphinxupquote{id}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-any _s_}}\production{any {}`s{}`}{ fix \sphinxcode{\sphinxupquote{u}}. try (\sphinxcode{\sphinxupquote{s}} ; \sphinxcode{\sphinxupquote{u}})}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-repeat _s_}}\production{repeat {}`s{}`}{ \sphinxcode{\sphinxupquote{s}} ; \sphinxcode{\sphinxupquote{any}} \sphinxcode{\sphinxupquote{s}}}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-bottomup s}}\production{bottomup s}{ fix \sphinxcode{\sphinxupquote{bu}}. (choice (progress (subterms bu)) s) ; try bu}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-topdown s}}\production{topdown s}{ fix \sphinxcode{\sphinxupquote{td}}. (choice s (progress (subterms td))) ; try td}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-innermost s}}\production{innermost s}{ fix \sphinxcode{\sphinxupquote{i}}. (choice (subterm i) s)}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:grammar-token-outermost s}}\production{outermost s}{ fix \sphinxcode{\sphinxupquote{o}}. (choice s (subterm o))}
\end{productionlist}


The basic control strategy semantics are straightforward: strategies
are applied to subterms of the term to rewrite, starting from the root
of the term. The lemma strategies unify the left-hand-side of the
lemma with the current subterm and on success rewrite it to the right-
hand-side. Composition can be used to continue rewriting on the
current subterm. The fail strategy always fails while the identity
strategy succeeds without making progress. The reflexivity strategy
succeeds, making progress using a reflexivity proof of rewriting.
Progress tests progress of the argument strategy and fails if no
progress was made, while \sphinxcode{\sphinxupquote{try}} always succeeds, catching failures.
Choice is left-biased: it will launch the first strategy and fall back
on the second one in case of failure. One can iterate a strategy at
least 1 time using \sphinxcode{\sphinxupquote{repeat}} and at least 0 times using \sphinxcode{\sphinxupquote{any}}.

The \sphinxcode{\sphinxupquote{subterm}} and \sphinxcode{\sphinxupquote{subterms}} strategies apply their argument strategy \sphinxcode{\sphinxupquote{s}} to
respectively one or all subterms of the current term under
consideration, left-to-right. \sphinxcode{\sphinxupquote{subterm}} stops at the first subterm for
which \sphinxcode{\sphinxupquote{s}} made progress. The composite strategies \sphinxcode{\sphinxupquote{innermost}} and \sphinxcode{\sphinxupquote{outermost}}
perform a single innermost or outermost rewrite using their argument
strategy. Their counterparts \sphinxcode{\sphinxupquote{bottomup}} and \sphinxcode{\sphinxupquote{topdown}} perform as many
rewritings as possible, starting from the bottom or the top of the
term.

Hint databases created for {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.autorewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{autorewrite}}}}} can also be used
by {\hyperref[\detokenize{addendum/generalized-rewriting:coq:tacn.rewrite-strat}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{rewrite\_strat}}}}} using the \sphinxcode{\sphinxupquote{hints}} strategy that applies any of the
lemmas at the current subterm. The \sphinxcode{\sphinxupquote{terms}} strategy takes the lemma
names directly as arguments. The \sphinxcode{\sphinxupquote{eval}} strategy expects a reduction
expression (see {\hyperref[\detokenize{proof-engine/tactics:performingcomputations}]{\sphinxcrossref{\DUrole{std,std-ref}{Performing computations}}}}) and succeeds
if it reduces the subterm under consideration. The \sphinxcode{\sphinxupquote{fold}} strategy takes
a term \sphinxcode{\sphinxupquote{c}} and tries to \sphinxstyleemphasis{unify} it to the current subterm, converting it to \sphinxcode{\sphinxupquote{c}}
on success, it is stronger than the tactic \sphinxcode{\sphinxupquote{fold}}.


\subsubsection{Usage}
\label{\detokenize{addendum/generalized-rewriting:usage}}\index{rewrite\_strat (tacn)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:tacn.rewrite-strat}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{notation}{rewrite\_strat~\DUrole{hole}{s}~{[}in~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}{]}}}}}
Rewrite using the strategy s in hypothesis ident or the conclusion.
\index{Nothing to rewrite (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:exn.nothing-to-rewrite}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Nothing~to~rewrite.}}}}
If the strategy failed.

\end{fulllineitems}

\index{No progress made (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:exn.no-progress-made}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{No~progress~made.}}}}
If the strategy succeeded but made no progress.

\end{fulllineitems}

\index{Unable to satisfy the rewriting constraints (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/generalized-rewriting:coq:exn.unable-to-satisfy-the-rewriting-constraints}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Unable~to~satisfy~the~rewriting~constraints.}}}}
If the strategy succeeded and made progress but the
corresponding rewriting constraints are not satisfied.

\end{fulllineitems}


The \sphinxcode{\sphinxupquote{setoid\_rewrite c}} tactic is basically equivalent to
\sphinxcode{\sphinxupquote{rewrite\_strat (outermost c)}}.

\end{fulllineitems}



\section{Asynchronous and Parallel Proof Processing}
\label{\detokenize{addendum/parallel-proof-processing:asynchronous-and-parallel-proof-processing}}\label{\detokenize{addendum/parallel-proof-processing:asynchronousandparallelproofprocessing}}\label{\detokenize{addendum/parallel-proof-processing::doc}}\begin{quote}\begin{description}
\item[{Author}] \leavevmode
Enrico Tassi

\end{description}\end{quote}

This chapter explains how proofs can be asynchronously processed by
\DUrole{smallcaps}{Coq}. This feature improves the reactivity of the system when used in
interactive mode via \DUrole{smallcaps}{CoqIDE}. In addition, it allows \DUrole{smallcaps}{Coq} to take
advantage of parallel hardware when used as a batch compiler by
decoupling the checking of statements and definitions from the
construction and checking of proofs objects.

This feature is designed to help dealing with huge libraries of
theorems characterized by long proofs. In the current state, it may
not be beneficial on small sets of short files.

This feature has some technical limitations that may make it
unsuitable for some use cases.

For example, in interactive mode, some errors coming from the kernel
of \DUrole{smallcaps}{Coq} are signaled late. The type of errors belonging to this
category are universe inconsistencies.

At the time of writing, only opaque proofs (ending with \sphinxcode{\sphinxupquote{Qed}} or
\sphinxcode{\sphinxupquote{Admitted}}) can be processed asynchronously.

Finally, asynchronous processing is disabled when running \DUrole{smallcaps}{CoqIDE} in
Windows. The current implementation of the feature is not stable on
Windows. It can be enabled, as described below at {\hyperref[\detokenize{addendum/parallel-proof-processing:interactive-mode}]{\sphinxcrossref{\DUrole{std,std-ref}{Interactive mode}}}},
though doing so is not recommended.


\subsection{Proof annotations}
\label{\detokenize{addendum/parallel-proof-processing:proof-annotations}}
To process a proof asynchronously \DUrole{smallcaps}{Coq} needs to know the precise
statement of the theorem without looking at the proof. This requires
some annotations if the theorem is proved inside a Section (see
Section {\hyperref[\detokenize{language/gallina-extensions:section-mechanism}]{\sphinxcrossref{\DUrole{std,std-ref}{Section mechanism}}}}).

When a section ends, \DUrole{smallcaps}{Coq} looks at the proof object to decide which
section variables are actually used and hence have to be quantified in
the statement of the theorem. To avoid making the construction of
proofs mandatory when ending a section, one can start each proof with
the \sphinxcode{\sphinxupquote{Proof using}} command (Section {\hyperref[\detokenize{proof-engine/proof-handling:proof-editing-mode}]{\sphinxcrossref{\DUrole{std,std-ref}{Switching on/off the proof editing mode}}}}) that
declares which section variables the theorem uses.

The presence of \sphinxcode{\sphinxupquote{Proof}} using is needed to process proofs asynchronously
in interactive mode.

It is not strictly mandatory in batch mode if it is not the first time
the file is compiled and if the file itself did not change. When the
proof does not begin with Proof using, the system records in an
auxiliary file, produced along with the \sphinxtitleref{.vo} file, the list of section
variables used.


\subsubsection{Automatic suggestion of proof annotations}
\label{\detokenize{addendum/parallel-proof-processing:automatic-suggestion-of-proof-annotations}}
The flag {\hyperref[\detokenize{proof-engine/proof-handling:coq:flag.suggest-proof-using}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Suggest Proof Using}}}}} makes \DUrole{smallcaps}{Coq} suggest, when a \sphinxcode{\sphinxupquote{Qed}}
command is processed, a correct proof annotation. It is up to the user
to modify the proof script accordingly.


\subsection{Proof blocks and error resilience}
\label{\detokenize{addendum/parallel-proof-processing:proof-blocks-and-error-resilience}}
\DUrole{smallcaps}{Coq} 8.6 introduced a mechanism for error resilience: in interactive
mode \DUrole{smallcaps}{Coq} is able to completely check a document containing errors
instead of bailing out at the first failure.

Two kind of errors are supported: errors occurring in vernacular
commands and errors occurring in proofs.

To properly recover from a failing tactic, \DUrole{smallcaps}{Coq} needs to recognize the
structure of the proof in order to confine the error to a sub proof.
Proof block detection is performed by looking at the syntax of the
proof script (i.e. also looking at indentation). \DUrole{smallcaps}{Coq} comes with four
kind of proof blocks, and an ML API to add new ones.
\begin{quote}\begin{description}
\item[{curly}] \leavevmode
blocks are delimited by \{ and \}, see Chapter {\hyperref[\detokenize{proof-engine/proof-handling:proofhandling}]{\sphinxcrossref{\DUrole{std,std-ref}{Proof handling}}}}

\item[{par}] \leavevmode
blocks are atomic, i.e. just one tactic introduced by the \sphinxtitleref{par:}
goal selector

\item[{indent}] \leavevmode
blocks end with a tactic indented less than the previous one

\item[{bullet}] \leavevmode
blocks are delimited by two equal bullet signs at the same
indentation level

\end{description}\end{quote}


\subsubsection{Caveats}
\label{\detokenize{addendum/parallel-proof-processing:caveats}}
When a vernacular command fails the subsequent error messages may be
bogus, i.e. caused by the first error. Error resilience for vernacular
commands can be switched off by passing \sphinxcode{\sphinxupquote{-async-proofs-command-error-resilience off}}
to \DUrole{smallcaps}{CoqIDE}.

An incorrect proof block detection can result into an incorrect error
recovery and hence in bogus errors. Proof block detection cannot be
precise for bullets or any other non well parenthesized proof
structure. Error resilience can be turned off or selectively activated
for any set of block kind passing to \DUrole{smallcaps}{CoqIDE} one of the following
options:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{-async-proofs-tactic-error-resilience off}}

\item {} 
\sphinxcode{\sphinxupquote{-async-proofs-tactic-error-resilience all}}

\item {} 
\sphinxcode{\sphinxupquote{-async-proofs-tactic-error-resilience}} \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{repeat-wrapper}{\DUrole{repeat}{blocktype}\DUrole{notation-sup}{*}\DUrole{notation-sub}{,}}}}}

\end{itemize}

Valid proof block types are: “curly”, “par”, “indent”, and “bullet”.


\subsection{Interactive mode}
\label{\detokenize{addendum/parallel-proof-processing:interactive-mode}}\label{\detokenize{addendum/parallel-proof-processing:id1}}
At the time of writing the only user interface supporting asynchronous
proof processing is \DUrole{smallcaps}{CoqIDE}.

When \DUrole{smallcaps}{CoqIDE} is started, two \DUrole{smallcaps}{Coq} processes are created. The master one
follows the user, giving feedback as soon as possible by skipping
proofs, which are delegated to the worker process. The worker process,
whose state can be seen by clicking on the button in the lower right
corner of the main \DUrole{smallcaps}{CoqIDE} window, asynchronously processes the proofs.
If a proof contains an error, it is reported in red in the label of
the very same button, that can also be used to see the list of errors
and jump to the corresponding line.

If a proof is processed asynchronously the corresponding Qed command
is colored using a lighter color than usual. This signals that the
proof has been delegated to a worker process (or will be processed
lazily if the \sphinxcode{\sphinxupquote{-async-proofs lazy}} option is used). Once finished, the
worker process will provide the proof object, but this will not be
automatically checked by the kernel of the main process. To force the
kernel to check all the proof objects, one has to click the button
with the gears (Fully check the document) on the top bar.
Only then all the universe constraints are checked.


\subsubsection{Caveats}
\label{\detokenize{addendum/parallel-proof-processing:id2}}
The number of worker processes can be increased by passing \DUrole{smallcaps}{CoqIDE}
the \sphinxcode{\sphinxupquote{-async-proofs-j n}} flag. Note that the memory consumption increases too,
since each worker requires the same amount of memory as the master
process. Also note that increasing the number of workers may reduce
the reactivity of the master process to user commands.

To disable this feature, one can pass the \sphinxcode{\sphinxupquote{-async-proofs off}} flag to
\DUrole{smallcaps}{CoqIDE}. Conversely, on Windows, where the feature is disabled by
default, pass the \sphinxcode{\sphinxupquote{-async-proofs on}} flag to enable it.

Proofs that are known to take little time to process are not delegated
to a worker process. The threshold can be configured with
\sphinxcode{\sphinxupquote{-async-proofs-delegation-threshold}}. Default is 0.03 seconds.


\subsection{Batch mode}
\label{\detokenize{addendum/parallel-proof-processing:batch-mode}}
When \DUrole{smallcaps}{Coq} is used as a batch compiler by running \sphinxtitleref{coqc} or \sphinxtitleref{coqtop}
-compile, it produces a \sphinxtitleref{.vo} file for each \sphinxtitleref{.v} file. A \sphinxtitleref{.vo} file contains,
among other things, theorem statements and proofs. Hence to produce a
.vo \DUrole{smallcaps}{Coq} need to process all the proofs of the \sphinxtitleref{.v} file.

The asynchronous processing of proofs can decouple the generation of a
compiled file (like the \sphinxtitleref{.vo} one) that can be loaded by \sphinxcode{\sphinxupquote{Require}} from the
generation and checking of the proof objects. The \sphinxcode{\sphinxupquote{-quick}} flag can be
passed to \sphinxtitleref{coqc} or \sphinxtitleref{coqtop} to produce, quickly, \sphinxtitleref{.vio} files.
Alternatively, when using a Makefile produced by \sphinxtitleref{coq\_makefile},
the \sphinxcode{\sphinxupquote{quick}} target can be used to compile all files using the \sphinxcode{\sphinxupquote{-quick}} flag.

A \sphinxtitleref{.vio} file can be loaded using \sphinxcode{\sphinxupquote{Require}} exactly as a \sphinxtitleref{.vo} file but
proofs will not be available (the Print command produces an error).
Moreover, some universe constraints might be missing, so universes
inconsistencies might go unnoticed. A \sphinxtitleref{.vio} file does not contain proof
objects, but proof tasks, i.e. what a worker process can transform
into a proof object.

Compiling a set of files with the \sphinxcode{\sphinxupquote{-quick}} flag allows one to work,
interactively, on any file without waiting for all the proofs to be
checked.

When working interactively, one can fully check all the \sphinxtitleref{.v} files by
running \sphinxtitleref{coqc} as usual.

Alternatively one can turn each \sphinxtitleref{.vio} into the corresponding \sphinxtitleref{.vo}. All
.vio files can be processed in parallel, hence this alternative might
be faster. The command \sphinxcode{\sphinxupquote{coqtop -schedule-vio2vo 2 a b c}} can be used to
obtain a good scheduling for two workers to produce \sphinxtitleref{a.vo}, \sphinxtitleref{b.vo}, and
\sphinxtitleref{c.vo}. When using a Makefile produced by \sphinxtitleref{coq\_makefile}, the \sphinxcode{\sphinxupquote{vio2vo}} target
can be used for that purpose. Variable \sphinxtitleref{J} should be set to the number
of workers, e.g. \sphinxcode{\sphinxupquote{make vio2vo J=2}}. The only caveat is that, while the
.vo files obtained from \sphinxtitleref{.vio} files are complete (they contain all proof
terms and universe constraints), the satisfiability of all universe
constraints has not been checked globally (they are checked to be
consistent for every single proof). Constraints will be checked when
these \sphinxtitleref{.vo} files are (recursively) loaded with \sphinxcode{\sphinxupquote{Require}}.

There is an extra, possibly even faster, alternative: just check the
proof tasks stored in \sphinxtitleref{.vio} files without producing the \sphinxtitleref{.vo} files. This
is possibly faster because all the proof tasks are independent, hence
one can further partition the job to be done between workers. The
\sphinxcode{\sphinxupquote{coqtop -schedule-vio-checking 6 a b c}} command can be used to obtain a
good scheduling for 6 workers to check all the proof tasks of \sphinxtitleref{a.vio},
\sphinxtitleref{b.vio}, and \sphinxtitleref{c.vio}. Auxiliary files are used to predict how long a proof
task will take, assuming it will take the same amount of time it took
last time. When using a Makefile produced by coq\_makefile, the
\sphinxcode{\sphinxupquote{checkproofs}} target can be used to check all \sphinxtitleref{.vio} files. Variable \sphinxtitleref{J}
should be set to the number of workers, e.g. \sphinxcode{\sphinxupquote{make checkproofs J=6}}. As
when converting \sphinxtitleref{.vio} files to \sphinxtitleref{.vo} files, universe constraints are not
checked to be globally consistent. Hence this compilation mode is only
useful for quick regression testing and on developments not making
heavy use of the \sphinxtitleref{Type} hierarchy.


\subsection{Limiting the number of parallel workers}
\label{\detokenize{addendum/parallel-proof-processing:limiting-the-number-of-parallel-workers}}
Many \DUrole{smallcaps}{Coq} processes may run on the same computer, and each of them may
start many additional worker processes. The \sphinxtitleref{coqworkmgr} utility lets
one limit the number of workers, globally.

The utility accepts the \sphinxcode{\sphinxupquote{-j}} argument to specify the maximum number of
workers (defaults to 2). \sphinxtitleref{coqworkmgr} automatically starts in the
background and prints an environment variable assignment
like \sphinxcode{\sphinxupquote{COQWORKMGR\_SOCKET=localhost:45634}}. The user must set this variable
in all the shells from which \DUrole{smallcaps}{Coq} processes will be started. If one
uses just one terminal running the bash shell, then
\sphinxcode{\sphinxupquote{export ‘coqworkmgr -j 4‘}} will do the job.

After that, all \DUrole{smallcaps}{Coq} processes, e.g. \sphinxtitleref{coqide} and \sphinxtitleref{coqc}, will respect the
limit, globally.


\section{Miscellaneous extensions}
\label{\detokenize{addendum/miscellaneous-extensions:miscellaneous-extensions}}\label{\detokenize{addendum/miscellaneous-extensions:miscellaneousextensions}}\label{\detokenize{addendum/miscellaneous-extensions::doc}}

\subsection{Program derivation}
\label{\detokenize{addendum/miscellaneous-extensions:program-derivation}}
\DUrole{smallcaps}{Coq} comes with an extension called \sphinxcode{\sphinxupquote{Derive}}, which supports program
derivation. Typically in the style of Bird and Meertens or derivations
of program refinements. To use the Derive extension it must first be
required with \sphinxcode{\sphinxupquote{Require Coq.derive.Derive}}. When the extension is loaded,
it provides the following command:
\index{Derive (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/miscellaneous-extensions:coq:cmd.derive}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Derive~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~SuchThat~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-term}]{\sphinxcrossref{\DUrole{hole}{term}}}}~As~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
\end{fulllineitems}


The first \sphinxtitleref{ident} can appear in \sphinxtitleref{term}. This command opens a new proof
presenting the user with a goal for term in which the name \sphinxtitleref{ident} is
bound to an existential variable \sphinxtitleref{?x} (formally, there are other goals
standing for the existential variables but they are shelved, as
described in {\hyperref[\detokenize{proof-engine/tactics:coq:tacn.shelve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{shelve}}}}}).

When the proof ends two constants are defined:
\begin{itemize}
\item {} 
The first one is named using the first \sphinxtitleref{ident} and is defined as the proof of the
shelved goal (which is also the value of \sphinxtitleref{?x}). It is always
transparent.

\item {} 
The second one is named using the second \sphinxtitleref{ident}. It has type \sphinxtitleref{term}, and its body is
the proof of the initially visible goal. It is opaque if the proof
ends with \sphinxcode{\sphinxupquote{Qed}}, and transparent if the proof ends with \sphinxcode{\sphinxupquote{Defined}}.

\end{itemize}

\begin{sphinxadmonition}{note}{Example}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Require} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{derive}\PYG{o}{.}\PYG{n}{Derive}\PYG{o}{.}
    \PYG{o}{[}\PYG{n}{Loading} \PYG{n}{ML} \PYG{n}{file} \PYG{n}{derive\PYGZus{}plugin}\PYG{o}{.}\PYG{n}{cmxs} \PYG{o}{..}\PYG{o}{.} \PYG{k+kp}{done}\PYG{o}{]}

\PYG{k+kn}{Require} \PYG{k+kn}{Import} \PYG{n}{Coq}\PYG{o}{.}\PYG{n}{Numbers}\PYG{o}{.}\PYG{n}{Natural}\PYG{o}{.}\PYG{n}{Peano}\PYG{o}{.}\PYG{n}{NPeano}\PYG{o}{.}
\PYG{k+kn}{Section} \PYG{n}{P}\PYG{o}{.}
\PYG{k+kn}{Variables} \PYG{o}{(}\PYG{n}{n} \PYG{n}{m} \PYG{n}{k}\PYG{o}{:}\PYG{k+kt}{nat}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{n} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{m} \PYG{k}{is} \PYG{n}{declared}
    \PYG{n}{k} \PYG{k}{is} \PYG{n}{declared}

\PYG{n}{Derive} \PYG{n}{p} \PYG{n}{SuchThat} \PYG{o}{(}\PYG{o}{(}\PYG{n}{k}\PYG{o}{*}\PYG{n}{n}\PYG{o}{)}\PYG{o}{+}\PYG{o}{(}\PYG{n}{k}\PYG{o}{*}\PYG{n}{m}\PYG{o}{)} \PYG{o}{=} \PYG{n}{p}\PYG{o}{)} \PYG{n}{As} \PYG{n}{h}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{focused} \PYG{n}{subgoal}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{1}\PYG{o}{)}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m}\PYG{o}{,} \PYG{n}{k} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{p} \PYG{o}{:=} \PYG{o}{?}\PYG{k+kn}{Goal} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{k} \PYG{o}{*} \PYG{n}{n} \PYG{o}{+} \PYG{n}{k} \PYG{o}{*} \PYG{n}{m} \PYG{o}{=} \PYG{n}{p}

\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k}{rewrite} \PYG{o}{\PYGZlt{}\PYGZhy{}} \PYG{n}{Nat}\PYG{o}{.}\PYG{n}{mul\PYGZus{}add\PYGZus{}distr\PYGZus{}l}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{focused} \PYG{n}{subgoal}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{1}\PYG{o}{)}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m}\PYG{o}{,} \PYG{n}{k} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{n}{p} \PYG{o}{:=} \PYG{o}{?}\PYG{k+kn}{Goal} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{k} \PYG{o}{*} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)} \PYG{o}{=} \PYG{n}{p}

\PYG{k}{subst} \PYG{n}{p}\PYG{o}{.}
    \PYG{l+m+mi}{1} \PYG{n}{focused} \PYG{n}{subgoal}
    \PYG{o}{(}\PYG{n}{shelved}\PYG{o}{:} \PYG{l+m+mi}{1}\PYG{o}{)}
      
      \PYG{n}{n}\PYG{o}{,} \PYG{n}{m}\PYG{o}{,} \PYG{n}{k} \PYG{o}{:} \PYG{k+kt}{nat}
      \PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}\PYG{o}{=}
      \PYG{n}{k} \PYG{o}{*} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)} \PYG{o}{=} \PYG{o}{?}\PYG{k+kn}{Goal}

\PYG{k+kp}{reflexivity}\PYG{o}{.}
    \PYG{n}{No} \PYG{n}{more} \PYG{n}{subgoals}\PYG{o}{.}

\PYG{k+kn}{Qed}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{P}\PYG{o}{.}
\PYG{k+kn}{Print} \PYG{n}{p}\PYG{o}{.}
    \PYG{n}{p} \PYG{o}{=} \PYG{k}{fun} \PYG{n}{n} \PYG{n}{m} \PYG{n}{k} \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{=\PYGZgt{}} \PYG{n}{k} \PYG{o}{*} \PYG{o}{(}\PYG{n}{n} \PYG{o}{+} \PYG{n}{m}\PYG{o}{)}
         \PYG{o}{:} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{nat}
    
    \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{nat\PYGZus{}scope} \PYG{n}{nat\PYGZus{}scope} \PYG{n}{nat\PYGZus{}scope}\PYG{o}{]}

\PYG{k+kn}{Check} \PYG{n}{h}\PYG{o}{.}
    \PYG{n}{h}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{n} \PYG{n}{m} \PYG{n}{k} \PYG{o}{:} \PYG{k+kt}{nat}\PYG{o}{,} \PYG{n}{k} \PYG{o}{*} \PYG{n}{n} \PYG{o}{+} \PYG{n}{k} \PYG{o}{*} \PYG{n}{m} \PYG{o}{=} \PYG{n}{p} \PYG{n}{n} \PYG{n}{m} \PYG{n}{k}
\end{sphinxVerbatim}
\end{sphinxadmonition}

Any property can be used as \sphinxtitleref{term}, not only an equation. In particular,
it could be an order relation specifying some form of program
refinement or a non-executable property from which deriving a program
is convenient.


\section{Polymorphic Universes}
\label{\detokenize{addendum/universe-polymorphism:polymorphic-universes}}\label{\detokenize{addendum/universe-polymorphism:polymorphicuniverses}}\label{\detokenize{addendum/universe-polymorphism::doc}}\begin{quote}\begin{description}
\item[{Author}] \leavevmode
Matthieu Sozeau

\end{description}\end{quote}


\subsection{General Presentation}
\label{\detokenize{addendum/universe-polymorphism:general-presentation}}
\begin{sphinxadmonition}{warning}{Warning:}
The status of Universe Polymorphism is experimental.
\end{sphinxadmonition}

This section describes the universe polymorphic extension of \DUrole{smallcaps}{Coq}.
Universe polymorphism makes it possible to write generic definitions
making use of universes and reuse them at different and sometimes
incompatible universe levels.

A standard example of the difference between universe \sphinxstyleemphasis{polymorphic}
and \sphinxstyleemphasis{monomorphic} definitions is given by the identity function:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{identity} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{a} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{a}\PYG{o}{.}
\end{sphinxVerbatim}

By default, constant declarations are monomorphic, hence the identity
function declares a global universe (say \sphinxcode{\sphinxupquote{Top.1}}) for its domain.
Subsequently, if we try to self-apply the identity, we will get an
error:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{Fail} \PYG{k+kn}{Definition} \PYG{n}{selfid} \PYG{o}{:=} \PYG{n}{identity} \PYG{o}{(}\PYG{o}{@}\PYG{n}{identity}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{The} \PYG{n}{command} \PYG{n}{has} \PYG{n}{indeed} \PYG{n}{failed} \PYG{k}{with} \PYG{n}{message}\PYG{o}{:}
    \PYG{n}{The} \PYG{n}{term} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{@identity}\PYG{l+s+s2}{\PYGZdq{}} \PYG{n}{has} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{forall A : Type, A \PYGZhy{}\PYGZgt{} A}\PYG{l+s+s2}{\PYGZdq{}}
    \PYG{n}{while} \PYG{n}{it} \PYG{k}{is} \PYG{n}{expected} \PYG{n}{to} \PYG{k}{have} \PYG{n}{type} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{?A}\PYG{l+s+s2}{\PYGZdq{}}
    \PYG{o}{(}\PYG{n}{unable} \PYG{n}{to} \PYG{n}{find} \PYG{n}{a} \PYG{n}{well}\PYG{o}{\PYGZhy{}}\PYG{n}{typed} \PYG{n}{instantiation} \PYG{k}{for} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{?A}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{:} \PYG{n}{cannot} \PYG{n}{ensure} \PYG{n}{that}
    \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Type@\PYGZob{}Top.1+1\PYGZcb{}}\PYG{l+s+s2}{\PYGZdq{}} \PYG{k}{is} \PYG{n}{a} \PYG{n}{subtype} \PYG{k}{of} \PYG{l+s+s2}{\PYGZdq{}}\PYG{l+s+s2}{Type@\PYGZob{}Top.1\PYGZcb{}}\PYG{l+s+s2}{\PYGZdq{}}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

Indeed, the global level \sphinxcode{\sphinxupquote{Top.1}} would have to be strictly smaller than
itself for this self-application to type check, as the type of
\sphinxcode{\sphinxupquote{\DUrole{operator}{(@}\DUrole{name}{identity}\DUrole{operator}{)}}} is \sphinxcode{\sphinxupquote{\DUrole{keyword}{forall} \DUrole{operator}{(}\DUrole{name}{A} \DUrole{operator}{:} \DUrole{keyword,type}{Type}\DUrole{operator}{@\{}\DUrole{name}{Top}\DUrole{operator}{.}\DUrole{literal,number,integer}{1}\DUrole{operator}{\}),} \DUrole{name}{A} \DUrole{operator}{-\textgreater{}} \DUrole{name}{A}}} whose type is itself
\sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}\DUrole{operator}{@\{}\DUrole{name}{Top}\DUrole{operator}{.}\DUrole{literal,number,integer}{1}\DUrole{operator}{+}\DUrole{literal,number,integer}{1}\DUrole{operator}{\}}}}.

A universe polymorphic identity function binds its domain universe
level at the definition level instead of making it global.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Polymorphic} \PYG{k+kn}{Definition} \PYG{n}{pidentity} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{a} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:=} \PYG{n}{a}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{n}{About} \PYG{n}{pidentity}\PYG{o}{.}
    \PYG{n}{pidentity}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{2}\PYG{o}{\PYGZcb{}} \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}
    
    \PYG{n}{pidentity} \PYG{k}{is} \PYG{n}{universe} \PYG{n}{polymorphic}
    \PYG{n}{Argument} \PYG{n}{A} \PYG{k}{is} \PYG{n}{implicit} \PYG{n}{and} \PYG{n}{maximally} \PYG{n}{inserted}
    \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}}\PYG{o}{]}
    \PYG{n}{pidentity} \PYG{k}{is} \PYG{n}{transparent}
    \PYG{n}{Expands} \PYG{n}{to}\PYG{o}{:} \PYG{n}{Constant} \PYG{n}{Top}\PYG{o}{.}\PYG{n}{pidentity}
\end{sphinxVerbatim}

It is then possible to reuse the constant at different levels, like
so:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{selfpid} \PYG{o}{:=} \PYG{n}{pidentity} \PYG{o}{(}\PYG{o}{@}\PYG{n}{pidentity}\PYG{o}{)}\PYG{o}{.}
\end{sphinxVerbatim}

Of course, the two instances of \sphinxcode{\sphinxupquote{\DUrole{name}{pidentity}}} in this definition are
different. This can be seen when the {\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-universes}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Universes}}}}} flag is on:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{n}{selfpid}\PYG{o}{.}
    \PYG{n}{selfpid} \PYG{o}{=} 
    \PYG{n}{pidentity}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{3}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{o}{@}\PYG{n}{pidentity}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{4}\PYG{o}{\PYGZcb{}}\PYG{o}{)}
         \PYG{o}{:} \PYG{k}{forall} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{4}\PYG{o}{\PYGZcb{}}\PYG{o}{,} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{A}
    \PYG{c}{(*}\PYG{c}{ \PYGZob{}Top.4 Top.3\PYGZcb{} \textbar{}= Top.4 \PYGZlt{} Top.3}
\PYG{c}{                         }\PYG{c}{*)}
    
    \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}}\PYG{o}{]}
\end{sphinxVerbatim}

Now \sphinxcode{\sphinxupquote{\DUrole{name}{pidentity}}} is used at two different levels: at the head of the
application it is instantiated at \sphinxcode{\sphinxupquote{Top.3}} while in the argument position
it is instantiated at \sphinxcode{\sphinxupquote{Top.4}}. This definition is only valid as long as
\sphinxcode{\sphinxupquote{Top.4}} is strictly smaller than \sphinxcode{\sphinxupquote{Top.3}}, as shown by the constraints. Note
that this definition is monomorphic (not universe polymorphic), so the
two universes (in this case \sphinxcode{\sphinxupquote{Top.3}} and \sphinxcode{\sphinxupquote{Top.4}}) are actually global
levels.

When printing \sphinxcode{\sphinxupquote{\DUrole{name}{pidentity}}}, we can see the universes it binds in
the annotation \sphinxcode{\sphinxupquote{\DUrole{operator}{@\{}\DUrole{name}{Top}\DUrole{operator}{.}\DUrole{literal,number,integer}{2}\DUrole{operator}{\}}}}. Additionally, when
{\hyperref[\detokenize{language/gallina-extensions:coq:flag.printing-universes}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Printing Universes}}}}} is on we print the "universe context" of
\sphinxcode{\sphinxupquote{\DUrole{name}{pidentity}}} consisting of the bound universes and the
constraints they must verify (for \sphinxcode{\sphinxupquote{\DUrole{name}{pidentity}}} there are no constraints).

Inductive types can also be declared universes polymorphic on
universes appearing in their parameters or fields. A typical example
is given by monoids:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Polymorphic} \PYG{k+kn}{Record} \PYG{n}{Monoid} \PYG{o}{:=} \PYG{o}{\PYGZob{}} \PYG{n}{mon\PYGZus{}car} \PYG{o}{:\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{;} \PYG{n}{mon\PYGZus{}unit} \PYG{o}{:} \PYG{n}{mon\PYGZus{}car}\PYG{o}{;}
  \PYG{n}{mon\PYGZus{}op} \PYG{o}{:} \PYG{n}{mon\PYGZus{}car} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{mon\PYGZus{}car} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{mon\PYGZus{}car} \PYG{o}{\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{n}{Monoid}\PYG{o}{.}
\end{sphinxVerbatim}

The Monoid's carrier universe is polymorphic, hence it is possible to
instantiate it for example with \sphinxcode{\sphinxupquote{\DUrole{name}{Monoid}}} itself. First we build the
trivial unit monoid in \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}}:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{unit\PYGZus{}monoid} \PYG{o}{:} \PYG{n}{Monoid} \PYG{o}{:=}
  \PYG{o}{\PYGZob{}\textbar{}} \PYG{n}{mon\PYGZus{}car} \PYG{o}{:=} \PYG{k+kt}{unit}\PYG{o}{;} \PYG{n}{mon\PYGZus{}unit} \PYG{o}{:=} \PYG{n}{tt}\PYG{o}{;} \PYG{n}{mon\PYGZus{}op} \PYG{n}{x} \PYG{n}{y} \PYG{o}{:=} \PYG{n}{tt} \PYG{o}{\textbar{}\PYGZcb{}}\PYG{o}{.}
\end{sphinxVerbatim}

From this we can build a definition for the monoid of \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}}-monoids
(where multiplication would be given by the product of monoids).

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Polymorphic} \PYG{k+kn}{Definition} \PYG{n}{monoid\PYGZus{}monoid} \PYG{o}{:} \PYG{n}{Monoid}\PYG{o}{.}
\PYG{k}{refine} \PYG{o}{(}\PYG{o}{@}\PYG{n}{Build\PYGZus{}Monoid} \PYG{n}{Monoid} \PYG{n}{unit\PYGZus{}monoid} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{n}{y} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}\PYG{o}{)}\PYG{o}{)}\PYG{o}{.}
\PYG{k+kn}{Defined}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{n}{monoid\PYGZus{}monoid}\PYG{o}{.}
    \PYG{k+kn}{Polymorphic} \PYG{n}{monoid\PYGZus{}monoid}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{10}\PYG{o}{\PYGZcb{}} \PYG{o}{=} 
    \PYG{o}{\PYGZob{}\textbar{}}
    \PYG{n}{mon\PYGZus{}car} \PYG{o}{:=} \PYG{n}{Monoid}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{k+kn}{Set}\PYG{o}{\PYGZcb{}}\PYG{o}{;}
    \PYG{n}{mon\PYGZus{}unit} \PYG{o}{:=} \PYG{n}{unit\PYGZus{}monoid}\PYG{o}{;}
    \PYG{n}{mon\PYGZus{}op} \PYG{o}{:=} \PYG{k}{fun} \PYG{n}{x} \PYG{o}{\PYGZus{}} \PYG{o}{:} \PYG{n}{Monoid}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{k+kn}{Set}\PYG{o}{\PYGZcb{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{x} \PYG{o}{\textbar{}\PYGZcb{}}
         \PYG{o}{:} \PYG{n}{Monoid}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{10}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ Top.10 \textbar{}= Set \PYGZlt{} Top.10}
\PYG{c}{                  }\PYG{c}{*)}
    
    \PYG{n}{monoid\PYGZus{}monoid} \PYG{k}{is} \PYG{n}{universe} \PYG{n}{polymorphic}
\end{sphinxVerbatim}

As one can see from the constraints, this monoid is “large”, it lives
in a universe strictly higher than \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}}.


\subsection{Polymorphic, Monomorphic}
\label{\detokenize{addendum/universe-polymorphism:polymorphic-monomorphic}}\index{Polymorphic (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:cmd.polymorphic}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Polymorphic~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-definition}]{\sphinxcrossref{\DUrole{hole}{definition}}}}}}}}
As shown in the examples, polymorphic definitions and inductives can be
declared using the \sphinxcode{\sphinxupquote{Polymorphic}} prefix.

\end{fulllineitems}

\index{Universe Polymorphism (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:flag.universe-polymorphism}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Universe~Polymorphism}}}}
Once enabled, this option will implicitly prepend \sphinxcode{\sphinxupquote{Polymorphic}} to any
definition of the user.

\end{fulllineitems}

\index{Monomorphic (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:cmd.monomorphic}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Monomorphic~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-definition}]{\sphinxcrossref{\DUrole{hole}{definition}}}}}}}}
When the {\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.universe-polymorphism}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Universe Polymorphism}}}}} option is set, to make a definition
producing global universe constraints, one can use the \sphinxcode{\sphinxupquote{Monomorphic}} prefix.

\end{fulllineitems}


Many other commands support the \sphinxcode{\sphinxupquote{Polymorphic}} flag, including:
\begin{itemize}
\item {} 
\sphinxcode{\sphinxupquote{Lemma}}, \sphinxcode{\sphinxupquote{Axiom}}, and all the other “definition” keywords support
polymorphism.

\item {} 
\sphinxcode{\sphinxupquote{Variables}}, \sphinxcode{\sphinxupquote{Context}}, \sphinxcode{\sphinxupquote{Universe}} and \sphinxcode{\sphinxupquote{Constraint}} in a section support
polymorphism. This means that the universe variables (and associated
constraints) are discharged polymorphically over definitions that use
them. In other words, two definitions in the section sharing a common
variable will both get parameterized by the universes produced by the
variable declaration. This is in contrast to a “mononorphic” variable
which introduces global universes and constraints, making the two
definitions depend on the \sphinxstyleemphasis{same} global universes associated to the
variable.

\item {} 
{\hyperref[\detokenize{proof-engine/tactics:coq:cmdv.hint-resolve}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Resolve}}}}} and {\hyperref[\detokenize{proof-engine/tactics:coq:cmd.hint-rewrite}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Hint Rewrite}}}}} will use the auto/rewrite hint
polymorphically, not at a single instance.

\end{itemize}


\subsection{Cumulative, NonCumulative}
\label{\detokenize{addendum/universe-polymorphism:cumulative-noncumulative}}
Polymorphic inductive types, coinductive types, variants and records can be
declared cumulative using the \sphinxcode{\sphinxupquote{\DUrole{name}{Cumulative}}} prefix.
\index{Cumulative (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:cmd.cumulative}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cumulative~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-inductive}]{\sphinxcrossref{\DUrole{hole}{inductive}}}}}}}}
Declares the inductive as cumulative

\end{fulllineitems}


Alternatively, there is a flag {\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.polymorphic-inductive-cumulativity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Polymorphic Inductive
Cumulativity}}}}} which when set, makes all subsequent \sphinxstyleemphasis{polymorphic}
inductive definitions cumulative.  When set, inductive types and the
like can be enforced to be non-cumulative using the \sphinxcode{\sphinxupquote{\DUrole{name}{NonCumulative}}}
prefix.
\index{NonCumulative (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:cmd.noncumulative}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{NonCumulative~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-inductive}]{\sphinxcrossref{\DUrole{hole}{inductive}}}}}}}}
Declares the inductive as non-cumulative

\end{fulllineitems}

\index{Polymorphic Inductive Cumulativity (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:flag.polymorphic-inductive-cumulativity}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Polymorphic~Inductive~Cumulativity}}}}
When this option is on, it sets all following polymorphic inductive
types as cumulative (it is off by default).

\end{fulllineitems}


Consider the examples below.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Polymorphic} \PYG{n}{Cumulative} \PYG{k+kn}{Inductive} \PYG{k+kt}{list} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}} \PYG{o}{:=}
\PYG{o}{\textbar{}} \PYG{n}{nil} \PYG{o}{:} \PYG{k+kt}{list}
\PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{k+kt}{list}\PYG{o}{.}
    \PYG{k+kn}{Polymorphic} \PYG{n}{Cumulative} \PYG{k+kn}{Inductive}
    \PYG{k+kt}{list}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{13}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{13}\PYG{o}{\PYGZcb{}}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{max}\PYG{o}{(}\PYG{k+kn}{Set}\PYG{o}{,}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{13}\PYG{o}{)}\PYG{o}{\PYGZcb{}} \PYG{o}{:=}
        \PYG{n}{nil} \PYG{o}{:} \PYG{k+kt}{list}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{13}\PYG{o}{\PYGZcb{}} \PYG{o}{\textbar{}} \PYG{n}{cons} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{13}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{list}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{13}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ }\PYG{c}{*}\PYG{c}{Top.13 \textbar{}=  }\PYG{c}{*)}
    
    \PYG{n}{For} \PYG{k+kt}{list}\PYG{o}{:} \PYG{n}{Argument} \PYG{n}{A} \PYG{k}{is} \PYG{n}{implicit} \PYG{n}{and} \PYG{n}{maximally} \PYG{n}{inserted}
    \PYG{n}{For} \PYG{n}{nil}\PYG{o}{:} \PYG{n}{Argument} \PYG{n}{A} \PYG{k}{is} \PYG{n}{implicit} \PYG{n}{and} \PYG{n}{maximally} \PYG{n}{inserted}
    \PYG{n}{For} \PYG{n}{cons}\PYG{o}{:} \PYG{n}{Argument} \PYG{n}{A} \PYG{k}{is} \PYG{n}{implicit} \PYG{n}{and} \PYG{n}{maximally} \PYG{n}{inserted}
    \PYG{n}{For} \PYG{k+kt}{list}\PYG{o}{:} \PYG{n}{Argument} \PYG{n}{scope} \PYG{k}{is} \PYG{o}{[}\PYG{n}{type\PYGZus{}scope}\PYG{o}{]}
    \PYG{n}{For} \PYG{n}{nil}\PYG{o}{:} \PYG{n}{Argument} \PYG{n}{scope} \PYG{k}{is} \PYG{o}{[}\PYG{n}{type\PYGZus{}scope}\PYG{o}{]}
    \PYG{n}{For} \PYG{n}{cons}\PYG{o}{:} \PYG{n}{Argument} \PYG{n}{scopes} \PYG{n}{are} \PYG{o}{[}\PYG{n}{type\PYGZus{}scope} \PYG{o}{\PYGZus{}} \PYG{o}{\PYGZus{}}\PYG{o}{]}
\end{sphinxVerbatim}

When printing \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{list}}}, the universe context indicates the subtyping
constraints by prefixing the level names with symbols.

Because inductive subtypings are only produced by comparing inductives
to themselves with universes changed, they amount to variance
information: each universe is either invariant, covariant or
irrelevant (there are no contravariant subtypings in Coq),
respectively represented by the symbols \sphinxtitleref{=}, \sphinxtitleref{+} and \sphinxtitleref{*}.

Here we see that \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{list}}} binds an irrelevant universe, so any two
instances of \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{list}}} are convertible: \(E[Γ] ⊢ \mathsf{list}@\{i\}~A
=_{βδιζη} \mathsf{list}@\{j\}~B\) whenever \(E[Γ] ⊢ A =_{βδιζη} B\) and
this applies also to their corresponding constructors, when
they are comparable at the same type.

See {\hyperref[\detokenize{language/cic:conversion-rules}]{\sphinxcrossref{\DUrole{std,std-ref}{Conversion rules}}}} for more details on convertibility and subtyping.
The following is an example of a record with non-trivial subtyping relation:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Polymorphic} \PYG{n}{Cumulative} \PYG{k+kn}{Record} \PYG{n}{packType} \PYG{o}{:=} \PYG{o}{\PYGZob{}}\PYG{n}{pk} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{packType} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{pk} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}

\sphinxcode{\sphinxupquote{\DUrole{name}{packType}}} binds a covariant universe, i.e.
\begin{equation*}
\begin{split}E[Γ] ⊢ \mathsf{packType}@\{i\} =_{βδιζη}
\mathsf{packType}@\{j\}~\mbox{ whenever }~i ≤ j\end{split}
\end{equation*}
Cumulative inductive types, coninductive types, variants and records
only make sense when they are universe polymorphic. Therefore, an
error is issued whenever the user uses the \sphinxcode{\sphinxupquote{\DUrole{name}{Cumulative}}} or
\sphinxcode{\sphinxupquote{\DUrole{name}{NonCumulative}}} prefix in a monomorphic context.
Notice that this is not the case for the option {\hyperref[\detokenize{addendum/universe-polymorphism:coq:flag.polymorphic-inductive-cumulativity}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Polymorphic Inductive Cumulativity}}}}}.
That is, this option, when set, makes all subsequent \sphinxstyleemphasis{polymorphic}
inductive declarations cumulative (unless, of course the \sphinxcode{\sphinxupquote{\DUrole{name}{NonCumulative}}} prefix is used)
but has no effect on \sphinxstyleemphasis{monomorphic} inductive declarations.

Consider the following examples.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Monomorphic} \PYG{n}{Cumulative} \PYG{k+kn}{Inductive} \PYG{n}{Unit} \PYG{o}{:=} \PYG{k+kt}{unit}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{46}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Monomorphic} \PYG{n}{Cumulative} \PYG{k+kn}{Inductive} \PYG{n}{Unit} \PYG{o}{:=} \PYG{k+kt}{unit}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:} \PYG{n}{The} \PYG{n}{Cumulative} \PYG{n}{prefix} \PYG{n}{can} \PYG{n}{only} \PYG{n}{be} \PYG{n}{used} \PYG{k}{in} \PYG{n}{a} \PYG{n}{polymorphic} \PYG{n}{context}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Monomorphic} \PYG{n}{NonCumulative} \PYG{k+kn}{Inductive} \PYG{n}{Unit} \PYG{o}{:=} \PYG{k+kt}{unit}\PYG{o}{.}
    \PYG{n}{Toplevel} \PYG{n}{input}\PYG{o}{,} \PYG{n}{characters} \PYG{l+m+mi}{0}\PYG{o}{\PYGZhy{}}\PYG{l+m+mi}{49}\PYG{o}{:}
    \PYG{o}{\PYGZgt{}} \PYG{k+kn}{Monomorphic} \PYG{n}{NonCumulative} \PYG{k+kn}{Inductive} \PYG{n}{Unit} \PYG{o}{:=} \PYG{k+kt}{unit}\PYG{o}{.}
    \PYG{o}{\PYGZgt{}} \PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}\PYGZca{}}\PYG{o}{\PYGZca{}}
    \PYG{n}{Error}\PYG{o}{:} \PYG{n}{The} \PYG{n}{NonCumulative} \PYG{n}{prefix} \PYG{n}{can} \PYG{n}{only} \PYG{n}{be} \PYG{n}{used} \PYG{k}{in} \PYG{n}{a} \PYG{n}{polymorphic} \PYG{n}{context}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{k+kn}{Polymorphic} \PYG{k+kn}{Inductive} \PYG{n}{Cumulativity}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{Unit} \PYG{o}{:=} \PYG{k+kt}{unit}\PYG{o}{.}
    \PYG{n}{Unit} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Unit\PYGZus{}rect} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Unit\PYGZus{}ind} \PYG{k}{is} \PYG{n}{defined}
    \PYG{n}{Unit\PYGZus{}rec} \PYG{k}{is} \PYG{n}{defined}
\end{sphinxVerbatim}


\subsubsection{An example of a proof using cumulativity}
\label{\detokenize{addendum/universe-polymorphism:an-example-of-a-proof-using-cumulativity}}
\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Set} \PYG{k+kn}{Universe} \PYG{n}{Polymorphism}\PYG{o}{.}
\PYG{k+kn}{Set} \PYG{k+kn}{Polymorphic} \PYG{k+kn}{Inductive} \PYG{n}{Cumulativity}\PYG{o}{.}
\PYG{k+kn}{Inductive} \PYG{n}{eq}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i}\PYG{o}{\PYGZcb{}}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{x} \PYG{o}{:} \PYG{n}{A}\PYG{o}{)} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i}\PYG{o}{\PYGZcb{}} \PYG{o}{:=} \PYG{n}{eq\PYGZus{}refl} \PYG{o}{:} \PYG{n}{eq} \PYG{n}{x} \PYG{n}{x}\PYG{o}{.}
\PYG{k+kn}{Definition} \PYG{n}{funext\PYGZus{}type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{a} \PYG{n}{b} \PYG{n}{e}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{a}\PYG{o}{\PYGZcb{}}\PYG{o}{)} \PYG{o}{(}\PYG{n}{B} \PYG{o}{:} \PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{b}\PYG{o}{\PYGZcb{}}\PYG{o}{)}
\PYG{o}{:=} \PYG{k}{forall} \PYG{n}{f} \PYG{n}{g} \PYG{o}{:} \PYG{o}{(}\PYG{k}{forall} \PYG{n}{a}\PYG{o}{,} \PYG{n}{B} \PYG{n}{a}\PYG{o}{)}\PYG{o}{,}
                \PYG{o}{(}\PYG{k}{forall} \PYG{n}{x}\PYG{o}{,} \PYG{n}{eq}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{e}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{f} \PYG{n}{x}\PYG{o}{)} \PYG{o}{(}\PYG{n}{g} \PYG{n}{x}\PYG{o}{)}\PYG{o}{)}
                \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{n}{eq}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{e}\PYG{o}{\PYGZcb{}} \PYG{n}{f} \PYG{n}{g}\PYG{o}{.}
\PYG{k+kn}{Section} \PYG{n}{down}\PYG{o}{.}
\PYG{n}{Universes} \PYG{n}{a} \PYG{n}{b} \PYG{n}{e} \PYG{n}{e\PYGZsq{}}\PYG{o}{.}
\PYG{n}{Constraint} \PYG{n}{e\PYGZsq{}} \PYG{o}{\PYGZlt{}} \PYG{n}{e}\PYG{o}{.}
\PYG{k+kn}{Lemma} \PYG{n}{funext\PYGZus{}down} \PYG{o}{\PYGZob{}}\PYG{n}{A} \PYG{n}{B}\PYG{o}{\PYGZcb{}}
     \PYG{o}{(}\PYG{n}{H} \PYG{o}{:} \PYG{o}{@}\PYG{n}{funext\PYGZus{}type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{a} \PYG{n}{b} \PYG{n}{e}\PYG{o}{\PYGZcb{}} \PYG{n}{A} \PYG{n}{B}\PYG{o}{)} \PYG{o}{:} \PYG{o}{@}\PYG{n}{funext\PYGZus{}type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{a} \PYG{n}{b} \PYG{n}{e\PYGZsq{}}\PYG{o}{\PYGZcb{}} \PYG{n}{A} \PYG{n}{B}\PYG{o}{.}
\PYG{k+kn}{Proof}\PYG{o}{.}
\PYG{k+kp}{exact} \PYG{n}{H}\PYG{o}{.}
\PYG{k+kn}{Defined}\PYG{o}{.}
\PYG{k+kn}{End} \PYG{n}{down}\PYG{o}{.}
\end{sphinxVerbatim}


\subsection{Cumulativity Weak Constraints}
\label{\detokenize{addendum/universe-polymorphism:cumulativity-weak-constraints}}\index{Cumulativity Weak Constraints (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:flag.cumulativity-weak-constraints}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Cumulativity~Weak~Constraints}}}}
When set, which is the default, causes "weak" constraints to be produced
when comparing universes in an irrelevant position. Processing weak
constraints is delayed until minimization time. A weak constraint
between \sphinxtitleref{u} and \sphinxtitleref{v} when neither is smaller than the other and
one is flexible causes them to be unified. Otherwise the constraint is
silently discarded.

This heuristic is experimental and may change in future versions.
Disabling weak constraints is more predictable but may produce
arbitrary numbers of universes.

\end{fulllineitems}



\subsection{Global and local universes}
\label{\detokenize{addendum/universe-polymorphism:global-and-local-universes}}
Each universe is declared in a global or local environment before it
can be used. To ensure compatibility, every \sphinxstyleemphasis{global} universe is set
to be strictly greater than \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}} when it is introduced, while every
\sphinxstyleemphasis{local} (i.e. polymorphically quantified) universe is introduced as
greater or equal to \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}}.


\subsection{Conversion and unification}
\label{\detokenize{addendum/universe-polymorphism:conversion-and-unification}}
The semantics of conversion and unification have to be modified a
little to account for the new universe instance arguments to
polymorphic references. The semantics respect the fact that
definitions are transparent, so indistinguishable from their bodies
during conversion.

This is accomplished by changing one rule of unification, the first-
order approximation rule, which applies when two applicative terms
with the same head are compared. It tries to short-cut unfolding by
comparing the arguments directly. In case the constant is universe
polymorphic, we allow this rule to fire only when unifying the
universes results in instantiating a so-called flexible universe
variables (not given by the user). Similarly for conversion, if such
an equation of applicative terms fail due to a universe comparison not
being satisfied, the terms are unfolded. This change implies that
conversion and unification can have different unfolding behaviors on
the same development with universe polymorphism switched on or off.


\subsection{Minimization}
\label{\detokenize{addendum/universe-polymorphism:minimization}}
Universe polymorphism with cumulativity tends to generate many useless
inclusion constraints in general. Typically at each application of a
polymorphic constant \sphinxcode{\sphinxupquote{\DUrole{name}{f}}}, if an argument has expected type \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}\DUrole{operator}{@\{}\DUrole{name}{i}\DUrole{operator}{\}}}}
and is given a term of type \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}\DUrole{operator}{@\{}\DUrole{name}{j}\DUrole{operator}{\}}}}, a \(j ≤ i\) constraint will be
generated. It is however often the case that an equation \(j = i\) would
be more appropriate, when \sphinxcode{\sphinxupquote{\DUrole{name}{f}}}'s universes are fresh for example.
Consider the following example:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Definition} \PYG{n}{id0} \PYG{o}{:=} \PYG{o}{@}\PYG{n}{pidentity} \PYG{k+kt}{nat} \PYG{l+m+mi}{0}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{n}{id0}\PYG{o}{.}
    \PYG{n}{id0}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{o}{\PYGZcb{}} \PYG{o}{=} \PYG{n}{pidentity}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{k+kn}{Set}\PYG{o}{\PYGZcb{}} \PYG{l+m+mi}{0}
         \PYG{o}{:} \PYG{k+kt}{nat}
    
    \PYG{n}{id0} \PYG{k}{is} \PYG{n}{universe} \PYG{n}{polymorphic}
\end{sphinxVerbatim}

This definition is elaborated by minimizing the universe of \sphinxcode{\sphinxupquote{\DUrole{name}{id0}}} to
level \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}} while the more general definition would keep the fresh level
\sphinxcode{\sphinxupquote{\DUrole{name}{i}}} generated at the application of \sphinxcode{\sphinxupquote{\DUrole{name}{id}}} and a constraint that \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}} \(≤ i\).
This minimization process is applied only to fresh universe variables.
It simply adds an equation between the variable and its lower bound if
it is an atomic universe (i.e. not an algebraic max() universe).
\index{Universe Minimization ToSet (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:flag.universe-minimization-toset}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Universe~Minimization~ToSet}}}}
Turning this flag off (it is on by default) disallows minimization
to the sort \sphinxcode{\sphinxupquote{\DUrole{keyword,namespace}{Set}}} and only collapses floating universes between
themselves.

\end{fulllineitems}



\subsection{Explicit Universes}
\label{\detokenize{addendum/universe-polymorphism:explicit-universes}}
The syntax has been extended to allow users to explicitly bind names
to universes and explicitly instantiate polymorphic definitions.
\index{Universe (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:cmd.universe}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Universe~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
In the monorphic case, this command declares a new global universe
named \sphinxcode{\sphinxupquote{\DUrole{name}{ident}}}, which can be referred to using its qualified name
as well. Global universe names live in a separate namespace. The
command supports the polymorphic flag only in sections, meaning the
universe quantification will be discharged on each section definition
independently. One cannot mix polymorphic and monomorphic
declarations in the same section.

\end{fulllineitems}

\index{Constraint (cmd)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:cmd.constraint}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Command}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Constraint~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}~\DUrole{hole}{ord}~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}}}}}
This command declares a new constraint between named universes. The
order relation \sphinxcode{\sphinxupquote{\DUrole{notation}{\DUrole{hole}{ord}}}} can be one of \(<\), \(≤\) or \(=\). If consistent, the constraint
is then enforced in the global environment. Like \sphinxcode{\sphinxupquote{Universe}}, it can be
used with the \sphinxcode{\sphinxupquote{Polymorphic}} prefix in sections only to declare
constraints discharged at section closing time. One cannot declare a
global constraint on polymorphic universes.
\index{Undeclared universe ‘ident’ (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:exn.undeclared-universe-ident}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Undeclared~universe~{\hyperref[\detokenize{language/gallina-specification-language:grammar-token-ident}]{\sphinxcrossref{\DUrole{hole}{ident}}}}.}}}}
\end{fulllineitems}

\index{Universe inconsistency (err)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:exn.universe-inconsistency}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Error}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Universe~inconsistency.}}}}
\end{fulllineitems}


\end{fulllineitems}



\subsubsection{Polymorphic definitions}
\label{\detokenize{addendum/universe-polymorphism:polymorphic-definitions}}
For polymorphic definitions, the declaration of (all) universe levels
introduced by a definition uses the following syntax:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Polymorphic} \PYG{k+kn}{Definition} \PYG{n}{le}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i} \PYG{n}{j}\PYG{o}{\PYGZcb{}} \PYG{o}{(}\PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i}\PYG{o}{\PYGZcb{}}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{j}\PYG{o}{\PYGZcb{}} \PYG{o}{:=} \PYG{n}{A}\PYG{o}{.}
\end{sphinxVerbatim}

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Print} \PYG{n}{le}\PYG{o}{.}
    \PYG{n}{le}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i} \PYG{n}{j}\PYG{o}{\PYGZcb{}} \PYG{o}{=} 
    \PYG{k}{fun} \PYG{n}{A} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i}\PYG{o}{\PYGZcb{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{A}
         \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{i}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{j}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ i j \textbar{}= i \PYGZlt{}= j}
\PYG{c}{               }\PYG{c}{*)}
    
    \PYG{n}{le} \PYG{k}{is} \PYG{n}{universe} \PYG{n}{polymorphic}
    \PYG{n}{Argument} \PYG{n}{scope} \PYG{k}{is} \PYG{o}{[}\PYG{n}{type\PYGZus{}scope}\PYG{o}{]}
\end{sphinxVerbatim}

During refinement we find that \sphinxcode{\sphinxupquote{\DUrole{name}{j}}} must be larger or equal than \sphinxcode{\sphinxupquote{\DUrole{name}{i}}}, as we
are using \sphinxcode{\sphinxupquote{\DUrole{name}{A} \DUrole{operator}{:} \DUrole{keyword,type}{Type}\DUrole{operator}{@\{}\DUrole{name}{i}\DUrole{operator}{\}} \DUrole{operator}{\textless{}=} \DUrole{keyword,type}{Type}\DUrole{operator}{@\{}\DUrole{name}{j}\DUrole{operator}{\}}}}, hence the generated constraint. At the
end of a definition or proof, we check that the only remaining
universes are the ones declared. In the term and in general in proof
mode, introduced universe names can be referred to in terms. Note that
local universe names shadow global universe names. During a proof, one
can use {\hyperref[\detokenize{proof-engine/proof-handling:coq:cmdv.show-universes}]{\sphinxcrossref{\sphinxcode{\sphinxupquote{Show Universes}}}}} to display the current context of universes.

Definitions can also be instantiated explicitly, giving their full
instance:

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{pidentity}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{k+kn}{Set}\PYG{o}{\PYGZcb{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{pidentity}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{k+kn}{Set}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{o}{?}\PYG{n}{A} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{o}{?}\PYG{n}{A}
    \PYG{n}{where}
    \PYG{o}{?}\PYG{n}{A} \PYG{o}{:} \PYG{o}{[} \PYG{o}{\textbar{}}\PYG{o}{\PYGZhy{}} \PYG{k+kn}{Set}\PYG{o}{]}

\PYG{k+kn}{Monomorphic} \PYG{n}{Universes} \PYG{n}{k} \PYG{n}{l}\PYG{o}{.}
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{n}{le}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{k} \PYG{n}{l}\PYG{o}{\PYGZcb{}}\PYG{o}{)}\PYG{o}{.}
    \PYG{n}{le}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{k} \PYG{n}{l}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{k}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{l}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ \PYGZob{}\PYGZcb{} \textbar{}= k \PYGZlt{}= l}
\PYG{c}{              }\PYG{c}{*)}
\end{sphinxVerbatim}

User-named universes and the anonymous universe implicitly attached to
an explicit \sphinxcode{\sphinxupquote{\DUrole{keyword,type}{Type}}} are considered rigid for unification and are never
minimized. Flexible anonymous universes can be produced with an
underscore or by omitting the annotation to a polymorphic definition.

\fvset{hllines={, ,}}%
\begin{sphinxVerbatim}[commandchars=\\\{\}]
\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{.}
    \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{50}\PYG{o}{\PYGZcb{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{50}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{51}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{50}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{51}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ \PYGZob{}Top.51 Top.50\PYGZcb{} \textbar{}= Top.50 \PYGZlt{}= Top.51}
\PYG{c}{                           }\PYG{c}{*)}

\PYG{k+kn}{Check} \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{o}{\PYGZus{}}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{o}{(}\PYG{k}{fun} \PYG{n}{x} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{52}\PYG{o}{\PYGZcb{}} \PYG{o}{=\PYGZgt{}} \PYG{n}{x}\PYG{o}{)} \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{52}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{52}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{52}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{52}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ \PYGZob{}Top.52\PYGZcb{} \textbar{}=  }\PYG{c}{*)}

\PYG{k+kn}{Check} \PYG{n}{le}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{k} \PYG{o}{\PYGZus{}}\PYG{o}{\PYGZcb{}}\PYG{o}{.}
    \PYG{n}{le}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{k} \PYG{n}{k}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{k}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{k}\PYG{o}{\PYGZcb{}}

\PYG{k+kn}{Check} \PYG{n}{le}\PYG{o}{.}
    \PYG{n}{le}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{55} \PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{55}\PYG{o}{\PYGZcb{}}
         \PYG{o}{:} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{55}\PYG{o}{\PYGZcb{}} \PYG{o}{\PYGZhy{}\PYGZgt{}} \PYG{k+kt}{Type}\PYG{o}{@}\PYG{o}{\PYGZob{}}\PYG{n}{Top}\PYG{o}{.}\PYG{l+m+mi}{55}\PYG{o}{\PYGZcb{}}
    \PYG{c}{(*}\PYG{c}{ \PYGZob{}Top.55\PYGZcb{} \textbar{}=  }\PYG{c}{*)}
\end{sphinxVerbatim}
\index{Strict Universe Declaration (flag)}

\begin{fulllineitems}
\phantomsection\label{\detokenize{addendum/universe-polymorphism:coq:flag.strict-universe-declaration}}\pysigline{\sphinxbfcode{\sphinxupquote{\DUrole{sigannot}{Flag}}} \sphinxbfcode{\sphinxupquote{\DUrole{notation}{Strict~Universe~Declaration}}}}
Turning this option off allows one to freely use
identifiers for universes without declaring them first, with the
semantics that the first use declares it. In this mode, the universe
names are not associated with the definition or proof once it has been
defined. This is meant mainly for debugging purposes.

\end{fulllineitems}

\phantomsection\label{\detokenize{zebibliography:bibliography}}


\begin{sphinxthebibliography}{GimenezC}
\bibitem[Asp00]{zebibliography:asp00}
David Aspinall. Proof general: a generic tool for proof development. In Susanne Graf and Michael Schwartzbach, editors, \sphinxstyleemphasis{Tools and Algorithms for the Construction and Analysis of Systems, TACAS 2000}, volume 1785 of Lecture Notes in Computer Science, pages 38\textendash{}43. Springer Berlin Heidelberg, 2000. \sphinxhref{https://doi.org/10.1007/3-540-46419-0\_3}{doi:10.1007/3-540-46419-0\_3}%
\begin{footnote}[27]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1007/3-540-46419-0\_3}
%
\end{footnote}.
\bibitem[Bar81]{zebibliography:bar81}
H.P. Barendregt. \sphinxstyleemphasis{The Lambda Calculus its Syntax and Semantics}. North-Holland, 1981.
\bibitem[BDenesGregoire11]{zebibliography:fullreduction}
Mathieu Boespflug, Maxime Dénès, and Benjamin Grégoire. Full reduction at full throttle. In Jean-Pierre Jouannaud and Zhong Shao, editors, \sphinxstyleemphasis{Certified Programs and Proofs - First International Conference, CPP 2011, Kenting, Taiwan, December 7-9, 2011. Proceedings}, volume 7086 of Lecture Notes in Computer Science, 362\textendash{}377. Springer, 2011. URL: \sphinxurl{http://dx.doi.org/10.1007/978-3-642-25379-9\_26}, \sphinxhref{https://doi.org/10.1007/978-3-642-25379-9\_26}{doi:10.1007/978-3-642-25379-9\_26}%
\begin{footnote}[28]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1007/978-3-642-25379-9\_26}
%
\end{footnote}.
\bibitem[Bou97]{zebibliography:bou97}
S. Boutin. Using reflection to build efficient and certified decision procedure s. In Martin Abadi and Takahashi Ito, editors, \sphinxstyleemphasis{TACS'97}, volume 1281 of Lecture Notes in Computer Science. Springer-Verlag, 1997.
\bibitem[Coq85]{zebibliography:coq85}
Th. Coquand. \sphinxstyleemphasis{Une Théorie des Constructions}. PhD thesis, Université Paris\textasciitilde{}7, January 1985.
\bibitem[Coq86]{zebibliography:coq86}
Th. Coquand. An Analysis of Girard's Paradox. In \sphinxstyleemphasis{Symposium on Logic in Computer Science}. Cambridge, MA, 1986. IEEE Computer Society Press.
\bibitem[Coq92]{zebibliography:coq92}
Th. Coquand. Pattern Matching with Dependent Types. In \sphinxstyleemphasis{Proceedings of the 1992 Workshop on Types for Proofs and Programs}. 1992.
\bibitem[CT95]{zebibliography:dblp-conf-types-cornest95}
Cristina Cornes and Delphine Terrasse. Automating inversion of inductive predicates in coq. In \sphinxstyleemphasis{TYPES}, 85\textendash{}104. 1995.
\bibitem[CFC58]{zebibliography:cur58}
Haskell B. Curry, Robert Feys, and William Craig. \sphinxstyleemphasis{Combinatory Logic}. Volume 1. North-Holland, 1958. \S{}9E.
\bibitem[dB72]{zebibliography:bru72}
N.J. de Bruijn. Lambda-Calculus Notation with Nameless Dummies, a Tool for Automatic Formula Manipulation, with Application to the Church-Rosser Theorem. \sphinxstyleemphasis{Indag. Math.}, 1972.
\bibitem[Del00]{zebibliography:del00}
D. Delahaye. A Tactic Language for the System \textbackslash{}sf Coq. In \sphinxstyleemphasis{Proceedings of Logic for Programming and Automated Reasoning (LPAR), Reunion Island}, volume 1955 of Lecture Notes in Computer Science, 85\textendash{}95. Springer-Verlag, November 2000.
\bibitem[dC95]{zebibliography:rc95}
R. di Cosmo. \sphinxstyleemphasis{Isomorphisms of Types: from \(\lambda\)-calculus to information retrieval and language design}. Progress in Theoretical Computer Science. Birkhauser, 1995. ISBN-0-8176-3763-X.
\bibitem[Dyc92]{zebibliography:dyc92}
Roy Dyckhoff. Contraction-free sequent calculi for intuitionistic logic. \sphinxstyleemphasis{The Journal of Symbolic Logic}, September 1992.
\bibitem[Fou90]{zebibliography:fourier}
Jean-Baptiste-Joseph Fourier. \sphinxstyleemphasis{Fourier's method to solve linear inequations/equations systems.} Gauthier-Villars, 1890.
\bibitem[Gimenez94]{zebibliography:gim94}
E. Giménez. Codifying guarded definitions with recursive schemes. In \sphinxstyleemphasis{Types'94 : Types for Proofs and Programs}, volume 996 of Lecture Notes in Computer Science. Springer-Verlag, 1994. Extended version in LIP research report 95-07, ENS Lyon.
\bibitem[Gimenez95]{zebibliography:gimenez95b}
E. Giménez. An application of co-inductive types in coq: verification of the alternating bit protocol. In \sphinxstyleemphasis{Workshop on Types for Proofs and Programs}, number 1158 in Lecture Notes in Computer Science, 135\textendash{}152. Springer-Verlag, 1995.
\bibitem[Gimenez98]{zebibliography:gim98}
E. Giménez. A tutorial on recursive types in coq. Technical Report, INRIA, March 1998.
\bibitem[GimenezCasteran05]{zebibliography:gimcas05}
E. Giménez and P. Castéran. A tutorial on {[}co-{]}inductive types in coq. available at http://coq.inria.fr/doc, January 2005.
\bibitem[GMN+91]{zebibliography:sugar}
Alessandro Giovini, Teo Mora, Gianfranco Niesi, Lorenzo Robbiano, and Carlo Traverso. "one sugar cube, please" or selection strategies in the buchberger algorithm. In \sphinxstyleemphasis{Proceedings of the ISSAC'91, ACM Press}, 5\textendash{}4. 1991.
\bibitem[GLT89]{zebibliography:gir89}
J.-Y. Girard, Y. Lafont, and P. Taylor. \sphinxstyleemphasis{Proofs and Types}. Cambridge Tracts in Theoretical Computer Science 7. Cambridge University Press, 1989.
\bibitem[GZND11]{zebibliography:cslessadhoc}
Georges Gonthier, Beta Ziliani, Aleksandar Nanevski, and Derek Dreyer. How to make ad hoc proof automation less ad hoc. \sphinxstyleemphasis{SIGPLAN Not.}, 46(9):163\textendash{}175, September 2011. URL: \sphinxurl{http://doi.acm.org/10.1145/2034574.2034798}, \sphinxhref{https://doi.org/10.1145/2034574.2034798}{doi:10.1145/2034574.2034798}%
\begin{footnote}[29]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1145/2034574.2034798}
%
\end{footnote}.
\bibitem[GregoireL02]{zebibliography:compiledstrongreduction}
Benjamin Grégoire and Xavier Leroy. A compiled implementation of strong reduction. In Mitchell Wand and Simon L. Peyton Jones, editors, \sphinxstyleemphasis{Proceedings of the Seventh ACM SIGPLAN International Conference on Functional Programming (ICFP '02), Pittsburgh, Pennsylvania, USA, October 4-6, 2002.}, 235\textendash{}246. ACM, 2002. URL: \sphinxurl{http://doi.acm.org/10.1145/581478.581501}, \sphinxhref{https://doi.org/10.1145/581478.581501}{doi:10.1145/581478.581501}%
\begin{footnote}[30]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1145/581478.581501}
%
\end{footnote}.
\bibitem[How80]{zebibliography:how80}
W.A. Howard. The formulae-as-types notion of constructions. In J.P. Seldin and J.R. Hindley, editors, \sphinxstyleemphasis{to H.B. Curry : Essays on Combinatory Logic, Lambda Calculus and Formalism.} Academic Press, 1980.
\bibitem[Hue89]{zebibliography:hue88}
G. Huet. The Constructive Engine. In R. Narasimhan, editor, \sphinxstyleemphasis{A perspective in Theoretical Computer Science. Commemorative Volume for Gift Siromoney}. World Scientific Publishing, 1989.
\bibitem[LW11]{zebibliography:leewerner11}
Gyesik Lee and Benjamin Werner. Proof-irrelevant model of CC with predicative induction and judgmental equality. \sphinxstyleemphasis{Logical Methods in Computer Science}, 2011.
\bibitem[Ler90]{zebibliography:leroy90}
X. Leroy. The ZINC experiment: an economical implementation of the ML language. Technical Report 117, INRIA, 1990.
\bibitem[Let02]{zebibliography:let02}
P. Letouzey. A new extraction for coq. In \sphinxstyleemphasis{TYPES}. 2002. URL: \sphinxurl{http://www.irif.fr/~letouzey/download/extraction2002.pdf}.
\bibitem[LV97]{zebibliography:luttik97specificationof}
Sebastiaan P. Luttik and Eelco Visser. Specification of rewriting strategies. In \sphinxstyleemphasis{2nd International Workshop on the Theory and Practice of Algebraic Specifications (ASF+SDF'97), Electronic Workshops in Computing}. Springer-Verlag, 1997.
\bibitem[MT13]{zebibliography:cswcu}
Assia Mahboubi and Enrico Tassi. Canonical Structures for the working Coq user. In Sandrine Blazy, Christine Paulin, and David Pichardie, editors, \sphinxstyleemphasis{ITP 2013, 4th Conference on Interactive Theorem Proving}, volume 7998 of LNCS, 19\textendash{}34. Rennes, France, 2013. Springer. URL: \sphinxurl{http://hal.inria.fr/hal-00816703}, \sphinxhref{https://doi.org/10.1007/978-3-642-39634-2\_5}{doi:10.1007/978-3-642-39634-2\_5}%
\begin{footnote}[31]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.1007/978-3-642-39634-2\_5}
%
\end{footnote}.
\bibitem[McB00]{zebibliography:dblp-conf-types-mcbride00}
Conor McBride. Elimination with a motive. In \sphinxstyleemphasis{TYPES}, 197\textendash{}216. 2000.
\bibitem[Mun94]{zebibliography:mun94}
C. Muñoz. Démonstration automatique dans la logique propositionnelle intuitionniste. Master's thesis, DEA d'Informatique Fondamentale, Université Paris 7, September 1994.
\bibitem[Par95]{zebibliography:parent95b}
C. Parent. Synthesizing proofs from programs in the Calculus of Inductive Constructions. In \sphinxstyleemphasis{Mathematics of Program Construction'95}, volume 947 of LNCS. Springer-Verlag, 1995.
\bibitem[PM93]{zebibliography:moh93}
C. Paulin-Mohring. Inductive Definitions in the System Coq - Rules and Properties. In M. Bezem and J.-F. Groote, editors, \sphinxstyleemphasis{Proceedings of the conference Typed Lambda Calculi and Applications}, number 664 in LNCS. Springer-Verlag, 1993. Also LIP research report 92-49, ENS Lyon.
\bibitem[PCC16]{zebibliography:pit16}
Clément Pit-Claudel and Pierre Courtieu. Company-coq: taking proof general one step closer to a real ide. In \sphinxstyleemphasis{CoqPL'16: The Second International Workshop on Coq for PL}. January 2016. \sphinxhref{https://doi.org/10.5281/zenodo.44331}{doi:10.5281/zenodo.44331}%
\begin{footnote}[32]\sphinxAtStartFootnote
\sphinxnolinkurl{https://doi.org/10.5281/zenodo.44331}
%
\end{footnote}.
\bibitem[Pug92]{zebibliography:theomegapaper}
W. Pugh. The omega test: a fast and practical integer programming algorithm for dependence analysis. \sphinxstyleemphasis{Communication of the ACM}, pages 102\textendash{}114, 1992.
\bibitem[ROS98]{zebibliography:rushby98}
John Rushby, Sam Owre, and N. Shankar. Subtypes for specifications: predicate subtyping in PVS. \sphinxstyleemphasis{IEEE Transactions on Software Engineering}, 24(9):709\textendash{}720, September 1998.
\bibitem[Soz07]{zebibliography:sozeau06}
Matthieu Sozeau. Subset coercions in Coq. In \sphinxstyleemphasis{TYPES'06}, volume 4502 of LNCS, 237\textendash{}252. Springer, 2007.
\bibitem[SO08]{zebibliography:sozeau08}
Matthieu Sozeau and Nicolas Oury. First-Class Type Classes. In \sphinxstyleemphasis{TPHOLs'08}. 2008.
\bibitem[Wer94]{zebibliography:wer94}
B. Werner. \sphinxstyleemphasis{Une théorie des constructions inductives}. PhD thesis, Université Paris 7, 1994.
\end{sphinxthebibliography}


\renewcommand{\indexname}{Command Index}
\begin{sphinxtheindex}
\let\bigletter\sphinxstyleindexlettergroup
\bigletter{a}
\item\relax\sphinxstyleindexentry{Abort}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.abort}}
\item\relax\sphinxstyleindexentry{About}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.about}}
\item\relax\sphinxstyleindexentry{Add @table}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.add-table}}
\item\relax\sphinxstyleindexentry{Add Field}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:cmd.add-field}}
\item\relax\sphinxstyleindexentry{Add LoadPath}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.add-loadpath}}
\item\relax\sphinxstyleindexentry{Add ML Path}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.add-ml-path}}
\item\relax\sphinxstyleindexentry{Add Morphism}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:cmd.add-morphism}}
\item\relax\sphinxstyleindexentry{Add Parametric Morphism}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:cmd.add-parametric-morphism}}
\item\relax\sphinxstyleindexentry{Add Parametric Relation}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:cmd.add-parametric-relation}}
\item\relax\sphinxstyleindexentry{Add Rec LoadPath}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.add-rec-loadpath}}
\item\relax\sphinxstyleindexentry{Add Rec ML Path}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.add-rec-ml-path}}
\item\relax\sphinxstyleindexentry{Add Relation}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:cmd.add-relation}}
\item\relax\sphinxstyleindexentry{Add Ring}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:cmd.add-ring}}
\item\relax\sphinxstyleindexentry{Add Setoid}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:cmd.add-setoid}}
\item\relax\sphinxstyleindexentry{Admit Obligations}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.admit-obligations}}
\item\relax\sphinxstyleindexentry{Admitted}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.admitted}}
\item\relax\sphinxstyleindexentry{Arguments}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.arguments}}
\item\relax\sphinxstyleindexentry{Arguments (implicits)}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.arguments-implicits}}
\item\relax\sphinxstyleindexentry{Arguments (scopes)}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.arguments-scopes}}
\item\relax\sphinxstyleindexentry{Axiom}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.axiom}}
\item\relax\sphinxstyleindexentry{Axioms}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.axioms}}
\indexspace
\bigletter{b}
\item\relax\sphinxstyleindexentry{Back}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.back}}
\item\relax\sphinxstyleindexentry{BackTo}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.backto}}
\item\relax\sphinxstyleindexentry{Backtrack}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmdv.backtrack}}
\item\relax\sphinxstyleindexentry{Bind Scope}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.bind-scope}}
\indexspace
\bigletter{c}
\item\relax\sphinxstyleindexentry{Canonical Structure}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.canonical-structure}}
\item\relax\sphinxstyleindexentry{Cd}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.cd}}
\item\relax\sphinxstyleindexentry{Check}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.check}}
\item\relax\sphinxstyleindexentry{Class}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:cmd.class}}
\item\relax\sphinxstyleindexentry{Close Scope}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.close-scope}}
\item\relax\sphinxstyleindexentry{Coercion}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:cmd.coercion}}
\item\relax\sphinxstyleindexentry{CoFixpoint}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmd.cofixpoint}}
\item\relax\sphinxstyleindexentry{CoInductive}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmd.coinductive}}
\item\relax\sphinxstyleindexentry{Collection}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.collection}}
\item\relax\sphinxstyleindexentry{Combined Scheme}\sphinxstyleindexpageref{user-extensions/proof-schemes:\detokenize{coq:cmd.combined-scheme}}
\item\relax\sphinxstyleindexentry{Compute}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.compute}}
\item\relax\sphinxstyleindexentry{Conjecture}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.conjecture}}
\item\relax\sphinxstyleindexentry{Conjectures}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.conjectures}}
\item\relax\sphinxstyleindexentry{Constraint}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:cmd.constraint}}
\item\relax\sphinxstyleindexentry{Context}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:cmd.context}}
\item\relax\sphinxstyleindexentry{Corollary}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.corollary}}
\item\relax\sphinxstyleindexentry{Create HintDb}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmd.create-hintdb}}
\item\relax\sphinxstyleindexentry{Cumulative}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:cmd.cumulative}}
\indexspace
\bigletter{d}
\item\relax\sphinxstyleindexentry{Declare Implicit Tactic}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmd.declare-implicit-tactic}}
\item\relax\sphinxstyleindexentry{Declare Instance}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:cmdv.declare-instance}}
\item\relax\sphinxstyleindexentry{Declare Left Step}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmd.declare-left-step}}
\item\relax\sphinxstyleindexentry{Declare ML Module}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.declare-ml-module}}
\item\relax\sphinxstyleindexentry{Declare Module}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.declare-module}}
\item\relax\sphinxstyleindexentry{Declare Reduction}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.declare-reduction}}
\item\relax\sphinxstyleindexentry{Declare Right Step}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmd.declare-right-step}}
\item\relax\sphinxstyleindexentry{Defined}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmdv.defined}}
\item\relax\sphinxstyleindexentry{Definition}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmd.definition}}
\item\relax\sphinxstyleindexentry{Delimit Scope}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.delimit-scope}}
\item\relax\sphinxstyleindexentry{Derive}\sphinxstyleindexpageref{addendum/miscellaneous-extensions:\detokenize{coq:cmd.derive}}
\item\relax\sphinxstyleindexentry{Derive Inversion}\sphinxstyleindexpageref{user-extensions/proof-schemes:\detokenize{coq:cmd.derive-inversion}}
\item\relax\sphinxstyleindexentry{Drop}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.drop}}
\indexspace
\bigletter{e}
\item\relax\sphinxstyleindexentry{End}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.end}}
\item\relax\sphinxstyleindexentry{Eval}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.eval}}
\item\relax\sphinxstyleindexentry{Example}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.example}}
\item\relax\sphinxstyleindexentry{Existential}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.existential}}
\item\relax\sphinxstyleindexentry{Existing Class}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:cmd.existing-class}}
\item\relax\sphinxstyleindexentry{Existing Instance}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:cmd.existing-instance}}
\item\relax\sphinxstyleindexentry{Export}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmdv.export}}
\item\relax\sphinxstyleindexentry{Extract Constant}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.extract-constant}}
\item\relax\sphinxstyleindexentry{Extract Inductive}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.extract-inductive}}
\item\relax\sphinxstyleindexentry{Extract Inlined Constant}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.extract-inlined-constant}}
\item\relax\sphinxstyleindexentry{Extraction}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.extraction}}
\item\relax\sphinxstyleindexentry{Extraction Blacklist}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.extraction-blacklist}}
\item\relax\sphinxstyleindexentry{Extraction Implicit}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.extraction-implicit}}
\item\relax\sphinxstyleindexentry{Extraction Inline}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.extraction-inline}}
\item\relax\sphinxstyleindexentry{Extraction Language Haskell}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.extraction-language-haskell}}
\item\relax\sphinxstyleindexentry{Extraction Language OCaml}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.extraction-language-ocaml}}
\item\relax\sphinxstyleindexentry{Extraction Language Scheme}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.extraction-language-scheme}}
\item\relax\sphinxstyleindexentry{Extraction Library}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.extraction-library}}
\item\relax\sphinxstyleindexentry{Extraction NoInline}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.extraction-noinline}}
\item\relax\sphinxstyleindexentry{Extraction TestCompile}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.extraction-testcompile}}
\indexspace
\bigletter{f}
\item\relax\sphinxstyleindexentry{Fact}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.fact}}
\item\relax\sphinxstyleindexentry{Fail}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.fail}}
\item\relax\sphinxstyleindexentry{Fixpoint}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmd.fixpoint}}
\item\relax\sphinxstyleindexentry{Focus}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.focus}}
\item\relax\sphinxstyleindexentry{Function}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.function}}
\item\relax\sphinxstyleindexentry{Functional Scheme}\sphinxstyleindexpageref{user-extensions/proof-schemes:\detokenize{coq:cmd.functional-scheme}}
\indexspace
\bigletter{g}
\item\relax\sphinxstyleindexentry{Generalizable}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.generalizable}}
\item\relax\sphinxstyleindexentry{Generalizable All Variables}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.generalizable-all-variables}}
\item\relax\sphinxstyleindexentry{Generalizable No Variables}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.generalizable-no-variables}}
\item\relax\sphinxstyleindexentry{Global}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.global}}
\item\relax\sphinxstyleindexentry{Global Close Scope}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.global-close-scope}}
\item\relax\sphinxstyleindexentry{Global Generalizable}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.global-generalizable}}
\item\relax\sphinxstyleindexentry{Global Opaque}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmdv.global-opaque}}
\item\relax\sphinxstyleindexentry{Global Open Scope}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.global-open-scope}}
\item\relax\sphinxstyleindexentry{Global Transparent}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmdv.global-transparent}}
\item\relax\sphinxstyleindexentry{Goal}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.goal}}
\item\relax\sphinxstyleindexentry{Grab Existential Variables}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.grab-existential-variables}}
\item\relax\sphinxstyleindexentry{Guarded}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.guarded}}
\indexspace
\bigletter{h}
\item\relax\sphinxstyleindexentry{Hint}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmd.hint}}
\item\relax\sphinxstyleindexentry{Hint ( Transparent \textbar{} Opaque )}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmdv.hint-transparent-opaque}}
\item\relax\sphinxstyleindexentry{Hint Constructors}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmdv.hint-constructors}}
\item\relax\sphinxstyleindexentry{Hint Extern}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmdv.hint-extern}}
\item\relax\sphinxstyleindexentry{Hint Immediate}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmdv.hint-immediate}}
\item\relax\sphinxstyleindexentry{Hint Resolve}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmdv.hint-resolve}}
\item\relax\sphinxstyleindexentry{Hint Rewrite}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmd.hint-rewrite}}
\item\relax\sphinxstyleindexentry{Hint Unfold}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmdv.hint-unfold}}
\item\relax\sphinxstyleindexentry{Hint View for}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:cmd.hint-view-for}}
\item\relax\sphinxstyleindexentry{Hint View for apply}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:cmd.hint-view-for-apply}}
\item\relax\sphinxstyleindexentry{Hint View for move}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:cmd.hint-view-for-move}}
\item\relax\sphinxstyleindexentry{Hypotheses}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.hypotheses}}
\item\relax\sphinxstyleindexentry{Hypothesis}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.hypothesis}}
\indexspace
\bigletter{i}
\item\relax\sphinxstyleindexentry{Identity Coercion}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:cmd.identity-coercion}}
\item\relax\sphinxstyleindexentry{Implicit Types}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.implicit-types}}
\item\relax\sphinxstyleindexentry{Import}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.import}}
\item\relax\sphinxstyleindexentry{Include}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.include}}
\item\relax\sphinxstyleindexentry{Inductive}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmd.inductive}}
\item\relax\sphinxstyleindexentry{Infix}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.infix}}
\item\relax\sphinxstyleindexentry{Info}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:cmd.info}}
\item\relax\sphinxstyleindexentry{Inline}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.inline}}
\item\relax\sphinxstyleindexentry{Inspect}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmdv.inspect}}
\item\relax\sphinxstyleindexentry{Instance}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:cmd.instance}}
\indexspace
\bigletter{l}
\item\relax\sphinxstyleindexentry{Lemma}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.lemma}}
\item\relax\sphinxstyleindexentry{Let}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmd.let}}
\item\relax\sphinxstyleindexentry{Let CoFixpoint}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.let-cofixpoint}}
\item\relax\sphinxstyleindexentry{Let Fixpoint}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.let-fixpoint}}
\item\relax\sphinxstyleindexentry{Load}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.load}}
\item\relax\sphinxstyleindexentry{Local}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.local}}
\item\relax\sphinxstyleindexentry{Local Close Scope}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.local-close-scope}}
\item\relax\sphinxstyleindexentry{Local Definition}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.local-definition}}
\item\relax\sphinxstyleindexentry{Local Notation}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.local-notation}}
\item\relax\sphinxstyleindexentry{Local Open Scope}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.local-open-scope}}
\item\relax\sphinxstyleindexentry{Local Parameter}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.local-parameter}}
\item\relax\sphinxstyleindexentry{Locate}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.locate}}
\item\relax\sphinxstyleindexentry{Locate File}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.locate-file}}
\item\relax\sphinxstyleindexentry{Locate Library}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.locate-library}}
\item\relax\sphinxstyleindexentry{Ltac}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:cmd.ltac}}
\indexspace
\bigletter{m}
\item\relax\sphinxstyleindexentry{Module}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.module}}
\item\relax\sphinxstyleindexentry{Module Type}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.module-type}}
\item\relax\sphinxstyleindexentry{Monomorphic}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:cmd.monomorphic}}
\indexspace
\bigletter{n}
\item\relax\sphinxstyleindexentry{Next Obligation}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.next-obligation}}
\item\relax\sphinxstyleindexentry{NonCumulative}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:cmd.noncumulative}}
\item\relax\sphinxstyleindexentry{Notation}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.notation}}
\indexspace
\bigletter{o}
\item\relax\sphinxstyleindexentry{Obligation num}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.obligation-num}}
\item\relax\sphinxstyleindexentry{Obligation Tactic}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.obligation-tactic}}
\item\relax\sphinxstyleindexentry{Obligations}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.obligations}}
\item\relax\sphinxstyleindexentry{Opaque}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.opaque}}
\item\relax\sphinxstyleindexentry{Open Scope}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.open-scope}}
\item\relax\sphinxstyleindexentry{Optimize Heap}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.optimize-heap}}
\item\relax\sphinxstyleindexentry{Optimize Proof}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.optimize-proof}}
\indexspace
\bigletter{p}
\item\relax\sphinxstyleindexentry{Parameter}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmd.parameter}}
\item\relax\sphinxstyleindexentry{Parameters}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.parameters}}
\item\relax\sphinxstyleindexentry{Polymorphic}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:cmd.polymorphic}}
\item\relax\sphinxstyleindexentry{Prenex Implicits}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:cmd.prenex-implicits}}
\item\relax\sphinxstyleindexentry{Preterm}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.preterm}}
\item\relax\sphinxstyleindexentry{Print}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.print}}
\item\relax\sphinxstyleindexentry{Print All}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.print-all}}
\item\relax\sphinxstyleindexentry{Print All Dependencies}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmdv.print-all-dependencies}}
\item\relax\sphinxstyleindexentry{Print Assumptions}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.print-assumptions}}
\item\relax\sphinxstyleindexentry{Print Canonical Projections}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.print-canonical-projections}}
\item\relax\sphinxstyleindexentry{Print Classes}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:cmd.print-classes}}
\item\relax\sphinxstyleindexentry{Print Coercion Paths}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:cmd.print-coercion-paths}}
\item\relax\sphinxstyleindexentry{Print Coercions}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:cmd.print-coercions}}
\item\relax\sphinxstyleindexentry{Print Extraction Blacklist}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.print-extraction-blacklist}}
\item\relax\sphinxstyleindexentry{Print Extraction Inline}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.print-extraction-inline}}
\item\relax\sphinxstyleindexentry{Print Firstorder Solver}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmd.print-firstorder-solver}}
\item\relax\sphinxstyleindexentry{Print Grammar constr}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.print-grammar-constr}}
\item\relax\sphinxstyleindexentry{Print Grammar pattern}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.print-grammar-pattern}}
\item\relax\sphinxstyleindexentry{Print Grammar tactic}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.print-grammar-tactic}}
\item\relax\sphinxstyleindexentry{Print Graph}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:cmd.print-graph}}
\item\relax\sphinxstyleindexentry{Print Hint}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmd.print-hint}}
\item\relax\sphinxstyleindexentry{Print HintDb}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmd.print-hintdb}}
\item\relax\sphinxstyleindexentry{Print Implicit}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.print-implicit}}
\item\relax\sphinxstyleindexentry{Print Instances}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:cmd.print-instances}}
\item\relax\sphinxstyleindexentry{Print Libraries}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.print-libraries}}
\item\relax\sphinxstyleindexentry{Print LoadPath}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.print-loadpath}}
\item\relax\sphinxstyleindexentry{Print Ltac}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:cmd.print-ltac}}
\item\relax\sphinxstyleindexentry{Print Ltac Signatures}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:cmd.print-ltac-signatures}}
\item\relax\sphinxstyleindexentry{Print ML Modules}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.print-ml-modules}}
\item\relax\sphinxstyleindexentry{Print ML Path}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.print-ml-path}}
\item\relax\sphinxstyleindexentry{Print Module}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.print-module}}
\item\relax\sphinxstyleindexentry{Print Module Type}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.print-module-type}}
\item\relax\sphinxstyleindexentry{Print Opaque Dependencies}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmdv.print-opaque-dependencies}}
\item\relax\sphinxstyleindexentry{Print Options}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.print-options}}
\item\relax\sphinxstyleindexentry{Print Rewrite HintDb}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmd.print-rewrite-hintdb}}
\item\relax\sphinxstyleindexentry{Print Scope}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmdv.print-scope}}
\item\relax\sphinxstyleindexentry{Print Scopes}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.print-scopes}}
\item\relax\sphinxstyleindexentry{Print Strategy}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.print-strategy}}
\item\relax\sphinxstyleindexentry{Print Table @table}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.print-table-table}}
\item\relax\sphinxstyleindexentry{Print Tables}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.print-tables}}
\item\relax\sphinxstyleindexentry{Print Term}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmdv.print-term}}
\item\relax\sphinxstyleindexentry{Print Transparent Dependencies}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmdv.print-transparent-dependencies}}
\item\relax\sphinxstyleindexentry{Print Universes}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.print-universes}}
\item\relax\sphinxstyleindexentry{Print Visibility}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.print-visibility}}
\item\relax\sphinxstyleindexentry{Program Definition}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.program-definition}}
\item\relax\sphinxstyleindexentry{Program Fixpoint}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.program-fixpoint}}
\item\relax\sphinxstyleindexentry{Program Instance}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:cmdv.program-instance}}
\item\relax\sphinxstyleindexentry{Program Lemma}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.program-lemma}}
\item\relax\sphinxstyleindexentry{Proof}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.proof}}
\item\relax\sphinxstyleindexentry{Proof {}`term{}`}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.proof-term}}
\item\relax\sphinxstyleindexentry{Proof using}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.proof-using}}
\item\relax\sphinxstyleindexentry{Proof with}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmd.proof-with}}
\item\relax\sphinxstyleindexentry{Proposition}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.proposition}}
\item\relax\sphinxstyleindexentry{Pwd}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.pwd}}
\indexspace
\bigletter{q}
\item\relax\sphinxstyleindexentry{Qed}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.qed}}
\item\relax\sphinxstyleindexentry{Quit}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.quit}}
\indexspace
\bigletter{r}
\item\relax\sphinxstyleindexentry{Record}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.record}}
\item\relax\sphinxstyleindexentry{Recursive Extraction}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.recursive-extraction}}
\item\relax\sphinxstyleindexentry{Recursive Extraction Library}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.recursive-extraction-library}}
\item\relax\sphinxstyleindexentry{Redirect}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.redirect}}
\item\relax\sphinxstyleindexentry{Remark}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.remark}}
\item\relax\sphinxstyleindexentry{Remove @table}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.remove-table}}
\item\relax\sphinxstyleindexentry{Remove Hints}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmd.remove-hints}}
\item\relax\sphinxstyleindexentry{Remove LoadPath}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.remove-loadpath}}
\item\relax\sphinxstyleindexentry{Require}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.require}}
\item\relax\sphinxstyleindexentry{Require Export}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmdv.require-export}}
\item\relax\sphinxstyleindexentry{Require Import}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmdv.require-import}}
\item\relax\sphinxstyleindexentry{Reset}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.reset}}
\item\relax\sphinxstyleindexentry{Reset Extraction Blacklist}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.reset-extraction-blacklist}}
\item\relax\sphinxstyleindexentry{Reset Extraction Inline}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.reset-extraction-inline}}
\item\relax\sphinxstyleindexentry{Reset Ltac Profile}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:cmd.reset-ltac-profile}}
\item\relax\sphinxstyleindexentry{Restart}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmdv.restart}}
\indexspace
\bigletter{s}
\item\relax\sphinxstyleindexentry{Save}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmdv.save}}
\item\relax\sphinxstyleindexentry{Scheme}\sphinxstyleindexpageref{user-extensions/proof-schemes:\detokenize{coq:cmd.scheme}}
\item\relax\sphinxstyleindexentry{Scheme Equality}\sphinxstyleindexpageref{user-extensions/proof-schemes:\detokenize{coq:cmdv.scheme-equality}}
\item\relax\sphinxstyleindexentry{Search}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.search}}
\item\relax\sphinxstyleindexentry{Search (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:cmd.search-ssreflect}}
\item\relax\sphinxstyleindexentry{SearchAbout}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmdv.searchabout}}
\item\relax\sphinxstyleindexentry{SearchHead}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.searchhead}}
\item\relax\sphinxstyleindexentry{SearchPattern}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.searchpattern}}
\item\relax\sphinxstyleindexentry{SearchRewrite}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.searchrewrite}}
\item\relax\sphinxstyleindexentry{Section}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:cmd.section}}
\item\relax\sphinxstyleindexentry{Separate Extraction}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:cmd.separate-extraction}}
\item\relax\sphinxstyleindexentry{Set}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.set}}
\item\relax\sphinxstyleindexentry{Set @option}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.set-option}}
\item\relax\sphinxstyleindexentry{Show}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.show}}
\item\relax\sphinxstyleindexentry{Show Conjectures}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmdv.show-conjectures}}
\item\relax\sphinxstyleindexentry{Show Existentials}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmdv.show-existentials}}
\item\relax\sphinxstyleindexentry{Show Intro}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmdv.show-intro}}
\item\relax\sphinxstyleindexentry{Show Intros}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmdv.show-intros}}
\item\relax\sphinxstyleindexentry{Show Ltac Profile}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:cmd.show-ltac-profile}}
\item\relax\sphinxstyleindexentry{Show Obligation Tactic}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.show-obligation-tactic}}
\item\relax\sphinxstyleindexentry{Show Proof}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmdv.show-proof}}
\item\relax\sphinxstyleindexentry{Show Script}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmdv.show-script}}
\item\relax\sphinxstyleindexentry{Show Universes}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmdv.show-universes}}
\item\relax\sphinxstyleindexentry{Solve All Obligations}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.solve-all-obligations}}
\item\relax\sphinxstyleindexentry{Solve Obligations}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:cmd.solve-obligations}}
\item\relax\sphinxstyleindexentry{Strategy}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.strategy}}
\item\relax\sphinxstyleindexentry{Structure}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:cmdv.structure}}
\indexspace
\bigletter{t}
\item\relax\sphinxstyleindexentry{Tactic Notation}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.tactic-notation}}
\item\relax\sphinxstyleindexentry{Test}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.test}}
\item\relax\sphinxstyleindexentry{Test @table for}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.test-table-for}}
\item\relax\sphinxstyleindexentry{Theorem}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmd.theorem}}
\item\relax\sphinxstyleindexentry{Time}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.time}}
\item\relax\sphinxstyleindexentry{Timeout}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.timeout}}
\item\relax\sphinxstyleindexentry{Transparent}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.transparent}}
\item\relax\sphinxstyleindexentry{Typeclasses eauto}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:cmd.typeclasses-eauto}}
\item\relax\sphinxstyleindexentry{Typeclasses Opaque}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:cmd.typeclasses-opaque}}
\item\relax\sphinxstyleindexentry{Typeclasses Transparent}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:cmd.typeclasses-transparent}}
\indexspace
\bigletter{u}
\item\relax\sphinxstyleindexentry{Undelimit Scope}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:cmd.undelimit-scope}}
\item\relax\sphinxstyleindexentry{Undo}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.undo}}
\item\relax\sphinxstyleindexentry{Unfocus}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.unfocus}}
\item\relax\sphinxstyleindexentry{Unfocused}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:cmd.unfocused}}
\item\relax\sphinxstyleindexentry{Universe}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:cmd.universe}}
\item\relax\sphinxstyleindexentry{Unset}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.unset}}
\item\relax\sphinxstyleindexentry{Unset @option}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:cmd.unset-option}}
\item\relax\sphinxstyleindexentry{Unshelve}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:cmd.unshelve}}
\indexspace
\bigletter{v}
\item\relax\sphinxstyleindexentry{Variable}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmd.variable}}
\item\relax\sphinxstyleindexentry{Variables}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmdv.variables}}
\item\relax\sphinxstyleindexentry{Variant}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:cmd.variant}}
\end{sphinxtheindex}
\renewcommand{\indexname}{Tactic Index}
\begin{sphinxtheindex}
\let\bigletter\sphinxstyleindexlettergroup
\bigletter{+}
\item\relax\sphinxstyleindexentry{+ (backtracking branching)}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.backtracking-branching}}
\indexspace
\bigletter{.}
\item\relax\sphinxstyleindexentry{... : ... (goal selector)}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.goal-selector}}
\item\relax\sphinxstyleindexentry{... : ... (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.ssreflect}}
\indexspace
\bigletter{=}
\item\relax\sphinxstyleindexentry{=\textgreater{}}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.}}
\indexspace
\bigletter{{[}}
\item\relax\sphinxstyleindexentry{{[}\textgreater{} ... \textbar{} ... \textbar{} ... {]} (dispatch)}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.dispatch}}
\indexspace
\bigletter{\_}
\item\relax\sphinxstyleindexentry{\_}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.}}
\indexspace
\bigletter{a}
\item\relax\sphinxstyleindexentry{abstract}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.abstract}}
\item\relax\sphinxstyleindexentry{abstract (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.abstract-ssreflect}}
\item\relax\sphinxstyleindexentry{absurd}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.absurd}}
\item\relax\sphinxstyleindexentry{admit}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.admit}}
\item\relax\sphinxstyleindexentry{all: ...}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacv.all}}
\item\relax\sphinxstyleindexentry{apply}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.apply}}
\item\relax\sphinxstyleindexentry{apply (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.apply-ssreflect}}
\item\relax\sphinxstyleindexentry{apply ... in}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.apply-in}}
\item\relax\sphinxstyleindexentry{apply ... in ... as}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.apply-in-as}}
\item\relax\sphinxstyleindexentry{assert}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.assert}}
\item\relax\sphinxstyleindexentry{assert\_fails}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.assert-fails}}
\item\relax\sphinxstyleindexentry{assert\_succeeds}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.assert-succeeds}}
\item\relax\sphinxstyleindexentry{assumption}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.assumption}}
\item\relax\sphinxstyleindexentry{auto}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.auto}}
\item\relax\sphinxstyleindexentry{autoapply}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:tacn.autoapply}}
\item\relax\sphinxstyleindexentry{autorewrite}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.autorewrite}}
\item\relax\sphinxstyleindexentry{autounfold}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.autounfold}}
\indexspace
\bigletter{b}
\item\relax\sphinxstyleindexentry{btauto}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.btauto}}
\item\relax\sphinxstyleindexentry{by}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.by}}
\indexspace
\bigletter{c}
\item\relax\sphinxstyleindexentry{case}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.case}}
\item\relax\sphinxstyleindexentry{case (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacv.case-ssreflect}}
\item\relax\sphinxstyleindexentry{cbn}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.cbn}}
\item\relax\sphinxstyleindexentry{cbv}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.cbv}}
\item\relax\sphinxstyleindexentry{change}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.change}}
\item\relax\sphinxstyleindexentry{classical\_left}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.classical-left}}
\item\relax\sphinxstyleindexentry{classical\_right}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.classical-right}}
\item\relax\sphinxstyleindexentry{clear}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.clear}}
\item\relax\sphinxstyleindexentry{clearbody}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.clearbody}}
\item\relax\sphinxstyleindexentry{cofix}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.cofix}}
\item\relax\sphinxstyleindexentry{compare}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.compare}}
\item\relax\sphinxstyleindexentry{compute}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.compute}}
\item\relax\sphinxstyleindexentry{congr}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.congr}}
\item\relax\sphinxstyleindexentry{congruence}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.congruence}}
\item\relax\sphinxstyleindexentry{congruence with}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.congruence-with}}
\item\relax\sphinxstyleindexentry{constr\_eq}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.constr-eq}}
\item\relax\sphinxstyleindexentry{constructor}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.constructor}}
\item\relax\sphinxstyleindexentry{contradict}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.contradict}}
\item\relax\sphinxstyleindexentry{contradiction}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.contradiction}}
\item\relax\sphinxstyleindexentry{cut}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.cut}}
\item\relax\sphinxstyleindexentry{cutrewrite}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.cutrewrite}}
\item\relax\sphinxstyleindexentry{cycle}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.cycle}}
\indexspace
\bigletter{d}
\item\relax\sphinxstyleindexentry{debug auto}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.debug-auto}}
\item\relax\sphinxstyleindexentry{debug trivial}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.debug-trivial}}
\item\relax\sphinxstyleindexentry{decide equality}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.decide-equality}}
\item\relax\sphinxstyleindexentry{decompose}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.decompose}}
\item\relax\sphinxstyleindexentry{dependent destruction}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.dependent-destruction}}
\item\relax\sphinxstyleindexentry{dependent induction}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.dependent-induction}}
\item\relax\sphinxstyleindexentry{dependent inversion}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.dependent-inversion}}
\item\relax\sphinxstyleindexentry{dependent inversion ... with ...}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.dependent-inversion-with}}
\item\relax\sphinxstyleindexentry{dependent rewrite -\textgreater{}}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.dependent-rewrite}}
\item\relax\sphinxstyleindexentry{dependent rewrite \textless{}-}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.dependent-rewrite}}
\item\relax\sphinxstyleindexentry{destruct}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.destruct}}
\item\relax\sphinxstyleindexentry{destruct ... eqn:}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.destruct-eqn}}
\item\relax\sphinxstyleindexentry{dintuition}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.dintuition}}
\item\relax\sphinxstyleindexentry{discriminate}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.discriminate}}
\item\relax\sphinxstyleindexentry{discrR}\sphinxstyleindexpageref{language/coq-library:\detokenize{coq:tacn.discrr}}
\item\relax\sphinxstyleindexentry{do}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.do}}
\item\relax\sphinxstyleindexentry{do (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.do-ssreflect}}
\item\relax\sphinxstyleindexentry{done}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.done}}
\item\relax\sphinxstyleindexentry{double induction}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.double-induction}}
\item\relax\sphinxstyleindexentry{dtauto}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.dtauto}}
\indexspace
\bigletter{e}
\item\relax\sphinxstyleindexentry{eapply}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.eapply}}
\item\relax\sphinxstyleindexentry{eassert}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.eassert}}
\item\relax\sphinxstyleindexentry{eassumption}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.eassumption}}
\item\relax\sphinxstyleindexentry{easy}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.easy}}
\item\relax\sphinxstyleindexentry{eauto}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.eauto}}
\item\relax\sphinxstyleindexentry{ecase}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.ecase}}
\item\relax\sphinxstyleindexentry{econstructor}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.econstructor}}
\item\relax\sphinxstyleindexentry{edestruct}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.edestruct}}
\item\relax\sphinxstyleindexentry{ediscriminate}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.ediscriminate}}
\item\relax\sphinxstyleindexentry{eelim}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.eelim}}
\item\relax\sphinxstyleindexentry{eenough}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.eenough}}
\item\relax\sphinxstyleindexentry{eexact}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.eexact}}
\item\relax\sphinxstyleindexentry{eexists}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.eexists}}
\item\relax\sphinxstyleindexentry{einduction}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.einduction}}
\item\relax\sphinxstyleindexentry{einjection}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.einjection}}
\item\relax\sphinxstyleindexentry{eleft}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.eleft}}
\item\relax\sphinxstyleindexentry{elim}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.elim}}
\item\relax\sphinxstyleindexentry{elim (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.elim-ssreflect}}
\item\relax\sphinxstyleindexentry{elim ... with}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.elim-with}}
\item\relax\sphinxstyleindexentry{elimtype}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.elimtype}}
\item\relax\sphinxstyleindexentry{enough}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.enough}}
\item\relax\sphinxstyleindexentry{epose}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.epose}}
\item\relax\sphinxstyleindexentry{eremember}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.eremember}}
\item\relax\sphinxstyleindexentry{erewrite}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.erewrite}}
\item\relax\sphinxstyleindexentry{eright}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.eright}}
\item\relax\sphinxstyleindexentry{eset}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.eset}}
\item\relax\sphinxstyleindexentry{esimplify\_eq}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.esimplify-eq}}
\item\relax\sphinxstyleindexentry{esplit}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.esplit}}
\item\relax\sphinxstyleindexentry{evar}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.evar}}
\item\relax\sphinxstyleindexentry{exact}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.exact}}
\item\relax\sphinxstyleindexentry{exactly\_once}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.exactly-once}}
\item\relax\sphinxstyleindexentry{exfalso}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.exfalso}}
\item\relax\sphinxstyleindexentry{exists}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.exists}}
\indexspace
\bigletter{f}
\item\relax\sphinxstyleindexentry{f\_equal}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.f-equal}}
\item\relax\sphinxstyleindexentry{fail}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.fail}}
\item\relax\sphinxstyleindexentry{field}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.field}}
\item\relax\sphinxstyleindexentry{field\_simplify}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.field-simplify}}
\item\relax\sphinxstyleindexentry{field\_simplify\_eq}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.field-simplify-eq}}
\item\relax\sphinxstyleindexentry{finish\_timing}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.finish-timing}}
\item\relax\sphinxstyleindexentry{first}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.first}}
\item\relax\sphinxstyleindexentry{first (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.first-ssreflect}}
\item\relax\sphinxstyleindexentry{first last}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.first-last}}
\item\relax\sphinxstyleindexentry{firstorder}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.firstorder}}
\item\relax\sphinxstyleindexentry{fix}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.fix}}
\item\relax\sphinxstyleindexentry{fold}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.fold}}
\item\relax\sphinxstyleindexentry{fourier}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.fourier}}
\item\relax\sphinxstyleindexentry{function induction}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.function-induction}}
\item\relax\sphinxstyleindexentry{functional inversion}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.functional-inversion}}
\indexspace
\bigletter{g}
\item\relax\sphinxstyleindexentry{generalize}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.generalize}}
\item\relax\sphinxstyleindexentry{generally have}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacv.generally-have}}
\item\relax\sphinxstyleindexentry{gfail}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacv.gfail}}
\item\relax\sphinxstyleindexentry{give\_up}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.give-up}}
\item\relax\sphinxstyleindexentry{guard}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.guard}}
\indexspace
\bigletter{h}
\item\relax\sphinxstyleindexentry{has\_evar}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.has-evar}}
\item\relax\sphinxstyleindexentry{have}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.have}}
\item\relax\sphinxstyleindexentry{hnf}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.hnf}}
\indexspace
\bigletter{i}
\item\relax\sphinxstyleindexentry{idtac}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.idtac}}
\item\relax\sphinxstyleindexentry{in}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.in}}
\item\relax\sphinxstyleindexentry{induction}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.induction}}
\item\relax\sphinxstyleindexentry{induction ... using ...}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.induction-using}}
\item\relax\sphinxstyleindexentry{info\_trivial}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.info-trivial}}
\item\relax\sphinxstyleindexentry{injection}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.injection}}
\item\relax\sphinxstyleindexentry{instantiate}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.instantiate}}
\item\relax\sphinxstyleindexentry{intro}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.intro}}
\item\relax\sphinxstyleindexentry{intros}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.intros}}
\item\relax\sphinxstyleindexentry{intros ...}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.intros}}
\item\relax\sphinxstyleindexentry{intuition}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.intuition}}
\item\relax\sphinxstyleindexentry{inversion}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.inversion}}
\item\relax\sphinxstyleindexentry{is\_evar}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.is-evar}}
\item\relax\sphinxstyleindexentry{is\_var}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.is-var}}
\indexspace
\bigletter{l}
\item\relax\sphinxstyleindexentry{lapply}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.lapply}}
\item\relax\sphinxstyleindexentry{last}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.last}}
\item\relax\sphinxstyleindexentry{last first}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.last-first}}
\item\relax\sphinxstyleindexentry{lazy}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.lazy}}
\item\relax\sphinxstyleindexentry{left}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.left}}
\item\relax\sphinxstyleindexentry{let ... := ...}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.let}}
\item\relax\sphinxstyleindexentry{lia}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:tacn.lia}}
\item\relax\sphinxstyleindexentry{lra}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:tacn.lra}}
\item\relax\sphinxstyleindexentry{ltac-seq}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.ltac-seq}}
\indexspace
\bigletter{m}
\item\relax\sphinxstyleindexentry{match goal}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.match-goal}}
\item\relax\sphinxstyleindexentry{move}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.move}}
\item\relax\sphinxstyleindexentry{move ... after ...}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.move-after}}
\item\relax\sphinxstyleindexentry{move ... at bottom}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.move-at-bottom}}
\item\relax\sphinxstyleindexentry{move ... at top}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.move-at-top}}
\item\relax\sphinxstyleindexentry{move ... before ...}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.move-before}}
\indexspace
\bigletter{n}
\item\relax\sphinxstyleindexentry{native\_compute}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.native-compute}}
\item\relax\sphinxstyleindexentry{nia}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:tacn.nia}}
\item\relax\sphinxstyleindexentry{notypeclasses refine}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.notypeclasses-refine}}
\item\relax\sphinxstyleindexentry{now}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.now}}
\item\relax\sphinxstyleindexentry{nra}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:tacn.nra}}
\item\relax\sphinxstyleindexentry{nsatz}\sphinxstyleindexpageref{addendum/nsatz:\detokenize{coq:tacn.nsatz}}
\indexspace
\bigletter{o}
\item\relax\sphinxstyleindexentry{omega}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.omega}}
\item\relax\sphinxstyleindexentry{once}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.once}}
\item\relax\sphinxstyleindexentry{only ... : ...}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacv.only}}
\item\relax\sphinxstyleindexentry{optimize\_heap}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.optimize-heap}}
\indexspace
\bigletter{p}
\item\relax\sphinxstyleindexentry{par: ...}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacv.par}}
\item\relax\sphinxstyleindexentry{pattern}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.pattern}}
\item\relax\sphinxstyleindexentry{pose}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.pose}}
\item\relax\sphinxstyleindexentry{pose (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.pose-ssreflect}}
\item\relax\sphinxstyleindexentry{pose proof}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.pose-proof}}
\item\relax\sphinxstyleindexentry{progress}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.progress}}
\item\relax\sphinxstyleindexentry{psatz}\sphinxstyleindexpageref{addendum/micromega:\detokenize{coq:tacn.psatz}}
\indexspace
\bigletter{q}
\item\relax\sphinxstyleindexentry{quote}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.quote}}
\indexspace
\bigletter{r}
\item\relax\sphinxstyleindexentry{red}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.red}}
\item\relax\sphinxstyleindexentry{refine}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.refine}}
\item\relax\sphinxstyleindexentry{reflexivity}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.reflexivity}}
\item\relax\sphinxstyleindexentry{remember}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.remember}}
\item\relax\sphinxstyleindexentry{rename}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.rename}}
\item\relax\sphinxstyleindexentry{repeat}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.repeat}}
\item\relax\sphinxstyleindexentry{replace}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.replace}}
\item\relax\sphinxstyleindexentry{reset ltac profile}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.reset-ltac-profile}}
\item\relax\sphinxstyleindexentry{restart\_timer}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.restart-timer}}
\item\relax\sphinxstyleindexentry{revert}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.revert}}
\item\relax\sphinxstyleindexentry{revert dependent}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.revert-dependent}}
\item\relax\sphinxstyleindexentry{revgoals}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.revgoals}}
\item\relax\sphinxstyleindexentry{rewrite}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.rewrite}}
\item\relax\sphinxstyleindexentry{rewrite (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.rewrite-ssreflect}}
\item\relax\sphinxstyleindexentry{rewrite\_strat}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:tacn.rewrite-strat}}
\item\relax\sphinxstyleindexentry{right}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.right}}
\item\relax\sphinxstyleindexentry{ring}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.ring}}
\item\relax\sphinxstyleindexentry{ring\_simplify}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.ring-simplify}}
\item\relax\sphinxstyleindexentry{romega}\sphinxstyleindexpageref{addendum/omega:\detokenize{coq:tacv.romega}}
\item\relax\sphinxstyleindexentry{rtauto}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.rtauto}}
\indexspace
\bigletter{s}
\item\relax\sphinxstyleindexentry{set}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.set}}
\item\relax\sphinxstyleindexentry{set (ssreflect)}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.set-ssreflect}}
\item\relax\sphinxstyleindexentry{setoid\_reflexivity}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:tacv.setoid-reflexivity}}
\item\relax\sphinxstyleindexentry{setoid\_replace}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:tacv.setoid-replace}}
\item\relax\sphinxstyleindexentry{setoid\_rewrite}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:tacv.setoid-rewrite}}
\item\relax\sphinxstyleindexentry{setoid\_symmetry}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:tacv.setoid-symmetry}}
\item\relax\sphinxstyleindexentry{setoid\_transitivity}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:tacv.setoid-transitivity}}
\item\relax\sphinxstyleindexentry{shelve}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.shelve}}
\item\relax\sphinxstyleindexentry{shelve\_unifiable}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.shelve-unifiable}}
\item\relax\sphinxstyleindexentry{show ltac profile}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.show-ltac-profile}}
\item\relax\sphinxstyleindexentry{simpl}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.simpl}}
\item\relax\sphinxstyleindexentry{simple apply}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.simple-apply}}
\item\relax\sphinxstyleindexentry{simple destruct}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.simple-destruct}}
\item\relax\sphinxstyleindexentry{simple eapply}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.simple-eapply}}
\item\relax\sphinxstyleindexentry{simple induction}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.simple-induction}}
\item\relax\sphinxstyleindexentry{simple inversion}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.simple-inversion}}
\item\relax\sphinxstyleindexentry{simple notypeclasses refine}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.simple-notypeclasses-refine}}
\item\relax\sphinxstyleindexentry{simple refine}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.simple-refine}}
\item\relax\sphinxstyleindexentry{simplify\_eq}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.simplify-eq}}
\item\relax\sphinxstyleindexentry{solve}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.solve}}
\item\relax\sphinxstyleindexentry{specialize}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.specialize}}
\item\relax\sphinxstyleindexentry{split}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.split}}
\item\relax\sphinxstyleindexentry{split\_Rabs}\sphinxstyleindexpageref{language/coq-library:\detokenize{coq:tacn.split-rabs}}
\item\relax\sphinxstyleindexentry{split\_Rmult}\sphinxstyleindexpageref{language/coq-library:\detokenize{coq:tacn.split-rmult}}
\item\relax\sphinxstyleindexentry{start ltac profiling}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.start-ltac-profiling}}
\item\relax\sphinxstyleindexentry{stepl}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.stepl}}
\item\relax\sphinxstyleindexentry{stepr}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.stepr}}
\item\relax\sphinxstyleindexentry{stop ltac profiling}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.stop-ltac-profiling}}
\item\relax\sphinxstyleindexentry{subst}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.subst}}
\item\relax\sphinxstyleindexentry{suff}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.suff}}
\item\relax\sphinxstyleindexentry{suffices}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacv.suffices}}
\item\relax\sphinxstyleindexentry{swap}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.swap}}
\item\relax\sphinxstyleindexentry{symmetry}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.symmetry}}
\indexspace
\bigletter{t}
\item\relax\sphinxstyleindexentry{tauto}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.tauto}}
\item\relax\sphinxstyleindexentry{time}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.time}}
\item\relax\sphinxstyleindexentry{time\_constr}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.time-constr}}
\item\relax\sphinxstyleindexentry{timeout}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.timeout}}
\item\relax\sphinxstyleindexentry{transitivity}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.transitivity}}
\item\relax\sphinxstyleindexentry{transparent\_abstract}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacv.transparent-abstract}}
\item\relax\sphinxstyleindexentry{trivial}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.trivial}}
\item\relax\sphinxstyleindexentry{try}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.try}}
\item\relax\sphinxstyleindexentry{tryif}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.tryif}}
\item\relax\sphinxstyleindexentry{typeclasses eauto}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:tacn.typeclasses-eauto}}
\indexspace
\bigletter{u}
\item\relax\sphinxstyleindexentry{unfold}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.unfold}}
\item\relax\sphinxstyleindexentry{unify}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacn.unify}}
\item\relax\sphinxstyleindexentry{unlock}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.unlock}}
\indexspace
\bigletter{v}
\item\relax\sphinxstyleindexentry{vm\_compute}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:tacv.vm-compute}}
\indexspace
\bigletter{w}
\item\relax\sphinxstyleindexentry{without loss}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacv.without-loss}}
\item\relax\sphinxstyleindexentry{wlog}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:tacn.wlog}}
\indexspace
\bigletter{\textbar{}}
\item\relax\sphinxstyleindexentry{\textbar{}\textbar{} (left-biased branching)}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:tacn.left-biased-branching}}
\end{sphinxtheindex}
\renewcommand{\indexname}{Flags, options and Tables Index}
\begin{sphinxtheindex}
\let\bigletter\sphinxstyleindexlettergroup
\bigletter{a}
\item\relax\sphinxstyleindexentry{Asymmetric Patterns}\sphinxstyleindexpageref{addendum/extended-pattern-matching:\detokenize{coq:flag.asymmetric-patterns}}
\item\relax\sphinxstyleindexentry{Automatic Coercions Import}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:flag.automatic-coercions-import}}
\item\relax\sphinxstyleindexentry{Automatic Introduction}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:flag.automatic-introduction}}
\indexspace
\bigletter{b}
\item\relax\sphinxstyleindexentry{Boolean Equality Schemes}\sphinxstyleindexpageref{user-extensions/proof-schemes:\detokenize{coq:flag.boolean-equality-schemes}}
\item\relax\sphinxstyleindexentry{Bracketing Last Introduction Pattern}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.bracketing-last-introduction-pattern}}
\item\relax\sphinxstyleindexentry{Bullet Behavior}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:opt.bullet-behavior}}
\indexspace
\bigletter{c}
\item\relax\sphinxstyleindexentry{Case Analysis Schemes}\sphinxstyleindexpageref{user-extensions/proof-schemes:\detokenize{coq:flag.case-analysis-schemes}}
\item\relax\sphinxstyleindexentry{Congruence Verbose}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.congruence-verbose}}
\item\relax\sphinxstyleindexentry{Contextual Implicit}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.contextual-implicit}}
\item\relax\sphinxstyleindexentry{Cumulativity Weak Constraints}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:flag.cumulativity-weak-constraints}}
\indexspace
\bigletter{d}
\item\relax\sphinxstyleindexentry{Debug Auto}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.debug-auto}}
\item\relax\sphinxstyleindexentry{Debug Cbv}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.debug-cbv}}
\item\relax\sphinxstyleindexentry{Debug Eauto}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.debug-eauto}}
\item\relax\sphinxstyleindexentry{Debug RAKAM}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.debug-rakam}}
\item\relax\sphinxstyleindexentry{Debug Trivial}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.debug-trivial}}
\item\relax\sphinxstyleindexentry{Decidable Equality Schemes}\sphinxstyleindexpageref{user-extensions/proof-schemes:\detokenize{coq:flag.decidable-equality-schemes}}
\item\relax\sphinxstyleindexentry{Default Goal Selector}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:opt.default-goal-selector}}
\item\relax\sphinxstyleindexentry{Default Proof Using}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:opt.default-proof-using}}
\item\relax\sphinxstyleindexentry{Default Timeout}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:opt.default-timeout}}
\indexspace
\bigletter{e}
\item\relax\sphinxstyleindexentry{Elimination Schemes}\sphinxstyleindexpageref{user-extensions/proof-schemes:\detokenize{coq:flag.elimination-schemes}}
\item\relax\sphinxstyleindexentry{Extraction AutoInline}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:flag.extraction-autoinline}}
\item\relax\sphinxstyleindexentry{Extraction Conservative Types}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:flag.extraction-conservative-types}}
\item\relax\sphinxstyleindexentry{Extraction KeepSingleton}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:flag.extraction-keepsingleton}}
\item\relax\sphinxstyleindexentry{Extraction Optimize}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:flag.extraction-optimize}}
\item\relax\sphinxstyleindexentry{Extraction SafeImplicits}\sphinxstyleindexpageref{addendum/extraction:\detokenize{coq:flag.extraction-safeimplicits}}
\indexspace
\bigletter{f}
\item\relax\sphinxstyleindexentry{Firstorder Depth}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:opt.firstorder-depth}}
\item\relax\sphinxstyleindexentry{Firstorder Solver}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:opt.firstorder-solver}}
\indexspace
\bigletter{h}
\item\relax\sphinxstyleindexentry{Hide Obligations}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:flag.hide-obligations}}
\item\relax\sphinxstyleindexentry{Hyps Limit}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:opt.hyps-limit}}
\indexspace
\bigletter{i}
\item\relax\sphinxstyleindexentry{Implicit Arguments}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.implicit-arguments}}
\item\relax\sphinxstyleindexentry{Info Auto}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.info-auto}}
\item\relax\sphinxstyleindexentry{Info Eauto}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.info-eauto}}
\item\relax\sphinxstyleindexentry{Info Level}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:opt.info-level}}
\item\relax\sphinxstyleindexentry{Info Trivial}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.info-trivial}}
\item\relax\sphinxstyleindexentry{Intuition Negation Unfolding}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.intuition-negation-unfolding}}
\indexspace
\bigletter{k}
\item\relax\sphinxstyleindexentry{Keep Proof Equalities}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.keep-proof-equalities}}
\indexspace
\bigletter{l}
\item\relax\sphinxstyleindexentry{Loose Hint Behavior}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:opt.loose-hint-behavior}}
\item\relax\sphinxstyleindexentry{Ltac Batch Debug}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:flag.ltac-batch-debug}}
\item\relax\sphinxstyleindexentry{Ltac Debug}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:flag.ltac-debug}}
\item\relax\sphinxstyleindexentry{Ltac Profiling}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:flag.ltac-profiling}}
\indexspace
\bigletter{m}
\item\relax\sphinxstyleindexentry{Maximal Implicit Insertion}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.maximal-implicit-insertion}}
\indexspace
\bigletter{n}
\item\relax\sphinxstyleindexentry{NativeCompute Profile Filename}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:opt.nativecompute-profile-filename}}
\item\relax\sphinxstyleindexentry{NativeCompute Profiling}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.nativecompute-profiling}}
\item\relax\sphinxstyleindexentry{Nonrecursive Elimination Schemes}\sphinxstyleindexpageref{user-extensions/proof-schemes:\detokenize{coq:flag.nonrecursive-elimination-schemes}}
\indexspace
\bigletter{o}
\item\relax\sphinxstyleindexentry{Omega Action}\sphinxstyleindexpageref{addendum/omega:\detokenize{coq:flag.omega-action}}
\item\relax\sphinxstyleindexentry{Omega System}\sphinxstyleindexpageref{addendum/omega:\detokenize{coq:flag.omega-system}}
\item\relax\sphinxstyleindexentry{Omega UseLocalDefs}\sphinxstyleindexpageref{addendum/omega:\detokenize{coq:flag.omega-uselocaldefs}}
\indexspace
\bigletter{p}
\item\relax\sphinxstyleindexentry{Parsing Explicit}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.parsing-explicit}}
\item\relax\sphinxstyleindexentry{Polymorphic Inductive Cumulativity}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:flag.polymorphic-inductive-cumulativity}}
\item\relax\sphinxstyleindexentry{Primitive Projections}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.primitive-projections}}
\item\relax\sphinxstyleindexentry{Printing All}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.printing-all}}
\item\relax\sphinxstyleindexentry{Printing Allow Match Default Clause}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.printing-allow-match-default-clause}}
\item\relax\sphinxstyleindexentry{Printing Coercion}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:table.printing-coercion}}
\item\relax\sphinxstyleindexentry{Printing Coercions}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:flag.printing-coercions}}
\item\relax\sphinxstyleindexentry{Printing Compact Contexts}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:flag.printing-compact-contexts}}
\item\relax\sphinxstyleindexentry{Printing Constructor}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:table.printing-constructor}}
\item\relax\sphinxstyleindexentry{Printing Dependent Evars Line}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:flag.printing-dependent-evars-line}}
\item\relax\sphinxstyleindexentry{Printing Depth}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:opt.printing-depth}}
\item\relax\sphinxstyleindexentry{Printing Existential Instances}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.printing-existential-instances}}
\item\relax\sphinxstyleindexentry{Printing Factorizable Match Patterns}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.printing-factorizable-match-patterns}}
\item\relax\sphinxstyleindexentry{Printing If}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:table.printing-if}}
\item\relax\sphinxstyleindexentry{Printing Implicit}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.printing-implicit}}
\item\relax\sphinxstyleindexentry{Printing Implicit Defensive}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.printing-implicit-defensive}}
\item\relax\sphinxstyleindexentry{Printing Let}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:table.printing-let}}
\item\relax\sphinxstyleindexentry{Printing Matching}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.printing-matching}}
\item\relax\sphinxstyleindexentry{Printing Notations}\sphinxstyleindexpageref{user-extensions/syntax-extensions:\detokenize{coq:flag.printing-notations}}
\item\relax\sphinxstyleindexentry{Printing Primitive Projection Compatibility}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.printing-primitive-projection-compatibility}}
\item\relax\sphinxstyleindexentry{Printing Primitive Projection Parameters}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.printing-primitive-projection-parameters}}
\item\relax\sphinxstyleindexentry{Printing Projections}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.printing-projections}}
\item\relax\sphinxstyleindexentry{Printing Record}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:table.printing-record}}
\item\relax\sphinxstyleindexentry{Printing Records}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.printing-records}}
\item\relax\sphinxstyleindexentry{Printing Synth}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.printing-synth}}
\item\relax\sphinxstyleindexentry{Printing Unfocused}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:flag.printing-unfocused}}
\item\relax\sphinxstyleindexentry{Printing Universes}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.printing-universes}}
\item\relax\sphinxstyleindexentry{Printing Width}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:opt.printing-width}}
\item\relax\sphinxstyleindexentry{Printing Wildcard}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.printing-wildcard}}
\item\relax\sphinxstyleindexentry{Program Cases}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:flag.program-cases}}
\item\relax\sphinxstyleindexentry{Program Generalized Coercion}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:flag.program-generalized-coercion}}
\indexspace
\bigletter{r}
\item\relax\sphinxstyleindexentry{Refine Instance Mode}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:flag.refine-instance-mode}}
\item\relax\sphinxstyleindexentry{Regular Subst Tactic}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.regular-subst-tactic}}
\item\relax\sphinxstyleindexentry{Reversible Pattern Implicit}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.reversible-pattern-implicit}}
\item\relax\sphinxstyleindexentry{Rewriting Schemes}\sphinxstyleindexpageref{user-extensions/proof-schemes:\detokenize{coq:flag.rewriting-schemes}}
\indexspace
\bigletter{s}
\item\relax\sphinxstyleindexentry{Search Blacklist ‘string’}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:table.search-blacklist-string}}
\item\relax\sphinxstyleindexentry{Search Output Name Only}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:flag.search-output-name-only}}
\item\relax\sphinxstyleindexentry{Short Module Printing}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.short-module-printing}}
\item\relax\sphinxstyleindexentry{Shrink Obligations}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:flag.shrink-obligations}}
\item\relax\sphinxstyleindexentry{Silent}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:flag.silent}}
\item\relax\sphinxstyleindexentry{SsrHave NoTCResolution}\sphinxstyleindexpageref{proof-engine/ssreflect-proof-language:\detokenize{coq:flag.ssrhave-notcresolution}}
\item\relax\sphinxstyleindexentry{Stable Omega}\sphinxstyleindexpageref{addendum/omega:\detokenize{coq:flag.stable-omega}}
\item\relax\sphinxstyleindexentry{Strict Implicit}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.strict-implicit}}
\item\relax\sphinxstyleindexentry{Strict Universe Declaration}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:flag.strict-universe-declaration}}
\item\relax\sphinxstyleindexentry{Strongly Strict Implicit}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:flag.strongly-strict-implicit}}
\item\relax\sphinxstyleindexentry{Structural Injection}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.structural-injection}}
\item\relax\sphinxstyleindexentry{Suggest Proof Using}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:flag.suggest-proof-using}}
\indexspace
\bigletter{t}
\item\relax\sphinxstyleindexentry{Transparent Obligations}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:flag.transparent-obligations}}
\item\relax\sphinxstyleindexentry{Typeclass Resolution For Conversion}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:flag.typeclass-resolution-for-conversion}}
\item\relax\sphinxstyleindexentry{Typeclasses Debug}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:flag.typeclasses-debug}}
\item\relax\sphinxstyleindexentry{Typeclasses Debug Verbosity}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:opt.typeclasses-debug-verbosity}}
\item\relax\sphinxstyleindexentry{Typeclasses Dependency Order}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:flag.typeclasses-dependency-order}}
\item\relax\sphinxstyleindexentry{Typeclasses Filtered Unification}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:flag.typeclasses-filtered-unification}}
\item\relax\sphinxstyleindexentry{Typeclasses Limit Intros}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:flag.typeclasses-limit-intros}}
\item\relax\sphinxstyleindexentry{Typeclasses Strict Resolution}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:flag.typeclasses-strict-resolution}}
\item\relax\sphinxstyleindexentry{Typeclasses Unique Instances}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:flag.typeclasses-unique-instances}}
\item\relax\sphinxstyleindexentry{Typeclasses Unique Solutions}\sphinxstyleindexpageref{addendum/type-classes:\detokenize{coq:flag.typeclasses-unique-solutions}}
\indexspace
\bigletter{u}
\item\relax\sphinxstyleindexentry{Universal Lemma Under Conjunction}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:flag.universal-lemma-under-conjunction}}
\item\relax\sphinxstyleindexentry{Universe Minimization ToSet}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:flag.universe-minimization-toset}}
\item\relax\sphinxstyleindexentry{Universe Polymorphism}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:flag.universe-polymorphism}}
\indexspace
\bigletter{w}
\item\relax\sphinxstyleindexentry{Warnings}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:opt.warnings}}
\end{sphinxtheindex}
\renewcommand{\indexname}{Errors and Warnings Index}
\begin{sphinxtheindex}
\let\bigletter\sphinxstyleindexlettergroup
\bigletter{@}
\item\relax\sphinxstyleindexentry{@ident already exists. (Axiom)}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:exn.ident-already-exists-axiom}}
\item\relax\sphinxstyleindexentry{@ident already exists. (Definition)}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:exn.ident-already-exists-definition}}
\item\relax\sphinxstyleindexentry{@ident already exists. (Let)}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:exn.ident-already-exists-let}}
\item\relax\sphinxstyleindexentry{@ident already exists. (Program Definition)}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:exn.ident-already-exists-program-definition}}
\item\relax\sphinxstyleindexentry{@ident already exists. (Theorem)}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:exn.ident-already-exists-theorem}}
\item\relax\sphinxstyleindexentry{@ident already exists. (Variable)}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:exn.ident-already-exists-variable}}
\indexspace
\bigletter{a}
\item\relax\sphinxstyleindexentry{Ambiguous path}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:warn.ambiguous-path}}
\item\relax\sphinxstyleindexentry{Argument of match does not evaluate to a term}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.argument-of-match-does-not-evaluate-to-a-term}}
\item\relax\sphinxstyleindexentry{Arguments of ring\_simplify do not have all the same type}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:exn.arguments-of-ring-simplify-do-not-have-all-the-same-type}}
\item\relax\sphinxstyleindexentry{Attempt to save an incomplete proof}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:exn.attempt-to-save-an-incomplete-proof}}
\indexspace
\bigletter{b}
\item\relax\sphinxstyleindexentry{Bad lemma for decidability of equality}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:exn.bad-lemma-for-decidability-of-equality}}
\item\relax\sphinxstyleindexentry{Bad magic number}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.bad-magic-number}}
\item\relax\sphinxstyleindexentry{Bad occurrence number of ‘qualid’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.bad-occurrence-number-of-qualid}}
\item\relax\sphinxstyleindexentry{Bad ring structure}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:exn.bad-ring-structure}}
\item\relax\sphinxstyleindexentry{Brackets only support the single numbered goal selector}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:exn.brackets-only-support-the-single-numbered-goal-selector}}
\indexspace
\bigletter{c}
\item\relax\sphinxstyleindexentry{Cannot build functional inversion principle}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:warn.cannot-build-functional-inversion-principle}}
\item\relax\sphinxstyleindexentry{Cannot define graph for ‘ident’}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:warn.cannot-define-graph-for-ident}}
\item\relax\sphinxstyleindexentry{Cannot define principle(s) for ‘ident’}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:warn.cannot-define-principle-s-for-ident}}
\item\relax\sphinxstyleindexentry{Cannot find a declared ring structure for equality ‘term’}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:exn.cannot-find-a-declared-ring-structure-for-equality-term}}
\item\relax\sphinxstyleindexentry{Cannot find a declared ring structure over ‘term’}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:exn.cannot-find-a-declared-ring-structure-over-term}}
\item\relax\sphinxstyleindexentry{Cannot find induction information on ‘qualid’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.cannot-find-induction-information-on-qualid}}
\item\relax\sphinxstyleindexentry{Cannot find inversion information for hypothesis ‘ident’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.cannot-find-inversion-information-for-hypothesis-ident}}
\item\relax\sphinxstyleindexentry{Cannot find library foo in loadpath}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.cannot-find-library-foo-in-loadpath}}
\item\relax\sphinxstyleindexentry{Cannot find the source class of ‘qualid’}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:exn.cannot-find-the-source-class-of-qualid}}
\item\relax\sphinxstyleindexentry{Cannot handle mutually (co)inductive records}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:exn.cannot-handle-mutually-co-inductive-records}}
\item\relax\sphinxstyleindexentry{Cannot infer a term for this placeholder. (Casual use of implicit arguments)}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:exn.cannot-infer-a-term-for-this-placeholder-casual-use-of-implicit-arguments}}
\item\relax\sphinxstyleindexentry{Cannot infer a term for this placeholder. (refine)}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.cannot-infer-a-term-for-this-placeholder-refine}}
\item\relax\sphinxstyleindexentry{Cannot load qualid: no physical path bound to dirpath}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.cannot-load-qualid-no-physical-path-bound-to-dirpath}}
\item\relax\sphinxstyleindexentry{Cannot move ‘ident’ after ‘ident’: it depends on ‘ident’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.cannot-move-ident-after-ident-it-depends-on-ident}}
\item\relax\sphinxstyleindexentry{Cannot move ‘ident’ after ‘ident’: it occurs in the type of ‘ident’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.cannot-move-ident-after-ident-it-occurs-in-the-type-of-ident}}
\item\relax\sphinxstyleindexentry{Cannot recognize a boolean equality}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.cannot-recognize-a-boolean-equality}}
\item\relax\sphinxstyleindexentry{Cannot recognize ‘class’ as a source class of ‘qualid’}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:exn.cannot-recognize-class-as-a-source-class-of-qualid}}
\item\relax\sphinxstyleindexentry{Cannot solve the goal}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.cannot-solve-the-goal}}
\item\relax\sphinxstyleindexentry{Cannot use mutual definition with well-founded recursion or measure}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:exn.cannot-use-mutual-definition-with-well-founded-recursion-or-measure}}
\item\relax\sphinxstyleindexentry{Can’t find file ‘ident’ on loadpath}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.cant-find-file-ident-on-loadpath}}
\item\relax\sphinxstyleindexentry{Compiled library ‘ident’.vo makes inconsistent assumptions over library qualid}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.compiled-library-ident-vo-makes-inconsistent-assumptions-over-library-qualid}}
\item\relax\sphinxstyleindexentry{Condition not satisfied}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.condition-not-satisfied}}
\indexspace
\bigletter{d}
\item\relax\sphinxstyleindexentry{Debug mode not available in the IDE}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.debug-mode-not-available-in-the-ide}}
\indexspace
\bigletter{e}
\item\relax\sphinxstyleindexentry{Either there is a type incompatibility or the problem involves dependencies}\sphinxstyleindexpageref{addendum/extended-pattern-matching:\detokenize{coq:exn.either-there-is-a-type-incompatibility-or-the-problem-involves-dependencies}}
\indexspace
\bigletter{f}
\item\relax\sphinxstyleindexentry{Failed to progress}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.failed-to-progress}}
\item\relax\sphinxstyleindexentry{File not found on loadpath: ‘string’}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.file-not-found-on-loadpath-string}}
\item\relax\sphinxstyleindexentry{Files processed by Load cannot leave open proofs}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.files-processed-by-load-cannot-leave-open-proofs}}
\item\relax\sphinxstyleindexentry{Found target class ... instead of ...}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:exn.found-target-class-instead-of}}
\item\relax\sphinxstyleindexentry{Funclass cannot be a source class}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:exn.funclass-cannot-be-a-source-class}}
\indexspace
\bigletter{g}
\item\relax\sphinxstyleindexentry{goal does not satisfy the expected preconditions}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.goal-does-not-satisfy-the-expected-preconditions}}
\item\relax\sphinxstyleindexentry{Goal is solvable by congruence but some arguments are missing. Try congruence with ‘term’…‘term’, replacing metavariables by arbitrary terms}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.goal-is-solvable-by-congruence-but-some-arguments-are-missing-try-congruence-with-term-term-replacing-metavariables-by-arbitrary-terms}}
\indexspace
\bigletter{h}
\item\relax\sphinxstyleindexentry{Hypothesis ‘ident’ must contain at least one Function}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.hypothesis-ident-must-contain-at-least-one-function}}
\indexspace
\bigletter{i}
\item\relax\sphinxstyleindexentry{I don’t know how to handle dependent equality}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.i-dont-know-how-to-handle-dependent-equality}}
\item\relax\sphinxstyleindexentry{Ill-formed recursive definition}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:exn.ill-formed-recursive-definition}}
\item\relax\sphinxstyleindexentry{In environment … the term: ‘term’ does not have type ‘type’. Actually, it has type ...}\sphinxstyleindexpageref{addendum/program:\detokenize{coq:exn.in-environment-the-term-term-does-not-have-type-type-actually-it-has-type}}
\item\relax\sphinxstyleindexentry{Invalid argument}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.invalid-argument}}
\item\relax\sphinxstyleindexentry{Invalid backtrack}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.invalid-backtrack}}
\indexspace
\bigletter{l}
\item\relax\sphinxstyleindexentry{Load is not supported inside proofs}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.load-is-not-supported-inside-proofs}}
\item\relax\sphinxstyleindexentry{Loading of ML object file forbidden in a native Coq}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.loading-of-ml-object-file-forbidden-in-a-native-coq}}
\indexspace
\bigletter{m}
\item\relax\sphinxstyleindexentry{Module/section ‘qualid’ not found}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.module-section-qualid-not-found}}
\indexspace
\bigletter{n}
\item\relax\sphinxstyleindexentry{No applicable tactic}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.no-applicable-tactic}}
\item\relax\sphinxstyleindexentry{No argument name ‘ident’}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:exn.no-argument-name-ident}}
\item\relax\sphinxstyleindexentry{No discriminable equalities}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.no-discriminable-equalities}}
\item\relax\sphinxstyleindexentry{No evars}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.no-evars}}
\item\relax\sphinxstyleindexentry{No focused proof}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:exn.no-focused-proof}}
\item\relax\sphinxstyleindexentry{No focused proof (No proof-editing in progress)}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:exn.no-focused-proof-no-proof-editing-in-progress}}
\item\relax\sphinxstyleindexentry{No focused proof to restart}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:exn.no-focused-proof-to-restart}}
\item\relax\sphinxstyleindexentry{No head constant to reduce}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.no-head-constant-to-reduce}}
\item\relax\sphinxstyleindexentry{No matching clauses for match}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.no-matching-clauses-for-match}}
\item\relax\sphinxstyleindexentry{No matching clauses for match goal}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.no-matching-clauses-for-match-goal}}
\item\relax\sphinxstyleindexentry{No primitive equality found}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.no-primitive-equality-found}}
\item\relax\sphinxstyleindexentry{No product even after head-reduction}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.no-product-even-after-head-reduction}}
\item\relax\sphinxstyleindexentry{No progress made}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:exn.no-progress-made}}
\item\relax\sphinxstyleindexentry{No such assumption}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.no-such-assumption}}
\item\relax\sphinxstyleindexentry{No such binder}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.no-such-binder}}
\item\relax\sphinxstyleindexentry{No such goal}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:exn.no-such-goal}}
\item\relax\sphinxstyleindexentry{No such goal. (fail)}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.no-such-goal-fail}}
\item\relax\sphinxstyleindexentry{No such goal. (Focusing)}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:exn.no-such-goal-focusing}}
\item\relax\sphinxstyleindexentry{No such goal. (Goal selector)}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.no-such-goal-goal-selector}}
\item\relax\sphinxstyleindexentry{No such goal. Focus next goal with bullet ‘bullet’}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:exn.no-such-goal-focus-next-goal-with-bullet-bullet}}
\item\relax\sphinxstyleindexentry{No such hypothesis}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.no-such-hypothesis}}
\item\relax\sphinxstyleindexentry{No such hypothesis in current goal}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.no-such-hypothesis-in-current-goal}}
\item\relax\sphinxstyleindexentry{No such hypothesis: ‘ident’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.no-such-hypothesis-ident}}
\item\relax\sphinxstyleindexentry{No such label ‘ident’}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:exn.no-such-label-ident}}
\item\relax\sphinxstyleindexentry{Non exhaustive pattern matching}\sphinxstyleindexpageref{addendum/extended-pattern-matching:\detokenize{coq:exn.non-exhaustive-pattern-matching}}
\item\relax\sphinxstyleindexentry{Non strictly positive occurrence of ‘ident’ in ‘type’}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:exn.non-strictly-positive-occurrence-of-ident-in-type}}
\item\relax\sphinxstyleindexentry{Not a context variable}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.not-a-context-variable}}
\item\relax\sphinxstyleindexentry{Not a discriminable equality}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-a-discriminable-equality}}
\item\relax\sphinxstyleindexentry{Not a primitive equality}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-a-primitive-equality}}
\item\relax\sphinxstyleindexentry{Not a projectable equality but a discriminable one}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-a-projectable-equality-but-a-discriminable-one}}
\item\relax\sphinxstyleindexentry{Not a proposition or a type}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-a-proposition-or-a-type}}
\item\relax\sphinxstyleindexentry{Not a valid ring equation}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:exn.not-a-valid-ring-equation}}
\item\relax\sphinxstyleindexentry{Not a variable or hypothesis}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-a-variable-or-hypothesis}}
\item\relax\sphinxstyleindexentry{Not an evar}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-an-evar}}
\item\relax\sphinxstyleindexentry{Not an exact proof}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-an-exact-proof}}
\item\relax\sphinxstyleindexentry{Not an inductive goal with 1 constructor}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-an-inductive-goal-with-1-constructor}}
\item\relax\sphinxstyleindexentry{Not an inductive goal with 2 constructors}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-an-inductive-goal-with-2-constructors}}
\item\relax\sphinxstyleindexentry{Not an inductive product}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-an-inductive-product}}
\item\relax\sphinxstyleindexentry{Not convertible}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-convertible}}
\item\relax\sphinxstyleindexentry{Not enough constructors}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-enough-constructors}}
\item\relax\sphinxstyleindexentry{Not equal}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-equal}}
\item\relax\sphinxstyleindexentry{Not reducible}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-reducible}}
\item\relax\sphinxstyleindexentry{Not the right number of induction arguments}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-the-right-number-of-induction-arguments}}
\item\relax\sphinxstyleindexentry{Not the right number of missing arguments}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.not-the-right-number-of-missing-arguments}}
\item\relax\sphinxstyleindexentry{Nothing to do, it is an equality between convertible ‘terms’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.nothing-to-do-it-is-an-equality-between-convertible-terms}}
\item\relax\sphinxstyleindexentry{Nothing to inject}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.nothing-to-inject}}
\item\relax\sphinxstyleindexentry{Nothing to rewrite}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:exn.nothing-to-rewrite}}
\indexspace
\bigletter{o}
\item\relax\sphinxstyleindexentry{omega can't solve this system}\sphinxstyleindexpageref{addendum/omega:\detokenize{coq:exn.omega-can-t-solve-this-system}}
\item\relax\sphinxstyleindexentry{omega: Can't solve a goal with equality on type ...}\sphinxstyleindexpageref{addendum/omega:\detokenize{coq:exn.omega-can-t-solve-a-goal-with-equality-on-type}}
\item\relax\sphinxstyleindexentry{omega: Can't solve a goal with non-linear products}\sphinxstyleindexpageref{addendum/omega:\detokenize{coq:exn.omega-can-t-solve-a-goal-with-non-linear-products}}
\item\relax\sphinxstyleindexentry{omega: Can't solve a goal with proposition variables}\sphinxstyleindexpageref{addendum/omega:\detokenize{coq:exn.omega-can-t-solve-a-goal-with-proposition-variables}}
\item\relax\sphinxstyleindexentry{omega: Not a quantifier-free goal}\sphinxstyleindexpageref{addendum/omega:\detokenize{coq:exn.omega-not-a-quantifier-free-goal}}
\item\relax\sphinxstyleindexentry{omega: Unrecognized atomic proposition: ...}\sphinxstyleindexpageref{addendum/omega:\detokenize{coq:exn.omega-unrecognized-atomic-proposition}}
\item\relax\sphinxstyleindexentry{omega: Unrecognized predicate or connective: ‘ident’}\sphinxstyleindexpageref{addendum/omega:\detokenize{coq:exn.omega-unrecognized-predicate-or-connective-ident}}
\item\relax\sphinxstyleindexentry{omega: Unrecognized proposition}\sphinxstyleindexpageref{addendum/omega:\detokenize{coq:exn.omega-unrecognized-proposition}}
\indexspace
\bigletter{p}
\item\relax\sphinxstyleindexentry{Proof is not complete. (abstract)}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.proof-is-not-complete-abstract}}
\item\relax\sphinxstyleindexentry{Proof is not complete. (assert)}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.proof-is-not-complete-assert}}
\indexspace
\bigletter{q}
\item\relax\sphinxstyleindexentry{quote: not a simple fixpoint}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.quote-not-a-simple-fixpoint}}
\indexspace
\bigletter{r}
\item\relax\sphinxstyleindexentry{Records declared with the keyword Record or Structure cannot be recursive}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:exn.records-declared-with-the-keyword-record-or-structure-cannot-be-recursive}}
\item\relax\sphinxstyleindexentry{Refine passed ill-formed term}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.refine-passed-ill-formed-term}}
\item\relax\sphinxstyleindexentry{Require is not allowed inside a module or a module type}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.require-is-not-allowed-inside-a-module-or-a-module-type}}
\item\relax\sphinxstyleindexentry{Ring operation should be declared as a morphism}\sphinxstyleindexpageref{addendum/ring:\detokenize{coq:exn.ring-operation-should-be-declared-as-a-morphism}}
\indexspace
\bigletter{s}
\item\relax\sphinxstyleindexentry{Signature components for label ‘ident’ do not match}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:exn.signature-components-for-label-ident-do-not-match}}
\item\relax\sphinxstyleindexentry{Statement without assumptions}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.statement-without-assumptions}}
\indexspace
\bigletter{t}
\item\relax\sphinxstyleindexentry{Tactic Failure message (level ‘num’)}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.tactic-failure-message-level-num}}
\item\relax\sphinxstyleindexentry{Tactic generated a subgoal identical to the original goal. This happens if ‘term’ does not occur in the goal}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.tactic-generated-a-subgoal-identical-to-the-original-goal-this-happens-if-term-does-not-occur-in-the-goal}}
\item\relax\sphinxstyleindexentry{Terms do not have convertible types}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.terms-do-not-have-convertible-types}}
\item\relax\sphinxstyleindexentry{The command has not failed!}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.the-command-has-not-failed}}
\item\relax\sphinxstyleindexentry{The conclusion is not a substitutive equation}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.the-conclusion-is-not-a-substitutive-equation}}
\item\relax\sphinxstyleindexentry{The conclusion of ‘type’ is not valid; it must be built from ‘ident’}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:exn.the-conclusion-of-type-is-not-valid-it-must-be-built-from-ident}}
\item\relax\sphinxstyleindexentry{The constructor ‘ident’ expects ‘num’ arguments}\sphinxstyleindexpageref{addendum/extended-pattern-matching:\detokenize{coq:exn.the-constructor-ident-expects-num-arguments}}
\item\relax\sphinxstyleindexentry{The elimination predicate term should be of arity ‘num’ (for non dependent case) or ‘num’ (for dependent case)}\sphinxstyleindexpageref{addendum/extended-pattern-matching:\detokenize{coq:exn.the-elimination-predicate-term-should-be-of-arity-num-for-non-dependent-case-or-num-for-dependent-case}}
\item\relax\sphinxstyleindexentry{The file {}`ident.vo{}` contains library dirpath and not library dirpath’}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.the-file-ident-vo-contains-library-dirpath-and-not-library-dirpath}}
\item\relax\sphinxstyleindexentry{The recursive argument must be specified}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:exn.the-recursive-argument-must-be-specified}}
\item\relax\sphinxstyleindexentry{The reference is not unfoldable}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.the-reference-is-not-unfoldable}}
\item\relax\sphinxstyleindexentry{The reference ‘qualid’ was not found in the current environment}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.the-reference-qualid-was-not-found-in-the-current-environment}}
\item\relax\sphinxstyleindexentry{The term ‘term’ has type ‘type’ which should be Set, Prop or Type}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:exn.the-term-term-has-type-type-which-should-be-set-prop-or-type}}
\item\relax\sphinxstyleindexentry{The term ‘term’ has type ‘type’ while it is expected to have type ‘type’'}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:exn.the-term-term-has-type-type-while-it-is-expected-to-have-type-type}}
\item\relax\sphinxstyleindexentry{The variable ‘ident’ is already defined}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.the-variable-ident-is-already-defined}}
\item\relax\sphinxstyleindexentry{The ‘num’ th argument of ‘ident’ must be ‘ident’ in ‘type’}\sphinxstyleindexpageref{language/gallina-specification-language:\detokenize{coq:exn.the-num-th-argument-of-ident-must-be-ident-in-type}}
\item\relax\sphinxstyleindexentry{The ‘term’ provided does not end with an equation}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.the-term-provided-does-not-end-with-an-equation}}
\item\relax\sphinxstyleindexentry{This is not the last opened module}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:exn.this-is-not-the-last-opened-module}}
\item\relax\sphinxstyleindexentry{This is not the last opened module type}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:exn.this-is-not-the-last-opened-module-type}}
\item\relax\sphinxstyleindexentry{This is not the last opened section}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:exn.this-is-not-the-last-opened-section}}
\item\relax\sphinxstyleindexentry{This object does not support universe names}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.this-object-does-not-support-universe-names}}
\item\relax\sphinxstyleindexentry{This proof is focused, but cannot be unfocused this way}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:exn.this-proof-is-focused-but-cannot-be-unfocused-this-way}}
\item\relax\sphinxstyleindexentry{This tactic has more than one success}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.this-tactic-has-more-than-one-success}}
\item\relax\sphinxstyleindexentry{Too few occurrences}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.too-few-occurrences}}
\item\relax\sphinxstyleindexentry{Trying to mask the absolute name ‘qualid’!}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:warn.trying-to-mask-the-absolute-name-qualid}}
\indexspace
\bigletter{u}
\item\relax\sphinxstyleindexentry{Unable to apply}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.unable-to-apply}}
\item\relax\sphinxstyleindexentry{Unable to find an instance for the variables ‘ident’…‘ident’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.unable-to-find-an-instance-for-the-variables-ident-ident}}
\item\relax\sphinxstyleindexentry{Unable to infer a match predicate}\sphinxstyleindexpageref{addendum/extended-pattern-matching:\detokenize{coq:exn.unable-to-infer-a-match-predicate}}
\item\relax\sphinxstyleindexentry{Unable to satisfy the rewriting constraints}\sphinxstyleindexpageref{addendum/generalized-rewriting:\detokenize{coq:exn.unable-to-satisfy-the-rewriting-constraints}}
\item\relax\sphinxstyleindexentry{Unable to unify ... with ...}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.unable-to-unify-with}}
\item\relax\sphinxstyleindexentry{Unable to unify ‘term’ with ‘term’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.unable-to-unify-term-with-term}}
\item\relax\sphinxstyleindexentry{Unbound context identifier ‘ident’}\sphinxstyleindexpageref{proof-engine/ltac:\detokenize{coq:exn.unbound-context-identifier-ident}}
\item\relax\sphinxstyleindexentry{Undeclared universe ‘ident’}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:exn.undeclared-universe-ident}}
\item\relax\sphinxstyleindexentry{Universe inconsistency}\sphinxstyleindexpageref{addendum/universe-polymorphism:\detokenize{coq:exn.universe-inconsistency}}
\item\relax\sphinxstyleindexentry{Universe instance should have length ‘num’}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.universe-instance-should-have-length-num}}
\item\relax\sphinxstyleindexentry{Unknown inductive type}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:exn.unknown-inductive-type}}
\indexspace
\bigletter{v}
\item\relax\sphinxstyleindexentry{Variable ‘ident’ is already declared}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.variable-ident-is-already-declared}}
\indexspace
\bigletter{w}
\item\relax\sphinxstyleindexentry{When ‘term’ contains more than one non dependent product the tactic lapply only takes into account the first product}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:warn.when-term-contains-more-than-one-non-dependent-product-the-tactic-lapply-only-takes-into-account-the-first-product}}
\item\relax\sphinxstyleindexentry{Wrong bullet ‘bullet’: Bullet ‘bullet’ is mandatory here}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:exn.wrong-bullet-bullet-bullet-bullet-is-mandatory-here}}
\item\relax\sphinxstyleindexentry{Wrong bullet ‘bullet’: Current bullet ‘bullet’ is not finished}\sphinxstyleindexpageref{proof-engine/proof-handling:\detokenize{coq:exn.wrong-bullet-bullet-current-bullet-bullet-is-not-finished}}
\indexspace
\bigletter{‘}
\item\relax\sphinxstyleindexentry{‘class’ must be a transparent constant}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:exn.class-must-be-a-transparent-constant}}
\item\relax\sphinxstyleindexentry{‘ident’ cannot be defined}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:warn.ident-cannot-be-defined}}
\item\relax\sphinxstyleindexentry{‘ident’ is already used}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.ident-is-already-used}}
\item\relax\sphinxstyleindexentry{‘ident’ is not a local definition}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.ident-is-not-a-local-definition}}
\item\relax\sphinxstyleindexentry{‘ident’ is not an inductive type}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.ident-is-not-an-inductive-type}}
\item\relax\sphinxstyleindexentry{‘ident’ is used in conclusion}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.ident-is-used-in-conclusion}}
\item\relax\sphinxstyleindexentry{‘ident’ is used in hypothesis ‘ident’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.ident-is-used-in-hypothesis-ident}}
\item\relax\sphinxstyleindexentry{‘ident’ is used in the conclusion}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.ident-is-used-in-the-conclusion}}
\item\relax\sphinxstyleindexentry{‘ident’ is used in the hypothesis ‘ident’}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.ident-is-used-in-the-hypothesis-ident}}
\item\relax\sphinxstyleindexentry{‘ident’: no such entry}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.ident-no-such-entry}}
\item\relax\sphinxstyleindexentry{‘qualid’ does not denote an evaluable constant}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.qualid-does-not-denote-an-evaluable-constant}}
\item\relax\sphinxstyleindexentry{‘qualid’ does not occur}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.qualid-does-not-occur}}
\item\relax\sphinxstyleindexentry{‘qualid’ does not respect the uniform inheritance condition}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:exn.qualid-does-not-respect-the-uniform-inheritance-condition}}
\item\relax\sphinxstyleindexentry{‘qualid’ is already a coercion}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:exn.qualid-is-already-a-coercion}}
\item\relax\sphinxstyleindexentry{‘qualid’ is not a function}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:exn.qualid-is-not-a-function}}
\item\relax\sphinxstyleindexentry{‘qualid’ is not a module}\sphinxstyleindexpageref{language/gallina-extensions:\detokenize{coq:exn.qualid-is-not-a-module}}
\item\relax\sphinxstyleindexentry{‘qualid’ not a defined object}\sphinxstyleindexpageref{proof-engine/vernacular-commands:\detokenize{coq:exn.qualid-not-a-defined-object}}
\item\relax\sphinxstyleindexentry{‘qualid’ not declared}\sphinxstyleindexpageref{addendum/implicit-coercions:\detokenize{coq:exn.qualid-not-declared}}
\item\relax\sphinxstyleindexentry{‘term’ cannot be used as a hint}\sphinxstyleindexpageref{proof-engine/tactics:\detokenize{coq:exn.term-cannot-be-used-as-a-hint}}
\end{sphinxtheindex}

\renewcommand{\indexname}{Index}
\printindex
\end{document}